diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 461968758fdc..b28c055cd5c1 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1370,6 +1370,10 @@ options SC_NO_SUSPEND_VTYSWITCH # 0x80 Put the video card in the VESA 800x600 dots, 16 color mode # 0x100 Probe for a keyboard device periodically if one is not present +# Enable experimental features of the syscons terminal emulator (teken). +options TEKEN_UTF8 # UTF-8 output handling +options TEKEN_XTERM # xterm-style terminal emulation + # # Optional devices: # diff --git a/sys/conf/options b/sys/conf/options index b7424f617941..5ce34ee9f004 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -726,6 +726,10 @@ SC_PIXEL_MODE opt_syscons.h SC_RENDER_DEBUG opt_syscons.h SC_TWOBUTTON_MOUSE opt_syscons.h +# teken terminal emulator options +TEKEN_UTF8 opt_teken.h +TEKEN_XTERM opt_teken.h + # options for printf PRINTF_BUFR_SIZE opt_printf.h diff --git a/sys/dev/syscons/teken/teken.c b/sys/dev/syscons/teken/teken.c index 62ded2741b96..575ffce61518 100644 --- a/sys/dev/syscons/teken/teken.c +++ b/sys/dev/syscons/teken/teken.c @@ -56,11 +56,11 @@ static inline int teken_wcwidth(teken_char_t c __unused) { -#ifdef TEKEN_CONS25 - return (1); -#else /* !TEKEN_CONS25 */ +#ifdef TEKEN_XTERM return (c <= 0x1B) ? -1 : 1; -#endif /* TEKEN_CONS25 */ +#else /* !TEKEN_XTERM */ + return (1); +#endif /* TEKEN_XTERM */ } #endif /* TEKEN_UTF8 */ @@ -72,11 +72,11 @@ teken_wcwidth(teken_char_t c __unused) #define TS_INSERT 0x02 /* Insert mode. */ #define TS_AUTOWRAP 0x04 /* Autowrap. */ #define TS_ORIGIN 0x08 /* Origin mode. */ -#ifdef TEKEN_CONS25 -#define TS_WRAPPED 0x00 /* Simple line wrapping. */ -#else /* !TEKEN_CONS25 */ +#ifdef TEKEN_XTERM #define TS_WRAPPED 0x10 /* Next character should be printed on col 0. */ -#endif /* TEKEN_CONS25 */ +#else /* !TEKEN_XTERM */ +#define TS_WRAPPED 0x00 /* Simple line wrapping. */ +#endif /* TEKEN_XTERM */ /* Character that blanks a cell. */ #define BLANK ' ' diff --git a/sys/dev/syscons/teken/teken.h b/sys/dev/syscons/teken/teken.h index 61c8afe74a57..025d8aa9551f 100644 --- a/sys/dev/syscons/teken/teken.h +++ b/sys/dev/syscons/teken/teken.h @@ -33,18 +33,16 @@ * libteken: terminal emulation library. * * This library converts an UTF-8 stream of bytes to terminal drawing - * commands. It implements commands similar to xterm-color. + * commands. + * + * Configuration switches: + * - TEKEN_UTF8: Enable/disable UTF-8 handling. + * - TEKEN_XTERM: Enable xterm-style emulation, instead of cons25. */ -#if 0 -/* - * XXX: Disable UTF-8 support for now. It requires UTF-8 keyboard input - * and rendering, which we do not yet support. - */ -#define TEKEN_UTF8 -#endif -/* Emulate cons25-like behaviour. */ -#define TEKEN_CONS25 +#if defined(__FreeBSD__) && defined(_KERNEL) +#include "opt_teken.h" +#endif /* __FreeBSD__ && _KERNEL */ #ifdef TEKEN_UTF8 typedef uint32_t teken_char_t; diff --git a/sys/dev/syscons/teken/teken_demo.c b/sys/dev/syscons/teken/teken_demo.c index 2d0a4bf3ad51..7fea64e87a5c 100644 --- a/sys/dev/syscons/teken/teken_demo.c +++ b/sys/dev/syscons/teken/teken_demo.c @@ -279,11 +279,11 @@ main(int argc __unused, char *argv[] __unused) perror("forkpty"); exit(1); case 0: -#ifdef TEKEN_CONS25 - setenv("TERM", "cons25", 1); -#else /* !TEKEN_CONS25 */ +#ifdef TEKEN_XTERM setenv("TERM", "xterm", 1); -#endif /* TEKEN_CONS25 */ +#else /* !TEKEN_XTERM */ + setenv("TERM", "cons25", 1); +#endif /* TEKEN_XTERM */ #ifdef TEKEN_UTF8 setenv("LC_CTYPE", "UTF-8", 0); #endif /* TEKEN_UTF8 */ diff --git a/sys/dev/syscons/teken/teken_subr.h b/sys/dev/syscons/teken/teken_subr.h index f26dc890d7a0..d0fbd5eedf2a 100644 --- a/sys/dev/syscons/teken/teken_subr.h +++ b/sys/dev/syscons/teken/teken_subr.h @@ -198,7 +198,13 @@ static void teken_subr_backspace(teken_t *t) { -#ifdef TEKEN_CONS25 +#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; @@ -207,13 +213,7 @@ teken_subr_backspace(teken_t *t) } else { t->t_cursor.tp_col--; } -#else /* !TEKEN_CONS25 */ - if (t->t_cursor.tp_col == 0) - return; - - t->t_cursor.tp_col--; - t->t_stateflags &= ~TS_WRAPPED; -#endif /* TEKEN_CONS25 */ +#endif /* TEKEN_XTERM */ teken_funcs_cursor(t); } @@ -542,10 +542,7 @@ teken_subr_horizontal_position_absolute(teken_t *t, unsigned int col) static void teken_subr_horizontal_tab(teken_t *t) { -#ifdef TEKEN_CONS25 - - teken_subr_cursor_forward_tabulation(t, 1); -#else /* !TEKEN_CONS25 */ +#ifdef TEKEN_XTERM teken_rect_t tr; tr.tr_begin = t->t_cursor; @@ -556,7 +553,10 @@ teken_subr_horizontal_tab(teken_t *t) /* 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); -#endif /* TEKEN_CONS25 */ +#else /* !TEKEN_XTERM */ + + teken_subr_cursor_forward_tabulation(t, 1); +#endif /* TEKEN_XTERM */ } static void @@ -664,7 +664,10 @@ teken_subr_newline(teken_t *t) static void teken_subr_newpage(teken_t *t) { -#ifdef TEKEN_CONS25 +#ifdef TEKEN_XTERM + + teken_subr_newline(t); +#else /* !TEKEN_XTERM */ teken_rect_t tr; tr.tr_begin.tp_row = tr.tr_begin.tp_col = 0; @@ -673,10 +676,7 @@ teken_subr_newpage(teken_t *t) t->t_cursor.tp_row = t->t_cursor.tp_col = 0; teken_funcs_cursor(t); -#else /* !TEKEN_CONS25 */ - - teken_subr_newline(t); -#endif /* TEKEN_CONS25 */ +#endif /* TEKEN_XTERM */ } static void @@ -746,22 +746,7 @@ teken_subr_regular_character(teken_t *t, teken_char_t c) if (width <= 0) return; -#ifdef TEKEN_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 /* !TEKEN_CONS25 */ +#ifdef TEKEN_XTERM if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1 && (t->t_stateflags & (TS_WRAPPED|TS_AUTOWRAP)) == (TS_WRAPPED|TS_AUTOWRAP)) { @@ -806,7 +791,22 @@ teken_subr_regular_character(teken_t *t, teken_char_t c) t->t_stateflags &= ~TS_WRAPPED; } } -#endif /* TEKEN_CONS25 */ +#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); }