Adding a more efficient drawing code. - 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 95033753be32e93915ddce14ea41b8765b665771
 (DIR) parent b7261c84aa3af984d5a7e5f5239c4173255a215d
 (HTM) Author: Christoph Lohmann <20h@r-36.net>
       Date:   Fri, 15 Feb 2013 19:10:22 +0100
       
       Adding a more efficient drawing code.
       
       Thanks Mihail Zenkov <mihail.zenkov@gmail.com> for giving the hint!
       
       Diffstat:
         M config.def.h                        |       5 ++++-
         M st.c                                |      65 ++++++++++++++++++-------------
       
       2 files changed, 42 insertions(+), 28 deletions(-)
       ---
 (DIR) diff --git a/config.def.h b/config.def.h
       @@ -9,10 +9,13 @@ static char font[] = "Liberation Mono:pixelsize=12:antialias=false:autohint=fals
        static int borderpx = 2;
        static char shell[] = "/bin/sh";
        
       -/* double-click timeout (in milliseconds) between clicks for selection */
       +/* timeouts (in milliseconds) */
        static unsigned int doubleclicktimeout = 300;
        static unsigned int tripleclicktimeout = 600;
        
       +/* frames per second st should at maximum draw to the screen */
       +static unsigned int framespersecond = 60;
       +
        /* TERM value */
        static char termname[] = "st-256color";
        
 (DIR) diff --git a/st.c b/st.c
       @@ -3166,10 +3166,12 @@ void
        run(void) {
                XEvent ev;
                fd_set rfd;
       -        int xfd = XConnectionNumber(xw.dpy), i;
       -        struct timeval drawtimeout, *tv = NULL;
       +        int xfd = XConnectionNumber(xw.dpy);
       +        struct timeval drawtimeout, *tv = NULL, now, last;
        
       -        for(i = 0;; i++) {
       +        gettimeofday(&last, NULL);
       +
       +        for(;;) {
                        FD_ZERO(&rfd);
                        FD_SET(cmdfd, &rfd);
                        FD_SET(xfd, &rfd);
       @@ -3179,35 +3181,44 @@ run(void) {
                                die("select failed: %s\n", SERRNO);
                        }
        
       -                /*
       -                 * Stop after a certain number of reads so the user does not
       -                 * feel like the system is stuttering.
       -                 */
       -                if(i < 1000 && FD_ISSET(cmdfd, &rfd)) {
       -                        ttyread();
       +                gettimeofday(&now, NULL);
       +                /* usecs until (next) frame */
       +                drawtimeout.tv_sec = 0;
       +                drawtimeout.tv_usec = \
       +                        ((1000/framespersecond) - TIMEDIFF(now, last)) * 1000;
        
       -                        /*
       -                         * Just wait a bit so it isn't disturbing the
       -                         * user and the system is able to write something.
       -                         */
       -                        drawtimeout.tv_sec = 0;
       -                        drawtimeout.tv_usec = 5;
       -                        tv = &drawtimeout;
       -                        continue;
       +                /* Let us draw a frame. */
       +                if(drawtimeout.tv_usec <= 0) {
       +                        draw();
       +                        XFlush(xw.dpy);
       +
       +                        last = now;
       +                        tv = NULL;
                        }
       -                i = 0;
       -                tv = NULL;
        
       -                while(XPending(xw.dpy)) {
       -                        XNextEvent(xw.dpy, &ev);
       -                        if(XFilterEvent(&ev, None))
       -                                continue;
       -                        if(handler[ev.type])
       -                                (handler[ev.type])(&ev);
       +                if(FD_ISSET(cmdfd, &rfd))
       +                        ttyread();
       +
       +                if(FD_ISSET(xfd, &rfd)) {
       +                        while(XPending(xw.dpy)) {
       +                                XNextEvent(xw.dpy, &ev);
       +                                if(XFilterEvent(&ev, None))
       +                                        continue;
       +                                if(handler[ev.type])
       +                                        (handler[ev.type])(&ev);
       +                        }
       +
       +                        if(drawtimeout.tv_usec <= 0) {
       +                                draw();
       +                                XFlush(xw.dpy);
       +                        }
                        }
        
       -                draw();
       -                XFlush(xw.dpy);
       +                /* There is still some time to wait until next frame. */
       +                if(drawtimeout.tv_usec > 0) {
       +                        tv = &drawtimeout;
       +                        continue;
       +                }
                }
        }