]> granicus.if.org Git - vim/commitdiff
patch 7.4.757 v7.4.757
authorBram Moolenaar <Bram@vim.org>
Thu, 25 Jun 2015 15:03:36 +0000 (17:03 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 25 Jun 2015 15:03:36 +0000 (17:03 +0200)
Problem:    Cannot detect the background color of a terminal.
Solution:   Add T_RBG to request the background color if possible. (Lubomir
            Rintel)

src/main.c
src/proto/term.pro
src/term.c
src/term.h
src/version.c

index d20c4b09582fa3cb104a05d17cc5afaad66b4198..d9202c2e560a76e2e22df656604183aeb24ccd9b 100644 (file)
@@ -837,8 +837,11 @@ vim_main2(int argc UNUSED, char **argv UNUSED)
 
     starttermcap();        /* start termcap if not done by wait_return() */
     TIME_MSG("start termcap");
-#if defined(FEAT_TERMRESPONSE) && defined(FEAT_MBYTE)
+#if defined(FEAT_TERMRESPONSE)
+# if defined(FEAT_MBYTE)
     may_req_ambiguous_char_width();
+# endif
+    may_req_bg_color();
 #endif
 
 #ifdef FEAT_MOUSE
index b3d0df39d81ba968b0ce989363605a4fa2b7bee7..f0c2a01f484cc7d1b952de2f405839d59698ef3c 100644 (file)
@@ -36,6 +36,7 @@ void starttermcap __ARGS((void));
 void stoptermcap __ARGS((void));
 void may_req_termresponse __ARGS((void));
 void may_req_ambiguous_char_width __ARGS((void));
+void may_req_bg_color __ARGS((void));
 int swapping_screen __ARGS((void));
 void setmouse __ARGS((void));
 int mouse_has __ARGS((int c));
index ffe9d43f2b4a4be958f4ea811a66092be51a8fa0..0d684e00fd1fadada15d129fd6e6569eabe577bc 100644 (file)
@@ -124,6 +124,11 @@ static int crv_status = CRV_GET;
 #  define U7_SENT      2       /* did send T_U7, waiting for answer */
 #  define U7_GOT       3       /* received T_U7 response */
 static int u7_status = U7_GET;
+/* Request background color report: */
+#  define RBG_GET      1       /* send T_RBG when switched to RAW mode */
+#  define RBG_SENT     2       /* did send T_RBG, waiting for answer */
+#  define RBG_GOT      3       /* received T_RBG response */
+static int rbg_status = RBG_GET;
 # endif
 
 /*
@@ -949,6 +954,7 @@ static struct builtin_term builtin_termcaps[] =
     {(int)KS_CWP,      IF_EB("\033[3;%d;%dt", ESC_STR "[3;%d;%dt")},
 #  endif
     {(int)KS_CRV,      IF_EB("\033[>c", ESC_STR "[>c")},
+    {(int)KS_RBG,      IF_EB("\033]11;?\007", ESC_STR "]11;?\007")},
     {(int)KS_U7,       IF_EB("\033[6n", ESC_STR "[6n")},
 
     {K_UP,             IF_EB("\033O*A", ESC_STR "O*A")},
@@ -1240,6 +1246,7 @@ static struct builtin_term builtin_termcaps[] =
 #  endif
     {(int)KS_CRV,      "[CRV]"},
     {(int)KS_U7,       "[U7]"},
+    {(int)KS_RBG,      "[RBG]"},
     {K_UP,             "[KU]"},
     {K_DOWN,           "[KD]"},
     {K_LEFT,           "[KL]"},
@@ -3224,7 +3231,8 @@ settmode(tmode)
                 * doesn't work in Cooked mode, an external program may get
                 * them. */
                if (tmode != TMODE_RAW && (crv_status == CRV_SENT
-                                        || u7_status == U7_SENT))
+                                        || u7_status == U7_SENT
+                                        || rbg_status == RBG_SENT))
                    (void)vpeekc_nomap();
                check_for_codes_from_term();
            }
