|
|
1.1 root 1: /*
2: * $Locker: $
3: */
4: static char *rcsid = "$Header: xwud.c,v 1.14 87/09/11 19:01:19 rws Exp $";
5: #include <X11/copyright.h>
6:
7: /* Copyright 1985, 1986, Massachusetts Institute of Technology */
8:
9: /*
10: * xwud.c - MIT Project Athena, X Window system window raster image
11: * undumper.
12: *
13: * This program will read a raster image of a window from stdin or a file
14: * and display it on an X display.
15: *
16: * Author: Tony Della Fera, DEC
17: *
18: * Modified 11/14/86 by William F. Wyatt,
19: * Smithsonian Astrophysical Observatory
20: * allows writing of monochrome XYFormat window dump files on a color
21: * display, using default WhitePixel for 1's and BlackPixel for 0's.
22: *
23: * Modified 11/20/86 WFW
24: * VERSION 6 - same as V5 for monochrome, but expects color map info
25: * in the file for color images. Checks to see if the requested
26: * colors are already in the display's map (e.g. if the window dump
27: * and undump are contemporaneous to the same display). If so,
28: * undump immediately. If not, request new colors, alter the
29: * pixels to the new values, then write the pixmap. Note that
30: * multi-plane XY format undumps don't work if the pixel values
31: * corresponding to the requested colors have to be changed.
32: */
33:
34: #ifndef lint
35: static char *rcsid_xwud_c = "$Header: xwud.c,v 1.14 87/09/11 19:01:19 rws Exp $";
36: #endif
37:
38: #include <X11/Xlib.h>
39: #include <X11/Xutil.h>
40: #include <stdio.h>
41: #include <strings.h>
42: #include <sys/types.h>
43: extern char *calloc();
44: #include "dsimple.h"
45:
46: #include <X11/XWDFile.h>
47:
48: extern int errno;
49:
50: usage()
51: {
52: outl("%s: %s [-help][-debug][-inverse][-in <file>][[host]:vs]\n",
53: program_name, program_name);
54: exit(1);
55: }
56:
57: main(argc, argv)
58: int argc;
59: char **argv;
60: {
61: register int i;
62: XImage image;
63: XSetWindowAttributes attributes;
64: XVisualInfo vinfo, *vinfos;
65: Visual *visual = NULL;
66: register char *buffer;
67:
68: unsigned long swaptest = 1;
69: int j, status;
70: unsigned buffer_size;
71: int win_name_size;
72: int ncolors;
73: char *str_index;
74: char *file_name;
75: char *win_name;
76: Bool standard_in = True;
77: Bool debug = False, inverse = False;
78:
79: XColor *colors;
80: Window image_win;
81: int win_depth;
82: Colormap colormap;
83: XEvent event;
84: register XExposeEvent *expose = (XExposeEvent *)&event;
85:
86: GC gc;
87: XGCValues gc_val;
88:
89: XWDFileHeader header;
90:
91: FILE *in_file = stdin;
92:
93: INIT_NAME;
94:
95: Setup_Display_And_Screen(&argc, argv);
96:
97: for (i = 1; i < argc; i++) {
98: str_index = (char *) index (argv [i], '-');
99: if (str_index == NULL) usage();
100: if (strncmp(argv[i], "-help", 5) == 0) {
101: usage();
102: }
103: if (strncmp(argv[i], "-in", 4) == 0) {
104: if (++i >= argc) usage();
105: file_name = argv[i];
106: standard_in = False;
107: continue;
108: }
109: if(strcmp(argv[i], "-inverse") == 0) {
110: inverse = True;
111: continue;
112: }
113: if(strcmp(argv[i], "-debug") == 0) {
114: debug = True;
115: continue;
116: }
117: usage();
118: }
119:
120: if (!standard_in) {
121: /*
122: * Open the output file.
123: */
124: in_file = fopen(file_name, "r");
125: if (in_file == NULL) {
126: Error("Can't open output file as specified.");
127: }
128: }
129:
130: /*
131: * Read in header information.
132: */
133: if(fread((char *)&header, sizeof(header), 1, in_file) != 1)
134: Error("Unable to read dump file header.");
135:
136: if (*(char *) &swaptest)
137: _swaplong((char *) &header, sizeof(header));
138:
139: /*
140: * check to see if the dump file is in the proper format.
141: */
142: if (header.file_version != XWD_FILE_VERSION) {
143: fprintf(stderr,"xwud: XWD file format version missmatch.");
144: Error("exiting.");
145: }
146: if (header.header_size < sizeof(header)) {
147: fprintf(stderr,"xwud: XWD header size is too small.");
148: Error("exiting.");
149: }
150:
151: /*
152: * Calloc window name.
153: */
154: win_name_size = (header.header_size - sizeof(header));
155: if((win_name = calloc((unsigned) win_name_size, sizeof(char))) == NULL)
156: Error("Can't calloc window name storage.");
157:
158: /*
159: * Read in window name.
160: */
161: if(fread(win_name, sizeof(char), win_name_size, in_file) != win_name_size)
162: Error("Unable to read window name from dump file.");
163:
164: image.width = (int) header.pixmap_width;
165: image.height = (int) header.pixmap_height;
166: image.xoffset = (int) header.xoffset;
167: image.format = (int) header.pixmap_format;
168: image.byte_order = (int) header.byte_order;
169: image.bitmap_unit = (int) header.bitmap_unit;
170: image.bitmap_bit_order = (int) header.bitmap_bit_order;
171: image.bitmap_pad = (int) header.bitmap_pad;
172: image.depth = (int) header.pixmap_depth;
173: image.bits_per_pixel = (int) header.bits_per_pixel;
174: image.bytes_per_line = (int) header.bytes_per_line;
175: image.red_mask = header.red_mask;
176: image.green_mask = header.green_mask;
177: image.blue_mask = header.blue_mask;
178: image.obdata = NULL;
179: _XInitImageFuncPtrs(&image);
180:
181:
182: /* Calloc the color map buffer.
183: * Read it in, copy it and use the copy to query for the
184: * existing colors at those pixel values.
185: */
186: if(ncolors = header.ncolors) {
187: colors = (XColor *)calloc(ncolors,sizeof(XColor));
188: if(fread((char *) colors, sizeof(XColor), ncolors, in_file) != ncolors)
189: Error("Unable to read color map from dump file.");
190: if(debug)
191: fprintf(stderr,"Read %d colors\n", ncolors);
192: if (*(char *) &swaptest) {
193: for (i = 0; i < ncolors; i++) {
194: _swaplong((char *) &colors[i].pixel, sizeof(long));
195: _swapshort((char *) &colors[i].red, 3 * sizeof(short));
196: }
197: }
198: }
199:
200: /*
201: * Calloc the pixel buffer.
202: */
203: buffer_size = Image_Size(&image);
204: if((buffer = calloc(buffer_size, 1)) == NULL)
205: Error("Can't calloc data buffer.");
206: image.data = buffer;
207:
208: /*
209: * Read in the pixmap buffer.
210: */
211: if((status = fread(buffer, sizeof(char), (int)buffer_size, in_file))
212: != buffer_size){
213: /* Add elaboration on error here. %%*/
214: Error("Unable to read pixmap from dump file.");
215: }
216: /*
217: * Close the input file.
218: */
219: (void) fclose(in_file);
220:
221: vinfo.screen = screen;
222: vinfo.depth = (int) header.pixmap_depth;
223: vinfo.class = (int) header.visual_class;
224: vinfo.red_mask = header.red_mask;
225: vinfo.green_mask = header.green_mask;
226: vinfo.blue_mask = header.blue_mask;
227: vinfo.colormap_size = (int) header.colormap_entries;
228: vinfo.bits_per_rgb = (int) header.bits_per_rgb;
229:
230: vinfos = (XVisualInfo *)
231: XGetVisualInfo(dpy,
232: /* XXX ignoring rgb mask differences */
233: VisualScreenMask|VisualDepthMask|VisualClassMask|
234: VisualColormapSizeMask|VisualBitsPerRGBMask,
235: &vinfo,
236: &j);
237: if (j > 0) {
238: visual = vinfos[0].visual;
239: win_depth = vinfo.depth;
240: } else if (header.pixmap_depth == 1) {
241: visual = DefaultVisual(dpy, screen);
242: win_depth = DefaultDepth(dpy, screen);
243: image.format = XYBitmap;
244: } else {
245: fprintf(stderr, "xwud: could not find matching visual.\n");
246: Error("exiting.");
247: }
248:
249: /* XXX */
250: if (visual == DefaultVisual(dpy, screen))
251: colormap = DefaultColormap(dpy, screen);
252: /* XXX */
253: #ifdef notdef
254: colormap = ModifyColors(image, visual, colormap, colors, ncolors);
255: #endif
256: else {
257: colormap = XCreateColormap(dpy, RootWindow(dpy, screen), visual,
258: visual->class & 1);
259: if (visual->class & 1)
260: XStoreColors(dpy, colormap, colors, ncolors);
261: /* XXX colors may not be accurate for static maps */
262: }
263:
264:
265: if (colormap != DefaultColormap(dpy, screen))
266: XInstallColormap(dpy, colormap); /* XXX */
267:
268: /*
269: * Create the image window.
270: */
271:
272: attributes.override_redirect = True;
273: attributes.background_pixel = BlackPixel(dpy, screen); /* XXX */
274: attributes.colormap = colormap;
275:
276: image_win = XCreateWindow(dpy,
277: RootWindow(dpy, screen),
278: header.window_x, header.window_y,
279: header.pixmap_width, header.pixmap_height,
280: 0, win_depth, InputOutput, visual,
281: CWOverrideRedirect|CWBackPixel|CWColormap, &attributes);
282:
283: if (!image_win) Error("Can't create image window.");
284:
285: /*
286: * Select mouse ButtonPressed on the window, this is how we determine
287: * when to stop displaying the window.
288: */
289: XSelectInput(dpy,image_win, (ButtonPressMask | ExposureMask));
290:
291: /*
292: * Store the window name string.
293: */
294: XStoreName(dpy, image_win, win_name);
295:
296: /*
297: * Map the image window.
298: */
299: XMapWindow(dpy, image_win);
300:
301: /* XXX */
302: if (inverse) {
303: gc_val.foreground = (unsigned long) WhitePixel (dpy, screen);
304: gc_val.background = (unsigned long) BlackPixel (dpy, screen);
305: } else {
306: gc_val.foreground = (unsigned long) BlackPixel (dpy, screen);
307: gc_val.background = (unsigned long) WhitePixel (dpy, screen);
308: }
309: gc = XCreateGC (dpy, image_win, GCForeground|GCBackground, &gc_val);
310:
311: /*
312: * Set up a while loop to maintain the image.
313: */
314:
315: while (True) {
316: /*
317: * Wait on mouse input event to terminate.
318: */
319: XNextEvent(dpy, &event);
320: if (event.type == ButtonPress) break;
321:
322: switch((int)event.type) {
323: case Expose:
324: if (expose->x < image.width &&
325: expose->y < image.height) {
326: if ((image.width - expose->x) < expose->width)
327: expose->width = image.width - expose->x;
328: if ((image.height - expose->y) < expose->height)
329: expose->height = image.height - expose->y;
330: XPutImage(dpy, image_win, gc, &image,
331: expose->x, expose->y, expose->x, expose->y,
332: expose->width, expose->height);
333: }
334: }
335: }
336:
337: /*
338: * Destroy the image window.
339: */
340: XDestroyWindow(dpy, image_win);
341:
342: /*
343: * Free the pixmap buffer.
344: */
345: free(buffer);
346:
347: /*
348: * Free window name string.
349: */
350: free(win_name);
351: exit(0);
352: }
353:
354: #ifdef notdef
355: Colormap
356: ModifyColors(image, visual, colormap, colors, ncolors)
357: XImage *image;
358: Visual *visual;
359: Colormap colormap;
360: XColor *colors;
361: int ncolors;
362: {
363: unsigned long *cplanes, *cpixels;
364: XColor *copycolors;
365: register int *histbuffer;
366: register u_short *wbuffer;
367:
368: /*
369: * If necessary, get and store the new colors, convert the pixels to the
370: * new colors appropriately.
371: */
372: if(ncolors) {
373: copycolors = (XColor *)calloc(ncolors,sizeof(XColor));
374: bcopy(colors, copycolors, sizeof(XColor)*ncolors);
375: if(XQueryColors(dpy, colormap, copycolors, ncolors) == 0)
376: Error("Can't query the color map?");
377: for(i=0; i<ncolors; i++)
378: if(!ColorEqual(&colors[i], ©colors[i])) {
379: copycolors = True;
380: break;
381: }
382: if(debug) {
383: if(copycolors) fprintf(stderr,"New colors needed\n");
384: else fprintf(stderr,"Old colors match!\n");
385: }
386: cpixels = (unsigned long *)calloc(ncolors+1,sizeof(int));
387: if(XAllocColorCells(dpy, colormap, 0, cplanes, 0, cpixels,
388: (unsigned int) ncolors) == 0)
389:
390: /* Old arguments (for XGetColorCells() in X10) were:
391: 0, ncolors, 0, &cplanes, cpixels %%*/
392:
393: Error("Can't allocate colors.");
394: for(i=0; i<ncolors; i++) {
395: copycolors[i].pixel = cpixels[i];
396: copycolors[i].red = colors[i].red;
397: copycolors[i].green = colors[i].green;
398: copycolors[i].blue = colors[i].blue;
399: if(debug)
400: fprintf(stderr,"Pixel %4d, r = %5d g = %5d b = %5d\n",
401: copycolors[i].pixel, copycolors[i].red,
402: copycolors[i].green, copycolors[i].blue);
403: }
404: XStoreColors(ncolors, copycolors);
405:
406: /* now, make a lookup table to convert old pixels into the new ones*/
407: if(header.pixmap_format == ZPixmap) {
408: if(header.display_planes < 9) {
409: histbuffer = (int *)calloc(256, sizeof(int));
410: bzero(histbuffer, 256*sizeof(int));
411: for(i=0; i<ncolors; i++)
412: histbuffer[colors[i].pixel] = copycolors[i].pixel;
413: for(i=0; i<buffer_size; i++)
414: buffer[i] = histbuffer[buffer[i]];
415: }
416: else if(header.display_planes < 17) {
417: histbuffer = (int *)calloc(65536, sizeof(int));
418: bzero(histbuffer, 65536*sizeof(int));
419: for(i=0; i<ncolors; i++)
420: histbuffer[colors[i].pixel] = copycolors[i].pixel;
421: wbuffer = (u_short *)buffer;
422: for(i=0; i<(buffer_size/sizeof(u_short)); i++)
423: wbuffer[i] = histbuffer[wbuffer[i]];
424: }
425: else if(header.display_planes > 16) {
426: Error("Unable to handle more than 16 planes at this time");
427: }
428: free(histbuffer);
429: }
430: free(cpixels);
431: bcopy(copycolors, colors, sizeof(XColor)*ncolors);
432: free(copycolors);
433: }
434: return colormap;
435: }
436:
437: /*
438: * test two color map entries for equality
439: */
440: ColorEqual(color1, color2)
441: register XColor *color1, *color2;
442: {
443: return(color1->pixel == color2->pixel &&
444: color1->red == color2->red &&
445: color1->green == color2->green &&
446: color1->blue == color2->blue);
447: }
448:
449: #endif
450:
451: int Image_Size(image)
452: XImage *image;
453: {
454: if (image->format != ZPixmap)
455: return(image->bytes_per_line * image->height * image->depth);
456:
457: return(image->bytes_per_line * image->height);
458:
459: }
460:
461: /*
462: * Error - Fatal xwud error.
463: */
464: Error(string)
465: char *string; /* Error description string. */
466: {
467: fprintf(stderr, "xwud: Error => %s\n", string);
468:
469: if (errno != 0) {
470: perror("xwud");
471: fprintf(stderr, "\n");
472: }
473:
474: exit(1);
475: }
476:
477: /* End of xwud.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.