[U-Boot] [PATCH 2/2] lcd: add ANSI escape support

Jean-Christophe PLAGNIOL-VILLARD plagnioj at jcrosoft.com
Sun Jun 21 21:52:22 CEST 2009


to use the new menu framework, clear and advance echo we need to add
the following escape ansi support \e[%dJ, \e[m, \e[%dm, and \e[%d;%dH

Tested on at91sam9263ek

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 common/lcd.c |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/common/lcd.c b/common/lcd.c
index b5e81f1..dbad380 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -34,6 +34,7 @@
 #include <command.h>
 #include <stdarg.h>
 #include <linux/types.h>
+#include <linux/ctype.h>
 #include <devices.h>
 #if defined(CONFIG_POST)
 #include <post.h>
@@ -172,6 +173,23 @@ static inline void console_newline (void)
 
 /*----------------------------------------------------------------------*/
 
+static void invert_fg_bg_color(void)
+{
+	int tmp;
+
+	tmp = lcd_color_fg;
+	lcd_color_fg = lcd_color_bg;
+	lcd_color_bg = tmp;
+}
+
+struct ansi_parsing_state {
+	int inprogress;
+	/* is FG/BG inverted */
+	int inverted;
+	int *pos;
+	int val[2];
+} state;
+
 void lcd_putc (const char c)
 {
 	if (!lcd_is_enabled) {
@@ -179,6 +197,55 @@ void lcd_putc (const char c)
 		return;
 	}
 
+	if (state.inprogress) {
+		switch (c) {
+		case '[':	state.val[0] = state.val[1] = 0;
+				state.pos = state.val;
+				return;
+		case ';':
+				state.pos++;
+				return;
+		case 'H':
+				state.inprogress = 0;
+				if (state.val[0] > CONSOLE_ROWS ||
+				    state.val[1] > CONSOLE_COLS) {
+					return;
+				}
+
+				if (state.val[0])
+					console_row = state.val[0] - 1;
+				else
+					console_row = 0;
+				if (state.val[1])
+					console_col = state.val[1] - 1;
+				else
+					console_col = 0;
+				return;
+		case 'J':
+				if (state.val[0] == 2)
+					lcd_clear(0);
+				state.inprogress = 0;
+				return;
+		case 'm':
+				if ((state.val[0] == 7) ||
+				    (state.val[0] == 0 && state.inverted)) {
+					invert_fg_bg_color();
+					state.inverted = (state.val[0] == 7);
+				}
+				state.inprogress = 0;
+				return;
+		default:
+			if(!isdigit(c)) {
+				state.inprogress = 0;
+				break;
+			} else {
+				*state.pos *= 10;
+				*state.pos += c - '0';
+				return;
+			}
+		}
+	}
+
 	switch (c) {
 	case '\r':	console_col = 0;
 			return;
@@ -198,6 +265,10 @@ void lcd_putc (const char c)
 	case '\b':	console_back();
 			return;
 
+	case '\e':	/* Escape ANSI \e[%dJ, \e[m, \e[%dm, and \e[%d;%dH */
+			state.inprogress = 1;
+			return;
+
 	default:	lcd_putc_xy (console_col * VIDEO_FONT_WIDTH,
 				     console_row * VIDEO_FONT_HEIGHT,
 				     c);
-- 
1.6.3.1



More information about the U-Boot mailing list