X11 | 8bit characters | xmodmap , latin1 keysyms , compose sequences | app resources, xterm | xmond | xev | mem footprints
Various | Home


Some hints about xmodmap(1) and the X11 keyboard model

"If you're thinking that this is all senselessly complicated... you're right." - Jamie Zawinski


Content:

See also the GUI xkeycaps(1) with very good documentation about the keyboard model of X11.

If you are new to the keyboard model, read there first, and then come back for even more comments about subtle things.

This file contains raw iso-8859-1 (latin1) characters for documentation.

Wether you can really use special (non-ASCII, 8bit) characters, likely will depend on your locale settings.

If you have the XKEYBOARD/XKB Xserver extension (e.g. X11R6/XFree86), then see also setxkbmap(1) and several xkb*(1) tools. The according file format is sort of similar to the "loadkeys" format on some unix flavours (however, when collecting these notes, i only used X11R5 regularly, which is not providing any XKB extension).

The best documentation i found about the XKB/XKEYBOARD extension, is ${X11SRC}/doc/hardcopy/XKB/XKBlib.ps.gz

xkbseldb(1) is a quite valuable tool to correct a messed up XKB keyboard mapping (that is, xkbseldb -r; xkbseldb -lb; xkbsel -s <mapname>).


How to use an xmodmap file:

Add a call to xmodmap(1) to your X11 startup script. It's usually ~/.xinitrc for startx(1) and ~/.xsession for display managers.

Don't forget to search for existing and possibly appropriate keymaps on your system before you write your own. Some Linux distributors provide numerous mappings on their ftp server, e.g. Mandrake. For XFree86, you should firsty properly configure XF86Config.


In the following you will read a lot about "KeySyms"

X11 uses these logical names for keys - instead of the printables themselves or the literal names on the caps. There are KeySym-names for really all common keys in X11, thus it stays independent from the myriades of different physical keyboards and slightly different namings.

See <X11/keysymdef.h> or a list of KeySym-names and KeySyms with printables (one should distinguish between "KeySym-names" like "backslash", and "KeySyms" themselves, i.e. hexadecimal values like "0x5c").

To confirm that your remapping, in particular about using modifiers, was successful, use xev(1) and xmodmap(1) (without options).

Apart from the regular KeySym-names / KeySyms, you can also map arbitrary values, using the hexadecimal KeySym-notation (up to four digits):

    xmodmap -e "keycode <Keycode> = 0x<Hex-Value>"
(pointed out by Florian Weimer, de.comp.os.unix.x11 22-2-01)

Related: You can add new KeySym-names to the file XKeysymDB (see xmodmap(1)), but later on those new KeySym-names will not be recognized from XKeysymToString(3). Only the KeySym-value is visible and tools like xev(1) and xmodmap(1) behave accordingly then.


What's the format of a "keycode-line"?

(i.e. the result of "xmodmap -pke" or Suns "xmakemap")
keycode <x> = <1> <2> <3> <4> <5> <6> <7> <8>

Only the first four elements are platform-independent and of real interest (see below about the last four) :

    Solaris Openwin 3.5 (X11R5), Type-5 US keyboard
     <1>                           <key>
     <2>                     <shift-key>
     <3>             <"Mode_switch"-key>
     <4>       <shift-"Mode_switch"-key>
     <5>                <"Num_Lock"-key> 
     <6>               -
     <7>  <"Num_Lock"-"Mode_switch"-key>
     <8>               - 

Look at positions 1-4: There are two groups, each with two keys. You get the 2nd group with 'Mode_shift'/AltGr and the second key in each group with 'Shift'.

The fastest way, concerning typing, to get special (e.g. latin1) characters on US/EN Keyboards is to use "Mode_switch": For this purpose you have to map the KeySym Mode_switch onto a keycode of your choice and map it to an arbitrary, still available logical modifier, called mod1-5, see below You certainly also have to provide the KeySyms for the wanted special characters, you will usually put them in the second group, i.e. the 3rd and 4th position.

(XFree86 usually doesn't require the explicit mapping as modifier. This shall apparently ease the configuring. But it's not possible to refrain from modifiers in general.)

In contrast, the "Multi_key/Compose" mechanism doesn't need to be also mapped as modifier and is easier to configure, but you'll have to type more then - and not all applications support it. However older X11R5 Xservers do it completely Xserver internally, then it works always.

( Only for the sake of completeness: If only a single key is defined in a group [certainly only possible with the last in a complete row], then it's a shorthand for a complete pair of a KeySym-name in small and CAPS. )

What about position 5-8:

(I only use X11R5 and thus most of my keycodes are only mapped with four KeySyms.)


The action of mapping itself

'General' order for mapping keys and modifiers:
- Clear the logical modifiers,
- Then map KeySyms to keycodes,
- Finally map the logical modifiers
(xkeycaps does it 2-1-3, which works as well)


System specific:


There are also application specific ways for mapping

For example XTerm(1): if you often use Meta for command line editing (bash/readline etc, or even emacs) - and if you want to get both latin1 chars and command line editing with the same modifier key (example: <meta-a>: "ä", <meta-b>: "backward word"), then you can use the 'translation tables' of libXt, e.g. in xterm(1):
XTerm.VT100.translations: #override Meta<Key>a: string("ä") \n\ [...]


post scriptum

The xkeycaps documentation mentions:
"Not all vendors support the use of the Multi_key keysym; in particular, Digital, Sun, and HP support it, but the X Con- sortium does not. (The reason for this, I am told, is that ``Compose'' sequences are considered obsolete; the party line is that you should be using Input Methods to do this.)"

Later on then:
"Whether Multi_key works is a property of the Xt library (not the X server) [...]"

This however is not true in general. In Sun-X11R5 this is done by the Xserver itself.


2002-07, 2005-05, Sven Mascheck