Keyboard configuration and use
I have yet to find good documentation on keyboard support in Linux. The
following is cobbled together from various sources using a lot of
guesswork - it is very likely to be wrong/misleading/incomplete in many
places.
How it works
The kernel contains a keyboard driver, which communicates with the
keyboard hardware and generates "input events" for key-presses and
key-releases. These events are passed via the "input sub-system" of the
kernel and made available to userland processes through the
/dev/input/eventX devices (documentation on this is in the file
/usr/src/linux/Documentation/input/input.txt). The key codes used in these events are listed (as "#define KEY_...") in the file /usr/src/linux/include/linux/input.h.
Kernel input events can be monitored using the evbug kernel module (see below). Alternatively, the program showkey can display the input-event codes for keys as they are pressed.
X server
The most important userland process that receives and processes input
events is the X server, which handles keyboard input for GUI processes.
The X-server itself generates an X-event for each input event
(key-press and key-release). GUI processes receive keyboard input as
these X-events, rather than as kernel input events. The two kinds of
events use different codes for the keys: for example the '5' key
generates an input event with code 6 (i.e. KEY_5 in /usr/src/linux/include/linux/input.h) and an X-event with code 14. Note
that neither of these codes is the same as the ASCII/UTF code, which is
53.
The mapping from X-events to ASCII/UTF8 codes (if done at all)
is specific to the GUI application. Command-line programs that are
run in an xterm rely on the xterm to do the mapping.
It's possible to monitor X-events using the program xev: just type xev on the command line, and try pressing keys. xev traces ALL X-events, so you will also see events for mouse movements, window resizing, etc.
Virtual terminals
If you are using a virtual terminal rather than the X server, then the
keyboard input events are handled within the kernel and provided as
ASCII/UTF8 codes via the /dev/ttyX (aka /dev/vc/X) devices.
Keyboard configuration
Kernel
The kernel configuration relevant to keyboard input is under "Device
Drivers -> Input Device Support". This won't normally need changing,
but there is an "Event Debugging" option, which can be handy if want to
see the kernel keyboard events. If you re-build the kernel with this
option as a module, you can do:
modprobe evbug
to get all keyboard events logged to /var/log/messages. Do:
rmmod evbug
to turn off the debug output.
For virtual terminals, the mapping from input events to ASCII/UTF8
codes is handled within the kernel. The map used for this is loaded
into the kernel using the 'loadkeys' command. This is done automatically at boot time from /etc/rc.d/rc.keymap. If you are having problems with keyboard mapping on a virtual terminal, a first step would be to check that rc.keymap is loading uk.map. The utility 'dumpkeys' will dump the map currently in use by the kernel. The format of kernel keymaps is documented on the 'keymaps' man page.
Laptop keys
The AOpen laptops have some extra keys (e.g. the silver buttons on the
left and at the top) that are not recognized by the standard keyboard
driver.
acerhk
We used to use the acerhk driver to handle these extra keys, but acerhk is no longer
maintained, and it's likely that it will eventually fail to compile with
the latest version of the kernel. So far (up to kernel 2.6.27) I've managed to keep it compiling by changing the
following line in the acerhk Makefile:
CFLAGS+=-c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe
to:
EXTRA_CFLAGS+=-c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe
Several warnings are also generated when building - I haven't investigated them.
wistron_btns
Kernel 2.6.15 introduced a new module called wistron_btns, which is an alternative acerhk. This was not easily usable until 2.6.21 (or thereabouts), when a generic keymap option was introduced. To use wistron_btns,
you need to configure the kernel with 'Device Drivers -> Input
device support -> Miscellaneous devices -> x86 Wistron laptop
button interface' selected as a module.
To load the wistron_btns module at boot-time add the line:
options wistron_btns keymap=generic
to /etc/modprobe.d/modprobe.conf, and add the line:
/sbin/modprobe -v wistron_btns
to /etc/rc.d/rc.modules.
The extra keys generate the following kernel input keycodes (discovered using evbug - see above) and X-event keycodes (discovered by using xev - see below):
Where |
Key |
Input keycode |
X keycode |
"Launch keys" - silver buttons to left of keyboard |
Wireless |
238 KEY_WLAN |
243 |
" |
Mail |
155 KEY_MAIL |
236 |
" |
WWW |
150 KEY_WWW |
130 |
" |
P1 |
148 KEY_PROG1 |
159 |
" |
P2 |
149 KEY_PROG2 |
151 |
"Audio DJ panel" - silver buttons at top of keyboard |
Rewind |
168 KEY_REWIND |
152 |
" |
Fast forward |
159 KEY_FORWARD |
233 |
" |
Play |
164 KEY_PLAYPAUSE |
162 |
" |
Stop |
166 KEY_STOPCD |
164 |
Function key with Fn held down |
Fn-F1 |
138 KEY_HELP |
245 |
Unlike acerhk, wistron_btns
(when using the generic keymap) does not automatically turn the WiFI on
and off when you press the wireless button. To get this to work, the
module needs to be patched. Edit the file
/usr/src/linux/drivers/input/misc/wistron_btns.c as follows, and
rebuild the kernel:
@@ -565,6 +565,20 @@
{ KE_END, FE_UNTESTED }
};
+static struct key_entry keymap_aopen_1557g[] __initdata = {
+ { KE_KEY, 0x01, {KEY_HELP} },
+ { KE_KEY, 0x11, {KEY_PROG1} },
+ { KE_KEY, 0x12, {KEY_PROG2} },
+ { KE_KEY, 0x22, {KEY_REWIND} },
+ { KE_KEY, 0x23, {KEY_FORWARD} },
+ { KE_KEY, 0x24, {KEY_PLAYPAUSE} },
+ { KE_KEY, 0x25, {KEY_STOPCD} },
+ { KE_WIFI, 0x30 },
+ { KE_KEY, 0x31, {KEY_MAIL} },
+ { KE_KEY, 0x36, {KEY_WWW} },
+ { KE_END, 0 }
+};
+
static struct key_entry keymap_wistron_generic[] __initdata = {
{ KE_KEY, 0x01, {KEY_HELP} },
{ KE_KEY, 0x02, {KEY_CONFIG} },
+
static struct key_entry keymap_wistron_generic[] __initdata = {
{ KE_KEY, 0x01, {KEY_HELP} },
{ KE_KEY, 0x02, {KEY_CONFIG} },
@@ -914,6 +928,14 @@
},
.driver_data = keymap_fs_amilo_d88x0
},
+ {
+ .callback = dmi_matched,
+ .ident = "AOpen 1557G",
+ .matches = {
+
DMI_MATCH(DMI_PRODUCT_SERIAL, "96NDU01G"),
+ },
+ .driver_data = keymap_aopen_1557g
+ },
{ NULL, }
};
If you use this patch, the module should be loaded without the 'keymap=generic' option.
I've submitted this patch to the author of wistron_btns, so it may eventually find its way into the official kernel.
X server
The X-server uses an amazingly obscure (but supposedly very flexible)
mechanism to map input-event key codes to X-event key codes -
documentation is in the file /etc/X11/xkb/README.config.
The main place to configure the X-server's keyboard handling is in the file /etc/X11/xorg.conf. This should contain an "InputDevice" section with lines like:
Option "XkbRules" "xorg"
Option "XkbModel" "pc104"
Option "XkbLayout" "gb"
Option "XKbOptions" "compose:rctrl"
The "XkbRules" option should always have the value "xorg".
The "XkbModel" option is supposed to be the model of keyboard that you have. There is a list of these in the file /etc/X11/xkb/rules/xorg.lst,
but unless you are lucky your specific keyboard model probably isn't
listed. You will then have to guess which of the generic models might
work - "pc104" seems OK for the AOpen laptops.
The "XkbLayout" option seems to be a country code. In our case, specifying "gb" enables the "£" key to work.
The "XkbOptions" option is a way specifying some specific tweaks. By default, "pc104"
seems to map the "menu" key (that's the one to the left of the right
control key) to the "compose" code. Since I wanted to use the menu
key as a menu key, I specified "compose:rctrl" to use the right control
key for "compose" instead. The possible values for "XkbOptions" are
listed in the file /etc/X11/xkb/rules/xorg.lst.
If you change the settings in xorg.conf
you will have to restart the X-server for the settings have an effect.
If you want to try out changes without restarting X, you can use the setxkbmap command. For example, the above settings could be specified on the command line using:
setxkbmap -rules xorg -model pc104 -layout gb -option "compose:rctrl"
Once you are happy with the changes you can edit them into xorg.conf to make them permanent.
If you want to do anything more advanced, you could consult the files /etc/X11/xkb/README.config and /etc/X11/xkb/README.enhancing, and the web page Creating custom keyboard layouts for X11 using XKB
Entering unusual characters
There are several ways of entering unusual characters such as '€'
(the Euro symbol), '©' (the copyright symbol) and 'é' (e
acute):
- Use the AltGr key (to the right of the spacebar) - it works like a special shift.
- Use the "compose" key (on the AOpen laptops this is, by default, set up as the "menu" key to the left of the right control key).
- Use an application-specific method.
See Accented Characters for a good explanation of the first two methods, particularly for getting accented characters.
You will probably need to set up Slackware to use Unicode in order for unusual characters to be handled sensibly.
AltGr key
The AltGr key is used like a shift key: hold it down while pressing
another key. It may be used on its own or with the normal shift key.
The following table was produced by experimentation using the X server on my laptop:
Key |
With AltGr |
With AltGr+Shift |
1 |
¹ |
|
2 |
² |
⅛ |
3 |
³ |
|
4 |
€ |
¼ |
5 |
½ |
⅜ |
6 |
¾ |
⅝ |
7 |
|
⅞ |
8 |
|
™ |
9 |
|
± |
0 |
|
° |
- |
|
¿ |
. |
· |
÷ |
, |
|
× |
\ |
|
¦ |
a |
æ |
Æ |
c |
¢ |
© |
d |
ð |
Ð |
f |
đ |
ª |
g |
ŋ |
Ŋ |
h |
ħ |
Ħ |
i |
→ |
ı |
k |
ĸ |
|
l |
ł |
Ł |
m |
µ |
º |
o |
ø |
Ø |
p |
þ |
Þ |
q |
|
Ω |
r |
¶ |
® |
s |
ß |
§ |
t |
ŧ |
Ŧ |
u |
↓ |
↑ |
w |
ł |
Ł |
x |
» |
|
y |
← |
¥ |
z |
« |
|
AltGr is handled in the kernel for virtual terminals, and by the X
server for GUI programs (including xterm). I haven't investigated
whether the virtual terminal support for AltGr is the same as the X
server's - I think you have to do something to enable it, but I don't
know what.
Compose key
To use the compose key, you press (and release) the compose key, and
then press two further keys. These two keys are "composed" to produce a
single character. For example, pressing <compose> 'a' 'e'
produces 'æ', and pressing <compose> '"' 'o' produces
'ö'.
There's a complete list of the compose sequences available under the X server at Linux Compose Key Sequences and in the file /usr/X11R6/lib/X11/locale/en_US.UTF-8/Compose (the compose key is referred to as "Multi_key" in this file).
Some of the more useful composed characters are (together with the AltGr method of typing them, where available):
Unicode |
Char |
Compose |
AltGr | AltGr+Shift | Comment |
00a0 |
|
" " |
| | nobreakspace # NO-BREAK SPACE |
00a6 |
¦ |
"!^" |
| \ | brokenbar # BROKEN BAR |
00a7 |
§ |
"so" "os" |
| s | section # SECTION SIGN |
00a9 |
© |
"oc" "oC" "Oc" "OC" |
| c | copyright # COPYRIGHT SIGN |
00ab |
« |
"<<" |
z | | guillemotleft # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK |
00ae |
® |
"or" "oR" "Or" "OR" |
| r | registered # REGISTERED SIGN |
00b0 |
° |
"oo" |
| 0 | degree # DEGREE SIGN |
00b1 |
± |
"+-" |
| 9 | plusminus # PLUS-MINUS SIGN |
00b2 |
² |
"^2" |
2 | | SUPERSCRIPT TWO |
00b3 |
³ |
"^3" |
3 | | SUPERSCRIPT THREE |
00b5 |
µ |
"mu" |
m | | MICRO SIGN |
00b6 |
¶ |
"p!" "P!" "PP" |
r | | paragraph # PILCROW SIGN |
00b7 |
· |
".." |
. | | MIDDLE DOT |
00b9 |
¹ |
"^1" |
1 | | SUPERSCRIPT ONE |
00bb |
» |
">>" |
x | | guillemotright # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK |
00bc |
¼ |
"14" |
| 4 | VULGAR FRACTION ONE QUARTER |
00bd |
½ |
"12" |
5 | | VULGAR FRACTION ONE HALF |
00be |
¾ |
"34" |
6 | | VULGAR FRACTION THREE QUARTERS |
00d7 |
× |
"xx" |
| , | MULTIPLICATION SIGN |
00d8 |
Ø |
"/O" |
| o | LATIN CAPITAL LETTER O WITH STROKE |
00f7 |
÷ |
":-" "-:" |
| . | DIVISION SIGN |
20ac |
€ |
"C=" "=C" "c=" "=c" "E=" "=E" |
4 | | EuroSign # EURO SIGN |
2122 |
™ |
"^TM" |
| 8 | TRADE MARK SIGN |
The compose key is handled in the kernel for virtual terminals, and by
the X server for GUI programs (including xterm). I haven't
investigated whether the virtual terminal support for the compose key
is the same as the X server's - I think you have to do something to
enable
it, but I don't know what.
Application-specific
In vim, you can enter a Unicode code using Ctrl-V u followed by a 4-digit hex number.
In nvu, thunderird and firefox you can enter a Unicode code by holding down control and shift whilst typing a 4-digit hex number.
Binding actions to special keys
The wistron_btns driver generates key-codes for the special keys on the AOpen
laptops, but unless you somehow bind an action to them they don't do
anything.
I have a Logitech USB headset, which has "volume control" buttons
on it - these also generate key-codes, which do nothing unless you can
bind an action to them.
A Google search found an application called xbindkeys, which will intercept X key events and perform actions for them.
Download and installation follows the usual pattern:
tar xvf xbindkeys-1.8.3.tgz
cd xbindkeys-1.8.3
./configure --disable-tk
make
vim description-pak
checkinstall
The "--disable-tk" option stops it installing a useless GUI program that requires TCL/TK.
xbindkeys uses a configuration file called .xbindkeysrc to map X-event key codes to actions. You can use xbindkeys itself to generate entries to go in the configuration file. Type:
xbindkeys -k
on the command line, and then press a key (with control, shift, etc. if required). xbindkeys will print out three lines that look like:
"NoCommand"
m:0x0 + c:117
Menu
Copy these lines into the .xbindkeysrc file and edit the "NoCommand" to whatever command you want executed. Repeat the process for each key that you want to associate an action with.
My .xbindkeysrc file looks like this:
"eject"
m:0x0 + c:151
NoSymbol
"amixer -c Headset -q set Speaker 5%+"
m:0x0 + c:176
NoSymbol
"amixer -c Headset -q set Speaker 5%-"
m:0x0 + c:174
NoSymbol
"screenshot"
m:0x0 + c:111
Print
"screendump"
m:0x8 + c:111
Alt + Print
As you can see, I haven't yet found uses for many of the laptop extra keys yet.
The "amixer" commands are for controlling the volume on my USB headset. The "screenshot" and "screendump" commands are for taking screenshots - see Screen Shots.
You can change .xbindkeysrc while xbindkeys is running and it will be re-read automatically.
Any keys that are not assigned actions in .xbindkeysrc will not be
intercepted by xbindkeys, and will be available to whatever program has
focus.
The final step is to arrange for xbindkeys to be started
automatically. This can't be done from /etc/rc.d/rc.local, since xbindkeys needs to
connect to the X server, which isn't running at that time. I have a
~/.xinitrc file, so I added the following line to that:
/usr/local/bin/xbindkeys
If you don't already have a .xinitrc file in your home directory, the following should work:
#!/bin/sh
/usr/local/bin/xbindkeys
exec /etc/X11/xdg/xfce4/xinitrc
For reference, my full .xinitrc is:
#!/bin/sh
# Trace commands
set -x
# Turn off beep
xset b off
# Allow any user/host to connect to X server
# (firewalls will stop unwanted hosts)
xhost +
# Start xbindkeys to handle special keys
/usr/local/bin/xbindkeys
# Start the desktop
exec /etc/X11/xdg/xfce4/xinitrc &> ~/logs/xfce