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