If you read something from STDIN, the read bytes are normally in ASCII format. In some cases it is useful to get the keyboard input as raw as possible. Imagine: Your program should react on the Alt or Ctrl Key with menu highlightning. In raw keyboard mode such things are possible. In this mode you get directly the untranslated keycodes coming from your keyboard. It doesn't generate ASCII like codes it is far away from that. If you press a key on your keyboard two codes are send to the controller in your PC a so called make code if you press a key and a break code if you release a key. The most generated codes are 1 byte codes. It is easy to recognize which sort of code you have received: bit 7 clear = make, bit 7 set = break.
Examples:
But there are also codes longer than 1 byte, such codes are escaped with a leading 0e0h. Example: RIGHT CTRL: 0e0h 01dh (make), 0e0h 09eh (break). Three byte codes are escaped with 0e1h (there should be only one such key on your keyboard: PAUSE. This key is a little bit special because it generates make and break codes without any delay if you press it).
The example code below will simply dump the hex code of every key to the terminal. Use ESC to exit the program. It will only work on local console.
The translation to ASCII Codes in the kernel is done via tables (the same tables are changed if you run the command loadkeys, which loads the correct keytable for your country). You can reach this tables with the ioctl's KDGKBENT and KDSKBENT. They expect a pointer to a structure of the type kbentry (see /usr/src/linux/include/linux/kd.h). If you want to get an entry you have to set the values kb_table and kb_index, if you want to set an entry kb_value must also be set. kb_index is the raw keycode, kb_table contains bits for the keys Shift, Alt, AltGr and Ctrl (it is some kind of table selector, for making things like Shift+A easier). kb_value contains the ASCII Code. For simple keyhandling this should be enough, the real key translation in the kernel seems to be a little bit more complex (think of escape sequences if you press a cursor key), in such cases kb_value contains some magic values.
Like all low level accesses you should try as hard as you can to restore the original state, because if you fail the keyboard stays in raw mode and this means the local console is unusable (Ctrl+Alt+Del doesn't work, no terminal switching etc.). Therefore you should catch all signals, which can terminate your program (including SIGSEGV) with an exit handler.
short procedure for switching to raw keyboard mode:
In this example we use STDIN as file descriptor for sys_ioctl. This is ok as long as nobody redirects it to a file or pipe. If you want that the program even works in this cases: open /dev/tty and use that file descriptor instead.
If you find mistakes or have suggestions, mail me.