2 Copyright (C) 1993, 1994 Free Software Foundation.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* This is derived from work by Lucid (some parts very loosely so). */
23 #include <sys/types.h>
41 #include "dispextern.h"
43 #include "blockinput.h"
45 #include "intervals.h"
48 /* Compensate for bug in Xos.h on some systems, on which it requires
49 time.h. On some such systems, Xos.h tries to redefine struct
50 timeval and struct timezone if USG is #defined while it is
52 #ifdef XOS_NEEDS_TIME_H
65 #endif /* HAVE_X_WINDOWS */
67 /* An explanation of the face data structures. */
69 /* ========================= Face Data Structures =========================
71 Let FACE-NAME be a symbol naming a face.
73 Let FACE-VECTOR be (assq FACE-NAME (frame-face-alist FRAME))
74 FACE-VECTOR is either nil, or a vector of the form
75 [face NAME ID FONT FOREGROUND BACKGROUND BACKGROUND-PIXMAP UNDERLINE-P]
77 face is the symbol `face',
78 NAME is the symbol with which this vector is associated (a backpointer),
79 ID is the face ID, an integer used internally by the C code to identify
81 FONT, FOREGROUND, and BACKGROUND are strings naming the fonts and colors
82 to use with the face, FONT may name fontsets,
83 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't
85 UNDERLINE-P is non-nil if the face should be underlined.
86 If any of these elements are nil, that parameter is considered
87 unspecified; parameters from faces specified by lower-priority
88 overlays or text properties, or the parameters of the frame itself,
89 can show through. (lisp/faces.el maintains these lists.)
91 (assq FACE-NAME global-face-data) returns a vector describing the
92 global parameters for that face.
94 Let PARAM-FACE be FRAME->output_data.x->param_faces[Faref (FACE-VECTOR, 2)].
95 PARAM_FACE is a struct face whose members are the Xlib analogues of
96 the parameters in FACE-VECTOR. If an element of FACE-VECTOR is
97 nil, then the corresponding member of PARAM_FACE is FACE_DEFAULT.
98 These faces are called "parameter faces", because they're the ones
99 lisp manipulates to control what gets displayed. Elements 0 and 1
100 of FRAME->output_data.x->param_faces are special - they describe the
101 default and mode line faces. None of the faces in param_faces have
102 GC's. (See src/dispextern.h for the definition of struct face.
103 lisp/faces.el maintains the isomorphism between face_alist and
106 The functions compute_char_face and compute_glyph_face find and
107 combine the parameter faces associated with overlays and text
108 properties. The resulting faces are called "computed faces"; none
109 of their members are FACE_DEFAULT; they are completely specified.
110 They then call intern_compute_face to search
111 FRAME->output_data.x->computed_faces for a matching face, add one if
112 none is found, and return the index into
113 FRAME->output_data.x->computed_faces. FRAME's glyph matrices use these
114 indices to record the faces of the matrix characters, and the X
115 display hooks consult compute_faces to decide how to display these
116 characters. Elements 0 and 1 of computed_faces always describe the
117 default and mode-line faces.
119 Each computed face belongs to a particular frame.
121 Computed faces have graphics contexts some of the time.
122 intern_face builds a GC for a specified computed face
123 if it doesn't have one already.
124 clear_face_cache clears out the GCs of all computed faces.
125 This is done from time to time so that we don't hold on to
126 lots of GCs that are no longer needed.
128 If a computed face has 0 as its font,
129 it is unused, and can be reused by new_computed_face.
133 Symbols naming faces must have associations on all frames; for any
134 FRAME, for all FACE-NAME, if (assq FACE-NAME (frame-face-alist
135 FRAME)) is non-nil, it must be non-nil for all frames.
137 Analogously, indices into param_faces must be valid on all frames;
138 if param_faces[i] is a non-zero face pointer on one frame, then it
139 must be filled in on all frames. Code assumes that face ID's can
140 be used on any frame.
144 Why do we keep param_faces and computed_faces separate?
145 computed_faces contains an element for every combination of facial
146 parameters we have ever displayed. indices into param_faces have
147 to be valid on all frames. If they were the same array, then that
148 array would grow very large on all frames, because any facial
149 combination displayed on any frame would need to be a valid entry
152 /* Definitions and declarations. */
154 /* The number of face-id's in use (same for all frames). */
155 static int next_face_id
;
157 /* The number of the face to use to indicate the region. */
158 static int region_face
;
160 /* This is what appears in a slot in a face to signify that the face
161 does not specify that display aspect. */
162 #define FACE_DEFAULT (~0)
164 Lisp_Object Qface
, Qmouse_face
;
165 Lisp_Object Qpixmap_spec_p
;
167 int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ );
169 struct face
*intern_face ( /* FRAME_PTR, struct face * */ );
170 static int new_computed_face ( /* FRAME_PTR, struct face * */ );
171 static int intern_computed_face ( /* FRAME_PTR, struct face * */ );
172 static void ensure_face_ready ( /* FRAME_PTR, int id */ );
173 void recompute_basic_faces ( /* FRAME_PTR f */ );
175 /* Allocating, copying, and comparing struct faces. */
177 /* Allocate a new face */
181 struct face
*result
= (struct face
*) xmalloc (sizeof (struct face
));
182 bzero (result
, sizeof (struct face
));
183 result
->font
= (XFontStruct
*) FACE_DEFAULT
;
184 result
->fontset
= -1;
185 result
->foreground
= FACE_DEFAULT
;
186 result
->background
= FACE_DEFAULT
;
187 result
->stipple
= FACE_DEFAULT
;
191 /* Make a new face that's a copy of an existing one. */
196 struct face
*result
= allocate_face ();
198 result
->font
= face
->font
;
199 result
->fontset
= face
->fontset
;
200 result
->foreground
= face
->foreground
;
201 result
->background
= face
->background
;
202 result
->stipple
= face
->stipple
;
203 result
->underline
= face
->underline
;
204 result
->pixmap_h
= face
->pixmap_h
;
205 result
->pixmap_w
= face
->pixmap_w
;
211 face_eql (face1
, face2
)
212 struct face
*face1
, *face2
;
214 return ( face1
->font
== face2
->font
215 && face1
->fontset
== face2
->fontset
216 && face1
->foreground
== face2
->foreground
217 && face1
->background
== face2
->background
218 && face1
->stipple
== face2
->stipple
219 && face1
->underline
== face2
->underline
);
222 /* Managing graphics contexts of faces. */
224 #ifdef HAVE_X_WINDOWS
225 /* Given a computed face, construct its graphics context if necessary. */
228 intern_face (f
, face
)
241 if (face
->foreground
!= FACE_DEFAULT
)
242 xgcv
.foreground
= face
->foreground
;
244 xgcv
.foreground
= f
->output_data
.x
->foreground_pixel
;
246 if (face
->background
!= FACE_DEFAULT
)
247 xgcv
.background
= face
->background
;
249 xgcv
.background
= f
->output_data
.x
->background_pixel
;
251 if (face
->font
&& face
->font
!= (XFontStruct
*) FACE_DEFAULT
)
252 xgcv
.font
= face
->font
->fid
;
254 xgcv
.font
= f
->output_data
.x
->font
->fid
;
256 xgcv
.graphics_exposures
= 0;
258 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
259 if (face
->stipple
&& face
->stipple
!= FACE_DEFAULT
)
261 xgcv
.fill_style
= FillStippled
;
262 xgcv
.stipple
= x_bitmap_pixmap (f
, face
->stipple
);
263 mask
|= GCFillStyle
| GCStipple
;
266 gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
270 /* We used the following GC for all non-ASCII characters by changing
271 only GCfont each time. */
272 face
->non_ascii_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
280 /* Clear out all graphics contexts for all computed faces
281 except for the default and mode line faces.
282 This should be done from time to time just to avoid
283 keeping too many graphics contexts that are no longer needed. */
288 Lisp_Object tail
, frame
;
291 FOR_EACH_FRAME (tail
, frame
)
293 FRAME_PTR f
= XFRAME (frame
);
297 Display
*dpy
= FRAME_X_DISPLAY (f
);
299 for (i
= 2; i
< FRAME_N_COMPUTED_FACES (f
); i
++)
301 struct face
*face
= FRAME_COMPUTED_FACES (f
) [i
];
304 XFreeGC (dpy
, face
->gc
);
305 XFreeGC (dpy
, face
->non_ascii_gc
);
315 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps.
317 These functions operate on param faces only.
318 Computed faces get their fonts, colors and pixmaps
319 by merging param faces. */
329 return (XFontStruct
*) FACE_DEFAULT
;
331 CHECK_STRING (name
, 0);
333 font
= XLoadQueryFont (FRAME_X_DISPLAY (f
), (char *) XSTRING (name
)->data
);
337 Fsignal (Qerror
, Fcons (build_string ("undefined font"),
338 Fcons (name
, Qnil
)));
343 unload_font (f
, font
)
347 int len
= FRAME_N_COMPUTED_FACES (f
);
350 if (!font
|| font
== ((XFontStruct
*) FACE_DEFAULT
))
354 /* Invalidate any computed faces which use this font,
355 and free their GC's if they have any. */
356 for (i
= 2; i
< len
; i
++)
358 struct face
*face
= FRAME_COMPUTED_FACES (f
)[i
];
359 if (face
->font
== font
)
361 Display
*dpy
= FRAME_X_DISPLAY (f
);
363 XFreeGC (dpy
, face
->gc
);
365 /* This marks the computed face as available to reuse. */
370 XFreeFont (FRAME_X_DISPLAY (f
), font
);
385 CHECK_STRING (name
, 0);
386 /* if the colormap is full, defined_color will return a best match
387 to the values in an an existing cell. */
388 result
= defined_color(f
, (char *) XSTRING (name
)->data
, &color
, 1);
390 Fsignal (Qerror
, Fcons (build_string ("undefined color"),
391 Fcons (name
, Qnil
)));
392 return (unsigned long) color
.pixel
;
396 unload_color (f
, pixel
)
401 Display
*dpy
= FRAME_X_DISPLAY (f
);
402 int class = FRAME_X_DISPLAY_INFO (f
)->visual
->class;
404 if (pixel
== FACE_DEFAULT
405 || pixel
== BLACK_PIX_DEFAULT (f
)
406 || pixel
== WHITE_PIX_DEFAULT (f
))
408 cmap
= DefaultColormapOfScreen (DefaultScreenOfDisplay (dpy
));
410 /* If display has an immutable color map, freeing colors is not
411 necessary and some servers don't allow it. So don't do it. */
412 if (! (class == StaticColor
|| class == StaticGray
|| class == TrueColor
))
414 int len
= FRAME_N_COMPUTED_FACES (f
);
418 /* Invalidate any computed faces which use this color,
419 and free their GC's if they have any. */
420 for (i
= 2; i
< len
; i
++)
422 struct face
*face
= FRAME_COMPUTED_FACES (f
)[i
];
423 if (face
->foreground
== pixel
424 || face
->background
== pixel
)
426 Display
*dpy
= FRAME_X_DISPLAY (f
);
428 XFreeGC (dpy
, face
->gc
);
430 /* This marks the computed face as available to reuse. */
435 XFreeColors (dpy
, cmap
, &pixel
, 1, (unsigned long)0);
440 DEFUN ("pixmap-spec-p", Fpixmap_spec_p
, Spixmap_spec_p
, 1, 1, 0,
441 "Return t if OBJECT is a valid pixmap specification.")
445 Lisp_Object height
, width
;
447 return ((STRINGP (object
)
449 && CONSP (XCONS (object
)->cdr
)
450 && CONSP (XCONS (XCONS (object
)->cdr
)->cdr
)
451 && NILP (XCONS (XCONS (XCONS (object
)->cdr
)->cdr
)->cdr
)
452 && (width
= XCONS (object
)->car
, INTEGERP (width
))
453 && (height
= XCONS (XCONS (object
)->cdr
)->car
, INTEGERP (height
))
454 && STRINGP (XCONS (XCONS (XCONS (object
)->cdr
)->cdr
)->car
)
457 /* The string must have enough bits for width * height. */
458 && ((XSTRING (XCONS (XCONS (XCONS (object
)->cdr
)->cdr
)->car
)->size
459 * (BITS_PER_INT
/ sizeof (int)))
460 >= XFASTINT (width
) * XFASTINT (height
))))
464 /* Load a bitmap according to NAME (which is either a file name
465 or a pixmap spec). Return the bitmap_id (see xfns.c)
466 or get an error if NAME is invalid.
468 Store the bitmap width in *W_PTR and height in *H_PTR. */
471 load_pixmap (f
, name
, w_ptr
, h_ptr
)
474 unsigned int *w_ptr
, *h_ptr
;
482 tem
= Fpixmap_spec_p (name
);
484 wrong_type_argument (Qpixmap_spec_p
, name
);
490 /* Decode a bitmap spec into a bitmap. */
495 w
= XINT (Fcar (name
));
496 h
= XINT (Fcar (Fcdr (name
)));
497 bits
= Fcar (Fcdr (Fcdr (name
)));
499 bitmap_id
= x_create_bitmap_from_data (f
, XSTRING (bits
)->data
,
504 /* It must be a string -- a file name. */
505 bitmap_id
= x_create_bitmap_from_file (f
, name
);
510 Fsignal (Qerror
, Fcons (build_string ("invalid or undefined bitmap"),
511 Fcons (name
, Qnil
)));
513 *w_ptr
= x_bitmap_width (f
, bitmap_id
);
514 *h_ptr
= x_bitmap_height (f
, bitmap_id
);
519 #else /* !HAVE_X_WINDOWS */
521 /* Stubs for MSDOS when not under X. */
524 intern_face (f
, face
)
548 CHECK_STRING (name
, 0);
549 result
= call1 (Qmsdos_color_translate
, name
);
550 if (INTEGERP (result
))
551 return XINT (result
);
553 Fsignal (Qerror
, Fcons (build_string ("undefined color"),
554 Fcons (name
, Qnil
)));
557 #endif /* !HAVE_X_WINDOWS */
560 /* Managing parameter face arrays for frames. */
566 ensure_face_ready (f
, 0);
567 ensure_face_ready (f
, 1);
569 FRAME_N_COMPUTED_FACES (f
) = 0;
570 FRAME_SIZE_COMPUTED_FACES (f
) = 0;
572 new_computed_face (f
, FRAME_PARAM_FACES (f
)[0]);
573 new_computed_face (f
, FRAME_PARAM_FACES (f
)[1]);
574 recompute_basic_faces (f
);
576 /* Find another X frame. */
578 Lisp_Object tail
, frame
, result
;
581 FOR_EACH_FRAME (tail
, frame
)
582 if ((FRAME_MSDOS_P (XFRAME (frame
)) || FRAME_X_P (XFRAME (frame
)))
583 && XFRAME (frame
) != f
)
589 /* If we didn't find any X frames other than f, then we don't need
590 any faces other than 0 and 1, so we're okay. Otherwise, make
591 sure that all faces valid on the selected frame are also valid
592 on this new frame. */
596 int n_faces
= FRAME_N_PARAM_FACES (XFRAME (result
));
597 struct face
**faces
= FRAME_PARAM_FACES (XFRAME (result
));
599 for (i
= 2; i
< n_faces
; i
++)
601 ensure_face_ready (f
, i
);
607 /* Called from Fdelete_frame. */
613 Display
*dpy
= FRAME_X_DISPLAY (f
);
618 for (i
= 0; i
< FRAME_N_PARAM_FACES (f
); i
++)
620 struct face
*face
= FRAME_PARAM_FACES (f
) [i
];
623 if (face
->fontset
< 0)
624 unload_font (f
, face
->font
);
625 unload_color (f
, face
->foreground
);
626 unload_color (f
, face
->background
);
627 x_destroy_bitmap (f
, face
->stipple
);
631 xfree (FRAME_PARAM_FACES (f
));
632 FRAME_PARAM_FACES (f
) = 0;
633 FRAME_N_PARAM_FACES (f
) = 0;
635 /* All faces in FRAME_COMPUTED_FACES use resources copied from
636 FRAME_PARAM_FACES; we can free them without fuss.
637 But we do free the GCs and the face objects themselves. */
638 for (i
= 0; i
< FRAME_N_COMPUTED_FACES (f
); i
++)
640 struct face
*face
= FRAME_COMPUTED_FACES (f
) [i
];
645 XFreeGC (dpy
, face
->gc
);
646 XFreeGC (dpy
, face
->non_ascii_gc
);
651 xfree (FRAME_COMPUTED_FACES (f
));
652 FRAME_COMPUTED_FACES (f
) = 0;
653 FRAME_N_COMPUTED_FACES (f
) = 0;
658 /* Interning faces in a frame's face array. */
661 new_computed_face (f
, new_face
)
663 struct face
*new_face
;
665 int len
= FRAME_N_COMPUTED_FACES (f
);
668 /* Search for an unused computed face in the middle of the table. */
669 for (i
= 0; i
< len
; i
++)
671 struct face
*face
= FRAME_COMPUTED_FACES (f
)[i
];
674 FRAME_COMPUTED_FACES (f
)[i
] = copy_face (new_face
);
679 if (i
>= FRAME_SIZE_COMPUTED_FACES (f
))
681 int new_size
= i
+ 32;
683 FRAME_COMPUTED_FACES (f
)
684 = (struct face
**) (FRAME_SIZE_COMPUTED_FACES (f
) == 0
685 ? xmalloc (new_size
* sizeof (struct face
*))
686 : xrealloc (FRAME_COMPUTED_FACES (f
),
687 new_size
* sizeof (struct face
*)));
688 FRAME_SIZE_COMPUTED_FACES (f
) = new_size
;
691 i
= FRAME_N_COMPUTED_FACES (f
)++;
692 FRAME_COMPUTED_FACES (f
)[i
] = copy_face (new_face
);
697 /* Find a match for NEW_FACE in a FRAME's computed face array, and add
698 it if we don't find one. */
700 intern_computed_face (f
, new_face
)
702 struct face
*new_face
;
704 int len
= FRAME_N_COMPUTED_FACES (f
);
707 /* Search for a computed face already on F equivalent to FACE. */
708 for (i
= 0; i
< len
; i
++)
710 if (! FRAME_COMPUTED_FACES (f
)[i
])
712 if (face_eql (new_face
, FRAME_COMPUTED_FACES (f
)[i
]))
716 /* We didn't find one; add a new one. */
717 return new_computed_face (f
, new_face
);
720 /* Make parameter face id ID valid on frame F. */
723 ensure_face_ready (f
, id
)
727 if (FRAME_N_PARAM_FACES (f
) <= id
)
731 if (!FRAME_N_PARAM_FACES (f
))
732 FRAME_PARAM_FACES (f
)
733 = (struct face
**) xmalloc (sizeof (struct face
*) * n
);
735 FRAME_PARAM_FACES (f
)
736 = (struct face
**) xrealloc (FRAME_PARAM_FACES (f
),
737 sizeof (struct face
*) * n
);
739 bzero (FRAME_PARAM_FACES (f
) + FRAME_N_PARAM_FACES (f
),
740 (n
- FRAME_N_PARAM_FACES (f
)) * sizeof (struct face
*));
741 FRAME_N_PARAM_FACES (f
) = n
;
744 if (FRAME_PARAM_FACES (f
) [id
] == 0)
745 FRAME_PARAM_FACES (f
) [id
] = allocate_face ();
748 #ifdef HAVE_X_WINDOWS
749 /* Return non-zero if FONT1 and FONT2 have the same width.
750 We do not check the height, because we can now deal with
752 We assume that they're both character-cell fonts. */
755 same_size_fonts (font1
, font2
)
756 XFontStruct
*font1
, *font2
;
758 XCharStruct
*bounds1
= &font1
->min_bounds
;
759 XCharStruct
*bounds2
= &font2
->min_bounds
;
761 return (bounds1
->width
== bounds2
->width
);
764 /* Update the line_height of frame F according to the biggest font in
765 any face. Return nonzero if if line_height changes. */
768 frame_update_line_height (f
)
772 int fontset
= f
->output_data
.x
->fontset
;
773 int biggest
= (fontset
> 0
774 ? FRAME_FONTSET_DATA (f
)->fontset_table
[fontset
]->height
775 : FONT_HEIGHT (f
->output_data
.x
->font
));
777 for (i
= 0; i
< f
->output_data
.x
->n_param_faces
; i
++)
778 if (f
->output_data
.x
->param_faces
[i
] != 0
779 && f
->output_data
.x
->param_faces
[i
]->font
!= (XFontStruct
*) FACE_DEFAULT
)
781 int height
= ((fontset
= f
->output_data
.x
->param_faces
[i
]->fontset
) > 0
782 ? FRAME_FONTSET_DATA (f
)->fontset_table
[fontset
]->height
783 : FONT_HEIGHT (f
->output_data
.x
->param_faces
[i
]->font
));
785 if (height
> biggest
)
789 if (biggest
== f
->output_data
.x
->line_height
)
792 f
->output_data
.x
->line_height
= biggest
;
795 #endif /* not HAVE_X_WINDOWS */
797 /* Modify face TO by copying from FROM all properties which have
798 nondefault settings. */
801 merge_faces (from
, to
)
802 struct face
*from
, *to
;
804 /* Only merge the font if it's the same width as the base font.
805 Otherwise ignore it, since we can't handle it properly. */
806 if (from
->font
!= (XFontStruct
*) FACE_DEFAULT
807 && same_size_fonts (from
->font
, to
->font
))
808 to
->font
= from
->font
;
809 if (from
->fontset
!= -1)
810 to
->fontset
= from
->fontset
;
811 if (from
->foreground
!= FACE_DEFAULT
)
812 to
->foreground
= from
->foreground
;
813 if (from
->background
!= FACE_DEFAULT
)
814 to
->background
= from
->background
;
815 if (from
->stipple
!= FACE_DEFAULT
)
817 to
->stipple
= from
->stipple
;
818 to
->pixmap_h
= from
->pixmap_h
;
819 to
->pixmap_w
= from
->pixmap_w
;
822 to
->underline
= from
->underline
;
825 /* Set up the basic set of facial parameters, based on the frame's
826 data; all faces are deltas applied to this. */
829 compute_base_face (f
, face
)
834 face
->foreground
= FRAME_FOREGROUND_PIXEL (f
);
835 face
->background
= FRAME_BACKGROUND_PIXEL (f
);
836 face
->font
= FRAME_FONT (f
);
842 /* Return the face ID to use to display a special glyph which selects
843 FACE_CODE as the face ID, assuming that ordinarily the face would
844 be CURRENT_FACE. F is the frame. */
847 compute_glyph_face (f
, face_code
, current_face
)
849 int face_code
, current_face
;
853 face
= *FRAME_COMPUTED_FACES (f
)[current_face
];
855 if (face_code
>= 0 && face_code
< FRAME_N_PARAM_FACES (f
)
856 && FRAME_PARAM_FACES (f
) [face_code
] != 0)
857 merge_faces (FRAME_PARAM_FACES (f
) [face_code
], &face
);
859 return intern_computed_face (f
, &face
);
862 /* Return the face ID to use to display a special glyph which selects
863 FACE_CODE as the face ID, assuming that ordinarily the face would
864 be CURRENT_FACE. F is the frame. */
867 compute_glyph_face_1 (f
, face_name
, current_face
)
869 Lisp_Object face_name
;
874 face
= *FRAME_COMPUTED_FACES (f
)[current_face
];
876 if (!NILP (face_name
))
878 int facecode
= face_name_id_number (f
, face_name
);
879 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
880 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
881 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
884 return intern_computed_face (f
, &face
);
887 /* Return the face ID associated with a buffer position POS.
888 Store into *ENDPTR the position at which a different face is needed.
889 This does not take account of glyphs that specify their own face codes.
890 F is the frame in use for display, and W is a window displaying
893 REGION_BEG, REGION_END delimit the region, so it can be highlighted.
895 LIMIT is a position not to scan beyond. That is to limit
896 the time this function can take.
898 If MOUSE is nonzero, use the character's mouse-face, not its face. */
901 compute_char_face (f
, w
, pos
, region_beg
, region_end
, endptr
, limit
, mouse
)
905 int region_beg
, region_end
;
911 Lisp_Object prop
, position
;
914 Lisp_Object
*overlay_vec
;
917 Lisp_Object propname
;
919 /* W must display the current buffer. We could write this function
920 to use the frame and buffer of W, but right now it doesn't. */
921 if (XBUFFER (w
->buffer
) != current_buffer
)
924 XSETFRAME (frame
, f
);
927 if (pos
< region_beg
&& region_beg
< endpos
)
930 XSETFASTINT (position
, pos
);
933 propname
= Qmouse_face
;
937 prop
= Fget_text_property (position
, propname
, w
->buffer
);
940 Lisp_Object limit1
, end
;
942 XSETFASTINT (limit1
, (limit
< endpos
? limit
: endpos
));
943 end
= Fnext_single_property_change (position
, propname
, w
->buffer
, limit1
);
952 /* First try with room for 40 overlays. */
954 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
956 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
,
957 &next_overlay
, (int *) 0);
959 /* If there are more than 40,
960 make enough space for all, and try again. */
964 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
965 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
,
966 &next_overlay
, (int *) 0);
969 if (next_overlay
< endpos
)
970 endpos
= next_overlay
;
975 /* Optimize the default case. */
976 if (noverlays
== 0 && NILP (prop
)
977 && !(pos
>= region_beg
&& pos
< region_end
))
980 compute_base_face (f
, &face
);
984 /* We have a list of faces, merge them in reverse order */
989 length
= Fsafe_length (prop
);
990 len
= XFASTINT (length
);
992 /* Put them into an array */
993 faces
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
994 for (j
= 0; j
< len
; j
++)
996 faces
[j
] = Fcar (prop
);
999 /* So that we can merge them in the reverse order */
1000 for (j
= len
- 1; j
>= 0; j
--)
1002 facecode
= face_name_id_number (f
, faces
[j
]);
1003 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
1004 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
1005 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
1008 else if (!NILP (prop
))
1010 facecode
= face_name_id_number (f
, prop
);
1011 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
1012 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
1013 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
1016 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
1018 /* Now merge the overlay data in that order. */
1019 for (i
= 0; i
< noverlays
; i
++)
1021 prop
= Foverlay_get (overlay_vec
[i
], propname
);
1024 /* We have a list of faces, merge them in reverse order */
1029 length
= Fsafe_length (prop
);
1030 len
= XFASTINT (length
);
1032 /* Put them into an array */
1033 faces
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
1034 for (j
= 0; j
< len
; j
++)
1036 faces
[j
] = Fcar (prop
);
1039 /* So that we can merge them in the reverse order */
1040 for (j
= len
- 1; j
>= 0; j
--)
1042 facecode
= face_name_id_number (f
, faces
[j
]);
1043 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
1044 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
1045 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
1048 else if (!NILP (prop
))
1053 facecode
= face_name_id_number (f
, prop
);
1054 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
1055 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
1056 merge_faces (FRAME_PARAM_FACES (f
)[facecode
], &face
);
1058 oend
= OVERLAY_END (overlay_vec
[i
]);
1059 oendpos
= OVERLAY_POSITION (oend
);
1060 if (oendpos
< endpos
)
1065 if (pos
>= region_beg
&& pos
< region_end
)
1067 if (region_end
< endpos
)
1068 endpos
= region_end
;
1069 if (region_face
>= 0 && region_face
< next_face_id
)
1070 merge_faces (FRAME_PARAM_FACES (f
)[region_face
], &face
);
1075 return intern_computed_face (f
, &face
);
1078 /* Recompute the GC's for the default and modeline faces.
1079 We call this after changing frame parameters on which those GC's
1083 recompute_basic_faces (f
)
1086 /* If the frame's faces haven't been initialized yet, don't worry about
1088 if (FRAME_N_PARAM_FACES (f
) < 2)
1093 if (FRAME_DEFAULT_FACE (f
)->gc
)
1095 XFreeGC (FRAME_X_DISPLAY (f
), FRAME_DEFAULT_FACE (f
)->gc
);
1096 XFreeGC (FRAME_X_DISPLAY (f
), FRAME_DEFAULT_FACE (f
)->non_ascii_gc
);
1098 if (FRAME_MODE_LINE_FACE (f
)->gc
)
1100 XFreeGC (FRAME_X_DISPLAY (f
), FRAME_MODE_LINE_FACE (f
)->gc
);
1101 XFreeGC (FRAME_X_DISPLAY (f
), FRAME_MODE_LINE_FACE (f
)->non_ascii_gc
);
1103 compute_base_face (f
, FRAME_DEFAULT_FACE (f
));
1104 compute_base_face (f
, FRAME_MODE_LINE_FACE (f
));
1106 merge_faces (FRAME_DEFAULT_PARAM_FACE (f
), FRAME_DEFAULT_FACE (f
));
1107 merge_faces (FRAME_MODE_LINE_PARAM_FACE (f
), FRAME_MODE_LINE_FACE (f
));
1109 intern_face (f
, FRAME_DEFAULT_FACE (f
));
1110 intern_face (f
, FRAME_MODE_LINE_FACE (f
));
1117 /* Lisp interface. */
1119 DEFUN ("frame-face-alist", Fframe_face_alist
, Sframe_face_alist
, 1, 1, 0,
1124 CHECK_FRAME (frame
, 0);
1125 return XFRAME (frame
)->face_alist
;
1128 DEFUN ("set-frame-face-alist", Fset_frame_face_alist
, Sset_frame_face_alist
,
1131 Lisp_Object frame
, value
;
1133 CHECK_FRAME (frame
, 0);
1134 XFRAME (frame
)->face_alist
= value
;
1139 DEFUN ("make-face-internal", Fmake_face_internal
, Smake_face_internal
, 1, 1, 0,
1140 "Create face number FACE-ID on all frames.")
1142 Lisp_Object face_id
;
1144 Lisp_Object rest
, frame
;
1145 int id
= XINT (face_id
);
1147 CHECK_NUMBER (face_id
, 0);
1148 if (id
< 0 || id
>= next_face_id
)
1149 error ("Face id out of range");
1151 FOR_EACH_FRAME (rest
, frame
)
1153 if (FRAME_MSDOS_P (XFRAME (frame
)) || FRAME_X_P (XFRAME (frame
)))
1154 ensure_face_ready (XFRAME (frame
), id
);
1160 DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal
,
1161 Sset_face_attribute_internal
, 4, 4, 0, "")
1162 (face_id
, attr_name
, attr_value
, frame
)
1163 Lisp_Object face_id
, attr_name
, attr_value
, frame
;
1171 CHECK_FRAME (frame
, 0);
1172 CHECK_NUMBER (face_id
, 0);
1173 CHECK_SYMBOL (attr_name
, 0);
1176 id
= XINT (face_id
);
1177 if (id
< 0 || id
>= next_face_id
)
1178 error ("Face id out of range");
1180 if (! FRAME_X_P (f
) && ! FRAME_MSDOS_P (f
))
1183 ensure_face_ready (f
, id
);
1184 face
= FRAME_PARAM_FACES (f
) [XFASTINT (face_id
)];
1186 if (EQ (attr_name
, intern ("font")))
1188 #if defined (MSDOS) && !defined (HAVE_X_WINDOWS)
1189 /* The one and only font. Must *not* be zero (which
1190 is taken to mean an unused face nowadays). */
1191 face
->font
= (XFontStruct
*)1 ;
1196 if (NILP (attr_value
))
1198 font
= (XFontStruct
*) FACE_DEFAULT
;
1203 CHECK_STRING (attr_value
, 0);
1204 fontset
= fs_query_fontset (f
, XSTRING (attr_value
)->data
);
1207 struct font_info
*fontp
;
1209 if (!(fontp
= fs_load_font (f
, FRAME_X_FONT_TABLE (f
),
1210 CHARSET_ASCII
, NULL
, fontset
)))
1212 Fcons (build_string ("ASCII font can't be loaded"),
1213 Fcons (attr_value
, Qnil
)));
1214 font
= (XFontStruct
*) (fontp
->font
);
1217 font
= load_font (f
, attr_value
);
1220 if (face
->fontset
== -1 && face
->font
!= f
->output_data
.x
->font
)
1221 unload_font (f
, face
->font
);
1224 face
->fontset
= fontset
;
1225 if (frame_update_line_height (f
))
1226 x_set_window_size (f
, 0, f
->width
, f
->height
);
1227 /* Must clear cache, since it might contain the font
1228 we just got rid of. */
1232 else if (EQ (attr_name
, intern ("foreground")))
1234 unsigned long new_color
= load_color (f
, attr_value
);
1235 unload_color (f
, face
->foreground
);
1236 face
->foreground
= new_color
;
1239 else if (EQ (attr_name
, intern ("background")))
1241 unsigned long new_color
= load_color (f
, attr_value
);
1242 unload_color (f
, face
->background
);
1243 face
->background
= new_color
;
1246 else if (EQ (attr_name
, intern ("background-pixmap")))
1249 unsigned long new_pixmap
= load_pixmap (f
, attr_value
, &w
, &h
);
1250 x_destroy_bitmap (f
, face
->stipple
);
1251 face
->stipple
= new_pixmap
;
1256 else if (EQ (attr_name
, intern ("underline")))
1258 int new = !NILP (attr_value
);
1259 face
->underline
= new;
1262 error ("unknown face attribute");
1264 if (id
== 0 || id
== 1)
1265 recompute_basic_faces (f
);
1267 /* We must redraw the frame whenever any face font or color changes,
1268 because it's possible that a merged (display) face
1269 contains the font or color we just replaced.
1270 And we must inhibit any Expose events until the redraw is done,
1271 since they would try to use the invalid display faces. */
1274 SET_FRAME_GARBAGED (f
);
1275 FRAME_X_DISPLAY_INFO (f
)->mouse_face_defer
= 1;
1281 DEFUN ("internal-next-face-id", Finternal_next_face_id
, Sinternal_next_face_id
,
1285 return make_number (next_face_id
++);
1288 /* Return the face id for name NAME on frame FRAME.
1289 (It should be the same for all frames,
1290 but it's as easy to use the "right" frame to look it up
1291 as to use any other one.) */
1294 face_name_id_number (f
, name
)
1300 tem
= Fcdr (assq_no_quit (name
, f
->face_alist
));
1303 CHECK_VECTOR (tem
, 0);
1304 tem
= XVECTOR (tem
)->contents
[2];
1305 CHECK_NUMBER (tem
, 0);
1309 /* Emacs initialization. */
1314 Qface
= intern ("face");
1316 Qmouse_face
= intern ("mouse-face");
1317 staticpro (&Qmouse_face
);
1318 Qpixmap_spec_p
= intern ("pixmap-spec-p");
1319 staticpro (&Qpixmap_spec_p
);
1321 DEFVAR_INT ("region-face", ®ion_face
,
1322 "Face number to use to highlight the region\n\
1323 The region is highlighted with this face\n\
1324 when Transient Mark mode is enabled and the mark is active.");
1326 #ifdef HAVE_X_WINDOWS
1327 defsubr (&Spixmap_spec_p
);
1329 defsubr (&Sframe_face_alist
);
1330 defsubr (&Sset_frame_face_alist
);
1331 defsubr (&Smake_face_internal
);
1332 defsubr (&Sset_face_attribute_internal
);
1333 defsubr (&Sinternal_next_face_id
);
1336 #endif /* HAVE_FACES */