From 3ea5e06bfb04278fa53885e551bc363a84bad8d1 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 20 May 2011 19:17:39 +0000 Subject: [PATCH] Support DECSCUSR sequence to set the cursor style with two new terminfo(5) extensions, Cs and Csr. Written by Ailin Nemui. --- input.c | 6 ++++++ options-table.c | 1 + screen.c | 9 +++++++++ tmux.1 | 13 +++++++++++++ tmux.h | 5 +++++ tty-term.c | 2 ++ tty.c | 17 +++++++++++++++++ 7 files changed, 53 insertions(+) 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)