[comp.sources.x] v04i095: Another xwps program, Part01/01

argv@island.uu.net (Dan Heller) (08/26/89)

Submitted-by: bchen@esvax.Berkeley.EDU (Benjamin Chen)
Posting-number: Volume 4, Issue 95
Archive-name: xwps2/part01

[ Here's another xwps program.  What I like best about it is that it has
  a set of common routines that all beginning X programmers are always
  asking how to do.  Novices: check out dsimple.c.  Much content of this
  program was taken from other existing programs.  Works under R2 and does
  not use widgets.  README is at the end of the file.  --argv ]

#! /bin/sh
export PATH || exec /bin/sh $0 $*
: # This is a shell archive.  Remove anything before #! /bin/sh line, then
: # unpack it by saving it in a file and typing "sh file", creating files:
: #	'dsimple.c'
: #	'psfile.c'
: #	'xwps.c'
: #	'dsimple.h'
: #	'extern.h'
: #	'Makefile'
: #	'README'
: # Made by wong on Thu Jul 20 14:31:47 PDT 1989
PATH="/bin:/usr/bin:/usr/ucb:$PATH"
export PATH
prog="`basename \"$0\"`"
error=0
if test -f 'dsimple.c' -o -d 'dsimple.c'; then
	echo "$prog: \"dsimple.c\" exists, skipping" >&2
	error=1
else
	echo 'x - dsimple.c'
	sed -e 's/^X//' << 'EOF dsimple.c' > 'dsimple.c'
