*** empty log message ***
[bpt/emacs.git] / src / xfaces.c
index 3f5a4f4..1f7c906 100644 (file)
@@ -1,5 +1,5 @@
 /* xfaces.c -- "Face" primitives.
-   Copyright (C) 1993, 1994, 1998, 1999, 2000, 2001
+   Copyright (C) 1993, 1994, 1998, 1999, 2000, 2001, 2002
    Free Software Foundation.
 
 This file is part of GNU Emacs.
@@ -196,7 +196,7 @@ Boston, MA 02111-1307, USA.  */
 #include <sys/stat.h>
 
 #include "lisp.h"
-#include "charset.h"
+#include "character.h"
 #include "keyboard.h"
 #include "frame.h"
 
@@ -364,6 +364,7 @@ Lisp_Object Qframe_update_face_colors;
 
 Lisp_Object Qdefault, Qtool_bar, Qregion, Qfringe;
 Lisp_Object Qheader_line, Qscroll_bar, Qcursor, Qborder, Qmouse, Qmenu;
+Lisp_Object Qmode_line_inactive;
 extern Lisp_Object Qmode_line;
 
 /* The symbol `face-alias'.  A symbols having that property is an
@@ -549,14 +550,14 @@ static unsigned hash_string_case_insensitive P_ ((Lisp_Object));
 static unsigned lface_hash P_ ((Lisp_Object *));
 static int lface_same_font_attributes_p P_ ((Lisp_Object *, Lisp_Object *));
 static struct face_cache *make_face_cache P_ ((struct frame *));
-static void free_realized_face P_ ((struct frame *, struct face *));
 static void clear_face_gcs P_ ((struct face_cache *));
 static void free_face_cache P_ ((struct face_cache *));
 static int face_numeric_weight P_ ((Lisp_Object));
 static int face_numeric_slant P_ ((Lisp_Object));
 static int face_numeric_swidth P_ ((Lisp_Object));
 static int face_fontset P_ ((Lisp_Object *));
-static char *choose_face_font P_ ((struct frame *, Lisp_Object *, int, int));
+static char *choose_face_font P_ ((struct frame *, Lisp_Object *,
+                                  struct face *, int));
 static void merge_face_vectors P_ ((struct frame *, Lisp_Object *, Lisp_Object*, Lisp_Object));
 static void merge_face_inheritance P_ ((struct frame *f, Lisp_Object,
                                        Lisp_Object *, Lisp_Object));
@@ -566,7 +567,6 @@ static int set_lface_from_font_name P_ ((struct frame *, Lisp_Object,
                                         Lisp_Object, int, int));
 static Lisp_Object lface_from_face_name P_ ((struct frame *, Lisp_Object, int));
 static struct face *make_realized_face P_ ((Lisp_Object *));
-static void free_realized_faces P_ ((struct face_cache *));
 static char *best_matching_font P_ ((struct frame *, Lisp_Object *,
                                     struct font_name *, int, int));
 static void cache_face P_ ((struct face_cache *, struct face *, unsigned));
@@ -875,7 +875,7 @@ frame_or_selected_frame (frame, nparam)
   if (NILP (frame))
     frame = selected_frame;
 
-  CHECK_LIVE_FRAME (frame, nparam);
+  CHECK_LIVE_FRAME (frame);
   return XFRAME (frame);
 }
 
@@ -1267,12 +1267,13 @@ load_face_font (f, face, c)
   face->font_info_id = -1;
   face->font = NULL;
 
-  font_name = choose_face_font (f, face->lface, face->fontset, c);
+  font_name = choose_face_font (f, face->lface, face, c);
+
   if (!font_name)
     return;
 
   BLOCK_INPUT;
-  font_info = FS_LOAD_FACE_FONT (f, c, font_name, face);
+  font_info = FS_LOAD_FONT (f, font_name);
   UNBLOCK_INPUT;
 
   if (font_info)
@@ -1490,8 +1491,8 @@ If FRAME is nil or omitted, use the selected frame.  */)
 {
   struct frame *f;
 
-  CHECK_FRAME (frame, 0);
-  CHECK_STRING (color, 0);
+  CHECK_FRAME (frame);
+  CHECK_STRING (color);
   f = XFRAME (frame);
   return face_color_gray_p (f, XSTRING (color)->data) ? Qt : Qnil;
 }
