1 /* "Face" primitives on the Microsoft W32 API.
2 Copyright (C) 1993, 1994, 1995, 1999 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 */
24 #include <sys/types.h>
31 #include "dispextern.h"
33 #include "blockinput.h"
35 #include "intervals.h"
40 /* An explanation of the face data structures. */
42 /* ========================= Face Data Structures =========================
44 Let FACE-NAME be a symbol naming a face.
46 Let FACE-VECTOR be (assq FACE-NAME (frame-face-alist FRAME))
47 FACE-VECTOR is either nil, or a vector of the form
48 [face NAME ID FONT FOREGROUND BACKGROUND BACKGROUND-PIXMAP UNDERLINE-P]
50 face is the symbol `face',
51 NAME is the symbol with which this vector is associated (a backpointer),
52 ID is the face ID, an integer used internally by the C code to identify
54 FONT, FOREGROUND, and BACKGROUND are strings naming the fonts and colors
55 to use with the face, FONT may name fontsets,
56 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't
58 UNDERLINE-P is non-nil if the face should be underlined.
59 If any of these elements are nil, that parameter is considered
60 unspecified; parameters from faces specified by lower-priority
61 overlays or text properties, or the parameters of the frame itself,
62 can show through. (lisp/faces.el maintains these lists.)
64 (assq FACE-NAME global-face-data) returns a vector describing the
65 global parameters for that face.
67 Let PARAM-FACE be FRAME->output_data.w32->param_faces[Faref(FACE-VECTOR,2)].
68 PARAM_FACE is a struct face whose members are the Xlib analogues of
69 the parameters in FACE-VECTOR. If an element of FACE-VECTOR is
70 nil, then the corresponding member of PARAM_FACE is FACE_DEFAULT.
71 These faces are called "parameter faces", because they're the ones
72 lisp manipulates to control what gets displayed. Elements 0 and 1
73 of FRAME->output_data.w32->param_faces are special - they describe the
74 default and mode line faces. None of the faces in param_faces have
75 GC's. (See src/dispextern.h for the definition of struct face.
76 lisp/faces.el maintains the isomorphism between face_alist and
79 The functions compute_char_face and compute_glyph_face find and
80 combine the parameter faces associated with overlays and text
81 properties. The resulting faces are called "computed faces"; none
82 of their members are FACE_DEFAULT; they are completely specified.
83 They then call intern_compute_face to search
84 FRAME->output_data.x->computed_faces for a matching face, add one if
85 none is found, and return the index into
86 FRAME->output_data.x->computed_faces. FRAME's glyph matrices use these
87 indices to record the faces of the matrix characters, and the X
88 display hooks consult compute_faces to decide how to display these
89 characters. Elements 0 and 1 of computed_faces always describe the
90 default and mode-line faces.
92 Each computed face belongs to a particular frame.
94 Computed faces have graphics contexts some of the time.
95 intern_face builds a GC for a specified computed face
96 if it doesn't have one already.
97 clear_face_cache clears out the GCs of all computed faces.
98 This is done from time to time so that we don't hold on to
99 lots of GCs that are no longer needed.
101 If a computed face has 0 as its font,
102 it is unused, and can be reused by new_computed_face.
106 Symbols naming faces must have associations on all frames; for any
107 FRAME, for all FACE-NAME, if (assq FACE-NAME (frame-face-alist
108 FRAME)) is non-nil, it must be non-nil for all frames.
110 Analogously, indices into param_faces must be valid on all frames;
111 if param_faces[i] is a non-zero face pointer on one frame, then it
112 must be filled in on all frames. Code assumes that face ID's can
113 be used on any frame.
117 Why do we keep param_faces and computed_faces separate?
118 computed_faces contains an element for every combination of facial
119 parameters we have ever displayed. indices into param_faces have
120 to be valid on all frames. If they were the same array, then that
121 array would grow very large on all frames, because any facial
122 combination displayed on any frame would need to be a valid entry
125 /* Definitions and declarations. */
127 /* The number of face-id's in use (same for all frames). */
128 static int next_face_id
;
130 /* The number of the face to use to indicate the region. */
131 static int region_face
;
133 /* This is what appears in a slot in a face to signify that the face
134 does not specify that display aspect. */
135 #define FACE_DEFAULT (~0)
138 Lisp_Object Qpixmap_spec_p
;
140 extern Lisp_Object Qmouse_face
; /* In textprop.c. */
142 int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ );
144 struct face
*intern_face ( /* FRAME_PTR, struct face * */ );
145 static int new_computed_face ( /* FRAME_PTR, struct face * */ );
146 static int intern_computed_face ( /* FRAME_PTR, struct face * */ );
147 static void ensure_face_ready ( /* FRAME_PTR, int id */ );
148 void recompute_basic_faces ( /* FRAME_PTR f */ );
149 static void merge_face_list ( /* FRAME_PTR, struct face *, Lisp_Object */ );
151 extern Lisp_Object Qforeground_color
, Qbackground_color
;
153 /* Allocating, copying, and comparing struct faces. */
155 /* Allocate a new face */
159 struct face
*result
= (struct face
*) xmalloc (sizeof (struct face
));
160 bzero (result
, sizeof (struct face
));
161 result
->font
= (XFontStruct
*) FACE_DEFAULT
;
162 result
->fontset
= -1;
163 result
->foreground
= FACE_DEFAULT
;
164 result
->background
= FACE_DEFAULT
;
165 result
->stipple
= FACE_DEFAULT
;
169 /* Make a new face that's a copy of an existing one. */
174 struct face
*result
= allocate_face ();
176 result
->font
= face
->font
;
177 result
->fontset
= face
->fontset
;
178 result
->foreground
= face
->foreground
;
179 result
->background
= face
->background
;
180 result
->stipple
= face
->stipple
;
181 result
->underline
= face
->underline
;
182 result
->pixmap_h
= face
->pixmap_h
;
183 result
->pixmap_w
= face
->pixmap_w
;
189 face_eql (face1
, face2
)
190 struct face
*face1
, *face2
;
192 return ( face1
->font
== face2
->font
193 && face1
->fontset
== face2
->fontset
194 && face1
->foreground
== face2
->foreground
195 && face1
->background
== face2
->background
196 && face1
->stipple
== face2
->stipple
197 && face1
->underline
== face2
->underline
);
200 /* Managing graphics contexts of faces. */
202 /* Given a computed face, construct its graphics context if necessary. */
205 intern_face (f
, face
)
214 /* Clear out all graphics contexts for all computed faces
215 except for the default and mode line faces.
216 This should be done from time to time just to avoid
217 keeping too many graphics contexts that are no longer needed. */
225 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps.
227 These functions operate on param faces only.
228 Computed faces get their fonts, colors and pixmaps
229 by merging param faces. */
236 struct font_info
*fontinf
;
237 XFontStruct
*font
= NULL
;
240 return (XFontStruct
*) FACE_DEFAULT
;
242 CHECK_STRING (name
, 0);
244 fontinf
= w32_load_font (f
, (char *) XSTRING (name
)->data
, 0);
247 font
= (XFontStruct
*)fontinf
->font
;
250 Fsignal (Qerror
, Fcons (build_string ("undefined font"),
251 Fcons (name
, Qnil
)));
256 unload_font (f
, font
)
260 if (!font
|| font
== ((XFontStruct
*) FACE_DEFAULT
))
264 w32_unload_font (FRAME_W32_DISPLAY_INFO (f
), font
);
279 CHECK_STRING (name
, 0);
280 /* if the colormap is full, defined_color will return a best match
281 to the values in an an existing cell. */
282 result
= defined_color(f
, (char *) XSTRING (name
)->data
, &color
, 1);
284 Fsignal (Qerror
, Fcons (build_string ("undefined color"),
285 Fcons (name
, Qnil
)));
286 return (unsigned long) color
;
290 unload_color (f
, pixel
)
296 DEFUN ("pixmap-spec-p", Fpixmap_spec_p
, Spixmap_spec_p
, 1, 1, 0,
297 "Return t if OBJECT is a valid pixmap specification.")
301 Lisp_Object height
, width
;
303 return ((STRINGP (object
)
305 && CONSP (XCDR (object
))
306 && CONSP (XCDR (XCDR (object
)))
307 && NILP (XCDR (XCDR (XCDR (object
))))
308 && (width
= XCAR (object
), INTEGERP (width
))
309 && (height
= XCAR (XCDR (object
)), INTEGERP (height
))
310 && STRINGP (XCAR (XCDR (XCDR (object
))))
313 /* The string must have enough bits for width * height. */
314 && ((XSTRING (XCAR (XCDR (XCDR (object
))))->size
315 * (BITS_PER_INT
/ sizeof (int)))
316 >= XFASTINT (width
) * XFASTINT (height
))))
320 /* Load a bitmap according to NAME (which is either a file name
321 or a pixmap spec). Return the bitmap_id (see xfns.c)
322 or get an error if NAME is invalid.
324 Store the bitmap width in *W_PTR and height in *H_PTR. */
327 load_pixmap (f
, name
, w_ptr
, h_ptr
)
330 unsigned int *w_ptr
, *h_ptr
;
338 tem
= Fpixmap_spec_p (name
);
340 wrong_type_argument (Qpixmap_spec_p
, name
);
346 /* Decode a bitmap spec into a bitmap. */
351 w
= XINT (Fcar (name
));
352 h
= XINT (Fcar (Fcdr (name
)));
353 bits
= Fcar (Fcdr (Fcdr (name
)));
355 bitmap_id
= x_create_bitmap_from_data (f
, XSTRING (bits
)->data
,
360 /* It must be a string -- a file name. */
361 bitmap_id
= x_create_bitmap_from_file (f
, name
);
366 Fsignal (Qerror
, Fcons (build_string ("invalid or undefined bitmap"),
367 Fcons (name
, Qnil
)));
369 *w_ptr
= x_bitmap_width (f
, bitmap_id
);
370 *h_ptr
= x_bitmap_height (f
, bitmap_id
);
376 /* Managing parameter face arrays for frames. */
382 ensure_face_ready (f
, 0);
383 ensure_face_ready (f
, 1);
385 FRAME_N_COMPUTED_FACES (f
) = 0;
386 FRAME_SIZE_COMPUTED_FACES (f
) = 0;
388 new_computed_face (f
, FRAME_PARAM_FACES (f
)[0]);
389 new_computed_face (f
, FRAME_PARAM_FACES (f
)[1]);
390 recompute_basic_faces (f
);
392 /* Find another frame. */
394 Lisp_Object tail
, frame
, result
;
397 FOR_EACH_FRAME (tail
, frame
)
398 if (FRAME_W32_P (XFRAME (frame
))
399 && XFRAME (frame
) != f
)
405 /* If we didn't find any X frames other than f, then we don't need
406 any faces other than 0 and 1, so we're okay. Otherwise, make
407 sure that all faces valid on the selected frame are also valid
408 on this new frame. */
412 int n_faces
= FRAME_N_PARAM_FACES (XFRAME (result
));
413 struct face
**faces
= FRAME_PARAM_FACES (XFRAME (result
));
415 for (i
= 2; i
< n_faces
; i
++)
417 ensure_face_ready (f
, i
);
423 /* Called from Fdelete_frame. */
433 for (i
= 0; i
< FRAME_N_PARAM_FACES (f
); i
++)
435 struct face
*face
= FRAME_PARAM_FACES (f
) [i
];
438 if (face
->fontset
< 0)
439 unload_font (f
, face
->font
);
440 unload_color (f
, face
->foreground
);
441 unload_color (f
, face
->background
);
442 x_destroy_bitmap (f
, face
->stipple
);
446 xfree (FRAME_PARAM_FACES (f
));
447 FRAME_PARAM_FACES (f
) = 0;
448 FRAME_N_PARAM_FACES (f
) = 0;
450 /* All faces in FRAME_COMPUTED_FACES use resources copied from
451 FRAME_PARAM_FACES; we can free them without fuss.
452 But we do free the GCs and the face objects themselves. */
453 for (i
= 0; i
< FRAME_N_COMPUTED_FACES (f
); i
++)
455 struct face
*face
= FRAME_COMPUTED_FACES (f
) [i
];
461 xfree (FRAME_COMPUTED_FACES (f
));
462 FRAME_COMPUTED_FACES (f
) = 0;
463 FRAME_N_COMPUTED_FACES (f
) = 0;
468 /* Interning faces in a frame's face array. */
471 new_computed_face (f
, new_face
)
473 struct face
*new_face
;
475 int len
= FRAME_N_COMPUTED_FACES (f
);
478 /* Search for an unused computed face in the middle of the table. */
479 for (i
= 0; i
< len
; i
++)
481 struct face
*face
= FRAME_COMPUTED_FACES (f
)[i
];
484 FRAME_COMPUTED_FACES (f
)[i
] = copy_face (new_face
);
489 if (i
>= FRAME_SIZE_COMPUTED_FACES (f
))
491 int new_size
= i
+ 32;
493 FRAME_COMPUTED_FACES (f
)
494 = (struct face
**) (FRAME_SIZE_COMPUTED_FACES (f
) == 0
495 ? xmalloc (new_size
* sizeof (struct face
*))
496 : xrealloc (FRAME_COMPUTED_FACES (f
),
497 new_size
* sizeof (struct face
*)));
498 FRAME_SIZE_COMPUTED_FACES (f
) = new_size
;
501 i
= FRAME_N_COMPUTED_FACES (f
)++;
502 FRAME_COMPUTED_FACES (f
)[i
] = copy_face (new_face
);
507 /* Find a match for NEW_FACE in a FRAME's computed face array, and add
508 it if we don't find one. */
510 intern_computed_face (f
, new_face
)
512 struct face
*new_face
;
514 int len
= FRAME_N_COMPUTED_FACES (f
);
517 /* Search for a computed face already on F equivalent to FACE. */
518 for (i
= 0; i
< len
; i
++)
520 if (! FRAME_COMPUTED_FACES (f
)[i
])
522 if (face_eql (new_face
, FRAME_COMPUTED_FACES (f
)[i
]))
526 /* We didn't find one; add a new one. */
527 return new_computed_face (f
, new_face
);
530 /* Make parameter face id ID valid on frame F. */
533 ensure_face_ready (f
, id
)
537 if (FRAME_N_PARAM_FACES (f
) <= id
)
541 if (!FRAME_N_PARAM_FACES (f
))
542 FRAME_PARAM_FACES (f
)
543 = (struct face
**) xmalloc (sizeof (struct face
*) * n
);
545 FRAME_PARAM_FACES (f
)
546 = (struct face
**) xrealloc (FRAME_PARAM_FACES (f
),
547 sizeof (struct face
*) * n
);
549 bzero (FRAME_PARAM_FACES (f
) + FRAME_N_PARAM_FACES (f
),
550 (n
- FRAME_N_PARAM_FACES (f
)) * sizeof (struct face
*));
551 FRAME_N_PARAM_FACES (f
) = n
;
554 if (FRAME_PARAM_FACES (f
) [id
] == 0)
555 FRAME_PARAM_FACES (f
) [id
] = allocate_face ();
558 /* Return non-zero if FONT1 and FONT2 have the same width.
559 We do not check the height, because we can now deal with
561 We assume that they're both character-cell fonts. */
564 same_size_fonts (font1
, font2
)
565 XFontStruct
*font1
, *font2
;
567 return (FONT_WIDTH(font1
) == FONT_WIDTH(font2
));
570 /* Update the line_height of frame F according to the biggest font in
571 any face. Return nonzero if if line_height changes. */
574 frame_update_line_height (f
)
578 int fontset
= FRAME_FONTSET (f
);
579 int biggest
= (fontset
> 0
580 ? FRAME_FONTSET_DATA (f
)->fontset_table
[fontset
]->height
581 : FONT_HEIGHT (FRAME_FONT (f
)));
583 for (i
= 0; i
< FRAME_N_PARAM_FACES (f
); i
++)
584 if (FRAME_PARAM_FACES (f
)[i
] != 0
585 && FRAME_PARAM_FACES (f
)[i
]->font
!= (XFontStruct
*) FACE_DEFAULT
)
587 int height
= ((fontset
=
588 FRAME_PARAM_FACES (f
)[i
]->fontset
) > 0
589 ? FRAME_FONTSET_DATA (f
)->fontset_table
[fontset
]->height
591 (FRAME_PARAM_FACES (f
)[i
]->font
));
592 if (height
> biggest
)
596 if (biggest
== FRAME_LINE_HEIGHT (f
))
599 FRAME_LINE_HEIGHT (f
) = biggest
;
603 /* Modify face TO by copying from FROM all properties which have
604 nondefault settings. */
607 merge_faces (from
, to
)
608 struct face
*from
, *to
;
610 /* Only merge the font if it's the same width as the base font.
611 Otherwise ignore it, since we can't handle it properly. */
612 if (from
->font
!= (XFontStruct
*) FACE_DEFAULT
613 && same_size_fonts (from
->font
, to
->font
))
614 to
->font
= from
->font
;
615 if (from
->fontset
!= -1)
616 to
->fontset
= from
->fontset
;
617 if (from
->foreground
!= FACE_DEFAULT
)
618 to
->foreground
= from
->foreground
;
619 if (from
->background
!= FACE_DEFAULT
)
620 to
->background
= from
->background
;
621 if (from
->stipple
!= FACE_DEFAULT
)
623 to
->stipple
= from
->stipple
;
624 to
->pixmap_h
= from
->pixmap_h
;
625 to
->pixmap_w
= from
->pixmap_w
;
628 to
->underline
= from
->underline
;
631 /* Set up the basic set of facial parameters, based on the frame's
632 data; all faces are deltas applied to this. */
635 compute_base_face (f
, face
)
640 face
->foreground
= FRAME_FOREGROUND_PIXEL (f
);
641 face
->background
= FRAME_BACKGROUND_PIXEL (f
);
642 face
->font
= FRAME_FONT (f
);
648 /* Return the face ID to use to display a special glyph which selects
649 FACE_CODE as the face ID, assuming that ordinarily the face would
650 be CURRENT_FACE. F is the frame. */
653 compute_glyph_face (f
, face_code
, current_face
)
655 int face_code
, current_face
;
659 face
= *FRAME_COMPUTED_FACES (f
)[current_face
];
661 if (face_code
>= 0 && face_code
< FRAME_N_PARAM_FACES (f
)
662 && FRAME_PARAM_FACES (f
) [face_code
] != 0)
663 merge_faces (FRAME_PARAM_FACES (f
) [face_code
], &face
);
665 return intern_computed_face (f
, &face
);
668 /* Return the face ID to use to display a special glyph which selects
669 FACE_CODE as the face ID, assuming that ordinarily the face would
670 be CURRENT_FACE. F is the frame. */
673 compute_glyph_face_1 (f
, face_name
, current_face
)
675 Lisp_Object face_name
;
680 face
= *FRAME_COMPUTED_FACES (f
)[current_face
];
682 if (!NILP (face_name
))
684 int facecode
= face_name_id_number (f
, face_name
);
685 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
686 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
687 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
690 return intern_computed_face (f
, &face
);
693 /* Return the face ID associated with a buffer position POS.
694 Store into *ENDPTR the position at which a different face is needed.
695 This does not take account of glyphs that specify their own face codes.
696 F is the frame in use for display, and W is a window displaying
699 REGION_BEG, REGION_END delimit the region, so it can be highlighted.
701 LIMIT is a position not to scan beyond. That is to limit
702 the time this function can take.
704 If MOUSE is nonzero, use the character's mouse-face, not its face. */
706 compute_char_face (f
, w
, pos
, region_beg
, region_end
, endptr
, limit
, mouse
)
710 int region_beg
, region_end
;
716 Lisp_Object prop
, position
;
719 Lisp_Object
*overlay_vec
;
722 Lisp_Object propname
;
724 /* W must display the current buffer. We could write this function
725 to use the frame and buffer of W, but right now it doesn't. */
726 if (XBUFFER (w
->buffer
) != current_buffer
)
729 XSETFRAME (frame
, f
);
732 if (pos
< region_beg
&& region_beg
< endpos
)
735 XSETFASTINT (position
, pos
);
738 propname
= Qmouse_face
;
742 prop
= Fget_text_property (position
, propname
, w
->buffer
);
745 Lisp_Object limit1
, end
;
747 XSETFASTINT (limit1
, (limit
< endpos
? limit
: endpos
));
748 end
= Fnext_single_property_change (position
, propname
, w
->buffer
, limit1
);
757 /* First try with room for 40 overlays. */
759 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
761 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
,
762 &next_overlay
, (int *) 0);
764 /* If there are more than 40,
765 make enough space for all, and try again. */
769 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
770 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
,
771 &next_overlay
, (int *) 0);
774 if (next_overlay
< endpos
)
775 endpos
= next_overlay
;
780 /* Optimize the default case. */
781 if (noverlays
== 0 && NILP (prop
)
782 && !(pos
>= region_beg
&& pos
< region_end
))
785 compute_base_face (f
, &face
);
787 merge_face_list (f
, &face
, prop
);
789 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
791 /* Now merge the overlay data in that order. */
792 for (i
= 0; i
< noverlays
; i
++)
797 prop
= Foverlay_get (overlay_vec
[i
], propname
);
798 merge_face_list (f
, &face
, prop
);
800 oend
= OVERLAY_END (overlay_vec
[i
]);
801 oendpos
= OVERLAY_POSITION (oend
);
802 if (oendpos
< endpos
)
806 if (pos
>= region_beg
&& pos
< region_end
)
808 if (region_end
< endpos
)
810 if (region_face
>= 0 && region_face
< next_face_id
)
811 merge_faces (FRAME_PARAM_FACES (f
)[region_face
], &face
);
816 return intern_computed_face (f
, &face
);
820 merge_face_list (f
, face
, prop
)
831 && ! STRINGP (XCDR (prop
)))
833 /* We have a list of faces, merge them in reverse order. */
835 length
= Fsafe_length (prop
);
836 len
= XFASTINT (length
);
838 /* Put them into an array. */
839 faces
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
840 for (j
= 0; j
< len
; j
++)
842 faces
[j
] = Fcar (prop
);
845 /* So that we can merge them in the reverse order. */
849 faces
= (Lisp_Object
*) alloca (sizeof (Lisp_Object
));
854 for (j
= len
- 1; j
>= 0; j
--)
856 if (CONSP (faces
[j
]))
858 if (EQ (XCAR (faces
[j
]), Qbackground_color
))
859 face
->background
= load_color (f
, XCDR (faces
[j
]));
860 if (EQ (XCAR (faces
[j
]), Qforeground_color
))
861 face
->foreground
= load_color (f
, XCDR (faces
[j
]));
865 int facecode
= face_name_id_number (f
, faces
[j
]);
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
);
874 /* Recompute the GC's for the default and modeline faces.
875 We call this after changing frame parameters on which those GC's
879 recompute_basic_faces (f
)
882 /* If the frame's faces haven't been initialized yet, don't worry about
884 if (FRAME_N_PARAM_FACES (f
) < 2)
889 compute_base_face (f
, FRAME_DEFAULT_FACE (f
));
890 compute_base_face (f
, FRAME_MODE_LINE_FACE (f
));
892 merge_faces (FRAME_DEFAULT_PARAM_FACE (f
), FRAME_DEFAULT_FACE (f
));
893 merge_faces (FRAME_MODE_LINE_PARAM_FACE (f
), FRAME_MODE_LINE_FACE (f
));
895 intern_face (f
, FRAME_DEFAULT_FACE (f
));
896 intern_face (f
, FRAME_MODE_LINE_FACE (f
));
903 /* Lisp interface. */
905 DEFUN ("frame-face-alist", Fframe_face_alist
, Sframe_face_alist
, 1, 1, 0,
910 CHECK_FRAME (frame
, 0);
911 return XFRAME (frame
)->face_alist
;
914 DEFUN ("set-frame-face-alist", Fset_frame_face_alist
, Sset_frame_face_alist
,
917 Lisp_Object frame
, value
;
919 CHECK_FRAME (frame
, 0);
920 XFRAME (frame
)->face_alist
= value
;
925 DEFUN ("make-face-internal", Fmake_face_internal
, Smake_face_internal
, 1, 1, 0,
926 "Create face number FACE-ID on all frames.")
930 Lisp_Object rest
, frame
;
931 int id
= XINT (face_id
);
933 CHECK_NUMBER (face_id
, 0);
934 if (id
< 0 || id
>= next_face_id
)
935 error ("Face id out of range");
937 FOR_EACH_FRAME (rest
, frame
)
939 if (FRAME_W32_P (XFRAME (frame
)))
940 ensure_face_ready (XFRAME (frame
), id
);
946 DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal
,
947 Sset_face_attribute_internal
, 4, 4, 0, "")
948 (face_id
, attr_name
, attr_value
, frame
)
949 Lisp_Object face_id
, attr_name
, attr_value
, frame
;
957 CHECK_FRAME (frame
, 0);
958 CHECK_NUMBER (face_id
, 0);
959 CHECK_SYMBOL (attr_name
, 0);
963 if (id
< 0 || id
>= next_face_id
)
964 error ("Face id out of range");
966 if (! FRAME_WINDOW_P (f
))
969 ensure_face_ready (f
, id
);
970 face
= FRAME_PARAM_FACES (f
) [XFASTINT (face_id
)];
972 if (EQ (attr_name
, intern ("font")))
974 XFontStruct
*font
= NULL
;
977 if (NILP (attr_value
))
979 font
= (XFontStruct
*) FACE_DEFAULT
;
984 CHECK_STRING (attr_value
, 0);
985 fontset
= fs_query_fontset (f
, XSTRING (attr_value
)->data
);
988 struct font_info
*fontp
;
990 if (!(fontp
= FS_LOAD_FONT (f
, FRAME_W32_FONT_TABLE (f
),
991 CHARSET_ASCII
, NULL
, fontset
)))
993 Fcons (build_string ("ASCII font can't be loaded"),
994 Fcons (attr_value
, Qnil
)));
995 font
= (XFontStruct
*) (fontp
->font
);
998 font
= load_font (f
, attr_value
);
1000 if (face
->fontset
== -1 && face
->font
!= f
->output_data
.w32
->font
)
1001 unload_font (f
, face
->font
);
1003 face
->fontset
= fontset
;
1004 if (frame_update_line_height (f
))
1005 x_set_window_size (f
, 0, f
->width
, f
->height
);
1006 /* Must clear cache, since it might contain the font
1007 we just got rid of. */
1010 else if (EQ (attr_name
, intern ("foreground")))
1012 unsigned long new_color
= load_color (f
, attr_value
);
1013 unload_color (f
, face
->foreground
);
1014 face
->foreground
= new_color
;
1017 else if (EQ (attr_name
, intern ("background")))
1019 unsigned long new_color
= load_color (f
, attr_value
);
1020 unload_color (f
, face
->background
);
1021 face
->background
= new_color
;
1024 else if (EQ (attr_name
, intern ("background-pixmap")))
1027 unsigned long new_pixmap
= load_pixmap (f
, attr_value
, &w
, &h
);
1028 x_destroy_bitmap (f
, face
->stipple
);
1029 face
->stipple
= (Pixmap
) new_pixmap
;
1034 else if (EQ (attr_name
, intern ("underline")))
1036 int new = !NILP (attr_value
);
1037 face
->underline
= new;
1040 error ("unknown face attribute");
1042 if (id
== 0 || id
== 1)
1043 recompute_basic_faces (f
);
1045 /* We must redraw the frame whenever any face font or color changes,
1046 because it's possible that a merged (display) face
1047 contains the font or color we just replaced.
1048 And we must inhibit any Expose events until the redraw is done,
1049 since they would try to use the invalid display faces. */
1051 SET_FRAME_GARBAGED (f
);
1056 DEFUN ("internal-next-face-id", Finternal_next_face_id
, Sinternal_next_face_id
,
1060 return make_number (next_face_id
++);
1063 /* Return the face id for name NAME on frame FRAME.
1064 (It should be the same for all frames,
1065 but it's as easy to use the "right" frame to look it up
1066 as to use any other one.) */
1069 face_name_id_number (f
, name
)
1075 tem
= Fcdr (assq_no_quit (name
, f
->face_alist
));
1078 CHECK_VECTOR (tem
, 0);
1079 tem
= XVECTOR (tem
)->contents
[2];
1080 CHECK_NUMBER (tem
, 0);
1084 /* Emacs initialization. */
1089 Qface
= intern ("face");
1091 Qmouse_face
= intern ("mouse-face");
1092 staticpro (&Qmouse_face
);
1093 Qpixmap_spec_p
= intern ("pixmap-spec-p");
1094 staticpro (&Qpixmap_spec_p
);
1096 DEFVAR_INT ("region-face", ®ion_face
,
1097 "Face number to use to highlight the region\n\
1098 The region is highlighted with this face\n\
1099 when Transient Mark mode is enabled and the mark is active.");
1101 defsubr (&Spixmap_spec_p
);
1102 defsubr (&Sframe_face_alist
);
1103 defsubr (&Sset_frame_face_alist
);
1104 defsubr (&Smake_face_internal
);
1105 defsubr (&Sset_face_attribute_internal
);
1106 defsubr (&Sinternal_next_face_id
);