From 6ba87f949b0e232f54c8a1552f9a0ed6ff4e9ae1 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 21 Sep 2006 16:44:31 -0700 Subject: [PATCH] Use the color table for the shadow, and make it user controllable --- README.menu | 44 +++++++++++++++++------------ com32/include/colortbl.h | 9 ++++++ com32/lib/sys/colortable.c | 2 +- com32/lib/sys/vesa/drawtxt.c | 39 +++++++++---------------- com32/lib/sys/vesa/fill.h | 66 +++++++++++++++++++++++++++++++++++++++++++ com32/lib/sys/vesa/initvesa.c | 12 ++++---- com32/lib/sys/vesa/video.h | 17 ++++------- com32/lib/sys/vesacon_write.c | 9 ++---- com32/modules/menumain.c | 36 +++++++++++------------ com32/modules/readconfig.c | 14 ++++++++- 10 files changed, 161 insertions(+), 87 deletions(-) create mode 100644 com32/lib/sys/vesa/fill.h diff --git a/README.menu b/README.menu index dac3596..3ec9abc 100644 --- a/README.menu +++ b/README.menu @@ -113,7 +113,7 @@ MENU BACKGROUND filename be 640x480 pixels and either in PNG or JPEG format. -MENU COLOR element ansi foreground background +MENU COLOR element ansi foreground background shadow Sets the color of element "element" to the specified color sequence: @@ -179,27 +179,35 @@ MENU COLOR element ansi foreground background white. - If any field is set to "*" then that field is left unchanged. + "shadow" controls the handling of the graphical console text + shadow. Permitted values are "none" (no shadowing), "std" or + "standard" (standard shadowing - foreground pixels are + raised), "all" (both background and foreground raised), and + "rev" or "reverse" (background pixels are raised.) + + + If any field is set to "*" or omitted (at the end of the line) + then that field is left unchanged. The current defaults are: - menu color screen 37;40 #80ffffff #00000000 - menu color border 30;44 #40000000 #00000000 - menu color title 1;36;44 #c00090f0 #00000000 - menu color unsel 37;44 #90ffffff #00000000 - menu color hotkey 1;37;44 #ffffffff #00000000 - menu color sel 7;37;40 #e0000000 #20ff8000 - menu color hotsel 1;7;37;40 #e0400000 #20ff8000 - menu color scrollbar 30;44 #40000000 #00000000 - menu color tabmsg 31;40 #90ffff00 #00000000 - menu color cmdmark 1;36;40 #c000ffff #00000000 - menu color cmdline 37;40 #c0ffffff #00000000 - menu color pwdborder 30;47 #80ffffff #20ffffff - menu color pwdheader 31;47 #80ff8080 #20ffffff - menu color pwdentry 30;47 #80ffffff #20ffffff - menu color timeout_msg 37;40 #80ffffff #00000000 - menu color timeout 1;37;40 #c0ffffff #00000000 + menu color screen 37;40 #80ffffff #00000000 std + menu color border 30;44 #40000000 #00000000 std + menu color title 1;36;44 #c00090f0 #00000000 std + menu color unsel 37;44 #90ffffff #00000000 std + menu color hotkey 1;37;44 #ffffffff #00000000 std + menu color sel 7;37;40 #e0000000 #20ff8000 all + menu color hotsel 1;7;37;40 #e0400000 #20ff8000 all + menu color scrollbar 30;44 #40000000 #00000000 std + menu color tabmsg 31;40 #90ffff00 #00000000 std + menu color cmdmark 1;36;40 #c000ffff #00000000 std + menu color cmdline 37;40 #c0ffffff #00000000 std + menu color pwdborder 30;47 #80ffffff #20ffffff std + menu color pwdheader 31;47 #80ff8080 #20ffffff std + menu color pwdentry 30;47 #80ffffff #20ffffff std + menu color timeout_msg 37;40 #80ffffff #00000000 std + menu color timeout 1;37;40 #c0ffffff #00000000 std MENU WIDTH 80 diff --git a/com32/include/colortbl.h b/com32/include/colortbl.h index 83a1343..ac3f340 100644 --- a/com32/include/colortbl.h +++ b/com32/include/colortbl.h @@ -31,11 +31,20 @@ /* Attribute/color table used by ansicon and vesacon to abstract out the color selection. */ +/* Note: vesacon relies on the encoding of these numbers */ +enum color_table_shadow { + SHADOW_NONE = 0, + SHADOW_ALL = 1, + SHADOW_NORMAL = 2, + SHADOW_REVERSE = 3, +}; + struct color_table { const char *name; /* Attribute name (used for customization) */ const char *ansi; /* ANSI attribute */ unsigned int argb_fg; /* ARGB for foreground */ unsigned int argb_bg; /* ARGB for background */ + enum color_table_shadow shadow; /* Shadow mode */ }; extern struct color_table *console_color_table; diff --git a/com32/lib/sys/colortable.c b/com32/lib/sys/colortable.c index aa1ed6e..5f7e802 100644 --- a/com32/lib/sys/colortable.c +++ b/com32/lib/sys/colortable.c @@ -1,7 +1,7 @@ #include static struct color_table default_color_table[] = { - {"default", "0", 0xffffffff, 0x00000000 } + {"default", "0", 0xffffffff, 0x00000000, SHADOW_NORMAL } }; struct color_table *console_color_table = &default_color_table; diff --git a/com32/lib/sys/vesa/drawtxt.c b/com32/lib/sys/vesa/drawtxt.c index f35e1b7..c30e19f 100644 --- a/com32/lib/sys/vesa/drawtxt.c +++ b/com32/lib/sys/vesa/drawtxt.c @@ -85,6 +85,7 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols) unsigned long pixel_offset, bytes_per_row; uint8_t row_buffer[VIDEO_X_SIZE*4], *rowbufptr; uint8_t *fbrowptr; + uint8_t sha; bgrowptr = &__vesacon_background[row*height+VIDEO_BORDER][col*width+VIDEO_BORDER]; @@ -125,8 +126,9 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols) chsbits = __vesacon_graphics_font[csptr->ch][pixsrow]; if (__unlikely(csptr == cursor_pointer)) chsbits |= cursor_pattern[pixsrow]; - chsbits &= (csptr->sha & 0x02) ? 0xff : 0x00; - chsbits ^= (csptr->sha & 0x01) ? 0xff : 0x00; + sha = console_color_table[csptr->attr].shadow; + chsbits &= (sha & 0x02) ? 0xff : 0x00; + chsbits ^= (sha & 0x01) ? 0xff : 0x00; chsbits <<= (width-2); csptr++; @@ -145,9 +147,10 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols) chbits = __vesacon_graphics_font[cptr->ch][pixrow]; if (__unlikely(cptr == cursor_pointer)) chbits |= cursor_pattern[pixrow]; + sha = console_color_table[cptr->attr].shadow; chxbits = chbits; - chxbits &= (cptr->sha & 0x02) ? 0xff : 0x00; - chxbits ^= (cptr->sha & 0x01) ? 0xff : 0x00; + chxbits &= (sha & 0x02) ? 0xff : 0x00; + chxbits ^= (sha & 0x01) ? 0xff : 0x00; fgcolor = console_color_table[cptr->attr].argb_fg; bgcolor = console_color_table[cptr->attr].argb_bg; cptr++; @@ -156,8 +159,9 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols) chsbits = __vesacon_graphics_font[csptr->ch][pixsrow]; if (__unlikely(csptr == cursor_pointer)) chsbits |= cursor_pattern[pixsrow]; - chsbits &= (csptr->sha & 0x02) ? 0xff : 0x00; - chsbits ^= (csptr->sha & 0x01) ? 0xff : 0x00; + sha = console_color_table[csptr->attr].shadow; + chsbits &= (sha & 0x02) ? 0xff : 0x00; + chsbits ^= (sha & 0x01) ? 0xff : 0x00; csptr++; break; default: @@ -234,21 +238,8 @@ static inline void vesacon_touch(int row, int col, int rows, int cols) upd_x1 = x1; } -/* Fill a number of characters... */ -static inline struct vesa_char *vesacon_fill(struct vesa_char *ptr, - struct vesa_char fill, - unsigned int count) -{ - asm volatile("cld; rep; stosl" - : "+D" (ptr), "+c" (count) - : "a" (fill) - : "memory"); - - return ptr; -} - /* Erase a region of the screen */ -void __vesacon_erase(int x0, int y0, int x1, int y1, uint8_t attr, int rev) +void __vesacon_erase(int x0, int y0, int x1, int y1, uint8_t attr) { int y; struct vesa_char *ptr = &__vesacon_text_display @@ -256,7 +247,6 @@ void __vesacon_erase(int x0, int y0, int x1, int y1, uint8_t attr, int rev) struct vesa_char fill = { .ch = ' ', .attr = attr, - .sha = rev }; int ncols = x1-x0+1; @@ -269,7 +259,7 @@ void __vesacon_erase(int x0, int y0, int x1, int y1, uint8_t attr, int rev) } /* Scroll the screen up */ -void __vesacon_scroll_up(int nrows, uint8_t attr, int rev) +void __vesacon_scroll_up(int nrows, uint8_t attr) { struct vesa_char *fromptr = &__vesacon_text_display [(nrows+1)*(TEXT_PIXEL_COLS/FONT_WIDTH+2)]; @@ -279,28 +269,25 @@ void __vesacon_scroll_up(int nrows, uint8_t attr, int rev) struct vesa_char fill = { .ch = ' ', .attr = attr, - .sha = rev, }; toptr = copy_dword(toptr, fromptr, dword_count); dword_count = nrows*(TEXT_PIXEL_COLS/FONT_WIDTH+2); - /* Danger, Will Robinson: this is wrong if rev != SHADOW_NORMAL */ vesacon_fill(toptr, fill, dword_count); vesacon_touch(0, 0, __vesacon_text_rows, TEXT_PIXEL_COLS/FONT_WIDTH); } /* Draw one character text at a specific area of the screen */ -void __vesacon_write_char(int x, int y, uint8_t ch, uint8_t attr, int rev) +void __vesacon_write_char(int x, int y, uint8_t ch, uint8_t attr) { struct vesa_char *ptr = &__vesacon_text_display [(y+1)*(TEXT_PIXEL_COLS/FONT_WIDTH+2)+(x+1)]; ptr->ch = ch; ptr->attr = attr; - ptr->sha = rev; vesacon_touch(y, x, 1, 1); } diff --git a/com32/lib/sys/vesa/fill.h b/com32/lib/sys/vesa/fill.h new file mode 100644 index 0000000..379852e --- /dev/null +++ b/com32/lib/sys/vesa/fill.h @@ -0,0 +1,66 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2006 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +#ifndef LIB_SYS_VESA_FILL_H +#define LIB_SYS_VESA_FILL_H + +#include "video.h" + +/* Fill a number of characters. */ +static inline struct vesa_char *vesacon_fill(struct vesa_char *ptr, + struct vesa_char fill, + unsigned int count) +{ + switch (sizeof(struct vesa_char)) { + case 1: + asm volatile("cld; rep; stosb" + : "+D" (ptr), "+c" (count) + : "a" (fill) + : "memory"); + break; + case 2: + asm volatile("cld; rep; stosw" + : "+D" (ptr), "+c" (count) + : "a" (fill) + : "memory"); + break; + case 4: + asm volatile("cld; rep; stosl" + : "+D" (ptr), "+c" (count) + : "a" (fill) + : "memory"); + break; + default: + while (count--) + *ptr++ = fill; + break; + } + + return ptr; +} + +#endif /* LIB_SYS_VESA_FILL_H */ diff --git a/com32/lib/sys/vesa/initvesa.c b/com32/lib/sys/vesa/initvesa.c index 7394c9d..3508444 100644 --- a/com32/lib/sys/vesa/initvesa.c +++ b/com32/lib/sys/vesa/initvesa.c @@ -41,6 +41,7 @@ #include #include "vesa.h" #include "video.h" +#include "fill.h" struct vesa_info __vesa_info; @@ -239,6 +240,10 @@ static int init_text_display(void) { size_t nchars; struct vesa_char *ptr; + struct vesa_char def_char = { + .ch = ' ', + .attr = 0, + }; nchars = (TEXT_PIXEL_ROWS/__vesacon_font_height+2)* (TEXT_PIXEL_COLS/FONT_WIDTH+2); @@ -248,11 +253,8 @@ static int init_text_display(void) if (!ptr) return -1; - /* I really which C had a memset() for larger-than-bytes objects... */ - asm volatile("cld; rep; stosl" - : "+D" (ptr), "+c" (nchars) - : "a" (' '+(0 << 8)+(SHADOW_NORMAL << 16)) - : "memory"); + + vesacon_fill(ptr, def_char, nchars); return 0; } diff --git a/com32/lib/sys/vesa/video.h b/com32/lib/sys/vesa/video.h index 5070f9e..f890150 100644 --- a/com32/lib/sys/vesa/video.h +++ b/com32/lib/sys/vesa/video.h @@ -28,6 +28,8 @@ #ifndef LIB_SYS_VESA_VIDEO_H #define LIB_SYS_VESA_VIDEO_H +#include + #define FONT_MAX_CHARS 256 #define FONT_MAX_HEIGHT 32 #define FONT_WIDTH 8 @@ -39,16 +41,9 @@ #define TEXT_PIXEL_ROWS (VIDEO_Y_SIZE-2*VIDEO_BORDER) #define TEXT_PIXEL_COLS (VIDEO_X_SIZE-2*VIDEO_BORDER) -#define SHADOW_NONE 0 -#define SHADOW_ALL 1 -#define SHADOW_NORMAL 2 -#define SHADOW_REVERSE 3 - struct vesa_char { uint8_t ch; /* Character */ - uint8_t attr; /* PC-style graphics attribute */ - uint8_t sha; /* Shadow attributes */ - uint8_t pad; /* Currently unused */ + uint8_t attr; /* Color table index */ }; /* Pixel formats in order of decreasing preference; PXF_NONE should be last */ @@ -76,9 +71,9 @@ int __vesacon_init_background(void); int vesacon_load_background(const char *); int __vesacon_init(void); void __vesacon_init_cursor(int); -void __vesacon_erase(int, int, int, int, uint8_t, int); -void __vesacon_scroll_up(int, uint8_t, int); -void __vesacon_write_char(int, int, uint8_t, uint8_t, int); +void __vesacon_erase(int, int, int, int, uint8_t); +void __vesacon_scroll_up(int, uint8_t); +void __vesacon_write_char(int, int, uint8_t, uint8_t); void __vesacon_redraw_text(void); void __vesacon_doit(void); void __vesacon_set_cursor(int, int, int); diff --git a/com32/lib/sys/vesacon_write.c b/com32/lib/sys/vesacon_write.c index 7f1570b..87f7066 100644 --- a/com32/lib/sys/vesacon_write.c +++ b/com32/lib/sys/vesacon_write.c @@ -117,16 +117,14 @@ int __vesacon_close(struct file_info *fp) static void vesacon_erase(const struct term_state *st, int x0, int y0, int x1, int y1) { - __vesacon_erase(x0, y0, x1, y1, st->attr, - st->reverse ? SHADOW_ALL : SHADOW_NORMAL); + __vesacon_erase(x0, y0, x1, y1, st->cindex); } /* Draw text on the screen */ static void vesacon_write_char(int x, int y, uint8_t ch, const struct term_state *st) { - __vesacon_write_char(x, y, ch, st->cindex, - st->reverse ? SHADOW_ALL : SHADOW_NORMAL); + __vesacon_write_char(x, y, ch, st->cindex); } /* Show or hide the cursor */ @@ -137,8 +135,7 @@ static void vesacon_showcursor(const struct term_state *st) static void vesacon_scroll_up(const struct term_state *st) { - __vesacon_scroll_up(1, st->cindex, - st->reverse ? SHADOW_ALL : SHADOW_NORMAL); + __vesacon_scroll_up(1, st->cindex); } ssize_t __vesacon_write(struct file_info *fp, const void *buf, size_t count) diff --git a/com32/modules/menumain.c b/com32/modules/menumain.c index 1f6d3c0..62494b2 100644 --- a/com32/modules/menumain.c +++ b/com32/modules/menumain.c @@ -60,22 +60,22 @@ int (*draw_background)(const char *filename); */ static const struct color_table default_color_table[] = { - { "screen", "37;40", 0x80ffffff, 0x00000000 }, - { "border", "30;44", 0x40000000, 0x00000000 }, - { "title", "1;36;44", 0xc00090f0, 0x00000000 }, - { "unsel", "37;44", 0x90ffffff, 0x00000000 }, - { "hotkey", "1;37;44", 0xffffffff, 0x00000000 }, - { "sel", "7;37;40", 0xe0000000, 0x20ff8000 }, - { "hotsel", "1;7;37;40", 0xe0400000, 0x20ff8000 }, - { "scrollbar", "30;44", 0x40000000, 0x00000000 }, - { "tabmsg", "31;40", 0x90ffff00, 0x00000000 }, - { "cmdmark", "1;36;40", 0xc000ffff, 0x00000000 }, - { "cmdline", "37;40", 0xc0ffffff, 0x00000000 }, - { "pwdborder", "30;47", 0x80ffffff, 0x20ffffff }, - { "pwdheader", "31;47", 0x80ff8080, 0x20ffffff }, - { "pwdentry", "30;47", 0x80ffffff, 0x20ffffff }, - { "timeout_msg", "37;40", 0x80ffffff, 0x00000000 }, - { "timeout", "1;37;40", 0xc0ffffff, 0x00000000 }, + { "screen", "37;40", 0x80ffffff, 0x00000000, SHADOW_NORMAL }, + { "border", "30;44", 0x40000000, 0x00000000, SHADOW_NORMAL }, + { "title", "1;36;44", 0xc00090f0, 0x00000000, SHADOW_NORMAL }, + { "unsel", "37;44", 0x90ffffff, 0x00000000, SHADOW_NORMAL }, + { "hotkey", "1;37;44", 0xffffffff, 0x00000000, SHADOW_NORMAL }, + { "sel", "7;37;40", 0xe0000000, 0x20ff8000, SHADOW_ALL }, + { "hotsel", "1;7;37;40", 0xe0400000, 0x20ff8000, SHADOW_ALL }, + { "scrollbar", "30;44", 0x40000000, 0x00000000, SHADOW_NORMAL }, + { "tabmsg", "31;40", 0x90ffff00, 0x00000000, SHADOW_NORMAL }, + { "cmdmark", "1;36;40", 0xc000ffff, 0x00000000, SHADOW_NORMAL }, + { "cmdline", "37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL }, + { "pwdborder", "30;47", 0x80ffffff, 0x20ffffff, SHADOW_NORMAL }, + { "pwdheader", "31;47", 0x80ff8080, 0x20ffffff, SHADOW_NORMAL }, + { "pwdentry", "30;47", 0x80ffffff, 0x20ffffff, SHADOW_NORMAL }, + { "timeout_msg", "37;40", 0x80ffffff, 0x00000000, SHADOW_NORMAL }, + { "timeout", "1;37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL }, }; #define NCOLORS (sizeof default_color_table/sizeof(struct color_table)) @@ -118,10 +118,8 @@ install_default_color_table(void) if (cp->ansi) free((void *)cp->ansi); - cp->name = dp->name; + *cp = *dp; cp->ansi = strdup(dp->ansi); - cp->argb_fg = dp->argb_fg; - cp->argb_bg = dp->argb_bg; cp++; dp++; diff --git a/com32/modules/readconfig.c b/com32/modules/readconfig.c index 2c593f0..fb9c3d6 100644 --- a/com32/modules/readconfig.c +++ b/com32/modules/readconfig.c @@ -363,7 +363,7 @@ static uint32_t parse_argb(char **p) static void parse_config_file(FILE *f) { - char line[MAX_LINE], *p, *ep; + char line[MAX_LINE], *p, *ep, ch; char *append = NULL; unsigned int ipappend = 0; struct labeldata ld; @@ -436,6 +436,18 @@ static void parse_config_file(FILE *f) p++; else cptr->argb_bg = parse_argb(&p); + + /* Parse a shadow mode */ + p = skipspace(p); + ch = *p | 0x20; + if (ch == 'n') /* none */ + cptr->shadow = SHADOW_NONE; + else if (ch == 's') /* std, standard */ + cptr->shadow = SHADOW_NORMAL; + else if (ch == 'a') /* all */ + cptr->shadow = SHADOW_ALL; + else if (ch == 'r') /* rev, reverse */ + cptr->shadow = SHADOW_REVERSE; } } } -- 2.7.4