---
 drivers/video/cfb_console.c |  387 ++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 361 insertions(+), 26 deletions(-)

diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index 3a93b64..e16c76a 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -371,6 +371,10 @@ static int console_row;            /* cursor row */
 
 static u32 eorx, fgx, bgx;     /* color pats */
 
+static char ansi_buf[10] = { 0, };
+static int ansi_buf_size = 0;
+static int ansi_colors_need_revert = 0;
+
 static const int video_font_draw_table8[] = {
        0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
        0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
@@ -597,22 +601,34 @@ static void video_putchar(int xx, int yy, unsigned char c)
        video_drawchars(xx, yy + video_logo_height, &c, 1);
 }
 
-#if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
-static void video_set_cursor(void)
+static void console_swap_colors(void)
 {
-       /* swap drawing colors */
        eorx = fgx;
        fgx = bgx;
        bgx = eorx;
        eorx = fgx ^ bgx;
+}
+
+static void console_set_text_color(int c)
+{
+       // TODO
+}
+
+static void console_set_background_color(int c)
+{
+       // TODO
+}
+
+#if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
+static void video_set_cursor(void)
+{
+       /* swap drawing colors */
+       console_swap_colors();
        /* draw cursor */
        video_putchar(console_col * VIDEO_FONT_WIDTH,
                      console_row * VIDEO_FONT_HEIGHT, ' ');
        /* restore drawing colors */
-       eorx = fgx;
-       fgx = bgx;
-       bgx = eorx;
-       eorx = fgx ^ bgx;
+       console_swap_colors();
 }
 #endif
 
@@ -672,6 +688,49 @@ static void memcpyl(int *d, int *s, int c)
 }
 #endif
 
+static void console_clear(void)
+{
+#ifdef VIDEO_HW_RECTFILL
+       video_hw_rectfill(VIDEO_PIXEL_SIZE,     /* bytes per pixel */
+                         0,                    /* dest pos x */
+                         video_logo_height,    /* dest pos y */
+                         VIDEO_VISIBLE_COLS,   /* frame width */
+                         VIDEO_VISIBLE_ROWS,   /* frame height */
+                         bgx                   /* fill color */
+       );
+#else
+       memsetl(CONSOLE_ROW_FIRST, CONSOLE_SIZE, bgx);
+#endif
+}
+
+static void console_clear_line(int line, int begin, int end)
+{
+#ifdef VIDEO_HW_RECTFILL
+       video_hw_rectfill(VIDEO_PIXEL_SIZE,                             /* 
bytes per pixel */
+                         VIDEO_FONT_WIDTH * begin,                     /* dest 
pos x */  /* FIXME: correct? */
+                         video_logo_height + CONSOLE_ROW_SIZE * line,  /* dest 
pos y */  /* FIXME: correct? */
+                         VIDEO_FONT_WIDTH * ( end - begin ),           /* 
frame width */ /* FIXME: correct? */
+                         VIDEO_FONT_HEIGHT,                            /* 
frame height */
+                         bgx                                           /* fill 
color */
+               );
+#else
+       int i;
+       if ( begin == 0 && end == CONSOLE_COLS )
+               memsetl(CONSOLE_ROW_FIRST + CONSOLE_ROW_SIZE * line,    /* 
offset of row */
+                       CONSOLE_ROW_SIZE >> 2,                          /* 
length of row */
+                       bgx                                             /* fill 
color */
+               );
+       else
+               for ( i = 0; i < VIDEO_FONT_HEIGHT; ++i )
+                       memsetl(CONSOLE_ROW_FIRST + CONSOLE_ROW_SIZE * line +   
/* offset of row */
+                               VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE * begin +   
/* offset of col */
+                               i * VIDEO_LINE_LEN,                             
/* col offset of i-th line */
+                               VIDEO_FONT_WIDTH * ( end - begin ) / 2,         
/* length to end of line */
+                               bgx                                             
/* fill color */
+                               );
+#endif
+}
+
 static void console_scrollup(void)
 {
        /* copy up rows ignoring the first one */
@@ -694,18 +753,7 @@ static void console_scrollup(void)
 #endif
 
        /* clear the last one */
-#ifdef VIDEO_HW_RECTFILL
-       video_hw_rectfill(VIDEO_PIXEL_SIZE,     /* bytes per pixel */
-                         0,                    /* dest pos x */
-                         VIDEO_VISIBLE_ROWS
-                         - VIDEO_FONT_HEIGHT,  /* dest pos y */
-                         VIDEO_VISIBLE_COLS,   /* frame width */
-                         VIDEO_FONT_HEIGHT,    /* frame height */
-                         CONSOLE_BG_COL        /* fill color */
-               );
-#else
-       memsetl(CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL);
-#endif
+       console_clear_line(CONSOLE_ROWS-1, 0, CONSOLE_COLS);
 }
 
 static void console_back(void)
