diff options
Diffstat (limited to 'st.c')
| -rw-r--r-- | st.c | 68 | 
1 files changed, 45 insertions, 23 deletions
@@ -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; +			goto check_control_code; +		} + + +		if (IS_SET(MODE_SIXEL)) { +			/* TODO: implement sixel mode */  			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(); -		 */ +		} +		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  | 
