~petersanchez/st

f7398434b8fa949af7bf43472caaefdd97eed0f3 — Roberto E. Vargas Caballero 5 years ago f0e2d28
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.
1 files changed, 45 insertions(+), 23 deletions(-)

M st.c
M st.c => st.c +45 -23
@@ 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