[comp.windows.x] what's wrong with this program?

ndd@romeo.cs.duke.edu (Ned D. Danieley) (07/22/88)

The following program behaves strangely when run on a Sun 3/280
under SunOs 3.5, X11R2, and twm. It is supposed to print the text
'hi there' and draw a line. It always draws the line, but sometimes
does not draw the text.  It seems to always work correctly without
twm running. I realize that I'm not doing anything with events, but
my application needs to be able to put up text and graphics before
worrying about events.

Another interesting problem with this program is that if I move the
call to XMapWindow down below the XLoadQueryFont, I don't get the text
or the line.

Any help with this problem would be appreciated; I've got a bunch of
X10 code to convert, so I need to understand this.

Ned Danieley (ndd@sunbar.mc.duke.edu)
Basic Arrhythmia Laboratory
Box 3140, Duke University Medical Center
Durham, NC  27710
(919) 684-6807 or 684-6942

--------------------------------------------------------------------
#include <stdio.h>
#include "X11/Intrinsic.h"

#define	BORDER		4

Window pw, rootw;

char *disp = NULL;
Display *dpy;

main(argc, argv)
int argc;
char *argv[];
{
register int i;
int screen, width, height;
Widget makemenu();
XFontStruct *font;
GC gc;
XGCValues gcv;
unsigned long black_pixel;		/* pixel value for black */
unsigned long white_pixel;		/* pixel value for white */


	if ((dpy = XOpenDisplay(disp)) == NULL) {
                fprintf(stderr, "%s: Can't open display '%s'\n", argv[0],
                        DisplayString(dpy));
                exit(1);
		}

/* create parent window */
	rootw = DefaultRootWindow(dpy);
	screen = DefaultScreen(dpy);
	width = DisplayWidth(dpy, screen);
	height = DisplayHeight(dpy, screen);
	white_pixel = WhitePixel(dpy, screen);
	black_pixel = BlackPixel(dpy, screen);

        pw = XCreateSimpleWindow(dpy, rootw, 0, 0,
		width / 4, height / 4,
		BORDER, white_pixel, black_pixel);

	XMapWindow(dpy, pw);
	if (!(font = XLoadQueryFont(dpy, "vg-25"))) {
		fprintf(stderr, "couldn't open %s\n", "vg-25");
		exit(1);
		}

/* put XMapWindow here and nothing is draw in the window */

	gcv.foreground = white_pixel;
	gcv.background = black_pixel;
	gcv.font = font->fid;
	gc = XCreateGC(dpy, pw, GCForeground | GCBackground | GCFont, &gcv);

        XDrawString(dpy, pw, gc, 100, 100, "hi there ", 9);

	for (i = 0; i < 100; i++) {
		XDrawPoint(dpy, pw, gc, 100 + i, 100 + i);
		XDrawPoint(dpy, pw, gc, 101 + i, 100 + i);
		}

	XFlush(dpy);

	for ( ;; ) {
		XEvent ev;

		if (XPending(dpy)) XNextEvent(dpy, &ev);
		}
}

jim@EXPO.LCS.MIT.EDU (Jim Fulton) (07/23/88)

> [describes mapping window and drawing without waiting for an expose event]

You *must* select for ExposureMask on the window and then wait for an Expose 
event before drawing.  This is to allow the window manager to grab the 
Map request, ask the user to size and place the window (if appropriate),
and then do the real map.  For example,

        pw = XCreateSimpleWindow(dpy, rootw, 0, 0,
                width / 4, height / 4,
                BORDER, white_pixel, black_pixel);
	XSelectInput (dpy, pw, ExposureMask);
	XMapWindow (dpy, pw);

	...

        /* wait for exposure */
        while (1) {
            XEvent event;

            XWindowEvent (dpy, pw, ExposureMask, &event);
            if (event.type == Expose) break;
        }

If you want to specify events later, then you can call XSelectInput again.


Jim Fulton
MIT X Consortium

ndd@SUNBAR.MC.DUKE.EDU (Ned Danieley) (07/23/88)

that did it. thanks.

Should I have understood that from the documentation? I read
about using XSelectInput and ExposureMask to avoid multiple
screen painting, but I didn't realize I had to do it before
any drawing.

ned