Archive

Multimedia keyboard hot keys

Introduction

A lot of keyboards now have multimedia hot keys on them. For example, most of the Logitech keyboards have the ability to mute the sound and turn the volume up or down. It is possible to use them under X on Linux.

Keyboard keys pass through a ludicrous number of different remappings on Linux before X applications receive them.

But they’re not “remapped” at all. The XServer has to communicate back to the XClient (via the window manager) the key that was pressed. This isn’t remapping whatsoever.

  1. The keyboard generates scancodes
  2. The Linux console driver remaps these to Linux keycodes (see /usr/include/linux/input.h)
  3. The X keyboard/kdb performs a HARD-CODED map to X keycodes
  4. The X server performs a mapping from X keycode to Key Symbol

But, being Linux, there is more than one way to do it.

  1. The keyboard generates scancodes
  2. The Linux event driver converts these to key events
  3. The X evdev driver converts events to keycodes
  4. The X server performs a mapping from X keycode to KeySym(bol)

I can’t get this second way to do anything with extended keys. The first way works, but there are lots of different maps to configure. Ideally, the aim is to get correct KeySyms to be generated by X when the key is pressed. This will allow all X clients to act on these keys in the expected way.

Finding where extended keys are failing

Run xev from a console. With the mouse pointer over the small white window, pressing the key you want should generate a Key Event in the window. This will list the X keycode and the name of the keysym, if there is one, or NoSymbol otherwise.

If no event is generated, X isn’t receiving the event, and your kernel scancode mapping is broken.

If the wrong KeySyms are coming out, your X keyboard map may be wrong. You should experiment with setxkbmap to find the correct keyboard layout. Not all keyboards will have a layout configured; you may have to add a new one in /usr/share/X11/xkb/symbols/inet. If your keyboard map is right, this could be caused by the kernel scancode mapping simply being incorrect.

Fixing an incorrect kernel scancode mapping

If your keyboard is available in Xkb, but the kernel scancode mapping is wrong, it is possible to reconfigure this map, preferably by writing an init script to do so.

  1. Deduce the X keycode the key SHOULD generate by reference to  /usr/share/X11/xkb/symbols/inet and /usr/share/X11/xkb/keycodes/xfree86.
  2. Refer to the table below to derive the kernel keycode it should have generated (this is the HARD-CODED map AIUI). If this doesn’t match up, more or less, with /usr/include/linux/input.h, it’s likely it’s the X mapping which is wrong.
  3. Run showkey -s at a text console to determine the scancode generated when you press the key
  4. Run setkeycodes <scancode> <kernel keycode> to set that mapping. Add this line to a script.
  5. Pressing the key should now produce the correct KeySym in X.
X code Kernel Code
0 0
9 1
10 2
11 3
12 4
13 5
14 6
15 7
16 8
17 9
18 10
19 11
20 12
21 13
22 14
23 15
24 16
25 17
26 18
27 19
28 20
29 21
30 22
31 23
32 24
33 25
34 26
35 27
36 28
37 29
38 30
39 31
40 32
41 33
42 34
43 35
44 36
45 37
46 38
47 39
48 40
49 41
50 42
51 43
52 44
53 45
54 46
55 47
56 48
57 49
58 50
59 51
60 52
61 53
62 54
63 55
64 56
65 57
66 58
67 59
68 60
69 61
70 62
71 63
72 64
73 65
74 66
75 67
76 68
77 69
79 71
80 72
81 73
82 74
83 75
84 76
85 77
86 78
87 79
88 80
89 81
90 82
91 83
93 186
94 86
95 87
96 88
97 102
98 103
99 104
100 105
101 224
102 106
103 107
104 108
105 109
106 110
107 111
108 96
109 97
110 119
111 84
112 98
113 100
115 125
116 126
117 127
118 213
119 214
120 215
121 216
122 136
123 118
126 95
127 91
128 90
129 92
130 172
131 94
132 189
133 124
134 121
135 131
136 176
137 181
138 182
139 120
140 132
142 233
143 178
144 165
146 152
147 147
148 222
149 195
150 196
151 149
152 168
153 163
154 197
155 198
157 117
158 139
159 148
160 113
161 140
162 164
163 160
164 166
165 205
166 154
167 199
168 200
169 201
170 190
171 202
172 203
173 204
174 114
175 206
176 115
177 167
178 150
179 207
180 208
181 101
182 183
183 184
184 185
185 210
186 211
187 212
188 137
190 169
191 134
192 135
193 141
194 218
195 219
196 220
197 221
198 144
199 145
200 146
201 151
202 223
203 153
204 161
205 193
207 194
208 93
209 122
210 123
211 89
212 225
213 234
214 227
215 228
216 229
217 230
218 231
219 191
220 177
221 85
222 116
223 142
227 143
228 232
229 217
230 156
231 173
232 128
233 159
234 158
235 157
236 155
237 226
239 112
240 235
241 236
242 237
243 238
244 239
245 138
246 179
247 188
248 133
249 192
251 180
253 162

