DRAW_IMAGE_SUNKEN
};
+static const XColor *x_color_cells P_ ((struct frame *, int *));
static void x_update_window_end P_ ((struct window *, int, int));
static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
void x_delete_display P_ ((struct x_display_info *));
#endif /* USE_X_TOOLKIT */
+/* Value is an array of XColor structures for the contents of the
+ color map of frame F. Set *NCELLS to the size of the array.
+ Note that this probably shouldn't be called for large color maps,
+ say a 24-bit TrueColor map. */
+
+static const XColor *
+x_color_cells (f, ncells)
+ struct frame *f;
+ int *ncells;
+{
+ struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+
+ if (dpyinfo->color_cells == NULL)
+ {
+ Display *display = FRAME_X_DISPLAY (f);
+ Screen *screen = FRAME_X_SCREEN (f);
+ int i;
+
+ dpyinfo->ncolor_cells
+ = XDisplayCells (display, XScreenNumberOfScreen (screen));
+ dpyinfo->color_cells
+ = (XColor *) xmalloc (dpyinfo->ncolor_cells
+ * sizeof *dpyinfo->color_cells);
+
+ for (i = 0; i < dpyinfo->ncolor_cells; ++i)
+ dpyinfo->color_cells[i].pixel = i;
+
+ XQueryColors (display, FRAME_X_COLORMAP (f),
+ dpyinfo->color_cells, dpyinfo->ncolor_cells);
+ }
+
+ *ncells = dpyinfo->ncolor_cells;
+ return dpyinfo->color_cells;
+}
+
+
+/* On frame F, translate pixel colors to RGB values for the NCOLORS
+ colors in COLORS. Use cached information, if available. */
+
+void
+x_query_colors (f, colors, ncolors)
+ struct frame *f;
+ XColor *colors;
+ int ncolors;
+{
+ struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+
+ if (dpyinfo->color_cells)
+ {
+ int i;
+ for (i = 0; i < ncolors; ++i)
+ {
+ unsigned long pixel = colors[i].pixel;
+ xassert (pixel < dpyinfo->ncolor_cells);
+ xassert (dpyinfo->color_cells[pixel].pixel == pixel);
+ colors[i] = dpyinfo->color_cells[pixel];
+ }
+ }
+ else
+ XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
+}
+
+
+/* On frame F, translate pixel color to RGB values for the color in
+ COLOR. Use cached information, if available. */
+
+void
+x_query_color (f, color)
+ struct frame *f;
+ XColor *color;
+{
+ x_query_colors (f, color, 1);
+}
+
+
/* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
CMAP. If an exact match can't be allocated, try the nearest color
available. Value is non-zero if successful. Set *COLOR to the
color matching with StaticColor visuals. */
int nearest, i;
unsigned long nearest_delta = ~0;
- int ncells = XDisplayCells (display, XScreenNumberOfScreen (screen));
- XColor *cells = (XColor *) alloca (ncells * sizeof *cells);
-
- for (i = 0; i < ncells; ++i)
- cells[i].pixel = i;
- XQueryColors (display, cmap, cells, ncells);
+ int ncells;
+ const XColor *cells = x_color_cells (f, &ncells);
for (nearest = i = 0; i < ncells; ++i)
{
color.pixel = pixel;
BLOCK_INPUT;
- XQueryColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
+ x_query_color (f, &color);
XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
UNBLOCK_INPUT;
#ifdef DEBUG_X_COLORS
/* Get RGB color values. */
color.pixel = *pixel;
- XQueryColor (display, cmap, &color);
+ x_query_color (f, &color);
/* Change RGB values by specified FACTOR. Avoid overflow! */
xassert (factor >= 0);
/* We have definitely succeeded. Record the new connection. */
dpyinfo = (struct x_display_info *) xmalloc (sizeof (struct x_display_info));
+ bzero (dpyinfo, sizeof *dpyinfo);
#ifdef MULTI_KBOARD
{
xfree (dpyinfo->font_table);
xfree (dpyinfo->x_id_name);
+ xfree (dpyinfo->color_cells);
xfree (dpyinfo);
}
+
\f
/* Set up use of X before we make the first connection. */