The keyboard interfaces and protocols in X
peter.hutterer at who-t.net
Tue Feb 15 00:35:58 UTC 2022
On Sun, Feb 13, 2022 at 07:01:04PM +0200, John Found wrote:
> I am trying to create a X client that to communicate to X server by the
> raw protocol, not using any libraries, such as XLib or XCB.
> While with the graphics part it was simple and straightforward task,
> solved by simply following the protocol (The documentation on X11 is
> pretty complete and well written) and extensions documentation is
> available (although the MIT-SHM documentation on the protocol does not
> exists at all), I have stuck with the keyboard part of
> the protocol.
> The biggest problem is the conversion from the keycodes into the
> Unicode characters (of course where it is possible).
> Do I need XKEYBOARD extension? On only XINPUT. Or both. The
> documentation is complex and poorly written. I have a feeling that part
> of it was written not to be useful, but simply because it had to be
> So, the question:
> What is the simplest, canonical, expected way to handle the keyboard
> events in X protocol in order to obtain the Unicode codes of the
> pressed keys? In raw protocol therms. And supporting multiple
> languages, of course.
> I understand that some processing on the client side is required, but I
> am missing the whole picture of the process.
Slightly more than "some" but yes, you need to process this. Think of the
keyboard as a 105-key mouse. Now you get a button event for button 72 - what
unicode code is that? The correct answer is: "this is the wrong question".
X works with keycodes which are _hardware_ codes.  You *need* a keymap,
which tells you that hardware code N maps to unicode point M. You can deal
with the core keymap only, or you can accept that everyone has been using XKB
for decades now. The server gives you that core keymap but that still means
you need to do the state handling for modifiers etc yourself.
If you want to avoid libx11/xcb, you should use libxkbcommon. Handling all
this yourself means you'll spend the majority figure all this out. I doubt
that's the goal. There's still some extra work needed since you don't get the
component names from the core protocol but you can hack around that. At least
you won't have to implement all of XKB client-side with libxkbcommon.
 They are now mostly normalized on Linux to evdev codes (+ offset 8) but
that's a relatively recent addition given the age of X.
More information about the xorg