xref: /plan9/sys/src/cmd/page/page.c (revision 14cc0f535177405a84c5b73603a98e5db6674719)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier #include <event.h>
57dd7cddfSDavid du Colombier #include <bio.h>
67dd7cddfSDavid du Colombier #include "page.h"
77dd7cddfSDavid du Colombier 
87dd7cddfSDavid du Colombier int resizing;
9d9306527SDavid du Colombier int mknewwindow;
107dd7cddfSDavid du Colombier int doabort;
117dd7cddfSDavid du Colombier int chatty;
127dd7cddfSDavid du Colombier int reverse = -1;
137dd7cddfSDavid du Colombier int goodps = 1;
147dd7cddfSDavid du Colombier int ppi = 100;
157dd7cddfSDavid du Colombier int teegs = 0;
167dd7cddfSDavid du Colombier int truetoboundingbox;
177dd7cddfSDavid du Colombier int textbits=4, gfxbits=4;
187dd7cddfSDavid du Colombier int wctlfd = -1;
197dd7cddfSDavid du Colombier int stdinfd;
207dd7cddfSDavid du Colombier int truecolor;
217dd7cddfSDavid du Colombier int imagemode;
227dd7cddfSDavid du Colombier int notewatcher;
237dd7cddfSDavid du Colombier int notegp;
247dd7cddfSDavid du Colombier 
257dd7cddfSDavid du Colombier int
watcher(void *,char * x)267dd7cddfSDavid du Colombier watcher(void*, char *x)
277dd7cddfSDavid du Colombier {
287dd7cddfSDavid du Colombier 	if(strcmp(x, "die") != 0)
297dd7cddfSDavid du Colombier 		postnote(PNGROUP, notegp, x);
307dd7cddfSDavid du Colombier 	_exits(0);
317dd7cddfSDavid du Colombier 	return 0;
327dd7cddfSDavid du Colombier }
337dd7cddfSDavid du Colombier 
347dd7cddfSDavid du Colombier int
bell(void * u,char * x)357dd7cddfSDavid du Colombier bell(void *u, char *x)
367dd7cddfSDavid du Colombier {
377dd7cddfSDavid du Colombier 	if(x && strcmp(x, "hangup") == 0)
387dd7cddfSDavid du Colombier 		_exits(0);
397dd7cddfSDavid du Colombier 
407dd7cddfSDavid du Colombier 	if(x && strstr(x, "die") == nil)
417dd7cddfSDavid du Colombier 		fprint(2, "postnote %d: %s\n", getpid(), x);
427dd7cddfSDavid du Colombier 
437dd7cddfSDavid du Colombier 	/* alarms come from the gs monitor */
447dd7cddfSDavid du Colombier 	if(x && strstr(x, "alarm")){
457dd7cddfSDavid du Colombier 		postnote(PNGROUP, getpid(), "die (gs error)");
467dd7cddfSDavid du Colombier 		postnote(PNPROC, notewatcher, "die (gs error)");
477dd7cddfSDavid du Colombier 	}
487dd7cddfSDavid du Colombier 
497dd7cddfSDavid du Colombier 	/* function mentions u so that it's in the stack trace */
507dd7cddfSDavid du Colombier 	if((u == nil || u != x) && doabort)
517dd7cddfSDavid du Colombier 		abort();
527dd7cddfSDavid du Colombier 
537dd7cddfSDavid du Colombier /*	fprint(2, "exiting %d\n", getpid()); */
547dd7cddfSDavid du Colombier 	wexits("note");
557dd7cddfSDavid du Colombier 	return 0;
567dd7cddfSDavid du Colombier }
577dd7cddfSDavid du Colombier 
583ff48bf5SDavid du Colombier static int
afmt(Fmt * fmt)593ff48bf5SDavid du Colombier afmt(Fmt *fmt)
603ff48bf5SDavid du Colombier {
613ff48bf5SDavid du Colombier 	char *s;
623ff48bf5SDavid du Colombier 
633ff48bf5SDavid du Colombier 	s = va_arg(fmt->args, char*);
643ff48bf5SDavid du Colombier 	if(s == nil || s[0] == '\0')
653ff48bf5SDavid du Colombier 		return fmtstrcpy(fmt, "");
663ff48bf5SDavid du Colombier 	else
673ff48bf5SDavid du Colombier 		return fmtprint(fmt, "%#q", s);
683ff48bf5SDavid du Colombier }
693ff48bf5SDavid du Colombier 
703ff48bf5SDavid du Colombier void
usage(void)713ff48bf5SDavid du Colombier usage(void)
723ff48bf5SDavid du Colombier {
733ff48bf5SDavid du Colombier 	fprint(2, "usage: page [-biRrw] [-p ppi] file...\n");
743ff48bf5SDavid du Colombier 	exits("usage");
753ff48bf5SDavid du Colombier }
763ff48bf5SDavid du Colombier 
777dd7cddfSDavid du Colombier void
main(int argc,char ** argv)787dd7cddfSDavid du Colombier main(int argc, char **argv)
797dd7cddfSDavid du Colombier {
807dd7cddfSDavid du Colombier 	Document *doc;
817dd7cddfSDavid du Colombier 	Biobuf *b;
8280ee5cbfSDavid du Colombier 	enum { Ninput = 16 };
8380ee5cbfSDavid du Colombier 	uchar buf[Ninput+1];
847dd7cddfSDavid du Colombier 	int readstdin;
857dd7cddfSDavid du Colombier 
867dd7cddfSDavid du Colombier 	ARGBEGIN{
877dd7cddfSDavid du Colombier 	/* "temporary" debugging options */
887dd7cddfSDavid du Colombier 	case 'P':
897dd7cddfSDavid du Colombier 		goodps = 0;
907dd7cddfSDavid du Colombier 		break;
917dd7cddfSDavid du Colombier 	case 'v':
927dd7cddfSDavid du Colombier 		chatty++;
937dd7cddfSDavid du Colombier 		break;
947dd7cddfSDavid du Colombier 	case 'V':
957dd7cddfSDavid du Colombier 		teegs++;
967dd7cddfSDavid du Colombier 		break;
977dd7cddfSDavid du Colombier 	case 'a':
987dd7cddfSDavid du Colombier 		doabort++;
997dd7cddfSDavid du Colombier 		break;
1003ff48bf5SDavid du Colombier 	case 'T':
1013ff48bf5SDavid du Colombier 		textbits = atoi(EARGF(usage()));
1023ff48bf5SDavid du Colombier 		gfxbits = atoi(EARGF(usage()));
1033ff48bf5SDavid du Colombier 		break;
1047dd7cddfSDavid du Colombier 
1057dd7cddfSDavid du Colombier 	/* real options */
1067dd7cddfSDavid du Colombier 	case 'R':
1077dd7cddfSDavid du Colombier 		resizing = 1;
1087dd7cddfSDavid du Colombier 		break;
1097dd7cddfSDavid du Colombier 	case 'r':
1107dd7cddfSDavid du Colombier 		reverse = 1;
1117dd7cddfSDavid du Colombier 		break;
1127dd7cddfSDavid du Colombier 	case 'p':
1133ff48bf5SDavid du Colombier 		ppi = atoi(EARGF(usage()));
1147dd7cddfSDavid du Colombier 		break;
1157dd7cddfSDavid du Colombier 	case 'b':
1167dd7cddfSDavid du Colombier 		truetoboundingbox = 1;
1177dd7cddfSDavid du Colombier 		break;
1187dd7cddfSDavid du Colombier 	case 'w':
119d9306527SDavid du Colombier 		mknewwindow = 1;
1207dd7cddfSDavid du Colombier 		resizing = 1;
1217dd7cddfSDavid du Colombier 		break;
1227dd7cddfSDavid du Colombier 	case 'i':
1237dd7cddfSDavid du Colombier 		imagemode = 1;
1247dd7cddfSDavid du Colombier 		break;
1257dd7cddfSDavid du Colombier 	default:
1263ff48bf5SDavid du Colombier 		usage();
1277dd7cddfSDavid du Colombier 	}ARGEND;
1287dd7cddfSDavid du Colombier 
1297dd7cddfSDavid du Colombier 	notegp = getpid();
1307dd7cddfSDavid du Colombier 
1317dd7cddfSDavid du Colombier 	switch(notewatcher = fork()){
1327dd7cddfSDavid du Colombier 	case -1:
133*14cc0f53SDavid du Colombier 		sysfatal("fork");
1347dd7cddfSDavid du Colombier 		exits(0);
1357dd7cddfSDavid du Colombier 	default:
1367dd7cddfSDavid du Colombier 		break;
1377dd7cddfSDavid du Colombier 	case 0:
1387dd7cddfSDavid du Colombier 		atnotify(watcher, 1);
1397dd7cddfSDavid du Colombier 		for(;;)
1407dd7cddfSDavid du Colombier 			sleep(1000);
141b85a8364SDavid du Colombier 		/* not reached */
1427dd7cddfSDavid du Colombier 	}
1437dd7cddfSDavid du Colombier 
1447dd7cddfSDavid du Colombier 	rfork(RFNOTEG);
1457dd7cddfSDavid du Colombier 	atnotify(bell, 1);
1467dd7cddfSDavid du Colombier 
1477dd7cddfSDavid du Colombier 	readstdin = 0;
1487dd7cddfSDavid du Colombier 	if(imagemode == 0 && argc == 0){
1497dd7cddfSDavid du Colombier 		readstdin = 1;
1507dd7cddfSDavid du Colombier 		stdinfd = dup(0, -1);
1517dd7cddfSDavid du Colombier 		close(0);
1527dd7cddfSDavid du Colombier 		open("/dev/cons", OREAD);
1537dd7cddfSDavid du Colombier 	}
1547dd7cddfSDavid du Colombier 
1553ff48bf5SDavid du Colombier 	quotefmtinstall();
1563ff48bf5SDavid du Colombier 	fmtinstall('a', afmt);
1573ff48bf5SDavid du Colombier 
1589a747e4fSDavid du Colombier 	fmtinstall('R', Rfmt);
1599a747e4fSDavid du Colombier 	fmtinstall('P', Pfmt);
160d9306527SDavid du Colombier 	if(mknewwindow)
1617dd7cddfSDavid du Colombier 		newwin();
1627dd7cddfSDavid du Colombier 
1637dd7cddfSDavid du Colombier 	if(readstdin){
1647dd7cddfSDavid du Colombier 		b = nil;
16580ee5cbfSDavid du Colombier 		if(readn(stdinfd, buf, Ninput) != Ninput){
1667dd7cddfSDavid du Colombier 			fprint(2, "page: short read reading %s\n", argv[0]);
1677dd7cddfSDavid du Colombier 			wexits("read");
1687dd7cddfSDavid du Colombier 		}
1697dd7cddfSDavid du Colombier 	}else if(argc != 0){
1707dd7cddfSDavid du Colombier 		if(!(b = Bopen(argv[0], OREAD))) {
1717dd7cddfSDavid du Colombier 			fprint(2, "page: cannot open \"%s\"\n", argv[0]);
1727dd7cddfSDavid du Colombier 			wexits("open");
1737dd7cddfSDavid du Colombier 		}
1747dd7cddfSDavid du Colombier 
17580ee5cbfSDavid du Colombier 		if(Bread(b, buf, Ninput) != Ninput) {
1767dd7cddfSDavid du Colombier 			fprint(2, "page: short read reading %s\n", argv[0]);
1777dd7cddfSDavid du Colombier 			wexits("read");
1787dd7cddfSDavid du Colombier 		}
1797dd7cddfSDavid du Colombier 	}else
1807dd7cddfSDavid du Colombier 		b = nil;
1817dd7cddfSDavid du Colombier 
18280ee5cbfSDavid du Colombier 	buf[Ninput] = '\0';
1837dd7cddfSDavid du Colombier 	if(imagemode)
1847dd7cddfSDavid du Colombier 		doc = initgfx(nil, 0, nil, nil, 0);
1857dd7cddfSDavid du Colombier 	else if(strncmp((char*)buf, "%PDF-", 5) == 0)
18680ee5cbfSDavid du Colombier 		doc = initpdf(b, argc, argv, buf, Ninput);
18780ee5cbfSDavid du Colombier 	else if(strncmp((char*)buf, "\x04%!", 2) == 0)
18880ee5cbfSDavid du Colombier 		doc = initps(b, argc, argv, buf, Ninput);
18980ee5cbfSDavid du Colombier 	else if(buf[0] == '\x1B' && strstr((char*)buf, "@PJL"))
19080ee5cbfSDavid du Colombier 		doc = initps(b, argc, argv, buf, Ninput);
1917dd7cddfSDavid du Colombier 	else if(strncmp((char*)buf, "%!", 2) == 0)
19280ee5cbfSDavid du Colombier 		doc = initps(b, argc, argv, buf, Ninput);
1937dd7cddfSDavid du Colombier 	else if(strcmp((char*)buf, "\xF7\x02\x01\x83\x92\xC0\x1C;") == 0)
19480ee5cbfSDavid du Colombier 		doc = initdvi(b, argc, argv, buf, Ninput);
195f5736e95SDavid du Colombier 	else if(strncmp((char*)buf, "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1", 8) == 0)
196f5736e95SDavid du Colombier 		doc = initmsdoc(b, argc, argv, buf, Ninput);
1977dd7cddfSDavid du Colombier 	else if(strncmp((char*)buf, "x T ", 4) == 0)
19880ee5cbfSDavid du Colombier 		doc = inittroff(b, argc, argv, buf, Ninput);
1997dd7cddfSDavid du Colombier 	else {
2007dd7cddfSDavid du Colombier 		if(ppi != 100) {
2017dd7cddfSDavid du Colombier 			fprint(2, "page: you can't specify -p with graphic files\n");
2027dd7cddfSDavid du Colombier 			wexits("-p and graphics");
2037dd7cddfSDavid du Colombier 		}
20480ee5cbfSDavid du Colombier 		doc = initgfx(b, argc, argv, buf, Ninput);
2057dd7cddfSDavid du Colombier 	}
2067dd7cddfSDavid du Colombier 
2077dd7cddfSDavid du Colombier 	if(doc == nil) {
2087dd7cddfSDavid du Colombier 		fprint(2, "page: error reading file: %r\n");
2097dd7cddfSDavid du Colombier 		wexits("document init");
2107dd7cddfSDavid du Colombier 	}
2117dd7cddfSDavid du Colombier 
2127dd7cddfSDavid du Colombier 	if(doc->npage < 1 && !imagemode) {
2137dd7cddfSDavid du Colombier 		fprint(2, "page: no pages found?\n");
2147dd7cddfSDavid du Colombier 		wexits("pagecount");
2157dd7cddfSDavid du Colombier 	}
2167dd7cddfSDavid du Colombier 
2177dd7cddfSDavid du Colombier 	if(reverse == -1) /* neither cmdline nor ps reader set it */
2187dd7cddfSDavid du Colombier 		reverse = 0;
2197dd7cddfSDavid du Colombier 
2207dd7cddfSDavid du Colombier 	if(initdraw(0, 0, "page") < 0){
2217dd7cddfSDavid du Colombier 		fprint(2, "page: initdraw failed: %r\n");
2227dd7cddfSDavid du Colombier 		wexits("initdraw");
2237dd7cddfSDavid du Colombier 	}
224493edcedSDavid du Colombier 	display->locking = 1;
225493edcedSDavid du Colombier 
2267dd7cddfSDavid du Colombier 	truecolor = screen->depth > 8;
2277dd7cddfSDavid du Colombier 	viewer(doc);
2287dd7cddfSDavid du Colombier 	wexits(0);
2297dd7cddfSDavid du Colombier }
2307dd7cddfSDavid du Colombier 
2317dd7cddfSDavid du Colombier void
wexits(char * s)2327dd7cddfSDavid du Colombier wexits(char *s)
2337dd7cddfSDavid du Colombier {
234d9306527SDavid du Colombier 	if(s && *s && strcmp(s, "note") != 0 && mknewwindow)
2357dd7cddfSDavid du Colombier 		sleep(10*1000);
2367dd7cddfSDavid du Colombier 	postnote(PNPROC, notewatcher, "die");
2377dd7cddfSDavid du Colombier 	exits(s);
2387dd7cddfSDavid du Colombier }
239