Handle color tables with more than 100 entries
authorH. Peter Anvin <hpa@zytor.com>
Thu, 31 May 2007 04:31:41 +0000 (21:31 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Thu, 31 May 2007 04:31:41 +0000 (21:31 -0700)
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
com32/lib/sys/ansi.h
com32/lib/sys/vesa/drawtxt.c
com32/lib/sys/vesa/video.h
com32/modules/menumain.c

index 64e7f34..1004299 100644 (file)
@@ -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;
   }
index ec2c58c..f2589c3 100644 (file)
@@ -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];
index b27ce4b..ca5c118 100644 (file)
@@ -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)];
index f890150..15ca324 100644 (file)
@@ -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
 #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);
index 24c720e..5a2c137 100644 (file)
@@ -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);
        }