From 33fbfe73c513e543e9e560eb4ed34821d1374ee1 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 30 May 2007 21:31:41 -0700 Subject: [PATCH] Handle color tables with more than 100 entries For sane handling of message files with attributes, we need to be able to do more than 256 attributes. The easiest way is to simply allow a table to be that large; we have enough memory for the job. --- com32/lib/sys/ansi.c | 62 ++++++++++++++++++++------------------------ com32/lib/sys/ansi.h | 6 ++--- com32/lib/sys/vesa/drawtxt.c | 6 ++--- com32/lib/sys/vesa/video.h | 13 ++++++---- com32/modules/menumain.c | 50 +++++++++++++++++------------------ 5 files changed, 67 insertions(+), 70 deletions(-) diff --git a/com32/lib/sys/ansi.c b/com32/lib/sys/ansi.c index 64e7f34..1004299 100644 --- a/com32/lib/sys/ansi.c +++ b/com32/lib/sys/ansi.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 2004-2006 H. Peter Anvin - All Rights Reserved + * Copyright 2004-2007 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 @@ -80,8 +80,9 @@ void __ansi_putchar(const struct term_info *ti, uint8_t ch) switch ( st->state ) { case st_init: switch ( ch ) { - case 1: - st->state = st_soh; + case 1 ... 5: + st->state = st_tbl; + st->tbl_chars = ch; break; case '\b': if ( xy.x > 0 ) xy.x--; @@ -374,49 +375,42 @@ void __ansi_putchar(const struct term_info *ti, uint8_t ch) } break; - case st_soh: + case st_tbl: + st->parms[0] = 0; if ( ch == '#' ) - st->state = st_sohc; + st->state = st_tblc; else st->state = st_init; break; - case st_sohc: + case st_tblc: { - int n = (unsigned char)ch - '0'; - if (n < 10) { - st->parms[0] = n*10; - st->state = st_sohc1; - } else { - st->state = st_init; - } - } - break; - - case st_sohc1: - { - int n = (unsigned char)ch - '0'; + unsigned int n = (unsigned char)ch - '0'; const char *p; if (n < 10) { - st->parms[0] += n; - if (st->parms[0] < console_color_table_size) { - /* Set the color table index */ - st->cindex = st->parms[0]; + st->parms[0] = st->parms[0]*10+n; - /* See if there are any other attributes we care about */ - p = console_color_table[st->parms[0]].ansi; - st->state = st_esc; - __ansi_putchar(ti, '['); - __ansi_putchar(ti, '0'); - __ansi_putchar(ti, ';'); - while (*p) - __ansi_putchar(ti, *p++); - __ansi_putchar(ti, 'm'); + if (! --st->tbl_chars) { + if (st->parms[0] < console_color_table_size) { + /* Set the color table index */ + st->cindex = st->parms[0]; + + /* See if there are any other attributes we care about */ + p = console_color_table[st->parms[0]].ansi; + st->state = st_esc; + __ansi_putchar(ti, '['); + __ansi_putchar(ti, '0'); + __ansi_putchar(ti, ';'); + while (*p) + __ansi_putchar(ti, *p++); + __ansi_putchar(ti, 'm'); + } + st->state = st_init; } + } else { + st->state = st_init; } - - st->state = st_init; } break; } diff --git a/com32/lib/sys/ansi.h b/com32/lib/sys/ansi.h index ec2c58c..f2589c3 100644 --- a/com32/lib/sys/ansi.h +++ b/com32/lib/sys/ansi.h @@ -13,9 +13,8 @@ enum ansi_state { st_init, st_esc, st_csi, - st_soh, - st_sohc, - st_sohc1, + st_tbl, + st_tblc, }; struct curxy { @@ -37,6 +36,7 @@ struct term_state { struct curxy saved_xy; int cursor; enum ansi_state state; + int tbl_chars; /* Digits to get in st_tblc */ int pvt; /* Private code? */ int nparms; /* Number of parameters seen */ int parms[ANSI_MAX_PARMS]; diff --git a/com32/lib/sys/vesa/drawtxt.c b/com32/lib/sys/vesa/drawtxt.c index b27ce4b..ca5c118 100644 --- a/com32/lib/sys/vesa/drawtxt.c +++ b/com32/lib/sys/vesa/drawtxt.c @@ -240,7 +240,7 @@ static inline void vesacon_touch(int row, int col, int rows, int cols) } /* Erase a region of the screen */ -void __vesacon_erase(int x0, int y0, int x1, int y1, uint8_t attr) +void __vesacon_erase(int x0, int y0, int x1, int y1, attr_t attr) { int y; struct vesa_char *ptr = &__vesacon_text_display @@ -260,7 +260,7 @@ void __vesacon_erase(int x0, int y0, int x1, int y1, uint8_t attr) } /* Scroll the screen up */ -void __vesacon_scroll_up(int nrows, uint8_t attr) +void __vesacon_scroll_up(int nrows, attr_t attr) { struct vesa_char *fromptr = &__vesacon_text_display [(nrows+1)*(TEXT_PIXEL_COLS/FONT_WIDTH+2)]; @@ -282,7 +282,7 @@ void __vesacon_scroll_up(int nrows, uint8_t attr) } /* 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) +void __vesacon_write_char(int x, int y, uint8_t ch, attr_t attr) { struct vesa_char *ptr = &__vesacon_text_display [(y+1)*(TEXT_PIXEL_COLS/FONT_WIDTH+2)+(x+1)]; diff --git a/com32/lib/sys/vesa/video.h b/com32/lib/sys/vesa/video.h index f890150..15ca324 100644 --- a/com32/lib/sys/vesa/video.h +++ b/com32/lib/sys/vesa/video.h @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 2006 H. Peter Anvin - All Rights Reserved + * Copyright 2006-2007 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 @@ -41,9 +41,12 @@ #define TEXT_PIXEL_ROWS (VIDEO_Y_SIZE-2*VIDEO_BORDER) #define TEXT_PIXEL_COLS (VIDEO_X_SIZE-2*VIDEO_BORDER) +typedef uint16_t attr_t; + struct vesa_char { uint8_t ch; /* Character */ - uint8_t attr; /* Color table index */ + uint8_t _filler; /* Currently unused */ + attr_t attr; /* Color table index */ }; /* Pixel formats in order of decreasing preference; PXF_NONE should be last */ @@ -71,9 +74,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); -void __vesacon_scroll_up(int, uint8_t); -void __vesacon_write_char(int, int, uint8_t, uint8_t); +void __vesacon_erase(int, int, int, int, attr_t); +void __vesacon_scroll_up(int, attr_t); +void __vesacon_write_char(int, int, uint8_t, attr_t); void __vesacon_redraw_text(void); void __vesacon_doit(void); void __vesacon_set_cursor(int, int, int); diff --git a/com32/modules/menumain.c b/com32/modules/menumain.c index 24c720e..5a2c137 100644 --- a/com32/modules/menumain.c +++ b/com32/modules/menumain.c @@ -39,7 +39,7 @@ int (*draw_background)(const char *filename); /* - * The color/attribute indexes (\1#XX) are as follows + * The color/attribute indexes (\1#X, \2#XX, \3#XXX) are as follows * * 00 - screen Rest of the screen * 01 - border Border area @@ -195,25 +195,25 @@ draw_row(int y, int sel, int top, int sbtop, int sbbot) { int i = (y-4-VSHIFT)+top; - printf("\033[%d;%dH\1#01\016x\017%s ", - y, MARGIN+1+HSHIFT, (i == sel) ? "\1#05" : "\1#03"); + printf("\033[%d;%dH\2#01\016x\017%s ", + y, MARGIN+1+HSHIFT, (i == sel) ? "\2#05" : "\2#03"); if ( i >= nentries ) { fputs(pad_line("", 0, WIDTH-2*MARGIN-4), stdout); } else { display_entry(&menu_entries[i], - (i == sel) ? "\1#05" : "\1#03", - (i == sel) ? "\1#06" : "\1#04", + (i == sel) ? "\2#05" : "\2#03", + (i == sel) ? "\2#06" : "\2#04", WIDTH-2*MARGIN-4); } if ( nentries <= MENU_ROWS ) { - printf(" \1#01\016x\017"); + printf(" \2#01\016x\017"); } else if ( sbtop > 0 ) { if ( y >= sbtop && y <= sbbot ) - printf(" \1#07\016a\017"); + printf(" \2#07\016a\017"); else - printf(" \1#01\016x\017"); + printf(" \2#01\016x\017"); } else { putchar(' '); /* Don't modify the scrollbar */ } @@ -294,7 +294,7 @@ ask_passwd(const char *menu_entry) int key; int x; - printf("\033[%d;%dH\1#11\016l", PASSWD_ROW, PASSWD_MARGIN+1); + printf("\033[%d;%dH\2#11\016l", PASSWD_ROW, PASSWD_MARGIN+1); for ( x = 2 ; x <= WIDTH-2*PASSWD_MARGIN-1 ; x++ ) putchar('q'); @@ -306,7 +306,7 @@ ask_passwd(const char *menu_entry) for ( x = 2 ; x <= WIDTH-2*PASSWD_MARGIN-1 ; x++ ) putchar('q'); - printf("j\017\033[%d;%dH\1#12 %s \033[%d;%dH\1#13", + printf("j\017\033[%d;%dH\2#12 %s \033[%d;%dH\2#13", PASSWD_ROW, (WIDTH-(strlen(messages[MSG_PASSPROMPT].msg)+2))/2, messages[MSG_PASSPROMPT].msg, PASSWD_ROW+1, PASSWD_MARGIN+3); @@ -380,16 +380,16 @@ draw_menu(int sel, int top, int edit_line) sbtop += 4; sbbot += 4; /* Starting row of scrollbar */ } - printf("\033[%d;%dH\1#01\016l", VSHIFT+1, HSHIFT+MARGIN+1); + printf("\033[%d;%dH\2#01\016l", VSHIFT+1, HSHIFT+MARGIN+1); for ( x = 2+HSHIFT ; x <= (WIDTH-2*MARGIN-1)+HSHIFT ; x++ ) putchar('q'); - printf("k\033[%d;%dH\1#01x\017\1#02 %s \1#01\016x", + printf("k\033[%d;%dH\2#01x\017\2#02 %s \2#01\016x", VSHIFT+2, HSHIFT+MARGIN+1, pad_line(messages[MSG_TITLE].msg, 1, WIDTH-2*MARGIN-4)); - printf("\033[%d;%dH\1#01t", VSHIFT+3, HSHIFT+MARGIN+1); + printf("\033[%d;%dH\2#01t", VSHIFT+3, HSHIFT+MARGIN+1); for ( x = 2+HSHIFT ; x <= (WIDTH-2*MARGIN-1)+HSHIFT ; x++ ) putchar('q'); fputs("u\017", stdout); @@ -397,7 +397,7 @@ draw_menu(int sel, int top, int edit_line) for ( y = 4+VSHIFT ; y < 4+VSHIFT+MENU_ROWS ; y++ ) draw_row(y, sel, top, sbtop, sbbot); - printf("\033[%d;%dH\1#01\016m", y, HSHIFT+MARGIN+1); + printf("\033[%d;%dH\2#01\016m", y, HSHIFT+MARGIN+1); for ( x = 2+HSHIFT ; x <= (WIDTH-2*MARGIN-1)+HSHIFT ; x++ ) putchar('q'); fputs("j\017", stdout); @@ -407,14 +407,14 @@ draw_menu(int sel, int top, int edit_line) else tabmsg = messages[MSG_NOTAB].msg; - printf("\1#08\033[%d;1H%s", TABMSG_ROW, pad_line(tabmsg, 1, WIDTH)); - printf("\1#00\033[%d;1H", END_ROW); + printf("\2#08\033[%d;1H%s", TABMSG_ROW, pad_line(tabmsg, 1, WIDTH)); + printf("\2#00\033[%d;1H", END_ROW); } static void clear_screen(void) { - fputs("\033e\033%@\033)0\033(B\1#00\033[?25l\033[2J", stdout); + fputs("\033e\033%@\033)0\033(B\2#00\033[?25l\033[2J", stdout); } static void @@ -425,9 +425,9 @@ display_help(const char *text) if (!text) { text = ""; - printf("\1#00\033[%d;1H", HELPMSG_ROW); + printf("\2#00\033[%d;1H", HELPMSG_ROW); } else { - printf("\1#16\033[%d;1H", HELPMSG_ROW); + printf("\2#16\033[%d;1H", HELPMSG_ROW); } for (p = text, row = HELPMSG_ROW; *p && row <= HELPMSGEND_ROW; p++) { @@ -477,9 +477,9 @@ edit_cmdline(char *input, int top) if ( redraw > 0 ) { /* Redraw the command line */ - printf("\033[?25l\033[%d;1H\1#09> \1#10%s", + printf("\033[?25l\033[%d;1H\2#09> \2#10%s", CMDLINE_ROW, pad_line(cmdline, 0, prev_len)); - printf("\1#10\033[%d;3H%s\033[?25h", + printf("\2#10\033[%d;3H%s\033[?25h", CMDLINE_ROW, pad_line(cmdline, 0, cursor)); prev_len = len; redraw = 0; @@ -688,7 +688,7 @@ run_menu(void) while ((size_t)(tq-buf) < (sizeof buf-16) && (tc = *tp)) { if (tc == '#') { - nnc = sprintf(tq, "\1#15%d\1#14", tol); + nnc = sprintf(tq, "\2#15%d\2#14", tol); tq += nnc; nc += nnc-8; /* 8 formatting characters */ } else { @@ -699,7 +699,7 @@ run_menu(void) } *tq = '\0'; - printf("\033[%d;%dH\1#14 %s ", TIMEOUT_ROW, 1+((WIDTH-nc)>>1), buf); + printf("\033[%d;%dH\2#14 %s ", TIMEOUT_ROW, 1+((WIDTH-nc)>>1), buf); to_clear = 1; } else { to_clear = 0; @@ -711,7 +711,7 @@ run_menu(void) if ( key != KEY_NONE ) { timeout_left = key_timeout; if ( to_clear ) - printf("\033[%d;1H\1#00\033[K", TIMEOUT_ROW); + printf("\033[%d;1H\2#00\033[K", TIMEOUT_ROW); } switch ( key ) { @@ -815,7 +815,7 @@ run_menu(void) draw_menu(-1, top, 0); } else { /* Erase [Tab] message and help text*/ - printf("\033[%d;1H\1#00\033[K", TABMSG_ROW); + printf("\033[%d;1H\2#00\033[K", TABMSG_ROW); display_help(NULL); } -- 2.7.4