diff options
author | Christoph Lohmann <20h@r-36.net> | 2013-04-26 18:41:54 +0200 |
---|---|---|
committer | Christoph Lohmann <20h@r-36.net> | 2013-04-26 18:41:54 +0200 |
commit | 1e09726518b84091e80dfaf96632c122f6f446a6 (patch) | |
tree | a5f86e5b086d69d52babb0128cadc174b18b2eec | |
parent | 1b2751f5c24ca06afbb68e41e73fc9fce6c6b521 (diff) | |
download | st-1e09726518b84091e80dfaf96632c122f6f446a6.tar.gz st-1e09726518b84091e80dfaf96632c122f6f446a6.zip |
Enable blinking in st.
-rw-r--r-- | config.def.h | 3 | ||||
-rw-r--r-- | st.c | 83 | ||||
-rw-r--r-- | st.info | 2 |
3 files changed, 74 insertions, 14 deletions
diff --git a/config.def.h b/config.def.h index d1c20bd..b44fe17 100644 --- a/config.def.h +++ b/config.def.h | |||
@@ -20,6 +20,9 @@ static bool allowaltscreen = true; | |||
20 | static unsigned int xfps = 60; | 20 | static unsigned int xfps = 60; |
21 | static unsigned int actionfps = 30; | 21 | static unsigned int actionfps = 30; |
22 | 22 | ||
23 | /* blinking timeout (set to 0 to disable blinking) */ | ||
24 | static unsigned int blinktimeout = 800; | ||
25 | |||
23 | /* TERM value */ | 26 | /* TERM value */ |
24 | static char termname[] = "st-256color"; | 27 | static char termname[] = "st-256color"; |
25 | 28 | ||
@@ -116,6 +116,8 @@ enum term_mode { | |||
116 | MODE_APPCURSOR = 2048, | 116 | MODE_APPCURSOR = 2048, |
117 | MODE_MOUSESGR = 4096, | 117 | MODE_MOUSESGR = 4096, |
118 | MODE_8BIT = 8192, | 118 | MODE_8BIT = 8192, |
119 | MODE_BLINK = 16384, | ||
120 | MODE_FBLINK = 32768, | ||
119 | }; | 121 | }; |
120 | 122 | ||
121 | enum escape_state { | 123 | enum escape_state { |
@@ -313,6 +315,7 @@ static void strhandle(void); | |||
313 | static void strparse(void); | 315 | static void strparse(void); |
314 | static void strreset(void); | 316 | static void strreset(void); |
315 | 317 | ||
318 | static int tattrset(int); | ||
316 | static void tclearregion(int, int, int, int); | 319 | static void tclearregion(int, int, int, int); |
317 | static void tcursor(int); | 320 | static void tcursor(int); |
318 | static void tdeletechar(int); | 321 | static void tdeletechar(int); |
@@ -334,6 +337,7 @@ static void tsetchar(char *, Glyph *, int, int); | |||
334 | static void tsetscroll(int, int); | 337 | static void tsetscroll(int, int); |
335 | static void tswapscreen(void); | 338 | static void tswapscreen(void); |
336 | static void tsetdirt(int, int); | 339 | static void tsetdirt(int, int); |
340 | static void tsetdirtattr(int); | ||
337 | static void tsetmode(bool, bool, int *, int); | 341 | static void tsetmode(bool, bool, int *, int); |
338 | static void tfulldirt(void); | 342 | static void tfulldirt(void); |
339 | static void techo(char *, int); | 343 | static void techo(char *, int); |
@@ -1175,6 +1179,20 @@ ttyresize(void) { | |||
1175 | fprintf(stderr, "Couldn't set window size: %s\n", SERRNO); | 1179 | fprintf(stderr, "Couldn't set window size: %s\n", SERRNO); |
1176 | } | 1180 | } |
1177 | 1181 | ||
1182 | int | ||
1183 | tattrset(int attr) { | ||
1184 | int i, j; | ||
1185 | |||
1186 | for(i = 0; i < term.row-1; i++) { | ||
1187 | for(j = 0; j < term.col-1; j++) { | ||
1188 | if(term.line[i][j].mode & attr) | ||
1189 | return 1; | ||
1190 | } | ||
1191 | } | ||
1192 | |||
1193 | return 0; | ||
1194 | } | ||
1195 | |||
1178 | void | 1196 | void |
1179 | tsetdirt(int top, int bot) { | 1197 | tsetdirt(int top, int bot) { |
1180 | int i; | 1198 | int i; |
@@ -1187,6 +1205,20 @@ tsetdirt(int top, int bot) { | |||
1187 | } | 1205 | } |
1188 | 1206 | ||
1189 | void | 1207 | void |
1208 | tsetdirtattr(int attr) { | ||
1209 | int i, j; | ||
1210 | |||
1211 | for(i = 0; i < term.row-1; i++) { | ||
1212 | for(j = 0; j < term.col-1; j++) { | ||
1213 | if(term.line[i][j].mode & attr) { | ||
1214 | tsetdirt(i, i); | ||
1215 | break; | ||
1216 | } | ||
1217 | } | ||
1218 | } | ||
1219 | } | ||
1220 | |||
1221 | void | ||
1190 | tfulldirt(void) { | 1222 | tfulldirt(void) { |
1191 | tsetdirt(0, term.row-1); | 1223 | tsetdirt(0, term.row-1); |
1192 | } | 1224 | } |
@@ -2838,6 +2870,9 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { | |||
2838 | bg = temp; | 2870 | bg = temp; |
2839 | } | 2871 | } |
2840 | 2872 | ||
2873 | if(base.mode & ATTR_BLINK && term.mode & MODE_BLINK) | ||
2874 | fg = bg; | ||
2875 | |||
2841 | /* Intelligent cleaning up of the borders. */ | 2876 | /* Intelligent cleaning up of the borders. */ |
2842 | if(x == 0) { | 2877 | if(x == 0) { |
2843 | xclear(0, (y == 0)? 0 : winy, borderpx, | 2878 | xclear(0, (y == 0)? 0 : winy, borderpx, |
@@ -3345,34 +3380,55 @@ void | |||
3345 | run(void) { | 3380 | run(void) { |
3346 | XEvent ev; | 3381 | XEvent ev; |
3347 | fd_set rfd; | 3382 | fd_set rfd; |
3348 | int xfd = XConnectionNumber(xw.dpy), xev; | 3383 | int xfd = XConnectionNumber(xw.dpy), xev, blinkset = 0, dodraw = 0; |
3349 | struct timeval drawtimeout, *tv = NULL, now, last; | 3384 | struct timeval drawtimeout, *tv = NULL, now, last, lastblink; |
3350 | 3385 | ||
3386 | gettimeofday(&lastblink, NULL); | ||
3351 | gettimeofday(&last, NULL); | 3387 | gettimeofday(&last, NULL); |
3352 | 3388 | ||
3353 | for(xev = actionfps;;) { | 3389 | for(xev = actionfps;;) { |
3354 | FD_ZERO(&rfd); | 3390 | FD_ZERO(&rfd); |
3355 | FD_SET(cmdfd, &rfd); | 3391 | FD_SET(cmdfd, &rfd); |
3356 | FD_SET(xfd, &rfd); | 3392 | FD_SET(xfd, &rfd); |
3357 | if(select(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, tv) < 0) { | 3393 | |
3394 | switch(select(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, tv) < 0) { | ||
3395 | case -1: | ||
3358 | if(errno == EINTR) | 3396 | if(errno == EINTR) |
3359 | continue; | 3397 | continue; |
3360 | die("select failed: %s\n", SERRNO); | 3398 | die("select failed: %s\n", SERRNO); |
3361 | } | 3399 | default: |
3400 | if(FD_ISSET(cmdfd, &rfd)) { | ||
3401 | ttyread(); | ||
3402 | if(blinktimeout) { | ||
3403 | blinkset = tattrset(ATTR_BLINK); | ||
3404 | if(!blinkset && term.mode & ATTR_BLINK) | ||
3405 | term.mode &= ~(MODE_BLINK); | ||
3406 | } | ||
3407 | } | ||
3362 | 3408 | ||
3409 | if(FD_ISSET(xfd, &rfd)) | ||
3410 | xev = actionfps; | ||
3411 | break; | ||
3412 | } | ||
3363 | gettimeofday(&now, NULL); | 3413 | gettimeofday(&now, NULL); |
3364 | drawtimeout.tv_sec = 0; | 3414 | drawtimeout.tv_sec = 0; |
3365 | drawtimeout.tv_usec = (1000/xfps) * 1000; | 3415 | drawtimeout.tv_usec = (1000/xfps) * 1000; |
3366 | tv = &drawtimeout; | 3416 | tv = &drawtimeout; |
3367 | 3417 | ||
3368 | if(FD_ISSET(cmdfd, &rfd)) | 3418 | dodraw = 0; |
3369 | ttyread(); | 3419 | if(blinktimeout && TIMEDIFF(now, lastblink) > blinktimeout) { |
3370 | 3420 | tsetdirtattr(ATTR_BLINK); | |
3371 | if(FD_ISSET(xfd, &rfd)) | 3421 | term.mode ^= MODE_BLINK; |
3372 | xev = actionfps; | 3422 | gettimeofday(&lastblink, NULL); |
3423 | dodraw = 1; | ||
3424 | } | ||
3425 | if(TIMEDIFF(now, last) \ | ||
3426 | > (xev? (1000/xfps) : (1000/actionfps))) { | ||
3427 | dodraw = 1; | ||
3428 | last = now; | ||
3429 | } | ||
3373 | 3430 | ||
3374 | if(TIMEDIFF(now, last) > \ | 3431 | if(dodraw) { |
3375 | (xev ? (1000/xfps) : (1000/actionfps))) { | ||
3376 | while(XPending(xw.dpy)) { | 3432 | while(XPending(xw.dpy)) { |
3377 | XNextEvent(xw.dpy, &ev); | 3433 | XNextEvent(xw.dpy, &ev); |
3378 | if(XFilterEvent(&ev, None)) | 3434 | if(XFilterEvent(&ev, None)) |
@@ -3383,12 +3439,13 @@ run(void) { | |||
3383 | 3439 | ||
3384 | draw(); | 3440 | draw(); |
3385 | XFlush(xw.dpy); | 3441 | XFlush(xw.dpy); |
3386 | last = now; | ||
3387 | 3442 | ||
3388 | if(xev && !FD_ISSET(xfd, &rfd)) | 3443 | if(xev && !FD_ISSET(xfd, &rfd)) |
3389 | xev--; | 3444 | xev--; |
3390 | if(!FD_ISSET(cmdfd, &rfd) && !FD_ISSET(xfd, &rfd)) | 3445 | if(!FD_ISSET(cmdfd, &rfd) && !FD_ISSET(xfd, &rfd) \ |
3446 | && !blinkset) { | ||
3391 | tv = NULL; | 3447 | tv = NULL; |
3448 | } | ||
3392 | } | 3449 | } |
3393 | } | 3450 | } |
3394 | } | 3451 | } |
@@ -5,7 +5,7 @@ st| simpleterm, | |||
5 | am, | 5 | am, |
6 | bce, | 6 | bce, |
7 | bel=^G, | 7 | bel=^G, |
8 | # blink=\E[5m, | 8 | blink=\E[5m, |
9 | bold=\E[1m, | 9 | bold=\E[1m, |
10 | cbt=\E[Z, | 10 | cbt=\E[Z, |
11 | cvvis=\E[?25h, | 11 | cvvis=\E[?25h, |