use dynwind_begin and dynwind_end
[bpt/emacs.git] / src / xfaces.c
index 717690a..e32a1f5 100644 (file)
@@ -1,6 +1,6 @@
 /* xfaces.c -- "Face" primitives.
 
-Copyright (C) 1993-1994, 1998-2013 Free Software Foundation, Inc.
+Copyright (C) 1993-1994, 1998-2014 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -273,10 +273,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #define IGNORE_DEFFACE_P(ATTR) EQ ((ATTR), QCignore_defface)
 
-/* Value is the number of elements of VECTOR.  */
-
-#define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
-
 /* Size of hash table of realized faces in face caches (should be a
    prime number).  */
 
@@ -323,6 +319,9 @@ Lisp_Object Qheader_line, Qscroll_bar, Qcursor;
 static Lisp_Object Qborder, Qmouse, Qmenu;
 Lisp_Object Qmode_line_inactive;
 static Lisp_Object Qvertical_border;
+static Lisp_Object Qwindow_divider;
+static Lisp_Object Qwindow_divider_first_pixel;
+static Lisp_Object Qwindow_divider_last_pixel;
 
 /* The symbol `face-alias'.  A symbols having that property is an
    alias for another face.  Value of the property is the name of
@@ -512,7 +511,7 @@ DEFUN ("dump-colors", Fdump_colors, Sdump_colors, 0, 0, 0,
 
   fputc ('\n', stderr);
 
-  for (i = n = 0; i < sizeof color_count / sizeof color_count[0]; ++i)
+  for (i = n = 0; i < ARRAYELTS (color_count); ++i)
     if (color_count[i])
       {
        fprintf (stderr, "%3d: %5d", i, color_count[i]);
@@ -693,7 +692,8 @@ init_frame_faces (struct frame *f)
 }
 
 
-/* Free face cache of frame F.  Called from delete_frame.  */
+/* Free face cache of frame F.  Called from frame-dependent
+   resource freeing function, e.g. (x|tty)_free_frame_resources.  */
 
 void
 free_frame_faces (struct frame *f)
@@ -788,7 +788,7 @@ Optional THOROUGHLY non-nil means try to free unused fonts, too.  */)
 {
   clear_face_cache (!NILP (thoroughly));
   ++face_change_count;
-  ++windows_or_buffers_changed;
+  windows_or_buffers_changed = 53;
   return Qnil;
 }
 
@@ -911,8 +911,6 @@ load_pixmap (struct frame *f, Lisp_Object name)
                                X Colors
  ***********************************************************************/
 
-#define NEAR_SAME_COLOR_THRESHOLD 30000
-
 /* Parse RGB_LIST, and fill in the RGB fields of COLOR.
    RGB_LIST should contain (at least) 3 lisp integers.
    Return 0 if there's a problem with RGB_LIST, otherwise return 1.  */
@@ -1250,9 +1248,6 @@ load_color2 (struct frame *f, struct face *face, Lisp_Object name,
    record that fact in flags of the face so that we don't try to free
    these colors.  */
 
-#ifndef MSDOS
-static
-#endif
 unsigned long
 load_color (struct frame *f, struct face *face, Lisp_Object name,
            enum lface_attribute_index target_index)
@@ -1264,6 +1259,8 @@ load_color (struct frame *f, struct face *face, Lisp_Object name,
 
 #ifdef HAVE_WINDOW_SYSTEM
 
+#define NEAR_SAME_COLOR_THRESHOLD 30000
+
 /* Load colors for face FACE which is used on frame F.  Colors are
    specified by slots LFACE_BACKGROUND_INDEX and LFACE_FOREGROUND_INDEX
    of ATTRS.  If the background color specified is not supported on F,
@@ -1569,7 +1566,7 @@ the face font sort order.  */)
   vec = Fvconcat (ndrivers, drivers);
   nfonts = ASIZE (vec);
 
-  qsort (XVECTOR (vec)->u.contents, nfonts, word_size,
+  qsort (XVECTOR (vec)->contents, nfonts, word_size,
         compare_fonts_by_sort_order);
 
   result = Qnil;
@@ -1839,7 +1836,7 @@ check_lface (Lisp_Object lface)
   if (!NILP (lface))
     {
       eassert (LFACEP (lface));
-      check_lface_attrs (XVECTOR (lface)->u.contents);
+      check_lface_attrs (XVECTOR (lface)->contents);
     }
 }
 
@@ -2016,7 +2013,7 @@ get_lface_attributes_no_remap (struct frame *f, Lisp_Object face_name,
   lface = lface_from_face_name_no_resolve (f, face_name, signal_p);
 
   if (! NILP (lface))
-    memcpy (attrs, XVECTOR (lface)->u.contents,
+    memcpy (attrs, XVECTOR (lface)->contents,
            LFACE_VECTOR_SIZE * sizeof *attrs);
 
   return !NILP (lface);
@@ -2073,7 +2070,8 @@ lface_fully_specified_p (Lisp_Object attrs[LFACE_VECTOR_SIZE])
   int i;
 
   for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
-    if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX)
+    if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX
+        && i != LFACE_DISTANT_FOREGROUND_INDEX)
       if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i])))
        break;
 
