This is a short discussion of how one can usefully combine the nosh package with BRLTTY.
Currently, to use BRLTTY on BSD operating systems it is necessary to use a patched version of the screen
program that dumps a copy of its output into a shared memory area.
This isn't a particularly satisfactory state of affairs.
One can only run up screen
after login, so it is not possible to access a login prompt with BRLTTY; and there's no useful input channel.
The nosh package, in contrast, comes with a user-space virtual terminal toolset that is designed to split apart. There's a terminal emulator program that takes its input from a FIFO and that outputs its display to files; and there are "realizer" programs that render the display from file onto a VDU and that translate real keyboard input events into messages sent over the FIFO. BRLTTY slots quite nicely into this design as simply just another realizer, that happens to "show" the display on a Braille terminal instead of on a VDU.
There are two dæmons that one needs to run, to implement most of a user-space virtual terminal except the part the BRLTTY is going to perform. There's more detailed information in the nosh Guide and in the manual pages about these tools and user-space virtual terminals in general, so this will be a brief overview. One runs:
a "terminal emulator" dæmon
This is an instances of the console-terminal-emulator
program that is pointed at a user-space virtual terminal directory of its own. For the sake of exposition let's say that we have such a dæmon pointed at /run/dev/vc1/
.
Its run program, if the dæmon is managed as a daemontools-style service (which the nosh package can do, q.v.), would be along the lines of:
root /var/sv #cat terminal-emulator@vc1/service/run #!/bin/nosh setuidgid daemon pty-get-tty console-terminal-emulator /run/dev/vc1/ root /var/sv #
a "tty login" dæmon
This is almost a standard login service, except that instead of talking to a kernel virtual terminal it talks to the terminal that the aforementioned terminal emulator dæmon is on the other side of.
There are more complete examples of login services in the nosh Guide, but a very minimal one (using tools that are simpler than even "minimal getty
") looks something like this:
root /var/sv #cat ttylogin@vc1-tty/service/run #!/bin/nosh setsid vc-get-tty vc1/tty open-controlling-tty vc-reset-tty login-prompt login-banner /etc/issue login root /var/sv #
Of course there are the various bits and bobs that accompany setting up the dæmons (such as making sure that /run/dev/
is created); we won't go into those here, as they are just the usual ones and this isn't a general tutorial on setting up dæmons.
With these two dæmons running, there's a login session that runs, talking to a normal terminal device as far as it knows, and a terminal emulator that is on the "back end" of that terminal device that in turn expects its keyboard input to come as messages down a FIFO and its display output to be taken from an ordinary file.
In fact, there are two display output files.
The second one we'll come to later; but the first one is /run/dev/vc1/vcsa
.
This is, as the name suggests, an ordinary Linux (sic!) virtual console image comprising 16-bit CGA character and attribute pairs, which BRLTTY already understands.
It should be very easy to plug BRLTTY into this.
It's the very vcsa file that is missing from the BSDs that has been the stumbling block that has led to mucking around patching screen
all of these years.
Indeed, on the BSDs one can use kevent
to monitor the file for EVFILE_VNODE
/NOTE_WRITE
events and not even need to poll the display file for changes.
(The other realizers supplied in the nosh package do exactly this, in fact.)
The /run/dev/vc1/input
file is for the input events going the other way.
There's a fairly simple 4-byte message protocol, documented in the manual pages, for input events.
Using it, BRLTTY could send function keys, extended keys, even consumer keys (such as the volume controls and so forth that one finds on some keyboards); and of course ordinary (Unicode) characters.
There's no need to worry about function key escape sequences and suchlike.
BRLTTY can just send the messages corresponding to the function keys and extended keys, and the terminal emulator program sorts out how to map that to the relevant escape and control sequences.
Unicode character input is one side of the coin.
The other is that there is a Unicode output capability, in the second display output file mentioned earlier.
This is /run/dev/vc1/display
.
Like /run/dev/vc1/vcsa
it's a simple array of character cells with a header at the beginning of the file giving cursor position, cursor shape, and screen size information.
But the character cells are full Unicode code points, with RGB colour and separate bold+italic+underline+reverse attributes.
One future direction that BRLTTY could take is to plumb itself into the Unicode version of the display buffer instead of the CGA version. The terminal emulator itself is fully UTF-8 capable, and supports the full ECMA-48 model for bold+italic+underline+reverse modes in addition to xterm-style 256-colour capability. This is reflected in the more expressive Unicode display buffer file. Modes are not folded into colours as they are with CGA-style display buffers, meaning that it's possible for a program such as BRLTTY to distinguish between actual true boldface and a colour change. (So if all that one wants to know is what text is underlined or boldfaced, one doesn't resort to guessing how that is being approximated with colour changes.)
Using the Unicode display buffer file leads on to another possible future enhancement.
The nosh package comes with a third dæmon, a "console multiplexor".
This can multiplex two or more user-space virtual terminals (e.g. /run/dev/vc1/
and /run/dev/vc2/
) onto another (e.g. /run/dev/vc0/
) and implements the same sort of session switching that kernel virtual terminals provide in response to ALT
+F1
, ALT
+F2
, and so forth.
Currently, this multiplexor only provides the full Unicode display buffer as its output, not the 16-bit vcsa one.
If BRLTTY gained Unicode capability, one could just drop the multiplexor in.
(BRLTTY would also need to know how to send the special screen switch input messages, which of course would be mapped to whatever Braille actions BRLTTY liked.)
This is a user-space virtual terminal system, and because of that there are differences to kernel virtual terminals and limits to the system.
One won't gain access to the kernel's own console input/output, used for boot messages and the kernel debugger; but then one doesn't have that now with screen
.
There are no special hotkey combinations as there are at the kernel virtual terminal for rebooting the machine and similar, but again that's also true with screen
.
On a more positive note, there are no limits (aside from the limits on running processes, obviously) on how many realizers can be attached to the display buffer and input FIFO of a single virtual terminal, or how many virtual terminals the multiplexor can multiplex. (The multiplexor protocol itself allows up to 65536 virtual terminals. One runs out of keyboard function keys to assign as session-switch hotkeys long before then.) There's no reserving of virtual terminals for an X server, and the system operates entirely independently of the kernel virtual terminal subsystem and X. All of the mucking about with framebuffers, graphics mode, drivers, VT switching, and whatnot that one sometimes encounters when dealing with "user-mode console" programs is the realm of a realizer program that BRLTTY is taking the place of and I/O devices that aren't involved here. This is a deliberate feature of the modular design of nosh user-space virtual terminals.
Similarly, note that the only part of this entire system that requires superuser privileges is the ttylogin dæmon, because (of course) it runs login
.
Everything else — the BRLTTY dæmon, the multiplexor, and the terminal emulator dæmon — should and does run as unprivileged users.