Need for XEventsQueued(display, QueuedAfterReading

2019-05-20 01:14发布

I am migrating some code of CYBOI from Xlib to XCB.

CYBOI uses a couple of threads for different communication channels like: serial_port, terminal, socket, x_window_system. However, it uses these threads only for signal/event/data detection; the actual receiving and sending is done in the main thread, in order to avoid any multi-threading conflicts of address space.

For the x_window_system channel, I previously detected events in a thread:

int n = XEventsQueued(display, QueuedAfterReading);

Upon detection of an event, an "interrupt flag" was set. Afterwards, the main thread was reading the actual event using:

XNextEvent(display, &event);

When no more events were available, the main thread stopped receiving events and the x_window_system channel thread started listening with XEventsQueued again.

Now, I am migrating the code to X C Binding (XCB). There is a blocking function "xcb_wait_for_event" which is fine for reading an event. What I miss is some function "peeking ahead" if there are events pending, WITHOUT actually returning/removing the event from the queue.

I was reading the web for a couple of hours now, but am not able to find such a function. The "xcb_poll_for_event" does not help. Blocking is fine for me, since my event detection runs in its own thread. The "xcb_request_check" as third input function does not seem to be what I want.

Could somebody help me out?

Thanks, Christian

标签: c xlib xcb
2条回答
forever°为你锁心
2楼-- · 2019-05-20 01:34

First, thanks to Julien for his reply.

I have studied the XCB 1.9 sources and found out that the "xcb_poll_for_queued_event" function is not what I need.

The functions "xcb_poll_for_event" and "xcb_poll_for_queued_event" both call "poll_for_next_event". The functions "poll_for_next_event" and "xcb_wait_for_event" both call "get_event".

If "get_event" finds an event, it changes the internal linked list to point to the next event. However, I would prefer NOT to change the event queue AT ALL, independent from whether or not events are available.

I therefore propose to add a function like the following to XCB:

void* NULL_POINTER = (void*) 0;

int xcb_test_for_event(xcb_connection_t* c) {

    int r = 0;

    if (c != NULL_POINTER) {

        struct _xcb_in in = c->in;
        struct event_list* l = in.events;

        if (l != NULL_POINTER) {

            xcb_generic_event_t* e = l->event;

            if (e != NULL_POINTER) {

                r = 1;
            }
        }
    }

    return r;
}

This would allow me to write an endless loop like:

while (!xcb_test_for_event(connection)) {

    sleep(t);
}

This is comparable to the old Xlib function:

int n = XEventsQueued(d, QueuedAfterReading);

which just checked the number of events in the event queue. The "XEventsQueued" function always returns immediately WITHOUT input/output, if there are events already in the queue.

Thanks Christian

查看更多
时光不老,我们不散
3楼-- · 2019-05-20 01:54

Are you looking for xcb_poll_for_queued_event(xcb_connection_t *c) which returns the next event without reading from the connection?

查看更多
登录 后发表回答