/* xfaces.c -- "Face" primitives.
-Copyright (C) 1993-1994, 1998-2013 Free Software Foundation, Inc.
+Copyright (C) 1993-1994, 1998-2014 Free Software Foundation, Inc.
This file is part of GNU Emacs.
merging faces of that character, that face is `realized'. The
realization process maps face attributes to what is physically
available on the system where Emacs runs. The result is a
- `realized face' in form of a struct face which is stored in the
+ `realized face' in the form of a struct face which is stored in the
face cache of the frame on which it was realized.
Face realization is done in the context of the character to display
used to fill in unspecified attributes of the default face. */
#include <config.h>
-#include <stdio.h>
+#include "sysstdio.h"
#include <sys/types.h>
#include <sys/stat.h>
-#include <stdio.h> /* This needs to be before termchar.h */
#include "lisp.h"
#include "character.h"
#include "frame.h"
#include "termhooks.h"
-#ifdef HAVE_X_WINDOWS
-#include "xterm.h"
#ifdef USE_MOTIF
#include <Xm/Xm.h>
#include <Xm/XmStrDefs.h>
#endif /* USE_MOTIF */
-#endif /* HAVE_X_WINDOWS */
#ifdef MSDOS
#include "dosfns.h"
#include TERM_HEADER
#include "fontset.h"
#ifdef HAVE_NTGUI
-#undef FRAME_X_DISPLAY_INFO
-#define FRAME_X_DISPLAY_INFO FRAME_W32_DISPLAY_INFO
#define x_display_info w32_display_info
-#define check_x check_w32
#define GCGraphicsExposures 0
#endif /* HAVE_NTGUI */
#ifdef HAVE_NS
-#undef FRAME_X_DISPLAY_INFO
-#define FRAME_X_DISPLAY_INFO FRAME_NS_DISPLAY_INFO
-#define x_display_info ns_display_info
-#define check_x check_ns
#define GCGraphicsExposures 0
#endif /* HAVE_NS */
#endif /* HAVE_WINDOW_SYSTEM */
#include <c-ctype.h>
-/* Number of pt per inch (from the TeXbook). */
-
-#define PT_PER_INCH 72.27
-
/* Non-zero if face attribute ATTR is unspecified. */
#define UNSPECIFIEDP(ATTR) EQ ((ATTR), Qunspecified)
static Lisp_Object QCfont, QCbold, QCitalic;
static Lisp_Object QCreverse_video;
static Lisp_Object QCoverline, QCstrike_through, QCbox, QCinherit;
-static Lisp_Object QCfontset;
+static Lisp_Object QCfontset, QCdistant_foreground;
/* Symbols used for attribute values. */
static Lisp_Object Qborder, Qmouse, Qmenu;
Lisp_Object Qmode_line_inactive;
static Lisp_Object Qvertical_border;
+static Lisp_Object Qwindow_divider;
+static Lisp_Object Qwindow_divider_first_pixel;
+static Lisp_Object Qwindow_divider_last_pixel;
/* The symbol `face-alias'. A symbols having that property is an
alias for another face. Value of the property is the name of
static Lisp_Object Qtty_color_alist;
+#ifdef HAVE_WINDOW_SYSTEM
+
/* Counter for calls to clear_face_cache. If this counter reaches
CLEAR_FONT_TABLE_COUNT, and a frame has more than
CLEAR_FONT_TABLE_NFONTS load, unused fonts are freed. */
#define CLEAR_FONT_TABLE_COUNT 100
#define CLEAR_FONT_TABLE_NFONTS 10
+#endif /* HAVE_WINDOW_SYSTEM */
+
/* Non-zero means face attributes have been changed since the last
redisplay. Used in redisplay_internal. */
static int menu_face_changed_default;
-\f
-/* Function prototypes. */
-
-struct table_entry;
struct named_merge_point;
-static void set_font_frame_param (Lisp_Object, Lisp_Object);
static struct face *realize_face (struct face_cache *, Lisp_Object *,
int);
-static struct face *realize_non_ascii_face (struct frame *, Lisp_Object,
- struct face *);
static struct face *realize_x_face (struct face_cache *, Lisp_Object *);
static struct face *realize_tty_face (struct face_cache *, Lisp_Object *);
-static int realize_basic_faces (struct frame *);
-static int realize_default_face (struct frame *);
+static bool realize_basic_faces (struct frame *);
+static bool realize_default_face (struct frame *);
static void realize_named_face (struct frame *, Lisp_Object, int);
static struct face_cache *make_face_cache (struct frame *);
-static void clear_face_gcs (struct face_cache *);
static void free_face_cache (struct face_cache *);
static int merge_face_ref (struct frame *, Lisp_Object, Lisp_Object *,
int, struct named_merge_point *);
+static int color_distance (XColor *x, XColor *y);
+
+#ifdef HAVE_WINDOW_SYSTEM
+static void set_font_frame_param (Lisp_Object, Lisp_Object);
+static void clear_face_gcs (struct face_cache *);
+static struct face *realize_non_ascii_face (struct frame *, Lisp_Object,
+ struct face *);
+#endif /* HAVE_WINDOW_SYSTEM */
-\f
/***********************************************************************
Utilities
***********************************************************************/
is called. */
void
-x_free_colors (struct frame *f, long unsigned int *pixels, int npixels)
+x_free_colors (struct frame *f, unsigned long *pixels, int npixels)
{
- int class = FRAME_X_DISPLAY_INFO (f)->visual->class;
+ 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. */
void
x_free_dpy_colors (Display *dpy, Screen *screen, Colormap cmap,
- long unsigned int *pixels, int npixels)
+ unsigned long *pixels, int npixels)
{
struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
int class = dpyinfo->visual->class;
are given by XGCV and MASK. */
static GC
-x_create_gc (struct frame *f, long unsigned int mask, XGCValues *xgcv)
+x_create_gc (struct frame *f, unsigned long mask, XGCValues *xgcv)
{
GC gc;
block_input ();
x_free_gc (struct frame *f, GC gc)
{
eassert (input_blocked_p ());
- IF_DEBUG (eassert (--ngcs >= 0));
+ IF_DEBUG ((--ngcs, eassert (ngcs >= 0)));
XFreeGC (FRAME_X_DISPLAY (f), gc);
}
static void
x_free_gc (struct frame *f, GC gc)
{
- IF_DEBUG (eassert (--ngcs >= 0));
+ IF_DEBUG ((--ngcs, eassert (ngcs >= 0)));
xfree (gc);
}
}
-/* Free face cache of frame F. Called from delete_frame. */
+/* Free face cache of frame F. Called from frame-dependent
+ resource freeing function, e.g. (x|tty)_free_frame_resources. */
void
free_frame_faces (struct frame *f)
if (clear_fonts_p
|| ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT)
{
-#if 0
- /* Not yet implemented. */
- clear_font_cache (frame);
-#endif
-
/* From time to time see if we can unload some fonts. This also
frees all realized faces on all frames. Fonts needed by
faces will be loaded again when faces are realized again. */
{
struct frame *f = XFRAME (frame);
if (FRAME_WINDOW_P (f)
- && FRAME_X_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS)
- free_all_realized_faces (frame);
+ && FRAME_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS)
+ {
+ clear_font_cache (f);
+ free_all_realized_faces (frame);
+ }
}
}
else
{
clear_face_cache (!NILP (thoroughly));
++face_change_count;
- ++windows_or_buffers_changed;
+ windows_or_buffers_changed = 53;
return Qnil;
}
\(WIDTH + 7)/8 bytes. */)
(Lisp_Object object)
{
- int pixmap_p = 0;
+ bool pixmap_p = 0;
if (STRINGP (object))
/* If OBJECT is a string, it's a file name. */
pixmap spec) for use on frame F. Value is the bitmap_id (see
xfns.c). If NAME is nil, return with a bitmap id of zero. If
bitmap cannot be loaded, display a message saying so, and return
- zero. Store the bitmap width in *W_PTR and its height in *H_PTR,
- if these pointers are not null. */
+ zero. */
static ptrdiff_t
-load_pixmap (FRAME_PTR f, Lisp_Object name, unsigned int *w_ptr,
- unsigned int *h_ptr)
+load_pixmap (struct frame *f, Lisp_Object name)
{
ptrdiff_t bitmap_id;
{
add_to_log ("Invalid or undefined bitmap `%s'", name, Qnil);
bitmap_id = 0;
-
- if (w_ptr)
- *w_ptr = 0;
- if (h_ptr)
- *h_ptr = 0;
}
else
{
#ifdef GLYPH_DEBUG
++npixmaps_allocated;
#endif
- if (w_ptr)
- *w_ptr = x_bitmap_width (f, bitmap_id);
-
- if (h_ptr)
- *h_ptr = x_bitmap_height (f, bitmap_id);
}
return bitmap_id;
}
-/* Load color with name NAME for use by face FACE on frame F.
- TARGET_INDEX must be one of LFACE_FOREGROUND_INDEX,
- LFACE_BACKGROUND_INDEX, LFACE_UNDERLINE_INDEX, LFACE_OVERLINE_INDEX,
- LFACE_STRIKE_THROUGH_INDEX, or LFACE_BOX_INDEX. Value is the
- pixel color. If color cannot be loaded, display a message, and
- return the foreground, background or underline color of F, but
- record that fact in flags of the face so that we don't try to free
- these colors. */
-
-unsigned long
-load_color (struct frame *f, struct face *face, Lisp_Object name,
- enum lface_attribute_index target_index)
+static unsigned long
+load_color2 (struct frame *f, struct face *face, Lisp_Object name,
+ enum lface_attribute_index target_index, XColor *color)
{
- XColor color;
-
eassert (STRINGP (name));
eassert (target_index == LFACE_FOREGROUND_INDEX
|| target_index == LFACE_BACKGROUND_INDEX
/* if the color map is full, defined_color will return a best match
to the values in an existing cell. */
- if (!defined_color (f, SSDATA (name), &color, 1))
+ if (!defined_color (f, SSDATA (name), color, 1))
{
add_to_log ("Unable to load color \"%s\"", name, Qnil);
{
case LFACE_FOREGROUND_INDEX:
face->foreground_defaulted_p = 1;
- color.pixel = FRAME_FOREGROUND_PIXEL (f);
+ color->pixel = FRAME_FOREGROUND_PIXEL (f);
break;
case LFACE_BACKGROUND_INDEX:
face->background_defaulted_p = 1;
- color.pixel = FRAME_BACKGROUND_PIXEL (f);
+ color->pixel = FRAME_BACKGROUND_PIXEL (f);
break;
case LFACE_UNDERLINE_INDEX:
face->underline_defaulted_p = 1;
- color.pixel = FRAME_FOREGROUND_PIXEL (f);
+ color->pixel = FRAME_FOREGROUND_PIXEL (f);
break;
case LFACE_OVERLINE_INDEX:
face->overline_color_defaulted_p = 1;
- color.pixel = FRAME_FOREGROUND_PIXEL (f);
+ color->pixel = FRAME_FOREGROUND_PIXEL (f);
break;
case LFACE_STRIKE_THROUGH_INDEX:
face->strike_through_color_defaulted_p = 1;
- color.pixel = FRAME_FOREGROUND_PIXEL (f);
+ color->pixel = FRAME_FOREGROUND_PIXEL (f);
break;
case LFACE_BOX_INDEX:
face->box_color_defaulted_p = 1;
- color.pixel = FRAME_FOREGROUND_PIXEL (f);
+ color->pixel = FRAME_FOREGROUND_PIXEL (f);
break;
default:
++ncolors_allocated;
#endif
- return color.pixel;
+ return color->pixel;
+}
+
+/* Load color with name NAME for use by face FACE on frame F.
+ TARGET_INDEX must be one of LFACE_FOREGROUND_INDEX,
+ LFACE_BACKGROUND_INDEX, LFACE_UNDERLINE_INDEX, LFACE_OVERLINE_INDEX,
+ LFACE_STRIKE_THROUGH_INDEX, or LFACE_BOX_INDEX. Value is the
+ pixel color. If color cannot be loaded, display a message, and
+ return the foreground, background or underline color of F, but
+ record that fact in flags of the face so that we don't try to free
+ these colors. */
+
+#ifndef MSDOS
+static
+#endif
+unsigned long
+load_color (struct frame *f, struct face *face, Lisp_Object name,
+ enum lface_attribute_index target_index)
+{
+ XColor color;
+ return load_color2 (f, face, name, target_index, &color);
}
#ifdef HAVE_WINDOW_SYSTEM
+#define NEAR_SAME_COLOR_THRESHOLD 30000
+
/* Load colors for face FACE which is used on frame F. Colors are
specified by slots LFACE_BACKGROUND_INDEX and LFACE_FOREGROUND_INDEX
of ATTRS. If the background color specified is not supported on F,
load_face_colors (struct frame *f, struct face *face,
Lisp_Object attrs[LFACE_VECTOR_SIZE])
{
- Lisp_Object fg, bg;
+ Lisp_Object fg, bg, dfg;
+ XColor xfg, xbg;
bg = attrs[LFACE_BACKGROUND_INDEX];
fg = attrs[LFACE_FOREGROUND_INDEX];
&& !NILP (Fbitmap_spec_p (Vface_default_stipple)))
{
x_destroy_bitmap (f, face->stipple);
- face->stipple = load_pixmap (f, Vface_default_stipple,
- &face->pixmap_w, &face->pixmap_h);
+ face->stipple = load_pixmap (f, Vface_default_stipple);
}
- face->background = load_color (f, face, bg, LFACE_BACKGROUND_INDEX);
- face->foreground = load_color (f, face, fg, LFACE_FOREGROUND_INDEX);
+ face->background = load_color2 (f, face, bg, LFACE_BACKGROUND_INDEX, &xbg);
+ face->foreground = load_color2 (f, face, fg, LFACE_FOREGROUND_INDEX, &xfg);
+
+ dfg = attrs[LFACE_DISTANT_FOREGROUND_INDEX];
+ if (!NILP (dfg) && !UNSPECIFIEDP (dfg)
+ && color_distance (&xbg, &xfg) < NEAR_SAME_COLOR_THRESHOLD)
+ {
+ if (EQ (attrs[LFACE_INVERSE_INDEX], Qt))
+ face->background = load_color (f, face, dfg, LFACE_BACKGROUND_INDEX);
+ else
+ face->foreground = load_color (f, face, dfg, LFACE_FOREGROUND_INDEX);
+ }
}
+#ifdef HAVE_X_WINDOWS
/* Free color PIXEL on frame F. */
void
-unload_color (struct frame *f, long unsigned int pixel)
+unload_color (struct frame *f, unsigned long pixel)
{
-#ifdef HAVE_X_WINDOWS
if (pixel != -1)
{
block_input ();
x_free_colors (f, &pixel, 1);
unblock_input ();
}
-#endif
}
-
/* Free colors allocated for FACE. */
static void
free_face_colors (struct frame *f, struct face *face)
{
-/* PENDING(NS): need to do something here? */
-#ifdef HAVE_X_WINDOWS
+ /* PENDING(NS): need to do something here? */
+
if (face->colors_copied_bitwise_p)
return;
}
unblock_input ();
-#endif /* HAVE_X_WINDOWS */
}
+#endif /* HAVE_X_WINDOWS */
+
#endif /* HAVE_WINDOW_SYSTEM */
(Lisp_Object family, Lisp_Object frame)
{
Lisp_Object font_spec, list, *drivers, vec;
+ struct frame *f = decode_live_frame (frame);
ptrdiff_t i, nfonts;
EMACS_INT ndrivers;
Lisp_Object result;
USE_SAFE_ALLOCA;
- if (NILP (frame))
- frame = selected_frame;
- CHECK_LIVE_FRAME (frame);
-
font_spec = Ffont_spec (0, NULL);
if (!NILP (family))
{
font_parse_family_registry (family, Qnil, font_spec);
}
- list = font_list_entities (frame, font_spec);
+ list = font_list_entities (f, font_spec);
if (NILP (list))
return Qnil;
ASET (v, 0, AREF (font, FONT_FAMILY_INDEX));
ASET (v, 1, FONT_WIDTH_SYMBOLIC (font));
point = PIXEL_TO_POINT (XINT (AREF (font, FONT_SIZE_INDEX)) * 10,
- XFRAME (frame)->resy);
+ FRAME_RES_Y (f));
ASET (v, 2, make_number (point));
ASET (v, 3, FONT_WEIGHT_SYMBOLIC (font));
ASET (v, 4, FONT_SLANT_SYMBOLIC (font));
struct frame *f;
int size, avgwidth IF_LINT (= 0);
- check_x ();
+ check_window_system (NULL);
CHECK_STRING (pattern);
if (! NILP (maximum))
if (!NILP (width))
CHECK_NUMBER (width);
- /* We can't simply call check_x_frame because this function may be
- called before any frame is created. */
+ /* We can't simply call decode_window_system_frame because
+ this function may be called before any frame is created. */
f = decode_live_frame (frame);
if (! FRAME_WINDOW_P (f))
{
#define LFACE_FONT(LFACE) AREF ((LFACE), LFACE_FONT_INDEX)
#define LFACE_INHERIT(LFACE) AREF ((LFACE), LFACE_INHERIT_INDEX)
#define LFACE_FONTSET(LFACE) AREF ((LFACE), LFACE_FONTSET_INDEX)
+#define LFACE_DISTANT_FOREGROUND(LFACE) \
+ AREF ((LFACE), LFACE_DISTANT_FOREGROUND_INDEX)
/* Non-zero if LFACE is a Lisp face. A Lisp face is a vector of size
LFACE_VECTOR_SIZE which has the symbol `face' in slot 0. */
eassert (UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_FOREGROUND_INDEX])
|| STRINGP (attrs[LFACE_FOREGROUND_INDEX]));
+ eassert (UNSPECIFIEDP (attrs[LFACE_DISTANT_FOREGROUND_INDEX])
+ || IGNORE_DEFFACE_P (attrs[LFACE_DISTANT_FOREGROUND_INDEX])
+ || STRINGP (attrs[LFACE_DISTANT_FOREGROUND_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_BACKGROUND_INDEX])
|| STRINGP (attrs[LFACE_BACKGROUND_INDEX]));
int i;
for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
- if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX)
+ if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX
+ && i != LFACE_DISTANT_FOREGROUND_INDEX)
if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i])))
break;
if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
{
- int pt = PIXEL_TO_POINT (font->pixel_size * 10, f->resy);
+ int pt = PIXEL_TO_POINT (font->pixel_size * 10, FRAME_RES_Y (f));
eassert (pt > 0);
ASET (lface, LFACE_HEIGHT_INDEX, make_number (pt));
else
err = 1;
}
+ else if (EQ (keyword, QCdistant_foreground))
+ {
+ if (STRINGP (value))
+ to[LFACE_DISTANT_FOREGROUND_INDEX] = value;
+ else
+ err = 1;
+ }
else if (EQ (keyword, QCbackground))
{
if (STRINGP (value))
if (NILP (Fget (face, Qface_no_inherit)))
{
++face_change_count;
- ++windows_or_buffers_changed;
+ windows_or_buffers_changed = 54;
}
eassert (LFACEP (lface));
if (NILP (Fget (to, Qface_no_inherit)))
{
++face_change_count;
- ++windows_or_buffers_changed;
+ windows_or_buffers_changed = 55;
}
return to;
}
else if (EQ (attr, QCunderline))
{
- int valid_p = 0;
+ bool valid_p = 0;
if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
valid_p = 1;
}
else if (EQ (attr, QCbox))
{
- int valid_p;
+ bool valid_p;
/* Allow t meaning a simple box of width 1 in foreground color
of the face. */
old_value = LFACE_FOREGROUND (lface);
ASET (lface, LFACE_FOREGROUND_INDEX, value);
}
+ else if (EQ (attr, QCdistant_foreground))
+ {
+ /* 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
+ on the frame (display) whether the color will be valid
+ when the face is realized. */
+ CHECK_STRING (value);
+ if (SCHARS (value) == 0)
+ signal_error ("Empty distant-foreground color value", value);
+ }
+ old_value = LFACE_DISTANT_FOREGROUND (lface);
+ ASET (lface, LFACE_DISTANT_FOREGROUND_INDEX, value);
+ }
else if (EQ (attr, QCbackground))
{
/* Compatibility with 20.x. */
{
if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
{
- FRAME_PTR f;
+ struct frame *f;
old_value = LFACE_FONT (lface);
if (! FONTP (value))
&& NILP (Fequal (old_value, value)))
{
++face_change_count;
- ++windows_or_buffers_changed;
+ windows_or_buffers_changed = 56;
}
if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
{
#ifdef HAVE_WINDOW_SYSTEM
/* Changed font-related attributes of the `default' face are
- reflected in changed `font' frame parameters. */
+ reflected in changed `font' frame parameters. */
if (FRAMEP (frame)
&& (prop_index || EQ (attr, QCfont))
&& lface_fully_specified_p (XVECTOR (lface)->contents))
#endif /* HAVE_WINDOW_SYSTEM */
else if (EQ (face, Qmenu))
{
- /* Indicate that we have to update the menu bar when
- realizing faces on FRAME. FRAME t change the
- default for new frames. We do this by setting
- setting the flag in new face caches */
+ /* Indicate that we have to update the menu bar when realizing
+ faces on FRAME. FRAME t change the default for new frames.
+ We do this by setting the flag in new face caches. */
if (FRAMEP (frame))
{
struct frame *f = XFRAME (frame);
&& NILP (Fget (face, Qface_no_inherit)))
{
++face_change_count;
- ++windows_or_buffers_changed;
+ windows_or_buffers_changed = 57;
}
}
ASET (lface, LFACE_FONT_INDEX, font);
}
f->default_face_done_p = 0;
- Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, font), Qnil));
+ Fmodify_frame_parameters (frame, list1 (Fcons (Qfont, font)));
}
}
-
-/* Get the value of X resource RESOURCE, class CLASS for the display
- of frame FRAME. This is here because ordinary `x-get-resource'
- doesn't take a frame argument. */
-
DEFUN ("internal-face-x-get-resource", Finternal_face_x_get_resource,
- Sinternal_face_x_get_resource, 3, 3, 0, doc: /* */)
+ Sinternal_face_x_get_resource, 2, 3, 0,
+ doc: /* Get the value of X resource RESOURCE, class CLASS.
+Returned value is for the display of frame FRAME. If FRAME is not
+specified or nil, use selected frame. This function exists because
+ordinary `x-get-resource' doesn't take a frame argument. */)
(Lisp_Object resource, Lisp_Object class, Lisp_Object frame)
{
Lisp_Object value = Qnil;
+ struct frame *f;
+
CHECK_STRING (resource);
CHECK_STRING (class);
- CHECK_LIVE_FRAME (frame);
+ f = decode_live_frame (frame);
block_input ();
- value = display_x_get_resource (FRAME_X_DISPLAY_INFO (XFRAME (frame)),
+ value = display_x_get_resource (FRAME_DISPLAY_INFO (f),
resource, class, Qnil, Qnil);
unblock_input ();
return value;
static void
x_update_menu_appearance (struct frame *f)
{
- struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
XrmDatabase rdb;
if (dpyinfo
Lisp_Object lface = lface_from_face_name (f, Qmenu, 1);
struct face *face = FACE_FROM_ID (f, MENU_FACE_ID);
const char *myname = SSDATA (Vx_resource_name);
- int changed_p = 0;
+ bool changed_p = 0;
#ifdef USE_MOTIF
const char *popup_path = "popup_menu";
#else
value = LFACE_INVERSE (lface);
else if (EQ (keyword, QCforeground))
value = LFACE_FOREGROUND (lface);
+ else if (EQ (keyword, QCdistant_foreground))
+ value = LFACE_DISTANT_FOREGROUND (lface);
else if (EQ (keyword, QCbackground))
value = LFACE_BACKGROUND (lface);
else if (EQ (keyword, QCstipple))
CHECK_SYMBOL (attr);
- if (EQ (attr, QCunderline))
- result = Fcons (Qt, Fcons (Qnil, Qnil));
- else if (EQ (attr, QCoverline))
- result = Fcons (Qt, Fcons (Qnil, Qnil));
- else if (EQ (attr, QCstrike_through))
- result = Fcons (Qt, Fcons (Qnil, Qnil));
- else if (EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video))
- result = Fcons (Qt, Fcons (Qnil, Qnil));
+ if (EQ (attr, QCunderline) || EQ (attr, QCoverline)
+ || EQ (attr, QCstrike_through)
+ || EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video))
+ result = list2 (Qt, Qnil);
return result;
}
&& newface->font)
{
Lisp_Object name = newface->font->props[FONT_NAME_INDEX];
- Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, name),
- Qnil));
+ Fmodify_frame_parameters (frame, list1 (Fcons (Qfont, name)));
}
if (STRINGP (gvec[LFACE_FOREGROUND_INDEX]))
Fmodify_frame_parameters (frame,
- Fcons (Fcons (Qforeground_color,
- gvec[LFACE_FOREGROUND_INDEX]),
- Qnil));
+ list1 (Fcons (Qforeground_color,
+ gvec[LFACE_FOREGROUND_INDEX])));
if (STRINGP (gvec[LFACE_BACKGROUND_INDEX]))
Fmodify_frame_parameters (frame,
- Fcons (Fcons (Qbackground_color,
- gvec[LFACE_BACKGROUND_INDEX]),
- Qnil));
+ list1 (Fcons (Qbackground_color,
+ gvec[LFACE_BACKGROUND_INDEX])));
}
}
all attributes are `equal'. Tries to be fast because this function
is called quite often. */
-static int
+static bool
face_attr_equal_p (Lisp_Object v1, Lisp_Object v2)
{
/* Type can differ, e.g. when one attribute is unspecified, i.e. nil,
all attributes are `equal'. Tries to be fast because this function
is called quite often. */
-static int
+static bool
lface_equal_p (Lisp_Object *v1, Lisp_Object *v2)
{
- int i, equal_p = 1;
+ int i;
+ bool equal_p = 1;
for (i = 1; i < LFACE_VECTOR_SIZE && equal_p; ++i)
equal_p = face_attr_equal_p (v1[i], v2[i]);
struct frame *f;
Lisp_Object lface1, lface2;
- /* Don't use check_x_frame here because this function is called
- before X frames exist. At that time, if FRAME is nil,
+ /* Don't use decode_window_system_frame here because this function
+ is called before X frames exist. At that time, if FRAME is nil,
selected_frame will be used which is the frame dumped with
Emacs. That frame is not an X frame. */
f = EQ (frame, Qt) ? NULL : decode_live_frame (frame);
^ XHASH (v[LFACE_HEIGHT_INDEX]));
}
+#ifdef HAVE_WINDOW_SYSTEM
/* Return non-zero if LFACE1 and LFACE2 specify the same font (without
considering charsets/registries). They do if they specify the same
);
}
+#endif /* HAVE_WINDOW_SYSTEM */
-\f
/***********************************************************************
Realized Faces
***********************************************************************/
static struct face *
make_realized_face (Lisp_Object *attr)
{
- struct face *face = xzalloc (sizeof *face);
- face->ascii_face = face;
+ enum { off = offsetof (struct face, id) };
+ struct face *face = xmalloc (sizeof *face);
+
memcpy (face->lface, attr, sizeof face->lface);
+ memset (&face->id, 0, sizeof *face - off);
+ face->ascii_face = face;
+
return face;
}
face->gc = 0;
unblock_input ();
}
-
+#ifdef HAVE_X_WINDOWS
free_face_colors (f, face);
+#endif /* HAVE_X_WINDOWS */
x_destroy_bitmap (f, face->stipple);
}
#endif /* HAVE_WINDOW_SYSTEM */
static struct face_cache *
make_face_cache (struct frame *f)
{
- struct face_cache *c;
- int size;
+ struct face_cache *c = xmalloc (sizeof *c);
- c = xzalloc (sizeof *c);
- size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
- c->buckets = xzalloc (size);
+ c->buckets = xzalloc (FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets);
c->size = 50;
+ c->used = 0;
c->faces_by_id = xmalloc (c->size * sizeof *c->faces_by_id);
c->f = f;
c->menu_face_changed_p = menu_face_changed_default;
return c;
}
+#ifdef HAVE_WINDOW_SYSTEM
/* Clear out all graphics contexts for all realized faces, except for
the basic faces. This should be done from time to time just to avoid
{
if (c && FRAME_WINDOW_P (c->f))
{
-#ifdef HAVE_WINDOW_SYSTEM
int i;
for (i = BASIC_FACE_ID_SENTINEL; i < c->used; ++i)
{
unblock_input ();
}
}
-#endif /* HAVE_WINDOW_SYSTEM */
}
}
+#endif /* HAVE_WINDOW_SYSTEM */
/* Free all realized faces in face cache C, including basic faces.
C may be null. If faces are freed, make sure the frame's current
if (WINDOWP (f->root_window))
{
clear_current_matrices (f);
- ++windows_or_buffers_changed;
+ windows_or_buffers_changed = 58;
}
unblock_input ();
#ifdef HAVE_WINDOW_SYSTEM
-/* Return non-zero if all the face attributes in ATTRS are supported
+/* Return true if all the face attributes in ATTRS are supported
on the window-system frame F.
The definition of `supported' is somewhat heuristic, but basically means
\(1) different in appearance than the default face, and
\(2) `close in spirit' to what the attributes specify, if not exact. */
-static int
+static bool
x_supports_face_attributes_p (struct frame *f,
Lisp_Object attrs[LFACE_VECTOR_SIZE],
struct face *def_face)
|| (!UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
&& face_attr_equal_p (attrs[LFACE_FOREGROUND_INDEX],
def_attrs[LFACE_FOREGROUND_INDEX]))
+ || (!UNSPECIFIEDP (attrs[LFACE_DISTANT_FOREGROUND_INDEX])
+ && face_attr_equal_p (attrs[LFACE_DISTANT_FOREGROUND_INDEX],
+ def_attrs[LFACE_DISTANT_FOREGROUND_INDEX]))
|| (!UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
&& face_attr_equal_p (attrs[LFACE_BACKGROUND_INDEX],
def_attrs[LFACE_BACKGROUND_INDEX]))
#endif /* HAVE_WINDOW_SYSTEM */
-/* Return non-zero if all the face attributes in ATTRS are supported
+/* Return true if all the face attributes in ATTRS are supported
on the tty frame F.
The definition of `supported' is somewhat heuristic, but basically means
will _not_ be satisfied by the tty display code's automatic
substitution of a `dim' face for italic. */
-static int
+static bool
tty_supports_face_attributes_p (struct frame *f,
Lisp_Object attrs[LFACE_VECTOR_SIZE],
struct face *def_face)
/* Color testing. */
- /* Default the color indices in FG_TTY_COLOR and BG_TTY_COLOR, since
- we use them when calling `tty_capable_p' below, even if the face
- specifies no colors. */
- fg_tty_color.pixel = FACE_TTY_DEFAULT_FG_COLOR;
- bg_tty_color.pixel = FACE_TTY_DEFAULT_BG_COLOR;
-
/* Check if foreground color is close enough. */
fg = attrs[LFACE_FOREGROUND_INDEX];
if (STRINGP (fg))
/* See if the capabilities we selected above are supported, with the
given colors. */
- if (test_caps != 0 &&
- ! tty_capable_p (FRAME_TTY (f), test_caps, fg_tty_color.pixel,
- bg_tty_color.pixel))
- return 0;
-
-
- /* Hmmm, everything checks out, this terminal must support this face. */
- return 1;
+ return tty_capable_p (FRAME_TTY (f), test_caps);
}
face for italic. */)
(Lisp_Object attributes, Lisp_Object display)
{
- int supports = 0, i;
+ bool supports = 0;
+ int i;
Lisp_Object frame;
struct frame *f;
struct face *def_face;
of F don't contain enough information needed to realize the default
face. */
-static int
+static bool
realize_basic_faces (struct frame *f)
{
- int success_p = 0;
+ bool success_p = 0;
ptrdiff_t count = SPECPDL_INDEX ();
/* Block input here so that we won't be surprised by an X expose
realize_named_face (f, Qmouse, MOUSE_FACE_ID);
realize_named_face (f, Qmenu, MENU_FACE_ID);
realize_named_face (f, Qvertical_border, VERTICAL_BORDER_FACE_ID);
+ realize_named_face (f, Qwindow_divider, WINDOW_DIVIDER_FACE_ID);
+ realize_named_face (f, Qwindow_divider_first_pixel,
+ WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
+ realize_named_face (f, Qwindow_divider_last_pixel,
+ WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
/* Reflect changes in the `menu' face in menu bars. */
if (FRAME_FACE_CACHE (f)->menu_face_changed_p)
specified, make it fully-specified. Attributes of the default face
that are not explicitly specified are taken from frame parameters. */
-static int
+static bool
realize_default_face (struct frame *f)
{
struct face_cache *c = FRAME_FACE_CACHE (f);
stipple = attrs[LFACE_STIPPLE_INDEX];
if (!NILP (stipple))
- face->stipple = load_pixmap (f, stipple, &face->pixmap_w, &face->pixmap_h);
+ face->stipple = load_pixmap (f, stipple);
#endif /* HAVE_WINDOW_SYSTEM */
return face;
int
face_at_buffer_position (struct window *w, ptrdiff_t pos,
- ptrdiff_t region_beg, ptrdiff_t region_end,
ptrdiff_t *endptr, ptrdiff_t limit,
int mouse, int base_face_id)
{
/* W must display the current buffer. We could write this function
to use the frame and buffer of W, but right now it doesn't. */
- /* eassert (XBUFFER (w->buffer) == current_buffer); */
+ /* eassert (XBUFFER (w->contents) == current_buffer); */
XSETFASTINT (position, pos);
endpos = ZV;
- if (pos < region_beg && region_beg < endpos)
- endpos = region_beg;
/* Get the `face' or `mouse_face' text property at POS, and
determine the next position at which the property changes. */
- prop = Fget_text_property (position, propname, w->buffer);
+ prop = Fget_text_property (position, propname, w->contents);
XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
- end = Fnext_single_property_change (position, propname, w->buffer, limit1);
+ end = Fnext_single_property_change (position, propname, w->contents, limit1);
if (INTEGERP (end))
endpos = XINT (end);
/* Optimize common cases where we can use the default face. */
if (noverlays == 0
- && NILP (prop)
- && !(pos >= region_beg && pos < region_end))
+ && NILP (prop))
return default_face->id;
/* Begin with attributes from the default face. */
endpos = oendpos;
}
- /* If in the region, merge in the region face. */
- if (pos >= region_beg && pos < region_end)
- {
- merge_named_face (f, Qregion, attrs, 0);
-
- if (region_end < endpos)
- endpos = region_end;
- }
-
*endptr = endpos;
/* Look up a realized face with the given face attributes,
int
face_for_overlay_string (struct window *w, ptrdiff_t pos,
- ptrdiff_t region_beg, ptrdiff_t region_end,
ptrdiff_t *endptr, ptrdiff_t limit,
int mouse, Lisp_Object overlay)
{
/* W must display the current buffer. We could write this function
to use the frame and buffer of W, but right now it doesn't. */
- /* eassert (XBUFFER (w->buffer) == current_buffer); */
+ /* eassert (XBUFFER (w->contents) == current_buffer); */
XSETFASTINT (position, pos);
endpos = ZV;
- if (pos < region_beg && region_beg < endpos)
- endpos = region_beg;
/* Get the `face' or `mouse_face' text property at POS, and
determine the next position at which the property changes. */
- prop = Fget_text_property (position, propname, w->buffer);
+ prop = Fget_text_property (position, propname, w->contents);
XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
- end = Fnext_single_property_change (position, propname, w->buffer, limit1);
+ end = Fnext_single_property_change (position, propname, w->contents, limit1);
if (INTEGERP (end))
endpos = XINT (end);
/* Optimize common case where we can use the default face. */
if (NILP (prop)
- && !(pos >= region_beg && pos < region_end)
&& NILP (Vface_remapping_alist))
return DEFAULT_FACE_ID;
if (!NILP (prop))
merge_face_ref (f, prop, attrs, 1, 0);
- /* If in the region, merge in the region face. */
- if (pos >= region_beg && pos < region_end)
- {
- merge_named_face (f, Qregion, attrs, 0);
-
- if (region_end < endpos)
- endpos = region_end;
- }
-
*endptr = endpos;
/* Look up a realized face with the given face attributes,
int
face_at_string_position (struct window *w, Lisp_Object string,
ptrdiff_t pos, ptrdiff_t bufpos,
- ptrdiff_t region_beg, ptrdiff_t region_end,
ptrdiff_t *endptr, enum face_id base_face_id,
int mouse_p)
{
base_face = FACE_FROM_ID (f, base_face_id);
eassert (base_face);
- /* Optimize the default case that there is no face property and we
- are not in the region. */
+ /* Optimize the default case that there is no face property. */
if (NILP (prop)
- && (base_face_id != DEFAULT_FACE_ID
- /* BUFPOS <= 0 means STRING is not an overlay string, so
- that the region doesn't have to be taken into account. */
- || bufpos <= 0
- || bufpos < region_beg
- || bufpos >= region_end)
&& (multibyte_p
/* We can't realize faces for different charsets differently
if we don't have fonts, so we can stop here if not working
if (!NILP (prop))
merge_face_ref (f, prop, attrs, 1, 0);
- /* If in the region, merge in the region face. */
- if (bufpos
- && bufpos >= region_beg
- && bufpos < region_end)
- merge_named_face (f, Qregion, attrs, 0);
-
/* Look up a realized face with the given face attributes,
or realize a new one for ASCII characters. */
return lookup_face (f, attrs);
CHECK_STRING (filename);
abspath = Fexpand_file_name (filename, Qnil);
- fp = fopen (SSDATA (abspath), "rt");
+ block_input ();
+ fp = emacs_fopen (SSDATA (abspath), "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 (num >= 0 && name[num] == '\n')
- name[num] = 0;
- cmap = Fcons (Fcons (build_string (name),
#ifdef HAVE_NTGUI
- make_number (RGB (red, green, blue))),
+ int color = RGB (red, green, blue);
#else
- make_number ((red << 16) | (green << 8) | blue)),
+ int color = (red << 16) | (green << 8) | blue;
#endif
+ char *name = buf + num;
+ ptrdiff_t len = strlen (name);
+ len -= 0 < len && name[len - 1] == '\n';
+ cmap = Fcons (Fcons (make_string (name, len), make_number (color)),
cmap);
}
}
fclose (fp);
-
- unblock_input ();
}
-
+ unblock_input ();
return cmap;
}
#endif
DEFSYM (QCwidth, ":width");
DEFSYM (QCfont, ":font");
DEFSYM (QCfontset, ":fontset");
+ DEFSYM (QCdistant_foreground, ":distant-foreground");
DEFSYM (QCbold, ":bold");
DEFSYM (QCitalic, ":italic");
DEFSYM (QCoverline, ":overline");
DEFSYM (Qmouse, "mouse");
DEFSYM (Qmode_line_inactive, "mode-line-inactive");
DEFSYM (Qvertical_border, "vertical-border");
+ DEFSYM (Qwindow_divider, "window-divider");
+ DEFSYM (Qwindow_divider_first_pixel, "window-divider-first-pixel");
+ DEFSYM (Qwindow_divider_last_pixel, "window-divider-last-pixel");
DEFSYM (Qtty_color_desc, "tty-color-desc");
DEFSYM (Qtty_color_standard_values, "tty-color-standard-values");
DEFSYM (Qtty_color_by_index, "tty-color-by-index");
DEFSYM (Qtty_color_alist, "tty-color-alist");
DEFSYM (Qscalable_fonts_allowed, "scalable-fonts-allowed");
- Vparam_value_alist = Fcons (Fcons (Qnil, Qnil), Qnil);
+ Vparam_value_alist = list1 (Fcons (Qnil, Qnil));
staticpro (&Vparam_value_alist);
Vface_alternative_font_family_alist = Qnil;
staticpro (&Vface_alternative_font_family_alist);