Library for translating XKB key codes to Windows ones
Today, there are at least four protocols for extended support for keyboard input in terminals (with such features as distinguishing between pressing and releasing a key, obtaining a key code regardless of the keyboard layout, and so on).
- Windows Terminal's one https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md
- far2l terminal extensions https://github.com/elfmz/far2l/blob/master/WinPort/FarTTY.h
- kitty's one https://sw.kovidgoyal.net/kitty/keyboard-protocol/
- iTerm2's one https://gitlab.com/gnachman/iterm2/-/issues/7440#note_129307021
Each has its own merits and demerits. This small library helps in implementing 2 of them, far2l extensions and win32-input-mode, in terminals on *nix platforms.
Both standards encode KEY_EVENT_RECORD Windows structure to escape sequences. The problem is that this structure uses Windows key codes that are not available on other platforms.
To solve such a problem, I wrote this library. It uses publicly available data (see comments in source code) to provide translation of XKB keycodes into Windows event keycodes. Also included is an example app showing how to properly use this library to process X11 input and generate win32-input-mode escape sequences.
Important note on Virtual Scan Code field. It is keyboard layout dependent, but we always set it as it would be for English keyboard layout. That can be probably be fixed using configuration file so user can override translation table, but I am not sure it is needed at all. Apps should not rely on Virtual Scan Code for char keys anyway as there is no way for app to know what keyboard layout is selected by terminal user (that problem is also noted in win32-input-mode spec). So for getting keyboard layout dependent input UnicodeChar field should be used instead, and for dealing with hot keys in keyboard layout independent mode Virtual Key Code should be used instead. Actually the only use case for Virtual Scan Code that I can see for now is distinguishing between left and right Shift key presses.