From: Po Lu Date: Sat, 7 May 2022 09:01:44 +0000 (+0800) Subject: Cache color lookup failures as well X-Git-Tag: emacs-29.0.90~1910^2~941 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=2fe4523518db061067b62b004e619e91653bb36a;p=emacs.git Cache color lookup failures as well * src/xterm.c (x_parse_color): Cache color lookup failures too. * src/xterm.h (struct color_name_cache_entry): New field `valid'. --- diff --git a/src/xterm.c b/src/xterm.c index 2141964c747..c841240a72b 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -6933,11 +6933,12 @@ x_parse_color (struct frame *f, const char *color_name, XColor *color) { unsigned short r, g, b; - Display *dpy = FRAME_X_DISPLAY (f); - Colormap cmap = FRAME_X_COLORMAP (f); + Display *dpy; + Colormap cmap; struct x_display_info *dpyinfo; struct color_name_cache_entry *cache_entry; unsigned int hash, idx; + int rc; /* Don't pass #RGB strings directly to XParseColor, because that follows the X convention of zero-extending each channel @@ -6949,37 +6950,49 @@ x_parse_color (struct frame *f, const char *color_name, color->red = r; color->green = g; color->blue = b; + return 1; } + /* Some X servers send BadValue on empty color names. */ + if (!strlen (color_name)) + return 0; + + cmap = FRAME_X_COLORMAP (f); + dpy = FRAME_X_DISPLAY (f); dpyinfo = FRAME_DISPLAY_INFO (f); + hash = x_hash_string_ignore_case (color_name); idx = hash % dpyinfo->color_names_size; - for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names[idx]; + for (cache_entry = dpyinfo->color_names[idx]; cache_entry; cache_entry = cache_entry->next) { if (!xstrcasecmp (cache_entry->name, color_name)) { - *color = cache_entry->rgb; - return 1; + if (cache_entry->valid) + *color = cache_entry->rgb; + + return cache_entry->valid; } } - /* Some X servers send BadValue on empty color names. */ - if (!strlen (color_name)) - return 0; - - if (XParseColor (dpy, cmap, color_name, color) == 0) - /* No caching of negative results, currently. */ - return 0; + block_input (); + rc = XParseColor (dpy, cmap, color_name, color); + unblock_input (); cache_entry = xzalloc (sizeof *cache_entry); - cache_entry->rgb = *color; + + if (rc) + cache_entry->rgb = *color; + + cache_entry->valid = rc; cache_entry->name = xstrdup (color_name); - cache_entry->next = FRAME_DISPLAY_INFO (f)->color_names[idx]; - FRAME_DISPLAY_INFO (f)->color_names[idx] = cache_entry; - return 1; + cache_entry->next = dpyinfo->color_names[idx]; + + dpyinfo->color_names[idx] = cache_entry; + + return rc; } diff --git a/src/xterm.h b/src/xterm.h index 3e06564bee9..66c4b178234 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -196,8 +196,15 @@ extern cairo_pattern_t *x_bitmap_stipple (struct frame *, Pixmap); struct color_name_cache_entry { struct color_name_cache_entry *next; + + /* The color values of the cached color entry. */ XColor rgb; + + /* The name of the cached color. */ char *name; + + /* Whether or not RGB is valid (i.e. the color actually exists). */ + bool_bf valid : 1; }; #ifdef HAVE_XINPUT2