[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

gnumach color support



Hi,

attached is the gnumach color support patch. I am not sure it still applies
cleanly, but the conflicts should be easily resolvable. Let me know.

There are at least two problems with this patch (apart from the simple
fact it is heading in the wrong direction):

* the colors are all scrambled, that means, you get colors, but
not the correct ones. I need a corrected list of the color values.

* There are some restrictions for the attributes. I think bold and dim
are not supported at the same time, or so. I don't think it matters much.
I copied the strategy from linux, IIRC.

I don't care about the latter, but the ordering of colors must be corrected.
So, someone please work this out and send me a corrected list, and then
I will compile and upload a new Debian package of gnumach, with color
support.

Because I planned this a while ago, you just need to apply it to gnumach
and compile. Then set

export TERM=mach-color

(you already should have it, it is in the newer ncurses packages).

or change the default in /etc/ttys (mach -> mach-color)

That's all folks.
Marcus
diff -ru gnumach.2.2/i386/i386at/kd.c gnumach.new/i386/i386at/kd.c
--- gnumach.2.2/i386/i386at/kd.c	Fri Sep 24 02:46:45 1999
+++ gnumach.new/i386/i386at/kd.c	Thu Sep 23 06:13:49 1999
@@ -165,6 +165,8 @@
 short	kd_lines	= 25;
 short	kd_cols		= 80;
 char	kd_attr		= KA_NORMAL;	/* current attribute */
+char	kd_color	= KA_NORMAL;
+char	kd_attrflags	= 0;		/* Not reverse, underline, blink */
 
 /* 
  * kd_state shows the state of the modifier keys (ctrl, caps lock, 
@@ -213,7 +215,7 @@
 boolean_t kd_extended	= FALSE;
 
 /* Array for processing escape sequences. */
-#define	K_MAXESC	16
+#define	K_MAXESC	32
 u_char	esc_seq[K_MAXESC];
 u_char	*esc_spt	= (u_char *)0;
 
@@ -1210,6 +1212,8 @@
 
 	esc_spt = esc_seq;
 	kd_attr = KA_NORMAL;
+	kd_attrflags = 0;
+	kd_color = KA_NORMAL;
 
 	/*
 	 * board specific initialization: set up globals and kd_dxxx
@@ -1481,6 +1485,30 @@
 
 }
 
+/* kd_update_kd_attr:
+ *
+ *	Updates kd_attr according to kd_attrflags and kd_color.
+ * This code has its origin from console.c and selection.h in
+ * linux 2.2 drivers/char/.
+ * Modified for GNU Mach by Marcus Brinkmann.
+ */
+
+#define reverse_video_char(a)       (((a) & 0x88) | ((((a) >> 4) | ((a) << 4)) & 0x77))
+void
+kd_update_kd_attr(void)
+{
+	kd_attr = kd_color;
+	if (kd_attrflags & KAX_UNDERLINE)
+		kd_attr = (kd_attr & 0xf0) | KAX_COL_UNDERLINE;
+	else if (kd_attrflags & KAX_DIM)
+		kd_attr = (kd_attr & 0xf0) | KAX_COL_DIM;
+	if (kd_attrflags & KAX_REVERSE)
+		kd_attr = reverse_video_char(kd_attr);
+	if (kd_attrflags & KAX_BLINK)
+		kd_attr ^= 0x80;
+	if (kd_attrflags & KAX_BOLD)
+		kd_attr ^= 0x08;
+}	
 
 /*
  * kd_parserest:
@@ -1498,130 +1526,169 @@
 kd_parserest(cp)
 u_char	*cp;
 {
-	int	number;
+	int	number[16], npar = 0, i;
 	csrpos_t newpos;
 
-	cp += kd_atoi(cp, &number);
+	for(i=0;i<=15;i++)
+		number[i] = DEFAULT;
+
+	do {
+		cp += kd_atoi(cp, &number[npar]);
+	} while (*cp == ';' && ++npar <= 15 && cp++);
+	
 	switch(*cp) {
 	case 'm':
-		switch(number) {
-		case DEFAULT:
-		case 0:
-			kd_attr = KA_NORMAL;
-			break;
-		case 7:
-			kd_attr = KA_REVERSE;
-			break;
-		default:
-			kd_attr = KA_NORMAL;
-			break;
-		}
+		for (i=0;i<=npar;i++)
+			switch(number[i]) {
+			case DEFAULT:
+			case 0:
+				kd_attrflags = 0;
+				kd_color = KA_NORMAL;
+				break;
+			case 1:
+				kd_attrflags |= KAX_BOLD;
+				kd_attrflags &= ~KAX_DIM;
+				break;
+			case 2:
+				kd_attrflags |= KAX_DIM;
+				kd_attrflags &= ~KAX_BOLD;
+				break;
+			case 4:
+				kd_attrflags |= KAX_UNDERLINE;
+				break;
+			case 5:
+				kd_attrflags |= KAX_BLINK;
+				break;
+			case 7:
+				kd_attrflags |= KAX_REVERSE;
+				break;
+			case 8:
+				kd_attrflags |= KAX_INVISIBLE;
+				break;
+			case 21:
+			case 22:
+				kd_attrflags &= ~(KAX_BOLD | KAX_DIM);
+				break;
+			case 24:
+				kd_attrflags &= ~KAX_UNDERLINE;
+				break;
+			case 25:
+				kd_attrflags &= ~KAX_BLINK;
+				break;
+			case 27:
+				kd_attrflags &= ~KAX_REVERSE;
+				break;
+			case 38:
+				kd_attrflags |= KAX_UNDERLINE;
+				kd_color = (kd_color & 0xf0) | (KA_NORMAL & 0x0f);
+				break;
+			case 39:
+				kd_attrflags &= ~KAX_UNDERLINE;
+				kd_color = (kd_color & 0xf0) | (KA_NORMAL & 0x0f);
+				break;
+			default:
+				if (number[i] >= 30 && number[i] <= 37) /* foreground color */
+					kd_color = (kd_color & 0xf0) | (number[i] - 30);
+				else if (number[i] >= 40 && number[i] <= 47) /* background color */
+					kd_color = (kd_color & 0x0f) | ((number[i] - 40) << 4);
+				break;
+			}
+		kd_update_kd_attr();
 		esc_spt = esc_seq;
 		break;
 	case '@':