X/* $Header: dsimple.c,v 1.5 88/02/09 11:28:35 jim Exp $ */
X#include <X11/Xos.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/cursorfont.h>
X#include <stdio.h>
X/*
X * Other_stuff.h: Definitions of routines in other_stuff.
X *
X * Written by Mark Lillibridge.   Last updated 7/1/87
X *
X * Send bugs, etc. to chariot@athena.mit.edu.
X */
X
Xunsigned long Resolve_Color();
XPixmap Bitmap_To_Pixmap();
XWindow Select_Window();
Xvoid out();
Xvoid blip();
XWindow Window_With_Name();
X/*
X * Just_display: A group of routines designed to make the writting of simple
X *               X11 applications which open a display but do not open
X *               any windows much faster and easier.  Unless a routine says
X *               otherwise, it may be assumed to require program_name, dpy,
X *               and screen already defined on entry.
X *
X * Written by Mark Lillibridge.   Last updated 7/1/87
X *
X * Send bugs, etc. to chariot@athena.mit.edu.
X */
X
X
X/* This stuff is defined in the calling program by just_display.h */
Xextern char *program_name;
Xextern Display *dpy;
Xextern int screen;
X
X
X/*
X * Standard fatal error routine - call like printf but maximum of 7 arguments.
X * Does not require dpy or screen defined.
X */
Xvoid Fatal_Error(msg, arg0,arg1,arg2,arg3,arg4,arg5,arg6)
Xchar *msg;
Xchar *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6;
X{
X	fflush(stdout);
X	fflush(stderr);
X	fprintf(stderr, "%s: error: ", program_name);
X	fprintf(stderr, msg, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
X	fprintf(stderr, "\n");
X	exit(1);
X}
X
X
X/*
X * Malloc: like malloc but handles out of memory using Fatal_Error.
X */
Xchar *Malloc(size)
X     unsigned size;
X{
X	char *data, *malloc();
X
X	if (!(data = malloc(size)))
X	  Fatal_Error("Out of memory!");
X
X	return(data);
X}
X	
X
X/*
X * Realloc: like Malloc except for realloc, handles NULL using Malloc.
X */
Xchar *Realloc(ptr, size)
X        char *ptr;
X        int size;
X{
X	char *new_ptr, *realloc();
X
X	if (!ptr)
X	  return(Malloc(size));
X
X	if (!(new_ptr = realloc(ptr, size)))
X	  Fatal_Error("Out of memory!");
X
X	return(new_ptr);
X}
X
X
X/*
X * Get_Display_Name (argc, argv) Look for -display, -d, or host:dpy (obselete)
X * If found, remove it from command line.  Don't go past a lone -.
X */
Xchar *Get_Display_Name(pargc, argv)
X    int *pargc;  /* MODIFIED */
X    char **argv; /* MODIFIED */
X{
X    int argc = *pargc;
X    char **pargv = argv+1;
X    char *displayname = NULL;
X    int i;
X
X    for (i = 1; i < argc; i++) {
X	char *arg = argv[i];
X
X	if (!strcmp (arg, "-display") || !strcmp (arg, "-d")) {
X	    if (++i >= argc) usage ();
X
X	    displayname = argv[i];
X	    *pargc -= 2;
X	    continue;
X	}
X	if (!strcmp(arg,"-")) {
X		while (i<argc)
X			*pargv++ = argv[i++];
X		break;
X	}
X	*pargv++ = arg;
X    }
X
X    *pargv = NULL;
X    return (displayname);
X}
X
X
X/*
X * Open_Display: Routine to open a display with correct error handling.
X *               Does not require dpy or screen defined on entry.
X */
XDisplay *Open_Display(display_name)
Xchar *display_name;
X{
X	Display *d;
X
X	d = XOpenDisplay(display_name);
X	if (d == NULL) {
X	    fprintf (stderr, "%s:  unable to open display '%s'\n",
X		     program_name, XDisplayName (display_name));
X	    usage ();
X	    /* doesn't return */
X	}
X
X	return(d);
X}
X
X
X/*
X * Setup_Display_And_Screen: This routine opens up the correct display (i.e.,
X *                           it calls Get_Display_Name) and then stores a
X *                           pointer to it in dpy.  The default screen
X *                           for this display is then stored in screen.
X *                           Does not require dpy or screen defined.
X */
Xvoid Setup_Display_And_Screen(argc, argv)
Xint *argc;      /* MODIFIED */
Xchar **argv;    /* MODIFIED */
X{
X	dpy = Open_Display (Get_Display_Name(argc, argv));
X	screen = DefaultScreen(dpy);
X}
X
X
X/*
X * Open_Font: This routine opens a font with error handling.
X */
XXFontStruct *Open_Font(name)
Xchar *name;
X{
X	XFontStruct *font;
X
X	if (!(font=XLoadQueryFont(dpy, name)))
X	  Fatal_Error("Unable to open font %s!", name);
X
X	return(font);
X}
X
X
X/*
X * Beep: Routine to beep the display.
X */
Xvoid Beep()
X{
X	XBell(dpy, 50);
X}
X
X
X/*
X * ReadBitmapFile: same as XReadBitmapFile except it returns the bitmap
X *                 directly and handles errors using Fatal_Error.
X */
Xstatic void _bitmap_error(status, filename)
X     int status;
X     char *filename;
X{
X  if (status == BitmapOpenFailed)
X    Fatal_Error("Can't open file %s!", filename);
X  else if (status == BitmapFileInvalid)
X    Fatal_Error("file %s: Bad bitmap format.", filename);
X  else
X    Fatal_Error("Out of memory!");
X}
X
XPixmap ReadBitmapFile(d, filename, width, height, x_hot, y_hot)
X     Drawable d;
X     char *filename;
X     int *width, *height, *x_hot, *y_hot;
X{
X  Pixmap bitmap;
X  int status;
X
X  status = XReadBitmapFile(dpy, RootWindow(dpy, screen), filename, width,
X			   height, &bitmap, x_hot, y_hot);
X  if (status != BitmapSuccess)
X    _bitmap_error(status, filename);
X
X  return(bitmap);
X}
X
X
X/*
X * WriteBitmapFile: same as XWriteBitmapFile except it handles errors
X *                  using Fatal_Error.
X */
Xvoid WriteBitmapFile(filename, bitmap, width, height, x_hot, y_hot)
X     char *filename;
X     Pixmap bitmap;
X     int width, height, x_hot, y_hot;
X{
X  int status;
X
X  status= XWriteBitmapFile(dpy, filename, bitmap, width, height, x_hot,
X			   y_hot);
X  if (status != BitmapSuccess)
X    _bitmap_error(status, filename);
X}
X
X
X/*
X * Select_Window_Args: a rountine to provide a common interface for
X *                     applications that need to allow the user to select one
X *                     window on the screen for special consideration.
X *                     This routine implements the following command line
X *                     arguments:
X *
X *                       -root            Selects the root window.
X *                       -id <id>         Selects window with id <id>. <id> may
X *                                        be either in decimal or hex.
X *                       -name <name>     Selects the window with name <name>.
X *
X *                     Call as Select_Window_Args(&argc, argv) in main before
X *                     parsing any of your program's command line arguments.
X *                     Select_Window_Args will remove its arguments so that
X *                     your program does not have to worry about them.
X *                     The window returned is the window selected or 0 if
X *                     none of the above arguments was present.  If 0 is
X *                     returned, Select_Window should probably be called after
X *                     all command line arguments, and other setup is done.
X *                     For examples of usage, see xwininfo, xwd, or xprop.
X */
XWindow Select_Window_Args(rargc, argv)
X     int *rargc;
X     char **argv;
X#define ARGC (*rargc)
X{
X	int nargc=1;
X	int argc;
X	char **nargv;
X	Window w=0;
X
X	nargv = argv+1; argc = ARGC;
X#define OPTION argv[0]
X#define NXTOPTP ++argv, --argc>0
X#define NXTOPT if (++argv, --argc==0) usage()
X#define COPYOPT nargv++[0]=OPTION; nargc++
X
X	while (NXTOPTP) {
X		if (!strcmp(OPTION, "-")) {
X			COPYOPT;
X			while (NXTOPTP)
X			  COPYOPT;
X			break;
X		}
X		if (!strcmp(OPTION, "-root")) {
X			w=RootWindow(dpy, screen);
X			continue;
X		}
X		if (!strcmp(OPTION, "-name")) {
X			NXTOPT;
X			w = Window_With_Name(dpy, RootWindow(dpy, screen),
X					     OPTION);
X			if (!w)
X			  Fatal_Error("No window with name %s exists!",OPTION);
X			continue;
X		}
X		if (!strcmp(OPTION, "-id")) {
X			NXTOPT;
X			w=0;
X			sscanf(OPTION, "0x%lx", &w);
X			if (!w)
X			  sscanf(OPTION, "%ld", &w);
X			if (!w)
X			  Fatal_Error("Invalid window id format: %s.", OPTION);
X			continue;
X		}
X		COPYOPT;
X	}
X	ARGC = nargc;
X	
X	return(w);
X}
X
X/*
X * Other_stuff: A group of routines which do common X11 tasks.
X *
X * Written by Mark Lillibridge.   Last updated 7/1/87
X *
X * Send bugs, etc. to chariot@athena.mit.edu.
X */
X
X
X#define NULL 0
X
Xextern Display *dpy;
Xextern int screen;
X
X/*
X * Resolve_Color: This routine takes a color name and returns the pixel #
X *                that when used in the window w will be of color name.
X *                (WARNING:  The colormap of w MAY be modified! )
X *                If colors are run out of, only the first n colors will be
X *                as correct as the hardware can make them where n depends
X *                on the display.  This routine does not require wind to
X *                be defined.
X */
Xunsigned long Resolve_Color(w, name)
X     Window w;
X     char *name;
X{
X	XColor c;
X	Colormap colormap;
X	XWindowAttributes wind_info;
X
X	/*
X	 * The following is a hack to insure machines without a rgb table
X	 * handle at least white & black right.
X	 */
X	if (!strcmp(name, "white"))
X	  name="#ffffffffffff";
X	if (!strcmp(name, "black"))
X	  name="#000000000000";
X
X	XGetWindowAttributes(dpy, w, &wind_info);
X	colormap = wind_info.colormap;
X
X	if (!XParseColor(dpy, colormap, name, &c))
X	  Fatal_Error("Bad color format '%s'.", name);
X
X	if (!XAllocColor(dpy, colormap, &c))
X	  Fatal_Error("XAllocColor failed!");
X
X	return(c.pixel);
X}
X
X
X/*
X * Bitmap_To_Pixmap: Convert a bitmap to a 2 colored pixmap.  The colors come
X *                   from the foreground and background colors of the gc.
X *                   Width and height are required solely for efficiency.
X *                   If needed, they can be obtained via. XGetGeometry.
X */
XPixmap Bitmap_To_Pixmap(dpy, d, gc, bitmap, width, height)
X     Display *dpy;
X     Drawable d;
X     GC gc;
X     Pixmap bitmap;
X     int width, height;
X{
X  Pixmap pix;
X  int x, depth;
X  Drawable root;
X
X  if (!XGetGeometry(dpy, d, &root, &x, &x, &x, &x, &x, &depth))
X    return(0);
X
X  pix = XCreatePixmap(dpy, d, width, height, depth);
X
X  XCopyPlane(dpy, bitmap, pix, gc, 0, 0, width, height, 0, 0, 1);
X
X  return(pix);
X}
X
X
X/*
X * outl: a debugging routine.  Flushes stdout then prints a message on stderr
X *       and flushes stderr.  Used to print messages when past certain points
X *       in code so we can tell where we are.  Outl may be invoked like
X *       printf with up to 7 arguments.
X */
Xoutl(msg, arg0,arg1,arg2,arg3,arg4,arg5,arg6)
X     char *msg;
X     char *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6;
X{
X	fflush(stdout);
X	fprintf(stderr, msg, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
X	fprintf(stderr, "\n");
X	fflush(stderr);
X}
X
X
X/*
X * blip: a debugging routine.  Prints Blip! on stderr with flushing. 
X */
Xvoid blip()
X{
X  outl("blip!");
X}
X
X
X/*
X * Routine to let user select a window using the mouse
X */
X
XWindow Select_Window(dpy)
X     Display *dpy;
X{
X  int status;
X  Cursor cursor;
X  XEvent event;
X  Window target_win = None;
X  int buttons = 0;
X
X  /* Make the target cursor */
X  cursor = XCreateFontCursor(dpy, XC_dot);
X
X  /* Grab the pointer using target cursor, letting it room all over */
X  status = XGrabPointer(dpy, RootWindow(dpy, screen), False,
X			ButtonPressMask|ButtonReleaseMask, GrabModeSync,
X			GrabModeAsync, None, cursor, CurrentTime);
X  if (status != GrabSuccess) Fatal_Error("Can't grab the mouse.");
X
X  /* Let the user select a window... */
X  while ((target_win == None) || (buttons != 0)) {
X    /* allow one more event */
X    XAllowEvents(dpy, SyncPointer, CurrentTime);
X    XWindowEvent(dpy, RootWindow(dpy, screen),
X		 ButtonPressMask|ButtonReleaseMask, &event);
X    switch (event.type) {
X    case ButtonPress:
X      if (target_win == None) {
X	target_win = event.xbutton.subwindow; /* window selected */
X	if (target_win == None)
X	  target_win = RootWindow(dpy, screen);
X      }
X      buttons++;
X      break;
X    case ButtonRelease:
X      if (buttons > 0) /* there may have been some down before we started */
X	buttons--;
X       break;
X    }
X  } 
X  XUngrabPointer(dpy, CurrentTime);      /* Done with pointer */
X
X  return(target_win);
X}
X
X
X/*
X * Window_With_Name: routine to locate a window with a given name on a display.
X *                   If no window with the given name is found, 0 is returned.
X *                   If more than one window has the given name, the first
X *                   one found will be returned.  Only top and its subwindows
X *                   are looked at.  Normally, top should be the RootWindow.
X */
XWindow Window_With_Name(dpy, top, name)
X     Display *dpy;
X     Window top;
X     char *name;
X{
X	Window *children, dummy;
X	int nchildren, i;
X	Window w=0;
X	char *window_name;
X
X	if (XFetchName(dpy, top, &window_name) && !strcmp(window_name, name))
X	  return(top);
X
X	if (!XQueryTree(dpy, top, &dummy, &dummy, &children, &nchildren))
X	  return(0);
X
X	for (i=0; i<nchildren; i++) {
X		w = Window_With_Name(dpy, children[i], name);
X		if (w)
X		  break;
X	}
X	XFree(children);
X	return(w);
X}
EOF dsimple.c
	case "`echo \`wc < 'dsimple.c'\``" in
	"499 1633 12545")
		;;
	*)
		echo "$prog: \"dsimple.c\" corrupted" >&2
		error=1
		;;
	esac
