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 mknewwindow; 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 static int 59 afmt(Fmt *fmt) 60 { 61 char *s; 62 63 s = va_arg(fmt->args, char*); 64 if(s == nil || s[0] == '\0') 65 return fmtstrcpy(fmt, ""); 66 else 67 return fmtprint(fmt, "%#q", s); 68 } 69 70 void 71 usage(void) 72 { 73 fprint(2, "usage: page [-biRrw] [-p ppi] file...\n"); 74 exits("usage"); 75 } 76 77 void 78 main(int argc, char **argv) 79 { 80 Document *doc; 81 Biobuf *b; 82 enum { Ninput = 16 }; 83 uchar buf[Ninput+1]; 84 int readstdin; 85 86 ARGBEGIN{ 87 /* "temporary" debugging options */ 88 case 'P': 89 goodps = 0; 90 break; 91 case 'v': 92 chatty++; 93 break; 94 case 'V': 95 teegs++; 96 break; 97 case 'a': 98 doabort++; 99 break; 100 case 'T': 101 textbits = atoi(EARGF(usage())); 102 gfxbits = atoi(EARGF(usage())); 103 break; 104 105 /* real options */ 106 case 'R': 107 resizing = 1; 108 break; 109 case 'r': 110 reverse = 1; 111 break; 112 case 'p': 113 ppi = atoi(EARGF(usage())); 114 break; 115 case 'b': 116 truetoboundingbox = 1; 117 break; 118 case 'w': 119 mknewwindow = 1; 120 resizing = 1; 121 break; 122 case 'i': 123 imagemode = 1; 124 break; 125 default: 126 usage(); 127 }ARGEND; 128 129 notegp = getpid(); 130 131 switch(notewatcher = fork()){ 132 case -1: 133 sysfatal("fork\n"); 134 exits(0); 135 default: 136 break; 137 case 0: 138 atnotify(watcher, 1); 139 for(;;) 140 sleep(1000); 141 /* not reached */ 142 } 143 144 rfork(RFNOTEG); 145 atnotify(bell, 1); 146 147 readstdin = 0; 148 if(imagemode == 0 && argc == 0){ 149 readstdin = 1; 150 stdinfd = dup(0, -1); 151 close(0); 152 open("/dev/cons", OREAD); 153 } 154 155 quotefmtinstall(); 156 fmtinstall('a', afmt); 157 158 fmtinstall('R', Rfmt); 159 fmtinstall('P', Pfmt); 160 if(mknewwindow) 161 newwin(); 162 163 if(readstdin){ 164 b = nil; 165 if(readn(stdinfd, buf, Ninput) != Ninput){ 166 fprint(2, "page: short read reading %s\n", argv[0]); 167 wexits("read"); 168 } 169 }else if(argc != 0){ 170 if(!(b = Bopen(argv[0], OREAD))) { 171 fprint(2, "page: cannot open \"%s\"\n", argv[0]); 172 wexits("open"); 173 } 174 175 if(Bread(b, buf, Ninput) != Ninput) { 176 fprint(2, "page: short read reading %s\n", argv[0]); 177 wexits("read"); 178 } 179 }else 180 b = nil; 181 182 buf[Ninput] = '\0'; 183 if(imagemode) 184 doc = initgfx(nil, 0, nil, nil, 0); 185 else if(strncmp((char*)buf, "%PDF-", 5) == 0) 186 doc = initpdf(b, argc, argv, buf, Ninput); 187 else if(strncmp((char*)buf, "\x04%!", 2) == 0) 188 doc = initps(b, argc, argv, buf, Ninput); 189 else if(buf[0] == '\x1B' && strstr((char*)buf, "@PJL")) 190 doc = initps(b, argc, argv, buf, Ninput); 191 else if(strncmp((char*)buf, "%!", 2) == 0) 192 doc = initps(b, argc, argv, buf, Ninput); 193 else if(strcmp((char*)buf, "\xF7\x02\x01\x83\x92\xC0\x1C;") == 0) 194 doc = initdvi(b, argc, argv, buf, Ninput); 195 else if(strncmp((char*)buf, "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1", 8) == 0) 196 doc = initmsdoc(b, argc, argv, buf, Ninput); 197 else if(strncmp((char*)buf, "x T ", 4) == 0) 198 doc = inittroff(b, argc, argv, buf, Ninput); 199 else { 200 if(ppi != 100) { 201 fprint(2, "page: you can't specify -p with graphic files\n"); 202 wexits("-p and graphics"); 203 } 204 doc = initgfx(b, argc, argv, buf, Ninput); 205 } 206 207 if(doc == nil) { 208 fprint(2, "page: error reading file: %r\n"); 209 wexits("document init"); 210 } 211 212 if(doc->npage < 1 && !imagemode) { 213 fprint(2, "page: no pages found?\n"); 214 wexits("pagecount"); 215 } 216 217 if(reverse == -1) /* neither cmdline nor ps reader set it */ 218 reverse = 0; 219 220 if(initdraw(0, 0, "page") < 0){ 221 fprint(2, "page: initdraw failed: %r\n"); 222 wexits("initdraw"); 223 } 224 truecolor = screen->depth > 8; 225 viewer(doc); 226 wexits(0); 227 } 228 229 void 230 wexits(char *s) 231 { 232 if(s && *s && strcmp(s, "note") != 0 && mknewwindow) 233 sleep(10*1000); 234 postnote(PNPROC, notewatcher, "die"); 235 exits(s); 236 } 237