use dynwind_begin and dynwind_end
[bpt/emacs.git] / src / xfaces.c
index 0a117b8..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.
 
@@ -211,13 +211,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "frame.h"
 #include "termhooks.h"
 
-#ifdef HAVE_X_WINDOWS
-#include "xterm.h"
 #ifdef USE_MOTIF
 #include <Xm/Xm.h>
 #include <Xm/XmStrDefs.h>
 #endif /* USE_MOTIF */
-#endif /* HAVE_X_WINDOWS */
 
 #ifdef MSDOS
 #include "dosfns.h"
@@ -227,22 +224,13 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include TERM_HEADER
 #include "fontset.h"
 #ifdef HAVE_NTGUI
-#undef FRAME_X_DISPLAY_INFO
-#define FRAME_X_DISPLAY_INFO FRAME_W32_DISPLAY_INFO
 #define x_display_info w32_display_info
 #define GCGraphicsExposures 0
 #endif /* HAVE_NTGUI */
 
 #ifdef HAVE_NS
-#undef FRAME_X_DISPLAY_INFO
-#define FRAME_X_DISPLAY_INFO FRAME_NS_DISPLAY_INFO
 #define GCGraphicsExposures 0
 #endif /* HAVE_NS */
-
-/* Number of pt per inch (from the TeXbook).  */
-
-#define PT_PER_INCH 72.27
-
 #endif /* HAVE_WINDOW_SYSTEM */
 
 #include "buffer.h"
@@ -285,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).  */
 
@@ -304,7 +288,7 @@ Lisp_Object QCwidth;
 static Lisp_Object QCfont, QCbold, QCitalic;
 static Lisp_Object QCreverse_video;
 static Lisp_Object QCoverline, QCstrike_through, QCbox, QCinherit;
-static Lisp_Object QCfontset;
+static Lisp_Object QCfontset, QCdistant_foreground;
 
 /* Symbols used for attribute values.  */
 
@@ -335,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
@@ -452,6 +439,7 @@ static struct face_cache *make_face_cache (struct frame *);
 static void free_face_cache (struct face_cache *);
 static int merge_face_ref (struct frame *, Lisp_Object, Lisp_Object *,
                           int, struct named_merge_point *);
+static int color_distance (XColor *x, XColor *y);
 
 #ifdef HAVE_WINDOW_SYSTEM
 static void set_font_frame_param (Lisp_Object, Lisp_Object);
