AnalogTerm2: Cursor and text blinking now separately configurable.
authorMatthew Mondor <mmondor@pulsar-zone.net>
Sun, 7 May 2023 17:23:48 +0000 (17:23 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Sun, 7 May 2023 17:23:48 +0000 (17:23 +0000)
mmsoftware/analogterm2/TODO.txt
mmsoftware/analogterm2/src/config.c
mmsoftware/analogterm2/src/config.h
mmsoftware/analogterm2/src/draw.c
mmsoftware/analogterm2/src/draw.h
mmsoftware/analogterm2/src/main.c
mmsoftware/analogterm2/src/state.c
mmsoftware/analogterm2/src/state.h

index 3756ec9..c3819b8 100644 (file)
@@ -1,9 +1,6 @@
 - Many operations are the equivalent of newline or scroll if the end of the
   scrolling buffer or bottom are reached.  Unify those in a function or two as
   possible.
-- Maybe provide the option to have text blinking settings independent from
-  cursor blinking ones.  Text blinking usually doesn't need to be asymmetric
-  and it may be too slow when used with rarely blinking cursors.
 - xterm and urxvt appear to set the tty(4) termios ospeed/ispeed so that
   baudrate be displayed as 38400 by stty(1).  Verify what they do, if it
   serves a purpose and if they observe any delay for NUL character padding at
@@ -32,7 +29,7 @@
   https://en.wikipedia.org/wiki/Box-drawing_character
 - Overwrite/clear selections before freeing them
 - ≣ † ☆ ツ ⌘›🍺∴ ( ͡° ͜ʖ ͡°)   ƒ   ︵  ₂   😈  θ  ƒ  ›  ʼ  ƒ ∂  ʻ  μ  ›  ∫   ◇ ♪
-  ► ə β ə ſ ρ ə ∴ ♪ 😱 † 😳 › ▛ ᵗ * ‽ ℣ Ω 
+  ► ə β ə ſ ρ ə ∴ ♪ 😱 † 😳 › ▛ ᵗ * ‽ ℣ Ω  ⌘
 - Verify if dead key support is incomplete for ISO-8859-4 and ISO-8859-10.
   There were special characters that were unicode since the start but also
   could have punctuation.  And others that used two at a time...  It might
   as a terminal rather than for a shell...
 - Some unicode characters are double-width.  This is not currently supported.
 - Combining unicode characters are not supported.
+- iterm2 has a feature where command-/ highlights the cursor location.
index 6120875..a1747c9 100644 (file)
@@ -53,10 +53,11 @@ static const struct eparam_s eparams[] = {
 
 int    cfg_color, cfg_monocolor;
 bool   cfg_mono;
-int    cfg_refreshspeed, cfg_blinkspeedon, cfg_blinkspeedoff, cfg_cursormode,
+int    cfg_refreshspeed, cfg_cursorblinkspeedon, cfg_cursorblinkspeedoff,
+       cfg_textblinkspeedon, cfg_textblinkspeedoff, cfg_cursormode,
        cfg_flashtime;
 bool   cfg_cursorblink, cfg_cursordisable, cfg_cursorbright,
-       cfg_cursorprintreset;
+       cfg_cursorprintreset, cfg_textblink;
 int    cfg_intmin, cfg_intstep, cfg_intfg, cfg_intscan, cfg_intbg;
 double cfg_intfgf, cfg_intscanf, cfg_intbgf;
 int    cfg_text_width, cfg_text_height;
@@ -82,14 +83,17 @@ cfg_setdefaults(void)
        cfg_monocolor = DEFAULT_MONOCOLOR;
        cfg_mono = MONOCHROME;
        cfg_refreshspeed = REFRESH_SPEED;
-       cfg_blinkspeedon = BLINK_SPEED_ON;
-       cfg_blinkspeedoff = BLINK_SPEED_OFF;
+       cfg_cursorblinkspeedon = CURSOR_BLINK_SPEED_ON;
+       cfg_cursorblinkspeedoff = CURSOR_BLINK_SPEED_OFF;
        cfg_cursormode = CURSOR_MODE;
        cfg_flashtime = FLASH_TIME;
        cfg_cursorblink = CURSOR_BLINK;
        cfg_cursorbright = CURSOR_BRIGHT;
        cfg_cursordisable = CURSOR_DISABLE;
        cfg_cursorprintreset = CURSOR_PRINTRESET;
+       cfg_textblink = TEXT_BLINK;
+       cfg_textblinkspeedon = TEXT_BLINK_SPEED_ON;
+       cfg_textblinkspeedoff = TEXT_BLINK_SPEED_OFF;
 
        cfg_intmin = INTENSITY_MIN;
        cfg_intstep = INTENSITY_STEP;
index 9504d6f..4f239d0 100644 (file)
@@ -78,17 +78,26 @@ extern bool cfg_mono;
 extern int cfg_refreshspeed;
 
 /*
- * The interval timer used to toggle text and cursor blinking, in number of
+ * The interval timer used to toggle cursor blinking, in number of
  * REFRESH_SPEED ticks.  ON and OFF are designed to be able to optionally be
  * asymmetric.
  */
-#define BLINK_SPEED_ON         40
-#define BLINK_SPEED_OFF                10
+#define CURSOR_BLINK_SPEED_ON          40
+#define CURSOR_BLINK_SPEED_OFF         10
 
-extern int cfg_blinkspeedon, cfg_blinkspeedoff;
+extern int cfg_cursorblinkspeedon, cfg_cursorblinkspeedoff;
+
+/*
+ * The interval timer used to toggle text blinking, in number of
+ * REFRESH_SPEED ticks.  ON and OFF are designed to be able to optionally be
+ * asymmetric.
+ */
+#define TEXT_BLINK_SPEED_ON            15
+#define TEXT_BLINK_SPEED_OFF           15
+
+extern int cfg_textblinkspeedon, cfg_textblinkspeedoff;
 
 /*
- *
  * Default cursor mode (0 = block, 1 = line, 2 = bar).
  */
 #define CURSOR_MODE            0
@@ -104,7 +113,16 @@ extern int cfg_cursormode;
 
 extern bool cfg_cursorblink;
 
-/* Very visible cursor */
+/*
+ * Text blinking
+ */
+
+#define TEXT_BLINK             true
+extern bool cfg_textblink;
+
+/*
+ * Very visible cursor
+ */
 
 #define CURSOR_BRIGHT          false
 
index 233fcfe..c714ce7 100644 (file)
@@ -103,11 +103,12 @@ static void               **row_glyphs = NULL;
 static uint32_t                *row_modes = NULL;
 static bool            *row_selected = NULL;
 static int             scanjmp = 0;
-static int             blink_ticks = 0;
+static int             cursor_blink_ticks = 0, text_blink_ticks = 0;
 static uint8_t         empty[FONT_WIDTH];
 
 /* Exported as a general utility */
-bool                   draw_blink_state = true;
+bool                   draw_cursor_blink_state = true,
+                       draw_text_blink_state = true;
 bool                   refresh_expired = false;
 int                    jump_scroll_lines = 0;
 
@@ -131,7 +132,7 @@ draw_init(state_t *st, screen_t *sc)
        color = cfg_color;
        lum = color_lum[color];
        intensity = cfg_intmin;
-       blink_ticks = 0;
+       cursor_blink_ticks = text_blink_ticks = 0;
        refresh_expired = false;
        jump_scroll_lines = 0;
 
@@ -186,7 +187,10 @@ draw_cleanup(void)
                free(row_glyphs);
 }
 
-/* Used to toggle the draw_blink_state exported boolean variable */
+/*
+ * General timer, used to refresh the display, toggle the exported
+ * draw_*_blink_state, decrease tick timers, etc.
+ */
 static void
 alarm_sighandler(int sig)
 {
@@ -204,23 +208,33 @@ alarm_sighandler(int sig)
                        draw_blink_reset();
        }
 
-       /* Modulate the blinking state */
-       blinkspeed = (draw_blink_state ?
+       /* Modulate the cursor blinking state */
+       blinkspeed = (draw_cursor_blink_state ?
            state->cursor_speed[state->cursor_mode][1] :
            state->cursor_speed[state->cursor_mode][0]);
-       if (++blink_ticks == blinkspeed) {
-               blink_ticks = 0;
-               draw_blink_state = !draw_blink_state;
+       if (++cursor_blink_ticks == blinkspeed) {
+               cursor_blink_ticks = 0;
+               draw_cursor_blink_state = !draw_cursor_blink_state;
+               state->blink_update = true;
+       }
+       /* And the text blinking state */
+       blinkspeed = (draw_text_blink_state ?
+           state->text_blink_speed_off : state->text_blink_speed_on);
+       if (++text_blink_ticks == blinkspeed) {
+               text_blink_ticks = 0;
+               draw_text_blink_state = !draw_text_blink_state;
                state->blink_update = true;
        }
+       if (!state->text_blink)
+               draw_text_blink_state = false;
 }
 
 void
 draw_blink_reset(void)
 {
 
-       draw_blink_state = true;
-       blink_ticks = 0;
+       draw_cursor_blink_state = draw_text_blink_state = true;
+       cursor_blink_ticks = text_blink_ticks = 0;
        state->blink_update = true;
 }
 
@@ -428,15 +442,15 @@ draw_lines(state_t *st, screen_t *sc, int low, int high)
                        if (st->cursor_disabled_ticks == 0 &&
                            !st->cursor_disabled && st->cursor_y == row &&
                            st->cursor_x == col &&
-                           (! ((draw_blink_state && sc->focus) &&
+                           (! ((draw_cursor_blink_state && sc->focus) &&
                            cursor_waitnext == 0))) {
                                if (cursor_waitnext > 0 &&
                                    state->cursor_blink) {
                                        if (cursor_laststate !=
-                                           draw_blink_state)
+                                           draw_cursor_blink_state)
                                                cursor_waitnext--;
                                }
-                               cursor_laststate = draw_blink_state;
+                               cursor_laststate = draw_cursor_blink_state;
                                cursor_xor = col;
                        }
 
@@ -474,7 +488,7 @@ draw_lines(state_t *st, screen_t *sc, int low, int high)
        else if ((m & TMODE_DIM) != 0)
                level = INTENSITY_DIM;
        olevel = level;
-       if ((m & TMODE_BLINK) != 0 && draw_blink_state)
+       if ((m & TMODE_BLINK) != 0 && draw_text_blink_state)
                level = 0;
        if ((m & (TMODE_INVERSE | TMODE_BLINK)) ==
            (TMODE_INVERSE | TMODE_BLINK))
@@ -525,7 +539,7 @@ draw_lines(state_t *st, screen_t *sc, int low, int high)
                if (!p)
                        p = olevel;
                else
-                       p = (!draw_blink_state ? 0 : olevel);
+                       p = (!draw_text_blink_state ? 0 : olevel);
        } else
                p = ((p ^ rev) ? level : 0);
 
index c6b78ba..fcdcef3 100644 (file)
@@ -66,7 +66,8 @@ void          draw_update_screen(screen_t *, state_t *);
 
 
 /* Regularly toggled by a timer */
-extern bool    draw_blink_state, refresh_expired;
+extern bool    draw_cursor_blink_state, draw_text_blink_state,
+               refresh_expired;
 extern int     jump_scroll_lines;
 
 
index 401b7bb..f0984f7 100644 (file)
@@ -206,7 +206,8 @@ usage(void)
            "    [-s] [-C <col>] [-c] [-W] [-b] [-r <ms>]\n"
            "    [-B <ticks>[,<ticks>]] [-j <n>] [-P] [-m <mode>] [-M] [-d]\n"
            "    [-D] [-S] [-p <parameters>] [-l <pixels>] [-f <delay>]\n"
-           "    [-U] [-z <ms>] [-Z <skip>] [-e <command> [<arguments>]]\n\n"
+           "    [-t] [-T <ticks>[,<ticks>]] [-U] [-z <ms>] [-Z <skip>]\n"
+           "    [-e <command> [<arguments>]]\n\n"
            "Where:\n"
            " -1 - Activate slow and smooth scrolling at startup.\n"
            "      Also see -j for more details.\n"
@@ -228,11 +229,11 @@ usage(void)
            " -r - Set the maximum screen refresh speedin microseconds.\n"
            "      Limits: 11111 (90fps) - 100000 (10fps).  This is also a\n"
            "      general timing source that also affects the text/cursor\n"
-           "      blinking rate setting -B and the speed of smooth scroll\n"
-           "      when enabled.  Low settings save CPU but will affect\n"
-           "      interactive performance.\n"
+           "      blinking rate settings -B/-T and the speed of smooth\n"
+           "      scrolling when enabled.  Low settings save CPU but will\n"
+           "      affect interactive performance.\n"
            " -b - Toggle blinking cursor.\n"
-           " -B - Set the cursor and text blinking speed, in refresh ticks.\n"
+           " -B - Set the cursor blinking speed, in refresh ticks.\n"
            "      Two comma-separated values may optionally be provided for\n"
            "      asymmetric on/off delays.  One value sets both symmetric.\n"
            "      Can also be changed with ESC [?658467;65538;<n>[;<n>]h\n"
@@ -257,6 +258,12 @@ usage(void)
            " -S - Wait in a sleeping loop until the user closes the window\n"
            "      before exiting.  This is useful to view the output of\n"
            "      custom commands along with -e.\n"
+           " -t - Toggle blinking text.\n"
+           " -T - Set the text blinking speed, in refresh ticks.\n"
+           "      Two comma-separated values may optionally be provided for\n"
+           "      asymmetric on/off delays.  One value sets both symmetric.\n"
+           "      Can also be changed with ESC [?658467;65547;<n>[;<n>]h\n"
+           "      This depends on the refresh rate setting, -r.\n"
            " -p - Analog scanline parameters.  These are described below.\n"
            " -l - Add extra leading pixels between lines.  This will also\n"
            "      affect the vertical connectivity of graphics characters.\n"
@@ -324,7 +331,7 @@ main(int argc, char **argv, char **envp)
 
        progname = strdup(argv[0]);
        while ((ch = getopt(argc, argv,
-           "?128uw:h:E:scC:Wr:bB:j:Pm:MdDSp:l:f:Uz:Z:e:")) != -1) {
+           "?128uw:h:E:scC:Wr:bB:j:Pm:MdDStT:p:l:f:Uz:Z:e:")) != -1) {
                switch (ch) {
                case '1':
                        cfg_slowscroll = cfg_smoothscroll = true;
@@ -389,8 +396,8 @@ main(int argc, char **argv, char **envp)
                case 'B':
                        {
                                char *cols[2], *str;
-                               int son = cfg_blinkspeedon,
-                                   soff = cfg_blinkspeedoff;
+                               int son = cfg_cursorblinkspeedon,
+                                   soff = cfg_cursorblinkspeedoff;
 
                                if ((str = strdup(optarg)) == NULL)
                                        err(EXIT_FAILURE, "stddup()");
@@ -401,9 +408,9 @@ main(int argc, char **argv, char **envp)
                                        son = soff = atoi(optarg);
                                free(str);
                                if (son > 0 && son < 501)
-                                       cfg_blinkspeedon = son;
+                                       cfg_cursorblinkspeedon = son;
                                if (soff > 0 && soff < 501)
-                                       cfg_blinkspeedoff = soff;
+                                       cfg_cursorblinkspeedoff = soff;
                        }
                        break;
                case 'j':
@@ -429,6 +436,29 @@ main(int argc, char **argv, char **envp)
                case 'S':
                        cfg_sleep = true;
                        break;
+               case 't':
+                       cfg_textblink = !cfg_textblink;
+                       break;
+               case 'T':
+                       {
+                               char *cols[2], *str;
+                               int son = cfg_textblinkspeedon,
+                                   soff = cfg_textblinkspeedoff;
+
+                               if ((str = strdup(optarg)) == NULL)
+                                       err(EXIT_FAILURE, "stddup()");
+                               if (cfg_strspl(cols, str, 2, ',') == 2) {
+                                       son = atoi(cols[0]);
+                                       soff = atoi(cols[1]);
+                               } else
+                                       son = soff = atoi(optarg);
+                               free(str);
+                               if (son > 0 && son < 501)
+                                       cfg_textblinkspeedon = son;
+                               if (soff > 0 && soff < 501)
+                                       cfg_textblinkspeedoff = soff;
+                       }
+                       break;
                case 'p':
                        cfg_setparams(optarg);
                        break;
index 459b6e4..20ed012 100644 (file)
@@ -142,13 +142,16 @@ state_init(int pty)
        st->pasting = None;
        state_reset(st);
        st->pty = pty;
+       st->blink_update = false;
 
        /* Cursor */
-       st->blink_update = false;
        for (y = 0; y < CMODE_MAX; y++) {
-               st->cursor_speed[y][0] = cfg_blinkspeedon;
-               st->cursor_speed[y][1] = cfg_blinkspeedoff;
+               st->cursor_speed[y][0] = cfg_cursorblinkspeedon;
+               st->cursor_speed[y][1] = cfg_cursorblinkspeedoff;
        }
+       /* Text */
+       st->text_blink_speed_on = cfg_textblinkspeedon;
+       st->text_blink_speed_off = cfg_textblinkspeedoff;
 
        /* Emulator double state */
        estate.cursor_x = st->cursor_x;
@@ -264,6 +267,7 @@ state_reset(state_t *st)
        st->cursor_x = st->cursor_y = 0;
        st->cursor_mode = cfg_cursormode;
        st->cursor_blink = cfg_cursorblink;
+       st->text_blink = cfg_textblink;
        st->cursor_disabled = false;
        st->cursor_bright = cfg_cursorbright;
        st->quotedpaste = false;
@@ -1167,15 +1171,32 @@ state_emul_printc(state_t *st, uint8_t c)
                                                          ? state->csiparam[3]
                                                          : s1);
 
-                                               /* Blinking speed */
+                                               /* Cursor blinking speed */
                                                if (s1 > 0 && s1 < 501)
                                                        st->cursor_speed[st->cursor_mode][0]
-                                                          = s1;
+                                                           = s1;
                                                if (s2 > 0 && s2 < 501)
                                                        st->cursor_speed[st->cursor_mode][1]
-                                                          = s2;
+                                                           = s2;
                                                draw_blink_reset();
                                                state_update_cursor(st);
+                                       } else if ((state->curparam == 2 ||
+                                                   state->curparam == 3) &&
+                                                  state->csiparam[1] ==
+                                                  65547) {
+                                               int s1 = state->csiparam[2],
+                                                   s2 = (state->curparam == 3
+                                                         ? state->csiparam[3]
+                                                         : s1);
+
+                                               /* Text blinking speed */
+                                               if (s1 > 0 && s1 < 501)
+                                                       st->text_blink_speed_on
+                                                           = s1;
+                                               if (s2 > 0 && s2 < 501)
+                                                       st->text_blink_speed_off
+                                                           = s2;
+                                               draw_blink_reset();
                                        } else if (state->curparam == 3 &&
                                                   state->csiparam[1] ==
                                                   65539) {
index a2573f7..4184957 100644 (file)
@@ -78,6 +78,7 @@ struct state_s {
        bool text_updateall;
        bool blink_update;
        bool cursor_blink, cursor_disabled, cursor_bright;
+       bool text_blink;
        bool quotedpaste;
        bool reverse_video;
        int reverse_video_timer;
@@ -86,6 +87,7 @@ struct state_s {
        int saved_cursor_x, saved_cursor_y;
        int cursor_disabled_ticks;
        int cursor_speed[CMODE_MAX][2];
+       int text_blink_speed_on, text_blink_speed_off;
        uint32_t mode;
        int scroll_top, scroll_bottom;
        bool scroll_slow, scroll_smooth;