Mercurial > emacs
changeset 10920:bb3f9aaf0e46
(defined_color): If colormap is full, find closest match.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Mon, 06 Mar 1995 04:33:56 +0000 |
parents | ebae5c953523 |
children | bf33c9179a6b |
files | src/xfns.c |
diffstat | 1 files changed, 62 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/src/xfns.c Mon Mar 06 04:32:25 1995 +0000 +++ b/src/xfns.c Mon Mar 06 04:33:56 1995 +0000 @@ -963,6 +963,7 @@ : FRAME_ICONIFIED_P (f) ? Qicon : Qnil)); } + /* Decide if color named COLOR is valid for the display associated with the selected frame; if so, return the rgb values in COLOR_DEF. If ALLOC is nonzero, allocate a new colormap cell. */ @@ -974,20 +975,72 @@ XColor *color_def; int alloc; { - register int foo; + register int status; Colormap screen_colormap; + Display *display = FRAME_X_DISPLAY (f); BLOCK_INPUT; - screen_colormap - = DefaultColormap (FRAME_X_DISPLAY (f), - XDefaultScreen (FRAME_X_DISPLAY (f))); - - foo = XParseColor (FRAME_X_DISPLAY (f), screen_colormap, color, color_def); - if (foo && alloc) - foo = XAllocColor (FRAME_X_DISPLAY (f), screen_colormap, color_def); + screen_colormap = DefaultColormap (display, XDefaultScreen (display)); + + status = XParseColor (display, screen_colormap, color, color_def); + if (status && alloc) + { + status = XAllocColor (display, screen_colormap, color_def); + if (!status) + { + /* If we got to this point, the colormap is full, so we're + going to try and get the next closest color. + The algorithm used is a least-squares matching, which is + what X uses for closest color matching with StaticColor visuals. */ + + XColor *cells; + int no_cells; + int nearest; + long nearest_delta, trial_delta; + int x; + + no_cells = XDisplayCells (display, XDefaultScreen (display)); + cells = (XColor *) alloca (sizeof (XColor) * no_cells); + + for (x = 0; x < no_cells; x++) + cells[x].pixel = x; + + XQueryColors (display, screen_colormap, cells, no_cells); + nearest = 0; + /* I'm assuming CSE so I'm not going to condense this. */ + nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8)) + * ((color_def->red >> 8) - (cells[0].red >> 8))) + + + (((color_def->green >> 8) - (cells[0].green >> 8)) + * ((color_def->green >> 8) - (cells[0].green >> 8))) + + + (((color_def->blue >> 8) - (cells[0].blue >> 8)) + * ((color_def->blue >> 8) - (cells[0].blue >> 8)))); + for (x = 1; x < no_cells; x++) + { + trial_delta = ((((color_def->red >> 8) - (cells[x].red >> 8)) + * ((color_def->red >> 8) - (cells[x].red >> 8))) + + + (((color_def->green >> 8) - (cells[x].green >> 8)) + * ((color_def->green >> 8) - (cells[x].green >> 8))) + + + + (((color_def->blue >> 8) - (cells[x].blue >> 8)) + * ((color_def->blue >> 8) - (cells[x].blue >> 8)))); + if (trial_delta < nearest_delta) + { + nearest = x; + nearest_delta = trial_delta; + } + } + color_def->red = cells[nearest].red; + color_def->green = cells[nearest].green; + color_def->blue = cells[nearest].blue; + status = XAllocColor (display, screen_colormap, color_def); + } + } UNBLOCK_INPUT; - if (foo) + if (status) return 1; else return 0;