@@ -523,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]);
@@ -547,9 +535,9 @@ DEFUN ("dump-colors", Fdump_colors, Sdump_colors, 0, 0, 0,
    is called.  */
 
 void
-x_free_colors (struct frame *f, long unsigned int *pixels, int npixels)
+x_free_colors (struct frame *f, unsigned long *pixels, int npixels)
 {
-  int class = FRAME_X_DISPLAY_INFO (f)->visual->class;
+  int class = FRAME_DISPLAY_INFO (f)->visual->class;
 
   /* If display has an immutable color map, freeing colors is not
      necessary and some servers don't allow it.  So don't do it.  */
@@ -572,7 +560,7 @@ x_free_colors (struct frame *f, long unsigned int *pixels, int npixels)
 
 void
 x_free_dpy_colors (Display *dpy, Screen *screen, Colormap cmap,
-                  long unsigned int *pixels, int npixels)
+                  unsigned long *pixels, int npixels)
 {
   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
   int class = dpyinfo->visual->class;
@@ -593,7 +581,7 @@ x_free_dpy_colors (Display *dpy, Screen *screen, Colormap cmap,
    are given by XGCV and MASK.  */
 
 static GC
-x_create_gc (struct frame *f, long unsigned int mask, XGCValues *xgcv)
+x_create_gc (struct frame *f, unsigned long mask, XGCValues *xgcv)
 {
   GC gc;
   block_input ();
@@ -610,7 +598,7 @@ static void
 x_free_gc (struct frame *f, GC gc)
 {
   eassert (input_blocked_p ());
-  IF_DEBUG (eassert (--ngcs >= 0));
+  IF_DEBUG ((--ngcs, eassert (ngcs >= 0)));
   XFreeGC (FRAME_X_DISPLAY (f), gc);
 }
 
@@ -636,7 +624,7 @@ x_create_gc (struct frame *f, unsigned long mask, XGCValues *xgcv)
 static void
 x_free_gc (struct frame *f, GC gc)
 {
-  IF_DEBUG (eassert (--ngcs >= 0));
+  IF_DEBUG ((--ngcs, eassert (ngcs >= 0)));
   xfree (gc);
 }
 
@@ -704,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)
@@ -770,7 +759,7 @@ clear_face_cache (int clear_fonts_p)
        {
          struct frame *f = XFRAME (frame);
          if (FRAME_WINDOW_P (f)
-             && FRAME_X_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS)
+             && FRAME_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS)
            {
              clear_font_cache (f);
              free_all_realized_faces (frame);
@@ -799,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;
 }
 
@@ -865,12 +854,10 @@ the pixmap.  Bits are stored row by row, each row occupies
    pixmap spec) for use on frame F.  Value is the bitmap_id (see
    xfns.c).  If NAME is nil, return with a bitmap id of zero.  If
    bitmap cannot be loaded, display a message saying so, and return
-   zero.  Store the bitmap width in *W_PTR and its height in *H_PTR,
-   if these pointers are not null.  */
+   zero.  */
 
 static ptrdiff_t
-load_pixmap (struct frame *f, Lisp_Object name, unsigned int *w_ptr,
-            unsigned int *h_ptr)
+load_pixmap (struct frame *f, Lisp_Object name)
 {
   ptrdiff_t bitmap_id;
 
@@ -905,22 +892,12 @@ load_pixmap (struct frame *f, Lisp_Object name, unsigned int *w_ptr,
     {
       add_to_log ("Invalid or undefined bitmap `%s'", name, Qnil);
       bitmap_id = 0;
-
-      if (w_ptr)
-       *w_ptr = 0;
-      if (h_ptr)
-       *h_ptr = 0;
     }
   else
     {
 #ifdef GLYPH_DEBUG
       ++npixmaps_allocated;
 #endif
-      if (w_ptr)
-       *w_ptr = x_bitmap_width (f, bitmap_id);
-
-      if (h_ptr)
-       *h_ptr = x_bitmap_height (f, bitmap_id);
     }
 
   return bitmap_id;
@@ -1200,21 +1177,10 @@ COLOR must be a valid color name.  */)
 }
 
 
-/* Load color with name NAME for use by face FACE on frame F.
-   TARGET_INDEX must be one of LFACE_FOREGROUND_INDEX,
-   LFACE_BACKGROUND_INDEX, LFACE_UNDERLINE_INDEX, LFACE_OVERLINE_INDEX,
-   LFACE_STRIKE_THROUGH_INDEX, or LFACE_BOX_INDEX.  Value is the
-   pixel color.  If color cannot be loaded, display a message, and
-   return the foreground, background or underline color of F, but
-   record that fact in flags of the face so that we don't try to free
-   these colors.  */
-
-unsigned long
-load_color (struct frame *f, struct face *face, Lisp_Object name,
-           enum lface_attribute_index target_index)
+static unsigned long
+load_color2 (struct frame *f, struct face *face, Lisp_Object name,
+             enum lface_attribute_index target_index, XColor *color)
 {
-  XColor color;
-
   eassert (STRINGP (name));
   eassert (target_index == LFACE_FOREGROUND_INDEX
           || target_index == LFACE_BACKGROUND_INDEX
@@ -1225,7 +1191,7 @@ load_color (struct frame *f, struct face *face, Lisp_Object name,
 
   /* if the color map is full, defined_color will return a best match
      to the values in an existing cell. */
-  if (!defined_color (f, SSDATA (name), &color, 1))
+  if (!defined_color (f, SSDATA (name), color, 1))
     {
       add_to_log ("Unable to load color \"%s\"", name, Qnil);
 
@@ -1233,32 +1199,32 @@ load_color (struct frame *f, struct face *face, Lisp_Object name,
        {
        case LFACE_FOREGROUND_INDEX:
          face->foreground_defaulted_p = 1;
-         color.pixel = FRAME_FOREGROUND_PIXEL (f);
+         color->pixel = FRAME_FOREGROUND_PIXEL (f);
          break;
 
        case LFACE_BACKGROUND_INDEX:
          face->background_defaulted_p = 1;
-         color.pixel = FRAME_BACKGROUND_PIXEL (f);
+         color->pixel = FRAME_BACKGROUND_PIXEL (f);
          break;
 
        case LFACE_UNDERLINE_INDEX:
          face->underline_defaulted_p = 1;
-         color.pixel = FRAME_FOREGROUND_PIXEL (f);
+         color->pixel = FRAME_FOREGROUND_PIXEL (f);
          break;
 
        case LFACE_OVERLINE_INDEX:
          face->overline_color_defaulted_p = 1;
-         color.pixel = FRAME_FOREGROUND_PIXEL (f);
+         color->pixel = FRAME_FOREGROUND_PIXEL (f);
          break;
 
        case LFACE_STRIKE_THROUGH_INDEX:
          face->strike_through_color_defaulted_p = 1;
-         color.pixel = FRAME_FOREGROUND_PIXEL (f);
+         color->pixel = FRAME_FOREGROUND_PIXEL (f);
          break;
 
        case LFACE_BOX_INDEX:
          face->box_color_defaulted_p = 1;
-         color.pixel = FRAME_FOREGROUND_PIXEL (f);
+         color->pixel = FRAME_FOREGROUND_PIXEL (f);
          break;
 
        default:
@@ -1270,12 +1236,31 @@ load_color (struct frame *f, struct face *face, Lisp_Object name,
     ++ncolors_allocated;
 #endif
 
-  return color.pixel;
+  return color->pixel;
+}
+
+/* Load color with name NAME for use by face FACE on frame F.
+   TARGET_INDEX must be one of LFACE_FOREGROUND_INDEX,
+   LFACE_BACKGROUND_INDEX, LFACE_UNDERLINE_INDEX, LFACE_OVERLINE_INDEX,
+   LFACE_STRIKE_THROUGH_INDEX, or LFACE_BOX_INDEX.  Value is the
+   pixel color.  If color cannot be loaded, display a message, and
+   return the foreground, background or underline color of F, but
+   record that fact in flags of the face so that we don't try to free
+   these colors.  */
+
+unsigned long
+load_color (struct frame *f, struct face *face, Lisp_Object name,
+           enum lface_attribute_index target_index)
+{
+  XColor color;
+  return load_color2 (f, face, name, target_index, &color);
 }
 
 
 #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,
@@ -1285,7 +1270,8 @@ static void
 load_face_colors (struct frame *f, struct face *face,
                  Lisp_Object attrs[LFACE_VECTOR_SIZE])
 {
-  Lisp_Object fg, bg;
+  Lisp_Object fg, bg, dfg;
+  XColor xfg, xbg;
 
   bg = attrs[LFACE_BACKGROUND_INDEX];
   fg = attrs[LFACE_FOREGROUND_INDEX];
@@ -1307,38 +1293,45 @@ load_face_colors (struct frame *f, struct face *face,
       && !NILP (Fbitmap_spec_p (Vface_default_stipple)))
     {
       x_destroy_bitmap (f, face->stipple);
-      face->stipple = load_pixmap (f, Vface_default_stipple,
-                                  &face->pixmap_w, &face->pixmap_h);
+      face->stipple = load_pixmap (f, Vface_default_stipple);
     }
 
-  face->background = load_color (f, face, bg, LFACE_BACKGROUND_INDEX);
-  face->foreground = load_color (f, face, fg, LFACE_FOREGROUND_INDEX);
+  face->background = load_color2 (f, face, bg, LFACE_BACKGROUND_INDEX, &xbg);
+  face->foreground = load_color2 (f, face, fg, LFACE_FOREGROUND_INDEX, &xfg);
+
+  dfg = attrs[LFACE_DISTANT_FOREGROUND_INDEX];
+  if (!NILP (dfg) && !UNSPECIFIEDP (dfg)
+      && color_distance (&xbg, &xfg) < NEAR_SAME_COLOR_THRESHOLD)
+    {
+      if (EQ (attrs[LFACE_INVERSE_INDEX], Qt))
+        face->background = load_color (f, face, dfg, LFACE_BACKGROUND_INDEX);
+      else
+        face->foreground = load_color (f, face, dfg, LFACE_FOREGROUND_INDEX);
+    }
 }
 
+#ifdef HAVE_X_WINDOWS
 
 /* Free color PIXEL on frame F.  */
 
 void
-unload_color (struct frame *f, long unsigned int pixel)
+unload_color (struct frame *f, unsigned long pixel)
 {
-#ifdef HAVE_X_WINDOWS
   if (pixel != -1)
     {
       block_input ();
       x_free_colors (f, &pixel, 1);
       unblock_input ();
     }
-#endif
 }
 
-
 /* Free colors allocated for FACE.  */
 
 static void
 free_face_colors (struct frame *f, struct face *face)
 {
-/* PENDING(NS): need to do something here? */
-#ifdef HAVE_X_WINDOWS
+  /* PENDING(NS): need to do something here? */
+
   if (face->colors_copied_bitwise_p)
     return;
 
@@ -1385,9 +1378,10 @@ free_face_colors (struct frame *f, struct face *face)
     }
 
   unblock_input ();
-#endif /* HAVE_X_WINDOWS */
 }
 
+#endif /* HAVE_X_WINDOWS */
+
 #endif /* HAVE_WINDOW_SYSTEM */
 
 
@@ -1744,6 +1738,8 @@ the WIDTH times as wide as FACE on FRAME.  */)
 #define LFACE_FONT(LFACE)          AREF ((LFACE), LFACE_FONT_INDEX)
 #define LFACE_INHERIT(LFACE)       AREF ((LFACE), LFACE_INHERIT_INDEX)
 #define LFACE_FONTSET(LFACE)       AREF ((LFACE), LFACE_FONTSET_INDEX)
+#define LFACE_DISTANT_FOREGROUND(LFACE) \
+  AREF ((LFACE), LFACE_DISTANT_FOREGROUND_INDEX)
 
 /* Non-zero if LFACE is a Lisp face.  A Lisp face is a vector of size
    LFACE_VECTOR_SIZE which has the symbol `face' in slot 0.  */
@@ -1806,6 +1802,9 @@ check_lface_attrs (Lisp_Object attrs[LFACE_VECTOR_SIZE])
   eassert (UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
           || IGNORE_DEFFACE_P (attrs[LFACE_FOREGROUND_INDEX])
           || STRINGP (attrs[LFACE_FOREGROUND_INDEX]));
+  eassert (UNSPECIFIEDP (attrs[LFACE_DISTANT_FOREGROUND_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_DISTANT_FOREGROUND_INDEX])
+          || STRINGP (attrs[LFACE_DISTANT_FOREGROUND_INDEX]));
   eassert (UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
           || IGNORE_DEFFACE_P (attrs[LFACE_BACKGROUND_INDEX])
           || STRINGP (attrs[LFACE_BACKGROUND_INDEX]));
@@ -2071,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;
 
@@ -2472,6 +2472,13 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
                  else
                    err = 1;
                }
+             else if (EQ (keyword, QCdistant_foreground))
+               {
+                 if (STRINGP (value))
+                   to[LFACE_DISTANT_FOREGROUND_INDEX] = value;
+                 else
+                   err = 1;
+               }
              else if (EQ (keyword, QCbackground))
                {
                  if (STRINGP (value))
@@ -2628,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));
@@ -2707,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;
@@ -3028,6 +3035,23 @@ FRAME 0 means change the face on all frames, and change the default
       old_value = LFACE_FOREGROUND (lface);
       ASET (lface, LFACE_FOREGROUND_INDEX, value);
     }
+  else if (EQ (attr, QCdistant_foreground))
+    {
+      /* Compatibility with 20.x.  */
+      if (NILP (value))
+       value = Qunspecified;
+      if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+       {
+         /* Don't check for valid color names here because it depends
+            on the frame (display) whether the color will be valid
+            when the face is realized.  */
+         CHECK_STRING (value);
+         if (SCHARS (value) == 0)
+           signal_error ("Empty distant-foreground color value", value);
+       }
+      old_value = LFACE_DISTANT_FOREGROUND (lface);
+      ASET (lface, LFACE_DISTANT_FOREGROUND_INDEX, value);
+    }
   else if (EQ (attr, QCbackground))
     {
       /* Compatibility with 20.x.  */
@@ -3181,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)
@@ -3195,7 +3219,7 @@ 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)->contents))
@@ -3354,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;
     }
 }
 
