Another update to the console enhancement patchset.

Some of the code from previous versions is now in -current, but if you want
the full experience, (256 colours, extra text attributes, etc), you'll still
need to apply the following diff.

This is against -current as of an hour or so ago.

NEW - Rasops code converted to use WSATTR bit assignments directly instead of
      moving the underline flag to bit 0.

NEW - Support for 256 colours on 16bpp framebuffers.

NEW - Byteswapped framebuffers should now work properly with 256 colours.

--- 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.current      Fri Jan 13 13:12:01 2023
+++ dev/wscons/wsemul_vt100_subr.c      Fri Jan 13 13:32:04 2023
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsemul_vt100_subr.c,v 1.29 2023/01/12 20:39:37 nicm Exp $ */
+/* $OpenBSD:  Exp $ */
 /* $NetBSD: wsemul_vt100_subr.c,v 1.7 2000/04/28 21:56:16 mycroft Exp $ */
 
 /*
@@ -588,6 +588,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;
@@ -597,11 +603,31 @@
                        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;
@@ -609,12 +635,76 @@
                        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:
                                /* fg color */
                                flags |= WSATTR_WSCOLORS;
                                fgcol = ARG(n) - 30;
                                break;
+                       /*
+                        * Sequences starting CSI 38 escape to a larger
+                        * colourspace, typically either 256 colours or 24-bit.
+                        *
+                        * We support CSI 38;5;X;m to set colour X from a
+                        * palette of 256.
+                        */
+#define EXIST_ARG2(i) ((edp->nargs-n)>=3)
+#define ARG2_OR_DEF(i) (EXIST_ARG2(i) ? ARG(i+2) : 0)
+                       case 38:
+                               /*
+                                * 38 followed by zero arguments is meaningless.
+                                */
+                               if (edp->nargs == n+1) {
+                                       break ;
+                               }
+                               /*
+                                * 5 should normally be followed by a single
+                                * argument, but zero arguments is also valid to
+                                * set colour zero.
+                                */
+                               if (ARG(n+1)==5) {
+                                       flags |= WSATTR_WSCOLORS;
+                                       if (edp->scrcapabilities &
+                                           WSSCREEN_256COL) {
+                                               fgcol = ARG2_OR_DEF(n);
+                                               } else {
+                                               fgcol = (ARG2_OR_DEF(n) < 8 ? 
ARG2_OR_DEF(n)
+                                                   : fgcol );
+                                               }
+                                       n+=(EXIST_ARG2(n) ? 2 : 1);
+                                       break;
+                               }
+                               /*
+                                * 2 should introduce a sequence of three
+                                * arguments, specifying RGB.
+                                *
+                                * We don't, (yet!), support setting colours by
+                                * 24-bit RGB arguments and don't want to
+                                * interpret these as regular SGR codes.
+                                *
+                                * If there are more then three, skip just
+                                * three, otherwise skip all of them.
+                                */
+                               if (ARG(n+1)==2) {
+                                       n=(edp->nargs-n > 5 ? n+4 :
+                                           edp->nargs);
+                                       break;
+                               }
+                               /*
+                                * Invalid code, I.E. not 2 or 5.
+                                *
+                                * We do what xterm does and just skip the
+                                * single unrecognised argument, then allow any
+                                * following arguments to be interpreted as SGR.
+                                */
+                               n++;
+                               break;
                        case 39:
                                /* reset fg color */
                                fgcol = WSCOL_WHITE;
@@ -627,6 +717,29 @@
                                flags |= WSATTR_WSCOLORS;
                                bgcol = ARG(n) - 40;
                                break;
+                       case 48: /* set 8-bit background colour */
+                               if (edp->nargs == n+1) {
+                                       break ;
+                               }
+                               if (ARG(n+1)==5) {
+                                       flags |= WSATTR_WSCOLORS;
+                                       if (edp->scrcapabilities &
+                                           WSSCREEN_256COL) {
+                                               bgcol = ARG2_OR_DEF(n);
+                                               } else {
+                                               bgcol = (ARG2_OR_DEF(n) < 8 ? 
ARG2_OR_DEF(n)
+                                                   : bgcol );
+                                               }
+                                       n+=(EXIST_ARG2(n) ? 2 : 1);
+                                       break;
+                               }
+                               if (ARG(n+1)==2) {
+                                       n=(edp->nargs-n > 5 ? n+4 :
+                                           edp->nargs);
+                                       break;
+                               }
+                               n++;
+                               break;
                        case 49:
                                /* reset bg color */
                                bgcol = WSCOL_BLACK;
