# HG changeset patch # User Christian Brabandt # Date 1503953104 -7200 # Node ID 48eac9bc2f82f71914013a8708ad6cb20afbca19 # Parent 8b386ef3a93d9700995287bda6a8647b0f48f597 patch 8.0.1009: Xterm cursor blinking status may be inverted commit https://github.com/vim/vim/commit/4db2554954056f21f2ba4cf4988c652745d7042a Author: Bram Moolenaar Date: Mon Aug 28 22:43:05 2017 +0200 patch 8.0.1009: Xterm cursor blinking status may be inverted Problem: Xterm cursor blinking status may be inverted. Solution: Use another request to get the blink status and compare with the cursor style report diff --git a/src/option.c b/src/option.c --- a/src/option.c +++ b/src/option.c @@ -3194,6 +3194,7 @@ static struct vimoption options[] = p_term("t_nd", T_ND) p_term("t_op", T_OP) p_term("t_RB", T_RBG) + p_term("t_RC", T_CRC) p_term("t_RI", T_CRI) p_term("t_RS", T_CRS) p_term("t_RV", T_CRV) diff --git a/src/proto/term.pro b/src/proto/term.pro --- a/src/proto/term.pro +++ b/src/proto/term.pro @@ -53,6 +53,7 @@ void cursor_on(void); void cursor_off(void); void term_cursor_mode(int forced); void term_cursor_color(char_u *color); +int blink_state_is_inverted(void); void term_cursor_shape(int shape, int blink); void scroll_region_set(win_T *wp, int off); void scroll_region_reset(void); diff --git a/src/term.c b/src/term.c --- a/src/term.c +++ b/src/term.c @@ -128,8 +128,11 @@ static int u7_status = STATUS_GET; /* Request background color report: */ static int rbg_status = STATUS_GET; -/* Request cursor mode report: */ -static int rcm_status = STATUS_GET; +/* Request cursor blinking mode report: */ +static int rbm_status = STATUS_GET; + +/* Request cursor style report: */ +static int rcs_status = STATUS_GET; # endif /* @@ -163,9 +166,14 @@ static int detected_8bit = FALSE; /* de #ifdef FEAT_TERMRESPONSE /* When the cursor shape was detected these values are used: - * 1: block, 2: underline, 3: vertical bar - * initial_cursor_blink is only valid when initial_cursor_shape is not zero. */ + * 1: block, 2: underline, 3: vertical bar */ static int initial_cursor_shape = 0; + +/* The blink flag from the style response may be inverted from the actual + * blinking state, xterm XORs the flags. */ +static int initial_cursor_shape_blink = FALSE; + +/* The blink flag from the blinking-cursor mode response */ static int initial_cursor_blink = FALSE; #endif @@ -835,6 +843,7 @@ static struct builtin_term builtin_termc # else {(int)KS_CSH, IF_EB("\033[%d q", ESC_STR "[%d q")}, # endif + {(int)KS_CRC, IF_EB("\033[?12$p", ESC_STR "[?12$p")}, {(int)KS_CRS, IF_EB("\033P$q q\033\\", ESC_STR "P$q q" ESC_STR "\\")}, # ifdef TERMINFO {(int)KS_CM, IF_EB("\033[%i%p1%d;%p2%dH", @@ -3316,7 +3325,8 @@ settmode(int tmode) if (tmode != TMODE_RAW && (crv_status == STATUS_SENT || u7_status == STATUS_SENT || rbg_status == STATUS_SENT - || rcm_status == STATUS_SENT)) + || rbm_status == STATUS_SENT + || rcs_status == STATUS_SENT)) (void)vpeekc_nomap(); check_for_codes_from_term(); } @@ -3386,7 +3396,8 @@ stoptermcap(void) if (crv_status == STATUS_SENT || u7_status == STATUS_SENT || rbg_status == STATUS_SENT - || rcm_status == STATUS_SENT) + || rbm_status == STATUS_SENT + || rcs_status == STATUS_SENT) { # ifdef UNIX /* Give the terminal a chance to respond. */ @@ -3500,6 +3511,8 @@ may_req_ambiguous_char_width(void) void may_req_bg_color(void) { + int did_one = FALSE; + if (can_get_termresponse() && starting == 0) { /* Only request background if t_RB is set and 'background' wasn't @@ -3511,7 +3524,20 @@ may_req_bg_color(void) LOG_TR("Sending BG request"); out_str(T_RBG); rbg_status = STATUS_SENT; - + did_one = TRUE; + } + + /* Only request cursor blinking mode if t_RC is set. */ + if (rbm_status == STATUS_GET && *T_CRC != NUL) + { + LOG_TR("Sending BC request"); + out_str(T_CRC); + rbm_status = STATUS_SENT; + did_one = TRUE; + } + + if (did_one) + { /* check for the characters now, otherwise they might be eaten by * get_keystroke() */ out_flush(); @@ -3751,6 +3777,13 @@ term_cursor_color(char_u *color) } # endif + int +blink_state_is_inverted() +{ + return rbm_status == STATUS_GOT && rcs_status == STATUS_GOT + && initial_cursor_blink != initial_cursor_shape_blink; +} + /* * "shape": 1 = block, 2 = underline, 3 = vertical bar */ @@ -3762,16 +3795,26 @@ term_cursor_shape(int shape, int blink) OUT_STR(tgoto((char *)T_CSH, 0, shape * 2 - blink)); out_flush(); } - /* When t_SH is not set try setting just the blink state. */ - else if (blink && *T_VS != NUL) + else { - out_str(T_VS); - out_flush(); - } - else if (!blink && *T_CVS != NUL) - { - out_str(T_CVS); - out_flush(); + int do_blink = blink; + + /* t_SH is empty: try setting just the blink state. + * The blink flags are XORed together, if the initial blinking from + * style and shape differs, we need to invert the flag here. */ + if (blink_state_is_inverted()) + do_blink = !blink; + + if (do_blink && *T_VS != NUL) + { + out_str(T_VS); + out_flush(); + } + else if (!do_blink && *T_CVS != NUL) + { + out_str(T_CVS); + out_flush(); + } } } #endif @@ -4533,7 +4576,7 @@ check_termcode( /* Only request the cursor style if t_SH and t_RS are * set. Not for Terminal.app, it can't handle t_RS, it * echoes the characters to the screen. */ - if (rcm_status == STATUS_GET + if (rcs_status == STATUS_GET # ifdef MACOS && !is_terminal_app # endif @@ -4542,7 +4585,7 @@ check_termcode( { LOG_TR("Sending cursor style request"); out_str(T_CRS); - rcm_status = STATUS_SENT; + rcs_status = STATUS_SENT; out_flush(); } } @@ -4558,6 +4601,29 @@ check_termcode( slen = i + 1; } + /* Check blinking cursor from xterm: + * {lead}?12;1$y set + * {lead}?12;2$y not set + * + * {lead} can be [ or CSI + */ + else if (rbm_status == STATUS_SENT + && tp[(j = 1 + (tp[0] == ESC))] == '?' + && i == j + 6 + && tp[j + 1] == '1' + && tp[j + 2] == '2' + && tp[j + 3] == ';' + && tp[i - 1] == '$' + && tp[i] == 'y') + { + initial_cursor_blink = (tp[j + 4] == '1'); + rbm_status = STATUS_GOT; + LOG_TR("Received cursor blinking mode response"); + key_name[0] = (int)KS_EXTRA; + key_name[1] = (int)KE_IGNORE; + slen = i + 1; + } + /* * Check for a window position response from the terminal: * {lead}3;{x}:{y}t @@ -4668,7 +4734,7 @@ check_termcode( * * Consume any code that starts with "{lead}.+r" or "{lead}.$r". */ - else if ((check_for_codes || rcm_status == STATUS_SENT) + else if ((check_for_codes || rcs_status == STATUS_SENT) && ((tp[0] == ESC && len >= 2 && tp[1] == 'P') || tp[0] == DCS)) { @@ -4710,8 +4776,9 @@ check_termcode( initial_cursor_shape = (number + 1) / 2; /* The blink flag is actually inverted, compared to * the value set with T_SH. */ - initial_cursor_blink = (number & 1) ? FALSE : TRUE; - rcm_status = STATUS_GOT; + initial_cursor_shape_blink = + (number & 1) ? FALSE : TRUE; + rcs_status = STATUS_GOT; LOG_TR("Received cursor shape response"); key_name[0] = (int)KS_EXTRA; diff --git a/src/term.h b/src/term.h --- a/src/term.h +++ b/src/term.h @@ -42,7 +42,8 @@ enum SpecialKey KS_VS, /* cursor very visible (blink) */ KS_CVS, /* cursor normally visible (no blink) */ KS_CSH, /* cursor shape */ - KS_CRS, /* request cursor shape */ + KS_CRC, /* request cursor blinking */ + KS_CRS, /* request cursor style */ KS_ME, /* normal mode */ KS_MR, /* reverse mode */ KS_MD, /* bold mode */ @@ -135,7 +136,8 @@ extern char_u *(term_strings[]); /* c #define T_VS (TERM_STR(KS_VS)) /* cursor very visible (blink) */ #define T_CVS (TERM_STR(KS_CVS)) /* cursor normally visible (no blink) */ #define T_CSH (TERM_STR(KS_CSH)) /* cursor shape */ -#define T_CRS (TERM_STR(KS_CRS)) /* request cursor shape */ +#define T_CRC (TERM_STR(KS_CRC)) /* request cursor blinking */ +#define T_CRS (TERM_STR(KS_CRS)) /* request cursor style */ #define T_ME (TERM_STR(KS_ME)) /* normal mode */ #define T_MR (TERM_STR(KS_MR)) /* reverse mode */ #define T_MD (TERM_STR(KS_MD)) /* bold mode */ diff --git a/src/terminal.c b/src/terminal.c --- a/src/terminal.c +++ b/src/terminal.c @@ -39,7 +39,6 @@ * * TODO: * - ":term NONE" does not work in MS-Windows. - * - better check for blinking - reply from Thomas Dickey Aug 22 * - test for writing lines to terminal job does not work on MS-Windows * - implement term_setsize() * - add test for giving error for invalid 'termsize' value. @@ -2482,7 +2481,8 @@ f_term_getcursor(typval_T *argvars, typv if (d != NULL) { dict_add_nr_str(d, "visible", term->tl_cursor_visible, NULL); - dict_add_nr_str(d, "blink", term->tl_cursor_blink, NULL); + dict_add_nr_str(d, "blink", blink_state_is_inverted() + ? !term->tl_cursor_blink : term->tl_cursor_blink, NULL); dict_add_nr_str(d, "shape", term->tl_cursor_shape, NULL); dict_add_nr_str(d, "color", 0L, term->tl_cursor_color == NULL ? (char_u *)"" : term->tl_cursor_color); diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -770,6 +770,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1009, +/**/ 1008, /**/ 1007,