]> code.delx.au - gnu-emacs/blobdiff - src/xfaces.c
Try other addresses when connecting to multihomed
[gnu-emacs] / src / xfaces.c
index f788c304bd8d9a9b7cc304d03a6e507483fa7c41..97a5ae01e36b3ef0b79d7d0ac5c1901ddcf20028 100644 (file)
@@ -1,13 +1,13 @@
 /* xfaces.c -- "Face" primitives.
 
-Copyright (C) 1993-1994, 1998-2014 Free Software Foundation, Inc.
+Copyright (C) 1993-1994, 1998-2016 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -80,7 +80,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    specs overwrite the font-spec in the 14th attribute.
 
 
-   Faces are frame-local by nature because Emacs allows to define the
+   Faces are frame-local by nature because Emacs allows you to define the
    same named face (face names are symbols) differently for different
    frames.  Each frame has an alist of face definitions for all named
    faces.  The value of a named face in such an alist is a Lisp vector
@@ -206,10 +206,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "lisp.h"
 #include "character.h"
-#include "charset.h"
-#include "keyboard.h"
 #include "frame.h"
-#include "termhooks.h"
 
 #ifdef USE_MOTIF
 #include <Xm/Xm.h>
@@ -224,7 +221,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include TERM_HEADER
 #include "fontset.h"
 #ifdef HAVE_NTGUI
-#define x_display_info w32_display_info
 #define GCGraphicsExposures 0
 #endif /* HAVE_NTGUI */
 
@@ -237,7 +233,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "dispextern.h"
 #include "blockinput.h"
 #include "window.h"
-#include "intervals.h"
 #include "termchar.h"
 
 #include "font.h"
@@ -265,11 +260,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <c-ctype.h>
 
-/* Non-zero if face attribute ATTR is unspecified.  */
+/* True if face attribute ATTR is unspecified.  */
 
 #define UNSPECIFIEDP(ATTR) EQ ((ATTR), Qunspecified)
 
-/* Non-zero if face attribute ATTR is `ignore-defface'.  */
+/* True if face attribute ATTR is `ignore-defface'.  */
 
 #define IGNORE_DEFFACE_P(ATTR) EQ ((ATTR), QCignore_defface)
 
@@ -278,57 +273,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #define FACE_CACHE_BUCKETS_SIZE 1001
 
-/* Keyword symbols used for face attribute names.  */
-
-Lisp_Object QCfamily, QCheight, QCweight, QCslant;
-static Lisp_Object QCunderline;
-static Lisp_Object QCinverse_video, QCstipple;
-Lisp_Object QCforeground, QCbackground;
-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, QCdistant_foreground;
-
-/* Symbols used for attribute values.  */
-
-Lisp_Object Qnormal;
-Lisp_Object Qbold;
-static Lisp_Object Qline, Qwave;
-Lisp_Object Qextra_light, Qlight;
-Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold;
-Lisp_Object Qoblique;
-Lisp_Object Qitalic;
-static Lisp_Object Qreleased_button, Qpressed_button;
-static Lisp_Object QCstyle, QCcolor, QCline_width;
-Lisp_Object Qunspecified;      /* used in dosfns.c */
-static Lisp_Object QCignore_defface;
-
 char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg";
 
-/* The name of the function to call when the background of the frame
-   has changed, frame_set_background_mode.  */
-
-static Lisp_Object Qframe_set_background_mode;
-
-/* Names of basic faces.  */
-
-Lisp_Object Qdefault, Qtool_bar, Qfringe;
-static Lisp_Object Qregion;
-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
-   the aliased face.  */
-
-static Lisp_Object Qface_alias;
-
 /* Alist of alternative font families.  Each element is of the form
    (FAMILY FAMILY1 FAMILY2 ...).  If fonts of FAMILY can't be loaded,
    try FAMILY1, then FAMILY2, ...  */
@@ -341,32 +287,6 @@ Lisp_Object Vface_alternative_font_family_alist;
 
 Lisp_Object Vface_alternative_font_registry_alist;
 
-/* Allowed scalable fonts.  A value of nil means don't allow any
-   scalable fonts.  A value of t means allow the use of any scalable
-   font.  Otherwise, value must be a list of regular expressions.  A
-   font may be scaled if its name matches a regular expression in the
-   list.  */
-
-static Lisp_Object Qscalable_fonts_allowed;
-
-/* The symbols `foreground-color' and `background-color' which can be
-   used as part of a `face' property.  This is for compatibility with
-   Emacs 20.2.  */
-
-Lisp_Object Qforeground_color, Qbackground_color;
-
-/* The symbols `face' and `mouse-face' used as text properties.  */
-
-Lisp_Object Qface;
-
-/* Property for basic faces which other faces cannot inherit.  */
-
-static Lisp_Object Qface_no_inherit;
-
-/* Error symbol for wrong_type_argument in load_pixmap.  */
-
-static Lisp_Object Qbitmap_spec_p;
-
 /* The next ID to assign to Lisp faces.  */
 
 static int next_lface_id;
@@ -376,14 +296,6 @@ static int next_lface_id;
 static Lisp_Object *lface_id_to_name;
 static ptrdiff_t lface_id_to_name_size;
 
-/* TTY color-related functions (defined in tty-colors.el).  */
-
-static Lisp_Object Qtty_color_desc, Qtty_color_by_index, Qtty_color_standard_values;
-
-/* The name of the function used to compute colors on TTYs.  */
-
-static Lisp_Object Qtty_color_alist;
-
 #ifdef HAVE_WINDOW_SYSTEM
 
 /* Counter for calls to clear_face_cache.  If this counter reaches
@@ -396,17 +308,17 @@ static int clear_font_table_count;
 
 #endif /* HAVE_WINDOW_SYSTEM */
 
-/* Non-zero means face attributes have been changed since the last
+/* True means face attributes have been changed since the last
    redisplay.  Used in redisplay_internal.  */
 
-int face_change_count;
+bool face_change;
 
-/* Non-zero means don't display bold text if a face's foreground
+/* True means don't display bold text if a face's foreground
    and background colors are the inverse of the default colors of the
    display.   This is a kluge to suppress `bold black' foreground text
    which is hard to read on an LCD monitor.  */
 
-static int tty_suppress_bold_inverse_default_colors_p;
+static bool tty_suppress_bold_inverse_default_colors_p;
 
 /* A list of the form `((x . y))' used to avoid consing in
    Finternal_set_lisp_face_attribute.  */
@@ -421,10 +333,10 @@ static int npixmaps_allocated;
 static int ngcs;
 #endif
 
-/* Non-zero means the definition of the `menu' face for new frames has
+/* True means the definition of the `menu' face for new frames has
    been changed.  */
 
-static int menu_face_changed_default;
+static bool menu_face_changed_default;
 
 struct named_merge_point;
 
@@ -437,8 +349,8 @@ 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 free_face_cache (struct face_cache *);
-static int merge_face_ref (struct frame *, Lisp_Object, Lisp_Object *,
-                          int, struct named_merge_point *);
+static bool merge_face_ref (struct frame *, Lisp_Object, Lisp_Object *,
+                           bool, struct named_merge_point *);
 static int color_distance (XColor *x, XColor *y);
 
 #ifdef HAVE_WINDOW_SYSTEM
