Hi Crystal,
I tried your patch on my laptop. With it applied, and my TERM set to
'xterm', I do get colors in mutt and tmux. The latter, however, shows
'^@^@' before the PS1 prompt upon starting a new session (`tmux new`),
behavior I don't see with a 'real' xterm.
I like the idea, thanks for your work on this diff.
Paul
On Wed, Jan 04, 2023 at 10:42:56AM -0300, Crystal Kolipe wrote:
| Continuing the move towards xterm becoming the default termtype for the
| console...
|
| This third version of the patchset adds the following features. New features
| since the last version are highlighted first:
|
| NEW - Control sequences for dim text, invisible text, strike through, italic,
| and double underline attributes are now recognised and set flags in
| wscons.
|
| NEW - Rendering of dim, invisible, struck, and double underlined text is now
| supported in rasops32.c, so users of 32bpp displays will see these text
| effects on the console.
|
| NEW - The default number of scrollback screens has been increased from five to
| twenty.
|
| * F1 - F4 now send different sequences.
| * F13 - F24 now send different sequences, but see notes below about F13 - F16.
| * With numlock OFF, keypad 5 is now 'begin' rather than unused.
| * Home, End, keypad home, and keypad end now send different sequences.
| * A new keysym has been added - KS_Backtab.
| * Shift-TAB is now defined as KS_Backtab and sends ESC [ Z.
| * Shift-F1 - Shift-F12 now send F13 - F24.
| * Five new escape sequences added for cursor movement.
|
| Running with this patch, all of the curses-based programs that I use on a
| regular basis are working and usable with TERM=xterm.
|
| The overall experience is much improved over TERM=vt220, as we get colour.
|
| Even compared to pccon, we gain the ability to use colour together with
| underline, show and hide the cursor, and use backtab. We also gain the
| practicality of relying on a very widely and well supported terminal
| definition, (xterm), which could much more reasonably become the default than
| could pccon.
|
| Additionally, a small side benefit of changing the function key sequences from
| those expected by pccon to those expected by xterm is that any programs or
| scripts which ignore terminfo and are hard coded to work with xterm will now
| work on the console as well.
|
| --- dev/wscons/wsemul_vt100_keys.c.dist Sat Mar 14 00:38:50 2015
| +++ dev/wscons/wsemul_vt100_keys.c Mon Jan 2 16:01:42 2023
| @@ -37,11 +37,9 @@
| #include <dev/wscons/wsemulvar.h>
| #include <dev/wscons/wsemul_vt100var.h>
|
| +#define vt100_fkeys_len(x) (5+(x>=8)+(x>=12))
| +
| static const u_char *vt100_fkeys[] = {
| - "\033[11~", /* F1 */
| - "\033[12~",
| - "\033[13~", /* F1-F5 normally don't send codes */
| - "\033[14~",
| "\033[15~", /* F5 */
| "\033[17~", /* F6 */
| "\033[18~",
| @@ -50,18 +48,18 @@
| "\033[21~",
| "\033[23~", /* VT100: ESC */
| "\033[24~", /* VT100: BS */
| - "\033[25~", /* VT100: LF */
| - "\033[26~",
| - "\033[28~", /* help */
| - "\033[29~", /* do */
| - "\033[31~",
| - "\033[32~",
| - "\033[33~",
| - "\033[34~", /* F20 */
| - "\033[35~",
| - "\033[36~",
| - "\033[37~",
| - "\033[38~"
| + "\033[1;2P", /* VT100: LF */
| + "\033[1;2Q",
| + "\033[1;2R", /* help */
| + "\033[1;2S", /* do */
| + "\033[15;2~",
| + "\033[17;2~",
| + "\033[18;2~",
| + "\033[19;2~", /* F20 */
| + "\033[20;2~",
| + "\033[21;2~",
| + "\033[23;2~",
| + "\033[24;2~"
| };
|
| static const u_char *vt100_pfkeys[] = {
| @@ -96,14 +94,22 @@
| edp->translatebuf, edp->flags & VTFL_UTF8));
| }
|
| - if (in >= KS_f1 && in <= KS_f24) {
| - *out = vt100_fkeys[in - KS_f1];
| - return (5);
| + if (in >= KS_f1 && in <= KS_f4) {
| + *out = vt100_pfkeys[in - KS_f1];
| + return (3);
| }
| - if (in >= KS_F1 && in <= KS_F24) {
| - *out = vt100_fkeys[in - KS_F1];
| - return (5);
| + if (in >= KS_F1 && in <= KS_F4) {
| + *out = vt100_pfkeys[in - KS_F1];
| + return (3);
| }
| + if (in >= KS_f5 && in <= KS_f24) {
| + *out = vt100_fkeys[in - KS_f5];
| + return vt100_fkeys_len(in - KS_f5);
| + }
| + if (in >= KS_F5 && in <= KS_F24) {
| + *out = vt100_fkeys[in - KS_F5];
| + return vt100_fkeys_len(in - KS_F5);
| + }
| if (in >= KS_KP_F1 && in <= KS_KP_F4) {
| *out = vt100_pfkeys[in - KS_KP_F1];
| return (3);
| @@ -148,12 +154,12 @@
| }
| switch (in) {
| case KS_Help:
| - *out = vt100_fkeys[15 - 1];
| + *out = vt100_fkeys[15 - 1 + 4]; /* vt100_fkeys starts at F5 */
| return (5);
| case KS_Execute: /* "Do" */
| - *out = vt100_fkeys[16 - 1];
| + *out = vt100_fkeys[16 - 1 + 4]; /* vt100_fkeys starts at F5 */
| return (5);
| - case KS_Find:
| + case KS_Find: /* Not defined in xterm
terminfo */
| *out = "\033[1~";
| return (4);
| case KS_Insert:
| @@ -163,7 +169,7 @@
| case KS_KP_Delete:
| *out = "\033[3~";
| return (4);
| - case KS_Select:
| + case KS_Select: /* Not defined in xterm
terminfo */
| *out = "\033[4~";
| return (4);
| case KS_Prior:
| @@ -174,14 +180,27 @@
| case KS_KP_Next:
| *out = "\033[6~";
| return (4);
| + case KS_Backtab:
| + *out = "\033[Z";
| + return (3);
| + /*
| + * Unlike insert, delete, page up, and page down, we purposely don't
| + * send the same sequence of \033OE for the non-keypad 'begin' key.
| + *
| + * This is because the terminfo xterm entry is mapping this to kb2,
| + * which is defined as 'centre of keypad'.
| + */
| + case KS_KP_Begin:
| + *out = "\033OE";
| + return (3);
| case KS_Home:
| case KS_KP_Home:
| - *out = "\033[7~";
| - return (4);
| + *out = "\033OH";
| + return (3);
| case KS_End:
| case KS_KP_End:
| - *out = "\033[8~";
| - return (4);
| + *out = "\033OF";
| + return (3);
| case KS_Up:
| case KS_KP_Up:
| if (edp->flags & VTFL_APPLCURSOR)
| --- dev/wscons/wsemul_vt100_subr.c.dist Mon May 25 06:55:49 2020
| +++ dev/wscons/wsemul_vt100_subr.c Wed Jan 4 09:25:38 2023
| @@ -461,6 +461,9 @@
| edp->ccol -= min(DEF1_ARG(0), edp->ccol);
| edp->flags &= ~VTFL_LASTCHAR;
| break;
| + case 'G': /* HPA */
| + edp->ccol = min(DEF1_ARG(0)-1, edp->ncols-1);
| + break;
| case 'H': /* CUP */
| case 'f': /* HVP */
| if (edp->flags & VTFL_DECOM)
| @@ -502,16 +505,37 @@
| WSEMULOP(rc, edp, &edp->abortstate, erasecols,
| ERASECOLS(NCOLS - n, n, edp->bkgdattr));
| break;
| + case 'S': /* INDN */
| + wsemul_vt100_scrollup (edp,DEF1_ARG(0));
| + break;
| + case 'T': /* RIN */
| + 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': /* KCBT */
| + 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': /* VPA */
| + edp->crow = min(DEF1_ARG(0)-1, edp->nrows-1);
| + break;
| case 'g': /* TBC */
| if (edp->tabs != NULL)
| switch (ARG(0)) {
| @@ -549,6 +573,12 @@
| case 1: /* bold */
| flags |= WSATTR_HILIT;
| break;
| + case 2: /* dim */
| + flags |= WSATTR_DIM;
| + break;
| + case 3: /* italic */
| + flags |= WSATTR_ITALIC;
| + break;
| case 4: /* underline */
| flags |= WSATTR_UNDERLINE;
| break;
| @@ -558,17 +588,43 @@
| case 7: /* reverse */
| flags |= WSATTR_REVERSE;
| break;
| - case 22: /* ~bold VT300 only */
| + /*
| + * Invisible text only makes the _glyph_ invisible.
| + *
| + * Other active attributes such as underlining and
| + * strikeout are still displayed in the character cell.
| + */
| + case 8: /* invisible */
| + flags |= WSATTR_INVISIBLE;
| + break;
| + case 9: /* strike */
| + flags |= WSATTR_STRIKE;
| + break;
| + case 21: /* double underline */
| + flags |= WSATTR_DOUBLE_UNDERLINE;
| + break;
| + case 22: /* ~bold ~dim VT300 only */
| flags &= ~WSATTR_HILIT;
| + flags &= ~WSATTR_DIM;
| break;
| + case 23: /* ~italic */
| + flags &= WSATTR_ITALIC;
| + break;
| case 24: /* ~underline VT300 only */
| flags &= ~WSATTR_UNDERLINE;
| + flags &= ~WSATTR_DOUBLE_UNDERLINE;
| break;
| case 25: /* ~blink VT300 only */
| flags &= ~WSATTR_BLINK;
| break;
| case 27: /* ~reverse VT300 only */
| flags &= ~WSATTR_REVERSE;
| + break;
| + case 28: /* ~invisible */
| + flags &= ~WSATTR_INVISIBLE;
| + break;
| + case 29: /* ~strike */
| + flags &= ~WSATTR_STRIKE;
| break;
| case 30: case 31: case 32: case 33:
| case 34: case 35: case 36: case 37:
| --- dev/wscons/wsksymdef.h.dist Mon Sep 20 14:32:39 2021
| +++ dev/wscons/wsksymdef.h Mon Jan 2 15:48:18 2023
| @@ -626,6 +626,7 @@
| #define KS_Open 0xf393
| #define KS_Paste 0xf394
| #define KS_Cut 0xf395
| +#define KS_Backtab 0xf396
|
| #define KS_Menu 0xf3c0
| #define KS_Pause 0xf3c1
| --- dev/wscons/wsdisplayvar.h.dist Sun Sep 13 07:05:46 2020
| +++ dev/wscons/wsdisplayvar.h Wed Jan 4 09:24:12 2023
| @@ -94,11 +94,16 @@
| #define WSCOL_CYAN 6
| #define WSCOL_WHITE 7
| /* flag values: */
| -#define WSATTR_REVERSE 1
| -#define WSATTR_HILIT 2
| -#define WSATTR_BLINK 4
| -#define WSATTR_UNDERLINE 8
| -#define WSATTR_WSCOLORS 16
| +#define WSATTR_REVERSE 1
| +#define WSATTR_HILIT 2
| +#define WSATTR_BLINK 4
| +#define WSATTR_UNDERLINE 8
| +#define WSATTR_WSCOLORS 16
| +#define WSATTR_DIM 32
| +#define WSATTR_STRIKE 64
| +#define WSATTR_DOUBLE_UNDERLINE 128
| +#define WSATTR_INVISIBLE 256
| +#define WSATTR_ITALIC 512
| };
|
| #define WSSCREEN_NAME_SIZE 16
| --- dev/pckbc/wskbdmap_mfii.c.dist Sat May 1 13:11:16 2021
| +++ dev/pckbc/wskbdmap_mfii.c Mon Jan 2 13:51:12 2023
| @@ -59,7 +59,7 @@
| KC(12), KS_minus, KS_underscore,
| KC(13), KS_equal, KS_plus,
| KC(14), KS_Cmd_ResetEmul, KS_Delete,
| - KC(15), KS_Tab,
| + KC(15), KS_Tab, KS_Backtab,
| KC(16), KS_q,
| KC(17), KS_w,
| KC(18), KS_e,
| @@ -103,16 +103,16 @@
| KC(56), KS_Cmd2, KS_Alt_L,
| KC(57), KS_space,
| KC(58), KS_Caps_Lock,
| - KC(59), KS_Cmd_Screen0, KS_f1,
| - KC(60), KS_Cmd_Screen1, KS_f2,
| - KC(61), KS_Cmd_Screen2, KS_f3,
| - KC(62), KS_Cmd_Screen3, KS_f4,
| - KC(63), KS_Cmd_Screen4, KS_f5,
| - KC(64), KS_Cmd_Screen5, KS_f6,
| - KC(65), KS_Cmd_Screen6, KS_f7,
| - KC(66), KS_Cmd_Screen7, KS_f8,
| - KC(67), KS_Cmd_Screen8, KS_f9,
| - KC(68), KS_Cmd_Screen9, KS_f10,
| + KC(59), KS_Cmd_Screen0, KS_f1, KS_f13,
| + KC(60), KS_Cmd_Screen1, KS_f2, KS_f14,
| + KC(61), KS_Cmd_Screen2, KS_f3, KS_f15,
| + KC(62), KS_Cmd_Screen3, KS_f4, KS_f16,
| + KC(63), KS_Cmd_Screen4, KS_f5, KS_f17,
| + KC(64), KS_Cmd_Screen5, KS_f6, KS_f18,
| + KC(65), KS_Cmd_Screen6, KS_f7, KS_f19,
| + KC(66), KS_Cmd_Screen7, KS_f8, KS_f20,
| + KC(67), KS_Cmd_Screen8, KS_f9, KS_f21,
| + KC(68), KS_Cmd_Screen9, KS_f10, KS_f22,
| KC(69), KS_Num_Lock,
| KC(70), KS_Hold_Screen,
| KC(71), KS_KP_Home, KS_KP_7,
| @@ -128,8 +128,8 @@
| KC(81), KS_KP_Next, KS_KP_3,
| KC(82), KS_KP_Insert, KS_KP_0,
| KC(83), KS_KP_Delete, KS_KP_Decimal,
| - KC(87), KS_Cmd_Screen10, KS_f11,
| - KC(88), KS_Cmd_Screen11, KS_f12,
| + KC(87), KS_Cmd_Screen10, KS_f11, KS_f23,
| + KC(88), KS_Cmd_Screen11, KS_f12, KS_f24,
| KC(91), KS_f13,
| KC(92), KS_f14,
| KC(93), KS_f15,
| };
|
| #if !defined(WSKBD_NO_INTL_LAYOUTS)
| --- dev/rasops/rasops.c.dist Thu Jul 23 06:17:03 2020
| +++ dev/rasops/rasops.c Wed Jan 4 09:53:30 2023
| @@ -141,7 +141,7 @@
| uint32_t rs_defattr;
|
| int rs_sbscreens;
| -#define RS_SCROLLBACK_SCREENS 5
| +#define RS_SCROLLBACK_SCREENS 20
| int rs_dispoffset; /* rs_bs index, start of our actual screen */
| int rs_visibleoffset; /* rs_bs index, current scrollback screen */
| };
| @@ -568,7 +568,19 @@
| if ((flg & WSATTR_HILIT) != 0)
| fg += 8;
|
| - flg = ((flg & WSATTR_UNDERLINE) ? 1 : 0);
| + /*
| + * The rapops code expects a different layout of the bitfields in flg:
| + *
| + * WSATTR_UNDERLINE is moved to bit 0
| + * Bits 1 and 2 are re-purposed to indicate whether the foreground and
| + * background are grey or not, (I.E. red==green==blue).
| + *
| + * This was probably a convenient hack when we only had to deal with
| + * underlining, but further attributes should maintain their original
| + * bit positions for consistency between the wscons and rasops code.
| + */
| +
| + flg = ((flg & 0xfff8) | (flg & WSATTR_UNDERLINE ? 1 : 0));
|
| if (rasops_isgray[fg])
| flg |= 2;
| --- dev/rasops/rasops32.c.dist Mon Jul 20 09:40:45 2020
| +++ dev/rasops/rasops32.c Wed Jan 4 09:22:07 2023
| @@ -93,11 +93,40 @@
|
| b = ri->ri_devcmap[(attr >> 16) & 0xf];
| f = ri->ri_devcmap[(attr >> 24) & 0xf];
| +
| + /*
| + * Implement dim by shifting each of the red, green and blue values by
one bit.
| + *
| + * Since we are shifting each channel equally, this works for both RGB
and BGR as
| + * long as the values are stored in the lower 24 bits.
| + *
| + * XXX should we shift the upper 8 bits as well, to support devices
that work in
| + * 0xRRGGBBXX and 0xBBGGRRXX formats? Or will that break devices that
expect a
| + * special value in the high byte?
| + */
| +
| + if ((attr & WSATTR_DIM)!=0) {
| + f=(f>>1) & 0x007F7F7F;
| + }
| +
| u.d[0][0] = b; u.d[0][1] = b;
| u.d[1][0] = b; u.d[1][1] = f;
| u.d[2][0] = f; u.d[2][1] = b;
| u.d[3][0] = f; u.d[3][1] = f;
|
| + /*
| + * Implement 'invisible' attribute by changing the character to a space.
| + *
| + * We need to do this rather than just ignoring the character or filling
| + * the bits with 0x00 and returning as a special case, because effects
| + * such as underline and strikethrough are still rendered on invisible
| + * characters, (at least they are in xterm).
| + */
| +
| + if ((attr & WSATTR_INVISIBLE)!=0) {
| + uc=' ';
| + }
| +
| if (uc == ' ') {
| while (height--) {
| /* the general, pixel-at-a-time case is fast enough */
| @@ -202,12 +231,44 @@
| }
| }
|
| + /* Double underline relies on normal underlining being done as well. */
| +
| /* Do underline a pixel at a time */
| - if ((attr & 1) != 0) {
| + if ((attr & (WSATTR_DOUBLE_UNDERLINE | 1)) != 0) {
| rp -= step;
| for (cnt = 0; cnt < width; cnt++)
| ((int *)rp)[cnt] = f;
| }
| +
| + /*
| + * Double underline now just needs to paint the second underline two
| + * rows up. */
| +
| + if ((attr & WSATTR_DOUBLE_UNDERLINE)!=0) {
| + rp-=(step << 1);
| + for (cnt=0; cnt< width; cnt++)
| + ((int *)rp)[cnt]=f;
| + /*
| + * Reset row pointer to ensure that strikethough appears at a
| + * consistent height if combined with double underlining.
| + */
| +
| + rp+=(step << 1);
| + }
| +
| + /*
| + * Reset pointer to ensure that strikethough appears at a consistent
| + * height if combined with single underlining.
| + */
| +
| + if ((attr & WSATTR_STRIKE)!=0) {
| + if ((attr & 1)==1) {
| + rp+=step ;
| + }
| + rp -= (1+ri->ri_font->fontheight/2)*step;
| + for (cnt=0; cnt< width; cnt++)
| + ((int *)rp)[cnt]=f;
| + }
|
| return 0;
| }
|
--
>++++++++[<++++++++++>-]<+++++++.>+++[<------>-]<.>+++[<+
+++++++++++>-]<.>++[<------------>-]<+.--------------.[-]
http://www.weirdnet.nl/