The following patch adds five escape sequences to the wscons vt100 emulation.
It's one part of a larger set of patches I am working on to make the console more like xterm. Note: Casual readers of -tech and those not familar with terminfo might prefer to read my write-up at https://research.exoticsilicon.com/articles/terminal_emulations Why do we want this? Currently the console emulates a superset of a subset of vt220 features. In other words, it supports most common vt220 sequences and a few additional sequences to do things like set colours, (which a real vt220 doesn't support). The problem is that since the terminal emulation has to default to something that is universally recognised, it's set by default to vt220, (in /etc/ttys). This means that none of these 'extra' features are available to curses-based programs running on the console, unless the user manually fiddles with the terminal type. The terminfo file has long included 'pccon', which claims to support the OpenBSD console, but this entry has numerous issues such as: * Simultaneous use of colour and underline is disabled, even though the framebuffer console supports it, (presumably because the VGA console does not). * The op entry is hard coded to set black text on a white background instead of resetting the terminal to it's default colours. This causes, for example, the mutt email client to exit with the terminal inverted, (black text on a white background). * It doesn't include support for civis or cnorm, (to hide/restore the cursor), even though both the framebuffer console and the VGA console support it. Even using the vt220 entry as is currently done causes some issues beyond lack of colour: * F1-F4 are not recognised as they send different sequences to what the vt220 entry expects. * Also doesn't include civis or cnorm. Fixing up the pccon entry is not feasible, as it would take many years for an updated version to appear on a sufficient number of systems for it to be suitable as a default in /etc/ttys. The solution: If wscons can be made to work adequately with the existing xterm entry in the terminfo file, then xterm could eventually become the default terminal emulation. In 2023, the xterm emulation should be almost as universally accepted as vt220, and allows for many more features such as colour. Currently, setting TERM=xterm in the console and starting any curses-based program will quickly show a lot of breakage. Comparing the terminfo entries for vt220 and xterm, the most obvious functions that are missing from the vt220 entry and which are not currently supported by wscons are: Sequence Equivalent to termcap Description CSI x T rin scroll back x lines CSI x S indn scroll forward x lines CSI x d vpa go to line x CSI x G hpa go to column x CSI Z cbt reverse horizontal tab (Note: indices are 1-based and not 0-based.) These are the five functions implemented by the attached patch. Already, just enabling these functions makes a lot of curses programs run fine on the console - in colour - with TERM set to xterm. This patch is very unintrusive, and it's hard to see how it could break anything. It also allows for more widespread testing with TERM=xterm to find out what works and what doesn't, and any odd corner cases. Beyond this, things become slightly more complicated for several reasons: 1. Xterm implements some features such as dim text, strikethrough, double underline, and italics, which wscons doesn't yet support. I have code to implement the first three in rasops32, but didn't make that part of this diff to keep things simple. 2. Xterm implements blinking text, which would require a lot of changes to implement on the framebuffer console. Should blinking text be represented in another way, (boxout? overline? drop shadow?) 3. To make the F1-F4 keys be recognised by the xterm termcap entry requires either changing the sequences they send in wsemul_vt100_keys.c, or changing the various keymaps in wskbdmap_mfii.c to use KS_KP_F1 - KS_KP_F4 instead of KS_f1 - KS_f4. These keys currently do NOT work by default anyway, as the vt220 termcap entry also requires the same change(!), however it would break pccon, which does correctly include the sequences that wscons currently generates. A similar situation exists for F13 - F24, home, and end. The keypad +, -, *, and / keys do currently work with vt220, but break using the xterm entry, (but only for programs that use them via termcap, obviously). Overall, the potential for breakage with this first patch is very small and even with the proposed future changes, should only affect people who are using a non-default configuration, or programs that rely on the terminfo description of the four previously mentioned numeric keypad keys. The potential advantages of this current proposed patch as a first step towards a change to xterm are: * No breakage for anybody using the default vt220 terminfo entry, (or pccons). * Easy to test the new functionality by setting TERM=xterm. * The xterm target is very widely supported already and has been for a long time. * Eventually xterm could become the default, and curses-based programs will 'just work'. Comments? Feedback? Do other people even care about this?
--- dev/wscons/wsemul_vt100_subr.c.dist Mon May 25 06:55:49 2020 +++ dev/wscons/wsemul_vt100_subr.c Sat Dec 31 20:29:19 2022 @@ -461,6 +461,9 @@ edp->ccol -= min(DEF1_ARG(0), edp->ccol); edp->flags &= ~VTFL_LASTCHAR; break; + case 'G': /* Go to absolute column */ + edp->ccol = min(DEF1_ARG(0)-1, edp->ncols-1); + break; case 'H': /* CUP */ case 'f': /* HVP */ if (edp->flags & VTFL_DECOM) @@ -502,15 +505,36 @@ WSEMULOP(rc, edp, &edp->abortstate, erasecols, ERASECOLS(NCOLS - n, n, edp->bkgdattr)); break; + case 'S': /* Scroll forwards X lines */ + wsemul_vt100_scrollup (edp,DEF1_ARG(0)); + break; + case 'T': /* Scroll backwards X lines */ + wsemul_vt100_scrolldown (edp,DEF1_ARG(0)); + break; case 'X': /* ECH erase character */ n = min(DEF1_ARG(0), COLS_LEFT + 1); WSEMULOP(rc, edp, &edp->abortstate, erasecols, ERASECOLS(edp->ccol, n, edp->bkgdattr)); break; + case 'Z': /* Reverse TAB */ + if (!edp->ccol) + break; + if (edp->tabs) { + for (n=edp->ccol-1 ; n>0; n--) + if (edp->tabs[n]) + break; + } else { + n=((edp->ccol - 1) & 8); + } + edp->ccol=n; + break; case 'c': /* DA primary */ if (ARG(0) == 0) wsdisplay_emulinput(edp->cbcookie, WSEMUL_VT_ID1, sizeof(WSEMUL_VT_ID1)); + break; + case 'd': /* Go to absolute row */ + edp->crow = min(DEF1_ARG(0)-1, edp->nrows-1); break; case 'g': /* TBC */ if (edp->tabs != NULL)