[comp.windows.x] XReadBitmapFile example

turner@daisy.UUCP (D'arc Angel) (05/10/88)

awhile ago someone posted a program that did a XReadBitmapFile call, but
didn't display the bitmap. After some hacking I got it to work for the bitmaps
that were distributed as poskbitmaps. It should be taken as an example not
as a finished program.

---cut here---cut here---cut here---cut here---cut here---cut here---cut here--


#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <stdio.h>

char* program_name;	/* aka argv[0] */
Pixmap ReadBitmapFile();
Display *display;
Window root;
int screen;

void
usage()
{
    fprintf(stderr,
	"Usage: %s [ -geometry spec ] [ -display spec ] file\n", program_name);
    exit(1);
}

main(argc, argv)
    int argc;
    char* argv[];
{
    char *geometry = NULL, *host = NULL;
    register int i;
    int border_wid = 2;
    char* filename = 0;
    Window showindow;
    XSetWindowAttributes attrs;
    XSizeHints hints;
    XGCValues gcv;
    GC gc;
    unsigned long bg, fg;
    int invert = 0;
    XEvent report;

    Pixmap bitmap = 0, pixmap = 0;
    int wid, hgt;
    int x_hot, y_hot;
    int my_x = 0, my_y = 0;

    program_name = argv[0];
    /* Parse command line */
    for (i = 1; i < argc; i++) {
	char *arg = argv[i];

	if (arg[0] == '-') {
	    switch (arg[1]) {
		case 'd':				/* -display host:dpy */
		    if (++i >= argc) usage ();
		    host = argv[i];
		    continue;
		case 'g':				/* -geometry geom */
		    if (++i >= argc) usage ();
		    geometry = argv[i];
		    continue;
		case 'i':
		    invert++;
		    continue;
		default:
		    usage ();
	    }
	} else
	    filename = argv[i];
    }

    if(filename == NULL)
	usage();

    if (!(display = XOpenDisplay(host))) {
	    fprintf(stderr, "%s:  unable to open display '%s'\n",
		    program_name, XDisplayName(host));
	    exit (1);
    }
    screen = DefaultScreen(display);
    root = RootWindow(display, screen);

    if(invert) {
	bg = BlackPixel (display, screen);
	fg = WhitePixel (display, screen);
    } else {
	bg = WhitePixel (display, screen);
	fg = BlackPixel (display, screen);
    }

    bitmap = ReadBitmapFile(filename, &wid, &hgt, &x_hot, &y_hot);

    showindow = XCreateWindow(
	display, root,
	my_x, my_y, wid, hgt,
	border_wid, CopyFromParent, CopyFromParent, CopyFromParent,
	CWBorderPixel | CWBackPixel, &attrs);

    gcv.function = GXcopy;
    gcv.background = bg;
    gcv.foreground = fg;
    gcv.graphics_exposures = False;

    gc = XCreateGC(display, showindow,
	GCFunction | GCForeground | GCBackground | GCGraphicsExposures, &gcv);

    pixmap = XCreatePixmap(display, showindow, wid, hgt, 
		(unsigned int)DefaultDepth (display, screen));
    XCopyPlane(display, bitmap, pixmap, gc, 0, 0, wid, hgt, 0, 0, 
	       (unsigned long) 1);

    XSelectInput(display, showindow, ExposureMask);

    XSetStandardProperties (display, showindow, "Bitmap Display", "showbitmap",
	None, argv, argc, &hints);

    XMapWindow(display, showindow);


    XCopyArea(display,
	      pixmap,
	      showindow,
	      gc,
	      0, 0,
	      wid, hgt,
	      0, 0);


    XFlush(display);

    XSelectInput(display, showindow, 
		 (unsigned long)(ButtonPressMask|KeyPressMask));
    while(report.type != ButtonPressMask & report.type != KeyPressMask)
      XNextEvent(display, &report);

    XFreePixmap(display, pixmap);
    XFreePixmap(display, bitmap);
    XFreeGC(display, gc);
}
Pixmap ReadBitmapFile(filename, width, height, x_hot, y_hot)
    char *filename;
    unsigned int *width, *height;
    int *x_hot, *y_hot;
{
    Pixmap bitmap;
    int status;

    status = XReadBitmapFile(display, root, filename, width,
			     height, &bitmap, x_hot, y_hot);
    if (status == BitmapSuccess)
      return(bitmap);
    else if (status == BitmapOpenFailed)
	fprintf(stderr, "%s: can't open file: %s\n", program_name, filename);
    else if (status == BitmapFileInvalid)
	fprintf(stderr, "%s: bad bitmap format file: %s\n",
			program_name, filename);
    else
	fprintf(stderr, "%s: insufficient memory for bitmap: %s",
			program_name, filename);
    exit(1);
    /*NOTREACHED*/
}

-- 
Laissez les bons temps rouler                     -  Queen Ida
...{decwrl|ucbvax}!imagen!atari!daisy!turner (James M. Turner)
Daisy Systems, 700 E. Middlefield Rd, P.O. Box 7006, 
Mountain View CA 94039-7006.                          (415)960-0123