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