X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/78b29cb3a21f6a4230ebf52edccde7c926a8c69a..c5f80d9d13d6033e5ee75d65bb5383d4d75dc427:/src/xfaces.c diff --git a/src/xfaces.c b/src/xfaces.c index 505e601c57..5137ab7e72 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -388,6 +388,10 @@ Lisp_Object Qforeground_color, Qbackground_color; Lisp_Object Qface; extern Lisp_Object Qmouse_face; +/* Property for basic faces which other faces cannot inherit. */ + +Lisp_Object Qface_no_inherit; + /* Error symbol for wrong_type_argument in load_pixmap. */ Lisp_Object Qbitmap_spec_p; @@ -1547,6 +1551,7 @@ DEFUN ("color-supported-p", Fcolor_supported_p, Scolor_supported_p, 1, 3, 0, doc: /* Return non-nil if COLOR can be displayed on FRAME. BACKGROUND-P non-nil means COLOR is used as a background. +Otherwise, this function tells whether it can be used as a foreground. If FRAME is nil or omitted, use the selected frame. COLOR must be a valid color name. */) (color, frame, background_p) @@ -3628,7 +3633,10 @@ merge_face_ref (f, face_ref, to, err_msgs, named_merge_points) Lisp_Object value = XCAR (XCDR (face_ref)); int err = 0; - if (EQ (keyword, QCfamily)) + /* Specifying `unspecified' is a no-op. */ + if (EQ (value, Qunspecified)) + ; + else if (EQ (keyword, QCfamily)) { if (STRINGP (value)) to[LFACE_FAMILY_INDEX] = value; @@ -3864,8 +3872,11 @@ Value is a vector of face attributes. */) depend on the face, make sure they are all removed. This is done by incrementing face_change_count. The next call to init_iterator will then free realized faces. */ - ++face_change_count; - ++windows_or_buffers_changed; + if (NILP (Fget (face, Qface_no_inherit))) + { + ++face_change_count; + ++windows_or_buffers_changed; + } xassert (LFACEP (lface)); check_lface (lface); @@ -3899,12 +3910,13 @@ Otherwise check for the existence of a global face. */) DEFUN ("internal-copy-lisp-face", Finternal_copy_lisp_face, Sinternal_copy_lisp_face, 4, 4, 0, doc: /* Copy face FROM to TO. -If FRAME is t, copy the global face definition of FROM to the -global face definition of TO. Otherwise, copy the frame-local -definition of FROM on FRAME to the frame-local definition of TO -on NEW-FRAME, or FRAME if NEW-FRAME is nil. +If FRAME is t, copy the global face definition of FROM. +Otherwise, copy the frame-local definition of FROM on FRAME. +If NEW-FRAME is a frame, copy that data into the frame-local +definition of TO on NEW-FRAME. If NEW-FRAME is nil. +FRAME controls where the data is copied to. -Value is TO. */) +The value is TO. */) (from, to, frame, new_frame) Lisp_Object from, to, frame, new_frame; { @@ -3912,8 +3924,6 @@ Value is TO. */) CHECK_SYMBOL (from); CHECK_SYMBOL (to); - if (NILP (new_frame)) - new_frame = frame; if (EQ (frame, Qt)) { @@ -3925,6 +3935,8 @@ Value is TO. */) else { /* Copy frame-local definition of FROM. */ + if (NILP (new_frame)) + new_frame = frame; CHECK_LIVE_FRAME (frame); CHECK_LIVE_FRAME (new_frame); lface = lface_from_face_name (XFRAME (frame), from, 1); @@ -3939,8 +3951,11 @@ Value is TO. */) depend on the face, make sure they are all removed. This is done by incrementing face_change_count. The next call to init_iterator will then free realized faces. */ - ++face_change_count; - ++windows_or_buffers_changed; + if (NILP (Fget (to, Qface_no_inherit))) + { + ++face_change_count; + ++windows_or_buffers_changed; + } return to; } @@ -4297,6 +4312,7 @@ FRAME 0 means change the face on all frames, and change the default by incrementing face_change_count. The next call to init_iterator will then free realized faces. */ if (!EQ (frame, Qt) + && NILP (Fget (face, Qface_no_inherit)) && (EQ (attr, QCfont) || NILP (Fequal (old_value, value)))) { @@ -4449,6 +4465,7 @@ update_face_from_frame_parameter (f, param, new_value) struct frame *f; Lisp_Object param, new_value; { + Lisp_Object face = Qnil; Lisp_Object lface; /* If there are no faces yet, give up. This is the case when called @@ -4457,17 +4474,10 @@ update_face_from_frame_parameter (f, param, new_value) if (NILP (f->face_alist)) return; - /* Changing a named face means that all realized faces depending on - that face are invalid. Since we cannot tell which realized faces - depend on the face, make sure they are all removed. This is done - by incrementing face_change_count. The next call to - init_iterator will then free realized faces. */ - ++face_change_count; - ++windows_or_buffers_changed; - if (EQ (param, Qforeground_color)) { - lface = lface_from_face_name (f, Qdefault, 1); + face = Qdefault; + lface = lface_from_face_name (f, face, 1); LFACE_FOREGROUND (lface) = (STRINGP (new_value) ? new_value : Qunspecified); realize_basic_faces (f); @@ -4482,29 +4492,45 @@ update_face_from_frame_parameter (f, param, new_value) XSETFRAME (frame, f); call1 (Qframe_update_face_colors, frame); - lface = lface_from_face_name (f, Qdefault, 1); + face = Qdefault; + lface = lface_from_face_name (f, face, 1); LFACE_BACKGROUND (lface) = (STRINGP (new_value) ? new_value : Qunspecified); realize_basic_faces (f); } - if (EQ (param, Qborder_color)) + else if (EQ (param, Qborder_color)) { - lface = lface_from_face_name (f, Qborder, 1); + face = Qborder; + lface = lface_from_face_name (f, face, 1); LFACE_BACKGROUND (lface) = (STRINGP (new_value) ? new_value : Qunspecified); } else if (EQ (param, Qcursor_color)) { - lface = lface_from_face_name (f, Qcursor, 1); + face = Qcursor; + lface = lface_from_face_name (f, face, 1); LFACE_BACKGROUND (lface) = (STRINGP (new_value) ? new_value : Qunspecified); } else if (EQ (param, Qmouse_color)) { - lface = lface_from_face_name (f, Qmouse, 1); + face = Qmouse; + lface = lface_from_face_name (f, face, 1); LFACE_BACKGROUND (lface) = (STRINGP (new_value) ? new_value : Qunspecified); } + + /* Changing a named face means that all realized faces depending on + that face are invalid. Since we cannot tell which realized faces + depend on the face, make sure they are all removed. This is done + by incrementing face_change_count. The next call to + init_iterator will then free realized faces. */ + if (!NILP (face) + && NILP (Fget (face, Qface_no_inherit))) + { + ++face_change_count; + ++windows_or_buffers_changed; + } } @@ -4915,6 +4941,7 @@ If FRAME is omitted or nil, use the selected frame. */) static INLINE int face_attr_equal_p (v1, v2) + Lisp_Object v1, v2; { /* Type can differ, e.g. when one attribute is unspecified, i.e. nil, and the other is specified. */ @@ -5849,7 +5876,7 @@ x_supports_face_attributes_p (f, attrs, def_face) face = FACE_FROM_ID (f, lookup_face (f, merged_attrs, 0, 0)); if (! face) - signal_error ("cannot make face", 0); + error ("cannot make face"); /* If the font is the same, then not supported. */ if (face->font == def_face->font) @@ -5884,7 +5911,7 @@ tty_supports_face_attributes_p (f, attrs, def_face) Lisp_Object *attrs; struct face *def_face; { - int weight, i; + int weight; Lisp_Object val, fg, bg; XColor fg_tty_color, fg_std_color; XColor bg_tty_color, bg_std_color; @@ -6106,7 +6133,7 @@ face for italic. */) if (def_face == NULL) { if (! realize_basic_faces (f)) - signal_error ("Cannot realize default face", 0); + error ("Cannot realize default face"); def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); } @@ -7761,6 +7788,8 @@ syms_of_xfaces () { Qface = intern ("face"); staticpro (&Qface); + Qface_no_inherit = intern ("face-no-inherit"); + staticpro (&Qface_no_inherit); Qbitmap_spec_p = intern ("bitmap-spec-p"); staticpro (&Qbitmap_spec_p); Qframe_update_face_colors = intern ("frame-update-face-colors");