From: Matthew Mondor Date: Fri, 15 Apr 2022 05:25:06 +0000 (+0000) Subject: Add MATT/sleepycat.c and update TODO X-Git-Url: http://git.pulsar-zone.net/?a=commitdiff_plain;h=c6f56d841ef56c29320db95cf08aa71dbcdfee3c;p=xscreensaver-5.35.git Add MATT/sleepycat.c and update TODO --- diff --git a/MATT/TODO.txt b/MATT/TODO.txt index 6fa3466..eb3f8fe 100644 --- a/MATT/TODO.txt +++ b/MATT/TODO.txt @@ -14,6 +14,10 @@ TODO - May need to support sending XOFF/XON to control speed, if too fast it still jump scrolls, because the next scroll operation is requested before the smooth scrolling offset animation expires. + So far nice with a tool like: | sleepycat -s0 -l144 -w80 + Where 150 is how many ms to delay per line and 80 is the width where + sleeping also occurs despite the lack of a newline. 144 was chosen since + it's a multiple of 8, the font's height. - When the cursor is down and a command is typed then the whole screen quickly refreshed, the scroll jump is a bit strange, similarly to a vertically desynched TV. Unsure if some control flow somewhere or timer @@ -27,6 +31,10 @@ TODO works when it's configured to put its status bar at the top rather than at the bottom, but a strange refresh artefact at the top happens. tmux(1) just redisplays its bar after scrolling. + - Smooth scrolling within a scroll region where the bottom is not the end of + the terminal would work, considering that the rendering is actually drawn + per scanline. The cursor drawing code would also need to take this into + account. - Various latin characters look strange and could be improved. - Links appears to enter DEC Special Graphics for some reason and to not exit it. This does not happen under tmux(1). diff --git a/MATT/sleepycat.c b/MATT/sleepycat.c new file mode 100644 index 0000000..d140f82 --- /dev/null +++ b/MATT/sleepycat.c @@ -0,0 +1,120 @@ +/* + * A slowed down cat for ascii animation. Also useful for rate-limiting + * a transfer over a narrow channel, e.g., sending data over a dialup + * link so as to not overly interfere with interactive use. + * + * bsy@cs.cmu.edu + * + * Adapted by Matthew Mondor in 2022 to support line/width based timer, for + * use with AnalogTerm's smooth scrolling. The original source was found + * here: + * https://github.com/bennetyee/TekGraphics + * To compile, use: + * $ cc -o sleepycat sleepycat.c + * Example usage for AnalogTerm: + * $ tail -F | sleepycat -s0 -l144 -w80 + */ +#include +#include +#include + +static void usage(void) { + fprintf(stderr,"Usage: sleepycat [-c skip] [-s ms] [-l ms] [-w width] [files]...\n"); +} + +static void sleepycat(FILE *fp, long c, long s, long ls, long w) { + int ch; + long i, wi, left; + + i = 0; + wi = 0; + s *= 1000; + if (s < 0 || s > 1000000) { + fprintf(stderr, "sleepycat: truncating character timer\n"); + s = 1000000; + } + ls *= 1000; + if (ls < 0) { + fprintf(stderr, "sleepycat: truncating line timer\n"); + ls = 1000000; + } + while ((ch = getc(fp)) != EOF) { + int s_p = 0; + + if (ls != 0) { + if (ch == '\n') { + wi = 0; + s_p = 1; + } + if (w != 0 && wi == w) { + wi = 0; + s_p = 1; + } + } + if (s_p) { + fflush(stdout); + for (left = ls; left > 0; ) { + long t; + + t = left; + if (t >= 1000000) t = 999999; + usleep(t); + left -= t; + } + } + putchar(ch); + if (w != 0) + wi++; + if (++i == c) { + fflush(stdout); + if (s != 0) + usleep(s); + i = 0; + } + } +} + +int main(int ac, char **av) { + long snooze, lsnooze, count, width; + int ch; + extern char *optarg; + extern int optind, getopt(); + FILE *fp, *fopen(); + + count = 1; + snooze = 1; + lsnooze = 0; + width = 0; + while ((ch = getopt(ac,av,"c:s:l:w:")) != EOF) switch (ch) { + case 'c': count = atol(optarg); break; + case 's': snooze = atol(optarg); break; + case 'l': lsnooze = atol(optarg); break; + case 'w': width = atol(optarg); break; + default: usage(); exit(1); + } + if (count <= 0) { + fprintf(stderr,"sleepycat: bogus skip count!\n"); + count = 1; + } + if (snooze < 0 || lsnooze < 0) { + fprintf(stderr,"sleepycat: bogus timer!\n"); + snooze = 1; + lsnooze = 0; + } + if (width < 0) { + fprintf(stderr,"sleepycat: bogus width!\n"); + width = 0; + } + if (optind == ac) sleepycat(stdin,count,snooze,lsnooze,width); + else for (; optind < ac; optind++) { + if ((fp = fopen(av[optind],"r"))) { + sleepycat(fp,count,snooze,lsnooze,width); + (void) fclose(fp); + } else { + perror("sleepycat"); + fprintf(stderr,"sleepycat: can not open %s\n",av[optind]); + } + } + + exit(EXIT_SUCCESS); +}