comparison src/objects-x.c @ 371:cc15677e0335 r21-2b1

Import from CVS: tag r21-2b1
author cvs
date Mon, 13 Aug 2007 11:03:08 +0200
parents 182f72e8cd0d
children 8626e4521993
comparison
equal deleted inserted replaced
370:bd866891f083 371:cc15677e0335
43 /* color instances */ 43 /* color instances */
44 /************************************************************************/ 44 /************************************************************************/
45 45
46 /* Replacement for XAllocColor() that tries to return the nearest 46 /* Replacement for XAllocColor() that tries to return the nearest
47 available color if the colormap is full. Original was from FSFmacs, 47 available color if the colormap is full. Original was from FSFmacs,
48 but rewritten by Jareth Hein <jareth@camelot-soft.com> 97/11/25 48 but rewritten by Jareth Hein <jareth@camelot-soft.com> 97/11/25 */
49 Modified by Lee Kindness <lkindness@csl.co.uk> 31/08/99 to handle previous 49
50 total failure which was due to a read/write colorcell being the nearest 50 /* Return value is 1 for normal success, 2 for nearest color success,
51 match - tries the next nearest... 51 3 for Non-deallocable sucess, and 0 for absolute failure (shouldn't
52 52 happen?) */
53 Return value is 1 for normal success, 2 for nearest color success,
54 3 for Non-deallocable sucess. */
55 int 53 int
56 allocate_nearest_color (Display *display, Colormap colormap, Visual *visual, 54 allocate_nearest_color (Display *display, Colormap colormap, Visual *visual,
57 XColor *color_def) 55 XColor *color_def)
58 { 56 {
59 int status; 57 int status;
140 } 138 }
141 } 139 }
142 } 140 }
143 else 141 else
144 { 142 {
145 XColor *cells = NULL;
146 /* JH: I can't believe there's no way to go backwards from a
147 colormap ID and get its visual and number of entries, but X
148 apparently isn't built that way... */
149 int no_cells = visual->map_entries;
150 status = 0;
151
152 if (XAllocColor (display, colormap, color_def) != 0) 143 if (XAllocColor (display, colormap, color_def) != 0)
153 status = 1; 144 status = 1;
154 else while( status != 2 ) 145 else
155 { 146 {
156 /* If we got to this point, the colormap is full, so we're 147 /* If we got to this point, the colormap is full, so we're
157 going to try and get the next closest color. The algorithm used 148 going to try and get the next closest color. The algorithm used
158 is a least-squares matching, which is what X uses for closest 149 is a least-squares matching, which is what X uses for closest
159 color matching with StaticColor visuals. */ 150 color matching with StaticColor visuals. */
151 XColor *cells;
152 /* JH: I can't believe there's no way to go backwards from a
153 colormap ID and get its visual and number of entries, but X
154 apparently isn't built that way... */
155 int no_cells = visual->map_entries;
160 int nearest; 156 int nearest;
161 long nearest_delta, trial_delta; 157 long nearest_delta, trial_delta;
162 int x; 158 int x;
163 159
164 if( cells == NULL ) 160 cells = alloca_array (XColor, no_cells);
165 { 161
166 cells = alloca_array (XColor, no_cells); 162 for (x = 0; x < no_cells; x++)
167 for (x = 0; x < no_cells; x++) 163 cells[x].pixel = x;
168 cells[x].pixel = x; 164
169 165 /* read the current colormap */
170 /* read the current colormap */ 166 XQueryColors (display, colormap, cells, no_cells);
171 XQueryColors (display, colormap, cells, no_cells);
172 }
173
174 nearest = 0; 167 nearest = 0;
175 /* I'm assuming CSE so I'm not going to condense this. */ 168 /* I'm assuming CSE so I'm not going to condense this. */
176 nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8)) 169 nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8))
177 * ((color_def->red >> 8) - (cells[0].red >> 8))) 170 * ((color_def->red >> 8) - (cells[0].red >> 8)))
178 + 171 +
189 (((color_def->green >> 8) - (cells[x].green >> 8)) 182 (((color_def->green >> 8) - (cells[x].green >> 8))
190 * ((color_def->green >> 8) - (cells[x].green >> 8))) 183 * ((color_def->green >> 8) - (cells[x].green >> 8)))
191 + 184 +
192 (((color_def->blue >> 8) - (cells[x].blue >> 8)) 185 (((color_def->blue >> 8) - (cells[x].blue >> 8))
193 * ((color_def->blue >> 8) - (cells[x].blue >> 8)))); 186 * ((color_def->blue >> 8) - (cells[x].blue >> 8))));
194 187 if (trial_delta < nearest_delta)
195 /* less? Ignore cells marked as previously failing */
196 if( (trial_delta < nearest_delta) && (cells[x].pixel != -1) )
197 { 188 {
198 nearest = x; 189 nearest = x;
199 nearest_delta = trial_delta; 190 nearest_delta = trial_delta;
200 } 191 }
201 } 192 }
202 color_def->red = cells[nearest].red; 193 color_def->red = cells[nearest].red;
203 color_def->green = cells[nearest].green; 194 color_def->green = cells[nearest].green;
204 color_def->blue = cells[nearest].blue; 195 color_def->blue = cells[nearest].blue;
205 if (XAllocColor (display, colormap, color_def) != 0) 196 if (XAllocColor (display, colormap, color_def) != 0) {
206 status = 2; 197 status = 2;
207 else 198 } else {
208 /* LSK: Either the colour map has changed since 199 status = 0; /* JH: how does this happen??? DOES this happen??? */
209 * we read it, or the colour is allocated 200 fprintf(stderr,"allocate_nearest_color returned 0!!!\n");
210 * read/write... Mark this cmap entry so it's 201 }
211 * ignored in the next iteration.
212 */
213 cells[nearest].pixel = -1;
214 } 202 }
215 } 203 }
216 return status; 204 return status;
217 } 205 }
218 206