diff options
| author | Gerd Moellmann | 2000-10-18 11:58:07 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2000-10-18 11:58:07 +0000 |
| commit | f04e1297ecb8613fadd8c27b9caf92de37fab2cf (patch) | |
| tree | 275e3798f2aaeb49cf663574f4761818f16eaef0 /src | |
| parent | a31fedb766dcf23f1df3fc8cc639dece5d2ab27e (diff) | |
| download | emacs-f04e1297ecb8613fadd8c27b9caf92de37fab2cf.tar.gz emacs-f04e1297ecb8613fadd8c27b9caf92de37fab2cf.zip | |
(x_color_cells, x_query_colors, x_query_color): New
functions.
(x_alloc_nearest_color): Use it to reduce calls to XQueryColors
which can be slow.
(x_copy_color, x_alloc_lighter_color): Likewise.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 91 |
1 files changed, 83 insertions, 8 deletions
diff --git a/src/xterm.c b/src/xterm.c index bb64fb1fc4f..a7698218ebc 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -396,6 +396,7 @@ enum draw_glyphs_face | |||
| 396 | DRAW_IMAGE_SUNKEN | 396 | DRAW_IMAGE_SUNKEN |
| 397 | }; | 397 | }; |
| 398 | 398 | ||
| 399 | static const XColor *x_color_cells P_ ((struct frame *, int *)); | ||
| 399 | static void x_update_window_end P_ ((struct window *, int, int)); | 400 | static void x_update_window_end P_ ((struct window *, int, int)); |
| 400 | static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *)); | 401 | static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *)); |
| 401 | void x_delete_display P_ ((struct x_display_info *)); | 402 | void x_delete_display P_ ((struct x_display_info *)); |
| @@ -3289,6 +3290,81 @@ x_alloc_lighter_color_for_widget (widget, display, cmap, pixel, factor, delta) | |||
| 3289 | #endif /* USE_X_TOOLKIT */ | 3290 | #endif /* USE_X_TOOLKIT */ |
| 3290 | 3291 | ||
| 3291 | 3292 | ||
| 3293 | /* Value is an array of XColor structures for the contents of the | ||
| 3294 | color map of frame F. Set *NCELLS to the size of the array. | ||
| 3295 | Note that this probably shouldn't be called for large color maps, | ||
| 3296 | say a 24-bit TrueColor map. */ | ||
| 3297 | |||
| 3298 | static const XColor * | ||
| 3299 | x_color_cells (f, ncells) | ||
| 3300 | struct frame *f; | ||
| 3301 | int *ncells; | ||
| 3302 | { | ||
| 3303 | struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); | ||
| 3304 | |||
| 3305 | if (dpyinfo->color_cells == NULL) | ||
| 3306 | { | ||
| 3307 | Display *display = FRAME_X_DISPLAY (f); | ||
| 3308 | Screen *screen = FRAME_X_SCREEN (f); | ||
| 3309 | int i; | ||
| 3310 | |||
| 3311 | dpyinfo->ncolor_cells | ||
| 3312 | = XDisplayCells (display, XScreenNumberOfScreen (screen)); | ||
| 3313 | dpyinfo->color_cells | ||
| 3314 | = (XColor *) xmalloc (dpyinfo->ncolor_cells | ||
| 3315 | * sizeof *dpyinfo->color_cells); | ||
| 3316 | |||
| 3317 | for (i = 0; i < dpyinfo->ncolor_cells; ++i) | ||
| 3318 | dpyinfo->color_cells[i].pixel = i; | ||
| 3319 | |||
| 3320 | XQueryColors (display, FRAME_X_COLORMAP (f), | ||
| 3321 | dpyinfo->color_cells, dpyinfo->ncolor_cells); | ||
| 3322 | } | ||
| 3323 | |||
| 3324 | *ncells = dpyinfo->ncolor_cells; | ||
| 3325 | return dpyinfo->color_cells; | ||
| 3326 | } | ||
| 3327 | |||
| 3328 | |||
| 3329 | /* On frame F, translate pixel colors to RGB values for the NCOLORS | ||
| 3330 | colors in COLORS. Use cached information, if available. */ | ||
| 3331 | |||
| 3332 | void | ||
| 3333 | x_query_colors (f, colors, ncolors) | ||
| 3334 | struct frame *f; | ||
| 3335 | XColor *colors; | ||
| 3336 | int ncolors; | ||
| 3337 | { | ||
| 3338 | struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); | ||
| 3339 | |||
| 3340 | if (dpyinfo->color_cells) | ||
| 3341 | { | ||
| 3342 | int i; | ||
| 3343 | for (i = 0; i < ncolors; ++i) | ||
| 3344 | { | ||
| 3345 | unsigned long pixel = colors[i].pixel; | ||
| 3346 | xassert (pixel < dpyinfo->ncolor_cells); | ||
| 3347 | xassert (dpyinfo->color_cells[pixel].pixel == pixel); | ||
| 3348 | colors[i] = dpyinfo->color_cells[pixel]; | ||
| 3349 | } | ||
| 3350 | } | ||
| 3351 | else | ||
| 3352 | XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors); | ||
| 3353 | } | ||
| 3354 | |||
| 3355 | |||
| 3356 | /* On frame F, translate pixel color to RGB values for the color in | ||
| 3357 | COLOR. Use cached information, if available. */ | ||
| 3358 | |||
| 3359 | void | ||
| 3360 | x_query_color (f, color) | ||
| 3361 | struct frame *f; | ||
| 3362 | XColor *color; | ||
| 3363 | { | ||
| 3364 | x_query_colors (f, color, 1); | ||
| 3365 | } | ||
| 3366 | |||
| 3367 | |||
| 3292 | /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap | 3368 | /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap |
| 3293 | CMAP. If an exact match can't be allocated, try the nearest color | 3369 | CMAP. If an exact match can't be allocated, try the nearest color |
| 3294 | available. Value is non-zero if successful. Set *COLOR to the | 3370 | available. Value is non-zero if successful. Set *COLOR to the |
| @@ -3314,12 +3390,8 @@ x_alloc_nearest_color (f, cmap, color) | |||
| 3314 | color matching with StaticColor visuals. */ | 3390 | color matching with StaticColor visuals. */ |
| 3315 | int nearest, i; | 3391 | int nearest, i; |
| 3316 | unsigned long nearest_delta = ~0; | 3392 | unsigned long nearest_delta = ~0; |
| 3317 | int ncells = XDisplayCells (display, XScreenNumberOfScreen (screen)); | 3393 | int ncells; |
| 3318 | XColor *cells = (XColor *) alloca (ncells * sizeof *cells); | 3394 | const XColor *cells = x_color_cells (f, &ncells); |
| 3319 | |||
| 3320 | for (i = 0; i < ncells; ++i) | ||
| 3321 | cells[i].pixel = i; | ||
| 3322 | XQueryColors (display, cmap, cells, ncells); | ||
| 3323 | 3395 | ||
| 3324 | for (nearest = i = 0; i < ncells; ++i) | 3396 | for (nearest = i = 0; i < ncells; ++i) |
| 3325 | { | 3397 | { |
| @@ -3363,7 +3435,7 @@ x_copy_color (f, pixel) | |||
| 3363 | 3435 | ||
| 3364 | color.pixel = pixel; | 3436 | color.pixel = pixel; |
| 3365 | BLOCK_INPUT; | 3437 | BLOCK_INPUT; |
| 3366 | XQueryColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color); | 3438 | x_query_color (f, &color); |
| 3367 | XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color); | 3439 | XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color); |
| 3368 | UNBLOCK_INPUT; | 3440 | UNBLOCK_INPUT; |
| 3369 | #ifdef DEBUG_X_COLORS | 3441 | #ifdef DEBUG_X_COLORS |
| @@ -3418,7 +3490,7 @@ x_alloc_lighter_color (f, display, cmap, pixel, factor, delta) | |||
| 3418 | 3490 | ||
| 3419 | /* Get RGB color values. */ | 3491 | /* Get RGB color values. */ |
| 3420 | color.pixel = *pixel; | 3492 | color.pixel = *pixel; |
| 3421 | XQueryColor (display, cmap, &color); | 3493 | x_query_color (f, &color); |
| 3422 | 3494 | ||
| 3423 | /* Change RGB values by specified FACTOR. Avoid overflow! */ | 3495 | /* Change RGB values by specified FACTOR. Avoid overflow! */ |
| 3424 | xassert (factor >= 0); | 3496 | xassert (factor >= 0); |
| @@ -13280,6 +13352,7 @@ x_term_init (display_name, xrm_option, resource_name) | |||
| 13280 | /* We have definitely succeeded. Record the new connection. */ | 13352 | /* We have definitely succeeded. Record the new connection. */ |
| 13281 | 13353 | ||
| 13282 | dpyinfo = (struct x_display_info *) xmalloc (sizeof (struct x_display_info)); | 13354 | dpyinfo = (struct x_display_info *) xmalloc (sizeof (struct x_display_info)); |
| 13355 | bzero (dpyinfo, sizeof *dpyinfo); | ||
| 13283 | 13356 | ||
| 13284 | #ifdef MULTI_KBOARD | 13357 | #ifdef MULTI_KBOARD |
| 13285 | { | 13358 | { |
| @@ -13631,8 +13704,10 @@ x_delete_display (dpyinfo) | |||
| 13631 | 13704 | ||
| 13632 | xfree (dpyinfo->font_table); | 13705 | xfree (dpyinfo->font_table); |
| 13633 | xfree (dpyinfo->x_id_name); | 13706 | xfree (dpyinfo->x_id_name); |
| 13707 | xfree (dpyinfo->color_cells); | ||
| 13634 | xfree (dpyinfo); | 13708 | xfree (dpyinfo); |
| 13635 | } | 13709 | } |
| 13710 | |||
| 13636 | 13711 | ||
| 13637 | /* Set up use of X before we make the first connection. */ | 13712 | /* Set up use of X before we make the first connection. */ |
| 13638 | 13713 | ||