1 /* "Face" primitives on the Microsoft W32 API.
2 Copyright (C) 1993, 1994, 1995 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, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Ported xfaces.c for w32 - Kevin Gallo */
23 #include <sys/types.h>
31 #include "dispextern.h"
33 #include "blockinput.h"
35 #include "intervals.h"
38 /* An explanation of the face data structures. */
40 /* ========================= Face Data Structures =========================
42 Let FACE-NAME be a symbol naming a face.
44 Let FACE-VECTOR be (assq FACE-NAME (frame-face-alist FRAME))
45 FACE-VECTOR is either nil, or a vector of the form
46 [face NAME ID FONT FOREGROUND BACKGROUND BACKGROUND-PIXMAP UNDERLINE-P]
48 face is the symbol `face',
49 NAME is the symbol with which this vector is associated (a backpointer),
50 ID is the face ID, an integer used internally by the C code to identify
52 FONT, FOREGROUND, and BACKGROUND are strings naming the fonts and colors
54 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't
56 UNDERLINE-P is non-nil if the face should be underlined.
57 If any of these elements are nil, that parameter is considered
58 unspecified; parameters from faces specified by lower-priority
59 overlays or text properties, or the parameters of the frame itself,
60 can show through. (lisp/faces.el maintains these lists.)
62 (assq FACE-NAME global-face-data) returns a vector describing the
63 global parameters for that face.
65 Let PARAM-FACE be FRAME->display.x->param_faces[Faref (FACE-VECTOR, 2)].
66 PARAM_FACE is a struct face whose members are the Xlib analogues of
67 the parameters in FACE-VECTOR. If an element of FACE-VECTOR is
68 nil, then the corresponding member of PARAM_FACE is FACE_DEFAULT.
69 These faces are called "parameter faces", because they're the ones
70 lisp manipulates to control what gets displayed. Elements 0 and 1
71 of FRAME->display.x->param_faces are special - they describe the
72 default and mode line faces. None of the faces in param_faces have
73 GC's. (See src/dispextern.h for the definition of struct face.
74 lisp/faces.el maintains the isomorphism between face_alist and
77 The functions compute_char_face and compute_glyph_face find and
78 combine the parameter faces associated with overlays and text
79 properties. The resulting faces are called "computed faces"; none
80 of their members are FACE_DEFAULT; they are completely specified.
81 They then call intern_compute_face to search
82 FRAME->display.x->computed_faces for a matching face, add one if
83 none is found, and return the index into
84 FRAME->display.x->computed_faces. FRAME's glyph matrices use these
85 indices to record the faces of the matrix characters, and the X
86 display hooks consult compute_faces to decide how to display these
87 characters. Elements 0 and 1 of computed_faces always describe the
88 default and mode-line faces.
90 Each computed face belongs to a particular frame.
92 Computed faces have graphics contexts some of the time.
93 intern_face builds a GC for a specified computed face
94 if it doesn't have one already.
95 clear_face_cache clears out the GCs of all computed faces.
96 This is done from time to time so that we don't hold on to
97 lots of GCs that are no longer needed.
101 Symbols naming faces must have associations on all frames; for any
102 FRAME, for all FACE-NAME, if (assq FACE-NAME (frame-face-alist
103 FRAME)) is non-nil, it must be non-nil for all frames.
105 Analogously, indices into param_faces must be valid on all frames;
106 if param_faces[i] is a non-zero face pointer on one frame, then it
107 must be filled in on all frames. Code assumes that face ID's can
108 be used on any frame.
112 Why do we keep param_faces and computed_faces separate?
113 computed_faces contains an element for every combination of facial
114 parameters we have ever displayed. indices into param_faces have
115 to be valid on all frames. If they were the same array, then that
116 array would grow very large on all frames, because any facial
117 combination displayed on any frame would need to be a valid entry
120 /* Definitions and declarations. */
122 /* The number of face-id's in use (same for all frames). */
123 static int next_face_id
;
125 /* The number of the face to use to indicate the region. */
126 static int region_face
;
128 /* This is what appears in a slot in a face to signify that the face
129 does not specify that display aspect. */
130 #define FACE_DEFAULT (~0)
132 Lisp_Object Qface
, Qmouse_face
;
133 Lisp_Object Qpixmap_spec_p
;
135 int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ );
137 struct face
*intern_face ( /* FRAME_PTR, struct face * */ );
138 static int new_computed_face ( /* FRAME_PTR, struct face * */ );
139 static int intern_computed_face ( /* FRAME_PTR, struct face * */ );
140 static void ensure_face_ready ( /* FRAME_PTR, int id */ );
141 void recompute_basic_faces ( /* FRAME_PTR f */ );
143 /* Allocating, copying, and comparing struct faces. */
145 /* Allocate a new face */
149 struct face
*result
= (struct face
*) xmalloc (sizeof (struct face
));
150 bzero (result
, sizeof (struct face
));
151 result
->font
= (XFontStruct
*) FACE_DEFAULT
;
152 result
->foreground
= FACE_DEFAULT
;
153 result
->background
= FACE_DEFAULT
;
154 result
->stipple
= FACE_DEFAULT
;
158 /* Make a new face that's a copy of an existing one. */
163 struct face
*result
= allocate_face ();
165 result
->font
= face
->font
;
166 result
->foreground
= face
->foreground
;
167 result
->background
= face
->background
;
168 result
->stipple
= face
->stipple
;
169 result
->underline
= face
->underline
;
170 result
->pixmap_h
= face
->pixmap_h
;
171 result
->pixmap_w
= face
->pixmap_w
;
177 face_eql (face1
, face2
)
178 struct face
*face1
, *face2
;
180 return ( face1
->font
== face2
->font
181 && face1
->foreground
== face2
->foreground
182 && face1
->background
== face2
->background
183 && face1
->stipple
== face2
->stipple
184 && face1
->underline
== face2
->underline
);
187 /* Managing graphics contexts of faces. */
189 /* Given a computed face, construct its graphics context if necessary. */
192 intern_face (f
, face
)
201 /* Clear out all graphics contexts for all computed faces
202 except for the default and mode line faces.
203 This should be done from time to time just to avoid
204 keeping too many graphics contexts that are no longer needed. */
212 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps.
214 These functions operate on param faces only.
215 Computed faces get their fonts, colors and pixmaps
216 by merging param faces. */
226 return (XFontStruct
*) FACE_DEFAULT
;
228 CHECK_STRING (name
, 0);
230 font
= w32_load_font (FRAME_W32_DISPLAY_INFO (f
), (char *) XSTRING (name
)->data
);
234 Fsignal (Qerror
, Fcons (build_string ("undefined font"),
235 Fcons (name
, Qnil
)));
240 unload_font (f
, font
)
244 if (!font
|| font
== ((XFontStruct
*) FACE_DEFAULT
))
248 w32_unload_font (FRAME_W32_DISPLAY_INFO (f
), font
);
263 CHECK_STRING (name
, 0);
264 /* if the colormap is full, defined_color will return a best match
265 to the values in an an existing cell. */
266 result
= defined_color(f
, (char *) XSTRING (name
)->data
, &color
, 1);
268 Fsignal (Qerror
, Fcons (build_string ("undefined color"),
269 Fcons (name
, Qnil
)));
270 return (unsigned long) color
;
274 unload_color (f
, pixel
)
280 DEFUN ("pixmap-spec-p", Fpixmap_spec_p
, Spixmap_spec_p
, 1, 1, 0,
281 "Return t if ARG is a valid pixmap specification.")
285 Lisp_Object height
, width
;
287 return ((STRINGP (arg
)
289 && CONSP (XCONS (arg
)->cdr
)
290 && CONSP (XCONS (XCONS (arg
)->cdr
)->cdr
)
291 && NILP (XCONS (XCONS (XCONS (arg
)->cdr
)->cdr
)->cdr
)
292 && (width
= XCONS (arg
)->car
, INTEGERP (width
))
293 && (height
= XCONS (XCONS (arg
)->cdr
)->car
, INTEGERP (height
))
294 && STRINGP (XCONS (XCONS (XCONS (arg
)->cdr
)->cdr
)->car
)
297 /* The string must have enough bits for width * height. */
298 && ((XSTRING (XCONS (XCONS (XCONS (arg
)->cdr
)->cdr
)->car
)->size
299 * (BITS_PER_INT
/ sizeof (int)))
300 >= XFASTINT (width
) * XFASTINT (height
))))
304 /* Load a bitmap according to NAME (which is either a file name
305 or a pixmap spec). Return the bitmap_id (see xfns.c)
306 or get an error if NAME is invalid.
308 Store the bitmap width in *W_PTR and height in *H_PTR. */
311 load_pixmap (f
, name
, w_ptr
, h_ptr
)
314 unsigned int *w_ptr
, *h_ptr
;
322 tem
= Fpixmap_spec_p (name
);
324 wrong_type_argument (Qpixmap_spec_p
, name
);
330 /* Decode a bitmap spec into a bitmap. */
335 w
= XINT (Fcar (name
));
336 h
= XINT (Fcar (Fcdr (name
)));
337 bits
= Fcar (Fcdr (Fcdr (name
)));
339 bitmap_id
= x_create_bitmap_from_data (f
, XSTRING (bits
)->data
,
344 /* It must be a string -- a file name. */
345 bitmap_id
= x_create_bitmap_from_file (f
, name
);
350 Fsignal (Qerror
, Fcons (build_string ("invalid or undefined bitmap"),
351 Fcons (name
, Qnil
)));
353 *w_ptr
= x_bitmap_width (f
, bitmap_id
);
354 *h_ptr
= x_bitmap_height (f
, bitmap_id
);
360 /* Managing parameter face arrays for frames. */
366 ensure_face_ready (f
, 0);
367 ensure_face_ready (f
, 1);
369 FRAME_N_COMPUTED_FACES (f
) = 0;
370 FRAME_SIZE_COMPUTED_FACES (f
) = 0;
372 new_computed_face (f
, FRAME_PARAM_FACES (f
)[0]);
373 new_computed_face (f
, FRAME_PARAM_FACES (f
)[1]);
374 recompute_basic_faces (f
);
376 /* Find another frame. */
378 Lisp_Object tail
, frame
, result
;
381 FOR_EACH_FRAME (tail
, frame
)
382 if (FRAME_W32_P (XFRAME (frame
))
383 && XFRAME (frame
) != f
)
389 /* If we didn't find any X frames other than f, then we don't need
390 any faces other than 0 and 1, so we're okay. Otherwise, make
391 sure that all faces valid on the selected frame are also valid
392 on this new frame. */
396 int n_faces
= FRAME_N_PARAM_FACES (XFRAME (result
));
397 struct face
**faces
= FRAME_PARAM_FACES (XFRAME (result
));
399 for (i
= 2; i
< n_faces
; i
++)
401 ensure_face_ready (f
, i
);
407 /* Called from Fdelete_frame. */
417 for (i
= 0; i
< FRAME_N_PARAM_FACES (f
); i
++)
419 struct face
*face
= FRAME_PARAM_FACES (f
) [i
];
422 unload_font (f
, face
->font
);
423 unload_color (f
, face
->foreground
);
424 unload_color (f
, face
->background
);
425 x_destroy_bitmap (f
, face
->stipple
);
429 xfree (FRAME_PARAM_FACES (f
));
430 FRAME_PARAM_FACES (f
) = 0;
431 FRAME_N_PARAM_FACES (f
) = 0;
433 /* All faces in FRAME_COMPUTED_FACES use resources copied from
434 FRAME_PARAM_FACES; we can free them without fuss.
435 But we do free the GCs and the face objects themselves. */
436 for (i
= 0; i
< FRAME_N_COMPUTED_FACES (f
); i
++)
438 struct face
*face
= FRAME_COMPUTED_FACES (f
) [i
];
444 xfree (FRAME_COMPUTED_FACES (f
));
445 FRAME_COMPUTED_FACES (f
) = 0;
446 FRAME_N_COMPUTED_FACES (f
) = 0;
451 /* Interning faces in a frame's face array. */
454 new_computed_face (f
, new_face
)
456 struct face
*new_face
;
458 int i
= FRAME_N_COMPUTED_FACES (f
);
460 if (i
>= FRAME_SIZE_COMPUTED_FACES (f
))
462 int new_size
= i
+ 32;
464 FRAME_COMPUTED_FACES (f
)
465 = (struct face
**) (FRAME_SIZE_COMPUTED_FACES (f
) == 0
466 ? xmalloc (new_size
* sizeof (struct face
*))
467 : xrealloc (FRAME_COMPUTED_FACES (f
),
468 new_size
* sizeof (struct face
*)));
469 FRAME_SIZE_COMPUTED_FACES (f
) = new_size
;
472 i
= FRAME_N_COMPUTED_FACES (f
)++;
473 FRAME_COMPUTED_FACES (f
)[i
] = copy_face (new_face
);
478 /* Find a match for NEW_FACE in a FRAME's computed face array, and add
479 it if we don't find one. */
481 intern_computed_face (f
, new_face
)
483 struct face
*new_face
;
485 int len
= FRAME_N_COMPUTED_FACES (f
);
488 /* Search for a computed face already on F equivalent to FACE. */
489 for (i
= 0; i
< len
; i
++)
491 if (! FRAME_COMPUTED_FACES (f
)[i
])
493 if (face_eql (new_face
, FRAME_COMPUTED_FACES (f
)[i
]))
497 /* We didn't find one; add a new one. */
498 return new_computed_face (f
, new_face
);
501 /* Make parameter face id ID valid on frame F. */
504 ensure_face_ready (f
, id
)
508 if (FRAME_N_PARAM_FACES (f
) <= id
)
512 if (!FRAME_N_PARAM_FACES (f
))
513 FRAME_PARAM_FACES (f
)
514 = (struct face
**) xmalloc (sizeof (struct face
*) * n
);
516 FRAME_PARAM_FACES (f
)
517 = (struct face
**) xrealloc (FRAME_PARAM_FACES (f
),
518 sizeof (struct face
*) * n
);
520 bzero (FRAME_PARAM_FACES (f
) + FRAME_N_PARAM_FACES (f
),
521 (n
- FRAME_N_PARAM_FACES (f
)) * sizeof (struct face
*));
522 FRAME_N_PARAM_FACES (f
) = n
;
525 if (FRAME_PARAM_FACES (f
) [id
] == 0)
526 FRAME_PARAM_FACES (f
) [id
] = allocate_face ();
529 /* Return non-zero if FONT1 and FONT2 have the same width.
530 We do not check the height, because we can now deal with
532 We assume that they're both character-cell fonts. */
535 same_size_fonts (font1
, font2
)
536 XFontStruct
*font1
, *font2
;
538 return (FONT_WIDTH(font1
) == FONT_WIDTH(font2
));
541 /* Update the line_height of frame F according to the biggest font in
542 any face. Return nonzero if if line_height changes. */
545 frame_update_line_height (f
)
549 int biggest
= FONT_HEIGHT (f
->output_data
.w32
->font
);
551 for (i
= 0; i
< f
->output_data
.w32
->n_param_faces
; i
++)
552 if (f
->output_data
.w32
->param_faces
[i
] != 0
553 && f
->output_data
.w32
->param_faces
[i
]->font
!= (XFontStruct
*) FACE_DEFAULT
)
555 int height
= FONT_HEIGHT (f
->output_data
.w32
->param_faces
[i
]->font
);
556 if (height
> biggest
)
560 if (biggest
== f
->output_data
.w32
->line_height
)
563 f
->output_data
.w32
->line_height
= biggest
;
567 /* Modify face TO by copying from FROM all properties which have
568 nondefault settings. */
571 merge_faces (from
, to
)
572 struct face
*from
, *to
;
574 /* Only merge the font if it's the same width as the base font.
575 Otherwise ignore it, since we can't handle it properly. */
576 if (from
->font
!= (XFontStruct
*) FACE_DEFAULT
577 && same_size_fonts (from
->font
, to
->font
))
578 to
->font
= from
->font
;
579 if (from
->foreground
!= FACE_DEFAULT
)
580 to
->foreground
= from
->foreground
;
581 if (from
->background
!= FACE_DEFAULT
)
582 to
->background
= from
->background
;
583 if (from
->stipple
!= FACE_DEFAULT
)
585 to
->stipple
= from
->stipple
;
586 to
->pixmap_h
= from
->pixmap_h
;
587 to
->pixmap_w
= from
->pixmap_w
;
590 to
->underline
= from
->underline
;
593 /* Set up the basic set of facial parameters, based on the frame's
594 data; all faces are deltas applied to this. */
597 compute_base_face (f
, face
)
602 face
->foreground
= FRAME_FOREGROUND_PIXEL (f
);
603 face
->background
= FRAME_BACKGROUND_PIXEL (f
);
604 face
->font
= FRAME_FONT (f
);
609 /* Return the face ID to use to display a special glyph which selects
610 FACE_CODE as the face ID, assuming that ordinarily the face would
611 be CURRENT_FACE. F is the frame. */
614 compute_glyph_face (f
, face_code
, current_face
)
616 int face_code
, current_face
;
620 face
= *FRAME_COMPUTED_FACES (f
)[current_face
];
622 if (face_code
>= 0 && face_code
< FRAME_N_PARAM_FACES (f
)
623 && FRAME_PARAM_FACES (f
) [face_code
] != 0)
624 merge_faces (FRAME_PARAM_FACES (f
) [face_code
], &face
);
626 return intern_computed_face (f
, &face
);
629 /* Return the face ID to use to display a special glyph which selects
630 FACE_CODE as the face ID, assuming that ordinarily the face would
631 be CURRENT_FACE. F is the frame. */
634 compute_glyph_face_1 (f
, face_name
, current_face
)
636 Lisp_Object face_name
;
641 face
= *FRAME_COMPUTED_FACES (f
)[current_face
];
643 if (!NILP (face_name
))
645 int facecode
= face_name_id_number (f
, face_name
);
646 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
647 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
648 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
651 return intern_computed_face (f
, &face
);
654 /* Return the face ID associated with a buffer position POS.
655 Store into *ENDPTR the position at which a different face is needed.
656 This does not take account of glyphs that specify their own face codes.
657 F is the frame in use for display, and W is a window displaying
660 REGION_BEG, REGION_END delimit the region, so it can be highlighted.
662 LIMIT is a position not to scan beyond. That is to limit
663 the time this function can take.
665 If MOUSE is nonzero, use the character's mouse-face, not its face. */
668 compute_char_face (f
, w
, pos
, region_beg
, region_end
, endptr
, limit
, mouse
)
672 int region_beg
, region_end
;
678 Lisp_Object prop
, position
;
681 Lisp_Object
*overlay_vec
;
684 Lisp_Object propname
;
686 /* W must display the current buffer. We could write this function
687 to use the frame and buffer of W, but right now it doesn't. */
688 if (XBUFFER (w
->buffer
) != current_buffer
)
691 XSETFRAME (frame
, f
);
694 if (pos
< region_beg
&& region_beg
< endpos
)
697 XSETFASTINT (position
, pos
);
700 propname
= Qmouse_face
;
704 prop
= Fget_text_property (position
, propname
, w
->buffer
);
707 Lisp_Object limit1
, end
;
709 XSETFASTINT (limit1
, (limit
< endpos
? limit
: endpos
));
710 end
= Fnext_single_property_change (position
, propname
, w
->buffer
, limit1
);
719 /* First try with room for 40 overlays. */
721 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
723 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
,
724 &next_overlay
, (int *) 0);
726 /* If there are more than 40,
727 make enough space for all, and try again. */
731 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
732 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
,
733 &next_overlay
, (int *) 0);
736 if (next_overlay
< endpos
)
737 endpos
= next_overlay
;
742 /* Optimize the default case. */
743 if (noverlays
== 0 && NILP (prop
)
744 && !(pos
>= region_beg
&& pos
< region_end
))
747 compute_base_face (f
, &face
);
751 /* We have a list of faces, merge them in reverse order */
752 Lisp_Object length
= Flength (prop
);
753 int len
= XINT (length
);
756 /* Put them into an array */
757 faces
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
758 for (j
= 0; j
< len
; j
++)
760 faces
[j
] = Fcar (prop
);
763 /* So that we can merge them in the reverse order */
764 for (j
= len
- 1; j
>= 0; j
--)
766 facecode
= face_name_id_number (f
, faces
[j
]);
767 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
768 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
769 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
772 else if (!NILP (prop
))
774 facecode
= face_name_id_number (f
, prop
);
775 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
776 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
777 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
780 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
782 /* Now merge the overlay data in that order. */
783 for (i
= 0; i
< noverlays
; i
++)
785 prop
= Foverlay_get (overlay_vec
[i
], propname
);
788 /* We have a list of faces, merge them in reverse order */
789 Lisp_Object length
= Flength (prop
);
790 int len
= XINT (length
);
794 /* Put them into an array */
795 faces
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
796 for (j
= 0; j
< len
; j
++)
798 faces
[j
] = Fcar (prop
);
801 /* So that we can merge them in the reverse order */
802 for (j
= len
- 1; j
>= 0; j
--)
804 facecode
= face_name_id_number (f
, faces
[j
]);
805 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
806 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
807 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
810 else if (!NILP (prop
))
815 facecode
= face_name_id_number (f
, prop
);
816 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
817 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
818 merge_faces (FRAME_PARAM_FACES (f
)[facecode
], &face
);
820 oend
= OVERLAY_END (overlay_vec
[i
]);
821 oendpos
= OVERLAY_POSITION (oend
);
822 if (oendpos
< endpos
)
827 if (pos
>= region_beg
&& pos
< region_end
)
829 if (region_end
< endpos
)
831 if (region_face
>= 0 && region_face
< next_face_id
)
832 merge_faces (FRAME_PARAM_FACES (f
)[region_face
], &face
);
837 return intern_computed_face (f
, &face
);
840 /* Recompute the GC's for the default and modeline faces.
841 We call this after changing frame parameters on which those GC's
845 recompute_basic_faces (f
)
848 /* If the frame's faces haven't been initialized yet, don't worry about
850 if (FRAME_N_PARAM_FACES (f
) < 2)
855 compute_base_face (f
, FRAME_DEFAULT_FACE (f
));
856 compute_base_face (f
, FRAME_MODE_LINE_FACE (f
));
858 merge_faces (FRAME_DEFAULT_PARAM_FACE (f
), FRAME_DEFAULT_FACE (f
));
859 merge_faces (FRAME_MODE_LINE_PARAM_FACE (f
), FRAME_MODE_LINE_FACE (f
));
861 intern_face (f
, FRAME_DEFAULT_FACE (f
));
862 intern_face (f
, FRAME_MODE_LINE_FACE (f
));
869 /* Lisp interface. */
871 DEFUN ("frame-face-alist", Fframe_face_alist
, Sframe_face_alist
, 1, 1, 0,
876 CHECK_FRAME (frame
, 0);
877 return XFRAME (frame
)->face_alist
;
880 DEFUN ("set-frame-face-alist", Fset_frame_face_alist
, Sset_frame_face_alist
,
883 Lisp_Object frame
, value
;
885 CHECK_FRAME (frame
, 0);
886 XFRAME (frame
)->face_alist
= value
;
891 DEFUN ("make-face-internal", Fmake_face_internal
, Smake_face_internal
, 1, 1, 0,
892 "Create face number FACE-ID on all frames.")
896 Lisp_Object rest
, frame
;
897 int id
= XINT (face_id
);
899 CHECK_NUMBER (face_id
, 0);
900 if (id
< 0 || id
>= next_face_id
)
901 error ("Face id out of range");
903 FOR_EACH_FRAME (rest
, frame
)
905 if (FRAME_W32_P (XFRAME (frame
)))
906 ensure_face_ready (XFRAME (frame
), id
);
912 DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal
,
913 Sset_face_attribute_internal
, 4, 4, 0, "")
914 (face_id
, attr_name
, attr_value
, frame
)
915 Lisp_Object face_id
, attr_name
, attr_value
, frame
;
923 CHECK_FRAME (frame
, 0);
924 CHECK_NUMBER (face_id
, 0);
925 CHECK_SYMBOL (attr_name
, 0);
929 if (id
< 0 || id
>= next_face_id
)
930 error ("Face id out of range");
932 if (! FRAME_W32_P (f
))
935 ensure_face_ready (f
, id
);
936 face
= FRAME_PARAM_FACES (f
) [XFASTINT (face_id
)];
938 if (EQ (attr_name
, intern ("font")))
940 XFontStruct
*font
= load_font (f
, attr_value
);
941 if (face
->font
!= f
->output_data
.w32
->font
)
942 unload_font (f
, face
->font
);
944 if (frame_update_line_height (f
))
945 x_set_window_size (f
, 0, f
->width
, f
->height
);
946 /* Must clear cache, since it might contain the font
947 we just got rid of. */
950 else if (EQ (attr_name
, intern ("foreground")))
952 unsigned long new_color
= load_color (f
, attr_value
);
953 unload_color (f
, face
->foreground
);
954 face
->foreground
= new_color
;
957 else if (EQ (attr_name
, intern ("background")))
959 unsigned long new_color
= load_color (f
, attr_value
);
960 unload_color (f
, face
->background
);
961 face
->background
= new_color
;
964 else if (EQ (attr_name
, intern ("background-pixmap")))
967 unsigned long new_pixmap
= load_pixmap (f
, attr_value
, &w
, &h
);
968 x_destroy_bitmap (f
, face
->stipple
);
969 face
->stipple
= (Pixmap
) new_pixmap
;
974 else if (EQ (attr_name
, intern ("underline")))
976 int new = !NILP (attr_value
);
977 face
->underline
= new;
980 error ("unknown face attribute");
982 if (id
== 0 || id
== 1)
983 recompute_basic_faces (f
);
985 /* We must redraw the frame whenever any face font or color changes,
986 because it's possible that a merged (display) face
987 contains the font or color we just replaced.
988 And we must inhibit any Expose events until the redraw is done,
989 since they would try to use the invalid display faces. */
991 SET_FRAME_GARBAGED (f
);
996 DEFUN ("internal-next-face-id", Finternal_next_face_id
, Sinternal_next_face_id
,
1000 return make_number (next_face_id
++);
1003 /* Return the face id for name NAME on frame FRAME.
1004 (It should be the same for all frames,
1005 but it's as easy to use the "right" frame to look it up
1006 as to use any other one.) */
1009 face_name_id_number (f
, name
)
1015 tem
= Fcdr (assq_no_quit (name
, f
->face_alist
));
1018 CHECK_VECTOR (tem
, 0);
1019 tem
= XVECTOR (tem
)->contents
[2];
1020 CHECK_NUMBER (tem
, 0);
1024 /* Emacs initialization. */
1029 Qface
= intern ("face");
1031 Qmouse_face
= intern ("mouse-face");
1032 staticpro (&Qmouse_face
);
1033 Qpixmap_spec_p
= intern ("pixmap-spec-p");
1034 staticpro (&Qpixmap_spec_p
);
1036 DEFVAR_INT ("region-face", ®ion_face
,
1037 "Face number to use to highlight the region\n\
1038 The region is highlighted with this face\n\
1039 when Transient Mark mode is enabled and the mark is active.");
1041 defsubr (&Spixmap_spec_p
);
1042 defsubr (&Sframe_face_alist
);
1043 defsubr (&Sset_frame_face_alist
);
1044 defsubr (&Smake_face_internal
);
1045 defsubr (&Sset_face_attribute_internal
);
1046 defsubr (&Sinternal_next_face_id
);