aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/syscons
diff options
context:
space:
mode:
authorBruce Evans <bde@FreeBSD.org>2017-08-25 07:04:41 +0000
committerBruce Evans <bde@FreeBSD.org>2017-08-25 07:04:41 +0000
commit9bc7c36337adfbcbfc9e65b4ce63825e72298db2 (patch)
tree8a727f16c361f6fa8446924789029eb93f481b6b /sys/dev/syscons
parent0012e436e364a88f513bc5d3167c08d57d15105a (diff)
Notes
Diffstat (limited to 'sys/dev/syscons')
-rw-r--r--sys/dev/syscons/scvgarndr.c58
-rw-r--r--sys/dev/syscons/syscons.c26
-rw-r--r--sys/dev/syscons/syscons.h11
3 files changed, 60 insertions, 35 deletions
diff --git a/sys/dev/syscons/scvgarndr.c b/sys/dev/syscons/scvgarndr.c
index aef157f169daa..8b098f240e538 100644
--- a/sys/dev/syscons/scvgarndr.c
+++ b/sys/dev/syscons/scvgarndr.c
@@ -356,32 +356,28 @@ vga_flipattr(u_short a, int blink)
}
static u_short
-vga_cursorattr_adj(u_short a, int blink)
+vga_cursorattr_adj(scr_stat *scp, u_short a, int blink)
{
- /*
- * !blink means pixel mode, and the cursor attribute in that case
- * is simplistic reverse video.
- */
- if (!blink)
- return (vga_flipattr(a, blink));
+ int i;
+ u_short bg, bgmask, fg, newbg;
/*
* The cursor attribute is usually that of the underlying char
- * with the bg changed to white. If the bg is already white,
- * then the bg is changed to black. The fg is usually not
- * changed, but if it is the same as the new bg then it is
- * changed to the inverse of the new bg.
+ * with only the bg changed, to the first preferred color that
+ * differs from both the fg and bg. If there is no such color,
+ * use reverse video.
*/
- if ((a & 0x7000) == 0x7000) {
- a &= 0x8f00;
- if ((a & 0x0700) == 0)
- a |= 0x0700;
- } else {
- a |= 0x7000;
- if ((a & 0x0700) == 0x0700)
- a &= 0xf000;
+ bgmask = blink ? 0x7000 : 0xf000;
+ bg = a & bgmask;
+ fg = a & 0x0f00;
+ for (i = 0; i < nitems(scp->curs_attr.bg); i++) {
+ newbg = (scp->curs_attr.bg[i] << 12) & bgmask;
+ if (newbg != bg && newbg != (fg << 4))
+ break;
}
- return (a);
+ if (i == nitems(scp->curs_attr.bg))
+ return (vga_flipattr(a, blink));
+ return (fg | newbg | (blink ? a & 0x8000 : 0));
}
static void
@@ -522,6 +518,12 @@ draw_txtcharcursor(scr_stat *scp, int at, u_short c, u_short a, int flip)
return;
if (flip)
a = vga_flipattr(a, TRUE);
+ /*
+ * This clause handles partial-block cursors in text mode.
+ * We want to change the attribute only under the partial
+ * block, but in text mode we can only change full blocks.
+ * Use reverse video instead.
+ */
bcopy(font + c*h, font + sc->cursor_char*h, h);
font = font + sc->cursor_char*h;
for (i = imax(h - scp->curs_attr.base - scp->curs_attr.height, 0);
@@ -536,7 +538,7 @@ draw_txtcharcursor(scr_stat *scp, int at, u_short c, u_short a, int flip)
{
if (flip)
a = vga_flipattr(a, TRUE);
- a = vga_cursorattr_adj(a, TRUE);
+ a = vga_cursorattr_adj(scp, a, TRUE);
sc_vtb_putc(&scp->scr, at, c, a);
}
}
@@ -1026,7 +1028,7 @@ draw_pxlcursor_direct(scr_stat *scp, int at, int on, int flip)
if (flip)
a = vga_flipattr(a, FALSE);
if (on)
- a = vga_cursorattr_adj(a, FALSE);
+ a = vga_cursorattr_adj(scp, a, FALSE);
col1 = (a & 0x0f00) >> 8;
col2 = a >> 12;
@@ -1070,7 +1072,7 @@ draw_pxlcursor_planar(scr_stat *scp, int at, int on, int flip)
if (flip)
a = vga_flipattr(a, FALSE);
if (on)
- a = vga_cursorattr_adj(a, FALSE);
+ a = vga_cursorattr_adj(scp, a, FALSE);
col = (a & 0xf000) >> 4;
outw(GDCIDX, col | 0x00); /* set/reset */
outw(GDCIDX, 0xff08); /* bit mask */
@@ -1202,7 +1204,7 @@ draw_pxlmouse_planar(scr_stat *scp, int x, int y)
outw(GDCIDX, 0x0003); /* data rotate/function select */
outw(GDCIDX, 0x0f01); /* set/reset enable */
- outw(GDCIDX, (0 << 8) | 0x00); /* set/reset */
+ outw(GDCIDX, (scp->curs_attr.mouse_ba << 8) | 0x00); /* set/reset */
p = scp->sc->adp->va_window + line_width*y + x/8;
for (i = y, j = 0; i < ymax; ++i, ++j) {
m = mdp->md_border[j] << 8 >> xoff;
@@ -1221,7 +1223,7 @@ draw_pxlmouse_planar(scr_stat *scp, int x, int y)
}
p += line_width;
}
- outw(GDCIDX, (15 << 8) | 0x00); /* set/reset */
+ outw(GDCIDX, (scp->curs_attr.mouse_ia << 8) | 0x00); /* set/reset */
p = scp->sc->adp->va_window + line_width*y + x/8;
for (i = y, j = 0; i < ymax; ++i, ++j) {
m = mdp->md_interior[j] << 8 >> xoff;
@@ -1325,9 +1327,11 @@ do_on:
for (i = 0; i < yend - y; i++, p += line_width)
for (j = xend - x - 1; j >= 0; j--)
if (mdp->md_interior[i] & (1 << (15 - j)))
- DRAW_PIXEL(scp, p + j * pixel_size, 15);
+ DRAW_PIXEL(scp, p + j * pixel_size,
+ scp->curs_attr.mouse_ia);
else if (mdp->md_border[i] & (1 << (15 - j)))
- DRAW_PIXEL(scp, p + j * pixel_size, 0);
+ DRAW_PIXEL(scp, p + j * pixel_size,
+ scp->curs_attr.mouse_ba);
}
static void
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index f54b20eed6c92..b6f9cc2e8d998 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -959,8 +959,16 @@ sctty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
cap = &scp->dflt_curs_attr;
break;
}
- ((int *)data)[1] = cap->base;
- ((int *)data)[2] = cap->height;
+ if (((int *)data)[0] & CONS_CHARCURSOR_COLORS) {
+ ((int *)data)[1] = cap->bg[0];
+ ((int *)data)[2] = cap->bg[1];
+ } else if (((int *)data)[0] & CONS_MOUSECURSOR_COLORS) {
+ ((int *)data)[1] = cap->mouse_ba;
+ ((int *)data)[2] = cap->mouse_ia;
+ } else {
+ ((int *)data)[1] = cap->base;
+ ((int *)data)[2] = cap->height;
+ }
((int *)data)[0] = cap->flags;
return 0;
@@ -3025,8 +3033,12 @@ sc_set_cursor_image(scr_stat *scp)
static void
sc_adjust_ca(struct cursor_attr *cap, int flags, int base, int height)
{
- if (0) {
- /* Dummy clause to avoid changing indentation later. */
+ if (flags & CONS_CHARCURSOR_COLORS) {
+ cap->bg[0] = base & 0xff;
+ cap->bg[1] = height & 0xff;
+ } else if (flags & CONS_MOUSECURSOR_COLORS) {
+ cap->mouse_ba = base & 0xff;
+ cap->mouse_ia = height & 0xff;
} else {
if (base >= 0)
cap->base = base;
@@ -3243,8 +3255,14 @@ scinit(int unit, int flags)
sc->dflt_curs_attr.base = 0;
sc->dflt_curs_attr.height = howmany(scp->font_size, 8);
sc->dflt_curs_attr.flags = 0;
+ sc->dflt_curs_attr.bg[0] = FG_RED;
+ sc->dflt_curs_attr.bg[1] = FG_LIGHTGREY;
+ sc->dflt_curs_attr.bg[2] = FG_BLUE;
+ sc->dflt_curs_attr.mouse_ba = FG_WHITE;
+ sc->dflt_curs_attr.mouse_ia = FG_RED;
sc->curs_attr = sc->dflt_curs_attr;
scp->base_curs_attr = scp->dflt_curs_attr = sc->curs_attr;
+ scp->curs_attr = scp->base_curs_attr;
#ifndef SC_NO_SYSMOUSE
sc_mouse_move(scp, scp->xpixel/2, scp->ypixel/2);
diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h
index fc9c8f50b07df..28b3628782079 100644
--- a/sys/dev/syscons/syscons.h
+++ b/sys/dev/syscons/syscons.h
@@ -167,11 +167,14 @@ typedef struct sc_vtb {
int vtb_tail; /* valid for VTB_RINGBUFFER only */
} sc_vtb_t;
-/* text cursor attributes */
+/* text and some mouse cursor attributes */
struct cursor_attr {
- int flags;
- int base;
- int height;
+ u_char flags;
+ u_char base;
+ u_char height;
+ u_char bg[3];
+ u_char mouse_ba;
+ u_char mouse_ia;
};
/* softc */