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