Name

console-fb-realizer — realize a user-space virtual terminal on a framebuffer

Synopsis

console-fb-realizer [--kernel-vt] [--kernel-vt-number number] [--input filename] [--ugen-input control-filename function-filename] [--atkeyboard filename] [--sysmouse filename] [--keyboard-map filename] [--font-light-r filename] [--font-light-o filename] [--font-light-i filename] [--font-medium-r filename] [--font-medium-o filename] [--font-medium-i filename] [--font-demibold-r filename] [--font-demibold-o filename] [--font-demibold-i filename] [--font-bold-r filename] [--font-bold-o filename] [--font-bold-i filename] [--vtfont-faint-r filename] [--vtfont-faint-o filename] [--vtfont-faint-i filename] [--vtfont-normal-r filename] [--vtfont-normal-o filename] [--vtfont-normal-i filename] [--vtfont filename] [--quadrant number] [--wrong-way-up] [--bold-as-colour] [--80-columns] [--initial-numlock] {vcname} [fbname]

Description

console-fb-realizer is the I/O back end for a (user-space) virtual terminal, that realizes that virtual terminal with a framebuffer device and event devices.

It opens the character/attribute buffer file vcname/display and the input FIFO vcname/input. These are the back end interfaces of the user-space virtual terminal, as detailed in console-terminal-emulator(1).

It also opens the framebuffer device and the input devices (if any) specified by command line options. These are the concrete devices with which the user-space virtual terminal is to be realized. It is the user's responsibility to ensure that these refer to the same, single, physical user station.

It then enters a loop where it simultaneously:

  • writes all data received from the input devices to the input FIFO for the virtual terminal, translating to the abstract keyboard and mouse; and

  • renders the contents of the character/attribute buffer file for the virtual terminal on the framebuffer.

The framebuffer device need not be the same size or height:width ratio as the virtual terminal display. When it is smaller than the display, the realizer will move the framebuffer around as a "window" onto the virtual terminal display, such that the cursor position is always within the window. When it is larger than the display, the realizer will align the virtual terminal display to one corner of the framebuffer, as specified by the --quadrant command-line option. It will render the parts of the framebuffer outwith the virtual terminal display area as black.

The --wrong-way-up command-line option causes the display to be realized the wrong way up, swapping the direction of increasing line numbers. This is an oft-requested terminal feature, albeit by people who have never actually experienced it.

Specifying I/O devices

I/O devices are specified by various command-line options.

--input filename

This command-line option option designates the superior choices of input device for each platform, the fundamental Human Input devices enumerated by the operating system. On Linux, filename must be the device file name of an event device, using the evdev subsystem, such as /dev/input/event0 for example. On the BSDs filename must be the device file name of a USB HID device, using the uhid(4) protocol, such as /dev/uhid0 for example.

The "type" of the device (e.g. keyboard, tablet, mouse, and so forth) is queried from the device itself, without need for explicitly describing it on the command line. Any combination of mouse, tablet, and keyboard input events in a single USB device can be handled.

--ugen-input control-filename function-filename

This command-line option option designates a slightly less superior choice of input device on the BSDs. control-filename and function-filename must be the the device file names of Generic USB control and function devices, using the ugen(4) protocol, such as /dev/usb/0.2.0 and /dev/usb/0.2.1 for example.

This is slightly less superior because it does not employ the operating system to filter out USB devices that are not Human Input devices. One can incorrectly give the names of non-HID devices to this option, and console-fb-realizer will attempt to use them as USB HID devices.

--atkeyboard filename

This command-line option option designates an inferior choice of input device. filename must be a device that speaks the "kbio" API to programs. On Linux only kernel virtual terminal devices speak this protocol. On the BSDs, filename must be an a kernel virtual terminal device or an atkbd(4) device, such as /dev/atkbd0, /dev/kbdmux0, or /dev/ukbd0 for examples.

This option employed with a kernel virtual terminal device is not generally as useful or functional as the Linux --kernel-vt-number or the BSD --kernel-vt option, of whose functionality it is essentially a subset.

