[home]
Linux on a Fujitsu P2120A


Changing the keyboard layout in X, the hard way

The following notes describe how I changed the keyboard layout on the Lifebook P2120 so that the right shift key is exchanged with the '/' key. Later, I figured out an easier way. To see how it's done the easy way, see here.

October 29, 2003: After several hours of experimentation, I figured out how to change the keyboard layout of the P2120 in order to solve the annoying problem with the right shift key.

As you can see in the picture, the original location of the right shift key is to the right of the "up" key. The shift key should actually be approximately where the "/" and "up" keys are. I solved this problem by exchanging the "shift" and "/" keys (as marked in blue in the picture). It is much easier for me to get used to the "/" key being in a non-standard location than the "shift" key. (Oh, and by the way: I did not write on my keyboard. I applied a layer of Scotch tape, wrote on that, and then I topped it off with a second layer of Scotch tape to keep the ink from smearing).

Background: keyboard maps in X

First, let me relate what I found out about how the keyboard is configured in the X Window system. Everything starts from your XF86Config file, which is usually located in /etc/X11. (Check near the top of /var/log/Xfree86.0.log to find out the location of the configuration file that is actually used - it might be XF86Config-4 in some cases?). This file contains a Keyboard section similar to the following:
Section "InputDevice"
        Identifier  "Keyboard0"
        Driver      "keyboard"
        Option      "XkbRules" "xfree86"
        Option      "XkbModel" "pc105"
        Option      "XkbLayout" "us"
EndSection
Let us look at what the different options mean. "Keyboard0" is just an arbitrary identifier. "keyboard" is the driver, and this refers to the driver described on the man page keyboard(4). This particular driver is built into the X Window system. "xfree86" is the name of a file which contains rules for how to interpret the remaining options. This file is actually located in /usr/X11R6/lib/X11/xkb/rules/xfree86. It is made up from comments and two kinds of code: the first kind are lines of the form
! $pcmodels = pc101 pc102 pc104 pc105
which are variable definitions (define $pcmodels to be an abbreviation of whatever is on the right-hand-side). The second kind of code in this file are several sections similar to the following (abbreviated):
! model         layout  =       symbols
  pc98          nec/jp  =       nec/jp(pc98)
 $pcmodels      *       =       pc/pc(%m)+pc/%l%(v)
  *             *       =       pc/pc(pc105)+pc/%l%(v)
The first line of this section (which starts with "!") has the words "model" and "layout" on the left of the equality sign. These words refer to the corresponding options "XkbModel" and "XkbLayout" in the file XF86Config. On the right of the equality sign, there is the word "symbols", which refers to a directory: in this case, the directory /usr/X11R6/lib/X11/xkb/symbols/.

The following lines of each section are of the form <patterns> = <action>. The patterns are matched from top to bottom against the corresponding values supplied by the "XkbModel" and "XkbLayout" options in the file XF86Config. A wildcard "*" matches anything. In our case, model="pc105" and layout="us". Since "pc105" is one of the $pcmodels defined earlier, the first line which matches in our case is the third line which reads:

 $pcmodels      *       =       pc/pc(%m)+pc/%l%(v)
The right-hand-side specifies where to get the rules for this keyboard. Here, %m stands for the model ("pc105" in our case), %l stands for the layout ("us" in our case), and %(v) stands for something (not sure, a variant maybe?). The plus sign "+" separates several files which should be read. Finally, the value in parentheses, if any, specifies a particular procedure in the given file. So in our case, we should read the pc105 procedure in the file pc/pc, as well as the default procedure in the file pc/us. These filenames are relative to the directory specified in the "!" line, so they are actually located in /usr/X11R6/lib/X11/xkb/symbols/pc/pc and /usr/X11R6/lib/X11/xkb/symbols/pc/us.

Looking at /usr/X11R6/lib/X11/xkb/symbols/pc/pc, we find that this file is made up of a number of procedure definitions of the form

xkb_symbols "sample" {
    include "pc/pc(pc104)"
    key <TLDE> {        [     grave,    asciitilde      ]       };
    key <AE01> {        [         1,    exclam          ]       };
    key <AE02> {        [         2,    at              ]       };
    key <AE03> {        [         3,    numbersign      ]       };
    key <AE04> {        [         4,    dollar          ]       };
    key <AE05> {        [         5,    percent         ]       };
    key <AE06> {        [         6,    asciicircum     ]       };
    key <AE07> {        [         7,    ampersand       ]       };
    key <AE08> {        [         8,    asterisk        ]       };
    key <AE09> {        [         9,    parenleft       ]       };
    key <AE10> {        [         0,    parenright      ]       };
    key <AE11> {        [     minus,    underscore      ]       };
    key <AE12> {        [     equal,    plus            ]       };
};
What this does is: it first includes another procedure from the same (or another) file, and then it contains a bunch of key definitions, mapping physical keys to logical keys. (Actually, this is not quite true; the "phycial" keys are themselves defined in another file, /usr/X11R6/lib/X11/xkb/keycodes/xfree86, where they are mapped to actual physical keycodes, and some aliases for them are defined in /usr/X11R6/lib/X11/xkb/keycodes/aliases). I am not entirely sure about the exact syntax of everything that goes into the key definitions; what is clear is that for most keys, there are two values, a without-shift and a with-shift value. Modifier keys also need a line such as the following:
    modifier_map Shift  { Shift_L, Shift_R };

How I changed the keymaps

I created a file /usr/X11R6/lib/X11/xkb/symbols/lifebook, into which I put a single definition as follows:
// exchange "/" and "right shift" keys on the Fujitsu Lifebook P2120
// Author: Peter Selinger 2003/10/29

partial hidden alphanumeric_keys modifier_keys
xkb_symbols "rshift" {
    key <AB10>  { [  Shift_R  ]   };
    key <RTSH>  { [  slash,  question  ]  };
    key <UP>    { [  Up,  Shift_R  ] };
    modifier_map Shift  { Shift_L, Shift_R };
};
The "/" key is physically known as <AB10>, and we re-assign it to be a right shift key. The right shift key is physically known as <RTSH>, and we re-assign it to be the "/" key, or "?" if shift is also pressed. Finally, we define that if the shift key is already pressed, the "up" key should behave just like a shift key. This helps to alleviate the annoying problem where one sometimes presses the (new) "shift" and "up" keys at the same time, because the shift key is still not quite in the right place (although better than before).

Now for this file to be read, we need to make a rule for it. I made the following rule in the file /usr/X11R6/lib/X11/xkb/rules/xfree86 in the section "! option = symbols":

! option                =       symbols
  ...
  ...
  lifebook              =       +lifebook(rshift)
Finally, we need to enable this rule in the /etc/X11/XF86Config file. This is achieved by adding the following line to the keyboard section:
        Option      "XkbOptions" "lifebook"
Then I restarted the X Server (by logging out and back in), and all was well. (Of course, this only worked on about the 50th trial).

Effects of the keyboard change

The most noticeable, and desirable, effect is that the shift and "/" keys have been exchanged. But there are a couple of other interesting effects:

Back to Peter Selinger's Homepage: [home]
Peter Selinger / Department of Mathematics and Statistics / Dalhousie University
selinger@mathstat.dal.ca / PGP key