svn commit: r197117 - head/sys/teken

Ed Schouten ed at FreeBSD.org
Sat Sep 12 12:44:22 UTC 2009


Author: ed
Date: Sat Sep 12 12:44:21 2009
New Revision: 197117
URL: http://svn.freebsd.org/changeset/base/197117

Log:
  Commit all local modifications I have to libteken:
  
  - Make xterm/cons25 support runtime configurable. This allows me to
    share libteken between syscons and my new vt driver.
  - Add a fix to print blanks after printing a double width character to
    prevent rendering artifacts.
  - Add some more utility functions that I use in the vt driver.

Modified:
  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/teken/teken.c
==============================================================================
--- head/sys/teken/teken.c	Sat Sep 12 10:41:32 2009	(r197116)
+++ head/sys/teken/teken.c	Sat Sep 12 12:44:21 2009	(r197117)
@@ -50,27 +50,16 @@ static FILE *df;
 
 #include "teken.h"
 #include "teken_wcwidth.h"
-
-#ifdef TEKEN_XTERM
 #include "teken_scs.h"
-#else /* !TEKEN_XTERM */
-#define	teken_scs_process(t, c)	(c)
-#define	teken_scs_restore(t)
-#define	teken_scs_save(t)
-#define	teken_scs_set(t, g, ts)
-#define	teken_scs_switch(t, g)
-#endif /* TEKEN_XTERM */
 
 /* Private flags for t_stateflags. */
 #define	TS_FIRSTDIGIT	0x01	/* First numeric digit in escape sequence. */
 #define	TS_INSERT	0x02	/* Insert mode. */
 #define	TS_AUTOWRAP	0x04	/* Autowrap. */
 #define	TS_ORIGIN	0x08	/* Origin mode. */
-#ifdef TEKEN_XTERM
 #define	TS_WRAPPED	0x10	/* Next character should be printed on col 0. */
-#else /* !TEKEN_XTERM */
-#define	TS_WRAPPED	0x00	/* Simple line wrapping. */
-#endif /* TEKEN_XTERM */
+#define	TS_8BIT		0x20	/* UTF-8 disabled. */
+#define	TS_CONS25	0x40	/* cons25 emulation. */
 
 /* Character that blanks a cell. */
 #define	BLANK	' '
@@ -172,14 +161,14 @@ teken_init(teken_t *t, const teken_funcs
 	t->t_softc = softc;
 
 	t->t_nextstate = teken_state_init;
+	t->t_stateflags = 0;
+	t->t_utf8_left = 0;
 
 	t->t_defattr.ta_format = 0;
 	t->t_defattr.ta_fgcolor = TC_WHITE;
 	t->t_defattr.ta_bgcolor = TC_BLACK;
 	teken_subr_do_reset(t);
 
-	t->t_utf8_left = 0;
-
 	teken_set_winsize(t, &tp);
 }
 
