Print control codes only in graphic mode - st - Personal fork of st
 (HTM) git clone git://git.drkhsh.at/st.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 2bd0c23fa7bb42724c75416342d36e00c435f404
 (DIR) parent 034dc71fb8227e8963f22b123f30962ec0b6bca7
 (HTM) Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
       Date:   Sat,  6 Oct 2012 19:15:30 +0200
       
       Print control codes only in graphic mode
       
       Non handled codes must be ignored, except in graphic mode. Also STR
       sequences have higher priority than control codes, so they must be handled
       before of them.
       ---
        st.c |  160 ++++++++++++++++++++++++++++++++++++------------------------------
        1 file changed, 87 insertions(+), 73 deletions(-)
       Diffstat:
         M st.c                                |     160 +++++++++++++++++--------------
       
       1 file changed, 87 insertions(+), 73 deletions(-)
       ---
 (DIR) diff --git a/st.c b/st.c
       @@ -1784,56 +1784,80 @@ tputtab(bool forward) {
        void
        tputc(char *c, int len) {
                uchar ascii = *c;
       +        bool control = ascii < '\x20' || ascii == 0177;
        
                if(iofd != -1)
                        write(iofd, c, len);
       -
       -        switch(ascii) {
       -        case '\t':        /* HT */
       -                tputtab(1);
       -                return;
       -        case '\b':        /* BS */
       -                tmoveto(term.c.x-1, term.c.y);
       -                return;
       -        case '\r':        /* CR */
       -                tmoveto(0, term.c.y);
       -                return;
       -        case '\f':        /* LF */
       -        case '\v':        /* VT */
       -        case '\n':        /* LF */
       -                /* go to first col if the mode is set */
       -                tnewline(IS_SET(MODE_CRLF));
       -                return;
       -        case '\a':        /* BEL */
       -                if(term.esc & ESC_STR)
       +        /*
       +         * STR sequences must be checked before of anything
       +         * because it can use some control codes as part of the sequence
       +         */
       +        if(term.esc & ESC_STR) {
       +                switch(ascii) {
       +                case '\033':
       +                        term.esc = ESC_START | ESC_STR_END;
                                break;
       -                if(!(xw.state & WIN_FOCUSED))
       -                        xseturgency(1);
       -                return;
       -        case '\033':        /* ESC */
       -                csireset();
       -                term.esc = ESC_START;
       -                return;
       -        case '\016':        /* SO */
       -                term.c.attr.mode |= ATTR_GFX;
       -                break;
       -        case '\017':        /* SI */
       -                term.c.attr.mode &= ~ATTR_GFX;
       -                return;
       -        case '\032':        /* SUB */
       -        case '\030':        /* CAN */
       -                csireset();
       +                case '\a': /* backwards compatibility to xterm */
       +                        term.esc = 0;
       +                        strhandle();
       +                        break;
       +                default:
       +                        strescseq.buf[strescseq.len++] = ascii;
       +                        if(strescseq.len+1 >= STR_BUF_SIZ) {
       +                                term.esc = 0;
       +                                strhandle();
       +                        }
       +                }
                        return;
       -        default:
       -        /* case '\005':        ENQ (IGNORED) */
       -        /* case '\000':        NUL (IGNORED) */
       -        /* case '\021':        XON (IGNORED) */
       -        /* case '\023':        XOFF (IGNORED) */
       -        /* case 0177:        DEL (IGNORED) */
       -                break;
                }
       -
       -        if(term.esc & ESC_START) {
       +        /*
       +         * Actions of control codes must be performed as soon they arrive
       +         * because they can be embedded inside a control sequence, and
       +         * they must not cause conflicts with sequences.
       +         */
       +        if(control) {
       +                switch(ascii) {
       +                case '\t':        /* HT */
       +                        tputtab(1);
       +                        return;
       +                case '\b':        /* BS */
       +                        tmoveto(term.c.x-1, term.c.y);
       +                        return;
       +                case '\r':        /* CR */
       +                        tmoveto(0, term.c.y);
       +                        return;
       +                case '\f':        /* LF */
       +                case '\v':        /* VT */
       +                case '\n':        /* LF */
       +                        /* go to first col if the mode is set */
       +                        tnewline(IS_SET(MODE_CRLF));
       +                        return;
       +                case '\a':        /* BEL */
       +                        if(!(xw.state & WIN_FOCUSED))
       +                                xseturgency(1);
       +                        return;
       +                case '\033':        /* ESC */
       +                        csireset();
       +                        term.esc = ESC_START;
       +                        return;
       +                case '\016':        /* SO */
       +                        term.c.attr.mode |= ATTR_GFX;
       +                        return;
       +                case '\017':        /* SI */
       +                        term.c.attr.mode &= ~ATTR_GFX;
       +                        return;
       +                case '\032':        /* SUB */
       +                case '\030':        /* CAN */
       +                        csireset();
       +                        return;
       +                 case '\005':        /* ENQ (IGNORED) */
       +                 case '\000':        /* NUL (IGNORED) */
       +                 case '\021':        /* XON (IGNORED) */
       +                 case '\023':        /* XOFF (IGNORED) */
       +                 case 0177:        /* DEL (IGNORED) */
       +                        return;
       +                }
       +        } else if(term.esc & ESC_START) {
                        if(term.esc & ESC_CSI) {
                                csiescseq.buf[csiescseq.len++] = ascii;
                                if(BETWEEN(ascii, 0x40, 0x7E)
       @@ -1841,22 +1865,6 @@ tputc(char *c, int len) {
                                        term.esc = 0;
                                        csiparse(), csihandle();
                                }
       -                } else if(term.esc & ESC_STR) {
       -                        switch(ascii) {
       -                        case '\033':
       -                                term.esc = ESC_START | ESC_STR_END;
       -                                break;
       -                        case '\a': /* backwards compatibility to xterm */
       -                                term.esc = 0;
       -                                strhandle();
       -                                break;
       -                        default:
       -                                strescseq.buf[strescseq.len++] = ascii;
       -                                if(strescseq.len+1 >= STR_BUF_SIZ) {
       -                                        term.esc = 0;
       -                                        strhandle();
       -                                }
       -                        }
                        } else if(term.esc & ESC_STR_END) {
                                term.esc = 0;
                                if(ascii == '\\')
       @@ -1955,20 +1963,26 @@ tputc(char *c, int len) {
                                        term.esc = 0;
                                }
                        }
       -        } else {
       -                if(sel.bx != -1 && BETWEEN(term.c.y, sel.by, sel.ey))
       -                        sel.bx = -1;
       -                if(ascii >= '\020' || term.c.attr.mode & ATTR_GFX) {
       -                        if(IS_SET(MODE_WRAP) && term.c.state & CURSOR_WRAPNEXT)
       -                                tnewline(1); /* always go to first col */
       -                        tsetchar(c);
       -                        if(term.c.x+1 < term.col) {
       -                                tmoveto(term.c.x+1, term.c.y);
       -                        } else {
       -                                term.c.state |= CURSOR_WRAPNEXT;
       -                        }
       -                }
       +                /*
       +                 * All characters which forms part of a sequence are not
       +                 * printed
       +                 */
       +                return;
                }
       +        /*
       +         * Display control codes only if we are in graphic mode
       +         */
       +        if(control && !(term.c.attr.mode & ATTR_GFX))
       +                return;
       +        if(sel.bx != -1 && BETWEEN(term.c.y, sel.by, sel.ey))
       +                sel.bx = -1;
       +        if(IS_SET(MODE_WRAP) && term.c.state & CURSOR_WRAPNEXT)
       +                tnewline(1); /* always go to first col */
       +        tsetchar(c);
       +        if(term.c.x+1 < term.col)
       +                tmoveto(term.c.x+1, term.c.y);
       +        else
       +                term.c.state |= CURSOR_WRAPNEXT;
        }
        
        int