Skip to content

Commit

Permalink
Separate "very visible" flag from blinking flag, it should not affect
Browse files Browse the repository at this point in the history
DECSCUSR. GitHub issue 2891.
  • Loading branch information
nicm committed Oct 5, 2021
1 parent 3d5a02b commit 9b1fdb2
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 96 deletions.
8 changes: 4 additions & 4 deletions input.c
Original file line number Diff line number Diff line change
Expand Up @@ -1646,7 +1646,7 @@ input_csi_dispatch_rm(struct input_ctx *ictx)
screen_write_mode_clear(sctx, MODE_INSERT);
break;
case 34:
screen_write_mode_set(sctx, MODE_BLINKING);
screen_write_mode_set(sctx, MODE_CURSOR_VERY_VISIBLE);
break;
default:
log_debug("%s: unknown '%c'", __func__, ictx->ch);
Expand Down Expand Up @@ -1682,7 +1682,7 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx)
screen_write_mode_clear(sctx, MODE_WRAP);
break;
case 12:
screen_write_mode_clear(sctx, MODE_BLINKING);
screen_write_mode_clear(sctx, MODE_CURSOR_BLINKING);
break;
case 25: /* TCEM */
screen_write_mode_clear(sctx, MODE_CURSOR);
Expand Down Expand Up @@ -1734,7 +1734,7 @@ input_csi_dispatch_sm(struct input_ctx *ictx)
screen_write_mode_set(sctx, MODE_INSERT);
break;
case 34:
screen_write_mode_clear(sctx, MODE_BLINKING);
screen_write_mode_clear(sctx, MODE_CURSOR_VERY_VISIBLE);
break;
default:
log_debug("%s: unknown '%c'", __func__, ictx->ch);
Expand Down Expand Up @@ -1771,7 +1771,7 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
screen_write_mode_set(sctx, MODE_WRAP);
break;
case 12:
screen_write_mode_set(sctx, MODE_BLINKING);
screen_write_mode_set(sctx, MODE_CURSOR_BLINKING);
break;
case 25: /* TCEM */
screen_write_mode_set(sctx, MODE_CURSOR);
Expand Down
18 changes: 10 additions & 8 deletions screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,27 +163,27 @@ screen_set_cursor_style(struct screen *s, u_int style)
break;
case 1:
s->cstyle = SCREEN_CURSOR_BLOCK;
s->mode |= MODE_BLINKING;
s->mode |= MODE_CURSOR_BLINKING;
break;
case 2:
s->cstyle = SCREEN_CURSOR_BLOCK;
s->mode &= ~MODE_BLINKING;
s->mode &= ~MODE_CURSOR_BLINKING;
break;
case 3:
s->cstyle = SCREEN_CURSOR_UNDERLINE;
s->mode |= MODE_BLINKING;
s->mode |= MODE_CURSOR_BLINKING;
break;
case 4:
s->cstyle = SCREEN_CURSOR_UNDERLINE;
s->mode &= ~MODE_BLINKING;
s->mode &= ~MODE_CURSOR_BLINKING;
break;
case 5:
s->cstyle = SCREEN_CURSOR_BAR;
s->mode |= MODE_BLINKING;
s->mode |= MODE_CURSOR_BLINKING;
break;
case 6:
s->cstyle = SCREEN_CURSOR_BAR;
s->mode &= ~MODE_BLINKING;
s->mode &= ~MODE_CURSOR_BLINKING;
break;
}
}
Expand Down Expand Up @@ -680,8 +680,10 @@ screen_mode_to_string(int mode)
strlcat(tmp, "MOUSE_STANDARD,", sizeof tmp);
if (mode & MODE_MOUSE_BUTTON)
strlcat(tmp, "MOUSE_BUTTON,", sizeof tmp);
if (mode & MODE_BLINKING)
strlcat(tmp, "BLINKING,", sizeof tmp);
if (mode & MODE_CURSOR_BLINKING)
strlcat(tmp, "CURSOR_BLINKING,", sizeof tmp);
if (mode & MODE_CURSOR_VERY_VISIBLE)
strlcat(tmp, "CURSOR_VERY_VISIBLE,", sizeof tmp);
if (mode & MODE_MOUSE_UTF8)
strlcat(tmp, "UTF8,", sizeof tmp);
if (mode & MODE_MOUSE_SGR)
Expand Down
4 changes: 3 additions & 1 deletion tmux.h
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ enum tty_code_code {
#define MODE_WRAP 0x10
#define MODE_MOUSE_STANDARD 0x20
#define MODE_MOUSE_BUTTON 0x40
#define MODE_BLINKING 0x80
#define MODE_CURSOR_BLINKING 0x80
#define MODE_MOUSE_UTF8 0x100
#define MODE_MOUSE_SGR 0x200
#define MODE_BRACKETPASTE 0x400
Expand All @@ -529,10 +529,12 @@ enum tty_code_code {
#define MODE_ORIGIN 0x2000
#define MODE_CRLF 0x4000
#define MODE_KEXTENDED 0x8000
#define MODE_CURSOR_VERY_VISIBLE 0x10000

#define ALL_MODES 0xffffff
#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
#define MOTION_MOUSE_MODES (MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
#define CURSOR_MODES (MODE_CURSOR|MODE_CURSOR_BLINKING|MODE_CURSOR_VERY_VISIBLE)

/* A single UTF-8 character. */
typedef u_int utf8_char;
Expand Down
159 changes: 76 additions & 83 deletions tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ tty_start_tty(struct tty *tty)
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 0;
if (tcsetattr(c->fd, TCSANOW, &tio) == 0)
tcflush(c->fd, TCIOFLUSH);
tcflush(c->fd, TCOFLUSH);

tty_putcode(tty, TTYC_SMCUP);

Expand Down Expand Up @@ -658,12 +658,83 @@ tty_force_cursor_colour(struct tty *tty, const char *ccolour)
tty->ccolour = xstrdup(ccolour);
}

static void
tty_update_cursor(struct tty *tty, int mode, int changed, struct screen *s)
{
enum screen_cursor_style cstyle;

/* Set cursor colour if changed. */
if (s != NULL && strcmp(s->ccolour, tty->ccolour) != 0)
tty_force_cursor_colour(tty, s->ccolour);

/* If cursor is off, set as invisible. */
if (~mode & MODE_CURSOR) {
if (changed & MODE_CURSOR)
tty_putcode(tty, TTYC_CIVIS);
return;
}

/* Check if blinking or very visible flag changed or style changed. */
if (s == NULL)
cstyle = tty->cstyle;
else
cstyle = s->cstyle;
if ((changed & CURSOR_MODES) == 0 && cstyle == tty->cstyle)
return;

/*
* Set cursor style. If an explicit style has been set with DECSCUSR,
* set it if supported, otherwise send cvvis for blinking styles.
*
* If no style, has been set (SCREEN_CURSOR_DEFAULT), then send cvvis
* if either the blinking or very visible flags are set.
*/
tty_putcode(tty, TTYC_CNORM);
switch (cstyle) {
case SCREEN_CURSOR_DEFAULT:
if (tty_term_has(tty->term, TTYC_SE))
tty_putcode(tty, TTYC_SE);
else
tty_putcode1(tty, TTYC_SS, 0);
if (mode & (MODE_CURSOR_BLINKING|MODE_CURSOR_VERY_VISIBLE))
tty_putcode(tty, TTYC_CVVIS);
break;
case SCREEN_CURSOR_BLOCK:
if (tty_term_has(tty->term, TTYC_SS)) {
if (mode & MODE_CURSOR_BLINKING)
tty_putcode1(tty, TTYC_SS, 1);
else
tty_putcode1(tty, TTYC_SS, 2);
} else if (mode & MODE_CURSOR_BLINKING)
tty_putcode(tty, TTYC_CVVIS);
break;
case SCREEN_CURSOR_UNDERLINE:
if (tty_term_has(tty->term, TTYC_SS)) {
if (mode & MODE_CURSOR_BLINKING)
tty_putcode1(tty, TTYC_SS, 3);
else
tty_putcode1(tty, TTYC_SS, 4);
} else if (mode & MODE_CURSOR_BLINKING)
tty_putcode(tty, TTYC_CVVIS);
break;
case SCREEN_CURSOR_BAR:
if (tty_term_has(tty->term, TTYC_SS)) {
if (mode & MODE_CURSOR_BLINKING)
tty_putcode1(tty, TTYC_SS, 5);
else
tty_putcode1(tty, TTYC_SS, 6);
} else if (mode & MODE_CURSOR_BLINKING)
tty_putcode(tty, TTYC_CVVIS);
break;
}
tty->cstyle = cstyle;
}

void
tty_update_mode(struct tty *tty, int mode, struct screen *s)
{
struct client *c = tty->client;
int changed;
enum screen_cursor_style cstyle = tty->cstyle;
struct client *c = tty->client;
int changed;

if (tty->flags & TTY_NOCURSOR)
mode &= ~MODE_CURSOR;
Expand All @@ -676,85 +747,7 @@ tty_update_mode(struct tty *tty, int mode, struct screen *s)
screen_mode_to_string(mode));
}