@@ -1508,8 +1509,8 @@ COLOR must be a valid color name.  */)
 {
   struct frame *f;
 
-  CHECK_FRAME (frame, 0);
-  CHECK_STRING (color, 0);
+  CHECK_FRAME (frame);
+  CHECK_STRING (color);
   f = XFRAME (frame);
   if (face_color_supported_p (f, XSTRING (color)->data, !NILP (background_p)))
     return Qt;
@@ -1664,6 +1665,9 @@ free_face_colors (f, face)
      struct face *face;
 {
 #ifdef HAVE_X_WINDOWS
+  if (face->colors_copied_bitwise_p)
+    return;
+
   BLOCK_INPUT;
 
   if (!face->foreground_defaulted_p)
@@ -2108,6 +2112,61 @@ face_numeric_swidth (width)
 }
 
 
+Lisp_Object
+generate_ascii_font (name, ascii_spec)
+     Lisp_Object name, ascii_spec;
+{
+  struct font_name font;
+  char *p;
+
+  font.name = LSTRDUPA (name);
+  if (! split_font_name (NULL, &font, 0))
+    return Qnil;
+
+  if (STRINGP (AREF (ascii_spec, FONT_SPEC_FAMILY_INDEX)))
+    {
+      p = LSTRDUPA (AREF (ascii_spec, FONT_SPEC_FAMILY_INDEX));
+      font.fields[XLFD_FOUNDRY] = p;
+      while (*p != '-') p++;
+      if (*p)
+       {
+         *p++ = 0;
+         font.fields[XLFD_FAMILY] = p;
+       }
+      else
+       {
+         font.fields[XLFD_FAMILY] = font.fields[XLFD_FOUNDRY];
+         font.fields[XLFD_FOUNDRY] = "*";
+       }
+    }
+  if (STRINGP (AREF (ascii_spec, FONT_SPEC_WEIGHT_INDEX)))
+    font.fields[XLFD_WEIGHT]
+      = XSTRING (AREF (ascii_spec, FONT_SPEC_WEIGHT_INDEX))->data;
+  if (STRINGP (AREF (ascii_spec, FONT_SPEC_SLANT_INDEX)))
+    font.fields[XLFD_SLANT]
+      = XSTRING (AREF (ascii_spec, FONT_SPEC_SLANT_INDEX))->data;
+  if (STRINGP (AREF (ascii_spec, FONT_SPEC_SWIDTH_INDEX)))
+    font.fields[XLFD_SWIDTH]
+      = XSTRING (AREF (ascii_spec, FONT_SPEC_SWIDTH_INDEX))->data;
+  if (STRINGP (AREF (ascii_spec, FONT_SPEC_ADSTYLE_INDEX)))
+    font.fields[XLFD_ADSTYLE]
+      = XSTRING (AREF (ascii_spec, FONT_SPEC_ADSTYLE_INDEX))->data;
+  p = LSTRDUPA (AREF (ascii_spec, FONT_SPEC_REGISTRY_INDEX));
+  font.fields[XLFD_REGISTRY] = p;
+  while (*p != '-') p++;
+  if (*p)
+    *p++ = 0;
+  else
+    p = "*";
+  font.fields[XLFD_ENCODING] = p;
+
+  p = build_font_name (&font);
+  name = build_string (p);
+  xfree (p);
+  return name;
+}
+
+
 #ifdef HAVE_WINDOW_SYSTEM
 
 /* Return non-zero if FONT is the name of a fixed-pitch font.  */
@@ -2717,7 +2776,7 @@ the face font sort order.  */)
   struct gcpro gcpro1;
 
   if (!NILP (family))
-    CHECK_STRING (family, 1);
+    CHECK_STRING (family);
 
   result = Qnil;
   GCPRO1 (result);
@@ -2826,18 +2885,18 @@ the WIDTH times as wide as FACE on FRAME.  */)
   int maxnames;
 
   check_x ();
-  CHECK_STRING (pattern, 0);
+  CHECK_STRING (pattern);
 
   if (NILP (maximum))
     maxnames = 2000;
   else
     {
-      CHECK_NATNUM (maximum, 0);
+      CHECK_NATNUM (maximum);
       maxnames = XINT (maximum);
     }
 
   if (!NILP (width))
-    CHECK_NUMBER (width, 4);
+    CHECK_NUMBER (width);
 
   /* We can't simply call check_x_frame because this function may be
      called before any frame is created.  */
@@ -3145,7 +3204,7 @@ set_lface_from_font_name (f, lface, fontname, force_p, may_fail_p)
      caching it now is not futail because we anyway load the font
      later.  */
   BLOCK_INPUT;
-  font_info = FS_LOAD_FONT (f, 0, font_name, -1);
+  font_info = FS_LOAD_FONT (f, font_name);
   UNBLOCK_INPUT;
 
   if (!font_info)