@@ -537,11 +449,9 @@ DEFUN ("dump-colors", Fdump_colors, Sdump_colors, 0, 0, 0,
 void
 x_free_colors (struct frame *f, unsigned long *pixels, int npixels)
 {
-  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.  */
-  if (class != StaticColor && class != StaticGray && class != TrueColor)
+  if (x_mutable_colormap (FRAME_X_VISUAL (f)))
     {
 #ifdef DEBUG_X_COLORS
       unregister_colors (pixels, npixels);
@@ -554,7 +464,7 @@ x_free_colors (struct frame *f, unsigned long *pixels, int npixels)
 
 #ifdef USE_X_TOOLKIT
 
-/* Free colors used on frame F.  PIXELS is an array of NPIXELS pixel
+/* Free colors used on display DPY.  PIXELS is an array of NPIXELS pixel
    color values.  Interrupt input must be blocked when this function
    is called.  */
 
@@ -563,11 +473,10 @@ x_free_dpy_colors (Display *dpy, Screen *screen, Colormap cmap,
                   unsigned long *pixels, int npixels)
 {
   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
-  int class = dpyinfo->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.  */
-  if (class != StaticColor && class != StaticGray && class != TrueColor)
+  if (x_mutable_colormap (dpyinfo->visual))
     {
 #ifdef DEBUG_X_COLORS
       unregister_colors (pixels, npixels);
@@ -714,25 +623,25 @@ free_frame_faces (struct frame *f)
 /* Clear face caches, and recompute basic faces for frame F.  Call
    this after changing frame parameters on which those faces depend,
    or when realized faces have been freed due to changing attributes
-   of named faces. */
+   of named faces.  */
 
 void
 recompute_basic_faces (struct frame *f)
 {
   if (FRAME_FACE_CACHE (f))
     {
-      clear_face_cache (0);
+      clear_face_cache (false);
       if (!realize_basic_faces (f))
        emacs_abort ();
     }
 }
 
 
-/* Clear the face caches of all frames.  CLEAR_FONTS_P non-zero means
+/* Clear the face caches of all frames.  CLEAR_FONTS_P means
    try to free unused fonts, too.  */
 
 void
-clear_face_cache (int clear_fonts_p)
+clear_face_cache (bool clear_fonts_p)
 {
 #ifdef HAVE_WINDOW_SYSTEM
   Lisp_Object tail, frame;
@@ -770,14 +679,13 @@ clear_face_cache (int clear_fonts_p)
 #endif /* HAVE_WINDOW_SYSTEM */
 }
 
-
 DEFUN ("clear-face-cache", Fclear_face_cache, Sclear_face_cache, 0, 1, 0,
        doc: /* Clear face caches on all frames.
 Optional THOROUGHLY non-nil means try to free unused fonts, too.  */)
   (Lisp_Object thoroughly)
 {
   clear_face_cache (!NILP (thoroughly));
-  ++face_change_count;
+  face_change = true;
   windows_or_buffers_changed = 53;
   return Qnil;
 }
@@ -798,11 +706,11 @@ the pixmap.  Bits are stored row by row, each row occupies
 \(WIDTH + 7)/8 bytes.  */)
   (Lisp_Object object)
 {
-  bool pixmap_p = 0;
+  bool pixmap_p = false;
 
   if (STRINGP (object))
     /* If OBJECT is a string, it's a file name.  */
-    pixmap_p = 1;
+    pixmap_p = true;
   else if (CONSP (object))
     {
       /* Otherwise OBJECT must be (WIDTH HEIGHT DATA), WIDTH and
@@ -832,7 +740,7 @@ the pixmap.  Bits are stored row by row, each row occupies
          int bytes_per_row = ((XINT (width) + BITS_PER_CHAR - 1)
                               / BITS_PER_CHAR);
          if (XINT (height) <= SBYTES (data) / bytes_per_row)
-           pixmap_p = 1;
+           pixmap_p = true;
        }
     }
 
@@ -880,7 +788,7 @@ load_pixmap (struct frame *f, Lisp_Object name)
 
   if (bitmap_id < 0)
     {
-      add_to_log ("Invalid or undefined bitmap `%s'", name, Qnil);
+      add_to_log ("Invalid or undefined bitmap `%s'", name);
       bitmap_id = 0;
     }
   else
@@ -903,9 +811,9 @@ load_pixmap (struct frame *f, Lisp_Object name)
 
 /* 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.  */
+   Return true iff RGB_LIST is OK.  */
 
-static int
+static bool
 parse_rgb_list (Lisp_Object rgb_list, XColor *color)
 {
 #define PARSE_RGB_LIST_FIELD(field)                                    \
@@ -915,13 +823,13 @@ parse_rgb_list (Lisp_Object rgb_list, XColor *color)
       rgb_list = XCDR (rgb_list);                                      \
     }                                                                  \
   else                                                                 \
-    return 0;
+    return false;
 
   PARSE_RGB_LIST_FIELD (red);
   PARSE_RGB_LIST_FIELD (green);
   PARSE_RGB_LIST_FIELD (blue);
 
-  return 1;
+  return true;
 }
 
 
@@ -937,7 +845,7 @@ tty_lookup_color (struct frame *f, Lisp_Object color, XColor *tty_color,
   Lisp_Object frame, color_desc;
 
   if (!STRINGP (color) || NILP (Ffboundp (Qtty_color_desc)))
-    return 0;
+    return false;
 
   XSETFRAME (frame, f);
 
@@ -947,13 +855,13 @@ tty_lookup_color (struct frame *f, Lisp_Object color, XColor *tty_color,
       Lisp_Object rgb;
 
       if (! INTEGERP (XCAR (XCDR (color_desc))))
-       return 0;
+       return false;
 
       tty_color->pixel = XINT (XCAR (XCDR (color_desc)));
 
       rgb = XCDR (XCDR (color_desc));
       if (! parse_rgb_list (rgb, tty_color))
-       return 0;
+       return false;
 
       /* Should we fill in STD_COLOR too?  */
       if (std_color)
@@ -972,21 +880,21 @@ tty_lookup_color (struct frame *f, Lisp_Object color, XColor *tty_color,
              /* Look up STD_COLOR separately.  */
              rgb = call1 (Qtty_color_standard_values, color);
              if (! parse_rgb_list (rgb, std_color))
-               return 0;
+               return false;
            }
        }
 
-      return 1;
+      return true;
     }
   else if (NILP (Fsymbol_value (intern ("tty-defined-color-alist"))))
     /* We were called early during startup, and the colors are not
        yet set up in tty-defined-color-alist.  Don't return a failure
        indication, since this produces the annoying "Unable to
        load color" messages in the *Messages* buffer.  */
-    return 1;
+    return true;
   else
     /* tty-color-desc seems to have returned a bad value.  */
-    return 0;
+    return false;
 }
 
 /* A version of defined_color for non-X frames.  */
@@ -995,7 +903,7 @@ static bool
 tty_defined_color (struct frame *f, const char *color_name,
                   XColor *color_def, bool alloc)
 {
-  bool status = 1;
+  bool status = true;
 
   /* Defaults.  */
   color_def->pixel = FACE_TTY_DEFAULT_COLOR;
@@ -1015,7 +923,7 @@ tty_defined_color (struct frame *f, const char *color_name,
     }
 
   if (color_def->pixel != FACE_TTY_DEFAULT_COLOR)
-    status = 1;
+    status = true;
 
   return status;
 }
@@ -1043,7 +951,7 @@ defined_color (struct frame *f, const char *color_name, XColor *color_def,
 #endif
 #ifdef HAVE_NS
   else if (FRAME_NS_P (f))
-    return ns_defined_color (f, color_name, color_def, alloc, 1);
+    return ns_defined_color (f, color_name, color_def, alloc, true);
 #endif
   else
     emacs_abort ();
@@ -1083,18 +991,18 @@ tty_color_name (struct frame *f, int idx)
 }
 
 
-/* Return non-zero if COLOR_NAME is a shade of gray (or white or
+/* Return true if COLOR_NAME is a shade of gray (or white or
    black) on frame F.
 
    The criterion implemented here is not a terribly sophisticated one.  */
 
-static int
+static bool
 face_color_gray_p (struct frame *f, const char *color_name)
 {
   XColor color;
-  int gray_p;
+  bool gray_p;
 
-  if (defined_color (f, color_name, &color, 0))
+  if (defined_color (f, color_name, &color, false))
     gray_p = (/* Any color sufficiently close to black counts as gray.  */
              (color.red < 5000 && color.green < 5000 && color.blue < 5000)
              ||
@@ -1105,19 +1013,18 @@ face_color_gray_p (struct frame *f, const char *color_name)
               && (eabs (color.blue - color.red)
                   < max (color.blue, color.red) / 20)));
   else
-    gray_p = 0;
+    gray_p = false;
 
   return gray_p;
 }
 
 
-/* Return non-zero if color COLOR_NAME can be displayed on frame F.
-   BACKGROUND_P non-zero means the color will be used as background
-   color.  */
+/* Return true if color COLOR_NAME can be displayed on frame F.
+   BACKGROUND_P means the color will be used as background color.  */
 
-static int
+static bool
 face_color_supported_p (struct frame *f, const char *color_name,
-                       int background_p)
+                       bool background_p)
 {
   Lisp_Object frame;
   XColor not_used;
@@ -1135,7 +1042,7 @@ face_color_supported_p (struct frame *f, const char *color_name,
           && face_color_gray_p (f, color_name)))
     :
 #endif
-    tty_defined_color (f, color_name, &not_used, 0);
+    tty_defined_color (f, color_name, &not_used, false);
 }
 
 
@@ -1181,39 +1088,39 @@ load_color2 (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, true))
     {
-      add_to_log ("Unable to load color \"%s\"", name, Qnil);
+      add_to_log ("Unable to load color \"%s\"", name);
 
       switch (target_index)
        {
        case LFACE_FOREGROUND_INDEX:
-         face->foreground_defaulted_p = 1;
+         face->foreground_defaulted_p = true;
          color->pixel = FRAME_FOREGROUND_PIXEL (f);
          break;
 
        case LFACE_BACKGROUND_INDEX:
-         face->background_defaulted_p = 1;
+         face->background_defaulted_p = true;
          color->pixel = FRAME_BACKGROUND_PIXEL (f);
          break;
 
        case LFACE_UNDERLINE_INDEX:
-         face->underline_defaulted_p = 1;
+         face->underline_defaulted_p = true;
          color->pixel = FRAME_FOREGROUND_PIXEL (f);
          break;
 
        case LFACE_OVERLINE_INDEX:
-         face->overline_color_defaulted_p = 1;
+         face->overline_color_defaulted_p = true;
          color->pixel = FRAME_FOREGROUND_PIXEL (f);
          break;
 
        case LFACE_STRIKE_THROUGH_INDEX:
-         face->strike_through_color_defaulted_p = 1;
+         face->strike_through_color_defaulted_p = true;
          color->pixel = FRAME_FOREGROUND_PIXEL (f);
          break;
 
        case LFACE_BOX_INDEX:
-         face->box_color_defaulted_p = 1;
+         face->box_color_defaulted_p = true;
          color->pixel = FRAME_FOREGROUND_PIXEL (f);
          break;
 
@@ -1279,7 +1186,7 @@ load_face_colors (struct frame *f, struct face *face,
      face_color_supported_p is smart enough to know that grays are
      "supported" as background because we are supposed to use stipple
      for them.  */
-  if (!face_color_supported_p (f, SSDATA (bg), 0)
+  if (!face_color_supported_p (f, SSDATA (bg), false)
       && !NILP (Fbitmap_spec_p (Vface_default_stipple)))
     {
       x_destroy_bitmap (f, face->stipple);
@@ -1612,7 +1519,7 @@ the WIDTH times as wide as FACE on FRAME.  */)
    Lisp_Object maximum, Lisp_Object width)
 {
   struct frame *f;
-  int size, avgwidth IF_LINT (= 0);
+  int size, avgwidth;
 
   check_window_system (NULL);
   CHECK_STRING (pattern);
@@ -1644,7 +1551,7 @@ the WIDTH times as wide as FACE on FRAME.  */)
     {
       /* This is of limited utility since it works with character
         widths.  Keep it for compatibility.  --gerd.  */
-      int face_id = lookup_named_face (f, face, 0);
+      int face_id = lookup_named_face (f, face, false);
       struct face *width_face = (face_id < 0
                                 ? NULL
                                 : FACE_FROM_ID (f, face_id));
@@ -1663,43 +1570,38 @@ the WIDTH times as wide as FACE on FRAME.  */)
        avgwidth *= XINT (width);
     }
 
-  {
-    Lisp_Object font_spec;
-    Lisp_Object args[2], tail;
-
-    font_spec = font_spec_from_name (pattern);
-    if (!FONTP (font_spec))
-      signal_error ("Invalid font name", pattern);
+  Lisp_Object font_spec = font_spec_from_name (pattern);
+  if (!FONTP (font_spec))
+    signal_error ("Invalid font name", pattern);
 
-    if (size)
-      {
-       Ffont_put (font_spec, QCsize, make_number (size));
-       Ffont_put (font_spec, QCavgwidth, make_number (avgwidth));
-      }
-    args[0] = Flist_fonts (font_spec, frame, maximum, font_spec);
-    for (tail = args[0]; CONSP (tail); tail = XCDR (tail))
-      {
-       Lisp_Object font_entity;
+  if (size)
+    {
+      Ffont_put (font_spec, QCsize, make_number (size));
+      Ffont_put (font_spec, QCavgwidth, make_number (avgwidth));
+    }
+  Lisp_Object fonts = Flist_fonts (font_spec, frame, maximum, font_spec);
+  for (Lisp_Object tail = fonts; CONSP (tail); tail = XCDR (tail))
+    {
+      Lisp_Object font_entity;
 
-       font_entity = XCAR (tail);
-       if ((NILP (AREF (font_entity, FONT_SIZE_INDEX))
-            || XINT (AREF (font_entity, FONT_SIZE_INDEX)) == 0)
-           && ! NILP (AREF (font_spec, FONT_SIZE_INDEX)))
-         {
-           /* This is a scalable font.  For backward compatibility,
-              we set the specified size. */
-           font_entity = copy_font_spec (font_entity);
-           ASET (font_entity, FONT_SIZE_INDEX,
-                 AREF (font_spec, FONT_SIZE_INDEX));
-         }
-       XSETCAR (tail, Ffont_xlfd_name (font_entity, Qnil));
-      }
-    if (NILP (frame))
-      /* We don't have to check fontsets.  */
-      return args[0];
-    args[1] = list_fontsets (f, pattern, size);
-    return Fnconc (2, args);
-  }
+      font_entity = XCAR (tail);
+      if ((NILP (AREF (font_entity, FONT_SIZE_INDEX))
+          || XINT (AREF (font_entity, FONT_SIZE_INDEX)) == 0)
+         && ! NILP (AREF (font_spec, FONT_SIZE_INDEX)))
+       {
+         /* This is a scalable font.  For backward compatibility,
+            we set the specified size. */
+         font_entity = copy_font_spec (font_entity);
+         ASET (font_entity, FONT_SIZE_INDEX,
+               AREF (font_spec, FONT_SIZE_INDEX));
+       }
+      XSETCAR (tail, Ffont_xlfd_name (font_entity, Qnil));
+    }
+  if (NILP (frame))
+    /* We don't have to check fontsets.  */
+    return fonts;
+  Lisp_Object fontsets = list_fontsets (f, pattern, size);
+  return CALLN (Fnconc, fonts, fontsets);
 }
 
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -1731,7 +1633,7 @@ the WIDTH times as wide as FACE on FRAME.  */)
 #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
+/* True 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.  */
 
 #define LFACEP(LFACE)                                  \
@@ -1758,8 +1660,7 @@ check_lface_attrs (Lisp_Object attrs[LFACE_VECTOR_SIZE])
           || SYMBOLP (attrs[LFACE_SWIDTH_INDEX]));
   eassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
           || IGNORE_DEFFACE_P (attrs[LFACE_HEIGHT_INDEX])
-          || INTEGERP (attrs[LFACE_HEIGHT_INDEX])
-          || FLOATP (attrs[LFACE_HEIGHT_INDEX])
+          || NUMBERP (attrs[LFACE_HEIGHT_INDEX])
           || FUNCTIONP (attrs[LFACE_HEIGHT_INDEX]));
   eassert (UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
           || IGNORE_DEFFACE_P (attrs[LFACE_WEIGHT_INDEX])
@@ -1861,12 +1762,12 @@ struct named_merge_point
 };
 
 
-/* If a face merging cycle is detected for FACE_NAME, return 0,
+/* If a face merging cycle is detected for FACE_NAME, return false,
    otherwise add NEW_NAMED_MERGE_POINT, which is initialized using
    FACE_NAME and NAMED_MERGE_POINT_KIND, as the head of the linked list
-   pointed to by NAMED_MERGE_POINTS, and return 1.  */
+   pointed to by NAMED_MERGE_POINTS, and return true.  */
 
