(realize_x_face): Make abort condition clearer.
[bpt/emacs.git] / src / xfaces.c
index ff5a636..a504ca1 100644 (file)
@@ -234,7 +234,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #define x_display_info w32_display_info
 #define FRAME_X_FONT_TABLE FRAME_W32_FONT_TABLE
 #define check_x check_w32
-#define x_list_fonts w32_list_fonts
 #define GCGraphicsExposures 0
 #endif /* WINDOWSNT */
 
@@ -245,7 +244,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #define x_display_info ns_display_info
 #define FRAME_X_FONT_TABLE FRAME_NS_FONT_TABLE
 #define check_x check_ns
-#define x_list_fonts ns_list_fonts
 #define GCGraphicsExposures 0
 #endif /* HAVE_NS */
 
@@ -557,14 +555,6 @@ static void uncache_face P_ ((struct face_cache *, struct face *));
 static GC x_create_gc P_ ((struct frame *, unsigned long, XGCValues *));
 static void x_free_gc P_ ((struct frame *, GC));
 
-#ifdef WINDOWSNT
-extern Lisp_Object w32_list_fonts P_ ((struct frame *, Lisp_Object, int, int));
-#endif /* WINDOWSNT */
-
-#ifdef HAVE_NS
-extern Lisp_Object ns_list_fonts P_ ((struct frame *, Lisp_Object, int, int));
-#endif /* HAVE_NS */
-
 #ifdef USE_X_TOOLKIT
 static void x_update_menu_appearance P_ ((struct frame *));
 
@@ -1838,21 +1828,6 @@ the face font sort order.  */)
   return result;
 }
 
-
-DEFUN ("x-font-family-list", Fx_font_family_list, Sx_font_family_list,
-       0, 1, 0,
-       doc: /* Return a list of available font families on FRAME.
-If FRAME is omitted or nil, use the selected frame.
-Value is a list of conses (FAMILY . FIXED-P) where FAMILY
-is a font family, and FIXED-P is non-nil if fonts of that family
-are fixed-pitch.  */)
-     (frame)
-     Lisp_Object frame;
-{
-  return Ffont_family_list (frame);
-}
-
-
 DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 5, 0,
        doc: /* Return a list of the names of available fonts matching PATTERN.
 If optional arguments FACE and FRAME are specified, return only fonts
@@ -1951,6 +1926,26 @@ the WIDTH times as wide as FACE on FRAME.  */)
 
 #endif /* HAVE_WINDOW_SYSTEM */
 
