Add parsing of DCS q sequences
These sequences are used to operate with sixels, but they are still str sequences, so they are finished with \a, ST or with a C1 control code. This patch also disables utf8 handling for the case of sixels.
This commit is contained in:
		
							
								
								
									
										44
									
								
								st.c
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								st.c
									
									
									
									
									
								
							| @ -138,6 +138,7 @@ enum term_mode { | |||||||
| 	MODE_BRCKTPASTE  = 1 << 19, | 	MODE_BRCKTPASTE  = 1 << 19, | ||||||
| 	MODE_PRINT       = 1 << 20, | 	MODE_PRINT       = 1 << 20, | ||||||
| 	MODE_UTF8        = 1 << 21, | 	MODE_UTF8        = 1 << 21, | ||||||
|  | 	MODE_SIXEL       = 1 << 22, | ||||||
| 	MODE_MOUSE       = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\ | 	MODE_MOUSE       = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\ | ||||||
| 	                  |MODE_MOUSEMANY, | 	                  |MODE_MOUSEMANY, | ||||||
| }; | }; | ||||||
| @ -155,11 +156,12 @@ enum charset { | |||||||
| enum escape_state { | enum escape_state { | ||||||
| 	ESC_START      = 1, | 	ESC_START      = 1, | ||||||
| 	ESC_CSI        = 2, | 	ESC_CSI        = 2, | ||||||
| 	ESC_STR        = 4,  /* DCS, OSC, PM, APC */ | 	ESC_STR        = 4,  /* OSC, PM, APC */ | ||||||
| 	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, | 	ESC_UTF8       = 64, | ||||||
|  | 	ESC_DCS        =128, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| enum window_state { | enum window_state { | ||||||
| @ -1485,7 +1487,7 @@ ttyread(void) | |||||||
| 	ptr = buf; | 	ptr = buf; | ||||||
|  |  | ||||||
| 	for (;;) { | 	for (;;) { | ||||||
| 		if (IS_SET(MODE_UTF8)) { | 		if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) { | ||||||
| 			/* process a complete utf8 char */ | 			/* process a complete utf8 char */ | ||||||
| 			charsize = utf8decode(ptr, &unicodep, buflen); | 			charsize = utf8decode(ptr, &unicodep, buflen); | ||||||
| 			if (charsize == 0) | 			if (charsize == 0) | ||||||
| @ -1578,7 +1580,7 @@ ttysend(char *s, size_t n) | |||||||
|  |  | ||||||
| 	lim = &s[n]; | 	lim = &s[n]; | ||||||
| 	for (t = s; t < lim; t += len) { | 	for (t = s; t < lim; t += len) { | ||||||
| 		if (IS_SET(MODE_UTF8)) { | 		if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) { | ||||||
| 			len = utf8decode(t, &u, n); | 			len = utf8decode(t, &u, n); | ||||||
| 		} else { | 		} else { | ||||||
| 			u = *t & 0xFF; | 			u = *t & 0xFF; | ||||||
| @ -2548,6 +2550,7 @@ strhandle(void) | |||||||
| 		xsettitle(strescseq.args[0]); | 		xsettitle(strescseq.args[0]); | ||||||
| 		return; | 		return; | ||||||
| 	case 'P': /* DCS -- Device Control String */ | 	case 'P': /* DCS -- Device Control String */ | ||||||
|  | 		term.mode |= ESC_DCS; | ||||||
| 	case '_': /* APC -- Application Program Command */ | 	case '_': /* APC -- Application Program Command */ | ||||||
| 	case '^': /* PM -- Privacy Message */ | 	case '^': /* PM -- Privacy Message */ | ||||||
| 		return; | 		return; | ||||||
| @ -2754,9 +2757,12 @@ tdectest(char c) | |||||||
| void | void | ||||||
| tstrsequence(uchar c) | tstrsequence(uchar c) | ||||||
| { | { | ||||||
|  | 	strreset(); | ||||||
|  |  | ||||||
| 	switch (c) { | 	switch (c) { | ||||||
| 	case 0x90:   /* DCS -- Device Control String */ | 	case 0x90:   /* DCS -- Device Control String */ | ||||||
| 		c = 'P'; | 		c = 'P'; | ||||||
|  | 		term.esc |= ESC_DCS; | ||||||
| 		break; | 		break; | ||||||
| 	case 0x9f:   /* APC -- Application Program Command */ | 	case 0x9f:   /* APC -- Application Program Command */ | ||||||
| 		c = '_'; | 		c = '_'; | ||||||
| @ -2768,7 +2774,6 @@ tstrsequence(uchar c) | |||||||
| 		c = ']'; | 		c = ']'; | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 	strreset(); |  | ||||||
| 	strescseq.type = c; | 	strescseq.type = c; | ||||||
| 	term.esc |= ESC_STR; | 	term.esc |= ESC_STR; | ||||||
| } | } | ||||||
| @ -2968,7 +2973,7 @@ tputc(Rune u) | |||||||
| 	Glyph *gp; | 	Glyph *gp; | ||||||
|  |  | ||||||
| 	control = ISCONTROL(u); | 	control = ISCONTROL(u); | ||||||
| 	if (!IS_SET(MODE_UTF8)) { | 	if (!IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) { | ||||||
| 		c[0] = u; | 		c[0] = u; | ||||||
| 		width = len = 1; | 		width = len = 1; | ||||||
| 	} else { | 	} else { | ||||||
| @ -2991,13 +2996,25 @@ tputc(Rune u) | |||||||
| 	if (term.esc & ESC_STR) { | 	if (term.esc & ESC_STR) { | ||||||
| 		if (u == '\a' || u == 030 || u == 032 || u == 033 || | 		if (u == '\a' || u == 030 || u == 032 || u == 033 || | ||||||
| 		   ISCONTROLC1(u)) { | 		   ISCONTROLC1(u)) { | ||||||
| 			term.esc &= ~(ESC_START|ESC_STR); | 			term.esc &= ~(ESC_START|ESC_STR|ESC_DCS); | ||||||
| 			term.esc |= ESC_STR_END; | 			if (IS_SET(MODE_SIXEL)) { | ||||||
| 		} else if (strescseq.len + len < sizeof(strescseq.buf) - 1) { | 				/* TODO: render sixel */; | ||||||
| 			memmove(&strescseq.buf[strescseq.len], c, len); | 				term.mode &= ~MODE_SIXEL; | ||||||
| 			strescseq.len += len; |  | ||||||
| 				return; | 				return; | ||||||
| 		} else { | 			} | ||||||
|  | 			term.esc |= ESC_STR_END; | ||||||
|  | 			goto check_control_code; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 		if (IS_SET(MODE_SIXEL)) { | ||||||
|  | 			/* TODO: implement sixel mode */ | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 		if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q') | ||||||
|  | 			term.mode |= MODE_SIXEL; | ||||||
|  |  | ||||||
|  | 		if (strescseq.len+len >= sizeof(strescseq.buf)-1) { | ||||||
| 			/* | 			/* | ||||||
| 			 * Here is a bug in terminals. If the user never sends | 			 * Here is a bug in terminals. If the user never sends | ||||||
| 			 * some code to stop the str or esc command, then st | 			 * some code to stop the str or esc command, then st | ||||||
| @ -3013,8 +3030,13 @@ tputc(Rune u) | |||||||
| 			 */ | 			 */ | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		memmove(&strescseq.buf[strescseq.len], c, len); | ||||||
|  | 		strescseq.len += len; | ||||||
|  | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | check_control_code: | ||||||
| 	/* | 	/* | ||||||
| 	 * Actions of control codes must be performed as soon they arrive | 	 * Actions of control codes must be performed as soon they arrive | ||||||
| 	 * because they can be embedded inside a control sequence, and | 	 * because they can be embedded inside a control sequence, and | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user