fi ; : # End of overwrite check
if test -f 'psfile.c' -o -d 'psfile.c'; then
	echo "$prog: \"psfile.c\" exists, skipping" >&2
	error=1
else
	echo 'x - psfile.c'
	sed -e 's/^X//' << 'EOF psfile.c' > 'psfile.c'
X#include "extern.h"
X
Xvoid openImage(psFile,width,height)
X    FILE *psFile;
X    int width, height;
X{
X    fprintf(psFile, "%%!\n");
X    fprintf(psFile, "/inch {72 mul} def\n");
X    fprintf(psFile, "/picstr %d string def\n", width);
X    fprintf(psFile, "/plotimage\n");
X    fprintf(psFile, " {%d %d %d [%d 0 0 %d 0 %d] \n", width, height,
X	    BITS_PER_SAMPLE, width, -height, height);
X    fprintf(psFile,"   {currentfile picstr readhexstring pop} \n");
X    fprintf(psFile,"   image\n } def\n");
X    fprintf(psFile, "gsave\n");
X    fprintf(psFile, "%.2f inch %.2f inch translate\n", translateX, translateY);
X    fprintf(psFile, "%.2f inch %.2f inch scale\n", scaleX, scaleY);
X    fprintf(psFile, "%d rotate\n", rotation);
X    fflush(psFile);
X}
X
Xvoid closeImage(psFile)
X	FILE *psFile;
X{
X    fprintf(psFile, "grestore\n");
X    fprintf(psFile, "showpage\n");
X    fflush(psFile);
X}
X 
Xvoid writeImage(psFile, ximage, width, height)
X     FILE *psFile;
X     XImage *ximage;
X     int width, height;
X{
X    int x, y;
X    XColor *pix;
X
X    pix = (XColor *)malloc(sizeof(XColor));
X    /* Output is hexadecimal */
X    fprintf(psFile, "plotimage\n");
X	for(y=0;y<height;y++){
X	    for(x=0;x<width;x++){
X		pix->pixel = XGetPixel(ximage,x,y);
X		pix->red = (pix->pixel >> 16 & 0xFF);
X		pix->green = (pix->pixel >> 8 & 0xFF);
X		pix->blue = (pix->pixel & 0xFF);
X		pix->pixel = luminance(*pix);
X		fprintf(psFile, "%02x", pix->pixel);
X	    }
X	    fprintf(psFile, "\n");
X	}
X    fprintf(psFile, "\n");
X}
X
Xint luminance(colorSpec)
X XColor colorSpec;
X{
X    int r, g, b, l;
X
X    r = 255 - (colorSpec.red);
X    g = 255 - (colorSpec.green);
X    b = 255 - (colorSpec.blue);
X    l = (0.33*r) + (0.33*g) + (0.34*b);
X    if(inverse) return(l);
X    else return(abs(l - 255));
X}
X
EOF psfile.c
	case "`echo \`wc < 'psfile.c'\``" in
	"67 193 1742")
		;;
	*)
		echo "$prog: \"psfile.c\" corrupted" >&2
		error=1
		;;
	esac
