Extra keyboard keys
Many keyboards include some special keys (also called hotkeys or multimedia keys), which are supposed to execute an application or print special characters (not included in the standard national keymaps). udev contains a large database of mappings specific to individual keyboards, so common keyboards usually work out of the box. If you have very recent or uncommon piece of hardware, you may need to adjust the mapping manually.
Prerequisite for modifying the key mapping is knowing how the keys are identified on the system. There are multiple levels:
- A scancode is the lowest identification number for a key, it is the value that a keyboard sends to a computer.
- A keycode is the second level of identification for a key, a keycode corresponds to a function.
- A keysym is the third level of identification for a key, it corresponds to a symbol. It may depend on whether the Shift key or another modifier key was also pressed.
Scancodes are mapped to keycodes, which are then mapped to keysyms depending on used keyboard layout. Most of your keys should already have a keycode, or at least a scancode. Keys without a scancode are not recognized by the kernel; these can include additional keys from 'gaming' keyboards, etc.
In Xorg, some keysyms (e.g.
XF86AudioRaiseVolume etc.) can be mapped to actions (i.e. launching an external application). See Extra Keyboard Keys in Xorg#Map keysyms to actions for details.
In Linux console, some keysyms (e.g.
F246) can be mapped to certain actions (e.g. switch to other console or print some sequence of characters). See Extra Keyboard Keys in Console for details.
Identifying key codes
The universal way to get a scancode is to use the showkey utility. showkey waits for a key to be pressed, or exits if no keys are pressed within 10 seconds. For showkey to work you need to be in a virtual console, not in a graphical environment or logged in via a network connection. Run the following command:
# showkey --scancodes
and try to push keyboard keys; you should see scancodes being printed to the output.
You can get the scancode of a key by pressing the desired key and looking the output of
dmesg command. For example, if you get:
Unknown key pressed (translated set 2, code 0xa0 on isa0060/serio0
then the scancode you need is
The keycodes for virtual console are reported by the showkey utility. showkey waits for a key to be pressed and if none is during 10 seconds it quits, which is the only way to exit the program. To execute showkey you need to be in a virtual console, not in a graphical environment. Run the following command
# showkey --keycodes
and try to push keyboard keys, you should see keycodes being printed to the output.
The keycodes used by Xorg are reported by a utility called xev, which is provided by the package. Of course to execute xev, you need to be in a graphical environment, not in the console.
With the following command you can start xev and show only the relevant parts:
$ xev | grep -A2 --line-buffered '^KeyRelease' | sed -n '/keycode /s/^.*keycode \([0-9]*\).* (.*, \(.*\)).*$/\1 \2/p'
Here is an example output:
38 a 27 r 54 c 43 h 153 NoSymbol 144 NoSymbol
In the example the keys
h and two other multimedia keys were pressed. The former four keys with keycodes
43 are properly mapped, while the multimedia keys with keycodes
144 are not. The
NoSymbol indicates that no keysyms are assigned to those keys.
If you press a key and nothing appears in the terminal, it means that either the key does not have a scancode, the scancode is not mapped to a keycode, or some other process is capturing the keypress. If you suspect that a process listening to X server is capturing the keypress, you can try running xev from a clean X session:
$ xinit /usr/bin/xterm -- :1
Mapping scancodes to keycodes
See the main article: Map scancodes to keycodes.
Mapping keycodes to keysyms
See the main article: Extra Keyboard Keys in Console.
See the main article: xmodmap.
Asus M series
In order to have control over the light sensor and the multimedia keys on your Asus machine, you should use the following command:
# echo 1 > /sys/devices/platform/asus_laptop/ls_switch
To have it run on boot create a Systemd tmpfile:
w /sys/devices/platform/asus_laptop/ls_switch - - - - 1
Asus N56VJ (or possibly others)
if most of your special keys don't work, try loading the asus-nb-wmi kernel module with
# modprobe asus-nb-wmi
then check xev again. if you combine this with the acpi_osi="!Windows 2012" boot option, you may get weird results in xev, so try not using it. If this did fix things, make sure to make the module load at boot with methods described here