|
@@ -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 */
|
|
- /*
|
|
|
|
- * Different charsets are hard to handle. Applications
|
|
|
|
- * 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.
|
|
|
|
- */
|
|
|
|
|
|
+ term.charset = 1;
|
|
|
|
+ tselcs();
|
|
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) {
|
|
|
|
- case '0': /* Line drawing set */
|
|
|
|
- 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);
|
|
|
|
- }
|
|
|
|
|
|
+ tdeftran(ascii);
|
|
|
|
+ tselcs();
|
|
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);
|