4.3BSD/usr/contrib/X/xwd/xwd.c

Compare this file to the similar file:
Show the results in this format:

#include <X/mit-copyright.h>

/* Copyright 1985, Massachusetts Institute of Technology */

/*
 * xwd.c MIT Project Athena, X Window system window raster image dumper.
 *
 * This program will dump a raster image of the contents of a window into a 
 * file for output on graphics printers or for other uses.
 *
 *  Author:	Tony Della Fera, DEC
 *		17-Jun-85
 */

#ifndef lint
static char *rcsid_xwd_c = "$Header: xwd.c,v 10.6 86/02/01 16:07:54 tony Rel $";
#endif

#include <X/Xlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <strings.h>

char *calloc();

typedef enum _bool {FALSE, TRUE} Bool;

#include "../cursors/target.cursor"
#include "../cursors/target_mask.cursor"

#include "XWDFile.h"

#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

#define FEEP_VOLUME 0

extern int errno;

main(argc, argv)
    int argc;
    char **argv;
{
    register int i;
    int status;
    unsigned buffer_size;
    int virt_x, virt_y;
    int virt_width, virt_height;
    int pixmap_format = XYFormat;
    int win_name_size;
    int header_size;
    char *str_index;
    char *file_name;
    char display[256];
    char *win_name;
    char *buffer;
    Bool nobdrs = FALSE;
    Bool debug = FALSE;
    Bool standard_out = TRUE;

    Display *dpy;
    Window target_win;
    Window image_win;
    WindowInfo win_info;
    Cursor cursor;
    XButtonEvent rep;

    XWDFileHeader header;

    FILE *out_file = stdout;

    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], "-nobdrs", 6) == 0) {
	    nobdrs = TRUE;
	    continue;
	}
	if (strncmp(argv[i], "-debug", 6) == 0) {
	    debug = TRUE;
	    continue;
	}
	if (strncmp(argv[i], "-help", 5) == 0) {
	    Syntax(argv[0]);
	}
	if (strncmp(argv[i], "-out", 4) == 0) {
	    if (++i >= argc) Syntax(argv[0]);
	    file_name = argv[i];
	    standard_out = FALSE;
	    continue;
	}
	if (strncmp(argv[i], "-z", 2) == 0) {
	    pixmap_format = ZFormat;
	    continue;
	}
	Syntax(argv[0]);
    }
    
    if (!standard_out) {
	/*
	 * Open the output file.
	 */
	out_file = fopen(file_name, "w");
	if (out_file == NULL) {
	    Error("Can't open output file as specified.");
	}
    }

    /*
     * Open the display.
     */
    if (debug) printf("xwd: Opening display.\n");
    if ((dpy = XOpenDisplay(display)) == NULL) {
	Error("Error occured while trying open display.");
    }

    /*
     * Store the cursor incase we need it.
     */
    if (debug) printf("xwd: Storing target cursor.\n");
    cursor = XCreateCursor(
    	target_width, target_height, 
    	target_bits, target_mask_bits, 
	8, 8,
	BlackPixel, WhitePixel,
	GXcopy
    );	
    if (cursor == FAILURE) {
	Error("Error occured while trying to store target cursor.");
    }

    /*
     * Check to see if we are in the right pixmap format for the
     * display type.
     */
    if ((dpy->dplanes == 1) && (pixmap_format == ZFormat)) {
	Error("ZFormat is not valid on a monochrome display.");
    }

    /*
     * Let the user select the target window.
     */
    status = XGrabMouse(RootWindow, cursor, ButtonPressed);
    if (status == FAILURE) Error("Can't grab the mouse.");
    XNextEvent(&rep);
    XUngrabMouse();
    target_win = rep.subwindow;
    if (target_win == 0) {
	/*
	 * The user must have indicated the root window.
	 */
	if (debug) printf("xwd: Root window selected as target.\n");
	target_win = RootWindow;
    }
    else if (debug) printf("xwd: Window 0x%x slected as target.\n", target_win);

    /*
     * Inform the user not to alter the screen.
     */
    XFeep(FEEP_VOLUME);

    /*
     * Get the parameters of the window being dumped.
     */
    if (debug) printf("xwd: Getting target window information.\n");
    status = XQueryWindow(target_win, &win_info);
    if (status == FAILURE) Error("Can't query target window.");
    status = XFetchName(target_win, &win_name);
    if (status == FAILURE) Error("Can't fetch target window name.");
    win_name_size = strlen(win_name) + sizeof(char);
    /* sizeof(char) is included for the null string terminator. */

    /*
     * Calculate the virtual x, y, width and height of the window pane image
     * (this depends on wether or not the borders are included.
     */
    if (nobdrs) {
	if (debug) printf("xwd: Image without borders selected.\n");
	image_win = target_win;
	virt_x = 0;
	virt_y = 0;
	virt_width = win_info.width;
	virt_height = win_info.height;
    }
    else {
	if (debug) printf("xwd: Image with borders selected.\n");
	image_win = RootWindow;
	virt_x = win_info.x;
	virt_y = win_info.y;
	virt_width = win_info.width + (win_info.bdrwidth << 1);
    	virt_height = win_info.height + (win_info.bdrwidth << 1);
    }

    /*
     * Determine the pixmap size.
     */
    if (pixmap_format == XYFormat) {
	buffer_size = XYPixmapSize(virt_width, virt_height, dpy->dplanes);
	if (debug) {
	    printf("xwd: Pixmap in XYFormat, size %d bytes.\n", buffer_size);
	}
    }
    else if (dpy->dplanes < 9) {
	buffer_size = BZPixmapSize(virt_width, virt_height);
	if (debug) {
	    printf("xwd: Pixmap in byte ZFormat, size %d bytes.\n", buffer_size);
	}
    }
    else {
	buffer_size = WZPixmapSize(virt_width, virt_height);
	if (debug) {
	    printf("xwd: Pixmap in word ZFormat, size %d bytes.\n", buffer_size);
	}
    }


    /*
     * Calloc the buffer.
     */
    if (debug) printf("xwd: Calloc'ing data buffer.\n");
    buffer = calloc(buffer_size , 1);
    if (buffer == NULL) Error("Can't calloc data buffer.");

    /*
     * Snarf the pixmap out of the frame buffer.
     */
    if (debug) printf("xwd: Getting pixmap.\n");
    if (pixmap_format == XYFormat) {
	(void) XPixmapGetXY(
	    image_win,
	    virt_x, virt_y,
	    virt_width, virt_height,
	    (short *)buffer
	);
    }
    else {
	(void) XPixmapGetZ(
	    image_win,
	    virt_x, virt_y,
	    virt_width, virt_height,
	    (caddr_t)buffer
	);
    }

    /*
     * Inform the user that the image has been retrieved.
     */
    XFeep(FEEP_VOLUME);
    XFeep(FEEP_VOLUME);
    XFlush();

    /*
     * Calculate header size.
     */
    if (debug) printf("xwd: Calculating header size.\n");
    header_size = sizeof(header) + win_name_size;

    /*
     * Writ out header information.
     */
    if (debug) printf("xwd: Constructing and dumping file header.\n");
    header.header_size = header_size;
    header.file_version = XWD_FILE_VERSION;
    header.display_type = dpy->dtype;
    header.display_planes = dpy->dplanes;
    header.pixmap_format = pixmap_format;
    header.pixmap_width = virt_width;
    header.pixmap_height = virt_height;
    header.window_width = win_info.width;
    header.window_height = win_info.height;
    header.window_x = win_info.x;
    header.window_y = win_info.y;
    header.window_bdrwidth = win_info.bdrwidth;
    header.padding = 0;

    (void) fwrite((char *)&header, sizeof(header), 1, out_file);
    (void) fwrite(win_name, win_name_size, 1, out_file);

    /*
     * Write out the buffer.
     */
    if (debug) printf("xwd: Dumping pixmap.\n");
    (void) fwrite(buffer, (int) buffer_size, 1, out_file);

    /*
     * Close the output file.
     */
    if (debug) printf("xwd: Closing output file.\n");
    (void) fclose(out_file);

    /*
     * Free the pixmap buffer.
     */
    if (debug) printf("xwd: Freeing pixmap buffer.\n");
    free(buffer);

    /*
     * Free window name string.
     */
    if (debug) printf("xwd: Freeing window name string.\n");
    free(win_name);
    exit(0);
}


/*
 * Report the syntax for calling xwd.
 */
Syntax(call)
    char *call;
{
    fprintf(
	stderr,
	"\nUsage: %s [-debug] [-help] [-nobdrs] [-out <file>]\n",
    	call
    );
    fprintf(stderr, "                [-z] [[host]:vs]\n\n");
    exit(0);
}


/*
 * Error - Fatal xwd error.
 */
Error(string)
	char *string;	/* Error description string. */
{
	fprintf(stderr, "\nxwd: Error => %s", string);
	fprintf(stderr, "\n\n");

	if (errno != 0) {
		perror("xwd");
		fprintf(stderr, "\n");
	}

	exit(1);
}

/* End of xwd.c */