@@ -3403,7 +3427,7 @@ ordinary `x-get-resource' doesn't take a frame argument.  */)
   CHECK_STRING (class);
   f = decode_live_frame (frame);
   block_input ();
-  value = display_x_get_resource (FRAME_X_DISPLAY_INFO (f),
+  value = display_x_get_resource (FRAME_DISPLAY_INFO (f),
                                  resource, class, Qnil, Qnil);
   unblock_input ();
   return value;
@@ -3493,7 +3517,7 @@ DEFUN ("internal-set-lisp-face-attribute-from-resource",
 static void
 x_update_menu_appearance (struct frame *f)
 {
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   XrmDatabase rdb;
 
   if (dpyinfo
@@ -3672,6 +3696,8 @@ frames).  If FRAME is omitted or nil, use the selected frame.  */)
     value = LFACE_INVERSE (lface);
   else if (EQ (keyword, QCforeground))
     value = LFACE_FOREGROUND (lface);
+  else if (EQ (keyword, QCdistant_foreground))
+    value = LFACE_DISTANT_FOREGROUND (lface);
   else if (EQ (keyword, QCbackground))
     value = LFACE_BACKGROUND (lface);
   else if (EQ (keyword, QCstipple))
@@ -3857,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));
 }
 
 
@@ -4027,9 +4031,13 @@ lface_same_font_attributes_p (Lisp_Object *lface1, Lisp_Object *lface2)
 static struct face *
 make_realized_face (Lisp_Object *attr)
 {
-  struct face *face = xzalloc (sizeof *face);
-  face->ascii_face = face;
+  enum { off = offsetof (struct face, id) };
+  struct face *face = xmalloc (sizeof *face);
+
   memcpy (face->lface, attr, sizeof face->lface);
+  memset (&face->id, 0, sizeof *face - off);
+  face->ascii_face = face;
+
   return face;
 }
 
@@ -4057,8 +4065,9 @@ free_realized_face (struct frame *f, struct face *face)
              face->gc = 0;
              unblock_input ();
            }
-
+#ifdef HAVE_X_WINDOWS
          free_face_colors (f, face);
+#endif /* HAVE_X_WINDOWS */
          x_destroy_bitmap (f, face->stipple);
        }
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -4067,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)
@@ -4103,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
@@ -4240,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 ();
@@ -4678,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
@@ -4688,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)
@@ -4706,6 +4715,9 @@ x_supports_face_attributes_p (struct frame *f,
       || (!UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
          && face_attr_equal_p (attrs[LFACE_FOREGROUND_INDEX],
                                def_attrs[LFACE_FOREGROUND_INDEX]))
+      || (!UNSPECIFIEDP (attrs[LFACE_DISTANT_FOREGROUND_INDEX])
+         && face_attr_equal_p (attrs[LFACE_DISTANT_FOREGROUND_INDEX],
+                               def_attrs[LFACE_DISTANT_FOREGROUND_INDEX]))
       || (!UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
          && face_attr_equal_p (attrs[LFACE_BACKGROUND_INDEX],
                                def_attrs[LFACE_BACKGROUND_INDEX]))
@@ -4775,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
@@ -4791,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)
@@ -4885,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))
@@ -4956,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);
 }
 
 
@@ -4988,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;
@@ -5064,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);
@@ -5093,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);
 
@@ -5201,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.  */
@@ -5221,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)
@@ -5235,7 +5240,7 @@ realize_basic_faces (struct frame *f)
       success_p = 1;
     }
 
-  unbind_to (count, Qnil);
+  dynwind_end ();
   unblock_input ();
   return success_p;
 }
@@ -5456,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
@@ -5725,7 +5729,7 @@ realize_x_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE])
 
   stipple = attrs[LFACE_STIPPLE_INDEX];
   if (!NILP (stipple))
-    face->stipple = load_pixmap (f, stipple, &face->pixmap_w, &face->pixmap_h);
+    face->stipple = load_pixmap (f, stipple);
 #endif /* HAVE_WINDOW_SYSTEM */
 
   return face;
@@ -5934,7 +5938,6 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop)
 
 int
 face_at_buffer_position (struct window *w, ptrdiff_t pos,
-                        ptrdiff_t region_beg, ptrdiff_t region_end,
                         ptrdiff_t *endptr, ptrdiff_t limit,
                         int mouse, int base_face_id)
 {
@@ -5955,8 +5958,6 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
   XSETFASTINT (position, pos);
 
   endpos = ZV;
-  if (pos < region_beg && region_beg < endpos)
-    endpos = region_beg;
 
   /* Get the `face' or `mouse_face' text property at POS, and
      determine the next position at which the property changes.  */