@@ -2637,7 +2635,7 @@ Value is a vector of face attributes.  */)
   if (NILP (Fget (face, Qface_no_inherit)))
     {
       ++face_change_count;
-      ++windows_or_buffers_changed;
+      windows_or_buffers_changed = 54;
     }
 
   eassert (LFACEP (lface));
@@ -2706,7 +2704,7 @@ The value is TO.  */)
       copy = Finternal_make_lisp_face (to, new_frame);
     }
 
-  vcopy (copy, 0, XVECTOR (lface)->u.contents, LFACE_VECTOR_SIZE);
+  vcopy (copy, 0, XVECTOR (lface)->contents, LFACE_VECTOR_SIZE);
 
   /* Changing a named face means that all realized faces depending on
      that face are invalid.  Since we cannot tell which realized faces
@@ -2716,7 +2714,7 @@ The value is TO.  */)
   if (NILP (Fget (to, Qface_no_inherit)))
     {
       ++face_change_count;
-      ++windows_or_buffers_changed;
+      windows_or_buffers_changed = 55;
     }
 
   return to;
@@ -3126,7 +3124,7 @@ FRAME 0 means change the face on all frames, and change the default
                f = XFRAME (frame);
              if (! FONT_OBJECT_P (value))
                {
-                 Lisp_Object *attrs = XVECTOR (lface)->u.contents;
+                 Lisp_Object *attrs = XVECTOR (lface)->contents;
                  Lisp_Object font_object;
 
                  font_object = font_load_for_lface (f, attrs, value);
@@ -3194,7 +3192,7 @@ FRAME 0 means change the face on all frames, and change the default
         the font to nil so that the font selector doesn't think that
         the attribute is mandatory.  Also, clear the average
         width.  */
-      font_clear_prop (XVECTOR (lface)->u.contents, prop_index);
+      font_clear_prop (XVECTOR (lface)->contents, prop_index);
     }
 
   /* Changing a named face means that all realized faces depending on
@@ -3207,7 +3205,7 @@ FRAME 0 means change the face on all frames, and change the default
       && NILP (Fequal (old_value, value)))
     {
       ++face_change_count;
-      ++windows_or_buffers_changed;
+      windows_or_buffers_changed = 56;
     }
 
   if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
@@ -3221,10 +3219,10 @@ FRAME 0 means change the face on all frames, and change the default
        {
 #ifdef HAVE_WINDOW_SYSTEM
          /* Changed font-related attributes of the `default' face are
-            reflected in changed `font' frame parameters. */
+            reflected in changed `font' frame parameters.  */
          if (FRAMEP (frame)
              && (prop_index || EQ (attr, QCfont))
-             && lface_fully_specified_p (XVECTOR (lface)->u.contents))
+             && lface_fully_specified_p (XVECTOR (lface)->contents))
            set_font_frame_param (frame, lface);
          else
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -3380,7 +3378,7 @@ update_face_from_frame_parameter (struct frame *f, Lisp_Object param,
       && NILP (Fget (face, Qface_no_inherit)))
     {
       ++face_change_count;
-      ++windows_or_buffers_changed;
+      windows_or_buffers_changed = 57;
     }
 }
 
@@ -3404,7 +3402,7 @@ set_font_frame_param (Lisp_Object frame, Lisp_Object lface)
     {
       if (FONT_SPEC_P (font))
        {
-         font = font_load_for_lface (f, XVECTOR (lface)->u.contents, font);
+         font = font_load_for_lface (f, XVECTOR (lface)->contents, font);
          if (NILP (font))
            return;
          ASET (lface, LFACE_FONT_INDEX, font);
@@ -3763,8 +3761,8 @@ Default face attributes override any local face attributes.  */)
      the local frame is defined from default specs in `face-defface-spec'
      and those should be overridden by global settings.  Hence the strange
      "global before local" priority.  */
