console-fb-realizer 1 user commands nosh
console-fb-realizer console-evdev-realizer console-uugen-hid-realizer console-uhid-realizer console-pcat-mouse-realizer console-pcat-keyboard-realizer console-ps2-mouse-realizer console-kvt-realizer realize a user-space virtual terminal on FBIO, KBIO, USB, evdev, or KVT devices

### BSDs

`console-ugen-hid-realizer` --mouse-primary ugendevicename `console-uhid-realizer` --mouse-primary uhiddevicename `console-pcat-mouse-realizer` --mouse-primary sysmousedevicename `console-pcat-keyboard-realizer` --mouse-primary atkbddevicename `console-wscons-realizer` --mouse-primary wsconsdevicename `console-fb-realizer` --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 --mouse-primary fbname `console-kvt-realizer` --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 --mouse-primary

### Linux

`console-evdev-realizer` --mouse-primary evdevdevicename `console-ps2-mouse-realizer` --mouse-primary ps2mousedevicename `console-fb-realizer` --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 --mouse-primary fbname `console-kvt-realizer` --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 --mouse-primary

## Description

These are the I/O back ends for a (user-space) virtual terminal, that realize that virtual terminal with various input and output devices.

Each one opens the back end interfaces of a user-space virtual terminal and opens the I/O devices (if any) specified by command line options and the particular command. The I/O devices are the concrete devices with which the user-space virtual terminal is to be (partly or wholly) realized. It is the user's responsibility to ensure that these refer to the same, single, physical user station.

They then enter a loop where they simultaneously:

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

- (if the --mouse-primary option is used) writes all mouse state changes recorded in the `mouse-state-file` to the input FIFO; and

- render the contents of the character/attribute buffer file for the virtual terminal on any output device.

I/O devices may be shared with other subsystems, or used exclusively.

Mouse and keyboard devices can be aggregated with other mouse and keyboard devices, or separated from them, by choosing whether to share mouse/keyboard state files amongst realizers.

- Shared keyboard state comprises information about the press, latch, and lock states of the various modifier keys. Sharing this with mouse device realizers enables modifier information to be generated in mouse events; without which all mouse events will have modifier flags set to zero.

- Shared mouse state comprises information about the mouse position and limits of its various axes, and the instantaneous combined states of buttons and wheels.

## Specifying I/O devices

I/O devices are specified by the choice of command, and thus their various command-line options.

### The superior (or sole) choices

For best results, `console-ugen-hid-realizer` should be employed to handle HIDs on the BSDs, `console-evdev-realizer` should be employed to handle HIDs on Linux, and (on both) `console-fb-realizer` to handle output using a framebuffer device. If VT switching support is needed, instead of `console-fb-realizer` substitute `console-kvt-realizer` to handle both VT switching and I/O using a VT-supplied framebuffer and keyboard.

ugendevicename

  This command-line option designates the superior choice of input device on the BSDs. ugendevicename must be the the device file name of a Generic USB device, using the ugen 4 protocol, such as `/dev/ugen0.2` for example. `console-ugen-hid-realizer` parses the bus and address from the name and actually opens the interface device names such as `/dev/usb/0.2.0`, `/dev/usb/0.2.1`, and `/dev/usb/0.2.2`.

  It queries the "type" of the device (e.g. keyboard, tablet, mouse, and so forth) from the device itself, without need for explicitly describing it to the comand. It reads the HID I/O report descriptors from the device and from them decides whether the interface has normal keys, consumer device keys, system keys, keyboard LEDs, relative positioning (mice), and absolute positioning (touchscreen). Any combination of HID I/O in a single USB device can be handled. Multiple keyboard and mice USB interfaces at the given bus+address are combined, and the program acts as if they are a single giant keyboard/mouse.

evdevdevicename

  This command-line option designates the superior choice of input device on Linux, the Human Input Devices enumerated by the operating system. On Linux, evdevdevicename must be the device file name of an event device, using the evdev subsystem, such as `/dev/input/event0` for example.

  `console-evdev-realizer` queries the "type" of the device (e.g. keyboard, tablet, mouse, and so forth) from the device itself, without need for explicitly describing it to the comand.

  Some BSDs have Linux evdev compatibility subsystems, but Generic USB is superior for two reasons. First, the compatibility is incomplete by its nature. Second, even natively evdev hides the extensible nature of the underlying USB HID I/O system.

wsconsdevicename

  This command-line option designates the superior choice of input device on BSDs, the Human Input Devices enumerated by the operating system. wsconsdevicename must be the device file name of a `wskbd` or `wsmouse` device.

  All wscons devices (e.g. keyboard, tablet, mouse, and so forth) speak the same event protocol.

