Mercurial > hg > xemacs-beta
diff src/objects-x.c @ 355:182f72e8cd0d r21-1-7
Import from CVS: tag r21-1-7
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:56:21 +0200 |
parents | c5d627a313b1 |
children | cc15677e0335 |
line wrap: on
line diff
--- a/src/objects-x.c Mon Aug 13 10:55:35 2007 +0200 +++ b/src/objects-x.c Mon Aug 13 10:56:21 2007 +0200 @@ -45,11 +45,13 @@ /* Replacement for XAllocColor() that tries to return the nearest available color if the colormap is full. Original was from FSFmacs, - but rewritten by Jareth Hein <jareth@camelot-soft.com> 97/11/25 */ + but rewritten by Jareth Hein <jareth@camelot-soft.com> 97/11/25 + Modified by Lee Kindness <lkindness@csl.co.uk> 31/08/99 to handle previous + total failure which was due to a read/write colorcell being the nearest + match - tries the next nearest... -/* Return value is 1 for normal success, 2 for nearest color success, - 3 for Non-deallocable sucess, and 0 for absolute failure (shouldn't - happen?) */ + Return value is 1 for normal success, 2 for nearest color success, + 3 for Non-deallocable sucess. */ int allocate_nearest_color (Display *display, Colormap colormap, Visual *visual, XColor *color_def) @@ -140,30 +142,35 @@ } else { + XColor *cells = NULL; + /* JH: I can't believe there's no way to go backwards from a + colormap ID and get its visual and number of entries, but X + apparently isn't built that way... */ + int no_cells = visual->map_entries; + status = 0; + if (XAllocColor (display, colormap, color_def) != 0) status = 1; - else + else while( status != 2 ) { /* 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; - /* JH: I can't believe there's no way to go backwards from a - colormap ID and get its visual and number of entries, but X - apparently isn't built that way... */ - int no_cells = visual->map_entries; int nearest; long nearest_delta, trial_delta; int x; - cells = alloca_array (XColor, no_cells); + if( cells == NULL ) + { + cells = alloca_array (XColor, no_cells); + for (x = 0; x < no_cells; x++) + cells[x].pixel = x; - for (x = 0; x < no_cells; x++) - cells[x].pixel = x; + /* read the current colormap */ + XQueryColors (display, colormap, cells, no_cells); + } - /* read the current colormap */ - XQueryColors (display, 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)) @@ -184,7 +191,9 @@ + (((color_def->blue >> 8) - (cells[x].blue >> 8)) * ((color_def->blue >> 8) - (cells[x].blue >> 8)))); - if (trial_delta < nearest_delta) + + /* less? Ignore cells marked as previously failing */ + if( (trial_delta < nearest_delta) && (cells[x].pixel != -1) ) { nearest = x; nearest_delta = trial_delta; @@ -193,12 +202,15 @@ color_def->red = cells[nearest].red; color_def->green = cells[nearest].green; color_def->blue = cells[nearest].blue; - if (XAllocColor (display, colormap, color_def) != 0) { - status = 2; - } else { - status = 0; /* JH: how does this happen??? DOES this happen??? */ - fprintf(stderr,"allocate_nearest_color returned 0!!!\n"); - } + if (XAllocColor (display, colormap, color_def) != 0) + status = 2; + else + /* LSK: Either the colour map has changed since + * we read it, or the colour is allocated + * read/write... Mark this cmap entry so it's + * ignored in the next iteration. + */ + cells[nearest].pixel = -1; } } return status;