This is inferior because the AT Keyboard model does not include things that are accessible via the USB HID protocol and (to a lesser extent) the Linux input event protocol. Those latter support extra keypads and more keys, including extra extended keys (equals, comma, plus/minus, and brackets on the calculator keypad for examples) and consumer device keys (calculator, WWW, and eject for examples).

--sysmouse filename

This command-line option option designates an inferior choice of input device on the BSDs. filename must be a device that speaks the BSD mouse(4) protocol to programs, such as /dev/sysmouse or /dev/psm0 for examples. BSD mouse devices, while speaking their own idiosyncratic protocols at "mouse level 1" all have a common "mouse level 2" of operation where they all speak this same protocol.

However, this protocol is limited compared to using the USB HID devices directly. It has no support for absolute-position pointing devices, such as USB tablets, because the protocol simply does not support the notion of transmitting absolute position information, only relative pointer movements.

Transparent "mouse integration" under some virtual machine systems requires support for absolute-position pointing devices. (In Oracle VirtualBox, for example, when "mouse integration" is off, host machine mouse input is reported to the guest machine as input from a relative-positioning mouse device; but when "mouse integration" is on, host machine mouse input is reported to the guest machine as input from an absolute-positioning tablet device.) This type of device cannot work with them.

--ps2mouse filename

This command-line option option designates an inferior choice of input device on Linux. filename must be a device that speaks the Linux ps2 mouse protocol to programs, such as /dev/input/mice for example.

This protocol has no scope for mice wheels, more than 3 buttons, Z or W axes. It is also poorly effected in some virtual machine systems, which try to enforce a relationship between "mickeys" in the virtual hardware and pixels on the host display, and do not always do that right.

--kernel-vt

This command-line option option designates using a kernel virtual terminal for input, output, and device sharing on the BSDs. One still designates the mouse device separately with an --input or a --sysmouse command line option, however. On the BSDs, the underlying keyboard input and framebuffer output devices are accessible via a kernel virtual terminal.

The realizer obtains the name of the allocated kernel virtual terminal device from the value of the TTY environment variable. (One can invoke the realizer via vc-get-tty(1) or a similar command that obtains a virtual terminal device name from an abbreviation, or just supply the full device name. Note that it is not required to pre-open this device, nor to set it as the controlling terminal.) It is used for keyboard input, framebuffer output, and device sharing and must speak the "fbio" and "kbio" APIs to programs.

For the duration, the realizer switches the virtual terminal display into a suitable graphics mode, configures it to deliver raw keycodes, switches its line discipline to non-canonical input (i.e. "raw") mode, and tells it not to draw output from the virtual terminal on the screen nor to send input to the virtual terminal from the keyboard; switching all of these back to their saved prior settings upon its termination. The realizer attempts to choose the highest resolution graphics mode available that has a 32-bit or 24-bit colour depth. The --80-columns option constrains its choice to graphics modes that are no wider than 80 columns (1280 pixels).

--kernel-vt-number number

This command-line option option designates using a kernel virtual terminal for input and device sharing on Linux. One still designates the mouse and framebuffer devices separately with an --input or a --ps2mouse command line option and a fbname command line argument, however. On Linux, only the underlying keyboard input devices are accessible via a kernel virtual terminal.

The realizer needs to know the number of the kernel virtual terminal, rather than its name. (The BSDs have an API where, with an open file descriptor to a kernel virtual terminal device, one can obtain its virtual terminal number. Linux lacks such an API. Note that it is not required to pre-open this device, nor to set it as the controlling terminal.)

For the duration, the realizer configures the virtual terminal to deliver raw keycodes, switches its line discipline to non-canonical input (i.e. "raw") mode, and tells it not to draw output from the virtual terminal on the screen nor to send input to the virtual terminal from the keyboard; switching all of these back to their saved prior settings upon its termination.

fbname

This command-line option option designates a choice of output device. fbname must be a device that speaks the "fbio" API to programs. On Linux only framebuffer devices, such as /dev/fb0, speak this protocol. (Remember that "kernel mode setting" device drivers create simple framebuffer devices for programs that use the "fbio" API.) On the BSDs, fbname must be an a kernel virtual terminal device, as framebuffers are not directly accessible via separate devices. On the BSDs, the --kernel-vt command-line option implies using the kernel virtual terminal's framebuffer, and renders this command-line argument superfluous.

