XEmacs 21.4.9 "Informed Management".
[chise/xemacs-chise.git.1] / src / glyphs.c
index d69bb2d..6fbe951 100644 (file)
@@ -46,7 +46,7 @@ Boston, MA 02111-1307, USA.  */
 #include "specifier.h"
 #include "window.h"
 
-#ifdef HAVE_XPM
+#if defined (HAVE_XPM) && !defined (HAVE_GTK)
 #include <X11/xpm.h>
 #endif
 
@@ -382,7 +382,7 @@ process_image_string_instantiator (Lisp_Object data,
         skip it. */
       if (!(dest_mask &
            IIFORMAT_METH (decode_image_instantiator_format
-                          (XVECTOR_DATA (typevec)[0], ERROR_ME),
+                          (INSTANTIATOR_TYPE (typevec), ERROR_ME),
                           possible_dest_types, ())))
        continue;
       if (fast_string_match (exp, 0, data, 0, -1, 0, ERROR_ME, 0) >= 0)
@@ -689,7 +689,7 @@ get_image_instantiator_governing_domain (Lisp_Object instantiator,
   int governing_domain;
 
   struct image_instantiator_methods *meths =
-    decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
+    decode_image_instantiator_format (INSTANTIATOR_TYPE (instantiator),
                                      ERROR_ME);
   governing_domain = IIFORMAT_METH_OR_GIVEN (meths, governing_domain, (),
                                             GOVERNING_DOMAIN_DEVICE);
@@ -742,7 +742,7 @@ normalize_image_instantiator (Lisp_Object instantiator,
 
     GCPRO1 (instantiator);
 
-    meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
+    meths = decode_image_instantiator_format (INSTANTIATOR_TYPE (instantiator),
                                              ERROR_ME);
     RETURN_UNGCPRO (IIFORMAT_METH_OR_GIVEN (meths, normalize,
                                            (instantiator, contype, dest_mask),
@@ -765,20 +765,20 @@ instantiate_image_instantiator (Lisp_Object governing_domain,
   struct gcpro gcpro1;
 
   GCPRO1 (ii);
-  if (!valid_image_instantiator_format_p (XVECTOR_DATA (instantiator)[0],
+  if (!valid_image_instantiator_format_p (INSTANTIATOR_TYPE (instantiator),
                                          DOMAIN_DEVICE (governing_domain)))
     signal_simple_error
       ("Image instantiator format is invalid in this locale.",
        instantiator);
 
-  meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
+  meths = decode_image_instantiator_format (INSTANTIATOR_TYPE (instantiator),
                                            ERROR_ME);
   MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg,
                                            pointer_bg, dest_mask, domain));
 
   /* Now do device specific instantiation. */
   device_meths = decode_device_ii_format (DOMAIN_DEVICE (governing_domain),
-                                         XVECTOR_DATA (instantiator)[0],
+                                         INSTANTIATOR_TYPE (instantiator),
                                          ERROR_ME_NOT);
 
   if (!HAS_IIFORMAT_METH_P (meths, instantiate)
@@ -1004,7 +1004,7 @@ print_image_instance (Lisp_Object obj, Lisp_Object printcharfun,
          print_internal
            (IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0);
        }
-
+      /* fallthrough */
 
     case IMAGE_SUBWINDOW:
       sprintf (buf, " %dx%d", IMAGE_INSTANCE_WIDTH (ii),
@@ -1469,7 +1469,7 @@ make_image_instance_1 (Lisp_Object data, Lisp_Object domain,
   GCPRO1 (data);
   /* After normalizing the data, it's always either an image instance (which
      we filtered out above) or a vector. */
-  if (EQ (XVECTOR_DATA (data)[0], Qinherit))
+  if (EQ (INSTANTIATOR_TYPE (data), Qinherit))
     signal_simple_error ("Inheritance not allowed here", data);
   governing_domain =
     get_image_instantiator_governing_domain (data, domain);
@@ -1992,9 +1992,6 @@ image_instance_layout (Lisp_Object image_instance,
   assert (XIMAGE_INSTANCE_YOFFSET (image_instance) >= 0
          && XIMAGE_INSTANCE_XOFFSET (image_instance) >= 0);
 
-  type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
-  meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
-
   /* If geometry is unspecified then get some reasonable values for it. */
   if (width == IMAGE_UNSPECIFIED_GEOMETRY
       ||
@@ -2002,20 +1999,11 @@ image_instance_layout (Lisp_Object image_instance,
     {
       int dwidth = IMAGE_UNSPECIFIED_GEOMETRY;
       int dheight = IMAGE_UNSPECIFIED_GEOMETRY;
-
       /* Get the desired geometry. */
-      if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry))
-       {
-         IIFORMAT_METH (meths, query_geometry, (image_instance, &dwidth, &dheight,
-                                                IMAGE_DESIRED_GEOMETRY,
-                                                domain));
-       }
-      else
-       {
-         dwidth = IMAGE_INSTANCE_WIDTH (ii);
-         dheight = IMAGE_INSTANCE_HEIGHT (ii);
-       }
-
+      image_instance_query_geometry (image_instance,
+                                    &dwidth, &dheight,
+                                    IMAGE_DESIRED_GEOMETRY,
+                                    domain);
       /* Compare with allowed geometry. */
       if (width == IMAGE_UNSPECIFIED_GEOMETRY)
        width = dwidth;
@@ -2042,12 +2030,15 @@ image_instance_layout (Lisp_Object image_instance,
   IMAGE_INSTANCE_WIDTH (ii) = width;
   IMAGE_INSTANCE_HEIGHT (ii) = height;
 
-  if (IIFORMAT_METH_OR_GIVEN (meths, layout,
-                             (image_instance, width, height, xoffset, yoffset,
-                              domain), 1))
-    /* Do not clear the dirty flag here - redisplay will do this for
-       us at the end. */
-    IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 0;
+  type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
+  meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
+
+  MAYBE_IIFORMAT_METH (meths, layout,
+                      (image_instance, width, height, xoffset, yoffset,
+                       domain));
+  /* Do not clear the dirty flag here - redisplay will do this for
+     us at the end. */
+  IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 0;
 }
 
 /* Update an image instance from its changed instantiator. */
@@ -2279,6 +2270,8 @@ query_string_geometry (Lisp_Object string, Lisp_Object face,
   struct face_cachel *cachel;
   Lisp_Object frame = DOMAIN_FRAME (domain);
 
+  CHECK_STRING (string);
+
   /* Compute height */
   if (height)
     {
@@ -2820,6 +2813,14 @@ xface_possible_dest_types (void)
  *                             XPM                                    *
  **********************************************************************/
 
+#ifdef HAVE_GTK
+/* Gtk has to be gratuitously different, eh? */
+Lisp_Object
+pixmap_to_lisp_data (Lisp_Object name, int ok_if_data_invalid)
+{
+  return (make_string_from_file (name));
+}
+#else
 Lisp_Object
 pixmap_to_lisp_data (Lisp_Object name, int ok_if_data_invalid)
 {
@@ -2901,6 +2902,7 @@ pixmap_to_lisp_data (Lisp_Object name, int ok_if_data_invalid)
 
   return Qnil; /* not reached */
 }
+#endif /* !HAVE_GTK */
 
 static void
 check_valid_xpm_color_symbols (Lisp_Object data)
@@ -3054,6 +3056,44 @@ image_mark (Lisp_Object obj)
   mark_object (IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image));
 }
 
+static int
+instantiator_eq_equal (Lisp_Object obj1, Lisp_Object obj2)
+{
+  if (EQ (obj1, obj2))
+    return 1;
+
+  else if (CONSP (obj1) && CONSP (obj2))
+    {
+      return instantiator_eq_equal (XCAR (obj1), XCAR (obj2))
+       &&
+       instantiator_eq_equal (XCDR (obj1), XCDR (obj2));
+    }
+  return 0;
+}
+
+static hashcode_t
+instantiator_eq_hash (Lisp_Object obj)
+{
+  if (CONSP (obj))
+    {
+      /* no point in worrying about tail recursion, since we're not
+        going very deep */
+      return HASH2 (instantiator_eq_hash (XCAR (obj)),
+                   instantiator_eq_hash (XCDR (obj)));
+    }
+  return LISP_HASH (obj);
+}
+
+/* We need a special hash table for storing image instances. */
+Lisp_Object
+make_image_instance_cache_hash_table (void)
+{
+  return make_general_lisp_hash_table
+    (instantiator_eq_hash, instantiator_eq_equal,
+     30, -1.0, -1.0,
+     HASH_TABLE_KEY_CAR_VALUE_WEAK);
+}
+
 static Lisp_Object
 image_instantiate_cache_result (Lisp_Object locative)
 {
@@ -3109,19 +3149,22 @@ image_instantiate (Lisp_Object specifier, Lisp_Object matchspec,
        signal_simple_error_2 ("Wrong domain for image instance",
                               instantiator, domain);
     }
+  /* How ugly !! An image instanciator that uses a kludgy syntax to snarf in
+     face properties. There's a design flaw here. -- didier */
   else if (VECTORP (instantiator)
-          && EQ (XVECTOR_DATA (instantiator)[0], Qinherit))
+          && EQ (INSTANTIATOR_TYPE (instantiator), Qinherit))
     {
       assert (XVECTOR_LENGTH (instantiator) == 3);
       return (FACE_PROPERTY_INSTANCE
              (Fget_face (XVECTOR_DATA (instantiator)[2]),
-              Qbackground_pixmap, domain, 0, depth));
+              Qbackground_pixmap, domain, 1, depth));
     }
   else
     {
       Lisp_Object instance = Qnil;
       Lisp_Object subtable = Qnil;
-      Lisp_Object ls3 = Qnil;
+      /* #### Should this be GCPRO'd? */
+      Lisp_Object hash_key = Qnil;
       Lisp_Object pointer_fg = Qnil;
       Lisp_Object pointer_bg = Qnil;
       Lisp_Object governing_domain =
@@ -3139,8 +3182,15 @@ image_instantiate (Lisp_Object specifier, Lisp_Object matchspec,
        {
          pointer_fg = FACE_FOREGROUND (Vpointer_face, domain);
          pointer_bg = FACE_BACKGROUND (Vpointer_face, domain);
-         ls3 = list3 (glyph, pointer_fg, pointer_bg);
+         hash_key = list4 (glyph, INSTANTIATOR_TYPE (instantiator),
+                           pointer_fg, pointer_bg);
        }
+      else
+       /* We cannot simply key on the glyph since fallbacks could use
+          the same glyph but have a totally different instantiator
+          type. Thus we key on the glyph and the type (but not any
+          other parts of the instantiator. */
+       hash_key = list2 (glyph, INSTANTIATOR_TYPE (instantiator));
 
       /* First look in the device cache. */
       if (DEVICEP (governing_domain))
@@ -3167,20 +3217,15 @@ image_instantiate (Lisp_Object specifier, Lisp_Object matchspec,
                 have to use EQUAL because we massaged the
                 instantiator into a cons3 also containing the
                 foreground and background of the pointer face.  */
+             subtable = make_image_instance_cache_hash_table ();
 
-             subtable = make_lisp_hash_table
-               (20, pointerp ? HASH_TABLE_KEY_CAR_WEAK
-                : HASH_TABLE_KEY_WEAK,
-                pointerp ? HASH_TABLE_EQUAL
-                : HASH_TABLE_EQ);
              Fputhash (make_int (dest_mask), subtable,
                        XDEVICE (governing_domain)->image_instance_cache);
              instance = Qunbound;
            }
          else
            {
-             instance = Fgethash (pointerp ? ls3 : glyph,
-                                  subtable, Qunbound);
+             instance = Fgethash (hash_key, subtable, Qunbound);
            }
        }
       else if (WINDOWP (governing_domain))
@@ -3188,7 +3233,7 @@ image_instantiate (Lisp_Object specifier, Lisp_Object matchspec,
          /* Subwindows have a per-window cache and have to be treated
             differently. */
          instance =
-           Fgethash (pointerp ? ls3 : glyph,
+           Fgethash (hash_key,
                      XWINDOW (governing_domain)->subwindow_instance_cache,
                      Qunbound);
        }
@@ -3201,7 +3246,7 @@ image_instantiate (Lisp_Object specifier, Lisp_Object matchspec,
        {
          Lisp_Object locative =
            noseeum_cons (Qnil,
-                         noseeum_cons (pointerp ? ls3 : glyph,
+                         noseeum_cons (hash_key,
                                        DEVICEP (governing_domain) ? subtable
                                        : XWINDOW (governing_domain)
                                        ->subwindow_instance_cache));
@@ -3234,7 +3279,7 @@ image_instantiate (Lisp_Object specifier, Lisp_Object matchspec,
 #ifdef ERROR_CHECK_GLYPHS
          if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
              & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK))
-           assert (EQ (Fgethash ((pointerp ? ls3 : glyph),
+           assert (EQ (Fgethash (hash_key,
                                  XWINDOW (governing_domain)
                                  ->subwindow_instance_cache,
                                  Qunbound), instance));
@@ -3258,7 +3303,7 @@ image_instantiate (Lisp_Object specifier, Lisp_Object matchspec,
             possible to make changes that don't get reflected in the
             display. */
          update_image_instance (instance, instantiator);
-         free_list (ls3);
+         free_list (hash_key);
        }
 
 #ifdef ERROR_CHECK_GLYPHS
@@ -3346,7 +3391,11 @@ image_after_change (Lisp_Object specifier, Lisp_Object locale)
   Lisp_Object property =
     IMAGE_SPECIFIER_ATTACHEE_PROPERTY (XIMAGE_SPECIFIER (specifier));
   if (FACEP (attachee))
-    face_property_was_changed (attachee, property, locale);
+    {
+      face_property_was_changed (attachee, property, locale);
+      if (BUFFERP (locale))
+       XBUFFER (locale)->buffer_local_face_property = 1;
+    }
   else if (GLYPHP (attachee))
     glyph_property_was_changed (attachee, property, locale);
 }
@@ -4374,9 +4423,9 @@ check_for_ignored_expose (struct frame* f, int x, int y, int width, int height)
         we have to check for overlaps. Being conservative, we will
         check for exposures wholly contained by the subwindow - this
         might give us what we want.*/
-      if (ei->x <= x && ei->y <= y
-         && ei->x + ei->width >= x + width
-         && ei->y + ei->height >= y + height)
+      if (ei->x <= (unsigned) x && ei->y <= (unsigned) y
+         && ei->x + ei->width >= (unsigned) (x + width)
+         && ei->y + ei->height >= (unsigned) (y + height))
        {
 #ifdef DEBUG_WIDGETS
          stderr_out ("ignored %d+%d, %dx%d for exposure %d+%d, %dx%d\n",
@@ -4444,15 +4493,15 @@ int find_matching_subwindow (struct frame* f, int x, int y, int width, int heigh
 
       if (IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii)
          &&
-         IMAGE_INSTANCE_DISPLAY_X (ii) <= x
+         IMAGE_INSTANCE_DISPLAY_X (ii) <= (unsigned) x
          &&
-         IMAGE_INSTANCE_DISPLAY_Y (ii) <= y
+         IMAGE_INSTANCE_DISPLAY_Y (ii) <= (unsigned) y
          &&
          IMAGE_INSTANCE_DISPLAY_X (ii)
-         + IMAGE_INSTANCE_DISPLAY_WIDTH (ii) >= x + width
+         + IMAGE_INSTANCE_DISPLAY_WIDTH (ii) >= (unsigned) (x + width)
          &&
          IMAGE_INSTANCE_DISPLAY_Y (ii)
-         + IMAGE_INSTANCE_DISPLAY_HEIGHT (ii) >= y + height)
+         + IMAGE_INSTANCE_DISPLAY_HEIGHT (ii) >= (unsigned) (y + height))
        {
          return 1;
        }
@@ -5133,7 +5182,7 @@ image_instantiator_format_create (void)
   Vimage_instantiator_format_list = Qnil;
   staticpro (&Vimage_instantiator_format_list);
 
-  dumpstruct (&the_image_instantiator_format_entry_dynarr, &iifed_description);
+  dump_add_root_struct_ptr (&the_image_instantiator_format_entry_dynarr, &iifed_description);
 
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (nothing, "nothing");