fi ; : # End of overwrite check
if test -f 'xwps.c' -o -d 'xwps.c'; then
	echo "$prog: \"xwps.c\" exists, skipping" >&2
	error=1
else
	echo 'x - xwps.c'
	sed -e 's/^X//' << 'EOF xwps.c' > 'xwps.c'
X#include <X11/copyright.h>
X
X/* Copyright 1987 Massachusetts Institute of Technology */
X
X/*
X * xwd.c MIT Project Athena, X Window system window raster image dumper.
X *
X * This program will dump a raster image of the contents of a window into a 
X * file for output on graphics printers or for other uses.
X *
X *  Author:	Tony Della Fera, DEC
X *		17-Jun-85
X * 
X *  Modification history:
X *
X *  11/14/86 Bill Wyatt, Smithsonian Astrophysical Observatory
X *    - Removed Z format option, changing it to an XY option. Monochrome 
X *      windows will always dump in XY format. Color windows will dump
X *      in Z format by default, but can be dumped in XY format with the
X *      -xy option.
X *
X *  11/18/86 Bill Wyatt
X *    - VERSION 6 is same as version 5 for monchrome. For colors, the 
X *      appropriate number of Color structs are dumped after the header,
X *      which has the number of colors (=0 for monochrome) in place of the
X *      V5 padding at the end. Up to 16-bit displays are supported. I
X *      don't yet know how 24- to 32-bit displays will be handled under
X *      the Version 11 protocol.
X *
X *  6/15/87 David Krikorian, MIT Project Athena
X *    - VERSION 7 runs under the X Version 11 servers, while the previous
X *      versions of xwd were are for X Version 10.  This version is based
X *      on xwd version 6, and should eventually have the same color
X *      abilities. (Xwd V7 has yet to be tested on a color machine, so
X *      all color-related code is commented out until color support
X *      becomes practical.)
X */
X
X#ifndef lint
Xstatic char *rcsid_xwd_c = "$Header: xwd.c,v 1.34 88/02/12 13:24:59 jim Exp $";
X#endif
X
X/*%
X *%    This is the format for commenting out color-related code until
X *%  color can be supported.
X */
X
X#define FEEP_VOLUME 0
X#define DECLARE
X#include "extern.h"
X
X/* Include routines to do parsing */
X#include "dsimple.h"
X
Xextern int (*_XErrorFunction)();
Xextern int _XDefaultError();
X
Xmain(argc, argv)
X    int argc;
X    char **argv;
X{
X    register i;
X    FILE *fopen();
X
X    INIT_NAME;
X
X    Setup_Display_And_Screen(&argc, argv);
X
X    /* Get window select on command line, if any */
X    target_win = Select_Window_Args(&argc, argv);
X
X    for (i = 1; i < argc; i++) {
X	if (!strcmp(argv[i], "-borders")) {
X	    bdrs = False;
X	    continue;
X	}
X	if (!strcmp(argv[i], "-debug")) {
X	    debug = True;
X	    continue;
X	}
X	if (!strcmp(argv[i], "-help"))
X	  usage();
X	if (!strcmp(argv[i], "-out")) {
X	    if (++i >= argc) usage();
X	    if (!(out_file = fopen(argv[i], "w"))){
X	      Error("Can't open output file as specified.");
X	      out_file = stdout;
X	    }
X	    continue;
X	}
X	if (!strcmp(argv[i], "-xy")) {
X	    format = XYPixmap;
X	    continue;
X	}
X	if(!strcmp(argv[i], "-rot")) {
X	    sscanf(argv[++i],"%d",&rotation); 
X	    continue;
X	}
X	if(!strcmp(argv[i], "-scale")){
X	    sscanf(argv[++i],"%d",&scaleX);
X	    sscanf(argv[++i],"%d",&scaleY);
X	    continue;
X	}
X	if(!strcmp(argv[i],"-off")){
X	    sscanf(argv[++i],"%d",&translateX);
X	    sscanf(argv[++i],"%d",&translateY);
X	    continue;
X	}
X	if(!strcmp(argv[i],"-inv")){
X	    inverse = 1;
X	    continue;
X	}
X		
X	usage();
X    }
X    
X    /*
X     * Let the user select the target window.
X     */
X    if (!target_win)
X      target_win = Select_Window(dpy);
X
X    /*
X     * Dump the window 
X     */
X    Window_Dump(target_win,out_file);
X
X    fclose(out_file);
X
X
X
X}
X
X
X/*
X * Window_Dump: dump a window to a file which must already be open for
X *              writting.
X */
X
Xchar *calloc();
X
X#include "X11/XWDFile.h"
X
XWindow_Dump(window, out)
X     Window window;
X     FILE *out;
X{
X    unsigned long swaptest = 1;
X    XColor *colors;
X    unsigned buffer_size;
X    int win_name_size;
X    int header_size;
X    int ncolors, i;
X    char *win_name;
X    XWindowAttributes win_info;
X    XImage *image;
X
X    XWDFileHeader header;
X
X    
X    /*
X     * Inform the user not to alter the screen.
X     */
X    Beep();
X
X    /*
X     * Get the parameters of the window being dumped.
X     */
X    if (debug) outl("xwd: Getting target window information.\n");
X    if(!XGetWindowAttributes(dpy, window, &win_info)) 
X      Fatal_Error("Can't get target window attributes.");
X
X    XFetchName(dpy, window, &win_name);
X    if (!win_name || !win_name[0])
X      win_name = "xwdump";
X
X    /* sizeof(char) is included for the null string terminator. */
X    win_name_size = strlen(win_name) + sizeof(char);
X
X    /*
X     * Snarf the pixmap with XGetImage.
X     */
X
X    if (!bdrs) {
X      	if (debug) outl("xwd: Image without borders selected.\n");
X	image = XGetImage ( dpy, window, 0, 0, win_info.width,
X			   win_info.height, ~0, format); 
X      }
X    else {
X	if (debug) outl("xwd: Image with borders selected.\n");
X	image = XGetImage ( dpy, window,
X			   -win_info.border_width, -win_info.border_width, 
X			   win_info.width + (win_info.border_width << 1),
X			   win_info.height + (win_info.border_width << 1),
X			   ~0, format); 
X      }
X    if (debug) outl("xwd: Getting pixmap.\n");
X
X    /*
X     * Determine the pixmap size.
X     */
X    buffer_size = Image_Size(image);
X
X    if (debug) outl("xwd: Getting Colors.\n");
X
X    ncolors = Get_XColors(&win_info, &colors);
X
X    /*
X     * Inform the user that the image has been retrieved.
X     */
X    XBell(dpy, FEEP_VOLUME);
X    XBell(dpy, FEEP_VOLUME);
X    XFlush(dpy);
X
X    /*
X     * Calculate header size.
X     */
X    if (debug) outl("xwd: Calculating header size.\n");
X    header_size = sizeof(header) + win_name_size;
X
X    /*
X     * Write out header information.
X     */
X    if (debug) outl("xwd: Constructing and dumping file header.\n");
X    header.header_size = (xwdval) header_size;
X    header.file_version = (xwdval) XWD_FILE_VERSION;
X    header.pixmap_format = (xwdval) format;
X    header.pixmap_depth = (xwdval) image->depth;
X    header.pixmap_width = (xwdval) image->width;
X    header.pixmap_height = (xwdval) image->height;
X    header.xoffset = (xwdval) image->xoffset;
X    header.byte_order = (xwdval) image->byte_order;
X    header.bitmap_unit = (xwdval) image->bitmap_unit;
X    header.bitmap_bit_order = (xwdval) image->bitmap_bit_order;
X    header.bitmap_pad = (xwdval) image->bitmap_pad;
X    header.bits_per_pixel = (xwdval) image->bits_per_pixel;
X    header.bytes_per_line = (xwdval) image->bytes_per_line;
X    header.visual_class = (xwdval) win_info.visual->class;
X    header.red_mask = (xwdval) win_info.visual->red_mask;
X    header.green_mask = (xwdval) win_info.visual->green_mask;
X    header.blue_mask = (xwdval) win_info.visual->blue_mask;
X    header.bits_per_rgb = (xwdval) win_info.visual->bits_per_rgb;
X    header.colormap_entries = (xwdval) win_info.visual->map_entries;
X    header.ncolors = ncolors;
X    header.window_width = (xwdval) win_info.width;
X    header.window_height = (xwdval) win_info.height;
X    if (!bdrs) {
X      header.window_x = (xwdval) (win_info.x + win_info.border_width);
X      header.window_y = (xwdval) (win_info.y + win_info.border_width);
X    } else {
X      header.window_x = (xwdval) win_info.x;
X      header.window_y = (xwdval) win_info.y;
X    }
X    header.window_bdrwidth = (xwdval) win_info.border_width;
X
X    if (*(char *) &swaptest) {
X	_swaplong((char *) &header, sizeof(header));
X	for (i = 0; i < ncolors; i++) {
X	    _swaplong((char *) &colors[i].pixel, sizeof(long));
X	    _swapshort((char *) &colors[i].red, 3 * sizeof(short));
X	}
X    }
X
X    /*
X     * (void) fwrite((char *)&header, sizeof(header), 1, out);
X     * (void) fwrite(win_name, win_name_size, 1, out);
X     */
X
X     openImage(out, header.pixmap_width, header.pixmap_height);
X     writeImage(out,image,header.pixmap_width, header.pixmap_height);
X     closeImage(out);
X
X    /*
X     * Write out the color maps, if any
X     */
X
X    /*
X     * if (debug) outl("xwd: Dumping %d colors.\n", ncolors);
X     * (void) fwrite((char *) colors, sizeof(XColor), ncolors, out);
X     */
X
X    /*
X     * Write out the buffer.
X     */
X    if (debug) outl("xwd: Dumping pixmap.  bufsize=%d\n",buffer_size);
X
X    /*
X     *    This copying of the bit stream (data) to a file is to be replaced
X     *  by an Xlib call which hasn't been written yet.  It is not clear
X     *  what other functions of xwd will be taken over by this (as yet)
X     *  non-existant X function.
X     */
X
X    /* 
X     * (void) fwrite(image->data, (int) buffer_size, 1, out);
X     */
X
X    /*
X     * free the color buffer.
X     */
X
X    if(debug && ncolors > 0) outl("xwd: Freeing colors.\n");
X    if(ncolors > 0) free(colors);
X
X    /*
X     * Free window name string.
X     *
X    if (debug) outl("xwd: Freeing window name string.\n");
X    free((char *)win_name);
X    */
X
X    /*
X     * Free image
X     */
X    XDestroyImage(image);
X}
X
X/*
X * Report the syntax for calling xwd.
X */
Xusage()
X{
X    fprintf (stderr,
X"usage: %s [-display host:dpy] [-debug] [-help] [-borders] [-out <file>]",
X	   program_name);
X    fprintf (stderr, " [-xy]\n\t[-rot <rotation>] [-scale <x y>] [-off <x y>] [-inv]\n");
X    exit(1);
X}
X
X
X/*
X * Error - Fatal xwd error.
X */
Xextern int errno;
X
XError(string)
X	char *string;	/* Error description string. */
X{
X	outl("\nxwd: Error => %s\n", string);
X	if (errno != 0) {
X		perror("xwd");
X		outl("\n");
X	}
X
X	exit(1);
X}
X
X
X/*
X * Determine the pixmap size.
X */
X
Xint Image_Size(image)
X     XImage *image;
X{
X    if (format != ZPixmap)
X      return(image->bytes_per_line * image->height * image->depth);
X
X    return(image->bytes_per_line * image->height);
X}
X
X
X/*
X * Get the XColors of all pixels in image - returns # of colors
X */
Xint Get_XColors(win_info, colors)
X     XWindowAttributes *win_info;
X     XColor **colors;
X{
X    int i, ncolors;
X
X    if (!win_info->colormap)
X	return(0);
X
X    if (win_info->visual->class == TrueColor ||
X	win_info->visual->class == DirectColor)
X	return(0);    /* XXX punt for now */
X
X    ncolors = win_info->visual->map_entries;
X    if (!(*colors = (XColor *) malloc (sizeof(XColor) * ncolors)))
X      Fatal_Error("Out of memory!");
X
X    for (i=0; i<ncolors; i++)
X      (*colors)[i].pixel = i;
X
X    XQueryColors(dpy, win_info->colormap, *colors, ncolors);
X    
X    return(ncolors);
X}
X
X_swapshort (bp, n)
X    register char *bp;
X    register unsigned n;
X{
X    register char c;
X    register char *ep = bp + n;
X
X    while (bp < ep) {
X	c = *bp;
X	*bp = *(bp + 1);
X	bp++;
X	*bp++ = c;
X    }
X}
X
X_swaplong (bp, n)
X    register char *bp;
X    register unsigned n;
X{
X    register char c;
X    register char *ep = bp + n;
X    register char *sp;
X
X    while (bp < ep) {
X	sp = bp + 3;
X	c = *sp;
X	*sp = *bp;
X	*bp++ = c;
X	sp = bp + 1;
X	c = *sp;
X	*sp = *bp;
X	*bp++ = c;
X	bp += 2;
X    }
X}
EOF xwps.c
	case "`echo \`wc < 'xwps.c'\``" in
	"425 1295 10482")
		;;
	*)
		echo "$prog: \"xwps.c\" corrupted" >&2
		error=1
		;;
	esac
