home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / mandel / xwd.c < prev   
Encoding:
C/C++ Source or Header  |  1995-05-03  |  9.3 KB  |  389 lines

  1. #include <X11/copyright.h>
  2.  
  3. /* Copyright 1987 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.  *  Modification history:
  15.  *
  16.  *  11/14/86 Bill Wyatt, Smithsonian Astrophysical Observatory
  17.  *    - Removed Z format option, changing it to an XY option. Monochrome 
  18.  *      windows will always dump in XY format. Color windows will dump
  19.  *      in Z format by default, but can be dumped in XY format with the
  20.  *      -xy option.
  21.  *
  22.  *  11/18/86 Bill Wyatt
  23.  *    - VERSION 6 is same as version 5 for monchrome. For colors, the 
  24.  *      appropriate number of Color structs are dumped after the header,
  25.  *      which has the number of colors (=0 for monochrome) in place of the
  26.  *      V5 padding at the end. Up to 16-bit displays are supported. I
  27.  *      don't yet know how 24- to 32-bit displays will be handled under
  28.  *      the Version 11 protocol.
  29.  *
  30.  *  6/15/87 David Krikorian, MIT Project Athena
  31.  *    - VERSION 7 runs under the X Version 11 servers, while the previous
  32.  *      versions of xwd were are for X Version 10.  This version is based
  33.  *      on xwd version 6, and should eventually have the same color
  34.  *      abilities. (Xwd V7 has yet to be tested on a color machine, so
  35.  *      all color-related code is commented out until color support
  36.  *      becomes practical.)
  37.  */
  38.  
  39. #ifndef lint
  40. static char *rcsid_xwd_c = "$XConsortium: xwd.c,v 1.51 89/12/10 16:49:07 rws Exp $";
  41. #endif
  42.  
  43. /*%
  44.  *%    This is the format for commenting out color-related code until
  45.  *%  color can be supported.
  46. %*/
  47.  
  48. #include <stdio.h>
  49. #include <X11/Xos.h>
  50. #include <X11/Xlib.h>
  51. #include <X11/Xutil.h>
  52. #include <Xm/Xm.h>
  53. #include <X11/Xmu/WinUtil.h>
  54.  
  55. #define FEEP_VOLUME 0
  56.  
  57. static Bool debug = False;
  58. static char program_name[] = "mandel";
  59. static int format = ZPixmap;
  60. static long add_pixel_value = 0;
  61.  
  62. /*
  63.  * Window_Dump: dump a window to a file which must already be open for
  64.  *              writing.
  65.  */
  66.  
  67. #include "X11/XWDFile.h"
  68.  
  69. Window_Dump(w, window, out)
  70.  
  71. Widget w;
  72. Window window;
  73. FILE *out;
  74.  
  75. {
  76.     unsigned long swaptest = 1;
  77.     XColor *colors;
  78.     unsigned buffer_size;
  79.     int win_name_size;
  80.     int header_size;
  81.     int ncolors, i;
  82.     char *win_name;
  83.     Bool got_win_name;
  84.     XWindowAttributes win_info;
  85.     XImage *image;
  86.     int absx, absy, x, y;
  87.     unsigned width, height;
  88.     int dwidth, dheight;
  89.     int bw;
  90.     Window dummywin;
  91.     XWDFileHeader header;
  92.     Display *dpy;
  93.  
  94.     dpy = XtDisplay(w);
  95. /*
  96.  * Inform the user not to alter the screen.
  97.  */
  98.     XBell(dpy, FEEP_VOLUME);
  99.  
  100. /*
  101.  * Get the parameters of the window being dumped.
  102.  */
  103.     if (debug) printf("xwd: Getting target window information.\n");
  104.     if(!XGetWindowAttributes(dpy, window, &win_info))
  105.         Error("Can't get target window attributes.");
  106.  
  107. /* handle any frame window */
  108.     if (!XTranslateCoordinates (dpy, window, RootWindow(dpy,
  109.         XDefaultScreen(XtDisplay(w))), 0, 0, &absx, &absy, &dummywin))
  110.     {
  111.         fprintf (stderr, 
  112.             "%s:  unable to translate window coordinates (%d,%d)\n",
  113.             program_name, absx, absy);
  114.         exit (1);
  115.     }
  116.     win_info.x = absx;
  117.     win_info.y = absy;
  118.     width = win_info.width;
  119.     height = win_info.height;
  120.     bw = 0;
  121.  
  122.     if (1) {
  123.         absx -= win_info.border_width;
  124.         absy -= win_info.border_width;
  125.         bw = win_info.border_width;
  126.         width += (2 * bw);
  127.         height += (2 * bw);
  128.     }
  129.     dwidth = DisplayWidth(dpy, XDefaultScreen(XtDisplay(w)));
  130.     dheight = DisplayHeight(dpy, XDefaultScreen(XtDisplay(w)));
  131.  
  132.  
  133.     /* clip to window */
  134.     if (absx < 0) width += absx, absx = 0;
  135.     if (absy < 0) height += absy, absy = 0;
  136.     if (absx + width > dwidth) width = dwidth - absx;
  137.     if (absy + height > dheight) height = dheight - absy;
  138.  
  139.     XFetchName(dpy, window, &win_name);
  140.     if (!win_name || !win_name[0]) {
  141.         win_name = "xwdump";
  142.         got_win_name = False;
  143.     } else {
  144.         got_win_name = True;
  145.     }
  146.  
  147.     /* sizeof(char) is included for the null string terminator. */
  148.     win_name_size = strlen(win_name) + sizeof(char);
  149.  
  150. /*
  151.  * Snarf the pixmap with XGetImage.
  152.  */
  153.  
  154.     x = absx - win_info.x;
  155.     y = absy - win_info.y;
  156.     image = XGetImage (dpy, window, x, y, width, height, AllPlanes, format);
  157.     if (!image) {
  158.         fprintf (stderr, "%s:  unable to get image at %dx%d+%d+%d\n",
  159.             program_name, width, height, x, y);
  160.         exit (1);
  161.     }
  162.  
  163.     if (add_pixel_value != 0)
  164.         XAddPixel(image, add_pixel_value);
  165.  
  166. /*
  167.  * Determine the pixmap size.
  168.  */
  169.     buffer_size = Image_Size(image);
  170.  
  171.     if (debug) printf("xwd: Getting Colors.\n");
  172.  
  173.     ncolors = Get_XColors(dpy, &win_info, &colors);
  174.  
  175. /*
  176.  * Inform the user that the image has been retrieved.
  177.  */
  178.     XBell(dpy, FEEP_VOLUME);
  179.     XBell(dpy, FEEP_VOLUME);
  180.     XFlush(dpy);
  181.  
  182.     /*
  183.      * Calculate header size.
  184.      */
  185.     if (debug) printf("xwd: Calculating header size.\n");
  186.     header_size = sizeof(header) + win_name_size;
  187.  
  188. /*
  189.  * Write out header information.
  190.  */
  191.     if (debug) printf("xwd: Constructing and dumping file header.\n");
  192.     header.header_size = (CARD32) header_size;
  193.     header.file_version = (CARD32) XWD_FILE_VERSION;
  194.     header.pixmap_format = (CARD32) format;
  195.     header.pixmap_depth = (CARD32) image->depth;
  196.     header.pixmap_width = (CARD32) image->width;
  197.     header.pixmap_height = (CARD32) image->height;
  198.     header.xoffset = (CARD32) image->xoffset;
  199.     header.byte_order = (CARD32) image->byte_order;
  200.     header.bitmap_unit = (CARD32) image->bitmap_unit;
  201.     header.bitmap_bit_order = (CARD32) image->bitmap_bit_order;
  202.     header.bitmap_pad = (CARD32) image->bitmap_pad;
  203.     header.bits_per_pixel = (CARD32) image->bits_per_pixel;
  204.     header.bytes_per_line = (CARD32) image->bytes_per_line;
  205.     header.visual_class = (CARD32) win_info.visual->class;
  206.     header.red_mask = (CARD32) win_info.visual->red_mask;
  207.     header.green_mask = (CARD32) win_info.visual->green_mask;
  208.     header.blue_mask = (CARD32) win_info.visual->blue_mask;
  209.     header.bits_per_rgb = (CARD32) win_info.visual->bits_per_rgb;
  210.     header.colormap_entries = (CARD32) win_info.visual->map_entries;
  211.     header.ncolors = ncolors;
  212.     header.window_width = (CARD32) win_info.width;
  213.     header.window_height = (CARD32) win_info.height;
  214.     header.window_x = absx;
  215.     header.window_y = absy;
  216.     header.window_bdrwidth = (CARD32) win_info.border_width;
  217.  
  218.     if (*(char *) &swaptest) {
  219.         _swaplong((char *) &header, sizeof(header));
  220.         for (i = 0; i < ncolors; i++) {
  221.             _swaplong((char *) &colors[i].pixel, sizeof(long));
  222.             _swapshort((char *) &colors[i].red, 3 * sizeof(short));
  223.         }
  224.     }
  225.  
  226.     (void) fwrite((char *)&header, sizeof(header), 1, out);
  227.     (void) fwrite(win_name, win_name_size, 1, out);
  228.  
  229. /*
  230.  * Write out the color maps, if any
  231.  */
  232.  
  233.     if (debug) printf("xwd: Dumping %d colors.\n", ncolors);
  234.     (void) fwrite((char *) colors, sizeof(XColor), ncolors, out);
  235.  
  236. /*
  237.  * Write out the buffer.
  238.  */
  239.     if (debug) printf("xwd: Dumping pixmap.  bufsize=%d\n",buffer_size);
  240.  
  241. /*
  242.  *    This copying of the bit stream (data) to a file is to be replaced
  243.  *  by an Xlib call which hasn't been written yet.  It is not clear
  244.  *  what other functions of xwd will be taken over by this (as yet)
  245.  *  non-existant X function.
  246.  */
  247.     (void) fwrite(image->data, (int) buffer_size, 1, out);
  248.  
  249. /*
  250.  * free the color buffer.
  251.  */
  252.  
  253.     if(debug && ncolors > 0) printf("xwd: Freeing colors.\n");
  254.     if(ncolors > 0) free(colors);
  255.  
  256. /*
  257.  * Free window name string.
  258.  */
  259.     if (debug) printf("xwd: Freeing window name string.\n");
  260.     if (got_win_name) XFree(win_name);
  261.  
  262. /*
  263.  * Free image
  264.  */
  265.     XDestroyImage(image);
  266. }
  267.  
  268. /*
  269.  * Error - Fatal xwd error.
  270.  */
  271. extern int errno;
  272.  
  273. Error(string)
  274.  
  275. char *string;    /* Error description string. */
  276.  
  277. {
  278.     printf("\nxwd: Error => %s\n", string);
  279.     if (errno != 0) {
  280.         perror("xwd");
  281.         printf("\n");
  282.     }
  283.     exit(1);
  284. }
  285.  
  286.  
  287. /*
  288.  * Determine the pixmap size.
  289.  */
  290.  
  291. int Image_Size(image)
  292. XImage *image;
  293. {
  294.     if (format != ZPixmap)
  295.         return(image->bytes_per_line * image->height * image->depth);
  296.  
  297.     return(image->bytes_per_line * image->height);
  298. }
  299.  
  300. #define lowbit(x) ((x) & (~(x) + 1))
  301.  
  302. /*
  303.  * Get the XColors of all pixels in image - returns # of colors
  304.  */
  305. int Get_XColors(dpy, win_info, colors)
  306. Display *dpy;
  307. XWindowAttributes *win_info;
  308. XColor **colors;
  309. {
  310.     int i, ncolors;
  311.  
  312.     if (!win_info->colormap)
  313.         return(0);
  314.  
  315.     if (win_info->visual->class == TrueColor)
  316.         return(0);    /* colormap is not needed */
  317.  
  318.     ncolors = win_info->visual->map_entries;
  319.     if (!(*colors = (XColor *) malloc (sizeof(XColor) * ncolors)))
  320.         Error("Out of memory!");
  321.  
  322.     if (win_info->visual->class == DirectColor) {
  323.         Pixel red, green, blue, red1, green1, blue1;
  324.  
  325.         red = green = blue = 0;
  326.         red1 = lowbit(win_info->visual->red_mask);
  327.         green1 = lowbit(win_info->visual->green_mask);
  328.         blue1 = lowbit(win_info->visual->blue_mask);
  329.         for (i=0; i<ncolors; i++) {
  330.             (*colors)[i].pixel = red|green|blue;
  331.             (*colors)[i].pad = 0;
  332.             red += red1;
  333.             if (red > win_info->visual->red_mask)
  334.                 red = 0;
  335.             green += green1;
  336.             if (green > win_info->visual->green_mask)
  337.                 green = 0;
  338.             blue += blue1;
  339.             if (blue > win_info->visual->blue_mask)
  340.                 blue = 0;
  341.         }
  342.     } else {
  343.         for (i=0; i<ncolors; i++) {
  344.             (*colors)[i].pixel = i;
  345.             (*colors)[i].pad = 0;
  346.         }
  347.     }
  348.  
  349.     XQueryColors(dpy, win_info->colormap, *colors, ncolors);
  350.  
  351.     return(ncolors);
  352. }
  353.  
  354. _swapshort (bp, n)
  355. register char *bp;
  356. register unsigned n;
  357. {
  358.     register char c;
  359.     register char *ep = bp + n;
  360.  
  361.     while (bp < ep) {
  362.         c = *bp;
  363.         *bp = *(bp + 1);
  364.         bp++;
  365.         *bp++ = c;
  366.     }
  367. }
  368.  
  369. _swaplong (bp, n)
  370. register char *bp;
  371. register unsigned n;
  372. {
  373.     register char c;
  374.     register char *ep = bp + n;
  375.     register char *sp;
  376.  
  377.     while (bp < ep) {
  378.         sp = bp + 3;
  379.         c = *sp;
  380.         *sp = *bp;
  381.         *bp++ = c;
  382.         sp = bp + 1;
  383.         c = *sp;
  384.         *sp = *bp;
  385.         *bp++ = c;
  386.         bp += 2;
  387.     }
  388. }
  389.