Index: share/man/man4/vt.4 =================================================================== --- share/man/man4/vt.4 +++ share/man/man4/vt.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 19, 2016 +.Dd December 28, 2017 .Dt "VT" 4 .Os .Sh NAME @@ -45,6 +45,7 @@ .Xr loader.conf 5 : .Cd hw.vga.textmode=1 .Cd kern.vty=vt +.Cd kern.vt.color..rgb="" .Cd kern.vt.fb.default_mode="x" .Cd kern.vt.fb.modes.="x" .Pp @@ -206,6 +207,16 @@ kernel uses .Nm when this value is not set. +.It Va kern.vt.color. Ns Ar colornum Ns Va .rgb +Set this value to override default palette entry for color +.Pa colornum +which should be in a range from 0 to 15 inclusive. +The value should be either a comma-separated triplet of +red, green, and blue values in a range from 0 to 255 or +HTML-like hex triplet. +See +.Sx EXAMPLES +below. .It Va kern.vt.fb.default_mode Set this value to a graphic mode to override the default mode picked by the .Nm @@ -310,6 +321,11 @@ .Dl info: [drm] Connector LVDS-1: get mode from tunables: .Dl info: [drm] - kern.vt.fb.modes.LVDS-1 .Dl info: [drm] - kern.vt.fb.default_mode +.Pp +To set black and white colors of console palette +.Pp +.Dl kern.vt.color.0.rgb="10,10,10" +.Dl kern.vt.color.15.rgb="#f0f0f0" .Sh SEE ALSO .Xr kbdcontrol 1 , .Xr login 1 , Index: sys/dev/vt/colors/vt_termcolors.c =================================================================== --- sys/dev/vt/colors/vt_termcolors.c +++ sys/dev/vt/colors/vt_termcolors.c @@ -33,14 +33,18 @@ __FBSDID("$FreeBSD$"); #include +#include +#include #include -static const struct { +#define NCOLORS 16 + +static struct { unsigned char r; /* Red percentage value. */ unsigned char g; /* Green percentage value. */ unsigned char b; /* Blue percentage value. */ -} color_def[16] = { +} color_def[NCOLORS] = { {0, 0, 0}, /* black */ {50, 0, 0}, /* dark red */ {0, 50, 0}, /* dark green */ @@ -65,19 +69,116 @@ * - blue and red are swapped (1 <-> 4) * - yellow ad cyan are swapped (3 <-> 6) */ -static const int cons_to_vga_colors[16] = { +static const int cons_to_vga_colors[NCOLORS] = { 0, 4, 2, 6, 1, 5, 3, 7, 0, 4, 2, 6, 1, 5, 3, 7 }; +static int +vt_parse_rgb_triplet(const char *rgb, unsigned char *r, + unsigned char *g, unsigned char *b) +{ + unsigned long v; + const char *ptr; + char *endptr; + + ptr = rgb; + + /* Handle #rrggbb case */ + if (*ptr == '#') { + if (strlen(ptr) != 7) + return (-1); + v = strtoul(ptr + 1, &endptr, 16); + if (*endptr != '\0') + return (-1); + + *r = (v >> 16) & 0xff; + *g = (v >> 8) & 0xff; + *b = v & 0xff; + + return (0); + } + + /* skip leading spaces */ + while (*ptr == ' ') + ptr++; + + /* "r, g, b" case */ + v = strtoul(ptr, &endptr, 10); + if (ptr == endptr) + return (-1); + if (v > 255) + return (-1); + *r = v & 0xff; + ptr = endptr; + + /* skip separator */ + while (*ptr == ',' || *ptr == ' ') + ptr++; + + v = strtoul(ptr, &endptr, 10); + if (ptr == endptr) + return (-1); + if (v > 255) + return (-1); + *g = v & 0xff; + ptr = endptr; + + /* skip separator */ + while (*ptr == ',' || *ptr == ' ') + ptr++; + + v = strtoul(ptr, &endptr, 10); + if (ptr == endptr) + return (-1); + if (v > 255) + return (-1); + *b = v & 0xff; + ptr = endptr; + + /* skip trailing spaces */ + while (*ptr == ' ') + ptr++; + + /* unexpected characters at the end of the string */ + if (*ptr != 0) + return (-1); + + return (0); +} + +static void +vt_palette_init() +{ + int i; + char rgb[32]; + char tunable[32]; + unsigned char r, g, b; + + for (i = 0; i < NCOLORS; i++) { + snprintf(tunable, sizeof(tunable), + "kern.vt.color.%d.rgb", i); + if (TUNABLE_STR_FETCH(tunable, rgb, sizeof(rgb))) { + if (vt_parse_rgb_triplet(rgb, strlen(rgb), &r, &g, &b) == 0) { + /* convert to percentages */ + color_def[i].r = r*100/255; + color_def[i].g = g*100/255; + color_def[i].b = b*100/255; + } + } + } +} + int vt_generate_cons_palette(uint32_t *palette, int format, uint32_t rmax, int roffset, uint32_t gmax, int goffset, uint32_t bmax, int boffset) { int i; + vt_palette_init(); + #define CF(_f, _i) ((_f ## max * color_def[(_i)]._f / 100) << _f ## offset) - for (i = 0; i < 16; i++) { + for (i = 0; i < NCOLORS; i++) { switch (format) { case COLOR_FORMAT_VGA: palette[i] = cons_to_vga_colors[i];