summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@openbsd.org>2011-05-20 19:17:39 +0000
committerNicholas Marriott <nicm@openbsd.org>2011-05-20 19:17:39 +0000
commit3ea5e06bfb04278fa53885e551bc363a84bad8d1 (patch)
tree155061457c80262457ba005863c44df9aaeeb8c5
parent944b5e6fa04e014501f465e3898315c84d10bd9e (diff)
Support DECSCUSR sequence to set the cursor style with two new
terminfo(5) extensions, Cs and Csr. Written by Ailin Nemui.
-rw-r--r--input.c6
-rw-r--r--options-table.c1
-rw-r--r--screen.c9
-rw-r--r--tmux.113
-rw-r--r--tmux.h5
-rw-r--r--tty-term.c2
-rw-r--r--tty.c17
7 files changed, 53 insertions, 0 deletions
diff --git a/input.c b/input.c
index 86d34b74..9c1c4dca 100644
--- a/input.c
+++ b/input.c
@@ -126,6 +126,7 @@ enum input_csi_type {
INPUT_CSI_CUU,
INPUT_CSI_DA,
INPUT_CSI_DCH,
+ INPUT_CSI_DECSCUSR,
INPUT_CSI_DECSTBM,
INPUT_CSI_DL,
INPUT_CSI_DSR,
@@ -168,6 +169,7 @@ const struct input_table_entry input_csi_table[] = {
{ 'l', "?", INPUT_CSI_RM_PRIVATE },
{ 'm', "", INPUT_CSI_SGR },
{ 'n', "", INPUT_CSI_DSR },
+ { 'q', " ", INPUT_CSI_DECSCUSR },
{ 'r', "", INPUT_CSI_DECSTBM },
};
@@ -1259,6 +1261,10 @@ input_csi_dispatch(struct input_ctx *ictx)
n = input_get(ictx, 0, 1, 1);
screen_write_cursormove(sctx, s->cx, n - 1);
break;
+ case INPUT_CSI_DECSCUSR:
+ n = input_get(ictx, 0, 0, 0);
+ screen_set_cursor_style(s, n);
+ break;
}
return (0);
diff --git a/options-table.c b/options-table.c
index c84c56a1..4b2f40bc 100644
--- a/options-table.c
+++ b/options-table.c
@@ -368,6 +368,7 @@ const struct options_table_entry session_options_table[] = {
.default_str = "*88col*:colors=88,*256col*:colors=256"
",xterm*:XT:Ms=\\E]52;%p1%s;%p2%s\\007"
":Cc=\\E]12;%p1%s\\007:Cr=\\E]112\\007"
+ ":Cs=\\E[%p1%d q:Csr=\\E[2 q"
},
{ .name = "update-environment",
diff --git a/screen.c b/screen.c
index 5e3be88c..3c8a5235 100644
--- a/screen.c
+++ b/screen.c
@@ -40,6 +40,7 @@ screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
else
s->title = xstrdup("");
+ s->cstyle = 0;
s->ccolour = xstrdup("");
s->tabs = NULL;
@@ -91,6 +92,14 @@ screen_reset_tabs(struct screen *s)
bit_set(s->tabs, i);
}
+/* Set screen cursor style. */
+void
+screen_set_cursor_style(struct screen *s, u_int style)
+{
+ if (style <= 4)
+ s->cstyle = style;
+}
+
/* Set screen cursor colour. */
void
screen_set_cursor_colour(struct screen *s, const char *colour_string)
diff --git a/tmux.1 b/tmux.1
index dbe54d52..1e3c57b2 100644
--- a/tmux.1
+++ b/tmux.1
@@ -2832,6 +2832,19 @@ See the
option above and the
.Xr xterm 1
man page.
+.It Em Cs, Csr
+Change the cursor style.
+If set allows a sequence such as:
+.Bd -literal -offset indent
+$ printf '\e033[4 q'
+.Ed
+.Pp
+To change the cursor to an underline.
+If
+.Em Csr
+is set, it will be used to reset the cursor style instead
+of
+.Em Cs .
.It Em Cc, Cr
The first takes one string argument and is used to set the cursor colour;
the second takes no arguments and restores the default cursor colour.
diff --git a/tmux.h b/tmux.h
index 0444b56d..adad1d7f 100644
--- a/tmux.h
+++ b/tmux.h
@@ -189,7 +189,9 @@ enum tty_code_code {
TTYC_CNORM, /* cursor_normal, ve */
TTYC_COLORS, /* max_colors, Co */
TTYC_CR, /* restore cursor colour, Cr */
+ TTYC_CS1, /* set cursor style, Cs */
TTYC_CSR, /* change_scroll_region, cs */
+ TTYC_CSR1, /* reset cursor style, Csr */
TTYC_CUB, /* parm_left_cursor, LE */
TTYC_CUB1, /* cursor_left, le */
TTYC_CUD, /* parm_down_cursor, DO */
@@ -716,6 +718,7 @@ struct screen {
u_int cx; /* cursor x */
u_int cy; /* cursor y */
+ u_int cstyle; /* cursor style */
char *ccolour; /* cursor colour string */
u_int rupper; /* scroll region top */
@@ -1014,6 +1017,7 @@ struct tty {
u_int cx;
u_int cy;
+ u_int cstyle;
char *ccolour;
int mode;
@@ -1850,6 +1854,7 @@ void screen_init(struct screen *, u_int, u_int, u_int);
void screen_reinit(struct screen *);
void screen_free(struct screen *);
void screen_reset_tabs(struct screen *);
+void screen_set_cursor_style(struct screen *, u_int);
void screen_set_cursor_colour(struct screen *, const char *);
void screen_set_title(struct screen *, const char *);
void screen_resize(struct screen *, u_int, u_int);
diff --git a/tty-term.c b/tty-term.c
index 7083e2ab..41cb97c4 100644
--- a/tty-term.c
+++ b/tty-term.c
@@ -44,7 +44,9 @@ const struct tty_term_code_entry tty_term_codes[NTTYCODE] = {
{ TTYC_CNORM, TTYCODE_STRING, "cnorm" },
{ TTYC_COLORS, TTYCODE_NUMBER, "colors" },
{ TTYC_CR, TTYCODE_STRING, "Cr" },
+ { TTYC_CS1, TTYCODE_STRING, "Cs" },
{ TTYC_CSR, TTYCODE_STRING, "csr" },
+ { TTYC_CSR1, TTYCODE_STRING, "Csr" },
{ TTYC_CUB, TTYCODE_STRING, "cub" },
{ TTYC_CUB1, TTYCODE_STRING, "cub1" },
{ TTYC_CUD, TTYCODE_STRING, "cud" },
diff --git a/tty.c b/tty.c
index 5f3ada8e..4fcf6f55 100644
--- a/tty.c
+++ b/tty.c
@@ -69,6 +69,7 @@ tty_init(struct tty *tty, int fd, char *term)
if ((path = ttyname(fd)) == NULL)
fatalx("ttyname failed");
tty->path = xstrdup(path);
+ tty->cstyle = 0;
tty->ccolour = xstrdup("");
tty->flags = 0;
@@ -244,6 +245,12 @@ 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_CS1) && tty->cstyle != 0) {
+ if (tty_term_has(tty->term, TTYC_CSR1))
+ tty_raw(tty, tty_term_string(tty->term, TTYC_CSR1));
+ else if (tty_term_has(tty->term, TTYC_CS1))
+ tty_raw(tty, tty_term_string1(tty->term, TTYC_CS1, 0));
+ }
tty_raw(tty, tty_term_string(tty->term, TTYC_CR));
tty_raw(tty, tty_term_string(tty->term, TTYC_CNORM));
@@ -429,6 +436,16 @@ tty_update_mode(struct tty *tty, int mode, struct screen *s)
else
tty_putcode(tty, TTYC_CIVIS);
}
+ if (tty->cstyle != s->cstyle) {
+ if (tty_term_has(tty->term, TTYC_CS1)) {
+ if (s->cstyle == 0 &&
+ tty_term_has(tty->term, TTYC_CSR1))
+ tty_putcode(tty, TTYC_CSR1);
+ else
+ tty_putcode1(tty, TTYC_CS1, s->cstyle);
+ }
+ tty->cstyle = s->cstyle;
+ }
if (changed & ALL_MOUSE_MODES) {
if (mode & ALL_MOUSE_MODES) {
if (mode & MODE_MOUSE_UTF8)