summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--screen.c32
-rw-r--r--tmux.h14
-rw-r--r--tty.c117
3 files changed, 120 insertions, 43 deletions
diff --git a/screen.c b/screen.c
index 0b1047ab..2d770abb 100644
--- a/screen.c
+++ b/screen.c
@@ -81,7 +81,7 @@ screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
s->titles = NULL;
s->path = NULL;
- s->cstyle = 0;
+ s->cstyle = SCREEN_CURSOR_DEFAULT;
s->ccolour = xstrdup("");
s->tabs = NULL;
s->sel = NULL;
@@ -156,9 +156,35 @@ screen_reset_tabs(struct screen *s)
void
screen_set_cursor_style(struct screen *s, u_int style)
{
- if (style <= 6) {
- s->cstyle = style;
+ switch (style)
+ {
+ case 0:
+ s->cstyle = SCREEN_CURSOR_DEFAULT;
+ break;
+ case 1:
+ s->cstyle = SCREEN_CURSOR_BLOCK;
+ s->mode |= MODE_BLINKING;
+ break;
+ case 2:
+ s->cstyle = SCREEN_CURSOR_BLOCK;
s->mode &= ~MODE_BLINKING;
+ break;
+ case 3:
+ s->cstyle = SCREEN_CURSOR_UNDERLINE;
+ s->mode |= MODE_BLINKING;
+ break;
+ case 4:
+ s->cstyle = SCREEN_CURSOR_UNDERLINE;
+ s->mode &= ~MODE_BLINKING;
+ break;
+ case 5:
+ s->cstyle = SCREEN_CURSOR_BAR;
+ s->mode |= MODE_BLINKING;
+ break;
+ case 6:
+ s->cstyle = SCREEN_CURSOR_BAR;
+ s->mode &= ~MODE_BLINKING;
+ break;
}
}
diff --git a/tmux.h b/tmux.h
index 508fddd3..96d829fb 100644
--- a/tmux.h
+++ b/tmux.h
@@ -794,6 +794,14 @@ struct style {
enum style_default_type default_type;
};
+/* Cursor style. */
+enum screen_cursor_style {
+ SCREEN_CURSOR_DEFAULT,
+ SCREEN_CURSOR_BLOCK,
+ SCREEN_CURSOR_UNDERLINE,
+ SCREEN_CURSOR_BAR
+};
+
/* Virtual screen. */
struct screen_sel;
struct screen_titles;
@@ -807,8 +815,8 @@ struct screen {
u_int cx; /* cursor x */
u_int cy; /* cursor y */
- u_int cstyle; /* cursor style */
- char *ccolour; /* cursor colour string */
+ enum screen_cursor_style cstyle; /* cursor style */
+ char *ccolour; /* cursor colour */
u_int rupper; /* scroll region top */
u_int rlower; /* scroll region bottom */
@@ -1296,7 +1304,7 @@ struct tty {
u_int cx;
u_int cy;
- u_int cstyle;
+ enum screen_cursor_style cstyle;
char *ccolour;
int oflag;
diff --git a/tty.c b/tty.c
index e8a8cbaa..367f54d5 100644
--- a/tty.c
+++ b/tty.c
@@ -98,7 +98,7 @@ tty_init(struct tty *tty, struct client *c)
memset(tty, 0, sizeof *tty);
tty->client = c;
- tty->cstyle = 0;
+ tty->cstyle = SCREEN_CURSOR_DEFAULT;
tty->ccolour = xstrdup("");
if (tcgetattr(c->fd, &tty->tio) != 0)
@@ -392,10 +392,10 @@ tty_stop_tty(struct tty *tty)
tty_raw(tty, tty_term_string(tty->term, TTYC_SGR0));
tty_raw(tty, tty_term_string(tty->term, TTYC_RMKX));
tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR));
- if (tty_term_has(tty->term, TTYC_SS) && tty->cstyle != 0) {
+ if (tty->cstyle != SCREEN_CURSOR_DEFAULT) {
if (tty_term_has(tty->term, TTYC_SE))
tty_raw(tty, tty_term_string(tty->term, TTYC_SE));
- else
+ else if (tty_term_has(tty->term, TTYC_SS))
tty_raw(tty, tty_term_string1(tty->term, TTYC_SS, 0));
}
if (tty->mode & MODE_BRACKETPASTE)
@@ -657,11 +657,9 @@ tty_force_cursor_colour(struct tty *tty, const char *ccolour)
void
tty_update_mode(struct tty *tty, int mode, struct screen *s)
{
- struct client *c = tty->client;
- int changed;
-
- if (s != NULL && strcmp(s->ccolour, tty->ccolour) != 0)
- tty_force_cursor_colour(tty, s->ccolour);
+ struct client *c = tty->client;
+ int changed;
+ enum screen_cursor_style cstyle = tty->cstyle;
if (tty->flags & TTY_NOCURSOR)
mode &= ~MODE_CURSOR;
@@ -670,38 +668,83 @@ tty_update_mode(struct tty *tty, int mode, struct screen *s)
if (changed != 0)
log_debug("%s: update mode %x to %x", c->name, tty->mode, mode);
- /*
- * The cursor blinking flag can be reset by setting the cursor style, so
- * set the style first.
- */
- if (s != NULL && tty->cstyle != s->cstyle) {
- if (tty_term_has(tty->term, TTYC_SS)) {
- if (s->cstyle == 0 && tty_term_has(tty->term, TTYC_SE))
- tty_putcode(tty, TTYC_SE);
- else
- tty_putcode1(tty, TTYC_SS, s->cstyle);
- }
- tty->cstyle = s->cstyle;
- changed |= (MODE_CURSOR|MODE_BLINKING);
+ if (s != NULL) {
+ if (strcmp(s->ccolour, tty->ccolour) != 0)
+ tty_force_cursor_colour(tty, s->ccolour);
+ cstyle = s->cstyle;
}
-
- /*
- * Cursor invisible (RM ?25) overrides cursor blinking (SM ?12 or RM
- * 34), and we need to be careful not send cnorm after cvvis since it
- * can undo it.
- */
- if (changed & (MODE_CURSOR|MODE_BLINKING)) {
- log_debug("%s: cursor %s, %sblinking", __func__,
- (mode & MODE_CURSOR) ? "on" : "off",
- (mode & MODE_BLINKING) ? "" : "not ");
- if (~mode & MODE_CURSOR)
+ if (~mode & MODE_CURSOR) {
+ /* Cursor now off - set as invisible. */
+ if (changed & MODE_CURSOR)
tty_putcode(tty, TTYC_CIVIS);
- else if (mode & MODE_BLINKING) {
- tty_putcode(tty, TTYC_CNORM);
- if (tty_term_has(tty->term, TTYC_CVVIS))
+ } 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);
- } else
- tty_putcode(tty, TTYC_CNORM);
+ 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;
}
if ((changed & ALL_MOUSE_MODES) &&