How to stop an X11 event loop gracefully asynchronously

你说的曾经没有我的故事 提交于 2019-12-06 03:25:43
dvhh

According to these pages

The best solution would be perform a select on the X event queue socket getting the socket is achieved by

#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

Display *dis;
Window win;
int x11_fd;
fd_set in_fds;

struct timeval tv;
XEvent ev;

int main() {
    dis = XOpenDisplay(NULL);
    win = XCreateSimpleWindow(dis, RootWindow(dis, 0), 1, 1, 256, 256,\
        0, BlackPixel (dis, 0), BlackPixel(dis, 0));

    // You don't need all of these. Make the mask as you normally would.
    XSelectInput(dis, win, 
        ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask |
        ButtonPressMask | ButtonReleaseMask  | StructureNotifyMask 
    );

    XMapWindow(dis, win);
    XFlush(dis);

    // This returns the FD of the X11 display (or something like that)
    x11_fd = ConnectionNumber(dis);

    // Main loop
    while(1) {
        // Create a File Description Set containing x11_fd
        FD_ZERO(&in_fds);
        FD_SET(x11_fd, &in_fds);

        // Set our timer.  One second sounds good.
        tv.tv_usec = 0;
        tv.tv_sec = 1;

        // Wait for X Event or a Timer
        if (select(x11_fd+1, &in_fds, 0, 0, &tv))
            printf("Event Received!\n");
        else
            // Handle timer here
            printf("Timer Fired!\n");

        // Handle XEvents and flush the input 
        while(XPending(dis))
            XNextEvent(dis, &ev);
    }
    return(0);
}

Use XCheckWindowEvent in your message loop to see if there are any messages (followed by XNextEvent if one exists), and since this is non-blocking you can proceed to use pthread_cond_timedwait or whatever equivalent may exist in the threading library you are using. That way the blocking is in your hands rather than xlib's. If it times out it will check for another event, and then resume to waiting for your thread.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!