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.
- The keyboard generates scancodes
- The Linux console driver remaps these to Linux keycodes (see /usr/include/linux/input.h)
- The X keyboard/kdb performs a HARD-CODED map to X keycodes
- The X server performs a mapping from X keycode to Key Symbol
But, being Linux, there is more than one way to do it.
- The keyboard generates scancodes
- The Linux event driver converts these to key events
- The X evdev driver converts events to keycodes
- 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.
- Deduce the X keycode the key SHOULD generate by reference to
/usr/share/X11/xkb/symbols/inet
and/usr/share/X11/xkb/keycodes/xfree86
. - 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.
- Run showkey -s at a text console to determine the scancode generated when you press the key
- Run setkeycodes <scancode> <kernel keycode> to set that mapping. Add this line to a script.
- 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
You must be logged in to post a comment.