@@ -3237,7 +3296,7 @@ merge_face_heights (from, to, invalid, gcpro)
     {
       if (INTEGERP (to))
        /* relative X absolute => absolute */
-       result = make_number (XFLOAT_DATA (from) * XINT (to));
+       result = make_number ((EMACS_INT)(XFLOAT_DATA (from) * XINT (to)));
       else if (FLOATP (to))
        /* relative X relative => relative */
        result = make_float (XFLOAT_DATA (from) * XFLOAT_DATA (to));
@@ -3307,10 +3366,12 @@ merge_face_vectors (f, from, to, cycle_check)
 
   for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
     if (!UNSPECIFIEDP (from[i]))
-      if (i == LFACE_HEIGHT_INDEX && !INTEGERP (from[i]))
-       to[i] = merge_face_heights (from[i], to[i], to[i], cycle_check);
-      else
-       to[i] = from[i];
+      {
+       if (i == LFACE_HEIGHT_INDEX && !INTEGERP (from[i]))
+         to[i] = merge_face_heights (from[i], to[i], to[i], cycle_check);
+       else
+         to[i] = from[i];
+      }
 
   /* TO is always an absolute face, which should inherit from nothing.
      We blindly copy the :inherit attribute above and fix it up here.  */
@@ -3325,7 +3386,7 @@ merge_face_vectors (f, from, to, cycle_check)
    elements, this macro begins consing in order to keep more precise
    track of elements.
 
-   Returns NIL if a cycle was detected, otherwise a new value for CHECK
+   Returns nil if a cycle was detected, otherwise a new value for CHECK
    that includes EL.
 
    CHECK is evaluated multiple times, EL and SUSPICIOUS 0 or 1 times, so
@@ -3623,12 +3684,12 @@ Value is a vector of face attributes.  */)
   struct frame *f;
   int i;
 
-  CHECK_SYMBOL (face, 0);
+  CHECK_SYMBOL (face);
   global_lface = lface_from_face_name (NULL, face, 0);
 
   if (!NILP (frame))
     {
-      CHECK_LIVE_FRAME (frame, 1);
+      CHECK_LIVE_FRAME (frame);
       f = XFRAME (frame);
       lface = lface_from_face_name (f, face, 0);
     }
@@ -3681,6 +3742,14 @@ Value is a vector of face attributes.  */)
   else
     lface = global_lface;
 
+  /* 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.  */
+  ++face_change_count;
+  ++windows_or_buffers_changed;
+
   xassert (LFACEP (lface));
   check_lface (lface);
   return lface;
@@ -3700,7 +3769,7 @@ Otherwise check for the existence of a global face.  */)
 
   if (!NILP (frame))
     {
-      CHECK_LIVE_FRAME (frame, 1);
+      CHECK_LIVE_FRAME (frame);
       lface = lface_from_face_name (XFRAME (frame), face, 0);
     }
   else
@@ -3724,8 +3793,8 @@ Value is TO.  */)
 {
   Lisp_Object lface, copy;
 
-  CHECK_SYMBOL (from, 0);
-  CHECK_SYMBOL (to, 1);
+  CHECK_SYMBOL (from);
+  CHECK_SYMBOL (to);
   if (NILP (new_frame))
     new_frame = frame;
 
@@ -3739,8 +3808,8 @@ Value is TO.  */)
   else
     {
       /* Copy frame-local definition of FROM.  */
-      CHECK_LIVE_FRAME (frame, 2);
-      CHECK_LIVE_FRAME (new_frame, 3);
+      CHECK_LIVE_FRAME (frame);
+      CHECK_LIVE_FRAME (new_frame);
       lface = lface_from_face_name (XFRAME (frame), from, 1);
       copy = Finternal_make_lisp_face (to, new_frame);
     }
@@ -3748,6 +3817,14 @@ Value is TO.  */)
   bcopy (XVECTOR (lface)->contents, XVECTOR (copy)->contents,
         LFACE_VECTOR_SIZE * sizeof (Lisp_Object));
 
+  /* 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.  */
+  ++face_change_count;
+  ++windows_or_buffers_changed;
+
   return to;
 }
 
@@ -3770,8 +3847,8 @@ FRAME 0 means change the face on all frames, and change the default
   /* Set 1 if ATTR is one of font-related attributes other than QCfont.  */
   int font_related_attr_p = 0;
 
-  CHECK_SYMBOL (face, 0);
-  CHECK_SYMBOL (attr, 1);
+  CHECK_SYMBOL (face);
+  CHECK_SYMBOL (attr);
 
   face = resolve_face_name (face);
 
@@ -3794,7 +3871,7 @@ FRAME 0 means change the face on all frames, and change the default
       if (NILP (frame))
        frame = selected_frame;
 
