xwd.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:10k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Stolen from X11R6's xwd.c
  3.  * $XConsortium: xwd.c /main/64 1996/01/14 16:53:13 kaleb $
  4.  * by John Heidemann, 15-Dec-97.
  5.  */
  6. /*
  7. Copyright (c) 1987  X Consortium
  8. Permission is hereby granted, free of charge, to any person obtaining a copy
  9. of this software and associated documentation files (the "Software"), to deal
  10. in the Software without restriction, including without limitation the rights
  11. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. copies of the Software, and to permit persons to whom the Software is
  13. furnished to do so, subject to the following conditions:
  14. The above copyright notice and this permission notice shall be included in
  15. all copies or substantial portions of the Software.
  16. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
  19. X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  20. AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. Except as contained in this notice, the name of the X Consortium shall not be
  23. used in advertising or otherwise to promote the sale, use or other dealings
  24. in this Software without prior written authorization from the X Consortium.
  25. */
  26. /*
  27.  * xwd.c MIT Project Athena, X Window system window raster image dumper.
  28.  *
  29.  * This program will dump a raster image of the contents of a window into a 
  30.  * file for output on graphics printers or for other uses.
  31.  *
  32.  *  Author: Tony Della Fera, DEC
  33.  * 17-Jun-85
  34.  * 
  35.  *  Modification history:
  36.  *
  37.  *  11/14/86 Bill Wyatt, Smithsonian Astrophysical Observatory
  38.  *    - Removed Z format option, changing it to an XY option. Monochrome 
  39.  *      windows will always dump in XY format. Color windows will dump
  40.  *      in Z format by default, but can be dumped in XY format with the
  41.  *      -xy option.
  42.  *
  43.  *  11/18/86 Bill Wyatt
  44.  *    - VERSION 6 is same as version 5 for monchrome. For colors, the 
  45.  *      appropriate number of Color structs are dumped after the header,
  46.  *      which has the number of colors (=0 for monochrome) in place of the
  47.  *      V5 padding at the end. Up to 16-bit displays are supported. I
  48.  *      don't yet know how 24- to 32-bit displays will be handled under
  49.  *      the Version 11 protocol.
  50.  *
  51.  *  6/15/87 David Krikorian, MIT Project Athena
  52.  *    - VERSION 7 runs under the X Version 11 servers, while the previous
  53.  *      versions of xwd were are for X Version 10.  This version is based
  54.  *      on xwd version 6, and should eventually have the same color
  55.  *      abilities. (Xwd V7 has yet to be tested on a color machine, so
  56.  *      all color-related code is commented out until color support
  57.  *      becomes practical.)
  58.  */
  59. /*%
  60.  *%    This is the format for commenting out color-related code until
  61.  *%  color can be supported.
  62. %*/
  63. #include <stdlib.h>
  64. #include <stdio.h>
  65. #include <errno.h>
  66. #include <tk.h>
  67. #include <X11/Xos.h>
  68. #ifdef X_NOT_STDC_ENV
  69. extern int errno;
  70. #endif
  71. #include <X11/Xlib.h>
  72. #include <X11/Xutil.h>
  73. #include <X11/Xmu/WinUtil.h>
  74. typedef unsigned long Pixel;
  75. /* Use our own... */
  76. #include "XWDFile.h"
  77. /*
  78.  * work-around solaris 2.6 problem:
  79.  * SIZEOF is defined in Xmd.h, which is included by XWDFile.h
  80.  * make sure we get the right (ansi) definition).
  81.  */
  82. #if defined(sun) && defined(__svr4__)
  83. #undef SIZEOF
  84. #define SIZEOF(x) sz_##x
  85. #endif
  86. /* work-around solaris 2.6 problem */
  87. #ifndef SIZEOF
  88. #define SIZEOF(x) sz_##x
  89. #endif
  90. /*
  91.  * Window_Dump: dump a window to a file which must already be open for
  92.  *              writting.
  93.  */
  94. static void
  95. outl(char *s)
  96. {
  97. }
  98. /*
  99.  * Determine the pixmap size.
  100.  */
  101. static int
  102. Image_Size(image)
  103. XImage *image;
  104. {
  105. if (image->format != ZPixmap)
  106. return(image->bytes_per_line * image->height * image->depth);
  107. return(image->bytes_per_line * image->height);
  108. }
  109. #define lowbit(x) ((x) & (~(x) + 1))
  110. static int
  111. ReadColors(tk,cmap,colors)
  112. Colormap cmap ;
  113. XColor **colors ;
  114. {
  115. Visual *vis = Tk_Visual(tk);
  116. int i,ncolors ;
  117. ncolors = vis->map_entries;
  118. if (!(*colors = (XColor *) Tcl_Alloc (sizeof(XColor) * ncolors))) {
  119. outl("Out of memory!");
  120. exit(1);
  121. }
  122. if (vis->class == DirectColor ||
  123.     vis->class == TrueColor) {
  124. Pixel red, green, blue, red1, green1, blue1;
  125. red = green = blue = 0;
  126. red1 = lowbit(vis->red_mask);
  127. green1 = lowbit(vis->green_mask);
  128. blue1 = lowbit(vis->blue_mask);
  129. for (i=0; i<ncolors; i++) {
  130. (*colors)[i].pixel = red|green|blue;
  131. (*colors)[i].pad = 0;
  132. red += red1;
  133. if (red > vis->red_mask)
  134. red = 0;
  135. green += green1;
  136. if (green > vis->green_mask)
  137. green = 0;
  138. blue += blue1;
  139. if (blue > vis->blue_mask)
  140. blue = 0;
  141. }
  142. } else {
  143. for (i=0; i<ncolors; i++) {
  144. (*colors)[i].pixel = i;
  145. (*colors)[i].pad = 0;
  146. }
  147. }
  148. XQueryColors(Tk_Display(tk), cmap, *colors, ncolors);
  149.     
  150. return(ncolors);
  151. }
  152. /*
  153.  * Get the XColors of all pixels in image - returns # of colors
  154.  */
  155. static int
  156. Get_XColors(tk, colors)
  157. Tk_Window tk;
  158. XColor **colors;
  159. {
  160. int ncolors;
  161. Colormap cmap = Tk_Colormap(tk);
  162. #if 0
  163. if (use_installed)
  164. /* assume the visual will be OK ... */
  165. cmap = XListInstalledColormaps(dpy, win_info->root, &i)[0];
  166. #endif
  167. if (!cmap)
  168. return(0);
  169. ncolors = ReadColors(tk,cmap,colors) ;
  170. return ncolors ;
  171. }
  172. static void
  173. _swapshort (bp, n)
  174. register char *bp;
  175. register unsigned n;
  176. {
  177. register char c;
  178. register char *ep = bp + n;
  179. while (bp < ep) {
  180. c = *bp;
  181. *bp = *(bp + 1);
  182. bp++;
  183. *bp++ = c;
  184. }
  185. }
  186. static void
  187. _swaplong (bp, n)
  188. register char *bp;
  189. register unsigned n;
  190. {
  191. register char c;
  192. register char *ep = bp + n;
  193. register char *sp;
  194. while (bp < ep) {
  195. sp = bp + 3;
  196. c = *sp;
  197. *sp = *bp;
  198. *bp++ = c;
  199. sp = bp + 1;
  200. c = *sp;
  201. *sp = *bp;
  202. *bp++ = c;
  203. bp += 2;
  204. }
  205. }
  206. void
  207. xwd_Window_Dump(tk, offscreen, width, height, out)
  208. Tk_Window tk;
  209. Drawable offscreen;
  210. unsigned width, height;
  211. FILE *out;
  212. {
  213. unsigned long swaptest = 1;
  214. XColor *colors;
  215. unsigned buffer_size;
  216. int header_size;
  217. int ncolors, i;
  218. char *win_name = "a";
  219. int win_name_size = 1; /* strlen("a") */
  220. XImage *image;
  221. int absx, absy, x, y;
  222. XWDFileHeader header;
  223. XWDColor xwdcolor;
  224. int format = ZPixmap;
  225. int debug = 0;
  226. Display *dpy = Tk_Display(tk);
  227. Visual *vis;
  228. absx = absy = 0;
  229. image = XGetImage (dpy, offscreen, 0, 0,
  230.    width, height, AllPlanes, format);
  231. if (!image) {
  232. fprintf (stderr, "%s:  unable to get image at %dx%d+%d+%dn",
  233.  "xwd", width, height, x, y);
  234. exit (1);
  235. }
  236. /*
  237.  * Determine the pixmap size.
  238.  */
  239. buffer_size = Image_Size(image);
  240. if (debug) outl("xwd: Getting Colors.n");
  241. ncolors = Get_XColors(tk, &colors);
  242. vis = Tk_Visual(tk);
  243. /*
  244.  * Calculate header size.
  245.  */
  246. if (debug) outl("xwd: Calculating header size.n");
  247. header_size = SIZEOF(XWDheader) + win_name_size;
  248. /*
  249.  * Write out header information.
  250.  */
  251. if (debug) outl("xwd: Constructing and dumping file header.n");
  252. header.header_size = (CARD32) header_size;
  253. header.file_version = (CARD32) XWD_FILE_VERSION;
  254. header.pixmap_format = (CARD32) format;
  255. header.pixmap_depth = (CARD32) image->depth;
  256. header.pixmap_width = (CARD32) image->width;
  257. header.pixmap_height = (CARD32) image->height;
  258. header.xoffset = (CARD32) image->xoffset;
  259. header.byte_order = (CARD32) image->byte_order;
  260. header.bitmap_unit = (CARD32) image->bitmap_unit;
  261. header.bitmap_bit_order = (CARD32) image->bitmap_bit_order;
  262. header.bitmap_pad = (CARD32) image->bitmap_pad;
  263. header.bits_per_pixel = (CARD32) image->bits_per_pixel;
  264. header.bytes_per_line = (CARD32) image->bytes_per_line;
  265. /****
  266.   header.visual_class = (CARD32) win_info.visual->class;
  267.   header.red_mask = (CARD32) win_info.visual->red_mask;
  268.   header.green_mask = (CARD32) win_info.visual->green_mask;
  269.   header.blue_mask = (CARD32) win_info.visual->blue_mask;
  270.   header.bits_per_rgb = (CARD32) win_info.visual->bits_per_rgb;
  271.   header.colormap_entries = (CARD32) win_info.visual->map_entries;
  272.   *****/
  273. header.visual_class = (CARD32) vis->class;
  274. header.red_mask = (CARD32) vis->red_mask;
  275. header.green_mask = (CARD32) vis->green_mask;
  276. header.blue_mask = (CARD32) vis->blue_mask;
  277. header.bits_per_rgb = (CARD32) vis->bits_per_rgb;
  278. header.colormap_entries = (CARD32) vis->map_entries;
  279. header.ncolors = ncolors;
  280. header.window_width = (CARD32) width;
  281. header.window_height = (CARD32) height;
  282. header.window_x = absx;
  283. header.window_y = absy;
  284. header.window_bdrwidth = (CARD32) 0;
  285. if (*(char *) &swaptest) {
  286. _swaplong((char *) &header, sizeof(header));
  287. for (i = 0; i < ncolors; i++) {
  288. _swaplong((char *) &colors[i].pixel, sizeof(long));
  289. _swapshort((char *) &colors[i].red, 3 * sizeof(short));
  290. }
  291. }
  292. if (fwrite((char *)&header, SIZEOF(XWDheader), 1, out) != 1 ||
  293.     fwrite(win_name, win_name_size, 1, out) != 1) {
  294. perror("xwd");
  295. exit(1);
  296. }
  297. /*
  298.  * Write out the color maps, if any
  299.  */
  300. /*    if (debug) outl("xwd: Dumping %d colors.n", ncolors); */
  301. for (i = 0; i < ncolors; i++) {
  302. xwdcolor.pixel = colors[i].pixel;
  303. xwdcolor.red = colors[i].red;
  304. xwdcolor.green = colors[i].green;
  305. xwdcolor.blue = colors[i].blue;
  306. xwdcolor.flags = colors[i].flags;
  307. if (fwrite((char *) &xwdcolor, SIZEOF(XWDColor), 1, out) != 1) {
  308. perror("xwd");
  309. exit(1);
  310. }
  311. }
  312. /*
  313.  * Write out the buffer.
  314.  */
  315. /*    if (debug) outl("xwd: Dumping pixmap.  bufsize=%dn",buffer_size); */
  316. /*
  317.  *    This copying of the bit stream (data) to a file is to be replaced
  318.  *  by an Xlib call which hasn't been written yet.  It is not clear
  319.  *  what other functions of xwd will be taken over by this (as yet)
  320.  *  non-existant X function.
  321.  */
  322. if (fwrite(image->data, (int) buffer_size, 1, out) != 1) {
  323. perror("xwd");
  324. exit(1);
  325. }
  326. /*
  327.  * free the color buffer.
  328.  */
  329. if(debug && ncolors > 0) outl("xwd: Freeing colors.n");
  330. if(ncolors > 0) Tcl_Free((char*)colors);
  331. /*
  332.  * Free image
  333.  */
  334. XDestroyImage(image);
  335. }
  336. int
  337. xwd_Window_Dump_To_File(
  338. Tk_Window tk,
  339. Drawable offscreen,
  340. unsigned width, unsigned height,
  341. char *name)
  342. {
  343. FILE *f;
  344. if (!(f = fopen(name, "w"))) {
  345. fprintf(stderr, "cannot open %s", name);
  346. return TCL_ERROR;
  347. };
  348. xwd_Window_Dump(tk, offscreen, width, height, f);
  349. fclose(f);
  350. return TCL_OK;
  351. }