-static int
+static bool
 push_named_merge_point (struct named_merge_point *new_named_merge_point,
                        Lisp_Object face_name,
                        enum named_merge_point_kind named_merge_point_kind,
@@ -1879,7 +1780,7 @@ push_named_merge_point (struct named_merge_point *new_named_merge_point,
       {
        if (prev->named_merge_point_kind == named_merge_point_kind)
          /* A cycle, so fail.  */
-         return 0;
+         return false;
        else if (prev->named_merge_point_kind == NAMED_MERGE_POINT_REMAP)
          /* A remap `hides ' any previous normal merge points
             (because the remap means that it's actually different face),
@@ -1894,7 +1795,7 @@ push_named_merge_point (struct named_merge_point *new_named_merge_point,
 
   *named_merge_points = new_named_merge_point;
 
-  return 1;
+  return true;
 }
 
 \f
@@ -1905,13 +1806,13 @@ push_named_merge_point (struct named_merge_point *new_named_merge_point,
    Return default face in case of errors.  */
 
 static Lisp_Object
-resolve_face_name (Lisp_Object face_name, int signal_p)
+resolve_face_name (Lisp_Object face_name, bool signal_p)
 {
   Lisp_Object orig_face;
   Lisp_Object tortoise, hare;
 
   if (STRINGP (face_name))
-    face_name = intern (SSDATA (face_name));
+    face_name = Fintern (face_name, Qnil);
 
   if (NILP (face_name) || !SYMBOLP (face_name))
     return face_name;
@@ -1919,7 +1820,7 @@ resolve_face_name (Lisp_Object face_name, int signal_p)
   orig_face = face_name;
   tortoise = hare = face_name;
 
-  while (1)
+  while (true)
     {
       face_name = hare;
       hare = Fget (hare, Qface_alias);
@@ -1947,12 +1848,12 @@ resolve_face_name (Lisp_Object face_name, int signal_p)
 /* Return the face definition of FACE_NAME on frame F.  F null means
    return the definition for new frames.  FACE_NAME may be a string or
    a symbol (apparently Emacs 20.2 allowed strings as face names in
-   face text properties; Ediff uses that).  If SIGNAL_P is non-zero,
-   signal an error if FACE_NAME is not a valid face name.  If SIGNAL_P
-   is zero, value is nil if FACE_NAME is not a valid face name.  */
+   face text properties; Ediff uses that).
+   If SIGNAL_P, signal an error if FACE_NAME is not a valid face name.
+   Otherwise, value is nil if FACE_NAME is not a valid face name.  */
 static Lisp_Object
 lface_from_face_name_no_resolve (struct frame *f, Lisp_Object face_name,
-                                int signal_p)
+                                bool signal_p)
 {
   Lisp_Object lface;
 
@@ -1975,12 +1876,11 @@ lface_from_face_name_no_resolve (struct frame *f, Lisp_Object face_name,
    return the definition for new frames.  FACE_NAME may be a string or
    a symbol (apparently Emacs 20.2 allowed strings as face names in
    face text properties; Ediff uses that).  If FACE_NAME is an alias
-   for another face, return that face's definition.  If SIGNAL_P is
-   non-zero, signal an error if FACE_NAME is not a valid face name.
-   If SIGNAL_P is zero, value is nil if FACE_NAME is not a valid face
-   name.  */
+   for another face, return that face's definition.
+   If SIGNAL_P, signal an error if FACE_NAME is not a valid face name.
+   Otherwise, value is nil if FACE_NAME is not a valid face name.  */
 static Lisp_Object
-lface_from_face_name (struct frame *f, Lisp_Object face_name, int signal_p)
+lface_from_face_name (struct frame *f, Lisp_Object face_name, bool signal_p)
 {
   face_name = resolve_face_name (face_name, signal_p);
   return lface_from_face_name_no_resolve (f, face_name, signal_p);
@@ -1989,14 +1889,14 @@ lface_from_face_name (struct frame *f, Lisp_Object face_name, int signal_p)
 
 /* Get face attributes of face FACE_NAME from frame-local faces on
    frame F.  Store the resulting attributes in ATTRS which must point
-   to a vector of Lisp_Objects of size LFACE_VECTOR_SIZE.  If SIGNAL_P
-   is non-zero, signal an error if FACE_NAME does not name a face.
-   Otherwise, value is zero if FACE_NAME is not a face.  */
+   to a vector of Lisp_Objects of size LFACE_VECTOR_SIZE.
+   If SIGNAL_P, signal an error if FACE_NAME does not name a face.
+   Otherwise, return true iff FACE_NAME is a face.  */
 
-static int
+static bool
 get_lface_attributes_no_remap (struct frame *f, Lisp_Object face_name,
                               Lisp_Object attrs[LFACE_VECTOR_SIZE],
-                              int signal_p)
+                              bool signal_p)
 {
   Lisp_Object lface;
 
@@ -2012,13 +1912,13 @@ get_lface_attributes_no_remap (struct frame *f, Lisp_Object face_name,
 /* Get face attributes of face FACE_NAME from frame-local faces on frame
    F.  Store the resulting attributes in ATTRS which must point to a
    vector of Lisp_Objects of size LFACE_VECTOR_SIZE.  If FACE_NAME is an
-   alias for another face, use that face's definition.  If SIGNAL_P is
-   non-zero, signal an error if FACE_NAME does not name a face.
-   Otherwise, value is zero if FACE_NAME is not a face.  */
+   alias for another face, use that face's definition.
+   If SIGNAL_P, signal an error if FACE_NAME does not name a face.
+   Otherwise, return true iff FACE_NAME is a face.  */
 
-static int
+static bool
 get_lface_attributes (struct frame *f, Lisp_Object face_name,
-                     Lisp_Object attrs[LFACE_VECTOR_SIZE], int signal_p,
+                     Lisp_Object attrs[LFACE_VECTOR_SIZE], bool signal_p,
                      struct named_merge_point *named_merge_points)
 {
   Lisp_Object face_remapping;
@@ -2051,10 +1951,10 @@ get_lface_attributes (struct frame *f, Lisp_Object face_name,
 }
 
 
-/* Non-zero if all attributes in face attribute vector ATTRS are
+/* True iff all attributes in face attribute vector ATTRS are
    specified, i.e. are non-nil.  */
 
-static int
+static bool
 lface_fully_specified_p (Lisp_Object attrs[LFACE_VECTOR_SIZE])
 {
   int i;
@@ -2071,13 +1971,13 @@ lface_fully_specified_p (Lisp_Object attrs[LFACE_VECTOR_SIZE])
 #ifdef HAVE_WINDOW_SYSTEM
 
 /* Set font-related attributes of Lisp face LFACE from FONT-OBJECT.
-   If FORCE_P is zero, set only unspecified attributes of LFACE.  The
+   If FORCE_P, set only unspecified attributes of LFACE.  The
    exception is `font' attribute.  It is set to FONT_OBJECT regardless
    of FORCE_P.  */
 
-static int
+static void
 set_lface_from_font (struct frame *f, Lisp_Object lface,
-                    Lisp_Object font_object, int force_p)
+                    Lisp_Object font_object, bool force_p)
 {
   Lisp_Object val;
   struct font *font = XFONT_OBJECT (font_object);
@@ -2125,7 +2025,6 @@ set_lface_from_font (struct frame *f, Lisp_Object lface,
     }
 
   ASET (lface, LFACE_FONT_INDEX, font_object);
-  return 1;
 }
 
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -2196,7 +2095,7 @@ merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to,
      other code uses `unspecified' as a generic value for face attributes. */
   if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX])
       && !NILP (from[LFACE_INHERIT_INDEX]))
-    merge_face_ref (f, from[LFACE_INHERIT_INDEX], to, 0, named_merge_points);
+    merge_face_ref (f, from[LFACE_INHERIT_INDEX], to, false, named_merge_points);
 
   if (FONT_SPEC_P (from[LFACE_FONT_INDEX]))
     {
@@ -2254,11 +2153,11 @@ merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to,
 }
 
 /* Merge the named face FACE_NAME on frame F, into the vector of face
-   attributes TO.  NAMED_MERGE_POINTS is used to detect loops in face
-   inheritance.  Returns true if FACE_NAME is a valid face name and
+   attributes TO.  Use NAMED_MERGE_POINTS to detect loops in face
+   inheritance.  Return true if FACE_NAME is a valid face name and
    merging succeeded.  */
 
-static int
+static bool
 merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to,
                  struct named_merge_point *named_merge_points)
 {
@@ -2268,29 +2167,25 @@ merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to,
                              face_name, NAMED_MERGE_POINT_NORMAL,
                              &named_merge_points))
     {
-      struct gcpro gcpro1;
       Lisp_Object from[LFACE_VECTOR_SIZE];
-      int ok = get_lface_attributes (f, face_name, from, 0, named_merge_points);
+      bool ok = get_lface_attributes (f, face_name, from, false,
+                                     named_merge_points);
 
       if (ok)
-       {
-         GCPRO1 (named_merge_point.face_name);
-         merge_face_vectors (f, from, to, named_merge_points);
-         UNGCPRO;
-       }
+       merge_face_vectors (f, from, to, named_merge_points);
 
       return ok;
     }
   else
-    return 0;
+    return false;
 }
 
 
 /* Merge face attributes from the lisp `face reference' FACE_REF on
-   frame F into the face attribute vector TO.  If ERR_MSGS is non-zero,
+   frame F into the face attribute vector TO.  If ERR_MSGS,
    problems with FACE_REF cause an error message to be shown.  Return
-   non-zero if no errors occurred (regardless of the value of ERR_MSGS).
-   NAMED_MERGE_POINTS is used to detect loops in face inheritance or
+   true if no errors occurred (regardless of the value of ERR_MSGS).
+   Use NAMED_MERGE_POINTS to detect loops in face inheritance or
    list structure; it may be 0 for most callers.
 
    FACE_REF may be a single face specification or a list of such
@@ -2309,11 +2204,11 @@ merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to,
    Face specifications earlier in lists take precedence over later
    specifications.  */
 
-static int
+static bool
 merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
-               int err_msgs, struct named_merge_point *named_merge_points)
+               bool err_msgs, struct named_merge_point *named_merge_points)
 {
-  int ok = 1;                  /* Succeed without an error? */
+  bool ok = true;              /* Succeed without an error? */
 
   if (CONSP (face_ref))
     {
@@ -2337,8 +2232,8 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
          else
            {
              if (err_msgs)
-               add_to_log ("Invalid face color", color_name, Qnil);
-             ok = 0;
+               add_to_log ("Invalid face color %S", color_name);
+             ok = false;
            }
        }
       else if (SYMBOLP (first)
@@ -2349,7 +2244,7 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
            {
              Lisp_Object keyword = XCAR (face_ref);
              Lisp_Object value = XCAR (XCDR (face_ref));
-             int err = 0;
+             bool err = false;
 
              /* Specifying `unspecified' is a no-op.  */
              if (EQ (value, Qunspecified))
@@ -2362,7 +2257,7 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
                      font_clear_prop (to, FONT_FAMILY_INDEX);
                    }
                  else
-                   err = 1;
+                   err = true;
                }
              else if (EQ (keyword, QCfoundry))
                {
@@ -2372,7 +2267,7 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
                      font_clear_prop (to, FONT_FOUNDRY_INDEX);
                    }
                  else
-                   err = 1;
+                   err = true;
                }
              else if (EQ (keyword, QCheight))
                {
@@ -2385,7 +2280,7 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
                      font_clear_prop (to, FONT_SIZE_INDEX);
                    }
                  else
-                   err = 1;
+                   err = true;
                }
              else if (EQ (keyword, QCweight))
                {
@@ -2395,7 +2290,7 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
                      font_clear_prop (to, FONT_WEIGHT_INDEX);
                    }
                  else
-                   err = 1;
+                   err = true;
                }
              else if (EQ (keyword, QCslant))
                {
@@ -2405,7 +2300,7 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
                      font_clear_prop (to, FONT_SLANT_INDEX);
                    }
                  else
-                   err = 1;
+                   err = true;
                }
              else if (EQ (keyword, QCunderline))
                {
@@ -2415,7 +2310,7 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
                      || CONSP (value))
                    to[LFACE_UNDERLINE_INDEX] = value;
                  else
-                   err = 1;
+                   err = true;
                }
              else if (EQ (keyword, QCoverline))
                {
@@ -2424,7 +2319,7 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
                      || STRINGP (value))
                    to[LFACE_OVERLINE_INDEX] = value;
                  else
-                   err = 1;
+                   err = true;
                }
              else if (EQ (keyword, QCstrike_through))
                {
@@ -2433,7 +2328,7 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
                      || STRINGP (value))
                    to[LFACE_STRIKE_THROUGH_INDEX] = value;
                  else
-                   err = 1;
+                   err = true;
                }
              else if (EQ (keyword, QCbox))
                {
@@ -2445,7 +2340,7 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
                      || NILP (value))
                    to[LFACE_BOX_INDEX] = value;
                  else
-                   err = 1;
+                   err = true;
                }
              else if (EQ (keyword, QCinverse_video)
                       || EQ (keyword, QCreverse_video))
@@ -2453,28 +2348,28 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
                  if (EQ (value, Qt) || NILP (value))
                    to[LFACE_INVERSE_INDEX] = value;
                  else
-                   err = 1;
+                   err = true;
                }
              else if (EQ (keyword, QCforeground))
                {
                  if (STRINGP (value))
                    to[LFACE_FOREGROUND_INDEX] = value;
                  else
-                   err = 1;
+                   err = true;
                }
              else if (EQ (keyword, QCdistant_foreground))
                {
                  if (STRINGP (value))
                    to[LFACE_DISTANT_FOREGROUND_INDEX] = value;
                  else
-                   err = 1;
+                   err = true;
                }
              else if (EQ (keyword, QCbackground))
                {
                  if (STRINGP (value))
                    to[LFACE_BACKGROUND_INDEX] = value;
                  else
-                   err = 1;
+                   err = true;
                }
              else if (EQ (keyword, QCstipple))
                {
@@ -2483,7 +2378,7 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
                  if (!NILP (pixmap_p))
                    to[LFACE_STIPPLE_INDEX] = value;
                  else
-                   err = 1;
+                   err = true;
 #endif /* HAVE_WINDOW_SYSTEM */
                }
              else if (EQ (keyword, QCwidth))
@@ -2494,14 +2389,14 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
                      font_clear_prop (to, FONT_WIDTH_INDEX);
                    }
                  else
-                   err = 1;
+                   err = true;
                }
              else if (EQ (keyword, QCfont))
                {
                  if (FONTP (value))
                    to[LFACE_FONT_INDEX] = value;
                  else
-                   err = 1;
+                   err = true;
                }
              else if (EQ (keyword, QCinherit))
                {
@@ -2509,15 +2404,15 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
                     normal face reference.  */
                  if (! merge_face_ref (f, value, to,
                                        err_msgs, named_merge_points))
-                   err = 1;
+                   err = true;
                }
              else
-               err = 1;
+               err = true;
 
              if (err)
                {
                  add_to_log ("Invalid face attribute %S %S", keyword, value);
-                 ok = 0;
+                 ok = false;
                }
 
              face_ref = XCDR (XCDR (face_ref));
@@ -2534,7 +2429,7 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
            ok = merge_face_ref (f, next, to, err_msgs, named_merge_points);
 
          if (! merge_face_ref (f, first, to, err_msgs, named_merge_points))
-           ok = 0;
+           ok = false;
        }
     }
   else
@@ -2542,7 +2437,7 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
       /* FACE_REF ought to be a face name.  */
       ok = merge_named_face (f, face_ref, to, named_merge_points);
       if (!ok && err_msgs)
