On naming: I am a bit wary about the right name for keys like this, whether to call them Funny Keys or Functional Keys. I coined the term FunKeys as a useful shorthand.
On this page:
Elsewhere:
Supported kernels: Linux 2.2.14 and up, 2.4.2 and up.
This patch is not being actively maintained, unlike my BadRAM patch. There is an alternative that is said to work without kernel patching on current Linux systems. We keep this page around for historic service, especially because the information about keyboard modes is still useful.
showkey -s
, set the mode for the console with kbd_mode -s
.:-(
showkey -k
, set the mode for the console with kbd_mode -k
, alter the translation tables with setkeycodes scancode keycode
and read these tables with getkeycodes
.showkey -a
, set the mode for the console with kbd_mode -a
, alter the translation from keycodes with loadkeys
and read them with dumpkeys
.
There are several ways to handle FunKeys. It would be possible to interpret the stream of characters over the console device outside the kernel, intercepting them before they reach the application. This has the disadvantage that the console stream can be at any of the four levels, and the targetted keys need not even be visible at all levels. It also has the potential of slowing down the keyboard feed into an application.
Another option would be to adapt the applications. Since these usually are either XFree86 or the Linux virtual terminals, the set of applications seems limited. A problem here is that XFree86 ignores the scan codes for keys it does not know, and it cannot be trivially altered to handle them. Another disadvantage is that it would require the same settings in two places, leading to maintaince issues and possible inconsistent system behaviour.
But the strongest reason for taking a different approach is that the keys are intended to serve a function rather than a string. This distinguishes them from other keys on the keyboard, although it could be argued that SysRq under Linux gets a similar treatment. Currently, SysRq is hardcoded in the keyboard handler code, and doing this for every volume control whim is a Bad Idea(tm).
For these reasons, it seems best to tap the keyboard codes into a second channel, which is not influenced by the interpretation level of the console stream, and which allowed a concurrent program, like a daemon, to operate on the keycodes in spite of what happened on the desktop.
The keyboard interpretation level transmitted over this secondary keyboard device is also a motivated choice. The scan codes have not only values which are keyboard-specific, but also a structure which is proprietary. The keycodes on the other hand, are almost as raw, but have a standardised structure. Therefore, keycodes lend themselves far better for handling by a daemon than scan codes. The translation to ASCII or UTF-8 seems unsuitable for transmission over the secondary keyboard device because these codes could then also be seen over the console, which is clearly undesirable for FunKeys.
Important information is entered through keyboards, including (root) passwords and possibly confidential information. Constraining the exposure of keystrokes therefore is a Good Thing(tm).
To avoid trojan horses set up by users, we can constrain access to the secondary keyboard device to root only. But to avoid unnoticed tapping of passwords by system administrators, it is useful to avoid that a keystroke ever goes to console and secondary keyboard stream. So, we will split keystrokes in a console stream and a FunKey stream.
This way, an attempt to tap information from the keyboard cannot go unnoticed. Furthermore, this split has the advantage that Fun Keys and plain keys receive a clearly distinct treatment. Whereas the Fun Keys are always handled in the background in spite of desktop activities, the plain keys bounde up and down in interpretation level as deemed useful by the desktop.
Keycodes and shifting state are interpreted by the kernel key maps, that translate keycodes to 16 bit numbers, which are normally Unicode/ASCII characters.
Unicode values from 0xf000
up are treated specially.
The low nibble of the high byte is a keycode type that explains how the low byte is to be handled.
The FunKey kernel patch adds a keycode type for `send to the FunKey device'.
That is, keycodes like 0xfe59
mean that keycode 0x59
(MSB reset) must be sent to /dev/funkey
when the described key is pressed, and 0xb9
(MSB set) when it is released.
The kernel patch is nothing more than the support for this extra key type and a character device to output it over.
All the remaining magic is standard Un*x material, a simple daemon.
We give a simple example of such a daemon here, under the name funky
, which recognises certain keys and starts a Un*x commond for it.
Viva le commandline!
Software available here comprises of the kernel patch and a daemon. They work fine on my system, and I would like some test output. So, please tell me about successes as well as about problems! See
What can you download right now?
/dev/funkey
character device.
The kernel patch is made for Linux 2.2.14, and it installs on top of the BadRAM patch; otherwise there will probably be a single harmless rejection on the CREDITS file. When configuring the kernel, open the character devices dialog, and mark Support for console on virtual terminal for inclusion.
Make sure that when booting your system, some scripts calls setkeycodes
and loadkeys
as suggested under Implementation.
After booting the newly built kernel, use setkeycodes
to assign keycodes to incoming scancodes.
Available scancodes can be found with
dumpkeys | grep ^keycode | grep =$For the generated keycodes, you may now enter a FunKey code to submit to the FunKey character device, and add 0xfe00 to it to incur sending through
/dev/funkey
.
On my RedHat system, I added a few lines
setkeycodes e020 89 e02e 90 e030 91 e022 92 \ e024 93 e010 94 e019 95 e05f 120 \ e06c 121 e065 122 e066 123 e032 124to
/etc/rc.d/init.d/keytable
.
Now use the standard utilities loadkeys
and dumpkeys
can be used to install any translation to FunKey codes in the kernel key maps.
For my Logitech Internet Keyboard, I used the following to instruct the kernel to pass a set of keys to /dev/funkey
(I simply selected the keycodes as FunKey codes, for no reason at all):
keycode 89 = U+fe59 keycode 90 = U+fe5a keycode 91 = U+fe5b keycode 92 = U+fe5c keycode 93 = U+fe5d keycode 94 = U+fe5e keycode 95 = U+fe5f shift keycode 120 = U+fe78 keycode 121 = U+fe79 keycode 122 = U+fe7a keycode 123 = U+fe7b keycode 124 = U+fe7cwhere the
U+
signifies a Unicode keycode.
Note how keycode 120 only works with shift down; that's because it is my halt key ;-)
.
In version 1999.03.02, loadkeys complains about Unicode keycodes, but it handles them well.
Perhaps a future version of loadkeys and dumpkeys will provide an enhanced syntax for these forms, something like:
keycode 89 = funkey 89 keycode 90 = funkey 90 shift keycode 120 = funkey 120and so on. Find the keymap that is loaded for your system and extend it with these settings.
After rebooting the FunKey-patched kernel, find the device major number from /proc/devices
.
Chances are this is 254; create a device node for it:
mknod /dev/funkey c 254 0Now start the daemon. You're in!
If you are interested in this project, you can mail me.
My current snail mail address is:
Rick van Rein Haarlebrink 5 7544 WP Enschede the NetherlandsThis overrules the address in the patch and daemon, which is intended as a longer-lasting address.