use dynwind_begin and dynwind_end
[bpt/emacs.git] / src / xfaces.c
index b2ace1b..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.
 
@@ -200,10 +200,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    used to fill in unspecified attributes of the default face.  */
 
 #include <config.h>
-#include <stdio.h>
+#include "sysstdio.h"
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <stdio.h>              /* This needs to be before termchar.h */
 
 #include "lisp.h"
 #include "character.h"
@@ -212,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"
@@ -228,16 +224,11 @@ 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 x_display_info ns_display_info
 #define GCGraphicsExposures 0
 #endif /* HAVE_NS */
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -274,10 +265,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <c-ctype.h>
 
-/* Number of pt per inch (from the TeXbook).  */
-
-#define PT_PER_INCH 72.27
-
 /* Non-zero if face attribute ATTR is unspecified.  */
 
 #define UNSPECIFIEDP(ATTR) EQ ((ATTR), Qunspecified)
@@ -286,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).  */
 
@@ -305,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.  */
 
@@ -336,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
@@ -398,6 +384,8 @@ static Lisp_Object Qtty_color_desc, Qtty_color_by_index, Qtty_color_standard_val
 
 static Lisp_Object Qtty_color_alist;
 
+#ifdef HAVE_WINDOW_SYSTEM
+
 /* Counter for calls to clear_face_cache.  If this counter reaches
    CLEAR_FONT_TABLE_COUNT, and a frame has more than
    CLEAR_FONT_TABLE_NFONTS load, unused fonts are freed.  */
@@ -406,6 +394,8 @@ static int clear_font_table_count;
 #define CLEAR_FONT_TABLE_COUNT 100
 #define CLEAR_FONT_TABLE_NFONTS        10
 
+#endif /* HAVE_WINDOW_SYSTEM */
+
 /* Non-zero means face attributes have been changed since the last
    redisplay.  Used in redisplay_internal.  */
 
@@ -436,29 +426,28 @@ static int ngcs;
 
 static int menu_face_changed_default;
 
-\f
-/* Function prototypes.  */
-
-struct table_entry;
 struct named_merge_point;
 
-static void set_font_frame_param (Lisp_Object, Lisp_Object);
 static struct face *realize_face (struct face_cache *, Lisp_Object *,
                                  int);
-static struct face *realize_non_ascii_face (struct frame *, Lisp_Object,
-                                           struct face *);
 static struct face *realize_x_face (struct face_cache *, Lisp_Object *);
 static struct face *realize_tty_face (struct face_cache *, Lisp_Object *);
-static int realize_basic_faces (struct frame *);
-static int realize_default_face (struct frame *);
+static bool realize_basic_faces (struct frame *);
+static bool realize_default_face (struct frame *);
 static void realize_named_face (struct frame *, Lisp_Object, int);
 static struct face_cache *make_face_cache (struct frame *);
-static void clear_face_gcs (struct face_cache *);
 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);
+static void clear_face_gcs (struct face_cache *);
+static struct face *realize_non_ascii_face (struct frame *, Lisp_Object,
+                                           struct face *);
+#endif /* HAVE_WINDOW_SYSTEM */
 
-\f
 /***********************************************************************
                              Utilities
  ***********************************************************************/
@@ -522,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]);
@@ -546,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.  */
@@ -571,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;
@@ -592,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 ();
@@ -609,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);
 }
 
@@ -635,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);
 }
 
@@ -703,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)
@@ -760,11 +750,6 @@ clear_face_cache (int clear_fonts_p)
   if (clear_fonts_p
       || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT)
     {
-#if 0
-      /* Not yet implemented.  */
-      clear_font_cache (frame);
-#endif
-
       /* From time to time see if we can unload some fonts.  This also
         frees all realized faces on all frames.  Fonts needed by
         faces will be loaded again when faces are realized again.  */
@@ -774,8 +759,11 @@ 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)
-           free_all_realized_faces (frame);
+             && FRAME_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS)
+           {
+             clear_font_cache (f);
+             free_all_realized_faces (frame);
+           }
        }
     }
   else
@@ -800,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;
 }
 
