On Wed, Jan 04, 2023 at 08:08:48PM +0100, Paul de Weerd wrote:
> On Wed, Jan 04, 2023 at 02:33:57PM -0300, Crystal Kolipe wrote:
> | On Wed, Jan 04, 2023 at 04:42:55PM +0100, Paul de Weerd wrote:
> | > 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.
> | 
> | Great!  Thanks for testing :).
> | 
> | > The latter, however, shows
> | > '^@^@' before the PS1 prompt upon starting a new session (`tmux new`),
> | > behavior I don't see with a 'real' xterm.
> | 
> | This looks like an off-by-one in the wscons code, (not introduced by me!)
> | 
> | Does the following patch, (on top of the last one), fix it?
> 
> Fixes only half of it: we're down to one ^@ now (which is not fixed
> with a s/1/2/ in your below diff).

Interestingly, I haven't been able to reproduce this, and when I tested it
originally I was only ever seeing one ^@, which was fixed by the previous
patch.

However, there is another similar off-by-one nearby, which I strongly suspect
is the culprit as fixing it makes the output of 'ESC [ c' more closely match
what a real xterm does.

I'm sending the complete diff again as anybody else testing the version from
this morning will definitely want these two new fixes.  So back-out the
previous mini-patch and the main one before applying this.

Hopefully it'll fix the problem.

--- 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 16:46:43 2023
@@ -231,7 +231,7 @@
        switch (A3(edp->modif1, edp->modif2, c)) {
        case A3('>', '\0', 'c'): /* DA secondary */
                wsdisplay_emulinput(edp->cbcookie, WSEMUL_VT_ID2,
-                   sizeof(WSEMUL_VT_ID2));
+                   sizeof(WSEMUL_VT_ID2)-1);
                break;
 
        case A3('\0', '\0', 'J'): /* ED selective erase in display */
@@ -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));
+                           sizeof(WSEMUL_VT_ID1)-1);
                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,
--- 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;
 }

Reply via email to