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