For a tutorial on how to employ these in concert, see the nosh Guide.

Display features

Virtual terminal display buffers encompass a "light/dark" screen flag and various kinds of glyph for the cursor and the pointer. All of the cursor and pointer glyph types are supported. The blinking attribute for the cursor is not, however, supported.

As with real DEC VTs, but unlike some terminal emulators, the "light/dark" flag causes foreground and background colours to be swapped when displaying every display cell, i.e. "reverse video". The cursor is not realized by reverse video. Rather, the foreground and background colours of the cell with the cursor are complemented against white.

Fonts

Virtual terminal display buffers have faint, boldface, italic, strikethrough, and underline attributes for character cells. Only faint, boldface, and italic involve font support, mapping to four font weights (light, medium, demibold, and bold) and three slants (upright, italic, and oblique). Strikethrough and underline attributes are rendered not through font selection but by overwriting the non-strikethrough non-underline glyphs with appropriate horizontal lines. If faint and demibold weights are unavailable, the faint attribute is emulated by shading the foreground and background colours towards black. If bold weight is unavailable, the bold attribute is rendered by overlaying a glyph with a shifted copy of itself. (The --bold-as-colour command-line option will as an alternative always render boldface by tinting foreground colours towards white, but this is of limited use with applications that employ 256-colour or true-colour terminal controls, as many do nowadays.) If italic stroke is unavailable, the first fallback is to use an oblique font. (Oblique is not the same as italic, note, and is often an inferior substitute for it.) If neither italic nor oblique are available, the italic attribute is rendered by shifting the upright glyph into an oblique form within the character bounding square if the character size permits.

Fonts are loaded from font files, which may be either in the FreeBSD/TrueOS "vtfont" format or in the straight 8 by 16 unadorned bitmap format used by FreeBSD's "syscons". (To convert an Adobe BDF format font file to "vtfont" format, use the FreeBSD vtfontcvt(1) utility.) Font files are specified by the filename in the various font command-line options: --vtfont-faint-r , --vtfont-faint-o , --vtfont-faint-i , --vtfont-normal-r , --vtfont-normal-o , --vtfont-normal-i , --vtfont , --font-light-r , --font-light-o , --font-light-i , --font-medium-r , --font-medium-o , --font-medium-i , --font-demibold-r , --font-demibold-o , --font-demibold-i , --font-bold-r , --font-bold-o , and --font-bold-i .

The weight and slant are encoded via these command-line options, because meta-information about weight and slant is not in a font file itself (it usually being encoded in the filename). Bitmap fonts contain just one glyph set. The "vtfont" format has two glyph sets for a pair of unspecified weights.

  • The "vtfont" command-line options load both sets of glyphs from a "vtfont" format font. "normal" in the option name specifies that the presumed weights of the pair are medium and bold; "faint" specifies that the presumed weights are light and demibold. "r", "o", and "i" specify the presumed slants as upright, oblique, and italic respectively.

  • The "font" command-line options are the only way to load bitmap fonts, and can also be used to load just the first set of glyphs from a "vtfont" format font, providing fine-grained control of what glyphs are used if that is required. Again, "r", "o", and "i" in the option name specify the presumed slants as upright, oblique, and italic respectively. The four presumable weights in the option name are "light", "medium", "demibold", and "bold".

Fonts must be monospace fonts with a height of 8, 14, 15, or 16 and a width of 8, 9, 12, or 16. All glyphs are rendered in a 16 by 16 bounding square, with 8 by 8 pixel fonts doubled to 16 by 16 pixels. 8 by 16 pixel block graphic and box drawing characters are doubled in width. Any "horizontally extendable" characters (such as the em dash) not otherwise extended to 16 pixels wide are extended by overlaying themselves to the right.

With no fonts loaded, and for any characters which cannot be found in the loaded fonts, console-fb-realizer "greeks" its output, falling back to displaying a blank for any whitespace characters, a box for any C0 or C1 control characters, and a block for all other characters. Such "greeking" is of course illegible; and it is recommended that sufficient fonts be loaded in order to render at least the whole of Microsoft's Windows Glyph List 4. (One might be tempted to simply cover the OpenType World Glyph Set 1 character set instead. Bear in mind that the W1G character set does not include line drawing, block, arrow, and other characters that are commonly employed by TUI systems to draw UI widgets; whereas WGL4 does.)

