BSD 4_3_Tahoe development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Mon, 1 Dec 1986 10:28:39 +0000 (02:28 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Mon, 1 Dec 1986 10:28:39 +0000 (02:28 -0800)
Work on file usr/src/new/X/xwud/Makefile
Work on file usr/src/new/X/xwud/xwud.c

Synthesized-from: CSRG/cd2/4.3tahoe

usr/src/new/X/xwud/Makefile [new file with mode: 0644]
usr/src/new/X/xwud/xwud.c [new file with mode: 0644]

diff --git a/usr/src/new/X/xwud/Makefile b/usr/src/new/X/xwud/Makefile
new file mode 100644 (file)
index 0000000..ff2fc33
--- /dev/null
@@ -0,0 +1,42 @@
+# Copyright 1985, Massachusetts Institute of Technology
+#      xwud - makefile for the Athena X window system window
+#                 window raster image undumper.
+#
+#              Written by:     Tony Della Fera, DEC
+#
+
+DESTDIR =
+INCLUDES = -I../include
+
+CONFDIR = /usr/new
+XLIB = ../Xlib/libX.a
+XH = ../Xlib/Xlib.h
+
+CFLAGS = -O $(INCLUDES)
+CLIBS =
+
+.SUFFIXES: .o .h .c .a
+
+OBJS = xwud.o
+
+all: xwud
+
+xwud: $(OBJS)
+       $(CC) $(CFLAGS) -o xwud $(OBJS) $(XLIB) $(CLIBS)
+
+xwud.o: ../include/X/XWDFile.h $(XH)
+
+link:
+       $(CC) $(CFLAGS) -o xwud $(OBJS) $(XLIB) $(CLIBS)
+
+install: all
+       install -s xwud $(DESTDIR)$(CONFDIR)
+       chmod 755 $(DESTDIR)$(CONFDIR)/xwud
+
+clean: 
+       rm -f *~* *.bak core \#*
+       rm -f xwud.c.[0-9]* Makefile.[0-9]* xwud.1.[0-9]*
+       rm -f xwud.o xwud
+
+igrind:
+       igrind xwud.c
diff --git a/usr/src/new/X/xwud/xwud.c b/usr/src/new/X/xwud/xwud.c
new file mode 100644 (file)
index 0000000..d20af42
--- /dev/null
@@ -0,0 +1,466 @@
+#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 */