|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.