From Fedora Project Wiki

< SIGs‎ | Laptop‎ | HotKeys

Key Processing

The processing of key events is completely different on the console than form X11. Both start with a key pressed or released on the keyboard. The keyboard then sends a scan code to the computer.

Kernel

Processing keys changed from 2.4 to 2.6 Kernel. Now (2.6) all key pressed are directly translated into input event using the constants from file:///usr/include/linux/input.h. For PS/2 and AT keyboards there is a mapping from scancodes provided by the hardware to keycodes. For normal keyboards this mapping is preconfigured but it can be extented with setkeycodes.

For USB keyboards and other input devices no scancodes exist. The device itself provides a description of its protocol (see USB Human Interface Devices ) and a mapping to USB event symbols found in the USB HID Usage Tables . These are then mapped to Linux keycodes. The USB driver still does not support many internet keyboards and their brokeness. As all special cases are directly compiled in it is difficult to make (yet) unsupported keyboards work or even to get to the information needed to fix them.

["../GenericUSBHandling"]

Keycodes are then mapped to events like Shift now pressed, Shift Lock, or q pressed. Per key there are 256 possible event - one per state of the mode keys (shift, alt control, altgr, + some more up to 8).

Console

On the console key presses are then be mapped to strings (normally single characters, but also escape sequences) wrote to the current tty. This mapping can be found under /lib/kbd/keymaps.

X11

X11 curently uses the kbd/keyboard driver. It switches the tty X runs in to raw mode. In raw mode the 2.4 kernel simply wrote the keyboard scancodes with out any mapping. Kernel 2.6 does not pass any scancodes through the driver stack and USB keyboards don't have scancodes at all. To cope with that the 2.6 kernel uses scancodes emulation: Each keycode is mapped to an scancodes that matches the default scancodes for default keyboards for default keys. In fact there is a one to one mapping from linux keycodes to scancodes produced. Because of that it is (should be) sufficient to configure hotkeys on kernel level via setkeycodes.

The following keys are mapped to the same scancodes:

  • HANGEUL, FRONT -> 140
  • ISO, KATAKANAHIRAGANA -> 112

The raw mode emulation has the disadvantage that it can only support 240 (in theorie 255) keycodes. But the kernel knows over 300 keys to the emulation just doesn't cut it anymore.

Further processing within X is done by xkb. The scancodes are mapped to xkeycodes (/usr/share/X11/xkb/keycodes/xfree86) which are mapped to keysyms (e.g. /usr/share/X11/xkb/keycodes/de). This keycodes are very different from those used in the linux kernel. The mapping process is controlled by /usr/share/X11/xkb/rules/xorg.

Right now there is no mapping for the scancodes/keycodes produced by hotkeys. But if the kernel handles them correctly they produce defined scancodes with could be preconfigured to be mapped to keysyms. Main problem with that is that there are some linux keycodes that don't have a corresponding X keysym.

evdev

There is an still unfinished driver in X11 for using the /dev/input/event* devices which give much better access to the input event that the legacy raw mode. The X11 driver is named evdev like the kernel module providing these devices. It currently uses a hand crafted, compiled in table to map linux keycodes to X keysyms. If it could be extended to use the xkbd machinery it would be a good replacement for the kbd driver.

Other Sources of Keypresses

Right now there are two other sources of keypresses that are currently not fed into the regular key processing:

On IBM/Lenovo laptops some keys are only accessable as bits in /dev/nvram. There exist two daemons that can handle that: One in hotkey-setup and one in the tpb package. While the later does a lot of other things - like involing programs on keypresses - the first just feds the key presses into /dev/input/uinput which simulates regular key presses.

Another source might be ACPI events but it is still unclear if ACPI event should really trigger keypresses. Todo: Have a look at

/usr/share/hal/fdi/policy/10osvendor/10-power-mgmt-policy.fdi
/usr/libexec/hald-addon-acpi

/usr/share/hal/fdi/policy/10osvendor/10-toshiba-buttons.fdi
/usr/libexec/hald-addon-acpi-buttons-toshiba