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