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