]> code.delx.au - gnu-emacs/blobdiff - src/xfaces.c
(mark_terminals): Typo.
[gnu-emacs] / src / xfaces.c
index a5c5a21f585a526a90d95dc18a5c5d481dc3eb5c..01ac364589fd6fac869019bec62ce5524b2744a0 100644 (file)
@@ -1,12 +1,12 @@
 /* xfaces.c -- "Face" primitives.
    Copyright (C) 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-                 2005, 2006 Free Software Foundation, Inc.
+                 2005, 2006, 2007 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 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -195,11 +195,13 @@ Boston, MA 02110-1301, USA.  */
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <stdio.h>              /* This needs to be before termchar.h */
 
 #include "lisp.h"
 #include "charset.h"
 #include "keyboard.h"
 #include "frame.h"
+#include "termhooks.h"
 
 #ifdef HAVE_WINDOW_SYSTEM
 #include "fontset.h"
@@ -242,6 +244,7 @@ Boston, MA 02110-1301, USA.  */
 #include "blockinput.h"
 #include "window.h"
 #include "intervals.h"
+#include "termchar.h"
 
 #ifdef HAVE_X_WINDOWS
 
@@ -264,8 +267,6 @@ Boston, MA 02110-1301, USA.  */
 
 #include <ctype.h>
 
-#define abs(X)         ((X) < 0 ? -(X) : (X))
-
 /* Number of pt per inch (from the TeXbook).  */
 
 #define PT_PER_INCH 72.27
@@ -486,7 +487,6 @@ static int font_scalable_p P_ ((struct font_name *));
 static int get_lface_attributes P_ ((struct frame *, Lisp_Object, Lisp_Object *, int));
 static int load_pixmap P_ ((struct frame *, Lisp_Object, unsigned *, unsigned *));
 static unsigned char *xstrlwr P_ ((unsigned char *));
-static void signal_error P_ ((char *, Lisp_Object));
 static struct frame *frame_or_selected_frame P_ ((Lisp_Object, int));
 static void load_face_font P_ ((struct frame *, struct face *, int));
 static void load_face_colors P_ ((struct frame *, struct face *, Lisp_Object *));
@@ -744,10 +744,9 @@ x_free_gc (f, gc)
      struct frame *f;
      GC gc;
 {
-  BLOCK_INPUT;
+  eassert (interrupt_input_blocked);
   IF_DEBUG (xassert (--ngcs >= 0));
   XFreeGC (FRAME_X_DISPLAY (f), gc);
-  UNBLOCK_INPUT;
 }
 
 #endif /* HAVE_X_WINDOWS */
@@ -777,10 +776,8 @@ x_free_gc (f, gc)
      struct frame *f;
      GC gc;
 {
-  BLOCK_INPUT;
   IF_DEBUG (xassert (--ngcs >= 0));
   xfree (gc);
-  UNBLOCK_INPUT;
 }
 
 #endif  /* WINDOWSNT */
@@ -807,10 +804,9 @@ x_free_gc (f, gc)
      struct frame *f;
      GC gc;
 {
-  BLOCK_INPUT;
+  eassert (interrupt_input_blocked);
   IF_DEBUG (xassert (--ngcs >= 0));
   XFreeGC (FRAME_MAC_DISPLAY (f), gc);
-  UNBLOCK_INPUT;
 }
 
 #endif  /* MAC_OS */
@@ -855,17 +851,6 @@ xstrlwr (s)
 }
 
 