-  lvec = XVECTOR (local_lface)->u.contents;
-  gvec = XVECTOR (global_lface)->u.contents;
+  lvec = XVECTOR (local_lface)->contents;
+  gvec = XVECTOR (global_lface)->contents;
   for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
     if (IGNORE_DEFFACE_P (gvec[i]))
       ASET (local_lface, i, Qunspecified);
@@ -3885,29 +3883,7 @@ return the font name used for CHARACTER.  */)
 static bool
 face_attr_equal_p (Lisp_Object v1, Lisp_Object v2)
 {
-  /* Type can differ, e.g. when one attribute is unspecified, i.e. nil,
-     and the other is specified.  */
-  if (XTYPE (v1) != XTYPE (v2))
-    return 0;
-
-  if (EQ (v1, v2))
-    return 1;
-
-  switch (XTYPE (v1))
-    {
-    case Lisp_String:
-      if (SBYTES (v1) != SBYTES (v2))
-       return 0;
-
-      return memcmp (SDATA (v1), SDATA (v2), SBYTES (v1)) == 0;
-
-    case_Lisp_Int:
-    case Lisp_Symbol:
-      return 0;
-
-    default:
-      return !NILP (Fequal (v1, v2));
-    }
+  return !NILP (Fequal (v1, v2));
 }
 
 
@@ -3948,8 +3924,8 @@ If FRAME is omitted or nil, use the selected frame.  */)
 
   lface1 = lface_from_face_name (f, face1, 1);
   lface2 = lface_from_face_name (f, face2, 1);
-  equal_p = lface_equal_p (XVECTOR (lface1)->u.contents,
-                          XVECTOR (lface2)->u.contents);
+  equal_p = lface_equal_p (XVECTOR (lface1)->contents,
+                          XVECTOR (lface2)->contents);
   return equal_p ? Qt : Qnil;
 }
 
@@ -4100,15 +4076,15 @@ free_realized_face (struct frame *f, struct face *face)
     }
 }
 
+#ifdef HAVE_WINDOW_SYSTEM
 
-/* Prepare face FACE for subsequent display on frame F.  This
-   allocated GCs if they haven't been allocated yet or have been freed
-   by clearing the face cache.  */
+/* Prepare face FACE for subsequent display on frame F.  This must be called
+   before using X resources of FACE to allocate GCs if they haven't been
+   allocated yet or have been freed by clearing the face cache.  */
 
 void
 prepare_face_for_display (struct frame *f, struct face *face)
 {
-#ifdef HAVE_WINDOW_SYSTEM
   eassert (FRAME_WINDOW_P (f));
 
   if (face->gc == 0)
@@ -4136,10 +4112,10 @@ prepare_face_for_display (struct frame *f, struct face *face)
        font_prepare_for_face (f, face);
       unblock_input ();
     }
-#endif /* HAVE_WINDOW_SYSTEM */
 }
 
-\f
+#endif /* HAVE_WINDOW_SYSTEM */
+
 /* Returns the `distance' between the colors X and Y.  */
 
 static int
