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 /* Compensate for bug in Xos.h on some systems. */
38 #ifdef XOS_NEEDS_TIME_H
43 /* These don't seem to be used. */
45 /* Display Context for the icons */
46 #include <X11/Intrinsic.h>
47 #include <X11/StringDefs.h>
48 #include <X11/Xmu/Drawing.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
63 [face NAME ID FONT FOREGROUND BACKGROUND BACKGROUND-PIXMAP UNDERLINE-P]
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
69 FONT, FOREGROUND, and BACKGROUND are strings naming the fonts and colors
71 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't
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
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
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
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. */
145 /* The allocated length of the table. */
146 int nfaces_allocated
;
148 /* The number of face-id's in use (same for all frames). */
151 /* The number of the face to use to indicate the region. */
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 */
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
;
181 /* Make a new face that's a copy of an existing one. */
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
;
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
214 get_cached_face (f
, face
)
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)
238 /* If no empty slots, make one. */
239 if (empty
< 0 && nfaces
== nfaces_allocated
)
241 int newsize
= nfaces
+ 20;
243 = (struct face
**) xrealloc (face_vector
,
244 newsize
* sizeof (struct face
*));
245 nfaces_allocated
= newsize
;
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
);
261 /* Given a frame face, return an equivalent display face
262 (one which has a graphics context). */
265 intern_face (f
, 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. */
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. */
302 Display
*dpy
= x_current_display
;
306 /* Free the display faces in the face_vector. */
307 for (i
= 0; i
< nfaces
; i
++)
309 struct face
*face
= face_vector
[i
];
311 XFreeGC (dpy
, face
->gc
);
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. */
334 if (face
->foreground
!= FACE_DEFAULT
)
335 xgcv
.foreground
= face
->foreground
;
337 xgcv
.foreground
= f
->display
.x
->foreground_pixel
;
339 if (face
->background
!= FACE_DEFAULT
)
340 xgcv
.background
= face
->background
;
342 xgcv
.background
= f
->display
.x
->background_pixel
;
344 if (face
->font
&& (int) face
->font
!= FACE_DEFAULT
)
345 xgcv
.font
= face
->font
->fid
;
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
),
356 if (face
->stipple
&& face
->stipple
!= FACE_DEFAULT
)
357 XSetStipple (x_current_display
, gc
, face
->stipple
);
365 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps. */
375 return (XFontStruct
*) FACE_DEFAULT
;
377 CHECK_STRING (name
, 0);
379 font
= XLoadQueryFont (x_current_display
, (char *) XSTRING (name
)->data
);
383 Fsignal (Qerror
, Fcons (build_string ("undefined font"),
384 Fcons (name
, Qnil
)));
389 unload_font (f
, font
)
393 if (!font
|| font
== ((XFontStruct
*) FACE_DEFAULT
))
397 XFreeFont (x_current_display
, font
);
406 Display
*dpy
= x_current_display
;
414 cmap
= DefaultColormapOfScreen (DefaultScreenOfDisplay (x_current_display
));
416 CHECK_STRING (name
, 0);
418 result
= XParseColor (dpy
, cmap
, (char *) XSTRING (name
)->data
, &color
);
421 Fsignal (Qerror
, Fcons (build_string ("undefined color"),
422 Fcons (name
, Qnil
)));
424 result
= XAllocColor (dpy
, cmap
, &color
);
427 Fsignal (Qerror
, Fcons (build_string ("X server cannot allocate color"),
428 Fcons (name
, Qnil
)));
429 return (unsigned long) color
.pixel
;
433 unload_color (f
, 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. */
445 Display
*dpy
= x_current_display
;
446 if (pixel
== FACE_DEFAULT
447 || pixel
== BLACK_PIX_DEFAULT
448 || pixel
== WHITE_PIX_DEFAULT
)
450 cmap
= DefaultColormapOfScreen (DefaultScreenOfDisplay (x_current_display
));
452 XFreeColors (dpy
, cmap
, &pixel
, 1, 0);
457 /* Initializing face arrays for frames. */
463 ensure_face_ready (f
, 0);
464 ensure_face_ready (f
, 1);
466 recompute_basic_faces (f
);
468 /* Find another X frame. */
470 Lisp_Object tail
, frame
, result
;
473 FOR_EACH_FRAME (tail
, frame
)
474 if (FRAME_X_P (XFRAME (frame
))
475 && XFRAME (frame
) != f
)
481 /* If we didn't find any X frames other than f, then we don't need
482 any faces other than 0 and 1, so we're okay. Otherwise, make
483 sure that all faces valid on the selected frame are also valid
484 on this new frame. */
488 int n_faces
= XFRAME (result
)->display
.x
->n_faces
;
489 struct face
**faces
= XFRAME (result
)->display
.x
->faces
;
491 for (i
= 2; i
< n_faces
; i
++)
493 ensure_face_ready (f
, i
);
499 /* Called from Fdelete_frame. */
504 Display
*dpy
= x_current_display
;
509 for (i
= 0; i
< FRAME_N_FACES (f
); i
++)
511 struct face
*face
= FRAME_FACES (f
) [i
];
515 XFreeGC (dpy
, face
->gc
);
518 unload_font (f
, face
->font
);
519 unload_color (f
, face
->foreground
);
520 unload_color (f
, face
->background
);
522 unload_pixmap (f
, face
->stipple
);
528 xfree (FRAME_FACES (f
));
530 FRAME_N_FACES (f
) = 0;
535 /* Interning faces in a frame's face array. */
537 /* Find a match for NEW_FACE in a FRAME's face array, and add it if we don't
540 intern_frame_face (frame
, new_face
)
542 struct face
*new_face
;
544 int len
= FRAME_N_FACES (frame
);
547 /* Search for a face already on FRAME equivalent to FACE. */
548 for (i
= 0; i
< len
; i
++)
550 struct face
*frame_face
= FRAME_FACES (frame
)[i
];
552 if (frame_face
&& face_eql (new_face
, frame_face
))
556 /* We didn't find one; add a new one. */
559 ensure_face_ready (frame
, i
);
560 bcopy (new_face
, FRAME_FACES (frame
)[i
], sizeof (*new_face
));
561 FRAME_FACES (frame
)[i
]->copy
= 1;
566 /* Make face id ID valid on frame F. */
569 ensure_face_ready (f
, id
)
573 if (FRAME_N_FACES (f
) <= id
)
577 if (!FRAME_N_FACES (f
))
579 = (struct face
**) xmalloc (sizeof (struct face
*) * n
);
582 = (struct face
**) xrealloc (FRAME_FACES (f
),
583 sizeof (struct face
*) * n
);
585 bzero (FRAME_FACES (f
) + FRAME_N_FACES (f
),
586 (n
- FRAME_N_FACES (f
)) * sizeof (struct face
*));
587 FRAME_N_FACES (f
) = n
;
590 if (FRAME_FACES (f
) [id
] == 0)
591 FRAME_FACES (f
) [id
] = allocate_face ();
594 /* Computing faces appropriate for a given piece of text in a buffer. */
596 /* Return non-zero if FONT1 and FONT2 have the same size bounding box.
597 We assume that they're both character-cell fonts. */
599 same_size_fonts (font1
, font2
)
600 XFontStruct
*font1
, *font2
;
602 XCharStruct
*bounds1
= &font1
->min_bounds
;
603 XCharStruct
*bounds2
= &font2
->min_bounds
;
605 return (bounds1
->width
== bounds2
->width
);
606 /* Checking the following caused bad results in some cases
607 when fonts that should be the same size
608 actually have very slightly different size.
609 It is possible that this reintroduces the bug whereby line positions
610 were not right. However, the right way to fix that is to change xterm.c
611 so that the vertical positions of lines
612 depend only on the height of the frame's font.
613 && bounds1->ascent == bounds2->ascent
614 && bounds1->descent == bounds2->descent); */
617 /* Modify face TO by copying from FROM all properties which have
618 nondefault settings. */
620 merge_faces (from
, to
)
621 struct face
*from
, *to
;
623 /* Only merge the font if it's the same size as the base font. */
624 if (from
->font
!= (XFontStruct
*) FACE_DEFAULT
625 && same_size_fonts (from
->font
, to
->font
))
626 to
->font
= from
->font
;
627 if (from
->foreground
!= FACE_DEFAULT
)
628 to
->foreground
= from
->foreground
;
629 if (from
->background
!= FACE_DEFAULT
)
630 to
->background
= from
->background
;
631 if (from
->stipple
!= FACE_DEFAULT
)
632 to
->stipple
= from
->stipple
;
634 to
->underline
= from
->underline
;
637 /* Set up the basic set of facial parameters, based on the frame's
638 data; all faces are deltas applied to this. */
640 compute_base_face (f
, face
)
644 struct x_display
*d
= f
->display
.x
;
647 face
->foreground
= d
->foreground_pixel
;
648 face
->background
= d
->background_pixel
;
649 face
->font
= d
->font
;
662 sort_overlays (s1
, s2
)
663 struct sortvec
*s1
, *s2
;
665 if (s1
->priority
!= s2
->priority
)
666 return s1
->priority
- s2
->priority
;
667 if (s1
->beg
!= s2
->beg
)
668 return s1
->beg
- s2
->beg
;
669 if (s1
->end
!= s2
->end
)
670 return s2
->end
- s1
->end
;
674 /* Return the face ID associated with a buffer position POS.
675 Store into *ENDPTR the position at which a different face is needed.
676 This does not take account of glyphs that specify their own face codes.
677 F is the frame in use for display, and W is a window displaying
680 REGION_BEG, REGION_END delimit the region, so it can be highlighted. */
683 compute_char_face (f
, w
, pos
, region_beg
, region_end
, endptr
)
687 int region_beg
, region_end
;
691 Lisp_Object prop
, position
;
694 Lisp_Object
*overlay_vec
;
695 struct sortvec
*sortvec
;
699 /* W must display the current buffer. We could write this function
700 to use the frame and buffer of W, but right now it doesn't. */
701 if (XBUFFER (w
->buffer
) != current_buffer
)
704 XSET (frame
, Lisp_Frame
, f
);
707 if (pos
< region_beg
&& region_beg
< endpos
)
710 XFASTINT (position
) = pos
;
711 prop
= Fget_text_property (position
, Qface
, w
->buffer
);
715 end
= Fnext_single_property_change (position
, Qface
, w
->buffer
);
724 /* First try with room for 40 overlays. */
726 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
728 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, &next_overlay
);
730 /* If there are more than 40,
731 make enough space for all, and try again. */
735 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
736 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, &next_overlay
);
739 if (next_overlay
< endpos
)
740 endpos
= next_overlay
;
745 /* Optimize the default case. */
746 if (noverlays
== 0 && NILP (prop
)
747 && !(pos
>= region_beg
&& pos
< region_end
))
750 compute_base_face (f
, &face
);
754 facecode
= face_name_id_number (f
, prop
);
755 if (facecode
>= 0 && facecode
< FRAME_N_FACES (f
)
756 && FRAME_FACES (f
) [facecode
] != 0)
757 merge_faces (FRAME_FACES (f
) [facecode
], &face
);
760 /* Put the valid and relevant overlays into sortvec. */
761 sortvec
= (struct sortvec
*) alloca (noverlays
* sizeof (struct sortvec
));
763 for (i
= 0, j
= 0; i
< noverlays
; i
++)
765 Lisp_Object overlay
= overlay_vec
[i
];
767 if (OVERLAY_VALID (overlay
)
768 && OVERLAY_POSITION (OVERLAY_START (overlay
)) > 0
769 && OVERLAY_POSITION (OVERLAY_END (overlay
)) > 0)
772 window
= Foverlay_get (overlay
, Qwindow
);
774 /* Also ignore overlays limited to one window
775 if it's not the window we are using. */
776 if (XTYPE (window
) != Lisp_Window
777 || XWINDOW (window
) == w
)
781 /* This overlay is good and counts:
782 put it in sortvec. */
783 sortvec
[j
].overlay
= overlay
;
784 sortvec
[j
].beg
= OVERLAY_POSITION (OVERLAY_START (overlay
));
785 sortvec
[j
].end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
786 tem
= Foverlay_get (overlay
, Qpriority
);
788 sortvec
[j
].priority
= XINT (tem
);
790 sortvec
[j
].priority
= 0;
797 /* Sort the overlays into the proper order: increasing priority. */
800 qsort (sortvec
, noverlays
, sizeof (struct sortvec
), sort_overlays
);
802 /* Now merge the overlay data in that order. */
803 for (i
= 0; i
< noverlays
; i
++)
805 prop
= Foverlay_get (sortvec
[i
].overlay
, Qface
);
811 facecode
= face_name_id_number (f
, prop
);
812 if (facecode
>= 0 && facecode
< FRAME_N_FACES (f
)
813 && FRAME_FACES (f
) [facecode
] != 0)
814 merge_faces (FRAME_FACES (f
) [facecode
], &face
);
816 oend
= OVERLAY_END (sortvec
[i
].overlay
);
817 oendpos
= OVERLAY_POSITION (oend
);
818 if (oendpos
< endpos
)
823 if (pos
>= region_beg
&& pos
< region_end
)
825 if (region_end
< endpos
)
827 if (region_face
>= 0 && region_face
< next_face_id
)
828 merge_faces (FRAME_FACES (f
) [region_face
], &face
);
833 return intern_frame_face (f
, &face
);
836 /* Return the face ID to use to display a special glyph which selects
837 FACE_CODE as the face ID, assuming that ordinarily the face would
838 be BASIC_FACE. F is the frame. */
840 compute_glyph_face (f
, face_code
)
846 compute_base_face (f
, &face
);
848 if (face_code
>= 0 && face_code
< FRAME_N_FACES (f
)
849 && FRAME_FACES (f
) [face_code
] != 0)
850 merge_faces (FRAME_FACES (f
) [face_code
], &face
);
852 return intern_frame_face (f
, &face
);
856 /* Recompute the GC's for the default and modeline faces.
857 We call this after changing frame parameters on which those GC's
860 recompute_basic_faces (f
)
863 /* If the frame's faces haven't been initialized yet, don't worry about
865 if (FRAME_N_FACES (f
) < 2)
870 if (FRAME_DEFAULT_FACE (f
)->gc
)
871 XFreeGC (x_current_display
, FRAME_DEFAULT_FACE (f
)->gc
);
872 build_face (f
, FRAME_DEFAULT_FACE (f
));
874 if (FRAME_MODE_LINE_FACE (f
)->gc
)
875 XFreeGC (x_current_display
, FRAME_MODE_LINE_FACE (f
)->gc
);
876 build_face (f
, FRAME_MODE_LINE_FACE (f
));
883 /* Lisp interface. */
885 DEFUN ("frame-face-alist", Fframe_face_alist
, Sframe_face_alist
, 1, 1, 0,
890 CHECK_FRAME (frame
, 0);
891 return XFRAME (frame
)->face_alist
;
894 DEFUN ("set-frame-face-alist", Fset_frame_face_alist
, Sset_frame_face_alist
,
897 Lisp_Object frame
, value
;
899 CHECK_FRAME (frame
, 0);
900 XFRAME (frame
)->face_alist
= value
;
905 DEFUN ("make-face-internal", Fmake_face_internal
, Smake_face_internal
, 1, 1, 0,
906 "Create face number FACE-ID on all frames.")
911 int id
= XINT (face_id
);
913 CHECK_NUMBER (face_id
, 0);
914 if (id
< 0 || id
>= next_face_id
)
915 error ("Face id out of range");
917 for (rest
= Vframe_list
; !NILP (rest
); rest
= XCONS (rest
)->cdr
)
919 struct frame
*f
= XFRAME (XCONS (rest
)->car
);
921 ensure_face_ready (f
, id
);
927 DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal
,
928 Sset_face_attribute_internal
, 4, 4, 0, "")
929 (face_id
, attr_name
, attr_value
, frame
)
930 Lisp_Object face_id
, attr_name
, attr_value
, frame
;
937 CHECK_FRAME (frame
, 0);
938 CHECK_NUMBER (face_id
, 0);
939 CHECK_SYMBOL (attr_name
, 0);
943 if (id
< 0 || id
>= next_face_id
)
944 error ("Face id out of range");
949 ensure_face_ready (f
, id
);
950 face
= FRAME_FACES (f
) [XFASTINT (face_id
)];
952 if (EQ (attr_name
, intern ("font")))
954 XFontStruct
*font
= load_font (f
, attr_value
);
955 if (face
->font
!= f
->display
.x
->font
)
956 unload_font (f
, face
->font
);
959 else if (EQ (attr_name
, intern ("foreground")))
961 unsigned long new_color
= load_color (f
, attr_value
);
962 unload_color (f
, face
->foreground
);
963 face
->foreground
= new_color
;
965 else if (EQ (attr_name
, intern ("background")))
967 unsigned long new_color
= load_color (f
, attr_value
);
968 unload_color (f
, face
->background
);
969 face
->background
= new_color
;
972 else if (EQ (attr_name
, intern ("background-pixmap")))
974 unsigned int w
, h
, d
;
975 unsigned long new_pixmap
= load_pixmap (f
, attr_value
, &w
, &h
, &d
, 0);
976 unload_pixmap (f
, face
->stipple
);
977 if (NILP (attr_value
))
979 face
->stipple
= new_pixmap
;
982 /* face->pixmap_depth = d; */
985 else if (EQ (attr_name
, intern ("underline")))
987 int new = !NILP (attr_value
);
988 face
->underline
= new;
991 error ("unknown face attribute");
996 if (FRAME_DEFAULT_FACE (f
)->gc
!= 0)
997 XFreeGC (x_current_display
, FRAME_DEFAULT_FACE (f
)->gc
);
998 build_face (f
, FRAME_DEFAULT_FACE (f
));
1005 if (FRAME_MODE_LINE_FACE (f
)->gc
!= 0)
1006 XFreeGC (x_current_display
, FRAME_MODE_LINE_FACE (f
)->gc
);
1007 build_face (f
, FRAME_MODE_LINE_FACE (f
));
1011 /* If we're modifying either of the frame's display faces, that
1012 means that we're changing the parameters of a fixed face code;
1013 since the color/font/whatever is changed but the face ID hasn't,
1014 redisplay won't know to redraw the affected sections. Give it a
1016 if (id
== 0 || id
== 1)
1017 SET_FRAME_GARBAGED (f
);
1019 /* Otherwise, it's enough to tell it to redisplay the text. */
1020 windows_or_buffers_changed
= 1;
1025 DEFUN ("internal-next-face-id", Finternal_next_face_id
, Sinternal_next_face_id
,
1029 return make_number (next_face_id
++);
1032 /* Return the face id for name NAME on frame FRAME.
1033 (It should be the same for all frames,
1034 but it's as easy to use the "right" frame to look it up
1035 as to use any other one.) */
1038 face_name_id_number (f
, name
)
1044 tem
= Fcdr (Fassq (name
, f
->face_alist
));
1047 CHECK_VECTOR (tem
, 0);
1048 tem
= XVECTOR (tem
)->contents
[2];
1049 CHECK_NUMBER (tem
, 0);
1053 /* Emacs initialization. */
1058 Qwindow
= intern ("window");
1059 staticpro (&Qwindow
);
1060 Qface
= intern ("face");
1062 Qpriority
= intern ("priority");
1063 staticpro (&Qpriority
);
1065 DEFVAR_INT ("region-face", ®ion_face
,
1066 "Face number to use to highlight the region\n\
1067 The region is highlighted with this face\n\
1068 when Transient Mark mode is enabled and the mark is active.");
1070 defsubr (&Sframe_face_alist
);
1071 defsubr (&Sset_frame_face_alist
);
1072 defsubr (&Smake_face_internal
);
1073 defsubr (&Sset_face_attribute_internal
);
1074 defsubr (&Sinternal_next_face_id
);
1077 #endif /* HAVE_X_WINDOWS */