# Terminals and `TERM`

With the wrong environment settings, programs can't properly control
your terminal. It is critical that the `TERM` environment variable be
correct for your shell, and that the terminfo database entry keyed
by this variable be up-to-date. Furthermore, for 24-bit TrueColor, it
is necessary to either use a `-direct` variant of your terminfo
entry, or to declare `COLORTERM=24bit`. The latter instruct Notcurses
to use 24-bit escapes regardless of advertised support. If you define
this variable, and your terminal doesn't actually support these sequences,
you're going to have a bad time.

The following have been established on a Debian Unstable workstation.

| Terminal | `ccc` | Recommended environment | Notes |
| -------- | ----- | ------ | ----- |
| Linux console | ✔ | `TERM=linux` `COLORTERM=24bit` | 8 (512 glyph fonts) or 16 (256 glyph fonts) colors max, but RGB values are downsampled to a 256-index palette. See below. |
| FBterm | | `TERM=fbterm` | 256 colors, no RGB color. |
| kmscon | | `TERM=xterm-256color` | No RGB color AFAICT, nor any distinct terminfo entry. |
| XTerm | | `TERM=xterm-256color` `COLORTERM=24bit` | Must configure with `--enable-direct-color`. `TERM=xterm-direct` seems to have the undesirable effect of mapping low RGB values to a palette; I don't yet understand this well. The problem is not seen with the specified configuration. Sixel support when built with `--enable-sixel-graphics` and run in vt340 mode. |
| XFCE4 Terminal | ✔ | `TERM=xfce` `COLORTERM=24bit` | No `xfce-direct` variant exists. |
| Gnome Terminal | 🗴 | `TERM=gnome` `COLORTERM=24bit` | `ccc` support *is* available when run with `vte-256color`. |
| Konsole | 🗴 | `TERM=konsole-direct` | |
| Alacritty | ✔ | `TERM=alacritty` `COLORTERM=24bit` | |
| Kitty | ✔ |`TERM=kitty-direct` | |
| Sakura | ✔ |`TERM=vte-256color` `COLORTERM=24bit` | No terminfo entry? |
| mlterm | 🗴 |`TERM=mlterm-256color` | Do not set `COLORTERM`. `mlterm-direct` gives strange results. |
| st | ✔ |`TERM=st-256color` `COLORTERM=24bit` | |
| GNU Screen | 🗴 |`TERM=screen.OLDTERM` | Must be compiled with `--enable-256color`. `TERM` should typically be `screen.` suffixed by the appropriate `TERM` value for the true connected terminal, e.g. `screen.vte-256color`. See below. |
| tmux | | | |

Note that `xfce4-terminal`, `gnome-terminal`, etc. are all skinning atop the
common VTE ("Virtual TErminal") library.

## GNU screen

GNU screen does have 24-bit color support, but only in the 5.X series. Note
that many distributions ship screen 4.X as of 2020. When built with truecolor
support, add `truecolor on` to your `screenrc`, or run it with `--truecolor`.
Attempting to force RGB color in screen 4.X **will not work**.

Add `defutf8 on` to your `screenrc`, or run screen with `-U`, to ensure UTF-8.

## The Linux console

The Linux console supports concurrent virtual terminals, and is manipulated
by userspace via `ioctl()`s. These `ioctl()`s generally fail when applied to
a pseudotty device, as will happen if e.g. invoked upon one's controlling
terminal whilst running in a terminal emulator under X (it is still generally
possible to use them by explicitly specifying a console device, i.e.
`showconsolefont -C /dev/tty0`).

The VGA text console requires the kernel option `CONFIG_VGA_CONSOLE`. A
framebuffer console for VESA 2.0 is provided by `CONFIG_FB_VESA`, while
UEFI-compatible systems can use `CONFIG_FB_EFI`. So long as a framebuffer
driver is present, `CONFIG_FRAMEBUFFER_CONSOLE` will enable a graphics-mode
console using the framebuffer device.

The Linux console can be in either text or graphics mode. The mode can be
determined with the `KDGETMODE` `ioctl()`, and changed with `KDSETMODE`,
using the constants `KD_TEXT` and `KD_GRAPHICS`. Text mode supports a
rectangular matrix of multipixel cells, filled with glyphs from a font,
a foreground color, and a background color. Graphics ("All-Points-Addressable")
mode supports a rectangular matrix of pixels, each with a single color.
Note that both modes require appropriate hardware support (and kernel
configuration options), and might or might not be available on a given
installation. Non-x86 platforms often provide only a framebuffer (graphics)
console.

The kernel text mode loosely corresponds to the 1987 IBM VGA definition. At any
time, the display is configured with a monospace raster font, a palette, and
(when in Unicode mode) a mapping from multibyte sequences to font elements. Up
to 16 colors can be used with a font of 256 glyphs or fewer. Only 8 colors can
be used with fonts having more than 256 glyphs; the maximum font size in any
configuration is 512 glyphs. The keyboard is further configured with a keymap,
mapping keyboard scancodes to elements of the character set. These properties
are per-virtual console, not common to all of them. These limitations are not
typically present on framebuffer consoles.

Exporting `COLORTERM=24bit` and emitting RGB escapes to the Linux console
**does** work, though the RGB values provided are downsampled to a 256-slot
palette. Backgrounds don't seem to have the same degree of flexibility in this
situation as do foregrounds. The output is better, but not as much better as
one might expect. More research is necessary here.

The following more-or-less standard tools exist:
* `showconsolefont`: show the console font
* `setfont`: load console font
* `fbset`: show and modify framebuffer settings
* `fgconsole`: print name of foreground terminal
* `chvt`: change the foreground terminal
* `deallocvt`: destroy a virtual console
* `dumpkeys`: print all keycodes
* `loadkeys`: load scancode/keycode mapping (the keymap)
* `setkeycodes`: load scancode/keycode mappings one at a time
* `showkeys`: interactively print scancodes
* `kbd_mode`: show or set the keyboard mode

Both `mapscrn` and `loadunimap` are obsolete; their functionality is present
in `setfont`.
