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