Fonts are loaded at program initialization and remain loaded thereafter. To change fonts, it is necessary to stop and restart console-fb-realizer. This does not, of course, affect the operation of the terminal emulator or the processes using the terminal.

Keyboard mapping

The keyboard input event device provides a sequence of keycode numbers, with attached press/release flags. These are translated to keyboard actions through use of a loadable keyboard map. Unfortunately, Linux and the BSDs do not agree on a single set of keycode numbers, and cannot share one another's keyboard layout definitions. So the realizer first translates the non-portable Linux and BSD keycodes, and USB HID keyboard usages, into a common codeset. It is this common set that is actually used in key maps.

The map is stored in the file kbdmapname in machine-readable form. FreeBSD/TrueOS keymaps can be compiled from the BSD/SCO kbdmap(5) human-readable form to this machine-readable form with the console-convert-kbdmap(1) command.

Map file logical keyboard matrix

In machine-readable form, a map is a simple 2-dimensional array of 96-octet map entries, representing 17 "rows" of 16 "columns" per row, in row-major order. This is the "matrix" of a logical keyboard denoted by the aforementioned common codeset.

These rows are, in order:

ISO 9995 "E" row

An unused position, positions E01 to E12, the additional key from the 106/109-key PC keyboard at E13, one more unused position, then position E14. The language-variant key sometimes found at position E00 is grouped with other similar keys in the third row, where the IBM PC/AT keyboard numbering actually placed it.

ISO 9995 "D" row

Positions D00 to D12, two unused positions, then position D14. The key sometimes found at position D13 is grouped with other similar keys in the third row, where most IBM PC/AT layouts actually place it.

ISO 9995 "C" row

An unused position, positions C01 to C11, the key usually found in position E00 (grave or kanji/zenkaku/hankaku), the key usually found in position C12 (on 102/105-key, 103/106-key, 104/107-key, and 106/109-key PC keyboards) or D13 (on 101/104-key PC keyboards), then two more unused positions.

ISO 9995 "B" row

An unused position, the additional "Europe 2" key from the 102/105-key and 104/107-key PC keyboards at B00, positions B01 to B10, the additional key from the 104/107-key and 106/109-key PC keyboards at B11, and three more unused positions.

Modifiers

1st ⇧ Level 2 shift, 2nd ⇧ Level 2 shift, ⇫ Level 3 shift, an unused position, 1st ⎈ Control, 2nd ⎈ Control, 1st ⌘ Super, 2nd ⌘ Super, 1st ⎇ Alt, three unused positions, ⇬ Caps Lock, Scroll Lock, ⇭ Num Lock, and an unused position.

ISO 9995 "A" row

An unused position, the ひらツな/カタカナ/ローマ字 (Hiragana/Katakana/Romaji) key from the 106/109-key PC keyboard, the 半角/全角 (Zenkaku/Hankaku) key (from USB but not a PC keyboard key, and not to be confused with the PC keyboard key at E00), the Hiragana key (from USB but not a PC keyboard key), the Katakana key (from USB but not a PC keyboard key), the 変換 (Henkan or XFER) key from the 106/109-key PC keyboard, the 無変換 (Muhenkan or NFER) key from the 106/109-key PC keyboard, an unused position, the Han/Yeong key from the 103/106-key PC keyboard, the 変換 (Hanja) key from the 103/106-key PC keyboard, three unused positions, Alternate Erase, ⎄ Compose, and ␣ Space.

Cursor/Editing keypad

⇱ Home, Up Arrow, Page Up, Left Arrow, Right Arrow, ⇲ End, Down Arrow, Page Down, Insert, Delete, and 6 unused positions.

Calculator keypad 1

*, 7, 8, 9, -, 4, 5, 6, +, 1, 2, 3, 0, . Decimal Point, Enter, and / Divide.

Calculator keypad 2

, Thousands Separator from the Apple Pro JIS and 107-key PC keyboards, , JP Comma, = from the Apple Pro JIS keyboard, AS/400 =, ± Sign Change, (, ), {, }, and 7 unused positions.

