]> granicus.if.org Git - vim/commitdiff
patch 7.4.2094 v7.4.2094
authorBram Moolenaar <Bram@vim.org>
Sat, 23 Jul 2016 12:35:12 +0000 (14:35 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 23 Jul 2016 12:35:12 +0000 (14:35 +0200)
Problem:    The color allocation in X11 is overly complicated.
Solution:   Remove find_closest_color(), XAllocColor() already does this.
            (Kazunobu Kuriyama)

src/gui_x11.c
src/version.c

index 3ccc92a5539d23baf8785d374717a7922bcb3762..7f09880cd01b5080a37ab38f77fcfc0778bdb126 100644 (file)
 # define DFLT_MENU_FG_COLOR    "black"
 # define DFLT_SCROLL_BG_COLOR  "gray60"
 # define DFLT_SCROLL_FG_COLOR  "gray77"
-# define DFLT_TOOLTIP_BG_COLOR "#ffffffff9191"
-# define DFLT_TOOLTIP_FG_COLOR "#000000000000"
+# define DFLT_TOOLTIP_BG_COLOR "#ffff91"
+# define DFLT_TOOLTIP_FG_COLOR "#000000"
 #else
 /* use the default (CDE) colors */
 # define DFLT_MENU_BG_COLOR    ""
 # define DFLT_MENU_FG_COLOR    ""
 # define DFLT_SCROLL_BG_COLOR  ""
 # define DFLT_SCROLL_FG_COLOR  ""
-# define DFLT_TOOLTIP_BG_COLOR "#ffffffff9191"
-# define DFLT_TOOLTIP_FG_COLOR "#000000000000"
+# define DFLT_TOOLTIP_BG_COLOR "#ffff91"
+# define DFLT_TOOLTIP_FG_COLOR "#000000"
 #endif
 
 Widget vimShell = (Widget)0;
@@ -136,7 +136,6 @@ static guicolor_T   prev_sp_color = INVALCOLOR;
 static XButtonPressedEvent last_mouse_event;
 #endif
 
-static int find_closest_color(Colormap colormap, XColor *colorPtr);
 static void gui_x11_timer_cb(XtPointer timed_out, XtIntervalId *interval_id);
 static void gui_x11_visibility_cb(Widget w, XtPointer dud, XEvent *event, Boolean *dum);
 static void gui_x11_expose_cb(Widget w, XtPointer dud, XEvent *event, Boolean *dum);
@@ -2242,173 +2241,35 @@ fontset_ascent(XFontSet fs)
  * Return INVALCOLOR for error.
  */
     guicolor_T
-gui_mch_get_color(char_u *reqname)
+gui_mch_get_color(char_u *name)
 {
-    int                i;
-    char_u     *name = reqname;
+    guicolor_T  requested;
+    XColor      available;
     Colormap   colormap;
-    XColor      color;
-    static char *(vimnames[][2]) =
-    {
-       /* A number of colors that some X11 systems don't have */
-       {"LightRed",    "#FFBBBB"},
-       {"LightGreen",  "#88FF88"},
-       {"LightMagenta","#FFBBFF"},
-       {"DarkCyan",    "#008888"},
-       {"DarkBlue",    "#0000BB"},
-       {"DarkRed",     "#BB0000"},
-       {"DarkMagenta", "#BB00BB"},
-       {"DarkGrey",    "#BBBBBB"},
-       {"DarkYellow",  "#BBBB00"},
-       {"Gray10",      "#1A1A1A"},
-       {"Grey10",      "#1A1A1A"},
-       {"Gray20",      "#333333"},
-       {"Grey20",      "#333333"},
-       {"Gray30",      "#4D4D4D"},
-       {"Grey30",      "#4D4D4D"},
-       {"Gray40",      "#666666"},
-       {"Grey40",      "#666666"},
-       {"Gray50",      "#7F7F7F"},
-       {"Grey50",      "#7F7F7F"},
-       {"Gray60",      "#999999"},
-       {"Grey60",      "#999999"},
-       {"Gray70",      "#B3B3B3"},
-       {"Grey70",      "#B3B3B3"},
-       {"Gray80",      "#CCCCCC"},
-       {"Grey80",      "#CCCCCC"},
-       {"Gray90",      "#E5E5E5"},
-       {"Grey90",      "#E5E5E5"},
-       {NULL, NULL}
-    };
+#define COLORSPECBUFSIZE 8 /* space enough to hold "#RRGGBB" */
+    char        spec[COLORSPECBUFSIZE];
 
     /* can't do this when GUI not running */
-    if (!gui.in_use || *reqname == NUL)
+    if (!gui.in_use || name == NULL || *name == NUL)
        return INVALCOLOR;
 
-    colormap = DefaultColormap(gui.dpy, XDefaultScreen(gui.dpy));
-
-    /* Do this twice if the name isn't recognized. */
-    while (name != NULL)
-    {
-       i = XParseColor(gui.dpy, colormap, (char *)name, &color);
-
-#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
-       if (i == 0)
-       {
-           char *old;
-
-           /* The X11 system is trying to resolve named colors only by names
-            * corresponding to the current locale language.  But Vim scripts
-            * usually contain the English color names.  Therefore we have to
-            * try a second time here with the native "C" locale set.
-            * Hopefully, restoring the old locale this way works on all
-            * systems...
-            */
-           old = setlocale(LC_ALL, NULL);
-           if (old != NULL && STRCMP(old, "C") != 0)
-           {
-               old = (char *)vim_strsave((char_u *)old);
-               setlocale(LC_ALL, "C");
-               i = XParseColor(gui.dpy, colormap, (char *)name, &color);
-               setlocale(LC_ALL, old);
-               vim_free(old);
-           }
-       }
-#endif
-       if (i != 0 && (XAllocColor(gui.dpy, colormap, &color) != 0
-                   || find_closest_color(colormap, &color) == OK))
-           return (guicolor_T)color.pixel;
+    requested = gui_get_color_cmn(name);
+    if (requested == INVALCOLOR)
+       return INVALCOLOR;
 
-       /* check for a few builtin names */
-       for (i = 0; ; ++i)
-       {
-           if (vimnames[i][0] == NULL)
-           {
-               name = NULL;
-               break;
-           }
-           if (STRICMP(name, vimnames[i][0]) == 0)
-           {
-               name = (char_u *)vimnames[i][1];
-               break;
-           }
-       }
-    }
+    vim_snprintf(spec, COLORSPECBUFSIZE, "#%.2x%.2x%.2x",
+           (requested & 0xff0000) >> 16,
+           (requested & 0xff00) >> 8,
+           requested & 0xff);
+#undef COLORSPECBUFSIZE
+    colormap = DefaultColormap(gui.dpy, DefaultScreen(gui.dpy));
+    if (XParseColor(gui.dpy, colormap, (char *)spec, &available) != 0
+           && XAllocColor(gui.dpy, colormap, &available) != 0)
+       return (guicolor_T)available.pixel;
 
     return INVALCOLOR;
 }
 
-/*
- * Find closest color for "colorPtr" in "colormap".  set "colorPtr" to the
- * resulting color.
- * Based on a similar function in TCL.
- * Return FAIL if not able to find or allocate a color.
- */
-    static int
-find_closest_color(Colormap colormap, XColor *colorPtr)
-{
-    double     tmp, distance, closestDistance;
-    int                i, closest, numFound, cmap_size;
-    XColor     *colortable;
-    XVisualInfo        template, *visInfoPtr;
-
-    template.visualid = XVisualIDFromVisual(DefaultVisual(gui.dpy,
-                                                   XDefaultScreen(gui.dpy)));
-    visInfoPtr = XGetVisualInfo(gui.dpy, (long)VisualIDMask,
-                                                       &template, &numFound);
-    if (numFound < 1)
-       /* FindClosestColor couldn't lookup visual */
-       return FAIL;
-
-    cmap_size = visInfoPtr->colormap_size;
-    XFree((char *)visInfoPtr);
-    colortable = (XColor *)alloc((unsigned)(cmap_size * sizeof(XColor)));
-    if (!colortable)
-       return FAIL;  /* out of memory */
-
-    for (i = 0; i  < cmap_size; i++)
-       colortable[i].pixel = (unsigned long)i;
-    XQueryColors(gui.dpy, colormap, colortable, cmap_size);
-
-    /*
-     * Find the color that best approximates the desired one, then
-     * try to allocate that color.  If that fails, it must mean that
-     * the color was read-write (so we can't use it, since it's owner
-     * might change it) or else it was already freed.  Try again,
-     * over and over again, until something succeeds.
-     */
-    closestDistance = 1e30;
-    closest = 0;
-    for (i = 0; i < cmap_size; i++)
-    {
-       /*
-        * Use Euclidean distance in RGB space, weighted by Y (of YIQ)
-        * as the objective function;  this accounts for differences
-        * in the color sensitivity of the eye.
-        */
-       tmp = .30 * (((int)colorPtr->red) - (int)colortable[i].red);
-       distance = tmp * tmp;
-       tmp = .61 * (((int)colorPtr->green) - (int)colortable[i].green);
-       distance += tmp * tmp;
-       tmp = .11 * (((int)colorPtr->blue) - (int)colortable[i].blue);
-       distance += tmp * tmp;
-       if (distance < closestDistance)
-       {
-           closest = i;
-           closestDistance = distance;
-       }
-    }
-
-    if (XAllocColor(gui.dpy, colormap, &colortable[closest]) != 0)
-    {
-       gui.color_approx = TRUE;
-       *colorPtr = colortable[closest];
-    }
-
-    vim_free(colortable);
-    return OK;
-}
-
 /*
  * Set the current text foreground color.
  */
index 13c6bfed2d75983302428b8985a842362ea6ae68..0110c1d28b54bff3de6c12e326b6238d50e32a93 100644 (file)
@@ -758,6 +758,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2094,
 /**/
     2093,
 /**/