[Xcb] Some comments on XCB

Jamey Sharp jamey at minilop.net
Tue May 31 14:04:56 PDT 2005


I wrote a detailed reply to this a few days after you sent it, Carl, but
just as I finished, Evolution ate it. I was too frustrated about that to
re-type it at the time. I'll try again now.

On Mon, 2005-05-16 at 15:57 -0700, Carl Worth wrote:
> The first thing I ran across was an inconsistent case convention in
> XCB types. I found the following in the code I was using:
> 
> 	XCBConnection
> 	XCBGCONTEXT
> 	XCBDRAWABLE
> 	XCBVISUALTYPE
> 	XCBRenderPICTURE
> 
> The result is that it's impossible for me to discern a consistent rule
> for capitalization. I imagine there might actually be a consistent
> rule, but I would argue it's not helpful to the user, as it's not
> discernible and therefore likely to just be a source of confusion and
> consternation. (Not to mention the fact that three words strung
> together in ALLCAPS as in XCBVISUALTYPE makes it REALLYHARDTOREAD even
> when ThisIsBadEnough.)

Yeah, it's been mentioned occasionally on this list XCB's general policy
of following Xlib's capitalization convention is maybe unfortunate. What
you've noticed is that the protocol specifications' capitalization
currently trumps anything else, which certainly is worse.

I fixed one of these sorts of issues back in the M4 era, and Josh
provided a fine implementation of that fix in XSLT. The idea is to have
the XML protocol description follow the English specification as closely
as possible, and then automatically apply a case convention appropriate
for the target language during code generation. So in the special case
we handle already, "visual_type" is transformed to "VisualType" (or
whatever): '_' is a word separator, and the first letter of each word is
forced uppercase.

To fix this, I propose to:
      * Add '-' and ' ' to the accepted separators, as these are often
        used in protocol specs as well.
      * Apply the above-described transformation to all function and
        type names, and extend it to force the letters after the first
        to lowercase.
      * Add a new transformation with the same separators, to be used
        for all structure fields and function parameter names. For C
        this would presumably be all-lowercase and underscore separated.
      * Mark-up the XML with spaces at word boundaries.

> The second thing I ran into is that the useful prototypes I needed to
> consult while coding are in XCB/xproto.h but this file has a reckless
> disregard for helpful whitespace, containing things like:

Josh did a great job fixing this. I think we can agree it's OK now?

> Another minor snag I hit was with specifically with the
> XCBCreatePixmap call. If I have the pid of my new pixmap in
> "drawable.pixmap", it's tempting to look at the prototype above and
> think that I might need to pass "drawable" in for the drawable
> parameter. ...
> 
> Maybe the "drawable" parameter just needs a more descriptive name to
> indicate its purpose, (along similar lines as "XCBWINDOW parent" in
> XCBCreateWindow). But what? "screen_drawable" ? I'm not sure.
> 
> It occurs to me that if we were just inventing a new API here, it's
> the screen that is really relevant to XCBCreatePixmap, so passing an
> XCBSCREEN* rather than an XCBDRAWABLE, (which the server uses to
> identify the screen), would work fine and would be simpler. But, since
> XCB is intended to be a tight binding to the actual protocol, that
> would not be a good idea.

I think that would make the expected use cases more difficult. My
reading of the intent of the request is to make it easy to create a
pixmap that's compatible with some specific other window or pixmap, for
later CopyArea operations. If a screen were required, then you'd need to
wait a GetGeometry round-trip to find out the root of that other
drawable before you could make your CreatePixmap request.

This means that your comparison with the "parent" argument of
CreateWindow is apt, though. This is maybe more of a "cousin"?

I leave it to others to edit the X protocol specification, though. My
goal is for XCB's XML descriptions to match the English specifications
as closely as possible, and so I'm not inclined to fix this in XCB
unless somebody fixes it in the English.

