(compute_char_face): New arg MOUSE.
[bpt/emacs.git] / src / xfaces.c
1 /* "Face" primitives.
2 Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 /* This is derived from work by Lucid (some parts very loosely so). */
21
22 #include <sys/types.h>
23 #include <sys/stat.h>
24
25 #include <config.h>
26 #include "lisp.h"
27
28 #ifdef HAVE_X_WINDOWS
29
30 #include "xterm.h"
31 #include "buffer.h"
32 #include "dispextern.h"
33 #include "frame.h"
34 #include "blockinput.h"
35 #include "window.h"
36
37 /* Compensate for bug in Xos.h on some systems, on which it requires
38 time.h. On some such systems, Xos.h tries to redefine struct
39 timeval and struct timezone if USG is #defined while it is
40 #included. */
41 #ifdef XOS_NEEDS_TIME_H
42
43 #include <time.h>
44 #undef USG
45 #include <X11/Xos.h>
46 #define USG
47 #define __TIMEVAL__
48
49 #else
50
51 #include <X11/Xos.h>
52
53 #endif
54
55 \f
56 /* An explanation of the face data structures. */
57
58 /* ========================= Face Data Structures =========================
59
60 Let FACE-NAME be a symbol naming a face.
61
62 Let FACE-VECTOR be (assq FACE-NAME (frame-face-alist FRAME))
63 FACE-VECTOR is either nil, or a vector of the form
64 [face NAME ID FONT FOREGROUND BACKGROUND BACKGROUND-PIXMAP UNDERLINE-P]
65 where
66 face is the symbol `face',
67 NAME is the symbol with which this vector is associated (a backpointer),
68 ID is the face ID, an integer used internally by the C code to identify
69 the face,
70 FONT, FOREGROUND, and BACKGROUND are strings naming the fonts and colors
71 to use with the face,
72 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't
73 use right now, and
74 UNDERLINE-P is non-nil if the face should be underlined.
75 If any of these elements are nil, that parameter is considered
76 unspecified; parameters from faces specified by lower-priority
77 overlays or text properties, or the parameters of the frame itself,
78 can show through. (lisp/faces.el maintains these lists.)
79
80 (assq FACE-NAME global-face-data) returns a vector describing the
81 global parameters for that face.
82
83 Let PARAM-FACE be FRAME->display.x->param_faces[Faref (FACE-VECTOR, 2)].
84 PARAM_FACE is a struct face whose members are the Xlib analogues of
85 the parameters in FACE-VECTOR. If an element of FACE-VECTOR is
86 nil, then the corresponding member of PARAM_FACE is FACE_DEFAULT.
87 These faces are called "parameter faces", because they're the ones
88 lisp manipulates to control what gets displayed. Elements 0 and 1
89 of FRAME->display.x->param_faces are special - they describe the
90 default and mode line faces. None of the faces in param_faces have
91 GC's. (See src/dispextern.h for the definiton of struct face.
92 lisp/faces.el maintains the isomorphism between face_alist and
93 param_faces.)
94
95 The functions compute_char_face and compute_glyph_face find and
96 combine the parameter faces associated with overlays and text
97 properties. The resulting faces are called "computed faces"; none
98 of their members are FACE_DEFAULT; they are completely specified.
99 They then call intern_compute_face to search
100 FRAME->display.x->computed_faces for a matching face, add one if
101 none is found, and return the index into
102 FRAME->display.x->computed_faces. FRAME's glyph matrices use these
103 indices to record the faces of the matrix characters, and the X
104 display hooks consult compute_faces to decide how to display these
105 characters. Elements 0 and 1 of computed_faces always describe the
106 default and mode-line faces.
107
108 Elements 0 and 1 of computed_faces have GC's; all the other faces
109 in computed_faces do not. The global array face_vector contains
110 faces with their GC's set. Given a computed_face, the function
111 intern_face finds (or adds) an element of face_vector with
112 equivalent parameters, and returns a pointer to that face, whose GC
113 can then be used for display.
114
115 Constraints:
116
117 Symbols naming faces must have associations on all frames; for any
118 FRAME, for all FACE-NAME, if (assq FACE-NAME (frame-face-alist
119 FRAME)) is non-nil, it must be non-nil for all frames.
120
121 Analogously, indices into param_faces must be valid on all frames;
122 if param_faces[i] is a non-zero face pointer on one frame, then it
123 must be filled in on all frames. Code assumes that face ID's can
124 be used on any frame.
125
126 Some subtleties:
127
128 Why do we keep param_faces and computed_faces separate?
129 computed_faces contains an element for every combination of facial
130 parameters we have ever displayed. indices into param_faces have
131 to be valid on all frames. If they were the same array, then that
132 array would grow very large on all frames, because any facial
133 combination displayed on any frame would need to be a valid entry
134 on all frames.
135
136 Since face_vector is just a cache --- there are no pointers into it
137 from the rest of the code, and everyone accesses it through
138 intern_face --- we could just free its GC's and throw the whole
139 thing away without breaking anything. This gives us a simple way
140 to garbage-collect old GC's nobody's using any more - we can just
141 purge face_vector, and then let subsequent calls to intern_face
142 refill it as needed. The function clear_face_vector performs this
143 purge.
144
145 We're often applying intern_face to faces in computed_faces -
146 for example, we do this while sending GLYPHs from a struct
147 frame_glyphs to X during redisplay. It would be nice to avoid
148 searching all of face_vector every time we intern a frame's face.
149 So, when intern_face finds a match for FACE in face_vector, it
150 stores the index of the match in FACE's cached_index member, and
151 checks there first next time. */
152
153 \f
154 /* Definitions and declarations. */
155
156 /* A table of display faces. */
157 static struct face **face_vector;
158 /* The length in use of the table. */
159 static int nfaces;
160 /* The allocated length of the table. */
161 static int nfaces_allocated;
162
163 /* The number of face-id's in use (same for all frames). */
164 int next_face_id;
165
166 /* The number of the face to use to indicate the region. */
167 int region_face;
168
169 /* This is what appears in a slot in a face to signify that the face
170 does not specify that display aspect. */
171 #define FACE_DEFAULT (~0)
172
173 Lisp_Object Qface, Qmouse_face;
174
175 static void build_face ( /* FRAME_PTR, struct face * */ );
176 int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ );
177
178 struct face *intern_face ( /* FRAME_PTR, struct face * */ );
179 static int new_computed_face ( /* FRAME_PTR, struct face * */ );
180 static int intern_computed_face ( /* FRAME_PTR, struct face * */ );
181 static void ensure_face_ready ( /* FRAME_PTR, int id */ );
182 void recompute_basic_faces ( /* FRAME_PTR f */ );
183 \f
184 /* Allocating, copying, and comparing struct faces. */
185
186 /* Allocate a new face */
187 static struct face *
188 allocate_face ()
189 {
190 struct face *result = (struct face *) xmalloc (sizeof (struct face));
191 bzero (result, sizeof (struct face));
192 result->font = (XFontStruct *) FACE_DEFAULT;
193 result->foreground = FACE_DEFAULT;
194 result->background = FACE_DEFAULT;
195 result->stipple = FACE_DEFAULT;
196 return result;
197 }
198
199 /* Make a new face that's a copy of an existing one. */
200 static struct face *
201 copy_face (face)
202 struct face *face;
203 {
204 struct face *result = allocate_face ();
205
206 result->font = face->font;
207 result->foreground = face->foreground;
208 result->background = face->background;
209 result->stipple = face->stipple;
210 result->underline = face->underline;
211
212 return result;
213 }
214
215 static int
216 face_eql (face1, face2)
217 struct face *face1, *face2;
218 {
219 return ( face1->font == face2->font
220 && face1->foreground == face2->foreground
221 && face1->background == face2->background
222 && face1->stipple == face2->stipple
223 && face1->underline == face2->underline);
224 }
225 \f
226 /* Interning faces in the `face_vector' cache, and clearing that cache. */
227
228 /* Return the unique display face corresponding to the user-level face FACE.
229 If there isn't one, make one, and find a slot in the face_vector to
230 put it in. */
231 static struct face *
232 get_cached_face (f, face)
233 struct frame *f;
234 struct face *face;
235 {
236 int i, empty = -1;
237 struct face *result;
238
239 /* Perhaps FACE->cached_index is valid; this could happen if FACE is
240 in a frame's face list. */
241 if (face->cached_index >= 0
242 && face->cached_index < nfaces
243 && face_eql (face_vector[face->cached_index], face))
244 return face_vector[face->cached_index];
245
246 /* Look for an existing display face that does the job.
247 Also find an empty slot if any. */
248 for (i = 0; i < nfaces; i++)
249 {
250 if (face_eql (face_vector[i], face))
251 return face_vector[i];
252 if (face_vector[i] == 0)
253 empty = i;
254 }
255
256 /* If no empty slots, make one. */
257 if (empty < 0 && nfaces == nfaces_allocated)
258 {
259 int newsize = nfaces + 20;
260 face_vector
261 = (struct face **) xrealloc (face_vector,
262 newsize * sizeof (struct face *));
263 nfaces_allocated = newsize;
264 }
265
266 if (empty < 0)
267 empty = nfaces++;
268
269 /* Put a new display face in the empty slot. */
270 result = copy_face (face);
271 face_vector[empty] = result;
272
273 /* Make a graphics context for it. */
274 build_face (f, result);
275
276 return result;
277 }
278
279 /* Given a computed face, return an equivalent display face
280 (one which has a graphics context). */
281
282 struct face *
283 intern_face (f, face)
284 struct frame *f;
285 struct face *face;
286 {
287 /* If it's equivalent to the default face, use that. */
288 if (face_eql (face, FRAME_DEFAULT_FACE (f)))
289 {
290 if (!FRAME_DEFAULT_FACE (f)->gc)
291 build_face (f, FRAME_DEFAULT_FACE (f));
292 return FRAME_DEFAULT_FACE (f);
293 }
294
295 /* If it's equivalent to the mode line face, use that. */
296 if (face_eql (face, FRAME_MODE_LINE_FACE (f)))
297 {
298 if (!FRAME_MODE_LINE_FACE (f)->gc)
299 build_face (f, FRAME_MODE_LINE_FACE (f));
300 return FRAME_MODE_LINE_FACE (f);
301 }
302
303 /* If it's not one of the frame's default faces, it shouldn't have a GC. */
304 if (face->gc)
305 abort ();
306
307 /* Get a specialized display face. */
308 return get_cached_face (f, face);
309 }
310
311 /* Clear out face_vector and start anew.
312 This should be done from time to time just to avoid
313 keeping too many graphics contexts in face_vector
314 that are no longer needed. */
315
316 void
317 clear_face_vector ()
318 {
319 Lisp_Object rest;
320 Display *dpy = x_current_display;
321 int i;
322
323 BLOCK_INPUT;
324 /* Free the display faces in the face_vector. */
325 for (i = 0; i < nfaces; i++)
326 {
327 struct face *face = face_vector[i];
328 if (face->gc)
329 XFreeGC (dpy, face->gc);
330 xfree (face);
331 }
332 nfaces = 0;
333
334 UNBLOCK_INPUT;
335 }
336 \f
337 /* Allocating and freeing X resources for display faces. */
338
339 /* Make a graphics context for face FACE, which is on frame F,
340 if that can be done. */
341 static void
342 build_face (f, face)
343 struct frame *f;
344 struct face *face;
345 {
346 GC gc;
347 XGCValues xgcv;
348 unsigned long mask;
349
350 BLOCK_INPUT;
351
352 if (face->foreground != FACE_DEFAULT)
353 xgcv.foreground = face->foreground;
354 else
355 xgcv.foreground = f->display.x->foreground_pixel;
356
357 if (face->background != FACE_DEFAULT)
358 xgcv.background = face->background;
359 else
360 xgcv.background = f->display.x->background_pixel;
361
362 if (face->font && (int) face->font != FACE_DEFAULT)
363 xgcv.font = face->font->fid;
364 else
365 xgcv.font = f->display.x->font->fid;
366
367 xgcv.graphics_exposures = 0;
368
369 mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
370 gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f),
371 mask, &xgcv);
372
373 #if 0
374 if (face->stipple && face->stipple != FACE_DEFAULT)
375 XSetStipple (x_current_display, gc, face->stipple);
376 #endif
377
378 face->gc = gc;
379
380 UNBLOCK_INPUT;
381 }
382
383 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps. */
384
385 static XFontStruct *
386 load_font (f, name)
387 struct frame *f;
388 Lisp_Object name;
389 {
390 XFontStruct *font;
391
392 if (NILP (name))
393 return (XFontStruct *) FACE_DEFAULT;
394
395 CHECK_STRING (name, 0);
396 BLOCK_INPUT;
397 font = XLoadQueryFont (x_current_display, (char *) XSTRING (name)->data);
398 UNBLOCK_INPUT;
399
400 if (! font)
401 Fsignal (Qerror, Fcons (build_string ("undefined font"),
402 Fcons (name, Qnil)));
403 return font;
404 }
405
406 static void
407 unload_font (f, font)
408 struct frame *f;
409 XFontStruct *font;
410 {
411 if (!font || font == ((XFontStruct *) FACE_DEFAULT))
412 return;
413
414 BLOCK_INPUT;
415 XFreeFont (x_current_display, font);
416 UNBLOCK_INPUT;
417 }
418
419 static unsigned long
420 load_color (f, name)
421 struct frame *f;
422 Lisp_Object name;
423 {
424 Display *dpy = x_current_display;
425 Colormap cmap;
426 XColor color;
427 int result;
428
429 if (NILP (name))
430 return FACE_DEFAULT;
431
432 cmap = DefaultColormapOfScreen (DefaultScreenOfDisplay (x_current_display));
433
434 CHECK_STRING (name, 0);
435 BLOCK_INPUT;
436 result = XParseColor (dpy, cmap, (char *) XSTRING (name)->data, &color);
437 UNBLOCK_INPUT;
438 if (! result)
439 Fsignal (Qerror, Fcons (build_string ("undefined color"),
440 Fcons (name, Qnil)));
441 BLOCK_INPUT;
442 result = XAllocColor (dpy, cmap, &color);
443 UNBLOCK_INPUT;
444 if (! result)
445 Fsignal (Qerror, Fcons (build_string ("X server cannot allocate color"),
446 Fcons (name, Qnil)));
447 return (unsigned long) color.pixel;
448 }
449
450 static void
451 unload_color (f, pixel)
452 struct frame *f;
453 unsigned long pixel;
454 {
455 /* Since faces get built by copying parameters from other faces, the
456 allocation counts for the colors get all screwed up. I don't see
457 any solution that will take less than 10 minutes, and it's better
458 to have a color leak than a crash, so I'm just dyking this out.
459 This isn't really a color leak, anyway - if we ask for it again,
460 we'll get the same pixel. */
461 #if 0
462 Colormap cmap;
463 Display *dpy = x_current_display;
464 if (pixel == FACE_DEFAULT
465 || pixel == BLACK_PIX_DEFAULT
466 || pixel == WHITE_PIX_DEFAULT)
467 return;
468 cmap = DefaultColormapOfScreen (DefaultScreenOfDisplay (x_current_display));
469 BLOCK_INPUT;
470 XFreeColors (dpy, cmap, &pixel, 1, 0);
471 UNBLOCK_INPUT;
472 #endif
473 }
474 \f
475 /* Managing parameter face arrays for frames. */
476
477 void
478 init_frame_faces (f)
479 FRAME_PTR f;
480 {
481 ensure_face_ready (f, 0);
482 ensure_face_ready (f, 1);
483
484 FRAME_N_COMPUTED_FACES (f) = 0;
485 FRAME_SIZE_COMPUTED_FACES (f) = 0;
486
487 new_computed_face (f, FRAME_PARAM_FACES (f)[0]);
488 new_computed_face (f, FRAME_PARAM_FACES (f)[1]);
489 recompute_basic_faces (f);
490
491 /* Find another X frame. */
492 {
493 Lisp_Object tail, frame, result;
494
495 result = Qnil;
496 FOR_EACH_FRAME (tail, frame)
497 if (FRAME_X_P (XFRAME (frame))
498 && XFRAME (frame) != f)
499 {
500 result = frame;
501 break;
502 }
503
504 /* If we didn't find any X frames other than f, then we don't need
505 any faces other than 0 and 1, so we're okay. Otherwise, make
506 sure that all faces valid on the selected frame are also valid
507 on this new frame. */
508 if (FRAMEP (result))
509 {
510 int i;
511 int n_faces = FRAME_N_PARAM_FACES (XFRAME (result));
512 struct face **faces = FRAME_PARAM_FACES (XFRAME (result));
513
514 for (i = 2; i < n_faces; i++)
515 if (faces[i])
516 ensure_face_ready (f, i);
517 }
518 }
519 }
520
521
522 /* Called from Fdelete_frame. */
523 void
524 free_frame_faces (f)
525 struct frame *f;
526 {
527 Display *dpy = x_current_display;
528 int i;
529
530 BLOCK_INPUT;
531
532 for (i = 0; i < FRAME_N_PARAM_FACES (f); i++)
533 {
534 struct face *face = FRAME_PARAM_FACES (f) [i];
535 if (face)
536 {
537 if (face->gc)
538 XFreeGC (dpy, face->gc);
539 unload_font (f, face->font);
540 unload_color (f, face->foreground);
541 unload_color (f, face->background);
542 #if 0
543 unload_pixmap (f, face->stipple);
544 #endif
545 xfree (face);
546 }
547 }
548 xfree (FRAME_PARAM_FACES (f));
549 FRAME_PARAM_FACES (f) = 0;
550 FRAME_N_PARAM_FACES (f) = 0;
551
552 /* All faces in FRAME_COMPUTED_FACES use resources copied from
553 FRAME_PARAM_FACES; we can free them without fuss. */
554 xfree (FRAME_COMPUTED_FACES (f));
555 FRAME_COMPUTED_FACES (f) = 0;
556 FRAME_N_COMPUTED_FACES (f) = 0;
557
558 UNBLOCK_INPUT;
559 }
560 \f
561 /* Interning faces in a frame's face array. */
562
563 static int
564 new_computed_face (f, new_face)
565 struct frame *f;
566 struct face *new_face;
567 {
568 int i = FRAME_N_COMPUTED_FACES (f);
569
570 if (i >= FRAME_SIZE_COMPUTED_FACES (f))
571 {
572 int new_size = i + 32;
573
574 FRAME_COMPUTED_FACES (f)
575 = (struct face **) (FRAME_SIZE_COMPUTED_FACES (f) == 0
576 ? xmalloc (new_size * sizeof (struct face *))
577 : xrealloc (FRAME_COMPUTED_FACES (f),
578 new_size * sizeof (struct face *)));
579 FRAME_SIZE_COMPUTED_FACES (f) = new_size;
580 }
581
582 i = FRAME_N_COMPUTED_FACES (f)++;
583 FRAME_COMPUTED_FACES (f)[i] = copy_face (new_face);
584 return i;
585 }
586
587
588 /* Find a match for NEW_FACE in a FRAME's computed face array, and add
589 it if we don't find one. */
590 static int
591 intern_computed_face (f, new_face)
592 struct frame *f;
593 struct face *new_face;
594 {
595 int len = FRAME_N_COMPUTED_FACES (f);
596 int i;
597
598 /* Search for a computed face already on F equivalent to FACE. */
599 for (i = 0; i < len; i++)
600 {
601 if (! FRAME_COMPUTED_FACES (f)[i])
602 abort ();
603 if (face_eql (new_face, FRAME_COMPUTED_FACES (f)[i]))
604 return i;
605 }
606
607 /* We didn't find one; add a new one. */
608 return new_computed_face (f, new_face);
609 }
610
611 /* Make parameter face id ID valid on frame F. */
612
613 static void
614 ensure_face_ready (f, id)
615 struct frame *f;
616 int id;
617 {
618 if (FRAME_N_PARAM_FACES (f) <= id)
619 {
620 int n = id + 10;
621 int i;
622 if (!FRAME_N_PARAM_FACES (f))
623 FRAME_PARAM_FACES (f)
624 = (struct face **) xmalloc (sizeof (struct face *) * n);
625 else
626 FRAME_PARAM_FACES (f)
627 = (struct face **) xrealloc (FRAME_PARAM_FACES (f),
628 sizeof (struct face *) * n);
629
630 bzero (FRAME_PARAM_FACES (f) + FRAME_N_PARAM_FACES (f),
631 (n - FRAME_N_PARAM_FACES (f)) * sizeof (struct face *));
632 FRAME_N_PARAM_FACES (f) = n;
633 }
634
635 if (FRAME_PARAM_FACES (f) [id] == 0)
636 FRAME_PARAM_FACES (f) [id] = allocate_face ();
637 }
638 \f
639 /* Computing faces appropriate for a given piece of text in a buffer. */
640
641 /* Return non-zero if FONT1 and FONT2 have the same size bounding box.
642 We assume that they're both character-cell fonts. */
643 int
644 same_size_fonts (font1, font2)
645 XFontStruct *font1, *font2;
646 {
647 XCharStruct *bounds1 = &font1->min_bounds;
648 XCharStruct *bounds2 = &font2->min_bounds;
649
650 return (bounds1->width == bounds2->width);
651 /* Checking the following caused bad results in some cases
652 when fonts that should be the same size
653 actually have very slightly different size.
654 It is possible that this reintroduces the bug whereby line positions
655 were not right. However, the right way to fix that is to change xterm.c
656 so that the vertical positions of lines
657 depend only on the height of the frame's font.
658 && bounds1->ascent == bounds2->ascent
659 && bounds1->descent == bounds2->descent); */
660 }
661
662 /* Modify face TO by copying from FROM all properties which have
663 nondefault settings. */
664 static void
665 merge_faces (from, to)
666 struct face *from, *to;
667 {
668 /* Only merge the font if it's the same size as the base font. */
669 if (from->font != (XFontStruct *) FACE_DEFAULT
670 && same_size_fonts (from->font, to->font))
671 to->font = from->font;
672 if (from->foreground != FACE_DEFAULT)
673 to->foreground = from->foreground;
674 if (from->background != FACE_DEFAULT)
675 to->background = from->background;
676 if (from->stipple != FACE_DEFAULT)
677 to->stipple = from->stipple;
678 if (from->underline)
679 to->underline = from->underline;
680 }
681
682 /* Set up the basic set of facial parameters, based on the frame's
683 data; all faces are deltas applied to this. */
684 static void
685 compute_base_face (f, face)
686 FRAME_PTR f;
687 struct face *face;
688 {
689 struct x_display *d = f->display.x;
690
691 face->gc = 0;
692 face->foreground = d->foreground_pixel;
693 face->background = d->background_pixel;
694 face->font = d->font;
695 face->stipple = 0;
696 face->underline = 0;
697
698 /* Avoid a face comparison by making this invalid. */
699 face->cached_index = -1;
700 }
701
702
703 /* Return the face ID associated with a buffer position POS.
704 Store into *ENDPTR the position at which a different face is needed.
705 This does not take account of glyphs that specify their own face codes.
706 F is the frame in use for display, and W is a window displaying
707 the current buffer.
708
709 REGION_BEG, REGION_END delimit the region, so it can be highlighted.
710
711 LIMIT is a position not to scan beyond. That is to limit
712 the time this function can take.
713
714 If MOUSE is nonzero, use the character's mouse-face, not its face. */
715
716 int
717 compute_char_face (f, w, pos, region_beg, region_end, endptr, limit, mouse)
718 struct frame *f;
719 struct window *w;
720 int pos;
721 int region_beg, region_end;
722 int *endptr;
723 int limit;
724 int mouse;
725 {
726 struct face face;
727 Lisp_Object prop, position;
728 int i, j, noverlays;
729 int facecode;
730 Lisp_Object *overlay_vec;
731 Lisp_Object frame;
732 int endpos;
733 Lisp_Object propname;
734
735 /* W must display the current buffer. We could write this function
736 to use the frame and buffer of W, but right now it doesn't. */
737 if (XBUFFER (w->buffer) != current_buffer)
738 abort ();
739
740 XSET (frame, Lisp_Frame, f);
741
742 endpos = ZV;
743 if (pos < region_beg && region_beg < endpos)
744 endpos = region_beg;
745
746 XFASTINT (position) = pos;
747
748 if (mouse)
749 propname = Qmouse_face;
750 else
751 propname = Qface;
752
753 prop = Fget_text_property (position, propname, w->buffer);
754
755 {
756 Lisp_Object limit1, end;
757
758 XFASTINT (limit1) = (limit < endpos ? limit : endpos);
759 end = Fnext_single_property_change (position, propname, w->buffer, limit1);
760 if (INTEGERP (end))
761 endpos = XINT (end);
762 }
763
764 {
765 int next_overlay;
766 int len;
767
768 /* First try with room for 40 overlays. */
769 len = 40;
770 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
771
772 noverlays = overlays_at (pos, 0, &overlay_vec, &len, &next_overlay);
773
774 /* If there are more than 40,
775 make enough space for all, and try again. */
776 if (noverlays > len)
777 {
778 len = noverlays;
779 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
780 noverlays = overlays_at (pos, 0, &overlay_vec, &len, &next_overlay);
781 }
782
783 if (next_overlay < endpos)
784 endpos = next_overlay;
785 }
786
787 *endptr = endpos;
788
789 /* Optimize the default case. */
790 if (noverlays == 0 && NILP (prop)
791 && !(pos >= region_beg && pos < region_end))
792 return 0;
793
794 compute_base_face (f, &face);
795
796 if (!NILP (prop))
797 {
798 facecode = face_name_id_number (f, prop);
799 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
800 && FRAME_PARAM_FACES (f) [facecode] != 0)
801 merge_faces (FRAME_PARAM_FACES (f) [facecode], &face);
802 }
803
804 noverlays = sort_overlays (overlay_vec, noverlays, w);
805
806 /* Now merge the overlay data in that order. */
807 for (i = 0; i < noverlays; i++)
808 {
809 prop = Foverlay_get (overlay_vec[i], propname);
810 if (!NILP (prop))
811 {
812 Lisp_Object oend;
813 int oendpos;
814
815 facecode = face_name_id_number (f, prop);
816 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
817 && FRAME_PARAM_FACES (f) [facecode] != 0)
818 merge_faces (FRAME_PARAM_FACES (f)[facecode], &face);
819
820 oend = OVERLAY_END (overlay_vec[i]);
821 oendpos = OVERLAY_POSITION (oend);
822 if (oendpos < endpos)
823 endpos = oendpos;
824 }
825 }
826
827 if (pos >= region_beg && pos < region_end)
828 {
829 if (region_end < endpos)
830 endpos = region_end;
831 if (region_face >= 0 && region_face < next_face_id)
832 merge_faces (FRAME_PARAM_FACES (f)[region_face], &face);
833 }
834
835 *endptr = endpos;
836
837 return intern_computed_face (f, &face);
838 }
839
840 /* Return the face ID to use to display a special glyph which selects
841 FACE_CODE as the face ID, assuming that ordinarily the face would
842 be CURRENT_FACE. F is the frame. */
843
844 int
845 compute_glyph_face (f, face_code, current_face)
846 struct frame *f;
847 int face_code, current_face;
848 {
849 struct face face;
850
851 face = *FRAME_COMPUTED_FACES (f)[current_face];
852
853 if (face_code >= 0 && face_code < FRAME_N_PARAM_FACES (f)
854 && FRAME_PARAM_FACES (f) [face_code] != 0)
855 merge_faces (FRAME_PARAM_FACES (f) [face_code], &face);
856
857 return intern_computed_face (f, &face);
858 }
859
860
861 /* Recompute the GC's for the default and modeline faces.
862 We call this after changing frame parameters on which those GC's
863 depend. */
864
865 void
866 recompute_basic_faces (f)
867 FRAME_PTR f;
868 {
869 /* If the frame's faces haven't been initialized yet, don't worry about
870 this stuff. */
871 if (FRAME_N_PARAM_FACES (f) < 2)
872 return;
873
874 BLOCK_INPUT;
875
876 if (FRAME_DEFAULT_FACE (f)->gc)
877 XFreeGC (x_current_display, FRAME_DEFAULT_FACE (f)->gc);
878 if (FRAME_MODE_LINE_FACE (f)->gc)
879 XFreeGC (x_current_display, FRAME_MODE_LINE_FACE (f)->gc);
880
881 compute_base_face (f, FRAME_DEFAULT_FACE (f));
882 compute_base_face (f, FRAME_MODE_LINE_FACE (f));
883
884 merge_faces (FRAME_DEFAULT_PARAM_FACE (f), FRAME_DEFAULT_FACE (f));
885 merge_faces (FRAME_MODE_LINE_PARAM_FACE (f), FRAME_MODE_LINE_FACE (f));
886
887 build_face (f, FRAME_DEFAULT_FACE (f));
888 build_face (f, FRAME_MODE_LINE_FACE (f));
889
890 UNBLOCK_INPUT;
891 }
892
893
894 \f
895 /* Lisp interface. */
896
897 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist, 1, 1, 0,
898 "")
899 (frame)
900 Lisp_Object frame;
901 {
902 CHECK_FRAME (frame, 0);
903 return XFRAME (frame)->face_alist;
904 }
905
906 DEFUN ("set-frame-face-alist", Fset_frame_face_alist, Sset_frame_face_alist,
907 2, 2, 0, "")
908 (frame, value)
909 Lisp_Object frame, value;
910 {
911 CHECK_FRAME (frame, 0);
912 XFRAME (frame)->face_alist = value;
913 return value;
914 }
915
916
917 DEFUN ("make-face-internal", Fmake_face_internal, Smake_face_internal, 1, 1, 0,
918 "Create face number FACE-ID on all frames.")
919 (face_id)
920 Lisp_Object face_id;
921 {
922 Lisp_Object rest;
923 int id = XINT (face_id);
924
925 CHECK_NUMBER (face_id, 0);
926 if (id < 0 || id >= next_face_id)
927 error ("Face id out of range");
928
929 for (rest = Vframe_list; !NILP (rest); rest = XCONS (rest)->cdr)
930 {
931 struct frame *f = XFRAME (XCONS (rest)->car);
932 if (FRAME_X_P (f))
933 ensure_face_ready (f, id);
934 }
935 return Qnil;
936 }
937
938
939 DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal,
940 Sset_face_attribute_internal, 4, 4, 0, "")
941 (face_id, attr_name, attr_value, frame)
942 Lisp_Object face_id, attr_name, attr_value, frame;
943 {
944 struct face *face;
945 struct frame *f;
946 int magic_p;
947 int id;
948
949 CHECK_FRAME (frame, 0);
950 CHECK_NUMBER (face_id, 0);
951 CHECK_SYMBOL (attr_name, 0);
952
953 f = XFRAME (frame);
954 id = XINT (face_id);
955 if (id < 0 || id >= next_face_id)
956 error ("Face id out of range");
957
958 if (! FRAME_X_P (f))
959 return;
960
961 ensure_face_ready (f, id);
962 face = FRAME_PARAM_FACES (f) [XFASTINT (face_id)];
963
964 if (EQ (attr_name, intern ("font")))
965 {
966 XFontStruct *font = load_font (f, attr_value);
967 if (face->font != f->display.x->font)
968 unload_font (f, face->font);
969 face->font = font;
970 }
971 else if (EQ (attr_name, intern ("foreground")))
972 {
973 unsigned long new_color = load_color (f, attr_value);
974 unload_color (f, face->foreground);
975 face->foreground = new_color;
976 }
977 else if (EQ (attr_name, intern ("background")))
978 {
979 unsigned long new_color = load_color (f, attr_value);
980 unload_color (f, face->background);
981 face->background = new_color;
982 }
983 #if 0
984 else if (EQ (attr_name, intern ("background-pixmap")))
985 {
986 unsigned int w, h, d;
987 unsigned long new_pixmap = load_pixmap (f, attr_value, &w, &h, &d, 0);
988 unload_pixmap (f, face->stipple);
989 if (NILP (attr_value))
990 new_pixmap = 0;
991 face->stipple = new_pixmap;
992 face->pixmap_w = w;
993 face->pixmap_h = h;
994 /* face->pixmap_depth = d; */
995 }
996 #endif /* 0 */
997 else if (EQ (attr_name, intern ("underline")))
998 {
999 int new = !NILP (attr_value);
1000 face->underline = new;
1001 }
1002 else
1003 error ("unknown face attribute");
1004
1005 if (id == 0 || id == 1)
1006 recompute_basic_faces (f);
1007
1008 /* If we're modifying either of the frame's display faces, that
1009 means that we're changing the parameters of a fixed face code;
1010 since the color/font/whatever is changed but the face ID hasn't,
1011 redisplay won't know to redraw the affected sections. Give it a
1012 kick. */
1013 if (id == 0 || id == 1)
1014 SET_FRAME_GARBAGED (f);
1015 else
1016 /* Otherwise, it's enough to tell it to redisplay the text. */
1017 windows_or_buffers_changed = 1;
1018
1019 return Qnil;
1020 }
1021
1022 DEFUN ("internal-next-face-id", Finternal_next_face_id, Sinternal_next_face_id,
1023 0, 0, 0, "")
1024 ()
1025 {
1026 return make_number (next_face_id++);
1027 }
1028
1029 /* Return the face id for name NAME on frame FRAME.
1030 (It should be the same for all frames,
1031 but it's as easy to use the "right" frame to look it up
1032 as to use any other one.) */
1033
1034 int
1035 face_name_id_number (f, name)
1036 FRAME_PTR f;
1037 Lisp_Object name;
1038 {
1039 Lisp_Object tem;
1040
1041 tem = Fcdr (assq_no_quit (name, f->face_alist));
1042 if (NILP (tem))
1043 return 0;
1044 CHECK_VECTOR (tem, 0);
1045 tem = XVECTOR (tem)->contents[2];
1046 CHECK_NUMBER (tem, 0);
1047 return XINT (tem);
1048 }
1049 \f
1050 /* Emacs initialization. */
1051
1052 void
1053 syms_of_xfaces ()
1054 {
1055 Qface = intern ("face");
1056 staticpro (&Qface);
1057 Qmouse_face = intern ("mouse-face");
1058 staticpro (&Qmouse_face);
1059
1060 DEFVAR_INT ("region-face", &region_face,
1061 "Face number to use to highlight the region\n\
1062 The region is highlighted with this face\n\
1063 when Transient Mark mode is enabled and the mark is active.");
1064
1065 defsubr (&Sframe_face_alist);
1066 defsubr (&Sset_frame_face_alist);
1067 defsubr (&Smake_face_internal);
1068 defsubr (&Sset_face_attribute_internal);
1069 defsubr (&Sinternal_next_face_id);
1070 }
1071
1072 #endif /* HAVE_X_WINDOWS */
1073