fi ; : # End of overwrite check
if test -f 'dsimple.h' -o -d 'dsimple.h'; then
	echo "$prog: \"dsimple.h\" exists, skipping" >&2
	error=1
else
	echo 'x - dsimple.h'
	sed -e 's/^X//' << 'EOF dsimple.h' > 'dsimple.h'
X/* $Header: dsimple.h,v 1.1 87/09/11 08:17:50 toddb Exp $ */
X/*
X * Just_display.h: This file contains the definitions needed to use the
X *                 functions in just_display.c.  It also declares the global
X *                 variables dpy, screen, and program_name which are needed to
X *                 use just_display.c.
X *
X * Written by Mark Lillibridge.   Last updated 7/1/87
X *
X * Send bugs, etc. to chariot@athena.mit.edu.
X */
X
X    /* Global variables used by routines in just_display.c */
X
Xchar *program_name = "unknown_program";       /* Name of this program */
XDisplay *dpy;                                 /* The current display */
Xint screen;                                   /* The current screen */
X
X#define INIT_NAME program_name=argv[0]        /* use this in main to setup
X                                                 program_name */
X
X    /* Declaritions for functions in just_display.c */
X
Xvoid Fatal_Error();
Xchar *Malloc();
Xchar *Realloc();
Xchar *Get_Display_Name();
XDisplay *Open_Display();
Xvoid Setup_Display_And_Screen();
XXFontStruct *Open_Font();
Xvoid Beep();
XPixmap ReadBitmapFile();
Xvoid WriteBitmapFile();
XWindow Select_Window_Args();
X
X#define X_USAGE "[host:display]"              /* X arguments handled by
X						 Get_Display_Name */
X#define SELECT_USAGE "[{-root|-id <id>|-font <font>|-name <name>}]"
X
X/*
X * Other_stuff.h: Definitions of routines in other_stuff.
X *
X * Written by Mark Lillibridge.   Last updated 7/1/87
X *
X * Send bugs, etc. to chariot@athena.mit.edu.
X */
X
Xunsigned long Resolve_Color();
XPixmap Bitmap_To_Pixmap();
XWindow Select_Window();
Xvoid out();
Xvoid blip();
XWindow Window_With_Name();
EOF dsimple.h
	case "`echo \`wc < 'dsimple.h'\``" in
	"53 189 1648")
		;;
	*)
		echo "$prog: \"dsimple.h\" corrupted" >&2
		error=1
		;;
	esac
