From 7482a4bf5f58274f7f0c032b91c18c673375b277 Mon Sep 17 00:00:00 2001 From: Anders Eurenius Date: Sun, 22 Jun 2014 16:02:06 +0200 Subject: [PATCH 6/6] Refactor mainloop, add fast blink support --- st.c | 136 ++++++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 86 insertions(+), 50 deletions(-) diff --git a/st.c b/st.c index 1621352..f256528 100644 --- a/st.c +++ b/st.c @@ -3244,6 +3244,9 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { if(base.mode & ATTR_BLINK && term.mode & MODE_BLINK) fg = bg; + if(base.mode & ATTR_FASTBLINK && term.mode & MODE_FBLINK) + fg = bg; + if(base.mode & ATTR_INVISIBLE) fg = bg; @@ -3752,12 +3755,10 @@ resize(XEvent *e) { } void -run(void) { +init(void) +{ XEvent ev; int w = xw.w, h = xw.h; - fd_set rfd; - int xfd = XConnectionNumber(xw.dpy), xev, blinkset = 0, dodraw = 0; - struct timeval drawtimeout, *tv = NULL, now, last, lastblink; /* Waiting for window mapping */ while(1) { @@ -3772,32 +3773,75 @@ run(void) { ttynew(); cresize(w, h); +} + +const int xev_activity = 1; +const int cmd_activity = 2; + +int do_select(struct timeval *tv) +{ + int xfd = XConnectionNumber(xw.dpy); + fd_set rfd; + + FD_ZERO(&rfd); + FD_SET(cmdfd, &rfd); + FD_SET(xfd, &rfd); + + while(select(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, tv) < 0) { + if(errno == EINTR) + continue; + die("select failed: %s\n", strerror(errno)); + } + + return (FD_ISSET(xfd, &rfd)? xev_activity: 0) | + (FD_ISSET(cmdfd, &rfd)? cmd_activity: 0); +} + +int +setblinks(struct timeval *now) +{ + unsigned long long int t = now->tv_sec * 1000 + now->tv_usec / 1000; + int blink, fblink, change = 0; + + blink = (t / blinktimeout) & 1; + if(!!(term.mode & MODE_BLINK) != blink) + change = 1; + + fblink = (t / (blinktimeout / 4)) & 1; + if(!!(term.mode & MODE_FBLINK) != fblink) + change = 1; + + MODBIT(term.mode, blink, MODE_BLINK); + MODBIT(term.mode, fblink, MODE_FBLINK); + + return change; +} + +void +run(void) { + XEvent ev; + int s, xev, blinkset = 0, dodraw = 0; + struct timeval drawtimeout, *tv = NULL, now, last; + + init(); gettimeofday(&last, NULL); - lastblink = last; + xev = actionfps; - for(xev = actionfps;;) { + for(;;) { long deltatime; - FD_ZERO(&rfd); - FD_SET(cmdfd, &rfd); - FD_SET(xfd, &rfd); + s = do_select(tv); - if(select(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, tv) < 0) { - if(errno == EINTR) - continue; - die("select failed: %s\n", strerror(errno)); - } - if(FD_ISSET(cmdfd, &rfd)) { + if(s & cmd_activity) { ttyread(); if(blinktimeout) { - blinkset = tattrset(ATTR_BLINK); - if(!blinkset) - MODBIT(term.mode, 0, MODE_BLINK); + blinkset = tattrset(ATTR_BLINK) | + tattrset(ATTR_FASTBLINK); } } - if(FD_ISSET(xfd, &rfd)) + if(s & xev_activity) xev = actionfps; gettimeofday(&now, NULL); @@ -3806,10 +3850,9 @@ run(void) { tv = &drawtimeout; dodraw = 0; - if(blinktimeout && TIMEDIFF(now, lastblink) > blinktimeout) { + if(blinktimeout && blinkset && setblinks(&now)) { tsetdirtattr(ATTR_BLINK); - term.mode ^= MODE_BLINK; - lastblink = now; + tsetdirtattr(ATTR_FASTBLINK); dodraw = 1; } deltatime = TIMEDIFF(now, last); @@ -3819,35 +3862,28 @@ run(void) { last = now; } - if(dodraw) { - while(XPending(xw.dpy)) { - XNextEvent(xw.dpy, &ev); - if(XFilterEvent(&ev, None)) - continue; - if(handler[ev.type]) - (handler[ev.type])(&ev); - } + if(!dodraw) + continue; - draw(); - XFlush(xw.dpy); - - if(xev && !FD_ISSET(xfd, &rfd)) - xev--; - if(!FD_ISSET(cmdfd, &rfd) && !FD_ISSET(xfd, &rfd)) { - if(blinkset) { - if(TIMEDIFF(now, lastblink) \ - > blinktimeout) { - drawtimeout.tv_usec = 1; - } else { - drawtimeout.tv_usec = (1000 * \ - (blinktimeout - \ - TIMEDIFF(now, - lastblink))); - } - } else { - tv = NULL; - } - } + while(XPending(xw.dpy)) { + XNextEvent(xw.dpy, &ev); + if(XFilterEvent(&ev, None)) + continue; + if(handler[ev.type]) + (handler[ev.type])(&ev); + } + + draw(); + XFlush(xw.dpy); + + if(xev && !(s & xev_activity)) + xev--; + if(blinkset) { + drawtimeout.tv_sec = 0; + drawtimeout.tv_usec = blinktimeout / 2; + tv = &drawtimeout; + } else { + tv = NULL; } } } -- 2.0.0