To: vim_dev@googlegroups.com Subject: Patch 7.4.2094 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.2094 Problem: The color allocation in X11 is overly complicated. Solution: Remove find_closest_color(), XAllocColor() already does this. (Kazunobu Kuriyama) Files: src/gui_x11.c *** ../vim-7.4.2093/src/gui_x11.c 2016-07-07 16:42:57.318788362 +0200 --- src/gui_x11.c 2016-07-23 14:06:47.970608223 +0200 *************** *** 71,86 **** # 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" #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" #endif Widget vimShell = (Widget)0; --- 71,86 ---- # define DFLT_MENU_FG_COLOR "black" # define DFLT_SCROLL_BG_COLOR "gray60" # define DFLT_SCROLL_FG_COLOR "gray77" ! # 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 "#ffff91" ! # define DFLT_TOOLTIP_FG_COLOR "#000000" #endif Widget vimShell = (Widget)0; *************** *** 136,142 **** 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); --- 136,141 ---- *************** *** 2242,2415 **** * Return INVALCOLOR for error. */ guicolor_T ! gui_mch_get_color(char_u *reqname) { ! int i; ! char_u *name = reqname; 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} ! }; /* can't do this when GUI not running */ ! if (!gui.in_use || *reqname == 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; ! /* 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; ! } ! } ! } 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 --- 2241,2276 ---- * Return INVALCOLOR for error. */ guicolor_T ! gui_mch_get_color(char_u *name) { ! guicolor_T requested; ! XColor available; Colormap colormap; ! #define COLORSPECBUFSIZE 8 /* space enough to hold "#RRGGBB" */ ! char spec[COLORSPECBUFSIZE]; /* can't do this when GUI not running */ ! if (!gui.in_use || name == NULL || *name == NUL) return INVALCOLOR; ! requested = gui_get_color_cmn(name); ! if (requested == INVALCOLOR) ! return INVALCOLOR; ! 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; } /* * Set the current text foreground color. */ void *** ../vim-7.4.2093/src/version.c 2016-07-23 14:01:11.393652479 +0200 --- src/version.c 2016-07-23 14:34:46.443242019 +0200 *************** *** 760,761 **** --- 760,763 ---- { /* Add new patch number below this line */ + /**/ + 2094, /**/ -- Mental Floss prevents moral decay! /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///