Annotation of 43BSDTahoe/new/X/xwd/xwd.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:  * xwd.c MIT Project Athena, X Window system window raster image dumper.
                      7:  *
                      8:  * This program will dump a raster image of the contents of a window into a 
                      9:  * file for output on graphics printers or for other uses.
                     10:  *
                     11:  *  Author:    Tony Della Fera, DEC
                     12:  *             17-Jun-85
                     13:  * 
                     14:  *  Modification history:
                     15:  *
                     16:  *  11/14/86 Bill Wyatt, Smithsonian Astrophysical Observatory
                     17:  *    - Removed Z format option, changing it to an XY option. Monochrome 
                     18:  *      windows will always dump in XY format. Color windows will dump
                     19:  *      in Z format by default, but can be dumped in XY format with the
                     20:  *      -xy option.
                     21:  *
                     22:  *  11/18/86 Bill Wyatt
                     23:  *    - VERSION 6 is same as version 5 for monchrome. For colors, the 
                     24:  *      appropriate number of Color structs are dumped after the header,
                     25:  *      which has the number of colors (=0 for monochrome) in place of the
                     26:  *      V5 padding at the end. Up to 16-bit displays are supported. I
                     27:  *      don't yet know how 24- to 32-bit displays will be handled under
                     28:  *      the Version 11 protocol.
                     29:  */
                     30: 
                     31: #ifndef lint
                     32: static char *rcsid_xwd_c = "$Header: xwd.c,v 10.12 86/11/25 09:01:08 jg Rel $";
                     33: #endif
                     34: 
                     35: #include <X/Xlib.h>
                     36: #include <sys/types.h>
                     37: #include <stdio.h>
                     38: #include <strings.h>
                     39: 
                     40: char *calloc();
                     41: 
                     42: typedef enum _bool {FALSE, TRUE} Bool;
                     43: 
                     44: #include "../cursors/target.cursor"
                     45: #include "../cursors/target_mask.cursor"
                     46: 
                     47: #include "XWDFile.h"
                     48: 
                     49: #define MAX(a, b) (a) > (b) ? (a) : (b)
                     50: #define MIN(a, b) (a) < (b) ? (a) : (b)
                     51: #define ABS(a) (a) < 0 ? -(a) : (a)
                     52: 
                     53: #define FAILURE 0
                     54: 
                     55: #define FEEP_VOLUME 0
                     56: 
                     57: extern int errno;
                     58: 
                     59: main(argc, argv)
                     60:     int argc;
                     61:     char **argv;
                     62: {
                     63:     register int i, *histbuffer;
                     64:     register u_short *wbuffer;
                     65:     register char *buffer, *cbuffer;
                     66: 
                     67:     unsigned buffer_size;
                     68:     int virt_x, virt_y;
                     69:     int virt_width, virt_height;
                     70:     int pixmap_format = -1;
                     71:     int win_name_size;
                     72:     int header_size;
                     73:     int ncolors = 0;
                     74:     char *str_index;
                     75:     char *file_name;
                     76:     char display[256];
                     77:     char *win_name;
                     78:     Bool nobdrs = FALSE;
                     79:     Bool debug = FALSE;
                     80:     Bool standard_out = TRUE;
                     81: 
                     82:     Color *pixcolors;
                     83:     Display *dpy;
                     84:     Window target_win;
                     85:     Window image_win;
                     86:     WindowInfo win_info;
                     87:     Cursor cursor;
                     88:     XButtonEvent rep;
                     89: 
                     90:     XWDFileHeader header;
                     91: 
                     92:     FILE *out_file = stdout;
                     93: 
                     94:     for (i = 1; i < argc; i++) {
                     95:        str_index = (char *)index (argv[i], ':');
                     96:        if(str_index != (char *)NULL) {
                     97:            (void) strncpy(display,argv[i],sizeof(display));
                     98:            continue;
                     99:         }
                    100:        str_index = (char *) index (argv [i], '-');
                    101:        if (str_index == (char *)NULL) Syntax(argv[0]);
                    102:        if (strncmp(argv[i], "-nobdrs", 6) == 0) {
                    103:            nobdrs = TRUE;
                    104:            continue;
                    105:        }
                    106:        if (strncmp(argv[i], "-debug", 6) == 0) {
                    107:            debug = TRUE;
                    108:            continue;
                    109:        }
                    110:        if (strncmp(argv[i], "-help", 5) == 0) {
                    111:            Syntax(argv[0]);
                    112:        }
                    113:        if (strncmp(argv[i], "-out", 4) == 0) {
                    114:            if (++i >= argc) Syntax(argv[0]);
                    115:            file_name = argv[i];
                    116:            standard_out = FALSE;
                    117:            continue;
                    118:        }
                    119:        if(strncmp(argv[i], "-xy") == 0) {
                    120:            pixmap_format = XYFormat;
                    121:            continue;
                    122:        }
                    123:        Syntax(argv[0]);
                    124:     }
                    125:     
                    126:     if (!standard_out) {
                    127:        /*
                    128:         * Open the output file.
                    129:         */
                    130:        if((out_file = fopen(file_name, "w")) == NULL)
                    131:          Error("Can't open output file as specified.");
                    132:     }
                    133: 
                    134:     /*
                    135:      * Open the display.
                    136:      */
                    137:     if ((dpy = XOpenDisplay(display)) == NULL) {
                    138:         fprintf(stderr, "%s: Can't open display '%s'\n",
                    139:                argv[0], XDisplayName(display));
                    140:        exit(1);
                    141:       }
                    142: 
                    143: 
                    144:     /*
                    145:      * Store the cursor incase we need it.
                    146:      */
                    147:     if (debug) fprintf(stderr,"xwd: Storing target cursor.\n");
                    148:     if((cursor = XCreateCursor(
                    149:        target_width, target_height, 
                    150:        target_bits, target_mask_bits, 
                    151:        8, 8,
                    152:        BlackPixel, WhitePixel,
                    153:        GXcopy
                    154:     )) == FAILURE)
                    155:        Error("Error occured while trying to store target cursor.");
                    156: 
                    157:     /*
                    158:      * Set the right pixmap format for the display type.
                    159:      */
                    160:     if(DisplayPlanes() == 1) pixmap_format = XYFormat;
                    161:     else {
                    162:        if(pixmap_format != XYFormat) pixmap_format = ZFormat;
                    163:     }
                    164: 
                    165:     /*
                    166:      * Let the user select the target window.
                    167:      */
                    168:     if(XGrabMouse(RootWindow, cursor, ButtonPressed) == FAILURE)
                    169:       Error("Can't grab the mouse.");
                    170:     XNextEvent(&rep);
                    171:     XUngrabMouse();
                    172:     target_win = rep.subwindow;
                    173:     if (target_win == 0) {
                    174:        /*
                    175:         * The user must have indicated the root window.
                    176:         */
                    177:        if (debug) fprintf(stderr,"xwd: Root window selected as target.\n");
                    178:        target_win = RootWindow;
                    179:     }
                    180:     else if (debug) 
                    181:      fprintf(stderr,
                    182:             "xwd: Window 0x%x slected as target.\n", target_win);
                    183: 
                    184:     /*
                    185:      * Inform the user not to alter the screen.
                    186:      */
                    187:     XFeep(FEEP_VOLUME);
                    188: 
                    189:     /*
                    190:      * Get the parameters of the window being dumped.
                    191:      */
                    192:     if (debug) fprintf(stderr,"xwd: Getting target window information.\n");
                    193: 
                    194:     if(XQueryWindow(target_win, &win_info) == FAILURE) 
                    195:      Error("Can't query target window.");
                    196:     if(XFetchName(target_win, &win_name) == FAILURE)
                    197:      Error("Can't fetch target window name.");
                    198: 
                    199:     /* sizeof(char) is included for the null string terminator. */
                    200:     win_name_size = strlen(win_name) + sizeof(char);
                    201: 
                    202:     /*
                    203:      * Calculate the virtual x, y, width and height of the window pane image
                    204:      * (this depends on wether or not the borders are included.
                    205:      */
                    206:     if (nobdrs) {
                    207:        if (debug) fprintf(stderr,"xwd: Image without borders selected.\n");
                    208:        image_win = target_win;
                    209:        virt_x = 0;
                    210:        virt_y = 0;
                    211:        virt_width = win_info.width;
                    212:        virt_height = win_info.height;
                    213:     }
                    214:     else {
                    215:        if (debug) fprintf(stderr,"xwd: Image with borders selected.\n");
                    216:        image_win = RootWindow;
                    217:        virt_x = win_info.x;
                    218:        virt_y = win_info.y;
                    219:        virt_width = win_info.width + (win_info.bdrwidth << 1);
                    220:        virt_height = win_info.height + (win_info.bdrwidth << 1);
                    221:     }
                    222: 
                    223:     /*
                    224:      * Determine the pixmap size.
                    225:      */
                    226:     if (pixmap_format == XYFormat) {
                    227:        buffer_size = XYPixmapSize(virt_width, virt_height, DisplayPlanes());
                    228:        if (debug) {
                    229:            fprintf(stderr,
                    230:                    "xwd: Pixmap in XYFormat, size %d bytes.\n", buffer_size);
                    231:        }
                    232:     }
                    233:     else if (DisplayPlanes() < 9) {
                    234:        buffer_size = BZPixmapSize(virt_width, virt_height);
                    235:        if (debug) {
                    236:            fprintf(stderr,
                    237:              "xwd: Pixmap in byte ZFormat, size %d bytes.\n", buffer_size);
                    238:        }
                    239:     }
                    240:     else {
                    241:        buffer_size = WZPixmapSize(virt_width, virt_height);
                    242:        if (debug) {
                    243:            fprintf(stderr,
                    244:              "xwd: Pixmap in word ZFormat, size %d bytes.\n", buffer_size);
                    245:        }
                    246:     }
                    247: 
                    248: 
                    249:     /*
                    250:      * Calloc the buffer.
                    251:      */
                    252:     if (debug) fprintf(stderr,"xwd: Calloc'ing data buffer.\n");
                    253:     if((buffer = calloc(buffer_size , 1)) == NULL)
                    254:        Error("Can't calloc data buffer.");
                    255: 
                    256:     /*
                    257:      * Snarf the pixmap out of the frame buffer.
                    258:      * Color windows get snarfed in Z format first to check the color
                    259:      * map allocations before resnarfing if XY format selected.
                    260:      */
                    261:     if (debug) fprintf(stderr,"xwd: Getting pixmap.\n");
                    262:     if (DisplayPlanes() == 1) {
                    263:        (void) XPixmapGetXY(
                    264:            image_win,
                    265:            virt_x, virt_y,
                    266:            virt_width, virt_height,
                    267:            (short *)buffer
                    268:        );
                    269:     }
                    270:     else {
                    271:        (void) XPixmapGetZ(
                    272:            image_win,
                    273:            virt_x, virt_y,
                    274:            virt_width, virt_height,
                    275:            (caddr_t)buffer
                    276:        );
                    277:     }
                    278: 
                    279:     /*
                    280:      * Find the number of colors used, then write them out to the file.
                    281:      */
                    282:     ncolors = 0;
                    283:     if(DisplayPlanes() > 1) {
                    284:        if(DisplayPlanes() < 9) {
                    285:            histbuffer = (int *)calloc(256, sizeof(int));
                    286:            bzero(histbuffer, 256*sizeof(int));
                    287:            pixcolors = (Color *)calloc(1, sizeof(Color));
                    288:            for(i=0; i<buffer_size; i++) {
                    289:                /* if previously found, skip color query */
                    290:                if(histbuffer[(int)buffer[i]] == 0) {
                    291:                    pixcolors = 
                    292:                      (Color *)realloc(pixcolors, sizeof(Color)*(++ncolors));
                    293:                    if(debug)
                    294:                      fprintf(stderr,"Color %3d at pixel val %5d, i= %5d =",
                    295:                              ncolors, buffer[i], i);
                    296:                    histbuffer[(int)buffer[i]]++;
                    297:                    pixcolors[ncolors-1].pixel = (int)buffer[i];
                    298:                    if(XQueryColor(&pixcolors[ncolors-1]) == 0) 
                    299:                      Error("Unable to query color table?");
                    300:                    if(debug) fprintf(stderr,"%5d %5d %5d\n",
                    301:                                      pixcolors[ncolors-1].red,
                    302:                                      pixcolors[ncolors-1].green,
                    303:                                      pixcolors[ncolors-1].blue);
                    304:                }
                    305:            }
                    306:        }
                    307:        else if(DisplayPlanes() < 17) {
                    308:            wbuffer = (u_short *)buffer;
                    309:            histbuffer = (int *)calloc(65536, sizeof(int));
                    310:            bzero(histbuffer, 65536*sizeof(int));
                    311:            pixcolors = (Color *)calloc(1, sizeof(Color));
                    312:            for(i=0; i<(buffer_size/sizeof(u_short)); i++) {
                    313:                /* if previously found, skip color query */
                    314:                if(histbuffer[(int)wbuffer[i]] == 0) {
                    315:                    pixcolors = 
                    316:                      (Color *)realloc(pixcolors, sizeof(Color)*(++ncolors));
                    317:                    if(debug)
                    318:                      fprintf(stderr,"Color %2d at pixel val %d, i= %d =",
                    319:                              ncolors, wbuffer[i], i);
                    320:                    histbuffer[(int)wbuffer[i]]++;
                    321:                    pixcolors[ncolors-1].pixel = (int)wbuffer[i];
                    322:                    if(XQueryColor(&pixcolors[ncolors-1]) == 0) 
                    323:                      Error("Unable to query color table?");
                    324:                    if(debug) fprintf(stderr,"%d %d %d\n",
                    325:                                      pixcolors[ncolors-1].red,
                    326:                                      pixcolors[ncolors-1].green,
                    327:                                      pixcolors[ncolors-1].blue);
                    328:                }
                    329:            }
                    330:        } 
                    331:        else if(DisplayPlanes() > 16)
                    332:          Error("Unable to handle more than 16 planes at this time");
                    333: 
                    334:        /* reread in XY format if necessary */
                    335:        if(pixmap_format == XYFormat) {
                    336:            (void) XPixmapGetXY(image_win,
                    337:                                virt_x, virt_y,
                    338:                                virt_width, virt_height,
                    339:                                (short *)buffer);
                    340:        }
                    341: 
                    342:        free(histbuffer);
                    343:     }
                    344: 
                    345:     /*
                    346:      * Inform the user that the image has been retrieved.
                    347:      */
                    348:     XFeep(FEEP_VOLUME);
                    349:     XFeep(FEEP_VOLUME);
                    350:     XFlush();
                    351: 
                    352:     /*
                    353:      * Calculate header size.
                    354:      */
                    355:     if (debug) fprintf(stderr,"xwd: Calculating header size.\n");
                    356:     header_size = sizeof(header) + win_name_size;
                    357: 
                    358:     /*
                    359:      * Write out header information.
                    360:      */
                    361:     if (debug) fprintf(stderr,"xwd: Constructing and dumping file header.\n");
                    362:     header.header_size = header_size;
                    363:     header.file_version = XWD_FILE_VERSION;
                    364:     header.display_type = DisplayType();
                    365:     header.display_planes = DisplayPlanes();
                    366:     header.pixmap_format = pixmap_format;
                    367:     header.pixmap_width = virt_width;
                    368:     header.pixmap_height = virt_height;
                    369:     header.window_width = win_info.width;
                    370:     header.window_height = win_info.height;
                    371:     header.window_x = win_info.x;
                    372:     header.window_y = win_info.y;
                    373:     header.window_bdrwidth = win_info.bdrwidth;
                    374:     header.window_ncolors = ncolors;
                    375: 
                    376:     (void) fwrite((char *)&header, sizeof(header), 1, out_file);
                    377:     (void) fwrite(win_name, win_name_size, 1, out_file);
                    378: 
                    379:     /*
                    380:      * Write out the color maps, if any
                    381:      */
                    382:     if (debug) fprintf(stderr,"xwd: Dumping %d colors.\n",ncolors);
                    383:     (void) fwrite(pixcolors, sizeof(Color), ncolors, out_file);
                    384: 
                    385:     /*
                    386:      * Write out the buffer.
                    387:      */
                    388:     if (debug) fprintf(stderr,"xwd: Dumping pixmap.\n");
                    389:     (void) fwrite(buffer, (int) buffer_size, 1, out_file);
                    390: 
                    391:     /*
                    392:      * Close the output file.
                    393:      */
                    394:     if (debug) fprintf(stderr,"xwd: Closing output file.\n");
                    395:     (void) fclose(out_file);
                    396: 
                    397:     /*
                    398:      * free the color buffer.
                    399:      */
                    400:     if(debug && ncolors > 0) fprintf(stderr,"xwd: Freeing color map.\n");
                    401:     if(ncolors > 0) free(pixcolors);
                    402: 
                    403:     /*
                    404:      * Free the pixmap buffer.
                    405:      */
                    406:     if (debug) fprintf(stderr,"xwd: Freeing pixmap buffer.\n");
                    407:     free(buffer);
                    408: 
                    409:     /*
                    410:      * Free window name string.
                    411:      */
                    412:     if (debug) fprintf(stderr,"xwd: Freeing window name string.\n");
                    413:     free(win_name);
                    414:     exit(0);
                    415: }
                    416: 
                    417: /*
                    418:  * Report the syntax for calling xwd.
                    419:  */
                    420: Syntax(call)
                    421:     char *call;
                    422: {
                    423:     fprintf(
                    424:        stderr,
                    425:        "xwd: %s [-debug] [-help] [-nobdrs] [-out <file>]\n",
                    426:        call
                    427:     );
                    428:     fprintf(stderr, "                [-xy] [[host]:vs]\n");
                    429:     exit(1);
                    430: }
                    431: 
                    432: 
                    433: /*
                    434:  * Error - Fatal xwd error.
                    435:  */
                    436: Error(string)
                    437:        char *string;   /* Error description string. */
                    438: {
                    439:        fprintf(stderr, "\nxwd: Error => %s", string);
                    440:        if (errno != 0) {
                    441:                perror("xwd");
                    442:                fprintf(stderr, "\n");
                    443:        }
                    444: 
                    445:        exit(1);
                    446: }
                    447: 
                    448: /* End of xwd.c */

unix.superglobalmegacorp.com

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