xwd.c revision afe13c8e
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 94b3307321Smrgint format = ZPixmap; 95b3307321SmrgBool nobdrs = False; 96b3307321SmrgBool on_root = False; 97b3307321SmrgBool standard_out = True; 98b3307321SmrgBool debug = False; 99b3307321SmrgBool silent = False; 100b3307321SmrgBool use_installed = False; 101b3307321Smrglong 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 115b3307321Smrgstatic long parse_long (s) 116b3307321Smrg char *s; 117b3307321Smrg{ 118b3307321Smrg char *fmt = "%lu"; 119b3307321Smrg long retval = 0L; 120b3307321Smrg int thesign = 1; 121b3307321Smrg 122b3307321Smrg if (s && s[0]) { 123b3307321Smrg if (s[0] == '-') s++, thesign = -1; 124b3307321Smrg if (s[0] == '0') s++, fmt = "%lo"; 125b3307321Smrg if (s[0] == 'x' || s[0] == 'X') s++, fmt = "%lx"; 126b3307321Smrg (void) sscanf (s, fmt, &retval); 127b3307321Smrg } 128b3307321Smrg return (thesign * retval); 129b3307321Smrg} 130b3307321Smrg 131b3307321Smrgint 132b3307321Smrgmain(argc, argv) 133b3307321Smrg int argc; 134b3307321Smrg char **argv; 135b3307321Smrg{ 136b3307321Smrg register int i; 137b3307321Smrg Window target_win; 138b3307321Smrg FILE *out_file = stdout; 139b3307321Smrg Bool frame_only = False; 140b3307321Smrg 141b3307321Smrg INIT_NAME; 142b3307321Smrg 143b3307321Smrg Setup_Display_And_Screen(&argc, argv); 144b3307321Smrg 145b3307321Smrg /* Get window select on command line, if any */ 146b3307321Smrg target_win = Select_Window_Args(&argc, argv); 147b3307321Smrg 148b3307321Smrg for (i = 1; i < argc; i++) { 149b3307321Smrg if (!strcmp(argv[i], "-nobdrs")) { 150b3307321Smrg nobdrs = True; 151b3307321Smrg continue; 152b3307321Smrg } 153b3307321Smrg if (!strcmp(argv[i], "-debug")) { 154b3307321Smrg debug = True; 155b3307321Smrg continue; 156b3307321Smrg } 157b3307321Smrg if (!strcmp(argv[i], "-help")) 158b3307321Smrg usage(); 159b3307321Smrg if (!strcmp(argv[i], "-out")) { 160b3307321Smrg if (++i >= argc) usage(); 161b3307321Smrg if (!(out_file = fopen(argv[i], "wb"))) 162b3307321Smrg Fatal_Error("Can't open output file as specified."); 163b3307321Smrg standard_out = False; 164b3307321Smrg continue; 165b3307321Smrg } 166b3307321Smrg if (!strcmp(argv[i], "-xy")) { 167b3307321Smrg format = XYPixmap; 168b3307321Smrg continue; 169b3307321Smrg } 170b3307321Smrg if (!strcmp(argv[i], "-screen")) { 171b3307321Smrg on_root = True; 172b3307321Smrg continue; 173b3307321Smrg } 174b3307321Smrg if (!strcmp(argv[i], "-icmap")) { 175b3307321Smrg use_installed = True; 176b3307321Smrg continue; 177b3307321Smrg } 178b3307321Smrg if (!strcmp(argv[i], "-add")) { 179b3307321Smrg if (++i >= argc) usage(); 180b3307321Smrg add_pixel_value = parse_long (argv[i]); 181b3307321Smrg continue; 182b3307321Smrg } 183b3307321Smrg if (!strcmp(argv[i], "-frame")) { 184b3307321Smrg frame_only = True; 185b3307321Smrg continue; 186b3307321Smrg } 187b3307321Smrg if (!strcmp(argv[i], "-silent")) { 188b3307321Smrg silent = True; 189b3307321Smrg continue; 190b3307321Smrg } 191b3307321Smrg usage(); 192b3307321Smrg } 193b3307321Smrg#ifdef WIN32 194b3307321Smrg if (standard_out) 195b3307321Smrg _setmode(fileno(out_file), _O_BINARY); 196b3307321Smrg#endif 197b3307321Smrg 198b3307321Smrg /* 199b3307321Smrg * Let the user select the target window. 200b3307321Smrg */ 201afe13c8eSmrg if (target_win == None) 202afe13c8eSmrg target_win = Select_Window(dpy, !frame_only); 203b3307321Smrg 204b3307321Smrg /* 205b3307321Smrg * Dump it! 206b3307321Smrg */ 207b3307321Smrg Window_Dump(target_win, out_file); 208b3307321Smrg 209b3307321Smrg XCloseDisplay(dpy); 210b3307321Smrg if (fclose(out_file)) { 211b3307321Smrg perror("xwd"); 212b3307321Smrg exit(1); 213b3307321Smrg } 214b3307321Smrg exit(0); 215b3307321Smrg} 216b3307321Smrg 217b3307321Smrgstatic int 218b3307321SmrgGet24bitDirectColors(colors) 219b3307321SmrgXColor **colors ; 220b3307321Smrg{ 221b3307321Smrg int i , ncolors = 256 ; 222b3307321Smrg XColor *tcol ; 223b3307321Smrg 224b3307321Smrg *colors = tcol = (XColor *)malloc(sizeof(XColor) * ncolors) ; 225b3307321Smrg 226b3307321Smrg for(i=0 ; i < ncolors ; i++) 227b3307321Smrg { 228b3307321Smrg tcol[i].pixel = i << 16 | i << 8 | i ; 229b3307321Smrg tcol[i].red = tcol[i].green = tcol[i].blue = i << 8 | i ; 230b3307321Smrg } 231b3307321Smrg 232b3307321Smrg return ncolors ; 233b3307321Smrg} 234b3307321Smrg 235b3307321Smrg 236b3307321Smrg/* 237b3307321Smrg * Window_Dump: dump a window to a file which must already be open for 238b3307321Smrg * writting. 239b3307321Smrg */ 240b3307321Smrg 241b3307321Smrgvoid 242b3307321SmrgWindow_Dump(window, out) 243b3307321Smrg Window window; 244b3307321Smrg FILE *out; 245b3307321Smrg{ 246b3307321Smrg unsigned long swaptest = 1; 247b3307321Smrg XColor *colors; 248b3307321Smrg unsigned buffer_size; 249b3307321Smrg int win_name_size; 250b3307321Smrg int header_size; 251b3307321Smrg int ncolors, i; 252b3307321Smrg char *win_name; 253b3307321Smrg Bool got_win_name; 254b3307321Smrg XWindowAttributes win_info; 255b3307321Smrg XImage *image; 256b3307321Smrg int absx, absy, x, y; 257b3307321Smrg unsigned width, height; 258b3307321Smrg int dwidth, dheight; 259b3307321Smrg int bw; 260b3307321Smrg Window dummywin; 261b3307321Smrg XWDFileHeader header; 262b3307321Smrg XWDColor xwdcolor; 263b3307321Smrg 264b3307321Smrg int transparentOverlays , multiVis; 265b3307321Smrg int numVisuals; 266b3307321Smrg XVisualInfo *pVisuals; 267b3307321Smrg int numOverlayVisuals; 268b3307321Smrg OverlayInfo *pOverlayVisuals; 269b3307321Smrg int numImageVisuals; 270b3307321Smrg XVisualInfo **pImageVisuals; 271b3307321Smrg list_ptr vis_regions; /* list of regions to read from */ 272b3307321Smrg list_ptr vis_image_regions ; 273b3307321Smrg Visual vis_h,*vis ; 274b3307321Smrg int allImage = 0 ; 275b3307321Smrg 276b3307321Smrg /* 277b3307321Smrg * Inform the user not to alter the screen. 278b3307321Smrg */ 279b3307321Smrg if (!silent) { 280b3307321Smrg#ifdef XKB 281b3307321Smrg XkbStdBell(dpy,None,50,XkbBI_Wait); 282b3307321Smrg#else 283b3307321Smrg XBell(dpy,FEEP_VOLUME); 284b3307321Smrg#endif 285b3307321Smrg XFlush(dpy); 286b3307321Smrg } 287b3307321Smrg 288b3307321Smrg /* 289b3307321Smrg * Get the parameters of the window being dumped. 290b3307321Smrg */ 291b3307321Smrg if (debug) outl("xwd: Getting target window information.\n"); 292b3307321Smrg if(!XGetWindowAttributes(dpy, window, &win_info)) 293b3307321Smrg Fatal_Error("Can't get target window attributes."); 294b3307321Smrg 295b3307321Smrg /* handle any frame window */ 296b3307321Smrg if (!XTranslateCoordinates (dpy, window, RootWindow (dpy, screen), 0, 0, 297b3307321Smrg &absx, &absy, &dummywin)) { 298b3307321Smrg fprintf (stderr, 299b3307321Smrg "%s: unable to translate window coordinates (%d,%d)\n", 300b3307321Smrg program_name, absx, absy); 301b3307321Smrg exit (1); 302b3307321Smrg } 303b3307321Smrg win_info.x = absx; 304b3307321Smrg win_info.y = absy; 305b3307321Smrg width = win_info.width; 306b3307321Smrg height = win_info.height; 307b3307321Smrg bw = 0; 308b3307321Smrg 309b3307321Smrg if (!nobdrs) { 310b3307321Smrg absx -= win_info.border_width; 311b3307321Smrg absy -= win_info.border_width; 312b3307321Smrg bw = win_info.border_width; 313b3307321Smrg width += (2 * bw); 314b3307321Smrg height += (2 * bw); 315b3307321Smrg } 316b3307321Smrg dwidth = DisplayWidth (dpy, screen); 317b3307321Smrg dheight = DisplayHeight (dpy, screen); 318b3307321Smrg 319b3307321Smrg 320b3307321Smrg /* clip to window */ 321b3307321Smrg if (absx < 0) width += absx, absx = 0; 322b3307321Smrg if (absy < 0) height += absy, absy = 0; 323b3307321Smrg if (absx + width > dwidth) width = dwidth - absx; 324b3307321Smrg if (absy + height > dheight) height = dheight - absy; 325b3307321Smrg 326b3307321Smrg XFetchName(dpy, window, &win_name); 327b3307321Smrg if (!win_name || !win_name[0]) { 328b3307321Smrg win_name = "xwdump"; 329b3307321Smrg got_win_name = False; 330b3307321Smrg } else { 331b3307321Smrg got_win_name = True; 332b3307321Smrg } 333b3307321Smrg 334b3307321Smrg /* sizeof(char) is included for the null string terminator. */ 335b3307321Smrg win_name_size = strlen(win_name) + sizeof(char); 336b3307321Smrg 337b3307321Smrg /* 338b3307321Smrg * Snarf the pixmap with XGetImage. 339b3307321Smrg */ 340b3307321Smrg 341b3307321Smrg x = absx - win_info.x; 342b3307321Smrg y = absy - win_info.y; 343b3307321Smrg 344b3307321Smrg multiVis = GetMultiVisualRegions(dpy,RootWindow(dpy, screen), 345b3307321Smrg absx, absy, 346b3307321Smrg width, height,&transparentOverlays,&numVisuals, &pVisuals, 347b3307321Smrg &numOverlayVisuals,&pOverlayVisuals,&numImageVisuals, 348b3307321Smrg &pImageVisuals,&vis_regions,&vis_image_regions,&allImage) ; 349b3307321Smrg if (on_root || multiVis) 350b3307321Smrg { 351b3307321Smrg if(!multiVis) 352b3307321Smrg image = XGetImage (dpy, RootWindow(dpy, screen), absx, absy, 353b3307321Smrg width, height, AllPlanes, format); 354b3307321Smrg else 355b3307321Smrg image = ReadAreaToImage(dpy, RootWindow(dpy, screen), absx, absy, 356b3307321Smrg width, height, 357b3307321Smrg numVisuals,pVisuals,numOverlayVisuals,pOverlayVisuals, 358b3307321Smrg numImageVisuals, pImageVisuals,vis_regions, 359b3307321Smrg vis_image_regions,format,allImage); 360b3307321Smrg } 361b3307321Smrg else 362b3307321Smrg image = XGetImage (dpy, window, x, y, width, height, AllPlanes, format); 363b3307321Smrg if (!image) { 364b3307321Smrg fprintf (stderr, "%s: unable to get image at %dx%d+%d+%d\n", 365b3307321Smrg program_name, width, height, x, y); 366b3307321Smrg exit (1); 367b3307321Smrg } 368b3307321Smrg 369b3307321Smrg if (add_pixel_value != 0) XAddPixel (image, add_pixel_value); 370b3307321Smrg 371b3307321Smrg /* 372b3307321Smrg * Determine the pixmap size. 373b3307321Smrg */ 374b3307321Smrg buffer_size = Image_Size(image); 375b3307321Smrg 376b3307321Smrg if (debug) outl("xwd: Getting Colors.\n"); 377b3307321Smrg 378b3307321Smrg if( !multiVis) 379b3307321Smrg { 380b3307321Smrg ncolors = Get_XColors(&win_info, &colors); 381b3307321Smrg vis = win_info.visual ; 382b3307321Smrg } 383b3307321Smrg else 384b3307321Smrg { 385b3307321Smrg ncolors = Get24bitDirectColors(&colors) ; 386b3307321Smrg initFakeVisual(&vis_h) ; 387b3307321Smrg vis = &vis_h ; 388b3307321Smrg } 389b3307321Smrg /* 390b3307321Smrg * Inform the user that the image has been retrieved. 391b3307321Smrg */ 392b3307321Smrg if (!silent) { 393b3307321Smrg#ifdef XKB 394b3307321Smrg XkbStdBell(dpy,window,FEEP_VOLUME,XkbBI_Proceed); 395b3307321Smrg XkbStdBell(dpy,window,FEEP_VOLUME,XkbBI_RepeatingLastBell); 396b3307321Smrg#else 397b3307321Smrg XBell(dpy, FEEP_VOLUME); 398b3307321Smrg XBell(dpy, FEEP_VOLUME); 399b3307321Smrg#endif 400b3307321Smrg XFlush(dpy); 401b3307321Smrg } 402b3307321Smrg 403b3307321Smrg /* 404b3307321Smrg * Calculate header size. 405b3307321Smrg */ 406b3307321Smrg if (debug) outl("xwd: Calculating header size.\n"); 407b3307321Smrg header_size = SIZEOF(XWDheader) + win_name_size; 408b3307321Smrg 409b3307321Smrg /* 410b3307321Smrg * Write out header information. 411b3307321Smrg */ 412b3307321Smrg if (debug) outl("xwd: Constructing and dumping file header.\n"); 413b3307321Smrg header.header_size = (CARD32) header_size; 414b3307321Smrg header.file_version = (CARD32) XWD_FILE_VERSION; 415b3307321Smrg header.pixmap_format = (CARD32) format; 416b3307321Smrg header.pixmap_depth = (CARD32) image->depth; 417b3307321Smrg header.pixmap_width = (CARD32) image->width; 418b3307321Smrg header.pixmap_height = (CARD32) image->height; 419b3307321Smrg header.xoffset = (CARD32) image->xoffset; 420b3307321Smrg header.byte_order = (CARD32) image->byte_order; 421b3307321Smrg header.bitmap_unit = (CARD32) image->bitmap_unit; 422b3307321Smrg header.bitmap_bit_order = (CARD32) image->bitmap_bit_order; 423b3307321Smrg header.bitmap_pad = (CARD32) image->bitmap_pad; 424b3307321Smrg header.bits_per_pixel = (CARD32) image->bits_per_pixel; 425b3307321Smrg header.bytes_per_line = (CARD32) image->bytes_per_line; 426b3307321Smrg /**** 427b3307321Smrg header.visual_class = (CARD32) win_info.visual->class; 428b3307321Smrg header.red_mask = (CARD32) win_info.visual->red_mask; 429b3307321Smrg header.green_mask = (CARD32) win_info.visual->green_mask; 430b3307321Smrg header.blue_mask = (CARD32) win_info.visual->blue_mask; 431b3307321Smrg header.bits_per_rgb = (CARD32) win_info.visual->bits_per_rgb; 432b3307321Smrg header.colormap_entries = (CARD32) win_info.visual->map_entries; 433b3307321Smrg *****/ 434b3307321Smrg header.visual_class = (CARD32) vis->class; 435b3307321Smrg header.red_mask = (CARD32) vis->red_mask; 436b3307321Smrg header.green_mask = (CARD32) vis->green_mask; 437b3307321Smrg header.blue_mask = (CARD32) vis->blue_mask; 438b3307321Smrg header.bits_per_rgb = (CARD32) vis->bits_per_rgb; 439b3307321Smrg header.colormap_entries = (CARD32) vis->map_entries; 440b3307321Smrg 441b3307321Smrg header.ncolors = ncolors; 442b3307321Smrg header.window_width = (CARD32) win_info.width; 443b3307321Smrg header.window_height = (CARD32) win_info.height; 444b3307321Smrg header.window_x = absx; 445b3307321Smrg header.window_y = absy; 446b3307321Smrg header.window_bdrwidth = (CARD32) win_info.border_width; 447b3307321Smrg 448b3307321Smrg if (*(char *) &swaptest) { 449b3307321Smrg _swaplong((char *) &header, sizeof(header)); 450b3307321Smrg for (i = 0; i < ncolors; i++) { 451b3307321Smrg _swaplong((char *) &colors[i].pixel, sizeof(CARD32)); 452b3307321Smrg _swapshort((char *) &colors[i].red, 3 * sizeof(short)); 453b3307321Smrg } 454b3307321Smrg } 455b3307321Smrg 456b3307321Smrg if (fwrite((char *)&header, SIZEOF(XWDheader), 1, out) != 1 || 457b3307321Smrg fwrite(win_name, win_name_size, 1, out) != 1) { 458b3307321Smrg perror("xwd"); 459b3307321Smrg exit(1); 460b3307321Smrg } 461b3307321Smrg 462b3307321Smrg /* 463b3307321Smrg * Write out the color maps, if any 464b3307321Smrg */ 465b3307321Smrg 466b3307321Smrg if (debug) outl("xwd: Dumping %d colors.\n", ncolors); 467b3307321Smrg for (i = 0; i < ncolors; i++) { 468b3307321Smrg xwdcolor.pixel = colors[i].pixel; 469b3307321Smrg xwdcolor.red = colors[i].red; 470b3307321Smrg xwdcolor.green = colors[i].green; 471b3307321Smrg xwdcolor.blue = colors[i].blue; 472b3307321Smrg xwdcolor.flags = colors[i].flags; 473b3307321Smrg if (fwrite((char *) &xwdcolor, SIZEOF(XWDColor), 1, out) != 1) { 474b3307321Smrg perror("xwd"); 475b3307321Smrg exit(1); 476b3307321Smrg } 477b3307321Smrg } 478b3307321Smrg 479b3307321Smrg /* 480b3307321Smrg * Write out the buffer. 481b3307321Smrg */ 482b3307321Smrg if (debug) outl("xwd: Dumping pixmap. bufsize=%d\n",buffer_size); 483b3307321Smrg 484b3307321Smrg /* 485b3307321Smrg * This copying of the bit stream (data) to a file is to be replaced 486b3307321Smrg * by an Xlib call which hasn't been written yet. It is not clear 487b3307321Smrg * what other functions of xwd will be taken over by this (as yet) 488b3307321Smrg * non-existant X function. 489b3307321Smrg */ 490b3307321Smrg if (fwrite(image->data, (int) buffer_size, 1, out) != 1) { 491b3307321Smrg perror("xwd"); 492b3307321Smrg exit(1); 493b3307321Smrg } 494b3307321Smrg 495b3307321Smrg /* 496b3307321Smrg * free the color buffer. 497b3307321Smrg */ 498b3307321Smrg 499b3307321Smrg if(debug && ncolors > 0) outl("xwd: Freeing colors.\n"); 500b3307321Smrg if(ncolors > 0) free(colors); 501b3307321Smrg 502b3307321Smrg /* 503b3307321Smrg * Free window name string. 504b3307321Smrg */ 505b3307321Smrg if (debug) outl("xwd: Freeing window name string.\n"); 506b3307321Smrg if (got_win_name) XFree(win_name); 507b3307321Smrg 508b3307321Smrg /* 509b3307321Smrg * Free image 510b3307321Smrg */ 511b3307321Smrg XDestroyImage(image); 512b3307321Smrg} 513b3307321Smrg 514b3307321Smrg/* 515b3307321Smrg * Report the syntax for calling xwd. 516b3307321Smrg */ 517b3307321Smrgvoid 518b3307321Smrgusage() 519b3307321Smrg{ 520b3307321Smrg fprintf (stderr, 521b3307321Smrg"usage: %s [-display host:dpy] [-debug] [-help] %s [-nobdrs] [-out <file>]", 522b3307321Smrg program_name, "[{-root|-id <id>|-name <name>}]"); 523b3307321Smrg fprintf (stderr, " [-xy] [-add value] [-frame]\n"); 524b3307321Smrg exit(1); 525b3307321Smrg} 526b3307321Smrg 527b3307321Smrg 528b3307321Smrg/* 529b3307321Smrg * Determine the pixmap size. 530b3307321Smrg */ 531b3307321Smrg 532b3307321Smrgint Image_Size(image) 533b3307321Smrg XImage *image; 534b3307321Smrg{ 535b3307321Smrg if (image->format != ZPixmap) 536b3307321Smrg return(image->bytes_per_line * image->height * image->depth); 537b3307321Smrg 538b3307321Smrg return(image->bytes_per_line * image->height); 539b3307321Smrg} 540b3307321Smrg 541b3307321Smrg#define lowbit(x) ((x) & (~(x) + 1)) 542b3307321Smrg 543b3307321Smrgstatic int 544b3307321SmrgReadColors(vis,cmap,colors) 545b3307321SmrgVisual *vis ; 546b3307321SmrgColormap cmap ; 547b3307321SmrgXColor **colors ; 548b3307321Smrg{ 549b3307321Smrg int i,ncolors ; 550b3307321Smrg 551b3307321Smrg ncolors = vis->map_entries; 552b3307321Smrg 553b3307321Smrg if (!(*colors = (XColor *) malloc (sizeof(XColor) * ncolors))) 554b3307321Smrg Fatal_Error("Out of memory!"); 555b3307321Smrg 556b3307321Smrg if (vis->class == DirectColor || 557b3307321Smrg vis->class == TrueColor) { 558b3307321Smrg Pixel red, green, blue, red1, green1, blue1; 559b3307321Smrg 560b3307321Smrg red = green = blue = 0; 561b3307321Smrg red1 = lowbit(vis->red_mask); 562b3307321Smrg green1 = lowbit(vis->green_mask); 563b3307321Smrg blue1 = lowbit(vis->blue_mask); 564b3307321Smrg for (i=0; i<ncolors; i++) { 565b3307321Smrg (*colors)[i].pixel = red|green|blue; 566b3307321Smrg (*colors)[i].pad = 0; 567b3307321Smrg red += red1; 568b3307321Smrg if (red > vis->red_mask) 569b3307321Smrg red = 0; 570b3307321Smrg green += green1; 571b3307321Smrg if (green > vis->green_mask) 572b3307321Smrg green = 0; 573b3307321Smrg blue += blue1; 574b3307321Smrg if (blue > vis->blue_mask) 575b3307321Smrg blue = 0; 576b3307321Smrg } 577b3307321Smrg } else { 578b3307321Smrg for (i=0; i<ncolors; i++) { 579b3307321Smrg (*colors)[i].pixel = i; 580b3307321Smrg (*colors)[i].pad = 0; 581b3307321Smrg } 582b3307321Smrg } 583b3307321Smrg 584b3307321Smrg XQueryColors(dpy, cmap, *colors, ncolors); 585b3307321Smrg 586b3307321Smrg return(ncolors); 587b3307321Smrg} 588b3307321Smrg 589b3307321Smrg/* 590b3307321Smrg * Get the XColors of all pixels in image - returns # of colors 591b3307321Smrg */ 592b3307321Smrgint Get_XColors(win_info, colors) 593b3307321Smrg XWindowAttributes *win_info; 594b3307321Smrg XColor **colors; 595b3307321Smrg{ 596b3307321Smrg int i, ncolors; 597b3307321Smrg Colormap cmap = win_info->colormap; 598b3307321Smrg 599b3307321Smrg if (use_installed) 600b3307321Smrg /* assume the visual will be OK ... */ 601b3307321Smrg cmap = XListInstalledColormaps(dpy, win_info->root, &i)[0]; 602b3307321Smrg if (!cmap) 603b3307321Smrg return(0); 604b3307321Smrg ncolors = ReadColors(win_info->visual,cmap,colors) ; 605b3307321Smrg return ncolors ; 606b3307321Smrg} 607b3307321Smrg 608b3307321Smrgvoid 609b3307321Smrg_swapshort (bp, n) 610b3307321Smrg register char *bp; 611b3307321Smrg register unsigned n; 612b3307321Smrg{ 613b3307321Smrg register char c; 614b3307321Smrg register char *ep = bp + n; 615b3307321Smrg 616b3307321Smrg while (bp < ep) { 617b3307321Smrg c = *bp; 618b3307321Smrg *bp = *(bp + 1); 619b3307321Smrg bp++; 620b3307321Smrg *bp++ = c; 621b3307321Smrg } 622b3307321Smrg} 623b3307321Smrg 624b3307321Smrgvoid 625b3307321Smrg_swaplong (bp, n) 626b3307321Smrg register char *bp; 627b3307321Smrg register unsigned n; 628b3307321Smrg{ 629b3307321Smrg register char c; 630b3307321Smrg register char *ep = bp + n; 631b3307321Smrg 632b3307321Smrg while (bp < ep) { 633b3307321Smrg c = bp[3]; 634b3307321Smrg bp[3] = bp[0]; 635b3307321Smrg bp[0] = c; 636b3307321Smrg c = bp[2]; 637b3307321Smrg bp[2] = bp[1]; 638b3307321Smrg bp[1] = c; 639b3307321Smrg bp += 4; 640b3307321Smrg } 641b3307321Smrg} 642