|
|
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.