changeset 32607:00d2748a616a

(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.
author Gerd Moellmann <gerd@gnu.org>
date Wed, 18 Oct 2000 11:58:07 +0000
parents 78b4e9f31087
children 0c09f18456e3
files src/xterm.c
diffstat 1 files changed, 83 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/xterm.c	Wed Oct 18 11:57:35 2000 +0000
+++ b/src/xterm.c	Wed Oct 18 11:58:07 2000 +0000
@@ -396,6 +396,7 @@
   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 *));
@@ -3289,6 +3290,81 @@
 #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
@@ -3314,12 +3390,8 @@
 	 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)
 	{
@@ -3363,7 +3435,7 @@
 
   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
@@ -3418,7 +3490,7 @@
 
   /* 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);
@@ -13280,6 +13352,7 @@
   /* 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
   {
@@ -13631,8 +13704,10 @@
   
   xfree (dpyinfo->font_table);
   xfree (dpyinfo->x_id_name);
+  xfree (dpyinfo->color_cells);
   xfree (dpyinfo);
 }
+
 
 /* Set up use of X before we make the first connection.  */