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.
This commit is contained in:
Ed Schouten 2009-09-12 12:44:21 +00:00
parent 5e666eb395
commit eba77f5c40
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=197117
5 changed files with 122 additions and 102 deletions

View File

@ -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;
}
/*

View File

@ -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_ */

View File

@ -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);

View File

@ -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);

View File

@ -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)
{