Annotation of 43BSDTahoe/new/X/xwud/xwud.c, revision 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.