Skip to content

Commit 4658228

Browse files
committed
patch 7.4.2094
Problem: The color allocation in X11 is overly complicated. Solution: Remove find_closest_color(), XAllocColor() already does this. (Kazunobu Kuriyama)
1 parent a58c58b commit 4658228

2 files changed

Lines changed: 24 additions & 161 deletions

File tree

src/gui_x11.c

Lines changed: 22 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,16 @@
7171
# define DFLT_MENU_FG_COLOR "black"
7272
# define DFLT_SCROLL_BG_COLOR "gray60"
7373
# define DFLT_SCROLL_FG_COLOR "gray77"
74-
# define DFLT_TOOLTIP_BG_COLOR "#ffffffff9191"
75-
# define DFLT_TOOLTIP_FG_COLOR "#000000000000"
74+
# define DFLT_TOOLTIP_BG_COLOR "#ffff91"
75+
# define DFLT_TOOLTIP_FG_COLOR "#000000"
7676
#else
7777
/* use the default (CDE) colors */
7878
# define DFLT_MENU_BG_COLOR ""
7979
# define DFLT_MENU_FG_COLOR ""
8080
# define DFLT_SCROLL_BG_COLOR ""
8181
# define DFLT_SCROLL_FG_COLOR ""
82-
# define DFLT_TOOLTIP_BG_COLOR "#ffffffff9191"
83-
# define DFLT_TOOLTIP_FG_COLOR "#000000000000"
82+
# define DFLT_TOOLTIP_BG_COLOR "#ffff91"
83+
# define DFLT_TOOLTIP_FG_COLOR "#000000"
8484
#endif
8585

8686
Widget vimShell = (Widget)0;
@@ -136,7 +136,6 @@ static guicolor_T prev_sp_color = INVALCOLOR;
136136
static XButtonPressedEvent last_mouse_event;
137137
#endif
138138

139-
static int find_closest_color(Colormap colormap, XColor *colorPtr);
140139
static void gui_x11_timer_cb(XtPointer timed_out, XtIntervalId *interval_id);
141140
static void gui_x11_visibility_cb(Widget w, XtPointer dud, XEvent *event, Boolean *dum);
142141
static void gui_x11_expose_cb(Widget w, XtPointer dud, XEvent *event, Boolean *dum);
@@ -2242,173 +2241,35 @@ fontset_ascent(XFontSet fs)
22422241
* Return INVALCOLOR for error.
22432242
*/
22442243
guicolor_T
2245-
gui_mch_get_color(char_u *reqname)
2244+
gui_mch_get_color(char_u *name)
22462245
{
2247-
int i;
2248-
char_u *name = reqname;
2246+
guicolor_T requested;
2247+
XColor available;
22492248
Colormap colormap;
2250-
XColor color;
2251-
static char *(vimnames[][2]) =
2252-
{
2253-
/* A number of colors that some X11 systems don't have */
2254-
{"LightRed", "#FFBBBB"},
2255-
{"LightGreen", "#88FF88"},
2256-
{"LightMagenta","#FFBBFF"},
2257-
{"DarkCyan", "#008888"},
2258-
{"DarkBlue", "#0000BB"},
2259-
{"DarkRed", "#BB0000"},
2260-
{"DarkMagenta", "#BB00BB"},
2261-
{"DarkGrey", "#BBBBBB"},
2262-
{"DarkYellow", "#BBBB00"},
2263-
{"Gray10", "#1A1A1A"},
2264-
{"Grey10", "#1A1A1A"},
2265-
{"Gray20", "#333333"},
2266-
{"Grey20", "#333333"},
2267-
{"Gray30", "#4D4D4D"},
2268-
{"Grey30", "#4D4D4D"},
2269-
{"Gray40", "#666666"},
2270-
{"Grey40", "#666666"},
2271-
{"Gray50", "#7F7F7F"},
2272-
{"Grey50", "#7F7F7F"},
2273-
{"Gray60", "#999999"},
2274-
{"Grey60", "#999999"},
2275-
{"Gray70", "#B3B3B3"},
2276-
{"Grey70", "#B3B3B3"},
2277-
{"Gray80", "#CCCCCC"},
2278-
{"Grey80", "#CCCCCC"},
2279-
{"Gray90", "#E5E5E5"},
2280-
{"Grey90", "#E5E5E5"},
2281-
{NULL, NULL}
2282-
};
2249+
#define COLORSPECBUFSIZE 8 /* space enough to hold "#RRGGBB" */
2250+
char spec[COLORSPECBUFSIZE];
22832251

22842252
/* can't do this when GUI not running */
2285-
if (!gui.in_use || *reqname == NUL)
2253+
if (!gui.in_use || name == NULL || *name == NUL)
22862254
return INVALCOLOR;
22872255

2288-
colormap = DefaultColormap(gui.dpy, XDefaultScreen(gui.dpy));
2289-
2290-
/* Do this twice if the name isn't recognized. */
2291-
while (name != NULL)
2292-
{
2293-
i = XParseColor(gui.dpy, colormap, (char *)name, &color);
2294-
2295-
#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
2296-
if (i == 0)
2297-
{
2298-
char *old;
2299-
2300-
/* The X11 system is trying to resolve named colors only by names
2301-
* corresponding to the current locale language. But Vim scripts
2302-
* usually contain the English color names. Therefore we have to
2303-
* try a second time here with the native "C" locale set.
2304-
* Hopefully, restoring the old locale this way works on all
2305-
* systems...
2306-
*/
2307-
old = setlocale(LC_ALL, NULL);
2308-
if (old != NULL && STRCMP(old, "C") != 0)
2309-
{
2310-
old = (char *)vim_strsave((char_u *)old);
2311-
setlocale(LC_ALL, "C");
2312-
i = XParseColor(gui.dpy, colormap, (char *)name, &color);
2313-
setlocale(LC_ALL, old);
2314-
vim_free(old);
2315-
}
2316-
}
2317-
#endif
2318-
if (i != 0 && (XAllocColor(gui.dpy, colormap, &color) != 0
2319-
|| find_closest_color(colormap, &color) == OK))
2320-
return (guicolor_T)color.pixel;
2256+
requested = gui_get_color_cmn(name);
2257+
if (requested == INVALCOLOR)
2258+
return INVALCOLOR;
23212259

2322-
/* check for a few builtin names */
2323-
for (i = 0; ; ++i)
2324-
{
2325-
if (vimnames[i][0] == NULL)
2326-
{
2327-
name = NULL;
2328-
break;
2329-
}
2330-
if (STRICMP(name, vimnames[i][0]) == 0)
2331-
{
2332-
name = (char_u *)vimnames[i][1];
2333-
break;
2334-
}
2335-
}
2336-
}
2260+
vim_snprintf(spec, COLORSPECBUFSIZE, "#%.2x%.2x%.2x",
2261+
(requested & 0xff0000) >> 16,
2262+
(requested & 0xff00) >> 8,
2263+
requested & 0xff);
2264+
#undef COLORSPECBUFSIZE
2265+
colormap = DefaultColormap(gui.dpy, DefaultScreen(gui.dpy));
2266+
if (XParseColor(gui.dpy, colormap, (char *)spec, &available) != 0
2267+
&& XAllocColor(gui.dpy, colormap, &available) != 0)
2268+
return (guicolor_T)available.pixel;
23372269

23382270
return INVALCOLOR;
23392271
}
23402272

