* This patch add support for cursor move 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
---
drivers/video/cfb_console.c | 205 ++-
1 files changed, 204 insertions(+), 1 deletions(-)
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index 9e0f665..845efde 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -377,6 +377,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[] = {
0x, 0x00ff, 0xff00, 0x,
0x00ff, 0x00ff00ff, 0x0000, 0x00ff,
@@ -845,7 +849,7 @@ 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;
@@ -888,6 +892,205 @@ void video_putc(const char c)
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
+ */
+ 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 {
+ --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] == 'm') {
+