> OK, so finally, let's look at the code I came up with to get an
> XCBDRAWABLE from a screen, (let's assume screen 0), to pass into this
> parameter for XCBCreatePixmap. I wrote:
> 
> 	XCBSCREEN *root;
> 	XCBDRAWABLE root_drawable;
> 	root = XCBConnSetupSuccessRepRootsIter(XCBGetSetup(c)).data;
> 	root_drawable.window = root->root;
> 
> Ouch. Am I bringing pain upon myself, or is there no more convenient
> way to pull this off in XCB?

Well, in this case you don't need the 'root' temporary variable. ;-)

> Note that the equivalent code from Xlib is:
> 
> 	DefaultRootWindow (dpy)

Note too that XCB refuses to track the screen number for you, so any XCB
equivalent is going to require that you provide the screen number too.

> I certainly won't recommend Xlib's namespace polluting naming
> convention, but it is nice that there is a single call to get the job
> done here.

Vincent's XCBAux bits, previously mentioned, I guess are the way to deal
with this. I'm still waiting to see a coherent, orthogonal, etc. model
appear for the functions in that library, but it makes a good
development playground right now.

> Let me mention a few specifics about the block of XCB code above:
> 
> "XCBConnection" seems a fine name for the primary opaque handle.
> 
> "XCBConnSetupSuccessRep" seems rather unwieldy, but I can imagine the
> name choice might be somewhat constrained by naming conventions. But,
> assuming this name is as commonly used as I suspect, it would be
> really nice to make it shorter if possible.

"ConnSetupSuccessRep" is a string that appears in the XML description.
We can change that to anything we want. I picked it not long after
starting work on XCB, and simply haven't touched it since. So what would
you recommend?

> Is there a one-to-one mapping between XCBConnection and
> XCBConnSetupSuccessRep? (I'm guessing so since one is opaque and one
> is not). If so, is there really a benefit to passing the
> XCBConnSetupSuccessRep* rather than the XCBConnection* to the iterator
> fetch functions like XCBConnSetupSeccussRepRootsIter ? It leads to the
> nesting in the calls above and also more use of the longer name. Could
> something like this work instead (or in addition):
> 
> 	XCBConnectionRootsIter (c).data;

In normal usage, there certainly is one and only one setup data chunk
for every connection. I could imagine somebody creating their own setup
data chunk somehow, but I'm not sure how or why they would. So from an
API perspective, this suggestion seems fine to me.

Due to code generation it's hard to implement, though, except by
hand-writing wrapper functions like:

XCBSCREENIter XCBConnectionRootsIter(XCBConnection *c)
{
        return XCBConnSetupSuccessRepRootsIter(XCBGetSetup(c));
}

And I have trouble seeing the point of that.

> Finally, once I do get an XCBSCREEN* through the above, I can find a
> root->root XCBWINDOW but XCBCreatePixmap needs an XCBDRAWABLE
> instead. Hence, I'm forced to do the root_drawable wrapping
> above. This is a rather annoying side effect of the otherwise very
> useful feature of extra type checking. Anyone have a suggestion for
> simplifying this "casting" operation which is known to be safe in this
> direction?

Two suggestions, and both have problems.

GCC has an extension for a "transparent_union" attribute for types (see
http://gcc.gnu.org/onlinedocs/gcc-3.4.4/gcc/Type-Attributes.html). But
"Transparent unions are designed for library functions that have
multiple interfaces for compatibility reasons." I figure the
non-portability makes this a non-option, but it sure is tempting.

I've previously demonstrated, with XCL, that GCC's optimizer can replace
inline functions that do these type conversions with zero instructions,
at least on x86. A function that unwraps the CARD32 from a window and
wraps it in a drawable requires no C type-casts anywhere, keeping
type-safety intact; but this still requires the syntax of a function
call everywhere the cast is required. Probably worse is the problem that
I don't know how to implement this portably: I think compilers that, for
whatever reason, ignore the 'inline' keyword are going to do weird
things, and I don't think this can be implemented in macros without
using more GCC extensions.

(The third suggestion, of course, is "don't use C", but I guess we'd
best not go there just now.)

> Anyway, I hope these few random thoughts might be useful. I know it's
> nothing like a comprehensive overview of the API, but I did want to
> pass along the few things that I ran into.

Yeah, this is great, Carl. Thanks!

--Jamey



More information about the xcb mailing list