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:
parent
5e666eb395
commit
eba77f5c40
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=197117
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user