/* $XConsortium: xwd.c,v 1.56 91/07/25 18:00:15 rws Exp $ */ /* Copyright 1987 Massachusetts Institute of Technology */ /* * xwd.c MIT Project Athena, X Window system window raster image dumper. * */ /* * This copy of xwd.c contains no main, it was hacked out for inclusion * of this functionality into XFelt ... basically we just took out the * the functionality that we didn't need to form a simple window * dumper. */ # include # include # include # include # include # include # include # include # include # include "malloc.h" # include "error.h" int Image_Size ( ); int Get_XColors ( ); void _swaplong ( ); void _swapshort ( ); Display *dpy; int screen; int DumpWidget(widget, out) Widget widget; FILE *out; { unsigned long swaptest = 1; XColor *colors; unsigned buffer_size; int win_name_size; int header_size; int ncolors, i; char *win_name; XWindowAttributes win_info; XImage *image; int absx, absy, x, y; unsigned width, height; int dwidth, dheight; int bw; Window dummywin; XWDFileHeader header; Window window; window = XtWindow (widget); dpy = XtDisplay (widget); screen = DefaultScreen (dpy); /* * Get the parameters of the window being dumped. */ if(!XGetWindowAttributes(dpy, window, &win_info)) { error("could not get window attributes"); return 1; } /* handle any frame window */ if (!XTranslateCoordinates (dpy, window, RootWindow (dpy, screen), 0, 0, &absx, &absy, &dummywin)) { error ("unable to perform translation"); return 1; } win_info.x = absx; win_info.y = absy; width = win_info.width; height = win_info.height; bw = 0; absx -= win_info.border_width; absy -= win_info.border_width; bw = win_info.border_width; width += (2 * bw); height += (2 * bw); dwidth = DisplayWidth (dpy, screen); dheight = DisplayHeight (dpy, screen); /* clip to window */ if (absx < 0) width += absx, absx = 0; if (absy < 0) height += absy, absy = 0; if (absx + width > dwidth) width = dwidth - absx; if (absy + height > dheight) height = dheight - absy; win_name = "FElt_XWD"; /* sizeof(char) is included for the null string terminator. */ win_name_size = strlen(win_name) + sizeof(char); /* * Snarf the pixmap with XGetImage. */ x = absx - win_info.x; y = absy - win_info.y; image = XGetImage (dpy, window, x, y, width, height, AllPlanes, ZPixmap); if (!image) { error ("unable to capture image"); return 1; } /* * Determine the pixmap size. */ buffer_size = Image_Size(image); ncolors = Get_XColors(&win_info, &colors); /* * Calculate header size. */ header_size = sizeof(header) + win_name_size; /* * Write out header information. */ header.header_size = (CARD32) header_size; header.file_version = (CARD32) XWD_FILE_VERSION; header.pixmap_format = (CARD32) ZPixmap; header.pixmap_depth = (CARD32) image->depth; header.pixmap_width = (CARD32) image->width; header.pixmap_height = (CARD32) image->height; header.xoffset = (CARD32) image->xoffset; header.byte_order = (CARD32) image->byte_order; header.bitmap_unit = (CARD32) image->bitmap_unit; header.bitmap_bit_order = (CARD32) image->bitmap_bit_order; header.bitmap_pad = (CARD32) image->bitmap_pad; header.bits_per_pixel = (CARD32) image->bits_per_pixel; header.bytes_per_line = (CARD32) image->bytes_per_line; header.visual_class = (CARD32) win_info.visual->class; header.red_mask = (CARD32) win_info.visual->red_mask; header.green_mask = (CARD32) win_info.visual->green_mask; header.blue_mask = (CARD32) win_info.visual->blue_mask; header.bits_per_rgb = (CARD32) win_info.visual->bits_per_rgb; header.colormap_entries = (CARD32) win_info.visual->map_entries; header.ncolors = ncolors; header.window_width = (CARD32) win_info.width; header.window_height = (CARD32) win_info.height; header.window_x = absx; header.window_y = absy; header.window_bdrwidth = (CARD32) win_info.border_width; if (*(char *) &swaptest) { _swaplong((char *) &header, sizeof(header)); for (i = 0; i < ncolors; i++) { _swaplong((char *) &colors[i].pixel, sizeof(long)); _swapshort((char *) &colors[i].red, 3 * sizeof(short)); } } (void) fwrite((char *)&header, sizeof(header), 1, out); (void) fwrite(win_name, win_name_size, 1, out); /* * Write out the color maps, if any */ (void) fwrite((char *) colors, sizeof(XColor), ncolors, out); /* * Write out the buffer. */ /* * This copying of the bit stream (data) to a file is to be replaced * by an Xlib call which hasn't been written yet. It is not clear * what other functions of xwd will be taken over by this (as yet) * non-existant X function. */ (void) fwrite(image->data, (int) buffer_size, 1, out); /* * free the color buffer. */ if(ncolors > 0) free(colors); /* * Free image */ XDestroyImage(image); return 0; } XImage *WidgetToXImage(widget, colors, ncolors) Widget widget; XColor **colors; int *ncolors; { unsigned long swaptest = 1; unsigned buffer_size; int i; XWindowAttributes win_info; XImage *image; int absx, absy, x, y; unsigned width, height; int dwidth, dheight; int bw; Window dummywin; Window window; window = XtWindow (widget); dpy = XtDisplay (widget); screen = DefaultScreen (dpy); /* * Get the parameters of the window being dumped. */ if(!XGetWindowAttributes(dpy, window, &win_info)) { error("could not get window attributes"); return NULL; } /* handle any frame window */ if (!XTranslateCoordinates (dpy, window, RootWindow (dpy, screen), 0, 0, &absx, &absy, &dummywin)) { error ("unable to perform translation"); return NULL; } win_info.x = absx; win_info.y = absy; width = win_info.width; height = win_info.height; bw = 0; absx -= win_info.border_width; absy -= win_info.border_width; bw = win_info.border_width; width += (2 * bw); height += (2 * bw); dwidth = DisplayWidth (dpy, screen); dheight = DisplayHeight (dpy, screen); /* clip to window */ if (absx < 0) width += absx, absx = 0; if (absy < 0) height += absy, absy = 0; if (absx + width > dwidth) width = dwidth - absx; if (absy + height > dheight) height = dheight - absy; /* * Snarf the pixmap with XGetImage. */ x = absx - win_info.x; y = absy - win_info.y; image = XGetImage (dpy, window, x, y, width, height, AllPlanes, ZPixmap); if (!image) { error ("unable to capture image"); return NULL; } /* * Determine the pixmap size. */ buffer_size = Image_Size(image); if (ncolors) *ncolors = Get_XColors(&win_info, colors); if (*(char *) &swaptest) { for (i = 0; i < *ncolors; i++) { _swaplong((char *) &((*colors)[i].pixel), sizeof(long)); _swapshort((char *) &((*colors)[i].red), 3 * sizeof(short)); } } return image; } int XImageCellXY(img, x, y, colors, ncolors) XImage *img; int x, y; XColor *colors; int ncolors; { int i; unsigned long point; int idx; point = XGetPixel(img, x, y); _swaplong((char *) &point, sizeof(long)); fprintf (stderr,"%u\n", point); for (i = 0 ; i < ncolors ; i++) if (point == colors [i].pixel) return i; return 0; } /* * Determine the pixmap size. */ int Image_Size(image) XImage *image; { if (image->format != ZPixmap) return(image->bytes_per_line * image->height * image->depth); return(image->bytes_per_line * image->height); } #define lowbit(x) ((x) & (~(x) + 1)) /* * Get the XColors of all pixels in image - returns # of colors */ int Get_XColors(win_info, colors) XWindowAttributes *win_info; XColor **colors; { int i, ncolors; Colormap cmap = win_info->colormap; ncolors = win_info->visual->map_entries; if (!(*colors = (XColor *) malloc (sizeof(XColor) * ncolors))) { error ("could not allocate color memory"); return 1; } if (win_info->visual->class == DirectColor || win_info->visual->class == TrueColor) { Pixel red, green, blue, red1, green1, blue1; red = green = blue = 0; red1 = lowbit(win_info->visual->red_mask); green1 = lowbit(win_info->visual->green_mask); blue1 = lowbit(win_info->visual->blue_mask); for (i=0; i win_info->visual->red_mask) red = 0; green += green1; if (green > win_info->visual->green_mask) green = 0; blue += blue1; if (blue > win_info->visual->blue_mask) blue = 0; } } else { for (i=0; i