diff options
| author | Bruce Evans <bde@FreeBSD.org> | 2017-08-25 07:04:41 +0000 |
|---|---|---|
| committer | Bruce Evans <bde@FreeBSD.org> | 2017-08-25 07:04:41 +0000 |
| commit | 9bc7c36337adfbcbfc9e65b4ce63825e72298db2 (patch) | |
| tree | 8a727f16c361f6fa8446924789029eb93f481b6b /sys/dev/syscons | |
| parent | 0012e436e364a88f513bc5d3167c08d57d15105a (diff) | |
Notes
Diffstat (limited to 'sys/dev/syscons')
| -rw-r--r-- | sys/dev/syscons/scvgarndr.c | 58 | ||||
| -rw-r--r-- | sys/dev/syscons/syscons.c | 26 | ||||
| -rw-r--r-- | sys/dev/syscons/syscons.h | 11 |
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 */ |
