diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/boot/Makefile.version | 2 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/common/gfx_fb.c | 86 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/common/tem.c | 280 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/efi/libefi/efi_console.c | 6 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/i386/libi386/vbe.c | 20 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/i386/libi386/vidconsole.c | 8 | ||||
-rw-r--r-- | usr/src/boot/sys/sys/tem_impl.h | 23 | ||||
-rw-r--r-- | usr/src/common/font/font.c | 54 | ||||
-rw-r--r-- | usr/src/uts/common/io/tem.c | 16 | ||||
-rw-r--r-- | usr/src/uts/common/io/tem_safe.c | 376 | ||||
-rw-r--r-- | usr/src/uts/common/sys/font.h | 6 | ||||
-rw-r--r-- | usr/src/uts/common/sys/rgb.h | 6 | ||||
-rw-r--r-- | usr/src/uts/common/sys/tem_impl.h | 23 | ||||
-rw-r--r-- | usr/src/uts/common/sys/visual_io.h | 9 | ||||
-rw-r--r-- | usr/src/uts/i86pc/boot/boot_fb.c | 3 | ||||
-rw-r--r-- | usr/src/uts/i86pc/io/gfx_private/gfxp_bitmap.c | 33 | ||||
-rw-r--r-- | usr/src/uts/i86pc/io/gfx_private/gfxp_vgatext.c | 8 |
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) | ' '; |