@@ -4273,7 +4249,7 @@ free_realized_faces (struct face_cache *c)
       if (WINDOWP (f->root_window))
        {
          clear_current_matrices (f);
-         ++windows_or_buffers_changed;
+         windows_or_buffers_changed = 58;
        }
 
       unblock_input ();
@@ -4691,7 +4667,7 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
   Lisp_Object lface;
   lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
                        Qunspecified);
-  merge_face_ref (XFRAME (selected_frame), plist, XVECTOR (lface)->u.contents,
+  merge_face_ref (XFRAME (selected_frame), plist, XVECTOR (lface)->contents,
                  1, 0);
   return lface;
 }
@@ -4711,7 +4687,7 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
 
 #ifdef HAVE_WINDOW_SYSTEM
 
-/* Return non-zero if all the face attributes in ATTRS are supported
+/* Return true if all the face attributes in ATTRS are supported
    on the window-system frame F.
 
    The definition of `supported' is somewhat heuristic, but basically means
@@ -4721,7 +4697,7 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
     \(1) different in appearance than the default face, and
     \(2) `close in spirit' to what the attributes specify, if not exact.  */
 
-static int
+static bool
 x_supports_face_attributes_p (struct frame *f,
                              Lisp_Object attrs[LFACE_VECTOR_SIZE],
                              struct face *def_face)