@@ -5992,8 +5993,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
 
   /* Optimize common cases where we can use the default face.  */
   if (noverlays == 0
-      && NILP (prop)
-      && !(pos >= region_beg && pos < region_end))
+      && NILP (prop))
     return default_face->id;
 
   /* Begin with attributes from the default face.  */
@@ -6020,15 +6020,6 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
        endpos = oendpos;
     }
 
-  /* If in the region, merge in the region face.  */
-  if (pos >= region_beg && pos < region_end)
-    {
-      merge_named_face (f, Qregion, attrs, 0);
-
-      if (region_end < endpos)
-       endpos = region_end;
-    }
-
   *endptr = endpos;
 
   /* Look up a realized face with the given face attributes,
@@ -6044,7 +6035,6 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
 
 int
 face_for_overlay_string (struct window *w, ptrdiff_t pos,
-                        ptrdiff_t region_beg, ptrdiff_t region_end,
                         ptrdiff_t *endptr, ptrdiff_t limit,
                         int mouse, Lisp_Object overlay)
 {
@@ -6063,8 +6053,6 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos,
   XSETFASTINT (position, pos);
 
   endpos = ZV;
-  if (pos < region_beg && region_beg < endpos)
-    endpos = region_beg;
 
   /* Get the `face' or `mouse_face' text property at POS, and
      determine the next position at which the property changes.  */
