Using xmodmap to change the keyboard layout

One of the first things I do whenever I get on a new computer is to go the GNOME keyboard preference dialog and switch caps lock and the left control. While this has sufficed in the past, I now have a situation where I’d like to do a more complicated keyboard modification.

Note: The following was done on an Lenovo S10-3t running MeeGo 1.1.

A KeyCode is the numerical code for the key. A KeySym is the symbolic code for the key. For example, my Return key has a KeyCode of 36 and a KeySym of Return.

Determining KeyCodes and KeySyms
The first thing to do is to determine the KeyCode and KeySym for the keys your want to change. This can be done by generating a list for all keys or interactively. The former approach is done by issuing the following command.

xmodmap -pke > kbd_mapping.txt

Here I’ve redirected the output to a text file so that I can view the results in a text editor. A small section of the contents look like this.

keycode 36 = Return NoSymbol Return
keycode 37 = Control_L NoSymbol Control_L
keycode 38 = a A a A ae AE
keycode 39 = s S s S ssharp section
keycode 40 = d D d D eth ETH
keycode 41 = f F f F dstroke ordfeminine
keycode 42 = g G g G eng ENG
keycode 43 = h H h H hstroke Hstroke
keycode 44 = j J j J
keycode 45 = k K k K kra ampersand
keycode 46 = l L l L lstroke Lstroke
keycode 47 = semicolon colon semicolon colon dead_acute dead_doubleacute
keycode 48 = apostrophe at apostrophe at dead_circumflex dead_caron

The different columns to the right of the equals sign corrospond to the way modifier keys change the key. Obviously the second column is the effect of the shift key being pressed. As always, the man page is the place to look for more details.

The interactive approach uses the following command.

xev | grep -A 4 KeyPress

Because xev produces a lot of output we use grep to filter only for ‘KeyPress’ events.

Here is some example output

KeyPress event, serial 29, synthetic NO, window 0x2400001,
root 0xaa, subw 0x0, time 3663762, (159,-24), root:(582,207),
state 0x0, keycode 36 (keysym 0xff0d, Return), same_screen YES,
XLookupString gives 1 bytes: (0d)

Here the KeyCode is 36 and the KeySym (also given in hex) is Return.

Once you’ve got the code and symbol combination you want, you you can place them in a file named .Xmodmap. The format for entries is the same as the output from the ‘xmodmap -pke’ command. A section of my file looks like this.
keycode 66 = Control_L NoSymbol Control_L
clear Lock
add Control = Control_L

keycode 135 = ISO_Level3_Shift Multi_key ISO_Level3_Shift Multi_key
keycode 108 = Alt_L Meta_L Alt_L Meta_L

Here I’ve turned my Caps Lock key into a control key. I’ve also moved ‘Alt Gr’ to the menu key and ‘Alt Gr’ is now an additional Alt key. The clear and add commands are necessary to redefine modifier keys. Again, see the man page for more info.

While I’ve put the commands in .Xmodmap so that it’ll persist acrooss restarts, you can also use the ‘xmodmap -e’ to test these changes out. For example, the first 3 commands would look like this.

xmodmap -e 'keycode 66 = Control_L NoSymbol Control_L'
xmodmap -e 'clear Lock'
xmodmap -e 'add Control = Control_L'

On MeeGo and openSUSE the .Xmodmap file is detected at session start. However, I’ve read that’s not always the case. So, consult your distro’s help if you have problems with loading.

Leave a Reply