tEnable blinking in st. - st - [fork] customized build of st, the simple termin… | |
git clone git://src.adamsgaard.dk/st | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 1e09726518b84091e80dfaf96632c122f6f446a6 | |
parent 1b2751f5c24ca06afbb68e41e73fc9fce6c6b521 | |
Author: Christoph Lohmann <[email protected]> | |
Date: Fri, 26 Apr 2013 18:41:54 +0200 | |
Enable blinking in st. | |
Diffstat: | |
M config.def.h | 3 +++ | |
M st.c | 83 ++++++++++++++++++++++++++---… | |
M st.info | 2 +- | |
3 files changed, 74 insertions(+), 14 deletions(-) | |
--- | |
diff --git a/config.def.h b/config.def.h | |
t@@ -20,6 +20,9 @@ static bool allowaltscreen = true; | |
static unsigned int xfps = 60; | |
static unsigned int actionfps = 30; | |
+/* blinking timeout (set to 0 to disable blinking) */ | |
+static unsigned int blinktimeout = 800; | |
+ | |
/* TERM value */ | |
static char termname[] = "st-256color"; | |
diff --git a/st.c b/st.c | |
t@@ -116,6 +116,8 @@ enum term_mode { | |
MODE_APPCURSOR = 2048, | |
MODE_MOUSESGR = 4096, | |
MODE_8BIT = 8192, | |
+ MODE_BLINK = 16384, | |
+ MODE_FBLINK = 32768, | |
}; | |
enum escape_state { | |
t@@ -313,6 +315,7 @@ static void strhandle(void); | |
static void strparse(void); | |
static void strreset(void); | |
+static int tattrset(int); | |
static void tclearregion(int, int, int, int); | |
static void tcursor(int); | |
static void tdeletechar(int); | |
t@@ -334,6 +337,7 @@ static void tsetchar(char *, Glyph *, int, int); | |
static void tsetscroll(int, int); | |
static void tswapscreen(void); | |
static void tsetdirt(int, int); | |
+static void tsetdirtattr(int); | |
static void tsetmode(bool, bool, int *, int); | |
static void tfulldirt(void); | |
static void techo(char *, int); | |
t@@ -1175,6 +1179,20 @@ ttyresize(void) { | |
fprintf(stderr, "Couldn't set window size: %s\n", SERRNO); | |
} | |
+int | |
+tattrset(int attr) { | |
+ int i, j; | |
+ | |
+ for(i = 0; i < term.row-1; i++) { | |
+ for(j = 0; j < term.col-1; j++) { | |
+ if(term.line[i][j].mode & attr) | |
+ return 1; | |
+ } | |
+ } | |
+ | |
+ return 0; | |
+} | |
+ | |
void | |
tsetdirt(int top, int bot) { | |
int i; | |
t@@ -1187,6 +1205,20 @@ tsetdirt(int top, int bot) { | |
} | |
void | |
+tsetdirtattr(int attr) { | |
+ int i, j; | |
+ | |
+ for(i = 0; i < term.row-1; i++) { | |
+ for(j = 0; j < term.col-1; j++) { | |
+ if(term.line[i][j].mode & attr) { | |
+ tsetdirt(i, i); | |
+ break; | |
+ } | |
+ } | |
+ } | |
+} | |
+ | |
+void | |
tfulldirt(void) { | |
tsetdirt(0, term.row-1); | |
} | |
t@@ -2838,6 +2870,9 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, i… | |
bg = temp; | |
} | |
+ if(base.mode & ATTR_BLINK && term.mode & MODE_BLINK) | |
+ fg = bg; | |
+ | |
/* Intelligent cleaning up of the borders. */ | |
if(x == 0) { | |
xclear(0, (y == 0)? 0 : winy, borderpx, | |
t@@ -3345,34 +3380,55 @@ void | |
run(void) { | |
XEvent ev; | |
fd_set rfd; | |
- int xfd = XConnectionNumber(xw.dpy), xev; | |
- struct timeval drawtimeout, *tv = NULL, now, last; | |
+ int xfd = XConnectionNumber(xw.dpy), xev, blinkset = 0, dodraw = 0; | |
+ struct timeval drawtimeout, *tv = NULL, now, last, lastblink; | |
+ gettimeofday(&lastblink, NULL); | |
gettimeofday(&last, NULL); | |
for(xev = actionfps;;) { | |
FD_ZERO(&rfd); | |
FD_SET(cmdfd, &rfd); | |
FD_SET(xfd, &rfd); | |
- if(select(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, tv) < 0) { | |
+ | |
+ switch(select(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, tv) < 0) { | |
+ case -1: | |
if(errno == EINTR) | |
continue; | |
die("select failed: %s\n", SERRNO); | |
- } | |
+ default: | |
+ if(FD_ISSET(cmdfd, &rfd)) { | |
+ ttyread(); | |
+ if(blinktimeout) { | |
+ blinkset = tattrset(ATTR_BLINK); | |
+ if(!blinkset && term.mode & ATTR_BLINK) | |
+ term.mode &= ~(MODE_BLINK); | |
+ } | |
+ } | |
+ if(FD_ISSET(xfd, &rfd)) | |
+ xev = actionfps; | |
+ break; | |
+ } | |
gettimeofday(&now, NULL); | |
drawtimeout.tv_sec = 0; | |
drawtimeout.tv_usec = (1000/xfps) * 1000; | |
tv = &drawtimeout; | |
- if(FD_ISSET(cmdfd, &rfd)) | |
- ttyread(); | |
- | |
- if(FD_ISSET(xfd, &rfd)) | |
- xev = actionfps; | |
+ dodraw = 0; | |
+ if(blinktimeout && TIMEDIFF(now, lastblink) > blinktimeout) { | |
+ tsetdirtattr(ATTR_BLINK); | |
+ term.mode ^= MODE_BLINK; | |
+ gettimeofday(&lastblink, NULL); | |
+ dodraw = 1; | |
+ } | |
+ if(TIMEDIFF(now, last) \ | |
+ > (xev? (1000/xfps) : (1000/actionfps))) { | |
+ dodraw = 1; | |
+ last = now; | |
+ } | |
- if(TIMEDIFF(now, last) > \ | |
- (xev ? (1000/xfps) : (1000/actionfps))) { | |
+ if(dodraw) { | |
while(XPending(xw.dpy)) { | |
XNextEvent(xw.dpy, &ev); | |
if(XFilterEvent(&ev, None)) | |
t@@ -3383,12 +3439,13 @@ run(void) { | |
draw(); | |
XFlush(xw.dpy); | |
- last = now; | |
if(xev && !FD_ISSET(xfd, &rfd)) | |
xev--; | |
- if(!FD_ISSET(cmdfd, &rfd) && !FD_ISSET(xfd, &rfd)) | |
+ if(!FD_ISSET(cmdfd, &rfd) && !FD_ISSET(xfd, &rfd) \ | |
+ && !blinkset) { | |
tv = NULL; | |
+ } | |
} | |
} | |
} | |
diff --git a/st.info b/st.info | |
t@@ -5,7 +5,7 @@ st| simpleterm, | |
am, | |
bce, | |
bel=^G, | |
-# blink=\E[5m, | |
+ blink=\E[5m, | |
bold=\E[1m, | |
cbt=\E[Z, | |
cvvis=\E[?25h, |