-       add_to_log ("Invalid face reference: %s", face_ref, Qnil);
+       add_to_log ("Invalid face reference: %s", face_ref);
     }
 
   return ok;
@@ -2563,13 +2458,13 @@ Value is a vector of face attributes.  */)
   int i;
 
   CHECK_SYMBOL (face);
-  global_lface = lface_from_face_name (NULL, face, 0);
+  global_lface = lface_from_face_name (NULL, face, false);
 
   if (!NILP (frame))
     {
       CHECK_LIVE_FRAME (frame);
       f = XFRAME (frame);
-      lface = lface_from_face_name (f, face, 0);
+      lface = lface_from_face_name (f, face, false);
     }
   else
     f = NULL, lface = Qnil;
@@ -2620,12 +2515,20 @@ Value is a vector of face attributes.  */)
   /* Changing a named face means that all realized faces depending on
      that face are invalid.  Since we cannot tell which realized faces
      depend on the face, make sure they are all removed.  This is done
-     by incrementing face_change_count.  The next call to
-     init_iterator will then free realized faces.  */
+     by setting face_change.  The next call to init_iterator will then
+     free realized faces.  */
   if (NILP (Fget (face, Qface_no_inherit)))
     {
-      ++face_change_count;
-      windows_or_buffers_changed = 54;
+      if (f)
+       {
+         f->face_change = true;
+         fset_redisplay (f);
+       }
+      else
+       {
+         face_change = true;
+         windows_or_buffers_changed = 54;
+       }
     }
 
   eassert (LFACEP (lface));
@@ -2645,15 +2548,15 @@ Otherwise check for the existence of a global face.  */)
 {
   Lisp_Object lface;
 
-  face = resolve_face_name (face, 1);
+  face = resolve_face_name (face, true);
 
   if (!NILP (frame))
     {
       CHECK_LIVE_FRAME (frame);
-      lface = lface_from_face_name (XFRAME (frame), face, 0);
+      lface = lface_from_face_name (XFRAME (frame), face, false);
     }
   else
-    lface = lface_from_face_name (NULL, face, 0);
+    lface = lface_from_face_name (NULL, face, false);
 
   return lface;
 }
@@ -2672,6 +2575,7 @@ The value is TO.  */)
   (Lisp_Object from, Lisp_Object to, Lisp_Object frame, Lisp_Object new_frame)
 {
   Lisp_Object lface, copy;
+  struct frame *f;
 
   CHECK_SYMBOL (from);
   CHECK_SYMBOL (to);
@@ -2680,8 +2584,9 @@ The value is TO.  */)
     {
       /* Copy global definition of FROM.  We don't make copies of
         strings etc. because 20.2 didn't do it either.  */
-      lface = lface_from_face_name (NULL, from, 1);
+      lface = lface_from_face_name (NULL, from, true);
       copy = Finternal_make_lisp_face (to, Qnil);
+      f = NULL;
     }
   else
     {
@@ -2690,8 +2595,9 @@ The value is TO.  */)
        new_frame = frame;
       CHECK_LIVE_FRAME (frame);
       CHECK_LIVE_FRAME (new_frame);
-      lface = lface_from_face_name (XFRAME (frame), from, 1);
+      lface = lface_from_face_name (XFRAME (frame), from, true);
       copy = Finternal_make_lisp_face (to, new_frame);
+      f = XFRAME (new_frame);
     }
 
   vcopy (copy, 0, XVECTOR (lface)->contents, LFACE_VECTOR_SIZE);
@@ -2699,12 +2605,20 @@ The value is TO.  */)
   /* Changing a named face means that all realized faces depending on
      that face are invalid.  Since we cannot tell which realized faces
      depend on the face, make sure they are all removed.  This is done
-     by incrementing face_change_count.  The next call to
-     init_iterator will then free realized faces.  */
+     by setting face_change.  The next call to init_iterator will then
+     free realized faces.  */
   if (NILP (Fget (to, Qface_no_inherit)))
     {
-      ++face_change_count;
-      windows_or_buffers_changed = 55;
+      if (f)
+       {
+         f->face_change = true;
+         fset_redisplay (f);
+       }
+      else
+       {
+         face_change = true;
+         windows_or_buffers_changed = 55;
+       }
     }
 
   return to;
@@ -2726,11 +2640,12 @@ FRAME 0 means change the face on all frames, and change the default
   /* Set one of enum font_property_index (> 0) if ATTR is one of
      font-related attributes other than QCfont and QCfontset.  */
   enum font_property_index prop_index = 0;
+  struct frame *f;
 
   CHECK_SYMBOL (face);
   CHECK_SYMBOL (attr);
 
-  face = resolve_face_name (face, 1);
+  face = resolve_face_name (face, true);
 
   /* If FRAME is 0, change face on all frames, and change the
      default for new frames.  */
@@ -2746,7 +2661,8 @@ FRAME 0 means change the face on all frames, and change the default
   /* Set lface to the Lisp attribute vector of FACE.  */
   if (EQ (frame, Qt))
     {
-      lface = lface_from_face_name (NULL, face, 1);
+      f = NULL;
+      lface = lface_from_face_name (NULL, face, true);
 
       /* When updating face-new-frame-defaults, we put :ignore-defface
         where the caller wants `unspecified'.  This forces the frame
@@ -2763,7 +2679,9 @@ FRAME 0 means change the face on all frames, and change the default
        frame = selected_frame;
 
       CHECK_LIVE_FRAME (frame);
-      lface = lface_from_face_name (XFRAME (frame), face, 0);
+      f = XFRAME (frame);
+
+      lface = lface_from_face_name (f, face, false);
 
       /* If a frame-local face doesn't exist yet, create one.  */
       if (NILP (lface))
@@ -2848,14 +2766,14 @@ FRAME 0 means change the face on all frames, and change the default
     }
   else if (EQ (attr, QCunderline))
     {
-      bool valid_p = 0;
+      bool valid_p = false;
 
       if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
-       valid_p = 1;
+       valid_p = true;
       else if (NILP (value) || EQ (value, Qt))
-        valid_p = 1;
+        valid_p = true;
       else if (STRINGP (value) && SCHARS (value) > 0)
-        valid_p = 1;
+        valid_p = true;
       else if (CONSP (value))
         {
           Lisp_Object key, val, list;
@@ -2867,7 +2785,7 @@ FRAME 0 means change the face on all frames, and change the default
              Non-nil symbols other than t are not documented as being valid.
              Eg compare with inverse-video, which explicitly rejects them.
           */
-          valid_p = 1;
+          valid_p = true;
 
           while (!NILP (CAR_SAFE(list)))
             {
@@ -2878,7 +2796,7 @@ FRAME 0 means change the face on all frames, and change the default
 
               if (NILP (key) || NILP (val))
                 {
-                  valid_p = 0;
+                  valid_p = false;
                   break;
                 }
 
@@ -2886,14 +2804,14 @@ FRAME 0 means change the face on all frames, and change the default
                        && !(EQ (val, Qforeground_color)
                             || (STRINGP (val) && SCHARS (val) > 0)))
                 {
-                  valid_p = 0;
+                  valid_p = false;
                   break;
                 }
 
               else if (EQ (key, QCstyle)
                        && !(EQ (val, Qline) || EQ (val, Qwave)))
                 {
-                  valid_p = 0;
+                  valid_p = false;
                   break;
                 }
             }
@@ -2943,9 +2861,9 @@ FRAME 0 means change the face on all frames, and change the default
        value = make_number (1);
 
       if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
-       valid_p = 1;
+       valid_p = true;
       else if (NILP (value))
-       valid_p = 1;
+       valid_p = true;
       else if (INTEGERP (value))
        valid_p = XINT (value) != 0;
       else if (STRINGP (value))
@@ -2988,7 +2906,7 @@ FRAME 0 means change the face on all frames, and change the default
          valid_p = NILP (tem);
        }
       else
-       valid_p = 0;
+       valid_p = false;
 
       if (!valid_p)
        signal_error ("Invalid face box", value);
