Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <event.h>
5 #include <bio.h>
6 #include "page.h"
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;
25 int
26 watcher(void *v, char *x)
27 {
28 USED(v);
30 if(strcmp(x, "die") != 0)
31 postnote(PNGROUP, notegp, x);
32 _exits(0);
33 return 0;
34 }
36 int
37 bell(void *u, char *x)
38 {
39 if(x && strcmp(x, "hangup") == 0)
40 _exits(0);
42 if(x && strstr(x, "die") == nil)
43 fprint(2, "postnote %d: %s\n", getpid(), x);
45 /* alarms come from the gs monitor */
46 if(x && strstr(x, "alarm")){
47 postnote(PNGROUP, getpid(), "die (gs error)");
48 postnote(PNPROC, notewatcher, "die (gs error)");
49 }
51 /* function mentions u so that it's in the stack trace */
52 if((u == nil || u != x) && doabort)
53 abort();
55 /* fprint(2, "exiting %d\n", getpid()); */
56 wexits("note");
57 return 0;
58 }
60 static int
61 afmt(Fmt *fmt)
62 {
63 char *s;
65 s = va_arg(fmt->args, char*);
66 if(s == nil || s[0] == '\0')
67 return fmtstrcpy(fmt, "");
68 else
69 return fmtprint(fmt, "%#q", s);
70 }
72 void
73 usage(void)
74 {
75 fprint(2, "usage: page [-biRrw] [-p ppi] file...\n");
76 exits("usage");
77 }
79 void
80 main(int argc, char **argv)
81 {
82 Document *doc;
83 Biobuf *b;
84 enum { Ninput = 16 };
85 uchar buf[Ninput+1];
86 int readstdin;
88 ARGBEGIN{
89 /* "temporary" debugging options */
90 case 'P':
91 goodps = 0;
92 break;
93 case 'v':
94 chatty++;
95 break;
96 case 'V':
97 teegs++;
98 break;
99 case 'a':
100 doabort++;
101 break;
102 case 'T':
103 textbits = atoi(EARGF(usage()));
104 gfxbits = atoi(EARGF(usage()));
105 break;
107 /* real options */
108 case 'R':
109 resizing = 1;
110 break;
111 case 'r':
112 reverse = 1;
113 break;
114 case 'p':
115 ppi = atoi(EARGF(usage()));
116 break;
117 case 'b':
118 truetoboundingbox = 1;
119 break;
120 case 'w':
121 mknewwindow = 1;
122 resizing = 1;
123 break;
124 case 'i':
125 imagemode = 1;
126 break;
127 default:
128 usage();
129 }ARGEND;
131 notegp = getpid();
133 switch(notewatcher = fork()){
134 case -1:
135 sysfatal("fork\n");
136 exits(0);
137 default:
138 break;
139 case 0:
140 atnotify(watcher, 1);
141 for(;;)
142 sleep(1000);
143 _exits(0);
146 rfork(RFNOTEG);
147 atnotify(bell, 1);
149 readstdin = 0;
150 if(imagemode == 0 && argc == 0){
151 readstdin = 1;
152 stdinfd = dup(0, -1);
153 close(0);
154 open("/dev/cons", OREAD);
157 quotefmtinstall();
158 fmtinstall('a', afmt);
160 fmtinstall('R', Rfmt);
161 fmtinstall('P', Pfmt);
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");
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");
175 if(Bread(b, buf, Ninput) != Ninput) {
176 fprint(2, "page: short read reading %s\n", argv[0]);
177 wexits("read");
179 }else
180 b = nil;
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");
204 doc = initgfx(b, argc, argv, buf, Ninput);
207 if(doc == nil) {
208 fprint(2, "page: error reading file: %r\n");
209 wexits("document init");
212 if(doc->npage < 1 && !imagemode) {
213 fprint(2, "page: no pages found?\n");
214 wexits("pagecount");
217 if(reverse == -1) /* neither cmdline nor ps reader set it */
218 reverse = 0;
220 if(initdraw(0, 0, "page") < 0){
221 fprint(2, "page: initdraw failed: %r\n");
222 wexits("initdraw");
224 truecolor = screen->depth > 8;
225 viewer(doc);
226 wexits(0);
229 void
230 wexits(char *s)
232 if(s && *s && strcmp(s, "note") != 0 && mknewwindow)
233 sleep(10*1000);
234 postnote(PNPROC, notewatcher, "die");
235 exits(s);