Annotation of 43BSDTahoe/new/X/xwud/xwud.c, revision 1.1.1.1

1.1       root        1: #include <X/mit-copyright.h>
                      2: 
                      3: /* Copyright 1985, 1986, Massachusetts Institute of Technology */
                      4: 
                      5: /*
                      6:  * xwud.c - MIT Project Athena, X Window system window raster image
                      7:  *         undumper.
                      8:  *
                      9:  * This program will read a raster image of a window from stdin or a file
                     10:  * and display it on an X display.
                     11:  *
                     12:  *  Author:    Tony Della Fera, DEC
                     13:  *
                     14:  *  Modified 11/14/86 by William F. Wyatt,
                     15:  *                        Smithsonian Astrophysical Observatory
                     16:  *    allows writing of monochrome XYFormat window dump files on a color
                     17:  *    display, using default WhitePixel for 1's and BlackPixel for 0's.
                     18:  *
                     19:  *  Modified 11/20/86 WFW
                     20:  *    VERSION 6 - same as V5 for monochrome, but expects color map info
                     21:  *    in the file for color images. Checks to see if the requested
                     22:  *    colors are already in the display's map (e.g. if the window dump
                     23:  *    and undump are contemporaneous to the same display). If so,
                     24:  *    undump immediately. If not, request new colors, alter the 
                     25:  *    pixels to the new values, then write the pixmap. Note that
                     26:  *    multi-plane XY format undumps don't work if the pixel values
                     27:  *    corresponding to the requested colors have to be changed.
                     28:  */
                     29: 
                     30: #ifndef lint
                     31: static char *rcsid_xwud_c = "$Header: xwud.c,v 10.10 86/11/25 08:44:25 jg Rel $";
                     32: #endif
                     33: 
                     34: #include <X/Xlib.h>
                     35: #include <stdio.h>
                     36: #include <strings.h>
                     37: #include <sys/types.h>
                     38: extern char *calloc();
                     39: 
                     40: #include <X/XWDFile.h>
                     41: 
                     42: typedef enum _bool {FALSE, TRUE} Bool;
                     43: 
                     44: #define MAX(a, b) (a) > (b) ? (a) : (b)
                     45: #define MIN(a, b) (a) < (b) ? (a) : (b)
                     46: #define ABS(a) (a) < 0 ? -(a) : (a)
                     47: 
                     48: #define FAILURE 0
                     49: 
                     50: extern int errno;
                     51: 
                     52: main(argc, argv)
                     53:     int argc;
                     54:     char **argv;
                     55: {
                     56:     register int i;
                     57:     register int *histbuffer;
                     58:     register u_short *wbuffer;
                     59:     register char *buffer;
                     60: 
                     61:     int j, status;
                     62:     int *cpixels, cplanes;
                     63:     int onebufsize;
                     64:     int planes;
                     65:     int forepixel;
                     66:     int backpixel;
                     67:     unsigned buffer_size, total_buffer_size;
                     68:     int win_name_size;
                     69:     char *str_index;
                     70:     char *file_name;
                     71:     char display[256];
                     72:     char *win_name;
                     73:     Bool standard_in = TRUE;
                     74:     Bool newcolors = FALSE, debug = FALSE, inverse = FALSE;
                     75: 
                     76:     Color *pixcolors, *newpixcolors;
                     77:     Display *dpy;
                     78:     Window image_win;
                     79:     Pixmap image_pixmap;
                     80:     XEvent event;
                     81:     register XExposeEvent *xevent = (XExposeEvent *)&event;
                     82: 
                     83:     XWDFileHeader header;
                     84: 
                     85:     FILE *in_file = stdin;
                     86: 
                     87:     for (i = 1; i < argc; i++) {
                     88:        str_index = (char *)index (argv[i], ':');
                     89:        if(str_index != NULL) {
                     90:            (void) strncpy(display,argv[i],sizeof(display));
                     91:            continue;
                     92:         }
                     93:        str_index = (char *) index (argv [i], '-');
                     94:        if (str_index == NULL) Syntax(argv[0]);
                     95:        if (strncmp(argv[i], "-help", 5) == 0) {
                     96:            Syntax(argv[0]);
                     97:        }
                     98:        if (strncmp(argv[i], "-in", 4) == 0) {
                     99:            if (++i >= argc) Syntax(argv[0]);
                    100:            file_name = argv[i];
                    101:            standard_in = FALSE;
                    102:            continue;
                    103:        }
                    104:        if(strcmp(argv[i], "-inverse") == 0) {
                    105:            inverse = TRUE;
                    106:            continue;
                    107:        }
                    108:        if(strcmp(argv[i], "-debug") == 0) {
                    109:            debug = TRUE;
                    110:            continue;
                    111:        }
                    112:        Syntax(argv[0]);
                    113:     }
                    114:     
                    115:     if (!standard_in) {
                    116:        /*
                    117:         * Open the output file.
                    118:         */
                    119:        in_file = fopen(file_name, "r");
                    120:        if (in_file == NULL) {
                    121:            Error("Can't open output file as specified.");
                    122:        }
                    123:     }
                    124:     
                    125:     /*
                    126:      * Open the display.
                    127:      */
                    128:     if ((dpy = XOpenDisplay(display)) == NULL) {
                    129:         fprintf(stderr, "%s: Can't open display '%s'\n",
                    130:                argv[0], XDisplayName(display));
                    131:        exit(1);
                    132:     }
                    133: 
                    134:     /*
                    135:      * Read in header information.
                    136:      */
                    137:     if(fread((char *)&header, sizeof(header), 1, in_file) != 1)
                    138:       Error("Unable to read dump file header.");
                    139: 
                    140:     /*
                    141:      * check to see if the dump file is in the proper format.
                    142:      */
                    143:     if (header.file_version != XWD_FILE_VERSION) {
                    144:        fprintf(stderr,"xwud: XWD file format version missmatch.");
                    145:        if(header.file_version == 5 && header.display_planes == 1)
                    146:          fprintf(stderr,"\n      (monochrome works anyway)\n");
                    147:        else Error("exiting.");
                    148:     }
                    149: 
                    150:     if(DisplayPlanes() < header.display_planes)
                    151:       Error("Windump has more planes than display.");
                    152: 
                    153:     /*
                    154:      * Check to see if we are in the right pixmap format for the
                    155:      * display type.
                    156:      */
                    157:     if ((DisplayPlanes() == 1) && (header.pixmap_format != XYFormat)) {
                    158:        Error(
                    159:         "Windump is in ZFormat which is not valid on a monochrome display.");
                    160:     }
                    161: 
                    162:     /*
                    163:      * Calloc window name.
                    164:      */
                    165:     win_name_size = ABS(header.header_size - sizeof(header));
                    166:     if((win_name = calloc((unsigned) win_name_size, sizeof(char))) == NULL)
                    167:       Error("Can't calloc window name storage.");
                    168: 
                    169:     /*
                    170:      * Read in window name.
                    171:      */
                    172:     if(fread(win_name, sizeof(char), win_name_size, in_file) != win_name_size)
                    173:       Error("Unable to read window name from dump file.");
                    174:     if(debug) fprintf(stderr,"win_name =%s\n", win_name);
                    175: 
                    176:     /*
                    177:      * Determine the pixmap size.
                    178:      */
                    179:     if (header.pixmap_format == XYFormat) {
                    180:        buffer_size =
                    181:          XYPixmapSize(
                    182:            header.pixmap_width,
                    183:            header.pixmap_height,
                    184:            header.display_planes);
                    185:        total_buffer_size = 
                    186:          XYPixmapSize(
                    187:            header.pixmap_width,
                    188:            header.pixmap_height,
                    189:            DisplayPlanes() );
                    190:     }
                    191:     else if (header.display_planes < 9) {
                    192:        total_buffer_size = buffer_size = BZPixmapSize(
                    193:            header.pixmap_width,
                    194:            header.pixmap_height
                    195:        );
                    196:     }
                    197:     else if(header.display_planes < 17) {
                    198:        total_buffer_size = buffer_size = WZPixmapSize(
                    199:            header.pixmap_width,
                    200:            header.pixmap_height
                    201:        );
                    202:     }
                    203:     else {
                    204:        Error("Can't undump pixmaps more than 16 bits deep.\n");
                    205:     } 
                    206: 
                    207: 
                    208:     /* Calloc the color map buffer.
                    209:      * Read it in, copy it and use the copy to query for the
                    210:      * existing colors at those pixel values.
                    211:      */
                    212:     if(header.window_ncolors) {
                    213:        pixcolors = (Color *)calloc(header.window_ncolors,sizeof(Color));
                    214:        if(fread(pixcolors,sizeof(Color),header.window_ncolors, in_file)
                    215:           != header.window_ncolors)
                    216:          Error("Unable to read color map from dump file.");
                    217:        if(debug)
                    218:          fprintf(stderr,"Read %d colors\n", header.window_ncolors);
                    219:        newpixcolors = (Color *)calloc(header.window_ncolors,sizeof(Color));
                    220:        bcopy(pixcolors, newpixcolors, sizeof(Color)*header.window_ncolors);
                    221:        if(XQueryColors(newpixcolors,header.window_ncolors) == 0)
                    222:          Error("Can't query the color map?");
                    223:        for(i=0; i<header.window_ncolors; i++)
                    224:          if(!ColorEqual(&pixcolors[i], &newpixcolors[i])) {
                    225:              newcolors = TRUE;
                    226:              break;
                    227:          }
                    228:        if(debug) {
                    229:            if(newcolors)  fprintf(stderr,"New colors needed\n");
                    230:            else fprintf(stderr,"Old colors match!\n");
                    231:        }
                    232:     }
                    233: 
                    234:     /*
                    235:      * Calloc the pixel buffer.
                    236:      */
                    237:     if((buffer = calloc(total_buffer_size, 1)) == NULL)
                    238:       Error("Can't calloc data buffer.");
                    239:     bzero(buffer,total_buffer_size);
                    240: 
                    241:     /*
                    242:      * Read in the pixmap buffer.
                    243:      */
                    244:     if((status = fread(buffer, sizeof(char), (int)buffer_size, in_file))
                    245:        != buffer_size)
                    246:       Error("Unable to read pixmap from dump file.");
                    247:     /*
                    248:      * Close the input file.
                    249:      */
                    250:     (void) fclose(in_file);
                    251: 
                    252:     /*
                    253:      * If necessary, get and store the new colors, convert the pixels to the
                    254:      * new colors appropriately.
                    255:      */
                    256:     if(newcolors) {
                    257:        cpixels = (int *)calloc(header.window_ncolors+1,sizeof(int));
                    258:        if(XGetColorCells(0, header.window_ncolors, 0, &cplanes, cpixels)
                    259:           == 0)
                    260:          Error("Can't allocate colors.");
                    261:        for(i=0; i<header.window_ncolors; i++) {
                    262:            newpixcolors[i].pixel = cpixels[i];
                    263:            newpixcolors[i].red   = pixcolors[i].red;
                    264:            newpixcolors[i].green = pixcolors[i].green;
                    265:            newpixcolors[i].blue  = pixcolors[i].blue;
                    266:            if(debug) 
                    267:              fprintf(stderr,"Pixel %4d, r = %5d  g = %5d  b = %5d\n",
                    268:                      newpixcolors[i].pixel, newpixcolors[i].red,
                    269:                      newpixcolors[i].green, newpixcolors[i].blue);
                    270:        }
                    271:        XStoreColors(header.window_ncolors, newpixcolors);
                    272: 
                    273:        /* now, make a lookup table to convert old pixels into the new ones*/
                    274:        if(header.pixmap_format == ZFormat) {
                    275:            if(header.display_planes < 9) {
                    276:                histbuffer = (int *)calloc(256, sizeof(int));
                    277:                bzero(histbuffer, 256*sizeof(int));
                    278:                for(i=0; i<header.window_ncolors; i++)
                    279:                  histbuffer[pixcolors[i].pixel] = newpixcolors[i].pixel;
                    280:                for(i=0; i<buffer_size; i++)
                    281:                  buffer[i] = histbuffer[buffer[i]];
                    282:            }
                    283:            else if(header.display_planes < 17) {
                    284:                histbuffer = (int *)calloc(65536, sizeof(int));
                    285:                bzero(histbuffer, 65536*sizeof(int));
                    286:                for(i=0; i<header.window_ncolors; i++)
                    287:                  histbuffer[pixcolors[i].pixel] = newpixcolors[i].pixel;
                    288:                wbuffer = (u_short *)buffer;
                    289:                for(i=0; i<(buffer_size/sizeof(u_short)); i++)
                    290:                  wbuffer[i] = histbuffer[wbuffer[i]];
                    291:            } 
                    292:            else if(header.display_planes > 16) {
                    293:                Error("Unable to handle more than 16 planes at this time");
                    294:            }
                    295:            free(histbuffer);
                    296:        }
                    297:        free(cpixels);
                    298:        bcopy(newpixcolors, pixcolors, sizeof(Color)*header.window_ncolors);
                    299:        free(newpixcolors);
                    300:     }
                    301: 
                    302: 
                    303:     /*
                    304:      * Create the image window.
                    305:      */
                    306:     image_win = XCreateWindow(
                    307:        RootWindow,
                    308:        header.window_x, header.window_y,
                    309:        header.pixmap_width, header.pixmap_height,
                    310:        0, (Pixmap) 0,
                    311:        (Pixmap) 0
                    312:     );
                    313:     if (image_win == FAILURE) Error("Can't create image window.");
                    314: 
                    315:     /*
                    316:      * Select mouse ButtonPressed on the window, this is how we determine
                    317:      * when to stop displaying the window.
                    318:      */
                    319:     XSelectInput(image_win, (ButtonPressed | ExposeWindow | ExposeRegion));
                    320:      
                    321:     /*
                    322:      * Store the window name string.
                    323:      */
                    324:     XStoreName(image_win, win_name);
                    325:     
                    326:     /*
                    327:      * Map the image window.
                    328:      */
                    329:     XMapWindow(image_win);
                    330: 
                    331:     /*
                    332:      * Set up a while loop to maintain the image.
                    333:      */
                    334:     while (TRUE) {
                    335:        int i, nbytes;
                    336:        /*
                    337:         * Wait on mouse input event to terminate.
                    338:         */
                    339:        XNextEvent(&event);
                    340:        if (event.type == ButtonPressed) break;
                    341: 
                    342:        switch((int)event.type) {
                    343:          case ExposeWindow:  /* Copy the data into the window.*/
                    344:          case ExposeRegion:  /* simpler to copy from x=0 for full width */
                    345:            if(header.pixmap_format == XYFormat) {
                    346:                onebufsize =  /* size of each bitmap */
                    347:                  XYPixmapSize(header.pixmap_width,
                    348:                               header.pixmap_height, 1);
                    349:                nbytes = BitmapSize(header.pixmap_width,1);
                    350:                if(header.display_planes > 1) {
                    351:                    forepixel = -1;
                    352:                    backpixel = 0;
                    353:                    planes = 1<<(DisplayPlanes()); /* MSB << 1 */
                    354:                }
                    355:                else {
                    356:                    forepixel = WhitePixel;
                    357:                    backpixel = BlackPixel;
                    358:                    planes = AllPlanes;
                    359:                }
                    360:                for(j=0; j<header.display_planes; j++) {        
                    361:                    if(header.display_planes > 1)
                    362:                        planes >>= 1; /* shift down a bit */
                    363:                    for(i=0; i<xevent->height; i+=100)
                    364:                      if(inverse)
                    365:                        XBitmapBitsPut(image_win,
                    366:                                       0, i + xevent->y,
                    367:                                       header.pixmap_width, 
                    368:                                       MIN(100, xevent->height - i),
                    369:                                       buffer+((i+xevent->y)*nbytes)
                    370:                                          + (onebufsize * j), 
                    371:                                       backpixel, forepixel,
                    372:                                       0, GXcopy, planes);
                    373:                      else
                    374:                        XBitmapBitsPut(image_win,
                    375:                                       0, i + xevent->y,
                    376:                                       header.pixmap_width, 
                    377:                                       MIN(100, xevent->height - i),
                    378:                                       buffer+((i+xevent->y)*nbytes)
                    379:                                          + (onebufsize * j), 
                    380:                                       forepixel, backpixel,
                    381:                                       0, GXcopy, planes);
                    382:                }
                    383:            } 
                    384:            else if(DisplayPlanes() < 9) {
                    385:                nbytes = BZPixmapSize(header.pixmap_width,1);
                    386:                for(i=0; i<xevent->height; i+=100)
                    387:                  XPixmapBitsPutZ(image_win, 
                    388:                                  0, i + xevent->y,
                    389:                                  header.pixmap_width,
                    390:                                  MIN(100, xevent->height - i),
                    391:                                  buffer+((i+xevent->y)*nbytes),
                    392:                                  0, GXcopy, AllPlanes);
                    393:            }
                    394:            else {  /* Display Planes > 8 */
                    395:                nbytes = WZPixmapSize(header.pixmap_width, 1);
                    396:                for(i=0; i<xevent->height; i+=100)
                    397:                  XPixmapBitsPutZ(image_win, 
                    398:                                  0, i + xevent->y,
                    399:                                  header.pixmap_width,
                    400:                                  MIN(50, xevent->height - i),
                    401:                                  buffer+((i+xevent->y)*nbytes),
                    402:                                  0, GXcopy, AllPlanes);
                    403:            }
                    404:        }
                    405:     }
                    406: 
                    407:     /*
                    408:      * Destroy the image window.
                    409:      */
                    410:     XDestroyWindow(image_win);
                    411:     
                    412:     /*
                    413:      * Free the pixmap buffer.
                    414:      */
                    415:     free(buffer);
                    416: 
                    417:     /*
                    418:      * Free window name string.
                    419:      */
                    420:     free(win_name);
                    421:     exit(0);
                    422: }
                    423: 
                    424: /*
                    425:  * test two color map entries for equality
                    426:  */
                    427: ColorEqual(color1, color2)
                    428:      register Color *color1, *color2;
                    429: {
                    430:     return(color1->pixel == color2->pixel &&
                    431:           color1->red   == color2->red &&
                    432:           color1->green == color2->green &&
                    433:           color1->blue  == color2->blue);
                    434: }
                    435: 
                    436: /*
                    437:  * Report the syntax for calling xwud.
                    438:  */
                    439: Syntax(call)
                    440:     char *call;
                    441: {
                    442:     fprintf( stderr,
                    443:        "xwud: %s [-help][-debug][-inverse][-in <file>][[host]:vs]\n",
                    444:        call
                    445:     );
                    446:     exit(1);
                    447: }
                    448: 
                    449: 
                    450: /*
                    451:  * Error - Fatal xwud error.
                    452:  */
                    453: Error(string)
                    454:        char *string;   /* Error description string. */
                    455: {
                    456:        fprintf(stderr, "xwud: Error => %s\n", string);
                    457: 
                    458:        if (errno != 0) {
                    459:                perror("xwud");
                    460:                fprintf(stderr, "\n");
                    461:        }
                    462: 
                    463:        exit(1);
                    464: }
                    465: 
                    466: /* End of xwud.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.