diff src/term.c @ 12632:b1a7e3968a31 v8.0.1194

patch 8.0.1194: actual fg and bg colors of terminal are unknown commit https://github.com/vim/vim/commit/65e4c4f6868882a380c319632a1728a5e7d274ad Author: Bram Moolenaar <Bram@vim.org> Date: Sat Oct 14 23:24:25 2017 +0200 patch 8.0.1194: actual fg and bg colors of terminal are unknown Problem: Actual fg and bg colors of terminal are unknown. Solution: Add t_RF. Store response to t_RB and t_RF, use for terminal.
author Christian Brabandt <cb@256bit.org>
date Sat, 14 Oct 2017 23:30:05 +0200
parents 895da0cbb16e
children 94566ecb55f0
line wrap: on
line diff
--- a/src/term.c
+++ b/src/term.c
@@ -125,6 +125,17 @@ static int crv_status = STATUS_GET;
 /* Request Cursor position report: */
 static int u7_status = STATUS_GET;
 
+#ifdef FEAT_TERMINAL
+/* Request foreground color report: */
+static int rfg_status = STATUS_GET;
+static int fg_r = 0;
+static int fg_g = 0;
+static int fg_b = 0;
+static int bg_r = 255;
+static int bg_g = 255;
+static int bg_b = 255;
+#endif
+
 /* Request background color report: */
 static int rbg_status = STATUS_GET;
 
@@ -882,6 +893,7 @@ static struct builtin_term builtin_termc
     {(int)KS_CGP,	IF_EB("\033[13t", ESC_STR "[13t")},
 #  endif
     {(int)KS_CRV,	IF_EB("\033[>c", ESC_STR "[>c")},
+    {(int)KS_RFG,	IF_EB("\033]10;?\007", ESC_STR "]10;?\007")},
     {(int)KS_RBG,	IF_EB("\033]11;?\007", ESC_STR "]11;?\007")},
     {(int)KS_U7,	IF_EB("\033[6n", ESC_STR "[6n")},
 #  ifdef FEAT_TERMGUICOLORS
@@ -1185,6 +1197,7 @@ static struct builtin_term builtin_termc
 #  endif
     {(int)KS_CRV,	"[CRV]"},
     {(int)KS_U7,	"[U7]"},
+    {(int)KS_RFG,	"[RFG]"},
     {(int)KS_RBG,	"[RBG]"},
     {K_UP,		"[KU]"},
     {K_DOWN,		"[KD]"},
@@ -1608,7 +1621,7 @@ set_termname(char_u *term)
 				{KS_TS, "ts"}, {KS_FS, "fs"},
 				{KS_CWP, "WP"}, {KS_CWS, "WS"},
 				{KS_CSI, "SI"}, {KS_CEI, "EI"},
-				{KS_U7, "u7"}, {KS_RBG, "RB"},
+				{KS_U7, "u7"}, {KS_RFG, "RF"}, {KS_RBG, "RB"},
 				{KS_8F, "8f"}, {KS_8B, "8b"},
 				{KS_CBE, "BE"}, {KS_CBD, "BD"},
 				{KS_CPS, "PS"}, {KS_CPE, "PE"},
@@ -3320,6 +3333,9 @@ settmode(int tmode)
 		 * them. */
 		if (tmode != TMODE_RAW && (crv_status == STATUS_SENT
 					 || u7_status == STATUS_SENT
+#ifdef FEAT_TERMINAL
+					 || rfg_status == STATUS_SENT
+#endif
 					 || rbg_status == STATUS_SENT
 					 || rbm_status == STATUS_SENT
 					 || rcs_status == STATUS_SENT))
@@ -3391,6 +3407,9 @@ stoptermcap(void)
 	    /* May need to discard T_CRV, T_U7 or T_RBG response. */
 	    if (crv_status == STATUS_SENT
 		    || u7_status == STATUS_SENT
+# ifdef FEAT_TERMINAL
+		    || rfg_status == STATUS_SENT
+# endif
 		    || rbg_status == STATUS_SENT
 		    || rbm_status == STATUS_SENT
 		    || rcs_status == STATUS_SENT)
