Add MATT/sleepycat.c and update TODO
authorMatthew Mondor <mmondor@pulsar-zone.net>
Fri, 15 Apr 2022 05:25:06 +0000 (05:25 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Fri, 15 Apr 2022 05:25:06 +0000 (05:25 +0000)
MATT/TODO.txt
MATT/sleepycat.c [new file with mode: 0644]

index 6fa3466..eb3f8fe 100644 (file)
@@ -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 (file)
index 0000000..d140f82
--- /dev/null
@@ -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 <logfile> | sleepycat -s0 -l144 -w80
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+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);
+}