/* 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,
#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"
#include "blockinput.h"
#include "window.h"
#include "intervals.h"
+#include "termchar.h"
#ifdef HAVE_X_WINDOWS
#include <ctype.h>
-#define abs(X) ((X) < 0 ? -(X) : (X))
-
/* Number of pt per inch (from the TeXbook). */
#define PT_PER_INCH 72.27
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 *));
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 */
struct frame *f;
GC gc;
{
- BLOCK_INPUT;
IF_DEBUG (xassert (--ngcs >= 0));
xfree (gc);
- UNBLOCK_INPUT;
}
#endif /* WINDOWSNT */
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 */
}
-/* 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
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))
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)
face->overstrike = needs_overstrike;
if (face->gc)
{
+ BLOCK_INPUT;
x_free_gc (f, face->gc);
face->gc = 0;
+ UNBLOCK_INPUT;
}
}
else
\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,
if (EQ (hare, tortoise))
{
if (signal_p)
- Fsignal (Qcircular_list, Fcons (orig_face, Qnil));
+ xsignal1 (Qcircular_list, orig_face);
return Qdefault;
}
}
{
Lisp_Object lface;
+ face = resolve_face_name (face, 1);
+
if (!NILP (frame))
{
CHECK_LIVE_FRAME (frame);
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;
{
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);
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));
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 */
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))
/* 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;
(attributes, display)
Lisp_Object attributes, display;
{
- int supports, i;
+ int supports = 0, i;
Lisp_Object frame;
struct frame *f;
struct face *def_face;
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. */
{
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];
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. */
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)))
{
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;
}
}
{
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
}
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 ();
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 ();
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;
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 ();
staticpro (&QCforeground);
QCbackground = intern (":background");
staticpro (&QCbackground);
- QCstipple = intern (":stipple");;
+ QCstipple = intern (":stipple");
staticpro (&QCstipple);
QCwidth = intern (":width");
staticpro (&QCwidth);