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, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* Ported xfaces.c for win32 - Kevin Gallo */
22 #include <sys/types.h>
30 #include "dispextern.h"
32 #include "blockinput.h"
34 #include "intervals.h"
37 /* An explanation of the face data structures. */
39 /* ========================= Face Data Structures =========================
41 Let FACE-NAME be a symbol naming a face.
43 Let FACE-VECTOR be (assq FACE-NAME (frame-face-alist FRAME))
44 FACE-VECTOR is either nil, or a vector of the form
45 [face NAME ID FONT FOREGROUND BACKGROUND BACKGROUND-PIXMAP UNDERLINE-P]
47 face is the symbol `face',
48 NAME is the symbol with which this vector is associated (a backpointer),
49 ID is the face ID, an integer used internally by the C code to identify
51 FONT, FOREGROUND, and BACKGROUND are strings naming the fonts and colors
53 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't
55 UNDERLINE-P is non-nil if the face should be underlined.
56 If any of these elements are nil, that parameter is considered
57 unspecified; parameters from faces specified by lower-priority
58 overlays or text properties, or the parameters of the frame itself,
59 can show through. (lisp/faces.el maintains these lists.)
61 (assq FACE-NAME global-face-data) returns a vector describing the
62 global parameters for that face.
64 Let PARAM-FACE be FRAME->display.x->param_faces[Faref (FACE-VECTOR, 2)].
65 PARAM_FACE is a struct face whose members are the Xlib analogues of
66 the parameters in FACE-VECTOR. If an element of FACE-VECTOR is
67 nil, then the corresponding member of PARAM_FACE is FACE_DEFAULT.
68 These faces are called "parameter faces", because they're the ones
69 lisp manipulates to control what gets displayed. Elements 0 and 1
70 of FRAME->display.x->param_faces are special - they describe the
71 default and mode line faces. None of the faces in param_faces have
72 GC's. (See src/dispextern.h for the definiton of struct face.
73 lisp/faces.el maintains the isomorphism between face_alist and
76 The functions compute_char_face and compute_glyph_face find and
77 combine the parameter faces associated with overlays and text
78 properties. The resulting faces are called "computed faces"; none
79 of their members are FACE_DEFAULT; they are completely specified.
80 They then call intern_compute_face to search
81 FRAME->display.x->computed_faces for a matching face, add one if
82 none is found, and return the index into
83 FRAME->display.x->computed_faces. FRAME's glyph matrices use these
84 indices to record the faces of the matrix characters, and the X
85 display hooks consult compute_faces to decide how to display these
86 characters. Elements 0 and 1 of computed_faces always describe the
87 default and mode-line faces.
89 Each computed face belongs to a particular frame.
91 Computed faces have graphics contexts some of the time.
92 intern_face builds a GC for a specified computed face
93 if it doesn't have one already.
94 clear_face_cache clears out the GCs of all computed faces.
95 This is done from time to time so that we don't hold on to
96 lots of GCs that are no longer needed.
100 Symbols naming faces must have associations on all frames; for any
101 FRAME, for all FACE-NAME, if (assq FACE-NAME (frame-face-alist
102 FRAME)) is non-nil, it must be non-nil for all frames.
104 Analogously, indices into param_faces must be valid on all frames;
105 if param_faces[i] is a non-zero face pointer on one frame, then it
106 must be filled in on all frames. Code assumes that face ID's can
107 be used on any frame.
111 Why do we keep param_faces and computed_faces separate?
112 computed_faces contains an element for every combination of facial
113 parameters we have ever displayed. indices into param_faces have
114 to be valid on all frames. If they were the same array, then that
115 array would grow very large on all frames, because any facial
116 combination displayed on any frame would need to be a valid entry
119 /* Definitions and declarations. */
121 /* The number of face-id's in use (same for all frames). */
122 static int next_face_id
;
124 /* The number of the face to use to indicate the region. */
125 static int region_face
;
127 /* This is what appears in a slot in a face to signify that the face
128 does not specify that display aspect. */
129 #define FACE_DEFAULT (~0)
131 Lisp_Object Qface
, Qmouse_face
;
132 Lisp_Object Qpixmap_spec_p
;
134 int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ );
136 struct face
*intern_face ( /* FRAME_PTR, struct face * */ );
137 static int new_computed_face ( /* FRAME_PTR, struct face * */ );
138 static int intern_computed_face ( /* FRAME_PTR, struct face * */ );
139 static void ensure_face_ready ( /* FRAME_PTR, int id */ );
140 void recompute_basic_faces ( /* FRAME_PTR f */ );
142 /* Allocating, copying, and comparing struct faces. */
144 /* Allocate a new face */
148 struct face
*result
= (struct face
*) xmalloc (sizeof (struct face
));
149 bzero (result
, sizeof (struct face
));
150 result
->font
= (XFontStruct
*) FACE_DEFAULT
;
151 result
->foreground
= FACE_DEFAULT
;
152 result
->background
= FACE_DEFAULT
;
153 result
->stipple
= FACE_DEFAULT
;
157 /* Make a new face that's a copy of an existing one. */
162 struct face
*result
= allocate_face ();
164 result
->font
= face
->font
;
165 result
->foreground
= face
->foreground
;
166 result
->background
= face
->background
;
167 result
->stipple
= face
->stipple
;
168 result
->underline
= face
->underline
;
169 result
->pixmap_h
= face
->pixmap_h
;
170 result
->pixmap_w
= face
->pixmap_w
;
176 face_eql (face1
, face2
)
177 struct face
*face1
, *face2
;
179 return ( face1
->font
== face2
->font
180 && face1
->foreground
== face2
->foreground
181 && face1
->background
== face2
->background
182 && face1
->stipple
== face2
->stipple
183 && face1
->underline
== face2
->underline
);
186 /* Managing graphics contexts of faces. */
188 /* Given a computed face, construct its graphics context if necessary. */
191 intern_face (f
, face
)
200 /* Clear out all graphics contexts for all computed faces
201 except for the default and mode line faces.
202 This should be done from time to time just to avoid
203 keeping too many graphics contexts that are no longer needed. */
211 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps.
213 These functions operate on param faces only.
214 Computed faces get their fonts, colors and pixmaps
215 by merging param faces. */
225 return (XFontStruct
*) FACE_DEFAULT
;
227 CHECK_STRING (name
, 0);
229 font
= win32_load_font (FRAME_WIN32_DISPLAY_INFO (f
), (char *) XSTRING (name
)->data
);
233 Fsignal (Qerror
, Fcons (build_string ("undefined font"),
234 Fcons (name
, Qnil
)));
239 unload_font (f
, font
)
243 if (!font
|| font
== ((XFontStruct
*) FACE_DEFAULT
))
247 win32_unload_font (FRAME_WIN32_DISPLAY_INFO (f
), font
);
262 CHECK_STRING (name
, 0);
263 /* if the colormap is full, defined_color will return a best match
264 to the values in an an existing cell. */
265 result
= defined_color(f
, (char *) XSTRING (name
)->data
, &color
, 1);
267 Fsignal (Qerror
, Fcons (build_string ("undefined color"),
268 Fcons (name
, Qnil
)));
269 return (unsigned long) color
;
273 unload_color (f
, pixel
)
279 DEFUN ("pixmap-spec-p", Fpixmap_spec_p
, Spixmap_spec_p
, 1, 1, 0,
280 "Return t if ARG is a valid pixmap specification.")
284 Lisp_Object height
, width
;
286 return ((STRINGP (arg
)
288 && CONSP (XCONS (arg
)->cdr
)
289 && CONSP (XCONS (XCONS (arg
)->cdr
)->cdr
)
290 && NILP (XCONS (XCONS (XCONS (arg
)->cdr
)->cdr
)->cdr
)
291 && (width
= XCONS (arg
)->car
, INTEGERP (width
))
292 && (height
= XCONS (XCONS (arg
)->cdr
)->car
, INTEGERP (height
))
293 && STRINGP (XCONS (XCONS (XCONS (arg
)->cdr
)->cdr
)->car
)
296 /* The string must have enough bits for width * height. */
297 && ((XSTRING (XCONS (XCONS (XCONS (arg
)->cdr
)->cdr
)->car
)->size
298 * (BITS_PER_INT
/ sizeof (int)))
299 >= XFASTINT (width
) * XFASTINT (height
))))
303 /* Load a bitmap according to NAME (which is either a file name
304 or a pixmap spec). Return the bitmap_id (see xfns.c)
305 or get an error if NAME is invalid.
307 Store the bitmap width in *W_PTR and height in *H_PTR. */
310 load_pixmap (f
, name
, w_ptr
, h_ptr
)
313 unsigned int *w_ptr
, *h_ptr
;
321 tem
= Fpixmap_spec_p (name
);
323 wrong_type_argument (Qpixmap_spec_p
, name
);
329 /* Decode a bitmap spec into a bitmap. */
334 w
= XINT (Fcar (name
));
335 h
= XINT (Fcar (Fcdr (name
)));
336 bits
= Fcar (Fcdr (Fcdr (name
)));
338 bitmap_id
= x_create_bitmap_from_data (f
, XSTRING (bits
)->data
,
343 /* It must be a string -- a file name. */
344 bitmap_id
= x_create_bitmap_from_file (f
, name
);
349 Fsignal (Qerror
, Fcons (build_string ("invalid or undefined bitmap"),
350 Fcons (name
, Qnil
)));
352 *w_ptr
= x_bitmap_width (f
, bitmap_id
);
353 *h_ptr
= x_bitmap_height (f
, bitmap_id
);
359 /* Managing parameter face arrays for frames. */
365 ensure_face_ready (f
, 0);
366 ensure_face_ready (f
, 1);
368 FRAME_N_COMPUTED_FACES (f
) = 0;
369 FRAME_SIZE_COMPUTED_FACES (f
) = 0;
371 new_computed_face (f
, FRAME_PARAM_FACES (f
)[0]);
372 new_computed_face (f
, FRAME_PARAM_FACES (f
)[1]);
373 recompute_basic_faces (f
);
376 /* Find another frame. */
378 Lisp_Object tail
, frame
, result
;
381 FOR_EACH_FRAME (tail
, frame
)
382 if (FRAME_WIN32_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
);
404 #endif /* MULTI_FRAME */
408 /* Called from Fdelete_frame. */
418 for (i
= 0; i
< FRAME_N_PARAM_FACES (f
); i
++)
420 struct face
*face
= FRAME_PARAM_FACES (f
) [i
];
423 unload_font (f
, face
->font
);
424 unload_color (f
, face
->foreground
);
425 unload_color (f
, face
->background
);
426 x_destroy_bitmap (f
, face
->stipple
);
430 xfree (FRAME_PARAM_FACES (f
));
431 FRAME_PARAM_FACES (f
) = 0;
432 FRAME_N_PARAM_FACES (f
) = 0;
434 /* All faces in FRAME_COMPUTED_FACES use resources copied from
435 FRAME_PARAM_FACES; we can free them without fuss.
436 But we do free the GCs and the face objects themselves. */
437 for (i
= 0; i
< FRAME_N_COMPUTED_FACES (f
); i
++)
439 struct face
*face
= FRAME_COMPUTED_FACES (f
) [i
];
445 xfree (FRAME_COMPUTED_FACES (f
));
446 FRAME_COMPUTED_FACES (f
) = 0;
447 FRAME_N_COMPUTED_FACES (f
) = 0;
452 /* Interning faces in a frame's face array. */
455 new_computed_face (f
, new_face
)
457 struct face
*new_face
;
459 int i
= FRAME_N_COMPUTED_FACES (f
);
461 if (i
>= FRAME_SIZE_COMPUTED_FACES (f
))
463 int new_size
= i
+ 32;
465 FRAME_COMPUTED_FACES (f
)
466 = (struct face
**) (FRAME_SIZE_COMPUTED_FACES (f
) == 0
467 ? xmalloc (new_size
* sizeof (struct face
*))
468 : xrealloc (FRAME_COMPUTED_FACES (f
),
469 new_size
* sizeof (struct face
*)));
470 FRAME_SIZE_COMPUTED_FACES (f
) = new_size
;
473 i
= FRAME_N_COMPUTED_FACES (f
)++;
474 FRAME_COMPUTED_FACES (f
)[i
] = copy_face (new_face
);
479 /* Find a match for NEW_FACE in a FRAME's computed face array, and add
480 it if we don't find one. */
482 intern_computed_face (f
, new_face
)
484 struct face
*new_face
;
486 int len
= FRAME_N_COMPUTED_FACES (f
);
489 /* Search for a computed face already on F equivalent to FACE. */
490 for (i
= 0; i
< len
; i
++)
492 if (! FRAME_COMPUTED_FACES (f
)[i
])
494 if (face_eql (new_face
, FRAME_COMPUTED_FACES (f
)[i
]))
498 /* We didn't find one; add a new one. */
499 return new_computed_face (f
, new_face
);
502 /* Make parameter face id ID valid on frame F. */
505 ensure_face_ready (f
, id
)
509 if (FRAME_N_PARAM_FACES (f
) <= id
)
513 if (!FRAME_N_PARAM_FACES (f
))
514 FRAME_PARAM_FACES (f
)
515 = (struct face
**) xmalloc (sizeof (struct face
*) * n
);
517 FRAME_PARAM_FACES (f
)
518 = (struct face
**) xrealloc (FRAME_PARAM_FACES (f
),
519 sizeof (struct face
*) * n
);
521 bzero (FRAME_PARAM_FACES (f
) + FRAME_N_PARAM_FACES (f
),
522 (n
- FRAME_N_PARAM_FACES (f
)) * sizeof (struct face
*));
523 FRAME_N_PARAM_FACES (f
) = n
;
526 if (FRAME_PARAM_FACES (f
) [id
] == 0)
527 FRAME_PARAM_FACES (f
) [id
] = allocate_face ();
530 /* Return non-zero if FONT1 and FONT2 have the same width.
531 We do not check the height, because we can now deal with
533 We assume that they're both character-cell fonts. */
536 same_size_fonts (font1
, font2
)
537 XFontStruct
*font1
, *font2
;
539 return (FONT_WIDTH(font1
) == FONT_WIDTH(font2
));
542 /* Update the line_height of frame F according to the biggest font in
543 any face. Return nonzero if if line_height changes. */
546 frame_update_line_height (f
)
550 int biggest
= FONT_HEIGHT (f
->output_data
.win32
->font
);
552 for (i
= 0; i
< f
->output_data
.win32
->n_param_faces
; i
++)
553 if (f
->output_data
.win32
->param_faces
[i
] != 0
554 && f
->output_data
.win32
->param_faces
[i
]->font
!= (XFontStruct
*) FACE_DEFAULT
)
556 int height
= FONT_HEIGHT (f
->output_data
.win32
->param_faces
[i
]->font
);
557 if (height
> biggest
)
561 if (biggest
== f
->output_data
.win32
->line_height
)
564 f
->output_data
.win32
->line_height
= biggest
;
568 /* Modify face TO by copying from FROM all properties which have
569 nondefault settings. */
572 merge_faces (from
, to
)
573 struct face
*from
, *to
;
575 /* Only merge the font if it's the same width as the base font.
576 Otherwise ignore it, since we can't handle it properly. */
577 if (from
->font
!= (XFontStruct
*) FACE_DEFAULT
578 && same_size_fonts (from
->font
, to
->font
))
579 to
->font
= from
->font
;
580 if (from
->foreground
!= FACE_DEFAULT
)
581 to
->foreground
= from
->foreground
;
582 if (from
->background
!= FACE_DEFAULT
)
583 to
->background
= from
->background
;
584 if (from
->stipple
!= FACE_DEFAULT
)
586 to
->stipple
= from
->stipple
;
587 to
->pixmap_h
= from
->pixmap_h
;
588 to
->pixmap_w
= from
->pixmap_w
;
591 to
->underline
= from
->underline
;
594 /* Set up the basic set of facial parameters, based on the frame's
595 data; all faces are deltas applied to this. */
598 compute_base_face (f
, face
)
603 face
->foreground
= FRAME_FOREGROUND_PIXEL (f
);
604 face
->background
= FRAME_BACKGROUND_PIXEL (f
);
605 face
->font
= FRAME_FONT (f
);
610 /* Return the face ID to use to display a special glyph which selects
611 FACE_CODE as the face ID, assuming that ordinarily the face would
612 be CURRENT_FACE. F is the frame. */
615 compute_glyph_face (f
, face_code
, current_face
)
617 int face_code
, current_face
;
621 face
= *FRAME_COMPUTED_FACES (f
)[current_face
];
623 if (face_code
>= 0 && face_code
< FRAME_N_PARAM_FACES (f
)
624 && FRAME_PARAM_FACES (f
) [face_code
] != 0)
625 merge_faces (FRAME_PARAM_FACES (f
) [face_code
], &face
);
627 return intern_computed_face (f
, &face
);
630 /* Return the face ID to use to display a special glyph which selects
631 FACE_CODE as the face ID, assuming that ordinarily the face would
632 be CURRENT_FACE. F is the frame. */
635 compute_glyph_face_1 (f
, face_name
, current_face
)
637 Lisp_Object face_name
;
642 face
= *FRAME_COMPUTED_FACES (f
)[current_face
];
644 if (!NILP (face_name
))
646 int facecode
= face_name_id_number (f
, face_name
);
647 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
648 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
649 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
652 return intern_computed_face (f
, &face
);
655 /* Return the face ID associated with a buffer position POS.
656 Store into *ENDPTR the position at which a different face is needed.
657 This does not take account of glyphs that specify their own face codes.
658 F is the frame in use for display, and W is a window displaying
661 REGION_BEG, REGION_END delimit the region, so it can be highlighted.
663 LIMIT is a position not to scan beyond. That is to limit
664 the time this function can take.
666 If MOUSE is nonzero, use the character's mouse-face, not its face. */
669 compute_char_face (f
, w
, pos
, region_beg
, region_end
, endptr
, limit
, mouse
)
673 int region_beg
, region_end
;
679 Lisp_Object prop
, position
;
682 Lisp_Object
*overlay_vec
;
685 Lisp_Object propname
;
687 /* W must display the current buffer. We could write this function
688 to use the frame and buffer of W, but right now it doesn't. */
689 if (XBUFFER (w
->buffer
) != current_buffer
)
692 XSETFRAME (frame
, f
);
695 if (pos
< region_beg
&& region_beg
< endpos
)
698 XSETFASTINT (position
, pos
);
701 propname
= Qmouse_face
;
705 prop
= Fget_text_property (position
, propname
, w
->buffer
);
708 Lisp_Object limit1
, end
;
710 XSETFASTINT (limit1
, (limit
< endpos
? limit
: endpos
));
711 end
= Fnext_single_property_change (position
, propname
, w
->buffer
, limit1
);
720 /* First try with room for 40 overlays. */
722 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
724 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
,
725 &next_overlay
, (int *) 0);
727 /* If there are more than 40,
728 make enough space for all, and try again. */
732 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
733 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
,
734 &next_overlay
, (int *) 0);
737 if (next_overlay
< endpos
)
738 endpos
= next_overlay
;
743 /* Optimize the default case. */
744 if (noverlays
== 0 && NILP (prop
)
745 && !(pos
>= region_beg
&& pos
< region_end
))
748 compute_base_face (f
, &face
);
752 /* We have a list of faces, merge them in reverse order */
753 Lisp_Object length
= Flength (prop
);
754 int len
= XINT (length
);
757 /* Put them into an array */
758 faces
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
759 for (j
= 0; j
< len
; j
++)
761 faces
[j
] = Fcar (prop
);
764 /* So that we can merge them in the reverse order */
765 for (j
= len
- 1; j
>= 0; j
--)
767 facecode
= face_name_id_number (f
, faces
[j
]);
768 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
769 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
770 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
773 else if (!NILP (prop
))
775 facecode
= face_name_id_number (f
, prop
);
776 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
777 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
778 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
781 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
783 /* Now merge the overlay data in that order. */
784 for (i
= 0; i
< noverlays
; i
++)
786 prop
= Foverlay_get (overlay_vec
[i
], propname
);
789 /* We have a list of faces, merge them in reverse order */
790 Lisp_Object length
= Flength (prop
);
791 int len
= XINT (length
);
795 /* Put them into an array */
796 faces
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
797 for (j
= 0; j
< len
; j
++)
799 faces
[j
] = Fcar (prop
);
802 /* So that we can merge them in the reverse order */
803 for (j
= len
- 1; j
>= 0; j
--)
805 facecode
= face_name_id_number (f
, faces
[j
]);
806 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
807 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
808 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
811 else if (!NILP (prop
))
816 facecode
= face_name_id_number (f
, prop
);
817 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
818 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
819 merge_faces (FRAME_PARAM_FACES (f
)[facecode
], &face
);
821 oend
= OVERLAY_END (overlay_vec
[i
]);
822 oendpos
= OVERLAY_POSITION (oend
);
823 if (oendpos
< endpos
)
828 if (pos
>= region_beg
&& pos
< region_end
)
830 if (region_end
< endpos
)
832 if (region_face
>= 0 && region_face
< next_face_id
)
833 merge_faces (FRAME_PARAM_FACES (f
)[region_face
], &face
);
838 return intern_computed_face (f
, &face
);
841 /* Recompute the GC's for the default and modeline faces.
842 We call this after changing frame parameters on which those GC's
846 recompute_basic_faces (f
)
849 /* If the frame's faces haven't been initialized yet, don't worry about
851 if (FRAME_N_PARAM_FACES (f
) < 2)
856 compute_base_face (f
, FRAME_DEFAULT_FACE (f
));
857 compute_base_face (f
, FRAME_MODE_LINE_FACE (f
));
859 merge_faces (FRAME_DEFAULT_PARAM_FACE (f
), FRAME_DEFAULT_FACE (f
));
860 merge_faces (FRAME_MODE_LINE_PARAM_FACE (f
), FRAME_MODE_LINE_FACE (f
));
862 intern_face (f
, FRAME_DEFAULT_FACE (f
));
863 intern_face (f
, FRAME_MODE_LINE_FACE (f
));
870 /* Lisp interface. */
872 DEFUN ("frame-face-alist", Fframe_face_alist
, Sframe_face_alist
, 1, 1, 0,
877 CHECK_FRAME (frame
, 0);
878 return XFRAME (frame
)->face_alist
;
881 DEFUN ("set-frame-face-alist", Fset_frame_face_alist
, Sset_frame_face_alist
,
884 Lisp_Object frame
, value
;
886 CHECK_FRAME (frame
, 0);
887 XFRAME (frame
)->face_alist
= value
;
892 DEFUN ("make-face-internal", Fmake_face_internal
, Smake_face_internal
, 1, 1, 0,
893 "Create face number FACE-ID on all frames.")
897 Lisp_Object rest
, frame
;
898 int id
= XINT (face_id
);
900 CHECK_NUMBER (face_id
, 0);
901 if (id
< 0 || id
>= next_face_id
)
902 error ("Face id out of range");
904 FOR_EACH_FRAME (rest
, frame
)
906 if (FRAME_WIN32_P (XFRAME (frame
)))
907 ensure_face_ready (XFRAME (frame
), id
);
913 DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal
,
914 Sset_face_attribute_internal
, 4, 4, 0, "")
915 (face_id
, attr_name
, attr_value
, frame
)
916 Lisp_Object face_id
, attr_name
, attr_value
, frame
;
924 CHECK_FRAME (frame
, 0);
925 CHECK_NUMBER (face_id
, 0);
926 CHECK_SYMBOL (attr_name
, 0);
930 if (id
< 0 || id
>= next_face_id
)
931 error ("Face id out of range");
933 if (! FRAME_WIN32_P (f
))
936 ensure_face_ready (f
, id
);
937 face
= FRAME_PARAM_FACES (f
) [XFASTINT (face_id
)];
939 if (EQ (attr_name
, intern ("font")))
941 XFontStruct
*font
= load_font (f
, attr_value
);
942 if (face
->font
!= f
->output_data
.win32
->font
)
943 unload_font (f
, face
->font
);
945 if (frame_update_line_height (f
))
946 x_set_window_size (f
, 0, f
->width
, f
->height
);
947 /* Must clear cache, since it might contain the font
948 we just got rid of. */
951 else if (EQ (attr_name
, intern ("foreground")))
953 unsigned long new_color
= load_color (f
, attr_value
);
954 unload_color (f
, face
->foreground
);
955 face
->foreground
= new_color
;
958 else if (EQ (attr_name
, intern ("background")))
960 unsigned long new_color
= load_color (f
, attr_value
);
961 unload_color (f
, face
->background
);
962 face
->background
= new_color
;
965 else if (EQ (attr_name
, intern ("background-pixmap")))
968 unsigned long new_pixmap
= load_pixmap (f
, attr_value
, &w
, &h
);
969 x_destroy_bitmap (f
, face
->stipple
);
970 face
->stipple
= (Pixmap
) new_pixmap
;
975 else if (EQ (attr_name
, intern ("underline")))
977 int new = !NILP (attr_value
);
978 face
->underline
= new;
981 error ("unknown face attribute");
983 if (id
== 0 || id
== 1)
984 recompute_basic_faces (f
);
986 /* We must redraw the frame whenever any face font or color changes,
987 because it's possible that a merged (display) face
988 contains the font or color we just replaced.
989 And we must inhibit any Expose events until the redraw is done,
990 since they would try to use the invalid display faces. */
992 SET_FRAME_GARBAGED (f
);
997 DEFUN ("internal-next-face-id", Finternal_next_face_id
, Sinternal_next_face_id
,
1001 return make_number (next_face_id
++);
1004 /* Return the face id for name NAME on frame FRAME.
1005 (It should be the same for all frames,
1006 but it's as easy to use the "right" frame to look it up
1007 as to use any other one.) */
1010 face_name_id_number (f
, name
)
1016 tem
= Fcdr (assq_no_quit (name
, f
->face_alist
));
1019 CHECK_VECTOR (tem
, 0);
1020 tem
= XVECTOR (tem
)->contents
[2];
1021 CHECK_NUMBER (tem
, 0);
1025 /* Emacs initialization. */
1028 syms_of_win32faces ()
1030 Qface
= intern ("face");
1032 Qmouse_face
= intern ("mouse-face");
1033 staticpro (&Qmouse_face
);
1034 Qpixmap_spec_p
= intern ("pixmap-spec-p");
1035 staticpro (&Qpixmap_spec_p
);
1037 DEFVAR_INT ("region-face", ®ion_face
,
1038 "Face number to use to highlight the region\n\
1039 The region is highlighted with this face\n\
1040 when Transient Mark mode is enabled and the mark is active.");
1042 defsubr (&Spixmap_spec_p
);
1043 defsubr (&Sframe_face_alist
);
1044 defsubr (&Sset_frame_face_alist
);
1045 defsubr (&Smake_face_internal
);
1046 defsubr (&Sset_face_attribute_internal
);
1047 defsubr (&Sinternal_next_face_id
);