Why I love D: interfacing with XCB

H. S. Teoh hsteoh at quickfur.ath.cx
Wed Apr 6 20:20:26 UTC 2022


On Wed, Apr 06, 2022 at 07:10:36PM +0000, Adam D Ruppe via Digitalmars-d wrote:
> On Wednesday, 6 April 2022 at 18:42:42 UTC, H. S. Teoh wrote:
> > The original core library is Xlib, which is still in widespread use
> > but is dated and suffers from a variety of issues.
> 
> Those alleged issues are pretty overblown. My biggest sadness with it
> is it assumes i/o failures are fatal, but you can kinda hack around
> that by throwing a D exception from the handler lol.

I suspect some of the issues have since been solved, since Xlib nowadays
is implemented on top of XCB. :-P


> > One such pain area is keyboard handling.  Won't get into the dirty
> > details here, but if anybody's interested, just ask. ;-) (I *did*
> > manage to get rudimentary keyboard handling without touching Xlib at
> > all.)
> 
> keyboard handling is kinda inherently messy

Yeah, but with X (like *core* X protocol, without Xlib) it's a whole new
level of messy that I hadn't expected before. :-P

Basically, the X server *only* trades in keycodes, which are arbitrary
numbers associated with physical keys on your keyboard.  To make any
sense of these keycodes, you need to map them to keysyms, i.e., standard
numbers representing named keys. In Xlib, mapping a keycode to a keysym
is just 1 or 2 function calls away.  In XCB, however, you have to
reinvent what Xlib does under the hood:

1) First, you have to retrieve the keyboard mapping from the X server,
which is a table of keysyms that a particular keycode may map to.

2) But each keycode may map to ≥4 keysyms; to decide which one is in
effect at the time of a keypress, you need to look at the current
modifiers in effect (shift, capsLock, etc), and based on the
algorithm described in the X protocol, decide which of 4 keysyms it will
be. This would've been a trivial task, except that the meaning of the
modifier bitmask may change depending on server configuration; in order
to figure out which bit corresponds with the "mode switch" modifier, you
need to ask the X server for the modifier map, and scan the table for
the "mode switch" keysym and remember which bit it corresponds to.

3) You'd think that solves the problem, but no, there's more. Both the
modifier map and the keyboard map may change over time, so you also have
to process MappingNotify events, and reload the relevant portions of the
keyboard map or the modifier map (and potentially refresh your current
understanding of modifier bits).  One potential gotcha here is that all
subsequent KeyPress events after the MappingNotify will use the new
mapping, so you have to make sure you refresh the keymap and modmap
*before* processing any subsequent KeyPress events.

4) But even after this, you're not quite done yet. Most applications
don't know nor care what keycodes or keysyms are; they usually want to
translate keysyms into actual characters (ASCII, Unicode,
what-have-you). To do this, you need to use a table of keysym -> ISO
10646 (i.e., Unicode) values:

	https://www.cl.cam.ac.uk/~mgk25/ucs/keysym2ucs.c

5) This isn't all there is to it, though. There's also XKB and the Input
extension, which you will need if you want to support things like
combining characters, dead keys, and input methods. (I haven't gotten
that far yet, 'cos with (1)-(4) I already have a pretty workable system.
XKB, if the server has it (pretty much all modern servers do), simulates
most of its functionality via X11 core protocol to clients who didn't
enable the XKB extension, so keyboard input will "mostly work" at this
point, as long as you handle (1)-(4) correctly.)

So there you have it, X11 keyboard handling without Xlib in a nutshell.
;-)


T

-- 
Ph.D. = Permanent head Damage


More information about the Digitalmars-d mailing list