To: vim_dev@googlegroups.com Subject: Patch 8.0.1009 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1009 Problem: Xterm cursor blinking status may be inverted. Solution: Use another request to get the blink status and compare with the cursor style report Files: src/term.c, src/proto/term.pro, src/term.h, src/option.c, src/terminal.c *** ../vim-8.0.1008/src/term.c 2017-08-26 15:29:42.768908371 +0200 --- src/term.c 2017-08-28 22:42:01.794619025 +0200 *************** *** 128,135 **** /* Request background color report: */ static int rbg_status = STATUS_GET; ! /* Request cursor mode report: */ ! static int rcm_status = STATUS_GET; # endif /* --- 128,138 ---- /* Request background color report: */ static int rbg_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,171 **** #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. */ static int initial_cursor_shape = 0; static int initial_cursor_blink = FALSE; #endif --- 166,179 ---- #ifdef FEAT_TERMRESPONSE /* When the cursor shape was detected these values are used: ! * 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,840 **** --- 843,849 ---- # 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,3322 **** if (tmode != TMODE_RAW && (crv_status == STATUS_SENT || u7_status == STATUS_SENT || rbg_status == STATUS_SENT ! || rcm_status == STATUS_SENT)) (void)vpeekc_nomap(); check_for_codes_from_term(); } --- 3325,3332 ---- if (tmode != TMODE_RAW && (crv_status == STATUS_SENT || u7_status == STATUS_SENT || rbg_status == STATUS_SENT ! || rbm_status == STATUS_SENT ! || rcs_status == STATUS_SENT)) (void)vpeekc_nomap(); check_for_codes_from_term(); } *************** *** 3386,3392 **** if (crv_status == STATUS_SENT || u7_status == STATUS_SENT || rbg_status == STATUS_SENT ! || rcm_status == STATUS_SENT) { # ifdef UNIX /* Give the terminal a chance to respond. */ --- 3396,3403 ---- if (crv_status == STATUS_SENT || u7_status == STATUS_SENT || rbg_status == STATUS_SENT ! || rbm_status == STATUS_SENT ! || rcs_status == STATUS_SENT) { # ifdef UNIX /* Give the terminal a chance to respond. */ *************** *** 3500,3505 **** --- 3511,3518 ---- 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,3517 **** --- 3524,3543 ---- 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,3756 **** --- 3777,3789 ---- } # 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,3777 **** 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) ! { ! out_str(T_VS); ! out_flush(); ! } ! else if (!blink && *T_CVS != NUL) { ! out_str(T_CVS); ! out_flush(); } } #endif --- 3795,3820 ---- OUT_STR(tgoto((char *)T_CSH, 0, shape * 2 - blink)); out_flush(); } ! else { ! 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,4539 **** /* 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 # ifdef MACOS && !is_terminal_app # endif --- 4576,4582 ---- /* 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 (rcs_status == STATUS_GET # ifdef MACOS && !is_terminal_app # endif *************** *** 4542,4548 **** { LOG_TR("Sending cursor style request"); out_str(T_CRS); ! rcm_status = STATUS_SENT; out_flush(); } } --- 4585,4591 ---- { LOG_TR("Sending cursor style request"); out_str(T_CRS); ! rcs_status = STATUS_SENT; out_flush(); } } *************** *** 4558,4563 **** --- 4601,4629 ---- 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,4674 **** * * Consume any code that starts with "{lead}.+r" or "{lead}.$r". */ ! else if ((check_for_codes || rcm_status == STATUS_SENT) && ((tp[0] == ESC && len >= 2 && tp[1] == 'P') || tp[0] == DCS)) { --- 4734,4740 ---- * * Consume any code that starts with "{lead}.+r" or "{lead}.$r". */ ! else if ((check_for_codes || rcs_status == STATUS_SENT) && ((tp[0] == ESC && len >= 2 && tp[1] == 'P') || tp[0] == DCS)) { *************** *** 4710,4717 **** 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; LOG_TR("Received cursor shape response"); key_name[0] = (int)KS_EXTRA; --- 4776,4784 ---- initial_cursor_shape = (number + 1) / 2; /* The blink flag is actually inverted, compared to * the value set with T_SH. */ ! initial_cursor_shape_blink = ! (number & 1) ? FALSE : TRUE; ! rcs_status = STATUS_GOT; LOG_TR("Received cursor shape response"); key_name[0] = (int)KS_EXTRA; *** ../vim-8.0.1008/src/proto/term.pro 2017-08-20 15:05:11.616196327 +0200 --- src/proto/term.pro 2017-08-28 22:24:18.605080709 +0200 *************** *** 53,58 **** --- 53,59 ---- 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); *** ../vim-8.0.1008/src/term.h 2017-08-20 15:05:11.616196327 +0200 --- src/term.h 2017-08-28 22:02:41.705174754 +0200 *************** *** 42,48 **** KS_VS, /* cursor very visible (blink) */ KS_CVS, /* cursor normally visible (no blink) */ KS_CSH, /* cursor shape */ ! KS_CRS, /* request cursor shape */ KS_ME, /* normal mode */ KS_MR, /* reverse mode */ KS_MD, /* bold mode */ --- 42,49 ---- KS_VS, /* cursor very visible (blink) */ KS_CVS, /* cursor normally visible (no blink) */ KS_CSH, /* 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,141 **** #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_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 */ --- 136,143 ---- #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_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 */ *** ../vim-8.0.1008/src/option.c 2017-08-26 22:30:10.994510924 +0200 --- src/option.c 2017-08-28 22:03:04.429032077 +0200 *************** *** 3194,3199 **** --- 3194,3200 ---- 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) *** ../vim-8.0.1008/src/terminal.c 2017-08-26 23:43:23.978903346 +0200 --- src/terminal.c 2017-08-28 22:27:26.723916208 +0200 *************** *** 39,45 **** * * 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. --- 39,44 ---- *************** *** 2482,2488 **** 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, "shape", term->tl_cursor_shape, NULL); dict_add_nr_str(d, "color", 0L, term->tl_cursor_color == NULL ? (char_u *)"" : term->tl_cursor_color); --- 2481,2488 ---- if (d != NULL) { dict_add_nr_str(d, "visible", term->tl_cursor_visible, 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); *** ../vim-8.0.1008/src/version.c 2017-08-27 17:38:23.748775250 +0200 --- src/version.c 2017-08-28 22:28:05.371676902 +0200 *************** *** 771,772 **** --- 771,774 ---- { /* Add new patch number below this line */ + /**/ + 1009, /**/ -- The startling truth finally became apparent, and it was this: Numbers written on restaurant checks within the confines of restaurants do not follow the same mathematical laws as numbers written on any other pieces of paper in any other parts of the Universe. This single statement took the scientific world by storm. So many mathematical conferences got held in such good restaurants that many of the finest minds of a generation died of obesity and heart failure, and the science of mathematics was put back by years. -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy" /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///