Keycodes, keysyms, and keymaps

Author: John M. Gabriele
Date: May 2007
Back to:homepage

Contents


I'm one of those folks who ends up needing to know some of this stuff because I use GNU/Linux with a programmable keyboard, and also touch type using the dvorak keyboard layout.

When you hit a key on your keyboard, it generates a signal (a "scan-code") that gets sent to the OS which is translated into a "keycode". You'll usually see keycodes written as decimal numbers (ex. 'a' is 38). Ctrl and Alt work like the Shift key and are called modifier keys.

BTW, ESC some_key (that is, pressing and releasing the ESC key, then hitting some_key) gets you the same thing as the Alt-some_key key combo. Also, you can get ESC by doing Ctrl-[.

If you're working in a console (no X11), then that's it. The keycode either gets turned into an alphanumeric symbol and written on the command line, or else is use for some other usual purpose on the command line. At the console, you can see what keycode gets generate by which key by running the showkey command. For example, on my system, 'a' keydown generates 0x1e (decimal 30), and 'a' keyup (when I release the key) generates 0x9e (decimal 158).

XXX Wait. Why does `showkey` in the console tell me 'a' is 0x1e (decimal 30) for keydown, and 0x9e (decimal 158) for keyup, but `xev` tells me it's keycode 38? (decimal, I believe). Hm. I get the same output using the -k option as I do with the -s option, so I may just be seeing scan-code values here. XXX

If you're using X, there's another level of indirection. X intercepts the keycode and turns it into a so-called "keysym", and then hands it off to whatever X client program it's destined for, letting that client decide what to do with it. For example, the letter 'a' is keysym 0x61 (decimal 97) otherwise known as 'a'.

Besides having a number (usually written in hex), keysyms have names too. For example, keycode 113 maps to keysym 0xffea, known as "Alt_R" -- the Alt key on the right side. Anyhow, X intercepts the keycode, and sends the keysym to to the current X client you were using when you hit the key.

Tip: in xterm, you can Ctrl-left_click and get a menu which lets you change a few settings regarding how xterm deals with various keysyms. For example, you may have to enable "Meta Sends Escape" to get the Alt key to work with some text editors (such as GNU nano). To make that persistent, add "xterm*metaSendsEscape: true" to your ~/.Xresources file.

The mapping between keycodes and keysyms (the "keymap") is accessed via the xmodmap command. To see your mapping, try xmodmap -pk to get something like:

There are 6 KeySyms per KeyCode; KeyCodes range from 8 to 255.

    KeyCode     Keysym (Keysym) ...
    Value       Value   (Name)  ...

      8
      9         0xff1b (Escape)
     10         0x0031 (1)      0x0021 (exclam)
     11         0x0032 (2)      0x0040 (at)
     12         0x0033 (3)      0x0023 (numbersign)
     13         0x0034 (4)      0x0024 (dollar)
     14         0x0035 (5)      0x0025 (percent)
     15         0x0036 (6)      0x005e (asciicircum)
     16         0x0037 (7)      0x0026 (ampersand)
     17         0x0038 (8)      0x002a (asterisk)
     18         0x0039 (9)      0x0028 (parenleft)
     19         0x0030 (0)      0x0029 (parenright)
     20         0x002d (minus)  0x005f (underscore)

...and so on.

Note that a short list of keysyms are associated with each keycode. That list is: the original symbol on a key, what you get using the shift key too, what you get using the next modifier key (like Ctrl), and so on. To see your list of modifier keys, use xmodmap -pm.

Modifying your mapping from keycodes to keysyms

To modify your keymap (aside from using the loadkeys command), you can pass a command expression to the xmodmap command, or you can run xmodmap on a text file full of such commands.

Further, those command expressions you use can be one of two kinds: either one that sets a keycode directly to keysym name, or else one that creates an alias of one keysym name to another:

xmodmap -e "keycode 107 = BackSpace"
xmodmap -e "keysym Delete = BackSpace"

That first one says to make the keycode 107 generate a BackSpace keysym. (Keycode 107 gets generated when I hit my Delete key.)

The 2nd one says to make whatever keycode that would usually result in a Delete to instead generate a Backspace.

Dvorak

There's a few ways to remap your keys to dvorak:

Links