changeset 9634:86d470495333 v7.4.2094

commit https://github.com/vim/vim/commit/4658228262f491fcb582d531d4e8e5754b0d5e83 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jul 23 14:35:12 2016 +0200 patch 7.4.2094 Problem: The color allocation in X11 is overly complicated. Solution: Remove find_closest_color(), XAllocColor() already does this. (Kazunobu Kuriyama)
author Christian Brabandt <cb@256bit.org>
date Sat, 23 Jul 2016 14:45:05 +0200
parents c2fba797633f
children 974a40c76e19
files src/gui_x11.c src/version.c
diffstat 2 files changed, 25 insertions(+), 162 deletions(-) [+]
line wrap: on
line diff
--- a/src/gui_x11.c
+++ b/src/gui_x11.c
@@ -71,16 +71,16 @@
 # 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 = INVALC
 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,174 +2241,36 @@ 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;
+
+    requested = gui_get_color_cmn(name);
+    if (requested == INVALCOLOR)
 	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;
-
-	/* 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.
  */
     void
--- a/src/version.c
+++ b/src/version.c
@@ -759,6 +759,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2094,
+/**/
     2093,
 /**/
     2092,