Multimediakeys with .Xmodmap HOWTO

Christian Weiske

Revision History
Revision 1.12006-07-30

Added global Xmodmap loading

Revision 1.22006-08-17

Getting horizontal scrolling work with my Logitech Trackball

Revision 1.32008-05-12

Adjust file locations

Abstract

This HowTo describes how to activate the extra keys (multimedia keys) like "mute", "play" and "mail" based on the ".Xmodmap" file when you are using a windowmanager based on a graphics environment like XFree86 or Xorg.


Table of Contents

Why should I do this by hand?
Getting started
Xmodmap
xev
Writing your own xmodmap
Activating the .Xmodmap at startup
Using a global Xmodmap file
Tips and scripts
play
stop
forward
rewind
Maps for Keyboards
Acer Travelmate 6000 (6003)
Logitech Internet Keyboard
Mice
Logitech Cordless Optical TrackMan
Links
License

Why should I do this by hand?

KDE allows you to do the same thing I describe here with its control center, perhaps Gnome as well. So why should you bother to do this by hand?

Answer 1: You want to get some more control and knowledge over your system. If you did it by hand, you'll know what to do when it doesn't work

Answer 2: You don't use KDE and want to use Multimediakeys

Answer 3: You don't like to have an extra program running (KDE daemon) just to have the multimedia keys working.

Getting started

(simplified) When you press a key on your keyboard, a keycode (e.g. 116) is sent to your computer. This keycode has to be converted to a symbol an application can understand, like an "a" or a "Space". The X window system contains a tool called xmodmap with which you can change the assignment of the keys - this is the point we interfere.

Xmodmap

'''Note''': I assume the xmodmap executable is in your {{PATH}}, so that you just have to type xmodmap. If it is not: xmodmap can be found at:

/usr/bin/xmodmap

To get a first impression what keycodes are mapped to which keys, just type

xmodmap -pke

which gives you a list of all mappings. For example, the line

keycode  57 = n N

means that the keycode 57 is mapped to a lowercase "n" if no extra key is pressed, and an uppercase "N" if shift is held.

xev

"Hey dude, how do I know the keycodes of the 'forward' key?" You're not a clairvoyant, and so there is a tool called xev - the X event tester. Open a console an type in

xev

Now you should see funny output in your console, especially if you move your mouse over the xev window. But now press one of your keys, e.g. the "a". The output should be something like that:

KeyPress event, serial 26, synthetic NO, window 0x3400001,
    root 0xae, subw 0x0, time 5800192, (600,303), root:(604,326),
    state 0x12, keycode 38 (keysym 0x41, A), same_screen YES,
    XLookupString gives 1 bytes:  "A"

KeyRelease event, serial 26, synthetic NO, window 0x3400001,
    root 0xae, subw 0x0, time 5800248, (600,303), root:(604,326),
    state 0x12, keycode 38 (keysym 0x41, A), same_screen YES,
    XLookupString gives 1 bytes:  "A"

You see two events here, the press and the release event. We just need one thing and that is the text

keycode 38

So you know that the "a"-Key on your keyboard has keycode 38. Now note the keycodes of your multimedia keys. If {{xev}} does not display an event if you press an extra key, than - bad luck. This HowTo won't help you.

Writing your own xmodmap

The standard location for your own modmap is ~/.Xmodmap [noobs: "~" is your home directory]. The format of the file is the same as xmodmap -pke gave you in the last section:

keycode (number) = (key name)

You know the number ( the keycode), just the key names are in the dark. One could use "F13", "F14" and so forth for the extra keys, but there are several names which describe the function of your keys perfectly: "XF86AudioMute", "XF86Mail", ... . There is a list of this names in

/usr/share/X11/XKeysymDB

With this knowledge you can create your own modmap. If this is too much work for you, have a look at the "Maps for Keyboards" section with predefined maps for several keyboard types. You can test your own map with

xmodmap $HOME/.Xmodmap

Activating the .Xmodmap at startup

Some distributions automatically load the ~/.Xmodmap when a user logs on in X - if yours does, consider yourself happy. One of the distris which doesn't do it is Gentoo, while SuSE does.

Here is how you get it loaded automatically: You've got to open

$KDEDIR/share/config/kdm/Xsession

