Search Contact information
University of Cambridge Home Department of Engineering
University of Cambridge >  Engineering Department >  computing help

Customising keyboards under X

[Non-motif applications] [Motif applications] [Other libraries and applications] [SuSE]
The original was posted to comp.windows.x by Chuck Dillon (dillon@gcg.com).

Although this may seem like a simple issue it is in fact one of the most complicated/convoluted things about X Windows - "If you're thinking that this is all senselessly complicated... you're right" - Jamie Zawinski, author of xkeycaps.

Non-motif applications

When you press a key on the keyboard in a non-Motif program the following applies
  1. A code for the key is passed from the OS driver to the X server. Those codes are specific to the operating system. (i.e. BackSpace might be the value 79)
  2. The X server translates those codes (together with the state of the modifier keys - SHIFT, etc) to what are called X keysyms (key symbols) which are OS independent. (e.g. BackSpace becomes XK_BackSpace (=0xff08)). On a Unix system, typing "xmodmap -pk" will show you the mapping from the keycode (the identity of the physical key pressed) to the keysym (the interpretation). A single keycode can generate up to 8 different keysyms. Programs can change this mapping but it will affect all clients currently running.
  3. The keysym is converted to a string. This can be changed on a per-client-program basis.

Typing "man xmodmap" and "man xev" offers help on 2 useful programs

The potential problem with using xmodmap is that all applications are affected so remapping at that level could fix a problem in one place (i.e. Motif apps) and break it in another (i.e. Athena or OpenWindows apps or in xterm). If your investigation leads you to xmodmap make sure you also check the capabilities of your Xserver. It may well provide (under properties) a GUI based dialog for doing keycode mappings.

If you are talking about an xterm (or dtterm but dtterm is a Motif app so the stuff below applies) you should also type "man stty" and investigate how the tty is handling keyboard events. Also the "xkeycaps" program (which is free) is useful to check current settings. xkeycaps creates a virtual keyboard which can be connected to another program's window.

On our teaching system some applications interpret the Backspace key in unexpected ways. You can try

     xmodmap -e "keycode 111=BackSpace"
to change that behaviour and
     xmodmap -e "keycode 111=Delete"
to restore it.

Motif applications

In Motif the steps are slightly different
  1. A code for the key is passed from the OS driver to the X server.
  2. The X server translates those codes into X keysyms
  3. These X keysyms are translated into Motif 'virtual keysyms'. (e.g. BackSpace becomes osfBackSpace whose value is specific to the particular process)
  4. These virtual keysyms are translated into actions to take. (i.e. osfBackSpace in a textfield means call the delete-previous function)

On our system /usr/lib/X11/XKeysymDB lists some virtual keysyms.

For Motif applications the mapping in stage 3 is set up by default, but users can override this by having a ~/.motifbind file. Under Solaris, the default configuration file is at /usr/dt/lib/bindings/sun_at. The standard (built in) virtual bindings (mapping from X keysyms to virtual keysyms) on a solaris machine (using the Sun provided Motif libraries) are tailored to a Sun keyboard. Copying sun_at to ~/.motifbind describes, to Motif, a mapping that is tailored to a typical AT style PC keyboard. You might need to tweak the file depending on how well that vanilla definition of an AT keyboard matches what you have.

NOTE: a binding file describes a particular keyboard. If you use more than one desktop display/keyboard with different keyboards you may need two or more binding files. For example, if you put sun_at in ~/.motifbind and then sit in front of a Solaris machine with a Sun keyboard you will probably see problems with Motif apps because the ~/.motifbind still describes a PC keyboard. To solve this you need a more elaborate setup. Type "man VirtualBindings" for details. In a nutshell, you can either explicitly assert the appropriate bindings using the "xmbind" program (e.g. in your .login, .xinitrc, interactively or whatever) or you can set up a 'binding alias' mechanism that maps the Xserver's 'vendor string' to a specific binding file.

For a Motif application (Netscape for example) you can try putting client-specific lines like the following in the X defaults files

Netscape*XmText.translations: #override\n\
      <Key>osfDelete: delete-previous-character()\n\
      <Key>Delete: delete-previous-character()\n\
      <Key>Backspace: delete-previous-character()
     
Netscape*XmTextField.translations: #override\n\
      <Key>osfDelete: delete-previous-character()\n\
      <Key>Delete: delete-previous-character()\n\
      <Key>Backspace: delete-previous-character()

Other libraries and applications

SuSE

When setting up a thin-client to a SuSE machine (sieve), in June 2004 ceb found that she could get Backspace to be backwards-delete in emacs by interactively using "M-x normal-erase-is-backspace". However, putting "(normal-erase-is-backspace-mode 1)" into ".emacs" had no effect.

Backspace could be set to be backwards delete in a shell in xterm on SuSE linux (but not Redhat Linux where it is also mapped to forwards delete!), by adding "XTerm*deleteIsDEL: True" to Xresources.

© Cambridge University Engineering Dept
Information provided by Tim Love (tpl)
Updated October 2004
Localised by Tim Love from an original by dillon@gcg.com.