@@ -4811,7 +4787,7 @@ x_supports_face_attributes_p (struct frame *f,
 
 #endif /* HAVE_WINDOW_SYSTEM */
 
-/* Return non-zero if all the face attributes in ATTRS are supported
+/* Return true if all the face attributes in ATTRS are supported
    on the tty frame F.
 
    The definition of `supported' is somewhat heuristic, but basically means
@@ -4827,7 +4803,7 @@ x_supports_face_attributes_p (struct frame *f,
    will _not_ be satisfied by the tty display code's automatic
    substitution of a `dim' face for italic.  */
 
-static int
+static bool
 tty_supports_face_attributes_p (struct frame *f,
                                Lisp_Object attrs[LFACE_VECTOR_SIZE],
                                struct face *def_face)
@@ -4921,12 +4897,6 @@ tty_supports_face_attributes_p (struct frame *f,
 
   /* Color testing.  */
 
-  /* Default the color indices in FG_TTY_COLOR and BG_TTY_COLOR, since
-     we use them when calling `tty_capable_p' below, even if the face
-     specifies no colors.  */
-  fg_tty_color.pixel = FACE_TTY_DEFAULT_FG_COLOR;
-  bg_tty_color.pixel = FACE_TTY_DEFAULT_BG_COLOR;
-
   /* Check if foreground color is close enough.  */
   fg = attrs[LFACE_FOREGROUND_INDEX];
   if (STRINGP (fg))
@@ -4992,14 +4962,7 @@ tty_supports_face_attributes_p (struct frame *f,
 
   /* See if the capabilities we selected above are supported, with the
      given colors.  */
-  if (test_caps != 0 &&
-      ! tty_capable_p (FRAME_TTY (f), test_caps, fg_tty_color.pixel,
-                      bg_tty_color.pixel))
-    return 0;
-
-
-  /* Hmmm, everything checks out, this terminal must support this face.  */
-  return 1;
+  return tty_capable_p (FRAME_TTY (f), test_caps);
 }
 
 
@@ -5024,7 +4987,8 @@ satisfied by the tty display code's automatic substitution of a `dim'
 face for italic.  */)
   (Lisp_Object attributes, Lisp_Object display)
 {
-  int supports = 0, i;
+  bool supports = 0;
+  int i;
   Lisp_Object frame;
   struct frame *f;
   struct face *def_face;
@@ -5100,14 +5064,14 @@ Value is ORDER.  */)
 {
   Lisp_Object list;
   int i;
-  int indices[DIM (font_sort_order)];
+  int indices[ARRAYELTS (font_sort_order)];
 
   CHECK_LIST (order);
   memset (indices, 0, sizeof indices);
   i = 0;
 
   for (list = order;
-       CONSP (list) && i < DIM (indices);
+       CONSP (list) && i < ARRAYELTS (indices);
        list = XCDR (list), ++i)
     {
       Lisp_Object attr = XCAR (list);
@@ -5129,9 +5093,9 @@ Value is ORDER.  */)
       indices[i] = xlfd;
     }
 
-  if (!NILP (list) || i != DIM (indices))
+  if (!NILP (list) || i != ARRAYELTS (indices))
     signal_error ("Invalid font sort order", order);
-  for (i = 0; i < DIM (font_sort_order); ++i)
+  for (i = 0; i < ARRAYELTS (font_sort_order); ++i)
     if (indices[i] == 0)
       signal_error ("Invalid font sort order", order);
 
@@ -5237,7 +5201,7 @@ static bool
 realize_basic_faces (struct frame *f)
 {
   bool success_p = 0;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
 
   /* Block input here so that we won't be surprised by an X expose
      event, for instance, without having the faces set up.  */
@@ -5257,6 +5221,11 @@ realize_basic_faces (struct frame *f)
       realize_named_face (f, Qmouse, MOUSE_FACE_ID);
       realize_named_face (f, Qmenu, MENU_FACE_ID);
       realize_named_face (f, Qvertical_border, VERTICAL_BORDER_FACE_ID);
+      realize_named_face (f, Qwindow_divider, WINDOW_DIVIDER_FACE_ID);
+      realize_named_face (f, Qwindow_divider_first_pixel,
+                         WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
+      realize_named_face (f, Qwindow_divider_last_pixel,
+                         WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
 
       /* Reflect changes in the `menu' face in menu bars.  */
       if (FRAME_FACE_CACHE (f)->menu_face_changed_p)
@@ -5271,7 +5240,7 @@ realize_basic_faces (struct frame *f)
       success_p = 1;
     }
 
-  unbind_to (count, Qnil);
+  dynwind_end ();
   unblock_input ();
   return success_p;
 }
@@ -5355,9 +5324,6 @@ realize_default_face (struct frame *f)
        emacs_abort ();
     }
 
-  if (UNSPECIFIEDP (LFACE_DISTANT_FOREGROUND (lface)))
-    ASET (lface, LFACE_DISTANT_FOREGROUND_INDEX, Qnil);
-
   if (UNSPECIFIEDP (LFACE_BACKGROUND (lface)))
     {
       /* This function is called so early that colors are not yet
@@ -5377,9 +5343,9 @@ realize_default_face (struct frame *f)
     ASET (lface, LFACE_STIPPLE_INDEX, Qnil);
 
   /* Realize the face; it must be fully-specified now.  */
-  eassert (lface_fully_specified_p (XVECTOR (lface)->u.contents));
+  eassert (lface_fully_specified_p (XVECTOR (lface)->contents));
   check_lface (lface);
-  memcpy (attrs, XVECTOR (lface)->u.contents, sizeof attrs);
+  memcpy (attrs, XVECTOR (lface)->contents, sizeof attrs);
   face = realize_face (c, attrs, DEFAULT_FACE_ID);
 
 #ifdef HAVE_WINDOW_SYSTEM
@@ -5495,7 +5461,6 @@ realize_non_ascii_face (struct frame *f, Lisp_Object font_object,
   face = xmalloc (sizeof *face);
   *face = *base_face;
   face->gc = 0;
-  face->extra = NULL;
   face->overstrike
     = (! NILP (font_object)
        && FONT_WEIGHT_NAME_NUMERIC (face->lface[LFACE_WEIGHT_INDEX]) > 100
@@ -6353,7 +6318,7 @@ DEFUN ("dump-face", Fdump_face, Sdump_face, 0, 1, 0, doc: /* */)
       int i;
 
       fprintf (stderr, "font selection order: ");
-      for (i = 0; i < DIM (font_sort_order); ++i)
+      for (i = 0; i < ARRAYELTS (font_sort_order); ++i)
        fprintf (stderr, "%d ", font_sort_order[i]);
       fprintf (stderr, "\n");
 
@@ -6399,6 +6364,8 @@ DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources,
 void
 syms_of_xfaces (void)
 {
+#include "xfaces.x"
+
   DEFSYM (Qface, "face");
   DEFSYM (Qface_no_inherit, "face-no-inherit");
   DEFSYM (Qbitmap_spec_p, "bitmap-spec-p");
@@ -6462,6 +6429,9 @@ syms_of_xfaces (void)
   DEFSYM (Qmouse, "mouse");
   DEFSYM (Qmode_line_inactive, "mode-line-inactive");
   DEFSYM (Qvertical_border, "vertical-border");
+  DEFSYM (Qwindow_divider, "window-divider");
+  DEFSYM (Qwindow_divider_first_pixel, "window-divider-first-pixel");
+  DEFSYM (Qwindow_divider_last_pixel, "window-divider-last-pixel");
   DEFSYM (Qtty_color_desc, "tty-color-desc");
   DEFSYM (Qtty_color_standard_values, "tty-color-standard-values");
   DEFSYM (Qtty_color_by_index, "tty-color-by-index");
@@ -6475,44 +6445,6 @@ syms_of_xfaces (void)
   Vface_alternative_font_registry_alist = Qnil;
   staticpro (&Vface_alternative_font_registry_alist);
 
-  defsubr (&Sinternal_make_lisp_face);
-  defsubr (&Sinternal_lisp_face_p);
-  defsubr (&Sinternal_set_lisp_face_attribute);
-#ifdef HAVE_WINDOW_SYSTEM
-  defsubr (&Sinternal_set_lisp_face_attribute_from_resource);
-#endif
-  defsubr (&Scolor_gray_p);
-  defsubr (&Scolor_supported_p);
-#ifndef HAVE_X_WINDOWS
-  defsubr (&Sx_load_color_file);
-#endif
-  defsubr (&Sface_attribute_relative_p);
-  defsubr (&Smerge_face_attribute);
-  defsubr (&Sinternal_get_lisp_face_attribute);
-  defsubr (&Sinternal_lisp_face_attribute_values);
-  defsubr (&Sinternal_lisp_face_equal_p);
-  defsubr (&Sinternal_lisp_face_empty_p);
-  defsubr (&Sinternal_copy_lisp_face);
-  defsubr (&Sinternal_merge_in_global_face);
-  defsubr (&Sface_font);
-  defsubr (&Sframe_face_alist);
-  defsubr (&Sdisplay_supports_face_attributes_p);
-  defsubr (&Scolor_distance);
-  defsubr (&Sinternal_set_font_selection_order);
-  defsubr (&Sinternal_set_alternative_font_family_alist);
-  defsubr (&Sinternal_set_alternative_font_registry_alist);
-  defsubr (&Sface_attributes_as_vector);
-#ifdef GLYPH_DEBUG
-  defsubr (&Sdump_face);
-  defsubr (&Sshow_face_resources);
-#endif /* GLYPH_DEBUG */
-  defsubr (&Sclear_face_cache);
-  defsubr (&Stty_suppress_bold_inverse_default_colors);
-
-#if defined DEBUG_X_COLORS && defined HAVE_X_WINDOWS
-  defsubr (&Sdump_colors);
-#endif
-
   DEFVAR_LISP ("face-new-frame-defaults", Vface_new_frame_defaults,
     doc: /* List of global face definitions (for internal use only.)  */);
   Vface_new_frame_defaults = Qnil;
@@ -6596,11 +6528,4 @@ RESCALE-RATIO is a floating point number to specify how much larger
 \(or smaller) font we should use.  For instance, if a face requests
 a font of 10 point, we actually use a font of 10 * RESCALE-RATIO point.  */);
   Vface_font_rescale_alist = Qnil;
-
-#ifdef HAVE_WINDOW_SYSTEM
-  defsubr (&Sbitmap_spec_p);
-  defsubr (&Sx_list_fonts);
-  defsubr (&Sinternal_face_x_get_resource);
-  defsubr (&Sx_family_fonts);
-#endif
 }