2341-
/*
2342-
* Find closest color for "colorPtr" in "colormap". set "colorPtr" to the
2343-
* resulting color.
2344-
* Based on a similar function in TCL.
2345-
* Return FAIL if not able to find or allocate a color.
2346-
*/
2347-
static int
2348-
find_closest_color(Colormap colormap, XColor *colorPtr)
2349-
{
2350-
double tmp, distance, closestDistance;
2351-
int i, closest, numFound, cmap_size;
2352-
XColor *colortable;
2353-
XVisualInfo template, *visInfoPtr;
2354-
2355-
template.visualid = XVisualIDFromVisual(DefaultVisual(gui.dpy,
2356-
XDefaultScreen(gui.dpy)));
2357-
visInfoPtr = XGetVisualInfo(gui.dpy, (long)VisualIDMask,
2358-
&template, &numFound);
2359-
if (numFound < 1)
2360-
/* FindClosestColor couldn't lookup visual */
2361-
return FAIL;
2362-
2363-
cmap_size = visInfoPtr->colormap_size;
2364-
XFree((char *)visInfoPtr);
2365-
colortable = (XColor *)alloc((unsigned)(cmap_size * sizeof(XColor)));
2366-
if (!colortable)
2367-
return FAIL; /* out of memory */
2368-
2369-
for (i = 0; i < cmap_size; i++)
2370-
colortable[i].pixel = (unsigned long)i;
2371-
XQueryColors(gui.dpy, colormap, colortable, cmap_size);
2372-
2373-
/*
2374-
* Find the color that best approximates the desired one, then
2375-
* try to allocate that color. If that fails, it must mean that
2376-
* the color was read-write (so we can't use it, since it's owner
2377-
* might change it) or else it was already freed. Try again,
2378-
* over and over again, until something succeeds.
2379-
*/
2380-
closestDistance = 1e30;
2381-
closest = 0;
2382-
for (i = 0; i < cmap_size; i++)
2383-
{
2384-
/*
2385-
* Use Euclidean distance in RGB space, weighted by Y (of YIQ)
2386-
* as the objective function; this accounts for differences
2387-
* in the color sensitivity of the eye.
2388-
*/
2389-
tmp = .30 * (((int)colorPtr->red) - (int)colortable[i].red);
2390-
distance = tmp * tmp;
2391-
tmp = .61 * (((int)colorPtr->green) - (int)colortable[i].green);
2392-
distance += tmp * tmp;
2393-
tmp = .11 * (((int)colorPtr->blue) - (int)colortable[i].blue);
2394-
distance += tmp * tmp;
2395-
if (distance < closestDistance)
2396-
{
2397-
closest = i;
2398-
closestDistance = distance;
2399-
}
2400-
}
2401-
2402-
if (XAllocColor(gui.dpy, colormap, &colortable[closest]) != 0)
2403-
{
2404-
gui.color_approx = TRUE;
2405-
*colorPtr = colortable[closest];
2406-
}
2407-
2408-
vim_free(colortable);
2409-
return OK;
2410-
}
2411-
24122273
/*
24132274
* Set the current text foreground color.
24142275
*/

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,8 @@ static char *(features[]) =
758758

759759
static int included_patches[] =
760760
{ /* Add new patch number below this line */
761+
/**/
762+
2094,
761763
/**/
762764
2093,
763765
/**/

0 commit comments

Comments
 (0)