|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T x
Length: 12496 (0x30d0) Types: TextFile Names: »xwud.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z« └─⟦2109abc41⟧ └─⟦this⟧ »./X.V10R4/xwud/xwud.c«
#include <X/mit-copyright.h> /* Copyright 1985, 1986, Massachusetts Institute of Technology */ /* * xwud.c - MIT Project Athena, X Window system window raster image * undumper. * * This program will read a raster image of a window from stdin or a file * and display it on an X display. * * Author: Tony Della Fera, DEC * * Modified 11/14/86 by William F. Wyatt, * Smithsonian Astrophysical Observatory * allows writing of monochrome XYFormat window dump files on a color * display, using default WhitePixel for 1's and BlackPixel for 0's. * * Modified 11/20/86 WFW * VERSION 6 - same as V5 for monochrome, but expects color map info * in the file for color images. Checks to see if the requested * colors are already in the display's map (e.g. if the window dump * and undump are contemporaneous to the same display). If so, * undump immediately. If not, request new colors, alter the * pixels to the new values, then write the pixmap. Note that * multi-plane XY format undumps don't work if the pixel values * corresponding to the requested colors have to be changed. */ #ifndef lint static char *rcsid_xwud_c = "$Header: xwud.c,v 10.10 86/11/25 08:44:25 jg Rel $"; #endif #include <X/Xlib.h> #include <stdio.h> #include <strings.h> #include <sys/types.h> extern char *calloc(); #include <X/XWDFile.h> typedef enum _bool {FALSE, TRUE} Bool; #define MAX(a, b) (a) > (b) ? (a) : (b) #define MIN(a, b) (a) < (b) ? (a) : (b) #define ABS(a) (a) < 0 ? -(a) : (a) #define FAILURE 0 extern int errno; main(argc, argv) int argc; char **argv; { register int i; register int *histbuffer; register u_short *wbuffer; register char *buffer; int j, status; int *cpixels, cplanes; int onebufsize; int planes; int forepixel; int backpixel; unsigned buffer_size, total_buffer_size; int win_name_size; char *str_index; char *file_name; char display[256]; char *win_name; Bool standard_in = TRUE; Bool newcolors = FALSE, debug = FALSE, inverse = FALSE; Color *pixcolors, *newpixcolors; Display *dpy; Window image_win; Pixmap image_pixmap; XEvent event; register XExposeEvent *xevent = (XExposeEvent *)&event; XWDFileHeader header; FILE *in_file = stdin; for (i = 1; i < argc; i++) { str_index = (char *)index (argv[i], ':'); if(str_index != NULL) { (void) strncpy(display,argv[i],sizeof(display)); continue; } str_index = (char *) index (argv [i], '-'); if (str_index == NULL) Syntax(argv[0]); if (strncmp(argv[i], "-help", 5) == 0) { Syntax(argv[0]); } if (strncmp(argv[i], "-in", 4) == 0) { if (++i >= argc) Syntax(argv[0]); file_name = argv[i]; standard_in = FALSE; continue; } if(strcmp(argv[i], "-inverse") == 0) { inverse = TRUE; continue; } if(strcmp(argv[i], "-debug") == 0) { debug = TRUE; continue; } Syntax(argv[0]); } if (!standard_in) { /* * Open the output file. */ in_file = fopen(file_name, "r"); if (in_file == NULL) { Error("Can't open output file as specified."); } } /* * Open the display. */ if ((dpy = XOpenDisplay(display)) == NULL) { fprintf(stderr, "%s: Can't open display '%s'\n", argv[0], XDisplayName(display)); exit(1); } /* * Read in header information. */ if(fread((char *)&header, sizeof(header), 1, in_file) != 1) Error("Unable to read dump file header."); /* * check to see if the dump file is in the proper format. */ if (header.file_version != XWD_FILE_VERSION) { fprintf(stderr,"xwud: XWD file format version missmatch."); if(header.file_version == 5 && header.display_planes == 1) fprintf(stderr,"\n (monochrome works anyway)\n"); else Error("exiting."); } if(DisplayPlanes() < header.display_planes) Error("Windump has more planes than display."); /* * Check to see if we are in the right pixmap format for the * display type. */ if ((DisplayPlanes() == 1) && (header.pixmap_format != XYFormat)) { Error( "Windump is in ZFormat which is not valid on a monochrome display."); } /* * Calloc window name. */ win_name_size = ABS(header.header_size - sizeof(header)); if((win_name = calloc((unsigned) win_name_size, sizeof(char))) == NULL) Error("Can't calloc window name storage."); /* * Read in window name. */ if(fread(win_name, sizeof(char), win_name_size, in_file) != win_name_size) Error("Unable to read window name from dump file."); if(debug) fprintf(stderr,"win_name =%s\n", win_name); /* * Determine the pixmap size. */ if (header.pixmap_format == XYFormat) { buffer_size = XYPixmapSize( header.pixmap_width, header.pixmap_height, header.display_planes); total_buffer_size = XYPixmapSize( header.pixmap_width, header.pixmap_height, DisplayPlanes() ); } else if (header.display_planes < 9) { total_buffer_size = buffer_size = BZPixmapSize( header.pixmap_width, header.pixmap_height ); } else if(header.display_planes < 17) { total_buffer_size = buffer_size = WZPixmapSize( header.pixmap_width, header.pixmap_height ); } else { Error("Can't undump pixmaps more than 16 bits deep.\n"); } /* Calloc the color map buffer. * Read it in, copy it and use the copy to query for the * existing colors at those pixel values. */ if(header.window_ncolors) { pixcolors = (Color *)calloc(header.window_ncolors,sizeof(Color)); if(fread(pixcolors,sizeof(Color),header.window_ncolors, in_file) != header.window_ncolors) Error("Unable to read color map from dump file."); if(debug) fprintf(stderr,"Read %d colors\n", header.window_ncolors); newpixcolors = (Color *)calloc(header.window_ncolors,sizeof(Color)); bcopy(pixcolors, newpixcolors, sizeof(Color)*header.window_ncolors); if(XQueryColors(newpixcolors,header.window_ncolors) == 0) Error("Can't query the color map?"); for(i=0; i<header.window_ncolors; i++) if(!ColorEqual(&pixcolors[i], &newpixcolors[i])) { newcolors = TRUE; break; } if(debug) { if(newcolors) fprintf(stderr,"New colors needed\n"); else fprintf(stderr,"Old colors match!\n"); } } /* * Calloc the pixel buffer. */ if((buffer = calloc(total_buffer_size, 1)) == NULL) Error("Can't calloc data buffer."); bzero(buffer,total_buffer_size); /* * Read in the pixmap buffer. */ if((status = fread(buffer, sizeof(char), (int)buffer_size, in_file)) != buffer_size) Error("Unable to read pixmap from dump file."); /* * Close the input file. */ (void) fclose(in_file); /* * If necessary, get and store the new colors, convert the pixels to the * new colors appropriately. */ if(newcolors) { cpixels = (int *)calloc(header.window_ncolors+1,sizeof(int)); if(XGetColorCells(0, header.window_ncolors, 0, &cplanes, cpixels) == 0) Error("Can't allocate colors."); for(i=0; i<header.window_ncolors; i++) { newpixcolors[i].pixel = cpixels[i]; newpixcolors[i].red = pixcolors[i].red; newpixcolors[i].green = pixcolors[i].green; newpixcolors[i].blue = pixcolors[i].blue; if(debug) fprintf(stderr,"Pixel %4d, r = %5d g = %5d b = %5d\n", newpixcolors[i].pixel, newpixcolors[i].red, newpixcolors[i].green, newpixcolors[i].blue); } XStoreColors(header.window_ncolors, newpixcolors); /* now, make a lookup table to convert old pixels into the new ones*/ if(header.pixmap_format == ZFormat) { if(header.display_planes < 9) { histbuffer = (int *)calloc(256, sizeof(int)); bzero(histbuffer, 256*sizeof(int)); for(i=0; i<header.window_ncolors; i++) histbuffer[pixcolors[i].pixel] = newpixcolors[i].pixel; for(i=0; i<buffer_size; i++) buffer[i] = histbuffer[buffer[i]]; } else if(header.display_planes < 17) { histbuffer = (int *)calloc(65536, sizeof(int)); bzero(histbuffer, 65536*sizeof(int)); for(i=0; i<header.window_ncolors; i++) histbuffer[pixcolors[i].pixel] = newpixcolors[i].pixel; wbuffer = (u_short *)buffer; for(i=0; i<(buffer_size/sizeof(u_short)); i++) wbuffer[i] = histbuffer[wbuffer[i]]; } else if(header.display_planes > 16) { Error("Unable to handle more than 16 planes at this time"); } free(histbuffer); } free(cpixels); bcopy(newpixcolors, pixcolors, sizeof(Color)*header.window_ncolors); free(newpixcolors); } /* * Create the image window. */ image_win = XCreateWindow( RootWindow, header.window_x, header.window_y, header.pixmap_width, header.pixmap_height, 0, (Pixmap) 0, (Pixmap) 0 ); if (image_win == FAILURE) Error("Can't create image window."); /* * Select mouse ButtonPressed on the window, this is how we determine * when to stop displaying the window. */ XSelectInput(image_win, (ButtonPressed | ExposeWindow | ExposeRegion)); /* * Store the window name string. */ XStoreName(image_win, win_name); /* * Map the image window. */ XMapWindow(image_win); /* * Set up a while loop to maintain the image. */ while (TRUE) { int i, nbytes; /* * Wait on mouse input event to terminate. */ XNextEvent(&event); if (event.type == ButtonPressed) break; switch((int)event.type) { case ExposeWindow: /* Copy the data into the window.*/ case ExposeRegion: /* simpler to copy from x=0 for full width */ if(header.pixmap_format == XYFormat) { onebufsize = /* size of each bitmap */ XYPixmapSize(header.pixmap_width, header.pixmap_height, 1); nbytes = BitmapSize(header.pixmap_width,1); if(header.display_planes > 1) { forepixel = -1; backpixel = 0; planes = 1<<(DisplayPlanes()); /* MSB << 1 */ } else { forepixel = WhitePixel; backpixel = BlackPixel; planes = AllPlanes; } for(j=0; j<header.display_planes; j++) { if(header.display_planes > 1) planes >>= 1; /* shift down a bit */ for(i=0; i<xevent->height; i+=100) if(inverse) XBitmapBitsPut(image_win, 0, i + xevent->y, header.pixmap_width, MIN(100, xevent->height - i), buffer+((i+xevent->y)*nbytes) + (onebufsize * j), backpixel, forepixel, 0, GXcopy, planes); else XBitmapBitsPut(image_win, 0, i + xevent->y, header.pixmap_width, MIN(100, xevent->height - i), buffer+((i+xevent->y)*nbytes) + (onebufsize * j), forepixel, backpixel, 0, GXcopy, planes); } } else if(DisplayPlanes() < 9) { nbytes = BZPixmapSize(header.pixmap_width,1); for(i=0; i<xevent->height; i+=100) XPixmapBitsPutZ(image_win, 0, i + xevent->y, header.pixmap_width, MIN(100, xevent->height - i), buffer+((i+xevent->y)*nbytes), 0, GXcopy, AllPlanes); } else { /* Display Planes > 8 */ nbytes = WZPixmapSize(header.pixmap_width, 1); for(i=0; i<xevent->height; i+=100) XPixmapBitsPutZ(image_win, 0, i + xevent->y, header.pixmap_width, MIN(50, xevent->height - i), buffer+((i+xevent->y)*nbytes), 0, GXcopy, AllPlanes); } } } /* * Destroy the image window. */ XDestroyWindow(image_win); /* * Free the pixmap buffer. */ free(buffer); /* * Free window name string. */ free(win_name); exit(0); } /* * test two color map entries for equality */ ColorEqual(color1, color2) register Color *color1, *color2; { return(color1->pixel == color2->pixel && color1->red == color2->red && color1->green == color2->green && color1->blue == color2->blue); } /* * Report the syntax for calling xwud. */ Syntax(call) char *call; { fprintf( stderr, "xwud: %s [-help][-debug][-inverse][-in <file>][[host]:vs]\n", call ); exit(1); } /* * Error - Fatal xwud error. */ Error(string) char *string; /* Error description string. */ { fprintf(stderr, "xwud: Error => %s\n", string); if (errno != 0) { perror("xwud"); fprintf(stderr, "\n"); } exit(1); } /* End of xwud.c */