I am writing a couple applications that change how your keyboard works. (One that allows key-chording, and another that allows you to say syllables out loud to type individual characters.) The "layouts" of these applications are handled in a way that it shouldn't matter what kind of keyboard or what kind of keyboard layout the person has while running the program, it should print the character you tell it to print anyway. I had to jump through a lot of hoops to get this working, and I think I understand how keyboard input normally works now on a typical Linux computer:

  • At the startup of the computer, XKB memorizes a table of what evdev scancodes correspond to what XF86 keycodes.
  • At the loading of the layout, XKB memorizes another table of what XF86 keysyms correspond to what Unicode characters to type out, mainly done by reading /usr/include/X11/keysymdef.h. Then it memorizes yet another table of what XF86 keycodes correspond to what keysyms (this is the "layout"). This is presumably just collapsed into a mapping of keycodes to characters.
  • Now, whenever evdev hears a keypress from the keyboard, and sends a scancode to XKB...
  • ...and XKB tells X to type out a particular Unicode character.

Since the backend of my applications is evdev, and what I actually want to do is what X does, this is very frustrating, because I have to simulate everything in between. Can I just directly tell X what to do? I don't mind needing admin access; that obviously comes with the territory. Just, I mean, if XKB can simulate keyboards with arbitrary geometries, why can't I pretend to be a keyboard with a key for every Unicode character?

My applications are in Python, but I can make do with anything in other languages.

EDIT: It appears that the dam is at the point where the process reading in the keypresses calls XLookupString() on the report of the XKeyEvent generated by the keypress. The process will interpret the keypress as corresponding to whatever KeySym that XLookupString() returns. This is bad news, because XLookupString() gets the information about the keycode-keysym correspondence from XKB's layout. So to fake the typing of an arbitrary keysym, either we need to make XKB lie about the layout, or make XLookupString() lie about the keysym.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.