@@ -6078,7 +6066,6 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos,
 
   /* Optimize common case where we can use the default face.  */
   if (NILP (prop)
-      && !(pos >= region_beg && pos < region_end)
       && NILP (Vface_remapping_alist))
     return DEFAULT_FACE_ID;
 
@@ -6090,15 +6077,6 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos,
   if (!NILP (prop))
     merge_face_ref (f, prop, attrs, 1, 0);
 
-  /* If in the region, merge in the region face.  */
-  if (pos >= region_beg && pos < region_end)
-    {
-      merge_named_face (f, Qregion, attrs, 0);
-
-      if (region_end < endpos)
-       endpos = region_end;
-    }
-
   *endptr = endpos;
 
   /* Look up a realized face with the given face attributes,
@@ -6131,7 +6109,6 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos,
 int
 face_at_string_position (struct window *w, Lisp_Object string,
                         ptrdiff_t pos, ptrdiff_t bufpos,
-                        ptrdiff_t region_beg, ptrdiff_t region_end,
                         ptrdiff_t *endptr, enum face_id base_face_id,
                         int mouse_p)
 {
@@ -6163,15 +6140,8 @@ face_at_string_position (struct window *w, Lisp_Object string,
   base_face = FACE_FROM_ID (f, base_face_id);
   eassert (base_face);
 
-  /* Optimize the default case that there is no face property and we
-     are not in the region.  */
+  /* Optimize the default case that there is no face property.  */
   if (NILP (prop)
-      && (base_face_id != DEFAULT_FACE_ID
-         /* BUFPOS <= 0 means STRING is not an overlay string, so
-            that the region doesn't have to be taken into account.  */
-         || bufpos <= 0
-         || bufpos < region_beg
-         || bufpos >= region_end)
       && (multibyte_p
          /* We can't realize faces for different charsets differently
             if we don't have fonts, so we can stop here if not working
@@ -6187,12 +6157,6 @@ face_at_string_position (struct window *w, Lisp_Object string,
   if (!NILP (prop))
     merge_face_ref (f, prop, attrs, 1, 0);
 
-  /* If in the region, merge in the region face.  */
-  if (bufpos
-      && bufpos >= region_beg
-      && bufpos < region_end)
-    merge_named_face (f, Qregion, attrs, 0);
-
   /* Look up a realized face with the given face attributes,
      or realize a new one for ASCII characters.  */
   return lookup_face (f, attrs);
@@ -6354,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");
 
@@ -6400,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");
@@ -6419,6 +6385,7 @@ syms_of_xfaces (void)
   DEFSYM (QCwidth, ":width");
   DEFSYM (QCfont, ":font");
   DEFSYM (QCfontset, ":fontset");
+  DEFSYM (QCdistant_foreground, ":distant-foreground");
   DEFSYM (QCbold, ":bold");
   DEFSYM (QCitalic, ":italic");
   DEFSYM (QCoverline, ":overline");
@@ -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
 }