Support the DECSCUSR CSI escape sequence
authorLemonBoy <thatlemon@gmail.com>
Wed, 18 Mar 2015 20:12:47 +0000 (21:12 +0100)
committerRoberto E. Vargas Caballero <k0ga@shike2.com>
Thu, 19 Mar 2015 05:36:54 +0000 (05:36 +0000)
st.c

diff --git a/st.c b/st.c
index aa4185c..00fca99 100644 (file)
--- 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':