Xlib event loop

Hi guys,

How should I make an event loop for a game using Xlib on Linux?

I have tried using XNextEvent as some documentation suggests and that seems to block until it has any events to return.

Then I tried to use XCheckMaskEvent which apparently does almost the same as XNextEvent and it doesn't block, but I ran into problems when trying to handle the close button of the window, turns out the events fired by the close button can't be captured by XCheckMaskEvent so I had to make another loop to see if that event was there, anyway it was nasty.

I have seen some people suggest an approach similar to select function in sockets programming but I can't understand that yet so I would like to avoid that one if possible.

Thanks!

Edited by BernFeth on Reason: Initial post
oh boy, Xlib is a can of worms. The fact that is pollutes the namespace with things like "Window", "Display" and "Bool" annoys me enough ;)
But the multithreaded stuff is where it gets hard.
To answer your question, look at "XPending" it will read more events from the socket connection and return to you the number of events in the queue. If you do not wish to block:
1. call "XPending" and store the count in a variable
2. Then loop until you have exhausted the queue with "XNextEvent".
3. Then Repeat until "XPending" returns 0.

Also XNextEvent will never return if it is called when no windows exist. So make sure you only call it when you have a Window that is subscribed with "XSelectInput". By using XPending how I listed above, it will prevent this from becoming a reality.

Hope this helps :)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
int count = 1;
XEvent xe;
while (count) {
    count -= 1;
    if (count == 0) {
        count = XPending(display);
        if (count == 0) break;
    }
    XNextEvent(display, &xe);
    // process xe here
}
That looks more complicated that it should be. If XPending returns count of events that are not removed from even queue yet, then just loop until it returns 0:
1
2
3
4
5
6
while (XPending(display)) {
  XEvent xe;
  XNextEvent(display, &xe);
  // process xe here
  // ...
}


There will no big difference in performance, as XPending simply returns cached integer for pending events: https://gitlab.freedesktop.org/xo...1/-/blob/master/src/Pending.c#L53

Edited by Mārtiņš Možeiko on
That looks great,

thanks guys! :)