aboutsummaryrefslogtreecommitdiffstats
path: root/packages/u-boot/u-boot-mkimage-openmoko-native/console-ansi.patch
blob: 2ac5b75dee5ffc5bafd0af7548722195e3fd2103 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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,