@@ -3085,11 +3003,11 @@ FRAME 0 means change the face on all frames, and change the default
   else if (EQ (attr, QCfont))
     {
 #ifdef HAVE_WINDOW_SYSTEM
-      if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
+      if (EQ (frame, Qt) || FRAME_WINDOW_P (f))
        {
          if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
            {
-             struct frame *f;
+             struct frame *f1;
 
              old_value = LFACE_FONT (lface);
              if (! FONTP (value))
@@ -3109,20 +3027,30 @@ FRAME 0 means change the face on all frames, and change the default
                    signal_error ("Invalid font or font-spec", value);
                }
              if (EQ (frame, Qt))
-               f = XFRAME (selected_frame);
+               f1 = XFRAME (selected_frame);
              else
-               f = XFRAME (frame);
-             if (! FONT_OBJECT_P (value))
-               {
-                 Lisp_Object *attrs = XVECTOR (lface)->contents;
-                 Lisp_Object font_object;
-
-                 font_object = font_load_for_lface (f, attrs, value);
-                 if (NILP (font_object))
-                   signal_error ("Font not available", value);
-                 value = font_object;
-               }
-             set_lface_from_font (f, lface, value, 1);
+               f1 = XFRAME (frame);
+
+              /* FIXME:
+                 If frame is t, and selected frame is a tty frame, the font
+                 can't be realized.  An improvement would be to loop over frames
+                 for a non-tty frame and use that.  See discussion in Bug#18573.
+                 For a daemon, frame may be an initial frame (Bug#18869).  */
+              if (FRAME_WINDOW_P (f1))
+                {
+                  if (! FONT_OBJECT_P (value))
+                    {
+                      Lisp_Object *attrs = XVECTOR (lface)->contents;
+                      Lisp_Object font_object;
+
+                      font_object = font_load_for_lface (f1, attrs, value);
+                      if (NILP (font_object))
+                        signal_error ("Font not available", value);
+                      value = font_object;
+                    }
+                  set_lface_from_font (f1, lface, value, true);
+                 f1->face_change = 1;
+                }
            }
          else
            ASET (lface, LFACE_FONT_INDEX, value);
@@ -3132,7 +3060,7 @@ FRAME 0 means change the face on all frames, and change the default
   else if (EQ (attr, QCfontset))
     {
 #ifdef HAVE_WINDOW_SYSTEM
-      if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
+      if (EQ (frame, Qt) || FRAME_WINDOW_P (f))
        {
          Lisp_Object tmp;
 
@@ -3188,14 +3116,14 @@ FRAME 0 means change the face on all frames, and change the default
   /* Changing a named face means that all realized faces depending on
      that face are invalid.  Since we cannot tell which realized faces
      depend on the face, make sure they are all removed.  This is done
-     by incrementing face_change_count.  The next call to
-     init_iterator will then free realized faces.  */
+     by setting face_change.  The next call to init_iterator will then
+     free realized faces.  */
   if (!EQ (frame, Qt)
       && NILP (Fget (face, Qface_no_inherit))
       && NILP (Fequal (old_value, value)))
     {
-      ++face_change_count;
-      windows_or_buffers_changed = 56;
+      f->face_change = true;
+      fset_redisplay (f);
     }
 
   if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
@@ -3266,10 +3194,10 @@ FRAME 0 means change the face on all frames, and change the default
              struct frame *f = XFRAME (frame);
              if (FRAME_FACE_CACHE (f) == NULL)
                FRAME_FACE_CACHE (f) = make_face_cache (f);
-             FRAME_FACE_CACHE (f)->menu_face_changed_p = 1;
+             FRAME_FACE_CACHE (f)->menu_face_changed_p = true;
            }
          else
-           menu_face_changed_default = 1;
+           menu_face_changed_default = true;
        }
 
       if (!NILP (param))
@@ -3314,7 +3242,7 @@ update_face_from_frame_parameter (struct frame *f, Lisp_Object param,
   if (EQ (param, Qforeground_color))
     {
       face = Qdefault;
-      lface = lface_from_face_name (f, face, 1);
+      lface = lface_from_face_name (f, face, true);
       ASET (lface, LFACE_FOREGROUND_INDEX,
            (STRINGP (new_value) ? new_value : Qunspecified));
       realize_basic_faces (f);
@@ -3330,7 +3258,7 @@ update_face_from_frame_parameter (struct frame *f, Lisp_Object param,
       call1 (Qframe_set_background_mode, frame);
 
       face = Qdefault;
-      lface = lface_from_face_name (f, face, 1);
+      lface = lface_from_face_name (f, face, true);
       ASET (lface, LFACE_BACKGROUND_INDEX,
            (STRINGP (new_value) ? new_value : Qunspecified));
       realize_basic_faces (f);
@@ -3339,21 +3267,21 @@ update_face_from_frame_parameter (struct frame *f, Lisp_Object param,
   else if (EQ (param, Qborder_color))
     {
       face = Qborder;
-      lface = lface_from_face_name (f, face, 1);
+      lface = lface_from_face_name (f, face, true);
       ASET (lface, LFACE_BACKGROUND_INDEX,
            (STRINGP (new_value) ? new_value : Qunspecified));
     }
   else if (EQ (param, Qcursor_color))
     {
       face = Qcursor;
-      lface = lface_from_face_name (f, face, 1);
+      lface = lface_from_face_name (f, face, true);
       ASET (lface, LFACE_BACKGROUND_INDEX,
            (STRINGP (new_value) ? new_value : Qunspecified));
     }
   else if (EQ (param, Qmouse_color))
     {
       face = Qmouse;
-      lface = lface_from_face_name (f, face, 1);
+      lface = lface_from_face_name (f, face, true);
       ASET (lface, LFACE_BACKGROUND_INDEX,
            (STRINGP (new_value) ? new_value : Qunspecified));
     }
@@ -3362,13 +3290,13 @@ update_face_from_frame_parameter (struct frame *f, Lisp_Object param,
   /* Changing a named face means that all realized faces depending on
      that face are invalid.  Since we cannot tell which realized faces
      depend on the face, make sure they are all removed.  This is done
-     by incrementing face_change_count.  The next call to
-     init_iterator will then free realized faces.  */
+     by setting face_change.  The next call to init_iterator will then
+     free realized faces.  */
   if (!NILP (face)
       && NILP (Fget (face, Qface_no_inherit)))
     {
-      ++face_change_count;
-      windows_or_buffers_changed = 57;
+      f->face_change = true;
+      fset_redisplay (f);
     }
 }
 
@@ -3397,8 +3325,9 @@ set_font_frame_param (Lisp_Object frame, Lisp_Object lface)
            return;
          ASET (lface, LFACE_FONT_INDEX, font);
        }
-      f->default_face_done_p = 0;
-      Fmodify_frame_parameters (frame, FRAME_PARAMETER (Qfont, font));
+      f->default_face_done_p = false;
+      AUTO_FRAME_ARG (arg, Qfont, font);
+      Fmodify_frame_parameters (frame, arg);
     }
 }
 
@@ -3426,11 +3355,11 @@ ordinary `x-get-resource' doesn't take a frame argument.  */)
 
 /* Return resource string VALUE as a boolean value, i.e. nil, or t.
    If VALUE is "on" or "true", return t.  If VALUE is "off" or
-   "false", return nil.  Otherwise, if SIGNAL_P is non-zero, signal an
-   error; if SIGNAL_P is zero, return 0.  */
+   "false", return nil.  Otherwise, if SIGNAL_P, signal an
+   error; if !SIGNAL_P, return 0.  */
 
 static Lisp_Object
-face_boolean_x_resource_value (Lisp_Object value, int signal_p)
+face_boolean_x_resource_value (Lisp_Object value, bool signal_p)
 {
   Lisp_Object result = make_number (0);
 
@@ -3470,11 +3399,11 @@ DEFUN ("internal-set-lisp-face-attribute-from-resource",
        signal_error ("Invalid face height from X resource", value);
     }
   else if (EQ (attr, QCbold) || EQ (attr, QCitalic))
-    value = face_boolean_x_resource_value (value, 1);
+    value = face_boolean_x_resource_value (value, true);
   else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth))
     value = intern (SSDATA (value));
   else if (EQ (attr, QCreverse_video) || EQ (attr, QCinverse_video))
-    value = face_boolean_x_resource_value (value, 1);
+    value = face_boolean_x_resource_value (value, true);
   else if (EQ (attr, QCunderline)
           || EQ (attr, QCoverline)
           || EQ (attr, QCstrike_through))
@@ -3483,7 +3412,7 @@ DEFUN ("internal-set-lisp-face-attribute-from-resource",
 
       /* If the result of face_boolean_x_resource_value is t or nil,
         VALUE does NOT specify a color. */
-      boolean_value = face_boolean_x_resource_value (value, 0);
+      boolean_value = face_boolean_x_resource_value (value, false);
       if (SYMBOLP (boolean_value))
        value = boolean_value;
     }
@@ -3517,10 +3446,10 @@ x_update_menu_appearance (struct frame *f)
       char line[512];
       char *buf = line;
       ptrdiff_t bufsize = sizeof line;
-      Lisp_Object lface = lface_from_face_name (f, Qmenu, 1);
+      Lisp_Object lface = lface_from_face_name (f, Qmenu, true);
       struct face *face = FACE_FROM_ID (f, MENU_FACE_ID);
       const char *myname = SSDATA (Vx_resource_name);
-      bool changed_p = 0;
+      bool changed_p = false;
 #ifdef USE_MOTIF
       const char *popup_path = "popup_menu";
 #else
@@ -3536,7 +3465,7 @@ x_update_menu_appearance (struct frame *f)
          exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*foreground: %s",
                    myname, SDATA (LFACE_FOREGROUND (lface)));
          XrmPutLineResource (&rdb, line);
-         changed_p = 1;
+         changed_p = true;
        }
 
       if (STRINGP (LFACE_BACKGROUND (lface)))
@@ -3549,7 +3478,7 @@ x_update_menu_appearance (struct frame *f)
          exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*background: %s",
                    myname, SDATA (LFACE_BACKGROUND (lface)));
          XrmPutLineResource (&rdb, line);
-         changed_p = 1;
+         changed_p = true;
        }
 
       if (face->font
@@ -3567,7 +3496,7 @@ x_update_menu_appearance (struct frame *f)
          Lisp_Object xlfd = Ffont_xlfd_name (LFACE_FONT (lface), Qnil);
 #ifdef USE_MOTIF
          const char *suffix = "List";
-         Bool motif = True;
+         bool motif = true;
 #else
 #if defined HAVE_X_I18N
 
@@ -3575,7 +3504,7 @@ x_update_menu_appearance (struct frame *f)
 #else
          const char *suffix = "";
 #endif
-         Bool motif = False;
+         bool motif = false;
 #endif
 
          if (! NILP (xlfd))
@@ -3592,7 +3521,7 @@ x_update_menu_appearance (struct frame *f)
              exprintf (&buf, &bufsize, line, -1, "%s.%s*font%s: %s",
                        myname, popup_path, suffix, fontsetname);
              XrmPutLineResource (&rdb, line);
-             changed_p = 1;
+             changed_p = true;
              if (fontsetname != SSDATA (xlfd))
                xfree (fontsetname);
            }
@@ -3619,7 +3548,8 @@ with the value VALUE is relative.
 A relative value is one that doesn't entirely override whatever is
 inherited from another face.  For most possible attributes,
 the only relative value that users see is `unspecified'.
-However, for :height, floating point values are also relative.  */)
+However, for :height, floating point values are also relative.  */
+       attributes: const)
   (Lisp_Object attribute, Lisp_Object value)
 {
   if (EQ (value, Qunspecified) || (EQ (value, QCignore_defface)))
@@ -3658,7 +3588,7 @@ frames).  If FRAME is omitted or nil, use the selected frame.  */)
   (Lisp_Object symbol, Lisp_Object keyword, Lisp_Object frame)
 {
   struct frame *f = EQ (frame, Qt) ? NULL : decode_live_frame (frame);
-  Lisp_Object lface = lface_from_face_name (f, symbol, 1), value = Qnil;
+  Lisp_Object lface = lface_from_face_name (f, symbol, true), value = Qnil;
 
   CHECK_SYMBOL (symbol);
   CHECK_SYMBOL (keyword);
@@ -3741,8 +3671,8 @@ Default face attributes override any local face attributes.  */)
   struct frame *f = XFRAME (frame);
 
   CHECK_LIVE_FRAME (frame);
-  global_lface = lface_from_face_name (NULL, face, 1);
-  local_lface = lface_from_face_name (f, face, 0);
+  global_lface = lface_from_face_name (NULL, face, true);
+  local_lface = lface_from_face_name (f, face, false);
   if (NILP (local_lface))
     local_lface = Finternal_make_lisp_face (face, frame);
 
@@ -3764,7 +3694,7 @@ Default face attributes override any local face attributes.  */)
   if (EQ (face, Qdefault))
     {
       struct face_cache *c = FRAME_FACE_CACHE (f);
-      struct face *newface, *oldface = FACE_FROM_ID (f, DEFAULT_FACE_ID);
+      struct face *newface, *oldface = FACE_OPT_FROM_ID (f, DEFAULT_FACE_ID);
       Lisp_Object attrs[LFACE_VECTOR_SIZE];
 
       /* This can be NULL (e.g., in batch mode).  */
@@ -3787,18 +3717,23 @@ Default face attributes override any local face attributes.  */)
              && newface->font)
            {
              Lisp_Object name = newface->font->props[FONT_NAME_INDEX];
-             Fmodify_frame_parameters (frame, FRAME_PARAMETER (Qfont, name));
+             AUTO_FRAME_ARG (arg, Qfont, name);
+             Fmodify_frame_parameters (frame, arg);
            }
 
          if (STRINGP (gvec[LFACE_FOREGROUND_INDEX]))
-           Fmodify_frame_parameters
-             (frame, FRAME_PARAMETER (Qforeground_color,
-                                      gvec[LFACE_FOREGROUND_INDEX]));
+           {
+             AUTO_FRAME_ARG (arg, Qforeground_color,
+                             gvec[LFACE_FOREGROUND_INDEX]);
+             Fmodify_frame_parameters (frame, arg);
+           }
 
          if (STRINGP (gvec[LFACE_BACKGROUND_INDEX]))
-           Fmodify_frame_parameters
-             (frame, FRAME_PARAMETER (Qbackground_color,
-                                      gvec[LFACE_BACKGROUND_INDEX]));
+           {
+             AUTO_FRAME_ARG (arg, Qbackground_color,
+                             gvec[LFACE_BACKGROUND_INDEX]);
+             Fmodify_frame_parameters (frame, arg);
+           }
        }
     }
 
@@ -3826,7 +3761,7 @@ return the font name used for CHARACTER.  */)
   if (EQ (frame, Qt))
     {
       Lisp_Object result = Qnil;
-      Lisp_Object lface = lface_from_face_name (NULL, face, 1);
+      Lisp_Object lface = lface_from_face_name (NULL, face, true);
 
       if (!UNSPECIFIEDP (LFACE_WEIGHT (lface))
          && !EQ (LFACE_WEIGHT (lface), Qnormal))
@@ -3841,8 +3776,8 @@ return the font name used for CHARACTER.  */)
   else
     {
       struct frame *f = decode_live_frame (frame);
-      int face_id = lookup_named_face (f, face, 1);
-      struct face *fface = FACE_FROM_ID (f, face_id);
+      int face_id = lookup_named_face (f, face, true);
+      struct face *fface = FACE_OPT_FROM_ID (f, face_id);
 
       if (! fface)
        return Qnil;
@@ -3866,7 +3801,7 @@ return the font name used for CHARACTER.  */)
 }
 
 
-/* Compare face-attribute values v1 and v2 for equality.  Value is non-zero if
+/* Compare face-attribute values v1 and v2 for equality.  Value is true if
    all attributes are `equal'.  Tries to be fast because this function
    is called quite often.  */
 
@@ -3876,22 +3811,22 @@ 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;
+    return false;
 
   if (EQ (v1, v2))
-    return 1;
+    return true;
 
   switch (XTYPE (v1))
     {
     case Lisp_String:
       if (SBYTES (v1) != SBYTES (v2))
-       return 0;
+       return false;
 
       return memcmp (SDATA (v1), SDATA (v2), SBYTES (v1)) == 0;
 
     case_Lisp_Int:
     case Lisp_Symbol:
-      return 0;
+      return false;
 
     default:
       return !NILP (Fequal (v1, v2));
@@ -3899,7 +3834,7 @@ face_attr_equal_p (Lisp_Object v1, Lisp_Object v2)
 }
 
 
-/* Compare face vectors V1 and V2 for equality.  Value is non-zero if
+/* Compare face vectors V1 and V2 for equality.  Value is true if
    all attributes are `equal'.  Tries to be fast because this function
    is called quite often.  */
 
@@ -3907,7 +3842,7 @@ static bool
 lface_equal_p (Lisp_Object *v1, Lisp_Object *v2)
 {
   int i;
-  bool equal_p = 1;
+  bool equal_p = true;
 
   for (i = 1; i < LFACE_VECTOR_SIZE && equal_p; ++i)
     equal_p = face_attr_equal_p (v1[i], v2[i]);
@@ -3924,7 +3859,7 @@ If FRAME is t, report on the defaults for FACE1 and FACE2 (for new frames).
 If FRAME is omitted or nil, use the selected frame.  */)
   (Lisp_Object face1, Lisp_Object face2, Lisp_Object frame)
 {
-  int equal_p;
+  bool equal_p;
   struct frame *f;
   Lisp_Object lface1, lface2;
 
@@ -3934,8 +3869,8 @@ If FRAME is omitted or nil, use the selected frame.  */)
      Emacs.  That frame is not an X frame.  */
   f = EQ (frame, Qt) ? NULL : decode_live_frame (frame);
 
-  lface1 = lface_from_face_name (f, face1, 1);
-  lface2 = lface_from_face_name (f, face2, 1);
+  lface1 = lface_from_face_name (f, face1, true);
+  lface2 = lface_from_face_name (f, face2, true);
   equal_p = lface_equal_p (XVECTOR (lface1)->contents,
                           XVECTOR (lface2)->contents);
   return equal_p ? Qt : Qnil;
