aboutsummaryrefslogtreecommitdiff
path: root/st.c
diff options
context:
space:
mode:
authorRoberto E. Vargas Caballero <roberto.vargas@igrid-td.com>2016-09-13 14:01:18 +0200
committerRoberto E. Vargas Caballero <roberto.vargas@igrid-td.com>2016-09-13 14:01:18 +0200
commitf0e2d28732549690466df995981698173daf39c0 (patch)
treec4c1cee5bd43b3f4588b51c4a4809f16bc9b1b7a /st.c
parent078337d7457f7869a85f4ec364be92b79e93c502 (diff)
downloadst-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.c79
1 files changed, 62 insertions, 17 deletions
diff --git a/st.c b/st.c
index 2594c65..ebbd7ca 100644
--- a/st.c
+++ b/st.c
@@ -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
163enum window_state { 165enum window_state {
@@ -412,6 +414,7 @@ static void tfulldirt(void);
412static void techo(Rune); 414static void techo(Rune);
413static void tcontrolcode(uchar ); 415static void tcontrolcode(uchar );
414static void tdectest(char ); 416static void tdectest(char );
417static void tdefutf8(char);
415static int32_t tdefcolor(int *, int *, int); 418static int32_t tdefcolor(int *, int *, int);
416static void tdeftran(char); 419static void tdeftran(char);
417static inline int match(uint, uint); 420static 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
1554ttysend(char *s, size_t n) 1569ttysend(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
1568void 1594void
@@ -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
2692void 2718void
2719tdefutf8(char ascii)
2720{
2721 if (ascii == 'G')
2722 term.mode |= MODE_UTF8;
2723 else if (ascii == '@')
2724 term.mode &= ~MODE_UTF8;
2725}
2726
2727void
2693tdeftran(char ascii) 2728tdeftran(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) {