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