-      CHECK_LIVE_FRAME (frame, 3);
+      CHECK_LIVE_FRAME (frame);
       lface = lface_from_face_name (XFRAME (frame), face, 0);
 
       /* If a frame-local face doesn't exist yet, create one.  */
@@ -3806,7 +3883,7 @@ FRAME 0 means change the face on all frames, and change the default
     {
       if (!UNSPECIFIEDP (value))
        {
-         CHECK_STRING (value, 3);
+         CHECK_STRING (value);
          if (XSTRING (value)->size == 0)
            signal_error ("Invalid face family", value);
        }
@@ -3839,7 +3916,7 @@ FRAME 0 means change the face on all frames, and change the default
     {
       if (!UNSPECIFIEDP (value))
        {
-         CHECK_SYMBOL (value, 3);
+         CHECK_SYMBOL (value);
          if (face_numeric_weight (value) < 0)
            signal_error ("Invalid face weight", value);
        }
@@ -3851,7 +3928,7 @@ FRAME 0 means change the face on all frames, and change the default
     {
       if (!UNSPECIFIEDP (value))
        {
-         CHECK_SYMBOL (value, 3);
+         CHECK_SYMBOL (value);
          if (face_numeric_slant (value) < 0)
            signal_error ("Invalid face slant", value);
        }
@@ -3969,7 +4046,7 @@ FRAME 0 means change the face on all frames, and change the default
     {
       if (!UNSPECIFIEDP (value))
        {
-         CHECK_SYMBOL (value, 3);
+         CHECK_SYMBOL (value);
          if (!EQ (value, Qt) && !NILP (value))
            signal_error ("Invalid inverse-video face attribute value", value);
        }
@@ -3983,7 +4060,7 @@ FRAME 0 means change the face on all frames, and change the default
          /* Don't check for valid color names here because it depends
             on the frame (display) whether the color will be valid
             when the face is realized.  */
-         CHECK_STRING (value, 3);
+         CHECK_STRING (value);
          if (XSTRING (value)->size == 0)
            signal_error ("Empty foreground color value", value);
        }
@@ -3997,7 +4074,7 @@ FRAME 0 means change the face on all frames, and change the default
          /* Don't check for valid color names here because it depends
             on the frame (display) whether the color will be valid
             when the face is realized.  */
-         CHECK_STRING (value, 3);
+         CHECK_STRING (value);
          if (XSTRING (value)->size == 0)
            signal_error ("Empty background color value", value);
        }
@@ -4019,7 +4096,7 @@ FRAME 0 means change the face on all frames, and change the default
     {
       if (!UNSPECIFIEDP (value))
        {
-         CHECK_SYMBOL (value, 3);
+         CHECK_SYMBOL (value);
          if (face_numeric_swidth (value) < 0)
            signal_error ("Invalid face width", value);
        }
@@ -4037,7 +4114,7 @@ FRAME 0 means change the face on all frames, and change the default
          struct frame *f;
          Lisp_Object tmp;
 
-         CHECK_STRING (value, 3);
+         CHECK_STRING (value);
          if (EQ (frame, Qt))
            f = SELECTED_FRAME ();
          else
@@ -4182,20 +4259,22 @@ FRAME 0 means change the face on all frames, and change the default
        }
 
       if (!NILP (param))
-       if (EQ (frame, Qt))
-         /* Update `default-frame-alist', which is used for new frames.  */
-         {
-           store_in_alist (&Vdefault_frame_alist, param, value);
-         }
-       else
-         /* Update the current frame's parameters.  */
-         {
-           Lisp_Object cons;
-           cons = XCAR (Vparam_value_alist);
-           XSETCAR (cons, param);
-           XSETCDR (cons, value);
-           Fmodify_frame_parameters (frame, Vparam_value_alist);
-         }
+       {
+         if (EQ (frame, Qt))
+           /* Update `default-frame-alist', which is used for new frames.  */
+           {
+             store_in_alist (&Vdefault_frame_alist, param, value);
+           }
+         else
+           /* Update the current frame's parameters.  */
+           {
+             Lisp_Object cons;
+             cons = XCAR (Vparam_value_alist);
+             XSETCAR (cons, param);
+             XSETCDR (cons, value);
+             Fmodify_frame_parameters (frame, Vparam_value_alist);
+           }
+       }
     }
 
   return face;
@@ -4228,7 +4307,7 @@ set_font_frame_param (frame, lface)
          /* Choose a font name that reflects LFACE's attributes and has
             the registry and encoding pattern specified in the default
             fontset (3rd arg: -1) for ASCII characters (4th arg: 0).  */
-         font = choose_face_font (f, XVECTOR (lface)->contents, -1, 0);
+         font = choose_face_font (f, XVECTOR (lface)->contents, NULL, 0);
          if (!font)
            error ("No font matches the specified attribute");
          font_name = build_string (font);
@@ -4256,6 +4335,14 @@ update_face_from_frame_parameter (f, param, new_value)
   if (NILP (f->face_alist))
     return;
 
+  /* 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.  */
+  ++face_change_count;
+  ++windows_or_buffers_changed;
+
   if (EQ (param, Qforeground_color))
     {
       lface = lface_from_face_name (f, Qdefault, 1);
@@ -4311,9 +4398,9 @@ DEFUN ("internal-face-x-get-resource", Finternal_face_x_get_resource,
   Lisp_Object value = Qnil;
 #ifndef WINDOWSNT
 #ifndef macintosh
-  CHECK_STRING (resource, 0);
-  CHECK_STRING (class, 1);
-  CHECK_LIVE_FRAME (frame, 2);
+  CHECK_STRING (resource);
+  CHECK_STRING (class);
+  CHECK_LIVE_FRAME (frame);
   BLOCK_INPUT;
   value = display_x_get_resource (FRAME_X_DISPLAY_INFO (XFRAME (frame)),
                                  resource, class, Qnil, Qnil);
@@ -4360,9 +4447,9 @@ DEFUN ("internal-set-lisp-face-attribute-from-resource",
      (face, attr, value, frame)
      Lisp_Object face, attr, value, frame;
 {
-  CHECK_SYMBOL (face, 0);
-  CHECK_SYMBOL (attr, 1);
-  CHECK_STRING (value, 2);
+  CHECK_SYMBOL (face);
+  CHECK_SYMBOL (attr);
+  CHECK_STRING (value);
 
   if (xstricmp (XSTRING (value)->data, "unspecified") == 0)
     value = Qunspecified;
@@ -4380,8 +4467,7 @@ DEFUN ("internal-set-lisp-face-attribute-from-resource",
     value = face_boolean_x_resource_value (value, 1);
   else if (EQ (attr, QCunderline)
           || EQ (attr, QCoverline)
-          || EQ (attr, QCstrike_through)
-          || EQ (attr, QCbox))
+          || EQ (attr, QCstrike_through))
     {
       Lisp_Object boolean_value;
 
@@ -4391,6 +4477,8 @@ DEFUN ("internal-set-lisp-face-attribute-from-resource",
       if (SYMBOLP (boolean_value))
        value = boolean_value;
     }
+  else if (EQ (attr, QCbox))
+    value = Fcar (Fread_from_string (value, Qnil, Qnil));
 
   return Finternal_set_lisp_face_attribute (face, attr, value, frame);
 }
@@ -4487,6 +4575,7 @@ DEFUN ("face-attribute-relative-p", Fface_attribute_relative_p,
        2, 2, 0,
        doc: /* Return non-nil if face ATTRIBUTE VALUE is relative.  */)
      (attribute, value)
+     Lisp_Object attribute, value;
 {
   if (EQ (value, Qunspecified))
     return Qt;
@@ -4527,8 +4616,8 @@ frames).  If FRAME is omitted or nil, use the selected frame.  */)
 {
   Lisp_Object lface, value = Qnil;
 
-  CHECK_SYMBOL (symbol, 0);
-  CHECK_SYMBOL (keyword, 1);
+  CHECK_SYMBOL (symbol);
+  CHECK_SYMBOL (keyword);
 
   if (EQ (frame, Qt))
     lface = lface_from_face_name (NULL, symbol, 1);
@@ -4536,7 +4625,7 @@ frames).  If FRAME is omitted or nil, use the selected frame.  */)
     {
       if (NILP (frame))
        frame = selected_frame;
-      CHECK_LIVE_FRAME (frame, 2);
+      CHECK_LIVE_FRAME (frame);
       lface = lface_from_face_name (XFRAME (frame), symbol, 1);
     }
 
@@ -4588,7 +4677,7 @@ Value is nil if ATTR doesn't have a discrete set of valid values.  */)
 {
   Lisp_Object result = Qnil;
 
-  CHECK_SYMBOL (attr, 0);
+  CHECK_SYMBOL (attr);
 
   if (EQ (attr, QCweight)
       || EQ (attr, QCslant)
@@ -4633,7 +4722,7 @@ Value is nil if ATTR doesn't have a discrete set of valid values.  */)
 
 DEFUN ("internal-merge-in-global-face", Finternal_merge_in_global_face,
        Sinternal_merge_in_global_face, 2, 2, 0,
-  doc: /* Add attributes from frame-default definition of FACE to FACE on FRAME.
+       doc: /* Add attributes from frame-default definition of FACE to FACE on FRAME.
 Default face attributes override any local face attributes.  */)
      (face, frame)
      Lisp_Object face, frame;
@@ -4641,7 +4730,7 @@ Default face attributes override any local face attributes.  */)
   int i;
   Lisp_Object global_lface, local_lface, *gvec, *lvec;
 
-  CHECK_LIVE_FRAME (frame, 1);
+  CHECK_LIVE_FRAME (frame);
   global_lface = lface_from_face_name (NULL, face, 1);
   local_lface = lface_from_face_name (XFRAME (frame), face, 0);
   if (NILP (local_lface))
@@ -4668,7 +4757,7 @@ Default face attributes override any local face attributes.  */)
    done in fontset.el.  */
 
 DEFUN ("face-font", Fface_font, Sface_font, 1, 2, 0,
-  doc: /* Return the font name of face FACE, or nil if it is unspecified.
+       doc: /* Return the font name of face FACE, or nil if it is unspecified.
 If the optional argument FRAME is given, report on face FACE in that frame.
 If FRAME is t, report on the defaults for face FACE (for new frames).
   The font default for a face is either nil, or a list
@@ -4795,7 +4884,7 @@ If FRAME is omitted or nil, use the selected frame.  */)
 
   if (NILP (frame))
     frame = selected_frame;
-  CHECK_LIVE_FRAME (frame, 0);
+  CHECK_LIVE_FRAME (frame);
   f = XFRAME (frame);
 
   if (EQ (frame, Qt))
@@ -4904,7 +4993,7 @@ make_realized_face (attr)
 /* Free realized face FACE, including its X resources.  FACE may
    be null.  */
 
-static void
+void
 free_realized_face (f, face)
      struct frame *f;
      struct face *face;
@@ -5082,11 +5171,10 @@ free_realized_faces (c)
 }
 
 
-/* Free all faces realized for multibyte characters on frame F that
-   has FONTSET.  */
+/* Free all realized faces that are using FONTSET on frame F.  */
 
 void
-free_realized_multibyte_face (f, fontset)
+free_realized_faces_for_fontset (f, fontset)
      struct frame *f;
      int fontset;
 {
@@ -5103,7 +5191,6 @@ free_realized_multibyte_face (f, fontset)
     {
       face = cache->faces_by_id[i];
       if (face
-         && face != face->ascii_face
          && face->fontset == fontset)
        {
          uncache_face (cache, face);
@@ -5485,7 +5572,7 @@ lookup_derived_face (f, symbol, c, face_id)
 
 DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
        Sface_attributes_as_vector, 1, 1, 0,
-       doc: /* Return a vector of face attributes corresponding to PLIST. */)
+       doc: /* Return a vector of face attributes corresponding to PLIST.  */)
      (plist)
      Lisp_Object plist;
 {
@@ -5521,7 +5608,7 @@ Value is ORDER.  */)
   int i;
   int indices[DIM (font_sort_order)];
 
-  CHECK_LIST (order, 0);
+  CHECK_LIST (order);
   bzero (indices, sizeof indices);
   i = 0;
 
@@ -5567,14 +5654,14 @@ Value is ORDER.  */)
 DEFUN ("internal-set-alternative-font-family-alist",
        Finternal_set_alternative_font_family_alist,
        Sinternal_set_alternative_font_family_alist, 1, 1, 0,
-  doc: /* Define alternative font families to try in face font selection.
+       doc: /* Define alternative font families to try in face font selection.
 ALIST is an alist of (FAMILY ALTERNATIVE1 ALTERNATIVE2 ...) entries.
 Each ALTERNATIVE is tried in order if no fonts of font family FAMILY can
 be found.  Value is ALIST.  */)
      (alist)
      Lisp_Object alist;
 {
-  CHECK_LIST (alist, 0);
+  CHECK_LIST (alist);
   Vface_alternative_font_family_alist = alist;
   free_all_realized_faces (Qnil);
   return alist;
@@ -5584,14 +5671,14 @@ be found.  Value is ALIST.  */)
 DEFUN ("internal-set-alternative-font-registry-alist",
        Finternal_set_alternative_font_registry_alist,
        Sinternal_set_alternative_font_registry_alist, 1, 1, 0,
-  doc: /* Define alternative font registries to try in face font selection.
+       doc: /* Define alternative font registries to try in face font selection.
 ALIST is an alist of (REGISTRY ALTERNATIVE1 ALTERNATIVE2 ...) entries.
 Each ALTERNATIVE is tried in order if no fonts of font registry REGISTRY can
 be found.  Value is ALIST.  */)
      (alist)
      Lisp_Object alist;
 {
-  CHECK_LIST (alist, 0);
+  CHECK_LIST (alist);
   Vface_alternative_font_registry_alist = alist;
   free_all_realized_faces (Qnil);
   return alist;
@@ -5985,12 +6072,12 @@ try_font_list (f, attrs, family, registry, fonts)
   int nfonts = 0;
   Lisp_Object face_family = attrs[LFACE_FAMILY_INDEX];
 
-  if (STRINGP (face_family))
-    nfonts = try_alternative_families (f, face_family, registry, fonts);
-
-  if (nfonts == 0 && !NILP (family))
+  if (!NILP (family))
     nfonts = try_alternative_families (f, family, registry, fonts);
 
+  if (nfonts == 0 && STRINGP (face_family))
+    nfonts = try_alternative_families (f, face_family, registry, fonts);
+
   /* Try font family of the default face or "fixed".  */
   if (nfonts == 0)
     {
@@ -6030,26 +6117,28 @@ face_fontset (attrs)
 /* Choose a name of font to use on frame F to display character C with
    Lisp face attributes specified by ATTRS.  The font name is
    determined by the font-related attributes in ATTRS and the name
-   pattern for C in FONTSET.  Value is the font name which is
-   allocated from the heap and must be freed by the caller, or NULL if
-   we can get no information about the font name of C.  It is assured
-   that we always get some information for a single byte
-   character.  */
+   pattern for C in FACE->fontset (or Vdefault_fontset if FACE is
+   null).  Value is the font name which is allocated from the heap and
+   must be freed by the caller, or NULL if we can get no information
+   about the font name of C.  It is assured that we always get some
+   information for a single byte character.  */
 
 static char *
-choose_face_font (f, attrs, fontset, c)
+choose_face_font (f, attrs, face, c)
      struct frame *f;
      Lisp_Object *attrs;
-     int fontset, c;
+     struct face *face;
+     int c;
 {
-  Lisp_Object pattern;
+  Lisp_Object val;
+  Lisp_Object pattern, family, registry;
+  Lisp_Object new_attrs[LFACE_VECTOR_SIZE];
   char *font_name = NULL;
   struct font_name *fonts;
   int nfonts, width_ratio;
 
-  /* Get (foundry and) family name and registry (and encoding) name of
-     a font for C.  */
-  pattern = fontset_font_pattern (f, fontset, c);
+  /* Get font spec of a font for C.  */
+  pattern = fontset_font_pattern (f, face, c);
   if (NILP (pattern))
     {
       xassert (!SINGLE_BYTE_CHAR_P (c));
@@ -6060,13 +6149,34 @@ choose_face_font (f, attrs, fontset, c)
   if (STRINGP (pattern))
     return xstrdup (XSTRING (pattern)->data);
 
+  family = AREF (pattern, FONT_SPEC_FAMILY_INDEX);
+  registry = AREF (pattern, FONT_SPEC_REGISTRY_INDEX);
+
+  bcopy (attrs, new_attrs, sizeof (Lisp_Object) * LFACE_VECTOR_SIZE);
+
+#if 0
+  /* This doesn't work well for the moment.  */
+  if (! NILP (AREF (pattern, FONT_SPEC_WEIGHT_INDEX)))
+    new_attrs[LFACE_WEIGHT_INDEX] = AREF (pattern, FONT_SPEC_WEIGHT_INDEX);
+  if (! NILP (AREF (pattern, FONT_SPEC_SLANT_INDEX)))
+    new_attrs[LFACE_SLANT_INDEX] = AREF (pattern, FONT_SPEC_SLANT_INDEX);
+  if (! NILP (AREF (pattern, FONT_SPEC_SWIDTH_INDEX)))
+    new_attrs[LFACE_SWIDTH_INDEX] = AREF (pattern, FONT_SPEC_SWIDTH_INDEX);
+#endif
+
+  /* If C is an ASCII character, family name in ATTRS has higher
+     priority than what specified in the fontset.  */
+  if (STRINGP (attrs[LFACE_FAMILY_INDEX])
+      && ASCII_CHAR_P (c))
+    family = Qnil;
+
   /* Get a list of fonts matching that pattern and choose the
      best match for the specified face attributes from it.  */
-  nfonts = try_font_list (f, attrs, XCAR (pattern), XCDR (pattern), &fonts);
-  width_ratio = (SINGLE_BYTE_CHAR_P (c)
+  nfonts = try_font_list (f, new_attrs, family, registry, &fonts);
+  width_ratio = (ASCII_CHAR_P (c)
                 ? 1
-                : CHARSET_WIDTH (CHAR_CHARSET (c)));
-  font_name = best_matching_font (f, attrs, fonts, nfonts, width_ratio);
+                : CHAR_WIDTH (c));
+  font_name = best_matching_font (f, new_attrs, fonts, nfonts, width_ratio);
   return font_name;
 }
 
@@ -6097,8 +6207,9 @@ realize_basic_faces (f)
   if (realize_default_face (f))
     {
       realize_named_face (f, Qmode_line, MODE_LINE_FACE_ID);
+      realize_named_face (f, Qmode_line_inactive, MODE_LINE_INACTIVE_FACE_ID);
       realize_named_face (f, Qtool_bar, TOOL_BAR_FACE_ID);
-      realize_named_face (f, Qfringe, BITMAP_AREA_FACE_ID);
+      realize_named_face (f, Qfringe, FRINGE_FACE_ID);
       realize_named_face (f, Qheader_line, HEADER_LINE_FACE_ID);
       realize_named_face (f, Qscroll_bar, SCROLL_BAR_FACE_ID);
       realize_named_face (f, Qborder, BORDER_FACE_ID);
@@ -6163,8 +6274,10 @@ realize_default_face (f)
       LFACE_FAMILY (lface) = build_string ("default");
       LFACE_SWIDTH (lface) = Qnormal;
       LFACE_HEIGHT (lface) = make_number (1);
-      LFACE_WEIGHT (lface) = Qnormal;
-      LFACE_SLANT (lface) = Qnormal;
+      if (UNSPECIFIEDP (LFACE_WEIGHT (lface)))
+       LFACE_WEIGHT (lface) = Qnormal;
+      if (UNSPECIFIEDP (LFACE_SLANT (lface)))
+       LFACE_SLANT (lface) = Qnormal;
       LFACE_AVGWIDTH (lface) = Qunspecified;
     }
 
@@ -6340,21 +6453,16 @@ realize_x_face (cache, attrs, c, base_face)
 
   f = cache->f;
 
-  /* If C is a multibyte character, we share all face attirbutes with
+  /* If C is a non-ASCII character, we share all face attirbutes with
      BASE_FACE including the realized fontset.  But, we must load a
      different font.  */
-  if (!SINGLE_BYTE_CHAR_P (c))
+  if (! ASCII_CHAR_P (c))
     {
       bcopy (base_face, face, sizeof *face);
       face->gc = 0;
 
       /* Don't try to free the colors copied bitwise from BASE_FACE.  */
-      face->foreground_defaulted_p = 1;
-      face->background_defaulted_p = 1;
-      face->underline_defaulted_p = 1;
-      face->overline_color_defaulted_p = 1;
-      face->strike_through_color_defaulted_p = 1;
-      face->box_color_defaulted_p = 1;
+      face->colors_copied_bitwise_p = 1;
 
       /* to force realize_face to load font */
       face->font = NULL;
@@ -6403,7 +6511,7 @@ realize_x_face (cache, attrs, c, base_face)
       if (STRINGP (attrs[LFACE_FONT_INDEX]))
         {
           struct font_info *font_info =
-            FS_LOAD_FONT (f, 0, XSTRING (attrs[LFACE_FONT_INDEX])->data, -1);
+            FS_LOAD_FONT (f, XSTRING (attrs[LFACE_FONT_INDEX])->data);
           if (font_info)
             face->font = font_info->font;
         }
@@ -6695,7 +6803,7 @@ realize_tty_face (cache, attrs, c)
 DEFUN ("tty-suppress-bold-inverse-default-colors",
        Ftty_suppress_bold_inverse_default_colors,
        Stty_suppress_bold_inverse_default_colors, 1, 1, 0,
-  doc: /* Suppress/allow boldness of faces with inverse default colors.
+       doc: /* Suppress/allow boldness of faces with inverse default colors.
 SUPPRESS non-nil means suppress it.
 This affects bold faces on TTYs whose foreground is the default background
 color of the display and whose background is the default foreground color.
@@ -7039,7 +7147,7 @@ DEFUN ("dump-face", Fdump_face, Sdump_face, 0, 1, 0, doc: /* */)
   else
     {
       struct face *face;
-      CHECK_NUMBER (n, 0);
+      CHECK_NUMBER (n);
       face = FACE_FROM_ID (SELECTED_FRAME (), XINT (n));
       if (face == NULL)
        error ("Not a valid face");
@@ -7198,6 +7306,8 @@ syms_of_xfaces ()
   staticpro (&Qborder);
   Qmouse = intern ("mouse");
   staticpro (&Qmouse);
+  Qmode_line_inactive = intern ("mode-line-inactive");
+  staticpro (&Qmode_line_inactive);
   Qtty_color_desc = intern ("tty-color-desc");
   staticpro (&Qtty_color_desc);
   Qtty_color_by_index = intern ("tty-color-by-index");