drivers/cfb_console.c: added processing of ANSI escape sequences \e[2J, \e[m,
  \e[7m, and \e[row;colH
drivers/cfb_console.c (video_putc): make \r return to the beginning of the line

- Werner Almesberger <werner@openmoko.org>

Index: u-boot/drivers/cfb_console.c
===================================================================
--- u-boot.orig/drivers/cfb_console.c
+++ u-boot/drivers/cfb_console.c
@@ -181,6 +181,7 @@ CONFIG_VIDEO_HW_CURSOR:	     - Uses the 
 
 #include <version.h>
 #include <linux/types.h>
+#include <linux/ctype.h>
 #include <devices.h>
 #include <video_font.h>
 #ifdef CFG_CMD_DATE
@@ -676,10 +677,96 @@ static void console_newline (void)
 
 /*****************************************************************************/
 
+static enum {
+	CS_NORMAL = 0,
+	CS_ESC,
+	CS_NUM1,
+	CS_NUM2,
+} state = 0;
+
+static int num1, num2;
+
+
+static void swap_drawing_colors(void)
+{
+	eorx = fgx;
+	fgx = bgx;
+	bgx = eorx;
+	eorx = fgx ^ bgx;
+}
+
+
+static void process_sequence(char c)
+{
+	static int inverted = 0;
+	int i, inv;
+
+	switch (c) {
+		case 'J':
+			/* assume num1 == 2 */
+			for (i = 0; i != CONSOLE_ROWS; i++)
+				console_scrollup();
+			break;
+		case 'H':
+			if (num1 > CONSOLE_ROWS || num2 > CONSOLE_COLS)
+				break;
+			console_col = num2 ? num2-1 : 0;
+			console_row = num1 ? num1-1 : 0;
+			break;
+		case 'm':
+			inv = num1 == 7;
+			if (num1 && !inv)
+				break;
+			if (inverted != inv)
+				swap_drawing_colors();
+			inverted = inv;
+			break;
+	}
+}
+
+
+static void escape_sequence(char c)
+{
+	switch (state) {
+		case CS_ESC:
+			state = c == '[' ? CS_NUM1 : CS_NORMAL;
+			num1 = num2 = 0;
+			break;
+		case CS_NUM1:
+			if (isdigit(c))
+				num1 = num1*10+c-'0';
+			else if (c == ';')
+				state = CS_NUM2;
+			else {
+				process_sequence(c);
+				state = CS_NORMAL;
+			}
+			break;
+		case CS_NUM2:
+			if (isdigit(c))
+				num2 = num2*10+c-'0';
+			else {
+				process_sequence(c);
+				state = CS_NORMAL;
+			}
+		default:
+			/* can't happen */;
+	}
+}
+
+
 void video_putc (const char c)
 {
+	if (state) {
+		escape_sequence(c);
+		CURSOR_SET;
+		return;
+	}
+
 	switch (c) {
-	case 13:		/* ignore */
+	case 13:		/* return to beginning of line */
+		CURSOR_OFF;
+		console_col = 0;
 		break;
 
 	case '\n':		/* next line */
@@ -698,6 +785,10 @@ void video_putc (const char c)
 		console_back ();
 		break;
 
+	case '\e':
+		state = CS_ESC;
+		break;
+
 	default:		/* draw the char */
 		video_putchar (console_col * VIDEO_FONT_WIDTH,
 			       console_row * VIDEO_FONT_HEIGHT,