and insert the following code at the beginning of the file (but after the shebang #!/bin/sh):

if [ -f $HOME/.Xmodmap ]; then
    /usr/bin/xmodmap $HOME/.Xmodmap
fi

Now save, logout and log in again. Your modmap should have been loaded now.

Using a global Xmodmap file

Xorg (at least in version 7.0) has an xinit script at /etc/X11/xinit/xinitrc that loads a global Xmodmap file for all users. The default location is /etc/X11/Xmodmap. Since KDE doesn't automatically do this, you should add it: Open the Xsession file (as described above) and add the following line:

[ -f /etc/X11/Xmodmap ] && xmodmap /etc/X11/Xmodmap

Tips and scripts

I associated the multimedia keys in the K MenuEditor with some scripts which handle functions like play, stop and forward. In this scripts you can do nice things like controlling XMMS when it is not the active window or control multiple applications with one key:

play

#!/bin/sh
#check if kaffeine is running
kaffeine=`dcop | grep kaffeine -c`
if [ $kaffeine = '1' ]; then
    #kaffeine is running, control it
    dcop kaffeine Kaffeine togglePlayPause
elif [ `pgrep tvtime` ]
then
    #tvtime
    tvtime-command TOGGLE_PAUSE
    tvtime-command TOGGLE_MUTE
else
    #no kaffeine, no tvtime
    #xmms play-pause
    xmms -t
fi

This code does the following: - if kaffeine (KDE video player) is running, a play/pause signal is sent to it - if tvtime (TV application) is running (but not kaffeine), the picture is paused and the sound is muted in tvtime - if none of the above, XMMS (X Multimedia System, like Winamp) shall play/pause

stop

#!/bin/sh
kaffeine=`dcop | grep kaffeine -c`
if [ $kaffeine = '1' ]
then
    dcop kaffeine Kaffeine stop
elif [ `pgrep tvtime` ]
then
    tvtime-command TOGGLE_PAUSE
    tvtime-command TOGGLE_MUTE
else
    xmms -s
fi

forward

#!/bin/sh
if [ `dcop | grep kaffeine -c` = '1' ]
then
    dcop kaffeine PlaybackControl posPlus
elif [ `pgrep tvtime` ]
then
    tvtime-command CHANNEL_UP
elif [ `dcop | grep kwintv -c` -gt 0 ]
then
    dcop kwintv KWinTVIface channelUp
else
    #xmms forward
    xmms -f
fi

rewind

#!/bin/sh
if [ `dcop | grep kaffeine -c` -gt 0 ]
then
    dcop kaffeine PlaybackControl posMinus
elif [ `pgrep tvtime` ]
then
    tvtime-command CHANNEL_DOWN
elif [ `dcop | grep kwintv -c` -gt 0 ]
then
    dcop kwintv KWinTVIface channelDown
else
    xmms -r
fi

Maps for Keyboards

Here are some keyboard maps I use. I know that there are many different keyboards out there and everyone needs its own map. So don't consider this list complete; and I won't extend this howto to a complete list.

Acer Travelmate 6000 (6003)

keycode 176 = XF86AudioRaiseVolume
keycode 174 = XF86AudioLowerVolume
keycode 160 = XF86AudioMute
keycode 236 = XF86Mail
keycode 178 = XF86WWW

Logitech Internet Keyboard

keycode 160 = XF86AudioMute
keycode 174 = XF86AudioLowerVolume
keycode 176 = XF86AudioRaiseVolume
keycode 162 = XF86AudioPlay
keycode 164 = XF86AudioStop
keycode 144 = XF86AudioPrev
keycode 153 = XF86AudioNext
keycode 236 = XF86Mail
keycode 229 = XF86Search
keycode 230 = XF86Go
keycode 178 = XF86HomePage
keycode 223 = XF86Sleep

Mice

A mouse sometimes needs a bit Xmodmap, too.

Logitech Cordless Optical TrackMan

Getting buttons beside the standard ones (Left/Right/Middle/Scroll wheel) to work sometimes is a bit tricky, but there is lots of documentation in the web. Here I describe how I got some more buttons working on my Logitech Trackball. Basically that are the left/right scroller - the tiny up/down scroller and the scroll lock button don't generate events here.

Using the Event Interface evdev

Using the standard IMPS/2 protocol for the trackball does not give us access to the additional buttons, we need to use the event interface of the Linux kernel and the respective X.org driver.

Note

I use X.org 7.0; the settings are different on X.org 6.8

Now check if the event interface already exists in your kernel: grep Handlers /proc/bus/input/devices which should return something like

H: Handlers=mouse0 event0

if it is activated (notice the "event0"). If not, enable it in your kernel at Device Drivers/Input device support/Event interface.

Now you are ready to activate the evdev driver in your /etc/X11/xorg.conf:

Section "InputDevice"
        Identifier  "Cordless Optical Trackman"
        Driver      "evdev"
        Option      "Device"        "/dev/input/event2"
        Option      "ZAxisMapping"  "4 5"
        Option      "Buttons"       "10"
EndSection

For the right event device number, see the grep output above.

Getting buttons to work

The driver alone doesn't assign the buttons correctly, so you have to do it on your own; the solution is - again - your Xmodmap file:

pointer = 1 3 2 4 5 8 9 7 6 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

Basically we assign the normal buttons (1 - left, 2 - right, 3 - middle), the wheel (4 and 5) but also assign buttons 8 and 9 to be at place 6 and 7, so that they can be used as left/right scrolling - which gives you the ability to move in your browser history by pressing the arrow buttons direcly above the left mouse button.

Links

License

This document is licensed under a Creative Commons license.