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