Function row 1

The ⎋ Escape key, then F01 to F15.

Function row 2

F16 to F31.

Function row 3

F32 to F47.

Function row 4

F47 to F63.

System Commands keypad

An unused position, Power, Sleep, Wake, Debug, and 11 more unused positions.

Application Commands keypad 1

Pause, Print Screen, Attention, ⯉ Application, Break, 8 unused posititions, Mute, Volume Down, and Volume Up.

Application Commands keypad 2

An unused position, Execute, Help, Menu, Select, Cancel, Clear, Prior, Return, Separator, Out, Oper, Clear/again, Ex Sel, and 2 more unused positions.

Application Commands keypad 3

An unused position, Stop, Again, Properties, Undo, Redo, Copy, Open, Paste, Find, Cut, and 5 more unused positions.

Consumer keypad 1

Calculator, File Manager, WWW, Home, Refresh, Mail, Bookmarks, Computer, Back, Forward, Lock, CLI, Next Track, Prev Track, Play/Pause, and Stop Playing.

Consumer keypad 2

Record, Rewind, Fast Forward, Eject, New, Exit, and 10 unused positions.

Map file entries

Each 96-octet map entry comprises twenty-four big-endian 32-bit integers.

A map entry describes two things: a set of possible actions to be taken when the key is pressed and released, and how to select which action based upon the momentary keyboard modifier state. A selection class determines how the set of modifiers is reduced to a four-bit action index (giving sixteen possible combinations) by combining modifiers with one another.

Keyboard modifiers comprise (in ISO 9995-1 terminology) modifiers for level 2, level 3, and group 2; for caps, num, and shift locks; and for super, alt, and control. What keys act as these modifiers is of course determined by the keyboard layout: but often the level 2 modifiers are the ⇧ Shift keys; the level 3 modifier is the right ⌥ Option/Closed Apple (Apple keyboards) or ⇮ AltGr (Windows and IBM PC/AT keyboards) key; the alt modifier is the left ⌥ Option/Closed Apple (Apple keyboards) or ⎇ Alt (Windows and IBM PC/AT keyboards) key; and super is the ⌘ Command/Open Apple (Apple keyboards), Meta (Sun keyboards), or Windows (Windows keyboards) key. The initial state of all locks is off, except for the numeric lock when the --initial-numlock option is used.

The selection class code is first in each entry, and the code values are here designated by their UCS-4 code points.

'p' (U+00000070, "plain")

The keyboard modifier state is entirely ignored and the first action is always chosen.

's' (U+00000073, "shiftable")

When selecting an action, the sense of the level2 modifier state is inverted by the shift lock state. Shift lock operates like the typewriter facility of that name, locking on until either level2 modifier key is pressed. This is generally used for non-alphabetic keys that obey shift lock but not caps lock.

'c' (U+00000063, "capsable")

When selecting an action, the sense of the level2 modifier state is inverted by the OR-combined caps lock and shift lock states. This is generally used for alphabetic keys that obey caps lock and shift lock.

'n' (U+0000006E, "numable")

When selecting an action, the sense of the level2 modifier state is inverted by the OR-combined num lock and shift lock states. This is generally used for auxiliary keys that obey num lock and shift lock.

'f' (U+00000066, "funcable")

When selecting an action, the sense of the level2 modifier state is inverted by the shift lock state, and the level3 modifier state is replaced by the alt state. This is generally used for function block keys that obey shift lock but not caps lock.

The next seven 32-bit numbers are reserved, and should be set to zero. The remaining sixteen 32-bit numbers are the actions, chosen according to the selection class. These denote the actions for various combinations of modifiers: none, level2, control, control+level2, level3, level2+level3, control+level3, control+level2+level3, group2, group2+level2, group2+control, group2+control+level2, group2+level3, group2+level2+level3, group2+control+level3, and group2+control+level2+level3, with inversions and replacements as aforementioned.

Map file actions

An individual action in a map entry is a big-endian 32-bit integer, which comprises three or four sub-fields.

