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.
This commit is contained in:
		
							parent
							
								
									078337d745
								
							
						
					
					
						commit
						f0e2d28732
					
				
							
								
								
									
										59
									
								
								st.c
								
								
								
								
							
							
						
						
									
										59
									
								
								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,16 +1481,28 @@ 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))) { | 
 | ||||||
|  | 	for (;;) { | ||||||
|  | 		if (IS_SET(MODE_UTF8)) { | ||||||
|  | 			/* process a complete utf8 char */ | ||||||
|  | 			charsize = utf8decode(ptr, &unicodep, buflen); | ||||||
|  | 			if (charsize == 0) | ||||||
|  | 				break; | ||||||
| 			tputc(unicodep); | 			tputc(unicodep); | ||||||
| 			ptr += charsize; | 			ptr += charsize; | ||||||
| 			buflen -= 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 */ | ||||||
|  | 	if (buflen > 0) | ||||||
| 		memmove(buf, ptr, buflen); | 		memmove(buf, ptr, buflen); | ||||||
| 
 | 
 | ||||||
| 	return ret; | 	return ret; | ||||||
|  | @ -1554,14 +1569,25 @@ 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; | ||||||
|  | 
 | ||||||
|  | 	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); | 		techo(u); | ||||||
| 		n -= len; | 		n -= len; | ||||||
| 			s += len; |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -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,11 +2968,16 @@ tputc(Rune u) | ||||||
| 	Glyph *gp; | 	Glyph *gp; | ||||||
| 
 | 
 | ||||||
| 	control = ISCONTROL(u); | 	control = ISCONTROL(u); | ||||||
|  | 	if (!IS_SET(MODE_UTF8)) { | ||||||
|  | 		c[0] = u; | ||||||
|  | 		width = len = 1; | ||||||
|  | 	} else { | ||||||
| 		len = utf8encode(u, c); | 		len = utf8encode(u, c); | ||||||
| 		if (!control && (width = wcwidth(u)) == -1) { | 		if (!control && (width = wcwidth(u)) == -1) { | ||||||
| 			memcpy(c, "\357\277\275", 4); /* UTF_INVALID */ | 			memcpy(c, "\357\277\275", 4); /* UTF_INVALID */ | ||||||
| 			width = 1; | 			width = 1; | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	if (IS_SET(MODE_PRINT)) | 	if (IS_SET(MODE_PRINT)) | ||||||
| 		tprinter(c, len); | 		tprinter(c, len); | ||||||
|  | @ -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) { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue