I've separated out the 256 colour code from the rest of my console enhancement
patchset, because it seems that the bold and italic code was causing some
problems that I haven't yet fully resolved.

Also, various bits from the previous mega-patch are now in cvs, so it no
longer applies cleanly.

Index: rasops/rasops.c
===================================================================
RCS file: /cvs/src/sys/dev/rasops/rasops.c,v
retrieving revision 1.69
diff -u -p -r1.69 rasops.c
--- rasops/rasops.c     18 Jan 2023 11:08:49 -0000      1.69
+++ rasops/rasops.c     30 Jan 2023 09:08:22 -0000
@@ -446,6 +446,10 @@ rasops_reconfig(struct rasops_info *ri, 
                    WSSCREEN_WSCOLORS | WSSCREEN_REVERSE;
        }
 
+       if (ri->ri_depth == 32) {
+               ri->ri_caps |= WSSCREEN_256COL ;
+       }
+
        switch (ri->ri_depth) {
 #if NRASOPS1 > 0
        case 1:
@@ -561,7 +565,7 @@ rasops_pack_cattr(void *cookie, int fg, 
        if ((flg & WSATTR_HILIT) != 0 && fg < 8)
                fg += 8;
 
-       *attr = (bg << 16) | (fg << 24) | (flg & WSATTR_UNDERLINE);
+       *attr = (bg << 16) | (fg << 24) | flg;
        return (0);
 }
 
@@ -867,6 +871,18 @@ rasops_init_devcmap(struct rasops_info *
                ri->ri_devcmap[i] = c;
 #endif
        }
+
+       /* Define colours 16-255 iff we are running in 32bpp */
+
+       if (ri->ri_depth == 32) {
+               for (i = 16 ; i <= 231; i++) {
+                       ri->ri_devcmap[i] = EBCOL(i);
+               }
+               for (i = 232 ; i < 256; i++) {
+                       ri->ri_devcmap[i] = EBGREY(i) | EBGREY(i) << 8 |
+                           EBGREY(i) << 16;
+               }
+       }
 #endif
 }
 
@@ -876,8 +892,8 @@ rasops_init_devcmap(struct rasops_info *
 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 & WSATTR_UNDERLINE;
 }
@@ -907,7 +923,7 @@ rasops_eraserows(void *cookie, int row, 
                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
@@ -1061,7 +1077,7 @@ rasops_erasecols(void *cookie, int row, 
        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) {
@@ -1263,7 +1279,7 @@ rasops_putchar_rotated(void *cookie, int
 
        /* XXX this assumes 16-bit color depth */
        if ((attr & WSATTR_UNDERLINE) != 0) {
-               int16_t c = (int16_t)ri->ri_devcmap[((u_int)attr >> 24) & 0xf];
+               int16_t c = (int16_t)ri->ri_devcmap[((u_int)attr >> 24) & 0xff];
 
                while (height--) {
                        *(int16_t *)rp = c;
@@ -1791,8 +1807,8 @@ rasops_wronly_do_cursor(struct rasops_in
        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);
        }
Index: rasops/rasops.h
===================================================================
RCS file: /cvs/src/sys/dev/rasops/rasops.h,v
retrieving revision 1.25
diff -u -p -r1.25 rasops.h
--- rasops/rasops.h     25 May 2020 09:55:49 -0000      1.25
+++ rasops/rasops.h     30 Jan 2023 09:08:22 -0000
@@ -106,7 +106,7 @@ struct rasops_info {
        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;
@@ -184,5 +184,16 @@ int        rasops_check_framebuffer(paddr_t);
 
 extern const u_char    rasops_isgray[16];
 extern const u_char    rasops_cmap[256*3];
+
+/*
+ * Macros to calculate the 6x6x6 colour cube and greyscale ramp used when
+ * supporting 256-colours
+ */
+
+#define EBCOL_RED(x) (48*((x-16)%6))
+#define EBCOL_GREEN(x) ((48*(((x-16)/6)%6)) << 8)
+#define EBCOL_BLUE(x) ((48*(((x-16)/36)%6)) << 16)
+#define EBCOL(x) EBCOL_RED(x) | EBCOL_GREEN(x) | EBCOL_BLUE(x)
+#define EBGREY(x) (int)(1+((i-232)*11))
 
 #endif /* _RASOPS_H_ */
Index: rasops/rasops32.c
===================================================================
RCS file: /cvs/src/sys/dev/rasops/rasops32.c,v
retrieving revision 1.13
diff -u -p -r1.13 rasops32.c
--- rasops/rasops32.c   18 Jan 2023 11:08:49 -0000      1.13
+++ rasops/rasops32.c   30 Jan 2023 09:08:22 -0000
@@ -91,8 +91,8 @@ rasops32_putchar(void *cookie, int row, 
        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];
        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;
Index: wscons/wsdisplayvar.h
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wsdisplayvar.h,v
retrieving revision 1.38
diff -u -p -r1.38 wsdisplayvar.h
--- wscons/wsdisplayvar.h       13 Sep 2020 10:05:46 -0000      1.38
+++ wscons/wsdisplayvar.h       30 Jan 2023 09:08:22 -0000
@@ -114,6 +114,7 @@ struct wsscreen_descr {
 #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 */
 };
 
 /*
Index: wscons/wsemul_vt100_subr.c
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wsemul_vt100_subr.c,v
retrieving revision 1.29
diff -u -p -r1.29 wsemul_vt100_subr.c
--- wscons/wsemul_vt100_subr.c  12 Jan 2023 20:39:37 -0000      1.29
+++ wscons/wsemul_vt100_subr.c  30 Jan 2023 09:08:22 -0000
@@ -615,6 +615,62 @@ wsemul_vt100_handle_csi(struct wsemul_vt
                                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.
+                        */
+                       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;
@@ -626,6 +682,29 @@ wsemul_vt100_handle_csi(struct wsemul_vt
                                /* bg color */
                                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 */
Index: wscons/wsemul_vt100var.h
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wsemul_vt100var.h,v
retrieving revision 1.12
diff -u -p -r1.12 wsemul_vt100var.h
--- wscons/wsemul_vt100var.h    12 Jan 2023 20:39:37 -0000      1.12
+++ wscons/wsemul_vt100var.h    30 Jan 2023 09:08:22 -0000
@@ -130,6 +130,8 @@ struct wsemul_vt100_emuldata {
 #define ERASECOLS(f, n, a)     (edp->emulcookie, edp->crow, (f), (n), (a))
 #endif
 #define        COLS_LEFT       (NCOLS - edp->ccol - 1)
+#define EXIST_ARG2(i) ((edp->nargs-n) >= 3)
+#define ARG2_OR_DEF(i) (EXIST_ARG2(i) ? ARG(i + 2) : 0)
 
 /*
  * response to primary DA request

Reply via email to