st

fork of suckless's simple terminal
Index Commits Files Refs README LICENSE
commit 580302f3179ef3f24cf0329755686dfa7100996b
parent 86d1e432a823dad7bb64808b8192014fddc8cd9f
Author: LemonBoy <thatlemon@gmail.com>
Date:   Wed, 18 Mar 2015 21:12:47 +0100

Support the DECSCUSR CSI escape sequence

Diffstat:
Mst.c | 62+++++++++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 49 insertions(+), 13 deletions(-)
diff --git a/st.c b/st.c
@@ -197,14 +197,14 @@ typedef struct {
 } TCursor;
 
 /* CSI Escape sequence structs */
-/* ESC '[' [[ [<priv>] <arg> [;]] <mode>] */
+/* ESC '[' [[ [<priv>] <arg> [;]] <mode> [<mode>]] */
 typedef struct {
     char buf[ESC_BUF_SIZ]; /* raw string */
     int len;               /* raw string length */
     char priv;
     int arg[ESC_ARG_SIZ];
     int narg;              /* nb of args */
-    char mode;
+    char mode[2];
 } CSIEscape;
 
 /* STR Escape sequence structs */
@@ -257,6 +257,7 @@ typedef struct {
     int ch; /* char height */
     int cw; /* char width  */
     char state; /* focus, redraw, visible */
+    int cursor; /* cursor style */
 } XWindow;
 
 typedef struct {
@@ -1545,7 +1546,8 @@ csiparse(void) {
             break;
         p++;
     }
-    csiescseq.mode = *p;
+    csiescseq.mode[0] = *p++;
+    csiescseq.mode[1] = (p < csiescseq.buf+csiescseq.len) ? *p : '\0';
 }
 
 /* for absolute user moves, when decom is set */
@@ -1983,7 +1985,7 @@ csihandle(void) {
     char buf[40];
     int len;
 
-    switch(csiescseq.mode) {
+    switch(csiescseq.mode[0]) {
     default:
     unknown:
         fprintf(stderr, "erresc: unknown csi ");
@@ -2171,6 +2173,19 @@ csihandle(void) {
     case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */
         tcursor(CURSOR_LOAD);
         break;
+    case ' ':
+        switch (csiescseq.mode[1]) {
+            case 'q': /* DECSCUSR -- Set Cursor Style */
+                DEFAULT(csiescseq.arg[0], 1);
+                if (!BETWEEN(csiescseq.arg[0], 0, 6)) {
+                    goto unknown;
+                }
+                xw.cursor = csiescseq.arg[0];
+                break;
+            default:
+                goto unknown;
+        }
+        break;
     }
 }
 
@@ -3551,16 +3566,36 @@ xdrawcursor(void) {
 
     /* draw the new one */
     if(xw.state & WIN_FOCUSED) {
-        if(IS_SET(MODE_REVERSE)) {
-            g.mode |= ATTR_REVERSE;
-            g.fg = defaultcs;
-            g.bg = defaultfg;
-        }
+        switch (xw.cursor) {
+            case 0: /* Blinking Block */
+            case 1: /* Blinking Block (Default) */
+            case 2: /* Steady Block */
+                if(IS_SET(MODE_REVERSE)) {
+                        g.mode |= ATTR_REVERSE;
+                        g.fg = defaultcs;
+                        g.bg = defaultfg;
+                    }
 
-        sl = utf8len(g.c);
-        width = (term.line[term.c.y][curx].mode & ATTR_WIDE)\
-            ? 2 : 1;
-        xdraws(g.c, g, term.c.x, term.c.y, width, sl);
+                sl = utf8len(g.c);
+                width = (term.line[term.c.y][curx].mode & ATTR_WIDE)\
+                    ? 2 : 1;
+                xdraws(g.c, g, term.c.x, term.c.y, width, sl);
+                break;
+            case 3: /* Blinking Underline */
+            case 4: /* Steady Underline */
+                XftDrawRect(xw.draw, &dc.col[defaultcs],
+                        borderpx + curx * xw.cw,
+                        borderpx + (term.c.y + 1) * xw.ch - 1,
+                        xw.cw, 1);
+                break;
+            case 5: /* Blinking bar */
+            case 6: /* Steady bar */
+                XftDrawRect(xw.draw, &dc.col[defaultcs],
+                                borderpx + curx * xw.cw,
+                                borderpx + term.c.y * xw.ch,
+                                1, xw.ch);
+                break;
+        }
     } else {
         XftDrawRect(xw.draw, &dc.col[defaultcs],
                 borderpx + curx * xw.cw,
@@ -3985,6 +4020,7 @@ main(int argc, char *argv[]) {
 
     xw.l = xw.t = 0;
     xw.isfixed = False;
+    xw.cursor = 0;
 
     ARGBEGIN {
     case 'a':