Other software packages

If X is providing correct Keysyms for your extended keys, most X clients can accept the extended keys directly. In particular, KDE “Input Actions”, KDE Applications’ “Global Shortcuts” settings or Beryl/Compiz’s “Settings Manager” can be configured to act directly on Keysyms.

If KeySyms aren’t coming out correctly, a package called hotkeys can be quite easily configured to respond to X keycodes instead of KeySyms, as long as they generate events.

If X isn’t receiving kernel events at all, a package called keytouch combines the hotkeys functionality with a kernel keycode configuration script. This attempts to integrate all the various keyboard mappings together with an event dispatcher. It does not however, have very many keyboards available as yet. It did not work for me (I want to use KDE Keyboard event dispatch, not a separate daemon. Also it didn’t get the kernel map right).

Configuring `hotkeys`

The core package is called hotkeys. Debian users can aptitude install hotkeys. Other “useful” packages are libxosd2 (when you press a hot key, get an On Screen Display of what’s happening) and xev (should already be installed with X).

How to make it work

First of all:

$ hotkeys --kbd-list

Look through the list and see if your keyboard is there. If it is listed, there’s already a definition for your keyboard. If not, read on and I’ll explain what to do.

Now edit /etc/hotkeys.conf (root required) and change as required. The most important bit to change is Kbd so when hotkeys is run, it knows what keyboard type you have (obtained above). Otherwise you must specify the keyboard type with the -t arguement.

My configuration looks like the following (comments removed):

Kbd=itouch   
!WebBrowser=firefox   
Email=thunderbird   
!FileManager=rox   
!MyComputer=rox   
!MyDocuments=rox   
Search=firefox http://www.google.com

To test hotkeys, simply run hotkeys. It will fork in to the background automatically. Finally, press one of your hot keys!

No keyboard definition?

If your keyboard wasn’t listed in hotkeys –kbd-list then you can create your own definition. Definitions are XML files and are stored in /usr/share/hotkeys (Debian). Look at some of the other *.def files to get an idea how they’re structured first. You will notice that standard “actions” (i.e. Play, Mute VolUp, WebBorwser) relate to the “standard command definitions” in /etc/hotkeys.conf (i.e. WebBrowser=firefox).

You can’t invent your own “action”. Instead you have to create a user defined action, such as:

<userdef keycode="237" command="xmms">Multimedia</userdef>

You will also notice each “action” has a key code related to it. This ties in the code sent from the keyboard to the computer with that this button is suppose to do. To find the key codes run xev and press the hot key on the keyboard. You’ll notice in the terminal window xev is running in, that when everytime you press a key it scrolls up some information. From that information look for the keycode xx. Where xx is the code for the key you just pressed. So create your definition and save it.

Lastly, re-read the “How to make it work” section.

Starting with X

If you use a ~/.xsession or any other variations of this, simply add in (anywhere before the WM is started):

hotkeys -Z

The -Z arguement stops the splash screen from being displayed.

If you use a login manager (XDM, GDM, KDM etc.) to login you will probably need to get your window manager to start this program for you. Some window managers have directories in $HOME for this, such as Autostart etc.

Page written by David Ramsden 2007-06-07 Modified initial section with a technical explanation and alternative (arguably, better) solutions

Leave a Reply