- 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
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.
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;
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;
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
extern bool cfg_cursorblink;
-/* Very visible cursor */
+/*
+ * Text blinking
+ */
+
+#define TEXT_BLINK true
+extern bool cfg_textblink;
+
+/*
+ * Very visible cursor
+ */
#define CURSOR_BRIGHT false
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;
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;
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)
{
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;
}
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;
}
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))
if (!p)
p = olevel;
else
- p = (!draw_blink_state ? 0 : olevel);
+ p = (!draw_text_blink_state ? 0 : olevel);
} else
p = ((p ^ rev) ? level : 0);
/* 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;
" [-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"
" -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"
" -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"
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;
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()");
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':
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;
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;
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;
? 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) {
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;
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;