Properly implement the VT100 SCS sequences in xterm-mode.
Even though VT100-like devices can display non-ASCII characters, they do not use an 8-bit character set. Special escape sequences allow the VT100 to switch character maps. The special graphics character set stores the box drawing characters, starting at 0x60, ending at 0x7e. This means we now pass the character map tests in vttest, even the save/restore cursor test, combined with character maps. dialog(1) also works a lot better now. This commit also includes some other minor fixes: - Default to 24 lines in teken_demo when using xterm emulation. - Make white foreground and background work in teken_demo.
This commit is contained in:
parent
b1a4c8e522
commit
4873b07e2a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=187469
@ -71,6 +71,16 @@ DSR Device Status Report ^[ [ ? n r
|
||||
ECH Erase character ^[ [ X n
|
||||
ED Erase display ^[ [ J r
|
||||
EL Erase line ^[ [ K r
|
||||
G0SCS0 G0 SCS Special Graphics ^[ ( 0
|
||||
G0SCS1 G0 SCS US ASCII ^[ ( 1
|
||||
G0SCS2 G0 SCS Special Graphics ^[ ( 2
|
||||
G0SCSA G0 SCS UK National ^[ ( A
|
||||
G0SCSB G0 SCS US ASCII ^[ ( B
|
||||
G1SCS0 G1 SCS Special Graphics ^[ ) 0
|
||||
G1SCS1 G1 SCS US ASCII ^[ ) 1
|
||||
G1SCS2 G1 SCS Special Graphics ^[ ) 2
|
||||
G1SCSA G1 SCS UK National ^[ ) A
|
||||
G1SCSB G1 SCS US ASCII ^[ ) B
|
||||
HPA Horizontal Position Absolute ^[ [ G n
|
||||
HPA Horizontal Position Absolute ^[ [ ` n
|
||||
HTS Horizontal Tab Set ^[ H
|
||||
@ -81,16 +91,6 @@ NEL Next line ^[ E
|
||||
RI Reverse index ^[ M
|
||||
RIS Reset to Initial State ^[ c
|
||||
RM Reset Mode ^[ [ l r
|
||||
SCS SCS ^[ ( 0
|
||||
SCS SCS ^[ ( 1
|
||||
SCS SCS ^[ ( 2
|
||||
SCS SCS ^[ ( A
|
||||
SCS SCS ^[ ( B
|
||||
SCS SCS ^[ ) 0
|
||||
SCS SCS ^[ ) 1
|
||||
SCS SCS ^[ ) 2
|
||||
SCS SCS ^[ ) A
|
||||
SCS SCS ^[ ) B
|
||||
SD Pan Up ^[ [ T n
|
||||
SGR Set Graphic Rendition ^[ [ m v
|
||||
SM Set Mode ^[ [ h r
|
||||
|
@ -49,21 +49,27 @@ static FILE *df;
|
||||
#endif /* __FreeBSD__ && _KERNEL */
|
||||
|
||||
#include "teken.h"
|
||||
|
||||
#ifdef TEKEN_UTF8
|
||||
#include "teken_wcwidth.h"
|
||||
#else /* !TEKEN_UTF8 */
|
||||
static inline int
|
||||
teken_wcwidth(teken_char_t c __unused)
|
||||
{
|
||||
|
||||
#ifdef TEKEN_XTERM
|
||||
return (c <= 0x1B) ? -1 : 1;
|
||||
#define teken_wcwidth(c) ((c <= 0x1B) ? -1 : 1)
|
||||
#else /* !TEKEN_XTERM */
|
||||
return (1);
|
||||
#define teken_wcwidth(c) (1)
|
||||
#endif /* TEKEN_XTERM */
|
||||
}
|
||||
#endif /* TEKEN_UTF8 */
|
||||
|
||||
#if defined(TEKEN_XTERM) && defined(TEKEN_UTF8)
|
||||
#include "teken_scs.h"
|
||||
#else /* !(TEKEN_XTERM && TEKEN_UTF8) */
|
||||
#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 && TEKEN_UTF8 */
|
||||
|
||||
/* Private flags for teken_format_t. */
|
||||
#define TF_REVERSE 0x08
|
||||
|
||||
@ -229,6 +235,14 @@ teken_input_char(teken_t *t, teken_char_t c)
|
||||
case '\x0C':
|
||||
teken_subr_newpage(t);
|
||||
break;
|
||||
#if defined(TEKEN_XTERM) && defined(TEKEN_UTF8)
|
||||
case '\x0E':
|
||||
teken_scs_switch(t, 1);
|
||||
break;
|
||||
case '\x0F':
|
||||
teken_scs_switch(t, 0);
|
||||
break;
|
||||
#endif /* TEKEN_XTERM && TEKEN_UTF8 */
|
||||
case '\r':
|
||||
teken_subr_carriage_return(t);
|
||||
break;
|
||||
|
@ -117,6 +117,10 @@ typedef struct {
|
||||
tf_respond_t *tf_respond;
|
||||
} teken_funcs_t;
|
||||
|
||||
#if defined(TEKEN_XTERM) && defined(TEKEN_UTF8)
|
||||
typedef teken_char_t teken_scs_t(teken_char_t);
|
||||
#endif /* TEKEN_XTERM && TEKEN_UTF8 */
|
||||
|
||||
/*
|
||||
* Terminal state.
|
||||
*/
|
||||
@ -146,12 +150,18 @@ struct __teken {
|
||||
teken_span_t t_originreg;
|
||||
|
||||
#define T_NUMCOL 160
|
||||
unsigned int t_tabstops[T_NUMCOL / (sizeof(unsigned int) * 8)];
|
||||
unsigned int t_tabstops[T_NUMCOL / (sizeof(unsigned int) * 8)];
|
||||
|
||||
#ifdef TEKEN_UTF8
|
||||
unsigned int t_utf8_left;
|
||||
teken_char_t t_utf8_partial;
|
||||
unsigned int t_utf8_left;
|
||||
teken_char_t t_utf8_partial;
|
||||
#endif /* TEKEN_UTF8 */
|
||||
|
||||
#if defined(TEKEN_XTERM) && defined(TEKEN_UTF8)
|
||||
unsigned int t_curscs;
|
||||
teken_scs_t *t_saved_curscs;
|
||||
teken_scs_t *t_scs[2];
|
||||
#endif /* TEKEN_XTERM && TEKEN_UTF8 */
|
||||
};
|
||||
|
||||
/* Initialize teken structure. */
|
||||
|
@ -70,7 +70,11 @@ 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;
|
||||
@ -104,7 +108,7 @@ printchar(const teken_pos_t *p)
|
||||
if (px->a.ta_format & TF_BLINK)
|
||||
attr |= A_BLINK;
|
||||
|
||||
bkgdset(attr | COLOR_PAIR(px->a.ta_fgcolor + 8 * px->a.ta_bgcolor + 1));
|
||||
bkgdset(attr | COLOR_PAIR(px->a.ta_fgcolor + 8 * px->a.ta_bgcolor));
|
||||
mvaddch(p->tp_row, p->tp_col, px->c);
|
||||
|
||||
move(y, x);
|
||||
@ -301,7 +305,7 @@ main(int argc __unused, char *argv[] __unused)
|
||||
start_color();
|
||||
for (i = 0; i < 8; i++)
|
||||
for (j = 0; j < 8; j++)
|
||||
init_pair(i + 8 * j + 1, ccolors[i], ccolors[j]);
|
||||
init_pair(i + 8 * j, ccolors[i], ccolors[j]);
|
||||
|
||||
redraw_border();
|
||||
|
||||
|
98
sys/dev/syscons/teken/teken_scs.h
Normal file
98
sys/dev/syscons/teken/teken_scs.h
Normal file
@ -0,0 +1,98 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 Ed Schouten <ed@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
static void
|
||||
teken_scs_set(teken_t *t, unsigned int g, teken_scs_t *ts)
|
||||
{
|
||||
|
||||
t->t_scs[g] = ts;
|
||||
}
|
||||
|
||||
static void
|
||||
teken_scs_switch(teken_t *t, unsigned int g)
|
||||
{
|
||||
|
||||
t->t_curscs = g;
|
||||
}
|
||||
|
||||
static void
|
||||
teken_scs_restore(teken_t *t)
|
||||
{
|
||||
|
||||
t->t_scs[t->t_curscs] = t->t_saved_curscs;
|
||||
}
|
||||
|
||||
static void
|
||||
teken_scs_save(teken_t *t)
|
||||
{
|
||||
|
||||
t->t_saved_curscs = t->t_scs[t->t_curscs];
|
||||
}
|
||||
|
||||
static teken_char_t
|
||||
teken_scs_process(teken_t *t, teken_char_t c)
|
||||
{
|
||||
|
||||
return (t->t_scs[t->t_curscs](c));
|
||||
}
|
||||
|
||||
/* Unicode points for VT100 box drawing. */
|
||||
static const teken_char_t teken_boxdrawing[31] = {
|
||||
0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
|
||||
0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
|
||||
0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
|
||||
0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7
|
||||
};
|
||||
|
||||
static teken_char_t
|
||||
teken_scs_special_graphics(teken_char_t c)
|
||||
{
|
||||
|
||||
/* Box drawing. */
|
||||
if (c >= '`' && c <= '~')
|
||||
return (teken_boxdrawing[c - '`']);
|
||||
return (c);
|
||||
}
|
||||
|
||||
static teken_char_t
|
||||
teken_scs_uk_national(teken_char_t c)
|
||||
{
|
||||
|
||||
/* Pound sign. */
|
||||
if (c == '#')
|
||||
return (0xa3);
|
||||
return (c);
|
||||
}
|
||||
|
||||
static teken_char_t
|
||||
teken_scs_us_ascii(teken_char_t c)
|
||||
{
|
||||
|
||||
/* No processing. */
|
||||
return (c);
|
||||
}
|
@ -30,6 +30,7 @@ static void teken_subr_cursor_up(teken_t *, unsigned int);
|
||||
static void teken_subr_erase_line(teken_t *, unsigned int);
|
||||
static void teken_subr_regular_character(teken_t *, teken_char_t);
|
||||
static void teken_subr_reset_to_initial_state(teken_t *);
|
||||
static void teken_subr_save_cursor(teken_t *);
|
||||
|
||||
static inline int
|
||||
teken_tab_isset(teken_t *t, unsigned int col)
|
||||
@ -527,6 +528,48 @@ teken_subr_erase_line(teken_t *t, unsigned int mode)
|
||||
teken_funcs_fill(t, &r, BLANK, &t->t_curattr);
|
||||
}
|
||||
|
||||
static void
|
||||
teken_subr_g0_scs_special_graphics(teken_t *t __unused)
|
||||
{
|
||||
|
||||
teken_scs_set(t, 0, teken_scs_special_graphics);
|
||||
}
|
||||
|
||||
static void
|
||||
teken_subr_g0_scs_uk_national(teken_t *t __unused)
|
||||
{
|
||||
|
||||
teken_scs_set(t, 0, teken_scs_uk_national);
|
||||
}
|
||||
|
||||
static void
|
||||
teken_subr_g0_scs_us_ascii(teken_t *t __unused)
|
||||
{
|
||||
|
||||
teken_scs_set(t, 0, teken_scs_us_ascii);
|
||||
}
|
||||
|
||||
static void
|
||||
teken_subr_g1_scs_special_graphics(teken_t *t __unused)
|
||||
{
|
||||
|
||||
teken_scs_set(t, 1, teken_scs_special_graphics);
|
||||
}
|
||||
|
||||
static void
|
||||
teken_subr_g1_scs_uk_national(teken_t *t __unused)
|
||||
{
|
||||
|
||||
teken_scs_set(t, 1, teken_scs_uk_national);
|
||||
}
|
||||
|
||||
static void
|
||||
teken_subr_g1_scs_us_ascii(teken_t *t __unused)
|
||||
{
|
||||
|
||||
teken_scs_set(t, 1, teken_scs_us_ascii);
|
||||
}
|
||||
|
||||
static void
|
||||
teken_subr_horizontal_position_absolute(teken_t *t, unsigned int col)
|
||||
{
|
||||
@ -740,6 +783,8 @@ static void
|
||||
teken_subr_regular_character(teken_t *t, teken_char_t c)
|
||||
{
|
||||
int width;
|
||||
|
||||
c = teken_scs_process(t, c);
|
||||
|
||||
/* XXX: Don't process zero-width characters yet. */
|
||||
width = teken_wcwidth(c);
|
||||
@ -877,11 +922,15 @@ static void
|
||||
teken_subr_do_reset(teken_t *t)
|
||||
{
|
||||
|
||||
t->t_curattr = t->t_saved_curattr = t->t_defattr;
|
||||
t->t_curattr = t->t_defattr;
|
||||
t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
|
||||
t->t_saved_cursor = t->t_cursor;
|
||||
t->t_stateflags = TS_AUTOWRAP;
|
||||
|
||||
teken_scs_set(t, 0, teken_scs_us_ascii);
|
||||
teken_scs_set(t, 1, teken_scs_us_ascii);
|
||||
teken_scs_switch(t, 0);
|
||||
|
||||
teken_subr_save_cursor(t);
|
||||
teken_tab_default(t);
|
||||
}
|
||||
|
||||
@ -902,6 +951,7 @@ teken_subr_restore_cursor(teken_t *t)
|
||||
t->t_cursor = t->t_saved_cursor;
|
||||
t->t_curattr = t->t_saved_curattr;
|
||||
t->t_stateflags &= ~TS_WRAPPED;
|
||||
teken_scs_restore(t);
|
||||
teken_funcs_cursor(t);
|
||||
}
|
||||
|
||||
@ -924,13 +974,7 @@ teken_subr_save_cursor(teken_t *t)
|
||||
|
||||
t->t_saved_cursor = t->t_cursor;
|
||||
t->t_saved_curattr = t->t_curattr;
|
||||
}
|
||||
|
||||
static void
|
||||
teken_subr_scs(teken_t *t __unused)
|
||||
{
|
||||
|
||||
teken_printf("scs???\n");
|
||||
teken_scs_save(t);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user