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