@@ -635,13 +748,13 @@
                                break;
                        case 90: case 91: case 92: case 93:
                        case 94: case 95: case 96: case 97:
-                               /* bright foreground color */
+                               /* bright foreground colour */
                                flags |= WSATTR_WSCOLORS;
                                fgcol = ARG(n) - 82;
                                break;
                        case 100: case 101: case 102: case 103:
                        case 104: case 105: case 106: case 107:
-                               /* bright background color */
+                               /* bright background colour */
                                flags |= WSATTR_WSCOLORS;
                                bgcol = ARG(n) - 92;
                                break;
--- 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   Fri Jan  6 20:09:43 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
@@ -114,6 +119,7 @@
 #define WSSCREEN_HILIT         4       /* can highlight (however) */
 #define WSSCREEN_BLINK         8       /* can blink */
 #define WSSCREEN_UNDERLINE     16      /* can underline */
+#define WSSCREEN_256COL                32      /* supports 256 colours */
 };
 
 /*
--- dev/wscons/wsconsio.h.dist  Fri Jul 15 14:57:27 2022
+++ dev/wscons/wsconsio.h       Mon Jan  9 14:45:11 2023
@@ -536,6 +536,7 @@
 #define        WSDISPLAY_FONTORDER_R2L         2
        void *cookie;
        void *data;
+       void *data_bold;
 };
 #define WSDISPLAYIO_LDFONT     _IOW ('W', 77, struct wsdisplay_font)
 #define        WSDISPLAYIO_LSFONT      _IOWR('W', 78, struct wsdisplay_font)
--- dev/wsfont/wsfont.c.dist    Mon Apr  4 16:53:15 2022
+++ dev/wsfont/wsfont.c Fri Jan 13 13:33:16 2023
@@ -586,6 +586,19 @@
 
                lc = ++ent->lockcount;
                *ptr = ent->font;
+
+               /* Create a bold version of the font */
+#define FONT_DATA ((*ptr)->data)
+#define FONT_DATA_BOLD ((*ptr)->data_bold)
+#define FONT_BYTES_PER_GLYPH (((*ptr)->stride) * (((*ptr)->fontheight)))
+#define FONT_DATA_LEN FONT_BYTES_PER_GLYPH * ((*ptr)->numchars) 
+               (*ptr)->data_bold=malloc(FONT_DATA_LEN, M_TEMP, M_WAITOK);
+               int i;
+               for (i=0; i < FONT_DATA_LEN ; i++) {
+                       *(unsigned char *)(FONT_DATA_BOLD + i) =
+                           *(unsigned char *)(FONT_DATA + i) |
+                           (*(unsigned char *)(FONT_DATA + i) >> 1) ;
+               }
        } else
                lc = -1;
 
@@ -600,6 +613,7 @@
 wsfont_unlock(int cookie)
 {
        struct font *ent;
+       struct wsdisplay_font *ptr;
        int s, lc;
 
        s = splhigh();
@@ -607,6 +621,8 @@
        if ((ent = wsfont_find0(cookie)) != NULL) {
                if (ent->lockcount == 0)
                        panic("wsfont_unlock: font not locked");
+               ptr = ent->font;
+               free (ptr->data_bold, M_TEMP, 0);
                lc = --ent->lockcount;
        } else
                lc = -1;
--- 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.current Thu Jan 12 16:01:07 2023
+++ dev/rasops/rasops.c Fri Jan 13 12:52:21 2023
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rasops.c,v 1.68 2023/01/12 12:28:08 nicm Exp $        */
+/*     $OpenBSD: rasops.c                                  Exp $       */
 /*     $NetBSD: rasops.c,v 1.35 2001/02/02 06:01:01 marcus Exp $       */
 
 /*-
@@ -133,7 +133,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 */
 };
@@ -446,6 +446,10 @@
                    WSSCREEN_WSCOLORS | WSSCREEN_REVERSE;
        }
 
+       if (ri->ri_depth == 32 || ri->ri_depth==16) {
+               ri->ri_caps |= WSSCREEN_256COL ;
+       }
+
        switch (ri->ri_depth) {
 #if NRASOPS1 > 0
        case 1:
@@ -557,13 +561,7 @@
                bg = swap;
        }
 
