XEmacs 21.2.20 "Yoko".
[chise/xemacs-chise.git.1] / src / objects-x.c
index 29d51cf..536228c 100644 (file)
@@ -28,6 +28,7 @@ Boston, MA 02111-1307, USA.  */
 
 #include <config.h>
 #include "lisp.h"
+#include <limits.h>
 
 #include "console-x.h"
 #include "objects-x.h"
@@ -45,11 +46,13 @@ int x_handle_non_fully_specified_fonts;
 
 /* Replacement for XAllocColor() that tries to return the nearest
    available color if the colormap is full.  Original was from FSFmacs,
-   but rewritten by Jareth Hein <jareth@camelot-soft.com> 97/11/25 */
+   but rewritten by Jareth Hein <jareth@camelot-soft.com> 97/11/25
+   Modified by Lee Kindness <lkindness@csl.co.uk> 31/08/99 to handle previous
+   total failure which was due to a read/write colorcell being the nearest
+   match - tries the next nearest...
 
-/* Return value is 1 for normal success, 2 for nearest color success,
-   3 for Non-deallocable sucess, and 0 for absolute failure (shouldn't
-   happen?) */
+   Return value is 1 for normal success, 2 for nearest color success,
+   3 for Non-deallocable sucess. */
 int
 allocate_nearest_color (Display *display, Colormap colormap, Visual *visual,
                        XColor *color_def)
@@ -140,30 +143,35 @@ allocate_nearest_color (Display *display, Colormap colormap, Visual *visual,
     }
   else
     {
+      XColor *cells = NULL;
+      /* JH: I can't believe there's no way to go backwards from a
+        colormap ID and get its visual and number of entries, but X
+        apparently isn't built that way... */
+      int no_cells = visual->map_entries;
+      status = 0;
+
       if (XAllocColor (display, colormap, color_def) != 0)
        status = 1;
-      else
+      else while( status != 2 )
        {
          /* If we got to this point, the colormap is full, so we're
             going to try and get the next closest color.  The algorithm used
             is a least-squares matching, which is what X uses for closest
             color matching with StaticColor visuals. */
-         XColor *cells;
-         /* JH: I can't believe there's no way to go backwards from a
-            colormap ID and get its visual and number of entries, but X
-            apparently isn't built that way... */
-         int no_cells = visual->map_entries;
          int nearest;
          long nearest_delta, trial_delta;
          int x;
 
-         cells = alloca_array (XColor, no_cells);
+         if( cells == NULL )
+             {
+                 cells = alloca_array (XColor, no_cells);
+                 for (x = 0; x < no_cells; x++)
+                     cells[x].pixel = x;
 
-         for (x = 0; x < no_cells; x++)
-           cells[x].pixel = x;
+                 /* read the current colormap */
+                 XQueryColors (display, colormap, cells, no_cells);
+             }
 
-         /* read the current colormap */
-         XQueryColors (display, colormap, cells, no_cells);
          nearest = 0;
          /* I'm assuming CSE so I'm not going to condense this. */
          nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8))
@@ -184,7 +192,10 @@ allocate_nearest_color (Display *display, Colormap colormap, Visual *visual,
                             +
                             (((color_def->blue >> 8) - (cells[x].blue >> 8))
                              * ((color_def->blue >> 8) - (cells[x].blue >> 8))));
-             if (trial_delta < nearest_delta)
+
+             /* less? Ignore cells marked as previously failing */
+             if( (trial_delta < nearest_delta) &&
+                 (cells[x].pixel != ULONG_MAX) )
                {
                  nearest = x;
                  nearest_delta = trial_delta;
@@ -193,12 +204,15 @@ allocate_nearest_color (Display *display, Colormap colormap, Visual *visual,
          color_def->red = cells[nearest].red;
          color_def->green = cells[nearest].green;
          color_def->blue = cells[nearest].blue;
-         if (XAllocColor (display, colormap, color_def) != 0) {
-           status = 2;
-         } else {
-           status = 0; /* JH: how does this happen??? DOES this happen??? */
-           fprintf(stderr,"allocate_nearest_color returned 0!!!\n");
-         }
+         if (XAllocColor (display, colormap, color_def) != 0)
+             status = 2;
+         else
+             /* LSK: Either the colour map has changed since
+              * we read it, or the colour is allocated
+              * read/write... Mark this cmap entry so it's
+              * ignored in the next iteration.
+              */
+             cells[nearest].pixel = ULONG_MAX;
        }
     }
   return status;
@@ -208,15 +222,11 @@ int
 x_parse_nearest_color (struct device *d, XColor *color, Bufbyte *name,
                       Bytecount len, Error_behavior errb)
 {
-  Display *dpy;
-  Colormap cmap;
-  Visual *visual;
+  Display *dpy   = DEVICE_X_DISPLAY  (d);
+  Colormap cmap  = DEVICE_X_COLORMAP (d);
+  Visual *visual = DEVICE_X_VISUAL   (d);
   int result;
 
-  dpy = DEVICE_X_DISPLAY (d);
-  cmap = DEVICE_X_COLORMAP(d);
-  visual = DEVICE_X_VISUAL (d);
-
   xzero (*color);
   {
     CONST Extbyte *extname;
@@ -447,10 +457,9 @@ x_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object name,
 }
 
 static void
-x_mark_font_instance (struct Lisp_Font_Instance *f,
-                      void (*markobj) (Lisp_Object))
+x_mark_font_instance (struct Lisp_Font_Instance *f)
 {
-  markobj (FONT_INSTANCE_X_TRUENAME (f));
+  mark_object (FONT_INSTANCE_X_TRUENAME (f));
 }
 
 static void