-/* Signal `error' with message S, and additional argument ARG.  */
-
-static void
-signal_error (s, arg)
-     char *s;
-     Lisp_Object arg;
-{
-  Fsignal (Qerror, Fcons (build_string (s), Fcons (arg, Qnil)));
-}
-
-
 /* If FRAME is nil, return a pointer to the selected frame.
    Otherwise, check that FRAME is a live frame, and return a pointer
    to it.  NPARAM is the parameter number of FRAME, for
@@ -1171,14 +1156,11 @@ load_pixmap (f, name, w_ptr, h_ptr)
      unsigned int *w_ptr, *h_ptr;
 {
   int bitmap_id;
-  Lisp_Object tem;
 
   if (NILP (name))
     return 0;
 
-  tem = Fbitmap_spec_p (name);
-  if (NILP (tem))
-    wrong_type_argument (Qbitmap_spec_p, name);
+  CHECK_TYPE (!NILP (Fbitmap_spec_p (name)), Qbitmap_spec_p, name);
 
   BLOCK_INPUT;
   if (CONSP (name))
@@ -1204,7 +1186,7 @@ load_pixmap (f, name, w_ptr, h_ptr)
 
   if (bitmap_id < 0)
     {
-      add_to_log ("Invalid or undefined bitmap %s", name, Qnil);
+      add_to_log ("Invalid or undefined bitmap `%s'", name, Qnil);
       bitmap_id = 0;
 
       if (w_ptr)
@@ -1271,8 +1253,10 @@ load_face_font (f, face, c)
       face->overstrike = needs_overstrike;
       if (face->gc)
        {
+         BLOCK_INPUT;
          x_free_gc (f, face->gc);
          face->gc = 0;
+         UNBLOCK_INPUT;
        }
     }
   else
@@ -3236,6 +3220,22 @@ push_named_merge_point (struct named_merge_point *new_named_merge_point,
 
 \f
 
+#if 0                          /* Seems to be unused.  */
+static Lisp_Object
+internal_resolve_face_name (nargs, args)
+     int nargs;
+     Lisp_Object *args;
+{
+  return Fget (args[0], args[1]);
+}
+
+static Lisp_Object
+resolve_face_name_error (ignore)
+     Lisp_Object ignore;
+{
+  return Qnil;
+}
+#endif
 
 /* Resolve face name FACE_NAME.  If FACE_NAME is a string, intern it
    to make it a symbol.  If FACE_NAME is an alias for another face,
@@ -3276,7 +3276,7 @@ resolve_face_name (face_name, signal_p)
       if (EQ (hare, tortoise))
        {
          if (signal_p)
-           Fsignal (Qcircular_list, Fcons (orig_face, Qnil));
+           xsignal1 (Qcircular_list, orig_face);
          return Qdefault;
        }
     }
@@ -3950,6 +3950,8 @@ Otherwise check for the existence of a global face.  */)
 {
   Lisp_Object lface;
 
+  face = resolve_face_name (face, 1);
+
   if (!NILP (frame))
     {
       CHECK_LIVE_FRAME (frame);
@@ -4799,7 +4801,14 @@ x_update_menu_appearance (f)
 DEFUN ("face-attribute-relative-p", Fface_attribute_relative_p,
        Sface_attribute_relative_p,
        2, 2, 0,
-       doc: /* Return non-nil if face ATTRIBUTE VALUE is relative.  */)
+       doc: /* Check whether a face attribute value is relative.
+Specifically, this function returns t if the attribute ATTRIBUTE
+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.  */)
      (attribute, value)
      Lisp_Object attribute, value;
 {
@@ -5245,8 +5254,10 @@ free_realized_face (f, face)
            free_face_fontset (f, face);
          if (face->gc)
            {
+             BLOCK_INPUT;
              x_free_gc (f, face->gc);
              face->gc = 0;
+             UNBLOCK_INPUT;
            }
 
          free_face_colors (f, face);
@@ -5356,13 +5367,11 @@ If FRAME is unspecified or nil, the current frame is used.  */)
   CHECK_LIVE_FRAME (frame);
   f = XFRAME (frame);
 
-  if ((CONSP (color1) && !parse_rgb_list (color1, &cdef1))
-      || !STRINGP (color1)
-      || !defined_color (f, SDATA (color1), &cdef1, 0))
+  if (!(CONSP (color1) && parse_rgb_list (color1, &cdef1))
+      && !(STRINGP (color1) && defined_color (f, SDATA (color1), &cdef1, 0)))
     signal_error ("Invalid color", color1);
-  if ((CONSP (color2) && !parse_rgb_list (color2, &cdef2))
-      || !STRINGP (color2)
-      || !defined_color (f, SDATA (color2), &cdef2, 0))
+  if (!(CONSP (color2) && parse_rgb_list (color2, &cdef2))
+      && !(STRINGP (color2) && defined_color (f, SDATA (color2), &cdef2, 0)))
     signal_error ("Invalid color", color2);
 
   return make_number (color_distance (&cdef1, &cdef2));
@@ -5412,8 +5421,10 @@ clear_face_gcs (c)
          struct face *face = c->faces_by_id[i];
          if (face && face->gc)
            {
+             BLOCK_INPUT;
              x_free_gc (c->f, face->gc);
              face->gc = 0;
+             UNBLOCK_INPUT;
            }
        }
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -5725,6 +5736,8 @@ lookup_named_face (f, symbol, c, signal_p)
       if (!realize_basic_faces (f))
        return -1;
       default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
