diff options
author | Roberto E. Vargas Caballero <roberto.vargas@igrid-td.com> | 2016-09-13 14:01:18 +0200 |
---|---|---|
committer | Roberto E. Vargas Caballero <roberto.vargas@igrid-td.com> | 2016-09-13 14:01:18 +0200 |
commit | f0e2d28732549690466df995981698173daf39c0 (patch) | |
tree | c4c1cee5bd43b3f4588b51c4a4809f16bc9b1b7a /st.c | |
parent | 078337d7457f7869a85f4ec364be92b79e93c502 (diff) | |
download | st-f0e2d28732549690466df995981698173daf39c0.tar.gz st-f0e2d28732549690466df995981698173daf39c0.zip |
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.
Diffstat (limited to 'st.c')
-rw-r--r-- | st.c | 79 |
1 files changed, 62 insertions, 17 deletions
@@ -137,6 +137,7 @@ enum term_mode { | |||
137 | MODE_MOUSEMANY = 1 << 18, | 137 | MODE_MOUSEMANY = 1 << 18, |
138 | MODE_BRCKTPASTE = 1 << 19, | 138 | MODE_BRCKTPASTE = 1 << 19, |
139 | MODE_PRINT = 1 << 20, | 139 | MODE_PRINT = 1 << 20, |
140 | MODE_UTF8 = 1 << 21, | ||
140 | MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\ | 141 | MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\ |
141 | |MODE_MOUSEMANY, | 142 | |MODE_MOUSEMANY, |
142 | }; | 143 | }; |
@@ -158,6 +159,7 @@ enum escape_state { | |||
158 | ESC_ALTCHARSET = 8, | 159 | ESC_ALTCHARSET = 8, |
159 | ESC_STR_END = 16, /* a final string was encountered */ | 160 | ESC_STR_END = 16, /* a final string was encountered */ |
160 | ESC_TEST = 32, /* Enter in test mode */ | 161 | ESC_TEST = 32, /* Enter in test mode */ |
162 | ESC_UTF8 = 64, | ||
161 | }; | 163 | }; |
162 | 164 | ||
163 | enum window_state { | 165 | enum window_state { |
@@ -412,6 +414,7 @@ static void tfulldirt(void); | |||
412 | static void techo(Rune); | 414 | static void techo(Rune); |
413 | static void tcontrolcode(uchar ); | 415 | static void tcontrolcode(uchar ); |
414 | static void tdectest(char ); | 416 | static void tdectest(char ); |
417 | static void tdefutf8(char); | ||
415 | static int32_t tdefcolor(int *, int *, int); | 418 | static int32_t tdefcolor(int *, int *, int); |
416 | static void tdeftran(char); | 419 | static void tdeftran(char); |
417 | static inline int match(uint, uint); | 420 | static inline int match(uint, uint); |
@@ -1478,17 +1481,29 @@ ttyread(void) | |||
1478 | if ((ret = read(cmdfd, buf+buflen, LEN(buf)-buflen)) < 0) | 1481 | if ((ret = read(cmdfd, buf+buflen, LEN(buf)-buflen)) < 0) |
1479 | die("Couldn't read from shell: %s\n", strerror(errno)); | 1482 | die("Couldn't read from shell: %s\n", strerror(errno)); |
1480 | 1483 | ||
1481 | /* process every complete utf8 char */ | ||
1482 | buflen += ret; | 1484 | buflen += ret; |
1483 | ptr = buf; | 1485 | ptr = buf; |
1484 | while ((charsize = utf8decode(ptr, &unicodep, buflen))) { | ||
1485 | tputc(unicodep); | ||
1486 | ptr += charsize; | ||
1487 | buflen -= charsize; | ||
1488 | } | ||
1489 | 1486 | ||
1487 | for (;;) { | ||
1488 | if (IS_SET(MODE_UTF8)) { | ||
1489 | /* process a complete utf8 char */ | ||
1490 | charsize = utf8decode(ptr, &unicodep, buflen); | ||
1491 | if (charsize == 0) | ||
1492 | break; | ||
1493 | tputc(unicodep); | ||
1494 | ptr += charsize; | ||
1495 | buflen -= charsize; | ||
1496 | |||
1497 | } else { | ||
1498 | if (buflen <= 0) | ||
1499 | break; | ||
1500 | tputc(*ptr++ & 0xFF); | ||
1501 | buflen--; | ||
1502 | } | ||
1503 | } | ||
1490 | /* keep any uncomplete utf8 char for the next call */ | 1504 | /* keep any uncomplete utf8 char for the next call */ |
1491 | memmove(buf, ptr, buflen); | 1505 | if (buflen > 0) |
1506 | memmove(buf, ptr, buflen); | ||
1492 | 1507 | ||
1493 | return ret; | 1508 | return ret; |
1494 | } | 1509 | } |
@@ -1554,15 +1569,26 @@ void | |||
1554 | ttysend(char *s, size_t n) | 1569 | ttysend(char *s, size_t n) |
1555 | { | 1570 | { |
1556 | int len; | 1571 | int len; |
1572 | char *t, *lim; | ||
1557 | Rune u; | 1573 | Rune u; |
1558 | 1574 | ||
1559 | ttywrite(s, n); | 1575 | ttywrite(s, n); |
1560 | if (IS_SET(MODE_ECHO)) | 1576 | if (!IS_SET(MODE_ECHO)) |
1561 | while ((len = utf8decode(s, &u, n)) > 0) { | 1577 | return; |
1562 | techo(u); | 1578 | |
1563 | n -= len; | 1579 | lim = &s[n]; |
1564 | s += len; | 1580 | for (t = s; t < lim; t += len) { |
1581 | if (IS_SET(MODE_UTF8)) { | ||
1582 | len = utf8decode(t, &u, n); | ||
1583 | } else { | ||
1584 | u = *t & 0xFF; | ||
1585 | len = 1; | ||
1565 | } | 1586 | } |
1587 | if (len <= 0) | ||
1588 | break; | ||
1589 | techo(u); | ||
1590 | n -= len; | ||
1591 | } | ||
1566 | } | 1592 | } |
1567 | 1593 | ||
1568 | void | 1594 | void |
@@ -1656,7 +1682,7 @@ treset(void) | |||
1656 | term.tabs[i] = 1; | 1682 | term.tabs[i] = 1; |
1657 | term.top = 0; | 1683 | term.top = 0; |
1658 | term.bot = term.row - 1; | 1684 | term.bot = term.row - 1; |
1659 | term.mode = MODE_WRAP; | 1685 | term.mode = MODE_WRAP|MODE_UTF8; |
1660 | memset(term.trantbl, CS_USA, sizeof(term.trantbl)); | 1686 | memset(term.trantbl, CS_USA, sizeof(term.trantbl)); |
1661 | term.charset = 0; | 1687 | term.charset = 0; |
1662 | 1688 | ||
@@ -2690,6 +2716,15 @@ techo(Rune u) | |||
2690 | } | 2716 | } |
2691 | 2717 | ||
2692 | void | 2718 | void |
2719 | tdefutf8(char ascii) | ||
2720 | { | ||
2721 | if (ascii == 'G') | ||
2722 | term.mode |= MODE_UTF8; | ||
2723 | else if (ascii == '@') | ||
2724 | term.mode &= ~MODE_UTF8; | ||
2725 | } | ||
2726 | |||
2727 | void | ||
2693 | tdeftran(char ascii) | 2728 | tdeftran(char ascii) |
2694 | { | 2729 | { |
2695 | static char cs[] = "0B"; | 2730 | static char cs[] = "0B"; |
@@ -2851,6 +2886,9 @@ eschandle(uchar ascii) | |||
2851 | case '#': | 2886 | case '#': |
2852 | term.esc |= ESC_TEST; | 2887 | term.esc |= ESC_TEST; |
2853 | return 0; | 2888 | return 0; |
2889 | case '%': | ||
2890 | term.esc |= ESC_UTF8; | ||
2891 | return 0; | ||
2854 | case 'P': /* DCS -- Device Control String */ | 2892 | case 'P': /* DCS -- Device Control String */ |
2855 | case '_': /* APC -- Application Program Command */ | 2893 | case '_': /* APC -- Application Program Command */ |
2856 | case '^': /* PM -- Privacy Message */ | 2894 | case '^': /* PM -- Privacy Message */ |
@@ -2930,10 +2968,15 @@ tputc(Rune u) | |||
2930 | Glyph *gp; | 2968 | Glyph *gp; |
2931 | 2969 | ||
2932 | control = ISCONTROL(u); | 2970 | control = ISCONTROL(u); |
2933 | len = utf8encode(u, c); | 2971 | if (!IS_SET(MODE_UTF8)) { |
2934 | if (!control && (width = wcwidth(u)) == -1) { | 2972 | c[0] = u; |
2935 | memcpy(c, "\357\277\275", 4); /* UTF_INVALID */ | 2973 | width = len = 1; |
2936 | width = 1; | 2974 | } else { |
2975 | len = utf8encode(u, c); | ||
2976 | if (!control && (width = wcwidth(u)) == -1) { | ||
2977 | memcpy(c, "\357\277\275", 4); /* UTF_INVALID */ | ||
2978 | width = 1; | ||
2979 | } | ||
2937 | } | 2980 | } |
2938 | 2981 | ||
2939 | if (IS_SET(MODE_PRINT)) | 2982 | if (IS_SET(MODE_PRINT)) |
@@ -2994,6 +3037,8 @@ tputc(Rune u) | |||
2994 | csihandle(); | 3037 | csihandle(); |
2995 | } | 3038 | } |
2996 | return; | 3039 | return; |
3040 | } else if (term.esc & ESC_UTF8) { | ||
3041 | tdefutf8(u); | ||
2997 | } else if (term.esc & ESC_ALTCHARSET) { | 3042 | } else if (term.esc & ESC_ALTCHARSET) { |
2998 | tdeftran(u); | 3043 | tdeftran(u); |
2999 | } else if (term.esc & ESC_TEST) { | 3044 | } else if (term.esc & ESC_TEST) { |