fi ; : # End of overwrite check
if test -f 'extern.h' -o -d 'extern.h'; then
	echo "$prog: \"extern.h\" exists, skipping" >&2
	error=1
else
	echo 'x - extern.h'
	sed -e 's/^X//' << 'EOF extern.h' > 'extern.h'
X/*	List of external variable and headers to be included in xwps	*/
X
X#include <X11/Xos.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <stdio.h>
X#include <signal.h>
X
X#define SAVE	0
X#define PRINT	1
X#define FILENAME	"xwpsfile"
X#define BITS_PER_SAMPLE 8
X
X#ifdef DECLARE
X    Bool debug		= False;
X    Bool inverse	= False;	/* inverse Flag */
X    Bool bdrs		= True;		/* borders Flag */
X    Bool output		= PRINT;	/* Save to File or Print */
X    int format		= ZPixmap;	/* XYBitmap, XYPixmap, ZPixmap */
X    int rotation	= 0;		/* In degrees counterclockwise */
X    float scaleX	= 6.0;		/* In inches */
X    float scaleY	= 6.0;		/* In inches */
X    float translateX	= 1.0;		/* In inches */
X    float translateY	= 1.0;		/* In inches */
X
X    Window target_win;			/* User selected target window */
X    FILE *out_file	= stdout;	/* File to save to */
X#else
X    extern Bool debug, inverse, bdrs, output;
X    extern int format, rotation;
X    extern float scaleX, scaleY, translateX, translateY;
X    extern Window target_win;
X    extern FILE *out_file;
X#endif
X
X
EOF extern.h
	case "`echo \`wc < 'extern.h'\``" in
	"36 160 1051")
		;;
	*)
		echo "$prog: \"extern.h\" corrupted" >&2
		error=1
		;;
	esac
