- Xlib
- Introducing XCB
- Remote Pointers and Errors
- Event Loops
- Events and Replies
- XCB Patterns
- Extensions
- Overall
Events and Replies
As I mentioned earlier, there are two kinds of messages you can get from the server: events and replies. Both of these arrive over the same socket, so if you are waiting for data on that socket with poll() or select(), then you will be notified when either is ready.
To get the next event, you typically call xcb_poll_for_event() in a loop something like this:
xcb_generic_event_t *event; while (NULL != (event = xcb_poll_for_event(connection)))
If there are no pending events, then this will return NULL so you go back to blocking, or process input from other file descriptors. If there are pending events, then you need to handle the event. The response_type field in the event structure tells you what kind of event it is, and you then have to cast the pointer to the real structure type before handling it. Note that this same return value is used for errors as well. The xcb_generic_error_t structure has the same fields as the event structure and is distinguished by the type.
When you cast these pointers, you get a structure with exactly the same fields as the message type. XCB will handle things like structure alignment and endian differences for you, but nothing else.
Replies can be handled in exactly the same way. We already saw how to handle specific replies synchronously, but most toolkits will want to expose an asynchronous API to application developers, where they can register handlers for replies that may take a while and avoid blocking. The xcb_poll_for_reply() function lets you do implement this kind of API.
Handling replies like this is using a lower-level part of the API than usual. This takes four arguments and lets you see whether a specific reply has been received:
xcb_poll_for_reply(connection, sequenceNumber, &reply, &error)
The second argument is the sequence number of the request, which will be the cookie returned when the request was issued. The other two arguments are pointers-to-pointers that will be used to return either the reply or an error, depending on whether the request succeeded.
Both of these functions will remove data from the socket and store it in queues private to the library. This means that you need to make sure that both the reply and event queues are empty before blocking and waiting for more data on the socket, or you will lose some messages. The biggest oversight with the XCB API is the lack of a single call for getting the next reply or event.