commit 1e09726518b84091e80dfaf96632c122f6f446a6
parent 1b2751f5c24ca06afbb68e41e73fc9fce6c6b521
Author: Christoph Lohmann <20h@r-36.net>
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
@@ -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
@@ -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 {
@@ -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);
@@ -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);
@@ -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;
@@ -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);
}
@@ -2838,6 +2870,9 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
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,
@@ -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))
@@ -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
@@ -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,