--- ray/src/px/x11image.c 1993/05/05 10:27:58 2.26 +++ ray/src/px/x11image.c 1993/10/28 11:39:59 2.32 @@ -21,6 +21,7 @@ static char SCCSid[] = "$SunId$ LBL"; #include "standard.h" +#include #include #include #include @@ -32,6 +33,13 @@ static char SCCSid[] = "$SunId$ LBL"; #include "random.h" #include "resolu.h" +#ifdef __alpha +#define int4 int +#endif +#ifndef int4 +#define int4 long +#endif + #define FONTNAME "8x13" /* text font we'll use */ #define CTRL(c) ((c)-'@') @@ -64,6 +72,8 @@ int scale = 0; /* scalefactor; power of two */ int xoff = 0; /* x image offset */ int yoff = 0; /* y image offset */ +int parent = 0; /* number of children, -1 if child */ + VIEW ourview = STDVIEW; /* image view parameters */ int gotview = 0; /* got parameters from file */ @@ -109,7 +119,11 @@ extern long ftell(); Display *thedisplay; Atom closedownAtom, wmProtocolsAtom; +int sigrecv; +int onsig() { sigrecv++; } + + main(argc, argv) int argc; char *argv[]; @@ -118,6 +132,7 @@ char *argv[]; char *gv; int headline(); int i; + int pid; progname = argv[0]; if ((gv = getenv("GAMMA")) != NULL) @@ -163,15 +178,30 @@ char *argv[]; else break; - if (i == argc-1) { + if (i > argc) + goto userr; + while (i < argc-1) { + sigrecv = 0; + signal(SIGCONT, onsig); + if ((pid=fork()) == 0) { /* a child for each picture */ + parent = -1; + break; + } + if (pid < 0) + quiterr("fork failed"); + parent++; + while (!sigrecv) + pause(); /* wait for wake-up call */ + i++; + } + if (i < argc) { /* open picture file */ fname = argv[i]; fin = fopen(fname, "r"); if (fin == NULL) { sprintf(errmsg, "cannot open file \"%s\"", fname); quiterr(errmsg); } - } else if (i != argc) - goto userr; + } /* get header */ getheader(fin, headline, NULL); /* get picture dimensions */ @@ -187,11 +217,15 @@ char *argv[]; init(argc, argv); /* get file and open window */ + if (parent < 0) { + kill(getppid(), SIGCONT); /* signal parent if child */ + sigrecv--; + } for ( ; ; ) getevent(); /* main loop */ userr: fprintf(stderr, -"Usage: %s [-di disp][[-ge] spec][-b][-m][-d][-f][-c nclrs][-e +/-stops] pic\n", +"Usage: %s [-di disp][[-ge] spec][-b][-m][-d][-f][-c nclrs][-e +/-stops] pic ..\n", progname); exit(1); } @@ -282,10 +316,11 @@ char **argv; quiterr("cannot create window"); width = xmax; height = ymax; - xgcv.foreground = ourblack; - xgcv.background = ourwhite; + /* prepare graphics drawing context */ if ((xgcv.font = XLoadFont(thedisplay, FONTNAME)) == 0) quiterr("cannot get font"); + xgcv.foreground = ourblack; + xgcv.background = ourwhite; ourgc = XCreateGC(thedisplay, wind, GCForeground|GCBackground| GCFont, &xgcv); xgcv.function = GXinvert; @@ -321,11 +356,23 @@ char **argv; quiterr(err) /* print message and exit */ char *err; { - if (err != NULL) { - fprintf(stderr, "%s: %s\n", progname, err); - exit(1); + register int es; + int cs; + + if (es = err != NULL) + fprintf(stderr, "%s: %s: %s\n", progname, + fname==NULL?"":fname, err); + if (parent > 0 & wind != 0) { + XDestroyWindow(thedisplay, wind); + XFlush(thedisplay); + } else if (parent < 0 & sigrecv == 0) + kill(getppid(), SIGCONT); + while (parent > 0 && wait(&cs) != -1) { /* wait for any children */ + if (es == 0) + es = cs>>8 & 0xff; + parent--; } - exit(0); + exit(es); } @@ -466,10 +513,10 @@ getras() /* get raster file */ goto fail; getmono(); } else if (ourvis.class == TrueColor | ourvis.class == DirectColor) { - ourdata = (unsigned char *)malloc(4*xmax*ymax); + ourdata = (unsigned char *)malloc(sizeof(int4)*xmax*ymax); if (ourdata == NULL) goto fail; - ourras = make_raster(thedisplay, &ourvis, 32, + ourras = make_raster(thedisplay, &ourvis, sizeof(int4)*8, ourdata, xmax, ymax, 32); if (ourras == NULL) goto fail; @@ -529,7 +576,7 @@ getevent() /* process the next event */ else getbox(&xev.xbutton); break; - case ClientMessage: + case ClientMessage: if ((xev.xclient.message_type == wmProtocolsAtom) && (xev.xclient.data.l[0] == closedownAtom)) quiterr(NULL); @@ -653,6 +700,14 @@ XKeyPressedEvent *ekey; make_rpixmap(ourras, wind); redraw(0, 0, width, height); return(0); + case 'f': /* turn on fast redraw */ + fast = 1; + make_rpixmap(ourras, wind); + return(0); + case 'F': /* turn off fast redraw */ + fast = 0; + free_rpixmap(ourras); + return(0); case '0': /* recenter origin */ if (xoff == 0 & yoff == 0) return(0); @@ -868,12 +923,12 @@ COLR *scan; getfull() /* get full (24-bit) data */ { int y; - register unsigned long *dp; + register unsigned int4 *dp; register int x; /* set gamma correction */ setcolrgam(gamcor); /* read and convert file */ - dp = (unsigned long *)ourdata; + dp = (unsigned int4 *)ourdata; for (y = 0; y < ymax; y++) { getscan(y); add2icon(y, scanline); @@ -928,13 +983,16 @@ getgrey() /* get greyscale data */ getmapped() /* get color-mapped data */ { int y; + /* make sure we can do it first */ + if (fname == NULL) + quiterr("cannot map colors from standard input"); /* set gamma correction */ setcolrgam(gamcor); /* make histogram */ new_histo(); for (y = 0; y < ymax; y++) { if (getscan(y) < 0) - quiterr("seek error in getmapped"); + break; add2icon(y, scanline); if (scale) shiftcolrs(scanline, xmax, scale); @@ -945,8 +1003,7 @@ getmapped() /* get color-mapped data */ if (!new_clrtab(maxcolors)) quiterr("cannot create color map"); for (y = 0; y < ymax; y++) { - if (getscan(y) < 0) - quiterr("seek error in getmapped"); + getscan(y); if (scale) shiftcolrs(scanline, xmax, scale); colrs_gambs(scanline, xmax); @@ -989,6 +1046,12 @@ double sf; getscan(y) int y; { + static int trunced = -1; /* truncated file? */ +skipit: + if (trunced >= 0 && y >= trunced) { + bzero(scanline, xmax*sizeof(COLR)); + return(-1); + } if (y != cury) { if (scanpos == NULL || scanpos[y] == -1) return(-1); @@ -998,9 +1061,12 @@ int y; } else if (scanpos != NULL && scanpos[y] == -1) scanpos[y] = ftell(fin); - if (freadcolrs(scanline, xmax, fin) < 0) - quiterr("read error"); - + if (freadcolrs(scanline, xmax, fin) < 0) { + fprintf(stderr, "%s: %s: unfinished picture\n", + progname, fname==NULL?"":fname); + trunced = y; + goto skipit; + } cury++; return(0); }