+#if defined(HAVE_WINDOW_SYSTEM) || defined(__MSDOS__)
+
+DEFUN ("x-font-family-list", Fx_font_family_list, Sx_font_family_list,
+       0, 1, 0,
+       doc: /* Return a list of available font families on FRAME.
+If FRAME is omitted or nil, use the selected frame.
+Value is a list of conses (FAMILY . FIXED-P) where FAMILY
+is a font family, and FIXED-P is non-nil if fonts of that family
+are fixed-pitch.  */)
+     (frame)
+     Lisp_Object frame;
+{
+#ifdef __MSDOS__
+  return Fcons (Fcons (build_string ("default"), Qt), Qnil);
+#else
+  return Ffont_family_list (frame);
+#endif
+}
+
+#endif /* HAVE_WINDOW_SYSTEM || __MSDOS__ */
 
 \f
 /***********************************************************************
@@ -3227,6 +3222,9 @@ FRAME 0 means change the face on all frames, and change the default
     }
   else if (EQ (attr, QCforeground))
     {
+      /* Compatibility with 20.x.  */
+      if (NILP (value))
+       value = Qunspecified;
       if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
        {
          /* Don't check for valid color names here because it depends
@@ -3241,6 +3239,9 @@ FRAME 0 means change the face on all frames, and change the default
     }
   else if (EQ (attr, QCbackground))
     {
+      /* Compatibility with 20.x.  */
+      if (NILP (value))
+       value = Qunspecified;
       if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
        {
          /* Don't check for valid color names here because it depends
@@ -3366,12 +3367,15 @@ FRAME 0 means change the face on all frames, and change the default
     signal_error ("Invalid face attribute name", attr);
 
   if (prop_index)
-    /* If a font-related attribute other than QCfont and QCfontset is
-       specified, and if the original QCfont attribute has a font
-       (font-spec or font-object), set the corresponding property in
-       the font to nil so that the font selector doesn't think that
-       the attribute is mandatory.  */
-    font_clear_prop (XVECTOR (lface)->contents, prop_index);
+    {
+      /* If a font-related attribute other than QCfont and QCfontset
+        is specified, and if the original QCfont attribute has a font
+        (font-spec or font-object), set the corresponding property in
+        the font to nil so that the font selector doesn't think that
+        the attribute is mandatory.  Also, clear the average
+        width.  */
+      font_clear_prop (XVECTOR (lface)->contents, prop_index);
+    }
 
   /* Changing a named face means that all realized faces depending on
      that face are invalid.  Since we cannot tell which realized faces
@@ -3743,6 +3747,10 @@ x_update_menu_appearance (f)
        }
 
       if (face->font
+         /* On Solaris 5.8, it's been reported that the `menu' face
+            can be unspecified here, during startup.  Why this
+            happens remains unknown.  -- cyd  */
+         && FONTP (LFACE_FONT (lface))
          && (!UNSPECIFIEDP (LFACE_FAMILY (lface))
              || !UNSPECIFIEDP (LFACE_FOUNDRY (lface))
              || !UNSPECIFIEDP (LFACE_SWIDTH (lface))
@@ -4984,7 +4992,9 @@ lookup_derived_face (f, symbol, face_id, signal_p)
   if (!default_face)
     abort ();
 
-  get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0);
+  if (!get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0))
+    return -1;
+
   bcopy (default_face->lface, attrs, sizeof attrs);
   merge_face_vectors (f, symbol_attrs, attrs, 0);
   return lookup_face (f, attrs);
@@ -5456,13 +5466,20 @@ be found.  Value is ALIST.  */)
      (alist)
      Lisp_Object alist;
 {
-  Lisp_Object tail, tail2;
+  Lisp_Object entry, tail, tail2;
 
   CHECK_LIST (alist);
   alist = Fcopy_sequence (alist);
   for (tail = alist; CONSP (tail); tail = XCDR (tail))
-    for (tail2 = XCAR (tail); CONSP (tail2); tail2 = XCDR (tail2))
-      XSETCAR (tail2, Fintern (XCAR (tail2), Qnil));
+    {
+      entry = XCAR (tail);
+      CHECK_LIST (entry);
+      entry = Fcopy_sequence (entry);
+      XSETCAR (tail, entry);
+      for (tail2 = entry; CONSP (tail2); tail2 = XCDR (tail2))
+       XSETCAR (tail2, Fintern (XCAR (tail2), Qnil));
+    }
+
   Vface_alternative_font_family_alist = alist;
   free_all_realized_faces (Qnil);
   return alist;
@@ -5479,13 +5496,19 @@ be found.  Value is ALIST.  */)
      (alist)
      Lisp_Object alist;
 {
-  Lisp_Object tail, tail2;
+  Lisp_Object entry, tail, tail2;
 
   CHECK_LIST (alist);
   alist = Fcopy_sequence (alist);
   for (tail = alist; CONSP (tail); tail = XCDR (tail))
-    for (tail2 = XCAR (tail); CONSP (tail2); tail2 = XCDR (tail2))
-      XSETCAR (tail2, Fdowncase (XCAR (tail2)));
+    {
+      entry = XCAR (tail);
+      CHECK_LIST (entry);
+      entry = Fcopy_sequence (entry);
+      XSETCAR (tail, entry);
+      for (tail2 = entry; CONSP (tail2); tail2 = XCDR (tail2))
+       XSETCAR (tail2, Fdowncase (XCAR (tail2)));
+    }
   Vface_alternative_font_registry_alist = alist;
   free_all_realized_faces (Qnil);
   return alist;
@@ -5863,9 +5886,12 @@ realize_x_face (cache, attrs)
         realizing the default face, thus the default face should have
         already been realized.  */
       if (fontset == -1)
-       fontset = default_face->fontset;
-      if (fontset == -1)
-       abort ();
+       {
+         if (default_face)
+           fontset = default_face->fontset;
+         if (fontset == -1)
+           abort ();
+       }
       if (! FONT_OBJECT_P (attrs[LFACE_FONT_INDEX]))
        attrs[LFACE_FONT_INDEX]
          = font_load_for_lface (f, attrs, attrs[LFACE_FONT_INDEX]);
@@ -6543,10 +6569,10 @@ merge_faces (f, face_name, face_id, base_face_id)
       if (face_id < 0 || face_id >= lface_id_to_name_size)
        return base_face_id;
       face_name = lface_id_to_name[face_id];
-      face_id = lookup_derived_face (f, face_name, base_face_id, 1);
-      if (face_id >= 0)
-       return face_id;
-      return base_face_id;
+      /* When called during make-frame, lookup_derived_face may fail
+        if the faces are uninitialized.  Don't signal an error.  */
+      face_id = lookup_derived_face (f, face_name, base_face_id, 0);
+      return (face_id >= 0 ? face_id : base_face_id);
     }
 
   /* Begin with attributes from the base face.  */
