Another update to the console patchset...
At this point, my focus has shifted to testing the currently implemented
functionality rather than adding anything new. Unless there is breakage that
I am not aware of, this version of the diff already allows the use of
TERM=xterm with no loss of functionality over TERM=pccon without it. It's
also a much better experience than the default TERM=vt220.
NEW - Bold is now displayed by over-printing each character with a
one-pixel offset to the right, instead of using a brighter colour.
NEW - The rasops_isgray function has been removed, along with the calls to
it. This simplifies the passing of WSATTR_ values to the rasops code.
NEW - The backtab sequence now supports an argument for moving back over
several tabs. Noticed by Nicholas.
The change to the rendering of bold text allows us to use bold in conjunction
with all 256 colours, instead of just the first eight ANSI colours.
But does it look any good, or does it look awful? As well as personal
preference, it also depends on which size font you are using, which in turn
depends on screen resolution. I think the effect looks reasonable for all
fonts except possibly spleen 32x64, (and bold 8x16, but I doubt that many
people are using that). The visual effect with spleen 32x64 can be improved
by further over-printing the glyphs with an additional 1 pixel shift, but that
isn't implemented in this version.
Also, double underlining is always done two pixels above the normal underline.
This might look better if it was changed to just one pixel on spleen 5x8, and
to three or more pixels on the 32x64 version. Feedback would be appreciated.
To anybody looking at this patchset for the first time, and who hasn't
followed the previous threads, the overall advantages of all this include:
* You get colour on the console with curses-based programs.
* Not just boring 8 or 16 colours, but 256 colours.
* You also get dim text, double underline, true bold, and invisible text.
* The scrollback buffer is now 20 screens instead of five.
* The terminal type of xterm is very widely supported on remote systems.
* The few known glitches that happened when using pccon are now eliminated.
* Shift-tab for backtab now works, and keypad 5 is usable with numlock off.
But it needs testing! So if you're interested please do test it and let me
know what you find.
And thanks for all of the feedback so far.
--- 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 Mon Jan 9 13:28:25 2023
@@ -217,7 +217,7 @@
wsemul_vt100_handle_csi(struct wsemul_vt100_emuldata *edp,
struct wsemul_inputstate *instate)
{
- int n, help, flags, fgcol, bgcol;
+ int n, m, help, flags, fgcol, bgcol;
uint32_t attr, bkgdattr;
u_char c;
int rc = 0;
@@ -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,41 @@
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': /* CBT */
+ if (edp->ccol == 0)
+ break;
+ for (m = 0; m < DEF1_ARG(0); m++) {
+ if (edp->tabs) {
+ for (n = edp->ccol - 1; n > 0; n--) {
+ if (edp->tabs[n])
+ break;
+ }
+ } else
+ n = (edp->ccol - 1) & ~7;
+ edp->ccol = n;
+ if (n == 0)
+ break;
+ }
+ 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 +577,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,11 +592,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;
@@ -570,12 +624,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;
@@ -588,11 +706,46 @@
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;
if (fgcol == WSCOL_WHITE)
flags &= ~WSATTR_WSCOLORS;
+ break;
+ case 90: case 91: case 92: case 93:
+ case 94: case 95: case 96: case 97:
+ /* 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 colour */
+ flags |= WSATTR_WSCOLORS;
+ bgcol = ARG(n) - 92;
break;
default:
#ifdef VT100_PRINTUNKNOWN
--- 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 Mon Jan 9 18:27:04 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.dist Thu Jul 23 06:17:03 2020
+++ dev/rasops/rasops.c Mon Jan 9 18:19:49 2023
@@ -122,14 +122,6 @@
#undef _C
};
-/* True if color is gray */
-const u_char rasops_isgray[16] = {
- 1, 0, 0, 0,
- 0, 0, 0, 1,
- 1, 0, 0, 0,
- 0, 0, 0, 1
-};
-
struct rasops_screen {
LIST_ENTRY(rasops_screen) rs_next;
struct rasops_info *rs_ri;
@@ -141,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 */
};
@@ -454,6 +446,10 @@
WSSCREEN_WSCOLORS | WSSCREEN_REVERSE;
}
+ if (ri->ri_depth == 32) {
+ ri->ri_caps |= WSSCREEN_256COL ;
+ }
+
switch (ri->ri_depth) {
#if NRASOPS1 > 0
case 1:
@@ -565,17 +561,14 @@
bg = swap;
}
- if ((flg & WSATTR_HILIT) != 0)
- fg += 8;
+ /*
+ * The rapops code expects a different layout of the bitfields in flg:
+ *
+ * WSATTR_UNDERLINE is duplicated in bit 0, overwriting WSATTR_REVERSE
+ */
- flg = ((flg & WSATTR_UNDERLINE) ? 1 : 0);
+ flg = ((flg & 0xfffe) | (flg & WSATTR_UNDERLINE ? 1 : 0));
- if (rasops_isgray[fg])
- flg |= 2;
-
- if (rasops_isgray[bg])
- flg |= 4;
-
*attr = (bg << 16) | (fg << 24) | flg;
return (0);
}
@@ -882,6 +875,21 @@
ri->ri_devcmap[i] = c;
#endif
}
+ /* Re-define colours 16-255 if we are running in 32bpp */
+ #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))
+ 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
}
@@ -891,8 +899,8 @@
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;
}
@@ -922,7 +930,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
@@ -1076,7 +1084,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) {
@@ -1277,7 +1285,7 @@
/* XXX this assumes 16-bit color depth */
if ((attr & 1) != 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;
@@ -1805,8 +1813,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 Mon Jan 9 15:45:14 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_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;
}