fi ; : # End of overwrite check
if test -f 'Makefile' -o -d 'Makefile'; then
	echo "$prog: \"Makefile\" exists, skipping" >&2
	error=1
else
	echo 'x - Makefile'
	sed -e 's/^X//' << 'EOF Makefile' > 'Makefile'
X#
X# 	Makefile for XWD -> XWPS: Xwindow Dump to a Postscript  format
X#
X
XXLIBS =  -lX 
XCFLAGS = -g
Xsrc = xwps.c dsimple.c psfile.c 
Xobj = xwps.o dsimple.o psfile.o 
Xheaders = dsimple.h extern.h
XDEST = ./xwps
X
Xxwps: $(obj)
X	$(CC) $(obj) $(XLIBS) -o $(DEST)
X
X$(obj): $(headers)
X
Xall: xwps clean
X	
Xclean:
X	rm -f $(obj)
EOF Makefile
	case "`echo \`wc < 'Makefile'\``" in
	"20 53 314")
		;;
	*)
		echo "$prog: \"Makefile\" corrupted" >&2
		error=1
		;;
	esac
fi ; : # End of overwrite check
if test -f 'README' -o -d 'README'; then
	echo "$prog: \"README\" exists, skipping" >&2
	error=1
else
	echo 'x - README'
	sed -e 's/^X//' << 'EOF README' > 'README'
XWell here it is. This works for my release of X11 which is R2 I think.
XYou will notice quite a few extra external variables hanging around, this is because
XI had to rip out the widget part. Also there is some X code in xwps.c that I
Xdidn't want to mess with because I didn't know if it was doing something.
EOF README
	case "`echo \`wc < 'README'\``" in
	"4 62 307")
		;;
	*)
		echo "$prog: \"README\" corrupted" >&2
		error=1
		;;
	esac
fi ; : # End of overwrite check
: # End of shell archive
exit $error

Benjamin Chen
Office:   550-A4 Cory Hall, 2-4332
UUCP:     !ucbvax!esvax!bchen               
HEPNET:   LBL::"bchen@esvax.Berkeley.EDU"