]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/page/page.c
merge
[plan9front.git] / sys / src / cmd / page / page.c
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");
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         display->locking = 1;
225
226         truecolor = screen->depth > 8;
227         viewer(doc);
228         wexits(0);
229 }
230
231 void
232 wexits(char *s)
233 {
234         if(s && *s && strcmp(s, "note") != 0 && mknewwindow)
235                 sleep(10*1000);
236         postnote(PNPROC, notewatcher, "die");
237         exits(s);
238 }