On Fri, Jun 21, 2019 at 1:54 AM Richard Stallman wrote: > > We're still using the X convention. It's time to switch. The HTML > > convention is what virtually everyone would expect these days, it > > allows specifying "white" concisely, and it's what we use in some > > contexts, such as when rendering SVGs. > > It seems plausible to me, speaking as a non-expert. Here's a patch. I've read the documentation and it appears already to have been updated by someone so it no longer links to the X documentation. * src/xterm.c (x_parse_color): Translate #RGB notation to rgb:R/G/B notation, which X handles slightly differently. --- src/xterm.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/xterm.c b/src/xterm.c index 1acff2af0d..614774f6bc 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -2381,6 +2381,8 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor) x_query_colors (f, bgcolor, 1); } +#define HEX_COLOR_NAME_LENGTH 32 + /* On frame F, translate the color name to RGB values. Use cached information, if possible. @@ -2398,9 +2400,35 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor) if (color_name[0] == '#') { - /* The hex form is parsed directly by XParseColor without + /* Don't pass #RGB strings directly to XParseColor, because that + follows the old convention of zero-extending each channel + value: #f00 means #f00000. We want the new convention of + scaling channel values, so #f00 means #ff0000. + + So we translate #f00 to rgb:f/0/0, which X handles + differently. */ + char rgb_color_name[HEX_COLOR_NAME_LENGTH]; + int len = strlen (color_name); + int digits_per_channel; + if (len == 4) + digits_per_channel = 1; + else if (len == 7) + digits_per_channel = 2; + else if (len == 10) + digits_per_channel = 3; + else if (len == 13) + digits_per_channel = 4; + else + return 0; + + snprintf (rgb_color_name, sizeof rgb_color_name, "rgb:%.*s/%.*s/%.*s", + digits_per_channel, color_name + 1, + digits_per_channel, color_name + digits_per_channel + 1, + digits_per_channel, color_name + 2 * digits_per_channel + 1); + + /* The rgb form is parsed directly by XParseColor without talking to the X server. No need for caching. */ - return XParseColor (dpy, cmap, color_name, color); + return XParseColor (dpy, cmap, rgb_color_name, color); } for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry; -- 2.20.1