mirror of
				git://git.suckless.org/st
				synced 2025-10-31 03:27:32 +00:00 
			
		
		
		
	Receive only a wchar_t in tchar()
It makes simpler the conversion from utf8 input string and makes simpler the checks done in tputc, but it still requires a lot of additional conversions that will be removed later.
This commit is contained in:
		
							parent
							
								
									d65ebe9aed
								
							
						
					
					
						commit
						e8f1308586
					
				
							
								
								
									
										150
									
								
								st.c
									
									
									
									
									
								
							
							
						
						
									
										150
									
								
								st.c
									
									
									
									
									
								
							| @ -379,20 +379,20 @@ static void tmoveato(int, int); | |||||||
| static void tnew(int, int); | static void tnew(int, int); | ||||||
| static void tnewline(int); | static void tnewline(int); | ||||||
| static void tputtab(int); | static void tputtab(int); | ||||||
| static void tputc(char *, int); | static void tputc(wchar_t); | ||||||
| static void treset(void); | static void treset(void); | ||||||
| static void tresize(int, int); | static void tresize(int, int); | ||||||
| static void tscrollup(int, int); | static void tscrollup(int, int); | ||||||
| static void tscrolldown(int, int); | static void tscrolldown(int, int); | ||||||
| static void tsetattr(int *, int); | static void tsetattr(int *, int); | ||||||
| static void tsetchar(char *, Glyph *, int, int); | static void tsetchar(wchar_t, Glyph *, int, int); | ||||||
| static void tsetscroll(int, int); | static void tsetscroll(int, int); | ||||||
| static void tswapscreen(void); | static void tswapscreen(void); | ||||||
| static void tsetdirt(int, int); | static void tsetdirt(int, int); | ||||||
| static void tsetdirtattr(int); | static void tsetdirtattr(int); | ||||||
| static void tsetmode(bool, bool, int *, int); | static void tsetmode(bool, bool, int *, int); | ||||||
| static void tfulldirt(void); | static void tfulldirt(void); | ||||||
| static void techo(char *, int); | static void techo(wchar_t); | ||||||
| static void tcontrolcode(uchar ); | static void tcontrolcode(uchar ); | ||||||
| static void tdectest(char ); | static void tdectest(char ); | ||||||
| static int32_t tdefcolor(int *, int *, int); | static int32_t tdefcolor(int *, int *, int); | ||||||
| @ -1251,7 +1251,6 @@ ttyread(void) { | |||||||
| 	static char buf[BUFSIZ]; | 	static char buf[BUFSIZ]; | ||||||
| 	static int buflen = 0; | 	static int buflen = 0; | ||||||
| 	char *ptr; | 	char *ptr; | ||||||
| 	char s[UTF_SIZ]; |  | ||||||
| 	int charsize; /* size of utf8 char in bytes */ | 	int charsize; /* size of utf8 char in bytes */ | ||||||
| 	wchar_t unicodep; | 	wchar_t unicodep; | ||||||
| 	int ret; | 	int ret; | ||||||
| @ -1264,8 +1263,7 @@ ttyread(void) { | |||||||
| 	buflen += ret; | 	buflen += ret; | ||||||
| 	ptr = buf; | 	ptr = buf; | ||||||
| 	while((charsize = utf8decode(ptr, &unicodep, buflen))) { | 	while((charsize = utf8decode(ptr, &unicodep, buflen))) { | ||||||
| 		utf8encode(unicodep, s); | 		tputc(unicodep); | ||||||
| 		tputc(s, charsize); |  | ||||||
| 		ptr += charsize; | 		ptr += charsize; | ||||||
| 		buflen -= charsize; | 		buflen -= charsize; | ||||||
| 	} | 	} | ||||||
| @ -1282,9 +1280,17 @@ ttywrite(const char *s, size_t n) { | |||||||
| 
 | 
 | ||||||
| void | void | ||||||
| ttysend(char *s, size_t n) { | ttysend(char *s, size_t n) { | ||||||
|  | 	int len; | ||||||
|  | 	wchar_t u; | ||||||
|  | 
 | ||||||
| 	ttywrite(s, n); | 	ttywrite(s, n); | ||||||
| 	if(IS_SET(MODE_ECHO)) | 	if(IS_SET(MODE_ECHO)) { | ||||||
| 		techo(s, n); | 		while ((len = utf8decode(s, &u, n)) != 0) { | ||||||
|  | 			techo(u); | ||||||
|  | 			n -= len; | ||||||
|  | 			s += len; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| @ -1534,7 +1540,7 @@ tmoveto(int x, int y) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| tsetchar(char *c, Glyph *attr, int x, int y) { | tsetchar(wchar_t u, Glyph *attr, int x, int y) { | ||||||
| 	static char *vt100_0[62] = { /* 0x41 - 0x7e */ | 	static char *vt100_0[62] = { /* 0x41 - 0x7e */ | ||||||
| 		"↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */ | 		"↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */ | ||||||
| 		0, 0, 0, 0, 0, 0, 0, 0, /* H - O */ | 		0, 0, 0, 0, 0, 0, 0, 0, /* H - O */ | ||||||
| @ -1545,16 +1551,21 @@ tsetchar(char *c, Glyph *attr, int x, int y) { | |||||||
| 		"⎻", "─", "⎼", "⎽", "├", "┤", "┴", "┬", /* p - w */ | 		"⎻", "─", "⎼", "⎽", "├", "┤", "┴", "┬", /* p - w */ | ||||||
| 		"│", "≤", "≥", "π", "≠", "£", "·", /* x - ~ */ | 		"│", "≤", "≥", "π", "≠", "£", "·", /* x - ~ */ | ||||||
| 	}; | 	}; | ||||||
|  | 	char c[UTF_SIZ]; | ||||||
| 
 | 
 | ||||||
|  | 	c[0] = '\0'; | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * The table is proudly stolen from rxvt. | 	 * The table is proudly stolen from rxvt. | ||||||
| 	 */ | 	 */ | ||||||
| 	if(term.trantbl[term.charset] == CS_GRAPHIC0) { | 	if(term.trantbl[term.charset] == CS_GRAPHIC0) { | ||||||
| 		if(BETWEEN(c[0], 0x41, 0x7e) && vt100_0[c[0] - 0x41]) { | 		if(BETWEEN(u, 0x41, 0x7e) && vt100_0[u - 0x41]) { | ||||||
| 			c = vt100_0[c[0] - 0x41]; | 			strcpy(c, vt100_0[u - 0x41]); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if (c[0] == '\0') | ||||||
|  | 		utf8encode(u, c); | ||||||
|  | 
 | ||||||
| 	if(term.line[y][x].mode & ATTR_WIDE) { | 	if(term.line[y][x].mode & ATTR_WIDE) { | ||||||
| 		if(x+1 < term.col) { | 		if(x+1 < term.col) { | ||||||
| 			term.line[y][x+1].c[0] = ' '; | 			term.line[y][x+1].c[0] = ' '; | ||||||
| @ -2343,26 +2354,18 @@ tputtab(int n) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| techo(char *buf, int len) { | techo(wchar_t u) { | ||||||
| 	for(; len > 0; buf++, len--) { | 	if(ISCONTROL(u)) { /* control code */ | ||||||
| 		char c = *buf; | 		if(u & 0x80) { | ||||||
| 
 | 			u &= 0x7f; | ||||||
| 		if(ISCONTROL((uchar) c)) { /* control code */ | 			tputc('^'); | ||||||
| 			if(c & 0x80) { | 			tputc('['); | ||||||
| 				c &= 0x7f; | 		} else if(u != '\n' && u != '\r' && u != '\t') { | ||||||
| 				tputc("^", 1); | 			u ^= 0x40; | ||||||
| 				tputc("[", 1); | 			tputc('^'); | ||||||
| 			} else if(c != '\n' && c != '\r' && c != '\t') { |  | ||||||
| 				c ^= 0x40; |  | ||||||
| 				tputc("^", 1); |  | ||||||
| 			} |  | ||||||
| 			tputc(&c, 1); |  | ||||||
| 		} else { |  | ||||||
| 			break; |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if(len) | 	tputc(u); | ||||||
| 		tputc(buf, len); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| @ -2380,13 +2383,12 @@ tdeftran(char ascii) { | |||||||
| 
 | 
 | ||||||
| void | void | ||||||
| tdectest(char c) { | tdectest(char c) { | ||||||
| 	static char E[UTF_SIZ] = "E"; |  | ||||||
| 	int x, y; | 	int x, y; | ||||||
| 
 | 
 | ||||||
| 	if(c == '8') { /* DEC screen alignment test. */ | 	if(c == '8') { /* DEC screen alignment test. */ | ||||||
| 		for(x = 0; x < term.col; ++x) { | 		for(x = 0; x < term.col; ++x) { | ||||||
| 			for(y = 0; y < term.row; ++y) | 			for(y = 0; y < term.row; ++y) | ||||||
| 				tsetchar(E, &term.c.attr, x, y); | 				tsetchar('E', &term.c.attr, x, y); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @ -2417,7 +2419,6 @@ tstrsequence(uchar c) { | |||||||
| 
 | 
 | ||||||
| void | void | ||||||
| tcontrolcode(uchar ascii) { | tcontrolcode(uchar ascii) { | ||||||
| 	static char question[UTF_SIZ] = "?"; |  | ||||||
| 
 | 
 | ||||||
| 	switch(ascii) { | 	switch(ascii) { | ||||||
| 	case '\t':   /* HT */ | 	case '\t':   /* HT */ | ||||||
| @ -2458,7 +2459,7 @@ tcontrolcode(uchar ascii) { | |||||||
| 		term.charset = 1; | 		term.charset = 1; | ||||||
| 		return; | 		return; | ||||||
| 	case '\032': /* SUB */ | 	case '\032': /* SUB */ | ||||||
| 		tsetchar(question, &term.c.attr, term.c.x, term.c.y); | 		tsetchar('?', &term.c.attr, term.c.x, term.c.y); | ||||||
| 	case '\030': /* CAN */ | 	case '\030': /* CAN */ | ||||||
| 		csireset(); | 		csireset(); | ||||||
| 		break; | 		break; | ||||||
| @ -2579,26 +2580,20 @@ eschandle(uchar ascii) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| tputc(char *c, int len) { | tputc(wchar_t u) { | ||||||
| 	uchar ascii; | 	char s[UTF_SIZ]; | ||||||
|  | 	int len; | ||||||
| 	bool control; | 	bool control; | ||||||
| 	wchar_t unicodep; |  | ||||||
| 	int width; | 	int width; | ||||||
| 	Glyph *gp; | 	Glyph *gp; | ||||||
| 
 | 
 | ||||||
| 	if(len == 1) { | 
 | ||||||
| 		width = 1; | 	width = wcwidth(u); | ||||||
| 		unicodep = ascii = *c; | 	control = ISCONTROLC1(u); | ||||||
| 	} else { |  | ||||||
| 		utf8decode(c, &unicodep, UTF_SIZ); |  | ||||||
| 		width = wcwidth(unicodep); |  | ||||||
| 		control = ISCONTROLC1(unicodep); |  | ||||||
| 		ascii = unicodep; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if(IS_SET(MODE_PRINT)) | 	if(IS_SET(MODE_PRINT)) | ||||||
| 		tprinter(unicodep); | 		tprinter(u); | ||||||
| 	control = ISCONTROL(unicodep); | 	control = ISCONTROL(u); | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * STR sequence must be checked before anything else | 	 * STR sequence must be checked before anything else | ||||||
| @ -2607,31 +2602,33 @@ tputc(char *c, int len) { | |||||||
| 	 * character. | 	 * character. | ||||||
| 	 */ | 	 */ | ||||||
| 	if(term.esc & ESC_STR) { | 	if(term.esc & ESC_STR) { | ||||||
| 		if(width == 1 && | 		if(u == '\a' || u == 030 || u == 032  || u == 033 || | ||||||
| 		   (ascii == '\a' || ascii == 030 || | 		   ISCONTROLC1(u)) { | ||||||
| 		    ascii == 032  || ascii == 033 || |  | ||||||
| 		    ISCONTROLC1(unicodep))) { |  | ||||||
| 			term.esc &= ~(ESC_START|ESC_STR); | 			term.esc &= ~(ESC_START|ESC_STR); | ||||||
| 			term.esc |= ESC_STR_END; | 			term.esc |= ESC_STR_END; | ||||||
| 		} else if(strescseq.len + len < sizeof(strescseq.buf) - 1) { |  | ||||||
| 			memmove(&strescseq.buf[strescseq.len], c, len); |  | ||||||
| 			strescseq.len += len; |  | ||||||
| 			return; |  | ||||||
| 		} else { | 		} else { | ||||||
| 		/*
 | 			/* TODO: make csiescseq.buf buffer of wchar_t */ | ||||||
| 		 * Here is a bug in terminals. If the user never sends | 			len = utf8encode(u, s); | ||||||
| 		 * some code to stop the str or esc command, then st | 			if(strescseq.len + len < sizeof(strescseq.buf) - 1) { | ||||||
| 		 * will stop responding. But this is better than | 				memmove(&strescseq.buf[strescseq.len], s, len); | ||||||
| 		 * silently failing with unknown characters. At least | 				strescseq.len += len; | ||||||
| 		 * then users will report back. | 				return; | ||||||
| 		 * | 			} else { | ||||||
| 		 * In the case users ever get fixed, here is the code: | 			/*
 | ||||||
| 		 */ | 			 * Here is a bug in terminals. If the user never sends | ||||||
| 		/*
 | 			 * some code to stop the str or esc command, then st | ||||||
| 		 * term.esc = 0; | 			 * will stop responding. But this is better than | ||||||
| 		 * strhandle(); | 			 * silently failing with unknown characters. At least | ||||||
| 		 */ | 			 * then users will report back. | ||||||
| 			return; | 			 * | ||||||
|  | 			 * In the case users ever get fixed, here is the code: | ||||||
|  | 			 */ | ||||||
|  | 			/*
 | ||||||
|  | 			 * term.esc = 0; | ||||||
|  | 			 * strhandle(); | ||||||
|  | 			 */ | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -2641,15 +2638,16 @@ tputc(char *c, int len) { | |||||||
| 	 * they must not cause conflicts with sequences. | 	 * they must not cause conflicts with sequences. | ||||||
| 	 */ | 	 */ | ||||||
| 	if(control) { | 	if(control) { | ||||||
| 		tcontrolcode(ascii); | 		tcontrolcode(u); | ||||||
| 		/*
 | 		/*
 | ||||||
| 		 * control codes are not shown ever | 		 * control codes are not shown ever | ||||||
| 		 */ | 		 */ | ||||||
| 		return; | 		return; | ||||||
| 	} else if(term.esc & ESC_START) { | 	} else if(term.esc & ESC_START) { | ||||||
| 		if(term.esc & ESC_CSI) { | 		if(term.esc & ESC_CSI) { | ||||||
| 			csiescseq.buf[csiescseq.len++] = ascii; | 			/* TODO: make csiescseq.buf buffer of wchar_t */ | ||||||
| 			if(BETWEEN(ascii, 0x40, 0x7E) | 			csiescseq.buf[csiescseq.len++] = u; | ||||||
|  | 			if(BETWEEN(u, 0x40, 0x7E) | ||||||
| 					|| csiescseq.len >= \ | 					|| csiescseq.len >= \ | ||||||
| 					sizeof(csiescseq.buf)-1) { | 					sizeof(csiescseq.buf)-1) { | ||||||
| 				term.esc = 0; | 				term.esc = 0; | ||||||
| @ -2658,11 +2656,11 @@ tputc(char *c, int len) { | |||||||
| 			} | 			} | ||||||
| 			return; | 			return; | ||||||
| 		} else if(term.esc & ESC_ALTCHARSET) { | 		} else if(term.esc & ESC_ALTCHARSET) { | ||||||
| 			tdeftran(ascii); | 			tdeftran(u); | ||||||
| 		} else if(term.esc & ESC_TEST) { | 		} else if(term.esc & ESC_TEST) { | ||||||
| 			tdectest(ascii); | 			tdectest(u); | ||||||
| 		} else { | 		} else { | ||||||
| 			if (!eschandle(ascii)) | 			if (!eschandle(u)) | ||||||
| 				return; | 				return; | ||||||
| 			/* sequence already finished */ | 			/* sequence already finished */ | ||||||
| 		} | 		} | ||||||
| @ -2688,7 +2686,7 @@ tputc(char *c, int len) { | |||||||
| 	if(term.c.x+width > term.col) | 	if(term.c.x+width > term.col) | ||||||
| 		tnewline(1); | 		tnewline(1); | ||||||
| 
 | 
 | ||||||
| 	tsetchar(c, &term.c.attr, term.c.x, term.c.y); | 	tsetchar(u, &term.c.attr, term.c.x, term.c.y); | ||||||
| 
 | 
 | ||||||
| 	if(width == 2) { | 	if(width == 2) { | ||||||
| 		gp->mode |= ATTR_WIDE; | 		gp->mode |= ATTR_WIDE; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user