Linux Support for text output
Because support for Linux keymapping and text output is provided by several different programs, it is necessary that a section about text support exist outside of sections talking about the various programs that support it.
Terminal support and recognition
The file /etc/gettydefs define the tty speeds.
The command "printenv TERM" will output the type of terminal you are using.
tty - Print the file name of the terminal connected to the standard output.
Steps to support terminals and text
Terminal and text (keymapping) support of the system involves 5 things.
- Determining the terminal type and setting it correctly.
- Setting the kernel keyboard driver to the correct mode.
- Mapping the key make code to the keycode using the keycode mapping table (key bindings).
- Mapping the keys from the keycode to the keymap (key mapping).
- Mapping the terminal and individual programs such as bash, emacs, X and others.
1. Determining the terminal type
The TERM environment variable is used to determine the type of terminal. It is set by the kernel first when the system boots. Then it is sometimes reset by getty, using the file "/etc/ttytype" or the argument specified in /etc/inittab. Sometimes, it is also set in /etc/profile. Usually on new systems, this value is set to "linux". When someone telnets in from a remote terminal, the telnet protocol will give the terminal type to the system and the TERM environment variable will be set by getty.
2. Setting the kernel keyboard driver mode
The kernel contains a keyboard driver which can be in one of four modes. There are four modes the kernel keyboard driver may be set to. They are:
- scancode (RAW)
- keycode (MEDIUMRAW) - The scan code is converted to key codes(Same as the key number) and sent to the application.
- ASC (XLATE) is the default mode - The keymap is used to convert the keycode to an ASC character or string or perform an action.
- UTF-8 (UNICODE) - This is a code that is an 8 or 16 bit code.
The program "kbd_mode" is used to set the mode.
The translation between keycodes and characters, strings, or actions is called the keymap. Therefore there are normally three types of codes that may be sent from the keyboard to the system or application:
- scan code - Generated by the keyboard controller, sent to the kernel keyboard driver. It usually includes a make and a break code for each key. On most keyboards, these values are fixed, but on some keyboards these values can be changed.
- keycode - A key value scan codes are converted to.
- keymap - The translation to the final character, string, or action to be sent to the application.
3. Mapping the make code to the keycode (keybindings)
The keycode mapping table is the translation between make key codes generated by the keyboard and the keymap value (roughly a key number value). The utility "getkeycodes" shows this mapping table and the utility setkeycodes is used to change this table.
The program "getkeycodes" shows a table similar to the following:
Plain scancodes xx (hex) versus keycodes (dec)
0 is an error; for 1-88 (0x01-0x58) scancode equals keycode
0x58: 88 124 125 126 127 0 0 0
0x60: 0 0 0 0 0 0 0 0
0x68: 0 0 0 0 0 122 0 123
0x70: 0 0 0 89 120 0 0 90
0x78: 91 92 93 94 95 124 121 0
Escaped scancodes e0 xx (hex)
e0 00: 0 0 0 0 0 0 0 0
e0 08: 0 0 0 0 0 0 0 0
e0 10: 0 0 0 0 0 0 0 0
e0 18: 0 0 0 0 96 97 0 0
e0 20: 0 0 0 0 0 0 0 0
e0 28: 0 0 0 0 0 0 0 0
e0 30: 0 0 0 0 0 98 0 99
e0 38: 100 0 0 0 0 113 114 115
e0 40: 116 117 0 0 0 0 101 102
e0 48: 103 104 0 105 124 106 118 107
e0 50: 108 109 110 111 0 0 0 0
e0 58: 0 0 0 125 126 127 0 0
e0 60: 0 0 0 0 0 0 0 0
e0 68: 0 0 0 0 0 0 0 112
e0 70: 0 0 0 0 0 0 0 0
e0 78: 0 0 0 0 0 0 0 0
The above table is called the keymap and it is used to map scan code values to keycode values which is called keybindings. If you compare the above chart to the keycode table and look under the scan code column, what is being done in the above table is the following:
- The make scan code values 01 through 57 hexadecimal are being translated directly to the keycode. You can see the make scan code and the keycode are the same value for these keys.
- The make scan values 58 through 7f hexadecimal are mapped to the decimal values shown in the table. There are none of the keycode values in my keycode table except for the 58 hex value.
- The special keys with make scan code starting with e0 hex and second byte value in the range 00 through 7f hexadecimal are mapped. Looking in the keycode table you can see that keys with values filled in in the above table have corresponding keycode values. For example the home key with make scan code values of e0 47 maps to keycode 102.
4. Mapping the keycode to the keymap (keymapping)
The keymap is the translation between keycodes and ASC characters. The utilities loadkeys and setmetamode are used to set the keymap. The keymap file is normally loaded into the system (kernel) at startup using the program loadkeys. An example keymap file is shown in the section "Example Keymap File".
If you type "dumpkeys" you will see output similar to the keytable file in "/usr/lib/kbd/keytables/*.map". The output can be saved to a file, and used to generate a new file to be used with the "loadkeys" command. There is a manpage describing the structure of this file. It can be accessed by typing "man keymaps". There are many symbols in this file that describe values for keys. You can see the value of many of them by typing "dumpkeys --long-info" or "dumpkeys -l". You may want to pipe its output to a file for further examination, "dumpkeys -l >current.kmap" or pipe it to less to look at it "dumpkeys -l |less". To figure out what each symbol does, must be determined by examining the kernel sources. This file is basically organized in the following manner consisting of three definition types.
- charset definitions - The command "dumpkeys --help" or "dumpkeys -g" will show available character set definitions. They are such as "iso-8859-1".
- keycode definitions - Define
- string definitions
A complete definition must fit on one line.
Eight modifiers to the keycode definition are supported:
- Shift - Weight 1
- AltGr - Weight 2
- Control - Weight 4
- Alt - Weight 8
- ShiftL - Weight 16
- ShiftR - Weight 32
- CtrlL - Weight 64
- CtrlR - Weight 128
Example lines in a ".kmap" file:
keycode 1 = Escape
alt keycode 1 = Meta_Escape
control keycode 1 = F243
The keycode number is the key number as shown in the "keycode table" in this document. The modifiers alt and control above are used to determine actions when the alt or controls are held down while the key is pressed. The value after the "=" is a string or keysym which will specify an action or string to be sent when the string is pressed.
How keymapping is done when the system is booted and how to change it.
The file "/etc/rc.d/rc.sysinit" contains the following line:
loadkeys $KEYMAP > /dev/tty0 < /dev/tty0 2</dev/null && success "Loading default keymap" || failure "loading default keymap"
$KEYMAP is previously defined as "/etc/sysconfig/console/default.kmap" if it exists, but normally it is defined as the value set in the file "/etc/sysconfig/keyboard" (which is normally "us" in the United Stated) if the directory "/usr/lib/kbd/keymaps" exists. Therefore the easy way to modify the key settings for the system is to modify the file /etc/sysconfig/keyboard to a new default value such as KEYTABLE="/etc/sysconfig/console/mykeymap". An example keymap file is shown in the section "Example Keymap File".
5. Mapping the terminal
Termcap and terminfo are databases used to support keymappings for terminals and other programs. This way, special drivers are not required for each terminal type.
- The termcap database is older than the terminfo database but is more accessible. Termcap is making the terminfo database obsolete. The termcap database is in "/etc/termcap".
- The terminfo data base is stored in compiled form in the directory structure "usr/share/terminfo". A program called tic is used to compile each terminal entry. When tic is used to compile a terminfo source file, the data is put in a file with a name depending on the name of the first alias. If the alias is linux, it would be put in "/usr/share/terminfo/l/linux". The contents of each terminfo file can be examined using the program "infocmp". The Linux console key sequences are documented in the "console_codes" man page.
In each terminfo source file is a name line and capability lines. The name line defines the name of the terminal and its aliases The capability lines define three types of capabilities.
- Boolean - Defines capabilities that the terminal has such as "am" for automatic right margins meaning when a line reaches the right side of the window it automatically wraps to the left side.
- Numeric - Defines numeric capabilities of the terminal such as the number of lines.
- String - Defines what key will issue what command to the terminal.
The termcap and terminfo commands are described in a table in this section.
The two ways to access the termcap functions are from the "curses" or "termlib" library. To access terminfo functions from a program requires "curses" or "terminfo" routines. The curses, or ncurses library is used to provide functions to programs that need to manipulate text on a non-graphical output (text output).
There are three additional terminal programs associated with terminfo used for terminal support and key mapping.
- tset - Used to detect and set the terminal.
- tput - Similar to tset, but relies on the environment TERM variable to detect the terminal.
- stty - Used to change and print terminal line settings, including key mappings.
The stty program
The stty program is used to map specific keys to special key functions along with setting up an array of control, input, output, and local settings for the terminal. If you type "stty -a", the following will be output:
speed 38400 baud; rows 43; columns 132; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>
eol2 = <undef> start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
The first line displays terminal parameters. The second through fourth lines display special functions and the keys they are mapped to. Some functions are:
- eof - End of file is sent to terminate the input.
- eol - End of line
- eol2 - Alternate eol
- erase - Erase the last typed character
- intr - Send an interrupt signal
- kill - Erase line
- quit - Send quit signal
- start - Restart the output
- stop - Stop the output
- susp - Stop the terminal
These functions relate to the program running on the terminal when the appropriate key is pressed. The last lines in the file define local options which include control, input, output and local settings. Control settings include line parity settings, character size in bits, stop bit configuration, and more. Input settings control how input is handled with regard to ignoring parity errors on the line when characters are received, if break should be ignored, and much more. Read the stty man page for more information or type "info stty". The keys used may be defined as follows using the character c as an example:
- ^C - Control C.
- 0x13 - Control C on hexadecimal.
- 19 - Control C in decimal.
- 023 - Control C in octal.
- C - The character C.
- 0x46 - The character C in hexadecimal.
The hexadecimal value for control C is 13. Its decimal value is 19.
Type "stty erase ^?" to set the terminal up so the DEL key will perform the erase function.
Most tty input to programs is through the kernel tty driver and the settings produced by the "stty" command. The stty command is used to set the eof, eol, erase, quit, start, stop, suspend, and other characters. Programs such as the"bash" shell, the "emacs" editor and the X window system have their own input handling. This is described in the next section.
Console key utilities and files
- Kernel keyboard driver
- kbd_mode - Report or set the keyboard mode to -s (scancode mode, RAW) -k (keycode mode, MEDIUMRAW) -a (ASC mode, XLATE) -u (UTF-8 mode, UNICODE). XLATE is default.
- kbdrate - modify the keyboard repeat rate and delay time after keypress.
- kbdconf - Configures the /etc/sysconfig/keyboard file which specifies the location of the keyboard map file.
- For system key mapping make codes to keycodes
- setkeycodes - used to set a translation between unusual scancodes and keycodes. This utility is not usually needed.
- getkeycodes - Print the kernel scancode to keycode mapping table.
- Mapping keycodes to keymaps
- dumpkeys - dump keyboard driver translation tables in the format specified by keymaps. The output of this program will look similar to the keytable file in "/usr/lib/kbd/keytables/*.map" and the output can be saved to a file, and used to generate a new file to be used with the "loadkeys" command.
- loadkeys - Load the keyboard translation table into the system from a specified file. Type "loadkeys -d" or "loadkeys defkeymap" to load the default keymap. Changes keys for all virtual consoles. The keyboard translation table set in the kernel (compiled in) is in the file "/usr/src/linux/drivers/char/defkeymap.map". To change the kernels keymap without having to load a new table after booting, you must modify the file, then re-compile the kernel. You would only need to do this to modify keymaps for remote boot systems that don't have access to all system programs.
- setmetamode - define the keyboard meta key handling. Controls whether the keystroke <Alt-key>, would send the keycode M-key or the key sequence ESC followed by key. You can have different setting in different virtual consoles.
- Debugging tools
- showkey - Examine the scancodes and keycodes sent by the keyboard. Options are -s (show scancodes) -k (show keycodes, default) -m (show keymap). This program outputs key values that the user presses on the keyboard. The program terminates when no keys are pressed for 10 seconds.
- Termcap and terminfo
- tic - Compiler for terminfo.
- infocmp - Used to examine terminfo files.
- /etc/termcap - The termcap database file.
- /usr/share/terminfo - The directory structures containing the terminfo compiled database.
- Other tools
- consolechars - Load console screen font (was called setfont). The directory "/usr/lib/kbd/consolefonts/" is the default directory for fonts. "/usr/lib/kbd/consoletrans" is the default directory for ACM's and SFM's.
- psfaddtable - Add a Unicode character to a console font.
- For terminals and terminal key mapping
- stty - Print or change the terminal line settings.
- setterm - Set terminal attributes.
- tput - Initialize a terminal or query terminfo database.
- setleds - Set or output the keyboard LED settings for caps lock, num lock, and scroll lock.
- setfont - Never use unless you know what you are doing. There is no man page for this command.
- chvt - Change virtual terminal. Usage: chvt3.
- deallocvt - De allocate unused virtual terminals
- For X
- xmodmap - Used to modify keymaps and pointer button mappings in X. Map X keycodes to keysyms. Usage "xmodmap mykeys.map".
- xkeycaps - A GUI front end to xmodmap.
- xev - Allows you to see key make and breaks generated on a window.
- showfont - font dumper for X font server
- xset - Set user preferences for the display.
- /etc/X11/xinit/Xmodmap or $HOME/.Xmodmap - File(s) that can be uset to set keycode mapping in X
- $HOME/.Xinitrc - A file run when X starts that is a script file. The program "xmodmap" can be invoked in this file to set keymappings for X.
- $HOME/.Xresources - Another file where keymappings may be changed for X.
- /etc/inputrc or $HOME/.inputrc - Where Bash keymapping is done.
- $HOME/.lessrc - Where keymapping is done for less.
- $HOME/.emacs - Where keymapping is done for emacs.
- bindkey - A program supplied by tsh to allow for binding keymaps.