svn commit: r197522 - in head/sys: dev/syscons teken

Ed Schouten ed at FreeBSD.org
Sat Sep 26 15:26:33 UTC 2009


Author: ed
Date: Sat Sep 26 15:26:32 2009
New Revision: 197522
URL: http://svn.freebsd.org/changeset/base/197522

Log:
  Add 256 color support.
  
  It is quite inconvenient that if an application for xterm uses 256 color
  mode, text suddenly starts to blink (because of ;5; in the middle).
  We'd better just implement 256 color mode and add a conversion routine
  from 256 to 8 color mode, which doesn't seem to be too bad in practice.
  
  Remapping colors is done quite simple. If one of the channels is most
  actively represented, primary colors are used. If two channels are most
  actively represented, secondary colors are used. If all three channels
  are equal (gray), it picks between black and white.
  
  Reported by:	Paul B. Mahol <onemda gmail com>

Modified:
  head/sys/dev/syscons/scterm-teken.c
  head/sys/teken/teken.c
  head/sys/teken/teken.h
  head/sys/teken/teken_demo.c
  head/sys/teken/teken_subr.h
  head/sys/teken/teken_subr_compat.h

Modified: head/sys/dev/syscons/scterm-teken.c
==============================================================================
--- head/sys/dev/syscons/scterm-teken.c	Sat Sep 26 15:07:11 2009	(r197521)
+++ head/sys/dev/syscons/scterm-teken.c	Sat Sep 26 15:26:32 2009	(r197522)
@@ -313,11 +313,11 @@ scteken_attr(const teken_attr_t *a)
 	teken_color_t fg, bg;
 
 	if (a->ta_format & TF_REVERSE) {
-		fg = a->ta_bgcolor;
-		bg = a->ta_fgcolor;
+		fg = teken_256to8(a->ta_bgcolor);
+		bg = teken_256to8(a->ta_fgcolor);
 	} else {
-		fg = a->ta_fgcolor;
-		bg = a->ta_bgcolor;
+		fg = teken_256to8(a->ta_fgcolor);
+		bg = teken_256to8(a->ta_bgcolor);
 	}
 	if (a->ta_format & TF_BOLD)
 		attr |= fgcolors_bold[fg];

Modified: head/sys/teken/teken.c
==============================================================================
--- head/sys/teken/teken.c	Sat Sep 26 15:07:11 2009	(r197521)
+++ head/sys/teken/teken.c	Sat Sep 26 15:26:32 2009	(r197522)
@@ -409,4 +409,55 @@ teken_state_numbers(teken_t *t, teken_ch
 	return (0);
 }
 
+teken_color_t
+teken_256to8(teken_color_t c)
+{
+	unsigned int r, g, b;
+
+	if (c < 16) {
+		/* Traditional color indices. */
+		return (c % 8);
+	} else if (c >= 244) {
+		/* Upper grayscale colors. */
+		return (TC_WHITE);
+	} else if (c >= 232) {
+		/* Lower grayscale colors. */
+		return (TC_BLACK);
+	}
+
+	/* Convert to RGB. */
+	c -= 16;
+	b = c % 6;
+	g = (c / 6) % 6;
+	r = c / 36;
+
+	if (r < g) {
+		/* Possibly green. */
+		if (g < b)
+			return (TC_BLUE);
+		else if (g > b)
+			return (TC_GREEN);
+		else
+			return (TC_CYAN);
+	} else if (r > g) {
+		/* Possibly red. */
+		if (r < b)
+			return (TC_BLUE);
+		else if (r > b)
+			return (TC_RED);
+		else
+			return (TC_MAGENTA);
+	} else {
+		/* Possibly brown. */
+		if (g < b)
+			return (TC_BLUE);
+		else if (g > b)
+			return (TC_BROWN);
+		else if (r < 3)
+			return (TC_BLACK);
+		else
+			return (TC_WHITE);
+	}
+}
+
 #include "teken_state.h"