fbname

  This command-line option option designates a framebuffer output device for realizing the user-space virtual terminal's display. 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, kernel virtual terminal devices speak this protocol, and framebuffers are not directly accessible via separate devices.

  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.

### Inferior choices

uhiddevicename

  This command-line option designates an inferior choice of input device on the BSDs, the Human Input Devices enumerated by the operating system or created by uhidd 8. Linux does not have such devices. uhiddeviceename must be the device file name of a USB HID device, using the uhid 4 protocol, such as `/dev/uhid0` for example. `console-uhid-realizer` queries the "type" of the device (e.g. keyboard, tablet, mouse, and so forth) from the device itself, without need for explicitly describing it on the command line.

  This is inferior to Generic USB because the kernel and uhidd 8 disagree on what the uhid 4 protocol actually is, and produce devices that are not I/O compatible. Do not use this with devices created by uhidd 8 (which is largely superfluous with these realizers anyway).
sysmousedevicename

  This command-line option designates an inferior choice of input device on the BSDs. sysmousedevicesname must be a device that speaks the BSD mouse 4 protocol to programs, such as `/dev/sysmouse`, or `/dev/ums0` (created by the kernel), 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 common mouse 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.

  If used at all this is best used only with the mouse concentrator device, `/dev/sysmouse`, as a backstop catch-all and with PS/2 mice devices.

atkbddevicename

  This command-line option designates an inferior choice of input device on the BSDs. filename must be a device that speaks the "kbio" API to programs. On the BSDs, atkbddevicename must be an a kernel virtual terminal device or an atkbd 4 device, such as `/dev/atkbd0`, `/dev/kbdmux0`, `/dev/ukbd0`, or `/dev/vkbd0` (created by uhidd 8) for examples.

  On Linux, "kbio" devices are not directly accessible via separate devices. Kernel virtual terminal devices speak this protocol, but the console-kvt-realizer 1 command is used to employ those.

  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), consumer device keys (calculator, WWW, and eject for examples), and system keys (power, wake, and sleep).

  If used at all this is best used only with the keyboard concentrator device, `/dev/kbdmux0`, as a backstop catch-all.

ps2mousedevicename

  This command-line option designates an inferior choice of input device on Linux. ps2mousdevicename must be a device that speaks the Linux PS/2 mouse protocol to programs, such as `/dev/input/mice` (a backwards-compatibility mouse concentrator provided by the evdev subsystem) for example.

  BSD PS/2 mouse devices (psm 4) speak BSD mouse protocols, not a PS/2 protocol. Do not use `console-ps2-mouse-realizer` with BSD PS/2 mouse devices. It is for Linux PS/2 mouse devices, which speak a 3-byte packet PS/2 protocol peculiar to Linux.

  This is inferior to accessing the mouse via its evdev device. This protocol has no scope for mice wheels, the Z or W axes, or more than 3 buttons. 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 VTs and device sharing

#### The unshared case

All realizers open their respective I/O devices and retain them open for as long as they run. On a system where they do not have to be shared with anything else, and are dedicated to realizing user-space virtual terminals, this just works as-is. One just runs a combination of `console-ugen-hid-realizer`, `console-evdev-realizer`, and `console-fb-realizer` (and any realizers for old PC/AT or PS/2 devices) that continually realize the user-space virtual terminals. Such a system would be Linux compiled without the `CONFIG_VT` option and not running an X11 server, for example, or where a secondary framebuffer and a set of input devices are dedicated only to realizing a user-space virtual terminal.

`console-kvt-realizer` is not used in this case.

#### The shared case

If more than one thing opens an I/O device, however, exactly what part of the system (say) ends up with a key press event from the keyboard can be unpredictable. This happens when realizers for user-space virtual terminals, the kernel's built-in terminal emulator, the Xorg X11 server, and other things all attempt to use the same I/O devices. Device sharing is a way that these all negotiate sharing I/O devices.

It is done by the participants (`console-kvt-realizer` and the Xorg server) allocating a (spare) kernel virtual terminal and waiting for acquire and release orders sent by the kernel. On release, it mutes all of its input devices, with `EV_DISABLE` passed to kevent 2, and notes not to access its output devices. On acquire, it unmutes all of its input devices, with `EV_ENABLE` passed to kevent 2, and notes that it is permitted to access its output devices. It also tells the kernel's built-in terminal emulator to do the complement, telling it not to draw output on the framebuffer nor to read input from the keyboard when that KVT is active.