@@ -203,14 +192,18 @@ teken_input_char(teken_t *t, teken_char_
 	case '\x0C':
 		teken_subr_newpage(t);
 		break;
-#ifdef TEKEN_XTERM
 	case '\x0E':
-		teken_scs_switch(t, 1);
+		if (t->t_stateflags & TS_CONS25)
+			t->t_nextstate(t, c);
+		else
+			teken_scs_switch(t, 1);
 		break;
 	case '\x0F':
-		teken_scs_switch(t, 0);
+		if (t->t_stateflags & TS_CONS25)
+			t->t_nextstate(t, c);
+		else
+			teken_scs_switch(t, 0);
 		break;
-#endif /* TEKEN_XTERM */
 	case '\r':
 		teken_subr_carriage_return(t);
 		break;
@@ -245,10 +238,7 @@ teken_input_byte(teken_t *t, unsigned ch
 	/*
 	 * UTF-8 handling.
 	 */
-	if (t->t_utf8_left == -1) {
-		/* UTF-8 disabled. */
-		teken_input_char(t, c);
-	} else if ((c & 0x80) == 0x00) {
+	if ((c & 0x80) == 0x00 || t->t_stateflags & TS_8BIT) {
 		/* One-byte sequence. */
 		t->t_utf8_left = 0;
 		teken_input_char(t, c);
@@ -285,6 +275,13 @@ teken_input(teken_t *t, const void *buf,
 		teken_input_byte(t, *c++);
 }
 
+const teken_pos_t *
+teken_get_cursor(teken_t *t)
+{
+
+	return (&t->t_cursor);
+}
+
 void
 teken_set_cursor(teken_t *t, const teken_pos_t *p)
 {
@@ -324,6 +321,13 @@ teken_set_defattr(teken_t *t, const teke
 	t->t_curattr = t->t_saved_curattr = t->t_defattr = *a;
 }
 
+const teken_pos_t *
+teken_get_winsize(teken_t *t)
+{
+
+	return (&t->t_winsize);
+}
+
 void
 teken_set_winsize(teken_t *t, const teken_pos_t *p)
 {
@@ -336,7 +340,14 @@ void
 teken_set_8bit(teken_t *t)
 {
 
-	t->t_utf8_left = -1;
+	t->t_stateflags |= TS_8BIT;
+}
+
+void
+teken_set_cons25(teken_t *t)
+{
+
+	t->t_stateflags |= TS_CONS25;
 }
 
 /*

Modified: head/sys/teken/teken.h
==============================================================================
--- head/sys/teken/teken.h	Sat Sep 12 10:41:32 2009	(r197116)
+++ head/sys/teken/teken.h	Sat Sep 12 12:44:21 2009	(r197117)
@@ -34,15 +34,8 @@
  *
  * This library converts an UTF-8 stream of bytes to terminal drawing
  * commands.
- *
- * Configuration switches:
- * - TEKEN_XTERM: Enable xterm-style emulation, instead of cons25.
  */
 
-#if defined(__FreeBSD__) && defined(_KERNEL)
-#include "opt_teken.h"
-#endif /* __FreeBSD__ && _KERNEL */
-
 typedef uint32_t teken_char_t;
 typedef unsigned short teken_unit_t;
 typedef unsigned char teken_format_t;
@@ -116,9 +109,7 @@ typedef struct {
 	tf_respond_t	*tf_respond;
 } teken_funcs_t;
 
-#ifdef TEKEN_XTERM
 typedef teken_char_t teken_scs_t(teken_char_t);
-#endif /* TEKEN_XTERM */
 
 /*
  * Terminal state.
@@ -151,14 +142,12 @@ struct __teken {
 #define	T_NUMCOL	160
 	unsigned int	 t_tabstops[T_NUMCOL / (sizeof(unsigned int) * 8)];
 
-	int		 t_utf8_left;
+	unsigned int	 t_utf8_left;
 	teken_char_t	 t_utf8_partial;
 
-#ifdef TEKEN_XTERM
 	unsigned int	 t_curscs;
 	teken_scs_t	*t_saved_curscs;
 	teken_scs_t	*t_scs[2];
-#endif /* TEKEN_XTERM */
 };
 
 /* Initialize teken structure. */
@@ -168,8 +157,11 @@ void	teken_init(teken_t *, const teken_f
 void	teken_input(teken_t *, const void *, size_t);
 
 /* Get/set teken attributes. */
+const teken_pos_t *teken_get_cursor(teken_t *);
 const teken_attr_t *teken_get_curattr(teken_t *);
 const teken_attr_t *teken_get_defattr(teken_t *);
+void	teken_get_defattr_cons25(teken_t *, int *, int *);
+const teken_pos_t *teken_get_winsize(teken_t *);
 void	teken_set_cursor(teken_t *, const teken_pos_t *);
 void	teken_set_curattr(teken_t *, const teken_attr_t *);
 void	teken_set_defattr(teken_t *, const teken_attr_t *);
@@ -177,5 +169,6 @@ void	teken_set_winsize(teken_t *, const 
 
 /* Legacy features. */
 void	teken_set_8bit(teken_t *);
+void	teken_set_cons25(teken_t *);
 
 #endif /* !_TEKEN_H_ */

Modified: head/sys/teken/teken_demo.c
==============================================================================
--- head/sys/teken/teken_demo.c	Sat Sep 12 10:41:32 2009	(r197116)
+++ head/sys/teken/teken_demo.c	Sat Sep 12 12:44:21 2009	(r197117)
@@ -71,11 +71,7 @@ struct pixel {
 };
 
 #define NCOLS	80
-#ifdef TEKEN_XTERM
 #define NROWS	24
-#else /* !TEKEN_XTERM */
-#define NROWS	25
-#endif /* TEKEN_XTERM */
 struct pixel buffer[NCOLS][NROWS];
 
 static int ptfd;
@@ -300,11 +296,7 @@ main(int argc __unused, char *argv[] __u
 		perror("forkpty");
 		exit(1);
 	case 0:
-#ifdef TEKEN_XTERM
 		setenv("TERM", "xterm", 1);
-#else /* !TEKEN_XTERM */
-		setenv("TERM", "cons25", 1);
-#endif /* TEKEN_XTERM */
 		setenv("LC_CTYPE", "UTF-8", 0);
 		execlp("zsh", "-zsh", NULL);
 		execlp("bash", "-bash", NULL);

Modified: head/sys/teken/teken_subr.h
==============================================================================
--- head/sys/teken/teken_subr.h	Sat Sep 12 10:41:32 2009	(r197116)
+++ head/sys/teken/teken_subr.h	Sat Sep 12 12:44:21 2009	(r197117)
@@ -202,22 +202,22 @@ static void
 teken_subr_backspace(teken_t *t)
 {
 
-#ifdef TEKEN_XTERM
-	if (t->t_cursor.tp_col == 0)
-		return;
-
-	t->t_cursor.tp_col--;
-	t->t_stateflags &= ~TS_WRAPPED;
-#else /* !TEKEN_XTERM */
-	if (t->t_cursor.tp_col == 0) {
-		if (t->t_cursor.tp_row == t->t_originreg.ts_begin)
-			return;
-		t->t_cursor.tp_row--;
-		t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
+	if (t->t_stateflags & TS_CONS25) {
+		if (t->t_cursor.tp_col == 0) {
+			if (t->t_cursor.tp_row == t->t_originreg.ts_begin)
+				return;
+			t->t_cursor.tp_row--;
+			t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
+		} else {
+			t->t_cursor.tp_col--;
+		}
 	} else {
+		if (t->t_cursor.tp_col == 0)
+			return;
+
 		t->t_cursor.tp_col--;
+		t->t_stateflags &= ~TS_WRAPPED;
 	}
-#endif /* TEKEN_XTERM */
 
 	teken_funcs_cursor(t);
 }
@@ -588,21 +588,21 @@ teken_subr_horizontal_position_absolute(
 static void
 teken_subr_horizontal_tab(teken_t *t)
 {
-#ifdef TEKEN_XTERM
-	teken_rect_t tr;
 
-	tr.tr_begin = t->t_cursor;
-	teken_subr_cursor_forward_tabulation(t, 1);
-	tr.tr_end.tp_row = tr.tr_begin.tp_row + 1;
-	tr.tr_end.tp_col = t->t_cursor.tp_col;
-
-	/* Blank region that we skipped. */
-	if (tr.tr_end.tp_col > tr.tr_begin.tp_col)
-		teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
-#else /* !TEKEN_XTERM */
+	if (t->t_stateflags & TS_CONS25) {
+		teken_subr_cursor_forward_tabulation(t, 1);
+	} else {
+		teken_rect_t tr;
 
-	teken_subr_cursor_forward_tabulation(t, 1);
-#endif /* TEKEN_XTERM */
+		tr.tr_begin = t->t_cursor;
+		teken_subr_cursor_forward_tabulation(t, 1);
+		tr.tr_end.tp_row = tr.tr_begin.tp_row + 1;
+		tr.tr_end.tp_col = t->t_cursor.tp_col;
+
+		/* Blank region that we skipped. */
+		if (tr.tr_end.tp_col > tr.tr_begin.tp_col)
+			teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
+	}
 }
 
 static void
@@ -710,19 +710,19 @@ teken_subr_newline(teken_t *t)
 static void
 teken_subr_newpage(teken_t *t)
 {
-#ifdef TEKEN_XTERM
 
-	teken_subr_newline(t);
-#else /* !TEKEN_XTERM */
-	teken_rect_t tr;
+	if (t->t_stateflags & TS_CONS25) {
+		teken_rect_t tr;
 
-	tr.tr_begin.tp_row = tr.tr_begin.tp_col = 0;
-	tr.tr_end = t->t_winsize;
-	teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
+		tr.tr_begin.tp_row = tr.tr_begin.tp_col = 0;
+		tr.tr_end = t->t_winsize;
+		teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
 
-	t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
-	teken_funcs_cursor(t);
-#endif /* TEKEN_XTERM */
+		t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
+		teken_funcs_cursor(t);
+	} else {
+		teken_subr_newline(t);
+	}
 }
 
 static void
@@ -779,6 +779,20 @@ teken_subr_do_putchar(teken_t *t, const 
 		teken_funcs_copy(t, &ctr, &ctp);
 	}
 
+	if (width == 2 && tp->tp_col + 1 < t->t_winsize.tp_col) {
+		teken_pos_t tp2;
+
+		/*
+		 * Store a space behind double width characters before
+		 * actually printing them. This prevents artifacts when
+		 * the consumer doesn't render it using double width
+		 * glyphs.
+		 */
+		tp2.tp_row = tp->tp_row;
+		tp2.tp_col = tp->tp_col + 1;
+		teken_funcs_putchar(t, &tp2, BLANK, &t->t_curattr);
+	}
+
 	teken_funcs_putchar(t, tp, c, &t->t_curattr);
 }
 
@@ -787,11 +801,9 @@ teken_subr_regular_character(teken_t *t,
 {
 	int width;
 
-	if (t->t_utf8_left == -1) {
-#ifdef TEKEN_XTERM
-		if (c <= 0x1B)
+	if (t->t_stateflags & TS_8BIT) {
+		if (!(t->t_stateflags & TS_CONS25) && c <= 0x1B)
 			return;
-#endif /* TEKEN_XTERM */
 		width = 1;
 	} else {
 		c = teken_scs_process(t, c);
@@ -801,8 +813,23 @@ teken_subr_regular_character(teken_t *t,
 			return;
 	}
 
-#ifdef TEKEN_XTERM
-	if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1 &&
+	if (t->t_stateflags & TS_CONS25) {
+		teken_subr_do_putchar(t, &t->t_cursor, c, width);
+		t->t_cursor.tp_col += width;
+
+		if (t->t_cursor.tp_col >= t->t_winsize.tp_col) {
+			if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) {
+				/* Perform scrolling. */
+				teken_subr_do_scroll(t, 1);
+			} else {
+				/* No scrolling needed. */
+				if (t->t_cursor.tp_row <
+				    t->t_winsize.tp_row - 1)
+					t->t_cursor.tp_row++;
+			}
+			t->t_cursor.tp_col = 0;
+		}
+	} else if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1 &&
 	    (t->t_stateflags & (TS_WRAPPED|TS_AUTOWRAP)) ==
 	    (TS_WRAPPED|TS_AUTOWRAP)) {
 		teken_pos_t tp;
@@ -846,22 +873,6 @@ teken_subr_regular_character(teken_t *t,
 			t->t_stateflags &= ~TS_WRAPPED;
 		}
 	}
-#else /* !TEKEN_XTERM */
-	teken_subr_do_putchar(t, &t->t_cursor, c, width);
-	t->t_cursor.tp_col += width;
-
-	if (t->t_cursor.tp_col >= t->t_winsize.tp_col) {
-		if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) {
-			/* Perform scrolling. */
-			teken_subr_do_scroll(t, 1);
-		} else {
-			/* No scrolling needed. */
-			if (t->t_cursor.tp_row < t->t_winsize.tp_row - 1)
-				t->t_cursor.tp_row++;
-		}
-		t->t_cursor.tp_col = 0;
-	}
-#endif /* TEKEN_XTERM */
 
 	teken_funcs_cursor(t);
 }
@@ -937,7 +948,8 @@ teken_subr_do_reset(teken_t *t)
 	t->t_scrollreg.ts_begin = 0;
 	t->t_scrollreg.ts_end = t->t_winsize.tp_row;
 	t->t_originreg = t->t_scrollreg;
-	t->t_stateflags = TS_AUTOWRAP;
+	t->t_stateflags &= TS_8BIT|TS_CONS25;
+	t->t_stateflags |= TS_AUTOWRAP;
 
 	teken_scs_set(t, 0, teken_scs_us_ascii);
 	teken_scs_set(t, 1, teken_scs_us_ascii);

Modified: head/sys/teken/teken_subr_compat.h
==============================================================================
--- head/sys/teken/teken_subr_compat.h	Sat Sep 12 10:41:32 2009	(r197116)
+++ head/sys/teken/teken_subr_compat.h	Sat Sep 12 12:44:21 2009	(r197117)
@@ -59,6 +59,18 @@ teken_subr_cons25_set_adapter_foreground
 	}
 }
 
+static const teken_color_t cons25_revcolors[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+void
+teken_get_defattr_cons25(teken_t *t, int *fg, int *bg)
+{
+
+	*fg = cons25_revcolors[t->t_defattr.ta_fgcolor];
+	if (t->t_defattr.ta_format & TF_BOLD)
+		*fg += 8;
+	*bg = cons25_revcolors[t->t_defattr.ta_bgcolor];
+}
+
 static void
 teken_subr_cons25_switch_virtual_terminal(teken_t *t, unsigned int vt)
 {


More information about the svn-src-head mailing list