URI:
       tpage.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tpage.c (4828B)
       ---
            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         char *basename = argv[0];
          100         enum { Ninput = 16 };
          101         uchar buf[Ninput+1];
          102         int readstdin;
          103 
          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                 ppi = atoi(EARGF(usage()));
          132                 break;
          133         case 'b':
          134                 truetoboundingbox = 1;
          135                 break;
          136         case 'w':
          137                 fprint(2, "%s: -w has only the effect of -R X11 systems\n", basename);
          138                 resizing = 1;
          139                 break;
          140         case 'i':
          141                 imagemode = 1;
          142                 break;
          143         case 'W':
          144                 winsize = EARGF(usage());
          145                 break;
          146         case 'f':
          147                 fitwin = 1;
          148                 break;
          149         default:
          150                 usage();
          151         }ARGEND;
          152 
          153         notegp = getpid();
          154 
          155         notewatcher = proccreate(watcherproc, NULL, 1024);
          156         if(notewatcher == -1){
          157                 sysfatal("proccreate");
          158                 threadexitsall(0);
          159         }
          160 
          161         rfork(RFNOTEG);
          162         threadnotify(bell, 1);
          163 
          164         readstdin = 0;
          165         if(imagemode == 0 && argc == 0){
          166                 readstdin = 1;
          167                 stdinfd = dup(0, -1);
          168                 close(0);
          169                 open("/dev/tty", OREAD);
          170         }
          171 
          172         quotefmtinstall();
          173         fmtinstall('a', afmt);
          174 
          175         fmtinstall('R', Rfmt);
          176         fmtinstall('P', Pfmt);
          177         /*
          178         if(mknewwindow)
          179                 newwin(); */
          180 
          181         if(readstdin){
          182                 b = nil;
          183                 if(readn(stdinfd, buf, Ninput) != Ninput){
          184                         fprint(2, "page: short read reading %s\n", argv[0]);
          185                         wexits("read");
          186                 }
          187 
          188                 atexit(cleanup);
          189         }else if(argc != 0){
          190                 if(!(b = Bopen(argv[0], OREAD))) {
          191                         fprint(2, "page: cannot open \"%s\"\n", argv[0]);
          192                         wexits("open");
          193                 }
          194 
          195                 if(Bread(b, buf, Ninput) != Ninput) {
          196                         fprint(2, "page: short read reading %s\n", argv[0]);
          197                         wexits("read");
          198                 }
          199         }else
          200                 b = nil;
          201 
          202         buf[Ninput] = '\0';
          203         if(imagemode)
          204                 doc = initgfx(nil, 0, nil, nil, 0);
          205         else if(strncmp((char*)buf, "%PDF-", 5) == 0)
          206                 doc = initpdf(b, argc, argv, buf, Ninput);
          207         else if(strncmp((char*)buf, "\x04%!", 2) == 0)
          208                 doc = initps(b, argc, argv, buf, Ninput);
          209         else if(buf[0] == '\x1B' && strstr((char*)buf, "@PJL"))
          210                 doc = initps(b, argc, argv, buf, Ninput);
          211         else if(strncmp((char*)buf, "%!", 2) == 0)
          212                 doc = initps(b, argc, argv, buf, Ninput);
          213         else if(strcmp((char*)buf, "\xF7\x02\x01\x83\x92\xC0\x1C;") == 0)
          214                 doc = initdvi(b, argc, argv, buf, Ninput);
          215         else if(strncmp((char*)buf, "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1", 8) == 0)
          216                 doc = initmsdoc(b, argc, argv, buf, Ninput);
          217         else if(strncmp((char*)buf, "x T ", 4) == 0)
          218                 doc = inittroff(b, argc, argv, buf, Ninput);
          219         else {
          220                 if(ppi != 100) {
          221                         fprint(2, "page: you can't specify -p with graphic files\n");
          222                         wexits("-p and graphics");
          223                 }
          224                 doc = initgfx(b, argc, argv, buf, Ninput);
          225         }
          226 
          227         if(doc == nil) {
          228                 fprint(2, "page: error reading file: %r\n");
          229                 wexits("document init");
          230         }
          231 
          232         if(doc->npage < 1 && !imagemode) {
          233                 fprint(2, "page: no pages found?\n");
          234                 wexits("pagecount");
          235         }
          236 
          237         if(reverse == -1) /* neither cmdline nor ps reader set it */
          238                 reverse = 0;
          239 
          240         if(initdraw(0, 0, "page") < 0){
          241                 fprint(2, "page: initdraw failed: %r\n");
          242                 wexits("initdraw");
          243         }
          244         display->locking = 1;
          245 
          246         truecolor = screen->depth > 8;
          247         viewer(doc);
          248         wexits(0);
          249 }
          250 
          251 void
          252 wexits(char *s)
          253 {
          254         if(s && *s && strcmp(s, "note") != 0 && mknewwindow)
          255                 sleep(10*1000);
          256         postnote(PNPROC, notewatcher, "die");
          257         postnote(PNGROUP, getpid(), "die");
          258         threadexitsall(s);
          259 }