changeset 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 3e8f6b06e414
children c247f9a0e56a
files runtime/doc/eval.txt src/eval.c src/proto/term.pro src/term.c src/term.h src/terminal.c src/version.c src/vim.h
diffstat 8 files changed, 148 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1912,11 +1912,16 @@ v:termstyleresp	The escape sequence retu
 		termcap entry.  This is used to find out what the shape of the
 		cursor is.  This is used by |term_getcursor()|.
 
-						*v:termrgbresp*
-v:termrgbresp	The escape sequence returned by the terminal for the |t_RB|
+						*v:termrbgresp*
+v:termrbgresp	The escape sequence returned by the terminal for the |t_RB|
 		termcap entry.  This is used to find out what the terminal
 		background color is, see 'background'.
 
+						*v:termrfgresp*
+v:termrfgresp	The escape sequence returned by the terminal for the |t_RF|
+		termcap entry.  This is used to find out what the terminal
+		foreground color is.
+
 						*v:termu7resp*
 v:termu7resp	The escape sequence returned by the terminal for the |t_u7|
 		termcap entry.  This is used to find out what the terminal
--- a/src/eval.c
+++ b/src/eval.c
@@ -187,7 +187,8 @@ static struct vimvar
     {VV_NAME("t_none",		 VAR_NUMBER), VV_RO},
     {VV_NAME("t_job",		 VAR_NUMBER), VV_RO},
     {VV_NAME("t_channel",	 VAR_NUMBER), VV_RO},
-    {VV_NAME("termrgbresp",	 VAR_STRING), VV_RO},
+    {VV_NAME("termrfgresp",	 VAR_STRING), VV_RO},
+    {VV_NAME("termrbgresp",	 VAR_STRING), VV_RO},
     {VV_NAME("termu7resp",	 VAR_STRING), VV_RO},
     {VV_NAME("termstyleresp",	VAR_STRING), VV_RO},
     {VV_NAME("termblinkresp",	VAR_STRING), VV_RO},
--- a/src/proto/term.pro
+++ b/src/proto/term.pro
@@ -64,6 +64,8 @@ char_u *get_termcode(int i);
 void del_termcode(char_u *name);
 void set_mouse_topline(win_T *wp);
 int check_termcode(int max_offset, char_u *buf, int bufsize, int *buflen);
+void term_get_fg_color(uint8_t *r, uint8_t *g, uint8_t *b);
+void term_get_bg_color(uint8_t *r, uint8_t *g, uint8_t *b);
 char_u *replace_termcodes(char_u *from, char_u **bufp, int from_part, int do_lt, int special);
 int find_term_bykeys(char_u *src);
 void show_termcodes(void);
--- 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
--- a/src/term.h
+++ b/src/term.h
@@ -88,6 +88,7 @@ enum SpecialKey
     KS_CGP,	/* get window position */
     KS_CWS,	/* set window size in characters */
     KS_CRV,	/* request version string */
+    KS_RFG,	/* request foreground color */
     KS_RBG,	/* request background color */
     KS_CSI,	/* start insert mode (bar cursor) */
     KS_CEI,	/* end insert mode (block cursor) */
@@ -185,6 +186,7 @@ extern char_u *(term_strings[]);    /* c
 #define T_CEI	(TERM_STR(KS_CEI))	/* end insert mode */
 #define T_CSR	(TERM_STR(KS_CSR))	/* start replace mode */
 #define T_CRV	(TERM_STR(KS_CRV))	/* request version string */
+#define T_RFG	(TERM_STR(KS_RFG))	/* request foreground RGB */
 #define T_RBG	(TERM_STR(KS_RBG))	/* request background RGB */
 #define T_OP	(TERM_STR(KS_OP))	/* original color pair */
 #define T_U7	(TERM_STR(KS_U7))	/* request cursor position */
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -40,12 +40,12 @@
  * TODO:
  * - in GUI vertical split causes problems.  Cursor is flickering. (Hirohito
  *   Higashi, 2017 Sep 19)
- * - Can we get the default fg/bg color of the terminal and use it for
- *   libvterm?  Should also fix ssh-in-a-win.
+ * - patch to handle composing characters. (Ozaki Kiichi, #2195)
  * - double click in Window toolbar starts Visual mode (but not always?).
  * - Shift-Tab does not work.
  * - after resizing windows overlap. (Boris Staletic, #2164)
  * - :wall gives an error message. (Marius Gedminas, #2190)
+ *   patch suggested by Yasuhiro Matsumoto, Oct 10
  * - Redirecting output does not work on MS-Windows, Test_terminal_redir_file()
  *   is disabled.
  * - cursor blinks in terminal on widows with a timer. (xtal8, #2142)
@@ -59,7 +59,7 @@
  * - GUI: when 'confirm' is set and trying to exit Vim, dialog offers to save
  *   changes to "!shell".
  *   (justrajdeep, 2017 Aug 22)
- * - Redrawing is slow with Athena and Motif.
+ * - Redrawing is slow with Athena and Motif.  Also other GUI? (Ramel Eshed)
  * - For the GUI fill termios with default values, perhaps like pangoterm:
  *   http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134
  * - if the job in the terminal does not support the mouse, we can use the
@@ -2608,28 +2608,37 @@ create_vterm(term_T *term, int rows, int
 	if (cterm_bg >= 0)
 	    cterm_color2rgb(cterm_bg, bg);
     }
-#if defined(WIN3264) && !defined(FEAT_GUI_W32)
     else
     {
+#if defined(WIN3264) && !defined(FEAT_GUI_W32)
 	int tmp;
+#endif
 
 	/* In an MS-Windows console we know the normal colors. */
 	if (cterm_normal_fg_color > 0)
 	{
 	    cterm_color2rgb(cterm_normal_fg_color - 1, fg);
+# if defined(WIN3264) && !defined(FEAT_GUI_W32)
 	    tmp = fg->red;
 	    fg->red = fg->blue;
 	    fg->blue = tmp;
+# endif
 	}
+	else
+	    term_get_fg_color(&fg->red, &fg->green, &fg->blue);
+
 	if (cterm_normal_bg_color > 0)
 	{
 	    cterm_color2rgb(cterm_normal_bg_color - 1, bg);
+# if defined(WIN3264) && !defined(FEAT_GUI_W32)
 	    tmp = bg->red;
 	    bg->red = bg->blue;
 	    bg->blue = tmp;
+# endif
 	}
+	else
+	    term_get_bg_color(&bg->red, &bg->green, &bg->blue);
     }
-#endif
 
     vterm_state_set_default_colors(vterm_obtain_state(vterm), fg, bg);
 
--- a/src/version.c
+++ b/src/version.c
@@ -762,6 +762,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1194,
+/**/
     1193,
 /**/
     1192,
--- a/src/vim.h
+++ b/src/vim.h
@@ -1998,11 +1998,12 @@ typedef int sock_T;
 #define VV_TYPE_NONE	78
 #define VV_TYPE_JOB	79
 #define VV_TYPE_CHANNEL	80
-#define VV_TERMRGBRESP	81
-#define VV_TERMU7RESP	82
-#define VV_TERMSTYLERESP 83
-#define VV_TERMBLINKRESP 84
-#define VV_LEN		85	/* number of v: vars */
+#define VV_TERMRFGRESP	81
+#define VV_TERMRBGRESP	82
+#define VV_TERMU7RESP	83
+#define VV_TERMSTYLERESP 84
+#define VV_TERMBLINKRESP 85
+#define VV_LEN		86	/* number of v: vars */
 
 /* used for v_number in VAR_SPECIAL */
 #define VVAL_FALSE	0L