@@ -3951,7 +3886,7 @@ If FRAME is omitted or nil, use the selected frame.  */)
   (Lisp_Object face, Lisp_Object frame)
 {
   struct frame *f = EQ (frame, Qt) ? NULL : decode_live_frame (frame);
-  Lisp_Object lface = lface_from_face_name (f, face, 1);
+  Lisp_Object lface = lface_from_face_name (f, face, true);
   int i;
 
   for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
@@ -4004,12 +3939,12 @@ lface_hash (Lisp_Object *v)
 
 #ifdef HAVE_WINDOW_SYSTEM
 
-/* Return non-zero if LFACE1 and LFACE2 specify the same font (without
+/* Return true if LFACE1 and LFACE2 specify the same font (without
    considering charsets/registries).  They do if they specify the same
    family, point size, weight, width, slant, and font.  Both
    LFACE1 and LFACE2 must be fully-specified.  */
 
-static int
+static bool
 lface_same_font_attributes_p (Lisp_Object *lface1, Lisp_Object *lface2)
 {
   eassert (lface_fully_specified_p (lface1)
@@ -4166,10 +4101,12 @@ If FRAME is unspecified or nil, the current frame is used.  */)
   XColor cdef1, cdef2;
 
   if (!(CONSP (color1) && parse_rgb_list (color1, &cdef1))
-      && !(STRINGP (color1) && defined_color (f, SSDATA (color1), &cdef1, 0)))
+      && !(STRINGP (color1)
+          && defined_color (f, SSDATA (color1), &cdef1, false)))
     signal_error ("Invalid color", color1);
   if (!(CONSP (color2) && parse_rgb_list (color2, &cdef2))
-      && !(STRINGP (color2) && defined_color (f, SSDATA (color2), &cdef2, 0)))
+      && !(STRINGP (color2)
+          && defined_color (f, SSDATA (color2), &cdef2, false)))
     signal_error ("Invalid color", color2);
 
   return make_number (color_distance (&cdef1, &cdef2));
@@ -4250,6 +4187,8 @@ free_realized_faces (struct face_cache *c)
          c->faces_by_id[i] = NULL;
        }
 
+      /* Forget the escape-glyph and glyphless-char faces.  */
+      forget_escape_and_glyphless_faces ();
       c->used = 0;
       size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
       memset (c->buckets, 0, size);
@@ -4261,7 +4200,7 @@ free_realized_faces (struct face_cache *c)
       if (WINDOWP (f->root_window))
        {
          clear_current_matrices (f);
-         windows_or_buffers_changed = 58;
+         fset_redisplay (f);
        }
 
       unblock_input ();
@@ -4281,6 +4220,7 @@ free_all_realized_faces (Lisp_Object frame)
       Lisp_Object rest;
       FOR_EACH_FRAME (rest, frame)
        free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
+      windows_or_buffers_changed = 58;
     }
   else
     free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
@@ -4485,19 +4425,17 @@ face_for_font (struct frame *f, Lisp_Object font_object, struct face *base_face)
    face isn't realized and cannot be realized.  */
 
 int
-lookup_named_face (struct frame *f, Lisp_Object symbol, int signal_p)
+lookup_named_face (struct frame *f, Lisp_Object symbol, bool signal_p)
 {
   Lisp_Object attrs[LFACE_VECTOR_SIZE];
   Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
-  struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
+  struct face *default_face = FACE_OPT_FROM_ID (f, DEFAULT_FACE_ID);
 
   if (default_face == NULL)
     {
       if (!realize_basic_faces (f))
        return -1;
       default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
-      if (default_face == NULL)
-       emacs_abort (); /* realize_basic_faces must have set it up  */
     }
 
   if (! get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0))
@@ -4552,7 +4490,7 @@ lookup_basic_face (struct frame *f, int face_id)
 
   /* If there is a remapping entry, lookup the face using NAME, which will
      handle the remapping too.  */
-  remapped_face_id = lookup_named_face (f, name, 0);
+  remapped_face_id = lookup_named_face (f, name, false);
   if (remapped_face_id < 0)
     return face_id;            /* Give up. */
 
@@ -4654,15 +4592,12 @@ face_with_height (struct frame *f, int face_id, int height)
 
 int
 lookup_derived_face (struct frame *f, Lisp_Object symbol, int face_id,
-                    int signal_p)
+                    bool signal_p)
 {
   Lisp_Object attrs[LFACE_VECTOR_SIZE];
   Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
   struct face *default_face = FACE_FROM_ID (f, face_id);
 
-  if (!default_face)
-    emacs_abort ();
-
   if (!get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0))
     return -1;
 
@@ -4680,7 +4615,7 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
   lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
                        Qunspecified);
   merge_face_ref (XFRAME (selected_frame), plist, XVECTOR (lface)->contents,
-                 1, 0);
+                 true, 0);
   return lface;
 }
 
@@ -4706,8 +4641,8 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
    that a face containing all the attributes in ATTRS, when merged with the
    default face for display, can be represented in a way that's
 
-    \(1) different in appearance than the default face, and
-    \(2) `close in spirit' to what the attributes specify, if not exact.  */
+    (1) different in appearance than the default face, and
+    (2) `close in spirit' to what the attributes specify, if not exact.  */
 
 static bool
 x_supports_face_attributes_p (struct frame *f,
@@ -4745,7 +4680,7 @@ x_supports_face_attributes_p (struct frame *f,
       || (!UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
          && face_attr_equal_p (attrs[LFACE_BOX_INDEX],
                                def_attrs[LFACE_BOX_INDEX])))
-    return 0;
+    return false;
 
   /* Check font-related attributes, as those are the most commonly
      "unsupported" on a window-system (because of missing fonts).  */
@@ -4766,7 +4701,7 @@ x_supports_face_attributes_p (struct frame *f,
       merge_face_vectors (f, attrs, merged_attrs, 0);
 
       face_id = lookup_face (f, merged_attrs);
-      face = FACE_FROM_ID (f, face_id);
+      face = FACE_OPT_FROM_ID (f, face_id);
 
       if (! face)
        error ("Cannot make face");
@@ -4775,7 +4710,7 @@ x_supports_face_attributes_p (struct frame *f,
         supported.  */
       if (face->font == def_face->font
          || ! face->font)
-       return 0;
+       return false;
       for (i = FONT_TYPE_INDEX; i <= FONT_SIZE_INDEX; i++)
        if (! EQ (face->font->props[i], def_face->font->props[i]))
          {
@@ -4783,18 +4718,18 @@ x_supports_face_attributes_p (struct frame *f,
 
            if (i < FONT_FOUNDRY_INDEX || i > FONT_REGISTRY_INDEX
                || face->font->driver->case_sensitive)
-             return 1;
+             return true;
            s1 = SYMBOL_NAME (face->font->props[i]);
            s2 = SYMBOL_NAME (def_face->font->props[i]);
            if (! EQ (Fcompare_strings (s1, make_number (0), Qnil,
                                        s2, make_number (0), Qnil, Qt), Qt))
-             return 1;
+             return true;
          }
-      return 0;
+      return false;
     }
 
   /* Everything checks out, this face is supported.  */
-  return 1;
+  return true;
 }
 
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -4806,8 +4741,8 @@ x_supports_face_attributes_p (struct frame *f,
    that a face containing all the attributes in ATTRS, when merged
    with the default face for display, can be represented in a way that's
 
-    \(1) different in appearance than the default face, and
-    \(2) `close in spirit' to what the attributes specify, if not exact.
+    (1) different in appearance than the default face, and
+    (2) `close in spirit' to what the attributes specify, if not exact.
 
    Point (2) implies that a `:weight black' attribute will be satisfied
    by any terminal that can display bold, and a `:foreground "yellow"' as
@@ -4843,7 +4778,7 @@ tty_supports_face_attributes_p (struct frame *f,
       || !UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
       || !UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
       || !UNSPECIFIEDP (attrs[LFACE_BOX_INDEX]))
-    return 0;
+    return false;
 
   /* Test for terminal `capabilities' (non-color character attributes).  */
 
@@ -4857,17 +4792,17 @@ tty_supports_face_attributes_p (struct frame *f,
       if (weight > 100)
        {
          if (def_weight > 100)
-           return 0;           /* same as default */
+           return false;       /* same as default */
          test_caps = TTY_CAP_BOLD;
        }
       else if (weight < 100)
        {
          if (def_weight < 100)
-           return 0;           /* same as default */
+           return false;       /* same as default */
          test_caps = TTY_CAP_DIM;
        }
       else if (def_weight == 100)
-       return 0;               /* same as default */
+       return false;           /* same as default */
     }
 
   /* font slant */
@@ -4877,7 +4812,7 @@ tty_supports_face_attributes_p (struct frame *f,
     {
       int def_slant = FONT_SLANT_NAME_NUMERIC (def_attrs[LFACE_SLANT_INDEX]);
       if (slant == 100 || slant == def_slant)
-       return 0; /* same as default */
+       return false;           /* same as default */
       else
        test_caps |= TTY_CAP_ITALIC;
     }
@@ -4887,11 +4822,11 @@ tty_supports_face_attributes_p (struct frame *f,
   if (!UNSPECIFIEDP (val))
     {
       if (STRINGP (val))
-       return 0;               /* ttys can't use colored underlines */
+       return false;           /* ttys can't use colored underlines */
       else if (EQ (CAR_SAFE (val), QCstyle) && EQ (CAR_SAFE (CDR_SAFE (val)), Qwave))
-       return 0;               /* ttys can't use wave underlines */
+       return false;           /* ttys can't use wave underlines */
       else if (face_attr_equal_p (val, def_attrs[LFACE_UNDERLINE_INDEX]))
-       return 0;               /* same as default */
+       return false;           /* same as default */
       else
        test_caps |= TTY_CAP_UNDERLINE;
     }
@@ -4901,7 +4836,7 @@ tty_supports_face_attributes_p (struct frame *f,
   if (!UNSPECIFIEDP (val))
     {
       if (face_attr_equal_p (val, def_attrs[LFACE_INVERSE_INDEX]))
-       return 0;               /* same as default */
+       return false;           /* same as default */
       else
        test_caps |= TTY_CAP_INVERSE;
     }
@@ -4916,12 +4851,12 @@ tty_supports_face_attributes_p (struct frame *f,
       Lisp_Object def_fg = def_attrs[LFACE_FOREGROUND_INDEX];
 
       if (face_attr_equal_p (fg, def_fg))
-       return 0;               /* same as default */
+       return false;           /* same as default */
       else if (! tty_lookup_color (f, fg, &fg_tty_color, &fg_std_color))
-       return 0;               /* not a valid color */
+       return false;           /* not a valid color */
       else if (color_distance (&fg_tty_color, &fg_std_color)
               > TTY_SAME_COLOR_THRESHOLD)
-       return 0;               /* displayed color is too different */
+       return false;           /* displayed color is too different */
       else
        /* Make sure the color is really different than the default.  */
        {
@@ -4929,7 +4864,7 @@ tty_supports_face_attributes_p (struct frame *f,
          if (tty_lookup_color (f, def_fg, &def_fg_color, 0)
              && (color_distance (&fg_tty_color, &def_fg_color)
                  <= TTY_SAME_COLOR_THRESHOLD))
-           return 0;
+           return false;
        }
     }
 
@@ -4940,12 +4875,12 @@ tty_supports_face_attributes_p (struct frame *f,
       Lisp_Object def_bg = def_attrs[LFACE_BACKGROUND_INDEX];
 
       if (face_attr_equal_p (bg, def_bg))
-       return 0;               /* same as default */
+       return false;           /* same as default */
       else if (! tty_lookup_color (f, bg, &bg_tty_color, &bg_std_color))
-       return 0;               /* not a valid color */
+       return false;           /* not a valid color */
       else if (color_distance (&bg_tty_color, &bg_std_color)
               > TTY_SAME_COLOR_THRESHOLD)
-       return 0;               /* displayed color is too different */
+       return false;           /* displayed color is too different */
       else
        /* Make sure the color is really different than the default.  */
        {
@@ -4953,7 +4888,7 @@ tty_supports_face_attributes_p (struct frame *f,
          if (tty_lookup_color (f, def_bg, &def_bg_color, 0)
              && (color_distance (&bg_tty_color, &def_bg_color)
                  <= TTY_SAME_COLOR_THRESHOLD))
-           return 0;
+           return false;
        }
     }
 
@@ -4968,7 +4903,7 @@ tty_supports_face_attributes_p (struct frame *f,
           - color_distance (&fg_tty_color, &bg_tty_color));
       if (delta_delta > TTY_SAME_COLOR_THRESHOLD
          || delta_delta < -TTY_SAME_COLOR_THRESHOLD)
-       return 0;
+       return false;
     }
 
 
@@ -4989,8 +4924,8 @@ The definition of `supported' is somewhat heuristic, but basically means
 that a face containing all the attributes in ATTRIBUTES, when merged
 with the default face for display, can be represented in a way that's
 
\(1) different in appearance than the default face, and
\(2) `close in spirit' to what the attributes specify, if not exact.
+ (1) different in appearance than the default face, and
+ (2) `close in spirit' to what the attributes specify, if not exact.
 
 Point (2) implies that a `:weight black' attribute will be satisfied by
 any display that can display bold, and a `:foreground \"yellow\"' as long
@@ -4999,7 +4934,7 @@ satisfied by the tty display code's automatic substitution of a `dim'
 face for italic.  */)
   (Lisp_Object attributes, Lisp_Object display)
 {
-  bool supports = 0;
+  bool supports = false;
   int i;
   Lisp_Object frame;
   struct frame *f;
@@ -5034,16 +4969,14 @@ face for italic.  */)
 
   for (i = 0; i < LFACE_VECTOR_SIZE; i++)
     attrs[i] = Qunspecified;
-  merge_face_ref (f, attributes, attrs, 1, 0);
+  merge_face_ref (f, attributes, attrs, true, 0);
 
-  def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
+  def_face = FACE_OPT_FROM_ID (f, DEFAULT_FACE_ID);
   if (def_face == NULL)
     {
       if (! realize_basic_faces (f))
        error ("Cannot realize default face");
       def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
-      if (def_face == NULL)
-       emacs_abort ();  /* realize_basic_faces must have set it up  */
     }
 
   /* Dispatch to the appropriate handler.  */
@@ -5212,13 +5145,11 @@ face_fontset (Lisp_Object attrs[LFACE_VECTOR_SIZE])
 static bool
 realize_basic_faces (struct frame *f)
 {
-  bool success_p = 0;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  bool success_p = false;
 
   /* Block input here so that we won't be surprised by an X expose
      event, for instance, without having the faces set up.  */
   block_input ();
-  specbind (Qscalable_fonts_allowed, Qt);
 
   if (realize_default_face (f))
     {
@@ -5242,17 +5173,16 @@ realize_basic_faces (struct frame *f)
       /* Reflect changes in the `menu' face in menu bars.  */
       if (FRAME_FACE_CACHE (f)->menu_face_changed_p)
        {
-         FRAME_FACE_CACHE (f)->menu_face_changed_p = 0;
+         FRAME_FACE_CACHE (f)->menu_face_changed_p = false;
 #ifdef USE_X_TOOLKIT
          if (FRAME_WINDOW_P (f))
            x_update_menu_appearance (f);
 #endif
        }
 
-      success_p = 1;
+      success_p = true;
     }
 
-  unbind_to (count, Qnil);
   unblock_input ();
   return success_p;
 }
@@ -5268,10 +5198,9 @@ realize_default_face (struct frame *f)
   struct face_cache *c = FRAME_FACE_CACHE (f);
   Lisp_Object lface;
   Lisp_Object attrs[LFACE_VECTOR_SIZE];
-  struct face *face;
 
   /* If the `default' face is not yet known, create it.  */
-  lface = lface_from_face_name (f, Qdefault, 0);
+  lface = lface_from_face_name (f, Qdefault, false);
   if (NILP (lface))
     {
        Lisp_Object frame;
@@ -5287,7 +5216,7 @@ realize_default_face (struct frame *f)
       XSETFONT (font_object, FRAME_FONT (f));
       set_lface_from_font (f, lface, font_object, f->default_face_done_p);
       ASET (lface, LFACE_FONTSET_INDEX, fontset_name (FRAME_FONTSET (f)));
-      f->default_face_done_p = 1;
+      f->default_face_done_p = true;
     }
 #endif /* HAVE_WINDOW_SYSTEM */
 
@@ -5329,7 +5258,7 @@ realize_default_face (struct frame *f)
       if (CONSP (color) && STRINGP (XCDR (color)))
        ASET (lface, LFACE_FOREGROUND_INDEX, XCDR (color));
       else if (FRAME_WINDOW_P (f))
-       return 0;
+       return false;
       else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
        ASET (lface, LFACE_FOREGROUND_INDEX, build_string (unspecified_fg));
       else
@@ -5344,7 +5273,7 @@ realize_default_face (struct frame *f)
       if (CONSP (color) && STRINGP (XCDR (color)))
        ASET (lface, LFACE_BACKGROUND_INDEX, XCDR (color));
       else if (FRAME_WINDOW_P (f))
-       return 0;
+       return false;
       else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
        ASET (lface, LFACE_BACKGROUND_INDEX, build_string (unspecified_bg));
       else
@@ -5358,16 +5287,17 @@ realize_default_face (struct frame *f)
   eassert (lface_fully_specified_p (XVECTOR (lface)->contents));
   check_lface (lface);
   memcpy (attrs, XVECTOR (lface)->contents, sizeof attrs);
-  face = realize_face (c, attrs, DEFAULT_FACE_ID);
+  struct face *face = realize_face (c, attrs, DEFAULT_FACE_ID);
 
-#ifdef HAVE_WINDOW_SYSTEM
-#ifdef HAVE_X_WINDOWS
+#ifndef HAVE_WINDOW_SYSTEM
+  (void) face;
+#else
   if (FRAME_X_P (f) && face->font != FRAME_FONT (f))
     {
       /* This can happen when making a frame on a display that does
         not support the default font.  */
       if (!face->font)
-       return 0;
+       return false;
 
       /* Otherwise, the font specified for the frame was not
         acceptable as a font for the default face (perhaps because
@@ -5375,9 +5305,8 @@ realize_default_face (struct frame *f)
         font.  */
       x_set_font (f, LFACE_FONT (lface), Qnil);
     }
-#endif /* HAVE_X_WINDOWS */
-#endif /* HAVE_WINDOW_SYSTEM */
-  return 1;
+#endif
+  return true;
 }
 
 
@@ -5389,12 +5318,12 @@ static void
 realize_named_face (struct frame *f, Lisp_Object symbol, int id)
 {
   struct face_cache *c = FRAME_FACE_CACHE (f);
-  Lisp_Object lface = lface_from_face_name (f, symbol, 0);
+  Lisp_Object lface = lface_from_face_name (f, symbol, false);
   Lisp_Object attrs[LFACE_VECTOR_SIZE];
   Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
 
   /* The default face must exist and be fully specified.  */
-  get_lface_attributes_no_remap (f, Qdefault, attrs, 1);
+  get_lface_attributes_no_remap (f, Qdefault, attrs, true);
   check_lface_attrs (attrs);
   eassert (lface_fully_specified_p (attrs));
 
@@ -5407,7 +5336,7 @@ realize_named_face (struct frame *f, Lisp_Object symbol, int id)
     }
 
   /* Merge SYMBOL's face with the default face.  */
-  get_lface_attributes_no_remap (f, symbol, symbol_attrs, 1);
+  get_lface_attributes_no_remap (f, symbol, symbol_attrs, true);
   merge_face_vectors (f, symbol_attrs, attrs, 0);
 
   /* Realize the face.  */
@@ -5479,7 +5408,7 @@ realize_non_ascii_face (struct frame *f, Lisp_Object font_object,
        && FONT_WEIGHT_NUMERIC (font_object) <= 100);
 
   /* Don't try to free the colors copied bitwise from BASE_FACE.  */
-  face->colors_copied_bitwise_p = 1;
+  face->colors_copied_bitwise_p = true;
   face->font = NILP (font_object) ? NULL : XFONT_OBJECT (font_object);
   face->gc = 0;
 
@@ -5516,7 +5445,7 @@ realize_x_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE])
 
   /* Determine the font to use.  Most of the time, the font will be
      the same as the font of the default face, so try that first.  */
-  default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
+  default_face = FACE_OPT_FROM_ID (f, DEFAULT_FACE_ID);
   if (default_face
       && lface_same_font_attributes_p (default_face->lface, attrs))
     {
@@ -5563,7 +5492,7 @@ realize_x_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE])
   if (face->font
       && FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]) > 100
       && FONT_WEIGHT_NUMERIC (attrs[LFACE_FONT_INDEX]) <= 100)
