applied blinking cursor
[st.git] / st.c
diff --git a/st.c b/st.c
index 0d35613..76b7e0d 100644 (file)
--- a/st.c
+++ b/st.c
@@ -51,7 +51,6 @@ enum term_mode {
        MODE_ECHO        = 1 << 4,
        MODE_PRINT       = 1 << 5,
        MODE_UTF8        = 1 << 6,
-       MODE_SIXEL       = 1 << 7,
 };
 
 enum cursor_movement {
@@ -78,12 +77,11 @@ enum charset {
 enum escape_state {
        ESC_START      = 1,
        ESC_CSI        = 2,
-       ESC_STR        = 4,  /* OSC, PM, APC */
+       ESC_STR        = 4,  /* DCS, 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,
 };
 
 typedef struct {
@@ -129,6 +127,7 @@ typedef struct {
        int charset;  /* current charset */
        int icharset; /* selected charset for sequence */
        int *tabs;
+       Rune lastc;   /* last printed char outside of sequence, 0 if control */
 } Term;
 
 /* CSI Escape sequence structs */
@@ -842,7 +841,6 @@ ttyread(void)
                if (buflen > 0)
                        memmove(buf, buf + written, buflen);
                return ret;
-
        }
 }
 
@@ -1648,6 +1646,12 @@ csihandle(void)
                if (csiescseq.arg[0] == 0)
                        ttywrite(vtiden, strlen(vtiden), 0);
                break;
+       case 'b': /* REP -- if last char is printable print it <n> more times */
+               DEFAULT(csiescseq.arg[0], 1);
+               if (term.lastc)
+                       while (csiescseq.arg[0]-- > 0)
+                               tputc(term.lastc);
+               break;
        case 'C': /* CUF -- Cursor <n> Forward */
        case 'a': /* HPR -- Cursor <n> Forward */
                DEFAULT(csiescseq.arg[0], 1);
@@ -1771,7 +1775,7 @@ csihandle(void)
                break;
        case 'n': /* DSR – Device Status Report (cursor position) */
                if (csiescseq.arg[0] == 6) {
-                       len = snprintf(buf, sizeof(buf),"\033[%i;%iR",
+                       len = snprintf(buf, sizeof(buf), "\033[%i;%iR",
                                        term.c.y+1, term.c.x+1);
                        ttywrite(buf, len, 0);
                }
@@ -1855,7 +1859,7 @@ strhandle(void)
                                xsettitle(strescseq.args[1]);
                        return;
                case 52:
-                       if (narg > 2) {
+                       if (narg > 2 && allowwindowops) {
                                dec = base64dec(strescseq.args[2]);
                                if (dec) {
                                        xsetsel(dec);
@@ -1891,7 +1895,6 @@ 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;
@@ -2085,12 +2088,9 @@ 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 = '_';
@@ -2102,6 +2102,7 @@ tstrsequence(uchar c)
                c = ']';
                break;
        }
+       strreset();
        strescseq.type = c;
        term.esc |= ESC_STR;
 }
@@ -2299,7 +2300,7 @@ tputc(Rune u)
        Glyph *gp;
 
        control = ISCONTROL(u);
-       if (u < 127 || !IS_SET(MODE_UTF8 | MODE_SIXEL)) {
+       if (u < 127 || !IS_SET(MODE_UTF8)) {
                c[0] = u;
                width = len = 1;
        } else {
@@ -2320,23 +2321,11 @@ 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|ESC_DCS);
-                       if (IS_SET(MODE_SIXEL)) {
-                               /* TODO: render sixel */;
-                               term.mode &= ~MODE_SIXEL;
-                               return;
-                       }
+                       term.esc &= ~(ESC_START|ESC_STR);
                        term.esc |= ESC_STR_END;
                        goto check_control_code;
                }
 
-               if (IS_SET(MODE_SIXEL)) {
-                       /* TODO: implement sixel mode */
-                       return;
-               }
-               if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q')
-                       term.mode |= MODE_SIXEL;
-
                if (strescseq.len+len >= strescseq.siz) {
                        /*
                         * Here is a bug in terminals. If the user never sends
@@ -2373,6 +2362,8 @@ check_control_code:
                /*
                 * control codes are not shown ever
                 */
+               if (!term.esc)
+                       term.lastc = 0;
                return;
        } else if (term.esc & ESC_START) {
                if (term.esc & ESC_CSI) {
@@ -2422,6 +2413,7 @@ check_control_code:
        }
 
        tsetchar(u, &term.c.attr, term.c.x, term.c.y);
+       term.lastc = u;
 
        if (width == 2) {
                gp->mode |= ATTR_WIDE;
@@ -2445,7 +2437,7 @@ twrite(const char *buf, int buflen, int show_ctrl)
        int n;
 
        for (n = 0; n < buflen; n += charsize) {
-               if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) {
+               if (IS_SET(MODE_UTF8)) {
                        /* process a complete utf8 char */
                        charsize = utf8decode(buf + n, &u, buflen - n);
                        if (charsize == 0)