iAdd parsing of DCS q sequences - st - Simple Terminal Err gopher.r-36.net 70 i Err gopher.r-36.net 70 1Log /scm/st//log.gph gopher.r-36.net 70 1Files /scm/st//files.gph gopher.r-36.net 70 1Refs /scm/st//refs.gph gopher.r-36.net 70 1README /scm/st//file/README.gph gopher.r-36.net 70 1LICENSE /scm/st//file/LICENSE.gph gopher.r-36.net 70 i--- Err gopher.r-36.net 70 1commit f7398434b8fa949af7bf43472caaefdd97eed0f3 /scm/st//commit/f7398434b8fa949af7bf43472caaefdd97eed0f3.gph gopher.r-36.net 70 1parent f0e2d28732549690466df995981698173daf39c0 /scm/st//commit/f0e2d28732549690466df995981698173daf39c0.gph gopher.r-36.net 70 hAuthor: Roberto E. Vargas Caballero URL:mailto:roberto.vargas@igrid-td.com gopher.r-36.net 70 iDate: Wed, 14 Sep 2016 08:27:32 +0200 Err gopher.r-36.net 70 i Err gopher.r-36.net 70 iAdd parsing of DCS q sequences Err gopher.r-36.net 70 i Err gopher.r-36.net 70 iThese sequences are used to operate with sixels, but they are still Err gopher.r-36.net 70 istr sequences, so they are finished with \a, ST or with a C1 control Err gopher.r-36.net 70 icode. This patch also disables utf8 handling for the case of sixels. Err gopher.r-36.net 70 i Err gopher.r-36.net 70 iDiffstat: Err gopher.r-36.net 70 i st.c | 68 ++++++++++++++++++++----------- Err gopher.r-36.net 70 i Err gopher.r-36.net 70 i1 file changed, 45 insertions(+), 23 deletions(-) Err gopher.r-36.net 70 i--- Err gopher.r-36.net 70 1diff --git a/st.c b/st.c /scm/st//file/st.c.gph gopher.r-36.net 70 i@@ -138,6 +138,7 @@ enum term_mode { Err gopher.r-36.net 70 i MODE_BRCKTPASTE = 1 << 19, Err gopher.r-36.net 70 i MODE_PRINT = 1 << 20, Err gopher.r-36.net 70 i MODE_UTF8 = 1 << 21, Err gopher.r-36.net 70 i+ MODE_SIXEL = 1 << 22, Err gopher.r-36.net 70 i MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\ Err gopher.r-36.net 70 i |MODE_MOUSEMANY, Err gopher.r-36.net 70 i }; Err gopher.r-36.net 70 i@@ -155,11 +156,12 @@ enum charset { Err gopher.r-36.net 70 i enum escape_state { Err gopher.r-36.net 70 i ESC_START = 1, Err gopher.r-36.net 70 i ESC_CSI = 2, Err gopher.r-36.net 70 i- ESC_STR = 4, /* DCS, OSC, PM, APC */ Err gopher.r-36.net 70 i+ ESC_STR = 4, /* OSC, PM, APC */ Err gopher.r-36.net 70 i ESC_ALTCHARSET = 8, Err gopher.r-36.net 70 i ESC_STR_END = 16, /* a final string was encountered */ Err gopher.r-36.net 70 i ESC_TEST = 32, /* Enter in test mode */ Err gopher.r-36.net 70 i ESC_UTF8 = 64, Err gopher.r-36.net 70 i+ ESC_DCS =128, Err gopher.r-36.net 70 i }; Err gopher.r-36.net 70 i Err gopher.r-36.net 70 i enum window_state { Err gopher.r-36.net 70 i@@ -1485,7 +1487,7 @@ ttyread(void) Err gopher.r-36.net 70 i ptr = buf; Err gopher.r-36.net 70 i Err gopher.r-36.net 70 i for (;;) { Err gopher.r-36.net 70 i- if (IS_SET(MODE_UTF8)) { Err gopher.r-36.net 70 i+ if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) { Err gopher.r-36.net 70 i /* process a complete utf8 char */ Err gopher.r-36.net 70 i charsize = utf8decode(ptr, &unicodep, buflen); Err gopher.r-36.net 70 i if (charsize == 0) Err gopher.r-36.net 70 i@@ -1578,7 +1580,7 @@ ttysend(char *s, size_t n) Err gopher.r-36.net 70 i Err gopher.r-36.net 70 i lim = &s[n]; Err gopher.r-36.net 70 i for (t = s; t < lim; t += len) { Err gopher.r-36.net 70 i- if (IS_SET(MODE_UTF8)) { Err gopher.r-36.net 70 i+ if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) { Err gopher.r-36.net 70 i len = utf8decode(t, &u, n); Err gopher.r-36.net 70 i } else { Err gopher.r-36.net 70 i u = *t & 0xFF; Err gopher.r-36.net 70 i@@ -2548,6 +2550,7 @@ strhandle(void) Err gopher.r-36.net 70 i xsettitle(strescseq.args[0]); Err gopher.r-36.net 70 i return; Err gopher.r-36.net 70 i case 'P': /* DCS -- Device Control String */ Err gopher.r-36.net 70 i+ term.mode |= ESC_DCS; Err gopher.r-36.net 70 i case '_': /* APC -- Application Program Command */ Err gopher.r-36.net 70 i case '^': /* PM -- Privacy Message */ Err gopher.r-36.net 70 i return; Err gopher.r-36.net 70 i@@ -2754,9 +2757,12 @@ tdectest(char c) Err gopher.r-36.net 70 i void Err gopher.r-36.net 70 i ttstrsequence(uchar c) Err gopher.r-36.net 70 i { Err gopher.r-36.net 70 i+ strreset(); Err gopher.r-36.net 70 i+ Err gopher.r-36.net 70 i switch (c) { Err gopher.r-36.net 70 i case 0x90: /* DCS -- Device Control String */ Err gopher.r-36.net 70 i c = 'P'; Err gopher.r-36.net 70 i+ term.esc |= ESC_DCS; Err gopher.r-36.net 70 i break; Err gopher.r-36.net 70 i case 0x9f: /* APC -- Application Program Command */ Err gopher.r-36.net 70 i c = '_'; Err gopher.r-36.net 70 i@@ -2768,7 +2774,6 @@ tstrsequence(uchar c) Err gopher.r-36.net 70 i c = ']'; Err gopher.r-36.net 70 i break; Err gopher.r-36.net 70 i } Err gopher.r-36.net 70 i- strreset(); Err gopher.r-36.net 70 i strescseq.type = c; Err gopher.r-36.net 70 i term.esc |= ESC_STR; Err gopher.r-36.net 70 i } Err gopher.r-36.net 70 i@@ -2968,7 +2973,7 @@ tputc(Rune u) Err gopher.r-36.net 70 i Glyph *gp; Err gopher.r-36.net 70 i Err gopher.r-36.net 70 i control = ISCONTROL(u); Err gopher.r-36.net 70 i- if (!IS_SET(MODE_UTF8)) { Err gopher.r-36.net 70 i+ if (!IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) { Err gopher.r-36.net 70 i c[0] = u; Err gopher.r-36.net 70 i width = len = 1; Err gopher.r-36.net 70 i } else { Err gopher.r-36.net 70 i@@ -2991,30 +2996,47 @@ tputc(Rune u) Err gopher.r-36.net 70 i if (term.esc & ESC_STR) { Err gopher.r-36.net 70 i if (u == '\a' || u == 030 || u == 032 || u == 033 || Err gopher.r-36.net 70 i ISCONTROLC1(u)) { Err gopher.r-36.net 70 i- term.esc &= ~(ESC_START|ESC_STR); Err gopher.r-36.net 70 i+ term.esc &= ~(ESC_START|ESC_STR|ESC_DCS); Err gopher.r-36.net 70 i+ if (IS_SET(MODE_SIXEL)) { Err gopher.r-36.net 70 i+ /* TODO: render sixel */; Err gopher.r-36.net 70 i+ term.mode &= ~MODE_SIXEL; Err gopher.r-36.net 70 i+ return; Err gopher.r-36.net 70 i+ } Err gopher.r-36.net 70 i term.esc |= ESC_STR_END; Err gopher.r-36.net 70 i- } else if (strescseq.len + len < sizeof(strescseq.buf) - 1) { Err gopher.r-36.net 70 i- memmove(&strescseq.buf[strescseq.len], c, len); Err gopher.r-36.net 70 i- strescseq.len += len; Err gopher.r-36.net 70 i+ goto check_control_code; Err gopher.r-36.net 70 i+ } Err gopher.r-36.net 70 i+ Err gopher.r-36.net 70 i+ Err gopher.r-36.net 70 i+ if (IS_SET(MODE_SIXEL)) { Err gopher.r-36.net 70 i+ /* TODO: implement sixel mode */ Err gopher.r-36.net 70 i return; Err gopher.r-36.net 70 i- } else { Err gopher.r-36.net 70 i- /* Err gopher.r-36.net 70 i- * Here is a bug in terminals. If the user never sends Err gopher.r-36.net 70 i- * some code to stop the str or esc command, then st Err gopher.r-36.net 70 i- * will stop responding. But this is better than Err gopher.r-36.net 70 i- * silently failing with unknown characters. At least Err gopher.r-36.net 70 i- * then users will report back. Err gopher.r-36.net 70 i- * Err gopher.r-36.net 70 i- * In the case users ever get fixed, here is the code: Err gopher.r-36.net 70 i- */ Err gopher.r-36.net 70 i- /* Err gopher.r-36.net 70 i- * term.esc = 0; Err gopher.r-36.net 70 i- * strhandle(); Err gopher.r-36.net 70 i- */ Err gopher.r-36.net 70 i+ } Err gopher.r-36.net 70 i+ if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q') Err gopher.r-36.net 70 i+ term.mode |= MODE_SIXEL; Err gopher.r-36.net 70 i+ Err gopher.r-36.net 70 i+ if (strescseq.len+len >= sizeof(strescseq.buf)-1) { Err gopher.r-36.net 70 i+ /* Err gopher.r-36.net 70 i+ * Here is a bug in terminals. If the user never sends Err gopher.r-36.net 70 i+ * some code to stop the str or esc command, then st Err gopher.r-36.net 70 i+ * will stop responding. But this is better than Err gopher.r-36.net 70 i+ * silently failing with unknown characters. At least Err gopher.r-36.net 70 i+ * then users will report back. Err gopher.r-36.net 70 i+ * Err gopher.r-36.net 70 i+ * In the case users ever get fixed, here is the code: Err gopher.r-36.net 70 i+ */ Err gopher.r-36.net 70 i+ /* Err gopher.r-36.net 70 i+ * term.esc = 0; Err gopher.r-36.net 70 i+ * strhandle(); Err gopher.r-36.net 70 i+ */ Err gopher.r-36.net 70 i return; Err gopher.r-36.net 70 i } Err gopher.r-36.net 70 i+ Err gopher.r-36.net 70 i+ memmove(&strescseq.buf[strescseq.len], c, len); Err gopher.r-36.net 70 i+ strescseq.len += len; Err gopher.r-36.net 70 i+ return; Err gopher.r-36.net 70 i } Err gopher.r-36.net 70 i Err gopher.r-36.net 70 i+check_control_code: Err gopher.r-36.net 70 i /* Err gopher.r-36.net 70 i * Actions of control codes must be performed as soon they arrive Err gopher.r-36.net 70 i * because they can be embedded inside a control sequence, and Err gopher.r-36.net 70 .