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: