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)
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>
32 #include "dispextern.h"
34 #include "blockinput.h"
37 /* Display Context for the icons */
38 #include <X11/Intrinsic.h>
39 #include <X11/StringDefs.h>
40 /* #include <X11/Xmu/Drawing.h> */ /* Appears not to be used */
44 /* An explanation of the face data structures. */
46 /* ========================= Face Data Structures =========================
48 All lisp code uses symbols as face names.
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
53 [face NAME ID FONT FOREGROUND BACKGROUND BACKGROUND-PIXMAP UNDERLINE-P]
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
59 FONT, FOREGROUND, and BACKGROUND are strings naming the fonts and colors
61 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't
63 UNDERLINE-P is non-nil if the face should be underlined.
64 (lisp/faces.el maintains these association lists.)
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.)
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.)
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.)
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.)
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
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
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. */
124 /* Definitions and declarations. */
126 /* A table of display faces. */
127 struct face
**face_vector
;
128 /* The length in use of the table. */
130 /* The allocated length of the table. */
131 int nfaces_allocated
;
133 /* The number of face-id's in use (same for all frames). */
136 /* The number of the face to use to indicate the region. */
139 /* This is what appears in a slot in a face to signify that the face
140 does not specify that display aspect. */
141 #define FACE_DEFAULT (~0)
143 Lisp_Object Qface
, Qwindow
, Qpriority
;
145 static void build_face ();
146 static Lisp_Object
face_name_id_number ();
148 struct face
*intern_face ();
149 static void ensure_face_ready ();
151 /* Allocating, copying, and comparing struct faces. */
153 /* Allocate a new face */
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
;
166 /* Make a new face that's a copy of an existing one. */
171 struct face
*result
= allocate_face ();
173 result
->font
= face
->font
;
174 result
->foreground
= face
->foreground
;
175 result
->background
= face
->background
;
176 result
->stipple
= face
->stipple
;
177 result
->underline
= face
->underline
;
183 face_eql (face1
, face2
)
184 struct face
*face1
, *face2
;
186 return ( face1
->font
== face2
->font
187 && face1
->foreground
== face2
->foreground
188 && face1
->background
== face2
->background
189 && face1
->stipple
== face2
->stipple
190 && face1
->underline
== face2
->underline
);
193 /* Interning faces in the `face_vector' cache, and clearing that cache. */
195 /* Return the unique display face corresponding to the user-level face FACE.
196 If there isn't one, make one, and find a slot in the face_vector to
199 get_cached_face (f
, face
)
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
];
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
++)
217 if (face_eql (face_vector
[i
], face
))
218 return face_vector
[i
];
219 if (face_vector
[i
] == 0)
223 /* If no empty slots, make one. */
224 if (empty
< 0 && nfaces
== nfaces_allocated
)
226 int newsize
= nfaces
+ 20;
228 = (struct face
**) xrealloc (face_vector
,
229 newsize
* sizeof (struct face
*));
230 nfaces_allocated
= newsize
;
236 /* Put a new display face in the empty slot. */
237 result
= copy_face (face
);
238 face_vector
[empty
] = result
;
240 /* Make a graphics context for it. */
241 build_face (f
, result
);
246 /* Given a frame face, return an equivalent display face
247 (one which has a graphics context). */
250 intern_face (f
, face
)
254 /* If it's equivalent to the default face, use that. */
255 if (face_eql (face
, FRAME_DEFAULT_FACE (f
)))
257 if (!FRAME_DEFAULT_FACE (f
)->gc
)
258 build_face (f
, FRAME_DEFAULT_FACE (f
));
259 return FRAME_DEFAULT_FACE (f
);
262 /* If it's equivalent to the mode line face, use that. */
263 if (face_eql (face
, FRAME_MODE_LINE_FACE (f
)))
265 if (!FRAME_MODE_LINE_FACE (f
)->gc
)
266 build_face (f
, FRAME_MODE_LINE_FACE (f
));
267 return FRAME_MODE_LINE_FACE (f
);
270 /* If it's not one of the frame's default faces, it shouldn't have a GC. */
274 /* Get a specialized display face. */
275 return get_cached_face (f
, face
);
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. */
287 Display
*dpy
= x_current_display
;
291 /* Free the display faces in the face_vector. */
292 for (i
= 0; i
< nfaces
; i
++)
294 struct face
*face
= face_vector
[i
];
296 XFreeGC (dpy
, face
->gc
);
304 /* Allocating and freeing X resources for display faces. */
306 /* Make a graphics context for face FACE, which is on frame F,
307 if that can be done. */
317 if (face
->foreground
!= FACE_DEFAULT
)
318 xgcv
.foreground
= face
->foreground
;
320 xgcv
. foreground
= f
->display
.x
->foreground_pixel
;
321 if (face
->background
!= FACE_DEFAULT
)
322 xgcv
.background
= face
->background
;
324 xgcv
. background
= f
->display
.x
->background_pixel
;
325 if (face
->font
&& (int) face
->font
!= FACE_DEFAULT
)
326 xgcv
.font
= face
->font
->fid
;
328 xgcv
.font
= f
->display
.x
->font
->fid
;
329 xgcv
.graphics_exposures
= 0;
330 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
331 gc
= XCreateGC (x_current_display
, FRAME_X_WINDOW (f
),
334 if (face
->stipple
&& face
->stipple
!= FACE_DEFAULT
)
335 XSetStipple (x_current_display
, gc
, face
->stipple
);
340 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps. */
350 return (XFontStruct
*) FACE_DEFAULT
;
352 CHECK_STRING (name
, 0);
354 font
= XLoadQueryFont (x_current_display
, (char *) XSTRING (name
)->data
);
358 Fsignal (Qerror
, Fcons (build_string ("undefined font"),
359 Fcons (name
, Qnil
)));
364 unload_font (f
, font
)
368 if (!font
|| font
== ((XFontStruct
*) FACE_DEFAULT
))
370 XFreeFont (x_current_display
, font
);
378 Display
*dpy
= x_current_display
;
386 cmap
= DefaultColormapOfScreen (DefaultScreenOfDisplay (x_current_display
));
388 CHECK_STRING (name
, 0);
390 result
= XParseColor (dpy
, cmap
, (char *) XSTRING (name
)->data
, &color
);
393 Fsignal (Qerror
, Fcons (build_string ("undefined color"),
394 Fcons (name
, Qnil
)));
396 result
= XAllocColor (dpy
, cmap
, &color
);
399 Fsignal (Qerror
, Fcons (build_string ("X server cannot allocate color"),
400 Fcons (name
, Qnil
)));
401 return (unsigned long) color
.pixel
;
405 unload_color (f
, pixel
)
410 Display
*dpy
= x_current_display
;
411 if (pixel
== FACE_DEFAULT
412 || pixel
== BLACK_PIX_DEFAULT
413 || pixel
== WHITE_PIX_DEFAULT
)
415 cmap
= DefaultColormapOfScreen (DefaultScreenOfDisplay (x_current_display
));
417 XFreeColors (dpy
, cmap
, &pixel
, 1, 0);
421 /* Initializing face arrays for frames. */
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.
427 Note that the first two faces just contain references to the
428 frame's own resources. We shouldn't free them. */
433 ensure_face_ready (f
, 0);
436 struct face
*face
= FRAME_FACES (f
) [0];
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
;
443 face
->font
= f
->display
.x
->font
;
448 ensure_face_ready (f
, 1);
451 struct face
*face
= FRAME_FACES (f
) [1];
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
;
458 face
->font
= f
->display
.x
->font
;
464 /* Called from Fdelete_frame. */
469 Display
*dpy
= x_current_display
;
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
++)
477 struct face
*face
= FRAME_FACES (f
) [i
];
481 XFreeGC (dpy
, face
->gc
);
482 unload_font (f
, face
->font
);
483 unload_color (f
, face
->foreground
);
484 unload_color (f
, face
->background
);
486 unload_pixmap (f
, face
->stipple
);
490 xfree (FRAME_FACES (f
));
492 FRAME_N_FACES (f
) = 0;
495 /* Interning faces in a frame's face array. */
497 /* Find a match for NEW_FACE in a FRAME's face array, and add it if we don't
500 intern_frame_face (frame
, new_face
)
502 struct face
*new_face
;
504 int len
= FRAME_N_FACES (frame
);
507 /* Search for a face already on FRAME equivalent to FACE. */
508 for (i
= 0; i
< len
; i
++)
510 struct face
*frame_face
= FRAME_FACES (frame
)[i
];
512 if (frame_face
&& face_eql (new_face
, frame_face
))
516 /* We didn't find one; add a new one. */
519 ensure_face_ready (frame
, i
);
520 bcopy (new_face
, FRAME_FACES (frame
)[i
], sizeof (*new_face
));
525 /* Make face id ID valid on frame F. */
528 ensure_face_ready (f
, id
)
532 if (FRAME_N_FACES (f
) <= id
)
536 if (!FRAME_N_FACES (f
))
538 = (struct face
**) xmalloc (sizeof (struct face
*) * n
);
541 = (struct face
**) xrealloc (FRAME_FACES (f
),
542 sizeof (struct face
*) * n
);
544 bzero (FRAME_FACES (f
) + FRAME_N_FACES (f
),
545 (n
- FRAME_N_FACES (f
)) * sizeof (struct face
*));
546 FRAME_N_FACES (f
) = n
;
549 if (FRAME_FACES (f
) [id
] == 0)
550 FRAME_FACES (f
) [id
] = allocate_face ();
553 /* Computing faces appropriate for a given piece of text in a buffer. */
555 /* Return non-zero if FONT1 and FONT2 have the same size bounding box.
556 We assume that they're both character-cell fonts. */
558 same_size_fonts (font1
, font2
)
559 XFontStruct
*font1
, *font2
;
561 XCharStruct
*bounds1
= &font1
->min_bounds
;
562 XCharStruct
*bounds2
= &font2
->min_bounds
;
564 return (bounds1
->width
== bounds2
->width
565 && bounds1
->ascent
== bounds2
->ascent
566 && bounds1
->descent
== bounds2
->descent
);
570 /* Modify face TO by copying from FROM all properties which have
571 nondefault settings. */
573 merge_faces (from
, to
)
574 struct face
*from
, *to
;
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
;
581 if (from
->foreground
!= FACE_DEFAULT
)
582 to
->foreground
= from
->foreground
;
583 if (from
->background
!= FACE_DEFAULT
)
584 to
->background
= from
->background
;
585 if (from
->stipple
!= FACE_DEFAULT
)
586 to
->stipple
= from
->stipple
;
588 to
->underline
= from
->underline
;
599 sort_overlays (s1
, s2
)
600 struct sortvec
*s1
, *s2
;
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
;
611 /* Return the face ID associated with a buffer position POS.
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.
614 F is the frame in use for display, and W is a window displaying
617 REGION_BEG, REGION_END delimit the region, so it can be highlighted. */
620 compute_char_face (f
, w
, pos
, region_beg
, region_end
, endptr
)
624 int region_beg
, region_end
;
628 Lisp_Object prop
, position
;
631 Lisp_Object
*overlay_vec
;
632 struct sortvec
*sortvec
;
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
)
641 XSET (frame
, Lisp_Frame
, f
);
644 if (pos
< region_beg
&& region_beg
< endpos
)
647 XFASTINT (position
) = pos
;
648 prop
= Fget_text_property (position
, Qface
, w
->buffer
);
652 end
= Fnext_single_property_change (position
, Qface
, w
->buffer
);
661 /* First try with room for 40 overlays. */
663 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
665 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, &next_overlay
);
667 /* If there are more than 40,
668 make enough space for all, and try again. */
672 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
673 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, &next_overlay
);
676 if (next_overlay
< endpos
)
677 endpos
= next_overlay
;
682 /* Optimize the default case. */
683 if (noverlays
== 0 && NILP (prop
)
684 && !(pos
>= region_beg
&& pos
< region_end
))
687 bcopy (FRAME_DEFAULT_FACE (f
), &face
, sizeof (struct face
));
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
);
698 /* Put the valid and relevant overlays into sortvec. */
699 sortvec
= (struct sortvec
*) alloca (noverlays
* sizeof (struct sortvec
));
701 for (i
= 0, j
= 0; i
< noverlays
; i
++)
703 Lisp_Object overlay
= overlay_vec
[i
];
705 if (OVERLAY_VALID (overlay
)
706 && OVERLAY_POSITION (OVERLAY_START (overlay
)) > 0
707 && OVERLAY_POSITION (OVERLAY_END (overlay
)) > 0)
710 window
= Foverlay_get (overlay
, Qwindow
);
712 /* Also ignore overlays limited to one window
713 if it's not the window we are using. */
714 if (XTYPE (window
) != Lisp_Window
715 || XWINDOW (window
) == w
)
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
);
726 sortvec
[j
].priority
= XINT (tem
);
728 sortvec
[j
].priority
= 0;
735 /* Sort the overlays into the proper order: increasing priority. */
738 qsort (sortvec
, noverlays
, sizeof (struct sortvec
), sort_overlays
);
740 /* Now merge the overlay data in that order. */
741 for (i
= 0; i
< noverlays
; i
++)
743 prop
= Foverlay_get (sortvec
[i
].overlay
, Qface
);
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
);
754 oend
= OVERLAY_END (sortvec
[i
].overlay
);
755 oendpos
= OVERLAY_POSITION (oend
);
756 if (oendpos
< endpos
)
761 if (pos
>= region_beg
&& pos
< region_end
)
763 if (region_end
< endpos
)
765 if (region_face
>= 0 && region_face
< next_face_id
)
766 merge_faces (FRAME_FACES (f
) [region_face
], &face
);
771 return intern_frame_face (f
, &face
);
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. */
778 compute_glyph_face (f
, face_code
)
784 bcopy (FRAME_DEFAULT_FACE (f
), &face
, sizeof (face
));
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
);
791 return intern_frame_face (f
, &face
);
794 /* Lisp interface. */
796 DEFUN ("frame-face-alist", Fframe_face_alist
, Sframe_face_alist
, 1, 1, 0,
801 CHECK_FRAME (frame
, 0);
802 return XFRAME (frame
)->face_alist
;
805 DEFUN ("set-frame-face-alist", Fset_frame_face_alist
, Sset_frame_face_alist
,
808 Lisp_Object frame
, value
;
810 CHECK_FRAME (frame
, 0);
811 XFRAME (frame
)->face_alist
= value
;
816 DEFUN ("make-face-internal", Fmake_face_internal
, Smake_face_internal
, 1, 1, 0,
817 "Create face number FACE-ID on all frames.")
822 int id
= XINT (face_id
);
824 CHECK_NUMBER (face_id
, 0);
825 if (id
< 0 || id
>= next_face_id
)
826 error ("Face id out of range");
828 for (rest
= Vframe_list
; !NILP (rest
); rest
= XCONS (rest
)->cdr
)
830 struct frame
*f
= XFRAME (XCONS (rest
)->car
);
832 ensure_face_ready (f
, id
);
838 DEFUN ("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
;
848 CHECK_FRAME (frame
, 0);
849 CHECK_NUMBER (face_id
, 0);
850 CHECK_SYMBOL (attr_name
, 0);
854 if (id
< 0 || id
>= next_face_id
)
855 error ("Face id out of range");
860 ensure_face_ready (f
, id
);
861 face
= FRAME_FACES (f
) [XFASTINT (face_id
)];
863 if (EQ (attr_name
, intern ("font")))
865 XFontStruct
*font
= load_font (f
, attr_value
);
866 unload_font (f
, face
->font
);
869 else if (EQ (attr_name
, intern ("foreground")))
871 unsigned long new_color
= load_color (f
, attr_value
);
872 unload_color (f
, face
->foreground
);
873 face
->foreground
= new_color
;
875 else if (EQ (attr_name
, intern ("background")))
877 unsigned long new_color
= load_color (f
, attr_value
);
878 unload_color (f
, face
->background
);
879 face
->background
= new_color
;
882 else if (EQ (attr_name
, intern ("background-pixmap")))
884 unsigned int w
, h
, d
;
885 unsigned long new_pixmap
= load_pixmap (f
, attr_value
, &w
, &h
, &d
, 0);
886 unload_pixmap (f
, face
->stipple
);
887 if (NILP (attr_value
))
889 face
->stipple
= new_pixmap
;
892 /* face->pixmap_depth = d; */
895 else if (EQ (attr_name
, intern ("underline")))
897 int new = !NILP (attr_value
);
898 face
->underline
= new;
901 error ("unknown face attribute");
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
));
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
));
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
926 if (id
== 0 || id
== 1)
927 SET_FRAME_GARBAGED (f
);
929 /* Otherwise, it's enough to tell it to redisplay the text. */
930 windows_or_buffers_changed
= 1;
935 DEFUN ("internal-next-face-id", Finternal_next_face_id
, Sinternal_next_face_id
,
939 return make_number (next_face_id
++);
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.) */
948 face_name_id_number (frame
, name
)
949 Lisp_Object frame
, name
;
953 CHECK_FRAME (frame
, 0);
954 tem
= Fcdr (Fassq (name
, XFRAME (frame
)->face_alist
));
957 CHECK_VECTOR (tem
, 0);
958 tem
= XVECTOR (tem
)->contents
[2];
959 CHECK_NUMBER (tem
, 0);
963 /* Emacs initialization. */
968 Qwindow
= intern ("window");
969 staticpro (&Qwindow
);
970 Qface
= intern ("face");
972 Qpriority
= intern ("priority");
973 staticpro (&Qpriority
);
975 DEFVAR_INT ("region-face", ®ion_face
,
976 "Face number to use to highlight the region\n\
977 The region is highlighted with this face\n\
978 when Transient Mark mode is enabled and the mark is active.");
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
);
987 #endif /* HAVE_X_WINDOWS */