
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.rohar@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)