if (s != NULL) {
if (strcmp(s->ccolour, tty->ccolour) != 0)
tty_force_cursor_colour(tty, s->ccolour);
cstyle = s->cstyle;
}
if (~mode & MODE_CURSOR) {
/* Cursor now off - set as invisible. */
if (changed & MODE_CURSOR)
tty_putcode(tty, TTYC_CIVIS);
} else if ((changed & (MODE_CURSOR|MODE_BLINKING)) ||
cstyle != tty->cstyle) {
/*
* Cursor now on, blinking flag changed or style changed. Start
* by setting the cursor to normal.
*/
tty_putcode(tty, TTYC_CNORM);
switch (cstyle) {
case SCREEN_CURSOR_DEFAULT:
/*
* If the old style wasn't default, then reset it to
* default.
*/
if (tty->cstyle != SCREEN_CURSOR_DEFAULT) {
if (tty_term_has(tty->term, TTYC_SE))
tty_putcode(tty, TTYC_SE);
else
tty_putcode1(tty, TTYC_SS, 0);
}

/* Set the cursor as very visible if necessary. */
if (mode & MODE_BLINKING)
tty_putcode(tty, TTYC_CVVIS);
break;
case SCREEN_CURSOR_BLOCK:
/*
* Set style to either block blinking (1) or steady (2)
* if supported, otherwise just check the blinking
* flag.
*/
if (tty_term_has(tty->term, TTYC_SS)) {
if (mode & MODE_BLINKING)
tty_putcode1(tty, TTYC_SS, 1);
else
tty_putcode1(tty, TTYC_SS, 2);
} else if (mode & MODE_BLINKING)
tty_putcode(tty, TTYC_CVVIS);
break;
case SCREEN_CURSOR_UNDERLINE:
/*
* Set style to either underline blinking (3) or steady
* (4) if supported, otherwise just check the blinking
* flag.
*/
if (tty_term_has(tty->term, TTYC_SS)) {
if (mode & MODE_BLINKING)
tty_putcode1(tty, TTYC_SS, 3);
else
tty_putcode1(tty, TTYC_SS, 4);
} else if (mode & MODE_BLINKING)
tty_putcode(tty, TTYC_CVVIS);
break;
case SCREEN_CURSOR_BAR:
/*
* Set style to either bar blinking (5) or steady (6)
* if supported, otherwise just check the blinking
* flag.
*/
if (tty_term_has(tty->term, TTYC_SS)) {
if (mode & MODE_BLINKING)
tty_putcode1(tty, TTYC_SS, 5);
else
tty_putcode1(tty, TTYC_SS, 6);
} else if (mode & MODE_BLINKING)
tty_putcode(tty, TTYC_CVVIS);
break;
}
tty->cstyle = cstyle;
}

tty_update_cursor(tty, mode, changed, s);
if ((changed & ALL_MOUSE_MODES) &&
tty_term_has(tty->term, TTYC_KMOUS)) {
/*
Expand Down

0 comments on commit 9b1fdb2

Please sign in to comment.