3 Jan 2007 crhodes   » (Master)

One of the things I like about X11 is that it's not the library API which is specified, but the wire protocol. This allows building of abstractions in an idiomatic way for every given language, with none of the penalties involved in layering atop an existing foreign library – which penalties can be both from impedance mismatches between the implementation languages, and from maintenance headaches should the details of the library change. Instead, the X11 wire protocol is extensible (through server extensions) in a backward-compatible way, so code written for old versions of the protocol continues to work, if perhaps less beautifully.

So, the Common Lisp community has inherited some work done by Texas Instruments in 1987 to write an interface, named CLX to the X11 protocol. Generally, the interface is quite idiomatic and naturally Lispy; anecdotally, it's nicer to use than Xlib (a C binding) – I haven't heard enough about the new C bindings (XCB) to judge.

The downside of this language neutrality is the possibility of not having enough eyes to find bugs and hands to fix them: given that very few people use CLX, and fewer still know much about the X11 protocol, problems can languish unfixed for a long time. One such was exposed by the McCLIM backend using freetype and the RENDER X11 extension for font rendering: an attempt to display strings of more than 254 characters in length would generate nasty-looking X errors (BadGlyphSet errors for strings of 255 characters, followed by LengthError for longer strings).

From inspecting the X server source code, it would appear that this is because the encoding of glyph sequences on the wire for the RenderCompositeGlyph32 request (and its 8-bit and 16-bit siblings) seems... how can I put this... odd. The protocol documentation is unclear (to me) on this issue, but it seems that there is an 8-bit length field for a sequence of glyphs from the current glyphset, and that 255 is an escape code in that length field to indicate a change of glyphset. I don't know why it was done this way, given that there are then three spare bytes which are unused by this protocol – maybe no-one anticipated that displaying strings of 255 or more characters might be desired? In any case, this, coupled with a naïve interface to the protocol request, explains the errors we were seeing, as attempting to render a string of 255 characters triggered the escape code, meaning that x- and y-offset values were in fact interpreted as a glyphset – unsurprisingly, an invalid one. Strings longer than 255 characters would have only the low 8 bits encoded in the length, and so would generate length mismatch errors. Hooray, everything makes sense.

I've constructed a putative fix for this in CLX, and sent it to the mailing list. It's not quite as efficient as it could be, and there will no doubt be extra hair as and when a :translate keyword argument is added to that function, analogous to the functionality for draw-glyphs, but it seems to work on the limited testing I've given it. I'd appreciate comments and corrections from people who actually know X11 and/or CLX, though.

Latest blog entries     Older blog entries

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!