Sync up with XEmacs 21.4.17.
[chise/xemacs-chise.git.1] / src / glyphs.c
index 6c5c03e..6f9d031 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
 
@@ -318,13 +318,13 @@ specifiers will not be affected.
        signal_simple_error ("Invalid mapping form", mapping);
       else
        {
-         Lisp_Object exp = XCAR (mapping);
+         Lisp_Object mapexp = XCAR (mapping);
          Lisp_Object typevec = XCAR (XCDR (mapping));
          Lisp_Object pos = Qnil;
          Lisp_Object newvec;
          struct gcpro gcpro1;
 
-         CHECK_STRING (exp);
+         CHECK_STRING (mapexp);
          CHECK_VECTOR (typevec);
          if (!NILP (XCDR (XCDR (mapping))))
            {
@@ -338,7 +338,7 @@ specifiers will not be affected.
 
          newvec = Fcopy_sequence (typevec);
          if (INTP (pos))
-           XVECTOR_DATA (newvec)[XINT (pos)] = exp;
+           XVECTOR_DATA (newvec)[XINT (pos)] = mapexp;
          GCPRO1 (newvec);
          image_validate (newvec);
          UNGCPRO;
@@ -374,7 +374,7 @@ process_image_string_instantiator (Lisp_Object data,
   LIST_LOOP (tail, *get_image_conversion_list (console_type))
     {
       Lisp_Object mapping = XCAR (tail);
-      Lisp_Object exp = XCAR (mapping);
+      Lisp_Object mapexp = XCAR (mapping);
       Lisp_Object typevec = XCAR (XCDR (mapping));
 
       /* if the result is of a type that can't be instantiated
@@ -382,10 +382,10 @@ 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)
+      if (fast_string_match (mapexp, 0, data, 0, -1, 0, ERROR_ME, 0) >= 0)
        {
          if (!NILP (XCDR (XCDR (mapping))))
            {
@@ -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);
@@ -711,7 +711,7 @@ get_image_instantiator_governing_domain (Lisp_Object instantiator,
   else if (governing_domain == GOVERNING_DOMAIN_DEVICE)
     domain = DOMAIN_DEVICE (domain);
   else
-    abort ();
+    ABORT ();
 
   return domain;
 }
@@ -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),
@@ -1032,7 +1032,7 @@ print_image_instance (Lisp_Object obj, Lisp_Object printcharfun,
       break;
 
     default:
-      abort ();
+      ABORT ();
     }
 
   MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), print_image_instance,
@@ -1155,7 +1155,7 @@ image_instance_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
       break;
 
     default:
-      abort ();
+      ABORT ();
     }
 
   return DEVMETH_OR_GIVEN (DOMAIN_XDEVICE (i1->domain),
@@ -1234,7 +1234,7 @@ image_instance_hash (Lisp_Object obj, int depth)
       break;
 
     default:
-      abort ();
+      ABORT ();
     }
 
   return HASH2 (hash, DEVMETH_OR_GIVEN
@@ -1322,7 +1322,7 @@ encode_image_instance_type (enum image_instance_type type)
     case IMAGE_SUBWINDOW:    return Qsubwindow;
     case IMAGE_WIDGET:    return Qwidget;
     default:
-      abort ();
+      ABORT ();
     }
 
   return Qnil; /* not reached */
@@ -1460,7 +1460,7 @@ make_image_instance_1 (Lisp_Object data, Lisp_Object domain,
     signal_simple_error ("Image instances not allowed here", data);
   image_validate (data);
   domain = decode_domain (domain);
-  /* instantiate_image_instantiator() will abort if given an
+  /* instantiate_image_instantiator() will ABORT if given an
      image instance ... */
   dest_mask = decode_image_instance_type_list (dest_types);
   data = normalize_image_instantiator (data,
@@ -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);
@@ -1989,12 +1989,6 @@ image_instance_layout (Lisp_Object image_instance,
   if (yoffset != IMAGE_UNCHANGED_GEOMETRY)
     XIMAGE_INSTANCE_YOFFSET (image_instance) = yoffset;
 
-  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 +1996,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 +2027,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. */
@@ -2224,7 +2212,7 @@ inherit_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
                     int dest_mask, Lisp_Object domain)
 {
   /* handled specially in image_instantiate */
-  abort ();
+  ABORT ();
 }
 
 \f
@@ -2274,11 +2262,13 @@ query_string_geometry (Lisp_Object string, Lisp_Object face,
                       int* width, int* height, int* descent, Lisp_Object domain)
 {
   struct font_metric_info fm;
-  unsigned char charsets[NUM_LEADING_BYTES];
+  Charset_ID charsets[NUM_LEADING_BYTES];
   struct face_cachel frame_cachel;
   struct face_cachel *cachel;
   Lisp_Object frame = DOMAIN_FRAME (domain);
 
+  CHECK_STRING (string);
+
   /* Compute height */
   if (height)
     {
@@ -2326,7 +2316,7 @@ query_string_geometry (Lisp_Object string, Lisp_Object face,
 Lisp_Object
 query_string_font (Lisp_Object string, Lisp_Object face, Lisp_Object domain)
 {
-  unsigned char charsets[NUM_LEADING_BYTES];
+  Charset_ID charsets[NUM_LEADING_BYTES];
   struct face_cachel frame_cachel;
   struct face_cachel *cachel;
   int i;
@@ -2820,6 +2810,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 +2899,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 +3053,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 +3146,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 +3179,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 +3214,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,12 +3230,12 @@ 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);
        }
       else
-       abort ();       /* We're not allowed anything else currently. */
+       ABORT ();       /* We're not allowed anything else currently. */
 
       /* If we don't have an instance at this point then create
          one. */
@@ -3201,7 +3243,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 +3276,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 +3300,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
@@ -3271,7 +3313,7 @@ image_instantiate (Lisp_Object specifier, Lisp_Object matchspec,
       RETURN_UNGCPRO (instance);
     }
 
-  abort ();
+  ABORT ();
   return Qnil; /* not reached */
 }
 
@@ -3668,7 +3710,7 @@ allocate_glyph (enum glyph_type type,
        | IMAGE_COLOR_PIXMAP_MASK;
       break;
     default:
-      abort ();
+      ABORT ();
     }
 
   /* I think Fmake_specifier can GC.  I think set_specifier_fallback can GC. */
@@ -3793,7 +3835,7 @@ The return value will be one of 'buffer, 'pointer, or 'icon.
   CHECK_GLYPH (glyph);
   switch (XGLYPH_TYPE (glyph))
     {
-    default: abort ();
+    default: ABORT ();
     case GLYPH_BUFFER:  return Qbuffer;
     case GLYPH_POINTER: return Qpointer;
     case GLYPH_ICON:    return Qicon;
@@ -4378,9 +4420,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",
@@ -4448,15 +4490,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;
        }
@@ -4481,7 +4523,7 @@ redisplay_subwindow (Lisp_Object subwindow)
   /* The update method is allowed to call eval.  Since it is quite
      common for this function to get called from somewhere in
      redisplay we need to make sure that quits are ignored.  Otherwise
-     Fsignal will abort. */
+     Fsignal will ABORT. */
   specbind (Qinhibit_quit, Qt);
 
   ERROR_CHECK_IMAGE_INSTANCE (subwindow);
@@ -4589,8 +4631,8 @@ void unmap_subwindow (Lisp_Object subwindow)
 
   ERROR_CHECK_IMAGE_INSTANCE (subwindow);
 
-  if (!image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (ii))
-      & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK)
+  if (!(image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (ii))
+       & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK))
       ||
       !IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii))
     return;
@@ -4620,8 +4662,8 @@ void map_subwindow (Lisp_Object subwindow, int x, int y,
 
   ERROR_CHECK_IMAGE_INSTANCE (subwindow);
 
-  if (!image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (ii))
-      & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK))
+  if (!(image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (ii))
+       & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK)))
     return;
 
 #ifdef DEBUG_WIDGETS
@@ -4844,7 +4886,7 @@ display_table_entry (Emchar ch, Lisp_Object face_table,
            continue;
        }
       else
-       abort ();
+       ABORT ();
     }
 }
 
@@ -5137,7 +5179,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");