Keyboard Programming Interface Andries Brouwer
aeb@cwi.nl
2002 Andries Brouwer This documentation is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For more details see the file COPYING in the source distribution of Linux.
Keyboard API This document describes the user interface to the kernel keyboard driver. The keyboard type unsigned char kbtype; ioctl(fd, KDGKBTYPE, &kbtype); /* get keyboard type */ The KDGKBTYPE ioctl returns the keyboard type in the unsigned char kbtype. This ioctl is fairly useless. It returns the value of the kernel variable keyboard_type, which defaults to KB_101 but is set to KB_84 in the Atari code. There is no real attempt in the kernel to determine and return the actual type of keyboard. The main use of this ioctl is to test the validity of the fd argument. When user space needs a file descriptor for doing keyboard or console ioctl's it might try file descriptors 0, 1, 2, or files like /dev/tty or /dev/console. The file descriptor is OK when the KDGKBTYPE ioctl succeeds: #include <sys/ioctl.h> #include <linux/kd.h> static int is_a_console(int fd) { unsigned char arg; arg = 0; return (ioctl(fd, KDGKBTYPE, &arg) == 0 && (arg == KB_101 || arg == KB_84)); } The keyboard modes int kbmode; ioctl(fd, KDGKBMODE, &kbmode); /* get keyboard mode */ ioctl(fd, KDSKBMODE, kbmode); /* set keyboard mode */ The keyboard can be in three modes: K_RAW, where scancodes are transmitted directly to user space (or, rather, to the tty line discipline), K_MEDIUMRAW, where scancodes are converted to keycodes, and these are transmitted to user space, and "cooked", where scancodes are converted to keycodes and keycodes are converted to keysyms using the user's keymap. This "cooked" mode comes in two flavours: K_XLATE, which is the default, and K_UNICODE (see below). Do not confuse the "raw" and "cooked" here with the "raw" and "cooked" of the tty line discipline, as set, e.g., by stty(1). The keyboard keycodes struct kbkeycode a; ioctl(fd, KDGETKEYCODE, &a); /* get keycode */ ioctl(fd, KDSETKEYCODE, &a); /* set keycode */ Scancodes are produced by the hardware. Keycodes are used by the user in their keymap. The usual PC keyboard, in the default mode, returns a sequence of scancodes for each key press and key release. The kernel parses the sequence into the keycode. The keycode is a single byte, of which the high order bit is used to indicate press(0)/release(1). The value 0 is used for special purposes. So, 127 keycodes are available to identify the keyboard keys. Usually this suffices, but not always. The correspondence between scancode sequence and keycode is hardwired to be the identity for single scancodes in the range 1-88 (0x01-0x58). For the remaining single scancodes (0x59-0x7f) or scancode pairs (sequences of length two: 0xe0 0x00 - 0xe0 0x7f), a corresponding keycode can be assigned (in the range 1-127). struct kbkeycode a; a.scancode = 0x59; /* for single scancode 59 (hex) */ a.scancode += 128; /* for scancode pair e0 59 (hex) */ a.keycode = 123; ioctl(fd,KDSETKEYCODE,&a); See also getkeycodes(8) and setkeycodes(8). Keycode 0 cannot be used: the value 0 is used to control allocation and deallocation of keymaps. For some architectures the setup is broken. The keyboard keymap struct kbentry ke; ioctl(fd, KDGKBENT, &ke); /* get keyboard keymap entry */ ioctl(fd, KDSKBENT, &ke); /* set keyboard keymap entry */ struct kbsentry sbuf; ioctl(fd, KDGKBSENT, &sbuf); /* get keyboard string entry */ ioctl(fd, KDSKBSENT, &sbuf); /* set keyboard string entry */ struct kbdiacrs kd; ioctl(fd, KDGKBDIACR, &kd); /* get keyboard compose pair */ ioctl(fd, KDSKBDIACR, &kd); /* set keyboard compose pair */ char meta; ioctl(0, KDGKBMETA, &meta; /* get meta treatment */ ioctl(0, KDSKBMETA, meta; /* set meta treatment */ The user's keymap indicates the correspondence between keycodes and symbols or actions belonging to these keys. alt_is_meta keycode 1 = Escape ... control alt keycode 83 = Boot ... alt keycode 103 = KeyboardSignal ... string F1 = "\033[[A" ... compose '`' 'A' to 'À' ... Ordinary entries of the keymap are set using the KDSKBENT ioctl: struct kbentry ke; ke.kb_table = table_number; ke.kb_index = keycode; ke.kb_value = resulting_value; ioctl(fd, KDSKBENT, &ke); Here there are 256 possible table numbers, corresponding to the simultaneous position of 8 shift keys (0: plain map, 1: shift, 2: altgr, 3: shift altgr, 4: control, 5: shift control, ...) where these 8 shift keys are conventionally called 1: shift, 2: altgr, 4: control, 8: alt, 16: shiftl, 32: shiftr, 64: ctrll, 128: ctrlr. Tables are dynamically allocated as needed, and deallocated by using keycode 0 with value K_NOSUCHMAP. The resulting_value variable is a 16-bit value. Its interpretation depends on the keyboard mode. In K_UNICODE mode it is a 16-bit Unicode value. In K_XLATE mode it is an 8-bit type field followed by an 8-bit value. See also keymaps(5), dumpkeys(1), loadkeys(1). String entries of the keymap are set using the KDSKBSENT ioctl: struct kbsentry sbuf; sbuf.kb_func = function_key_number; strncpy(sbuf.kb_string, "my string", 512); ioctl(fd, KDSKBSENT, &sbuf); Compose combinations are set using the KDSKBDIACR ioctl: struct kbdiacrs kd; int accent_table_size; if (accent_table_size > MAX_DIACR) accent_table_size = MAX_DIACR; for (i = 0; i < accent_table_size; i++) { kd.kbdiacr[i].diacr = diacritic[i]; kd.kbdiacr[i].base = base_symbol[i]; kd.kbdiacr[i].result = combined_symbol[i]; } kd.kb_cnt = accent_table_size; ioctl(fd, KDSKBDIACR, &kd); As mentioned already, in K_XLATE mode a keymap entry consists of an 8-bit type field followed by an 8-bit value. If the type is KT_META, then there are two possible treatments, depending on the metamode setting of the VC. The possible settings are K_METABIT and K_ESCPREFIX. In the former mode the meta request causes setting of the high order bit of the value. In the latter it produces an ESC prefix. char meta = esc ? K_ESCPREFIX : K_METABIT; ioctl(fd, KDSKBMETA, meta); The keyboard LEDs char leds; ioctl(fd, KDGETLED, &leds); /* get keyboard led settings */ ioctl(fd, KDSETLED, leds); /* set keyboard led settings */ #ifdef __sparc__ /* Special Sun version */ ioctl(fd, KIOCGLED, &leds); /* get keyboard led settings */ ioctl(fd, KIOCSLED, leds); /* set keyboard led settings */ #endif char flags; ioctl(fd, KDGKBLED, &flags); /* get keyboard flags */ ioctl(fd, KDSKBLED, flags); /* set keyboard flags */ Most keyboards have three or four LEDs, normally indicating NumLock, CapsLock, ScrollLock and perhaps Compose or so. The default situation is that the LEDs indicate these keyboard flags (for the current foreground console). This is the LED_SHOW_FLAGS mode. The KDSKBLED ioctl sets these keyboard flags (and the default flags that are used after a reset). /* Set CapsLock, as if the CapsLock key was hit. */ int flags = LED_CAP; int default_flags = 0; ioctl(fd, KDSKBLED, (default_flags << 4) | flags); It is also possible to show arbitrary information (or nice patterns - "blinkenlights") in the LEDs. This is the LED_SHOW_IOCTL mode. We get into this mode by using KDSETLED with a value that is zero outside the last three bits, and get out of it again by using the value 0xff. /* Blink LEDs - run on a text console */ #include <sys/ioctl.h> #include <linux/kd.h> main() { int leds = 0; while (1) { leds = 2*leds+1; if (leds & 8) leds ^= 9; if (ioctl(0, KDSETLED, leds)) exit(1); /* 0 is not a good fd */ sleep(1); } } See also setleds(1). On a Sun, this same effect is obtained using the ioctl KIOCSLED on a file descriptor obtained by opening /dev/kbd. The third and last LED mode is LED_SHOW_MEM, where the LEDs show the contents of three specified bits in kernel memory. See the routine register_leds() in keyboard.c. The keyboard repeat rate struct kbd_repeat kbdrep; kbdrep.rate = rate; kbdrep.delay = delay; ioctl(fd, KDKBDREP, &kbdrep); /* m68k, i386 */ fd = open("/dev/kbd", O_RDONLY); ioctl(fd, KIOCSRATE, &kbdrep); /* sparc */ The oldfashioned way of setting keyboard repeat rate on i386 was by direct port access. The KDKBDREP ioctl occurred in old m68k patches, but presently occurs in the stock kernel and is also usable for other architectures - they have to fill the function pointer kbd_rate in vt.c. The sparc uses a different name. See also kbdrate(8). The Keyboard Signal long sig; ioctl(fd, KDSIGACCEPT, sig); A program can indicate its willingness to receive keyboard signals by executing the KDSIGACCEPT ioctl. For example, init(8) does this, and upon receipt of a keyboard signal performs the action described after the "kb" label. The requested signal sig is sent when the key combination that maps to the keysym KeyboardSignal is pressed. This has been used to spawn a new console each time this key combination is pressed, and the terminology used still reflects that. See also spawn_console.c in the kbd package.