Modified: head/sys/teken/teken.h
==============================================================================
--- head/sys/teken/teken.h	Sat Sep 26 15:07:11 2009	(r197521)
+++ head/sys/teken/teken.h	Sat Sep 26 15:26:32 2009	(r197522)
@@ -171,4 +171,7 @@ void	teken_set_winsize(teken_t *, const 
 void	teken_set_8bit(teken_t *);
 void	teken_set_cons25(teken_t *);
 
+/* Color conversion. */
+teken_color_t teken_256to8(teken_color_t);
+
 #endif /* !_TEKEN_H_ */

Modified: head/sys/teken/teken_demo.c
==============================================================================
--- head/sys/teken/teken_demo.c	Sat Sep 26 15:07:11 2009	(r197521)
+++ head/sys/teken/teken_demo.c	Sat Sep 26 15:26:32 2009	(r197522)
@@ -116,7 +116,8 @@ printchar(const teken_pos_t *p)
 	if (px->a.ta_format & TF_REVERSE)
 		attr |= A_REVERSE;
 
-	bkgdset(attr | COLOR_PAIR(px->a.ta_fgcolor + 8 * px->a.ta_bgcolor));
+	bkgdset(attr | COLOR_PAIR(teken_256to8(px->a.ta_fgcolor) +
+	      8 * teken_256to8(px->a.ta_bgcolor)));
 	mvaddstr(p->tp_row, p->tp_col, str);
 
 	move(y, x);

Modified: head/sys/teken/teken_subr.h
==============================================================================
--- head/sys/teken/teken_subr.h	Sat Sep 26 15:07:11 2009	(r197521)
+++ head/sys/teken/teken_subr.h	Sat Sep 26 15:26:32 2009	(r197522)
@@ -1150,6 +1150,12 @@ teken_subr_set_graphic_rendition(teken_t
 		case 37: /* Set foreground color: white */
 			t->t_curattr.ta_fgcolor = n - 30;
 			break;
+		case 38: /* Set foreground color: 256 color mode */
+			if (i + 2 >= ncmds || cmds[i + 1] != 5)
+				continue;
+			t->t_curattr.ta_fgcolor = cmds[i + 2];
+			i += 2;
+			break;
 		case 39: /* Set default foreground color. */
 			t->t_curattr.ta_fgcolor = t->t_defattr.ta_fgcolor;
 			break;
@@ -1163,9 +1169,35 @@ teken_subr_set_graphic_rendition(teken_t
 		case 47: /* Set background color: white */
 			t->t_curattr.ta_bgcolor = n - 40;
 			break;
+		case 48: /* Set background color: 256 color mode */
+			if (i + 2 >= ncmds || cmds[i + 1] != 5)
+				continue;
+			t->t_curattr.ta_bgcolor = cmds[i + 2];
+			i += 2;
+			break;
 		case 49: /* Set default background color. */
 			t->t_curattr.ta_bgcolor = t->t_defattr.ta_bgcolor;
 			break;
+		case 90: /* Set bright foreground color: black */
+		case 91: /* Set bright foreground color: red */
+		case 92: /* Set bright foreground color: green */
+		case 93: /* Set bright foreground color: brown */
+		case 94: /* Set bright foreground color: blue */
+		case 95: /* Set bright foreground color: magenta */
+		case 96: /* Set bright foreground color: cyan */
+		case 97: /* Set bright foreground color: white */
+			t->t_curattr.ta_fgcolor = n - 90 + 8;
+			break;
+		case 100: /* Set bright background color: black */
+		case 101: /* Set bright background color: red */
+		case 102: /* Set bright background color: green */
+		case 103: /* Set bright background color: brown */
+		case 104: /* Set bright background color: blue */
+		case 105: /* Set bright background color: magenta */
+		case 106: /* Set bright background color: cyan */
+		case 107: /* Set bright background color: white */
+			t->t_curattr.ta_bgcolor = n - 100 + 8;
+			break;
 		default:
 			teken_printf("unsupported attribute %u\n", n);
 		}

Modified: head/sys/teken/teken_subr_compat.h
==============================================================================
--- head/sys/teken/teken_subr_compat.h	Sat Sep 26 15:07:11 2009	(r197521)
+++ head/sys/teken/teken_subr_compat.h	Sat Sep 26 15:26:32 2009	(r197522)
@@ -65,10 +65,10 @@ void
 teken_get_defattr_cons25(teken_t *t, int *fg, int *bg)
 {
 
-	*fg = cons25_revcolors[t->t_defattr.ta_fgcolor];
+	*fg = cons25_revcolors[teken_256to8(t->t_defattr.ta_fgcolor)];
 	if (t->t_defattr.ta_format & TF_BOLD)
 		*fg += 8;
-	*bg = cons25_revcolors[t->t_defattr.ta_bgcolor];
+	*bg = cons25_revcolors[teken_256to8(t->t_defattr.ta_bgcolor)];
 }
 
 static void


More information about the svn-src-all mailing list