comparison src/xfns.c @ 28096:244f283b3d03

(x_defined_color): Rewritten to use x_allocate_nearest_color.
author Gerd Moellmann <gerd@gnu.org>
date Sun, 12 Mar 2000 12:52:29 +0000
parents 79a67f9da183
children 71ebba3566ec
comparison
equal deleted inserted replaced
28095:087d75357c03 28096:244f283b3d03
1230 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5; 1230 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
1231 } 1231 }
1232 } 1232 }
1233 1233
1234 1234
1235 /* Decide if color named COLOR is valid for the display associated with 1235 /* Decide if color named COLOR_NAME is valid for use on frame F. If
1236 the selected frame; if so, return the rgb values in COLOR_DEF. 1236 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
1237 If ALLOC is nonzero, allocate a new colormap cell. */ 1237 allocate the color. Value is zero if COLOR_NAME is invalid, or
1238 no color could be allocated. */
1238 1239
1239 int 1240 int
1240 x_defined_color (f, color, color_def, alloc) 1241 x_defined_color (f, color_name, color, alloc_p)
1241 FRAME_PTR f; 1242 struct frame *f;
1242 char *color; 1243 char *color_name;
1243 XColor *color_def; 1244 XColor *color;
1244 int alloc; 1245 int alloc_p;
1245 { 1246 {
1246 register int status; 1247 int success_p;
1247 Colormap screen_colormap; 1248 Display *dpy = FRAME_X_DISPLAY (f);
1248 Display *display = FRAME_X_DISPLAY (f); 1249 Colormap cmap = FRAME_X_COLORMAP (f);
1249 1250
1250 BLOCK_INPUT; 1251 BLOCK_INPUT;
1251 screen_colormap = FRAME_X_COLORMAP (f); 1252 success_p = XParseColor (dpy, cmap, color_name, color);
1252 1253 if (success_p && alloc_p)
1253 status = XParseColor (display, screen_colormap, color, color_def); 1254 success_p = x_alloc_nearest_color (f, cmap, color);
1254 if (status && alloc)
1255 {
1256 /* Apply gamma correction. */
1257 gamma_correct (f, color_def);
1258
1259 status = XAllocColor (display, screen_colormap, color_def);
1260 if (!status)
1261 {
1262 /* If we got to this point, the colormap is full, so we're
1263 going to try and get the next closest color.
1264 The algorithm used is a least-squares matching, which is
1265 what X uses for closest color matching with StaticColor visuals. */
1266
1267 XColor *cells;
1268 int no_cells;
1269 int nearest;
1270 long nearest_delta, trial_delta;
1271 int x;
1272
1273 no_cells = XDisplayCells (display, XDefaultScreen (display));
1274 cells = (XColor *) alloca (sizeof (XColor) * no_cells);
1275
1276 for (x = 0; x < no_cells; x++)
1277 cells[x].pixel = x;
1278
1279 XQueryColors (display, screen_colormap, cells, no_cells);
1280 nearest = 0;
1281 /* I'm assuming CSE so I'm not going to condense this. */
1282 nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8))
1283 * ((color_def->red >> 8) - (cells[0].red >> 8)))
1284 +
1285 (((color_def->green >> 8) - (cells[0].green >> 8))
1286 * ((color_def->green >> 8) - (cells[0].green >> 8)))
1287 +
1288 (((color_def->blue >> 8) - (cells[0].blue >> 8))
1289 * ((color_def->blue >> 8) - (cells[0].blue >> 8))));
1290 for (x = 1; x < no_cells; x++)
1291 {
1292 trial_delta = ((((color_def->red >> 8) - (cells[x].red >> 8))
1293 * ((color_def->red >> 8) - (cells[x].red >> 8)))
1294 +
1295 (((color_def->green >> 8) - (cells[x].green >> 8))
1296 * ((color_def->green >> 8) - (cells[x].green >> 8)))
1297 +
1298 (((color_def->blue >> 8) - (cells[x].blue >> 8))
1299 * ((color_def->blue >> 8) - (cells[x].blue >> 8))));
1300 if (trial_delta < nearest_delta)
1301 {
1302 XColor temp;
1303 temp.red = cells[x].red;
1304 temp.green = cells[x].green;
1305 temp.blue = cells[x].blue;
1306 status = XAllocColor (display, screen_colormap, &temp);
1307 if (status)
1308 {
1309 nearest = x;
1310 nearest_delta = trial_delta;
1311 }
1312 }
1313 }
1314 color_def->red = cells[nearest].red;
1315 color_def->green = cells[nearest].green;
1316 color_def->blue = cells[nearest].blue;
1317 status = XAllocColor (display, screen_colormap, color_def);
1318 }
1319 }
1320 UNBLOCK_INPUT; 1255 UNBLOCK_INPUT;
1321 1256
1322 if (status) 1257 return success_p;
1323 return 1;
1324 else
1325 return 0;
1326 } 1258 }
1327 1259
1328 1260
1329 /* Return the pixel color value for color COLOR_NAME on frame F. If F 1261 /* Return the pixel color value for color COLOR_NAME on frame F. If F
1330 is a monochrome frame, return MONO_COLOR regardless of what ARG says. 1262 is a monochrome frame, return MONO_COLOR regardless of what ARG says.