-       /* Bold is only supported for ANSI colors 0 - 7. */
-       if ((flg & WSATTR_HILIT) != 0 && fg < 8)
-               fg += 8;
-
-       flg = ((flg & WSATTR_UNDERLINE) ? 1 : 0);
-
-       *attr = (bg << 16) | (fg << 24) | flg;
+       *attr = (bg << 16) | (fg << 24) | (flg & 0xffff);
        return (0);
 }
 
@@ -587,7 +585,7 @@
                bg = swap;
        }
 
-       *attr = (bg << 16) | (fg << 24) | ((flg & WSATTR_UNDERLINE) ? 7 : 6);
+       *attr = (bg << 16) | (fg << 24) | (flg & 0xffff);
        return (0);
 }
 
@@ -869,6 +867,24 @@
                ri->ri_devcmap[i] = c;
 #endif
        }
+       /* Re-define colours 16-255 if we are running in 32bpp */
+       #define EBCOL_BLUE(x) ((48*((x-16)%6) >> (8 - ri->ri_bnum)) << 
ri->ri_bpos)
+       #define EBCOL_GREEN(x) (((48*(((x-16)/6)%6)) >> (8 - ri->ri_gnum)) << 
ri->ri_gpos)
+       #define EBCOL_RED(x) (((48*(((x-16)/36)%6)) >> (8 - ri->ri_rnum)) << 
ri->ri_rpos)
+       #define EBCOL(x) EBCOL_RED(x) | EBCOL_GREEN(x) | EBCOL_BLUE(x)
+       #define EBGREY_CHANNEL(x) (int)(1+((i-232)*11))
+       #define EBGREY_R(x)(( EBGREY_CHANNEL(x) >> (8 - ri->ri_rnum)) << 
ri->ri_rpos)
+       #define EBGREY_G(x)(( EBGREY_CHANNEL(x) >> (8 - ri->ri_gnum)) << 
ri->ri_gpos)
+       #define EBGREY_B(x)(( EBGREY_CHANNEL(x) >> (8 - ri->ri_bnum)) << 
ri->ri_bpos)
+       #define EBGREY(x) EBGREY_R(x) | EBGREY_G(x) | EBGREY_B(x)
+       if (ri->ri_depth == 32 || ri->ri_depth==16) {
+               for (i=16 ; i<256; i++) {
+                       c = (i < 232 ? EBCOL(i) : EBGREY(i));
+                       if (ri->ri_flg & RI_BSWAP)
+                               c = (ri->ri_depth==16 ? swap16(c) : swap32(c));
+                       ri->ri_devcmap[i] = c;
+               }
+       }
 #endif
 }
 
@@ -878,10 +894,10 @@
 void
 rasops_unpack_attr(void *cookie, uint32_t attr, int *fg, int *bg, int 
*underline)
 {
-       *fg = ((u_int)attr >> 24) & 0xf;
-       *bg = ((u_int)attr >> 16) & 0xf;
+       *fg = ((u_int)attr >> 24) & 0xff;
+       *bg = ((u_int)attr >> 16) & 0xff;
        if (underline != NULL)
-               *underline = (u_int)attr & 1;
+               *underline = (u_int)attr & WSATTR_UNDERLINE;
 }
 
 /*
@@ -909,7 +925,7 @@
                return 0;
 #endif
 
-       clr = ri->ri_devcmap[(attr >> 16) & 0xf];
+       clr = ri->ri_devcmap[(attr >> 16) & 0xff];
 
        /*
         * XXX The wsdisplay_emulops interface seems a little deficient in
@@ -1063,7 +1079,7 @@
        num = num * ri->ri_xscale;
        rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
        height = ri->ri_font->fontheight;
-       clr = ri->ri_devcmap[(attr >> 16) & 0xf];
+       clr = ri->ri_devcmap[(attr >> 16) & 0xff];
 
        /* Don't bother using the full loop for <= 32 pels */
        if (num <= 32) {
@@ -1251,8 +1267,19 @@
        else
                col = ri->ri_cols - col - 1;
 
-       /* Do rotated char sans (side)underline */
-       rc = ri->ri_real_ops.putchar(cookie, col, row, uc, attr & ~1);
+       /*
+        * For rotated characters, attributes such as underline and double
+        * underline need to be painted in a different way.  The generic putchar
+        * routines know nothing about this, so we clear the corresponding bits
+        * of attr before calling putchar, then deal with painting the
+        * missing attributes the required custom way here instead.
+        *
+        * Not all attributes are affected.  Dim can be passed through and
+        * handled as normal by putchar, since the placement of individual
+        * pixels does not change the way that the effect is applied.
+        */
+#define BITMASK_UNSAFE_FOR_ROTATION (WSATTR_UNDERLINE | 
WSATTR_DOUBLE_UNDERLINE | WSATTR_STRIKE | WSATTR_ITALIC)
+       rc = ri->ri_real_ops.putchar(cookie, col, row, uc, attr & 
~(BITMASK_UNSAFE_FOR_ROTATION));
        if (rc != 0)
                return rc;
 
