A quick look at user-space virtual terminals

nosh pages:

User-space virtual terminals are one of the terminal management features of the nosh package. They allow one to run systems that still have virtual terminal system on the physical user stations, with all of the familiar accoutrements such as terminal login sessions and virtual terminal switching with hotkeys, but without that virtual terminal system being embedded into the operating system kernel. Conversely, they are X-less; they don't depend from any X11 tools or libraries.

The design comprises separate coöperating components.

These components are loosely coupled. One can restart the multiplexor or the realizer without affecting the terminal emulators that they attach to. One can attach multiple realizers to a single terminal emulator, or multiplexor.

And the system is designed to operate with reduced privileges. Not only are the programs not running in kernel mode as part of the operating system kernel, they don't even need superuser access. They can run under dedicated unprivileged accounts, with only the minimum file and device access that they individually need, secured even from one another by the POSIX user account system.

A Linux machine running a nosh user-space virtual terminal

The terminal is being realized onto the framebuffer device via the uvesafb driver, at the largest VESA resolution that it allows on the machine.

Several things are illustrated here.

Easy resizeability

In keeping with the DEC VT control sequence model, user-space terminals initialize at 80 columns by 25 rows. But the DEC VT protocol provides applications running on terminals with control sequences for adjusting both width and height (DECSNLS, DECSLPP, DECCOLM, and DECSCPP).

Linux and FreeBSD/PC-BSD kernel terminal emulators don't implement those control sequences. Changing virtual terminal size has to be done with special programs that know how to reprogram display hardware, that need superuser privileges, and that can only run locally on the machine where the kernel virtual terminal is, because they operate directly on local character devices with ioctl() calls. It also affects all virtual terminals in one go.

The terminal dimensions here have been adjusted with the console-resize (a.k.a. resizecons) utility to 100 columns and 64 rows, the all-black right hand columns of which have been clipped from this screenshot for size reasons. This utility simply emits the DEC VT control sequences for this, and has no need for ioctl() or mucking about with fonts. Its only (trivial by comparison) complexities are whether one wants to use the VT520 control sequences or the control sequences supported by earlier VT models, the user-space virtual terminal emulator supporting both, and whether control sequences are UTF-8 encoded.

It has only affected this individual virtual terminal, moreover. One can have multiple virtual terminals, of different sizes, multiplexed onto a single physical user station (a "head"). One can of course have multiple heads, if one has multiple framebuffer and input event devices. Because of the design, one can even migrate live terminal sessions from head to head, since one can adjust and restart the multiplexing layer without having to stop and restart the individual emulations that are being multiplexed or the login sessions running on the terminals.

Notice that the terminal emulator doesn't have the restrictions to only a subset of allowable widths and heights that are mandated by actual video terminal hardware. The DEC VT protocol itself supports arbitrary heights and widths, but with rules that they are silently rounded up to the next hardware-supported size. nosh user-space virtual terminals simply discard those rules and allow arbitrary sizes above a certain minimum. They can even be larger than the physical display size, the realizer automatically panning and scrolling to keep the cursor position always in view.

Unicode font support

The top part of the screen is the remains of viewing a Linux manual page in Chinese, after exiting the manual page viewer without clearing the screen. It illustrates the Unicode ability of nosh user-space virtual terminals. The terminal emulator speaks UTF-8, by default and natively, and its display mechanism supports a full 24-bit UCS range that covers all of the existing Supplementary Planes. The manual page is simply the Debian Linux Chinese language manual package and the -L zh_CN option to the man command.

Kernel virtual terminals are restricted by the fact that fonts occupy precious kernel memory space. There are tight limitations on the number of fonts that can be loaded.

The realizer part of the virtual terminal can be supplied with an arbitrary set of multiple fonts, as its fonts are not kernel-resident. It has a simple priority system giving one the ability to partially override large general fonts with small fonts for specific character repertoires. Fonts, and keyboard mappings, are changed by restarting the realizer part of the terminal with a different font set. Because of the design, the rest of the terminal keeps running unaffected.

Fonts use the vtfont format used by the FreeBSD 10 terminal subsystem. So tools to manage terminal fonts, such as the BSD vtfontcvt tool, are already available. As are fonts such as Ed Maste's vtfont collection and the fonts that actually come with FreeBSD/PC-BSD 10 in the operating system.

This terminal emulator has been set up with the GNU Unifont (converted to vtfont format), overridden by k16-1990 (a widely circulated 16×16 JISX0208.1990 font, converted from BDF with vtfontcvt) and 9x16 (built from two widely circulated 9x16 and 9x16B raster fonts) to improve the appearance of several characters over GNU Unifont.

Emulation of the same terminal type as the kernel virtual terminals

The shell prompt is an ordinary Z Shell prompt using termcap, that thinks that it is talking to a linux type terminal. This is the terminal type that is used by the kernel virtual terminals on Linux. On FreeBSD/PC-BSD, the nosh user-space virtual terminal emulator likewise emulates the same type as the FreeBSD/PC-BSD kernel virtual terminals.

Not shown here, because it is rather difficult to show as a screenshot, is the function key and extended key emulation. Although nominally kernel virtual terminals speak the DEC VT keyboard protocol, in reality they do not. As well as speaking "true DEC VT", the terminal emulator user-space virtual terminal speaks the various quirky keyboard input dialects that are spoken by the Linux, FreeBSD/PC-BSD, NetBSD, and SCO Xenix kernel virtual terminals.

As a bonus, user-space virtual terminals also add full DEC VT modifier support to those protocols, so that one can distinguish function and extended keys where modifiers are in effect.

256-colour and 24-bit True Colour support

The colour blocks indicate support for ISO 8613-3/ITU T.416 Set Graphic Rendition control sequences. Shown here are the effects of the SGR control sequences that select from the (conventional) 256-colour palette, the result of a fairly widely known Perl script. Not shown here, but also supported, is full 24-bit RGB SGR colour support.

Font styles and weights, and ECMA-48 attributes

The text at the bottom shows ECMA-48 Set Graphic Rendition attribute support, including attributes not implemented by some other terminal emulators such as strikethrough, italics, reverse video, and hidden text. The blank area is actually a word written with the hidden text attribute turned on. Only on a user-space virtual terminal does the sentence read as it does; on a kernel virtual terminal (lacking such things as strikethrough and hidden attribute support) it reads differently.

Italicization can be implemented by providing the realizer part of the terminal with a proper italicized font. Or the realizer can fake it by making the glyphs of the upright font oblique. (Oblique is not the same as italic. As you can see in the examples given in this MSDN article italics are actually drawn differently. Notice the differences in the letters f and a there, for examples.)

Similarly, either the realizer can be given a proper boldfaced font or it can fake boldface by merging glyphs with 1-pixel-shifted copies of themselves. The realizer uses font weights to realize the ECMA-48 boldface and dim graphic renditions, choosing lighter and heavier weights according to the attribute combinations.

It is important to notice that unlike other terminal emulators the attributes are maintained separately from the colours. User-space virtual terminals are not constrained by the model of the old IBM PC Colour Graphics Adapter to map boldface onto a colour change. This makes life easier for such tasks as implementing screen readers.


© Copyright 2015 Jonathan de Boyne Pollard. "Moral" rights asserted.
Permission is hereby granted to copy and to distribute this WWW page in its original, unmodified form as long as its last modification datestamp information is preserved.