summaryrefslogtreecommitdiffstats
path: root/sys/teken
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2009-09-12 12:44:21 +0000
committered <ed@FreeBSD.org>2009-09-12 12:44:21 +0000
commit6047d14a18b1b4e8084fe0b353740ae91abd3fe7 (patch)
tree10b40ef171c3256b962afcb40e7cfb809b0a0e3f /sys/teken
parente0831cf5d0a0f960d8518c8d799dada4d6c332ae (diff)
downloadFreeBSD-src-6047d14a18b1b4e8084fe0b353740ae91abd3fe7.zip
FreeBSD-src-6047d14a18b1b4e8084fe0b353740ae91abd3fe7.tar.gz
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.
Diffstat (limited to 'sys/teken')
-rw-r--r--sys/teken/teken.c59
-rw-r--r--sys/teken/teken.h17
-rw-r--r--sys/teken/teken_demo.c8
-rw-r--r--sys/teken/teken_subr.h128
-rw-r--r--sys/teken/teken_subr_compat.h12
5 files changed, 122 insertions, 102 deletions
diff --git a/sys/teken/teken.c b/sys/teken/teken.c
index 92a81f1..da5c056 100644
--- a/sys/teken/teken.c
+++ b/sys/teken/teken.c
@@ -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 *tf, void *softc)
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_t c)
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 char c)
/*
* 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, size_t len)
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 teken_attr_t *a)
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;
}
/*
diff --git a/sys/teken/teken.h b/sys/teken/teken.h
index 7f3afae..65ee05e 100644
--- a/sys/teken/teken.h
+++ b/sys/teken/teken.h
@@ -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_funcs_t *, void *);
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 teken_pos_t *);
/* Legacy features. */
void teken_set_8bit(teken_t *);
+void teken_set_cons25(teken_t *);
#endif /* !_TEKEN_H_ */
diff --git a/sys/teken/teken_demo.c b/sys/teken/teken_demo.c
index ebc3ea6..4f8a0d5 100644
--- a/sys/teken/teken_demo.c
+++ b/sys/teken/teken_demo.c
@@ -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[] __unused)
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);
diff --git a/sys/teken/teken_subr.h b/sys/teken/teken_subr.h
index 0ba531d..ab3e759 100644
--- a/sys/teken/teken_subr.h
+++ b/sys/teken/teken_subr.h
@@ -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(teken_t *t, unsigned int col)
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;
+ if (t->t_stateflags & TS_CONS25) {
+ teken_subr_cursor_forward_tabulation(t, 1);
+ } else {
+ teken_rect_t tr;
- /* 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 */
+ 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;
- teken_subr_cursor_forward_tabulation(t, 1);
-#endif /* TEKEN_XTERM */
+ /* 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_pos_t *tp, teken_char_t c,
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, teken_char_t c)
{
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, teken_char_t c)
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, teken_char_t c)
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);
diff --git a/sys/teken/teken_subr_compat.h b/sys/teken/teken_subr_compat.h
index 4e03c66..c642af7 100644
--- a/sys/teken/teken_subr_compat.h
+++ b/sys/teken/teken_subr_compat.h
@@ -59,6 +59,18 @@ teken_subr_cons25_set_adapter_foreground(teken_t *t, unsigned int c)
}
}
+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)
{
OpenPOWER on IntegriCloud