@@ -1263,8 +1290,8 @@
        height = ri->ri_font->fontheight;
 
        /* XXX this assumes 16-bit color depth */
-       if ((attr & 1) != 0) {
-               int16_t c = (int16_t)ri->ri_devcmap[((u_int)attr >> 24) & 0xf];
+       if ((attr & WSATTR_UNDERLINE) != 0) {
+               int16_t c = (int16_t)ri->ri_devcmap[((u_int)attr >> 24) & 0xff];
 
                while (height--) {
                        *(int16_t *)rp = c;
@@ -1792,8 +1819,8 @@
        attr = ri->ri_bs[off].attr;
 
        if ((ri->ri_flg & RI_CURSOR) == 0) {
-               fg = ((u_int)attr >> 24) & 0xf;
-               bg = ((u_int)attr >> 16) & 0xf;
+               fg = ((u_int)attr >> 24) & 0xff;
+               bg = ((u_int)attr >> 16) & 0xff;
                attr &= ~0x0ffff0000;
                attr |= (fg << 16) | (bg << 24);
        }
--- dev/rasops/rasops.h.dist    Mon May 25 06:55:49 2020
+++ dev/rasops/rasops.h Sat Jan  7 14:48:34 2023
@@ -106,7 +106,7 @@
        u_char  *ri_origbits;   /* where screen bits actually start */
        int     ri_xorigin;     /* where ri_bits begins (x) */
        int     ri_yorigin;     /* where ri_bits begins (y) */
-       int32_t ri_devcmap[16]; /* color -> framebuffer data */
+       int32_t ri_devcmap[256]; /* color -> framebuffer data */
 
        /* The emulops you need to use, and the screen caps for wscons */
        struct  wsdisplay_emulops ri_ops;
--- dev/rasops/rasops32.c.dist  Mon Jul 20 09:40:45 2020
+++ dev/rasops/rasops32.c       Thu Jan 12 15:29:05 2023
@@ -91,13 +91,46 @@
        width = ri->ri_font->fontwidth;
        step = ri->ri_stride >> 3;
 
-       b = ri->ri_devcmap[(attr >> 16) & 0xf];
-       f = ri->ri_devcmap[(attr >> 24) & 0xf];
+       b = ri->ri_devcmap[(attr >> 16) & 0xff];
+       f = ri->ri_devcmap[(attr >> 24) & 0xff];
+
+       /*
+        * 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 byte-swapped BGR formats with exactly 8 bits per channel,
+        * I.E. 0xXXRRGGBB, and 0xBBGGRRXX.
+        *
+        * The unused byte is always set to 0x00 for 32bpp in
+        * rasops_init_devcmap, so will be unaffected by the shift.
+        *
+        * XXX If we ever support 32-bit devices that are not 8 bits per channel
+        * then this code will need to change.
+        */
+
+       if ((attr & WSATTR_DIM)!=0) {
+               f=(f>>1) & 0x7F7F7F7F;
+               }
+
        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 */
@@ -107,7 +140,7 @@
                }
        } else {
                uc -= ri->ri_font->firstchar;
-               fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+               fr = (attr & WSATTR_HILIT ? (u_char *)ri->ri_font->data_bold : 
(u_char *)ri->ri_font->data) + uc * ri->ri_fontscale;
                fs = ri->ri_font->stride;
 
                /* double-pixel special cases for the common widths */
@@ -202,12 +235,45 @@
                }
        }
 
+       /* Double underline relies on normal underlining being done as well. */
+
        /* Do underline a pixel at a time */