@@ -820,7 +808,7 @@ the pixmap.  Bits are stored row by row, each row occupies
 \(WIDTH + 7)/8 bytes.  */)
   (Lisp_Object object)
 {
-  int pixmap_p = 0;
+  bool pixmap_p = 0;
 
   if (STRINGP (object))
     /* If OBJECT is a string, it's a file name.  */
@@ -866,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 (FRAME_PTR f, Lisp_Object name, unsigned int *w_ptr,
-            unsigned int *h_ptr)
+load_pixmap (struct frame *f, Lisp_Object name)
 {
   ptrdiff_t bitmap_id;
 
@@ -906,22 +892,12 @@ load_pixmap (FRAME_PTR 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;
@@ -1201,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
@@ -1226,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);
 
@@ -1234,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:
@@ -1271,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,
@@ -1286,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];
@@ -1308,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;
 
@@ -1386,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 */
 
 
@@ -1531,15 +1524,12 @@ the face font sort order.  */)
   (Lisp_Object family, Lisp_Object frame)
 {
   Lisp_Object font_spec, list, *drivers, vec;
+  struct frame *f = decode_live_frame (frame);
   ptrdiff_t i, nfonts;
   EMACS_INT ndrivers;
   Lisp_Object result;
   USE_SAFE_ALLOCA;
 
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_LIVE_FRAME (frame);
-
   font_spec = Ffont_spec (0, NULL);
   if (!NILP (family))
     {
@@ -1547,7 +1537,7 @@ the face font sort order.  */)
       font_parse_family_registry (family, Qnil, font_spec);
     }
 
-  list = font_list_entities (frame, font_spec);
+  list = font_list_entities (f, font_spec);
   if (NILP (list))
     return Qnil;
 
@@ -1590,7 +1580,7 @@ the face font sort order.  */)
       ASET (v, 0, AREF (font, FONT_FAMILY_INDEX));
       ASET (v, 1, FONT_WIDTH_SYMBOLIC (font));
       point = PIXEL_TO_POINT (XINT (AREF (font, FONT_SIZE_INDEX)) * 10,
-                             FRAME_RES_Y (XFRAME (frame)));
+                             FRAME_RES_Y (f));
       ASET (v, 2, make_number (point));
       ASET (v, 3, FONT_WEIGHT_SYMBOLIC (font));
       ASET (v, 4, FONT_SLANT_SYMBOLIC (font));
@@ -1748,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.  */
@@ -1810,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]));
@@ -2075,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;
 
@@ -2476,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))
@@ -2632,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));
@@ -2711,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;
@@ -2855,7 +2858,7 @@ FRAME 0 means change the face on all frames, and change the default
     }
   else if (EQ (attr, QCunderline))
     {
-      int valid_p = 0;
+      bool valid_p = 0;
 
       if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
        valid_p = 1;
@@ -2942,7 +2945,7 @@ FRAME 0 means change the face on all frames, and change the default
     }
   else if (EQ (attr, QCbox))
     {
-      int valid_p;
+      bool valid_p;
 
       /* Allow t meaning a simple box of width 1 in foreground color
         of the face.  */
@@ -3032,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.  */
@@ -3079,7 +3099,7 @@ FRAME 0 means change the face on all frames, and change the default
        {
          if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
            {
-             FRAME_PTR f;
+             struct frame *f;
 
              old_value = LFACE_FONT (lface);
              if (! FONTP (value))
@@ -3185,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)
@@ -3199,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))
@@ -3248,10 +3268,9 @@ FRAME 0 means change the face on all frames, and change the default
 #endif /* HAVE_WINDOW_SYSTEM */
       else if (EQ (face, Qmenu))
        {
-         /* Indicate that we have to update the menu bar when
-            realizing faces on FRAME.  FRAME t change the
-            default for new frames.  We do this by setting
-            setting the flag in new face caches   */
+         /* Indicate that we have to update the menu bar when realizing
+            faces on FRAME.  FRAME t change the default for new frames.
+            We do this by setting the flag in new face caches.  */
          if (FRAMEP (frame))
            {
              struct frame *f = XFRAME (frame);
@@ -3359,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;
     }
 }
 
@@ -3389,7 +3408,7 @@ set_font_frame_param (Lisp_Object frame, Lisp_Object lface)
          ASET (lface, LFACE_FONT_INDEX, font);
        }
       f->default_face_done_p = 0;
-      Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, font), Qnil));
+      Fmodify_frame_parameters (frame, list1 (Fcons (Qfont, font)));
     }
 }
 
@@ -3408,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;
@@ -3498,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
@@ -3511,7 +3530,7 @@ x_update_menu_appearance (struct frame *f)
       Lisp_Object lface = lface_from_face_name (f, Qmenu, 1);
       struct face *face = FACE_FROM_ID (f, MENU_FACE_ID);
       const char *myname = SSDATA (Vx_resource_name);
-      int changed_p = 0;
+      bool changed_p = 0;
 #ifdef USE_MOTIF
       const char *popup_path = "popup_menu";
 #else