@@ -723,7 +771,7 @@ static void console_back(void)
                      console_row * VIDEO_FONT_HEIGHT, ' ');
 }
 
-static void console_newline(void)
+static void console_cursor_check(void)
 {
        /* Check if last character in the line was just drawn. If so, cursor was
           overwriten and need not to be cleared. Cursor clearing without this
@@ -732,7 +780,62 @@ static void console_newline(void)
         */
        if (console_col < CONSOLE_COLS)
                CURSOR_OFF;
-       console_row++;
+}
+
+static void console_cursor_fix(void)
+{
+       if (console_row <= 0)
+               console_row = 0;
+       if (console_row > CONSOLE_ROWS)
+               console_row = CONSOLE_ROWS-1;
+       if (console_col <= 0)
+               console_col = 0;
+       if (console_col > CONSOLE_COLS)
+               console_col = CONSOLE_COLS;
+}
+
+static void console_cursor_up(int n)
+{
+       console_cursor_check();
+       console_row -= n;
+       console_cursor_fix();
+}
+
+static void console_cursor_down(int n)
+{
+       console_cursor_check();
+       console_row += n;
+       console_cursor_fix();
+}
+
+static void console_cursor_left(int n)
+{
+       console_cursor_check();
+       console_col -= n;
+       console_cursor_fix();
+}
+
+static void console_cursor_right(int n)
+{
+       console_cursor_check();
+       console_col += n;
+       console_cursor_fix();
+}
+
+static void console_cursor_set_position(int row, int col)
+{
+       console_cursor_check();
+       if (console_row != -1)
+               console_row = row;
+       if (console_col != -1)
+               console_col = col;
+       console_cursor_fix();
+}
+
+static void console_newline(int n)
+{
+       console_cursor_check();
+       console_row += n;
        console_col = 0;
 
        /* Check if we need to scroll the terminal */
@@ -741,17 +844,25 @@ static void console_newline(void)
                console_scrollup();
 
                /* Decrement row number */
-               console_row--;
+               console_row = CONSOLE_ROWS-1;
        }
 }
 
+static void console_previewsline(int n)
+{
+       /* FIXME: also scroll terminal ? */
+       console_cursor_check();
+       console_row -= n;
+       console_cursor_fix();
+}
+
 static void console_cr(void)
 {
        CURSOR_OFF;
        console_col = 0;
 }
 
-void video_putc(const char c)
+static void parse_putc(const char c)
 {
        static int nl = 1;
 
@@ -762,7 +873,7 @@ void video_putc(const char c)
 
        case '\n':              /* next line */
                if (console_col || (!console_col && nl))
-                       console_newline();
+                       console_newline(1);
                nl = 1;
                break;
 
@@ -772,7 +883,7 @@ void video_putc(const char c)
                console_col &= ~0x0007;
 
                if (console_col >= CONSOLE_COLS)
-                       console_newline();
+                       console_newline(1);
                break;
 
        case 8:         /* backspace */
@@ -786,13 +897,237 @@ void video_putc(const char c)
 
                /* check for newline */
                if (console_col >= CONSOLE_COLS) {
-                       console_newline();
+                       console_newline(1);
                        nl = 0;
                }
        }
        CURSOR_SET;
 }
 
