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 hpux. */
43 /* Display Context for the icons */
44 #include <X11/Intrinsic.h>
45 #include <X11/StringDefs.h>
46 /* #include <X11/Xmu/Drawing.h> */ /* Appears not to be used */
50 /* An explanation of the face data structures. */
52 /* ========================= Face Data Structures =========================
54 All lisp code uses symbols as face names.
56 Each frame has a face_alist member (with the frame-face-alist and
57 set-frame-face-alist accessors), associating the face names with
59 [face NAME ID FONT FOREGROUND BACKGROUND BACKGROUND-PIXMAP UNDERLINE-P]
61 face is the symbol `face',
62 NAME is the symbol with which this vector is associated (a backpointer),
63 ID is the face ID, an integer used internally by the C code to identify
65 FONT, FOREGROUND, and BACKGROUND are strings naming the fonts and colors
67 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't
69 UNDERLINE-P is non-nil if the face should be underlined.
70 If any of these elements are nil, that allows the frame's parameters to
72 (lisp/faces.el maintains these association lists.)
74 The frames' private alists hold the frame-local definitions for the
75 faces. The lisp variable global-face-data contains the global
76 defaults for faces. (See lisp/faces.el for this too.)
78 In the C code, we also have a `struct face' with the elements
79 `foreground', `background', `font', and `underline',
80 which specify its visual appearance, and elements
81 `gc' and `cached_index';
82 `gc' may be an X GC which has been built for the given display
83 parameters. Faces with GC's are called `display faces'. Whether
84 or not a face has a GC depends on what data structure the face is
85 in; we explain these more below. (See src/dispextern.h.)
87 Each frame also has members called `faces' and `n_faces' (with the
88 accessors FRAME_FACES and FRAME_N_FACES), which define an array of
89 struct face pointers, indexed by face ID (element 2 of the
90 vector). These are called "frame faces".
91 Element 0 is the default face --- the one used for normal text.
92 Element 1 is the modeline face.
93 These faces have their GC's set; the rest do not.
94 If faces[i] is filled in (i.e. non-zero) on one frame, then it must
95 be filled in on all frames. Code assumes that face ID's can be
96 used on any frame. (See src/xterm.h.)
98 The global variables `face_vector' and `nfaces' define another
99 array of struct face pointers, with their GC's set. This array
100 acts as a cache of GC's to be used by all frames. The function
101 `intern_face', passed a struct face *, searches face_vector for a
102 struct face with the same parameters, adds a new one with a GC if
103 it doesn't find one, and returns it. If you have a `struct face',
104 and you want a GC for it, call intern_face on that struct, and it
105 will return a `struct face *' with its GC set. The faces in
106 face_vector are called `cached faces.' (See src/xfaces.c.)
108 The `GLYPH' data type is an unsigned integer type; the bottom byte
109 is a character code, and the byte above that is a face id. The
110 `struct frame_glyphs' structure, used to describe frames' current
111 or desired contents, is essentially a matrix of GLYPHs; the face
112 ID's in a struct frame_glyphs are indices into FRAME_FACES. (See
117 Since face_vector is just a cache --- there are no pointers into it
118 from the rest of the code, and everyone accesses it through
119 intern_face --- we could just free its GC's and throw the whole
120 thing away without breaking anything. This gives us a simple way
121 to garbage-collect old GC's nobody's using any more - we can just
122 purge face_vector, and then let subsequent calls to intern_face
123 refill it as needed. The function clear_face_vector performs this
126 We're often applying intern_face to faces in frames' local arrays -
127 for example, we do this while sending GLYPHs from a struct
128 frame_glyphs to X during redisplay. It would be nice to avoid
129 searching all of face_vector every time we intern a frame's face.
130 So, when intern_face finds a match for FACE in face_vector, it
131 stores the index of the match in FACE's cached_index member, and
132 checks there first next time. */
135 /* Definitions and declarations. */
137 /* A table of display faces. */
138 struct face
**face_vector
;
139 /* The length in use of the table. */
141 /* The allocated length of the table. */
142 int nfaces_allocated
;
144 /* The number of face-id's in use (same for all frames). */
147 /* The number of the face to use to indicate the region. */
150 /* This is what appears in a slot in a face to signify that the face
151 does not specify that display aspect. */
152 #define FACE_DEFAULT (~0)
154 Lisp_Object Qface
, Qwindow
, Qpriority
;
156 static void build_face ();
157 int face_name_id_number ();
159 struct face
*intern_face ();
160 static void ensure_face_ready ();
162 /* Allocating, copying, and comparing struct faces. */
164 /* Allocate a new face */
168 struct face
*result
= (struct face
*) xmalloc (sizeof (struct face
));
169 bzero (result
, sizeof (struct face
));
170 result
->font
= (XFontStruct
*) FACE_DEFAULT
;
171 result
->foreground
= FACE_DEFAULT
;
172 result
->background
= FACE_DEFAULT
;
173 result
->stipple
= FACE_DEFAULT
;
177 /* Make a new face that's a copy of an existing one. */
182 struct face
*result
= allocate_face ();
184 result
->font
= face
->font
;
185 result
->foreground
= face
->foreground
;
186 result
->background
= face
->background
;
187 result
->stipple
= face
->stipple
;
188 result
->underline
= face
->underline
;
194 face_eql (face1
, face2
)
195 struct face
*face1
, *face2
;
197 return ( face1
->font
== face2
->font
198 && face1
->foreground
== face2
->foreground
199 && face1
->background
== face2
->background
200 && face1
->stipple
== face2
->stipple
201 && face1
->underline
== face2
->underline
);
204 /* Interning faces in the `face_vector' cache, and clearing that cache. */
206 /* Return the unique display face corresponding to the user-level face FACE.
207 If there isn't one, make one, and find a slot in the face_vector to
210 get_cached_face (f
, face
)
217 /* Perhaps FACE->cached_index is valid; this could happen if FACE is
218 in a frame's face list. */
219 if (face
->cached_index
>= 0
220 && face
->cached_index
< nfaces
221 && face_eql (face_vector
[face
->cached_index
], face
))
222 return face_vector
[face
->cached_index
];
224 /* Look for an existing display face that does the job.
225 Also find an empty slot if any. */
226 for (i
= 0; i
< nfaces
; i
++)
228 if (face_eql (face_vector
[i
], face
))
229 return face_vector
[i
];
230 if (face_vector
[i
] == 0)
234 /* If no empty slots, make one. */
235 if (empty
< 0 && nfaces
== nfaces_allocated
)
237 int newsize
= nfaces
+ 20;
239 = (struct face
**) xrealloc (face_vector
,
240 newsize
* sizeof (struct face
*));
241 nfaces_allocated
= newsize
;
247 /* Put a new display face in the empty slot. */
248 result
= copy_face (face
);
249 face_vector
[empty
] = result
;
251 /* Make a graphics context for it. */
252 build_face (f
, result
);
257 /* Given a frame face, return an equivalent display face
258 (one which has a graphics context). */
261 intern_face (f
, face
)
265 /* If it's equivalent to the default face, use that. */
266 if (face_eql (face
, FRAME_DEFAULT_FACE (f
)))
268 if (!FRAME_DEFAULT_FACE (f
)->gc
)
269 build_face (f
, FRAME_DEFAULT_FACE (f
));
270 return FRAME_DEFAULT_FACE (f
);
273 /* If it's equivalent to the mode line face, use that. */
274 if (face_eql (face
, FRAME_MODE_LINE_FACE (f
)))
276 if (!FRAME_MODE_LINE_FACE (f
)->gc
)
277 build_face (f
, FRAME_MODE_LINE_FACE (f
));
278 return FRAME_MODE_LINE_FACE (f
);
281 /* If it's not one of the frame's default faces, it shouldn't have a GC. */
285 /* Get a specialized display face. */
286 return get_cached_face (f
, face
);
289 /* Clear out face_vector and start anew.
290 This should be done from time to time just to avoid
291 keeping too many graphics contexts in face_vector
292 that are no longer needed. */
298 Display
*dpy
= x_current_display
;
302 /* Free the display faces in the face_vector. */
303 for (i
= 0; i
< nfaces
; i
++)
305 struct face
*face
= face_vector
[i
];
307 XFreeGC (dpy
, face
->gc
);
315 /* Allocating and freeing X resources for display faces. */
317 /* Make a graphics context for face FACE, which is on frame F,
318 if that can be done. */
330 if (face
->foreground
!= FACE_DEFAULT
)
331 xgcv
.foreground
= face
->foreground
;
333 xgcv
.foreground
= f
->display
.x
->foreground_pixel
;
335 if (face
->background
!= FACE_DEFAULT
)
336 xgcv
.background
= face
->background
;
338 xgcv
.background
= f
->display
.x
->background_pixel
;
340 if (face
->font
&& (int) face
->font
!= FACE_DEFAULT
)
341 xgcv
.font
= face
->font
->fid
;
343 xgcv
.font
= f
->display
.x
->font
->fid
;
345 xgcv
.graphics_exposures
= 0;
347 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
348 gc
= XCreateGC (x_current_display
, FRAME_X_WINDOW (f
),
352 if (face
->stipple
&& face
->stipple
!= FACE_DEFAULT
)
353 XSetStipple (x_current_display
, gc
, face
->stipple
);
361 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps. */
371 return (XFontStruct
*) FACE_DEFAULT
;
373 CHECK_STRING (name
, 0);
375 font
= XLoadQueryFont (x_current_display
, (char *) XSTRING (name
)->data
);
379 Fsignal (Qerror
, Fcons (build_string ("undefined font"),
380 Fcons (name
, Qnil
)));
385 unload_font (f
, font
)
389 if (!font
|| font
== ((XFontStruct
*) FACE_DEFAULT
))
393 XFreeFont (x_current_display
, font
);
402 Display
*dpy
= x_current_display
;
410 cmap
= DefaultColormapOfScreen (DefaultScreenOfDisplay (x_current_display
));
412 CHECK_STRING (name
, 0);
414 result
= XParseColor (dpy
, cmap
, (char *) XSTRING (name
)->data
, &color
);
417 Fsignal (Qerror
, Fcons (build_string ("undefined color"),
418 Fcons (name
, Qnil
)));
420 result
= XAllocColor (dpy
, cmap
, &color
);
423 Fsignal (Qerror
, Fcons (build_string ("X server cannot allocate color"),
424 Fcons (name
, Qnil
)));
425 return (unsigned long) color
.pixel
;
429 unload_color (f
, pixel
)
433 /* Since faces get built by copying parameters from other faces, the
434 allocation counts for the colors get all screwed up. I don't see
435 any solution that will take less than 10 minutes, and it's better
436 to have a color leak than a crash, so I'm just dyking this out.
437 This isn't really a color leak, anyway - if we ask for it again,
438 we'll get the same pixel. */
441 Display
*dpy
= x_current_display
;
442 if (pixel
== FACE_DEFAULT
443 || pixel
== BLACK_PIX_DEFAULT
444 || pixel
== WHITE_PIX_DEFAULT
)
446 cmap
= DefaultColormapOfScreen (DefaultScreenOfDisplay (x_current_display
));
448 XFreeColors (dpy
, cmap
, &pixel
, 1, 0);
453 /* Initializing face arrays for frames. */
459 ensure_face_ready (f
, 0);
460 ensure_face_ready (f
, 1);
462 recompute_basic_faces (f
);
464 /* Supposedly, we only apply this function to newly-created frames. */
465 if (selected_frame
== f
)
468 /* Make sure that all faces valid on the selected frame are also valid
469 on this new frame. */
472 int n_faces
= selected_frame
->display
.x
->n_faces
;
473 struct face
**faces
= selected_frame
->display
.x
->faces
;
475 for (i
= 2; i
< n_faces
; i
++)
477 ensure_face_ready (f
, i
);
482 /* Called from Fdelete_frame. */
487 Display
*dpy
= x_current_display
;
492 for (i
= 0; i
< FRAME_N_FACES (f
); i
++)
494 struct face
*face
= FRAME_FACES (f
) [i
];
498 XFreeGC (dpy
, face
->gc
);
501 unload_font (f
, face
->font
);
502 unload_color (f
, face
->foreground
);
503 unload_color (f
, face
->background
);
505 unload_pixmap (f
, face
->stipple
);
511 xfree (FRAME_FACES (f
));
513 FRAME_N_FACES (f
) = 0;
518 /* Interning faces in a frame's face array. */
520 /* Find a match for NEW_FACE in a FRAME's face array, and add it if we don't
523 intern_frame_face (frame
, new_face
)
525 struct face
*new_face
;
527 int len
= FRAME_N_FACES (frame
);
530 /* Search for a face already on FRAME equivalent to FACE. */
531 for (i
= 0; i
< len
; i
++)
533 struct face
*frame_face
= FRAME_FACES (frame
)[i
];
535 if (frame_face
&& face_eql (new_face
, frame_face
))
539 /* We didn't find one; add a new one. */
542 ensure_face_ready (frame
, i
);
543 bcopy (new_face
, FRAME_FACES (frame
)[i
], sizeof (*new_face
));
544 FRAME_FACES (frame
)[i
]->copy
= 1;
549 /* Make face id ID valid on frame F. */
552 ensure_face_ready (f
, id
)
556 if (FRAME_N_FACES (f
) <= id
)
560 if (!FRAME_N_FACES (f
))
562 = (struct face
**) xmalloc (sizeof (struct face
*) * n
);
565 = (struct face
**) xrealloc (FRAME_FACES (f
),
566 sizeof (struct face
*) * n
);
568 bzero (FRAME_FACES (f
) + FRAME_N_FACES (f
),
569 (n
- FRAME_N_FACES (f
)) * sizeof (struct face
*));
570 FRAME_N_FACES (f
) = n
;
573 if (FRAME_FACES (f
) [id
] == 0)
574 FRAME_FACES (f
) [id
] = allocate_face ();
577 /* Computing faces appropriate for a given piece of text in a buffer. */
579 /* Return non-zero if FONT1 and FONT2 have the same size bounding box.
580 We assume that they're both character-cell fonts. */
582 same_size_fonts (font1
, font2
)
583 XFontStruct
*font1
, *font2
;
585 XCharStruct
*bounds1
= &font1
->min_bounds
;
586 XCharStruct
*bounds2
= &font2
->min_bounds
;
588 return (bounds1
->width
== bounds2
->width
589 && bounds1
->ascent
== bounds2
->ascent
590 && bounds1
->descent
== bounds2
->descent
);
593 /* Modify face TO by copying from FROM all properties which have
594 nondefault settings. */
596 merge_faces (from
, to
)
597 struct face
*from
, *to
;
599 /* Only merge the font if it's the same size as the base font. */
600 if (from
->font
!= (XFontStruct
*) FACE_DEFAULT
601 && same_size_fonts (from
->font
, to
->font
))
602 to
->font
= from
->font
;
603 if (from
->foreground
!= FACE_DEFAULT
)
604 to
->foreground
= from
->foreground
;
605 if (from
->background
!= FACE_DEFAULT
)
606 to
->background
= from
->background
;
607 if (from
->stipple
!= FACE_DEFAULT
)
608 to
->stipple
= from
->stipple
;
610 to
->underline
= from
->underline
;
613 /* Set up the basic set of facial parameters, based on the frame's
614 data; all faces are deltas applied to this. */
616 compute_base_face (f
, face
)
620 struct x_display
*d
= f
->display
.x
;
623 face
->foreground
= d
->foreground_pixel
;
624 face
->background
= d
->background_pixel
;
625 face
->font
= d
->font
;
638 sort_overlays (s1
, s2
)
639 struct sortvec
*s1
, *s2
;
641 if (s1
->priority
!= s2
->priority
)
642 return s1
->priority
- s2
->priority
;
643 if (s1
->beg
!= s2
->beg
)
644 return s1
->beg
- s2
->beg
;
645 if (s1
->end
!= s2
->end
)
646 return s2
->end
- s1
->end
;
650 /* Return the face ID associated with a buffer position POS.
651 Store into *ENDPTR the position at which a different face is needed.
652 This does not take account of glyphs that specify their own face codes.
653 F is the frame in use for display, and W is a window displaying
656 REGION_BEG, REGION_END delimit the region, so it can be highlighted. */
659 compute_char_face (f
, w
, pos
, region_beg
, region_end
, endptr
)
663 int region_beg
, region_end
;
667 Lisp_Object prop
, position
;
670 Lisp_Object
*overlay_vec
;
671 struct sortvec
*sortvec
;
675 /* W must display the current buffer. We could write this function
676 to use the frame and buffer of W, but right now it doesn't. */
677 if (XBUFFER (w
->buffer
) != current_buffer
)
680 XSET (frame
, Lisp_Frame
, f
);
683 if (pos
< region_beg
&& region_beg
< endpos
)
686 XFASTINT (position
) = pos
;
687 prop
= Fget_text_property (position
, Qface
, w
->buffer
);
691 end
= Fnext_single_property_change (position
, Qface
, w
->buffer
);
700 /* First try with room for 40 overlays. */
702 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
704 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, &next_overlay
);
706 /* If there are more than 40,
707 make enough space for all, and try again. */
711 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
712 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, &next_overlay
);
715 if (next_overlay
< endpos
)
716 endpos
= next_overlay
;
721 /* Optimize the default case. */
722 if (noverlays
== 0 && NILP (prop
)
723 && !(pos
>= region_beg
&& pos
< region_end
))
726 compute_base_face (f
, &face
);
730 facecode
= face_name_id_number (f
, prop
);
731 if (facecode
>= 0 && facecode
< FRAME_N_FACES (f
)
732 && FRAME_FACES (f
) [facecode
] != 0)
733 merge_faces (FRAME_FACES (f
) [facecode
], &face
);
736 /* Put the valid and relevant overlays into sortvec. */
737 sortvec
= (struct sortvec
*) alloca (noverlays
* sizeof (struct sortvec
));
739 for (i
= 0, j
= 0; i
< noverlays
; i
++)
741 Lisp_Object overlay
= overlay_vec
[i
];
743 if (OVERLAY_VALID (overlay
)
744 && OVERLAY_POSITION (OVERLAY_START (overlay
)) > 0
745 && OVERLAY_POSITION (OVERLAY_END (overlay
)) > 0)
748 window
= Foverlay_get (overlay
, Qwindow
);
750 /* Also ignore overlays limited to one window
751 if it's not the window we are using. */
752 if (XTYPE (window
) != Lisp_Window
753 || XWINDOW (window
) == w
)
757 /* This overlay is good and counts:
758 put it in sortvec. */
759 sortvec
[j
].overlay
= overlay
;
760 sortvec
[j
].beg
= OVERLAY_POSITION (OVERLAY_START (overlay
));
761 sortvec
[j
].end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
762 tem
= Foverlay_get (overlay
, Qpriority
);
764 sortvec
[j
].priority
= XINT (tem
);
766 sortvec
[j
].priority
= 0;
773 /* Sort the overlays into the proper order: increasing priority. */
776 qsort (sortvec
, noverlays
, sizeof (struct sortvec
), sort_overlays
);
778 /* Now merge the overlay data in that order. */
779 for (i
= 0; i
< noverlays
; i
++)
781 prop
= Foverlay_get (sortvec
[i
].overlay
, Qface
);
787 facecode
= face_name_id_number (f
, prop
);
788 if (facecode
>= 0 && facecode
< FRAME_N_FACES (f
)
789 && FRAME_FACES (f
) [facecode
] != 0)
790 merge_faces (FRAME_FACES (f
) [facecode
], &face
);
792 oend
= OVERLAY_END (sortvec
[i
].overlay
);
793 oendpos
= OVERLAY_POSITION (oend
);
794 if (oendpos
< endpos
)
799 if (pos
>= region_beg
&& pos
< region_end
)
801 if (region_end
< endpos
)
803 if (region_face
>= 0 && region_face
< next_face_id
)
804 merge_faces (FRAME_FACES (f
) [region_face
], &face
);
809 return intern_frame_face (f
, &face
);
812 /* Return the face ID to use to display a special glyph which selects
813 FACE_CODE as the face ID, assuming that ordinarily the face would
814 be BASIC_FACE. F is the frame. */
816 compute_glyph_face (f
, face_code
)
822 compute_base_face (f
, &face
);
824 if (face_code
>= 0 && face_code
< FRAME_N_FACES (f
)
825 && FRAME_FACES (f
) [face_code
] != 0)
826 merge_faces (FRAME_FACES (f
) [face_code
], &face
);
828 return intern_frame_face (f
, &face
);
832 /* Recompute the GC's for the default and modeline faces.
833 We call this after changing frame parameters on which those GC's
836 recompute_basic_faces (f
)
839 /* If the frame's faces haven't been initialized yet, don't worry about
841 if (FRAME_N_FACES (f
) < 2)
846 if (FRAME_DEFAULT_FACE (f
)->gc
)
847 XFreeGC (x_current_display
, FRAME_DEFAULT_FACE (f
)->gc
);
848 build_face (f
, FRAME_DEFAULT_FACE (f
));
850 if (FRAME_MODE_LINE_FACE (f
)->gc
)
851 XFreeGC (x_current_display
, FRAME_MODE_LINE_FACE (f
)->gc
);
852 build_face (f
, FRAME_MODE_LINE_FACE (f
));
859 /* Lisp interface. */
861 DEFUN ("frame-face-alist", Fframe_face_alist
, Sframe_face_alist
, 1, 1, 0,
866 CHECK_FRAME (frame
, 0);
867 return XFRAME (frame
)->face_alist
;
870 DEFUN ("set-frame-face-alist", Fset_frame_face_alist
, Sset_frame_face_alist
,
873 Lisp_Object frame
, value
;
875 CHECK_FRAME (frame
, 0);
876 XFRAME (frame
)->face_alist
= value
;
881 DEFUN ("make-face-internal", Fmake_face_internal
, Smake_face_internal
, 1, 1, 0,
882 "Create face number FACE-ID on all frames.")
887 int id
= XINT (face_id
);
889 CHECK_NUMBER (face_id
, 0);
890 if (id
< 0 || id
>= next_face_id
)
891 error ("Face id out of range");
893 for (rest
= Vframe_list
; !NILP (rest
); rest
= XCONS (rest
)->cdr
)
895 struct frame
*f
= XFRAME (XCONS (rest
)->car
);
897 ensure_face_ready (f
, id
);
903 DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal
,
904 Sset_face_attribute_internal
, 4, 4, 0, "")
905 (face_id
, attr_name
, attr_value
, frame
)
906 Lisp_Object face_id
, attr_name
, attr_value
, frame
;
913 CHECK_FRAME (frame
, 0);
914 CHECK_NUMBER (face_id
, 0);
915 CHECK_SYMBOL (attr_name
, 0);
919 if (id
< 0 || id
>= next_face_id
)
920 error ("Face id out of range");
925 ensure_face_ready (f
, id
);
926 face
= FRAME_FACES (f
) [XFASTINT (face_id
)];
928 if (EQ (attr_name
, intern ("font")))
930 XFontStruct
*font
= load_font (f
, attr_value
);
931 if (face
->font
!= f
->display
.x
->font
)
932 unload_font (f
, face
->font
);
935 else if (EQ (attr_name
, intern ("foreground")))
937 unsigned long new_color
= load_color (f
, attr_value
);
938 unload_color (f
, face
->foreground
);
939 face
->foreground
= new_color
;
941 else if (EQ (attr_name
, intern ("background")))
943 unsigned long new_color
= load_color (f
, attr_value
);
944 unload_color (f
, face
->background
);
945 face
->background
= new_color
;
948 else if (EQ (attr_name
, intern ("background-pixmap")))
950 unsigned int w
, h
, d
;
951 unsigned long new_pixmap
= load_pixmap (f
, attr_value
, &w
, &h
, &d
, 0);
952 unload_pixmap (f
, face
->stipple
);
953 if (NILP (attr_value
))
955 face
->stipple
= new_pixmap
;
958 /* face->pixmap_depth = d; */
961 else if (EQ (attr_name
, intern ("underline")))
963 int new = !NILP (attr_value
);
964 face
->underline
= new;
967 error ("unknown face attribute");
972 if (FRAME_DEFAULT_FACE (f
)->gc
!= 0)
973 XFreeGC (x_current_display
, FRAME_DEFAULT_FACE (f
)->gc
);
974 build_face (f
, FRAME_DEFAULT_FACE (f
));
981 if (FRAME_MODE_LINE_FACE (f
)->gc
!= 0)
982 XFreeGC (x_current_display
, FRAME_MODE_LINE_FACE (f
)->gc
);
983 build_face (f
, FRAME_MODE_LINE_FACE (f
));
987 /* If we're modifying either of the frame's display faces, that
988 means that we're changing the parameters of a fixed face code;
989 since the color/font/whatever is changed but the face ID hasn't,
990 redisplay won't know to redraw the affected sections. Give it a
992 if (id
== 0 || id
== 1)
993 SET_FRAME_GARBAGED (f
);
995 /* Otherwise, it's enough to tell it to redisplay the text. */
996 windows_or_buffers_changed
= 1;
1001 DEFUN ("internal-next-face-id", Finternal_next_face_id
, Sinternal_next_face_id
,
1005 return make_number (next_face_id
++);
1008 /* Return the face id for name NAME on frame FRAME.
1009 (It should be the same for all frames,
1010 but it's as easy to use the "right" frame to look it up
1011 as to use any other one.) */
1014 face_name_id_number (f
, name
)
1020 tem
= Fcdr (Fassq (name
, f
->face_alist
));
1023 CHECK_VECTOR (tem
, 0);
1024 tem
= XVECTOR (tem
)->contents
[2];
1025 CHECK_NUMBER (tem
, 0);
1029 /* Emacs initialization. */
1034 Qwindow
= intern ("window");
1035 staticpro (&Qwindow
);
1036 Qface
= intern ("face");
1038 Qpriority
= intern ("priority");
1039 staticpro (&Qpriority
);
1041 DEFVAR_INT ("region-face", ®ion_face
,
1042 "Face number to use to highlight the region\n\
1043 The region is highlighted with this face\n\
1044 when Transient Mark mode is enabled and the mark is active.");
1046 defsubr (&Sframe_face_alist
);
1047 defsubr (&Sset_frame_face_alist
);
1048 defsubr (&Smake_face_internal
);
1049 defsubr (&Sset_face_attribute_internal
);
1050 defsubr (&Sinternal_next_face_id
);
1053 #endif /* HAVE_X_WINDOWS */