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
evdevscancodes 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
evdevhears 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
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.