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
					
				
							
								
								
									
										44
									
								
								st.c
								
								
								
								
							
							
						
						
									
										44
									
								
								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,13 +2996,25 @@ 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_STR_END;
 | 
			
		||||
		} else if (strescseq.len + len < sizeof(strescseq.buf) - 1) {
 | 
			
		||||
			memmove(&strescseq.buf[strescseq.len], c, len);
 | 
			
		||||
			strescseq.len += len;
 | 
			
		||||
			term.esc &= ~(ESC_START|ESC_STR|ESC_DCS);
 | 
			
		||||
			if (IS_SET(MODE_SIXEL)) {
 | 
			
		||||
				/* TODO: render sixel */;
 | 
			
		||||
				term.mode &= ~MODE_SIXEL;
 | 
			
		||||
				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
 | 
			
		||||
			 * some code to stop the str or esc command, then st
 | 
			
		||||
| 
						 | 
				
			
			@ -3013,8 +3030,13 @@ tputc(Rune u)
 | 
			
		|||
			 */
 | 
			
		||||
			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