-       if ((attr & 1) != 0) {
+       if ((attr & (WSATTR_UNDERLINE | WSATTR_DOUBLE_UNDERLINE)) != 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 & WSATTR_UNDERLINE) != 0) {
+                       rp+=step ;
+                       }
+               rp -= (1+ri->ri_font->fontheight/2)*step;
+               for (cnt=0; cnt< width; cnt++)
+                       ((int *)rp)[cnt]=f;
+               }
 
        return 0;
 }
--- dev/rasops/rasops24.c.dist  Mon May 25 06:55:49 2020
+++ dev/rasops/rasops24.c       Wed Jan 11 19:56:17 2023
@@ -167,7 +167,7 @@
        }
 
        /* Do underline */
-       if ((attr & 1) != 0) {
+       if ((attr & WSATTR_UNDERLINE) != 0) {
                rp -= ri->ri_stride << 1;
 
                while (width--) {
@@ -288,7 +288,7 @@
        }
 
        /* Do underline */
-       if ((attr & 1) != 0) {
+       if ((attr & WSATTR_UNDERLINE) != 0) {
                int32_t c = STAMP_READ(52);
 
                DELTA(rp, -(ri->ri_stride << 1), int32_t *);
@@ -372,7 +372,7 @@
        }
 
        /* Do underline */
-       if ((attr & 1) != 0) {
+       if ((attr & WSATTR_UNDERLINE) != 0) {
                int32_t c = STAMP_READ(52);
 
                DELTA(rp, -(ri->ri_stride << 1), int32_t *);
@@ -463,7 +463,7 @@
        }
 
        /* Do underline */
-       if ((attr & 1) != 0) {
+       if ((attr & WSATTR_UNDERLINE) != 0) {
                int32_t c = STAMP_READ(52);
 
                DELTA(rp, -(ri->ri_stride << 1), int32_t *);
--- dev/rasops/rasops15.c.dist  Mon May 25 06:55:49 2020
+++ dev/rasops/rasops15.c       Fri Jan 13 06:50:19 2023
@@ -126,8 +126,8 @@
        height = ri->ri_font->fontheight;
        width = ri->ri_font->fontwidth;
 
-       clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 0xf];
-       clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 0xf];
+       clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 0xff];
+       clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 0xff];
 
        if (uc == ' ') {
                int16_t c = (int16_t)clr[0];
@@ -159,7 +159,7 @@
        }
 
        /* Do underline */
-       if ((attr & 1) != 0) {
+       if ((attr & WSATTR_UNDERLINE) != 0) {
                int16_t c = (int16_t)clr[1];
                rp -= ri->ri_stride << 1;
 
@@ -182,8 +182,8 @@
        int32_t fg, bg;
        int i;
 
-       fg = ri->ri_devcmap[((u_int)attr >> 24) & 0xf] & 0xffff;
-       bg = ri->ri_devcmap[((u_int)attr >> 16) & 0xf] & 0xffff;
+       fg = ri->ri_devcmap[((u_int)attr >> 24) & 0xff] & 0xffff;
+       bg = ri->ri_devcmap[((u_int)attr >> 16) & 0xff] & 0xffff;
        stamp_attr = attr;
 
        for (i = 0; i < 32; i += 2) {
@@ -265,7 +265,7 @@
        }
 
        /* Do underline */
-       if ((attr & 1) != 0) {
+       if ((attr & WSATTR_UNDERLINE) != 0) {
                int32_t c = STAMP_READ(28);
 
                DELTA(rp, -(ri->ri_stride << 1), int32_t *);
@@ -345,7 +345,7 @@
        }
 
        /* Do underline */
-       if (attr & 1) {
+       if (attr & WSATTR_UNDERLINE) {
                int32_t c = STAMP_READ(28);
 
                DELTA(rp, -(ri->ri_stride << 1), int32_t *);
@@ -430,7 +430,7 @@
        }
 
        /* Do underline */
-       if (attr & 1) {
+       if (attr & WSATTR_UNDERLINE) {
                int32_t c = STAMP_READ(28);
 
                DELTA(rp, -(ri->ri_stride << 1), int32_t *);
--- dev/rasops/rasops8.c.dist   Mon May 25 06:55:49 2020
+++ dev/rasops/rasops8.c        Wed Jan 11 20:05:07 2023
@@ -145,7 +145,7 @@
        }
 
        /* Do underline */
-       if ((attr & 1) != 0) {
+       if ((attr & WSATTR_UNDERLINE) != 0) {
                u_char c = clr[1];
 
                rp -= (ri->ri_stride << 1);
@@ -248,7 +248,7 @@
        }
 
        /* Do underline */
-       if ((attr & 1) != 0) {
+       if ((attr & WSATTR_UNDERLINE) != 0) {
                DELTA(rp, -(ri->ri_stride << 1), int32_t *);
                rp[0] = rp[1] = stamp[15];
        }
@@ -319,7 +319,7 @@
        }
 
        /* Do underline */
-       if ((attr & 1) != 0) {
+       if ((attr & WSATTR_UNDERLINE) != 0) {
                DELTA(rp, -(ri->ri_stride << 1), int32_t *);
                rp[0] = rp[1] = rp[2] = stamp[15];
        }
@@ -387,7 +387,7 @@
        }
 
        /* Do underline */
-       if ((attr & 1) != 0) {
+       if ((attr & WSATTR_UNDERLINE) != 0) {
                DELTA(rp, -(ri->ri_stride << 1), int32_t *);
                rp[0] = rp[1] = rp[2] = rp[3] = stamp[15];
        }
--- dev/rasops/rasops4.c.dist   Mon May 25 06:55:49 2020
+++ dev/rasops/rasops4.c        Wed Jan 11 20:06:11 2023
@@ -157,7 +157,7 @@
                }
 
                /* Do underline */
-               if (attr & 1) {
+               if (attr & WSATTR_UNDERLINE) {
                        DELTA(rp, -(ri->ri_stride << 1), int32_t *);
                        *rp = (*rp & lmask) | (fg & rmask);
                }
@@ -194,7 +194,7 @@
                }
 
                /* Do underline */
-               if (attr & 1) {
+               if (attr & WSATTR_UNDERLINE) {
                        DELTA(rp, -(ri->ri_stride << 1), int32_t *);
                        rp[0] = (rp[0] & lmask) | (fg & ~lmask);
                        rp[1] = (rp[1] & rmask) | (fg & ~rmask);
@@ -305,7 +305,7 @@
        }
 
        /* Do underline */
-       if ((attr & 1) != 0) {
+       if ((attr & WSATTR_UNDERLINE) != 0) {
                rp -= (rs << 1);
                rp[0] = stamp[15];
                rp[1] = stamp[15];
@@ -379,7 +379,7 @@
        }
 
        /* Do underline */
-       if ((attr & 1) != 0) {
+       if ((attr & WSATTR_UNDERLINE) != 0) {
                rp -= (rs << 1);
                rp[0] = stamp[15];
                rp[1] = stamp[15];
@@ -456,7 +456,7 @@
        }
 
        /* Do underline */
-       if ((attr & 1) != 0) {
+       if ((attr & WSATTR_UNDERLINE) != 0) {
                rp -= (rs << 1);
                rp[0] = stamp[15];
                rp[1] = stamp[15];
--- dev/rasops/rasops1.c.dist   Sat Jan  9 15:20:47 2021
+++ dev/rasops/rasops1.c        Wed Jan 11 20:16:42 2023
@@ -160,7 +160,7 @@
                }
 
                /* Do underline */
-               if ((attr & 1) != 0) {
+               if ((attr & WSATTR_UNDERLINE) != 0) {
                        DELTA(rp, -(ri->ri_stride << 1), int32_t *);
                        *rp = (*rp & lmask) | (fg & rmask);
                }
@@ -213,7 +213,7 @@
                }
 
                /* Do underline */
-               if ((attr & 1) != 0) {
+               if ((attr & WSATTR_UNDERLINE) != 0) {
                        DELTA(rp, -(ri->ri_stride << 1), int32_t *);
                        rp[0] = (rp[0] & lmask) | (fg & ~lmask);
                        rp[1] = (rp[1] & rmask) | (fg & ~rmask);
@@ -281,7 +281,7 @@
        }
 
        /* Do underline */
-       if ((attr & 1) != 0)
+       if ((attr & WSATTR_UNDERLINE) != 0)
                rp[-(ri->ri_stride << 1)] = fg;
 
        return 0;
@@ -345,7 +345,7 @@
        }
 
        /* Do underline */
-       if ((attr & 1) != 0)
+       if ((attr & WSATTR_UNDERLINE) != 0)
                *(int16_t *)(rp - (ri->ri_stride << 1)) = fg;
 
        return 0;

Reply via email to