问题
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
回答1:
Are you looking for xcb_poll_for_queued_event(xcb_connection_t *c)
which returns the next event without reading from the connection?
回答2:
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
来源:https://stackoverflow.com/questions/15775281/need-for-xeventsqueueddisplay-queuedafterreading-in-xcb