new version
[emacs.git] / src / xfaces.c
blobd393a60f23b314d3374fe48d96399e2dc562ef6f
1 /* "Face" primitives.
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)
9 any later version.
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>
24 #include <sys/stat.h>
26 #include <config.h>
27 #include "lisp.h"
29 #include "charset.h"
31 #include "frame.h"
33 /* The number of face-id's in use (same for all frames). */
34 static int next_face_id;
36 #ifdef HAVE_FACES
38 #ifdef HAVE_X_WINDOWS
39 #include "xterm.h"
40 #include "fontset.h"
41 #endif
42 #ifdef MSDOS
43 #include "dosfns.h"
44 #endif
45 #include "buffer.h"
46 #include "dispextern.h"
47 #include "blockinput.h"
48 #include "window.h"
49 #include "intervals.h"
51 #ifdef HAVE_X_WINDOWS
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
55 #included. */
56 #ifdef XOS_NEEDS_TIME_H
58 #include <time.h>
59 #undef USG
60 #include <X11/Xos.h>
61 #define USG
62 #define __TIMEVAL__
64 #else
66 #include <X11/Xos.h>
68 #endif
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]
80 where
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
84 the face,
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
88 use right now, and
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
108 param_faces.)
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.
135 Constraints:
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.
146 Some subtleties:
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
154 on all frames. */
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 */
182 static struct face *
183 allocate_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;
192 return result;
195 /* Make a new face that's a copy of an existing one. */
196 static struct face *
197 copy_face (face)
198 struct face *face;
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;
211 return result;
214 static int
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. */
231 struct face *
232 intern_face (f, face)
233 struct frame *f;
234 struct face *face;
236 GC gc;
237 XGCValues xgcv;
238 unsigned long mask;
240 if (face->gc)
241 return face;
243 BLOCK_INPUT;
245 if (face->foreground != FACE_DEFAULT)
246 xgcv.foreground = face->foreground;
247 else
248 xgcv.foreground = f->output_data.x->foreground_pixel;
250 if (face->background != FACE_DEFAULT)
251 xgcv.background = face->background;
252 else
253 xgcv.background = f->output_data.x->background_pixel;
255 if (face->font && face->font != (XFontStruct *) FACE_DEFAULT)
256 xgcv.font = face->font->fid;
257 else
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),
271 mask, &xgcv);
273 face->gc = gc;
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),
277 mask, &xgcv);
279 UNBLOCK_INPUT;
281 return face;
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. */
289 void
290 clear_face_cache ()
292 Lisp_Object tail, frame;
294 BLOCK_INPUT;
295 FOR_EACH_FRAME (tail, frame)
297 FRAME_PTR f = XFRAME (frame);
298 if (FRAME_X_P (f))
300 int i;
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];
306 if (face->gc)
308 XFreeGC (dpy, face->gc);
309 XFreeGC (dpy, face->non_ascii_gc);
311 face->gc = 0;
316 UNBLOCK_INPUT;
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. */
325 static XFontStruct *
326 load_font (f, name)
327 struct frame *f;
328 Lisp_Object name;
330 XFontStruct *font;
332 if (NILP (name))
333 return (XFontStruct *) FACE_DEFAULT;
335 CHECK_STRING (name, 0);
336 BLOCK_INPUT;
337 font = XLoadQueryFont (FRAME_X_DISPLAY (f), (char *) XSTRING (name)->data);
338 UNBLOCK_INPUT;
340 if (! font)
341 Fsignal (Qerror, Fcons (build_string ("undefined font"),
342 Fcons (name, Qnil)));
343 return font;
346 static void
347 unload_font (f, font)
348 struct frame *f;
349 XFontStruct *font;
351 int len = FRAME_N_COMPUTED_FACES (f);
352 int i;
354 if (!font || font == ((XFontStruct *) FACE_DEFAULT))
355 return;
357 BLOCK_INPUT;
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);
366 if (face->gc)
367 XFreeGC (dpy, face->gc);
368 face->gc = 0;
369 /* This marks the computed face as available to reuse. */
370 face->font = 0;
374 XFreeFont (FRAME_X_DISPLAY (f), font);
375 UNBLOCK_INPUT;
378 static unsigned long
379 load_color (f, name)
380 struct frame *f;
381 Lisp_Object name;
383 XColor color;
384 int result;
386 if (NILP (name))
387 return FACE_DEFAULT;
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);
393 if (! result)
394 Fsignal (Qerror, Fcons (build_string ("undefined color"),
395 Fcons (name, Qnil)));
396 return (unsigned long) color.pixel;
399 static void
400 unload_color (f, pixel)
401 struct frame *f;
402 unsigned long pixel;
404 Colormap cmap;
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))
411 return;
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);
419 int i;
421 BLOCK_INPUT;
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);
431 if (face->gc)
432 XFreeGC (dpy, face->gc);
433 face->gc = 0;
434 /* This marks the computed face as available to reuse. */
435 face->font = 0;
439 XFreeColors (dpy, cmap, &pixel, 1, (unsigned long)0);
440 UNBLOCK_INPUT;
444 DEFUN ("pixmap-spec-p", Fpixmap_spec_p, Spixmap_spec_p, 1, 1, 0,
445 "Return t if OBJECT is a valid pixmap specification.")
446 (object)
447 Lisp_Object object;
449 Lisp_Object height, width;
451 return ((STRINGP (object)
452 || (CONSP (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)
459 && XINT (width) > 0
460 && XINT (height) > 0
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))))
465 ? Qt : Qnil);
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. */
474 static long
475 load_pixmap (f, name, w_ptr, h_ptr)
476 FRAME_PTR f;
477 Lisp_Object name;
478 unsigned int *w_ptr, *h_ptr;
480 int bitmap_id;
481 Lisp_Object tem;
483 if (NILP (name))
484 return FACE_DEFAULT;
486 tem = Fpixmap_spec_p (name);
487 if (NILP (tem))
488 wrong_type_argument (Qpixmap_spec_p, name);
490 BLOCK_INPUT;
492 if (CONSP (name))
494 /* Decode a bitmap spec into a bitmap. */
496 int h, w;
497 Lisp_Object bits;
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,
504 w, h);
506 else
508 /* It must be a string -- a file name. */
509 bitmap_id = x_create_bitmap_from_file (f, name);
511 UNBLOCK_INPUT;
513 if (bitmap_id < 0)
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);
520 return bitmap_id;
523 #else /* !HAVE_X_WINDOWS */
525 /* Stubs for MSDOS when not under X. */
527 struct face *
528 intern_face (f, face)
529 struct frame *f;
530 struct face *face;
532 return face;
535 void
536 clear_face_cache ()
538 /* No action. */
541 #ifdef MSDOS
542 unsigned long
543 load_color (f, name)
544 FRAME_PTR f;
545 Lisp_Object name;
547 Lisp_Object result;
549 if (NILP (name))
550 return FACE_DEFAULT;
552 CHECK_STRING (name, 0);
553 result = call1 (Qmsdos_color_translate, name);
554 if (INTEGERP (result))
555 return XINT (result);
556 else
557 Fsignal (Qerror, Fcons (build_string ("undefined color"),
558 Fcons (name, Qnil)));
560 #endif
561 #endif /* !HAVE_X_WINDOWS */
564 /* Managing parameter face arrays for frames. */
566 void
567 init_frame_faces (f)
568 FRAME_PTR f;
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;
584 result = Qnil;
585 FOR_EACH_FRAME (tail, frame)
586 if ((FRAME_MSDOS_P (XFRAME (frame)) || FRAME_X_P (XFRAME (frame)))
587 && XFRAME (frame) != f)
589 result = frame;
590 break;
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. */
597 if (FRAMEP (result))
599 int i;
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++)
604 if (faces[i])
605 ensure_face_ready (f, i);
611 /* Called from Fdelete_frame. */
613 void
614 free_frame_faces (f)
615 struct frame *f;
617 Display *dpy = FRAME_X_DISPLAY (f);
618 int i;
620 BLOCK_INPUT;
622 for (i = 0; i < FRAME_N_PARAM_FACES (f); i++)
624 struct face *face = FRAME_PARAM_FACES (f) [i];
625 if (face)
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);
632 xfree (face);
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];
645 if (face)
647 if (face->gc)
649 XFreeGC (dpy, face->gc);
650 XFreeGC (dpy, face->non_ascii_gc);
652 xfree (face);
655 xfree (FRAME_COMPUTED_FACES (f));
656 FRAME_COMPUTED_FACES (f) = 0;
657 FRAME_N_COMPUTED_FACES (f) = 0;
659 UNBLOCK_INPUT;
662 /* Interning faces in a frame's face array. */
664 static int
665 new_computed_face (f, new_face)
666 struct frame *f;
667 struct face *new_face;
669 int len = FRAME_N_COMPUTED_FACES (f);
670 int i;
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];
676 if (face->font == 0)
678 FRAME_COMPUTED_FACES (f)[i] = copy_face (new_face);
679 return i;
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);
697 return i;
701 /* Find a match for NEW_FACE in a FRAME's computed face array, and add
702 it if we don't find one. */
703 static int
704 intern_computed_face (f, new_face)
705 struct frame *f;
706 struct face *new_face;
708 int len = FRAME_N_COMPUTED_FACES (f);
709 int i;
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])
715 abort ();
716 if (face_eql (new_face, FRAME_COMPUTED_FACES (f)[i]))
717 return 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. */
726 static void
727 ensure_face_ready (f, id)
728 struct frame *f;
729 int id;
731 if (FRAME_N_PARAM_FACES (f) <= id)
733 int n = id + 10;
734 int i;
735 if (!FRAME_N_PARAM_FACES (f))
736 FRAME_PARAM_FACES (f)
737 = (struct face **) xmalloc (sizeof (struct face *) * n);
738 else
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
755 different heights.
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)
773 FRAME_PTR f;
775 int i;
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)
790 biggest = height;
793 if (biggest == f->output_data.x->line_height)
794 return 0;
796 f->output_data.x->line_height = biggest;
797 return 1;
799 #endif /* not HAVE_X_WINDOWS */
801 /* Modify face TO by copying from FROM all properties which have
802 nondefault settings. */
804 static void
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;
825 if (from->underline)
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. */
832 static void
833 compute_base_face (f, face)
834 FRAME_PTR f;
835 struct face *face;
837 face->gc = 0;
838 face->foreground = FRAME_FOREGROUND_PIXEL (f);
839 face->background = FRAME_BACKGROUND_PIXEL (f);
840 face->font = FRAME_FONT (f);
841 face->fontset = -1;
842 face->stipple = 0;
843 face->underline = 0;
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)
852 struct frame *f;
853 int face_code, current_face;
855 struct face 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)
872 struct frame *f;
873 Lisp_Object face_name;
874 int current_face;
876 struct face face;
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
895 the current buffer.
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)
906 struct frame *f;
907 struct window *w;
908 int pos;
909 int region_beg, region_end;
910 int *endptr;
911 int limit;
912 int mouse;
914 struct face face;
915 Lisp_Object prop, position;
916 int i, j, noverlays;
917 int facecode;
918 Lisp_Object *overlay_vec;
919 Lisp_Object frame;
920 int endpos;
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)
926 abort ();
928 XSETFRAME (frame, f);
930 endpos = ZV;
931 if (pos < region_beg && region_beg < endpos)
932 endpos = region_beg;
934 XSETFASTINT (position, pos);
936 if (mouse)
937 propname = Qmouse_face;
938 else
939 propname = Qface;
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);
948 if (INTEGERP (end))
949 endpos = XINT (end);
953 int next_overlay;
954 int len;
956 /* First try with room for 40 overlays. */
957 len = 40;
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. */
965 if (noverlays > len)
967 len = noverlays;
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;
977 *endptr = endpos;
979 /* Optimize the default case. */
980 if (noverlays == 0 && NILP (prop)
981 && !(pos >= region_beg && pos < region_end))
982 return 0;
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++)
993 Lisp_Object oend;
994 int oendpos;
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)
1002 endpos = oendpos;
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);
1013 *endptr = endpos;
1015 return intern_computed_face (f, &face);
1018 static void
1019 merge_face_list (f, face, prop)
1020 FRAME_PTR f;
1021 struct face *face;
1022 Lisp_Object prop;
1024 Lisp_Object length;
1025 int len;
1026 Lisp_Object *faces;
1027 int j;
1029 if (CONSP (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);
1042 prop = Fcdr (prop);
1044 /* So that we can merge them in the reverse order. */
1046 else
1048 faces = (Lisp_Object *) alloca (sizeof (Lisp_Object));
1049 faces[0] = prop;
1050 len = 1;
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);
1062 else
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
1075 depend. */
1077 void
1078 recompute_basic_faces (f)
1079 FRAME_PTR f;
1081 /* If the frame's faces haven't been initialized yet, don't worry about
1082 this stuff. */
1083 if (FRAME_N_PARAM_FACES (f) < 2)
1084 return;
1086 BLOCK_INPUT;
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));
1107 UNBLOCK_INPUT;
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.")
1116 (face_id)
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);
1131 return Qnil;
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;
1140 struct face *face;
1141 struct frame *f;
1142 int magic_p;
1143 int id;
1144 int garbaged = 0;
1146 CHECK_FRAME (frame, 0);
1147 CHECK_NUMBER (face_id, 0);
1148 CHECK_SYMBOL (attr_name, 0);
1150 f = XFRAME (frame);
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))
1156 return Qnil;
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 ;
1167 #else
1168 XFontStruct *font;
1169 int fontset;
1171 if (NILP (attr_value))
1173 font = (XFontStruct *) FACE_DEFAULT;
1174 fontset = -1;
1176 else
1178 CHECK_STRING (attr_value, 0);
1179 fontset = fs_query_fontset (f, XSTRING (attr_value)->data);
1180 if (fontset >= 0)
1182 struct font_info *fontp;
1184 if (!(fontp = FS_LOAD_FONT (f, FRAME_X_FONT_TABLE (f),
1185 CHARSET_ASCII, NULL, fontset)))
1186 Fsignal (Qerror,
1187 Fcons (build_string ("ASCII font can't be loaded"),
1188 Fcons (attr_value, Qnil)));
1189 font = (XFontStruct *) (fontp->font);
1191 else
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);
1198 face->font = 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. */
1204 garbaged = 1;
1205 #endif
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;
1212 garbaged = 1;
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;
1219 garbaged = 1;
1221 else if (EQ (attr_name, intern ("background-pixmap")))
1223 unsigned int w, h;
1224 unsigned long new_pixmap = load_pixmap (f, attr_value, &w, &h);
1225 x_destroy_bitmap (f, face->stipple);
1226 face->stipple = new_pixmap;
1227 face->pixmap_w = w;
1228 face->pixmap_h = h;
1229 garbaged = 1;
1231 else if (EQ (attr_name, intern ("underline")))
1233 int new = !NILP (attr_value);
1234 face->underline = new;
1236 else
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. */
1247 if (garbaged)
1249 SET_FRAME_GARBAGED (f);
1250 #ifdef HAVE_X_WINDOWS
1251 FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 1;
1252 #endif
1255 return Qnil;
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)
1264 FRAME_PTR f;
1265 Lisp_Object name;
1267 Lisp_Object tem;
1269 tem = Fcdr (assq_no_quit (name, f->face_alist));
1270 if (NILP (tem))
1271 return 0;
1272 CHECK_VECTOR (tem, 0);
1273 tem = XVECTOR (tem)->contents[2];
1274 CHECK_NUMBER (tem, 0);
1275 return XINT (tem);
1278 #endif /* HAVE_FACES */
1281 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist, 1, 1, 0,
1283 (frame)
1284 Lisp_Object frame;
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,
1291 2, 2, 0, "")
1292 (frame, value)
1293 Lisp_Object frame, value;
1295 CHECK_FRAME (frame, 0);
1296 XFRAME (frame)->face_alist = value;
1297 return value;
1300 DEFUN ("internal-next-face-id", Finternal_next_face_id, Sinternal_next_face_id,
1301 0, 0, 0, "")
1304 return make_number (next_face_id++);
1307 /* Emacs initialization. */
1309 void
1310 syms_of_xfaces ()
1312 #ifdef HAVE_FACES
1313 Qface = intern ("face");
1314 staticpro (&Qface);
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", &region_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);
1331 #endif
1333 defsubr (&Sframe_face_alist);
1334 defsubr (&Sset_frame_face_alist);
1335 defsubr (&Sinternal_next_face_id);