Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <thread.h>
5 #include <bio.h>
6 #include <cursor.h>
7 #include "page.h"
9 int resizing;
10 int mknewwindow;
11 int doabort;
12 int chatty;
13 int reverse = -1;
14 int goodps = 1;
15 int ppi = 100;
16 int teegs = 0;
17 int truetoboundingbox;
18 int textbits=4, gfxbits=4;
19 int stdinfd;
20 int truecolor;
21 int imagemode;
22 int notewatcher;
23 int notegp;
24 int fitwin;
25 char tempfile[40];
27 int
28 watcher(void *v, char *x)
29 {
30 USED(v);
31 if(strcmp(x, "die") != 0)
32 postnote(PNGROUP, notegp, x);
33 threadexitsall(0);
34 return 0;
35 }
37 void
38 watcherproc(void *v)
39 {
40 threadnotify(watcher, 1);
41 for(;;)
42 sleep(1000);
43 }
45 int
46 bell(void *u, char *x)
47 {
48 if(x && strcmp(x, "hangup") == 0)
49 threadexitsall(0);
51 if(x && strstr(x, "die") == nil)
52 fprint(2, "postnote %d: %s\n", getpid(), x);
54 /* alarms come from the gs monitor */
55 if(x && strstr(x, "alarm")){
56 postnote(PNGROUP, getpid(), "die (gs error)");
57 postnote(PNPROC, notewatcher, "die (gs error)");
58 }
60 /* function mentions u so that it's in the stack trace */
61 if((u == nil || u != x) && doabort)
62 abort();
64 /* fprint(2, "exiting %d\n", getpid()); */
65 wexits("note");
66 return 0;
67 }
69 static int
70 afmt(Fmt *fmt)
71 {
72 char *s;
74 s = va_arg(fmt->args, char*);
75 if(s == nil || s[0] == '\0')
76 return fmtstrcpy(fmt, "");
77 else
78 return fmtprint(fmt, "%#q", s);
79 }
81 void
82 usage(void)
83 {
84 fprint(2, "usage: page [-biRrwf] [-p ppi] file...\n");
85 wexits("usage");
86 }
88 void
89 cleanup(void)
90 {
91 remove(tempfile);
92 }
94 void
95 threadmain(int argc, char **argv)
96 {
97 Document *doc;
98 Biobuf *b;
99 char *basename = argv[0];
100 enum { Ninput = 16 };
101 uchar buf[Ninput+1];
102 int readstdin;
104 ARGBEGIN{
105 /* "temporary" debugging options */
106 case 'P':
107 goodps = 0;
108 break;
109 case 'v':
110 chatty++;
111 break;
112 case 'V':
113 teegs++;
114 break;
115 case 'a':
116 doabort++;
117 break;
118 case 'T':
119 textbits = atoi(EARGF(usage()));
120 gfxbits = atoi(EARGF(usage()));
121 break;
123 /* real options */
124 case 'R':
125 resizing = 1;
126 break;
127 case 'r':
128 reverse = 1;
129 break;
130 case 'p':
131 ppi = atoi(EARGF(usage()));
132 break;
133 case 'b':
134 truetoboundingbox = 1;
135 break;
136 case 'w':
137 fprint(2, "%s: -w has only the effect of -R X11 systems\n", basename);
138 resizing = 1;
139 break;
140 case 'i':
141 imagemode = 1;
142 break;
143 case 'W':
144 winsize = EARGF(usage());
145 break;
146 case 'f':
147 fitwin = 1;
148 break;
149 default:
150 usage();
151 }ARGEND;
153 notegp = getpid();
155 notewatcher = proccreate(watcherproc, NULL, 1024);
156 if(notewatcher == -1){
157 sysfatal("proccreate");
158 threadexitsall(0);
161 rfork(RFNOTEG);
162 threadnotify(bell, 1);
164 readstdin = 0;
165 if(imagemode == 0 && argc == 0){
166 readstdin = 1;
167 stdinfd = dup(0, -1);
168 close(0);
169 open("/dev/tty", OREAD);
172 quotefmtinstall();
173 fmtinstall('a', afmt);
175 fmtinstall('R', Rfmt);
176 fmtinstall('P', Pfmt);
177 /*
178 if(mknewwindow)
179 newwin(); */
181 if(readstdin){
182 b = nil;
183 if(readn(stdinfd, buf, Ninput) != Ninput){
184 fprint(2, "page: short read reading %s\n", argv[0]);
185 wexits("read");
188 atexit(cleanup);
189 }else if(argc != 0){
190 if(!(b = Bopen(argv[0], OREAD))) {
191 fprint(2, "page: cannot open \"%s\"\n", argv[0]);
192 wexits("open");
195 if(Bread(b, buf, Ninput) != Ninput) {
196 fprint(2, "page: short read reading %s\n", argv[0]);
197 wexits("read");
199 }else
200 b = nil;
202 buf[Ninput] = '\0';
203 if(imagemode)
204 doc = initgfx(nil, 0, nil, nil, 0);
205 else if(strncmp((char*)buf, "%PDF-", 5) == 0)
206 doc = initpdf(b, argc, argv, buf, Ninput);
207 else if(strncmp((char*)buf, "\x04%!", 2) == 0)
208 doc = initps(b, argc, argv, buf, Ninput);
209 else if(buf[0] == '\x1B' && strstr((char*)buf, "@PJL"))
210 doc = initps(b, argc, argv, buf, Ninput);
211 else if(strncmp((char*)buf, "%!", 2) == 0)
212 doc = initps(b, argc, argv, buf, Ninput);
213 else if(strcmp((char*)buf, "\xF7\x02\x01\x83\x92\xC0\x1C;") == 0)
214 doc = initdvi(b, argc, argv, buf, Ninput);
215 else if(strncmp((char*)buf, "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1", 8) == 0)
216 doc = initmsdoc(b, argc, argv, buf, Ninput);
217 else if(strncmp((char*)buf, "x T ", 4) == 0)
218 doc = inittroff(b, argc, argv, buf, Ninput);
219 else {
220 if(ppi != 100) {
221 fprint(2, "page: you can't specify -p with graphic files\n");
222 wexits("-p and graphics");
224 doc = initgfx(b, argc, argv, buf, Ninput);
227 if(doc == nil) {
228 fprint(2, "page: error reading file: %r\n");
229 wexits("document init");
232 if(doc->npage < 1 && !imagemode) {
233 fprint(2, "page: no pages found?\n");
234 wexits("pagecount");
237 if(reverse == -1) /* neither cmdline nor ps reader set it */
238 reverse = 0;
240 if(initdraw(0, 0, "page") < 0){
241 fprint(2, "page: initdraw failed: %r\n");
242 wexits("initdraw");
244 display->locking = 1;
246 truecolor = screen->depth > 8;
247 viewer(doc);
248 wexits(0);
251 void
252 wexits(char *s)
254 if(s && *s && strcmp(s, "note") != 0 && mknewwindow)
255 sleep(10*1000);
256 postnote(PNPROC, notewatcher, "die");
257 postnote(PNGROUP, getpid(), "die");
258 threadexitsall(s);