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:
		
							parent
							
								
									f0e2d28732
								
							
						
					
					
						commit
						f7398434b8
					
				
							
								
								
									
										70
									
								
								st.c
								
								
								
								
							
							
						
						
									
										70
									
								
								st.c
								
								
								
								
							|  | @ -138,6 +138,7 @@ enum term_mode { | |||
| 	MODE_BRCKTPASTE  = 1 << 19, | ||||
| 	MODE_PRINT       = 1 << 20, | ||||
| 	MODE_UTF8        = 1 << 21, | ||||
| 	MODE_SIXEL       = 1 << 22, | ||||
| 	MODE_MOUSE       = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\ | ||||
| 	                  |MODE_MOUSEMANY, | ||||
| }; | ||||
|  | @ -155,11 +156,12 @@ enum charset { | |||
| enum escape_state { | ||||
| 	ESC_START      = 1, | ||||
| 	ESC_CSI        = 2, | ||||
| 	ESC_STR        = 4,  /* DCS, OSC, PM, APC */ | ||||
| 	ESC_STR        = 4,  /* OSC, PM, APC */ | ||||
| 	ESC_ALTCHARSET = 8, | ||||
| 	ESC_STR_END    = 16, /* a final string was encountered */ | ||||
| 	ESC_TEST       = 32, /* Enter in test mode */ | ||||
| 	ESC_UTF8       = 64, | ||||
| 	ESC_DCS        =128, | ||||
| }; | ||||
| 
 | ||||
| enum window_state { | ||||
|  | @ -1485,7 +1487,7 @@ ttyread(void) | |||
| 	ptr = buf; | ||||
| 
 | ||||
| 	for (;;) { | ||||
| 		if (IS_SET(MODE_UTF8)) { | ||||
| 		if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) { | ||||
| 			/* process a complete utf8 char */ | ||||
| 			charsize = utf8decode(ptr, &unicodep, buflen); | ||||
| 			if (charsize == 0) | ||||
|  | @ -1578,7 +1580,7 @@ ttysend(char *s, size_t n) | |||
| 
 | ||||
| 	lim = &s[n]; | ||||
| 	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); | ||||
| 		} else { | ||||
| 			u = *t & 0xFF; | ||||
|  | @ -2548,6 +2550,7 @@ strhandle(void) | |||
| 		xsettitle(strescseq.args[0]); | ||||
| 		return; | ||||
| 	case 'P': /* DCS -- Device Control String */ | ||||
| 		term.mode |= ESC_DCS; | ||||
| 	case '_': /* APC -- Application Program Command */ | ||||
| 	case '^': /* PM -- Privacy Message */ | ||||
| 		return; | ||||
|  | @ -2754,9 +2757,12 @@ tdectest(char c) | |||
| void | ||||
| tstrsequence(uchar c) | ||||
| { | ||||
| 	strreset(); | ||||
| 
 | ||||
| 	switch (c) { | ||||
| 	case 0x90:   /* DCS -- Device Control String */ | ||||
| 		c = 'P'; | ||||
| 		term.esc |= ESC_DCS; | ||||
| 		break; | ||||
| 	case 0x9f:   /* APC -- Application Program Command */ | ||||
| 		c = '_'; | ||||
|  | @ -2768,7 +2774,6 @@ tstrsequence(uchar c) | |||
| 		c = ']'; | ||||
| 		break; | ||||
| 	} | ||||
| 	strreset(); | ||||
| 	strescseq.type = c; | ||||
| 	term.esc |= ESC_STR; | ||||
| } | ||||
|  | @ -2968,7 +2973,7 @@ tputc(Rune u) | |||
| 	Glyph *gp; | ||||
| 
 | ||||
| 	control = ISCONTROL(u); | ||||
| 	if (!IS_SET(MODE_UTF8)) { | ||||
| 	if (!IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) { | ||||
| 		c[0] = u; | ||||
| 		width = len = 1; | ||||
| 	} else { | ||||
|  | @ -2991,30 +2996,47 @@ tputc(Rune u) | |||
| 	if (term.esc & ESC_STR) { | ||||
| 		if (u == '\a' || u == 030 || u == 032 || u == 033 || | ||||
| 		   ISCONTROLC1(u)) { | ||||
| 			term.esc &= ~(ESC_START|ESC_STR); | ||||
| 			term.esc &= ~(ESC_START|ESC_STR|ESC_DCS); | ||||
| 			if (IS_SET(MODE_SIXEL)) { | ||||
| 				/* TODO: render sixel */; | ||||
| 				term.mode &= ~MODE_SIXEL; | ||||
| 				return; | ||||
| 			} | ||||
| 			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 { | ||||
| 		/*
 | ||||
| 		 * Here is a bug in terminals. If the user never sends | ||||
| 		 * some code to stop the str or esc command, then st | ||||
| 		 * will stop responding. But this is better than | ||||
| 		 * silently failing with unknown characters. At least | ||||
| 		 * then users will report back. | ||||
| 		 * | ||||
| 		 * In the case users ever get fixed, here is the code: | ||||
| 		 */ | ||||
| 		/*
 | ||||
| 		 * term.esc = 0; | ||||
| 		 * strhandle(); | ||||
| 		 */ | ||||
| 			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 | ||||
| 			 * some code to stop the str or esc command, then st | ||||
| 			 * will stop responding. But this is better than | ||||
| 			 * silently failing with unknown characters. At least | ||||
| 			 * then users will report back. | ||||
| 			 * | ||||
| 			 * In the case users ever get fixed, here is the code: | ||||
| 			 */ | ||||
| 			/*
 | ||||
| 			 * term.esc = 0; | ||||
| 			 * strhandle(); | ||||
| 			 */ | ||||
| 			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 | ||||
| 	 * because they can be embedded inside a control sequence, and | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue