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, on which it requires
38 time.h. On some such systems, Xos.h tries to redefine struct
39 timeval and struct timezone if USG is #defined while it is
41 #ifdef XOS_NEEDS_TIME_H
56 /* An explanation of the face data structures. */
58 /* ========================= Face Data Structures =========================
60 Let FACE-NAME be a symbol naming a face.
62 Let FACE-VECTOR be (assq FACE-NAME (frame-face-alist FRAME))
63 FACE-VECTOR is either nil, or a vector of the form
64 [face NAME ID FONT FOREGROUND BACKGROUND BACKGROUND-PIXMAP UNDERLINE-P]
66 face is the symbol `face',
67 NAME is the symbol with which this vector is associated (a backpointer),
68 ID is the face ID, an integer used internally by the C code to identify
70 FONT, FOREGROUND, and BACKGROUND are strings naming the fonts and colors
72 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't
74 UNDERLINE-P is non-nil if the face should be underlined.
75 If any of these elements are nil, that parameter is considered
76 unspecified; parameters from faces specified by lower-priority
77 overlays or text properties, or the parameters of the frame itself,
78 can show through. (lisp/faces.el maintains these lists.)
80 (assq FACE-NAME global-face-data) returns a vector describing the
81 global parameters for that face.
83 Let PARAM-FACE be FRAME->display.x->param_faces[Faref (FACE-VECTOR, 2)].
84 PARAM_FACE is a struct face whose members are the Xlib analogues of
85 the parameters in FACE-VECTOR. If an element of FACE-VECTOR is
86 nil, then the corresponding member of PARAM_FACE is FACE_DEFAULT.
87 These faces are called "parameter faces", because they're the ones
88 lisp manipulates to control what gets displayed. Elements 0 and 1
89 of FRAME->display.x->param_faces are special - they describe the
90 default and mode line faces. None of the faces in param_faces have
91 GC's. (See src/dispextern.h for the definiton of struct face.
92 lisp/faces.el maintains the isomorphism between face_alist and
95 The functions compute_char_face and compute_glyph_face find and
96 combine the parameter faces associated with overlays and text
97 properties. The resulting faces are called "computed faces"; none
98 of their members are FACE_DEFAULT; they are completely specified.
99 They then call intern_compute_face to search
100 FRAME->display.x->computed_faces for a matching face, add one if
101 none is found, and return the index into
102 FRAME->display.x->computed_faces. FRAME's glyph matrices use these
103 indices to record the faces of the matrix characters, and the X
104 display hooks consult compute_faces to decide how to display these
105 characters. Elements 0 and 1 of computed_faces always describe the
106 default and mode-line faces.
108 Elements 0 and 1 of computed_faces have GC's; all the other faces
109 in computed_faces do not. The global array face_vector contains
110 faces with their GC's set. Given a computed_face, the function
111 intern_face finds (or adds) an element of face_vector with
112 equivalent parameters, and returns a pointer to that face, whose GC
113 can then be used for display.
117 Symbols naming faces must have associations on all frames; for any
118 FRAME, for all FACE-NAME, if (assq FACE-NAME (frame-face-alist
119 FRAME)) is non-nil, it must be non-nil for all frames.
121 Analogously, indices into param_faces must be valid on all frames;
122 if param_faces[i] is a non-zero face pointer on one frame, then it
123 must be filled in on all frames. Code assumes that face ID's can
124 be used on any frame.
128 Why do we keep param_faces and computed_faces separate?
129 computed_faces contains an element for every combination of facial
130 parameters we have ever displayed. indices into param_faces have
131 to be valid on all frames. If they were the same array, then that
132 array would grow very large on all frames, because any facial
133 combination displayed on any frame would need to be a valid entry
136 Since face_vector is just a cache --- there are no pointers into it
137 from the rest of the code, and everyone accesses it through
138 intern_face --- we could just free its GC's and throw the whole
139 thing away without breaking anything. This gives us a simple way
140 to garbage-collect old GC's nobody's using any more - we can just
141 purge face_vector, and then let subsequent calls to intern_face
142 refill it as needed. The function clear_face_vector performs this
145 We're often applying intern_face to faces in computed_faces -
146 for example, we do this while sending GLYPHs from a struct
147 frame_glyphs to X during redisplay. It would be nice to avoid
148 searching all of face_vector every time we intern a frame's face.
149 So, when intern_face finds a match for FACE in face_vector, it
150 stores the index of the match in FACE's cached_index member, and
151 checks there first next time. */
154 /* Definitions and declarations. */
156 /* A table of display faces. */
157 static struct face
**face_vector
;
158 /* The length in use of the table. */
160 /* The allocated length of the table. */
161 static int nfaces_allocated
;
163 /* The number of face-id's in use (same for all frames). */
166 /* The number of the face to use to indicate the region. */
169 /* This is what appears in a slot in a face to signify that the face
170 does not specify that display aspect. */
171 #define FACE_DEFAULT (~0)
173 Lisp_Object Qface
, Qwindow
, Qpriority
;
175 static void build_face ( /* FRAME_PTR, struct face * */ );
176 int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ );
178 struct face
*intern_face ( /* FRAME_PTR, struct face * */ );
179 static int new_computed_face ( /* FRAME_PTR, struct face * */ );
180 static int intern_computed_face ( /* FRAME_PTR, struct face * */ );
181 static void ensure_face_ready ( /* FRAME_PTR, int id */ );
182 void recompute_basic_faces ( /* FRAME_PTR f */ );
184 /* Allocating, copying, and comparing struct faces. */
186 /* Allocate a new face */
190 struct face
*result
= (struct face
*) xmalloc (sizeof (struct face
));
191 bzero (result
, sizeof (struct face
));
192 result
->font
= (XFontStruct
*) FACE_DEFAULT
;
193 result
->foreground
= FACE_DEFAULT
;
194 result
->background
= FACE_DEFAULT
;
195 result
->stipple
= FACE_DEFAULT
;
199 /* Make a new face that's a copy of an existing one. */
204 struct face
*result
= allocate_face ();
206 result
->font
= face
->font
;
207 result
->foreground
= face
->foreground
;
208 result
->background
= face
->background
;
209 result
->stipple
= face
->stipple
;
210 result
->underline
= face
->underline
;
216 face_eql (face1
, face2
)
217 struct face
*face1
, *face2
;
219 return ( face1
->font
== face2
->font
220 && face1
->foreground
== face2
->foreground
221 && face1
->background
== face2
->background
222 && face1
->stipple
== face2
->stipple
223 && face1
->underline
== face2
->underline
);
226 /* Interning faces in the `face_vector' cache, and clearing that cache. */
228 /* Return the unique display face corresponding to the user-level face FACE.
229 If there isn't one, make one, and find a slot in the face_vector to
232 get_cached_face (f
, face
)
239 /* Perhaps FACE->cached_index is valid; this could happen if FACE is
240 in a frame's face list. */
241 if (face
->cached_index
>= 0
242 && face
->cached_index
< nfaces
243 && face_eql (face_vector
[face
->cached_index
], face
))
244 return face_vector
[face
->cached_index
];
246 /* Look for an existing display face that does the job.
247 Also find an empty slot if any. */
248 for (i
= 0; i
< nfaces
; i
++)
250 if (face_eql (face_vector
[i
], face
))
251 return face_vector
[i
];
252 if (face_vector
[i
] == 0)
256 /* If no empty slots, make one. */
257 if (empty
< 0 && nfaces
== nfaces_allocated
)
259 int newsize
= nfaces
+ 20;
261 = (struct face
**) xrealloc (face_vector
,
262 newsize
* sizeof (struct face
*));
263 nfaces_allocated
= newsize
;
269 /* Put a new display face in the empty slot. */
270 result
= copy_face (face
);
271 face_vector
[empty
] = result
;
273 /* Make a graphics context for it. */
274 build_face (f
, result
);
279 /* Given a computed face, return an equivalent display face
280 (one which has a graphics context). */
283 intern_face (f
, face
)
287 /* If it's equivalent to the default face, use that. */
288 if (face_eql (face
, FRAME_DEFAULT_FACE (f
)))
290 if (!FRAME_DEFAULT_FACE (f
)->gc
)
291 build_face (f
, FRAME_DEFAULT_FACE (f
));
292 return FRAME_DEFAULT_FACE (f
);
295 /* If it's equivalent to the mode line face, use that. */
296 if (face_eql (face
, FRAME_MODE_LINE_FACE (f
)))
298 if (!FRAME_MODE_LINE_FACE (f
)->gc
)
299 build_face (f
, FRAME_MODE_LINE_FACE (f
));
300 return FRAME_MODE_LINE_FACE (f
);
303 /* If it's not one of the frame's default faces, it shouldn't have a GC. */
307 /* Get a specialized display face. */
308 return get_cached_face (f
, face
);
311 /* Clear out face_vector and start anew.
312 This should be done from time to time just to avoid
313 keeping too many graphics contexts in face_vector
314 that are no longer needed. */
320 Display
*dpy
= x_current_display
;
324 /* Free the display faces in the face_vector. */
325 for (i
= 0; i
< nfaces
; i
++)
327 struct face
*face
= face_vector
[i
];
329 XFreeGC (dpy
, face
->gc
);
337 /* Allocating and freeing X resources for display faces. */
339 /* Make a graphics context for face FACE, which is on frame F,
340 if that can be done. */
352 if (face
->foreground
!= FACE_DEFAULT
)
353 xgcv
.foreground
= face
->foreground
;
355 xgcv
.foreground
= f
->display
.x
->foreground_pixel
;
357 if (face
->background
!= FACE_DEFAULT
)
358 xgcv
.background
= face
->background
;
360 xgcv
.background
= f
->display
.x
->background_pixel
;
362 if (face
->font
&& (int) face
->font
!= FACE_DEFAULT
)
363 xgcv
.font
= face
->font
->fid
;
365 xgcv
.font
= f
->display
.x
->font
->fid
;
367 xgcv
.graphics_exposures
= 0;
369 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
370 gc
= XCreateGC (x_current_display
, FRAME_X_WINDOW (f
),
374 if (face
->stipple
&& face
->stipple
!= FACE_DEFAULT
)
375 XSetStipple (x_current_display
, gc
, face
->stipple
);
383 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps. */
393 return (XFontStruct
*) FACE_DEFAULT
;
395 CHECK_STRING (name
, 0);
397 font
= XLoadQueryFont (x_current_display
, (char *) XSTRING (name
)->data
);
401 Fsignal (Qerror
, Fcons (build_string ("undefined font"),
402 Fcons (name
, Qnil
)));
407 unload_font (f
, font
)
411 if (!font
|| font
== ((XFontStruct
*) FACE_DEFAULT
))
415 XFreeFont (x_current_display
, font
);
424 Display
*dpy
= x_current_display
;
432 cmap
= DefaultColormapOfScreen (DefaultScreenOfDisplay (x_current_display
));
434 CHECK_STRING (name
, 0);
436 result
= XParseColor (dpy
, cmap
, (char *) XSTRING (name
)->data
, &color
);
439 Fsignal (Qerror
, Fcons (build_string ("undefined color"),
440 Fcons (name
, Qnil
)));
442 result
= XAllocColor (dpy
, cmap
, &color
);
445 Fsignal (Qerror
, Fcons (build_string ("X server cannot allocate color"),
446 Fcons (name
, Qnil
)));
447 return (unsigned long) color
.pixel
;
451 unload_color (f
, pixel
)
455 /* Since faces get built by copying parameters from other faces, the
456 allocation counts for the colors get all screwed up. I don't see
457 any solution that will take less than 10 minutes, and it's better
458 to have a color leak than a crash, so I'm just dyking this out.
459 This isn't really a color leak, anyway - if we ask for it again,
460 we'll get the same pixel. */
463 Display
*dpy
= x_current_display
;
464 if (pixel
== FACE_DEFAULT
465 || pixel
== BLACK_PIX_DEFAULT
466 || pixel
== WHITE_PIX_DEFAULT
)
468 cmap
= DefaultColormapOfScreen (DefaultScreenOfDisplay (x_current_display
));
470 XFreeColors (dpy
, cmap
, &pixel
, 1, 0);
475 /* Managing parameter face arrays for frames. */
481 ensure_face_ready (f
, 0);
482 ensure_face_ready (f
, 1);
484 FRAME_N_COMPUTED_FACES (f
) = 0;
485 FRAME_SIZE_COMPUTED_FACES (f
) = 0;
487 new_computed_face (f
, FRAME_PARAM_FACES (f
)[0]);
488 new_computed_face (f
, FRAME_PARAM_FACES (f
)[1]);
489 recompute_basic_faces (f
);
491 /* Find another X frame. */
493 Lisp_Object tail
, frame
, result
;
496 FOR_EACH_FRAME (tail
, frame
)
497 if (FRAME_X_P (XFRAME (frame
))
498 && XFRAME (frame
) != f
)
504 /* If we didn't find any X frames other than f, then we don't need
505 any faces other than 0 and 1, so we're okay. Otherwise, make
506 sure that all faces valid on the selected frame are also valid
507 on this new frame. */
511 int n_faces
= FRAME_N_PARAM_FACES (XFRAME (result
));
512 struct face
**faces
= FRAME_PARAM_FACES (XFRAME (result
));
514 for (i
= 2; i
< n_faces
; i
++)
516 ensure_face_ready (f
, i
);
522 /* Called from Fdelete_frame. */
527 Display
*dpy
= x_current_display
;
532 for (i
= 0; i
< FRAME_N_PARAM_FACES (f
); i
++)
534 struct face
*face
= FRAME_PARAM_FACES (f
) [i
];
538 XFreeGC (dpy
, face
->gc
);
539 unload_font (f
, face
->font
);
540 unload_color (f
, face
->foreground
);
541 unload_color (f
, face
->background
);
543 unload_pixmap (f
, face
->stipple
);
548 xfree (FRAME_PARAM_FACES (f
));
549 FRAME_PARAM_FACES (f
) = 0;
550 FRAME_N_PARAM_FACES (f
) = 0;
552 /* All faces in FRAME_COMPUTED_FACES use resources copied from
553 FRAME_PARAM_FACES; we can free them without fuss. */
554 xfree (FRAME_COMPUTED_FACES (f
));
555 FRAME_COMPUTED_FACES (f
) = 0;
556 FRAME_N_COMPUTED_FACES (f
) = 0;
561 /* Interning faces in a frame's face array. */
564 new_computed_face (f
, new_face
)
566 struct face
*new_face
;
568 int i
= FRAME_N_COMPUTED_FACES (f
);
570 if (i
>= FRAME_SIZE_COMPUTED_FACES (f
))
572 int new_size
= i
+ 32;
574 FRAME_COMPUTED_FACES (f
)
575 = (struct face
**) (FRAME_SIZE_COMPUTED_FACES (f
) == 0
576 ? xmalloc (new_size
* sizeof (struct face
*))
577 : xrealloc (FRAME_COMPUTED_FACES (f
),
578 new_size
* sizeof (struct face
*)));
579 FRAME_SIZE_COMPUTED_FACES (f
) = new_size
;
582 i
= FRAME_N_COMPUTED_FACES (f
)++;
583 FRAME_COMPUTED_FACES (f
)[i
] = copy_face (new_face
);
588 /* Find a match for NEW_FACE in a FRAME's computed face array, and add
589 it if we don't find one. */
591 intern_computed_face (f
, new_face
)
593 struct face
*new_face
;
595 int len
= FRAME_N_COMPUTED_FACES (f
);
598 /* Search for a computed face already on F equivalent to FACE. */
599 for (i
= 0; i
< len
; i
++)
601 if (! FRAME_COMPUTED_FACES (f
)[i
])
603 if (face_eql (new_face
, FRAME_COMPUTED_FACES (f
)[i
]))
607 /* We didn't find one; add a new one. */
608 return new_computed_face (f
, new_face
);
611 /* Make parameter face id ID valid on frame F. */
614 ensure_face_ready (f
, id
)
618 if (FRAME_N_PARAM_FACES (f
) <= id
)
622 if (!FRAME_N_PARAM_FACES (f
))
623 FRAME_PARAM_FACES (f
)
624 = (struct face
**) xmalloc (sizeof (struct face
*) * n
);
626 FRAME_PARAM_FACES (f
)
627 = (struct face
**) xrealloc (FRAME_PARAM_FACES (f
),
628 sizeof (struct face
*) * n
);
630 bzero (FRAME_PARAM_FACES (f
) + FRAME_N_PARAM_FACES (f
),
631 (n
- FRAME_N_PARAM_FACES (f
)) * sizeof (struct face
*));
632 FRAME_N_PARAM_FACES (f
) = n
;
635 if (FRAME_PARAM_FACES (f
) [id
] == 0)
636 FRAME_PARAM_FACES (f
) [id
] = allocate_face ();
639 /* Computing faces appropriate for a given piece of text in a buffer. */
641 /* Return non-zero if FONT1 and FONT2 have the same size bounding box.
642 We assume that they're both character-cell fonts. */
644 same_size_fonts (font1
, font2
)
645 XFontStruct
*font1
, *font2
;
647 XCharStruct
*bounds1
= &font1
->min_bounds
;
648 XCharStruct
*bounds2
= &font2
->min_bounds
;
650 return (bounds1
->width
== bounds2
->width
);
651 /* Checking the following caused bad results in some cases
652 when fonts that should be the same size
653 actually have very slightly different size.
654 It is possible that this reintroduces the bug whereby line positions
655 were not right. However, the right way to fix that is to change xterm.c
656 so that the vertical positions of lines
657 depend only on the height of the frame's font.
658 && bounds1->ascent == bounds2->ascent
659 && bounds1->descent == bounds2->descent); */
662 /* Modify face TO by copying from FROM all properties which have
663 nondefault settings. */
665 merge_faces (from
, to
)
666 struct face
*from
, *to
;
668 /* Only merge the font if it's the same size as the base font. */
669 if (from
->font
!= (XFontStruct
*) FACE_DEFAULT
670 && same_size_fonts (from
->font
, to
->font
))
671 to
->font
= from
->font
;
672 if (from
->foreground
!= FACE_DEFAULT
)
673 to
->foreground
= from
->foreground
;
674 if (from
->background
!= FACE_DEFAULT
)
675 to
->background
= from
->background
;
676 if (from
->stipple
!= FACE_DEFAULT
)
677 to
->stipple
= from
->stipple
;
679 to
->underline
= from
->underline
;
682 /* Set up the basic set of facial parameters, based on the frame's
683 data; all faces are deltas applied to this. */
685 compute_base_face (f
, face
)
689 struct x_display
*d
= f
->display
.x
;
692 face
->foreground
= d
->foreground_pixel
;
693 face
->background
= d
->background_pixel
;
694 face
->font
= d
->font
;
698 /* Avoid a face comparison by making this invalid. */
699 face
->cached_index
= -1;
711 sort_overlays (s1
, s2
)
712 struct sortvec
*s1
, *s2
;
714 if (s1
->priority
!= s2
->priority
)
715 return s1
->priority
- s2
->priority
;
716 if (s1
->beg
!= s2
->beg
)
717 return s1
->beg
- s2
->beg
;
718 if (s1
->end
!= s2
->end
)
719 return s2
->end
- s1
->end
;
723 /* Return the face ID associated with a buffer position POS.
724 Store into *ENDPTR the position at which a different face is needed.
725 This does not take account of glyphs that specify their own face codes.
726 F is the frame in use for display, and W is a window displaying
729 REGION_BEG, REGION_END delimit the region, so it can be highlighted.
731 LIMIT is a position not to scan beyond. That is to limit
732 the time this function can take. */
735 compute_char_face (f
, w
, pos
, region_beg
, region_end
, endptr
, limit
)
739 int region_beg
, region_end
;
744 Lisp_Object prop
, position
;
747 Lisp_Object
*overlay_vec
;
748 struct sortvec
*sortvec
;
752 /* W must display the current buffer. We could write this function
753 to use the frame and buffer of W, but right now it doesn't. */
754 if (XBUFFER (w
->buffer
) != current_buffer
)
757 XSET (frame
, Lisp_Frame
, f
);
760 if (pos
< region_beg
&& region_beg
< endpos
)
763 XFASTINT (position
) = pos
;
764 prop
= Fget_text_property (position
, Qface
, w
->buffer
);
766 Lisp_Object limit1
, end
;
768 XFASTINT (limit1
) = (limit
< endpos
? limit
: endpos
);
769 end
= Fnext_single_property_change (position
, Qface
, w
->buffer
, limit1
);
778 /* First try with room for 40 overlays. */
780 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
782 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, &next_overlay
);
784 /* If there are more than 40,
785 make enough space for all, and try again. */
789 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
790 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, &next_overlay
);
793 if (next_overlay
< endpos
)
794 endpos
= next_overlay
;
799 /* Optimize the default case. */
800 if (noverlays
== 0 && NILP (prop
)
801 && !(pos
>= region_beg
&& pos
< region_end
))
804 compute_base_face (f
, &face
);
808 facecode
= face_name_id_number (f
, prop
);
809 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
810 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
811 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
814 /* Put the valid and relevant overlays into sortvec. */
815 sortvec
= (struct sortvec
*) alloca (noverlays
* sizeof (struct sortvec
));
817 for (i
= 0, j
= 0; i
< noverlays
; i
++)
819 Lisp_Object overlay
= overlay_vec
[i
];
821 if (OVERLAY_VALID (overlay
)
822 && OVERLAY_POSITION (OVERLAY_START (overlay
)) > 0
823 && OVERLAY_POSITION (OVERLAY_END (overlay
)) > 0)
826 window
= Foverlay_get (overlay
, Qwindow
);
828 /* Also ignore overlays limited to one window
829 if it's not the window we are using. */
830 if (XTYPE (window
) != Lisp_Window
831 || XWINDOW (window
) == w
)
835 /* This overlay is good and counts:
836 put it in sortvec. */
837 sortvec
[j
].overlay
= overlay
;
838 sortvec
[j
].beg
= OVERLAY_POSITION (OVERLAY_START (overlay
));
839 sortvec
[j
].end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
840 tem
= Foverlay_get (overlay
, Qpriority
);
842 sortvec
[j
].priority
= XINT (tem
);
844 sortvec
[j
].priority
= 0;
851 /* Sort the overlays into the proper order: increasing priority. */
854 qsort (sortvec
, noverlays
, sizeof (struct sortvec
), sort_overlays
);
856 /* Now merge the overlay data in that order. */
857 for (i
= 0; i
< noverlays
; i
++)
859 prop
= Foverlay_get (sortvec
[i
].overlay
, Qface
);
865 facecode
= face_name_id_number (f
, prop
);
866 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
867 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
868 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
870 oend
= OVERLAY_END (sortvec
[i
].overlay
);
871 oendpos
= OVERLAY_POSITION (oend
);
872 if (oendpos
< endpos
)
877 if (pos
>= region_beg
&& pos
< region_end
)
879 if (region_end
< endpos
)
881 if (region_face
>= 0 && region_face
< next_face_id
)
882 merge_faces (FRAME_PARAM_FACES (f
) [region_face
], &face
);
887 return intern_computed_face (f
, &face
);
890 /* Return the face ID to use to display a special glyph which selects
891 FACE_CODE as the face ID, assuming that ordinarily the face would
892 be CURRENT_FACE. F is the frame. */
895 compute_glyph_face (f
, face_code
, current_face
)
897 int face_code
, current_face
;
901 face
= *FRAME_COMPUTED_FACES (f
)[current_face
];
903 if (face_code
>= 0 && face_code
< FRAME_N_PARAM_FACES (f
)
904 && FRAME_PARAM_FACES (f
) [face_code
] != 0)
905 merge_faces (FRAME_PARAM_FACES (f
) [face_code
], &face
);
907 return intern_computed_face (f
, &face
);
911 /* Recompute the GC's for the default and modeline faces.
912 We call this after changing frame parameters on which those GC's
916 recompute_basic_faces (f
)
919 /* If the frame's faces haven't been initialized yet, don't worry about
921 if (FRAME_N_PARAM_FACES (f
) < 2)
926 if (FRAME_DEFAULT_FACE (f
)->gc
)
927 XFreeGC (x_current_display
, FRAME_DEFAULT_FACE (f
)->gc
);
928 if (FRAME_MODE_LINE_FACE (f
)->gc
)
929 XFreeGC (x_current_display
, FRAME_MODE_LINE_FACE (f
)->gc
);
931 compute_base_face (f
, FRAME_DEFAULT_FACE (f
));
932 compute_base_face (f
, FRAME_MODE_LINE_FACE (f
));
934 merge_faces (FRAME_DEFAULT_PARAM_FACE (f
), FRAME_DEFAULT_FACE (f
));
935 merge_faces (FRAME_MODE_LINE_PARAM_FACE (f
), FRAME_MODE_LINE_FACE (f
));
937 build_face (f
, FRAME_DEFAULT_FACE (f
));
938 build_face (f
, FRAME_MODE_LINE_FACE (f
));
945 /* Lisp interface. */
947 DEFUN ("frame-face-alist", Fframe_face_alist
, Sframe_face_alist
, 1, 1, 0,
952 CHECK_FRAME (frame
, 0);
953 return XFRAME (frame
)->face_alist
;
956 DEFUN ("set-frame-face-alist", Fset_frame_face_alist
, Sset_frame_face_alist
,
959 Lisp_Object frame
, value
;
961 CHECK_FRAME (frame
, 0);
962 XFRAME (frame
)->face_alist
= value
;
967 DEFUN ("make-face-internal", Fmake_face_internal
, Smake_face_internal
, 1, 1, 0,
968 "Create face number FACE-ID on all frames.")
973 int id
= XINT (face_id
);
975 CHECK_NUMBER (face_id
, 0);
976 if (id
< 0 || id
>= next_face_id
)
977 error ("Face id out of range");
979 for (rest
= Vframe_list
; !NILP (rest
); rest
= XCONS (rest
)->cdr
)
981 struct frame
*f
= XFRAME (XCONS (rest
)->car
);
983 ensure_face_ready (f
, id
);
989 DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal
,
990 Sset_face_attribute_internal
, 4, 4, 0, "")
991 (face_id
, attr_name
, attr_value
, frame
)
992 Lisp_Object face_id
, attr_name
, attr_value
, frame
;
999 CHECK_FRAME (frame
, 0);
1000 CHECK_NUMBER (face_id
, 0);
1001 CHECK_SYMBOL (attr_name
, 0);
1004 id
= XINT (face_id
);
1005 if (id
< 0 || id
>= next_face_id
)
1006 error ("Face id out of range");
1008 if (! FRAME_X_P (f
))
1011 ensure_face_ready (f
, id
);
1012 face
= FRAME_PARAM_FACES (f
) [XFASTINT (face_id
)];
1014 if (EQ (attr_name
, intern ("font")))
1016 XFontStruct
*font
= load_font (f
, attr_value
);
1017 if (face
->font
!= f
->display
.x
->font
)
1018 unload_font (f
, face
->font
);
1021 else if (EQ (attr_name
, intern ("foreground")))
1023 unsigned long new_color
= load_color (f
, attr_value
);
1024 unload_color (f
, face
->foreground
);
1025 face
->foreground
= new_color
;
1027 else if (EQ (attr_name
, intern ("background")))
1029 unsigned long new_color
= load_color (f
, attr_value
);
1030 unload_color (f
, face
->background
);
1031 face
->background
= new_color
;
1034 else if (EQ (attr_name
, intern ("background-pixmap")))
1036 unsigned int w
, h
, d
;
1037 unsigned long new_pixmap
= load_pixmap (f
, attr_value
, &w
, &h
, &d
, 0);
1038 unload_pixmap (f
, face
->stipple
);
1039 if (NILP (attr_value
))
1041 face
->stipple
= new_pixmap
;
1044 /* face->pixmap_depth = d; */
1047 else if (EQ (attr_name
, intern ("underline")))
1049 int new = !NILP (attr_value
);
1050 face
->underline
= new;
1053 error ("unknown face attribute");
1055 if (id
== 0 || id
== 1)
1056 recompute_basic_faces (f
);
1058 /* If we're modifying either of the frame's display faces, that
1059 means that we're changing the parameters of a fixed face code;
1060 since the color/font/whatever is changed but the face ID hasn't,
1061 redisplay won't know to redraw the affected sections. Give it a
1063 if (id
== 0 || id
== 1)
1064 SET_FRAME_GARBAGED (f
);
1066 /* Otherwise, it's enough to tell it to redisplay the text. */
1067 windows_or_buffers_changed
= 1;
1072 DEFUN ("internal-next-face-id", Finternal_next_face_id
, Sinternal_next_face_id
,
1076 return make_number (next_face_id
++);
1079 /* Return the face id for name NAME on frame FRAME.
1080 (It should be the same for all frames,
1081 but it's as easy to use the "right" frame to look it up
1082 as to use any other one.) */
1085 face_name_id_number (f
, name
)
1091 tem
= Fcdr (assq_no_quit (name
, f
->face_alist
));
1094 CHECK_VECTOR (tem
, 0);
1095 tem
= XVECTOR (tem
)->contents
[2];
1096 CHECK_NUMBER (tem
, 0);
1100 /* Emacs initialization. */
1105 Qwindow
= intern ("window");
1106 staticpro (&Qwindow
);
1107 Qface
= intern ("face");
1109 Qpriority
= intern ("priority");
1110 staticpro (&Qpriority
);
1112 DEFVAR_INT ("region-face", ®ion_face
,
1113 "Face number to use to highlight the region\n\
1114 The region is highlighted with this face\n\
1115 when Transient Mark mode is enabled and the mark is active.");
1117 defsubr (&Sframe_face_alist
);
1118 defsubr (&Sset_frame_face_alist
);
1119 defsubr (&Smake_face_internal
);
1120 defsubr (&Sset_face_attribute_internal
);
1121 defsubr (&Sinternal_next_face_id
);
1124 #endif /* HAVE_X_WINDOWS */