vt(4): add support for configurable console palette
Introduce new set of loader tunables kern.vt.color.N.rgb, where N is a number from 0 to 15. The value is either comma-separated list decimal numbers ranging from 0 to 255 that represent values of red, green, and blue components respectively (i.e. "128,128,128") or 6-digit hex triplet commonly used to represent colors in HTML or xterm settings (i.e. #808080) Each tunable overrides one of the 16 hardcoded palette codes and can be set in loader.conf(5) Reviewed by: bcr(docs), jilles, manu, ray MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D13645
This commit is contained in:
parent
4e05ac247c
commit
29f61a2f42
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd July 19, 2016
|
||||
.Dd December 28, 2017
|
||||
.Dt "VT" 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -45,6 +45,7 @@ In
|
||||
.Xr loader.conf 5 :
|
||||
.Cd hw.vga.textmode=1
|
||||
.Cd kern.vty=vt
|
||||
.Cd kern.vt.color.<colornum>.rgb="<colorspec>"
|
||||
.Cd kern.vt.fb.default_mode="<X>x<Y>"
|
||||
.Cd kern.vt.fb.modes.<connector>="<X>x<Y>"
|
||||
.Pp
|
||||
@ -206,6 +207,16 @@ The
|
||||
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 @@ The connector name was found in
|
||||
.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 ,
|
||||
|
@ -33,14 +33,18 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/libkern.h>
|
||||
|
||||
#include <dev/vt/colors/vt_termcolors.h>
|
||||
|
||||
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,112 @@ static const struct {
|
||||
* - 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);
|
||||
}
|
||||
|
||||
/* "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];
|
||||
|
Loading…
x
Reference in New Issue
Block a user