@@ -3677,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))
@@ -3710,14 +3731,10 @@ Value is nil if ATTR doesn't have a discrete set of valid values.  */)
 
   CHECK_SYMBOL (attr);
 
-  if (EQ (attr, QCunderline))
-    result = Fcons (Qt, Fcons (Qnil, Qnil));
-  else if (EQ (attr, QCoverline))
-    result = Fcons (Qt, Fcons (Qnil, Qnil));
-  else if (EQ (attr, QCstrike_through))
-    result = Fcons (Qt, Fcons (Qnil, Qnil));
-  else if (EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video))
-    result = Fcons (Qt, Fcons (Qnil, Qnil));
+  if (EQ (attr, QCunderline) || EQ (attr, QCoverline)
+      || EQ (attr, QCstrike_through)
+      || EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video))
+    result = list2 (Qt, Qnil);
 
   return result;
 }
@@ -3780,21 +3797,18 @@ Default face attributes override any local face attributes.  */)
              && newface->font)
            {
              Lisp_Object name = newface->font->props[FONT_NAME_INDEX];
-             Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, name),
-                                                     Qnil));
+             Fmodify_frame_parameters (frame, list1 (Fcons (Qfont, name)));
            }
 
          if (STRINGP (gvec[LFACE_FOREGROUND_INDEX]))
            Fmodify_frame_parameters (frame,
-                                     Fcons (Fcons (Qforeground_color,
-                                                   gvec[LFACE_FOREGROUND_INDEX]),
-                                            Qnil));
+                                     list1 (Fcons (Qforeground_color,
+                                                   gvec[LFACE_FOREGROUND_INDEX])));
 
          if (STRINGP (gvec[LFACE_BACKGROUND_INDEX]))
            Fmodify_frame_parameters (frame,
-                                     Fcons (Fcons (Qbackground_color,
-                                                   gvec[LFACE_BACKGROUND_INDEX]),
-                                            Qnil));
+                                     list1 (Fcons (Qbackground_color,
+                                                   gvec[LFACE_BACKGROUND_INDEX])));
        }
     }
 
@@ -3866,32 +3880,10 @@ return the font name used for CHARACTER.  */)
    all attributes are `equal'.  Tries to be fast because this function
    is called quite often.  */
 
-static int
+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));
 }
 
 
@@ -3899,10 +3891,11 @@ face_attr_equal_p (Lisp_Object v1, Lisp_Object v2)
    all attributes are `equal'.  Tries to be fast because this function
    is called quite often.  */
 
-static int
+static bool
 lface_equal_p (Lisp_Object *v1, Lisp_Object *v2)
 {
-  int i, equal_p = 1;
+  int i;
+  bool equal_p = 1;
 
   for (i = 1; i < LFACE_VECTOR_SIZE && equal_p; ++i)
     equal_p = face_attr_equal_p (v1[i], v2[i]);
@@ -3997,6 +3990,7 @@ lface_hash (Lisp_Object *v)
          ^ XHASH (v[LFACE_HEIGHT_INDEX]));
 }
 
+#ifdef HAVE_WINDOW_SYSTEM
 
 /* Return non-zero if LFACE1 and LFACE2 specify the same font (without
    considering charsets/registries).  They do if they specify the same
@@ -4025,8 +4019,8 @@ lface_same_font_attributes_p (Lisp_Object *lface1, Lisp_Object *lface2)
          );
 }
 
+#endif /* HAVE_WINDOW_SYSTEM */
 
-\f
 /***********************************************************************
                            Realized Faces
  ***********************************************************************/
@@ -4037,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;
 }
 
@@ -4067,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 */
@@ -4077,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)
@@ -4113,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
@@ -4174,19 +4173,18 @@ If FRAME is unspecified or nil, the current frame is used.  */)
 static struct face_cache *
 make_face_cache (struct frame *f)
 {
-  struct face_cache *c;
-  int size;
+  struct face_cache *c = xmalloc (sizeof *c);
 
-  c = xzalloc (sizeof *c);
-  size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
-  c->buckets = xzalloc (size);
+  c->buckets = xzalloc (FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets);
   c->size = 50;
+  c->used = 0;
   c->faces_by_id = xmalloc (c->size * sizeof *c->faces_by_id);
   c->f = f;
   c->menu_face_changed_p = menu_face_changed_default;
   return c;
 }
 
