1: #include <X/mit-copyright.h> 2: 3: /* Copyright 1985, 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: 15: #ifndef lint 16: static char *rcsid_xwd_c = "$Header: xwd.c,v 10.6 86/02/01 16:07:54 tony Rel $"; 17: #endif 18: 19: #include <X/Xlib.h> 20: #include <sys/types.h> 21: #include <stdio.h> 22: #include <strings.h> 23: 24: char *calloc(); 25: 26: typedef enum _bool {FALSE, TRUE} Bool; 27: 28: #include "../cursors/target.cursor" 29: #include "../cursors/target_mask.cursor" 30: 31: #include "XWDFile.h" 32: 33: #define MAX(a, b) (a) > (b) ? (a) : (b) 34: #define MIN(a, b) (a) < (b) ? (a) : (b) 35: #define ABS(a) (a) < 0 ? -(a) : (a) 36: 37: #define FAILURE 0 38: 39: #define FEEP_VOLUME 0 40: 41: extern int errno; 42: 43: main(argc, argv) 44: int argc; 45: char **argv; 46: { 47: register int i; 48: int status; 49: unsigned buffer_size; 50: int virt_x, virt_y; 51: int virt_width, virt_height; 52: int pixmap_format = XYFormat; 53: int win_name_size; 54: int header_size; 55: char *str_index; 56: char *file_name; 57: char display[256]; 58: char *win_name; 59: char *buffer; 60: Bool nobdrs = FALSE; 61: Bool debug = FALSE; 62: Bool standard_out = TRUE; 63: 64: Display *dpy; 65: Window target_win; 66: Window image_win; 67: WindowInfo win_info; 68: Cursor cursor; 69: XButtonEvent rep; 70: 71: XWDFileHeader header; 72: 73: FILE *out_file = stdout; 74: 75: for (i = 1; i < argc; i++) { 76: str_index = (char *)index (argv[i], ':'); 77: if(str_index != NULL) { 78: (void) strncpy(display,argv[i],sizeof(display)); 79: continue; 80: } 81: str_index = (char *) index (argv [i], '-'); 82: if (str_index == NULL) Syntax(argv[0]); 83: if (strncmp(argv[i], "-nobdrs", 6) == 0) { 84: nobdrs = TRUE; 85: continue; 86: } 87: if (strncmp(argv[i], "-debug", 6) == 0) { 88: debug = TRUE; 89: continue; 90: } 91: if (strncmp(argv[i], "-help", 5) == 0) { 92: Syntax(argv[0]); 93: } 94: if (strncmp(argv[i], "-out", 4) == 0) { 95: if (++i >= argc) Syntax(argv[0]); 96: file_name = argv[i]; 97: standard_out = FALSE; 98: continue; 99: } 100: if (strncmp(argv[i], "-z", 2) == 0) { 101: pixmap_format = ZFormat; 102: continue; 103: } 104: Syntax(argv[0]); 105: } 106: 107: if (!standard_out) { 108: /* 109: * Open the output file. 110: */ 111: out_file = fopen(file_name, "w"); 112: if (out_file == NULL) { 113: Error("Can't open output file as specified."); 114: } 115: } 116: 117: /* 118: * Open the display. 119: */ 120: if (debug) printf("xwd: Opening display.\n"); 121: if ((dpy = XOpenDisplay(display)) == NULL) { 122: Error("Error occured while trying open display."); 123: } 124: 125: /* 126: * Store the cursor incase we need it. 127: */ 128: if (debug) printf("xwd: Storing target cursor.\n"); 129: cursor = XCreateCursor( 130: target_width, target_height, 131: target_bits, target_mask_bits, 132: 8, 8, 133: BlackPixel, WhitePixel, 134: GXcopy 135: ); 136: if (cursor == FAILURE) { 137: Error("Error occured while trying to store target cursor."); 138: } 139: 140: /* 141: * Check to see if we are in the right pixmap format for the 142: * display type. 143: */ 144: if ((dpy->dplanes == 1) && (pixmap_format == ZFormat)) { 145: Error("ZFormat is not valid on a monochrome display."); 146: } 147: 148: /* 149: * Let the user select the target window. 150: */ 151: status = XGrabMouse(RootWindow, cursor, ButtonPressed); 152: if (status == FAILURE) Error("Can't grab the mouse."); 153: XNextEvent(&rep); 154: XUngrabMouse(); 155: target_win = rep.subwindow; 156: if (target_win == 0) { 157: /* 158: * The user must have indicated the root window. 159: */ 160: if (debug) printf("xwd: Root window selected as target.\n"); 161: target_win = RootWindow; 162: } 163: else if (debug) printf("xwd: Window 0x%x slected as target.\n", target_win); 164: 165: /* 166: * Inform the user not to alter the screen. 167: */ 168: XFeep(FEEP_VOLUME); 169: 170: /* 171: * Get the parameters of the window being dumped. 172: */ 173: if (debug) printf("xwd: Getting target window information.\n"); 174: status = XQueryWindow(target_win, &win_info); 175: if (status == FAILURE) Error("Can't query target window."); 176: status = XFetchName(target_win, &win_name); 177: if (status == FAILURE) Error("Can't fetch target window name."); 178: win_name_size = strlen(win_name) + sizeof(char); 179: /* sizeof(char) is included for the null string terminator. */ 180: 181: /* 182: * Calculate the virtual x, y, width and height of the window pane image 183: * (this depends on wether or not the borders are included. 184: */ 185: if (nobdrs) { 186: if (debug) printf("xwd: Image without borders selected.\n"); 187: image_win = target_win; 188: virt_x = 0; 189: virt_y = 0; 190: virt_width = win_info.width; 191: virt_height = win_info.height; 192: } 193: else { 194: if (debug) printf("xwd: Image with borders selected.\n"); 195: image_win = RootWindow; 196: virt_x = win_info.x; 197: virt_y = win_info.y; 198: virt_width = win_info.width + (win_info.bdrwidth << 1); 199: virt_height = win_info.height + (win_info.bdrwidth << 1); 200: } 201: 202: /* 203: * Determine the pixmap size. 204: */ 205: if (pixmap_format == XYFormat) { 206: buffer_size = XYPixmapSize(virt_width, virt_height, dpy->dplanes); 207: if (debug) { 208: printf("xwd: Pixmap in XYFormat, size %d bytes.\n", buffer_size); 209: } 210: } 211: else if (dpy->dplanes < 9) { 212: buffer_size = BZPixmapSize(virt_width, virt_height); 213: if (debug) { 214: printf("xwd: Pixmap in byte ZFormat, size %d bytes.\n", buffer_size); 215: } 216: } 217: else { 218: buffer_size = WZPixmapSize(virt_width, virt_height); 219: if (debug) { 220: printf("xwd: Pixmap in word ZFormat, size %d bytes.\n", buffer_size); 221: } 222: } 223: 224: 225: /* 226: * Calloc the buffer. 227: */ 228: if (debug) printf("xwd: Calloc'ing data buffer.\n"); 229: buffer = calloc(buffer_size , 1); 230: if (buffer == NULL) Error("Can't calloc data buffer."); 231: 232: /* 233: * Snarf the pixmap out of the frame buffer. 234: */ 235: if (debug) printf("xwd: Getting pixmap.\n"); 236: if (pixmap_format == XYFormat) { 237: (void) XPixmapGetXY( 238: image_win, 239: virt_x, virt_y, 240: virt_width, virt_height, 241: (short *)buffer 242: ); 243: } 244: else { 245: (void) XPixmapGetZ( 246: image_win, 247: virt_x, virt_y, 248: virt_width, virt_height, 249: (caddr_t)buffer 250: ); 251: } 252: 253: /* 254: * Inform the user that the image has been retrieved. 255: */ 256: XFeep(FEEP_VOLUME); 257: XFeep(FEEP_VOLUME); 258: XFlush(); 259: 260: /* 261: * Calculate header size. 262: */ 263: if (debug) printf("xwd: Calculating header size.\n"); 264: header_size = sizeof(header) + win_name_size; 265: 266: /* 267: * Writ out header information. 268: */ 269: if (debug) printf("xwd: Constructing and dumping file header.\n"); 270: header.header_size = header_size; 271: header.file_version = XWD_FILE_VERSION; 272: header.display_type = dpy->dtype; 273: header.display_planes = dpy->dplanes; 274: header.pixmap_format = pixmap_format; 275: header.pixmap_width = virt_width; 276: header.pixmap_height = virt_height; 277: header.window_width = win_info.width; 278: header.window_height = win_info.height; 279: header.window_x = win_info.x; 280: header.window_y = win_info.y; 281: header.window_bdrwidth = win_info.bdrwidth; 282: header.padding = 0; 283: 284: (void) fwrite((char *)&header, sizeof(header), 1, out_file); 285: (void) fwrite(win_name, win_name_size, 1, out_file); 286: 287: /* 288: * Write out the buffer. 289: */ 290: if (debug) printf("xwd: Dumping pixmap.\n"); 291: (void) fwrite(buffer, (int) buffer_size, 1, out_file); 292: 293: /* 294: * Close the output file. 295: */ 296: if (debug) printf("xwd: Closing output file.\n"); 297: (void) fclose(out_file); 298: 299: /* 300: * Free the pixmap buffer. 301: */ 302: if (debug) printf("xwd: Freeing pixmap buffer.\n"); 303: free(buffer); 304: 305: /* 306: * Free window name string. 307: */ 308: if (debug) printf("xwd: Freeing window name string.\n"); 309: free(win_name); 310: exit(0); 311: } 312: 313: 314: /* 315: * Report the syntax for calling xwd. 316: */ 317: Syntax(call) 318: char *call; 319: { 320: fprintf( 321: stderr, 322: "\nUsage: %s [-debug] [-help] [-nobdrs] [-out <file>]\n", 323: call 324: ); 325: fprintf(stderr, " [-z] [[host]:vs]\n\n"); 326: exit(0); 327: } 328: 329: 330: /* 331: * Error - Fatal xwd error. 332: */ 333: Error(string) 334: char *string; /* Error description string. */ 335: { 336: fprintf(stderr, "\nxwd: Error => %s", string); 337: fprintf(stderr, "\n\n"); 338: 339: if (errno != 0) { 340: perror("xwd"); 341: fprintf(stderr, "\n"); 342: } 343: 344: exit(1); 345: } 346: 347: /* End of xwd.c */