|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T x
Length: 11833 (0x2e39) Types: TextFile Names: »xwd.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z« └─⟦2109abc41⟧ └─⟦this⟧ »./X.V10R4/xwd/xwd.c«
#include <X/mit-copyright.h> /* Copyright 1985, 1986, Massachusetts Institute of Technology */ /* * xwd.c MIT Project Athena, X Window system window raster image dumper. * * This program will dump a raster image of the contents of a window into a * file for output on graphics printers or for other uses. * * Author: Tony Della Fera, DEC * 17-Jun-85 * * Modification history: * * 11/14/86 Bill Wyatt, Smithsonian Astrophysical Observatory * - Removed Z format option, changing it to an XY option. Monochrome * windows will always dump in XY format. Color windows will dump * in Z format by default, but can be dumped in XY format with the * -xy option. * * 11/18/86 Bill Wyatt * - VERSION 6 is same as version 5 for monchrome. For colors, the * appropriate number of Color structs are dumped after the header, * which has the number of colors (=0 for monochrome) in place of the * V5 padding at the end. Up to 16-bit displays are supported. I * don't yet know how 24- to 32-bit displays will be handled under * the Version 11 protocol. */ #ifndef lint static char *rcsid_xwd_c = "$Header: xwd.c,v 10.12 86/11/25 09:01:08 jg Rel $"; #endif #include <X/Xlib.h> #include <sys/types.h> #include <stdio.h> #include <strings.h> char *calloc(); typedef enum _bool {FALSE, TRUE} Bool; #include "../cursors/target.cursor" #include "../cursors/target_mask.cursor" #include "XWDFile.h" #define MAX(a, b) (a) > (b) ? (a) : (b) #define MIN(a, b) (a) < (b) ? (a) : (b) #define ABS(a) (a) < 0 ? -(a) : (a) #define FAILURE 0 #define FEEP_VOLUME 0 extern int errno; main(argc, argv) int argc; char **argv; { register int i, *histbuffer; register u_short *wbuffer; register char *buffer, *cbuffer; unsigned buffer_size; int virt_x, virt_y; int virt_width, virt_height; int pixmap_format = -1; int win_name_size; int header_size; int ncolors = 0; char *str_index; char *file_name; char display[256]; char *win_name; Bool nobdrs = FALSE; Bool debug = FALSE; Bool standard_out = TRUE; Color *pixcolors; Display *dpy; Window target_win; Window image_win; WindowInfo win_info; Cursor cursor; XButtonEvent rep; XWDFileHeader header; FILE *out_file = stdout; for (i = 1; i < argc; i++) { str_index = (char *)index (argv[i], ':'); if(str_index != (char *)NULL) { (void) strncpy(display,argv[i],sizeof(display)); continue; } str_index = (char *) index (argv [i], '-'); if (str_index == (char *)NULL) Syntax(argv[0]); if (strncmp(argv[i], "-nobdrs", 6) == 0) { nobdrs = TRUE; continue; } if (strncmp(argv[i], "-debug", 6) == 0) { debug = TRUE; continue; } if (strncmp(argv[i], "-help", 5) == 0) { Syntax(argv[0]); } if (strncmp(argv[i], "-out", 4) == 0) { if (++i >= argc) Syntax(argv[0]); file_name = argv[i]; standard_out = FALSE; continue; } if(strncmp(argv[i], "-xy") == 0) { pixmap_format = XYFormat; continue; } Syntax(argv[0]); } if (!standard_out) { /* * Open the output file. */ if((out_file = fopen(file_name, "w")) == NULL) Error("Can't open output file as specified."); } /* * Open the display. */ if ((dpy = XOpenDisplay(display)) == NULL) { fprintf(stderr, "%s: Can't open display '%s'\n", argv[0], XDisplayName(display)); exit(1); } /* * Store the cursor incase we need it. */ if (debug) fprintf(stderr,"xwd: Storing target cursor.\n"); if((cursor = XCreateCursor( target_width, target_height, target_bits, target_mask_bits, 8, 8, BlackPixel, WhitePixel, GXcopy )) == FAILURE) Error("Error occured while trying to store target cursor."); /* * Set the right pixmap format for the display type. */ if(DisplayPlanes() == 1) pixmap_format = XYFormat; else { if(pixmap_format != XYFormat) pixmap_format = ZFormat; } /* * Let the user select the target window. */ if(XGrabMouse(RootWindow, cursor, ButtonPressed) == FAILURE) Error("Can't grab the mouse."); XNextEvent(&rep); XUngrabMouse(); target_win = rep.subwindow; if (target_win == 0) { /* * The user must have indicated the root window. */ if (debug) fprintf(stderr,"xwd: Root window selected as target.\n"); target_win = RootWindow; } else if (debug) fprintf(stderr, "xwd: Window 0x%x slected as target.\n", target_win); /* * Inform the user not to alter the screen. */ XFeep(FEEP_VOLUME); /* * Get the parameters of the window being dumped. */ if (debug) fprintf(stderr,"xwd: Getting target window information.\n"); if(XQueryWindow(target_win, &win_info) == FAILURE) Error("Can't query target window."); if(XFetchName(target_win, &win_name) == FAILURE) Error("Can't fetch target window name."); /* sizeof(char) is included for the null string terminator. */ win_name_size = strlen(win_name) + sizeof(char); /* * Calculate the virtual x, y, width and height of the window pane image * (this depends on wether or not the borders are included. */ if (nobdrs) { if (debug) fprintf(stderr,"xwd: Image without borders selected.\n"); image_win = target_win; virt_x = 0; virt_y = 0; virt_width = win_info.width; virt_height = win_info.height; } else { if (debug) fprintf(stderr,"xwd: Image with borders selected.\n"); image_win = RootWindow; virt_x = win_info.x; virt_y = win_info.y; virt_width = win_info.width + (win_info.bdrwidth << 1); virt_height = win_info.height + (win_info.bdrwidth << 1); } /* * Determine the pixmap size. */ if (pixmap_format == XYFormat) { buffer_size = XYPixmapSize(virt_width, virt_height, DisplayPlanes()); if (debug) { fprintf(stderr, "xwd: Pixmap in XYFormat, size %d bytes.\n", buffer_size); } } else if (DisplayPlanes() < 9) { buffer_size = BZPixmapSize(virt_width, virt_height); if (debug) { fprintf(stderr, "xwd: Pixmap in byte ZFormat, size %d bytes.\n", buffer_size); } } else { buffer_size = WZPixmapSize(virt_width, virt_height); if (debug) { fprintf(stderr, "xwd: Pixmap in word ZFormat, size %d bytes.\n", buffer_size); } } /* * Calloc the buffer. */ if (debug) fprintf(stderr,"xwd: Calloc'ing data buffer.\n"); if((buffer = calloc(buffer_size , 1)) == NULL) Error("Can't calloc data buffer."); /* * Snarf the pixmap out of the frame buffer. * Color windows get snarfed in Z format first to check the color * map allocations before resnarfing if XY format selected. */ if (debug) fprintf(stderr,"xwd: Getting pixmap.\n"); if (DisplayPlanes() == 1) { (void) XPixmapGetXY( image_win, virt_x, virt_y, virt_width, virt_height, (short *)buffer ); } else { (void) XPixmapGetZ( image_win, virt_x, virt_y, virt_width, virt_height, (caddr_t)buffer ); } /* * Find the number of colors used, then write them out to the file. */ ncolors = 0; if(DisplayPlanes() > 1) { if(DisplayPlanes() < 9) { histbuffer = (int *)calloc(256, sizeof(int)); bzero(histbuffer, 256*sizeof(int)); pixcolors = (Color *)calloc(1, sizeof(Color)); for(i=0; i<buffer_size; i++) { /* if previously found, skip color query */ if(histbuffer[(int)buffer[i]] == 0) { pixcolors = (Color *)realloc(pixcolors, sizeof(Color)*(++ncolors)); if(debug) fprintf(stderr,"Color %3d at pixel val %5d, i= %5d =", ncolors, buffer[i], i); histbuffer[(int)buffer[i]]++; pixcolors[ncolors-1].pixel = (int)buffer[i]; if(XQueryColor(&pixcolors[ncolors-1]) == 0) Error("Unable to query color table?"); if(debug) fprintf(stderr,"%5d %5d %5d\n", pixcolors[ncolors-1].red, pixcolors[ncolors-1].green, pixcolors[ncolors-1].blue); } } } else if(DisplayPlanes() < 17) { wbuffer = (u_short *)buffer; histbuffer = (int *)calloc(65536, sizeof(int)); bzero(histbuffer, 65536*sizeof(int)); pixcolors = (Color *)calloc(1, sizeof(Color)); for(i=0; i<(buffer_size/sizeof(u_short)); i++) { /* if previously found, skip color query */ if(histbuffer[(int)wbuffer[i]] == 0) { pixcolors = (Color *)realloc(pixcolors, sizeof(Color)*(++ncolors)); if(debug) fprintf(stderr,"Color %2d at pixel val %d, i= %d =", ncolors, wbuffer[i], i); histbuffer[(int)wbuffer[i]]++; pixcolors[ncolors-1].pixel = (int)wbuffer[i]; if(XQueryColor(&pixcolors[ncolors-1]) == 0) Error("Unable to query color table?"); if(debug) fprintf(stderr,"%d %d %d\n", pixcolors[ncolors-1].red, pixcolors[ncolors-1].green, pixcolors[ncolors-1].blue); } } } else if(DisplayPlanes() > 16) Error("Unable to handle more than 16 planes at this time"); /* reread in XY format if necessary */ if(pixmap_format == XYFormat) { (void) XPixmapGetXY(image_win, virt_x, virt_y, virt_width, virt_height, (short *)buffer); } free(histbuffer); } /* * Inform the user that the image has been retrieved. */ XFeep(FEEP_VOLUME); XFeep(FEEP_VOLUME); XFlush(); /* * Calculate header size. */ if (debug) fprintf(stderr,"xwd: Calculating header size.\n"); header_size = sizeof(header) + win_name_size; /* * Write out header information. */ if (debug) fprintf(stderr,"xwd: Constructing and dumping file header.\n"); header.header_size = header_size; header.file_version = XWD_FILE_VERSION; header.display_type = DisplayType(); header.display_planes = DisplayPlanes(); header.pixmap_format = pixmap_format; header.pixmap_width = virt_width; header.pixmap_height = virt_height; header.window_width = win_info.width; header.window_height = win_info.height; header.window_x = win_info.x; header.window_y = win_info.y; header.window_bdrwidth = win_info.bdrwidth; header.window_ncolors = ncolors; (void) fwrite((char *)&header, sizeof(header), 1, out_file); (void) fwrite(win_name, win_name_size, 1, out_file); /* * Write out the color maps, if any */ if (debug) fprintf(stderr,"xwd: Dumping %d colors.\n",ncolors); (void) fwrite(pixcolors, sizeof(Color), ncolors, out_file); /* * Write out the buffer. */ if (debug) fprintf(stderr,"xwd: Dumping pixmap.\n"); (void) fwrite(buffer, (int) buffer_size, 1, out_file); /* * Close the output file. */ if (debug) fprintf(stderr,"xwd: Closing output file.\n"); (void) fclose(out_file); /* * free the color buffer. */ if(debug && ncolors > 0) fprintf(stderr,"xwd: Freeing color map.\n"); if(ncolors > 0) free(pixcolors); /* * Free the pixmap buffer. */ if (debug) fprintf(stderr,"xwd: Freeing pixmap buffer.\n"); free(buffer); /* * Free window name string. */ if (debug) fprintf(stderr,"xwd: Freeing window name string.\n"); free(win_name); exit(0); } /* * Report the syntax for calling xwd. */ Syntax(call) char *call; { fprintf( stderr, "xwd: %s [-debug] [-help] [-nobdrs] [-out <file>]\n", call ); fprintf(stderr, " [-xy] [[host]:vs]\n"); exit(1); } /* * Error - Fatal xwd error. */ Error(string) char *string; /* Error description string. */ { fprintf(stderr, "\nxwd: Error => %s", string); if (errno != 0) { perror("xwd"); fprintf(stderr, "\n"); } exit(1); } /* End of xwd.c */