XCB enhancements

by havoc

Disclaimer: I’ve never followed XCB development, this may have
all been discussed already, but I hope this post is at least helpful
as a data point illustrating what I understood and didn’t understand.

Julien Danjou was
disappointed recently
because after porting dbus-launch to XCB, we had a bit of a “what’s
the point?” reaction to the patch. Why move “#ifdef XCB” up into apps,
when libX11 is already a compat layer that uses XCB if available?

However, XCB remains a useful idea. For the litl OS shell, we’ve
discovered that we really need certain X requests to be async. I ended
up digging into the XCB code to find an obscure
bug
. Since I’d just read a bunch of XCB code, I figured I’d try to
expand on the API docs
. Hopefully someone can fix up my docs
efforts and land them upstream. (If you happen to notice bugs in my
docs patch, please comment on the bug.)

Better docs ought to help people know when and how to use XCB. But
the library could also benefit from two larger changes inspired by the
higher-level desktop toolkits.

1. Better support a main loop, in addition to threads.

Heck, even server-side developers are
piling on this bandwagon lately. XCB goes to a lot of trouble to
support multithreaded operation. Unfortunately, multiple threads
messing with UI code is highly problematic for most actual Linux
toolkits and apps. (More conceptually: because X replies are always
returned in request order, and the X server is single-threaded,
everything is serialized anyhow…)

I filed a
bug
with my theory on what XCB needs for better main loop support.
Please, comment on the bug with corrections and improvements.

I’d like to be able to queue a reply handler as a main loop callback,
something that’s difficult with XCB as it stands, unless I’m
missing something.

2. Export the protocol introspection data (and use it to “dynamicize“
protocol bindings)

XCB is in the pre-gobject-introspection school of binding
implementation, i.e. libraries full of autogenerated stubs. (Not
saying gobject-introspection invented dynamic stubs; COM and CORBA
have it, as does Qt, doubtless many other things before that. But
gobject-introspection is the GNOME version.)

I filed
another bug
proposing that XCB could export a binary “typelib” for
the protocol. This could remove all request-specific code
from non-C language bindings. It could make the C language bindings
smaller, too. And it makes it easy to write debugging tools and code.

If the C bindings were dynamic, they could export two other flavors of
each request without adding bloat: a “fire and forget” flavor that
ignores both errors and replies; and a blocking, synchronous flavor
(matching the convenience of libX11). These two flavors would be nice
to have, without them XCB code can be more verbose than it ought to
be. (It’s a poor advertisement for XCB when the patch to go from
libX11 to XCB adds extra lines of code, which happens most of the time
when you make a request with a reply — at least two lines in xcb,
vs. one in Xlib.)

A bonus suggestion!

An easy X protocol debug hook would be fantastic. xtrace doesn’t provide easy
customization for a particular debugging problem or particular application.
I’m thinking something like:

void xcb_set_trace(xcb_connection_t *c,
                   xcb_trace_callback_t out_callback,
                   void *out_closure,
                   xcb_trace_callback_t in_callback,
                   void *in_closure);

Where I’m not sure yet if xcb_trace_callback_t should just take raw
bytes to be parsed by the app, or should be passed something
higher-level including sequence numbers and opcodes. A problem with
higher-level would be the need to parse the requests Xlib pushes
through xcb_writev() inside XCB. A potential middle road would provide
raw bytes to the trace callbacks, but export a simple X protocol
parser API that apps could use for tracing.

A trace hook wouldn’t be as useful without exporting the protocol
description “typelib” so apps and tools can make sense out of what
they’re seeing.

Adding XCB utility

At the moment, for a single-threaded application XCB only helps you
vs. Xlib in a narrow set of situations where you are willing to block
on a reply eventually, but not right now. This is handy to “batch“
requests as in the
tutorial examples
(search for useXCBProperly).

But XCB could offer much more, such as main loop
async callbacks
, dynamic language bindings, and debug/trace
support. These are simple features to add to XCB, that would have
been hard to add to the old libX11 codebase.

Just a bit more “what’s in it for me?” would be helpful when it comes
to convincing apps and toolkits to port over to XCB.

One more thing!

While I’m posting: it seems to be hard (impossible?) to use libxcb-glx
because libGL doesn’t export a way to get or set the context tag.
Not sure where to file this bug or if I’m just missing something.

(This post was originally found at http://log.ometer.com/2010–08.html#22)