[comp.windows.x] Copying a Pixmap into a Window? Help?

dave@romano.cs.wisc.edu (Dave Cohrs) (04/30/88)

I feel like such a fool, but I can't seem to get XCopyArea() to
work the way I think it should.  Here's the scoop:
- X11V2
- Sun4/110, SunOS3.2, B/W monitor, Type 3 Kbd

Here's what I tried to do:

A simple (stupid!) program that opens a window, reads a bitmap from
an X11 format bitmap file, with XReadBitmapFile(), and XCopyArea()s
that bitmap into the window, which just happens to be the same
size as the bitmap.  It all works fine up to the XCopyArea(), which
seems to do nothing (i.e.  The window remains the background color
no matter what I do).

Note:  I was able to almost do what I wanted by setting the
background_pixmap to the bitmap when I XCreateWindow()ed the window,
but this has turned into a challenge.  Anyway, here's the code.
Pls don't complain about it's stupidity, unless it relates to the
problem I'm having (yes, I know I'm not using the geometry spec;
first I get it to work, then I make it pretty).

Too bad there's not a standard Widget that does this.

Dave Cohrs
-----------------------------------Cut Here------------------------------------
#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <stdio.h>

char* myname;	/* aka argv[0] */

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

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

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

    myname = 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 (!(disp = XOpenDisplay(host))) {
	    fprintf(stderr, "%s:  unable to open display '%s'\n",
		    myname, XDisplayName(host));
	    exit (1);
    }
    screen = DefaultScreen(disp);

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

    if( XReadBitmapFile(disp, RootWindow(disp, screen),
	filename, &wid, &hgt, &source, &x_hot, &y_hot) != Success) {
	fprintf(stderr, "%s: cannot load bitmap file %s\n", myname, filename);
	exit(1);
    }

    attrs.background_pixel = bg;
    attrs.border_pixel = fg;
    attrs.cursor = XCreateFontCursor(disp, XC_top_left_arrow);

    bitwin = XCreateWindow(
	disp, RootWindow(disp, screen),
	my_x, my_y, wid, hgt,
	border_wid, CopyFromParent, CopyFromParent, CopyFromParent,
	CWBorderPixel | CWBackPixel | CWCursor, &attrs);

    XSetStandardProperties (disp, bitwin, "Bitmap Display", "showbitmap",
	None, argv, argc, &hints);

    XMapWindow(disp, bitwin);

    gcv.function = GXcopy;
    gcv.background = bg;
    gcv.foreground = fg;
    gcv.graphics_exposures = False;
    gc = XCreateGC(disp, bitwin,
	GCFunction | GCForeground | GCBackground | GCGraphicsExposures, &gcv);

    XCopyArea(disp, source, bitwin, gc, 0, 0, wid, hgt, 0, 0);
    XFlush(disp);

    while(1)
	sleep(100000);
}

--
Dave Cohrs
+1 608 262-6617                        UW-Madison Computer Sciences Department
dave@cs.wisc.edu                 ...!{harvard,ihnp4,rutgers,ucbvax}!uwvax!dave

oj@apollo.uucp (Ellis Oliver Jones) (05/04/88)

In article <5658@spool.cs.wisc.edu> dave@romano.cs.wisc.edu (Dave Cohrs) writes:
...
>A simple program that opens a window, reads a bitmap from
>an X11 format bitmap file, with XReadBitmapFile(), and XCopyArea()s
>that bitmap into the window, which just happens to be the same
>size as the bitmap.  It all works fine up to the XCopyArea(), which
>seems to do nothing (i.e.  The window remains the background color
>no matter what I do).

Don't do the XCopyArea until you get an Expose event.
Most window managers intercept each XMapWindow request (via 
SubstructureRedirectMask) and spend some time figuring out
what to do before reissuing the request.

The upshot is that you probably drew into an unmapped window.
/Ollie Jones