Mercurial > vim
comparison src/term.c @ 6874:a89cff862dda v7.4.757
patch 7.4.757
Problem: Cannot detect the background color of a terminal.
Solution: Add T_RBG to request the background color if possible. (Lubomir
Rintel)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Thu, 25 Jun 2015 17:03:36 +0200 |
parents | 7c5a0c69e1ac |
children | 7bd926109eea |
comparison
equal
deleted
inserted
replaced
6873:48ad20643c92 | 6874:a89cff862dda |
---|---|
122 /* Request Cursor position report: */ | 122 /* Request Cursor position report: */ |
123 # define U7_GET 1 /* send T_U7 when switched to RAW mode */ | 123 # define U7_GET 1 /* send T_U7 when switched to RAW mode */ |
124 # define U7_SENT 2 /* did send T_U7, waiting for answer */ | 124 # define U7_SENT 2 /* did send T_U7, waiting for answer */ |
125 # define U7_GOT 3 /* received T_U7 response */ | 125 # define U7_GOT 3 /* received T_U7 response */ |
126 static int u7_status = U7_GET; | 126 static int u7_status = U7_GET; |
127 /* Request background color report: */ | |
128 # define RBG_GET 1 /* send T_RBG when switched to RAW mode */ | |
129 # define RBG_SENT 2 /* did send T_RBG, waiting for answer */ | |
130 # define RBG_GOT 3 /* received T_RBG response */ | |
131 static int rbg_status = RBG_GET; | |
127 # endif | 132 # endif |
128 | 133 |
129 /* | 134 /* |
130 * Don't declare these variables if termcap.h contains them. | 135 * Don't declare these variables if termcap.h contains them. |
131 * Autoconf checks if these variables should be declared extern (not all | 136 * Autoconf checks if these variables should be declared extern (not all |
947 # else | 952 # else |
948 {(int)KS_CWS, IF_EB("\033[8;%d;%dt", ESC_STR "[8;%d;%dt")}, | 953 {(int)KS_CWS, IF_EB("\033[8;%d;%dt", ESC_STR "[8;%d;%dt")}, |
949 {(int)KS_CWP, IF_EB("\033[3;%d;%dt", ESC_STR "[3;%d;%dt")}, | 954 {(int)KS_CWP, IF_EB("\033[3;%d;%dt", ESC_STR "[3;%d;%dt")}, |
950 # endif | 955 # endif |
951 {(int)KS_CRV, IF_EB("\033[>c", ESC_STR "[>c")}, | 956 {(int)KS_CRV, IF_EB("\033[>c", ESC_STR "[>c")}, |
957 {(int)KS_RBG, IF_EB("\033]11;?\007", ESC_STR "]11;?\007")}, | |
952 {(int)KS_U7, IF_EB("\033[6n", ESC_STR "[6n")}, | 958 {(int)KS_U7, IF_EB("\033[6n", ESC_STR "[6n")}, |
953 | 959 |
954 {K_UP, IF_EB("\033O*A", ESC_STR "O*A")}, | 960 {K_UP, IF_EB("\033O*A", ESC_STR "O*A")}, |
955 {K_DOWN, IF_EB("\033O*B", ESC_STR "O*B")}, | 961 {K_DOWN, IF_EB("\033O*B", ESC_STR "O*B")}, |
956 {K_RIGHT, IF_EB("\033O*C", ESC_STR "O*C")}, | 962 {K_RIGHT, IF_EB("\033O*C", ESC_STR "O*C")}, |
1238 {(int)KS_CWS, "[%dCWS%d]"}, | 1244 {(int)KS_CWS, "[%dCWS%d]"}, |
1239 {(int)KS_CWP, "[%dCWP%d]"}, | 1245 {(int)KS_CWP, "[%dCWP%d]"}, |
1240 # endif | 1246 # endif |
1241 {(int)KS_CRV, "[CRV]"}, | 1247 {(int)KS_CRV, "[CRV]"}, |
1242 {(int)KS_U7, "[U7]"}, | 1248 {(int)KS_U7, "[U7]"}, |
1249 {(int)KS_RBG, "[RBG]"}, | |
1243 {K_UP, "[KU]"}, | 1250 {K_UP, "[KU]"}, |
1244 {K_DOWN, "[KD]"}, | 1251 {K_DOWN, "[KD]"}, |
1245 {K_LEFT, "[KL]"}, | 1252 {K_LEFT, "[KL]"}, |
1246 {K_RIGHT, "[KR]"}, | 1253 {K_RIGHT, "[KR]"}, |
1247 {K_XUP, "[xKU]"}, | 1254 {K_XUP, "[xKU]"}, |
3222 { | 3229 { |
3223 /* May need to check for T_CRV response and termcodes, it | 3230 /* May need to check for T_CRV response and termcodes, it |
3224 * doesn't work in Cooked mode, an external program may get | 3231 * doesn't work in Cooked mode, an external program may get |
3225 * them. */ | 3232 * them. */ |
3226 if (tmode != TMODE_RAW && (crv_status == CRV_SENT | 3233 if (tmode != TMODE_RAW && (crv_status == CRV_SENT |
3227 || u7_status == U7_SENT)) | 3234 || u7_status == U7_SENT |
3235 || rbg_status == RBG_SENT)) | |
3228 (void)vpeekc_nomap(); | 3236 (void)vpeekc_nomap(); |
3229 check_for_codes_from_term(); | 3237 check_for_codes_from_term(); |
3230 } | 3238 } |
3231 #endif | 3239 #endif |
3232 #ifdef FEAT_MOUSE_TTY | 3240 #ifdef FEAT_MOUSE_TTY |
3283 #ifdef FEAT_TERMRESPONSE | 3291 #ifdef FEAT_TERMRESPONSE |
3284 # ifdef FEAT_GUI | 3292 # ifdef FEAT_GUI |
3285 if (!gui.in_use && !gui.starting) | 3293 if (!gui.in_use && !gui.starting) |
3286 # endif | 3294 # endif |
3287 { | 3295 { |
3288 /* May need to discard T_CRV or T_U7 response. */ | 3296 /* May need to discard T_CRV, T_U7 or T_RBG response. */ |
3289 if (crv_status == CRV_SENT || u7_status == U7_SENT) | 3297 if (crv_status == CRV_SENT || u7_status == U7_SENT |
3298 || rbg_status == RBG_SENT) | |
3290 { | 3299 { |
3291 # ifdef UNIX | 3300 # ifdef UNIX |
3292 /* Give the terminal a chance to respond. */ | 3301 /* Give the terminal a chance to respond. */ |
3293 mch_delay(100L, FALSE); | 3302 mch_delay(100L, FALSE); |
3294 # endif | 3303 # endif |
3392 term_windgoto(0, 0); | 3401 term_windgoto(0, 0); |
3393 /* check for the characters now, otherwise they might be eaten by | 3402 /* check for the characters now, otherwise they might be eaten by |
3394 * get_keystroke() */ | 3403 * get_keystroke() */ |
3395 out_flush(); | 3404 out_flush(); |
3396 (void)vpeekc_nomap(); | 3405 (void)vpeekc_nomap(); |
3406 } | |
3407 } | |
3408 # endif | |
3409 | |
3410 #if defined(FEAT_TERMRESPONSE) || defined(PROTO) | |
3411 /* | |
3412 * Check how the terminal treats ambiguous character width (UAX #11). | |
3413 * First, we move the cursor to (1, 0) and print a test ambiguous character | |
3414 * \u25bd (WHITE DOWN-POINTING TRIANGLE) and query current cursor position. | |
3415 * If the terminal treats \u25bd as single width, the position is (1, 1), | |
3416 * or if it is treated as double width, that will be (1, 2). | |
3417 * This function has the side effect that changes cursor position, so | |
3418 * it must be called immediately after entering termcap mode. | |
3419 */ | |
3420 void | |
3421 may_req_bg_color() | |
3422 { | |
3423 if (rbg_status == RBG_GET | |
3424 && cur_tmode == TMODE_RAW | |
3425 && termcap_active | |
3426 && p_ek | |
3427 # ifdef UNIX | |
3428 && isatty(1) | |
3429 && isatty(read_cmd_fd) | |
3430 # endif | |
3431 && *T_RBG != NUL | |
3432 && !option_was_set((char_u *)"bg")) | |
3433 { | |
3434 LOG_TR("Sending BG request"); | |
3435 out_str(T_RBG); | |
3436 rbg_status = RBG_SENT; | |
3437 /* check for the characters now, otherwise they might be eaten by | |
3438 * get_keystroke() */ | |
3439 out_flush(); | |
3440 (void)vpeekc_nomap(); | |
3397 } | 3441 } |
3398 } | 3442 } |
3399 # endif | 3443 # endif |
3400 | 3444 |
3401 # ifdef DEBUG_TERMRESPONSE | 3445 # ifdef DEBUG_TERMRESPONSE |
4220 * the escape sequence ends with a letter or one of "{|}~". | 4264 * the escape sequence ends with a letter or one of "{|}~". |
4221 * | 4265 * |
4222 * - Cursor position report: <Esc>[{row};{col}R | 4266 * - Cursor position report: <Esc>[{row};{col}R |
4223 * The final byte must be 'R'. It is used for checking the | 4267 * The final byte must be 'R'. It is used for checking the |
4224 * ambiguous-width character state. | 4268 * ambiguous-width character state. |
4269 * | |
4270 * - Background color response: | |
4271 * <Esc>]11;rgb:{rrrr}/{gggg}/{bbbb}\007 | |
4272 * The final byte must be '\007'. | |
4225 */ | 4273 */ |
4226 p = tp[0] == CSI ? tp + 1 : tp + 2; | 4274 char_u *argp = tp[0] == CSI ? tp + 1 : tp + 2; |
4227 if ((*T_CRV != NUL || *T_U7 != NUL) | 4275 |
4276 if ((*T_CRV != NUL || *T_U7 != NUL || *T_RBG != NUL) | |
4228 && ((tp[0] == ESC && tp[1] == '[' && len >= 3) | 4277 && ((tp[0] == ESC && tp[1] == '[' && len >= 3) |
4278 || (tp[0] == ESC && tp[1] == ']' && len >= 24) | |
4229 || (tp[0] == CSI && len >= 2)) | 4279 || (tp[0] == CSI && len >= 2)) |
4230 && (VIM_ISDIGIT(*p) || *p == '>' || *p == '?')) | 4280 && (VIM_ISDIGIT(*argp) || *argp == '>' || *argp == '?')) |
4231 { | 4281 { |
4232 #ifdef FEAT_MBYTE | 4282 #ifdef FEAT_MBYTE |
4233 int col; | 4283 int col; |
4234 int row_char = NUL; | 4284 int row_char = NUL; |
4235 #endif | 4285 #endif |
4360 NULL, NULL, FALSE, curbuf); | 4410 NULL, NULL, FALSE, curbuf); |
4361 # endif | 4411 # endif |
4362 key_name[0] = (int)KS_EXTRA; | 4412 key_name[0] = (int)KS_EXTRA; |
4363 key_name[1] = (int)KE_IGNORE; | 4413 key_name[1] = (int)KE_IGNORE; |
4364 slen = i + 1; | 4414 slen = i + 1; |
4415 } | |
4416 else if (*T_RBG != NUL && len >= 24 - (tp[0] == CSI) | |
4417 && argp[0] == '1' && argp[1] == '1' | |
4418 && argp[2] == ';' && argp[3] == 'r' && argp[4] == 'g' | |
4419 && argp[5] == 'b' && argp[6] == ':' | |
4420 && argp[11] == '/' && argp[16] == '/' | |
4421 && argp[21] == '\007') | |
4422 { | |
4423 LOG_TR("Received RBG"); | |
4424 rbg_status = RBG_GOT; | |
4425 if (!option_was_set((char_u *)"bg")) | |
4426 { | |
4427 set_option_value((char_u *)"bg", 0L, (char_u *)( | |
4428 (3 * '6' < argp[7] + argp[12] + argp[17]) | |
4429 ? "light" : "dark"), 0); | |
4430 reset_option_was_set((char_u *)"bg"); | |
4431 redraw_asap(CLEAR); | |
4432 } | |
4433 key_name[0] = (int)KS_EXTRA; | |
4434 key_name[1] = (int)KE_IGNORE; | |
4435 slen = 24; | |
4365 } | 4436 } |
4366 } | 4437 } |
4367 | 4438 |
4368 /* Check for '<Esc>P1+r<hex bytes><Esc>\'. A "0" instead of the | 4439 /* Check for '<Esc>P1+r<hex bytes><Esc>\'. A "0" instead of the |
4369 * "1" means an invalid request. */ | 4440 * "1" means an invalid request. */ |