mirror of
https://github.com/alrayyes/st.git
synced 2024-11-23 03:36:21 +00:00
Add support for multiple charset definitions
vt100 has support for two defined charset, G0 and G1. Each charset can be defined, but in each moment is selected only one of both charset. This is usually used selecting a national charset in G0 and graphic charset in G1, so you can switch between graphic charset and text charset without losing the national charset already defined. st hasn't support for national charsets, because it is an utf8 based terminal emulator, but it has support for graphic charset because it is heavily used, but it only supports G0, without understanding G1 selection sequences, which causes some programs in some moments can print some garbage in the screen. This patch adds a fake support for multiple charset definitions, where we only support graphic charset and us-ascii charset, but we allow more of one charset definition. This patch allow define G0 until G3 charsets, but only accepts select G0 or G1, and it accepts some national charset definitions but all of them are mapped to us-ascii.
This commit is contained in:
parent
c5c2365ab7
commit
7a4eefe87c
1 changed files with 55 additions and 27 deletions
82
st.c
82
st.c
|
@ -137,6 +137,16 @@ enum term_mode {
|
||||||
|MODE_MOUSEMANY,
|
|MODE_MOUSEMANY,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum charset {
|
||||||
|
CS_GRAPHIC0,
|
||||||
|
CS_GRAPHIC1,
|
||||||
|
CS_UK,
|
||||||
|
CS_USA,
|
||||||
|
CS_MULTI,
|
||||||
|
CS_GER,
|
||||||
|
CS_FIN
|
||||||
|
};
|
||||||
|
|
||||||
enum escape_state {
|
enum escape_state {
|
||||||
ESC_START = 1,
|
ESC_START = 1,
|
||||||
ESC_CSI = 2,
|
ESC_CSI = 2,
|
||||||
|
@ -216,6 +226,9 @@ typedef struct {
|
||||||
int bot; /* bottom scroll limit */
|
int bot; /* bottom scroll limit */
|
||||||
int mode; /* terminal mode flags */
|
int mode; /* terminal mode flags */
|
||||||
int esc; /* escape state flags */
|
int esc; /* escape state flags */
|
||||||
|
char trantbl[4]; /* charset table translation */
|
||||||
|
int charset; /* current charset */
|
||||||
|
int icharset; /* selected charset for sequence */
|
||||||
bool numlock; /* lock numbers in keyboard */
|
bool numlock; /* lock numbers in keyboard */
|
||||||
bool *tabs;
|
bool *tabs;
|
||||||
} Term;
|
} Term;
|
||||||
|
@ -367,6 +380,8 @@ static void tsetmode(bool, bool, int *, int);
|
||||||
static void tfulldirt(void);
|
static void tfulldirt(void);
|
||||||
static void techo(char *, int);
|
static void techo(char *, int);
|
||||||
static long tdefcolor(int *, int *, int);
|
static long tdefcolor(int *, int *, int);
|
||||||
|
static void tselcs(void);
|
||||||
|
static void tdeftran(char);
|
||||||
static inline bool match(uint, uint);
|
static inline bool match(uint, uint);
|
||||||
static void ttynew(void);
|
static void ttynew(void);
|
||||||
static void ttyread(void);
|
static void ttyread(void);
|
||||||
|
@ -1369,6 +1384,8 @@ treset(void) {
|
||||||
term.top = 0;
|
term.top = 0;
|
||||||
term.bot = term.row - 1;
|
term.bot = term.row - 1;
|
||||||
term.mode = MODE_WRAP;
|
term.mode = MODE_WRAP;
|
||||||
|
memset(term.trantbl, sizeof(term.trantbl), CS_USA);
|
||||||
|
term.charset = 0;
|
||||||
|
|
||||||
tclearregion(0, 0, term.col-1, term.row-1);
|
tclearregion(0, 0, term.col-1, term.row-1);
|
||||||
tmoveto(0, 0);
|
tmoveto(0, 0);
|
||||||
|
@ -2259,6 +2276,33 @@ techo(char *buf, int len) {
|
||||||
tputc(buf, len);
|
tputc(buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tdeftran(char ascii) {
|
||||||
|
char c, (*bp)[2];
|
||||||
|
static char tbl[][2] = {
|
||||||
|
{'0', CS_GRAPHIC0}, {'1', CS_GRAPHIC1}, {'A', CS_UK},
|
||||||
|
{'B', CS_USA}, {'<', CS_MULTI}, {'K', CS_GER},
|
||||||
|
{'5', CS_FIN}, {'C', CS_FIN},
|
||||||
|
{0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (bp = &tbl[0]; (c = (*bp)[0]) && c != ascii; ++bp)
|
||||||
|
/* nothing */;
|
||||||
|
|
||||||
|
if (c == 0)
|
||||||
|
fprintf(stderr, "esc unhandled charset: ESC ( %c\n", ascii);
|
||||||
|
else
|
||||||
|
term.trantbl[term.icharset] = (*bp)[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tselcs(void) {
|
||||||
|
if (term.trantbl[term.charset] == CS_GRAPHIC0)
|
||||||
|
term.c.attr.mode |= ATTR_GFX;
|
||||||
|
else
|
||||||
|
term.c.attr.mode &= ~ATTR_GFX;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tputc(char *c, int len) {
|
tputc(char *c, int len) {
|
||||||
uchar ascii = *c;
|
uchar ascii = *c;
|
||||||
|
@ -2351,13 +2395,12 @@ tputc(char *c, int len) {
|
||||||
term.esc = ESC_START;
|
term.esc = ESC_START;
|
||||||
return;
|
return;
|
||||||
case '\016': /* SO */
|
case '\016': /* SO */
|
||||||
|
term.charset = 0;
|
||||||
|
tselcs();
|
||||||
|
return;
|
||||||
case '\017': /* SI */
|
case '\017': /* SI */
|
||||||
/*
|
term.charset = 1;
|
||||||
* Different charsets are hard to handle. Applications
|
tselcs();
|
||||||
* should use the right alt charset escapes for the
|
|
||||||
* only reason they still exist: line drawing. The
|
|
||||||
* rest is incompatible history st should not support.
|
|
||||||
*/
|
|
||||||
return;
|
return;
|
||||||
case '\032': /* SUB */
|
case '\032': /* SUB */
|
||||||
case '\030': /* CAN */
|
case '\030': /* CAN */
|
||||||
|
@ -2385,22 +2428,8 @@ tputc(char *c, int len) {
|
||||||
if(ascii == '\\')
|
if(ascii == '\\')
|
||||||
strhandle();
|
strhandle();
|
||||||
} else if(term.esc & ESC_ALTCHARSET) {
|
} else if(term.esc & ESC_ALTCHARSET) {
|
||||||
switch(ascii) {
|
tdeftran(ascii);
|
||||||
case '0': /* Line drawing set */
|
tselcs();
|
||||||
term.c.attr.mode |= ATTR_GFX;
|
|
||||||
break;
|
|
||||||
case 'B': /* USASCII */
|
|
||||||
term.c.attr.mode &= ~ATTR_GFX;
|
|
||||||
break;
|
|
||||||
case 'A': /* UK (IGNORED) */
|
|
||||||
case '<': /* multinational charset (IGNORED) */
|
|
||||||
case '5': /* Finnish (IGNORED) */
|
|
||||||
case 'C': /* Finnish (IGNORED) */
|
|
||||||
case 'K': /* German (IGNORED) */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "esc unhandled charset: ESC ( %c\n", ascii);
|
|
||||||
}
|
|
||||||
term.esc = 0;
|
term.esc = 0;
|
||||||
} else if(term.esc & ESC_TEST) {
|
} else if(term.esc & ESC_TEST) {
|
||||||
if(ascii == '8') { /* DEC screen alignment test. */
|
if(ascii == '8') { /* DEC screen alignment test. */
|
||||||
|
@ -2431,13 +2460,12 @@ tputc(char *c, int len) {
|
||||||
term.esc |= ESC_STR;
|
term.esc |= ESC_STR;
|
||||||
break;
|
break;
|
||||||
case '(': /* set primary charset G0 */
|
case '(': /* set primary charset G0 */
|
||||||
|
case ')': /* set secondary charset G1 */
|
||||||
|
case '*': /* set tertiary charset G2 */
|
||||||
|
case '+': /* set quaternary charset G3 */
|
||||||
|
term.icharset = ascii - '(';
|
||||||
term.esc |= ESC_ALTCHARSET;
|
term.esc |= ESC_ALTCHARSET;
|
||||||
break;
|
break;
|
||||||
case ')': /* set secondary charset G1 (IGNORED) */
|
|
||||||
case '*': /* set tertiary charset G2 (IGNORED) */
|
|
||||||
case '+': /* set quaternary charset G3 (IGNORED) */
|
|
||||||
term.esc = 0;
|
|
||||||
break;
|
|
||||||
case 'D': /* IND -- Linefeed */
|
case 'D': /* IND -- Linefeed */
|
||||||
if(term.c.y == term.bot) {
|
if(term.c.y == term.bot) {
|
||||||
tscrollup(term.top, 1);
|
tscrollup(term.top, 1);
|
||||||
|
|
Loading…
Reference in a new issue