optimize line_draw, reduces flicker in some terminals - sob - simple output bar
 (HTM) git clone git://git.codemadness.org/sob
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 47706e9bc61a337498f43c7053048932ce617b75
 (DIR) parent 34be376a9445ac7283268a5cdd7c07dee65e576d
 (HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
       Date:   Sun, 12 Oct 2014 22:05:12 +0000
       
       optimize line_draw, reduces flicker in some terminals
       
       Diffstat:
         M sob.c                               |      32 +++++++++++++++++++++++++++----
       
       1 file changed, 28 insertions(+), 4 deletions(-)
       ---
 (DIR) diff --git a/sob.c b/sob.c
       @@ -29,6 +29,7 @@ struct line {
                size_t utfpos;     /* pos in characters */
                size_t colpos;     /* cursor position (in columns) */
                size_t collen;     /* total length (in columns) */
       +        size_t dirtylen;   /* dirty length (in columns) */
        };
        
        static void   cb_pipe_insert(const char *, size_t);
       @@ -66,6 +67,7 @@ static int    pipe_readline(int, int, char *, void (*)(const char *, size_t));
        static int    pipe_cmd(char *[], char *, void (*)(const char *, size_t));
        
        static void   cleanup(void);
       +static void   clear(void);
        static void   gettermsize(void);
        static void   handleinput(const unsigned char *, size_t);
        static void   resize(void);
       @@ -245,11 +247,22 @@ line_prompt(void)
        static void
        line_draw(void)
        {
       -        fprintf(outfp, "\x1b[2J\x1b[H"); /* clear */
       -        fflush(outfp);
       +        size_t i;
       +
       +        fprintf(outfp, "\x1b[H"); /* move cursor to (0, 0) */
       +        fprintf(outfp, "\x1b[?25l"); /* hide cursor */
       +
                line_prompt();
                fwrite(line.line, 1, line.bytesiz, outfp);
       +
       +        /* replace dirty chars with ' ' */
       +        if(line.dirtylen > line.collen) {
       +                for(i = line.collen; i < line.dirtylen; i++)
       +                        fputc(' ', outfp);
       +        }
                line_cursor_move(line.colpos);
       +        fprintf(outfp, "\x1b[?25h"); /* show cursor */
       +        fflush(outfp);
        }
        
        static void
       @@ -394,7 +407,6 @@ line_delcharprev(void)
                line.utfpos--;
                line.colpos -= col;
                line.collen -= col;
       -
                line_draw();
        }
        
       @@ -691,6 +703,7 @@ sighandler(int signum)
                        isrunning = 0;
                        cleanup();
                } else if(signum == SIGWINCH) {
       +                clear();
                        gettermsize();
                        resize();
                        line_draw();
       @@ -710,10 +723,12 @@ setup(void)
        
                /* set the terminal attributes */
                tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
       -
                /* get terminal window size */
                gettermsize();
        
       +        /* clear screen */
       +        clear();
       +
                /* signal handling */
                memset(&sa, 0, sizeof(sa));
                sa.sa_flags = SA_RESTART;
       @@ -754,6 +769,7 @@ handleinput(const unsigned char *input, size_t len)
                int ismatch = 0;
                char buf[BUFSIZ];
        
       +        line.dirtylen = line.collen;
                while(p < len && input[p] != '\0') {
                        if(input[p] <= 0x1b) {
                                ismatch = 0;
       @@ -838,6 +854,14 @@ usage(void)
                exit(EXIT_FAILURE);
        }
        
       +static void
       +clear(void)
       +{
       +        /* clear screen, move cursor to (0, 0) */
       +        fprintf(outfp, "\x1b[2J\x1b[H");
       +        fflush(outfp);
       +}
       +
        int
        main(int argc, char **argv)
        {