summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/boot/Makefile.version2
-rw-r--r--usr/src/boot/sys/boot/common/gfx_fb.c86
-rw-r--r--usr/src/boot/sys/boot/common/tem.c280
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/efi_console.c6
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/vbe.c20
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/vidconsole.c8
-rw-r--r--usr/src/boot/sys/sys/tem_impl.h23
-rw-r--r--usr/src/common/font/font.c54
-rw-r--r--usr/src/uts/common/io/tem.c16
-rw-r--r--usr/src/uts/common/io/tem_safe.c376
-rw-r--r--usr/src/uts/common/sys/font.h6
-rw-r--r--usr/src/uts/common/sys/rgb.h6
-rw-r--r--usr/src/uts/common/sys/tem_impl.h23
-rw-r--r--usr/src/uts/common/sys/visual_io.h9
-rw-r--r--usr/src/uts/i86pc/boot/boot_fb.c3
-rw-r--r--usr/src/uts/i86pc/io/gfx_private/gfxp_bitmap.c33
-rw-r--r--usr/src/uts/i86pc/io/gfx_private/gfxp_vgatext.c8
17 files changed, 605 insertions, 354 deletions
diff --git a/usr/src/boot/Makefile.version b/usr/src/boot/Makefile.version
index e8dcc2dd0b..5f2a2b4676 100644
--- a/usr/src/boot/Makefile.version
+++ b/usr/src/boot/Makefile.version
@@ -34,4 +34,4 @@ LOADER_VERSION = 1.1
# Use date like formatting here, YYYY.MM.DD.XX, without leading zeroes.
# The version is processed from left to right, the version number can only
# be increased.
-BOOT_VERSION = $(LOADER_VERSION)-2021.05.16.1
+BOOT_VERSION = $(LOADER_VERSION)-2021.06.15.1
diff --git a/usr/src/boot/sys/boot/common/gfx_fb.c b/usr/src/boot/sys/boot/common/gfx_fb.c
index 1e54a73630..c4b62e4eb2 100644
--- a/usr/src/boot/sys/boot/common/gfx_fb.c
+++ b/usr/src/boot/sys/boot/common/gfx_fb.c
@@ -203,39 +203,10 @@ gfx_parse_mode_str(char *str, int *x, int *y, int *depth)
return (true);
}
-/*
- * Support for color mapping.
- * For 8, 24 and 32 bit depth, use mask size 8.
- * 15/16 bit depth needs to use mask size from mode,
- * or we will lose color information from 32-bit to 15/16 bit translation.
- */
uint32_t
gfx_fb_color_map(uint8_t index)
{
- rgb_t rgb;
- int bpp;
-
- bpp = roundup2(gfx_fb.framebuffer_common.framebuffer_bpp, 8) >> 3;
-
- rgb.red.pos = 16;
- if (bpp == 2)
- rgb.red.size = gfx_fb.u.fb2.framebuffer_red_mask_size;
- else
- rgb.red.size = 8;
-
- rgb.green.pos = 8;
- if (bpp == 2)
- rgb.green.size = gfx_fb.u.fb2.framebuffer_green_mask_size;
- else
- rgb.green.size = 8;
-
- rgb.blue.pos = 0;
- if (bpp == 2)
- rgb.blue.size = gfx_fb.u.fb2.framebuffer_blue_mask_size;
- else
- rgb.blue.size = 8;
-
- return (rgb_color_map(&rgb, index));
+ return (rgb_color_map(&rgb_info, index, 0xff));
}
static bool
@@ -957,19 +928,18 @@ int
gfx_fb_cons_clear(struct vis_consclear *ca)
{
int rv;
- uint32_t data, width, height;
+ uint32_t width, height;
#if defined(EFI)
EFI_TPL tpl;
#endif
- data = gfx_fb_color_map(ca->bg_color);
width = gfx_fb.framebuffer_common.framebuffer_width;
height = gfx_fb.framebuffer_common.framebuffer_height;
#if defined(EFI)
tpl = BS->RaiseTPL(TPL_NOTIFY);
#endif
- rv = gfxfb_blt(&data, GfxFbBltVideoFill, 0, 0,
+ rv = gfxfb_blt(&ca->bg_color, GfxFbBltVideoFill, 0, 0,
0, 0, width, height, 0);
#if defined(EFI)
BS->RestoreTPL(tpl);
@@ -1009,17 +979,22 @@ static uint8_t
alpha_blend(uint8_t fg, uint8_t bg, uint8_t alpha)
{
uint16_t blend, h, l;
+ uint8_t max_alpha;
+
+ /* 15/16 bit depths have alpha channel size less than 8 */
+ max_alpha = (1 << (rgb_info.red.size + rgb_info.green.size +
+ rgb_info.blue.size) / 3) - 1;
/* trivial corner cases */
if (alpha == 0)
return (bg);
- if (alpha == 0xFF)
+ if (alpha >= max_alpha)
return (fg);
- blend = (alpha * fg + (0xFF - alpha) * bg);
- /* Division by 0xFF */
+ blend = (alpha * fg + (max_alpha - alpha) * bg);
+ /* Division by max_alpha */
h = blend >> 8;
- l = blend & 0xFF;
- if (h + l >= 0xFF)
+ l = blend & max_alpha;
+ if (h + l >= max_alpha)
h++;
return (h);
}
@@ -1039,9 +1014,6 @@ bitmap_cpy(void *dst, void *src, size_t size)
ps = src;
pd = dst;
- /*
- * we only implement alpha blending for depth 32.
- */
for (i = 0; i < size; i++) {
a = ps[i].Reserved;
pd[i].Red = alpha_blend(ps[i].Red, pd[i].Red, a);
@@ -1163,14 +1135,8 @@ gfx_fb_display_cursor(struct vis_conscursor *ca)
tpl = BS->RaiseTPL(TPL_NOTIFY);
#endif
- fg.p.Reserved = 0;
- fg.p.Red = ca->fg_color.twentyfour[0];
- fg.p.Green = ca->fg_color.twentyfour[1];
- fg.p.Blue = ca->fg_color.twentyfour[2];
- bg.p.Reserved = 0;
- bg.p.Red = ca->bg_color.twentyfour[0];
- bg.p.Green = ca->bg_color.twentyfour[1];
- bg.p.Blue = ca->bg_color.twentyfour[2];
+ bcopy(&ca->fg_color, &fg.p32, sizeof (fg.p32));
+ bcopy(&ca->bg_color, &bg.p32, sizeof (bg.p32));
if (allocate_glyphbuffer(ca->width, ca->height) != NULL) {
if (gfxfb_blt(GlyphBuffer, GfxFbBltVideoToBltBuffer,
@@ -1215,20 +1181,18 @@ isqrt(int num)
void
gfx_fb_setpixel(uint32_t x, uint32_t y)
{
- uint32_t c;
text_color_t fg, bg;
if (plat_stdout_is_framebuffer() == 0)
return;
tem_get_colors((tem_vt_state_t)tems.ts_active, &fg, &bg);
- c = gfx_fb_color_map(fg);
if (x >= gfx_fb.framebuffer_common.framebuffer_width ||
y >= gfx_fb.framebuffer_common.framebuffer_height)
return;
- gfxfb_blt(&c, GfxFbBltVideoFill, 0, 0, x, y, 1, 1, 0);
+ gfxfb_blt(&fg.n, GfxFbBltVideoFill, 0, 0, x, y, 1, 1, 0);
}
/*
@@ -1238,23 +1202,25 @@ void
gfx_fb_drawrect(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2,
uint32_t fill)
{
- uint32_t c;
text_color_t fg, bg;
if (plat_stdout_is_framebuffer() == 0)
return;
tem_get_colors((tem_vt_state_t)tems.ts_active, &fg, &bg);
- c = gfx_fb_color_map(fg);
if (fill != 0) {
- gfxfb_blt(&c, GfxFbBltVideoFill, 0, 0, x1, y1, x2 - x1,
- y2 - y1, 0);
+ gfxfb_blt(&fg.n, GfxFbBltVideoFill,
+ 0, 0, x1, y1, x2 - x1, y2 - y1, 0);
} else {
- gfxfb_blt(&c, GfxFbBltVideoFill, 0, 0, x1, y1, x2 - x1, 1, 0);
- gfxfb_blt(&c, GfxFbBltVideoFill, 0, 0, x1, y2, x2 - x1, 1, 0);
- gfxfb_blt(&c, GfxFbBltVideoFill, 0, 0, x1, y1, 1, y2 - y1, 0);
- gfxfb_blt(&c, GfxFbBltVideoFill, 0, 0, x2, y1, 1, y2 - y1, 0);
+ gfxfb_blt(&fg.n, GfxFbBltVideoFill,
+ 0, 0, x1, y1, x2 - x1, 1, 0);
+ gfxfb_blt(&fg.n, GfxFbBltVideoFill,
+ 0, 0, x1, y2, x2 - x1, 1, 0);
+ gfxfb_blt(&fg.n, GfxFbBltVideoFill,
+ 0, 0, x1, y1, 1, y2 - y1, 0);
+ gfxfb_blt(&fg.n, GfxFbBltVideoFill,
+ 0, 0, x2, y1, 1, y2 - y1, 0);
}
}
diff --git a/usr/src/boot/sys/boot/common/tem.c b/usr/src/boot/sys/boot/common/tem.c
index 0ceb83c72a..2798f2883d 100644
--- a/usr/src/boot/sys/boot/common/tem.c
+++ b/usr/src/boot/sys/boot/common/tem.c
@@ -23,6 +23,7 @@
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright 2016 Joyent, Inc.
+ * Copyright 2021 Toomas Soome <tsoome@me.com>
*/
/*
@@ -55,9 +56,22 @@
* on the physical screen. We only store the character and color data in
* tem_vt_state since the bit2pix conversion only happens when actually
* rendering to the physical framebuffer.
+ *
+ * Color support:
+ * Text mode can only support standard system colors, 4-bit [0-15] indexed.
+ * On framebuffer devices, we can aditionally use [16-255] or truecolor.
+ * Additional colors can be used via CSI 38 and CSI 48 sequences.
+ * CSI 38/48;5 is using indexed colors [0-255], CSI 38/48;2 does
+ * specify color by RGB triple.
+ *
+ * While sending glyphs to display, we need to process glyph attributes:
+ * TEM_ATTR_BOLD will cause BOLD font to be used (or BRIGHT color if we
+ * we use indexed color [0-7]).
+ * We ignore TEM_ATTR_BRIGHT_FG/TEM_ATTR_BRIGHT_BG with RGB colors.
+ * TEM_ATTR_REVERSE and TEM_ATTR_SCREEN_REVERSE will cause fg and bg to be
+ * swapped.
*/
-
#include <stand.h>
#include <sys/ascii.h>
#include <sys/errno.h>
@@ -130,14 +144,16 @@ static void tem_pix_copy(struct tem_vt_state *,
static void tem_pix_cursor(struct tem_vt_state *, short);
static void tem_get_attr(struct tem_vt_state *, text_color_t *,
text_color_t *, text_attr_t *, uint8_t);
-static void tem_get_color(text_color_t *, text_color_t *, term_char_t);
+static void tem_get_color(struct tem_vt_state *,
+ text_color_t *, text_color_t *, term_char_t *);
+static void tem_set_color(text_color_t *, color_t *);
static void tem_pix_align(struct tem_vt_state *);
static void tem_text_display(struct tem_vt_state *, term_char_t *, int,
screen_pos_t, screen_pos_t);
static void tem_text_copy(struct tem_vt_state *,
screen_pos_t, screen_pos_t, screen_pos_t, screen_pos_t,
screen_pos_t, screen_pos_t);
-static void tem_pix_bit2pix(struct tem_vt_state *, term_char_t);
+static void tem_pix_bit2pix(struct tem_vt_state *, term_char_t *);
static void tem_pix_cls_range(struct tem_vt_state *, screen_pos_t, int,
int, screen_pos_t, int, int, boolean_t);
static void tem_pix_cls(struct tem_vt_state *, int,
@@ -867,10 +883,13 @@ tems_get_initial_color(tem_color_t *pcolor)
{
boolean_t inverse, inverse_screen;
unsigned short flags = 0;
+ uint8_t fg, bg;
- pcolor->fg_color = DEFAULT_ANSI_FOREGROUND;
- pcolor->bg_color = DEFAULT_ANSI_BACKGROUND;
- plat_tem_get_colors(&pcolor->fg_color, &pcolor->bg_color);
+ fg = DEFAULT_ANSI_FOREGROUND;
+ bg = DEFAULT_ANSI_BACKGROUND;
+ plat_tem_get_colors(&fg, &bg);
+ pcolor->fg_color.n = fg;
+ pcolor->bg_color.n = bg;
tems_get_inverses(&inverse, &inverse_screen);
if (inverse)
@@ -883,20 +902,20 @@ tems_get_initial_color(tem_color_t *pcolor)
* The reverse attribute is set.
* In case of black on white we want bright white for BG.
*/
- if (pcolor->fg_color == ANSI_COLOR_WHITE)
+ if (pcolor->fg_color.n == ANSI_COLOR_WHITE)
flags |= TEM_ATTR_BRIGHT_BG;
/*
* For white on black, unset the bright attribute we
* had set to have bright white background.
*/
- if (pcolor->fg_color == ANSI_COLOR_BLACK)
+ if (pcolor->fg_color.n == ANSI_COLOR_BLACK)
flags &= ~TEM_ATTR_BRIGHT_BG;
} else {
/*
* In case of black on white we want bright white for BG.
*/
- if (pcolor->bg_color == ANSI_COLOR_WHITE)
+ if (pcolor->bg_color.n == ANSI_COLOR_WHITE)
flags |= TEM_ATTR_BRIGHT_BG;
}
@@ -1165,12 +1184,23 @@ tem_setparam(struct tem_vt_state *tem, int count, int newparam)
* Colors 16-255 are used without translation.
*/
static void
-tem_select_color(struct tem_vt_state *tem, text_color_t color, bool fg)
+tem_select_color(struct tem_vt_state *tem, int color, bool fg)
{
- if (fg == true)
- tem->tvs_fg_color = color;
- else
- tem->tvs_bg_color = color;
+ if (color < 0 || color > 255)
+ return;
+
+ /* VGA text mode only does support 16 colors. */
+ if (tems.ts_display_mode == VIS_TEXT && color > 15)
+ return;
+
+ /* Switch to use indexed colors. */
+ if (fg == true) {
+ tem->tvs_flags &= ~TEM_ATTR_RGB_FG;
+ tem->tvs_fg_color.n = color;
+ } else {
+ tem->tvs_flags &= ~TEM_ATTR_RGB_BG;
+ tem->tvs_bg_color.n = color;
+ }
/*
* For colors 0-7, make sure the BRIGHT attribute is not set.
@@ -1188,10 +1218,10 @@ tem_select_color(struct tem_vt_state *tem, text_color_t color, bool fg)
*/
if (color < 16) {
if (fg == true) {
- tem->tvs_fg_color -= 8;
+ tem->tvs_fg_color.n -= 8;
tem->tvs_flags |= TEM_ATTR_BRIGHT_FG;
} else {
- tem->tvs_bg_color -= 8;
+ tem->tvs_bg_color.n -= 8;
tem->tvs_flags |= TEM_ATTR_BRIGHT_BG;
}
}
@@ -1206,6 +1236,7 @@ tem_selgraph(struct tem_vt_state *tem)
int curparam;
int count = 0;
int param;
+ int r, g, b;
tem->tvs_state = A_STATE_START;
@@ -1274,23 +1305,53 @@ tem_selgraph(struct tem_vt_state *tem)
case 35: /* magenta (light magenta) foreground */
case 36: /* cyan (light cyan) foreground */
case 37: /* white (bright white) foreground */
- tem->tvs_fg_color = param - 30;
+ tem->tvs_fg_color.n = param - 30;
tem->tvs_flags &= ~TEM_ATTR_BRIGHT_FG;
+ tem->tvs_flags &= ~TEM_ATTR_RGB_FG;
break;
case 38:
- /* We should have at least 3 parameters */
- if (curparam < 3)
+ /*
+ * We should have 3 parameters for 256 colors and
+ * 5 parameters for 24-bit colors.
+ */
+ if (curparam < 3) {
+ curparam = 0;
break;
+ }
/*
- * 256 and truecolor needs depth at least 24, but
+ * 256 and truecolor needs depth > 8, but
* we still need to process the sequence.
*/
count++;
curparam--;
param = tem->tvs_params[count];
switch (param) {
+ case 2: /* RGB colors */
+ if (curparam < 4) {
+ curparam = 0;
+ break;
+ }
+ r = tem->tvs_params[++count];
+ g = tem->tvs_params[++count];
+ b = tem->tvs_params[++count];
+ curparam -= 3;
+ if (r < 0 || r > 255 || g < 0 || g > 255 ||
+ b < 0 || b > 255)
+ break;
+
+ if (tems.ts_display_mode == VIS_PIXEL &&
+ tems.ts_pdepth > 8) {
+ tem->tvs_flags |= TEM_ATTR_RGB_FG;
+ tem->tvs_flags &= ~TEM_ATTR_BRIGHT_FG;
+ tem->tvs_fg_color.rgb.a =
+ tem->tvs_alpha;
+ tem->tvs_fg_color.rgb.r = r;
+ tem->tvs_fg_color.rgb.g = g;
+ tem->tvs_fg_color.rgb.b = b;
+ }
+ break;
case 5: /* 256 colors */
count++;
curparam--;
@@ -1298,6 +1359,7 @@ tem_selgraph(struct tem_vt_state *tem)
true);
break;
default:
+ curparam = 0;
break;
}
break;
@@ -1307,6 +1369,7 @@ tem_selgraph(struct tem_vt_state *tem)
* Reset the foreground colour and brightness.
*/
tem->tvs_fg_color = tems.ts_init_color.fg_color;
+ tem->tvs_flags &= ~TEM_ATTR_RGB_FG;
if (tems.ts_init_color.a_flags & TEM_ATTR_BRIGHT_FG)
tem->tvs_flags |= TEM_ATTR_BRIGHT_FG;
else
@@ -1321,23 +1384,54 @@ tem_selgraph(struct tem_vt_state *tem)
case 45: /* magenta (light magenta) background */
case 46: /* cyan (light cyan) background */
case 47: /* white (bright white) background */
- tem->tvs_bg_color = param - 40;
+ tem->tvs_bg_color.n = param - 40;
+ tem->tvs_flags &= ~TEM_ATTR_RGB_BG;
tem->tvs_flags &= ~TEM_ATTR_BRIGHT_BG;
break;
case 48:
+ /*
+ * We should have 3 parameters for 256 colors and
+ * 5 parameters for 24-bit colors.
+ */
/* We should have at least 3 parameters */
- if (curparam < 3)
+ if (curparam < 3) {
+ curparam = 0;
break;
+ }
/*
- * 256 and truecolor needs depth at least 24, but
+ * 256 and truecolor needs depth > 8, but
* we still need to process the sequence.
*/
count++;
curparam--;
param = tem->tvs_params[count];
switch (param) {
+ case 2: /* RGB colors */
+ if (curparam < 4) {
+ curparam = 0;
+ break;
+ }
+ r = tem->tvs_params[++count];
+ g = tem->tvs_params[++count];
+ b = tem->tvs_params[++count];
+ curparam -= 3;
+ if (r < 0 || r > 255 || g < 0 || g > 255 ||
+ b < 0 || b > 255)
+ break;
+
+ if (tems.ts_display_mode == VIS_PIXEL &&
+ tems.ts_pdepth > 8) {
+ tem->tvs_flags |= TEM_ATTR_RGB_BG;
+ tem->tvs_flags &= ~TEM_ATTR_BRIGHT_BG;
+ tem->tvs_bg_color.rgb.a =
+ tem->tvs_alpha;
+ tem->tvs_bg_color.rgb.r = r;
+ tem->tvs_bg_color.rgb.g = g;
+ tem->tvs_bg_color.rgb.b = b;
+ }
+ break;
case 5: /* 256 colors */
count++;
curparam--;
@@ -1345,6 +1439,7 @@ tem_selgraph(struct tem_vt_state *tem)
false);
break;
default:
+ curparam = 0;
break;
}
break;
@@ -1354,6 +1449,7 @@ tem_selgraph(struct tem_vt_state *tem)
* Reset the background colour and brightness.
*/
tem->tvs_bg_color = tems.ts_init_color.bg_color;
+ tem->tvs_flags &= ~TEM_ATTR_RGB_BG;
if (tems.ts_init_color.a_flags & TEM_ATTR_BRIGHT_BG)
tem->tvs_flags |= TEM_ATTR_BRIGHT_BG;
else
@@ -1368,8 +1464,9 @@ tem_selgraph(struct tem_vt_state *tem)
case 95: /* magenta (light magenta) foreground */
case 96: /* cyan (light cyan) foreground */
case 97: /* white (bright white) foreground */
- tem->tvs_fg_color = param - 90;
+ tem->tvs_fg_color.n = param - 90;
tem->tvs_flags |= TEM_ATTR_BRIGHT_FG;
+ tem->tvs_flags &= ~TEM_ATTR_RGB_FG;
break;
case 100: /* black (grey) background */
@@ -1380,8 +1477,9 @@ tem_selgraph(struct tem_vt_state *tem)
case 105: /* magenta (light magenta) background */
case 106: /* cyan (light cyan) background */
case 107: /* white (bright white) background */
- tem->tvs_bg_color = param - 100;
+ tem->tvs_bg_color.n = param - 100;
tem->tvs_flags |= TEM_ATTR_BRIGHT_BG;
+ tem->tvs_flags &= ~TEM_ATTR_RGB_BG;
break;
default:
@@ -2008,8 +2106,8 @@ tem_copy_width(term_char_t *src, term_char_t *dst, int cols)
* and colors.
*/
if (src[width].tc_char != dst[width].tc_char ||
- src[width].tc_fg_color != dst[width].tc_fg_color ||
- src[width].tc_bg_color != dst[width].tc_bg_color) {
+ src[width].tc_fg_color.n != dst[width].tc_fg_color.n ||
+ src[width].tc_bg_color.n != dst[width].tc_bg_color.n) {
break;
}
width--;
@@ -2130,6 +2228,7 @@ tem_text_display(struct tem_vt_state *tem __unused, term_char_t *string,
struct vis_consdisplay da;
int i;
tem_char_t c;
+ text_color_t bg, fg;
if (count == 0)
return;
@@ -2140,7 +2239,9 @@ tem_text_display(struct tem_vt_state *tem __unused, term_char_t *string,
da.col = col;
for (i = 0; i < count; i++) {
- tem_get_color(&da.fg_color, &da.bg_color, string[i]);
+ tem_get_color(tem, &fg, &bg, &string[i]);
+ tem_set_color(&fg, &da.fg_color);
+ tem_set_color(&bg, &da.bg_color);
c = TEM_CHAR(string[i].tc_char);
tems_display(&da);
da.col++;
@@ -2221,7 +2322,7 @@ tem_pix_display(struct tem_vt_state *tem,
da.col = (col * da.width) + tems.ts_p_offset.x;
for (i = 0; i < count; i++) {
- tem_callback_bit2pix(tem, string[i]);
+ tem_callback_bit2pix(tem, &string[i]);
tems_display(&da);
da.col += da.width;
}
@@ -2288,15 +2389,12 @@ tem_pix_copy(struct tem_vt_state *tem,
}
static void
-tem_pix_bit2pix(struct tem_vt_state *tem, term_char_t c)
+tem_pix_bit2pix(struct tem_vt_state *tem, term_char_t *c)
{
text_color_t fg, bg;
- fg = DEFAULT_ANSI_FOREGROUND;
- bg = DEFAULT_ANSI_BACKGROUND;
-
- tem_get_color(&fg, &bg, c);
- bit_to_pix32(tem, c.tc_char, fg, bg);
+ tem_get_color(tem, &fg, &bg, c);
+ bit_to_pix32(tem, c->tc_char, fg, bg);
}
@@ -2375,10 +2473,8 @@ tem_cls(struct tem_vt_state *tem)
TEM_ATTR_SCREEN_REVERSE);
c.tc_char = TEM_ATTR(attr);
- fg_color = DEFAULT_ANSI_FOREGROUND;
- bg_color = DEFAULT_ANSI_BACKGROUND;
- tem_get_color(&fg_color, &bg_color, c);
- cl.bg_color = bg_color;
+ tem_get_color(tem, &fg_color, &bg_color, &c);
+ tem_set_color(&bg_color, &cl.bg_color);
(void) tems_cls(&cl);
tem->tvs_c_cursor.row = 0;
@@ -2514,6 +2610,7 @@ tem_reset_emulator(struct tem_vt_state *tem, boolean_t init_color)
if (init_color) {
/* use initial settings */
+ tem->tvs_alpha = 0xff;
tem->tvs_fg_color = tems.ts_init_color.fg_color;
tem->tvs_bg_color = tems.ts_init_color.bg_color;
tem->tvs_flags = tems.ts_init_color.a_flags;
@@ -2612,7 +2709,6 @@ static void
tem_pix_cursor(struct tem_vt_state *tem, short action)
{
struct vis_conscursor ca;
- uint32_t color;
text_color_t fg, bg;
term_char_t c;
text_attr_t attr;
@@ -2628,18 +2724,9 @@ tem_pix_cursor(struct tem_vt_state *tem, short action)
TEM_ATTR_REVERSE);
c.tc_char = TEM_ATTR(attr);
- fg = DEFAULT_ANSI_FOREGROUND;
- bg = DEFAULT_ANSI_BACKGROUND;
- tem_get_color(&fg, &bg, c);
-
- color = tems.ts_color_map(fg);
- ca.fg_color.twentyfour[0] = (color >> 16) & 0xFF;
- ca.fg_color.twentyfour[1] = (color >> 8) & 0xFF;
- ca.fg_color.twentyfour[2] = color & 0xFF;
- color = tems.ts_color_map(bg);
- ca.bg_color.twentyfour[0] = (color >> 16) & 0xFF;
- ca.bg_color.twentyfour[1] = (color >> 8) & 0xFF;
- ca.bg_color.twentyfour[2] = color & 0xFF;
+ tem_get_color(tem, &fg, &bg, &c);
+ tem_set_color(&fg, &ca.fg_color);
+ tem_set_color(&bg, &ca.bg_color);
ca.action = action;
@@ -2662,17 +2749,12 @@ tem_pix_cursor(struct tem_vt_state *tem, short action)
static void
bit_to_pix32(struct tem_vt_state *tem,
- tem_char_t c,
- text_color_t fg_color4,
- text_color_t bg_color4)
+ tem_char_t c, text_color_t fg, text_color_t bg)
{
- uint32_t fg_color32, bg_color32, *dest;
-
- fg_color32 = (0xFF << 24) | tems.ts_color_map(fg_color4);
- bg_color32 = (0xFF << 24) | tems.ts_color_map(bg_color4);
+ uint32_t *dest;
dest = (uint32_t *)tem->tvs_pix_data;
- font_bit_to_pix32(&tems.ts_font, dest, c, fg_color32, bg_color32);
+ font_bit_to_pix32(&tems.ts_font, dest, c, fg.n, bg.n);
}
/*
@@ -2690,19 +2772,18 @@ tem_get_attr(struct tem_vt_state *tem, text_color_t *fg,
*bg = tem->tvs_bg_color;
}
- if (attr == NULL)
- return;
-
- *attr = tem->tvs_flags;
+ if (attr != NULL)
+ *attr = tem->tvs_flags;
}
static void
-tem_get_color(text_color_t *fg, text_color_t *bg, term_char_t c)
+tem_get_color(struct tem_vt_state *tem, text_color_t *fg, text_color_t *bg,
+ term_char_t *c)
{
bool bold_font;
- *fg = c.tc_fg_color;
- *bg = c.tc_bg_color;
+ *fg = c->tc_fg_color;
+ *bg = c->tc_bg_color;
bold_font = tems.ts_font.vf_map_count[VFNT_MAP_BOLD] != 0;
@@ -2712,19 +2793,55 @@ tem_get_color(text_color_t *fg, text_color_t *bg, term_char_t c)
* The bright color is traditionally used with TEM_ATTR_BOLD,
* in case there is no bold font.
*/
- if (c.tc_fg_color < XLATE_NCOLORS) {
- if (TEM_ATTR_ISSET(c.tc_char, TEM_ATTR_BRIGHT_FG) ||
- (TEM_ATTR_ISSET(c.tc_char, TEM_ATTR_BOLD) && !bold_font))
- *fg = brt_xlate[c.tc_fg_color];
+ if (!TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_RGB_FG) &&
+ c->tc_fg_color.n < XLATE_NCOLORS) {
+ if (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_BRIGHT_FG) ||
+ (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_BOLD) && !bold_font))
+ fg->n = brt_xlate[c->tc_fg_color.n];
else
- *fg = dim_xlate[c.tc_fg_color];
+ fg->n = dim_xlate[c->tc_fg_color.n];
}
- if (c.tc_bg_color < XLATE_NCOLORS) {
- if (TEM_ATTR_ISSET(c.tc_char, TEM_ATTR_BRIGHT_BG))
- *bg = brt_xlate[c.tc_bg_color];
+ if (!TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_RGB_BG) &&
+ c->tc_bg_color.n < XLATE_NCOLORS) {
+ if (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_BRIGHT_BG))
+ bg->n = brt_xlate[c->tc_bg_color.n];
else
- *bg = dim_xlate[c.tc_bg_color];
+ bg->n = dim_xlate[c->tc_bg_color.n];
+ }
+
+ if (tems.ts_display_mode == VIS_TEXT)
+ return;
+
+ /*
+ * Translate fg and bg to RGB colors.
+ */
+ if (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_RGB_FG)) {
+ fg->n = rgb_to_color(&rgb_info,
+ fg->rgb.a, fg->rgb.r, fg->rgb.g, fg->rgb.b);
+ } else {
+ fg->n = rgb_color_map(&rgb_info, fg->n, tem->tvs_alpha);
+ }
+
+ if (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_RGB_BG)) {
+ bg->n = rgb_to_color(&rgb_info,
+ bg->rgb.a, bg->rgb.r, bg->rgb.g, bg->rgb.b);
+ } else {
+ bg->n = rgb_color_map(&rgb_info, bg->n, tem->tvs_alpha);
+ }
+}
+
+static void
+tem_set_color(text_color_t *t, color_t *c)
+{
+ switch (tems.ts_pdepth) {
+ case 4:
+ c->four = t->n & 0xFF;
+ break;
+ default:
+ /* gfx module is expecting all pixel data in 32-bit colors */
+ *(uint32_t *)c = t->n;
+ break;
}
}
@@ -2738,7 +2855,7 @@ tem_get_colors(tem_vt_state_t tem_arg, text_color_t *fg, text_color_t *bg)
tem_get_attr(tem, &c.tc_fg_color, &c.tc_bg_color, &attr,
TEM_ATTR_REVERSE);
c.tc_char = TEM_ATTR(attr);
- tem_get_color(fg, bg, c);
+ tem_get_color(tem, fg, bg, &c);
}
/*
@@ -2777,7 +2894,7 @@ tem_pix_cls_range(struct tem_vt_state *tem,
/* Make sure we will not draw underlines */
c.tc_char = TEM_ATTR(attr & ~TEM_ATTR_UNDERLINE) | ' ';
- tem_callback_bit2pix(tem, c);
+ tem_callback_bit2pix(tem, &c);
da.data = (uint8_t *)tem->tvs_pix_data;
for (i = 0; i < nrows; i++, row++) {
@@ -2820,9 +2937,12 @@ tem_virtual_cls(struct tem_vt_state *tem, size_t count,
screen_pos_t row, screen_pos_t col)
{
term_char_t c;
+ text_attr_t attr;
- c.tc_char = ' ';
- tem_get_colors((tem_vt_state_t)tem, &c.tc_fg_color, &c.tc_bg_color);
+ tem_get_attr(tem, &c.tc_fg_color, &c.tc_bg_color, &attr,
+ TEM_ATTR_SCREEN_REVERSE);
+ /* Make sure we will not draw underlines */
+ c.tc_char = TEM_ATTR(attr & ~TEM_ATTR_UNDERLINE) | ' ';
while (count > 0) {
tem_virtual_display(tem, &c, 1, row, col);
diff --git a/usr/src/boot/sys/boot/efi/libefi/efi_console.c b/usr/src/boot/sys/boot/efi/libefi/efi_console.c
index 13c2ad0635..84a384e806 100644
--- a/usr/src/boot/sys/boot/efi/libefi/efi_console.c
+++ b/usr/src/boot/sys/boot/efi/libefi/efi_console.c
@@ -297,7 +297,7 @@ efi_text_cons_clear(struct vis_consclear *ca)
UINTN attr = conout->Mode->Attribute & 0x0F;
uint8_t bg;
- bg = solaris_color_to_efi_color[ca->bg_color & 0xF] & 0x7;
+ bg = solaris_color_to_efi_color[ca->bg_color.four & 0xF] & 0x7;
attr = EFI_TEXT_ATTR(attr, bg);
st = conout->SetAttribute(conout, attr);
@@ -338,8 +338,8 @@ efi_text_cons_display(struct vis_consdisplay *da)
da->width--;
data = (tem_char_t *)da->data;
- fg = solaris_color_to_efi_color[da->fg_color & 0xf];
- bg = solaris_color_to_efi_color[da->bg_color & 0xf] & 0x7;
+ fg = solaris_color_to_efi_color[da->fg_color.four & 0xf];
+ bg = solaris_color_to_efi_color[da->bg_color.four & 0xf] & 0x7;
attr = EFI_TEXT_ATTR(fg, bg);
st = conout->SetAttribute(conout, attr);
diff --git a/usr/src/boot/sys/boot/i386/libi386/vbe.c b/usr/src/boot/sys/boot/i386/libi386/vbe.c
index a0514aebec..19561bfce9 100644
--- a/usr/src/boot/sys/boot/i386/libi386/vbe.c
+++ b/usr/src/boot/sys/boot/i386/libi386/vbe.c
@@ -39,6 +39,7 @@
#include "gfx_fb.h" /* for EDID */
#include "vbe.h"
#include <sys/font.h>
+#include <sys/rgb.h>
#include <sys/vgareg.h>
#include <sys/vgasubr.h>
@@ -489,6 +490,25 @@ vbe_set_mode(int modenum)
gfx_fb.u.fb2.framebuffer_blue_mask_size = mi.BlueMaskSize;
}
+ /*
+ * Support for color mapping.
+ * For 8, 24 and 32 bit depth, use mask size 8.
+ * 15/16 bit depth needs to use mask size from mode, or we will
+ * lose color information from 32-bit to 15/16 bit translation.
+ */
+ if (mi.BitsPerPixel == 15 || mi.BitsPerPixel == 16) {
+ rgb_info.red.size = gfx_fb.u.fb2.framebuffer_red_mask_size;
+ rgb_info.green.size = gfx_fb.u.fb2.framebuffer_green_mask_size;
+ rgb_info.blue.size = gfx_fb.u.fb2.framebuffer_blue_mask_size;
+ } else {
+ rgb_info.red.size = 8;
+ rgb_info.green.size = 8;
+ rgb_info.blue.size = 8;
+ }
+ rgb_info.red.pos = 16;
+ rgb_info.green.pos = 8;
+ rgb_info.blue.pos = 0;
+
return (0);
}
diff --git a/usr/src/boot/sys/boot/i386/libi386/vidconsole.c b/usr/src/boot/sys/boot/i386/libi386/vidconsole.c
index dbdbcbc699..490c4571a4 100644
--- a/usr/src/boot/sys/boot/i386/libi386/vidconsole.c
+++ b/usr/src/boot/sys/boot/i386/libi386/vidconsole.c
@@ -253,7 +253,7 @@ vidc_text_cons_clear(struct vis_consclear *ca)
uint16_t val;
int i;
- val = (solaris_color_to_pc_color[ca->bg_color & 0xf] << 4) |
+ val = (solaris_color_to_pc_color[ca->bg_color.four & 0xf] << 4) |
DEFAULT_FGCOLOR;
val = (val << 8) | ' ';
@@ -470,8 +470,8 @@ vidc_text_cons_display(struct vis_consdisplay *da)
} *addr;
data = (tem_char_t *)da->data;
- attr = (solaris_color_to_pc_color[da->bg_color & 0xf] << 4) |
- solaris_color_to_pc_color[da->fg_color & 0xf];
+ attr = (solaris_color_to_pc_color[da->bg_color.four & 0xf] << 4) |
+ solaris_color_to_pc_color[da->fg_color.four & 0xf];
addr = (struct cgatext *)vgatext + (da->row * TEXT_COLS + da->col);
for (i = 0; i < da->width; i++) {
@@ -574,7 +574,7 @@ vidc_vbe_cons_put_cmap(struct vis_cmap *cm)
int idx;
/* Pick RGB from cmap4_to_24 */
- c = rgb_color_map(&rgb, i);
+ c = rgb_color_map(&rgb, i, 0);
/* The first 16 colors need to be in VGA color order. */
if (i < NCOLORS)
idx = solaris_color_to_pc_color[i];
diff --git a/usr/src/boot/sys/sys/tem_impl.h b/usr/src/boot/sys/sys/tem_impl.h
index 2afcb5df0a..3a13a7df0e 100644
--- a/usr/src/boot/sys/sys/tem_impl.h
+++ b/usr/src/boot/sys/sys/tem_impl.h
@@ -58,7 +58,6 @@ extern "C" {
* 21-31 attributes
*/
-typedef uint32_t tem_char_t; /* 32bit char to support UTF-8 */
#define TEM_ATTR_MASK 0x7FF
#define TEM_CHAR(c) ((c) & 0x1fffff)
#define TEM_CHAR_ATTR(c) (((c) >> 21) & TEM_ATTR_MASK)
@@ -85,6 +84,8 @@ typedef uint32_t tem_char_t; /* 32bit char to support UTF-8 */
#define TEM_ATTR_BRIGHT_BG 0x0040
#define TEM_ATTR_TRANSPARENT 0x0080
#define TEM_ATTR_IMAGE 0x0100
+#define TEM_ATTR_RGB_FG 0x0200
+#define TEM_ATTR_RGB_BG 0x0400
#define ANSI_COLOR_BLACK 0
#define ANSI_COLOR_RED 1
@@ -128,7 +129,16 @@ typedef uint32_t tem_char_t; /* 32bit char to support UTF-8 */
#define BUF_LEN 160 /* Two lines of data can be processed at a time */
-typedef uint8_t text_color_t;
+typedef uint32_t tem_char_t; /* 32bit char to support UTF-8 */
+typedef union {
+ uint32_t n;
+ struct bgra {
+ uint8_t b;
+ uint8_t g;
+ uint8_t r;
+ uint8_t a;
+ } rgb;
+} text_color_t;
typedef uint16_t text_attr_t;
typedef struct tem_color {
@@ -164,6 +174,7 @@ typedef struct term_char {
*/
struct tem_vt_state {
uint8_t tvs_fbmode; /* framebuffer mode */
+ uint8_t tvs_alpha; /* rgb alpha channel */
text_attr_t tvs_flags; /* flags for this x3.64 terminal */
int tvs_state; /* state in output esc seq processing */
bool tvs_gotparam; /* does output esc seq have a param */
@@ -184,8 +195,10 @@ struct tem_vt_state {
int tvs_outindex; /* index into a_outbuf */
void *tvs_pix_data; /* pointer to tmp bitmap area */
unsigned tvs_pix_data_size;
- text_color_t tvs_fg_color;
- text_color_t tvs_bg_color;
+
+ text_color_t tvs_fg_color; /* console foreground */
+ text_color_t tvs_bg_color; /* console background */
+
int tvs_first_line; /* kernel console output begins */
term_char_t *tvs_screen_buf; /* whole screen buffer */
@@ -205,7 +218,7 @@ typedef struct tem_callbacks {
screen_pos_t, screen_pos_t, screen_pos_t, screen_pos_t,
screen_pos_t, screen_pos_t);
void (*tsc_cursor)(struct tem_vt_state *, short);
- void (*tsc_bit2pix)(struct tem_vt_state *, term_char_t);
+ void (*tsc_bit2pix)(struct tem_vt_state *, term_char_t *);
void (*tsc_cls)(struct tem_vt_state *, int, screen_pos_t, screen_pos_t);
} tem_callbacks_t;
diff --git a/usr/src/common/font/font.c b/usr/src/common/font/font.c
index b3d1041b52..ac3b08926d 100644
--- a/usr/src/common/font/font.c
+++ b/usr/src/common/font/font.c
@@ -106,15 +106,41 @@ const text_cmap_t cmap4_to_24 = {
};
/* END CSTYLED */
-static uint32_t
-rgb_to_color(const rgb_t *rgb, uint32_t r, uint32_t g, uint32_t b)
+/* RGB configuration from boot loader */
+rgb_t rgb_info = {
+ .red = { .size = 8, .pos = 16 },
+ .green = { .size = 8, .pos = 8 },
+ .blue = { .size = 8, .pos = 0 }
+};
+
+/*
+ * Map r, g, b to RGB value.
+ */
+uint32_t
+rgb_to_color(const rgb_t *rgb, uint32_t a, uint32_t r, uint32_t g, uint32_t b)
{
uint32_t color;
int pos, size;
+ color = 0;
+ if (a != 0) {
+ if (rgb->red.pos != 0 &&
+ rgb->green.pos != 0 &&
+ rgb->blue.pos != 0) {
+ pos = 0;
+ size = MIN(rgb->red.pos,
+ MIN(rgb->green.pos, rgb->blue.pos));
+ } else {
+ pos = 24;
+ size = (rgb->red.size + rgb->green.size +
+ rgb->blue.size) / 3;
+ }
+ color = ((a * ((1 << size) - 1)) / 0xff) << pos;
+ }
+
pos = rgb->red.pos;
size = rgb->red.size;
- color = ((r * ((1 << size) - 1)) / 0xff) << pos;
+ color |= ((r * ((1 << size) - 1)) / 0xff) << pos;
pos = rgb->green.pos;
size = rgb->green.size;
@@ -128,12 +154,12 @@ rgb_to_color(const rgb_t *rgb, uint32_t r, uint32_t g, uint32_t b)
}
uint32_t
-rgb_color_map(const rgb_t *rgb, uint8_t index)
+rgb_color_map(const rgb_t *rgb, uint8_t index, uint8_t alpha)
{
uint32_t color, code, gray, level;
if (index < 16) {
- color = rgb_to_color(rgb, cmap4_to_24.red[index],
+ color = rgb_to_color(rgb, alpha, cmap4_to_24.red[index],
cmap4_to_24.green[index], cmap4_to_24.blue[index]);
return (color);
}
@@ -152,8 +178,8 @@ rgb_color_map(const rgb_t *rgb, uint8_t index)
red = red ? (red * 40 + 55) : 0;
green = green ? (green * 40 + 55) : 0;
blue = blue ? (blue * 40 + 55) : 0;
- color = rgb_to_color(rgb, red, green,
- blue);
+ color = rgb_to_color(rgb, alpha,
+ red, green, blue);
return (color);
}
}
@@ -167,7 +193,7 @@ rgb_color_map(const rgb_t *rgb, uint8_t index)
if (code == index)
break;
}
- return (rgb_to_color(rgb, level, level, level));
+ return (rgb_to_color(rgb, alpha, level, level, level));
}
/*
* Fonts are statically linked with this module. At some point an
@@ -365,8 +391,8 @@ font_bit_to_pix4(
struct font *f,
uint8_t *dest,
uint32_t c,
- uint8_t fg_color,
- uint8_t bg_color)
+ uint32_t fg_color,
+ uint32_t bg_color)
{
uint32_t row;
int byte;
@@ -426,8 +452,8 @@ font_bit_to_pix8(
struct font *f,
uint8_t *dest,
uint32_t c,
- uint8_t fg_color,
- uint8_t bg_color)
+ uint32_t fg_color,
+ uint32_t bg_color)
{
uint32_t row;
int byte;
@@ -489,8 +515,8 @@ font_bit_to_pix16(
struct font *f,
uint16_t *dest,
uint32_t c,
- uint16_t fg_color16,
- uint16_t bg_color16)
+ uint32_t fg_color16,
+ uint32_t bg_color16)
{
uint32_t row;
int byte;
diff --git a/usr/src/uts/common/io/tem.c b/usr/src/uts/common/io/tem.c
index b91952fc32..417a989f63 100644
--- a/usr/src/uts/common/io/tem.c
+++ b/usr/src/uts/common/io/tem.c
@@ -964,16 +964,20 @@ tems_get_initial_color(tem_color_t *pcolor)
{
boolean_t inverse, inverse_screen;
unsigned short flags = 0;
+ uint8_t fg, bg;
- pcolor->fg_color = DEFAULT_ANSI_FOREGROUND;
- pcolor->bg_color = DEFAULT_ANSI_BACKGROUND;
+ fg = DEFAULT_ANSI_FOREGROUND;
+ bg = DEFAULT_ANSI_BACKGROUND;
#ifndef _HAVE_TEM_FIRMWARE
/*
* _HAVE_TEM_FIRMWARE is defined on SPARC, at this time, the
* plat_tem_get_colors() is implemented only on x86.
*/
- plat_tem_get_colors(&pcolor->fg_color, &pcolor->bg_color);
+
+ plat_tem_get_colors(&fg, &bg);
#endif
+ pcolor->fg_color.n = fg;
+ pcolor->bg_color.n = bg;
tems_get_inverses(&inverse, &inverse_screen);
if (inverse)
@@ -1001,16 +1005,16 @@ tems_get_initial_color(tem_color_t *pcolor)
}
#else
if (flags != 0) {
- if (pcolor->fg_color == ANSI_COLOR_WHITE)
+ if (pcolor->fg_color.n == ANSI_COLOR_WHITE)
flags |= TEM_ATTR_BRIGHT_BG;
- if (pcolor->fg_color == ANSI_COLOR_BLACK)
+ if (pcolor->fg_color.n == ANSI_COLOR_BLACK)
flags &= ~TEM_ATTR_BRIGHT_BG;
} else {
/*
* In case of black on white we want bright white for BG.
*/
- if (pcolor->bg_color == ANSI_COLOR_WHITE)
+ if (pcolor->bg_color.n == ANSI_COLOR_WHITE)
flags |= TEM_ATTR_BRIGHT_BG;
}
#endif
diff --git a/usr/src/uts/common/io/tem_safe.c b/usr/src/uts/common/io/tem_safe.c
index 73f4604519..7b8730aa08 100644
--- a/usr/src/uts/common/io/tem_safe.c
+++ b/usr/src/uts/common/io/tem_safe.c
@@ -26,6 +26,7 @@
/*
* Copyright 2016 Joyent, Inc.
+ * Copyright 2021 Toomas Soome <tsoome@me.com>
*/
/*
@@ -58,6 +59,20 @@
*
* ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
* called_from == CALLED_FROM_STANDALONE);
+ *
+ * Color support:
+ * Text mode can only support standard system colors, 4-bit [0-15] indexed.
+ * On framebuffer devices, we can aditionally use [16-255] or truecolor.
+ * Additional colors can be used via CSI 38 and CSI 48 sequences.
+ * CSI 38/48;5 is using indexed colors [0-255], CSI 38/48;2 does
+ * specify color by RGB triple.
+ *
+ * While sending glyphs to display, we need to process glyph attributes:
+ * TEM_ATTR_BOLD will cause BOLD font to be used (or BRIGHT color if we
+ * we use indexed color [0-7]).
+ * We ignore TEM_ATTR_BRIGHT_FG/TEM_ATTR_BRIGHT_BG with RGB colors.
+ * TEM_ATTR_REVERSE and TEM_ATTR_SCREEN_REVERSE will cause fg and bg to be
+ * swapped.
*/
#include <sys/types.h>
@@ -139,7 +154,9 @@ static void tem_safe_bell(struct tem_vt_state *tem,
enum called_from called_from);
static void tem_safe_pix_clear_prom_output(struct tem_vt_state *tem,
cred_t *credp, enum called_from called_from);
-static void tem_safe_get_color(text_color_t *, text_color_t *, term_char_t);
+static void tem_safe_get_color(struct tem_vt_state *,
+ text_color_t *, text_color_t *, term_char_t *);
+static void tem_safe_set_color(text_color_t *, color_t *);
static void tem_safe_virtual_cls(struct tem_vt_state *, int, screen_pos_t,
screen_pos_t);
@@ -165,8 +182,6 @@ static void bit_to_pix32(struct tem_vt_state *tem, tem_char_t c,
cmap4_to_24.green[pix4] << 8 | \
cmap4_to_24.blue[pix4])
-#define INVERSE(ch) (ch ^ 0xff)
-
#define tem_safe_callback_display (*tems.ts_callbacks->tsc_display)
#define tem_safe_callback_copy (*tems.ts_callbacks->tsc_copy)
#define tem_safe_callback_cursor (*tems.ts_callbacks->tsc_cursor)
@@ -524,12 +539,23 @@ tem_safe_setparam(struct tem_vt_state *tem, int count, int newparam)
* Colors 16-255 are used without translation.
*/
static void
-tem_select_color(struct tem_vt_state *tem, text_color_t color, boolean_t fg)
+tem_select_color(struct tem_vt_state *tem, int color, boolean_t fg)
{
- if (fg == B_TRUE)
- tem->tvs_fg_color = color;
- else
- tem->tvs_bg_color = color;
+ if (color < 0 || color > 255)
+ return;
+
+ /* VGA text mode only does support 16 colors. */
+ if (tems.ts_display_mode == VIS_TEXT && color > 15)
+ return;
+
+ /* Switch to use indexed colors. */
+ if (fg == B_TRUE) {
+ tem->tvs_flags &= ~TEM_ATTR_RGB_FG;
+ tem->tvs_fg_color.n = color;
+ } else {
+ tem->tvs_flags &= ~TEM_ATTR_RGB_BG;
+ tem->tvs_bg_color.n = color;
+ }
/*
* For colors 0-7, make sure the BRIGHT attribute is not set.
@@ -547,10 +573,10 @@ tem_select_color(struct tem_vt_state *tem, text_color_t color, boolean_t fg)
*/
if (color < 16) {
if (fg == B_TRUE) {
- tem->tvs_fg_color -= 8;
+ tem->tvs_fg_color.n -= 8;
tem->tvs_flags |= TEM_ATTR_BRIGHT_FG;
} else {
- tem->tvs_bg_color -= 8;
+ tem->tvs_bg_color.n -= 8;
tem->tvs_flags |= TEM_ATTR_BRIGHT_BG;
}
}
@@ -565,6 +591,7 @@ tem_safe_selgraph(struct tem_vt_state *tem)
int curparam;
int count = 0;
int param;
+ int r, g, b;
tem->tvs_state = A_STATE_START;
@@ -632,14 +659,20 @@ tem_safe_selgraph(struct tem_vt_state *tem)
case 35: /* magenta (light magenta) foreground */
case 36: /* cyan (light cyan) foreground */
case 37: /* white (bright white) foreground */
- tem->tvs_fg_color = param - 30;
+ tem->tvs_fg_color.n = param - 30;
tem->tvs_flags &= ~TEM_ATTR_BRIGHT_FG;
+ tem->tvs_flags &= ~TEM_ATTR_RGB_FG;
break;
case 38:
- /* We should have at least 3 parameters */
- if (curparam < 3)
+ /*
+ * We should have 3 parameters for 256 colors and
+ * 5 parameters for 24-bit colors.
+ */
+ if (curparam < 3) {
+ curparam = 0;
break;
+ }
/*
* 256 and truecolor needs depth at least 24, but
@@ -649,6 +682,30 @@ tem_safe_selgraph(struct tem_vt_state *tem)
curparam--;
param = tem->tvs_params[count];
switch (param) {
+ case 2: /* RGB colors */
+ if (curparam < 4) {
+ curparam = 0;
+ break;
+ }
+ r = tem->tvs_params[++count];
+ g = tem->tvs_params[++count];
+ b = tem->tvs_params[++count];
+ curparam -= 3;
+ if (r < 0 || r > 255 || g < 0 || g > 255 ||
+ b < 0 || b > 255)
+ break;
+
+ if (tems.ts_display_mode == VIS_PIXEL &&
+ tems.ts_pdepth > 8) {
+ tem->tvs_flags |= TEM_ATTR_RGB_FG;
+ tem->tvs_flags &= ~TEM_ATTR_BRIGHT_FG;
+ tem->tvs_fg_color.rgb.a =
+ tem->tvs_alpha;
+ tem->tvs_fg_color.rgb.r = r;
+ tem->tvs_fg_color.rgb.g = g;
+ tem->tvs_fg_color.rgb.b = b;
+ }
+ break;
case 5: /* 256 colors */
count++;
curparam--;
@@ -656,6 +713,7 @@ tem_safe_selgraph(struct tem_vt_state *tem)
B_TRUE);
break;
default:
+ curparam = 0;
break;
}
break;
@@ -665,6 +723,7 @@ tem_safe_selgraph(struct tem_vt_state *tem)
* Reset the foreground colour and brightness.
*/
tem->tvs_fg_color = tems.ts_init_color.fg_color;
+ tem->tvs_flags &= ~TEM_ATTR_RGB_FG;
if (tems.ts_init_color.a_flags & TEM_ATTR_BRIGHT_FG)
tem->tvs_flags |= TEM_ATTR_BRIGHT_FG;
else
@@ -679,14 +738,20 @@ tem_safe_selgraph(struct tem_vt_state *tem)
case 45: /* magenta (light magenta) background */
case 46: /* cyan (light cyan) background */
case 47: /* white (bright white) background */
- tem->tvs_bg_color = param - 40;
+ tem->tvs_bg_color.n = param - 40;
+ tem->tvs_flags &= ~TEM_ATTR_RGB_BG;
tem->tvs_flags &= ~TEM_ATTR_BRIGHT_BG;
break;
case 48:
- /* We should have at least 3 parameters */
- if (curparam < 3)
+ /*
+ * We should have 3 parameters for 256 colors and
+ * 5 parameters for 24-bit colors.
+ */
+ if (curparam < 3) {
+ curparam = 0;
break;
+ }
/*
* 256 and truecolor needs depth at least 24, but
@@ -696,6 +761,30 @@ tem_safe_selgraph(struct tem_vt_state *tem)
curparam--;
param = tem->tvs_params[count];
switch (param) {
+ case 2: /* RGB colors */
+ if (curparam < 4) {
+ curparam = 0;
+ break;
+ }
+ r = tem->tvs_params[++count];
+ g = tem->tvs_params[++count];
+ b = tem->tvs_params[++count];
+ curparam -= 3;
+ if (r < 0 || r > 255 || g < 0 || g > 255 ||
+ b < 0 || b > 255)
+ break;
+
+ if (tems.ts_display_mode == VIS_PIXEL &&
+ tems.ts_pdepth > 8) {
+ tem->tvs_flags |= TEM_ATTR_RGB_BG;
+ tem->tvs_flags &= ~TEM_ATTR_BRIGHT_BG;
+ tem->tvs_bg_color.rgb.a =
+ tem->tvs_alpha;
+ tem->tvs_bg_color.rgb.r = r;
+ tem->tvs_bg_color.rgb.g = g;
+ tem->tvs_bg_color.rgb.b = b;
+ }
+ break;
case 5: /* 256 colors */
count++;
curparam--;
@@ -703,6 +792,7 @@ tem_safe_selgraph(struct tem_vt_state *tem)
B_FALSE);
break;
default:
+ curparam = 0;
break;
}
break;
@@ -712,6 +802,7 @@ tem_safe_selgraph(struct tem_vt_state *tem)
* Reset the background colour and brightness.
*/
tem->tvs_bg_color = tems.ts_init_color.bg_color;
+ tem->tvs_flags &= ~TEM_ATTR_RGB_BG;
if (tems.ts_init_color.a_flags & TEM_ATTR_BRIGHT_BG)
tem->tvs_flags |= TEM_ATTR_BRIGHT_BG;
else
@@ -726,8 +817,9 @@ tem_safe_selgraph(struct tem_vt_state *tem)
case 95: /* magenta (light magenta) foreground */
case 96: /* cyan (light cyan) foreground */
case 97: /* white (bright white) foreground */
- tem->tvs_fg_color = param - 90;
+ tem->tvs_fg_color.n = param - 90;
tem->tvs_flags |= TEM_ATTR_BRIGHT_FG;
+ tem->tvs_flags &= ~TEM_ATTR_RGB_FG;
break;
case 100: /* black (grey) background */
@@ -738,8 +830,9 @@ tem_safe_selgraph(struct tem_vt_state *tem)
case 105: /* magenta (light magenta) background */
case 106: /* cyan (light cyan) background */
case 107: /* white (bright white) background */
- tem->tvs_bg_color = param - 100;
+ tem->tvs_bg_color.n = param - 100;
tem->tvs_flags |= TEM_ATTR_BRIGHT_BG;
+ tem->tvs_flags &= ~TEM_ATTR_RGB_BG;
break;
default:
@@ -1433,8 +1526,8 @@ tem_copy_width(term_char_t *src, term_char_t *dst, int cols)
* and colors.
*/
if (src[width].tc_char != dst[width].tc_char ||
- src[width].tc_fg_color != dst[width].tc_fg_color ||
- src[width].tc_bg_color != dst[width].tc_bg_color) {
+ src[width].tc_fg_color.n != dst[width].tc_fg_color.n ||
+ src[width].tc_bg_color.n != dst[width].tc_bg_color.n) {
break;
}
width--;
@@ -1562,6 +1655,7 @@ tem_safe_text_display(struct tem_vt_state *tem, term_char_t *string,
struct vis_consdisplay da;
int i;
tem_char_t c;
+ text_color_t bg, fg;
ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
called_from == CALLED_FROM_STANDALONE);
@@ -1572,7 +1666,9 @@ tem_safe_text_display(struct tem_vt_state *tem, term_char_t *string,
da.col = col;
for (i = 0; i < count; i++) {
- tem_safe_get_color(&da.fg_color, &da.bg_color, string[i]);
+ tem_safe_get_color(tem, &fg, &bg, &string[i]);
+ tem_safe_set_color(&fg, &da.fg_color);
+ tem_safe_set_color(&bg, &da.bg_color);
c = TEM_CHAR(string[i].tc_char);
tems_safe_display(&da, credp, called_from);
da.col++;
@@ -1685,7 +1781,7 @@ tem_safe_pix_display(struct tem_vt_state *tem,
for (i = 0; i < count; i++) {
/* Do not display image area */
if (!TEM_ATTR_ISSET(string[i].tc_char, TEM_ATTR_IMAGE)) {
- tem_safe_callback_bit2pix(tem, string[i]);
+ tem_safe_callback_bit2pix(tem, &string[i]);
tems_safe_display(&da, credp, called_from);
}
da.col += da.width;
@@ -1759,13 +1855,13 @@ tem_safe_pix_copy(struct tem_vt_state *tem,
}
void
-tem_safe_pix_bit2pix(struct tem_vt_state *tem, term_char_t c)
+tem_safe_pix_bit2pix(struct tem_vt_state *tem, term_char_t *c)
{
text_color_t fg, bg;
void (*fp)(struct tem_vt_state *, tem_char_t,
- unsigned char, unsigned char);
+ text_color_t, text_color_t);
- tem_safe_get_color(&fg, &bg, c);
+ tem_safe_get_color(tem, &fg, &bg, c);
switch (tems.ts_pdepth) {
case 4:
fp = bit_to_pix4;
@@ -1787,7 +1883,7 @@ tem_safe_pix_bit2pix(struct tem_vt_state *tem, term_char_t c)
return;
}
- fp(tem, c.tc_char, fg, bg);
+ fp(tem, c->tc_char, fg, bg);
}
@@ -1873,8 +1969,8 @@ tem_safe_pix_clear_entire_screen(struct tem_vt_state *tem, cred_t *credp,
TEM_ATTR_SCREEN_REVERSE);
c.tc_char = TEM_ATTR(attr);
- tem_safe_get_color(&fg_color, &bg_color, c);
- cl.bg_color = bg_color;
+ tem_safe_get_color(tem, &fg_color, &bg_color, &c);
+ tem_safe_set_color(&bg_color, &cl.bg_color);
if (tems_cls_layered(&cl, credp) == 0)
return;
@@ -2080,7 +2176,7 @@ tem_safe_reset_emulator(struct tem_vt_state *tem,
tem->tvs_nscroll = 1;
if (init_color) {
- /* use initial settings */
+ tem->tvs_alpha = 0xff;
tem->tvs_fg_color = tems.ts_init_color.fg_color;
tem->tvs_bg_color = tems.ts_init_color.bg_color;
tem->tvs_flags = tems.ts_init_color.a_flags;
@@ -2201,7 +2297,6 @@ tem_safe_pix_cursor(struct tem_vt_state *tem, short action,
cred_t *credp, enum called_from called_from)
{
struct vis_conscursor ca;
- uint32_t color;
text_color_t fg, bg;
term_char_t c;
text_attr_t attr;
@@ -2220,64 +2315,9 @@ tem_safe_pix_cursor(struct tem_vt_state *tem, short action,
TEM_ATTR_REVERSE);
c.tc_char = TEM_ATTR(attr);
- tem_safe_get_color(&fg, &bg, c);
-
- switch (tems.ts_pdepth) {
- case 4:
- ca.fg_color.mono = fg;
- ca.bg_color.mono = bg;
- break;
- case 8:
-#ifdef _HAVE_TEM_FIRMWARE
- ca.fg_color.mono = fg;
- ca.bg_color.mono = bg;
-#else
- ca.fg_color.mono = tems.ts_color_map(fg);
- ca.bg_color.mono = tems.ts_color_map(bg);
-#endif
- break;
- case 15:
- case 16:
- color = tems.ts_color_map(fg);
- ca.fg_color.sixteen[0] = (color >> 8) & 0xFF;
- ca.fg_color.sixteen[1] = color & 0xFF;
- color = tems.ts_color_map(bg);
- ca.bg_color.sixteen[0] = (color >> 8) & 0xFF;
- ca.bg_color.sixteen[1] = color & 0xFF;
- break;
- case 24:
- case 32:
-#ifdef _HAVE_TEM_FIRMWARE
- /* Keeping this block to support old binary only drivers */
- if (tem->tvs_flags & TEM_ATTR_REVERSE) {
- ca.fg_color.twentyfour[0] = TEM_TEXT_WHITE24_RED;
- ca.fg_color.twentyfour[1] = TEM_TEXT_WHITE24_GREEN;
- ca.fg_color.twentyfour[2] = TEM_TEXT_WHITE24_BLUE;
-
- ca.bg_color.twentyfour[0] = TEM_TEXT_BLACK24_RED;
- ca.bg_color.twentyfour[1] = TEM_TEXT_BLACK24_GREEN;
- ca.bg_color.twentyfour[2] = TEM_TEXT_BLACK24_BLUE;
- } else {
- ca.fg_color.twentyfour[0] = TEM_TEXT_BLACK24_RED;
- ca.fg_color.twentyfour[1] = TEM_TEXT_BLACK24_GREEN;
- ca.fg_color.twentyfour[2] = TEM_TEXT_BLACK24_BLUE;
-
- ca.bg_color.twentyfour[0] = TEM_TEXT_WHITE24_RED;
- ca.bg_color.twentyfour[1] = TEM_TEXT_WHITE24_GREEN;
- ca.bg_color.twentyfour[2] = TEM_TEXT_WHITE24_BLUE;
- }
-#else
- color = tems.ts_color_map(fg);
- ca.fg_color.twentyfour[0] = (color >> 16) & 0xFF;
- ca.fg_color.twentyfour[1] = (color >> 8) & 0xFF;
- ca.fg_color.twentyfour[2] = color & 0xFF;
- color = tems.ts_color_map(bg);
- ca.bg_color.twentyfour[0] = (color >> 16) & 0xFF;
- ca.bg_color.twentyfour[1] = (color >> 8) & 0xFF;
- ca.bg_color.twentyfour[2] = color & 0xFF;
-#endif
- break;
- }
+ tem_safe_get_color(tem, &fg, &bg, &c);
+ tem_safe_set_color(&fg, &ca.fg_color);
+ tem_safe_set_color(&bg, &ca.bg_color);
ca.action = action;
@@ -2299,77 +2339,51 @@ tem_safe_pix_cursor(struct tem_vt_state *tem, short action,
}
static void
-bit_to_pix4(struct tem_vt_state *tem, tem_char_t c, text_color_t fg_color,
- text_color_t bg_color)
+bit_to_pix4(struct tem_vt_state *tem, tem_char_t c, text_color_t fg,
+ text_color_t bg)
{
uint8_t *dest = (uint8_t *)tem->tvs_pix_data;
- font_bit_to_pix4(&tems.ts_font, dest, c, fg_color, bg_color);
+
+ font_bit_to_pix4(&tems.ts_font, dest, c, fg.n, bg.n);
}
static void
-bit_to_pix8(struct tem_vt_state *tem, tem_char_t c, text_color_t fg_color,
- text_color_t bg_color)
+bit_to_pix8(struct tem_vt_state *tem, tem_char_t c, text_color_t fg,
+ text_color_t bg)
{
uint8_t *dest = (uint8_t *)tem->tvs_pix_data;
-#ifndef _HAVE_TEM_FIRMWARE
- fg_color = (text_color_t)tems.ts_color_map(fg_color);
- bg_color = (text_color_t)tems.ts_color_map(bg_color);
-#endif
- font_bit_to_pix8(&tems.ts_font, dest, c, fg_color, bg_color);
+ font_bit_to_pix8(&tems.ts_font, dest, c, fg.n, bg.n);
}
static void
-bit_to_pix16(struct tem_vt_state *tem, tem_char_t c, text_color_t fg_color4,
- text_color_t bg_color4)
+bit_to_pix16(struct tem_vt_state *tem, tem_char_t c, text_color_t fg,
+ text_color_t bg)
{
- uint16_t fg_color16, bg_color16;
uint16_t *dest;
- ASSERT(fg_color4 < 16 && bg_color4 < 16);
-
- fg_color16 = (uint16_t)tems.ts_color_map(fg_color4);
- bg_color16 = (uint16_t)tems.ts_color_map(bg_color4);
-
dest = (uint16_t *)tem->tvs_pix_data;
- font_bit_to_pix16(&tems.ts_font, dest, c, fg_color16, bg_color16);
+ font_bit_to_pix16(&tems.ts_font, dest, c, fg.n, bg.n);
}
static void
-bit_to_pix24(struct tem_vt_state *tem, tem_char_t c, text_color_t fg_color4,
- text_color_t bg_color4)
+bit_to_pix24(struct tem_vt_state *tem, tem_char_t c, text_color_t fg,
+ text_color_t bg)
{
- uint32_t fg_color32, bg_color32;
uint8_t *dest;
-#ifdef _HAVE_TEM_FIRMWARE
- fg_color32 = PIX4TO32(fg_color4);
- bg_color32 = PIX4TO32(bg_color4);
-#else
- fg_color32 = tems.ts_color_map(fg_color4);
- bg_color32 = tems.ts_color_map(bg_color4);
-#endif
-
dest = (uint8_t *)tem->tvs_pix_data;
- font_bit_to_pix24(&tems.ts_font, dest, c, fg_color32, bg_color32);
+ font_bit_to_pix24(&tems.ts_font, dest, c, fg.n, bg.n);
}
static void
-bit_to_pix32(struct tem_vt_state *tem, tem_char_t c, text_color_t fg_color4,
- text_color_t bg_color4)
+bit_to_pix32(struct tem_vt_state *tem, tem_char_t c, text_color_t fg,
+ text_color_t bg)
{
- uint32_t fg_color32, bg_color32, *dest;
-
-#ifdef _HAVE_TEM_FIRMWARE
- fg_color32 = PIX4TO32(fg_color4);
- bg_color32 = PIX4TO32(bg_color4);
-#else
- fg_color32 = ((uint32_t)0xFF << 24) | tems.ts_color_map(fg_color4);
- bg_color32 = ((uint32_t)0xFF << 24) | tems.ts_color_map(bg_color4);
-#endif
+ uint32_t *dest;
dest = (uint32_t *)tem->tvs_pix_data;
- font_bit_to_pix32(&tems.ts_font, dest, c, fg_color32, bg_color32);
+ font_bit_to_pix32(&tems.ts_font, dest, c, fg.n, bg.n);
}
/*
@@ -2387,19 +2401,18 @@ tem_safe_get_attr(struct tem_vt_state *tem, text_color_t *fg,
*bg = tem->tvs_bg_color;
}
- if (attr == NULL)
- return;
-
- *attr = tem->tvs_flags;
+ if (attr != NULL)
+ *attr = tem->tvs_flags;
}
static void
-tem_safe_get_color(text_color_t *fg, text_color_t *bg, term_char_t c)
+tem_safe_get_color(struct tem_vt_state *tem, text_color_t *fg,
+ text_color_t *bg, term_char_t *c)
{
boolean_t bold_font;
- *fg = c.tc_fg_color;
- *bg = c.tc_bg_color;
+ *fg = c->tc_fg_color;
+ *bg = c->tc_bg_color;
bold_font = tems.ts_font.vf_map_count[VFNT_MAP_BOLD] != 0;
@@ -2409,19 +2422,86 @@ tem_safe_get_color(text_color_t *fg, text_color_t *bg, term_char_t c)
* The bright color is traditionally used with TEM_ATTR_BOLD,
* in case there is no bold font.
*/
- if (c.tc_fg_color < XLATE_NCOLORS) {
- if (TEM_ATTR_ISSET(c.tc_char, TEM_ATTR_BRIGHT_FG) ||
- (TEM_ATTR_ISSET(c.tc_char, TEM_ATTR_BOLD) && !bold_font))
- *fg = brt_xlate[c.tc_fg_color];
+ if (!TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_RGB_FG) &&
+ c->tc_fg_color.n < XLATE_NCOLORS) {
+ if (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_BRIGHT_FG) ||
+ (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_BOLD) && !bold_font))
+ fg->n = brt_xlate[c->tc_fg_color.n];
else
- *fg = dim_xlate[c.tc_fg_color];
+ fg->n = dim_xlate[c->tc_fg_color.n];
}
- if (c.tc_bg_color < XLATE_NCOLORS) {
- if (TEM_ATTR_ISSET(c.tc_char, TEM_ATTR_BRIGHT_BG))
- *bg = brt_xlate[c.tc_bg_color];
+ if (!TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_RGB_BG) &&
+ c->tc_bg_color.n < XLATE_NCOLORS) {
+ if (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_BRIGHT_BG))
+ bg->n = brt_xlate[c->tc_bg_color.n];
else
- *bg = dim_xlate[c.tc_bg_color];
+ bg->n = dim_xlate[c->tc_bg_color.n];
+ }
+
+ if (tems.ts_display_mode == VIS_TEXT)
+ return;
+
+ if (tems.ts_pdepth == 8) {
+ /* 8-bit depth is using indexed colors. */
+#ifndef _HAVE_TEM_FIRMWARE
+ fg->n = tems.ts_color_map(fg->n);
+ bg->n = tems.ts_color_map(bg->n);
+#endif
+ return;
+ }
+
+ /*
+ * Translate fg and bg to RGB colors.
+ */
+ if (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_RGB_FG)) {
+ fg->n = rgb_to_color(&rgb_info,
+ fg->rgb.a, fg->rgb.r, fg->rgb.g, fg->rgb.b);
+ } else {
+#ifdef _HAVE_TEM_FIRMWARE
+ if (tems.ts_pdepth == 24 || tems.ts_pdepth == 32)
+ fg->n = PIX4TO32(fg->n);
+#else
+ fg->n = rgb_color_map(&rgb_info, fg->n, tem->tvs_alpha);
+#endif
+ }
+
+ if (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_RGB_BG)) {
+ bg->n = rgb_to_color(&rgb_info,
+ bg->rgb.a, bg->rgb.r, bg->rgb.g, bg->rgb.b);
+ } else {
+#ifdef _HAVE_TEM_FIRMWARE
+ if (tems.ts_pdepth == 24 || tems.ts_pdepth == 32)
+ bg->n = PIX4TO32(bg->n);
+#else
+ bg->n = rgb_color_map(&rgb_info, bg->n, tem->tvs_alpha);
+#endif
+ }
+}
+
+static void
+tem_safe_set_color(text_color_t *t, color_t *c)
+{
+ switch (tems.ts_pdepth) {
+ case 4:
+ c->four = t->n & 0xFF;
+ break;
+ case 8:
+ c->eight = t->n & 0xFF;
+ break;
+ case 15:
+ case 16:
+ c->sixteen[0] = (t->n >> 8) & 0xFF;
+ c->sixteen[1] = t->n & 0xFF;
+ break;
+ case 24:
+ c->twentyfour[0] = (t->n >> 16) & 0xFF;
+ c->twentyfour[1] = (t->n >> 8) & 0xFF;
+ c->twentyfour[2] = t->n & 0xFF;
+ break;
+ default:
+ *(uint32_t *)c = t->n;
+ break;
}
}
@@ -2465,7 +2545,7 @@ tem_safe_pix_cls_range(struct tem_vt_state *tem,
/* Make sure we will not draw underlines */
c.tc_char = TEM_ATTR(attr & ~TEM_ATTR_UNDERLINE) | ' ';
- tem_safe_callback_bit2pix(tem, c);
+ tem_safe_callback_bit2pix(tem, &c);
da.data = (uchar_t *)tem->tvs_pix_data;
for (i = 0; i < nrows; i++, row++) {
diff --git a/usr/src/uts/common/sys/font.h b/usr/src/uts/common/sys/font.h
index f8f154f428..fe65e69136 100644
--- a/usr/src/uts/common/sys/font.h
+++ b/usr/src/uts/common/sys/font.h
@@ -128,9 +128,9 @@ extern bitmap_data_t font_data_8x16;
void reset_font_flags(void);
bitmap_data_t *set_font(short *, short *, short, short);
const uint8_t *font_lookup(const struct font *, uint32_t);
-void font_bit_to_pix4(struct font *, uint8_t *, uint32_t, uint8_t, uint8_t);
-void font_bit_to_pix8(struct font *, uint8_t *, uint32_t, uint8_t, uint8_t);
-void font_bit_to_pix16(struct font *, uint16_t *, uint32_t, uint16_t, uint16_t);
+void font_bit_to_pix4(struct font *, uint8_t *, uint32_t, uint32_t, uint32_t);
+void font_bit_to_pix8(struct font *, uint8_t *, uint32_t, uint32_t, uint32_t);
+void font_bit_to_pix16(struct font *, uint16_t *, uint32_t, uint32_t, uint32_t);
void font_bit_to_pix24(struct font *, uint8_t *, uint32_t, uint32_t, uint32_t);
void font_bit_to_pix32(struct font *, uint32_t *, uint32_t, uint32_t, uint32_t);
diff --git a/usr/src/uts/common/sys/rgb.h b/usr/src/uts/common/sys/rgb.h
index 6e0ba29af2..3f5bc12937 100644
--- a/usr/src/uts/common/sys/rgb.h
+++ b/usr/src/uts/common/sys/rgb.h
@@ -43,6 +43,8 @@ typedef struct rgb {
rgb_color_t blue;
} rgb_t;
+extern rgb_t rgb_info;
+
typedef struct {
uint8_t red[NCOLORS];
uint8_t green[NCOLORS];
@@ -99,7 +101,9 @@ extern const uint8_t brt_xlate[XLATE_NCOLORS];
extern const uint8_t solaris_color_to_pc_color[NCOLORS];
extern const uint8_t pc_color_to_solaris_color[NCOLORS];
-extern uint32_t rgb_color_map(const rgb_t *, uint8_t);
+extern uint32_t rgb_to_color(const rgb_t *, uint32_t, uint32_t, uint32_t,
+ uint32_t);
+extern uint32_t rgb_color_map(const rgb_t *, uint8_t, uint8_t);
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/sys/tem_impl.h b/usr/src/uts/common/sys/tem_impl.h
index d039e4279b..8af55ab75f 100644
--- a/usr/src/uts/common/sys/tem_impl.h
+++ b/usr/src/uts/common/sys/tem_impl.h
@@ -95,6 +95,8 @@ extern "C" {
#define TEM_ATTR_BRIGHT_BG 0x0040
#define TEM_ATTR_TRANSPARENT 0x0080
#define TEM_ATTR_IMAGE 0x0100
+#define TEM_ATTR_RGB_FG 0x0200
+#define TEM_ATTR_RGB_BG 0x0400
#define ANSI_COLOR_BLACK 0
#define ANSI_COLOR_RED 1
@@ -139,7 +141,15 @@ extern "C" {
#define DEFAULT_ANSI_BACKGROUND ANSI_COLOR_WHITE
typedef uint32_t tem_char_t; /* 32bit char to support UTF-8 */
-typedef uint8_t text_color_t;
+typedef union {
+ uint32_t n;
+ struct bgra {
+ uint8_t b;
+ uint8_t g;
+ uint8_t r;
+ uint8_t a;
+ } rgb;
+} text_color_t;
typedef uint16_t text_attr_t;
#if !defined(_BOOT)
@@ -179,6 +189,7 @@ typedef struct term_char {
struct tem_vt_state {
kmutex_t tvs_lock;
uchar_t tvs_fbmode; /* framebuffer mode */
+ uchar_t tvs_alpha; /* rgb alpha channel */
text_attr_t tvs_flags; /* flags for this x3.64 terminal */
int tvs_state; /* state in output esc seq processing */
boolean_t tvs_gotparam; /* does output esc seq have a param */
@@ -200,8 +211,10 @@ struct tem_vt_state {
size_t tvs_outindex; /* index into a_outbuf */
void *tvs_pix_data; /* pointer to tmp bitmap area */
size_t tvs_pix_data_size;
- text_color_t tvs_fg_color;
- text_color_t tvs_bg_color;
+
+ text_color_t tvs_fg_color; /* console foreground */
+ text_color_t tvs_bg_color; /* console background */
+
int tvs_first_line; /* kernel console output begins */
term_char_t *tvs_screen_buf; /* whole screen buffer */
@@ -227,7 +240,7 @@ typedef struct tem_safe_callbacks {
screen_pos_t, screen_pos_t, cred_t *, enum called_from);
void (*tsc_cursor)(struct tem_vt_state *, short, cred_t *,
enum called_from);
- void (*tsc_bit2pix)(struct tem_vt_state *, term_char_t);
+ void (*tsc_bit2pix)(struct tem_vt_state *, term_char_t *);
void (*tsc_cls)(struct tem_vt_state *, int,
screen_pos_t, screen_pos_t, cred_t *, enum called_from);
} tem_safe_callbacks_t;
@@ -311,7 +324,7 @@ void tem_safe_pix_copy(struct tem_vt_state *,
cred_t *, enum called_from);
void tem_safe_pix_cursor(struct tem_vt_state *, short, cred_t *,
enum called_from);
-void tem_safe_pix_bit2pix(struct tem_vt_state *, term_char_t);
+void tem_safe_pix_bit2pix(struct tem_vt_state *, term_char_t *);
void tem_safe_pix_cls(struct tem_vt_state *, int, screen_pos_t, screen_pos_t,
cred_t *, enum called_from);
void tem_safe_pix_cls_range(struct tem_vt_state *,
diff --git a/usr/src/uts/common/sys/visual_io.h b/usr/src/uts/common/sys/visual_io.h
index 0194d00206..c894bb48bc 100644
--- a/usr/src/uts/common/sys/visual_io.h
+++ b/usr/src/uts/common/sys/visual_io.h
@@ -167,6 +167,7 @@ typedef union {
unsigned char eight; /* eight bit */
unsigned char sixteen[2]; /* 16 bit */
unsigned char twentyfour[3]; /* 24 bit */
+ unsigned char thirtytwo[4]; /* 32 bit */
} color_t;
/*
@@ -178,7 +179,7 @@ typedef union {
* ioctl(fd, VIS_DEVINIT, struct vis_devinit *)
*/
#define VIS_DEVINIT (VIOC|1)
-#define VIS_CONS_REV 4 /* Console IO interface version */
+#define VIS_CONS_REV 5 /* Console IO interface version */
/* Modes */
#define VIS_TEXT 0 /* Use text mode when displaying data */
#define VIS_PIXEL 1 /* Use pixel mode when displaying data */
@@ -237,7 +238,7 @@ typedef union {
#define VIS_CONSCLEAR (VIOC|8)
struct vis_consclear {
- unsigned char bg_color; /* Background color */
+ color_t bg_color; /* Background color */
};
struct vis_consdisplay {
@@ -246,8 +247,8 @@ struct vis_consdisplay {
screen_size_t width; /* Width of data */
screen_size_t height; /* Height of data */
unsigned char *data; /* Data to display */
- unsigned char fg_color; /* Foreground color */
- unsigned char bg_color; /* Background color */
+ color_t fg_color; /* Foreground color */
+ color_t bg_color; /* Background color */
};
struct vis_conscopy {
diff --git a/usr/src/uts/i86pc/boot/boot_fb.c b/usr/src/uts/i86pc/boot/boot_fb.c
index e0e79bd14e..8894f9f23b 100644
--- a/usr/src/uts/i86pc/boot/boot_fb.c
+++ b/usr/src/uts/i86pc/boot/boot_fb.c
@@ -206,6 +206,7 @@ xbi_fb_init(struct xboot_info *xbi, bcons_dev_t *bcons_dev)
fb_info.rgb.green.pos = tag->u.fb2.framebuffer_green_field_position;
fb_info.rgb.blue.size = tag->u.fb2.framebuffer_blue_mask_size;
fb_info.rgb.blue.pos = tag->u.fb2.framebuffer_blue_field_position;
+ rgb_info = fb_info.rgb;
return (B_TRUE);
}
@@ -408,7 +409,7 @@ boot_color_map(uint8_t index)
return (index);
}
- return (rgb_color_map(&fb_info.rgb, index));
+ return (rgb_color_map(&fb_info.rgb, index, 0));
}
/* set up out simple console. */
diff --git a/usr/src/uts/i86pc/io/gfx_private/gfxp_bitmap.c b/usr/src/uts/i86pc/io/gfx_private/gfxp_bitmap.c
index 1a11d7ff0f..dce4562987 100644
--- a/usr/src/uts/i86pc/io/gfx_private/gfxp_bitmap.c
+++ b/usr/src/uts/i86pc/io/gfx_private/gfxp_bitmap.c
@@ -444,9 +444,10 @@ bitmap_cons_clear(struct gfxp_fb_softc *softc, struct vis_consclear *ca)
console = softc->console;
pitch = console->fb.pitch;
- data = boot_color_map(ca->bg_color);
+
switch (console->fb.depth) {
case 8:
+ data = ca->bg_color.eight;
for (i = 0; i < console->fb.screen.y; i++) {
if (softc->mode == KD_TEXT) {
fb = console->fb.fb + i * pitch;
@@ -458,6 +459,8 @@ bitmap_cons_clear(struct gfxp_fb_softc *softc, struct vis_consclear *ca)
break;
case 15:
case 16:
+ data = (ca->bg_color.sixteen[0] << 8) |
+ ca->bg_color.sixteen[1];
for (i = 0; i < console->fb.screen.y; i++) {
fb16 = (uint16_t *)(console->fb.fb + i * pitch);
sfb16 = (uint16_t *)(console->fb.shadow_fb + i * pitch);
@@ -469,6 +472,9 @@ bitmap_cons_clear(struct gfxp_fb_softc *softc, struct vis_consclear *ca)
}
break;
case 24:
+ data = ca->bg_color.twentyfour[0] << 16;
+ data |= ca->bg_color.twentyfour[1] << 8;
+ data |= ca->bg_color.twentyfour[2];
for (i = 0; i < console->fb.screen.y; i++) {
fb = console->fb.fb + i * pitch;
sfb = console->fb.shadow_fb + i * pitch;
@@ -486,6 +492,7 @@ bitmap_cons_clear(struct gfxp_fb_softc *softc, struct vis_consclear *ca)
}
break;
case 32:
+ data = *(uint32_t *)&ca->bg_color;
for (i = 0; i < console->fb.screen.y; i++) {
fb32 = (uint32_t *)(console->fb.fb + i * pitch);
sfb32 = (uint32_t *)(console->fb.shadow_fb + i * pitch);
@@ -523,8 +530,8 @@ bitmap_display_cursor(struct gfxp_fb_softc *softc, struct vis_conscursor *ca)
offset = ca->col * bpp + ca->row * pitch;
switch (console->fb.depth) {
case 8:
- fg = ca->fg_color.mono;
- bg = ca->bg_color.mono;
+ fg = ca->fg_color.eight;
+ bg = ca->bg_color.eight;
for (i = 0; i < ca->height; i++) {
fb8 = console->fb.fb + offset + i * pitch;
sfb8 = console->fb.shadow_fb + offset + i * pitch;
@@ -559,12 +566,12 @@ bitmap_display_cursor(struct gfxp_fb_softc *softc, struct vis_conscursor *ca)
}
break;
case 24:
- fg = ca->fg_color.twentyfour[0] << console->fb.rgb.red.pos;
- fg |= ca->fg_color.twentyfour[1] << console->fb.rgb.green.pos;
- fg |= ca->fg_color.twentyfour[2] << console->fb.rgb.blue.pos;
- bg = ca->bg_color.twentyfour[0] << console->fb.rgb.red.pos;
- bg |= ca->bg_color.twentyfour[1] << console->fb.rgb.green.pos;
- bg |= ca->bg_color.twentyfour[2] << console->fb.rgb.blue.pos;
+ fg = ca->fg_color.twentyfour[0] << 16;
+ fg |= ca->fg_color.twentyfour[1] << 8;
+ fg |= ca->fg_color.twentyfour[2];
+ bg = ca->bg_color.twentyfour[0] << 16;
+ bg |= ca->bg_color.twentyfour[1] << 8;
+ bg |= ca->bg_color.twentyfour[2];
for (i = 0; i < ca->height; i++) {
fb8 = console->fb.fb + offset + i * pitch;
sfb8 = console->fb.shadow_fb + offset + i * pitch;
@@ -589,12 +596,8 @@ bitmap_display_cursor(struct gfxp_fb_softc *softc, struct vis_conscursor *ca)
}
break;
case 32:
- fg = ca->fg_color.twentyfour[0] << console->fb.rgb.red.pos;
- fg |= ca->fg_color.twentyfour[1] << console->fb.rgb.green.pos;
- fg |= ca->fg_color.twentyfour[2] << console->fb.rgb.blue.pos;
- bg = ca->bg_color.twentyfour[0] << console->fb.rgb.red.pos;
- bg |= ca->bg_color.twentyfour[1] << console->fb.rgb.green.pos;
- bg |= ca->bg_color.twentyfour[2] << console->fb.rgb.blue.pos;
+ fg = *(uint32_t *)&ca->fg_color;
+ bg = *(uint32_t *)&ca->bg_color;
for (i = 0; i < ca->height; i++) {
fb32 = (uint32_t *)
(console->fb.fb + offset + i * pitch);
diff --git a/usr/src/uts/i86pc/io/gfx_private/gfxp_vgatext.c b/usr/src/uts/i86pc/io/gfx_private/gfxp_vgatext.c
index de48a9fe00..d1e846eff0 100644
--- a/usr/src/uts/i86pc/io/gfx_private/gfxp_vgatext.c
+++ b/usr/src/uts/i86pc/io/gfx_private/gfxp_vgatext.c
@@ -616,8 +616,8 @@ vgatext_cons_display(struct gfxp_fb_softc *softc, struct vis_consdisplay *da)
* should support these ioctls from userland to enable simple
* system startup graphics.
*/
- attr = (solaris_color_to_pc_color[da->bg_color & 0xf] << 4)
- | solaris_color_to_pc_color[da->fg_color & 0xf];
+ attr = (solaris_color_to_pc_color[da->bg_color.four & 0xf] << 4)
+ | solaris_color_to_pc_color[da->fg_color.four & 0xf];
string = (uint32_t *)da->data;
addr = (struct cgatext *)softc->console->vga.current_base
+ (da->row * VGA_TEXT_COLS + da->col);
@@ -725,12 +725,12 @@ vgatext_cons_clear(struct gfxp_fb_softc *softc, struct vis_consclear *ca)
uint16_t val, fg, *base;
int i;
- if (ca->bg_color == 0) /* bright white */
+ if (ca->bg_color.four == 0) /* bright white */
fg = 1; /* black */
else
fg = 8;
- val = (solaris_color_to_pc_color[ca->bg_color & 0xf] << 4) |
+ val = (solaris_color_to_pc_color[ca->bg_color.four & 0xf] << 4) |
solaris_color_to_pc_color[fg];
val = (val << 8) | ' ';