plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

page.c (4860B)


      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"
      8 
      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];
     26 
     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 }
     36 
     37 void
     38 watcherproc(void *v)
     39 {
     40 	threadnotify(watcher, 1);
     41 	for(;;)
     42 		sleep(1000);
     43 }
     44 
     45 int
     46 bell(void *u, char *x)
     47 {
     48 	if(x && strcmp(x, "hangup") == 0)
     49 		threadexitsall(0);
     50 
     51 	if(x && strstr(x, "die") == nil)
     52 		fprint(2, "postnote %d: %s\n", getpid(), x);
     53 
     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 	}
     59 
     60 	/* function mentions u so that it's in the stack trace */
     61 	if((u == nil || u != x) && doabort)
     62 		abort();
     63 
     64 /*	fprint(2, "exiting %d\n", getpid()); */
     65 	wexits("note");
     66 	return 0;
     67 }
     68 
     69 static int
     70 afmt(Fmt *fmt)
     71 {
     72 	char *s;
     73 
     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 }
     80 
     81 void
     82 usage(void)
     83 {
     84 	fprint(2, "usage: page [-biRrwf] [-p ppi] file...\n");
     85 	wexits("usage");
     86 }
     87 
     88 void
     89 cleanup(void)
     90 {
     91 	remove(tempfile);
     92 }
     93 
     94 void
     95 threadmain(int argc, char **argv)
     96 {
     97 	Document *doc;
     98 	Biobuf *b;
     99 	enum { Ninput = 16 };
    100 	uchar buf[Ninput+1];
    101 	int readstdin, haveppi;
    102 
    103 	haveppi = 0;
    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;
    122 
    123 	/* real options */
    124 	case 'R':
    125 		resizing = 1;
    126 		break;
    127 	case 'r':
    128 		reverse = 1;
    129 		break;
    130 	case 'p':
    131 		haveppi = 1;
    132 		ppi = atoi(EARGF(usage()));
    133 		break;
    134 	case 'b':
    135 		truetoboundingbox = 1;
    136 		break;
    137 	case 'w':
    138 		fprint(2, "warning: page -w only supported on x11 systems\n");
    139 		resizing = 1;
    140 		break;
    141 	case 'i':
    142 		imagemode = 1;
    143 		break;
    144 	case 'W':
    145 		winsize = EARGF(usage());
    146 		break;
    147 	case 'f':
    148 		fitwin = 1;
    149 		break;
    150 	default:
    151 		usage();
    152 	}ARGEND;
    153 
    154 	notegp = getpid();
    155 
    156 	notewatcher = proccreate(watcherproc, NULL, 1024);
    157 	if(notewatcher == -1){
    158 		sysfatal("proccreate");
    159 		threadexitsall(0);
    160 	}
    161 
    162 	rfork(RFNOTEG);
    163 	threadnotify(bell, 1);
    164 
    165 	readstdin = 0;
    166 	if(imagemode == 0 && argc == 0){
    167 		readstdin = 1;
    168 		stdinfd = dup(0, -1);
    169 		close(0);
    170 		open("/dev/tty", OREAD);
    171 	}
    172 
    173 	quotefmtinstall();
    174 	fmtinstall('a', afmt);
    175 
    176 	fmtinstall('R', Rfmt);
    177 	fmtinstall('P', Pfmt);
    178 	/*
    179 	if(mknewwindow)
    180 		newwin(); */
    181 
    182 	if(readstdin){
    183 		b = nil;
    184 		if(readn(stdinfd, buf, Ninput) != Ninput){
    185 			fprint(2, "page: short read reading %s\n", argv[0]);
    186 			wexits("read");
    187 		}
    188 
    189 		atexit(cleanup);
    190 	}else if(argc != 0){
    191 		if(!(b = Bopen(argv[0], OREAD))) {
    192 			fprint(2, "page: cannot open \"%s\"\n", argv[0]);
    193 			wexits("open");
    194 		}
    195 
    196 		if(Bread(b, buf, Ninput) != Ninput) {
    197 			fprint(2, "page: short read reading %s\n", argv[0]);
    198 			wexits("read");
    199 		}
    200 	}else
    201 		b = nil;
    202 
    203 	if(initdraw(0, 0, "page") < 0){
    204 		fprint(2, "page: initdraw failed: %r\n");
    205 		wexits("initdraw");
    206 	}
    207 	display->locking = 1;
    208 	ppi = scalesize(display, ppi);
    209 
    210 	buf[Ninput] = '\0';
    211 	if(imagemode)
    212 		doc = initgfx(nil, 0, nil, nil, 0);
    213 	else if(strncmp((char*)buf, "%PDF-", 5) == 0)
    214 		doc = initpdf(b, argc, argv, buf, Ninput);
    215 	else if(strncmp((char*)buf, "\x04%!", 2) == 0)
    216 		doc = initps(b, argc, argv, buf, Ninput);
    217 	else if(buf[0] == '\x1B' && strstr((char*)buf, "@PJL"))
    218 		doc = initps(b, argc, argv, buf, Ninput);
    219 	else if(strncmp((char*)buf, "%!", 2) == 0)
    220 		doc = initps(b, argc, argv, buf, Ninput);
    221 	else if(strcmp((char*)buf, "\xF7\x02\x01\x83\x92\xC0\x1C;") == 0)
    222 		doc = initdvi(b, argc, argv, buf, Ninput);
    223 	else if(strncmp((char*)buf, "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1", 8) == 0)
    224 		doc = initmsdoc(b, argc, argv, buf, Ninput);
    225 	else if(strncmp((char*)buf, "x T ", 4) == 0)
    226 		doc = inittroff(b, argc, argv, buf, Ninput);
    227 	else {
    228 		if(haveppi) {
    229 			fprint(2, "page: you can't specify -p with graphic files\n");
    230 			wexits("-p and graphics");
    231 		}
    232 		doc = initgfx(b, argc, argv, buf, Ninput);
    233 	}
    234 
    235 	if(doc == nil) {
    236 		fprint(2, "page: error reading file: %r\n");
    237 		wexits("document init");
    238 	}
    239 
    240 	if(doc->npage < 1 && !imagemode) {
    241 		fprint(2, "page: no pages found?\n");
    242 		wexits("pagecount");
    243 	}
    244 
    245 	if(reverse == -1) /* neither cmdline nor ps reader set it */
    246 		reverse = 0;
    247 
    248 	truecolor = screen->depth > 8;
    249 	viewer(doc);
    250 	wexits(0);
    251 }
    252 
    253 void
    254 wexits(char *s)
    255 {
    256 	if(s && *s && strcmp(s, "note") != 0 && mknewwindow)
    257 		sleep(10*1000);
    258 	postnote(PNPROC, notewatcher, "die");
    259 	postnote(PNGROUP, getpid(), "die");
    260 	threadexitsall(s);
    261 }