@@ -3508,16 +3527,30 @@ may_req_bg_color(void)
 {
     if (can_get_termresponse() && starting == 0)
     {
-	/* Only request background if t_RB is set and 'background' wasn't
-	 * changed. */
-	if (rbg_status == STATUS_GET
-		&& *T_RBG != NUL
-		&& !option_was_set((char_u *)"bg"))
+	int didit = FALSE;
+
+#ifdef FEAT_TERMINAL
+	/* Only request foreground if t_RF is set. */
+	if (rfg_status == STATUS_GET && *T_RFG != NUL)
+	{
+	    LOG_TR("Sending FG request");
+	    out_str(T_RFG);
+	    rfg_status = STATUS_SENT;
+	    didit = TRUE;
+	}
+#endif
+
+	/* Only request background if t_RB is set. */
+	if (rbg_status == STATUS_GET && *T_RBG != NUL)
 	{
 	    LOG_TR("Sending BG request");
 	    out_str(T_RBG);
 	    rbg_status = STATUS_SENT;
-
+	    didit = TRUE;
+	}
+
+	if (didit)
+	{
 	    /* check for the characters now, otherwise they might be eaten by
 	     * get_keystroke() */
 	    out_flush();
@@ -4688,46 +4721,72 @@ check_termcode(
 		}
 	    }
 
-	    /* Check for background color response from the terminal:
+	    /* Check for fore/background color response from the terminal:
 	     *
-	     *       {lead}11;rgb:{rrrr}/{gggg}/{bbbb}{tail}
+	     *       {lead}{code};rgb:{rrrr}/{gggg}/{bbbb}{tail}
 	     *
+	     * {code} is 10 for foreground, 11 for background
 	     * {lead} can be <Esc>] or OSC
 	     * {tail} can be '\007', <Esc>\ or STERM.
 	     *
 	     * Consume any code that starts with "{lead}11;", it's also
 	     * possible that "rgba" is following.
 	     */
-	    else if (*T_RBG != NUL
+	    else if ((*T_RBG != NUL || *T_RFG != NUL)
 			&& ((tp[0] == ESC && len >= 2 && tp[1] == ']')
 			    || tp[0] == OSC))
 	    {
 		j = 1 + (tp[0] == ESC);
 		if (len >= j + 3 && (argp[0] != '1'
-					 || argp[1] != '1' || argp[2] != ';'))
+					 || (argp[1] != '1' && argp[1] != '0')
+					 || argp[2] != ';'))
 		  i = 0; /* no match */
 		else
 		  for (i = j; i < len; ++i)
 		    if (tp[i] == '\007' || (tp[0] == OSC ? tp[i] == STERM
 			: (tp[i] == ESC && i + 1 < len && tp[i + 1] == '\\')))
 		    {
+			int is_bg = argp[1] == '1';
+
 			if (i - j >= 21 && STRNCMP(tp + j + 3, "rgb:", 4) == 0
-			    && tp[j + 11] == '/' && tp[j + 16] == '/'
-			    && !option_was_set((char_u *)"bg"))
+			    && tp[j + 11] == '/' && tp[j + 16] == '/')
 			{
-			    char *newval = (3 * '6' < tp[j+7] + tp[j+12]
+			    int rval = hexhex2nr(tp + j + 7);
+			    int gval = hexhex2nr(tp + j + 12);
+			    int bval = hexhex2nr(tp + j + 17);
+
+			    if (is_bg)
+			    {
+				char *newval = (3 * '6' < tp[j+7] + tp[j+12]
 						+ tp[j+17]) ? "light" : "dark";
 
-			    LOG_TR("Received RBG response");
-			    rbg_status = STATUS_GOT;
-			    if (STRCMP(p_bg, newval) != 0)
+				LOG_TR("Received RBG response");
+				rbg_status = STATUS_GOT;
+#ifdef FEAT_TERMINAL
+				bg_r = rval;
+				bg_g = gval;
+				bg_b = bval;
+#endif
+				if (!option_was_set((char_u *)"bg")
+						  && STRCMP(p_bg, newval) != 0)
+				{
+				    /* value differs, apply it */
+				    set_option_value((char_u *)"bg", 0L,
+							  (char_u *)newval, 0);
+				    reset_option_was_set((char_u *)"bg");
+				    redraw_asap(CLEAR);
+				}
+			    }
+#ifdef FEAT_TERMINAL
+			    else
 			    {
-				/* value differs, apply it */
-				set_option_value((char_u *)"bg", 0L,
-							  (char_u *)newval, 0);
-				reset_option_was_set((char_u *)"bg");
-				redraw_asap(CLEAR);
+				LOG_TR("Received RFG response");
+				rfg_status = STATUS_GOT;
+				fg_r = rval;
+				fg_g = gval;
+				fg_b = bval;
 			    }
+#endif
 			}
 
 			/* got finished code: consume it */
@@ -4735,7 +4794,8 @@ check_termcode(
 			key_name[1] = (int)KE_IGNORE;
 			slen = i + 1 + (tp[i] == ESC);
 # ifdef FEAT_EVAL
-			set_vim_var_string(VV_TERMRGBRESP, tp, slen);
+			set_vim_var_string(is_bg ? VV_TERMRBGRESP
+						   : VV_TERMRFGRESP, tp, slen);
 # endif
 			break;
 		    }
@@ -5768,6 +5828,36 @@ check_termcode(
     return 0;			    /* no match found */
 }
 
+#if defined(FEAT_TERMINAL) || defined(PROTO)
+/*
+ * Get the text foreground color, if known.
+ */
+    void
+term_get_fg_color(uint8_t *r, uint8_t *g, uint8_t *b)
+{
+    if (rfg_status == STATUS_GOT)
+    {
+	*r = fg_r;
+	*g = fg_g;
+	*b = fg_b;
+    }
+}
+
+/*
+ * Get the text background color, if known.
+ */
+    void
+term_get_bg_color(uint8_t *r, uint8_t *g, uint8_t *b)
+{
+    if (rbg_status == STATUS_GOT)
+    {
+	*r = bg_r;
+	*g = bg_g;
+	*b = bg_b;
+    }
+}
+#endif
+
 /*
  * Replace any terminal code strings in from[] with the equivalent internal
  * vim representation.	This is used for the "from" and "to" part of a