Customizing the keyboard map

It might at first seem a bit strange to think that you would want to change the keyboard map, i.e. the symbols that the various keys on the keyboard generate. However, the way key presses are converted into characters under X11 is completely customizable, and this can be surprisingly convenient.

For example, if you enroll in a foreign language class, you may find yourself typing papers that contain characters or diacritical marks not used in English. In French, it is common to need a `c' with a cedilla or an `e' with a grave accent. In German, the eszett is required. All of these characters can be conveniently mapped to keys on the keyboard so they are available in programs like OpenOffice.

Before creating new key definitions, it is important to realize that there are two kinds of keys on a keyboard. There are keys that ``do something'' and there are keys that modify the behavior of other keys.

Shift, Ctrl, Alt, Caps Lock, Num Lock, and Scroll Lock are all modifier keys. On some keyboards you may also find Meta, Mode switch, and Multi keys. In fact, the Meta key is so important, that on many keyboards without a separate Meta key, the key labeled Alt is actually mapped to Meta.

There is a program that can tell you all of the key bindings under X called xev which reports ``X events.'' When run from an xterm window, xev opens a new small window. Move the mouse into the window and numerous events will be reported back in the xterm, mouse events in this case. Hit a key, however, and you see events corresponding to the key press and key release. For our use, the keycode number and keysym are the important parts to note.

Mapping single keys with xmodmap

According to xev, the right-most ``Windows key'' on my IBM keyboard has keycode 117. I don't have much use for such a key under X, so I have given it a new assignment with xmodmap, to Mode switch. The command to do this is:

Example 10-4. Assigning one key with xmodmap

$ xmodmap -e "keycode 117 = Mode_switch"

The Mode switch key is sort of like a super shift key, and we can use it to map foreign characters onto the keyboard. For example, to add a grave `e' to the keyboard, we might use:

Example 10-5. Assigning an accented character to the keyboard

$ xmodmap -e "keysym e = e E egrave Egrave"

Notice here the assignment is made by key symbol and not by key code, but otherwise the syntax is similar. This line assigns 4 characters to the what is currently the E key (usually this is the key with the letter E painted on it, but hopefully you can see why this wouldn't have to be the case). Unshifted, the key produces a lowercase e. With shift, it produces an upper case E. With mode switched (when you hold the Mode switch and press E), it produces a lowercase e with a grave accent. Finally, with both shift and mode switch, it produces an uppercase E with a grave accent.

Mapping the entire keyboard with xmodmap

The commands above might be convenient for mapping one or two keys, but it would be a burden to make mappings for a whole keyboard that way. Fortunately it is easy to save a key map, edit it, and reload the modified map again. To get the current map from xmodmap, use the -pke option.

Example 10-6. Saving the current key map

$ xmodmap -pke > keyboard.orig

This creates a file of keycode mappings, one per line, describing the current keyboard layout. Edit a copy of this file to make any desired changes and reload it with xmodmap to make the new assignments effective.

Example 10-7. Changing the entire key map

$ cp keyboard.orig
$ vi
$ xmodmap

The keyboard map is reset every time you logout (you wouldn't want your friends stuck with your map), so this file also serves as a way to restore everything to your preferred configuration when you login again.

Other customizations and information about using xmodmap

To make the most effective use of foreign characters and diacritical marks, it is helpful to have a list of available key symbols. One authoritative source of symbol names is keysymdef.h which is often located in /usr/X11R6/include/X11/keysymdef.h. You can also search for it using the locate command. It contain key symbol definitions for programmer, which typically have names like XK_egrave. Remove the XK_ to obtain names that can be used in xmodmap.

Note: keysymdef.h has symbols for many different character sets. You are probably using the Latin 1 set, so look for the section that begins ``#ifdef XK_LATIN1''.

Xmodmap can be used to make changes to the pointer (mouse) buttons as well. The most common use is to reverse the order of the buttons for left-handed people. It can also make buttons sticky, the way the Caps Lock is. Check the man page for more details.

Finally, there is one other way to enter foreign characters from the keyboard, by using a Multi key. If you define a key to have the Multi_key symbol, when you press that key, the computer knows the next two keys are to be combined to form a special character. For example, Multi then ` then a would enter a grave a.