# st

Unnamed repository; edit this file 'description' to name the repository.

| Log | Files | Refs | README | LICENSE

    commit f0e2d28732549690466df995981698173daf39c0
    parent 078337d7457f7869a85f4ec364be92b79e93c502
    Author: Roberto E. Vargas Caballero <roberto.vargas@igrid-td.com>
    Date:   Tue, 13 Sep 2016 14:01:18 +0200

    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:
    Mst.c | 79++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------

    1 file changed, 62 insertions(+), 17 deletions(-)
    diff --git a/st.c b/st.c
    @@ -137,6 +137,7 @@ enum term_mode {
     	MODE_MOUSEMANY   = 1 << 18,
     	MODE_BRCKTPASTE  = 1 << 19,
     	MODE_PRINT       = 1 << 20,
    +	MODE_UTF8        = 1 << 21,
     	MODE_MOUSE       = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\
     	                  |MODE_MOUSEMANY,
     };
    @@ -158,6 +159,7 @@ enum escape_state {
     	ESC_ALTCHARSET = 8,
     	ESC_STR_END    = 16, /* a final string was encountered */
     	ESC_TEST       = 32, /* Enter in test mode */
    +	ESC_UTF8       = 64,
     };

     enum window_state {
    @@ -412,6 +414,7 @@ static void tfulldirt(void);
     static void techo(Rune);
     static void tcontrolcode(uchar );
     static void tdectest(char );
    +static void tdefutf8(char);
     static int32_t tdefcolor(int *, int *, int);
     static void tdeftran(char);
     static inline int match(uint, uint);
    @@ -1478,17 +1481,29 @@ ttyread(void)
     	if ((ret = read(cmdfd, buf+buflen, LEN(buf)-buflen)) < 0)
     		die("Couldn't read from shell: %s\n", strerror(errno));

    -	/* process every complete utf8 char */
     	buflen += ret;
     	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 */
    -	memmove(buf, ptr, buflen);
    +	if (buflen > 0)
    +		memmove(buf, ptr, buflen);

     	return ret;
     }
    @@ -1554,15 +1569,26 @@ void
     ttysend(char *s, size_t n)
     {
     	int len;
    +	char *t, *lim;
     	Rune u;

     	ttywrite(s, n);
    -	if (IS_SET(MODE_ECHO))
    -		while ((len = utf8decode(s, &u, n)) > 0) {
    -			techo(u);
    -			n -= len;
    -			s += len;
    +	if (!IS_SET(MODE_ECHO))
    +		return;
    +
    +	lim = &s[n];
    +	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
    @@ -1656,7 +1682,7 @@ treset(void)
     		term.tabs[i] = 1;
     	term.top = 0;
     	term.bot = term.row - 1;
    -	term.mode = MODE_WRAP;
    +	term.mode = MODE_WRAP|MODE_UTF8;
     	memset(term.trantbl, CS_USA, sizeof(term.trantbl));
     	term.charset = 0;

    @@ -2690,6 +2716,15 @@ techo(Rune u)
     }

     void
    +tdefutf8(char ascii)
    +{
    +	if (ascii == 'G')
    +		term.mode |= MODE_UTF8;
    +	else if (ascii == '@')
    +		term.mode &= ~MODE_UTF8;
    +}
    +
    +void
     tdeftran(char ascii)
     {
     	static char cs[] = "0B";
    @@ -2851,6 +2886,9 @@ eschandle(uchar ascii)
     	case '#':
     		term.esc |= ESC_TEST;
     		return 0;
    +	case '%':
    +		term.esc |= ESC_UTF8;
    +		return 0;
     	case 'P': /* DCS -- Device Control String */
     	case '_': /* APC -- Application Program Command */
     	case '^': /* PM -- Privacy Message */
    @@ -2930,10 +2968,15 @@ tputc(Rune u)
     	Glyph *gp;

     	control = ISCONTROL(u);
    -	len = utf8encode(u, c);
    -	if (!control && (width = wcwidth(u)) == -1) {
    -		memcpy(c, "\357\277\275", 4); /* UTF_INVALID */
    -		width = 1;
    +	if (!IS_SET(MODE_UTF8)) {
    +		c[0] = u;
    +		width = len = 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))
    @@ -2994,6 +3037,8 @@ tputc(Rune u)
     				csihandle();
     			}
     			return;
    +		} else if (term.esc & ESC_UTF8) {
    +			tdefutf8(u);
     		} else if (term.esc & ESC_ALTCHARSET) {
     			tdeftran(u);
     		} else if (term.esc & ESC_TEST) {