`console-kvt-realizer` uses a kernel virtual terminal (KVT) for device sharing, and also for some I/O devices that they provide. On the BSDs, the "kbio" keyboard input and "fbio" framebuffer output devices are accessible via a KVT, but the mouse input devices are not. On Linux, only the "kbio" keyboard input devices are accessible via a KVT, but the framebuffer output and mouse input devices are not.

The X11 server Xorg 1, in particular its `config:devd` module, is faulty. It dynamically opens all USB mice as they are attached to the system, but does so exclusively, preventing access to the devices by any other programs. It should just open `/dev/sysmouse`, and rely upon the mouse device concentration already provided by moused 8 and these realizers. It actually does rely on input concentration for keyboard devices. Xorg 1 interferes both with the operation of the BSD moused 8 and with `console-pcat-mouse-realizer`.

#### console-kvt-realizer and the KVT

`console-kvt-realizer` obtains the name of the KVT device from the value of the `TTY` environment variable, and assumes that its standard input and standard output are already connected to it. One can invoke the realizer via vc-get-terminal 1 or a similar command that obtains a virtual terminal device name from an abbreviation, or just supply the full device name. To open the standard input and output one then chains through open-controlling-terminal 1 or a similar command.

When using other commands ensure that the KVT device is set as the controlling terminal. This is a quirk of the operating system kernels themselves, which require this in order for various parts of the mechanism to work.

At startup, `console-kvt-realizer` switches the virtual terminal display (if it is "fbio") into a suitable graphics mode, configures the ("kbio") input to deliver raw keycodes, and switches the line discipline (of the "kbio" device) to non-canonical input (i.e. "raw") mode (so that the raw keycodes are unmolested by the line discipline); 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).

## Autoconfiguration via device paths

Resources used by the realizers, including what virtual terminals to attach to and keyboard map files, are autoconfigured based upon the identity of the I/O device being used and the devicename arguments supplied on the command line. The configuration file and directory format is given in user-vt-realizer-configuration 5.

## 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.

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.

Fonts are loaded from font files, which may be either in the FreeBSD "vtfont" format or in the straight 8×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.

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 --vtfont-faint-r, --vtfont-faint-o, --vtfont-faint-i, --vtfont-normal-r, --vtfont-normal-o, --vtfont-normal-i, and --vtfont 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 --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 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×16 bounding square, with 8×8 pixel fonts doubled to 16×16 pixels. 8×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.

### Fallback behaviour

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.

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.)

## Keyboard mapping

A keyboard device realizer (`console-ugen-hid-realizer`, `console-evdev-realizer`, `console-uhid-realizer`, `console-wscons-realizer`, or `console-pcat-keyboard-realizer`) employs a loadable keyboard map to determine how input events from a keyboard device translate into keyboard messages sent to the input FIFO of a user-space virtual terminal. The keyboard input event device provides a sequence of non-portable, device and operating system specific, keycode numbers, with attached press/release flags. The realizer translates these keycodes into a portable logical keyboard, applies the actions defined in the keyboard map, in conjunction with the (shared or isolated) modifier state, resulting in keyboard messages.

The map file format is given in console-keyboard-map 5.

### 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. The keyboard realizers remember such "dead" keys, without transmitting them to the input FIFO as they are pressed (or autorepeated). They attempt to combine them with the next non-combining character keypress. In this respect they behave mostly according to ISO/IEC 9995-3 and DIN/EN 2137:

- The keyboard realizers implement 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. The keyboard realizers apply 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

The realizers only require sufficient privileges to access their various I/O devices, the shared keyboard/mouse state files, the display buffer file (if they are output device realizers), the FIFO (if they are input device realizers). They do not attempt to create the display 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. Owner access for any files, directories, FIFOs, or I/O devices is not necessary. The shared keyboard/mouse state files may be owned by the dedicated user, but this is not not a requirement.

Superuser privileges are not necessary for all realizers, which should be invoked without superuser privileges, employing setuidgid 1 or similar as necessary. The recommended configuration is that there be a dedicated unprivileged user or group that owns no files, devices, directories, or FIFOs; that the I/O devices be (as appropriate) readable and writable (but not owned) by that user or group; that the display file and the FIFO are (respectively) readable and writable (but not owned) by that user or group; and that the shared keyboard/mouse state files are both readable and writable (but not owned) by that user or group.

The exception is `console-ugen-hid-realizer`. That requires superuser access in order to detach any kernel device drivers from ugen 4 devices. After opening its devices and detaching their kernel device drivers, but before attempting to access font files or VT back-ends, it drops privileges in the manner of setuidgid-fromenv 1, and so requires that the appropriate environment variables have been set up via envuidgid 1 or similar.

## Author

Jonathan de Boyne Pollard