@@ -3285,8 +3293,9 @@ stoptermcap()
        if (!gui.in_use && !gui.starting)
 # endif
        {
-           /* May need to discard T_CRV or T_U7 response. */
-           if (crv_status == CRV_SENT || u7_status == U7_SENT)
+           /* May need to discard T_CRV, T_U7 or T_RBG response. */
+           if (crv_status == CRV_SENT || u7_status == U7_SENT
+                                                    || rbg_status == RBG_SENT)
            {
 # ifdef UNIX
                /* Give the terminal a chance to respond. */
@@ -3398,6 +3407,41 @@ may_req_ambiguous_char_width()
 }
 # endif
 
+#if defined(FEAT_TERMRESPONSE) || defined(PROTO)
+/*
+ * Check how the terminal treats ambiguous character width (UAX #11).
+ * First, we move the cursor to (1, 0) and print a test ambiguous character
+ * \u25bd (WHITE DOWN-POINTING TRIANGLE) and query current cursor position.
+ * If the terminal treats \u25bd as single width, the position is (1, 1),
+ * or if it is treated as double width, that will be (1, 2).
+ * This function has the side effect that changes cursor position, so
+ * it must be called immediately after entering termcap mode.
+ */
+    void
+may_req_bg_color()
+{
+    if (rbg_status == RBG_GET
+           && cur_tmode == TMODE_RAW
+           && termcap_active
+           && p_ek
+#  ifdef UNIX
+           && isatty(1)
+           && isatty(read_cmd_fd)
+#  endif
+           && *T_RBG != NUL
+           && !option_was_set((char_u *)"bg"))
+    {
+       LOG_TR("Sending BG request");
+       out_str(T_RBG);
+       rbg_status = RBG_SENT;
+       /* check for the characters now, otherwise they might be eaten by
+        * get_keystroke() */
+       out_flush();
+       (void)vpeekc_nomap();
+    }
+}
+# endif
+
 # ifdef DEBUG_TERMRESPONSE
     static void
 log_tr(char *msg)
@@ -4222,12 +4266,18 @@ check_termcode(max_offset, buf, bufsize, buflen)
             * - Cursor position report: <Esc>[{row};{col}R
             *   The final byte must be 'R'. It is used for checking the
             *   ambiguous-width character state.
+            *
+            * - Background color response:
+            *       <Esc>]11;rgb:{rrrr}/{gggg}/{bbbb}\007
+            *   The final byte must be '\007'.
             */
-           p = tp[0] == CSI ? tp + 1 : tp + 2;
-           if ((*T_CRV != NUL || *T_U7 != NUL)
+           char_u *argp = tp[0] == CSI ? tp + 1 : tp + 2;
+
+           if ((*T_CRV != NUL || *T_U7 != NUL || *T_RBG != NUL)
                        && ((tp[0] == ESC && tp[1] == '[' && len >= 3)
+                           || (tp[0] == ESC && tp[1] == ']' && len >= 24)
                            || (tp[0] == CSI && len >= 2))
-                       && (VIM_ISDIGIT(*p) || *p == '>' || *p == '?'))
+                       && (VIM_ISDIGIT(*argp) || *argp == '>' || *argp == '?'))
            {
 #ifdef FEAT_MBYTE
                int col;
@@ -4363,6 +4413,27 @@ check_termcode(max_offset, buf, bufsize, buflen)
                    key_name[1] = (int)KE_IGNORE;
                    slen = i + 1;
                }
+               else if (*T_RBG != NUL && len >= 24 - (tp[0] == CSI)
+                       && argp[0] == '1' && argp[1] == '1'
+                       && argp[2] == ';' && argp[3] == 'r' && argp[4] == 'g'
+                       && argp[5] == 'b' && argp[6] == ':'
+                       && argp[11] == '/' && argp[16] == '/'
+                       && argp[21] == '\007')
+               {
+                   LOG_TR("Received RBG");
+                   rbg_status = RBG_GOT;
+                   if (!option_was_set((char_u *)"bg"))
+                   {
+                       set_option_value((char_u *)"bg", 0L, (char_u *)(
+                                   (3 * '6' < argp[7] + argp[12] + argp[17])
+                                                     ? "light" : "dark"), 0);
+                       reset_option_was_set((char_u *)"bg");
+                       redraw_asap(CLEAR);
+                   }
+                   key_name[0] = (int)KS_EXTRA;
+                   key_name[1] = (int)KE_IGNORE;
+                   slen = 24;
+               }
            }
 
            /* Check for '<Esc>P1+r<hex bytes><Esc>\'.  A "0" instead of the
index 12d5eb90953a8f4a5fda5eda46de0afa1bac8575..07614ba1aaa2947c6d4fa0111d5a6ebae35d3158 100644 (file)
@@ -79,6 +79,7 @@ enum SpecialKey
     KS_CWP,    /* set window position in pixels */
     KS_CWS,    /* set window size in characters */
     KS_CRV,    /* request version string */
+    KS_RBG,    /* request background color */
     KS_CSI,    /* start insert mode (bar cursor) */
     KS_CEI,    /* end insert mode (block cursor) */
     KS_CSR,    /* start replace mode (underline cursor) */
@@ -162,6 +163,7 @@ extern char_u *(term_strings[]);    /* current terminal strings */
 #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_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 */
 
index ae01bdf8beff6b065d96754ef390e306e58234bf..917f71a652b5f93f762ab42bff4eaee2e8e027fc 100644 (file)
@@ -741,6 +741,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    757,
 /**/
     756,
 /**/