-		if (number == DEFAULT)
+		if (number[0] == DEFAULT)
 			kd_insch(1);
 		else
-			kd_insch(number);
-		esc_spt = esc_seq;
-		break;
-	case 'H':
-		kd_home();
+			kd_insch(number[0]);
 		esc_spt = esc_seq;
 		break;
 	case 'A':
-		if (number == DEFAULT)
+		if (number[0] == DEFAULT)
 			kd_up();
 		else
-			while (number--)
+			while (number[0]--)
 				kd_up();
 		esc_spt = esc_seq;
 		break;
 	case 'B':
-		if (number == DEFAULT)
+		if (number[0] == DEFAULT)
 			kd_down();
 		else
-			while (number--)
+			while (number[0]--)
 				kd_down();
 		esc_spt = esc_seq;
 		break;
 	case 'C':
-		if (number == DEFAULT)
+		if (number[0] == DEFAULT)
 			kd_right();
 		else
-			while (number--)
+			while (number[0]--)
 				kd_right();
 		esc_spt = esc_seq;
 		break;
 	case 'D':
-		if (number == DEFAULT)
+		if (number[0] == DEFAULT)
 			kd_left();
 		else
-			while (number--)
+			while (number[0]--)
 				kd_left();
 		esc_spt = esc_seq;
 		break;
 	case 'E':
 		kd_cr();
-		if (number == DEFAULT)
+		if (number[0] == DEFAULT)
 			kd_down();
 		else
-			while (number--)
+			while (number[0]--)
 				kd_down();
 		esc_spt = esc_seq;
 		break;
 	case 'F':
 		kd_cr();
-		if (number == DEFAULT)
+		if (number[0] == DEFAULT)
 			kd_up();
 		else
-			while (number--)
+			while (number[0]--)
 				kd_up();
 		esc_spt = esc_seq;
 		break;
 	case 'G':
-		if (number == DEFAULT)
-			number = 0;
+		if (number[0] == DEFAULT)
+			number[0] = 0;
 		else
-			if (number > 0)
-				--number;	/* because number is from 1 */
-		kd_setpos(BEG_OF_LINE(kd_curpos) + number * ONE_SPACE);
+			if (number[0] > 0)
+				--number[0];	/* because number[0] is from 1 */
+		kd_setpos(BEG_OF_LINE(kd_curpos) + number[0] * ONE_SPACE);
 		esc_spt = esc_seq;
 		break;