The most significant byte denotes the action type and the interpretation of the remainder of the action. (These are, intentionally, similar to the input protocol used by console-terminal-emulator(1), aimed at making debugging and trace analysis simpler. They are two distinct and separate protocols, however.)

0x00xxxxxx

No-operation, Take no action. This is used for keys that have no action in the key map.

0x01nnnnnn

UCS-3 key. On press or autorepeat, a Unicode character message for the code point U+00nnnnnn is sent to the input FIFO. If the alt modifier is in effect, a Unicode accelerator message is sent instead.

0x03nnnncc

Modifier key. Modifiers do not autorepeat. On press or release, the modifier key nnnn is enacted against the current keyboard modifier state according to the cc command. Commands are:

0x01

Momentary. The modifier is on when the key is pressed, and off when the key is released.

0x02

Latching. Pressing the key latches the modifier on until a non-modifier key is pressed.

0x03

Locking. Pressing the key locks the modifier on; releasing and pressing it again locks it back off.

0x0Annnnzz

Session selection key. On press or autorepeat, a session selection message for the session number nnnn is sent to the input FIFO. zz is ignored and should be set to zero for upwards compatibility.

0x0Cnnnnzz

Consumer key. On press or autorepeat, a consumer key message for the consumer key number nnnn is sent to the input FIFO. zz is ignored and should be set to zero for upwards compatibility.

0x0Ennnnzz

Extended key. On press or autorepeat, an extended key message for the extended key number nnnn is sent to the input FIFO. zz is ignored and should be set to zero for upwards compatibility.

0x1Ennnnzz

Unshiftable extended key. On press or autorepeat, an extended key message for the extended key number nnnn is sent to the input FIFO. zz is ignored and should be set to zero for upwards compatibility. The accompanying keyboard modifier state does not incorporate the level 2 modifier, which will never be seen by the terminal emulator or processes connected to the terminal. This is used for keyboard layouts where shift inverts the sense of numlock on calculator keys, and that shift is not considered to further modify the key or be visible to applications.

0x0Fnnnnzz

Function key. On press or autorepeat, a function key message for the function key number nnnn is sent. zz is ignored and should be set to zero for upwards compatibility. This is used for keyboard layouts where the function key block has a large number of actual keys. The terminal emulator, and processes connected to the terminal, will see function keys with modifiers.

0x1Fnnnnzz

Unmodifiable function key. On press or autorepeat, a function key message for the function key number nnnn is sent. zz is ignored and should be set to zero for upwards compatibility. The accompanying keyboard modifier state does not incorporate the level or group modifiers, which will never be seen by the terminal emulator or processes connected to the terminal. This is used for keyboard layouts where the function key block has a small number of actual keys and the level+group modifiers are used "locally" (within the realizer) to simulate a larger key block.

Function keys

It is (of course) the keyboard map that handles function key mapping. The function key entries in the matrix represent physical function keys, not composed keys created by combining modifiers with function keys. Those are, after all, represented by the individual actions in each function key's entry.

A keyboard map defines what input messages a combination of modifiers and a function key generates. It will usually be a function key (if the map maps physical function keys straight to terminal emulator function keys, passing the modifier state through to the terminal emulator), an unmodified function key (if the map uses modifiers to extend the function key set, and thus does not pass the modifier state that it has already consumed through to the terminal emulator), or an extended key.

See console-terminal-emulator(1) for why usually keyboard maps map function keys 1 to 5 to the cursor keypad extended keys PAD_F1 to PAD_F5, and not to the F1 to F5 function keys.

Example keyboard map entries

Keyboard maps are tailored, of course, to country, layout (QWERTY, AZERTY, Dvorak, Maltron, and so forth), and the physical layout of the keyboard (104 keys, 109 keys, 124 keys, and so forth). Here are some example keymap entries:

0x00000063, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01000073, 0x01000053, 0x01000013, 0x01000013, 0x010000DF, 0x010000A7, 0x01000013, 0x01000013. 0x01000073, 0x01000053, 0x01000013, 0x01000013, 0x010000DF, 0x010000A7, 0x01000013, 0x01000013.

'S' on the U.S. International IBM PC/AT keyboard, QWERTY layout. It varies according to caps lock, and produces 'ß' and '§' with the level 3 modifier. The control modifier always produces DC3 (U+0013).