+#ifdef HAVE_WINDOW_SYSTEM
 
 /* Clear out all graphics contexts for all realized faces, except for
    the basic faces.  This should be done from time to time just to avoid
@@ -4197,7 +4195,6 @@ clear_face_gcs (struct face_cache *c)
 {
   if (c && FRAME_WINDOW_P (c->f))
     {
-#ifdef HAVE_WINDOW_SYSTEM
       int i;
       for (i = BASIC_FACE_ID_SENTINEL; i < c->used; ++i)
        {
@@ -4212,10 +4209,10 @@ clear_face_gcs (struct face_cache *c)
              unblock_input ();
            }
        }
-#endif /* HAVE_WINDOW_SYSTEM */
     }
 }
 
+#endif /* HAVE_WINDOW_SYSTEM */
 
 /* Free all realized faces in face cache C, including basic faces.
    C may be null.  If faces are freed, make sure the frame's current
@@ -4252,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 ();
@@ -4690,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
@@ -4700,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)
@@ -4718,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]))
@@ -4787,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
@@ -4803,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)
@@ -4897,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))
@@ -4968,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);
 }
 
 
@@ -5000,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;
@@ -5076,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);
@@ -5105,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);
 
@@ -5209,11 +5197,11 @@ face_fontset (Lisp_Object attrs[LFACE_VECTOR_SIZE])
    of F don't contain enough information needed to realize the default
    face.  */
 
-static int
+static bool
 realize_basic_faces (struct frame *f)
 {
-  int success_p = 0;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  bool success_p = 0;
+  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.  */
@@ -5233,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)
@@ -5247,7 +5240,7 @@ realize_basic_faces (struct frame *f)
       success_p = 1;
     }
 
-  unbind_to (count, Qnil);
+  dynwind_end ();
   unblock_input ();
   return success_p;
 }
@@ -5257,7 +5250,7 @@ realize_basic_faces (struct frame *f)
    specified, make it fully-specified.  Attributes of the default face
    that are not explicitly specified are taken from frame parameters.  */
 
-static int
+static bool
 realize_default_face (struct frame *f)
 {
   struct face_cache *c = FRAME_FACE_CACHE (f);
@@ -5468,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
@@ -5737,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;
@@ -5946,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)
 {
@@ -5967,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.  */
@@ -6004,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.  */
@@ -6032,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,
@@ -6056,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)
 {
@@ -6075,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.  */
@@ -6090,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;
 
@@ -6102,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,
@@ -6143,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)
 {
@@ -6175,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
@@ -6199,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);
@@ -6291,36 +6243,32 @@ where R,G,B are numbers between 0 and 255 and name is an arbitrary string.  */)
   CHECK_STRING (filename);
   abspath = Fexpand_file_name (filename, Qnil);
 
-  fp = fopen (SSDATA (abspath), "rt");
+  block_input ();
+  fp = emacs_fopen (SSDATA (abspath), "rt");
   if (fp)
     {
       char buf[512];
       int red, green, blue;
       int num;
 
-      block_input ();
-
       while (fgets (buf, sizeof (buf), fp) != NULL) {
        if (sscanf (buf, "%u %u %u %n", &red, &green, &blue, &num) == 3)
          {
-           char *name = buf + num;
-           num = strlen (name) - 1;
-           if (num >= 0 && name[num] == '\n')
-             name[num] = 0;
-           cmap = Fcons (Fcons (build_string (name),
 #ifdef HAVE_NTGUI
-                                make_number (RGB (red, green, blue))),
+           int color = RGB (red, green, blue);
 #else
-                                make_number ((red << 16) | (green << 8) | blue)),
+           int color = (red << 16) | (green << 8) | blue;
 #endif
+           char *name = buf + num;
+           ptrdiff_t len = strlen (name);
+           len -= 0 < len && name[len - 1] == '\n';
+           cmap = Fcons (Fcons (make_string (name, len), make_number (color)),
                          cmap);
          }
       }
       fclose (fp);
-
-      unblock_input ();
     }
-
+  unblock_input ();
   return cmap;
 }
 #endif
@@ -6370,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");
 
@@ -6416,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");
@@ -6435,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");
@@ -6478,57 +6429,22 @@ 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");
   DEFSYM (Qtty_color_alist, "tty-color-alist");
   DEFSYM (Qscalable_fonts_allowed, "scalable-fonts-allowed");
 
-  Vparam_value_alist = Fcons (Fcons (Qnil, Qnil), Qnil);
+  Vparam_value_alist = list1 (Fcons (Qnil, Qnil));
   staticpro (&Vparam_value_alist);
   Vface_alternative_font_family_alist = Qnil;
   staticpro (&Vface_alternative_font_family_alist);
   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;
@@ -6612,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
 }