-	case ';':
-		++cp;
-		if (*cp == '\0')
-			break;			/* not ready yet */
-		if (number == DEFAULT)
-			number = 0;
-		else
-			if (number > 0)
-				--number;		/* numbered from 1 */
-		newpos = (number * ONE_LINE);   /* setup row */
-		cp += kd_atoi(cp, &number);
-		if (*cp == '\0')
-			break;			/* not ready yet */
-		if (number == DEFAULT)
-			number = 0;
-		else if (number > 0)
-			number--;
-		newpos += (number * ONE_SPACE);	/* setup column */
+	case 'f':
+	case 'H':
+		if (number[0] == DEFAULT && number[1] == DEFAULT)
+		{
+			kd_home();
+			esc_spt = esc_seq;
+			break;
+		}
+		if (number[0] == DEFAULT)
+			number[0] = 0;
+		else if (number[0] > 0)
+			--number[0];		/* numbered from 1 */
+		newpos = (number[0] * ONE_LINE);   /* setup row */
+		if (number[1] == DEFAULT)
+			number[1] = 0;
+		else if (number[1] > 0)
+			number[1]--;
+		newpos += (number[1] * ONE_SPACE);	/* setup column */
 		if (newpos < 0)
 			newpos = 0;		/* upper left */
 		if (newpos > ONE_PAGE)
-			newpos = (ONE_PAGE - ONE_SPACE); 
-		/* lower right */
-		if (*cp == '\0')
-			break;			/* not ready yet */
-		if (*cp == 'H') {
-			kd_setpos(newpos);
-			esc_spt = esc_seq;	/* done, reset */
-		}	
-		else
-			esc_spt = esc_seq;
+			newpos = (ONE_PAGE - ONE_SPACE); /* lower right */
+		kd_setpos(newpos);
+		esc_spt = esc_seq;
 		break;				/* done or not ready */
 	case 'J':
-		switch(number) {
+		switch(number[0]) {
 		case DEFAULT:
 		case 0:
 			kd_cltobcur();	/* clears from current
@@ -1642,7 +1709,7 @@
 		esc_spt = esc_seq;		/* reset it */
 		break;
 	case 'K':
-		switch(number) {
+		switch(number[0]) {
 		case DEFAULT:
 		case 0:
 			kd_cltoecur();	/* clears from current
@@ -1664,47 +1731,47 @@
 		esc_spt = esc_seq;
 		break;
 	case 'L':
-		if (number == DEFAULT)
+		if (number[0] == DEFAULT)
 			kd_insln(1);
 		else
-			kd_insln(number);
+			kd_insln(number[0]);
 		esc_spt = esc_seq;
 		break;
 	case 'M':
-		if (number == DEFAULT)
+		if (number[0] == DEFAULT)
 			kd_delln(1);
 		else
-			kd_delln(number);
+			kd_delln(number[0]);
 		esc_spt = esc_seq;
 		break;
 	case 'P':
-		if (number == DEFAULT)
+		if (number[0] == DEFAULT)
 			kd_delch(1);
 		else
-			kd_delch(number);
+			kd_delch(number[0]);
 		esc_spt = esc_seq;
 		break;
 	case 'S':
-		if (number == DEFAULT)
+		if (number[0] == DEFAULT)
 			kd_scrollup();
 		else
-			while (number--)
+			while (number[0]--)
 				kd_scrollup();
 		esc_spt = esc_seq;
 		break;
 	case 'T':
-		if (number == DEFAULT)
+		if (number[0] == DEFAULT)
 			kd_scrolldn();
 		else
-			while (number--)
+			while (number[0]--)
 				kd_scrolldn();
 		esc_spt = esc_seq;
 		break;
 	case 'X':
-		if (number == DEFAULT)
+		if (number[0] == DEFAULT)
 			kd_erase(1);
 		else
-			kd_erase(number);
+			kd_erase(number[0]);
 		esc_spt = esc_seq;
 		break;	
 	case '\0':
diff -ru gnumach.2.2/i386/i386at/kd.h gnumach.new/i386/i386at/kd.h
--- gnumach.2.2/i386/i386at/kd.h	Mon Apr 26 20:46:47 1999
+++ gnumach.new/i386/i386at/kd.h	Thu Sep 23 04:09:57 1999
@@ -212,6 +212,16 @@
 #define KA_NORMAL	0x07
 #define KA_REVERSE	0x70
 
+#define KAX_REVERSE	0x01
+#define KAX_UNDERLINE	0x02
+#define KAX_BLINK	0x04
+#define KAX_BOLD	0x08
+#define KAX_DIM		0x10
+#define KAX_INVISIBLE	0x20
+
+#define KAX_COL_UNDERLINE 0x0f	/* bright white */
+#define KAX_COL_DIM 0x08	/* gray */
+
 /*
  * For an EGA-like display, each character takes two bytes, one for the 
  * actual character, followed by one for its attributes.  

Reply to: