View Full Version : XWindows problem on Debian

01-27-2005, 04:52 AM
For a while now I was playing with XWindows programming on Suse 9.2 and everything was going well. I recently got a copy of the new Debian release (Sarge) and figured I'd try it on there. The program doesn't work. No windows are ever shown.

What appears to be happening is that the XNextEvent() function is never returning. I've copied the code that I'm using to show the windows into a small test program and it works just fine, but in the class everything stops at XNextEvent().

Here's the code I'm using to create the windows.

This block has all teh class variables used:

Colormap ccmpColorMap;
Display *cdisDisplay;
int ciScreenNum;
Screen *cscrScreenPtr;
Colormap ccmpColorMap;
Window Handle; //This is actually in a structure

This block is in the class initialization function (called by thread 1)

cdisDisplay = XOpenDisplay(NULL);
if (cdisDisplay == NULL)
{//Failed to connect to an X Server
printf("\nFailed to connect to the display\n");
//printf("\nConnected to server!\n");
ciScreenNum = DefaultScreen(cdisDisplay);
cscrScreenPtr = DefaultScreenOfDisplay(cdisDisplay);
ccmpColorMap = XDefaultColormap(cdisDisplay, ciScreenNum);

This block is in a CreateWindow function (called by thread 1)

XWMHints *xwmhHints;
XClassHint *xchClass;
XTextProperty xtpWinName, xtpIconName;
XSizeHints *xshSize;
char *pcIconName = "", *pcWinName = "Window Name?", *pcProgName = "";
Atom aProt;

Handle = XCreateSimpleWindow(cdisDisplay, RootWindow(cdisDisplay, ciScreenNum), 0, 0, 200, 200, 0, BlackPixel(cdisDisplay, ciScreenNum), WhitePixel(cdisDisplay, ciScreenNum));

//Allocate space for the hints
xshSize = XAllocSizeHints();
xwmhHints = XAllocWMHints();
xchClass = XAllocClassHint();

xshSize->flags = PPosition | PSize;

XStringListToTextProperty(&pcWinName, 1, &xtpWinName);
XStringListToTextProperty(&pcIconName, 1, &xtpIconName);

xwmhHints->initial_state = NormalState;
xwmhHints->input = True;
xwmhHints->flags = StateHint | InputHint;

xchClass->res_name = pcProgName;
xchClass->res_class = "";

XSetWMProperties(cdisDisplay, Handle, &xtpWinName, &xtpIconName, 0, 0, xshSize, xwmhHints, xchClass);

//request the close event from the window manager
aProt = XInternAtom(cdisDisplay, "WM_DELETE_WINDOW", True);
XSetWMProtocols(cdisDisplay, Handle, &aProt, 1);

XSelectInput(cdisDisplay, Handle, ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | EnterWindowMask | LeaveWindowMask);
XMapWindow(cdisDisplay, Handle); //Show the window

And finally is the event loop (called by thread 2)

XEvent xeEvent;

while (1)
XNextEvent(cdisDisplay, &xeEvent);

There was more in the event loop before, but I've been stripping it out thinking there was a problem after the XNextEvent() call.

The program is intended to be multithreaded, one thread setting up the window, and a second handling the events. I've made the test program work in that type of setup too.

I've checked the return values for the X functions, none appear to be returning an error. Though the man pages for them don't list what a success value should be so not sure I can guarentee no errors.

As I said when I run this with just this code in a test program everything works fine, its only when I put it in my full program do problems occur.

Any ideas what I should look at to find the error? I just don't get why it runs great on Suse, but not on Debian.

01-27-2005, 05:11 AM
Ok I really don't get it. I was tinkering with it a bit more, and it turns out that only sometimes does it not work.

The test program never fails, the full program will run successfully about half of the time. The rest it never recieves any events and is neverdrawn on the screen.

Edit: Only difference I can find about the two platforms is that Debian is using Xfree86 and Suse 9.2 is using the X.org version of XWindows. I was under the impression that these were essentially identical and shouldn't cause any issues.

01-27-2005, 09:04 AM
Problem solved! Or so I think....

I was able to reproduce the problem on Suse 9.0, which also runs Xfree86. After tinkering with it a bit I found out that XNextEvent() does not like to be called before there is a chance to recieve events. Not sure how to best explain that.

What I was doing was at startup the program called the first code block and started the event loop thread. So XNextEvent() was called before a window existed, so no events were possible to be retrieved. Then later in the program I ran the second code block and created a window. XNextEvent() was still blocking, and I suspect holding up the drawing routines to put the window on screen.

I deferred the creation of the event loop thread until after the first window was created and everything is workign fine on the Suse 9.0 box. I'll retest it on Debian when I get home.