» Mapping unsupported keys with xmodmap
Nowadays, many keyboard have additional, so called "multimedia" keys (e.g. to increase/decrease volume, write an email, etc...). On notebooks, keys for volume up/down/mute are the rule rather than the exception. Those keys don't work out-of-the-box on Linux, or rather on X-Window (be it Xorg or XFree86). Let's see how to make something useful out of those keys.
The problemThose keys are very well supported from a hardware point-of-view. Pressing them does trigger input events in the kernel, and they are even received by X-Window. But the problem is that you can only bind them to specific actions if they are mapped to a "keysym" (key symbol). Examples of key symbols: a, 8, EuroSign, Return, Escape, Home or F10. Key events are received as keycodes (numeric values) by X-Window, mapped internally to keysyms and then X-Window (or KDE, or GNOME, or whatever) reacts to those X events (KeyPress and KeyRelease + the keysym) accordingly. Those special keys on your keyboard don't work because although they send keycodes, they are not mapped to any keysym.
The solutionHere is the plan:
- bind the currently unassigned keycodes to unused keysyms (e.g. F13, F14, ...)
- use xbindkeys or khotkeys (KDE) to execute commands (scripts, DCOP, ...) when those keys are pressed
xmodmapxmodmap comes with X-Window, e.g. on SUSE Linux it's in the package xorg-x11. We're going to add keycode-to-keysym mappings in ~/.Xmodmap, which will be read by xmodmap on X server startup (actually, /etc/X11/xdm/Xsession and /etc/X11/xinit/xinitrc run xmodmap $HOME/.Xmodmap when that file exists). Note that you don't have a .Xmodmap file under your home directory by default (the system-wide /usr/X11R6/lib/X11/Xmodmap is used, that itself is a symlink to /etc/X11/Xmodmap). The syntax of ~/.Xmodmap for assigning keycodes to keysyms is as follows: keycode <keycode> = <keysym> Here, for example, the for the keysyms Return and Home: keycode 36 = Return keycode 97 = Home The format is very simple, but the most complicated part has to be done first: we have to find out the keycodes that are emitted by those special keys.
Finding the keycodesTo find out what keycodes are sent to X-Window by those special keys, we are going to use xev, that is part of the core X-Window package as well (xorg-x11 on SUSE Linux). xev is a handy little tool that opens a window and traces all the X events that are triggered when your mouse is above that window. It also tracks focus and mouse events that are of no interest to us in this case and that generate a lot of bloat. Start xev as follows to only show the KeyRelease events:
xev | grep -A2 --line-buffered '^KeyRelease' | sed -n '/keycode /s/^.*keycode \([0-9]*\).* (.*, \(.*\)).*$/\1 \2/p'(just copy/paste that command on a shell and run it with your normal, non-root user) When the xev window appears, move your mouse above that window. Then press one of those special keys on your keyboard, and you will see the appropriate keycode in the terminal window where you typed the command above, for example:
160 NoSymbol 174 NoSymbol 176 NoSymbolNote that after pressing the key, you will most probably have to move your mouse around above the xev window, as it seems to queue the X events and will only show the keycode after a few other X events have stacked up (MotionNotify events in this case, doesn't matter, will be enough to flush out the event queue and the keycode will show up in the terminal). Take good note of those numbers (160, 174 and 176 in our example above) and with what keys they are associated. Note that the numbers from our example correspond to the "volume mute", "volume increase" and "volume decrease" special keys on a Dell notebook. We're now finished with xev, so you can terminate by typing Control+C in the terminal where you entered the xev | ... command above.
Back to xmodmapNow that we have the keycodes, we can write them down in our very own xmodmap configuration, namely in the file ~/.Xmodmap. We just have to decide to which keysyms we shall map them. I would recommend to use keysyms that are usually not bound to any keys, like F13, F14, and so on. In this example, we're going to bind the keycode 160 to the keysym F13, 174 to F14 and 176 to F15. Use your favorite text editor (vim, emacs, kate, nano, whatever) and put the corresponding lines in a file named .Xmodmap (note the dot and the capital X) under your home directory, like this:
keycode 160 = F13 keycode 174 = F14 keycode 176 = F15
Applying the xmodmap configurationThe ~/.Xmodmap file will automatically be interpreted by xmodmap every time you start the X server with startx or when you log into an X session using XDM/KDM/GDM. But to avoid restarting our current X session, here is how to apply our configuration immediately: