comparison 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
comparison
equal deleted inserted replaced
354:3729bef672e0 355:182f72e8cd0d
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 49 Modified by Lee Kindness <lkindness@csl.co.uk> 31/08/99 to handle previous
50 /* Return value is 1 for normal success, 2 for nearest color success, 50 total failure which was due to a read/write colorcell being the nearest
51 3 for Non-deallocable sucess, and 0 for absolute failure (shouldn't 51 match - tries the next nearest...
52 happen?) */ 52
53 Return value is 1 for normal success, 2 for nearest color success,
54 3 for Non-deallocable sucess. */
53 int 55 int
54 allocate_nearest_color (Display *display, Colormap colormap, Visual *visual, 56 allocate_nearest_color (Display *display, Colormap colormap, Visual *visual,
55 XColor *color_def) 57 XColor *color_def)
56 { 58 {
57 int status; 59 int status;
138 } 140 }
139 } 141 }
140 } 142 }
141 else 143 else
142 { 144 {
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
143 if (XAllocColor (display, colormap, color_def) != 0) 152 if (XAllocColor (display, colormap, color_def) != 0)
144 status = 1; 153 status = 1;
145 else 154 else while( status != 2 )
146 { 155 {
147 /* If we got to this point, the colormap is full, so we're 156 /* If we got to this point, the colormap is full, so we're
148 going to try and get the next closest color. The algorithm used 157 going to try and get the next closest color. The algorithm used
149 is a least-squares matching, which is what X uses for closest 158 is a least-squares matching, which is what X uses for closest
150 color matching with StaticColor visuals. */ 159 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;
156 int nearest; 160 int nearest;
157 long nearest_delta, trial_delta; 161 long nearest_delta, trial_delta;
158 int x; 162 int x;
159 163
160 cells = alloca_array (XColor, no_cells); 164 if( cells == NULL )
161 165 {
162 for (x = 0; x < no_cells; x++) 166 cells = alloca_array (XColor, no_cells);
163 cells[x].pixel = x; 167 for (x = 0; x < no_cells; x++)
164 168 cells[x].pixel = x;
165 /* read the current colormap */ 169
166 XQueryColors (display, colormap, cells, no_cells); 170 /* read the current colormap */
171 XQueryColors (display, colormap, cells, no_cells);
172 }
173
167 nearest = 0; 174 nearest = 0;
168 /* I'm assuming CSE so I'm not going to condense this. */ 175 /* I'm assuming CSE so I'm not going to condense this. */
169 nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8)) 176 nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8))
170 * ((color_def->red >> 8) - (cells[0].red >> 8))) 177 * ((color_def->red >> 8) - (cells[0].red >> 8)))
171 + 178 +
182 (((color_def->green >> 8) - (cells[x].green >> 8)) 189 (((color_def->green >> 8) - (cells[x].green >> 8))
183 * ((color_def->green >> 8) - (cells[x].green >> 8))) 190 * ((color_def->green >> 8) - (cells[x].green >> 8)))
184 + 191 +
185 (((color_def->blue >> 8) - (cells[x].blue >> 8)) 192 (((color_def->blue >> 8) - (cells[x].blue >> 8))
186 * ((color_def->blue >> 8) - (cells[x].blue >> 8)))); 193 * ((color_def->blue >> 8) - (cells[x].blue >> 8))));
187 if (trial_delta < nearest_delta) 194
195 /* less? Ignore cells marked as previously failing */
196 if( (trial_delta < nearest_delta) && (cells[x].pixel != -1) )
188 { 197 {
189 nearest = x; 198 nearest = x;
190 nearest_delta = trial_delta; 199 nearest_delta = trial_delta;
191 } 200 }
192 } 201 }
193 color_def->red = cells[nearest].red; 202 color_def->red = cells[nearest].red;
194 color_def->green = cells[nearest].green; 203 color_def->green = cells[nearest].green;
195 color_def->blue = cells[nearest].blue; 204 color_def->blue = cells[nearest].blue;
196 if (XAllocColor (display, colormap, color_def) != 0) { 205 if (XAllocColor (display, colormap, color_def) != 0)
197 status = 2; 206 status = 2;
198 } else { 207 else
199 status = 0; /* JH: how does this happen??? DOES this happen??? */ 208 /* LSK: Either the colour map has changed since
200 fprintf(stderr,"allocate_nearest_color returned 0!!!\n"); 209 * we read it, or the colour is allocated
201 } 210 * read/write... Mark this cmap entry so it's
211 * ignored in the next iteration.
212 */
213 cells[nearest].pixel = -1;
202 } 214 }
203 } 215 }
204 return status; 216 return status;
205 } 217 }
206 218