/* xfaces.c -- "Face" primitives.
-Copyright (C) 1993-1994, 1998-2015 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
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
#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>
#include TERM_HEADER
#include "fontset.h"
#ifdef HAVE_NTGUI
-#define x_display_info w32_display_info
#define GCGraphicsExposures 0
#endif /* HAVE_NTGUI */
#include "dispextern.h"
#include "blockinput.h"
#include "window.h"
-#include "intervals.h"
#include "termchar.h"
#include "font.h"
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);
#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. */
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);
/* 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)
#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 maximum, Lisp_Object width)
{
struct frame *f;
- int size, avgwidth IF_LINT (= 0);
+ int size, avgwidth;
check_window_system (NULL);
CHECK_STRING (pattern);
|| 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])
face_name, NAMED_MERGE_POINT_NORMAL,
&named_merge_points))
{
- struct gcpro gcpro1;
Lisp_Object from[LFACE_VECTOR_SIZE];
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;
}
free realized faces. */
if (NILP (Fget (face, Qface_no_inherit)))
{
- face_change = true;
- 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));
(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);
strings etc. because 20.2 didn't do it either. */
lface = lface_from_face_name (NULL, from, true);
copy = Finternal_make_lisp_face (to, Qnil);
+ f = NULL;
}
else
{
CHECK_LIVE_FRAME (new_frame);
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);
free realized faces. */
if (NILP (Fget (to, Qface_no_inherit)))
{
- face_change = true;
- 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;
/* 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);
/* Set lface to the Lisp attribute vector of FACE. */
if (EQ (frame, Qt))
{
+ f = NULL;
lface = lface_from_face_name (NULL, face, true);
/* When updating face-new-frame-defaults, we put :ignore-defface
frame = selected_frame;
CHECK_LIVE_FRAME (frame);
- lface = lface_from_face_name (XFRAME (frame), face, false);
+ 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))
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))
signal_error ("Invalid font or font-spec", value);
}
if (EQ (frame, Qt))
- f = XFRAME (selected_frame);
+ f1 = XFRAME (selected_frame);
else
- f = XFRAME (frame);
+ 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 (f))
+ 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 (f, attrs, value);
+ 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 (f, lface, value, true);
+ set_lface_from_font (f1, lface, value, true);
+ f1->face_change = 1;
}
}
else
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;
&& NILP (Fget (face, Qface_no_inherit))
&& NILP (Fequal (old_value, value)))
{
- face_change = true;
- windows_or_buffers_changed = 56;
+ f->face_change = true;
+ fset_redisplay (f);
}
if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
if (!NILP (face)
&& NILP (Fget (face, Qface_no_inherit)))
{
- face_change = true;
- windows_or_buffers_changed = 57;
+ f->face_change = true;
+ fset_redisplay (f);
}
}
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). */
{
struct frame *f = decode_live_frame (frame);
int face_id = lookup_named_face (f, face, true);
- struct face *fface = FACE_FROM_ID (f, face_id);
+ struct face *fface = FACE_OPT_FROM_ID (f, face_id);
if (! fface)
return Qnil;
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);
if (WINDOWP (f->root_window))
{
clear_current_matrices (f);
- windows_or_buffers_changed = 58;
+ fset_redisplay (f);
}
unblock_input ();
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)));
{
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))
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;
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,
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");
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
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
attrs[i] = Qunspecified;
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. */
/* 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))
{
*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)
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;
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);
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);
{
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);
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