]> code.delx.au - gnu-emacs/blob - src/xfaces.c
(CODING_CATEGORY_MASK_BINARY): New macro.
[gnu-emacs] / 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 #include "frame.h"
32
33 /* The number of face-id's in use (same for all frames). */
34 static int next_face_id;
35
36 #ifdef HAVE_FACES
37
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"
50
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
57
58 #include <time.h>
59 #undef USG
60 #include <X11/Xos.h>
61 #define USG
62 #define __TIMEVAL__
63
64 #else
65
66 #include <X11/Xos.h>
67
68 #endif
69 #endif /* HAVE_X_WINDOWS */
70 \f
71 /* An explanation of the face data structures. */
72
73 /* ========================= Face Data Structures =========================
74
75 Let FACE-NAME be a symbol naming a face.
76
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.)
94
95 (assq FACE-NAME global-face-data) returns a vector describing the
96 global parameters for that face.
97
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.)
109
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.
122
123 Each computed face belongs to a particular frame.
124
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.
131
132 If a computed face has 0 as its font,
133 it is unused, and can be reused by new_computed_face.
134
135 Constraints:
136
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.
140
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.
145
146 Some subtleties:
147
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. */
155 \f
156 /* Definitions and declarations. */
157
158 /* The number of the face to use to indicate the region. */
159 static int region_face;
160
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)
164
165 Lisp_Object Qface, Qmouse_face;
166 Lisp_Object Qpixmap_spec_p;
167
168 int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ );
169
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 \f
176 /* Allocating, copying, and comparing struct faces. */
177
178 /* Allocate a new face */
179 static struct face *
180 allocate_face ()
181 {
182 struct face *result = (struct face *) xmalloc (sizeof (struct face));
183 bzero (result, sizeof (struct face));
184 result->font = (XFontStruct *) FACE_DEFAULT;
185 result->fontset = -1;
186 result->foreground = FACE_DEFAULT;
187 result->background = FACE_DEFAULT;
188 result->stipple = FACE_DEFAULT;
189 return result;
190 }
191
192 /* Make a new face that's a copy of an existing one. */
193 static struct face *
194 copy_face (face)
195 struct face *face;
196 {
197 struct face *result = allocate_face ();
198
199 result->font = face->font;
200 result->fontset = face->fontset;
201 result->foreground = face->foreground;
202 result->background = face->background;
203 result->stipple = face->stipple;
204 result->underline = face->underline;
205 result->pixmap_h = face->pixmap_h;
206 result->pixmap_w = face->pixmap_w;
207
208 return result;
209 }
210
211 static int
212 face_eql (face1, face2)
213 struct face *face1, *face2;
214 {
215 return ( face1->font == face2->font
216 && face1->fontset == face2->fontset
217 && face1->foreground == face2->foreground
218 && face1->background == face2->background
219 && face1->stipple == face2->stipple
220 && face1->underline == face2->underline);
221 }
222 \f
223 /* Managing graphics contexts of faces. */
224
225 #ifdef HAVE_X_WINDOWS
226 /* Given a computed face, construct its graphics context if necessary. */
227
228 struct face *
229 intern_face (f, face)
230 struct frame *f;
231 struct face *face;
232 {
233 GC gc;
234 XGCValues xgcv;
235 unsigned long mask;
236
237 if (face->gc)
238 return face;
239
240 BLOCK_INPUT;
241
242 if (face->foreground != FACE_DEFAULT)
243 xgcv.foreground = face->foreground;
244 else
245 xgcv.foreground = f->output_data.x->foreground_pixel;
246
247 if (face->background != FACE_DEFAULT)
248 xgcv.background = face->background;
249 else
250 xgcv.background = f->output_data.x->background_pixel;
251
252 if (face->font && face->font != (XFontStruct *) FACE_DEFAULT)
253 xgcv.font = face->font->fid;
254 else
255 xgcv.font = f->output_data.x->font->fid;
256
257 xgcv.graphics_exposures = 0;
258
259 mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
260 if (face->stipple && face->stipple != FACE_DEFAULT)
261 {
262 xgcv.fill_style = FillStippled;
263 xgcv.stipple = x_bitmap_pixmap (f, face->stipple);
264 mask |= GCFillStyle | GCStipple;
265 }
266
267 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
268 mask, &xgcv);
269
270 face->gc = gc;
271 /* We used the following GC for all non-ASCII characters by changing
272 only GCfont each time. */
273 face->non_ascii_gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
274 mask, &xgcv);
275
276 UNBLOCK_INPUT;
277
278 return face;
279 }
280
281 /* Clear out all graphics contexts for all computed faces
282 except for the default and mode line faces.
283 This should be done from time to time just to avoid
284 keeping too many graphics contexts that are no longer needed. */
285
286 void
287 clear_face_cache ()
288 {
289 Lisp_Object tail, frame;
290
291 BLOCK_INPUT;
292 FOR_EACH_FRAME (tail, frame)
293 {
294 FRAME_PTR f = XFRAME (frame);
295 if (FRAME_X_P (f))
296 {
297 int i;
298 Display *dpy = FRAME_X_DISPLAY (f);
299
300 for (i = 2; i < FRAME_N_COMPUTED_FACES (f); i++)
301 {
302 struct face *face = FRAME_COMPUTED_FACES (f) [i];
303 if (face->gc)
304 {
305 XFreeGC (dpy, face->gc);
306 XFreeGC (dpy, face->non_ascii_gc);
307 }
308 face->gc = 0;
309 }
310 }
311 }
312
313 UNBLOCK_INPUT;
314 }
315 \f
316 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps.
317
318 These functions operate on param faces only.
319 Computed faces get their fonts, colors and pixmaps
320 by merging param faces. */
321
322 static XFontStruct *
323 load_font (f, name)
324 struct frame *f;
325 Lisp_Object name;
326 {
327 XFontStruct *font;
328
329 if (NILP (name))
330 return (XFontStruct *) FACE_DEFAULT;
331
332 CHECK_STRING (name, 0);
333 BLOCK_INPUT;
334 font = XLoadQueryFont (FRAME_X_DISPLAY (f), (char *) XSTRING (name)->data);
335 UNBLOCK_INPUT;
336
337 if (! font)
338 Fsignal (Qerror, Fcons (build_string ("undefined font"),
339 Fcons (name, Qnil)));
340 return font;
341 }
342
343 static void
344 unload_font (f, font)
345 struct frame *f;
346 XFontStruct *font;
347 {
348 int len = FRAME_N_COMPUTED_FACES (f);
349 int i;
350
351 if (!font || font == ((XFontStruct *) FACE_DEFAULT))
352 return;
353
354 BLOCK_INPUT;
355 /* Invalidate any computed faces which use this font,
356 and free their GC's if they have any. */
357 for (i = 2; i < len; i++)
358 {
359 struct face *face = FRAME_COMPUTED_FACES (f)[i];
360 if (face->font == font)
361 {
362 Display *dpy = FRAME_X_DISPLAY (f);
363 if (face->gc)
364 XFreeGC (dpy, face->gc);
365 face->gc = 0;
366 /* This marks the computed face as available to reuse. */
367 face->font = 0;
368 }
369 }
370
371 XFreeFont (FRAME_X_DISPLAY (f), font);
372 UNBLOCK_INPUT;
373 }
374
375 static unsigned long
376 load_color (f, name)
377 struct frame *f;
378 Lisp_Object name;
379 {
380 XColor color;
381 int result;
382
383 if (NILP (name))
384 return FACE_DEFAULT;
385
386 CHECK_STRING (name, 0);
387 /* if the colormap is full, defined_color will return a best match
388 to the values in an an existing cell. */
389 result = defined_color(f, (char *) XSTRING (name)->data, &color, 1);
390 if (! result)
391 Fsignal (Qerror, Fcons (build_string ("undefined color"),
392 Fcons (name, Qnil)));
393 return (unsigned long) color.pixel;
394 }
395
396 static void
397 unload_color (f, pixel)
398 struct frame *f;
399 unsigned long pixel;
400 {
401 Colormap cmap;
402 Display *dpy = FRAME_X_DISPLAY (f);
403 int class = FRAME_X_DISPLAY_INFO (f)->visual->class;
404
405 if (pixel == FACE_DEFAULT
406 || pixel == BLACK_PIX_DEFAULT (f)
407 || pixel == WHITE_PIX_DEFAULT (f))
408 return;
409 cmap = DefaultColormapOfScreen (DefaultScreenOfDisplay (dpy));
410
411 /* If display has an immutable color map, freeing colors is not
412 necessary and some servers don't allow it. So don't do it. */
413 if (! (class == StaticColor || class == StaticGray || class == TrueColor))
414 {
415 int len = FRAME_N_COMPUTED_FACES (f);
416 int i;
417
418 BLOCK_INPUT;
419 /* Invalidate any computed faces which use this color,
420 and free their GC's if they have any. */
421 for (i = 2; i < len; i++)
422 {
423 struct face *face = FRAME_COMPUTED_FACES (f)[i];
424 if (face->foreground == pixel
425 || face->background == pixel)
426 {
427 Display *dpy = FRAME_X_DISPLAY (f);
428 if (face->gc)
429 XFreeGC (dpy, face->gc);
430 face->gc = 0;
431 /* This marks the computed face as available to reuse. */
432 face->font = 0;
433 }
434 }
435
436 XFreeColors (dpy, cmap, &pixel, 1, (unsigned long)0);
437 UNBLOCK_INPUT;
438 }
439 }
440
441 DEFUN ("pixmap-spec-p", Fpixmap_spec_p, Spixmap_spec_p, 1, 1, 0,
442 "Return t if OBJECT is a valid pixmap specification.")
443 (object)
444 Lisp_Object object;
445 {
446 Lisp_Object height, width;
447
448 return ((STRINGP (object)
449 || (CONSP (object)
450 && CONSP (XCONS (object)->cdr)
451 && CONSP (XCONS (XCONS (object)->cdr)->cdr)
452 && NILP (XCONS (XCONS (XCONS (object)->cdr)->cdr)->cdr)
453 && (width = XCONS (object)->car, INTEGERP (width))
454 && (height = XCONS (XCONS (object)->cdr)->car, INTEGERP (height))
455 && STRINGP (XCONS (XCONS (XCONS (object)->cdr)->cdr)->car)
456 && XINT (width) > 0
457 && XINT (height) > 0
458 /* The string must have enough bits for width * height. */
459 && ((XSTRING (XCONS (XCONS (XCONS (object)->cdr)->cdr)->car)->size
460 * (BITS_PER_INT / sizeof (int)))
461 >= XFASTINT (width) * XFASTINT (height))))
462 ? Qt : Qnil);
463 }
464
465 /* Load a bitmap according to NAME (which is either a file name
466 or a pixmap spec). Return the bitmap_id (see xfns.c)
467 or get an error if NAME is invalid.
468
469 Store the bitmap width in *W_PTR and height in *H_PTR. */
470
471 static long
472 load_pixmap (f, name, w_ptr, h_ptr)
473 FRAME_PTR f;
474 Lisp_Object name;
475 unsigned int *w_ptr, *h_ptr;
476 {
477 int bitmap_id;
478 Lisp_Object tem;
479
480 if (NILP (name))
481 return FACE_DEFAULT;
482
483 tem = Fpixmap_spec_p (name);
484 if (NILP (tem))
485 wrong_type_argument (Qpixmap_spec_p, name);
486
487 BLOCK_INPUT;
488
489 if (CONSP (name))
490 {
491 /* Decode a bitmap spec into a bitmap. */
492
493 int h, w;
494 Lisp_Object bits;
495
496 w = XINT (Fcar (name));
497 h = XINT (Fcar (Fcdr (name)));
498 bits = Fcar (Fcdr (Fcdr (name)));
499
500 bitmap_id = x_create_bitmap_from_data (f, XSTRING (bits)->data,
501 w, h);
502 }
503 else
504 {
505 /* It must be a string -- a file name. */
506 bitmap_id = x_create_bitmap_from_file (f, name);
507 }
508 UNBLOCK_INPUT;
509
510 if (bitmap_id < 0)
511 Fsignal (Qerror, Fcons (build_string ("invalid or undefined bitmap"),
512 Fcons (name, Qnil)));
513
514 *w_ptr = x_bitmap_width (f, bitmap_id);
515 *h_ptr = x_bitmap_height (f, bitmap_id);
516
517 return bitmap_id;
518 }
519
520 #else /* !HAVE_X_WINDOWS */
521
522 /* Stubs for MSDOS when not under X. */
523
524 struct face *
525 intern_face (f, face)
526 struct frame *f;
527 struct face *face;
528 {
529 return face;
530 }
531
532 void
533 clear_face_cache ()
534 {
535 /* No action. */
536 }
537
538 #ifdef MSDOS
539 unsigned long
540 load_color (f, name)
541 FRAME_PTR f;
542 Lisp_Object name;
543 {
544 Lisp_Object result;
545
546 if (NILP (name))
547 return FACE_DEFAULT;
548
549 CHECK_STRING (name, 0);
550 result = call1 (Qmsdos_color_translate, name);
551 if (INTEGERP (result))
552 return XINT (result);
553 else
554 Fsignal (Qerror, Fcons (build_string ("undefined color"),
555 Fcons (name, Qnil)));
556 }
557 #endif
558 #endif /* !HAVE_X_WINDOWS */
559
560 \f
561 /* Managing parameter face arrays for frames. */
562
563 void
564 init_frame_faces (f)
565 FRAME_PTR f;
566 {
567 ensure_face_ready (f, 0);
568 ensure_face_ready (f, 1);
569
570 FRAME_N_COMPUTED_FACES (f) = 0;
571 FRAME_SIZE_COMPUTED_FACES (f) = 0;
572
573 new_computed_face (f, FRAME_PARAM_FACES (f)[0]);
574 new_computed_face (f, FRAME_PARAM_FACES (f)[1]);
575 recompute_basic_faces (f);
576
577 /* Find another X frame. */
578 {
579 Lisp_Object tail, frame, result;
580
581 result = Qnil;
582 FOR_EACH_FRAME (tail, frame)
583 if ((FRAME_MSDOS_P (XFRAME (frame)) || FRAME_X_P (XFRAME (frame)))
584 && XFRAME (frame) != f)
585 {
586 result = frame;
587 break;
588 }
589
590 /* If we didn't find any X frames other than f, then we don't need
591 any faces other than 0 and 1, so we're okay. Otherwise, make
592 sure that all faces valid on the selected frame are also valid
593 on this new frame. */
594 if (FRAMEP (result))
595 {
596 int i;
597 int n_faces = FRAME_N_PARAM_FACES (XFRAME (result));
598 struct face **faces = FRAME_PARAM_FACES (XFRAME (result));
599
600 for (i = 2; i < n_faces; i++)
601 if (faces[i])
602 ensure_face_ready (f, i);
603 }
604 }
605 }
606
607
608 /* Called from Fdelete_frame. */
609
610 void
611 free_frame_faces (f)
612 struct frame *f;
613 {
614 Display *dpy = FRAME_X_DISPLAY (f);
615 int i;
616
617 BLOCK_INPUT;
618
619 for (i = 0; i < FRAME_N_PARAM_FACES (f); i++)
620 {
621 struct face *face = FRAME_PARAM_FACES (f) [i];
622 if (face)
623 {
624 if (face->fontset < 0)
625 unload_font (f, face->font);
626 unload_color (f, face->foreground);
627 unload_color (f, face->background);
628 x_destroy_bitmap (f, face->stipple);
629 xfree (face);
630 }
631 }
632 xfree (FRAME_PARAM_FACES (f));
633 FRAME_PARAM_FACES (f) = 0;
634 FRAME_N_PARAM_FACES (f) = 0;
635
636 /* All faces in FRAME_COMPUTED_FACES use resources copied from
637 FRAME_PARAM_FACES; we can free them without fuss.
638 But we do free the GCs and the face objects themselves. */
639 for (i = 0; i < FRAME_N_COMPUTED_FACES (f); i++)
640 {
641 struct face *face = FRAME_COMPUTED_FACES (f) [i];
642 if (face)
643 {
644 if (face->gc)
645 {
646 XFreeGC (dpy, face->gc);
647 XFreeGC (dpy, face->non_ascii_gc);
648 }
649 xfree (face);
650 }
651 }
652 xfree (FRAME_COMPUTED_FACES (f));
653 FRAME_COMPUTED_FACES (f) = 0;
654 FRAME_N_COMPUTED_FACES (f) = 0;
655
656 UNBLOCK_INPUT;
657 }
658 \f
659 /* Interning faces in a frame's face array. */
660
661 static int
662 new_computed_face (f, new_face)
663 struct frame *f;
664 struct face *new_face;
665 {
666 int len = FRAME_N_COMPUTED_FACES (f);
667 int i;
668
669 /* Search for an unused computed face in the middle of the table. */
670 for (i = 0; i < len; i++)
671 {
672 struct face *face = FRAME_COMPUTED_FACES (f)[i];
673 if (face->font == 0)
674 {
675 FRAME_COMPUTED_FACES (f)[i] = copy_face (new_face);
676 return i;
677 }
678 }
679
680 if (i >= FRAME_SIZE_COMPUTED_FACES (f))
681 {
682 int new_size = i + 32;
683
684 FRAME_COMPUTED_FACES (f)
685 = (struct face **) (FRAME_SIZE_COMPUTED_FACES (f) == 0
686 ? xmalloc (new_size * sizeof (struct face *))
687 : xrealloc (FRAME_COMPUTED_FACES (f),
688 new_size * sizeof (struct face *)));
689 FRAME_SIZE_COMPUTED_FACES (f) = new_size;
690 }
691
692 i = FRAME_N_COMPUTED_FACES (f)++;
693 FRAME_COMPUTED_FACES (f)[i] = copy_face (new_face);
694 return i;
695 }
696
697
698 /* Find a match for NEW_FACE in a FRAME's computed face array, and add
699 it if we don't find one. */
700 static int
701 intern_computed_face (f, new_face)
702 struct frame *f;
703 struct face *new_face;
704 {
705 int len = FRAME_N_COMPUTED_FACES (f);
706 int i;
707
708 /* Search for a computed face already on F equivalent to FACE. */
709 for (i = 0; i < len; i++)
710 {
711 if (! FRAME_COMPUTED_FACES (f)[i])
712 abort ();
713 if (face_eql (new_face, FRAME_COMPUTED_FACES (f)[i]))
714 return i;
715 }
716
717 /* We didn't find one; add a new one. */
718 return new_computed_face (f, new_face);
719 }
720
721 /* Make parameter face id ID valid on frame F. */
722
723 static void
724 ensure_face_ready (f, id)
725 struct frame *f;
726 int id;
727 {
728 if (FRAME_N_PARAM_FACES (f) <= id)
729 {
730 int n = id + 10;
731 int i;
732 if (!FRAME_N_PARAM_FACES (f))
733 FRAME_PARAM_FACES (f)
734 = (struct face **) xmalloc (sizeof (struct face *) * n);
735 else
736 FRAME_PARAM_FACES (f)
737 = (struct face **) xrealloc (FRAME_PARAM_FACES (f),
738 sizeof (struct face *) * n);
739
740 bzero (FRAME_PARAM_FACES (f) + FRAME_N_PARAM_FACES (f),
741 (n - FRAME_N_PARAM_FACES (f)) * sizeof (struct face *));
742 FRAME_N_PARAM_FACES (f) = n;
743 }
744
745 if (FRAME_PARAM_FACES (f) [id] == 0)
746 FRAME_PARAM_FACES (f) [id] = allocate_face ();
747 }
748 \f
749 #ifdef HAVE_X_WINDOWS
750 /* Return non-zero if FONT1 and FONT2 have the same width.
751 We do not check the height, because we can now deal with
752 different heights.
753 We assume that they're both character-cell fonts. */
754
755 int
756 same_size_fonts (font1, font2)
757 XFontStruct *font1, *font2;
758 {
759 XCharStruct *bounds1 = &font1->min_bounds;
760 XCharStruct *bounds2 = &font2->min_bounds;
761
762 return (bounds1->width == bounds2->width);
763 }
764
765 /* Update the line_height of frame F according to the biggest font in
766 any face. Return nonzero if if line_height changes. */
767
768 int
769 frame_update_line_height (f)
770 FRAME_PTR f;
771 {
772 int i;
773 int fontset = f->output_data.x->fontset;
774 int biggest = (fontset > 0
775 ? FRAME_FONTSET_DATA (f)->fontset_table[fontset]->height
776 : FONT_HEIGHT (f->output_data.x->font));
777
778 for (i = 0; i < f->output_data.x->n_param_faces; i++)
779 if (f->output_data.x->param_faces[i] != 0
780 && f->output_data.x->param_faces[i]->font != (XFontStruct *) FACE_DEFAULT)
781 {
782 int height = ((fontset = f->output_data.x->param_faces[i]->fontset) > 0
783 ? FRAME_FONTSET_DATA (f)->fontset_table[fontset]->height
784 : FONT_HEIGHT (f->output_data.x->param_faces[i]->font));
785
786 if (height > biggest)
787 biggest = height;
788 }
789
790 if (biggest == f->output_data.x->line_height)
791 return 0;
792
793 f->output_data.x->line_height = biggest;
794 return 1;
795 }
796 #endif /* not HAVE_X_WINDOWS */
797 \f
798 /* Modify face TO by copying from FROM all properties which have
799 nondefault settings. */
800
801 static void
802 merge_faces (from, to)
803 struct face *from, *to;
804 {
805 /* Only merge the font if it's the same width as the base font.
806 Otherwise ignore it, since we can't handle it properly. */
807 if (from->font != (XFontStruct *) FACE_DEFAULT
808 && same_size_fonts (from->font, to->font))
809 to->font = from->font;
810 if (from->fontset != -1)
811 to->fontset = from->fontset;
812 if (from->foreground != FACE_DEFAULT)
813 to->foreground = from->foreground;
814 if (from->background != FACE_DEFAULT)
815 to->background = from->background;
816 if (from->stipple != FACE_DEFAULT)
817 {
818 to->stipple = from->stipple;
819 to->pixmap_h = from->pixmap_h;
820 to->pixmap_w = from->pixmap_w;
821 }
822 if (from->underline)
823 to->underline = from->underline;
824 }
825
826 /* Set up the basic set of facial parameters, based on the frame's
827 data; all faces are deltas applied to this. */
828
829 static void
830 compute_base_face (f, face)
831 FRAME_PTR f;
832 struct face *face;
833 {
834 face->gc = 0;
835 face->foreground = FRAME_FOREGROUND_PIXEL (f);
836 face->background = FRAME_BACKGROUND_PIXEL (f);
837 face->font = FRAME_FONT (f);
838 face->fontset = -1;
839 face->stipple = 0;
840 face->underline = 0;
841 }
842
843 /* Return the face ID to use to display a special glyph which selects
844 FACE_CODE as the face ID, assuming that ordinarily the face would
845 be CURRENT_FACE. F is the frame. */
846
847 int
848 compute_glyph_face (f, face_code, current_face)
849 struct frame *f;
850 int face_code, current_face;
851 {
852 struct face face;
853
854 face = *FRAME_COMPUTED_FACES (f)[current_face];
855
856 if (face_code >= 0 && face_code < FRAME_N_PARAM_FACES (f)
857 && FRAME_PARAM_FACES (f) [face_code] != 0)
858 merge_faces (FRAME_PARAM_FACES (f) [face_code], &face);
859
860 return intern_computed_face (f, &face);
861 }
862
863 /* Return the face ID to use to display a special glyph which selects
864 FACE_CODE as the face ID, assuming that ordinarily the face would
865 be CURRENT_FACE. F is the frame. */
866
867 int
868 compute_glyph_face_1 (f, face_name, current_face)
869 struct frame *f;
870 Lisp_Object face_name;
871 int current_face;
872 {
873 struct face face;
874
875 face = *FRAME_COMPUTED_FACES (f)[current_face];
876
877 if (!NILP (face_name))
878 {
879 int facecode = face_name_id_number (f, face_name);
880 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
881 && FRAME_PARAM_FACES (f) [facecode] != 0)
882 merge_faces (FRAME_PARAM_FACES (f) [facecode], &face);
883 }
884
885 return intern_computed_face (f, &face);
886 }
887 \f
888 /* Return the face ID associated with a buffer position POS.
889 Store into *ENDPTR the position at which a different face is needed.
890 This does not take account of glyphs that specify their own face codes.
891 F is the frame in use for display, and W is a window displaying
892 the current buffer.
893
894 REGION_BEG, REGION_END delimit the region, so it can be highlighted.
895
896 LIMIT is a position not to scan beyond. That is to limit
897 the time this function can take.
898
899 If MOUSE is nonzero, use the character's mouse-face, not its face. */
900
901 int
902 compute_char_face (f, w, pos, region_beg, region_end, endptr, limit, mouse)
903 struct frame *f;
904 struct window *w;
905 int pos;
906 int region_beg, region_end;
907 int *endptr;
908 int limit;
909 int mouse;
910 {
911 struct face face;
912 Lisp_Object prop, position;
913 int i, j, noverlays;
914 int facecode;
915 Lisp_Object *overlay_vec;
916 Lisp_Object frame;
917 int endpos;
918 Lisp_Object propname;
919
920 /* W must display the current buffer. We could write this function
921 to use the frame and buffer of W, but right now it doesn't. */
922 if (XBUFFER (w->buffer) != current_buffer)
923 abort ();
924
925 XSETFRAME (frame, f);
926
927 endpos = ZV;
928 if (pos < region_beg && region_beg < endpos)
929 endpos = region_beg;
930
931 XSETFASTINT (position, pos);
932
933 if (mouse)
934 propname = Qmouse_face;
935 else
936 propname = Qface;
937
938 prop = Fget_text_property (position, propname, w->buffer);
939
940 {
941 Lisp_Object limit1, end;
942
943 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
944 end = Fnext_single_property_change (position, propname, w->buffer, limit1);
945 if (INTEGERP (end))
946 endpos = XINT (end);
947 }
948
949 {
950 int next_overlay;
951 int len;
952
953 /* First try with room for 40 overlays. */
954 len = 40;
955 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
956
957 noverlays = overlays_at (pos, 0, &overlay_vec, &len,
958 &next_overlay, (int *) 0);
959
960 /* If there are more than 40,
961 make enough space for all, and try again. */
962 if (noverlays > len)
963 {
964 len = noverlays;
965 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
966 noverlays = overlays_at (pos, 0, &overlay_vec, &len,
967 &next_overlay, (int *) 0);
968 }
969
970 if (next_overlay < endpos)
971 endpos = next_overlay;
972 }
973
974 *endptr = endpos;
975
976 /* Optimize the default case. */
977 if (noverlays == 0 && NILP (prop)
978 && !(pos >= region_beg && pos < region_end))
979 return 0;
980
981 compute_base_face (f, &face);
982
983 if (CONSP (prop))
984 {
985 /* We have a list of faces, merge them in reverse order */
986 Lisp_Object length;
987 int len;
988 Lisp_Object *faces;
989
990 length = Fsafe_length (prop);
991 len = XFASTINT (length);
992
993 /* Put them into an array */
994 faces = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
995 for (j = 0; j < len; j++)
996 {
997 faces[j] = Fcar (prop);
998 prop = Fcdr (prop);
999 }
1000 /* So that we can merge them in the reverse order */
1001 for (j = len - 1; j >= 0; j--)
1002 {
1003 facecode = face_name_id_number (f, faces[j]);
1004 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
1005 && FRAME_PARAM_FACES (f) [facecode] != 0)
1006 merge_faces (FRAME_PARAM_FACES (f) [facecode], &face);
1007 }
1008 }
1009 else if (!NILP (prop))
1010 {
1011 facecode = face_name_id_number (f, prop);
1012 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
1013 && FRAME_PARAM_FACES (f) [facecode] != 0)
1014 merge_faces (FRAME_PARAM_FACES (f) [facecode], &face);
1015 }
1016
1017 noverlays = sort_overlays (overlay_vec, noverlays, w);
1018
1019 /* Now merge the overlay data in that order. */
1020 for (i = 0; i < noverlays; i++)
1021 {
1022 prop = Foverlay_get (overlay_vec[i], propname);
1023 if (CONSP (prop))
1024 {
1025 /* We have a list of faces, merge them in reverse order */
1026 Lisp_Object length;
1027 int len;
1028 Lisp_Object *faces;
1029
1030 length = Fsafe_length (prop);
1031 len = XFASTINT (length);
1032
1033 /* Put them into an array */
1034 faces = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
1035 for (j = 0; j < len; j++)
1036 {
1037 faces[j] = Fcar (prop);
1038 prop = Fcdr (prop);
1039 }
1040 /* So that we can merge them in the reverse order */
1041 for (j = len - 1; j >= 0; j--)
1042 {
1043 facecode = face_name_id_number (f, faces[j]);
1044 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
1045 && FRAME_PARAM_FACES (f) [facecode] != 0)
1046 merge_faces (FRAME_PARAM_FACES (f) [facecode], &face);
1047 }
1048 }
1049 else if (!NILP (prop))
1050 {
1051 Lisp_Object oend;
1052 int oendpos;
1053
1054 facecode = face_name_id_number (f, prop);
1055 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
1056 && FRAME_PARAM_FACES (f) [facecode] != 0)
1057 merge_faces (FRAME_PARAM_FACES (f)[facecode], &face);
1058
1059 oend = OVERLAY_END (overlay_vec[i]);
1060 oendpos = OVERLAY_POSITION (oend);
1061 if (oendpos < endpos)
1062 endpos = oendpos;
1063 }
1064 }
1065
1066 if (pos >= region_beg && pos < region_end)
1067 {
1068 if (region_end < endpos)
1069 endpos = region_end;
1070 if (region_face >= 0 && region_face < next_face_id)
1071 merge_faces (FRAME_PARAM_FACES (f)[region_face], &face);
1072 }
1073
1074 *endptr = endpos;
1075
1076 return intern_computed_face (f, &face);
1077 }
1078 \f
1079 /* Recompute the GC's for the default and modeline faces.
1080 We call this after changing frame parameters on which those GC's
1081 depend. */
1082
1083 void
1084 recompute_basic_faces (f)
1085 FRAME_PTR f;
1086 {
1087 /* If the frame's faces haven't been initialized yet, don't worry about
1088 this stuff. */
1089 if (FRAME_N_PARAM_FACES (f) < 2)
1090 return;
1091
1092 BLOCK_INPUT;
1093
1094 if (FRAME_DEFAULT_FACE (f)->gc)
1095 {
1096 XFreeGC (FRAME_X_DISPLAY (f), FRAME_DEFAULT_FACE (f)->gc);
1097 XFreeGC (FRAME_X_DISPLAY (f), FRAME_DEFAULT_FACE (f)->non_ascii_gc);
1098 }
1099 if (FRAME_MODE_LINE_FACE (f)->gc)
1100 {
1101 XFreeGC (FRAME_X_DISPLAY (f), FRAME_MODE_LINE_FACE (f)->gc);
1102 XFreeGC (FRAME_X_DISPLAY (f), FRAME_MODE_LINE_FACE (f)->non_ascii_gc);
1103 }
1104 compute_base_face (f, FRAME_DEFAULT_FACE (f));
1105 compute_base_face (f, FRAME_MODE_LINE_FACE (f));
1106
1107 merge_faces (FRAME_DEFAULT_PARAM_FACE (f), FRAME_DEFAULT_FACE (f));
1108 merge_faces (FRAME_MODE_LINE_PARAM_FACE (f), FRAME_MODE_LINE_FACE (f));
1109
1110 intern_face (f, FRAME_DEFAULT_FACE (f));
1111 intern_face (f, FRAME_MODE_LINE_FACE (f));
1112
1113 UNBLOCK_INPUT;
1114 }
1115
1116
1117 \f
1118 /* Lisp interface. */
1119
1120 DEFUN ("make-face-internal", Fmake_face_internal, Smake_face_internal, 1, 1, 0,
1121 "Create face number FACE-ID on all frames.")
1122 (face_id)
1123 Lisp_Object face_id;
1124 {
1125 Lisp_Object rest, frame;
1126 int id = XINT (face_id);
1127
1128 CHECK_NUMBER (face_id, 0);
1129 if (id < 0 || id >= next_face_id)
1130 error ("Face id out of range");
1131
1132 FOR_EACH_FRAME (rest, frame)
1133 {
1134 if (FRAME_MSDOS_P (XFRAME (frame)) || FRAME_X_P (XFRAME (frame)))
1135 ensure_face_ready (XFRAME (frame), id);
1136 }
1137 return Qnil;
1138 }
1139
1140
1141 DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal,
1142 Sset_face_attribute_internal, 4, 4, 0, "")
1143 (face_id, attr_name, attr_value, frame)
1144 Lisp_Object face_id, attr_name, attr_value, frame;
1145 {
1146 struct face *face;
1147 struct frame *f;
1148 int magic_p;
1149 int id;
1150 int garbaged = 0;
1151
1152 CHECK_FRAME (frame, 0);
1153 CHECK_NUMBER (face_id, 0);
1154 CHECK_SYMBOL (attr_name, 0);
1155
1156 f = XFRAME (frame);
1157 id = XINT (face_id);
1158 if (id < 0 || id >= next_face_id)
1159 error ("Face id out of range");
1160
1161 if (! FRAME_X_P (f) && ! FRAME_MSDOS_P (f))
1162 return Qnil;
1163
1164 ensure_face_ready (f, id);
1165 face = FRAME_PARAM_FACES (f) [XFASTINT (face_id)];
1166
1167 if (EQ (attr_name, intern ("font")))
1168 {
1169 #if defined (MSDOS) && !defined (HAVE_X_WINDOWS)
1170 /* The one and only font. Must *not* be zero (which
1171 is taken to mean an unused face nowadays). */
1172 face->font = (XFontStruct *)1 ;
1173 #else
1174 XFontStruct *font;
1175 int fontset;
1176
1177 if (NILP (attr_value))
1178 {
1179 font = (XFontStruct *) FACE_DEFAULT;
1180 fontset = -1;
1181 }
1182 else
1183 {
1184 CHECK_STRING (attr_value, 0);
1185 fontset = fs_query_fontset (f, XSTRING (attr_value)->data);
1186 if (fontset >= 0)
1187 {
1188 struct font_info *fontp;
1189
1190 if (!(fontp = FS_LOAD_FONT (f, FRAME_X_FONT_TABLE (f),
1191 CHARSET_ASCII, NULL, fontset)))
1192 Fsignal (Qerror,
1193 Fcons (build_string ("ASCII font can't be loaded"),
1194 Fcons (attr_value, Qnil)));
1195 font = (XFontStruct *) (fontp->font);
1196 }
1197 else
1198 font = load_font (f, attr_value);
1199 }
1200
1201 if (face->fontset == -1 && face->font != f->output_data.x->font)
1202 unload_font (f, face->font);
1203
1204 face->font = font;
1205 face->fontset = fontset;
1206 if (frame_update_line_height (f))
1207 x_set_window_size (f, 0, f->width, f->height);
1208 /* Must clear cache, since it might contain the font
1209 we just got rid of. */
1210 garbaged = 1;
1211 #endif
1212 }
1213 else if (EQ (attr_name, intern ("foreground")))
1214 {
1215 unsigned long new_color = load_color (f, attr_value);
1216 unload_color (f, face->foreground);
1217 face->foreground = new_color;
1218 garbaged = 1;
1219 }
1220 else if (EQ (attr_name, intern ("background")))
1221 {
1222 unsigned long new_color = load_color (f, attr_value);
1223 unload_color (f, face->background);
1224 face->background = new_color;
1225 garbaged = 1;
1226 }
1227 else if (EQ (attr_name, intern ("background-pixmap")))
1228 {
1229 unsigned int w, h;
1230 unsigned long new_pixmap = load_pixmap (f, attr_value, &w, &h);
1231 x_destroy_bitmap (f, face->stipple);
1232 face->stipple = new_pixmap;
1233 face->pixmap_w = w;
1234 face->pixmap_h = h;
1235 garbaged = 1;
1236 }
1237 else if (EQ (attr_name, intern ("underline")))
1238 {
1239 int new = !NILP (attr_value);
1240 face->underline = new;
1241 }
1242 else
1243 error ("unknown face attribute");
1244
1245 if (id == 0 || id == 1)
1246 recompute_basic_faces (f);
1247
1248 /* We must redraw the frame whenever any face font or color changes,
1249 because it's possible that a merged (display) face
1250 contains the font or color we just replaced.
1251 And we must inhibit any Expose events until the redraw is done,
1252 since they would try to use the invalid display faces. */
1253 if (garbaged)
1254 {
1255 SET_FRAME_GARBAGED (f);
1256 #ifdef HAVE_X_WINDOWS
1257 FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 1;
1258 #endif
1259 }
1260
1261 return Qnil;
1262 }
1263 /* Return the face id for name NAME on frame FRAME.
1264 (It should be the same for all frames,
1265 but it's as easy to use the "right" frame to look it up
1266 as to use any other one.) */
1267
1268 int
1269 face_name_id_number (f, name)
1270 FRAME_PTR f;
1271 Lisp_Object name;
1272 {
1273 Lisp_Object tem;
1274
1275 tem = Fcdr (assq_no_quit (name, f->face_alist));
1276 if (NILP (tem))
1277 return 0;
1278 CHECK_VECTOR (tem, 0);
1279 tem = XVECTOR (tem)->contents[2];
1280 CHECK_NUMBER (tem, 0);
1281 return XINT (tem);
1282 }
1283
1284 #endif /* HAVE_FACES */
1285
1286 \f
1287 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist, 1, 1, 0,
1288 "")
1289 (frame)
1290 Lisp_Object frame;
1291 {
1292 CHECK_FRAME (frame, 0);
1293 return XFRAME (frame)->face_alist;
1294 }
1295
1296 DEFUN ("set-frame-face-alist", Fset_frame_face_alist, Sset_frame_face_alist,
1297 2, 2, 0, "")
1298 (frame, value)
1299 Lisp_Object frame, value;
1300 {
1301 CHECK_FRAME (frame, 0);
1302 XFRAME (frame)->face_alist = value;
1303 return value;
1304 }
1305
1306 DEFUN ("internal-next-face-id", Finternal_next_face_id, Sinternal_next_face_id,
1307 0, 0, 0, "")
1308 ()
1309 {
1310 return make_number (next_face_id++);
1311 }
1312 \f
1313 /* Emacs initialization. */
1314
1315 void
1316 syms_of_xfaces ()
1317 {
1318 #ifdef HAVE_FACES
1319 Qface = intern ("face");
1320 staticpro (&Qface);
1321 Qmouse_face = intern ("mouse-face");
1322 staticpro (&Qmouse_face);
1323 Qpixmap_spec_p = intern ("pixmap-spec-p");
1324 staticpro (&Qpixmap_spec_p);
1325
1326 DEFVAR_INT ("region-face", &region_face,
1327 "Face number to use to highlight the region\n\
1328 The region is highlighted with this face\n\
1329 when Transient Mark mode is enabled and the mark is active.");
1330
1331 defsubr (&Smake_face_internal);
1332 defsubr (&Sset_face_attribute_internal);
1333 #endif /* HAVE_FACES */
1334
1335 #ifdef HAVE_X_WINDOWS
1336 defsubr (&Spixmap_spec_p);
1337 #endif
1338
1339 defsubr (&Sframe_face_alist);
1340 defsubr (&Sset_frame_face_alist);
1341 defsubr (&Sinternal_next_face_id);
1342 }