diff options
| -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, |
