(mail-strip-quoted-names): Don't delete angle brackets
[bpt/emacs.git] / src / xfaces.c
1 /* "Face" primitives.
2 Copyright (C) 1993, 1994 Free Software Foundation.
3
4 This file is part of GNU Emacs.
5
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.
10
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.
15
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. */
20
21 /* This is derived from work by Lucid (some parts very loosely so). */
22
23 #include <sys/types.h>
24 #include <sys/stat.h>
25
26 #include <config.h>
27 #include "lisp.h"
28
29 #include "charset.h"
30
31 #ifdef HAVE_FACES
32
33 #ifdef HAVE_X_WINDOWS
34 #include "xterm.h"
35 #include "fontset.h"
36 #endif
37 #ifdef MSDOS
38 #include "dosfns.h"
39 #endif
40 #include "buffer.h"
41 #include "dispextern.h"
42 #include "frame.h"
43 #include "blockinput.h"
44 #include "window.h"
45 #include "intervals.h"
46
47 #ifdef HAVE_X_WINDOWS
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
51 #included. */
52 #ifdef XOS_NEEDS_TIME_H
53
54 #include <time.h>
55 #undef USG
56 #include <X11/Xos.h>
57 #define USG
58 #define __TIMEVAL__
59
60 #else
61
62 #include <X11/Xos.h>
63
64 #endif
65 #endif /* HAVE_X_WINDOWS */
66 \f
67 /* An explanation of the face data structures. */
68
69 /* ========================= Face Data Structures =========================
70
71 Let FACE-NAME be a symbol naming a face.
72
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]
76 where
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
80 the face,
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
84 use right now, and
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.)
90
91 (assq FACE-NAME global-face-data) returns a vector describing the
92 global parameters for that face.
93
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
104 param_faces.)
105
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.
118
119 Each computed face belongs to a particular frame.
120
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.
127
128 If a computed face has 0 as its font,
129 it is unused, and can be reused by new_computed_face.
130
131 Constraints:
132
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.
136
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.
141
142 Some subtleties:
143
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
150 on all frames. */
151 \f
152 /* Definitions and declarations. */
153
154 /* The number of face-id's in use (same for all frames). */
155 static int next_face_id;
156
157 /* The number of the face to use to indicate the region. */
158 static int region_face;
159
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)
163
164 Lisp_Object Qface, Qmouse_face;
165 Lisp_Object Qpixmap_spec_p;
166
167 int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ );
168
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 */ );
174 \f
175 /* Allocating, copying, and comparing struct faces. */
176
177 /* Allocate a new face */
178 static struct face *
179 allocate_face ()
180 {
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;
188 return result;
189 }
190
191 /* Make a new face that's a copy of an existing one. */
192 static struct face *
193 copy_face (face)
194 struct face *face;
195 {
196 struct face *result = allocate_face ();
197
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;
206
207 return result;
208 }
209
210 static int
211 face_eql (face1, face2)
212 struct face *face1, *face2;
213 {
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);
220 }
221 \f
222 /* Managing graphics contexts of faces. */
223
224 #ifdef HAVE_X_WINDOWS
225 /* Given a computed face, construct its graphics context if necessary. */
226
227 struct face *
228 intern_face (f, face)
229 struct frame *f;
230 struct face *face;
231 {
232 GC gc;
233 XGCValues xgcv;
234 unsigned long mask;
235
236 if (face->gc)
237 return face;
238
239 BLOCK_INPUT;
240
241 if (face->foreground != FACE_DEFAULT)
242 xgcv.foreground = face->foreground;
243 else
244 xgcv.foreground = f->output_data.x->foreground_pixel;
245
246 if (face->background != FACE_DEFAULT)
247 xgcv.background = face->background;
248 else
249 xgcv.background = f->output_data.x->background_pixel;
250
251 if (face->font && face->font != (XFontStruct *) FACE_DEFAULT)
252 xgcv.font = face->font->fid;
253 else
254 xgcv.font = f->output_data.x->font->fid;
255
256 xgcv.graphics_exposures = 0;
257
258 mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
259 if (face->stipple && face->stipple != FACE_DEFAULT)
260 {
261 xgcv.fill_style = FillStippled;
262 xgcv.stipple = x_bitmap_pixmap (f, face->stipple);
263 mask |= GCFillStyle | GCStipple;
264 }
265
266 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
267 mask, &xgcv);
268
269 face->gc = gc;
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),
273 mask, &xgcv);
274
275 UNBLOCK_INPUT;
276
277 return face;
278 }
279
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. */
284
285 void
286 clear_face_cache ()
287 {
288 Lisp_Object tail, frame;
289
290 BLOCK_INPUT;
291 FOR_EACH_FRAME (tail, frame)
292 {
293 FRAME_PTR f = XFRAME (frame);
294 if (FRAME_X_P (f))
295 {
296 int i;
297 Display *dpy = FRAME_X_DISPLAY (f);
298
299 for (i = 2; i < FRAME_N_COMPUTED_FACES (f); i++)
300 {
301 struct face *face = FRAME_COMPUTED_FACES (f) [i];
302 if (face->gc)
303 {
304 XFreeGC (dpy, face->gc);
305 XFreeGC (dpy, face->non_ascii_gc);
306 }
307 face->gc = 0;
308 }
309 }
310 }
311
312 UNBLOCK_INPUT;
313 }
314 \f
315 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps.
316
317 These functions operate on param faces only.
318 Computed faces get their fonts, colors and pixmaps
319 by merging param faces. */
320
321 static XFontStruct *
322 load_font (f, name)
323 struct frame *f;
324 Lisp_Object name;
325 {
326 XFontStruct *font;
327
328 if (NILP (name))
329 return (XFontStruct *) FACE_DEFAULT;
330
331 CHECK_STRING (name, 0);
332 BLOCK_INPUT;
333 font = XLoadQueryFont (FRAME_X_DISPLAY (f), (char *) XSTRING (name)->data);
334 UNBLOCK_INPUT;
335
336 if (! font)
337 Fsignal (Qerror, Fcons (build_string ("undefined font"),
338 Fcons (name, Qnil)));
339 return font;
340 }
341
342 static void
343 unload_font (f, font)
344 struct frame *f;
345 XFontStruct *font;
346 {
347 int len = FRAME_N_COMPUTED_FACES (f);
348 int i;
349
350 if (!font || font == ((XFontStruct *) FACE_DEFAULT))
351 return;
352
353 BLOCK_INPUT;
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++)
357 {
358 struct face *face = FRAME_COMPUTED_FACES (f)[i];
359 if (face->font == font)
360 {
361 Display *dpy = FRAME_X_DISPLAY (f);
362 if (face->gc)
363 XFreeGC (dpy, face->gc);
364 face->gc = 0;
365 /* This marks the computed face as available to reuse. */
366 face->font = 0;
367 }
368 }
369
370 XFreeFont (FRAME_X_DISPLAY (f), font);
371 UNBLOCK_INPUT;
372 }
373
374 static unsigned long
375 load_color (f, name)
376 struct frame *f;
377 Lisp_Object name;
378 {
379 XColor color;
380 int result;
381
382 if (NILP (name))
383 return FACE_DEFAULT;
384
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);
389 if (! result)
390 Fsignal (Qerror, Fcons (build_string ("undefined color"),
391 Fcons (name, Qnil)));
392 return (unsigned long) color.pixel;
393 }
394
395 static void
396 unload_color (f, pixel)
397 struct frame *f;
398 unsigned long pixel;
399 {
400 Colormap cmap;
401 Display *dpy = FRAME_X_DISPLAY (f);
402 int class = FRAME_X_DISPLAY_INFO (f)->visual->class;
403
404 if (pixel == FACE_DEFAULT
405 || pixel == BLACK_PIX_DEFAULT (f)
406 || pixel == WHITE_PIX_DEFAULT (f))
407 return;
408 cmap = DefaultColormapOfScreen (DefaultScreenOfDisplay (dpy));
409
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))
413 {
414 int len = FRAME_N_COMPUTED_FACES (f);
415 int i;
416
417 BLOCK_INPUT;
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++)
421 {
422 struct face *face = FRAME_COMPUTED_FACES (f)[i];
423 if (face->foreground == pixel
424 || face->background == pixel)
425 {
426 Display *dpy = FRAME_X_DISPLAY (f);
427 if (face->gc)
428 XFreeGC (dpy, face->gc);
429 face->gc = 0;
430 /* This marks the computed face as available to reuse. */
431 face->font = 0;
432 }
433 }
434
435 XFreeColors (dpy, cmap, &pixel, 1, (unsigned long)0);
436 UNBLOCK_INPUT;
437 }
438 }
439
440 DEFUN ("pixmap-spec-p", Fpixmap_spec_p, Spixmap_spec_p, 1, 1, 0,
441 "Return t if OBJECT is a valid pixmap specification.")
442 (object)
443 Lisp_Object object;
444 {
445 Lisp_Object height, width;
446
447 return ((STRINGP (object)
448 || (CONSP (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)
455 && XINT (width) > 0
456 && XINT (height) > 0
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))))
461 ? Qt : Qnil);
462 }
463
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.
467
468 Store the bitmap width in *W_PTR and height in *H_PTR. */
469
470 static long
471 load_pixmap (f, name, w_ptr, h_ptr)
472 FRAME_PTR f;
473 Lisp_Object name;
474 unsigned int *w_ptr, *h_ptr;
475 {
476 int bitmap_id;
477 Lisp_Object tem;
478
479 if (NILP (name))
480 return FACE_DEFAULT;
481
482 tem = Fpixmap_spec_p (name);
483 if (NILP (tem))
484 wrong_type_argument (Qpixmap_spec_p, name);
485
486 BLOCK_INPUT;
487
488 if (CONSP (name))
489 {
490 /* Decode a bitmap spec into a bitmap. */
491
492 int h, w;
493 Lisp_Object bits;
494
495 w = XINT (Fcar (name));
496 h = XINT (Fcar (Fcdr (name)));
497 bits = Fcar (Fcdr (Fcdr (name)));
498
499 bitmap_id = x_create_bitmap_from_data (f, XSTRING (bits)->data,
500 w, h);
501 }
502 else
503 {
504 /* It must be a string -- a file name. */
505 bitmap_id = x_create_bitmap_from_file (f, name);
506 }
507 UNBLOCK_INPUT;
508
509 if (bitmap_id < 0)
510 Fsignal (Qerror, Fcons (build_string ("invalid or undefined bitmap"),
511 Fcons (name, Qnil)));
512
513 *w_ptr = x_bitmap_width (f, bitmap_id);
514 *h_ptr = x_bitmap_height (f, bitmap_id);
515
516 return bitmap_id;
517 }
518
519 #else /* !HAVE_X_WINDOWS */
520
521 /* Stubs for MSDOS when not under X. */
522
523 struct face *
524 intern_face (f, face)
525 struct frame *f;
526 struct face *face;
527 {
528 return face;
529 }
530
531 void
532 clear_face_cache ()
533 {
534 /* No action. */
535 }
536
537 #ifdef MSDOS
538 unsigned long
539 load_color (f, name)
540 FRAME_PTR f;
541 Lisp_Object name;
542 {
543 Lisp_Object result;
544
545 if (NILP (name))
546 return FACE_DEFAULT;
547
548 CHECK_STRING (name, 0);
549 result = call1 (Qmsdos_color_translate, name);
550 if (INTEGERP (result))
551 return XINT (result);
552 else
553 Fsignal (Qerror, Fcons (build_string ("undefined color"),
554 Fcons (name, Qnil)));
555 }
556 #endif
557 #endif /* !HAVE_X_WINDOWS */
558
559 \f
560 /* Managing parameter face arrays for frames. */
561
562 void
563 init_frame_faces (f)
564 FRAME_PTR f;
565 {
566 ensure_face_ready (f, 0);
567 ensure_face_ready (f, 1);
568
569 FRAME_N_COMPUTED_FACES (f) = 0;
570 FRAME_SIZE_COMPUTED_FACES (f) = 0;
571
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);
575
576 /* Find another X frame. */
577 {
578 Lisp_Object tail, frame, result;
579
580 result = Qnil;
581 FOR_EACH_FRAME (tail, frame)
582 if ((FRAME_MSDOS_P (XFRAME (frame)) || FRAME_X_P (XFRAME (frame)))
583 && XFRAME (frame) != f)
584 {
585 result = frame;
586 break;
587 }
588
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. */
593 if (FRAMEP (result))
594 {
595 int i;
596 int n_faces = FRAME_N_PARAM_FACES (XFRAME (result));
597 struct face **faces = FRAME_PARAM_FACES (XFRAME (result));
598
599 for (i = 2; i < n_faces; i++)
600 if (faces[i])
601 ensure_face_ready (f, i);
602 }
603 }
604 }
605
606
607 /* Called from Fdelete_frame. */
608
609 void
610 free_frame_faces (f)
611 struct frame *f;
612 {
613 Display *dpy = FRAME_X_DISPLAY (f);
614 int i;
615
616 BLOCK_INPUT;
617
618 for (i = 0; i < FRAME_N_PARAM_FACES (f); i++)
619 {
620 struct face *face = FRAME_PARAM_FACES (f) [i];
621 if (face)
622 {
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);
628 xfree (face);
629 }
630 }
631 xfree (FRAME_PARAM_FACES (f));
632 FRAME_PARAM_FACES (f) = 0;
633 FRAME_N_PARAM_FACES (f) = 0;
634
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++)
639 {
640 struct face *face = FRAME_COMPUTED_FACES (f) [i];
641 if (face)
642 {
643 if (face->gc)
644 {
645 XFreeGC (dpy, face->gc);
646 XFreeGC (dpy, face->non_ascii_gc);
647 }
648 xfree (face);
649 }
650 }
651 xfree (FRAME_COMPUTED_FACES (f));
652 FRAME_COMPUTED_FACES (f) = 0;
653 FRAME_N_COMPUTED_FACES (f) = 0;
654
655 UNBLOCK_INPUT;
656 }
657 \f
658 /* Interning faces in a frame's face array. */
659
660 static int
661 new_computed_face (f, new_face)
662 struct frame *f;
663 struct face *new_face;
664 {
665 int len = FRAME_N_COMPUTED_FACES (f);
666 int i;
667
668 /* Search for an unused computed face in the middle of the table. */
669 for (i = 0; i < len; i++)
670 {
671 struct face *face = FRAME_COMPUTED_FACES (f)[i];
672 if (face->font == 0)
673 {
674 FRAME_COMPUTED_FACES (f)[i] = copy_face (new_face);
675 return i;
676 }
677 }
678
679 if (i >= FRAME_SIZE_COMPUTED_FACES (f))
680 {
681 int new_size = i + 32;
682
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;
689 }
690
691 i = FRAME_N_COMPUTED_FACES (f)++;
692 FRAME_COMPUTED_FACES (f)[i] = copy_face (new_face);
693 return i;
694 }
695
696
697 /* Find a match for NEW_FACE in a FRAME's computed face array, and add
698 it if we don't find one. */
699 static int
700 intern_computed_face (f, new_face)
701 struct frame *f;
702 struct face *new_face;
703 {
704 int len = FRAME_N_COMPUTED_FACES (f);
705 int i;
706
707 /* Search for a computed face already on F equivalent to FACE. */
708 for (i = 0; i < len; i++)
709 {
710 if (! FRAME_COMPUTED_FACES (f)[i])
711 abort ();
712 if (face_eql (new_face, FRAME_COMPUTED_FACES (f)[i]))
713 return i;
714 }
715
716 /* We didn't find one; add a new one. */
717 return new_computed_face (f, new_face);
718 }
719
720 /* Make parameter face id ID valid on frame F. */
721
722 static void
723 ensure_face_ready (f, id)
724 struct frame *f;
725 int id;
726 {
727 if (FRAME_N_PARAM_FACES (f) <= id)
728 {
729 int n = id + 10;
730 int i;
731 if (!FRAME_N_PARAM_FACES (f))
732 FRAME_PARAM_FACES (f)
733 = (struct face **) xmalloc (sizeof (struct face *) * n);
734 else
735 FRAME_PARAM_FACES (f)
736 = (struct face **) xrealloc (FRAME_PARAM_FACES (f),
737 sizeof (struct face *) * n);
738
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;
742 }
743
744 if (FRAME_PARAM_FACES (f) [id] == 0)
745 FRAME_PARAM_FACES (f) [id] = allocate_face ();
746 }
747 \f
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
751 different heights.
752 We assume that they're both character-cell fonts. */
753
754 int
755 same_size_fonts (font1, font2)
756 XFontStruct *font1, *font2;
757 {
758 XCharStruct *bounds1 = &font1->min_bounds;
759 XCharStruct *bounds2 = &font2->min_bounds;
760
761 return (bounds1->width == bounds2->width);
762 }
763
764 /* Update the line_height of frame F according to the biggest font in
765 any face. Return nonzero if if line_height changes. */
766
767 int
768 frame_update_line_height (f)
769 FRAME_PTR f;
770 {
771 int i;
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));
776
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)
780 {
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));
784
785 if (height > biggest)
786 biggest = height;
787 }
788
789 if (biggest == f->output_data.x->line_height)
790 return 0;
791
792 f->output_data.x->line_height = biggest;
793 return 1;
794 }
795 #endif /* not HAVE_X_WINDOWS */
796 \f
797 /* Modify face TO by copying from FROM all properties which have
798 nondefault settings. */
799
800 static void
801 merge_faces (from, to)
802 struct face *from, *to;
803 {
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)
816 {
817 to->stipple = from->stipple;
818 to->pixmap_h = from->pixmap_h;
819 to->pixmap_w = from->pixmap_w;
820 }
821 if (from->underline)
822 to->underline = from->underline;
823 }
824
825 /* Set up the basic set of facial parameters, based on the frame's
826 data; all faces are deltas applied to this. */
827
828 static void
829 compute_base_face (f, face)
830 FRAME_PTR f;
831 struct face *face;
832 {
833 face->gc = 0;
834 face->foreground = FRAME_FOREGROUND_PIXEL (f);
835 face->background = FRAME_BACKGROUND_PIXEL (f);
836 face->font = FRAME_FONT (f);
837 face->fontset = -1;
838 face->stipple = 0;
839 face->underline = 0;
840 }
841
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. */
845
846 int
847 compute_glyph_face (f, face_code, current_face)
848 struct frame *f;
849 int face_code, current_face;
850 {
851 struct face face;
852
853 face = *FRAME_COMPUTED_FACES (f)[current_face];
854
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);
858
859 return intern_computed_face (f, &face);
860 }
861
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. */
865
866 int
867 compute_glyph_face_1 (f, face_name, current_face)
868 struct frame *f;
869 Lisp_Object face_name;
870 int current_face;
871 {
872 struct face face;
873
874 face = *FRAME_COMPUTED_FACES (f)[current_face];
875
876 if (!NILP (face_name))
877 {
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);
882 }
883
884 return intern_computed_face (f, &face);
885 }
886 \f
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
891 the current buffer.
892
893 REGION_BEG, REGION_END delimit the region, so it can be highlighted.
894
895 LIMIT is a position not to scan beyond. That is to limit
896 the time this function can take.
897
898 If MOUSE is nonzero, use the character's mouse-face, not its face. */
899
900 int
901 compute_char_face (f, w, pos, region_beg, region_end, endptr, limit, mouse)
902 struct frame *f;
903 struct window *w;
904 int pos;
905 int region_beg, region_end;
906 int *endptr;
907 int limit;
908 int mouse;
909 {
910 struct face face;
911 Lisp_Object prop, position;
912 int i, j, noverlays;
913 int facecode;
914 Lisp_Object *overlay_vec;
915 Lisp_Object frame;
916 int endpos;
917 Lisp_Object propname;
918
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)
922 abort ();
923
924 XSETFRAME (frame, f);
925
926 endpos = ZV;
927 if (pos < region_beg && region_beg < endpos)
928 endpos = region_beg;
929
930 XSETFASTINT (position, pos);
931
932 if (mouse)
933 propname = Qmouse_face;
934 else
935 propname = Qface;
936
937 prop = Fget_text_property (position, propname, w->buffer);
938
939 {
940 Lisp_Object limit1, end;
941
942 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
943 end = Fnext_single_property_change (position, propname, w->buffer, limit1);
944 if (INTEGERP (end))
945 endpos = XINT (end);
946 }
947
948 {
949 int next_overlay;
950 int len;
951
952 /* First try with room for 40 overlays. */
953 len = 40;
954 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
955
956 noverlays = overlays_at (pos, 0, &overlay_vec, &len,
957 &next_overlay, (int *) 0);
958
959 /* If there are more than 40,
960 make enough space for all, and try again. */
961 if (noverlays > len)
962 {
963 len = noverlays;
964 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
965 noverlays = overlays_at (pos, 0, &overlay_vec, &len,
966 &next_overlay, (int *) 0);
967 }
968
969 if (next_overlay < endpos)
970 endpos = next_overlay;
971 }
972
973 *endptr = endpos;
974
975 /* Optimize the default case. */
976 if (noverlays == 0 && NILP (prop)
977 && !(pos >= region_beg && pos < region_end))
978 return 0;
979
980 compute_base_face (f, &face);
981
982 if (CONSP (prop))
983 {
984 /* We have a list of faces, merge them in reverse order */
985 Lisp_Object length;
986 int len;
987 Lisp_Object *faces;
988
989 length = Fsafe_length (prop);
990 len = XFASTINT (length);
991
992 /* Put them into an array */
993 faces = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
994 for (j = 0; j < len; j++)
995 {
996 faces[j] = Fcar (prop);
997 prop = Fcdr (prop);
998 }
999 /* So that we can merge them in the reverse order */
1000 for (j = len - 1; j >= 0; j--)
1001 {
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);
1006 }
1007 }
1008 else if (!NILP (prop))
1009 {
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);
1014 }
1015
1016 noverlays = sort_overlays (overlay_vec, noverlays, w);
1017
1018 /* Now merge the overlay data in that order. */
1019 for (i = 0; i < noverlays; i++)
1020 {
1021 prop = Foverlay_get (overlay_vec[i], propname);
1022 if (CONSP (prop))
1023 {
1024 /* We have a list of faces, merge them in reverse order */
1025 Lisp_Object length;
1026 int len;
1027 Lisp_Object *faces;
1028
1029 length = Fsafe_length (prop);
1030 len = XFASTINT (length);
1031
1032 /* Put them into an array */
1033 faces = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
1034 for (j = 0; j < len; j++)
1035 {
1036 faces[j] = Fcar (prop);
1037 prop = Fcdr (prop);
1038 }
1039 /* So that we can merge them in the reverse order */
1040 for (j = len - 1; j >= 0; j--)
1041 {
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);
1046 }
1047 }
1048 else if (!NILP (prop))
1049 {
1050 Lisp_Object oend;
1051 int oendpos;
1052
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);
1057
1058 oend = OVERLAY_END (overlay_vec[i]);
1059 oendpos = OVERLAY_POSITION (oend);
1060 if (oendpos < endpos)
1061 endpos = oendpos;
1062 }
1063 }
1064
1065 if (pos >= region_beg && pos < region_end)
1066 {
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);
1071 }
1072
1073 *endptr = endpos;
1074
1075 return intern_computed_face (f, &face);
1076 }
1077 \f
1078 /* Recompute the GC's for the default and modeline faces.
1079 We call this after changing frame parameters on which those GC's
1080 depend. */
1081
1082 void
1083 recompute_basic_faces (f)
1084 FRAME_PTR f;
1085 {
1086 /* If the frame's faces haven't been initialized yet, don't worry about
1087 this stuff. */
1088 if (FRAME_N_PARAM_FACES (f) < 2)
1089 return;
1090
1091 BLOCK_INPUT;
1092
1093 if (FRAME_DEFAULT_FACE (f)->gc)
1094 {
1095 XFreeGC (FRAME_X_DISPLAY (f), FRAME_DEFAULT_FACE (f)->gc);
1096 XFreeGC (FRAME_X_DISPLAY (f), FRAME_DEFAULT_FACE (f)->non_ascii_gc);
1097 }
1098 if (FRAME_MODE_LINE_FACE (f)->gc)
1099 {
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);
1102 }
1103 compute_base_face (f, FRAME_DEFAULT_FACE (f));
1104 compute_base_face (f, FRAME_MODE_LINE_FACE (f));
1105
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));
1108
1109 intern_face (f, FRAME_DEFAULT_FACE (f));
1110 intern_face (f, FRAME_MODE_LINE_FACE (f));
1111
1112 UNBLOCK_INPUT;
1113 }
1114
1115
1116 \f
1117 /* Lisp interface. */
1118
1119 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist, 1, 1, 0,
1120 "")
1121 (frame)
1122 Lisp_Object frame;
1123 {
1124 CHECK_FRAME (frame, 0);
1125 return XFRAME (frame)->face_alist;
1126 }
1127
1128 DEFUN ("set-frame-face-alist", Fset_frame_face_alist, Sset_frame_face_alist,
1129 2, 2, 0, "")
1130 (frame, value)
1131 Lisp_Object frame, value;
1132 {
1133 CHECK_FRAME (frame, 0);
1134 XFRAME (frame)->face_alist = value;
1135 return value;
1136 }
1137
1138
1139 DEFUN ("make-face-internal", Fmake_face_internal, Smake_face_internal, 1, 1, 0,
1140 "Create face number FACE-ID on all frames.")
1141 (face_id)
1142 Lisp_Object face_id;
1143 {
1144 Lisp_Object rest, frame;
1145 int id = XINT (face_id);
1146
1147 CHECK_NUMBER (face_id, 0);
1148 if (id < 0 || id >= next_face_id)
1149 error ("Face id out of range");
1150
1151 FOR_EACH_FRAME (rest, frame)
1152 {
1153 if (FRAME_MSDOS_P (XFRAME (frame)) || FRAME_X_P (XFRAME (frame)))
1154 ensure_face_ready (XFRAME (frame), id);
1155 }
1156 return Qnil;
1157 }
1158
1159
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;
1164 {
1165 struct face *face;
1166 struct frame *f;
1167 int magic_p;
1168 int id;
1169 int garbaged = 0;
1170
1171 CHECK_FRAME (frame, 0);
1172 CHECK_NUMBER (face_id, 0);
1173 CHECK_SYMBOL (attr_name, 0);
1174
1175 f = XFRAME (frame);
1176 id = XINT (face_id);
1177 if (id < 0 || id >= next_face_id)
1178 error ("Face id out of range");
1179
1180 if (! FRAME_X_P (f) && ! FRAME_MSDOS_P (f))
1181 return Qnil;
1182
1183 ensure_face_ready (f, id);
1184 face = FRAME_PARAM_FACES (f) [XFASTINT (face_id)];
1185
1186 if (EQ (attr_name, intern ("font")))
1187 {
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 ;
1192 #else
1193 XFontStruct *font;
1194 int fontset;
1195
1196 if (NILP (attr_value))
1197 {
1198 font = (XFontStruct *) FACE_DEFAULT;
1199 fontset = -1;
1200 }
1201 else
1202 {
1203 CHECK_STRING (attr_value, 0);
1204 fontset = fs_query_fontset (f, XSTRING (attr_value)->data);
1205 if (fontset >= 0)
1206 {
1207 struct font_info *fontp;
1208
1209 if (!(fontp = fs_load_font (f, FRAME_X_FONT_TABLE (f),
1210 CHARSET_ASCII, NULL, fontset)))
1211 Fsignal (Qerror,
1212 Fcons (build_string ("ASCII font can't be loaded"),
1213 Fcons (attr_value, Qnil)));
1214 font = (XFontStruct *) (fontp->font);
1215 }
1216 else
1217 font = load_font (f, attr_value);
1218 }
1219
1220 if (face->fontset == -1 && face->font != f->output_data.x->font)
1221 unload_font (f, face->font);
1222
1223 face->font = 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. */
1229 garbaged = 1;
1230 #endif
1231 }
1232 else if (EQ (attr_name, intern ("foreground")))
1233 {
1234 unsigned long new_color = load_color (f, attr_value);
1235 unload_color (f, face->foreground);
1236 face->foreground = new_color;
1237 garbaged = 1;
1238 }
1239 else if (EQ (attr_name, intern ("background")))
1240 {
1241 unsigned long new_color = load_color (f, attr_value);
1242 unload_color (f, face->background);
1243 face->background = new_color;
1244 garbaged = 1;
1245 }
1246 else if (EQ (attr_name, intern ("background-pixmap")))
1247 {
1248 unsigned int w, h;
1249 unsigned long new_pixmap = load_pixmap (f, attr_value, &w, &h);
1250 x_destroy_bitmap (f, face->stipple);
1251 face->stipple = new_pixmap;
1252 face->pixmap_w = w;
1253 face->pixmap_h = h;
1254 garbaged = 1;
1255 }
1256 else if (EQ (attr_name, intern ("underline")))
1257 {
1258 int new = !NILP (attr_value);
1259 face->underline = new;
1260 }
1261 else
1262 error ("unknown face attribute");
1263
1264 if (id == 0 || id == 1)
1265 recompute_basic_faces (f);
1266
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. */
1272 if (garbaged)
1273 {
1274 SET_FRAME_GARBAGED (f);
1275 FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 1;
1276 }
1277
1278 return Qnil;
1279 }
1280
1281 DEFUN ("internal-next-face-id", Finternal_next_face_id, Sinternal_next_face_id,
1282 0, 0, 0, "")
1283 ()
1284 {
1285 return make_number (next_face_id++);
1286 }
1287
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.) */
1292
1293 int
1294 face_name_id_number (f, name)
1295 FRAME_PTR f;
1296 Lisp_Object name;
1297 {
1298 Lisp_Object tem;
1299
1300 tem = Fcdr (assq_no_quit (name, f->face_alist));
1301 if (NILP (tem))
1302 return 0;
1303 CHECK_VECTOR (tem, 0);
1304 tem = XVECTOR (tem)->contents[2];
1305 CHECK_NUMBER (tem, 0);
1306 return XINT (tem);
1307 }
1308 \f
1309 /* Emacs initialization. */
1310
1311 void
1312 syms_of_xfaces ()
1313 {
1314 Qface = intern ("face");
1315 staticpro (&Qface);
1316 Qmouse_face = intern ("mouse-face");
1317 staticpro (&Qmouse_face);
1318 Qpixmap_spec_p = intern ("pixmap-spec-p");
1319 staticpro (&Qpixmap_spec_p);
1320
1321 DEFVAR_INT ("region-face", &region_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.");
1325
1326 #ifdef HAVE_X_WINDOWS
1327 defsubr (&Spixmap_spec_p);
1328 #endif
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);
1334 }
1335
1336 #endif /* HAVE_FACES */