xwd.c revision 5e358eca
1b3307321Smrg/* $Xorg: xwd.c,v 1.5 2001/02/09 02:06:03 xorgcvs Exp $ */ 2b3307321Smrg 3b3307321Smrg/* 4b3307321Smrg 5b3307321SmrgCopyright 1987, 1998 The Open Group 6b3307321Smrg 7b3307321SmrgPermission to use, copy, modify, distribute, and sell this software and its 8b3307321Smrgdocumentation for any purpose is hereby granted without fee, provided that 9b3307321Smrgthe above copyright notice appear in all copies and that both that 10b3307321Smrgcopyright notice and this permission notice appear in supporting 11b3307321Smrgdocumentation. 12b3307321Smrg 13b3307321SmrgThe above copyright notice and this permission notice shall be included in 14b3307321Smrgall copies or substantial portions of the Software. 15b3307321Smrg 16b3307321SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17b3307321SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18b3307321SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19b3307321SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 20b3307321SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21b3307321SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22b3307321Smrg 23b3307321SmrgExcept as contained in this notice, the name of The Open Group shall not be 24b3307321Smrgused in advertising or otherwise to promote the sale, use or other dealings 25b3307321Smrgin this Software without prior written authorization from The Open Group. 26b3307321Smrg 27b3307321Smrg*/ 28b3307321Smrg/* $XFree86: xc/programs/xwd/xwd.c,v 3.11 2002/09/16 18:06:21 eich Exp $ */ 29b3307321Smrg 30b3307321Smrg/* 31b3307321Smrg * xwd.c MIT Project Athena, X Window system window raster image dumper. 32b3307321Smrg * 33b3307321Smrg * This program will dump a raster image of the contents of a window into a 34b3307321Smrg * file for output on graphics printers or for other uses. 35b3307321Smrg * 36b3307321Smrg * Author: Tony Della Fera, DEC 37b3307321Smrg * 17-Jun-85 38b3307321Smrg * 39b3307321Smrg * Modification history: 40b3307321Smrg * 41b3307321Smrg * 11/14/86 Bill Wyatt, Smithsonian Astrophysical Observatory 42b3307321Smrg * - Removed Z format option, changing it to an XY option. Monochrome 43b3307321Smrg * windows will always dump in XY format. Color windows will dump 44b3307321Smrg * in Z format by default, but can be dumped in XY format with the 45b3307321Smrg * -xy option. 46b3307321Smrg * 47b3307321Smrg * 11/18/86 Bill Wyatt 48b3307321Smrg * - VERSION 6 is same as version 5 for monchrome. For colors, the 49b3307321Smrg * appropriate number of Color structs are dumped after the header, 50b3307321Smrg * which has the number of colors (=0 for monochrome) in place of the 51b3307321Smrg * V5 padding at the end. Up to 16-bit displays are supported. I 52b3307321Smrg * don't yet know how 24- to 32-bit displays will be handled under 53b3307321Smrg * the Version 11 protocol. 54b3307321Smrg * 55b3307321Smrg * 6/15/87 David Krikorian, MIT Project Athena 56b3307321Smrg * - VERSION 7 runs under the X Version 11 servers, while the previous 57b3307321Smrg * versions of xwd were are for X Version 10. This version is based 58b3307321Smrg * on xwd version 6, and should eventually have the same color 59b3307321Smrg * abilities. (Xwd V7 has yet to be tested on a color machine, so 60b3307321Smrg * all color-related code is commented out until color support 61b3307321Smrg * becomes practical.) 62b3307321Smrg */ 63b3307321Smrg 64b3307321Smrg/*% 65b3307321Smrg *% This is the format for commenting out color-related code until 66b3307321Smrg *% color can be supported. 67b3307321Smrg%*/ 68b3307321Smrg 69b3307321Smrg#include <stdio.h> 70b3307321Smrg#include <errno.h> 71b3307321Smrg#include <X11/Xos.h> 72b3307321Smrg#include <stdlib.h> 73b3307321Smrg 74b3307321Smrg#include <X11/Xlib.h> 75b3307321Smrg#include <X11/Xutil.h> 76b3307321Smrg 77b3307321Smrgtypedef unsigned long Pixel; 78b3307321Smrg#include "X11/XWDFile.h" 79b3307321Smrg 80b3307321Smrg#define FEEP_VOLUME 0 81b3307321Smrg 82b3307321Smrg/* Include routines to do parsing */ 83b3307321Smrg#include "dsimple.h" 84b3307321Smrg#include "list.h" 85b3307321Smrg#include "wsutils.h" 86b3307321Smrg#include "multiVis.h" 87b3307321Smrg 88b3307321Smrg#ifdef XKB 89b3307321Smrg#include <X11/extensions/XKBbells.h> 90b3307321Smrg#endif 91b3307321Smrg 92b3307321Smrg/* Setable Options */ 93b3307321Smrg 945e358ecaSmrgstatic int format = ZPixmap; 955e358ecaSmrgstatic Bool nobdrs = False; 965e358ecaSmrgstatic Bool on_root = False; 975e358ecaSmrgstatic Bool standard_out = True; 985e358ecaSmrgstatic Bool debug = False; 995e358ecaSmrgstatic Bool silent = False; 1005e358ecaSmrgstatic Bool use_installed = False; 1015e358ecaSmrgstatic long add_pixel_value = 0; 102b3307321Smrg 103b3307321Smrg 104b3307321Smrgextern int main(int, char **); 105b3307321Smrgextern void Window_Dump(Window, FILE *); 106b3307321Smrgextern int Image_Size(XImage *); 107b3307321Smrgextern int Get_XColors(XWindowAttributes *, XColor **); 108b3307321Smrgextern void _swapshort(register char *, register unsigned); 109b3307321Smrgextern void _swaplong(register char *, register unsigned); 110b3307321Smrgstatic long parse_long(char *); 111b3307321Smrgstatic int Get24bitDirectColors(XColor **); 112b3307321Smrgstatic int ReadColors(Visual *, Colormap, XColor **); 113b3307321Smrg 114b3307321Smrg 1155e358ecaSmrgstatic long parse_long (char *s) 116b3307321Smrg{ 117b3307321Smrg char *fmt = "%lu"; 118b3307321Smrg long retval = 0L; 119b3307321Smrg int thesign = 1; 120b3307321Smrg 121b3307321Smrg if (s && s[0]) { 122b3307321Smrg if (s[0] == '-') s++, thesign = -1; 123b3307321Smrg if (s[0] == '0') s++, fmt = "%lo"; 124b3307321Smrg if (s[0] == 'x' || s[0] == 'X') s++, fmt = "%lx"; 125b3307321Smrg (void) sscanf (s, fmt, &retval); 126b3307321Smrg } 127b3307321Smrg return (thesign * retval); 128b3307321Smrg} 129b3307321Smrg 130b3307321Smrgint 1315e358ecaSmrgmain(int argc, char **argv) 132b3307321Smrg{ 133b3307321Smrg register int i; 134b3307321Smrg Window target_win; 135b3307321Smrg FILE *out_file = stdout; 136b3307321Smrg Bool frame_only = False; 137b3307321Smrg 138b3307321Smrg INIT_NAME; 139b3307321Smrg 140b3307321Smrg Setup_Display_And_Screen(&argc, argv); 141b3307321Smrg 142b3307321Smrg /* Get window select on command line, if any */ 143b3307321Smrg target_win = Select_Window_Args(&argc, argv); 144b3307321Smrg 145b3307321Smrg for (i = 1; i < argc; i++) { 146b3307321Smrg if (!strcmp(argv[i], "-nobdrs")) { 147b3307321Smrg nobdrs = True; 148b3307321Smrg continue; 149b3307321Smrg } 150b3307321Smrg if (!strcmp(argv[i], "-debug")) { 151b3307321Smrg debug = True; 152b3307321Smrg continue; 153b3307321Smrg } 154b3307321Smrg if (!strcmp(argv[i], "-help")) 155b3307321Smrg usage(); 156b3307321Smrg if (!strcmp(argv[i], "-out")) { 157b3307321Smrg if (++i >= argc) usage(); 158b3307321Smrg if (!(out_file = fopen(argv[i], "wb"))) 159b3307321Smrg Fatal_Error("Can't open output file as specified."); 160b3307321Smrg standard_out = False; 161b3307321Smrg continue; 162b3307321Smrg } 163b3307321Smrg if (!strcmp(argv[i], "-xy")) { 164b3307321Smrg format = XYPixmap; 165b3307321Smrg continue; 166b3307321Smrg } 167b3307321Smrg if (!strcmp(argv[i], "-screen")) { 168b3307321Smrg on_root = True; 169b3307321Smrg continue; 170b3307321Smrg } 171b3307321Smrg if (!strcmp(argv[i], "-icmap")) { 172b3307321Smrg use_installed = True; 173b3307321Smrg continue; 174b3307321Smrg } 175b3307321Smrg if (!strcmp(argv[i], "-add")) { 176b3307321Smrg if (++i >= argc) usage(); 177b3307321Smrg add_pixel_value = parse_long (argv[i]); 178b3307321Smrg continue; 179b3307321Smrg } 180b3307321Smrg if (!strcmp(argv[i], "-frame")) { 181b3307321Smrg frame_only = True; 182b3307321Smrg continue; 183b3307321Smrg } 184b3307321Smrg if (!strcmp(argv[i], "-silent")) { 185b3307321Smrg silent = True; 186b3307321Smrg continue; 187b3307321Smrg } 188b3307321Smrg usage(); 189b3307321Smrg } 190b3307321Smrg#ifdef WIN32 191b3307321Smrg if (standard_out) 192b3307321Smrg _setmode(fileno(out_file), _O_BINARY); 193b3307321Smrg#endif 194b3307321Smrg 195b3307321Smrg /* 196b3307321Smrg * Let the user select the target window. 197b3307321Smrg */ 198afe13c8eSmrg if (target_win == None) 199afe13c8eSmrg target_win = Select_Window(dpy, !frame_only); 200b3307321Smrg 201b3307321Smrg /* 202b3307321Smrg * Dump it! 203b3307321Smrg */ 204b3307321Smrg Window_Dump(target_win, out_file); 205b3307321Smrg 206b3307321Smrg XCloseDisplay(dpy); 207b3307321Smrg if (fclose(out_file)) { 208b3307321Smrg perror("xwd"); 209b3307321Smrg exit(1); 210b3307321Smrg } 211b3307321Smrg exit(0); 212b3307321Smrg} 213b3307321Smrg 214b3307321Smrgstatic int 2155e358ecaSmrgGet24bitDirectColors(XColor **colors) 216b3307321Smrg{ 217b3307321Smrg int i , ncolors = 256 ; 218b3307321Smrg XColor *tcol ; 219b3307321Smrg 220b3307321Smrg *colors = tcol = (XColor *)malloc(sizeof(XColor) * ncolors) ; 221b3307321Smrg 222b3307321Smrg for(i=0 ; i < ncolors ; i++) 223b3307321Smrg { 224b3307321Smrg tcol[i].pixel = i << 16 | i << 8 | i ; 225b3307321Smrg tcol[i].red = tcol[i].green = tcol[i].blue = i << 8 | i ; 226b3307321Smrg } 227b3307321Smrg 228b3307321Smrg return ncolors ; 229b3307321Smrg} 230b3307321Smrg 231b3307321Smrg 232b3307321Smrg/* 233b3307321Smrg * Window_Dump: dump a window to a file which must already be open for 234b3307321Smrg * writting. 235b3307321Smrg */ 236b3307321Smrg 237b3307321Smrgvoid 2385e358ecaSmrgWindow_Dump(Window window, FILE *out) 239b3307321Smrg{ 240b3307321Smrg unsigned long swaptest = 1; 241b3307321Smrg XColor *colors; 242b3307321Smrg unsigned buffer_size; 243b3307321Smrg int win_name_size; 244b3307321Smrg int header_size; 245b3307321Smrg int ncolors, i; 246b3307321Smrg char *win_name; 247b3307321Smrg Bool got_win_name; 248b3307321Smrg XWindowAttributes win_info; 249b3307321Smrg XImage *image; 250b3307321Smrg int absx, absy, x, y; 251b3307321Smrg unsigned width, height; 252b3307321Smrg int dwidth, dheight; 253b3307321Smrg int bw; 254b3307321Smrg Window dummywin; 255b3307321Smrg XWDFileHeader header; 256b3307321Smrg XWDColor xwdcolor; 257b3307321Smrg 258b3307321Smrg int transparentOverlays , multiVis; 259b3307321Smrg int numVisuals; 260b3307321Smrg XVisualInfo *pVisuals; 261b3307321Smrg int numOverlayVisuals; 262b3307321Smrg OverlayInfo *pOverlayVisuals; 263b3307321Smrg int numImageVisuals; 264b3307321Smrg XVisualInfo **pImageVisuals; 265b3307321Smrg list_ptr vis_regions; /* list of regions to read from */ 266b3307321Smrg list_ptr vis_image_regions ; 267b3307321Smrg Visual vis_h,*vis ; 268b3307321Smrg int allImage = 0 ; 269b3307321Smrg 270b3307321Smrg /* 271b3307321Smrg * Inform the user not to alter the screen. 272b3307321Smrg */ 273b3307321Smrg if (!silent) { 274b3307321Smrg#ifdef XKB 275b3307321Smrg XkbStdBell(dpy,None,50,XkbBI_Wait); 276b3307321Smrg#else 277b3307321Smrg XBell(dpy,FEEP_VOLUME); 278b3307321Smrg#endif 279b3307321Smrg XFlush(dpy); 280b3307321Smrg } 281b3307321Smrg 282b3307321Smrg /* 283b3307321Smrg * Get the parameters of the window being dumped. 284b3307321Smrg */ 285b3307321Smrg if (debug) outl("xwd: Getting target window information.\n"); 286b3307321Smrg if(!XGetWindowAttributes(dpy, window, &win_info)) 287b3307321Smrg Fatal_Error("Can't get target window attributes."); 288b3307321Smrg 289b3307321Smrg /* handle any frame window */ 290b3307321Smrg if (!XTranslateCoordinates (dpy, window, RootWindow (dpy, screen), 0, 0, 291b3307321Smrg &absx, &absy, &dummywin)) { 292b3307321Smrg fprintf (stderr, 293b3307321Smrg "%s: unable to translate window coordinates (%d,%d)\n", 294b3307321Smrg program_name, absx, absy); 295b3307321Smrg exit (1); 296b3307321Smrg } 297b3307321Smrg win_info.x = absx; 298b3307321Smrg win_info.y = absy; 299b3307321Smrg width = win_info.width; 300b3307321Smrg height = win_info.height; 301b3307321Smrg bw = 0; 302b3307321Smrg 303b3307321Smrg if (!nobdrs) { 304b3307321Smrg absx -= win_info.border_width; 305b3307321Smrg absy -= win_info.border_width; 306b3307321Smrg bw = win_info.border_width; 307b3307321Smrg width += (2 * bw); 308b3307321Smrg height += (2 * bw); 309b3307321Smrg } 310b3307321Smrg dwidth = DisplayWidth (dpy, screen); 311b3307321Smrg dheight = DisplayHeight (dpy, screen); 312b3307321Smrg 313b3307321Smrg 314b3307321Smrg /* clip to window */ 315b3307321Smrg if (absx < 0) width += absx, absx = 0; 316b3307321Smrg if (absy < 0) height += absy, absy = 0; 317b3307321Smrg if (absx + width > dwidth) width = dwidth - absx; 318b3307321Smrg if (absy + height > dheight) height = dheight - absy; 319b3307321Smrg 320b3307321Smrg XFetchName(dpy, window, &win_name); 321b3307321Smrg if (!win_name || !win_name[0]) { 322b3307321Smrg win_name = "xwdump"; 323b3307321Smrg got_win_name = False; 324b3307321Smrg } else { 325b3307321Smrg got_win_name = True; 326b3307321Smrg } 327b3307321Smrg 328b3307321Smrg /* sizeof(char) is included for the null string terminator. */ 329b3307321Smrg win_name_size = strlen(win_name) + sizeof(char); 330b3307321Smrg 331b3307321Smrg /* 332b3307321Smrg * Snarf the pixmap with XGetImage. 333b3307321Smrg */ 334b3307321Smrg 335b3307321Smrg x = absx - win_info.x; 336b3307321Smrg y = absy - win_info.y; 337b3307321Smrg 338b3307321Smrg multiVis = GetMultiVisualRegions(dpy,RootWindow(dpy, screen), 339b3307321Smrg absx, absy, 340b3307321Smrg width, height,&transparentOverlays,&numVisuals, &pVisuals, 341b3307321Smrg &numOverlayVisuals,&pOverlayVisuals,&numImageVisuals, 342b3307321Smrg &pImageVisuals,&vis_regions,&vis_image_regions,&allImage) ; 343b3307321Smrg if (on_root || multiVis) 344b3307321Smrg { 345b3307321Smrg if(!multiVis) 346b3307321Smrg image = XGetImage (dpy, RootWindow(dpy, screen), absx, absy, 347b3307321Smrg width, height, AllPlanes, format); 348b3307321Smrg else 349b3307321Smrg image = ReadAreaToImage(dpy, RootWindow(dpy, screen), absx, absy, 350b3307321Smrg width, height, 351b3307321Smrg numVisuals,pVisuals,numOverlayVisuals,pOverlayVisuals, 352b3307321Smrg numImageVisuals, pImageVisuals,vis_regions, 353b3307321Smrg vis_image_regions,format,allImage); 354b3307321Smrg } 355b3307321Smrg else 356b3307321Smrg image = XGetImage (dpy, window, x, y, width, height, AllPlanes, format); 357b3307321Smrg if (!image) { 358b3307321Smrg fprintf (stderr, "%s: unable to get image at %dx%d+%d+%d\n", 359b3307321Smrg program_name, width, height, x, y); 360b3307321Smrg exit (1); 361b3307321Smrg } 362b3307321Smrg 363b3307321Smrg if (add_pixel_value != 0) XAddPixel (image, add_pixel_value); 364b3307321Smrg 365b3307321Smrg /* 366b3307321Smrg * Determine the pixmap size. 367b3307321Smrg */ 368b3307321Smrg buffer_size = Image_Size(image); 369b3307321Smrg 370b3307321Smrg if (debug) outl("xwd: Getting Colors.\n"); 371b3307321Smrg 372b3307321Smrg if( !multiVis) 373b3307321Smrg { 374b3307321Smrg ncolors = Get_XColors(&win_info, &colors); 375b3307321Smrg vis = win_info.visual ; 376b3307321Smrg } 377b3307321Smrg else 378b3307321Smrg { 379b3307321Smrg ncolors = Get24bitDirectColors(&colors) ; 380b3307321Smrg initFakeVisual(&vis_h) ; 381b3307321Smrg vis = &vis_h ; 382b3307321Smrg } 383b3307321Smrg /* 384b3307321Smrg * Inform the user that the image has been retrieved. 385b3307321Smrg */ 386b3307321Smrg if (!silent) { 387b3307321Smrg#ifdef XKB 388b3307321Smrg XkbStdBell(dpy,window,FEEP_VOLUME,XkbBI_Proceed); 389b3307321Smrg XkbStdBell(dpy,window,FEEP_VOLUME,XkbBI_RepeatingLastBell); 390b3307321Smrg#else 391b3307321Smrg XBell(dpy, FEEP_VOLUME); 392b3307321Smrg XBell(dpy, FEEP_VOLUME); 393b3307321Smrg#endif 394b3307321Smrg XFlush(dpy); 395b3307321Smrg } 396b3307321Smrg 397b3307321Smrg /* 398b3307321Smrg * Calculate header size. 399b3307321Smrg */ 400b3307321Smrg if (debug) outl("xwd: Calculating header size.\n"); 401b3307321Smrg header_size = SIZEOF(XWDheader) + win_name_size; 402b3307321Smrg 403b3307321Smrg /* 404b3307321Smrg * Write out header information. 405b3307321Smrg */ 406b3307321Smrg if (debug) outl("xwd: Constructing and dumping file header.\n"); 407b3307321Smrg header.header_size = (CARD32) header_size; 408b3307321Smrg header.file_version = (CARD32) XWD_FILE_VERSION; 409b3307321Smrg header.pixmap_format = (CARD32) format; 410b3307321Smrg header.pixmap_depth = (CARD32) image->depth; 411b3307321Smrg header.pixmap_width = (CARD32) image->width; 412b3307321Smrg header.pixmap_height = (CARD32) image->height; 413b3307321Smrg header.xoffset = (CARD32) image->xoffset; 414b3307321Smrg header.byte_order = (CARD32) image->byte_order; 415b3307321Smrg header.bitmap_unit = (CARD32) image->bitmap_unit; 416b3307321Smrg header.bitmap_bit_order = (CARD32) image->bitmap_bit_order; 417b3307321Smrg header.bitmap_pad = (CARD32) image->bitmap_pad; 418b3307321Smrg header.bits_per_pixel = (CARD32) image->bits_per_pixel; 419b3307321Smrg header.bytes_per_line = (CARD32) image->bytes_per_line; 420b3307321Smrg /**** 421b3307321Smrg header.visual_class = (CARD32) win_info.visual->class; 422b3307321Smrg header.red_mask = (CARD32) win_info.visual->red_mask; 423b3307321Smrg header.green_mask = (CARD32) win_info.visual->green_mask; 424b3307321Smrg header.blue_mask = (CARD32) win_info.visual->blue_mask; 425b3307321Smrg header.bits_per_rgb = (CARD32) win_info.visual->bits_per_rgb; 426b3307321Smrg header.colormap_entries = (CARD32) win_info.visual->map_entries; 427b3307321Smrg *****/ 428b3307321Smrg header.visual_class = (CARD32) vis->class; 429b3307321Smrg header.red_mask = (CARD32) vis->red_mask; 430b3307321Smrg header.green_mask = (CARD32) vis->green_mask; 431b3307321Smrg header.blue_mask = (CARD32) vis->blue_mask; 432b3307321Smrg header.bits_per_rgb = (CARD32) vis->bits_per_rgb; 433b3307321Smrg header.colormap_entries = (CARD32) vis->map_entries; 434b3307321Smrg 435b3307321Smrg header.ncolors = ncolors; 436b3307321Smrg header.window_width = (CARD32) win_info.width; 437b3307321Smrg header.window_height = (CARD32) win_info.height; 438b3307321Smrg header.window_x = absx; 439b3307321Smrg header.window_y = absy; 440b3307321Smrg header.window_bdrwidth = (CARD32) win_info.border_width; 441b3307321Smrg 442b3307321Smrg if (*(char *) &swaptest) { 443b3307321Smrg _swaplong((char *) &header, sizeof(header)); 444b3307321Smrg for (i = 0; i < ncolors; i++) { 445b3307321Smrg _swaplong((char *) &colors[i].pixel, sizeof(CARD32)); 446b3307321Smrg _swapshort((char *) &colors[i].red, 3 * sizeof(short)); 447b3307321Smrg } 448b3307321Smrg } 449b3307321Smrg 450b3307321Smrg if (fwrite((char *)&header, SIZEOF(XWDheader), 1, out) != 1 || 451b3307321Smrg fwrite(win_name, win_name_size, 1, out) != 1) { 452b3307321Smrg perror("xwd"); 453b3307321Smrg exit(1); 454b3307321Smrg } 455b3307321Smrg 456b3307321Smrg /* 457b3307321Smrg * Write out the color maps, if any 458b3307321Smrg */ 459b3307321Smrg 460b3307321Smrg if (debug) outl("xwd: Dumping %d colors.\n", ncolors); 461b3307321Smrg for (i = 0; i < ncolors; i++) { 462b3307321Smrg xwdcolor.pixel = colors[i].pixel; 463b3307321Smrg xwdcolor.red = colors[i].red; 464b3307321Smrg xwdcolor.green = colors[i].green; 465b3307321Smrg xwdcolor.blue = colors[i].blue; 466b3307321Smrg xwdcolor.flags = colors[i].flags; 467b3307321Smrg if (fwrite((char *) &xwdcolor, SIZEOF(XWDColor), 1, out) != 1) { 468b3307321Smrg perror("xwd"); 469b3307321Smrg exit(1); 470b3307321Smrg } 471b3307321Smrg } 472b3307321Smrg 473b3307321Smrg /* 474b3307321Smrg * Write out the buffer. 475b3307321Smrg */ 476b3307321Smrg if (debug) outl("xwd: Dumping pixmap. bufsize=%d\n",buffer_size); 477b3307321Smrg 478b3307321Smrg /* 479b3307321Smrg * This copying of the bit stream (data) to a file is to be replaced 480b3307321Smrg * by an Xlib call which hasn't been written yet. It is not clear 481b3307321Smrg * what other functions of xwd will be taken over by this (as yet) 482b3307321Smrg * non-existant X function. 483b3307321Smrg */ 484b3307321Smrg if (fwrite(image->data, (int) buffer_size, 1, out) != 1) { 485b3307321Smrg perror("xwd"); 486b3307321Smrg exit(1); 487b3307321Smrg } 488b3307321Smrg 489b3307321Smrg /* 490b3307321Smrg * free the color buffer. 491b3307321Smrg */ 492b3307321Smrg 493b3307321Smrg if(debug && ncolors > 0) outl("xwd: Freeing colors.\n"); 494b3307321Smrg if(ncolors > 0) free(colors); 495b3307321Smrg 496b3307321Smrg /* 497b3307321Smrg * Free window name string. 498b3307321Smrg */ 499b3307321Smrg if (debug) outl("xwd: Freeing window name string.\n"); 500b3307321Smrg if (got_win_name) XFree(win_name); 501b3307321Smrg 502b3307321Smrg /* 503b3307321Smrg * Free image 504b3307321Smrg */ 505b3307321Smrg XDestroyImage(image); 506b3307321Smrg} 507b3307321Smrg 508b3307321Smrg/* 509b3307321Smrg * Report the syntax for calling xwd. 510b3307321Smrg */ 511b3307321Smrgvoid 5125e358ecaSmrgusage(void) 513b3307321Smrg{ 514b3307321Smrg fprintf (stderr, 515b3307321Smrg"usage: %s [-display host:dpy] [-debug] [-help] %s [-nobdrs] [-out <file>]", 516b3307321Smrg program_name, "[{-root|-id <id>|-name <name>}]"); 517b3307321Smrg fprintf (stderr, " [-xy] [-add value] [-frame]\n"); 518b3307321Smrg exit(1); 519b3307321Smrg} 520b3307321Smrg 521b3307321Smrg 522b3307321Smrg/* 523b3307321Smrg * Determine the pixmap size. 524b3307321Smrg */ 525b3307321Smrg 5265e358ecaSmrgint Image_Size(XImage *image) 527b3307321Smrg{ 528b3307321Smrg if (image->format != ZPixmap) 529b3307321Smrg return(image->bytes_per_line * image->height * image->depth); 530b3307321Smrg 531b3307321Smrg return(image->bytes_per_line * image->height); 532b3307321Smrg} 533b3307321Smrg 534b3307321Smrg#define lowbit(x) ((x) & (~(x) + 1)) 535b3307321Smrg 536b3307321Smrgstatic int 5375e358ecaSmrgReadColors(Visual *vis, Colormap cmap, XColor **colors) 538b3307321Smrg{ 539b3307321Smrg int i,ncolors ; 540b3307321Smrg 541b3307321Smrg ncolors = vis->map_entries; 542b3307321Smrg 543b3307321Smrg if (!(*colors = (XColor *) malloc (sizeof(XColor) * ncolors))) 544b3307321Smrg Fatal_Error("Out of memory!"); 545b3307321Smrg 546b3307321Smrg if (vis->class == DirectColor || 547b3307321Smrg vis->class == TrueColor) { 548b3307321Smrg Pixel red, green, blue, red1, green1, blue1; 549b3307321Smrg 550b3307321Smrg red = green = blue = 0; 551b3307321Smrg red1 = lowbit(vis->red_mask); 552b3307321Smrg green1 = lowbit(vis->green_mask); 553b3307321Smrg blue1 = lowbit(vis->blue_mask); 554b3307321Smrg for (i=0; i<ncolors; i++) { 555b3307321Smrg (*colors)[i].pixel = red|green|blue; 556b3307321Smrg (*colors)[i].pad = 0; 557b3307321Smrg red += red1; 558b3307321Smrg if (red > vis->red_mask) 559b3307321Smrg red = 0; 560b3307321Smrg green += green1; 561b3307321Smrg if (green > vis->green_mask) 562b3307321Smrg green = 0; 563b3307321Smrg blue += blue1; 564b3307321Smrg if (blue > vis->blue_mask) 565b3307321Smrg blue = 0; 566b3307321Smrg } 567b3307321Smrg } else { 568b3307321Smrg for (i=0; i<ncolors; i++) { 569b3307321Smrg (*colors)[i].pixel = i; 570b3307321Smrg (*colors)[i].pad = 0; 571b3307321Smrg } 572b3307321Smrg } 573b3307321Smrg 574b3307321Smrg XQueryColors(dpy, cmap, *colors, ncolors); 575b3307321Smrg 576b3307321Smrg return(ncolors); 577b3307321Smrg} 578b3307321Smrg 579b3307321Smrg/* 580b3307321Smrg * Get the XColors of all pixels in image - returns # of colors 581b3307321Smrg */ 5825e358ecaSmrgint Get_XColors(XWindowAttributes *win_info, XColor **colors) 583b3307321Smrg{ 584b3307321Smrg int i, ncolors; 585b3307321Smrg Colormap cmap = win_info->colormap; 586b3307321Smrg 587b3307321Smrg if (use_installed) 588b3307321Smrg /* assume the visual will be OK ... */ 589b3307321Smrg cmap = XListInstalledColormaps(dpy, win_info->root, &i)[0]; 590b3307321Smrg if (!cmap) 591b3307321Smrg return(0); 592b3307321Smrg ncolors = ReadColors(win_info->visual,cmap,colors) ; 593b3307321Smrg return ncolors ; 594b3307321Smrg} 595b3307321Smrg 596b3307321Smrgvoid 5975e358ecaSmrg_swapshort (register char *bp, register unsigned n) 598b3307321Smrg{ 599b3307321Smrg register char c; 600b3307321Smrg register char *ep = bp + n; 601b3307321Smrg 602b3307321Smrg while (bp < ep) { 603b3307321Smrg c = *bp; 604b3307321Smrg *bp = *(bp + 1); 605b3307321Smrg bp++; 606b3307321Smrg *bp++ = c; 607b3307321Smrg } 608b3307321Smrg} 609b3307321Smrg 610b3307321Smrgvoid 6115e358ecaSmrg_swaplong (register char *bp, register unsigned n) 612b3307321Smrg{ 613b3307321Smrg register char c; 614b3307321Smrg register char *ep = bp + n; 615b3307321Smrg 616b3307321Smrg while (bp < ep) { 617b3307321Smrg c = bp[3]; 618b3307321Smrg bp[3] = bp[0]; 619b3307321Smrg bp[0] = c; 620b3307321Smrg c = bp[2]; 621b3307321Smrg bp[2] = bp[1]; 622b3307321Smrg bp[1] = c; 623b3307321Smrg bp += 4; 624b3307321Smrg } 625b3307321Smrg} 626