Add parsing of DCS q sequences - st - Simple Terminal
Log
Files
Refs
README
LICENSE
---
commit f7398434b8fa949af7bf43472caaefdd97eed0f3
parent f0e2d28732549690466df995981698173daf39c0
Author: Roberto E. Vargas Caballero 
Date:   Wed, 14 Sep 2016 08:27:32 +0200

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.

Diffstat:
  st.c                                |      68 ++++++++++++++++++++-----------

1 file changed, 45 insertions(+), 23 deletions(-)
---
diff --git a/st.c b/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
 ttstrsequence(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