0x00000066, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0E0F0100, 0x1F000D00, 0x1F001900, 0x1F002500, 0x0A000100, 0x0A000D00, 0x0A001900, 0x0A002500. 0x0E0F0100, 0x1F000D00, 0x1F001900, 0x1F002500, 0x0A000100, 0x0A000D00, 0x0A001900, 0x0A002500.

F1 on the U.S. International IBM PC/AT keyboard, QWERTY layout. It ignores level 3, varying according to the level 2, alt, and control modifiers to produce either PAD_F1, F13, F25, and F37 or session switch commands for sessions 1, 13, 25, and 37.

Dead keys

So-called "dead" keys are otherwise ordinary UCS-3 keys in a keyboard map, except that they denote Unicode combining characters; i.e. characters in the "Me" ("Mark, Enclosing") and "Mn" ("Mark, Non-spacing") Unicode code point categories. console-fb-realizer remembers such "dead" keys, without transmitting them to the input FIFO as they are pressed (or autorepeated). It attempts to combine them with the next non-combining character keypress. In this respect it behaves mostly according to ISO/IEC 9995-3 and DIN/EN 2137:

  • console-fb-realizer implements the extra so-called "peculiar" combinations given by the ISO and DIN standards (and also found in several other national keyboard standards). These are applied before attempting any Unicode composition. Most of these involve:

    COMBINING SHORT STROKE OVERLAY (U+0335)

    In ISO 9995-3 keyboard layouts this is Group2+⇫ Level3+C08 (⇧ Shift+⌥ Option, ⌥ Option+K on the U.S. International keyboard). Unicode does not define any compositions using this combining character.

    COMBINING LONG SOLIDUS OVERLAY (U+0338)

    In ISO 9995-3 keyboard layouts this is Group2+⇫ Level3+C09 (⇧ Shift+⌥ Option, ⌥ Option+L on the U.S. International keyboard). Unicode also defines compositions using this combining character. The ISO 9995-3 compositions overlap in only one case, which is the same in both ISO 9995-3 and Unicode.

  • The ISO and DIN standards define "peculiar" combinations with the space character that generate standalone accents. Any sequence of "dead" keys followed by Space generates a sequence of precomposed non-combining accent characters that correspond to the combining characters.

  • The ISO and DIN standards are not specific about Unicode combining characters. console-fb-realizer applies the "canonical" composition rules given by Unicode, attempting to produce a stream of input characters in Unicode Normalized Form C. Any leftover combining characters that cannot be precomposed are treated as if combined with Space, and emitted before the composed character. This differs from Unicode Normalization, where leftover combining characters always follow the "starter" character. Having leftover combining characters precede the composed character both mimicks the existing behaviour of "dead" keys on several systems and is least surprising to the typist as it (roughly) preserves typed order. (Typed order is not entirely preserved; the "dead" keys are sorted by Unicode combining class as a side-effect of NFC composition.)

  • Not all input is in Unicode Normalized Form C. The ISO and DIN standards define a "pass-through" mechanism that allows a typist to enter combining characters as-is: any sequence of "dead" keys followed by the Zero-Width Non-Joiner (entered as Group2+⇧ Level2+A03 in ISO 9995-3 keyboard layouts; which is ⇧ Shift+⌥ Option, ⇧ Shift+␣ Space on the U.S. International keyboard) generates that sequence of non-combining characters in typed order.

  • Full Unicode Normalization is not performed. In particular, if the typist enters a precomposed character after the "dead" keys, it is not decomposed before the composition rules are applied. This is done in order not to surprise the typist. Full Unicode NFD decomposition followed by Unicode NFC composition could result in different leftover combining characters in some cases. It also would perform various one-way transformations.

Security

console-fb-realizer only requires sufficient privileges to access the framebuffer, the input device(s), the display buffer file, and the FIFO. Superuser privileges are not necessary. The recommended configuration is that the file and the FIFO are (respectively) readable and writable by a dedicated unprivileged user or group.

It does not attempt to create the file or FIFO if they do not exist, because this would create them with the wrong owner and group; and it thus requires no write access to their containing directory.

Author

Jonathan de Boyne Pollard