@@ -6574,6 +6600,60 @@ merge_faces (f, face_name, face_id, base_face_id)
 }
 
 \f
+
+#ifndef HAVE_X_WINDOWS
+DEFUN ("x-load-color-file", Fx_load_color_file,
+       Sx_load_color_file, 1, 1, 0,
+       doc: /* Create an alist of color entries from an external file.
+
+The file should define one named RGB color per line like so:
+  R G B   name
+where R,G,B are numbers between 0 and 255 and name is an arbitrary string.  */)
+    (filename)
+    Lisp_Object filename;
+{
+  FILE *fp;
+  Lisp_Object cmap = Qnil;
+  Lisp_Object abspath;
+
+  CHECK_STRING (filename);
+  abspath = Fexpand_file_name (filename, Qnil);
+
+  fp = fopen (SDATA (filename), "rt");
+  if (fp)
+    {
+      char buf[512];
+      int red, green, blue;
+      int num;
+
+      BLOCK_INPUT;
+
+      while (fgets (buf, sizeof (buf), fp) != NULL) {
+       if (sscanf (buf, "%u %u %u %n", &red, &green, &blue, &num) == 3)
+         {
+           char *name = buf + num;
+           num = strlen (name) - 1;
+           if (name[num] == '\n')
+             name[num] = 0;
+           cmap = Fcons (Fcons (build_string (name),
+#ifdef WINDOWSNT
+                                make_number (RGB (red, green, blue))),
+#else
+                                make_number ((red << 16) | (green << 8) | blue)),
+#endif
+                         cmap);
+         }
+      }
+      fclose (fp);
+
+      UNBLOCK_INPUT;
+    }
+
+  return cmap;
+}
+#endif
+
+\f
 /***********************************************************************
                                Tests
  ***********************************************************************/
@@ -6829,6 +6909,9 @@ syms_of_xfaces ()
 #endif
   defsubr (&Scolor_gray_p);
   defsubr (&Scolor_supported_p);
+#ifndef HAVE_X_WINDOWS
+  defsubr (&Sx_load_color_file);
+#endif
   defsubr (&Sface_attribute_relative_p);
   defsubr (&Smerge_face_attribute);
   defsubr (&Sinternal_get_lisp_face_attribute);
@@ -6944,8 +7027,10 @@ a font of 10 point, we actually use a font of 10 * RESCALE-RATIO point.  */);
   defsubr (&Sx_list_fonts);
   defsubr (&Sinternal_face_x_get_resource);
   defsubr (&Sx_family_fonts);
+#endif
+#if defined(HAVE_WINDOW_SYSTEM) || defined(__MSDOS__)
   defsubr (&Sx_font_family_list);
-#endif /* HAVE_WINDOW_SYSTEM */
+#endif /* HAVE_WINDOW_SYSTEM || __MSDOS__ */
 }
 
 /* arch-tag: 8a0f7598-5517-408d-9ab3-1da6fcd4c749