From owner-svn-src-head@freebsd.org Fri Aug 25 07:04:43 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1D838DF1457; Fri, 25 Aug 2017 07:04:43 +0000 (UTC) (envelope-from bde@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B50AA75E88; Fri, 25 Aug 2017 07:04:42 +0000 (UTC) (envelope-from bde@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v7P74fPh028901; Fri, 25 Aug 2017 07:04:41 GMT (envelope-from bde@FreeBSD.org) Received: (from bde@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v7P74fE9028895; Fri, 25 Aug 2017 07:04:41 GMT (envelope-from bde@FreeBSD.org) Message-Id: <201708250704.v7P74fE9028895@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: bde set sender to bde@FreeBSD.org using -f From: Bruce Evans Date: Fri, 25 Aug 2017 07:04:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r322878 - in head: sys/dev/syscons sys/sys usr.sbin/vidcontrol X-SVN-Group: head X-SVN-Commit-Author: bde X-SVN-Commit-Paths: in head: sys/dev/syscons sys/sys usr.sbin/vidcontrol X-SVN-Commit-Revision: 322878 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Aug 2017 07:04:43 -0000 Author: bde Date: Fri Aug 25 07:04:41 2017 New Revision: 322878 URL: https://svnweb.freebsd.org/changeset/base/322878 Log: Support setting the colors of cursors for the VGA renderer. Advertise this by changing the defaults to mostly red. If you don't like this, change them (almost) back using: vidcontrol -c charcolors,base=7,height=0 vidcontrol -c mousecolors,base=0[,height=15] The (graphics mode only) mouse cursor colors were hard-coded to a black border and lightwhite interior. Black for the border is the worst possible default, since it is the same as the default black background and not good for any dark background. Reversing this gives the better default of X Windows. Coloring everything works better still. Now the coloring defaults to a lightwhite border and red interior. Coloring for the character cursor is more complicated and mode dependent. The new coloring doesn't apply for hardware cursors. For non-block cursors, it only applies in graphics mode. In text mode, the cursor color was usually a hard-coded (dull)white for the background only, unless the foreground was white when it was a hard-coded black for the background only, unless the foreground was white and the background was black it was reverse video. In graphics mode, it was always reverse video for the block cursor. Reverse video is worse, especially over cutmarking regions, since cutmarking still uses simple reverse video (nothing better is possible in text mode) and double reverse video for the cursor gives normal video. Now, graphics mode uses the same algorithm as the best case for text mode in all cases for graphics mode. The hard-coded sequence { white, black, } for the background is now { red, white, blue, } where the first 2 colors can be configured. The blue color at the end is a sentinel which prevents reverse video being used in most cases but breaks the compatibility setting for white on black and black on white characters. This will be fixed later. The compatibility setting is most needed for mono modes. The previous commit to syscons.c changed sc_cnterm() to be more careful. It followed null pointers in some cases. But sc_cnterm() has been unreachable for 15+ years since changes for multiple consoles turned off calls to the the cnterm destructor for all console drivers. Before them, it was only called at boot time. So no driver with an attached console has ever been unloadable and not even the non-console destructors have been tested much. Modified: head/sys/dev/syscons/scvgarndr.c head/sys/dev/syscons/syscons.c head/sys/dev/syscons/syscons.h head/sys/sys/consio.h head/usr.sbin/vidcontrol/vidcontrol.1 head/usr.sbin/vidcontrol/vidcontrol.c Modified: head/sys/dev/syscons/scvgarndr.c ============================================================================== --- head/sys/dev/syscons/scvgarndr.c Fri Aug 25 05:49:37 2017 (r322877) +++ head/sys/dev/syscons/scvgarndr.c Fri Aug 25 07:04:41 2017 (r322878) @@ -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 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 { 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, i 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, i 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 Modified: head/sys/dev/syscons/syscons.c ============================================================================== --- head/sys/dev/syscons/syscons.c Fri Aug 25 05:49:37 2017 (r322877) +++ head/sys/dev/syscons/syscons.c Fri Aug 25 07:04:41 2017 (r322878) @@ -959,8 +959,16 @@ sctty_ioctl(struct tty *tp, u_long cmd, caddr_t data, 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); Modified: head/sys/dev/syscons/syscons.h ============================================================================== --- head/sys/dev/syscons/syscons.h Fri Aug 25 05:49:37 2017 (r322877) +++ head/sys/dev/syscons/syscons.h Fri Aug 25 07:04:41 2017 (r322878) @@ -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 */ Modified: head/sys/sys/consio.h ============================================================================== --- head/sys/sys/consio.h Fri Aug 25 05:49:37 2017 (r322877) +++ head/sys/sys/consio.h Fri Aug 25 07:04:41 2017 (r322878) @@ -187,6 +187,8 @@ typedef struct mouse_info mouse_info_t; #define CONS_HIDDEN_CURSOR (1 << 2) #define CONS_CURSOR_ATTRS (CONS_BLINK_CURSOR | CONS_CHAR_CURSOR | \ CONS_HIDDEN_CURSOR) +#define CONS_CHARCURSOR_COLORS (1 << 26) +#define CONS_MOUSECURSOR_COLORS (1 << 27) #define CONS_DEFAULT_CURSOR (1 << 28) #define CONS_SHAPEONLY_CURSOR (1 << 29) #define CONS_RESET_CURSOR (1 << 30) Modified: head/usr.sbin/vidcontrol/vidcontrol.1 ============================================================================== --- head/usr.sbin/vidcontrol/vidcontrol.1 Fri Aug 25 05:49:37 2017 (r322877) +++ head/usr.sbin/vidcontrol/vidcontrol.1 Fri Aug 25 07:04:41 2017 (r322878) @@ -219,6 +219,50 @@ Set or clear the hidden attribute. The following (non-sticky) flags control application of the .Cm setting Ns s : .Bl -tag -width indent +.It Cm charcolors +Apply +.Cm base +and +.Cm height +to the (character) cursor's list of preferred colors instead of its shape. +Beware that the color numbers are raw VGA palette indexes, +not ANSI color numbers. +The indexes are reduced mod 8, 16 or 256, +or ignored, +depending on the video mode and renderer. +.It Cm mousecolors +Colors for the mouse cursor in graphics mode. +Like +.Cm charcolors , +except there is no preference or sequence; +.Cm base +gives the mouse border color and +.Cm height +gives the mouse interior color. +Together with +.Cm charcolors , +this gives 2 selection bits which select between +only 3 of 4 sub-destinations of the 4 destinations selected by +.Cm default +and +.Cm local +(by ignoring +.Cm mousecolors +if +.Cm charcolors +is also set). +.It Cm default +Apply the changes to the default settings and then to the active settings, +instead of only to the active settings. +Together with +.Cm local , +this gives 2 selection bits which select between 4 destinations. +.It Cm shapeonly +Ignore any changes to the +.Cm block +and +.Cm hidden +attributes. .It Cm local Apply the changes to the current vty. The default is to apply them to a global place @@ -233,10 +277,8 @@ to default local settings. Otherwise, the current global settings are reset to default global settings and then copied to the current and default settings for all vtys. -The global defaults are decided (not quite right) at boot time -and cannot be fixed up. -The local defaults are obtained as above and cannot be fixed up -locally. +.It Cm show +Show the current changes. .El .It Fl d Print out current output screen map. Modified: head/usr.sbin/vidcontrol/vidcontrol.c ============================================================================== --- head/usr.sbin/vidcontrol/vidcontrol.c Fri Aug 25 05:49:37 2017 (r322877) +++ head/usr.sbin/vidcontrol/vidcontrol.c Fri Aug 25 07:04:41 2017 (r322878) @@ -650,10 +650,21 @@ parse_cursor_params(char *param, struct cshape *shape) shape->shape[1] = strtol(word + 5, NULL, 0); else if (strncmp(word, "height=", 7) == 0) shape->shape[2] = strtol(word + 7, NULL, 0); + else if (strcmp(word, "charcolors") == 0) + type |= CONS_CHARCURSOR_COLORS; + else if (strcmp(word, "mousecolors") == 0) + type |= CONS_MOUSECURSOR_COLORS; + else if (strcmp(word, "default") == 0) + type |= CONS_DEFAULT_CURSOR; + else if (strcmp(word, "shapeonly") == 0) + type |= CONS_SHAPEONLY_CURSOR; else if (strcmp(word, "local") == 0) type |= CONS_LOCAL_CURSOR; else if (strcmp(word, "reset") == 0) type |= CONS_RESET_CURSOR; + else if (strcmp(word, "show") == 0) + printf("flags %#x, base %d, height %d\n", + type, shape->shape[1], shape->shape[2]); else { revert(); errx(1, @@ -676,11 +687,13 @@ set_cursor_type(char *param) { struct cshape shape; - /* Determine if the new setting is local (default to non-local). */ + /* Dry run to determine color, default and local flags. */ shape.shape[0] = 0; + shape.shape[1] = -1; + shape.shape[2] = -1; parse_cursor_params(param, &shape); - /* Get the relevant shape (the local flag is the only input arg). */ + /* Get the relevant old setting. */ if (ioctl(0, CONS_GETCURSORSHAPE, &shape) != 0) { revert(); err(1, "ioctl(CONS_GETCURSORSHAPE)");