st

fork of suckless's simple terminal
Index Commits Files Refs README LICENSE
commit f7398434b8fa949af7bf43472caaefdd97eed0f3
parent f0e2d28732549690466df995981698173daf39c0
Author: Roberto E. Vargas Caballero <roberto.vargas@igrid-td.com>
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:
Mst.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
 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