Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}