+void video_putc(const char c)
+{
+       int i;
+
+       if (c == 27)
+       {
+               for (i = 0; i < ansi_buf_size; ++i)
+                       parse_putc(ansi_buf[i]);
+               ansi_buf[0] = 27;
+               ansi_buf_size = 1;
+               return;
+       }
+
+       if (ansi_buf_size > 0)
+       {
+               // 0 - ESC
+               // 1 - [
+               // 2 - num1
+               // 3 - ..
+               // 4 - ;
+               // 5 - num2
+               // 6 - ..
+               // 7 - cchar
+               int next = 0;
+
+               int flush = 0;
+               int fail = 0;
+
+               int num1 = 0;
+               int num2 = 0;
+               int cchar = 0;
+
+               ansi_buf[ansi_buf_size++] = c;
+
+               if (ansi_buf_size >= sizeof (ansi_buf))
+                       fail = 1;
+
+               for (i = 0; i < ansi_buf_size; ++i)
+               {
+                       if (fail)
+                               break;
+
+                       switch (next) {
+                       case 0:
+                               if (ansi_buf[i] == 27)
+                                       next = 1;
+                               else
+                                       fail = 1;
+                               break;
+
+                       case 1:
+                               if (ansi_buf[i] == '[')
+                                       next = 2;
+                               else
+                                       fail = 1;
+                               break;
+
+                       case 2:
+                               if (ansi_buf[i] >= '0' && ansi_buf[i] <= '9')
+                               {
+                                       num1 = ansi_buf[i]-'0';
+                                       next = 3;
+                               }
+                               else
+                                       fail = 1;
+                               break;
+
+                       case 3:
+                               if (ansi_buf[i] >= '0' && ansi_buf[i] <= '9')
+                               {
+                                       num1 *= 10;
+                                       num1 += ansi_buf[i]-'0';
+                               }
+                               else
+                               {
+                                       --i;
+                                       next = 4;
+                               }
+                               break;
+
+                       case 4:
+                               if (ansi_buf[i] != ';')
+                               {
+                                       --i;
+                                       next = 7;
+                               }
+                               else
+                                       next = 5;
+                               break;
+
+                       case 5:
+                               if (ansi_buf[i] >= '0' && ansi_buf[i] <= '9')
+                               {
+                                       num2 = ansi_buf[i]-'0';
+                                       next = 6;
+                               }
+                               else
+                                       fail = 1;
+                               break;
+
+                       case 6:
+                               if (ansi_buf[i] >= '0' && ansi_buf[i] <= '9')
+                               {
+                                       num2 *= 10;
+                                       num2 += ansi_buf[i]-'0';
+                               }
+                               else
+                               {
+                                       --i;
+                                       next = 7;
+                               }
+                               break;
+
+                       case 7:
+                               if ((ansi_buf[i] >= 'A' && ansi_buf[i] <= 'H') 
|| ansi_buf[i] == 'J' || ansi_buf[i] == 'K' || ansi_buf[i] == 'm')
+                               {
+                                       cchar = ansi_buf[i];
+                                       flush = 1;
+                               }
+                               else
+                                       fail = 1;
+                               break;
+                       }
+               }
+
+               if (fail)
+               {
+                       for (i = 0; i < ansi_buf_size; ++i)
+                               parse_putc(ansi_buf[i]);
+                       ansi_buf_size = 0;
+                       return;
+               }
+
+               if (flush)
+               {
+                       ansi_buf_size = 0;
+                       switch (cchar) {
+                       case 'A':
+                               //move cursor num1 rows up
+                               console_cursor_up(num1);
+                               break;
+                       case 'B':
+                               //move cursor num1 rows down
+                               console_cursor_down(num1);
+                               break;
+                       case 'C':
+                               //move cursor num1 columns forward
+                               console_cursor_right(num1);
+                               break;
+                       case 'D':
+                               //move cursor num1 columns back
+                               console_cursor_left(num1);
+                               break;
+                       case 'E':
+                               //move cursor num1 rows up at begin of row
+                               console_previewsline(num1);
+                               break;
+                       case 'F':
+                               //move cursor num1 rows down at begin of row
+                               console_newline(num1);
+                               break;
+                       case 'G':
+                               //move cursor to column num1
+                               console_cursor_set_position(-1, num1-1);
+                               break;
+                       case 'H':
+                               //move cursor to row num1, column num2
+                               console_cursor_set_position(num1-1, num2-1);
+                               break;
+                       case 'J':
+                               //clear console and move cursor to 0, 0
+                               console_clear();
+                               console_cursor_set_position(0, 0);
+                               break;
+                       case 'K':
+                               //clear line
+                               if ( num1 == 0 )
+                                       console_clear_line(console_row, 
console_col, CONSOLE_COLS-1);
+                               else if ( num1 == 1 )
+                                       console_clear_line(console_row, 0, 
console_col);
+                               else
+                                       console_clear_line(console_row, 0, 
CONSOLE_COLS-1);
+                               break;
+                       case 'm':
+                               if (num1 == 0) //reset swapped colors
+                               {
+                                       if (ansi_colors_need_revert)
+                                       {
+                                               console_swap_colors();
+                                               ansi_colors_need_revert = 0;
+                                       }
+                               }
+                               else if (num1 == 7) //swap colors (only once)
+                               {
+                                       if (!ansi_colors_need_revert)
+                                       {
+                                               console_swap_colors();
+                                               ansi_colors_need_revert = 1;
+                                       }
+                               }
+                               else if (num1 == 38) // set default text color
+                               {
+                                       fgx = CONSOLE_FG_COL;
+                                       eorx = fgx ^ bgx;
+                               }
+                               else if (num1 == 48) // set default background 
color
+                               {
+                                       bgx = CONSOLE_BG_COL;
+                                       eorx = fgx ^ bgx;
+                               }
+                               else if (num1 >= 30 && num1 <= 37) //set text 
color
+                                       console_set_text_color(num1-30);
+                               else if (num1 >= 40 && num1 <= 37) //set 
background color
+                                       console_set_background_color(num1-40);
+                               break;
+                       }
+               }
+       }
+       else
+       {
+               parse_putc(c);
+       }
+}
+
 void video_puts(const char *s)
 {
        int count = strlen(s);
-- 
1.7.4.1

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to