+      if (default_face == NULL)
+       abort ();  /* realize_basic_faces must have set it up  */
     }
 
   if (!get_lface_attributes (f, symbol, symbol_attrs, signal_p))
@@ -6153,7 +6166,7 @@ tty_supports_face_attributes_p (f, attrs, def_face)
   /* See if the capabilities we selected above are supported, with the
      given colors.  */
   if (test_caps != 0 &&
-      ! tty_capable_p (f, test_caps, fg_tty_color.pixel, bg_tty_color.pixel))
+      ! tty_capable_p (FRAME_TTY (f), test_caps, fg_tty_color.pixel, bg_tty_color.pixel))
     return 0;
 
 
@@ -6184,7 +6197,7 @@ face for italic.  */)
   (attributes, display)
      Lisp_Object attributes, display;
 {
-  int supports, i;
+  int supports = 0, i;
   Lisp_Object frame;
   struct frame *f;
   struct face *def_face;
@@ -6229,6 +6242,8 @@ face for italic.  */)
       if (! realize_basic_faces (f))
        error ("Cannot realize default face");
       def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
+      if (def_face == NULL)
+       abort ();  /* realize_basic_faces must have set it up  */
     }
 
   /* Dispatch to the appropriate handler.  */
@@ -6383,6 +6398,12 @@ better_font_p (values, font1, font2, compare_pt_p, avgwidth)
 {
   int i;
 
+  /* Any font is better than no font.  */
+  if (! font1)
+    return 0;
+  if (! font2)
+    return 1;
+
   for (i = 0; i < DIM (font_sort_order); ++i)
     {
       int xlfd_idx = font_sort_order[i];
@@ -6627,29 +6648,19 @@ best_matching_font (f, attrs, fonts, nfonts, width_ratio, needs_overstrike)
   if (needs_overstrike)
     *needs_overstrike = 0;
 
-  /* Start with the first non-scalable font in the list.  */
-  for (i = 0; i < nfonts; ++i)
-    if (!font_scalable_p (fonts + i))
-      break;
+  best = NULL;
 
   /* Find the best match among the non-scalable fonts.  */
-  if (i < nfonts)
-    {
-      best = fonts + i;
-
-      for (i = 1; i < nfonts; ++i)
-       if (!font_scalable_p (fonts + i)
-           && better_font_p (specified, fonts + i, best, 1, avgwidth))
-         {
-           best = fonts + i;
+  for (i = 0; i < nfonts; ++i)
+    if (!font_scalable_p (fonts + i)
+       && better_font_p (specified, fonts + i, best, 1, avgwidth))
+      {
+       best = fonts + i;
 
-           exact_p = exact_face_match_p (specified, best, avgwidth);
-           if (exact_p)
-             break;
-         }
-    }
-  else
-    best = NULL;
+       exact_p = exact_face_match_p (specified, best, avgwidth);
+       if (exact_p)
+         break;
+      }
 
   /* Unless we found an exact match among non-scalable fonts, see if
      we can find a better match among scalable fonts.  */
@@ -6673,8 +6684,7 @@ best_matching_font (f, attrs, fonts, nfonts, width_ratio, needs_overstrike)
       for (i = 0; i < nfonts; ++i)
        if (font_scalable_p (fonts + i))
          {
-           if (best == NULL
-               || better_font_p (specified, fonts + i, best, 0, 0)
+           if (better_font_p (specified, fonts + i, best, 0, 0)
                || (!non_scalable_has_exact_height_p
                    && !better_font_p (specified, best, fonts + i, 0, 0)))
              {
@@ -6682,23 +6692,27 @@ best_matching_font (f, attrs, fonts, nfonts, width_ratio, needs_overstrike)
                best = fonts + i;
              }
          }
+    }
 
-      if (needs_overstrike)
-       {
-         enum xlfd_weight want_weight = specified[XLFD_WEIGHT];
-         enum xlfd_weight got_weight = best->numeric[XLFD_WEIGHT];
+  /* We should have found SOME font.  */
+  if (best == NULL)
+    abort ();
 
-         if (want_weight > XLFD_WEIGHT_MEDIUM && want_weight > got_weight)
-           {
-             /* We want a bold font, but didn't get one; try to use
-                overstriking instead to simulate bold-face.  However,
-                don't overstrike an already-bold fontn unless the
-                desired weight grossly exceeds the available weight.  */
-             if (got_weight > XLFD_WEIGHT_MEDIUM)
-               *needs_overstrike = (got_weight - want_weight) > 2;
-             else
-               *needs_overstrike = 1;
-           }
+  if (! exact_p && needs_overstrike)
+    {
+      enum xlfd_weight want_weight = specified[XLFD_WEIGHT];
+      enum xlfd_weight got_weight = best->numeric[XLFD_WEIGHT];
+
+      if (want_weight > XLFD_WEIGHT_MEDIUM && want_weight > got_weight)
+       {
+         /* We want a bold font, but didn't get one; try to use
+            overstriking instead to simulate bold-face.  However,
+            don't overstrike an already-bold font unless the
+            desired weight grossly exceeds the available weight.  */
+         if (got_weight > XLFD_WEIGHT_MEDIUM)
+           *needs_overstrike = (want_weight - got_weight) > 2;
+         else
+           *needs_overstrike = 1;
        }
     }
 
@@ -6956,7 +6970,8 @@ realize_basic_faces (f)
        {
          FRAME_FACE_CACHE (f)->menu_face_changed_p = 0;
 #ifdef USE_X_TOOLKIT
-         x_update_menu_appearance (f);
+          if (FRAME_WINDOW_P (f))
+            x_update_menu_appearance (f);
 #endif
        }
 
@@ -7043,7 +7058,7 @@ realize_default_face (f)
        LFACE_FOREGROUND (lface) = XCDR (color);
       else if (FRAME_WINDOW_P (f))
        return 0;
-      else if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
+      else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
        LFACE_FOREGROUND (lface) = build_string (unspecified_fg);
       else
        abort ();
@@ -7058,7 +7073,7 @@ realize_default_face (f)
        LFACE_BACKGROUND (lface) = XCDR (color);
       else if (FRAME_WINDOW_P (f))
        return 0;
-      else if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
+      else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
        LFACE_BACKGROUND (lface) = build_string (unspecified_bg);
       else
        abort ();
@@ -7074,12 +7089,20 @@ realize_default_face (f)
   face = realize_face (c, attrs, 0, NULL, DEFAULT_FACE_ID);
 
 #ifdef HAVE_WINDOW_SYSTEM
-#ifdef HAVE_X_WINDOWS  
-  if (face->font != FRAME_FONT (f))
-    /* As the font specified for the frame was not acceptable as a
-       font for the default face (perhaps because auto-scaled fonts
-       are rejected), we must adjust the frame font.  */
-    x_set_font (f, build_string (face->font_name), Qnil);
+#ifdef HAVE_X_WINDOWS
+  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;
+      /* Otherwise, the font specified for the frame was not
+        acceptable as a font for the default face (perhaps because
+        auto-scaled fonts are rejected), so we must adjust the frame
+        font.  */
+      x_set_font (f, build_string (face->font_name), Qnil);
+    }
 #endif /* HAVE_X_WINDOWS */
 #endif /* HAVE_WINDOW_SYSTEM */
   return 1;
@@ -7157,6 +7180,11 @@ realize_face (cache, attrs, c, base_face, former_face_id)
     face = realize_x_face (cache, attrs, c, base_face);
   else if (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f))
     face = realize_tty_face (cache, attrs, c);
+  else if (FRAME_INITIAL_P (cache->f))
+    {
+      /* Create a dummy face. */
+      face = make_realized_face (attrs);
+    }
   else
     abort ();
 
@@ -7986,7 +8014,7 @@ syms_of_xfaces ()
   staticpro (&QCforeground);
   QCbackground = intern (":background");
   staticpro (&QCbackground);
-  QCstipple = intern (":stipple");;
+  QCstipple = intern (":stipple");
   staticpro (&QCstipple);
   QCwidth = intern (":width");
   staticpro (&QCwidth);