1 #include <u.h> 2 #include <libc.h> 3 #include <draw.h> 4 #include <event.h> 5 #include <bio.h> 6 #include "page.h" 7 8 int resizing; 9 int newwindow; 10 int doabort; 11 int chatty; 12 int reverse = -1; 13 int goodps = 1; 14 int ppi = 100; 15 int teegs = 0; 16 int truetoboundingbox; 17 int textbits=4, gfxbits=4; 18 int wctlfd = -1; 19 int stdinfd; 20 int truecolor; 21 int imagemode; 22 int notewatcher; 23 int notegp; 24 25 int 26 watcher(void*, char *x) 27 { 28 if(strcmp(x, "die") != 0) 29 postnote(PNGROUP, notegp, x); 30 _exits(0); 31 return 0; 32 } 33 34 int 35 bell(void *u, char *x) 36 { 37 if(x && strcmp(x, "hangup") == 0) 38 _exits(0); 39 40 if(x && strstr(x, "die") == nil) 41 fprint(2, "postnote %d: %s\n", getpid(), x); 42 43 /* alarms come from the gs monitor */ 44 if(x && strstr(x, "alarm")){ 45 postnote(PNGROUP, getpid(), "die (gs error)"); 46 postnote(PNPROC, notewatcher, "die (gs error)"); 47 } 48 49 /* function mentions u so that it's in the stack trace */ 50 if((u == nil || u != x) && doabort) 51 abort(); 52 53 /* fprint(2, "exiting %d\n", getpid()); */ 54 wexits("note"); 55 return 0; 56 } 57 58 void 59 main(int argc, char **argv) 60 { 61 Document *doc; 62 Biobuf *b; 63 enum { Ninput = 16 }; 64 uchar buf[Ninput+1]; 65 int readstdin; 66 67 ARGBEGIN{ 68 /* "temporary" debugging options */ 69 case 'P': 70 goodps = 0; 71 break; 72 case 'v': 73 chatty++; 74 break; 75 case 'V': 76 teegs++; 77 break; 78 case 'a': 79 doabort++; 80 break; 81 82 /* real options */ 83 case 'R': 84 resizing = 1; 85 break; 86 case 'r': 87 reverse = 1; 88 break; 89 case 'p': 90 ppi = atoi(ARGF()); 91 break; 92 case 'b': 93 truetoboundingbox = 1; 94 break; 95 case 'w': 96 newwindow = 1; 97 resizing = 1; 98 break; 99 case 'i': 100 imagemode = 1; 101 break; 102 default: 103 fprint(2, "usage: page file...\n"); 104 wexits("usage"); 105 }ARGEND; 106 107 notegp = getpid(); 108 109 switch(notewatcher = fork()){ 110 case -1: 111 sysfatal("fork\n"); 112 exits(0); 113 default: 114 break; 115 case 0: 116 atnotify(watcher, 1); 117 for(;;) 118 sleep(1000); 119 _exits(0); 120 } 121 122 rfork(RFNOTEG); 123 atnotify(bell, 1); 124 125 readstdin = 0; 126 if(imagemode == 0 && argc == 0){ 127 readstdin = 1; 128 stdinfd = dup(0, -1); 129 close(0); 130 open("/dev/cons", OREAD); 131 } 132 133 fmtinstall('R', Rfmt); 134 fmtinstall('P', Pfmt); 135 if(newwindow) 136 newwin(); 137 138 if(readstdin){ 139 b = nil; 140 if(readn(stdinfd, buf, Ninput) != Ninput){ 141 fprint(2, "page: short read reading %s\n", argv[0]); 142 wexits("read"); 143 } 144 }else if(argc != 0){ 145 if(!(b = Bopen(argv[0], OREAD))) { 146 fprint(2, "page: cannot open \"%s\"\n", argv[0]); 147 wexits("open"); 148 } 149 150 if(Bread(b, buf, Ninput) != Ninput) { 151 fprint(2, "page: short read reading %s\n", argv[0]); 152 wexits("read"); 153 } 154 }else 155 b = nil; 156 157 buf[Ninput] = '\0'; 158 if(imagemode) 159 doc = initgfx(nil, 0, nil, nil, 0); 160 else if(strncmp((char*)buf, "%PDF-", 5) == 0) 161 doc = initpdf(b, argc, argv, buf, Ninput); 162 else if(strncmp((char*)buf, "\x04%!", 2) == 0) 163 doc = initps(b, argc, argv, buf, Ninput); 164 else if(buf[0] == '\x1B' && strstr((char*)buf, "@PJL")) 165 doc = initps(b, argc, argv, buf, Ninput); 166 else if(strncmp((char*)buf, "%!", 2) == 0) 167 doc = initps(b, argc, argv, buf, Ninput); 168 else if(strcmp((char*)buf, "\xF7\x02\x01\x83\x92\xC0\x1C;") == 0) 169 doc = initdvi(b, argc, argv, buf, Ninput); 170 else if(strncmp((char*)buf, "x T ", 4) == 0) 171 doc = inittroff(b, argc, argv, buf, Ninput); 172 else { 173 if(ppi != 100) { 174 fprint(2, "page: you can't specify -p with graphic files\n"); 175 wexits("-p and graphics"); 176 } 177 doc = initgfx(b, argc, argv, buf, Ninput); 178 } 179 180 if(doc == nil) { 181 fprint(2, "page: error reading file: %r\n"); 182 wexits("document init"); 183 } 184 185 if(doc->npage < 1 && !imagemode) { 186 fprint(2, "page: no pages found?\n"); 187 wexits("pagecount"); 188 } 189 190 if(reverse == -1) /* neither cmdline nor ps reader set it */ 191 reverse = 0; 192 193 if(initdraw(0, 0, "page") < 0){ 194 fprint(2, "page: initdraw failed: %r\n"); 195 wexits("initdraw"); 196 } 197 truecolor = screen->depth > 8; 198 viewer(doc); 199 wexits(0); 200 } 201 202 void 203 wexits(char *s) 204 { 205 if(s && *s && strcmp(s, "note") != 0 && newwindow) 206 sleep(10*1000); 207 postnote(PNPROC, notewatcher, "die"); 208 exits(s); 209 } 210