Add support for enabling/disabling utf
There are some ocasions where we want to disable the enconding/decoding of utf8, mainly because it adds an important overhead. This is partial patch for ESC % G and ESC % @, where they modified the way that st reads and write from/to the serial line, but it does not modifies how it interacts with the X window part.master
parent
078337d745
commit
f0e2d28732
79
st.c
79
st.c
|
@ -137,6 +137,7 @@ enum term_mode {
|
||||||
MODE_MOUSEMANY = 1 << 18,
|
MODE_MOUSEMANY = 1 << 18,
|
||||||
MODE_BRCKTPASTE = 1 << 19,
|
MODE_BRCKTPASTE = 1 << 19,
|
||||||
MODE_PRINT = 1 << 20,
|
MODE_PRINT = 1 << 20,
|
||||||
|
MODE_UTF8 = 1 << 21,
|
||||||
MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\
|
MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\
|
||||||
|MODE_MOUSEMANY,
|
|MODE_MOUSEMANY,
|
||||||
};
|
};
|
||||||
|
@ -158,6 +159,7 @@ enum escape_state {
|
||||||
ESC_ALTCHARSET = 8,
|
ESC_ALTCHARSET = 8,
|
||||||
ESC_STR_END = 16, /* a final string was encountered */
|
ESC_STR_END = 16, /* a final string was encountered */
|
||||||
ESC_TEST = 32, /* Enter in test mode */
|
ESC_TEST = 32, /* Enter in test mode */
|
||||||
|
ESC_UTF8 = 64,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum window_state {
|
enum window_state {
|
||||||
|
@ -412,6 +414,7 @@ static void tfulldirt(void);
|
||||||
static void techo(Rune);
|
static void techo(Rune);
|
||||||
static void tcontrolcode(uchar );
|
static void tcontrolcode(uchar );
|
||||||
static void tdectest(char );
|
static void tdectest(char );
|
||||||
|
static void tdefutf8(char);
|
||||||
static int32_t tdefcolor(int *, int *, int);
|
static int32_t tdefcolor(int *, int *, int);
|
||||||
static void tdeftran(char);
|
static void tdeftran(char);
|
||||||
static inline int match(uint, uint);
|
static inline int match(uint, uint);
|
||||||
|
@ -1478,17 +1481,29 @@ ttyread(void)
|
||||||
if ((ret = read(cmdfd, buf+buflen, LEN(buf)-buflen)) < 0)
|
if ((ret = read(cmdfd, buf+buflen, LEN(buf)-buflen)) < 0)
|
||||||
die("Couldn't read from shell: %s\n", strerror(errno));
|
die("Couldn't read from shell: %s\n", strerror(errno));
|
||||||
|
|
||||||
/* process every complete utf8 char */
|
|
||||||
buflen += ret;
|
buflen += ret;
|
||||||
ptr = buf;
|
ptr = buf;
|
||||||
while ((charsize = utf8decode(ptr, &unicodep, buflen))) {
|
|
||||||
tputc(unicodep);
|
|
||||||
ptr += charsize;
|
|
||||||
buflen -= charsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (IS_SET(MODE_UTF8)) {
|
||||||
|
/* process a complete utf8 char */
|
||||||
|
charsize = utf8decode(ptr, &unicodep, buflen);
|
||||||
|
if (charsize == 0)
|
||||||
|
break;
|
||||||
|
tputc(unicodep);
|
||||||
|
ptr += charsize;
|
||||||
|
buflen -= charsize;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (buflen <= 0)
|
||||||
|
break;
|
||||||
|
tputc(*ptr++ & 0xFF);
|
||||||
|
buflen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* keep any uncomplete utf8 char for the next call */
|
/* keep any uncomplete utf8 char for the next call */
|
||||||
memmove(buf, ptr, buflen);
|
if (buflen > 0)
|
||||||
|
memmove(buf, ptr, buflen);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1554,15 +1569,26 @@ void
|
||||||
ttysend(char *s, size_t n)
|
ttysend(char *s, size_t n)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
char *t, *lim;
|
||||||
Rune u;
|
Rune u;
|
||||||
|
|
||||||
ttywrite(s, n);
|
ttywrite(s, n);
|
||||||
if (IS_SET(MODE_ECHO))
|
if (!IS_SET(MODE_ECHO))
|
||||||
while ((len = utf8decode(s, &u, n)) > 0) {
|
return;
|
||||||
techo(u);
|
|
||||||
n -= len;
|
lim = &s[n];
|
||||||
s += len;
|
for (t = s; t < lim; t += len) {
|
||||||
|
if (IS_SET(MODE_UTF8)) {
|
||||||
|
len = utf8decode(t, &u, n);
|
||||||
|
} else {
|
||||||
|
u = *t & 0xFF;
|
||||||
|
len = 1;
|
||||||
}
|
}
|
||||||
|
if (len <= 0)
|
||||||
|
break;
|
||||||
|
techo(u);
|
||||||
|
n -= len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1656,7 +1682,7 @@ treset(void)
|
||||||
term.tabs[i] = 1;
|
term.tabs[i] = 1;
|
||||||
term.top = 0;
|
term.top = 0;
|
||||||
term.bot = term.row - 1;
|
term.bot = term.row - 1;
|
||||||
term.mode = MODE_WRAP;
|
term.mode = MODE_WRAP|MODE_UTF8;
|
||||||
memset(term.trantbl, CS_USA, sizeof(term.trantbl));
|
memset(term.trantbl, CS_USA, sizeof(term.trantbl));
|
||||||
term.charset = 0;
|
term.charset = 0;
|
||||||
|
|
||||||
|
@ -2689,6 +2715,15 @@ techo(Rune u)
|
||||||
tputc(u);
|
tputc(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tdefutf8(char ascii)
|
||||||
|
{
|
||||||
|
if (ascii == 'G')
|
||||||
|
term.mode |= MODE_UTF8;
|
||||||
|
else if (ascii == '@')
|
||||||
|
term.mode &= ~MODE_UTF8;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tdeftran(char ascii)
|
tdeftran(char ascii)
|
||||||
{
|
{
|
||||||
|
@ -2851,6 +2886,9 @@ eschandle(uchar ascii)
|
||||||
case '#':
|
case '#':
|
||||||
term.esc |= ESC_TEST;
|
term.esc |= ESC_TEST;
|
||||||
return 0;
|
return 0;
|
||||||
|
case '%':
|
||||||
|
term.esc |= ESC_UTF8;
|
||||||
|
return 0;
|
||||||
case 'P': /* DCS -- Device Control String */
|
case 'P': /* DCS -- Device Control String */
|
||||||
case '_': /* APC -- Application Program Command */
|
case '_': /* APC -- Application Program Command */
|
||||||
case '^': /* PM -- Privacy Message */
|
case '^': /* PM -- Privacy Message */
|
||||||
|
@ -2930,10 +2968,15 @@ tputc(Rune u)
|
||||||
Glyph *gp;
|
Glyph *gp;
|
||||||
|
|
||||||
control = ISCONTROL(u);
|
control = ISCONTROL(u);
|
||||||
len = utf8encode(u, c);
|
if (!IS_SET(MODE_UTF8)) {
|
||||||
if (!control && (width = wcwidth(u)) == -1) {
|
c[0] = u;
|
||||||
memcpy(c, "\357\277\275", 4); /* UTF_INVALID */
|
width = len = 1;
|
||||||
width = 1;
|
} else {
|
||||||
|
len = utf8encode(u, c);
|
||||||
|
if (!control && (width = wcwidth(u)) == -1) {
|
||||||
|
memcpy(c, "\357\277\275", 4); /* UTF_INVALID */
|
||||||
|
width = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_SET(MODE_PRINT))
|
if (IS_SET(MODE_PRINT))
|
||||||
|
@ -2994,6 +3037,8 @@ tputc(Rune u)
|
||||||
csihandle();
|
csihandle();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
} else if (term.esc & ESC_UTF8) {
|
||||||
|
tdefutf8(u);
|
||||||
} else if (term.esc & ESC_ALTCHARSET) {
|
} else if (term.esc & ESC_ALTCHARSET) {
|
||||||
tdeftran(u);
|
tdeftran(u);
|
||||||
} else if (term.esc & ESC_TEST) {
|
} else if (term.esc & ESC_TEST) {
|
||||||
|
|
Reference in New Issue