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