-    face->overstrike = 1;
+    face->overstrike = true;
 
   /* Load colors, and set remaining attributes.  */
 
@@ -5588,7 +5517,7 @@ realize_x_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE])
       face->box = FACE_SIMPLE_BOX;
       face->box_line_width = XINT (box);
       face->box_color = face->foreground;
-      face->box_color_defaulted_p = 1;
+      face->box_color_defaulted_p = true;
     }
   else if (CONSP (box))
     {
@@ -5596,7 +5525,7 @@ realize_x_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE])
         being one of `raised' or `sunken'.  */
       face->box = FACE_SIMPLE_BOX;
       face->box_color = face->foreground;
-      face->box_color_defaulted_p = 1;
+      face->box_color_defaulted_p = true;
       face->box_line_width = 1;
 
       while (CONSP (box))
@@ -5622,7 +5551,7 @@ realize_x_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE])
                {
                  face->box_color = load_color (f, face, value,
                                                LFACE_BOX_INDEX);
-                 face->use_box_color_for_shadows_p = 1;
+                 face->use_box_color_for_shadows_p = true;
                }
            }
          else if (EQ (keyword, QCstyle))
@@ -5641,34 +5570,34 @@ realize_x_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE])
   if (EQ (underline, Qt))
     {
       /* Use default color (same as foreground color).  */
-      face->underline_p = 1;
+      face->underline_p = true;
       face->underline_type = FACE_UNDER_LINE;
-      face->underline_defaulted_p = 1;
+      face->underline_defaulted_p = true;
       face->underline_color = 0;
     }
   else if (STRINGP (underline))
     {
       /* Use specified color.  */
-      face->underline_p = 1;
+      face->underline_p = true;
       face->underline_type = FACE_UNDER_LINE;
-      face->underline_defaulted_p = 0;
+      face->underline_defaulted_p = false;
       face->underline_color
        = load_color (f, face, underline,
                      LFACE_UNDERLINE_INDEX);
     }
   else if (NILP (underline))
     {
-      face->underline_p = 0;
-      face->underline_defaulted_p = 0;
+      face->underline_p = false;
+      face->underline_defaulted_p = false;
       face->underline_color = 0;
     }
   else if (CONSP (underline))
     {
       /* `(:color COLOR :style STYLE)'.
          STYLE being one of `line' or `wave'. */
-      face->underline_p = 1;
+      face->underline_p = true;
       face->underline_color = 0;
-      face->underline_defaulted_p = 1;
+      face->underline_defaulted_p = true;
       face->underline_type = FACE_UNDER_LINE;
 
       /* FIXME?  This is also not robust about checking the precise form.
@@ -5689,12 +5618,12 @@ realize_x_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE])
             {
               if (EQ (value, Qforeground_color))
                 {
-                  face->underline_defaulted_p = 1;
+                  face->underline_defaulted_p = true;
                   face->underline_color = 0;
                 }
               else if (STRINGP (value))
                 {
-                  face->underline_defaulted_p = 0;
+                  face->underline_defaulted_p = false;
                   face->underline_color = load_color (f, face, value,
                                                       LFACE_UNDERLINE_INDEX);
                 }
@@ -5715,13 +5644,13 @@ realize_x_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE])
       face->overline_color
        = load_color (f, face, attrs[LFACE_OVERLINE_INDEX],
                      LFACE_OVERLINE_INDEX);
-      face->overline_p = 1;
+      face->overline_p = true;
     }
   else if (EQ (overline, Qt))
     {
       face->overline_color = face->foreground;
-      face->overline_color_defaulted_p = 1;
-      face->overline_p = 1;
+      face->overline_color_defaulted_p = true;
+      face->overline_p = true;
     }
 
   strike_through = attrs[LFACE_STRIKE_THROUGH_INDEX];
@@ -5730,13 +5659,13 @@ realize_x_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE])
       face->strike_through_color
        = load_color (f, face, attrs[LFACE_STRIKE_THROUGH_INDEX],
                      LFACE_STRIKE_THROUGH_INDEX);
-      face->strike_through_p = 1;
+      face->strike_through_p = true;
     }
   else if (EQ (strike_through, Qt))
     {
       face->strike_through_color = face->foreground;
-      face->strike_through_color_defaulted_p = 1;
-      face->strike_through_p = 1;
+      face->strike_through_color_defaulted_p = true;
+      face->strike_through_p = true;
     }
 
   stipple = attrs[LFACE_STIPPLE_INDEX];
@@ -5750,15 +5679,15 @@ realize_x_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE])
 
 /* Map a specified color of face FACE on frame F to a tty color index.
    IDX is either LFACE_FOREGROUND_INDEX or LFACE_BACKGROUND_INDEX, and
-   specifies which color to map.  Set *DEFAULTED to 1 if mapping to the
+   specifies which color to map.  Set *DEFAULTED to true if mapping to the
    default foreground/background colors.  */
 
 static void
 map_tty_color (struct frame *f, struct face *face,
-              enum lface_attribute_index idx, int *defaulted)
+              enum lface_attribute_index idx, bool *defaulted)
 {
   Lisp_Object frame, color, def;
-  int foreground_p = idx == LFACE_FOREGROUND_INDEX;
+  bool foreground_p = idx == LFACE_FOREGROUND_INDEX;
   unsigned long default_pixel =
     foreground_p ? FACE_TTY_DEFAULT_FG_COLOR : FACE_TTY_DEFAULT_BG_COLOR;
   unsigned long pixel = default_pixel;
@@ -5775,7 +5704,7 @@ map_tty_color (struct frame *f, struct face *face,
   if (STRINGP (color)
       && SCHARS (color)
       && CONSP (Vtty_defined_color_alist)
-      && (def = assq_no_quit (color, call1 (Qtty_color_alist, frame)),
+      && (def = assoc_no_quit (color, call1 (Qtty_color_alist, frame)),
          CONSP (def)))
     {
       /* Associations in tty-defined-color-alist are of the form
@@ -5800,7 +5729,7 @@ map_tty_color (struct frame *f, struct face *face,
              else
                pixel = FRAME_BACKGROUND_PIXEL (f);
              face->lface[idx] = tty_color_name (f, pixel);
-             *defaulted = 1;
+             *defaulted = true;
            }
          else if (pixel == default_other_pixel)
            {
@@ -5809,7 +5738,7 @@ map_tty_color (struct frame *f, struct face *face,
              else
                pixel = FRAME_FOREGROUND_PIXEL (f);
              face->lface[idx] = tty_color_name (f, pixel);
-             *defaulted = 1;
+             *defaulted = true;
            }
        }
 #endif /* MSDOS */
@@ -5832,7 +5761,7 @@ realize_tty_face (struct face_cache *cache,
 {
   struct face *face;
   int weight, slant;
-  int face_colors_defaulted = 0;
+  bool face_colors_defaulted = false;
   struct frame *f = cache->f;
 
   /* Frame must be a termcap frame.  */
@@ -5840,7 +5769,7 @@ realize_tty_face (struct face_cache *cache,
 
   /* Allocate a new realized face.  */
   face = make_realized_face (attrs);
-#if 0
+#if false
   face->font_name = FRAME_MSDOS_P (cache->f) ? "ms-dos" : "tty";
 #endif
 
@@ -5848,13 +5777,13 @@ realize_tty_face (struct face_cache *cache,
   weight = FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]);
   slant = FONT_SLANT_NAME_NUMERIC (attrs[LFACE_SLANT_INDEX]);
   if (weight > 100)
-    face->tty_bold_p = 1;
+    face->tty_bold_p = true;
   if (slant != 100)
-    face->tty_italic_p = 1;
+    face->tty_italic_p = true;
   if (!NILP (attrs[LFACE_UNDERLINE_INDEX]))
-    face->tty_underline_p = 1;
+    face->tty_underline_p = true;
   if (!NILP (attrs[LFACE_INVERSE_INDEX]))
-    face->tty_reverse_p = 1;
+    face->tty_reverse_p = true;
 
   /* Map color names to color indices.  */
   map_tty_color (f, face, LFACE_FOREGROUND_INDEX, &face_colors_defaulted);
@@ -5874,7 +5803,7 @@ realize_tty_face (struct face_cache *cache,
       && face->tty_bold_p
       && face->background == FACE_TTY_DEFAULT_FG_COLOR
       && face->foreground == FACE_TTY_DEFAULT_BG_COLOR)
-    face->tty_bold_p = 0;
+    face->tty_bold_p = false;
 
   return face;
 }
@@ -5892,7 +5821,7 @@ is non-nil.  */)
   (Lisp_Object suppress)
 {
   tty_suppress_bold_inverse_default_colors_p = !NILP (suppress);
-  ++face_change_count;
+  face_change = true;
   return suppress;
 }
 
@@ -5923,7 +5852,7 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop)
       Lisp_Object attrs[LFACE_VECTOR_SIZE];
       struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
       memcpy (attrs, default_face->lface, sizeof attrs);
-      merge_face_ref (f, prop, attrs, 1, 0);
+      merge_face_ref (f, prop, attrs, true, 0);
       face_id = lookup_face (f, attrs);
     }
 
@@ -5941,7 +5870,7 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop)
    LIMIT is a position not to scan beyond.  That is to limit the time
    this function can take.
 
-   If MOUSE is non-zero, use the character's mouse-face, not its face.
+   If MOUSE, use the character's mouse-face, not its face.
 
    BASE_FACE_ID, if non-negative, specifies a base face id to use
    instead of DEFAULT_FACE_ID.
@@ -5951,7 +5880,7 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop)
 int
 face_at_buffer_position (struct window *w, ptrdiff_t pos,
                         ptrdiff_t *endptr, ptrdiff_t limit,
-                        int mouse, int base_face_id)
+                        bool mouse, int base_face_id)
 {
   struct frame *f = XFRAME (w->frame);
   Lisp_Object attrs[LFACE_VECTOR_SIZE];
@@ -5984,7 +5913,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
   {
     ptrdiff_t next_overlay;
 
-    GET_OVERLAYS_AT (pos, overlay_vec, noverlays, &next_overlay, 0);
+    GET_OVERLAYS_AT (pos, overlay_vec, noverlays, &next_overlay, false);
     if (next_overlay < endpos)
       endpos = next_overlay;
   }
@@ -6017,7 +5946,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
 
   /* Merge in attributes specified via text properties.  */
   if (!NILP (prop))
-    merge_face_ref (f, prop, attrs, 1, 0);
+    merge_face_ref (f, prop, attrs, true, 0);
 
   /* Now merge the overlay data.  */
   noverlays = sort_overlays (overlay_vec, noverlays, w);
@@ -6028,7 +5957,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
 
       prop = Foverlay_get (overlay_vec[i], propname);
       if (!NILP (prop))
-       merge_face_ref (f, prop, attrs, 1, 0);
+       merge_face_ref (f, prop, attrs, true, 0);
 
       oend = OVERLAY_END (overlay_vec[i]);
       oendpos = OVERLAY_POSITION (oend);
@@ -6054,7 +5983,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
 int
 face_for_overlay_string (struct window *w, ptrdiff_t pos,
                         ptrdiff_t *endptr, ptrdiff_t limit,
-                        int mouse, Lisp_Object overlay)
+                        bool mouse, Lisp_Object overlay)
 {
   struct frame *f = XFRAME (w->frame);
   Lisp_Object attrs[LFACE_VECTOR_SIZE];
@@ -6093,7 +6022,7 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos,
 
   /* Merge in attributes specified via text properties.  */
   if (!NILP (prop))
-    merge_face_ref (f, prop, attrs, 1, 0);
+    merge_face_ref (f, prop, attrs, true, 0);
 
   *endptr = endpos;
 
@@ -6115,7 +6044,7 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos,
    BASE_FACE_ID is the id of a face to merge with.  For strings coming
    from overlays or the `display' property it is the face at BUFPOS.
 
-   If MOUSE_P is non-zero, use the character's mouse-face, not its face.
+   If MOUSE_P, use the character's mouse-face, not its face.
 
    Set *ENDPTR to the next position where to check for faces in
    STRING; -1 if the face is constant from POS to the end of the
@@ -6128,7 +6057,7 @@ int
 face_at_string_position (struct window *w, Lisp_Object string,
                         ptrdiff_t pos, ptrdiff_t bufpos,
                         ptrdiff_t *endptr, enum face_id base_face_id,
-                        int mouse_p)
+                        bool mouse_p)
 {
   Lisp_Object prop, position, end, limit;
   struct frame *f = XFRAME (WINDOW_FRAME (w));
@@ -6156,7 +6085,6 @@ face_at_string_position (struct window *w, Lisp_Object string,
     *endptr = -1;
 
   base_face = FACE_FROM_ID (f, base_face_id);
-  eassert (base_face);
 
   /* Optimize the default case that there is no face property.  */
   if (NILP (prop)
@@ -6165,7 +6093,7 @@ face_at_string_position (struct window *w, Lisp_Object string,
             if we don't have fonts, so we can stop here if not working
             on a window-system frame.  */
          || !FRAME_WINDOW_P (f)
-         || FACE_SUITABLE_FOR_ASCII_CHAR_P (base_face, 0)))
+         || FACE_SUITABLE_FOR_ASCII_CHAR_P (base_face)))
     return base_face->id;
 
   /* Begin with attributes from the base face.  */
@@ -6173,7 +6101,7 @@ face_at_string_position (struct window *w, Lisp_Object string,
 
   /* Merge in attributes specified via text properties.  */
   if (!NILP (prop))
-    merge_face_ref (f, prop, attrs, 1, 0);
+    merge_face_ref (f, prop, attrs, true, 0);
 
   /* Look up a realized face with the given face attributes,
      or realize a new one for ASCII characters.  */
@@ -6203,7 +6131,7 @@ merge_faces (struct frame *f, Lisp_Object face_name, int face_id,
   Lisp_Object attrs[LFACE_VECTOR_SIZE];
   struct face *base_face;
 
-  base_face = FACE_FROM_ID (f, base_face_id);
+  base_face = FACE_OPT_FROM_ID (f, base_face_id);
   if (!base_face)
     return base_face_id;
 
@@ -6231,7 +6159,7 @@ merge_faces (struct frame *f, Lisp_Object face_name, int face_id,
       struct face *face;
       if (face_id < 0)
        return base_face_id;
-      face = FACE_FROM_ID (f, face_id);
+      face = FACE_OPT_FROM_ID (f, face_id);
       if (!face)
        return base_face_id;
       merge_face_vectors (f, face->lface, attrs, 0);
@@ -6262,7 +6190,7 @@ where R,G,B are numbers between 0 and 255 and name is an arbitrary string.  */)
   abspath = Fexpand_file_name (filename, Qnil);
 
   block_input ();
-  fp = emacs_fopen (SSDATA (abspath), "rt");
+  fp = emacs_fopen (SSDATA (abspath), "r" FOPEN_TEXT);
   if (fp)
     {
       char buf[512];
@@ -6270,7 +6198,7 @@ where R,G,B are numbers between 0 and 255 and name is an arbitrary string.  */)
       int num;
 
       while (fgets (buf, sizeof (buf), fp) != NULL) {
-       if (sscanf (buf, "%u %u %u %n", &red, &green, &blue, &num) == 3)
+       if (sscanf (buf, "%d %d %d %n", &red, &green, &blue, &num) == 3)
          {
 #ifdef HAVE_NTGUI
            int color = RGB (red, green, blue);
@@ -6351,7 +6279,7 @@ DEFUN ("dump-face", Fdump_face, Sdump_face, 0, 1, 0, doc: /* */)
     {
       struct face *face;
       CHECK_NUMBER (n);
-      face = FACE_FROM_ID (SELECTED_FRAME (), XINT (n));
+      face = FACE_OPT_FROM_ID (SELECTED_FRAME (), XINT (n));
       if (face == NULL)
        error ("Not a valid face");
       dump_realized_face (face);
@@ -6382,9 +6310,17 @@ DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources,
 void
 syms_of_xfaces (void)
 {
+  /* The symbols `face' and `mouse-face' used as text properties.  */
   DEFSYM (Qface, "face");
+
+  /* Property for basic faces which other faces cannot inherit.  */
   DEFSYM (Qface_no_inherit, "face-no-inherit");
+
+  /* Error symbol for wrong_type_argument in load_pixmap.  */
   DEFSYM (Qbitmap_spec_p, "bitmap-spec-p");
+
+  /* The name of the function to call when the background of the frame
+     has changed, frame_set_background_mode.  */
   DEFSYM (Qframe_set_background_mode, "frame-set-background-mode");
 
   /* Lisp face attribute keywords.  */
@@ -6427,15 +6363,24 @@ syms_of_xfaces (void)
   DEFSYM (Qultra_bold, "ultra-bold");
   DEFSYM (Qoblique, "oblique");
   DEFSYM (Qitalic, "italic");
+
+  /* The symbols `foreground-color' and `background-color' which can be
+     used as part of a `face' property.  This is for compatibility with
+     Emacs 20.2.  */
   DEFSYM (Qbackground_color, "background-color");
   DEFSYM (Qforeground_color, "foreground-color");
+
   DEFSYM (Qunspecified, "unspecified");
   DEFSYM (QCignore_defface, ":ignore-defface");
 
+  /* The symbol `face-alias'.  A symbol having that property is an
+     alias for another face.  Value of the property is the name of
+     the aliased face.  */
   DEFSYM (Qface_alias, "face-alias");
+
+  /* Names of basic faces.  */
   DEFSYM (Qdefault, "default");
   DEFSYM (Qtool_bar, "tool-bar");
-  DEFSYM (Qregion, "region");
   DEFSYM (Qfringe, "fringe");
   DEFSYM (Qheader_line, "header-line");
   DEFSYM (Qscroll_bar, "scroll-bar");
@@ -6445,14 +6390,17 @@ syms_of_xfaces (void)
   DEFSYM (Qmouse, "mouse");
   DEFSYM (Qmode_line_inactive, "mode-line-inactive");
   DEFSYM (Qvertical_border, "vertical-border");
+
+  /* TTY color-related functions (defined in tty-colors.el).  */
   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");
+
+  /* The name of the function used to compute colors on TTYs.  */
   DEFSYM (Qtty_color_alist, "tty-color-alist");
-  DEFSYM (Qscalable_fonts_allowed, "scalable-fonts-allowed");
 
   Vparam_value_alist = list1 (Fcons (Qnil, Qnil));
   staticpro (&Vparam_value_alist);
@@ -6545,8 +6493,8 @@ REPLACEMENT is a face specification, i.e. one of the following:
   (3) a list in which each element has the form of (1) or (2).
 
 List values for REPLACEMENT are merged to form the final face
-specification, with earlier entries taking precedence, in the same as
-as in the `face' text property.
+specification, with earlier entries taking precedence, in the same way
+as with the `face' text property.
 
 Face-name remapping cycles are suppressed; recursive references use
 the underlying face instead of the remapped face.  So a remapping of
@@ -6566,8 +6514,8 @@ If this variable is made buffer-local, the face remapping takes effect
 only in that buffer.  For instance, the mode my-mode could define a
 face `my-mode-default', and then in the mode setup function, do:
 
-   (set (make-local-variable 'face-remapping-alist)
-       '((default my-mode-default)))).
+   (set (make-local-variable \\='face-remapping-alist)
+       \\='((default my-mode-default)))).
 
 Because Emacs normally only redraws screen areas when the underlying
 buffer contents change, you may need to call `redraw-display' after