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>
33 /* The number of face-id's in use (same for all frames). */
34 static int next_face_id
;
46 #include "dispextern.h"
47 #include "blockinput.h"
49 #include "intervals.h"
52 /* Compensate for bug in Xos.h on some systems, on which it requires
53 time.h. On some such systems, Xos.h tries to redefine struct
54 timeval and struct timezone if USG is #defined while it is
56 #ifdef XOS_NEEDS_TIME_H
69 #endif /* HAVE_X_WINDOWS */
71 /* An explanation of the face data structures. */
73 /* ========================= Face Data Structures =========================
75 Let FACE-NAME be a symbol naming a face.
77 Let FACE-VECTOR be (assq FACE-NAME (frame-face-alist FRAME))
78 FACE-VECTOR is either nil, or a vector of the form
79 [face NAME ID FONT FOREGROUND BACKGROUND BACKGROUND-PIXMAP UNDERLINE-P]
81 face is the symbol `face',
82 NAME is the symbol with which this vector is associated (a backpointer),
83 ID is the face ID, an integer used internally by the C code to identify
85 FONT, FOREGROUND, and BACKGROUND are strings naming the fonts and colors
86 to use with the face, FONT may name fontsets,
87 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't
89 UNDERLINE-P is non-nil if the face should be underlined.
90 If any of these elements are nil, that parameter is considered
91 unspecified; parameters from faces specified by lower-priority
92 overlays or text properties, or the parameters of the frame itself,
93 can show through. (lisp/faces.el maintains these lists.)
95 (assq FACE-NAME global-face-data) returns a vector describing the
96 global parameters for that face.
98 Let PARAM-FACE be FRAME->output_data.x->param_faces[Faref (FACE-VECTOR, 2)].
99 PARAM_FACE is a struct face whose members are the Xlib analogues of
100 the parameters in FACE-VECTOR. If an element of FACE-VECTOR is
101 nil, then the corresponding member of PARAM_FACE is FACE_DEFAULT.
102 These faces are called "parameter faces", because they're the ones
103 lisp manipulates to control what gets displayed. Elements 0 and 1
104 of FRAME->output_data.x->param_faces are special - they describe the
105 default and mode line faces. None of the faces in param_faces have
106 GC's. (See src/dispextern.h for the definition of struct face.
107 lisp/faces.el maintains the isomorphism between face_alist and
110 The functions compute_char_face and compute_glyph_face find and
111 combine the parameter faces associated with overlays and text
112 properties. The resulting faces are called "computed faces"; none
113 of their members are FACE_DEFAULT; they are completely specified.
114 They then call intern_compute_face to search
115 FRAME->output_data.x->computed_faces for a matching face, add one if
116 none is found, and return the index into
117 FRAME->output_data.x->computed_faces. FRAME's glyph matrices use these
118 indices to record the faces of the matrix characters, and the X
119 display hooks consult compute_faces to decide how to display these
120 characters. Elements 0 and 1 of computed_faces always describe the
121 default and mode-line faces.
123 Each computed face belongs to a particular frame.
125 Computed faces have graphics contexts some of the time.
126 intern_face builds a GC for a specified computed face
127 if it doesn't have one already.
128 clear_face_cache clears out the GCs of all computed faces.
129 This is done from time to time so that we don't hold on to
130 lots of GCs that are no longer needed.
132 If a computed face has 0 as its font,
133 it is unused, and can be reused by new_computed_face.
137 Symbols naming faces must have associations on all frames; for any
138 FRAME, for all FACE-NAME, if (assq FACE-NAME (frame-face-alist
139 FRAME)) is non-nil, it must be non-nil for all frames.
141 Analogously, indices into param_faces must be valid on all frames;
142 if param_faces[i] is a non-zero face pointer on one frame, then it
143 must be filled in on all frames. Code assumes that face ID's can
144 be used on any frame.
148 Why do we keep param_faces and computed_faces separate?
149 computed_faces contains an element for every combination of facial
150 parameters we have ever displayed. indices into param_faces have
151 to be valid on all frames. If they were the same array, then that
152 array would grow very large on all frames, because any facial
153 combination displayed on any frame would need to be a valid entry
156 /* Definitions and declarations. */
158 /* The number of the face to use to indicate the region. */
159 static int region_face
;
161 /* This is what appears in a slot in a face to signify that the face
162 does not specify that display aspect. */
163 #define FACE_DEFAULT (~0)
165 Lisp_Object Qface
, Qmouse_face
;
166 Lisp_Object Qpixmap_spec_p
;
168 int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ );
170 struct face
*intern_face ( /* FRAME_PTR, struct face * */ );
171 static int new_computed_face ( /* FRAME_PTR, struct face * */ );
172 static int intern_computed_face ( /* FRAME_PTR, struct face * */ );
173 static void ensure_face_ready ( /* FRAME_PTR, int id */ );
174 void recompute_basic_faces ( /* FRAME_PTR f */ );
175 static void merge_face_list ( /* FRAME_PTR, struct face *, Lisp_Object */ );
177 extern Lisp_Object Qforeground_color
, Qbackground_color
;
179 /* Allocating, copying, and comparing struct faces. */
181 /* Allocate a new face */
185 struct face
*result
= (struct face
*) xmalloc (sizeof (struct face
));
186 bzero (result
, sizeof (struct face
));
187 result
->font
= (XFontStruct
*) FACE_DEFAULT
;
188 result
->fontset
= -1;
189 result
->foreground
= FACE_DEFAULT
;
190 result
->background
= FACE_DEFAULT
;
191 result
->stipple
= FACE_DEFAULT
;
195 /* Make a new face that's a copy of an existing one. */
200 struct face
*result
= allocate_face ();
202 result
->font
= face
->font
;
203 result
->fontset
= face
->fontset
;
204 result
->foreground
= face
->foreground
;
205 result
->background
= face
->background
;
206 result
->stipple
= face
->stipple
;
207 result
->underline
= face
->underline
;
208 result
->pixmap_h
= face
->pixmap_h
;
209 result
->pixmap_w
= face
->pixmap_w
;
215 face_eql (face1
, face2
)
216 struct face
*face1
, *face2
;
218 return ( face1
->font
== face2
->font
219 && face1
->fontset
== face2
->fontset
220 && face1
->foreground
== face2
->foreground
221 && face1
->background
== face2
->background
222 && face1
->stipple
== face2
->stipple
223 && face1
->underline
== face2
->underline
);
226 /* Managing graphics contexts of faces. */
228 #ifdef HAVE_X_WINDOWS
229 /* Given a computed face, construct its graphics context if necessary. */
232 intern_face (f
, face
)
245 if (face
->foreground
!= FACE_DEFAULT
)
246 xgcv
.foreground
= face
->foreground
;
248 xgcv
.foreground
= f
->output_data
.x
->foreground_pixel
;
250 if (face
->background
!= FACE_DEFAULT
)
251 xgcv
.background
= face
->background
;
253 xgcv
.background
= f
->output_data
.x
->background_pixel
;
255 if (face
->font
&& face
->font
!= (XFontStruct
*) FACE_DEFAULT
)
256 xgcv
.font
= face
->font
->fid
;
258 xgcv
.font
= f
->output_data
.x
->font
->fid
;
260 xgcv
.graphics_exposures
= 0;
262 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
263 if (face
->stipple
&& face
->stipple
!= FACE_DEFAULT
)
265 xgcv
.fill_style
= FillStippled
;
266 xgcv
.stipple
= x_bitmap_pixmap (f
, face
->stipple
);
267 mask
|= GCFillStyle
| GCStipple
;
270 gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
274 /* We used the following GC for all non-ASCII characters by changing
275 only GCfont each time. */
276 face
->non_ascii_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
284 /* Clear out all graphics contexts for all computed faces
285 except for the default and mode line faces.
286 This should be done from time to time just to avoid
287 keeping too many graphics contexts that are no longer needed. */
292 Lisp_Object tail
, frame
;
295 FOR_EACH_FRAME (tail
, frame
)
297 FRAME_PTR f
= XFRAME (frame
);
301 Display
*dpy
= FRAME_X_DISPLAY (f
);
303 for (i
= 2; i
< FRAME_N_COMPUTED_FACES (f
); i
++)
305 struct face
*face
= FRAME_COMPUTED_FACES (f
) [i
];
308 XFreeGC (dpy
, face
->gc
);
309 XFreeGC (dpy
, face
->non_ascii_gc
);
319 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps.
321 These functions operate on param faces only.
322 Computed faces get their fonts, colors and pixmaps
323 by merging param faces. */
333 return (XFontStruct
*) FACE_DEFAULT
;
335 CHECK_STRING (name
, 0);
337 font
= XLoadQueryFont (FRAME_X_DISPLAY (f
), (char *) XSTRING (name
)->data
);
341 Fsignal (Qerror
, Fcons (build_string ("undefined font"),
342 Fcons (name
, Qnil
)));
347 unload_font (f
, font
)
351 int len
= FRAME_N_COMPUTED_FACES (f
);
354 if (!font
|| font
== ((XFontStruct
*) FACE_DEFAULT
))
358 /* Invalidate any computed faces which use this font,
359 and free their GC's if they have any. */
360 for (i
= 2; i
< len
; i
++)
362 struct face
*face
= FRAME_COMPUTED_FACES (f
)[i
];
363 if (face
->font
== font
)
365 Display
*dpy
= FRAME_X_DISPLAY (f
);
367 XFreeGC (dpy
, face
->gc
);
369 /* This marks the computed face as available to reuse. */
374 XFreeFont (FRAME_X_DISPLAY (f
), font
);
389 CHECK_STRING (name
, 0);
390 /* if the colormap is full, defined_color will return a best match
391 to the values in an an existing cell. */
392 result
= defined_color (f
, (char *) XSTRING (name
)->data
, &color
, 1);
394 Fsignal (Qerror
, Fcons (build_string ("undefined color"),
395 Fcons (name
, Qnil
)));
396 return (unsigned long) color
.pixel
;
400 unload_color (f
, pixel
)
405 Display
*dpy
= FRAME_X_DISPLAY (f
);
406 int class = FRAME_X_DISPLAY_INFO (f
)->visual
->class;
408 if (pixel
== FACE_DEFAULT
409 || pixel
== BLACK_PIX_DEFAULT (f
)
410 || pixel
== WHITE_PIX_DEFAULT (f
))
412 cmap
= DefaultColormapOfScreen (DefaultScreenOfDisplay (dpy
));
414 /* If display has an immutable color map, freeing colors is not
415 necessary and some servers don't allow it. So don't do it. */
416 if (! (class == StaticColor
|| class == StaticGray
|| class == TrueColor
))
418 int len
= FRAME_N_COMPUTED_FACES (f
);
422 /* Invalidate any computed faces which use this color,
423 and free their GC's if they have any. */
424 for (i
= 2; i
< len
; i
++)
426 struct face
*face
= FRAME_COMPUTED_FACES (f
)[i
];
427 if (face
->foreground
== pixel
428 || face
->background
== pixel
)
430 Display
*dpy
= FRAME_X_DISPLAY (f
);
432 XFreeGC (dpy
, face
->gc
);
434 /* This marks the computed face as available to reuse. */
439 XFreeColors (dpy
, cmap
, &pixel
, 1, (unsigned long)0);
444 DEFUN ("pixmap-spec-p", Fpixmap_spec_p
, Spixmap_spec_p
, 1, 1, 0,
445 "Return t if OBJECT is a valid pixmap specification.")
449 Lisp_Object height
, width
;
451 return ((STRINGP (object
)
453 && CONSP (XCONS (object
)->cdr
)
454 && CONSP (XCONS (XCONS (object
)->cdr
)->cdr
)
455 && NILP (XCONS (XCONS (XCONS (object
)->cdr
)->cdr
)->cdr
)
456 && (width
= XCONS (object
)->car
, INTEGERP (width
))
457 && (height
= XCONS (XCONS (object
)->cdr
)->car
, INTEGERP (height
))
458 && STRINGP (XCONS (XCONS (XCONS (object
)->cdr
)->cdr
)->car
)
461 /* The string must have enough bits for width * height. */
462 && ((XSTRING (XCONS (XCONS (XCONS (object
)->cdr
)->cdr
)->car
)->size
463 * (BITS_PER_INT
/ sizeof (int)))
464 >= XFASTINT (width
) * XFASTINT (height
))))
468 /* Load a bitmap according to NAME (which is either a file name
469 or a pixmap spec). Return the bitmap_id (see xfns.c)
470 or get an error if NAME is invalid.
472 Store the bitmap width in *W_PTR and height in *H_PTR. */
475 load_pixmap (f
, name
, w_ptr
, h_ptr
)
478 unsigned int *w_ptr
, *h_ptr
;
486 tem
= Fpixmap_spec_p (name
);
488 wrong_type_argument (Qpixmap_spec_p
, name
);
494 /* Decode a bitmap spec into a bitmap. */
499 w
= XINT (Fcar (name
));
500 h
= XINT (Fcar (Fcdr (name
)));
501 bits
= Fcar (Fcdr (Fcdr (name
)));
503 bitmap_id
= x_create_bitmap_from_data (f
, XSTRING (bits
)->data
,
508 /* It must be a string -- a file name. */
509 bitmap_id
= x_create_bitmap_from_file (f
, name
);
514 Fsignal (Qerror
, Fcons (build_string ("invalid or undefined bitmap"),
515 Fcons (name
, Qnil
)));
517 *w_ptr
= x_bitmap_width (f
, bitmap_id
);
518 *h_ptr
= x_bitmap_height (f
, bitmap_id
);
523 #else /* !HAVE_X_WINDOWS */
525 /* Stubs for MSDOS when not under X. */
528 intern_face (f
, face
)
552 CHECK_STRING (name
, 0);
553 result
= call1 (Qmsdos_color_translate
, name
);
554 if (INTEGERP (result
))
555 return XINT (result
);
557 Fsignal (Qerror
, Fcons (build_string ("undefined color"),
558 Fcons (name
, Qnil
)));
561 #endif /* !HAVE_X_WINDOWS */
564 /* Managing parameter face arrays for frames. */
570 ensure_face_ready (f
, 0);
571 ensure_face_ready (f
, 1);
573 FRAME_N_COMPUTED_FACES (f
) = 0;
574 FRAME_SIZE_COMPUTED_FACES (f
) = 0;
576 new_computed_face (f
, FRAME_PARAM_FACES (f
)[0]);
577 new_computed_face (f
, FRAME_PARAM_FACES (f
)[1]);
578 recompute_basic_faces (f
);
580 /* Find another X frame. */
582 Lisp_Object tail
, frame
, result
;
585 FOR_EACH_FRAME (tail
, frame
)
586 if ((FRAME_MSDOS_P (XFRAME (frame
)) || FRAME_X_P (XFRAME (frame
)))
587 && XFRAME (frame
) != f
)
593 /* If we didn't find any X frames other than f, then we don't need
594 any faces other than 0 and 1, so we're okay. Otherwise, make
595 sure that all faces valid on the selected frame are also valid
596 on this new frame. */
600 int n_faces
= FRAME_N_PARAM_FACES (XFRAME (result
));
601 struct face
**faces
= FRAME_PARAM_FACES (XFRAME (result
));
603 for (i
= 2; i
< n_faces
; i
++)
605 ensure_face_ready (f
, i
);
611 /* Called from Fdelete_frame. */
617 Display
*dpy
= FRAME_X_DISPLAY (f
);
622 for (i
= 0; i
< FRAME_N_PARAM_FACES (f
); i
++)
624 struct face
*face
= FRAME_PARAM_FACES (f
) [i
];
627 if (face
->fontset
< 0)
628 unload_font (f
, face
->font
);
629 unload_color (f
, face
->foreground
);
630 unload_color (f
, face
->background
);
631 x_destroy_bitmap (f
, face
->stipple
);
635 xfree (FRAME_PARAM_FACES (f
));
636 FRAME_PARAM_FACES (f
) = 0;
637 FRAME_N_PARAM_FACES (f
) = 0;
639 /* All faces in FRAME_COMPUTED_FACES use resources copied from
640 FRAME_PARAM_FACES; we can free them without fuss.
641 But we do free the GCs and the face objects themselves. */
642 for (i
= 0; i
< FRAME_N_COMPUTED_FACES (f
); i
++)
644 struct face
*face
= FRAME_COMPUTED_FACES (f
) [i
];
649 XFreeGC (dpy
, face
->gc
);
650 XFreeGC (dpy
, face
->non_ascii_gc
);
655 xfree (FRAME_COMPUTED_FACES (f
));
656 FRAME_COMPUTED_FACES (f
) = 0;
657 FRAME_N_COMPUTED_FACES (f
) = 0;
662 /* Interning faces in a frame's face array. */
665 new_computed_face (f
, new_face
)
667 struct face
*new_face
;
669 int len
= FRAME_N_COMPUTED_FACES (f
);
672 /* Search for an unused computed face in the middle of the table. */
673 for (i
= 0; i
< len
; i
++)
675 struct face
*face
= FRAME_COMPUTED_FACES (f
)[i
];
678 FRAME_COMPUTED_FACES (f
)[i
] = copy_face (new_face
);
683 if (i
>= FRAME_SIZE_COMPUTED_FACES (f
))
685 int new_size
= i
+ 32;
687 FRAME_COMPUTED_FACES (f
)
688 = (struct face
**) (FRAME_SIZE_COMPUTED_FACES (f
) == 0
689 ? xmalloc (new_size
* sizeof (struct face
*))
690 : xrealloc (FRAME_COMPUTED_FACES (f
),
691 new_size
* sizeof (struct face
*)));
692 FRAME_SIZE_COMPUTED_FACES (f
) = new_size
;
695 i
= FRAME_N_COMPUTED_FACES (f
)++;
696 FRAME_COMPUTED_FACES (f
)[i
] = copy_face (new_face
);
701 /* Find a match for NEW_FACE in a FRAME's computed face array, and add
702 it if we don't find one. */
704 intern_computed_face (f
, new_face
)
706 struct face
*new_face
;
708 int len
= FRAME_N_COMPUTED_FACES (f
);
711 /* Search for a computed face already on F equivalent to FACE. */
712 for (i
= 0; i
< len
; i
++)
714 if (! FRAME_COMPUTED_FACES (f
)[i
])
716 if (face_eql (new_face
, FRAME_COMPUTED_FACES (f
)[i
]))
720 /* We didn't find one; add a new one. */
721 return new_computed_face (f
, new_face
);
724 /* Make parameter face id ID valid on frame F. */
727 ensure_face_ready (f
, id
)
731 if (FRAME_N_PARAM_FACES (f
) <= id
)
735 if (!FRAME_N_PARAM_FACES (f
))
736 FRAME_PARAM_FACES (f
)
737 = (struct face
**) xmalloc (sizeof (struct face
*) * n
);
739 FRAME_PARAM_FACES (f
)
740 = (struct face
**) xrealloc (FRAME_PARAM_FACES (f
),
741 sizeof (struct face
*) * n
);
743 bzero (FRAME_PARAM_FACES (f
) + FRAME_N_PARAM_FACES (f
),
744 (n
- FRAME_N_PARAM_FACES (f
)) * sizeof (struct face
*));
745 FRAME_N_PARAM_FACES (f
) = n
;
748 if (FRAME_PARAM_FACES (f
) [id
] == 0)
749 FRAME_PARAM_FACES (f
) [id
] = allocate_face ();
752 #ifdef HAVE_X_WINDOWS
753 /* Return non-zero if FONT1 and FONT2 have the same width.
754 We do not check the height, because we can now deal with
756 We assume that they're both character-cell fonts. */
759 same_size_fonts (font1
, font2
)
760 XFontStruct
*font1
, *font2
;
762 XCharStruct
*bounds1
= &font1
->min_bounds
;
763 XCharStruct
*bounds2
= &font2
->min_bounds
;
765 return (bounds1
->width
== bounds2
->width
);
768 /* Update the line_height of frame F according to the biggest font in
769 any face. Return nonzero if if line_height changes. */
772 frame_update_line_height (f
)
776 int fontset
= f
->output_data
.x
->fontset
;
777 int biggest
= (fontset
> 0
778 ? FRAME_FONTSET_DATA (f
)->fontset_table
[fontset
]->height
779 : FONT_HEIGHT (f
->output_data
.x
->font
));
781 for (i
= 0; i
< f
->output_data
.x
->n_param_faces
; i
++)
782 if (f
->output_data
.x
->param_faces
[i
] != 0
783 && f
->output_data
.x
->param_faces
[i
]->font
!= (XFontStruct
*) FACE_DEFAULT
)
785 int height
= ((fontset
= f
->output_data
.x
->param_faces
[i
]->fontset
) > 0
786 ? FRAME_FONTSET_DATA (f
)->fontset_table
[fontset
]->height
787 : FONT_HEIGHT (f
->output_data
.x
->param_faces
[i
]->font
));
789 if (height
> biggest
)
793 if (biggest
== f
->output_data
.x
->line_height
)
796 f
->output_data
.x
->line_height
= biggest
;
799 #endif /* not HAVE_X_WINDOWS */
801 /* Modify face TO by copying from FROM all properties which have
802 nondefault settings. */
805 merge_faces (from
, to
)
806 struct face
*from
, *to
;
808 /* Only merge the font if it's the same width as the base font.
809 Otherwise ignore it, since we can't handle it properly. */
810 if (from
->font
!= (XFontStruct
*) FACE_DEFAULT
811 && same_size_fonts (from
->font
, to
->font
))
812 to
->font
= from
->font
;
813 if (from
->fontset
!= -1)
814 to
->fontset
= from
->fontset
;
815 if (from
->foreground
!= FACE_DEFAULT
)
816 to
->foreground
= from
->foreground
;
817 if (from
->background
!= FACE_DEFAULT
)
818 to
->background
= from
->background
;
819 if (from
->stipple
!= FACE_DEFAULT
)
821 to
->stipple
= from
->stipple
;
822 to
->pixmap_h
= from
->pixmap_h
;
823 to
->pixmap_w
= from
->pixmap_w
;
826 to
->underline
= from
->underline
;
829 /* Set up the basic set of facial parameters, based on the frame's
830 data; all faces are deltas applied to this. */
833 compute_base_face (f
, face
)
838 face
->foreground
= FRAME_FOREGROUND_PIXEL (f
);
839 face
->background
= FRAME_BACKGROUND_PIXEL (f
);
840 face
->font
= FRAME_FONT (f
);
846 /* Return the face ID to use to display a special glyph which selects
847 FACE_CODE as the face ID, assuming that ordinarily the face would
848 be CURRENT_FACE. F is the frame. */
851 compute_glyph_face (f
, face_code
, current_face
)
853 int face_code
, current_face
;
857 face
= *FRAME_COMPUTED_FACES (f
)[current_face
];
859 if (face_code
>= 0 && face_code
< FRAME_N_PARAM_FACES (f
)
860 && FRAME_PARAM_FACES (f
) [face_code
] != 0)
861 merge_faces (FRAME_PARAM_FACES (f
) [face_code
], &face
);
863 return intern_computed_face (f
, &face
);
866 /* Return the face ID to use to display a special glyph which selects
867 FACE_CODE as the face ID, assuming that ordinarily the face would
868 be CURRENT_FACE. F is the frame. */
871 compute_glyph_face_1 (f
, face_name
, current_face
)
873 Lisp_Object face_name
;
878 face
= *FRAME_COMPUTED_FACES (f
)[current_face
];
880 if (!NILP (face_name
))
882 int facecode
= face_name_id_number (f
, face_name
);
883 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
884 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
885 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
888 return intern_computed_face (f
, &face
);
891 /* Return the face ID associated with a buffer position POS.
892 Store into *ENDPTR the position at which a different face is needed.
893 This does not take account of glyphs that specify their own face codes.
894 F is the frame in use for display, and W is a window displaying
897 REGION_BEG, REGION_END delimit the region, so it can be highlighted.
899 LIMIT is a position not to scan beyond. That is to limit
900 the time this function can take.
902 If MOUSE is nonzero, use the character's mouse-face, not its face. */
905 compute_char_face (f
, w
, pos
, region_beg
, region_end
, endptr
, limit
, mouse
)
909 int region_beg
, region_end
;
915 Lisp_Object prop
, position
;
918 Lisp_Object
*overlay_vec
;
921 Lisp_Object propname
;
923 /* W must display the current buffer. We could write this function
924 to use the frame and buffer of W, but right now it doesn't. */
925 if (XBUFFER (w
->buffer
) != current_buffer
)
928 XSETFRAME (frame
, f
);
931 if (pos
< region_beg
&& region_beg
< endpos
)
934 XSETFASTINT (position
, pos
);
937 propname
= Qmouse_face
;
941 prop
= Fget_text_property (position
, propname
, w
->buffer
);
944 Lisp_Object limit1
, end
;
946 XSETFASTINT (limit1
, (limit
< endpos
? limit
: endpos
));
947 end
= Fnext_single_property_change (position
, propname
, w
->buffer
, limit1
);
956 /* First try with room for 40 overlays. */
958 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
960 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
,
961 &next_overlay
, (int *) 0);
963 /* If there are more than 40,
964 make enough space for all, and try again. */
968 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
969 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
,
970 &next_overlay
, (int *) 0);
973 if (next_overlay
< endpos
)
974 endpos
= next_overlay
;
979 /* Optimize the default case. */
980 if (noverlays
== 0 && NILP (prop
)
981 && !(pos
>= region_beg
&& pos
< region_end
))
984 compute_base_face (f
, &face
);
986 merge_face_list (f
, &face
, prop
);
988 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
990 /* Now merge the overlay data in that order. */
991 for (i
= 0; i
< noverlays
; i
++)
996 prop
= Foverlay_get (overlay_vec
[i
], propname
);
997 merge_face_list (f
, &face
, prop
);
999 oend
= OVERLAY_END (overlay_vec
[i
]);
1000 oendpos
= OVERLAY_POSITION (oend
);
1001 if (oendpos
< endpos
)
1005 if (pos
>= region_beg
&& pos
< region_end
)
1007 if (region_end
< endpos
)
1008 endpos
= region_end
;
1009 if (region_face
>= 0 && region_face
< next_face_id
)
1010 merge_faces (FRAME_PARAM_FACES (f
)[region_face
], &face
);
1015 return intern_computed_face (f
, &face
);
1019 merge_face_list (f
, face
, prop
)
1030 && ! STRINGP (XCONS (prop
)->cdr
))
1032 /* We have a list of faces, merge them in reverse order. */
1034 length
= Fsafe_length (prop
);
1035 len
= XFASTINT (length
);
1037 /* Put them into an array. */
1038 faces
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
1039 for (j
= 0; j
< len
; j
++)
1041 faces
[j
] = Fcar (prop
);
1044 /* So that we can merge them in the reverse order. */
1048 faces
= (Lisp_Object
*) alloca (sizeof (Lisp_Object
));
1053 for (j
= len
- 1; j
>= 0; j
--)
1055 if (CONSP (faces
[j
]))
1057 if (EQ (XCONS (faces
[j
])->car
, Qbackground_color
))
1058 face
->background
= load_color (f
, XCONS (faces
[j
])->cdr
);
1059 if (EQ (XCONS (faces
[j
])->car
, Qforeground_color
))
1060 face
->foreground
= load_color (f
, XCONS (faces
[j
])->cdr
);
1064 int facecode
= face_name_id_number (f
, faces
[j
]);
1065 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
1066 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
1067 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], face
);
1073 /* Recompute the GC's for the default and modeline faces.
1074 We call this after changing frame parameters on which those GC's
1078 recompute_basic_faces (f
)
1081 /* If the frame's faces haven't been initialized yet, don't worry about
1083 if (FRAME_N_PARAM_FACES (f
) < 2)
1088 if (FRAME_DEFAULT_FACE (f
)->gc
)
1090 XFreeGC (FRAME_X_DISPLAY (f
), FRAME_DEFAULT_FACE (f
)->gc
);
1091 XFreeGC (FRAME_X_DISPLAY (f
), FRAME_DEFAULT_FACE (f
)->non_ascii_gc
);
1093 if (FRAME_MODE_LINE_FACE (f
)->gc
)
1095 XFreeGC (FRAME_X_DISPLAY (f
), FRAME_MODE_LINE_FACE (f
)->gc
);
1096 XFreeGC (FRAME_X_DISPLAY (f
), FRAME_MODE_LINE_FACE (f
)->non_ascii_gc
);
1098 compute_base_face (f
, FRAME_DEFAULT_FACE (f
));
1099 compute_base_face (f
, FRAME_MODE_LINE_FACE (f
));
1101 merge_faces (FRAME_DEFAULT_PARAM_FACE (f
), FRAME_DEFAULT_FACE (f
));
1102 merge_faces (FRAME_MODE_LINE_PARAM_FACE (f
), FRAME_MODE_LINE_FACE (f
));
1104 intern_face (f
, FRAME_DEFAULT_FACE (f
));
1105 intern_face (f
, FRAME_MODE_LINE_FACE (f
));
1112 /* Lisp interface. */
1114 DEFUN ("make-face-internal", Fmake_face_internal
, Smake_face_internal
, 1, 1, 0,
1115 "Create face number FACE-ID on all frames.")
1117 Lisp_Object face_id
;
1119 Lisp_Object rest
, frame
;
1120 int id
= XINT (face_id
);
1122 CHECK_NUMBER (face_id
, 0);
1123 if (id
< 0 || id
>= next_face_id
)
1124 error ("Face id out of range");
1126 FOR_EACH_FRAME (rest
, frame
)
1128 if (FRAME_MSDOS_P (XFRAME (frame
)) || FRAME_X_P (XFRAME (frame
)))
1129 ensure_face_ready (XFRAME (frame
), id
);
1135 DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal
,
1136 Sset_face_attribute_internal
, 4, 4, 0, "")
1137 (face_id
, attr_name
, attr_value
, frame
)
1138 Lisp_Object face_id
, attr_name
, attr_value
, frame
;
1146 CHECK_FRAME (frame
, 0);
1147 CHECK_NUMBER (face_id
, 0);
1148 CHECK_SYMBOL (attr_name
, 0);
1151 id
= XINT (face_id
);
1152 if (id
< 0 || id
>= next_face_id
)
1153 error ("Face id out of range");
1155 if (! FRAME_X_P (f
) && ! FRAME_MSDOS_P (f
))
1158 ensure_face_ready (f
, id
);
1159 face
= FRAME_PARAM_FACES (f
) [XFASTINT (face_id
)];
1161 if (EQ (attr_name
, intern ("font")))
1163 #if defined (MSDOS) && !defined (HAVE_X_WINDOWS)
1164 /* The one and only font. Must *not* be zero (which
1165 is taken to mean an unused face nowadays). */
1166 face
->font
= (XFontStruct
*)1 ;
1171 if (NILP (attr_value
))
1173 font
= (XFontStruct
*) FACE_DEFAULT
;
1178 CHECK_STRING (attr_value
, 0);
1179 fontset
= fs_query_fontset (f
, XSTRING (attr_value
)->data
);
1182 struct font_info
*fontp
;
1184 if (!(fontp
= FS_LOAD_FONT (f
, FRAME_X_FONT_TABLE (f
),
1185 CHARSET_ASCII
, NULL
, fontset
)))
1187 Fcons (build_string ("ASCII font can't be loaded"),
1188 Fcons (attr_value
, Qnil
)));
1189 font
= (XFontStruct
*) (fontp
->font
);
1192 font
= load_font (f
, attr_value
);
1195 if (face
->fontset
== -1 && face
->font
!= f
->output_data
.x
->font
)
1196 unload_font (f
, face
->font
);
1199 face
->fontset
= fontset
;
1200 if (frame_update_line_height (f
))
1201 x_set_window_size (f
, 0, f
->width
, f
->height
);
1202 /* Must clear cache, since it might contain the font
1203 we just got rid of. */
1207 else if (EQ (attr_name
, intern ("foreground")))
1209 unsigned long new_color
= load_color (f
, attr_value
);
1210 unload_color (f
, face
->foreground
);
1211 face
->foreground
= new_color
;
1214 else if (EQ (attr_name
, intern ("background")))
1216 unsigned long new_color
= load_color (f
, attr_value
);
1217 unload_color (f
, face
->background
);
1218 face
->background
= new_color
;
1221 else if (EQ (attr_name
, intern ("background-pixmap")))
1224 unsigned long new_pixmap
= load_pixmap (f
, attr_value
, &w
, &h
);
1225 x_destroy_bitmap (f
, face
->stipple
);
1226 face
->stipple
= new_pixmap
;
1231 else if (EQ (attr_name
, intern ("underline")))
1233 int new = !NILP (attr_value
);
1234 face
->underline
= new;
1237 error ("unknown face attribute");
1239 if (id
== 0 || id
== 1)
1240 recompute_basic_faces (f
);
1242 /* We must redraw the frame whenever any face font or color changes,
1243 because it's possible that a merged (display) face
1244 contains the font or color we just replaced.
1245 And we must inhibit any Expose events until the redraw is done,
1246 since they would try to use the invalid display faces. */
1249 SET_FRAME_GARBAGED (f
);
1250 #ifdef HAVE_X_WINDOWS
1251 FRAME_X_DISPLAY_INFO (f
)->mouse_face_defer
= 1;
1257 /* Return the face id for name NAME on frame FRAME.
1258 (It should be the same for all frames,
1259 but it's as easy to use the "right" frame to look it up
1260 as to use any other one.) */
1263 face_name_id_number (f
, name
)
1269 tem
= Fcdr (assq_no_quit (name
, f
->face_alist
));
1272 CHECK_VECTOR (tem
, 0);
1273 tem
= XVECTOR (tem
)->contents
[2];
1274 CHECK_NUMBER (tem
, 0);
1278 #endif /* HAVE_FACES */
1281 DEFUN ("frame-face-alist", Fframe_face_alist
, Sframe_face_alist
, 1, 1, 0,
1286 CHECK_FRAME (frame
, 0);
1287 return XFRAME (frame
)->face_alist
;
1290 DEFUN ("set-frame-face-alist", Fset_frame_face_alist
, Sset_frame_face_alist
,
1293 Lisp_Object frame
, value
;
1295 CHECK_FRAME (frame
, 0);
1296 XFRAME (frame
)->face_alist
= value
;
1300 DEFUN ("internal-next-face-id", Finternal_next_face_id
, Sinternal_next_face_id
,
1304 return make_number (next_face_id
++);
1307 /* Emacs initialization. */
1313 Qface
= intern ("face");
1315 Qmouse_face
= intern ("mouse-face");
1316 staticpro (&Qmouse_face
);
1317 Qpixmap_spec_p
= intern ("pixmap-spec-p");
1318 staticpro (&Qpixmap_spec_p
);
1320 DEFVAR_INT ("region-face", ®ion_face
,
1321 "Face number to use to highlight the region\n\
1322 The region is highlighted with this face\n\
1323 when Transient Mark mode is enabled and the mark is active.");
1325 defsubr (&Smake_face_internal
);
1326 defsubr (&Sset_face_attribute_internal
);
1327 #endif /* HAVE_FACES */
1329 #ifdef HAVE_X_WINDOWS
1330 defsubr (&Spixmap_spec_p
);
1333 defsubr (&Sframe_face_alist
);
1334 defsubr (&Sset_frame_face_alist
);
1335 defsubr (&Sinternal_next_face_id
);