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