Dear Pali Rohár,

>  * This patch add support for move cursor and reverse colors
>    via ANSI espace codes in cfb_console driver
>  * ANSI escape codes can be enabled/disabled via CONFIG_CFB_CONSOLE_ANSI
> 
> Signed-off-by: Pali Rohár <pali.ro...@gmail.com>
> ---
> Changes since v1:
>    - Added support ANSI code show/hide cursor
>    - Added info to README
> 
> Changes since original version:
>    - Fixed commit message
> 
>  README                      |    3 +
>  drivers/video/cfb_console.c |  234
> ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 234
> insertions(+), 3 deletions(-)
> 
> diff --git a/README b/README
> index 60ad9c2..4a610f7 100644
> --- a/README
> +++ b/README
> @@ -613,6 +613,9 @@ The following options need to be configured:
>                                               additional board info beside
>                                               the logo
> 
> +             When CONFIG_CFB_CONSOLE_ANSI is defined, console will have
> +             ANSI terminal support. Needed for CONFIG_CMDLINE_EDITING.
> +
>               When CONFIG_CFB_CONSOLE is defined, video console is
>               default i/o. Serial console can be forced with
>               environment 'console=serial'.
> diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
> index 43eb994..c9f9765 100644
> --- a/drivers/video/cfb_console.c
> +++ b/drivers/video/cfb_console.c
> @@ -377,6 +377,11 @@ static int console_row;          /* cursor row */
> 
>  static u32 eorx, fgx, bgx;   /* color pats */
> 
> +static char ansi_buf[10] = { 0, };
> +static int ansi_buf_size;
> +static int ansi_colors_need_revert;
> +static int ansi_cursor_hidden;
> +
>  static const int video_font_draw_table8[] = {
>       0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
>       0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
> @@ -602,6 +607,14 @@ static void video_putchar(int xx, int yy, unsigned
> char c) video_drawchars(xx, yy + video_logo_height, &c, 1);
>  }
> 
> +static void console_swap_colors(void)
> +{
> +     eorx = fgx;
> +     fgx = bgx;
> +     bgx = eorx;
> +     eorx = fgx ^ bgx;
> +}
> +
>  #if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
>  static void video_set_cursor(void)
>  {
> @@ -843,11 +856,12 @@ static void console_cr(void)
>       console_col = 0;
>  }
> 
> -void video_putc(const char c)
> +static void parse_putc(const char c)
>  {
>       static int nl = 1;
> 
> -     CURSOR_OFF;
> +     if (!ansi_cursor_hidden)
> +             CURSOR_OFF;
> 
>       switch (c) {
>       case 13:                /* back to first column */
> @@ -883,7 +897,221 @@ void video_putc(const char c)
>                       nl = 0;
>               }
>       }
> -     CURSOR_SET;
> +
> +     if (!ansi_cursor_hidden)
> +             CURSOR_SET;
> +}
> +
> +void video_putc(const char c)
> +{
> +#ifdef CONFIG_CFB_CONSOLE_ANSI
> +     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

wrong comment ... did you even run these patches through checkpatch? Run them 
and resubmit please, I'm ending my review here.

> +             */
> +             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 if (ansi_buf[i] != '?') {
> +                                     --i;
> +                                     num1 = 1;
> +                                     next = 4;
> +                             }
> +                             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] == 'h'
> +                                     || ansi_buf[i] == 'l'
> +                                     || 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) {
> +                     if (!ansi_cursor_hidden)
> +                             CURSOR_OFF;
> +                     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 'h':
> +                             ansi_cursor_hidden = 0;
> +                             break;
> +                     case 'l':
> +                             ansi_cursor_hidden = 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) { /* once swap colors */
> +                                     if (!ansi_colors_need_revert) {
> +                                             console_swap_colors();
> +                                             ansi_colors_need_revert = 1;
> +                                     }
> +                             }
> +                             break;
> +                     }
> +                     if (!ansi_cursor_hidden)
> +                             CURSOR_SET;
> +             }
> +     } else {
> +             parse_putc(c);
> +     }
> +#else
> +     parse_putc(c);
> +#endif
>  }
> 
>  void video_puts(const char *s)
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to