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 win32 - 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
= win32_load_font (FRAME_WIN32_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 win32_unload_font (FRAME_WIN32_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
);
377 /* Find another frame. */
379 Lisp_Object tail
, frame
, result
;
382 FOR_EACH_FRAME (tail
, frame
)
383 if (FRAME_WIN32_P (XFRAME (frame
))
384 && XFRAME (frame
) != f
)
390 /* If we didn't find any X frames other than f, then we don't need
391 any faces other than 0 and 1, so we're okay. Otherwise, make
392 sure that all faces valid on the selected frame are also valid
393 on this new frame. */
397 int n_faces
= FRAME_N_PARAM_FACES (XFRAME (result
));
398 struct face
**faces
= FRAME_PARAM_FACES (XFRAME (result
));
400 for (i
= 2; i
< n_faces
; i
++)
402 ensure_face_ready (f
, i
);
405 #endif /* MULTI_FRAME */
409 /* Called from Fdelete_frame. */
419 for (i
= 0; i
< FRAME_N_PARAM_FACES (f
); i
++)
421 struct face
*face
= FRAME_PARAM_FACES (f
) [i
];
424 unload_font (f
, face
->font
);
425 unload_color (f
, face
->foreground
);
426 unload_color (f
, face
->background
);
427 x_destroy_bitmap (f
, face
->stipple
);
431 xfree (FRAME_PARAM_FACES (f
));
432 FRAME_PARAM_FACES (f
) = 0;
433 FRAME_N_PARAM_FACES (f
) = 0;
435 /* All faces in FRAME_COMPUTED_FACES use resources copied from
436 FRAME_PARAM_FACES; we can free them without fuss.
437 But we do free the GCs and the face objects themselves. */
438 for (i
= 0; i
< FRAME_N_COMPUTED_FACES (f
); i
++)
440 struct face
*face
= FRAME_COMPUTED_FACES (f
) [i
];
446 xfree (FRAME_COMPUTED_FACES (f
));
447 FRAME_COMPUTED_FACES (f
) = 0;
448 FRAME_N_COMPUTED_FACES (f
) = 0;
453 /* Interning faces in a frame's face array. */
456 new_computed_face (f
, new_face
)
458 struct face
*new_face
;
460 int i
= FRAME_N_COMPUTED_FACES (f
);
462 if (i
>= FRAME_SIZE_COMPUTED_FACES (f
))
464 int new_size
= i
+ 32;
466 FRAME_COMPUTED_FACES (f
)
467 = (struct face
**) (FRAME_SIZE_COMPUTED_FACES (f
) == 0
468 ? xmalloc (new_size
* sizeof (struct face
*))
469 : xrealloc (FRAME_COMPUTED_FACES (f
),
470 new_size
* sizeof (struct face
*)));
471 FRAME_SIZE_COMPUTED_FACES (f
) = new_size
;
474 i
= FRAME_N_COMPUTED_FACES (f
)++;
475 FRAME_COMPUTED_FACES (f
)[i
] = copy_face (new_face
);
480 /* Find a match for NEW_FACE in a FRAME's computed face array, and add
481 it if we don't find one. */
483 intern_computed_face (f
, new_face
)
485 struct face
*new_face
;
487 int len
= FRAME_N_COMPUTED_FACES (f
);
490 /* Search for a computed face already on F equivalent to FACE. */
491 for (i
= 0; i
< len
; i
++)
493 if (! FRAME_COMPUTED_FACES (f
)[i
])
495 if (face_eql (new_face
, FRAME_COMPUTED_FACES (f
)[i
]))
499 /* We didn't find one; add a new one. */
500 return new_computed_face (f
, new_face
);
503 /* Make parameter face id ID valid on frame F. */
506 ensure_face_ready (f
, id
)
510 if (FRAME_N_PARAM_FACES (f
) <= id
)
514 if (!FRAME_N_PARAM_FACES (f
))
515 FRAME_PARAM_FACES (f
)
516 = (struct face
**) xmalloc (sizeof (struct face
*) * n
);
518 FRAME_PARAM_FACES (f
)
519 = (struct face
**) xrealloc (FRAME_PARAM_FACES (f
),
520 sizeof (struct face
*) * n
);
522 bzero (FRAME_PARAM_FACES (f
) + FRAME_N_PARAM_FACES (f
),
523 (n
- FRAME_N_PARAM_FACES (f
)) * sizeof (struct face
*));
524 FRAME_N_PARAM_FACES (f
) = n
;
527 if (FRAME_PARAM_FACES (f
) [id
] == 0)
528 FRAME_PARAM_FACES (f
) [id
] = allocate_face ();
531 /* Return non-zero if FONT1 and FONT2 have the same width.
532 We do not check the height, because we can now deal with
534 We assume that they're both character-cell fonts. */
537 same_size_fonts (font1
, font2
)
538 XFontStruct
*font1
, *font2
;
540 return (FONT_WIDTH(font1
) == FONT_WIDTH(font2
));
543 /* Update the line_height of frame F according to the biggest font in
544 any face. Return nonzero if if line_height changes. */
547 frame_update_line_height (f
)
551 int biggest
= FONT_HEIGHT (f
->output_data
.win32
->font
);
553 for (i
= 0; i
< f
->output_data
.win32
->n_param_faces
; i
++)
554 if (f
->output_data
.win32
->param_faces
[i
] != 0
555 && f
->output_data
.win32
->param_faces
[i
]->font
!= (XFontStruct
*) FACE_DEFAULT
)
557 int height
= FONT_HEIGHT (f
->output_data
.win32
->param_faces
[i
]->font
);
558 if (height
> biggest
)
562 if (biggest
== f
->output_data
.win32
->line_height
)
565 f
->output_data
.win32
->line_height
= biggest
;
569 /* Modify face TO by copying from FROM all properties which have
570 nondefault settings. */
573 merge_faces (from
, to
)
574 struct face
*from
, *to
;
576 /* Only merge the font if it's the same width as the base font.
577 Otherwise ignore it, since we can't handle it properly. */
578 if (from
->font
!= (XFontStruct
*) FACE_DEFAULT
579 && same_size_fonts (from
->font
, to
->font
))
580 to
->font
= from
->font
;
581 if (from
->foreground
!= FACE_DEFAULT
)
582 to
->foreground
= from
->foreground
;
583 if (from
->background
!= FACE_DEFAULT
)
584 to
->background
= from
->background
;
585 if (from
->stipple
!= FACE_DEFAULT
)
587 to
->stipple
= from
->stipple
;
588 to
->pixmap_h
= from
->pixmap_h
;
589 to
->pixmap_w
= from
->pixmap_w
;
592 to
->underline
= from
->underline
;
595 /* Set up the basic set of facial parameters, based on the frame's
596 data; all faces are deltas applied to this. */
599 compute_base_face (f
, face
)
604 face
->foreground
= FRAME_FOREGROUND_PIXEL (f
);
605 face
->background
= FRAME_BACKGROUND_PIXEL (f
);
606 face
->font
= FRAME_FONT (f
);
611 /* Return the face ID to use to display a special glyph which selects
612 FACE_CODE as the face ID, assuming that ordinarily the face would
613 be CURRENT_FACE. F is the frame. */
616 compute_glyph_face (f
, face_code
, current_face
)
618 int face_code
, current_face
;
622 face
= *FRAME_COMPUTED_FACES (f
)[current_face
];
624 if (face_code
>= 0 && face_code
< FRAME_N_PARAM_FACES (f
)
625 && FRAME_PARAM_FACES (f
) [face_code
] != 0)
626 merge_faces (FRAME_PARAM_FACES (f
) [face_code
], &face
);
628 return intern_computed_face (f
, &face
);
631 /* Return the face ID to use to display a special glyph which selects
632 FACE_CODE as the face ID, assuming that ordinarily the face would
633 be CURRENT_FACE. F is the frame. */
636 compute_glyph_face_1 (f
, face_name
, current_face
)
638 Lisp_Object face_name
;
643 face
= *FRAME_COMPUTED_FACES (f
)[current_face
];
645 if (!NILP (face_name
))
647 int facecode
= face_name_id_number (f
, face_name
);
648 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
649 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
650 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
653 return intern_computed_face (f
, &face
);
656 /* Return the face ID associated with a buffer position POS.
657 Store into *ENDPTR the position at which a different face is needed.
658 This does not take account of glyphs that specify their own face codes.
659 F is the frame in use for display, and W is a window displaying
662 REGION_BEG, REGION_END delimit the region, so it can be highlighted.
664 LIMIT is a position not to scan beyond. That is to limit
665 the time this function can take.
667 If MOUSE is nonzero, use the character's mouse-face, not its face. */
670 compute_char_face (f
, w
, pos
, region_beg
, region_end
, endptr
, limit
, mouse
)
674 int region_beg
, region_end
;
680 Lisp_Object prop
, position
;
683 Lisp_Object
*overlay_vec
;
686 Lisp_Object propname
;
688 /* W must display the current buffer. We could write this function
689 to use the frame and buffer of W, but right now it doesn't. */
690 if (XBUFFER (w
->buffer
) != current_buffer
)
693 XSETFRAME (frame
, f
);
696 if (pos
< region_beg
&& region_beg
< endpos
)
699 XSETFASTINT (position
, pos
);
702 propname
= Qmouse_face
;
706 prop
= Fget_text_property (position
, propname
, w
->buffer
);
709 Lisp_Object limit1
, end
;
711 XSETFASTINT (limit1
, (limit
< endpos
? limit
: endpos
));
712 end
= Fnext_single_property_change (position
, propname
, w
->buffer
, limit1
);
721 /* First try with room for 40 overlays. */
723 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
725 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
,
726 &next_overlay
, (int *) 0);
728 /* If there are more than 40,
729 make enough space for all, and try again. */
733 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
734 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
,
735 &next_overlay
, (int *) 0);
738 if (next_overlay
< endpos
)
739 endpos
= next_overlay
;
744 /* Optimize the default case. */
745 if (noverlays
== 0 && NILP (prop
)
746 && !(pos
>= region_beg
&& pos
< region_end
))
749 compute_base_face (f
, &face
);
753 /* We have a list of faces, merge them in reverse order */
754 Lisp_Object length
= Flength (prop
);
755 int len
= XINT (length
);
758 /* Put them into an array */
759 faces
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
760 for (j
= 0; j
< len
; j
++)
762 faces
[j
] = Fcar (prop
);
765 /* So that we can merge them in the reverse order */
766 for (j
= len
- 1; j
>= 0; j
--)
768 facecode
= face_name_id_number (f
, faces
[j
]);
769 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
770 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
771 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
774 else if (!NILP (prop
))
776 facecode
= face_name_id_number (f
, prop
);
777 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
778 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
779 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
782 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
784 /* Now merge the overlay data in that order. */
785 for (i
= 0; i
< noverlays
; i
++)
787 prop
= Foverlay_get (overlay_vec
[i
], propname
);
790 /* We have a list of faces, merge them in reverse order */
791 Lisp_Object length
= Flength (prop
);
792 int len
= XINT (length
);
796 /* Put them into an array */
797 faces
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
798 for (j
= 0; j
< len
; j
++)
800 faces
[j
] = Fcar (prop
);
803 /* So that we can merge them in the reverse order */
804 for (j
= len
- 1; j
>= 0; j
--)
806 facecode
= face_name_id_number (f
, faces
[j
]);
807 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
808 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
809 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
812 else if (!NILP (prop
))
817 facecode
= face_name_id_number (f
, prop
);
818 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
819 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
820 merge_faces (FRAME_PARAM_FACES (f
)[facecode
], &face
);
822 oend
= OVERLAY_END (overlay_vec
[i
]);
823 oendpos
= OVERLAY_POSITION (oend
);
824 if (oendpos
< endpos
)
829 if (pos
>= region_beg
&& pos
< region_end
)
831 if (region_end
< endpos
)
833 if (region_face
>= 0 && region_face
< next_face_id
)
834 merge_faces (FRAME_PARAM_FACES (f
)[region_face
], &face
);
839 return intern_computed_face (f
, &face
);
842 /* Recompute the GC's for the default and modeline faces.
843 We call this after changing frame parameters on which those GC's
847 recompute_basic_faces (f
)
850 /* If the frame's faces haven't been initialized yet, don't worry about
852 if (FRAME_N_PARAM_FACES (f
) < 2)
857 compute_base_face (f
, FRAME_DEFAULT_FACE (f
));
858 compute_base_face (f
, FRAME_MODE_LINE_FACE (f
));
860 merge_faces (FRAME_DEFAULT_PARAM_FACE (f
), FRAME_DEFAULT_FACE (f
));
861 merge_faces (FRAME_MODE_LINE_PARAM_FACE (f
), FRAME_MODE_LINE_FACE (f
));
863 intern_face (f
, FRAME_DEFAULT_FACE (f
));
864 intern_face (f
, FRAME_MODE_LINE_FACE (f
));
871 /* Lisp interface. */
873 DEFUN ("frame-face-alist", Fframe_face_alist
, Sframe_face_alist
, 1, 1, 0,
878 CHECK_FRAME (frame
, 0);
879 return XFRAME (frame
)->face_alist
;
882 DEFUN ("set-frame-face-alist", Fset_frame_face_alist
, Sset_frame_face_alist
,
885 Lisp_Object frame
, value
;
887 CHECK_FRAME (frame
, 0);
888 XFRAME (frame
)->face_alist
= value
;
893 DEFUN ("make-face-internal", Fmake_face_internal
, Smake_face_internal
, 1, 1, 0,
894 "Create face number FACE-ID on all frames.")
898 Lisp_Object rest
, frame
;
899 int id
= XINT (face_id
);
901 CHECK_NUMBER (face_id
, 0);
902 if (id
< 0 || id
>= next_face_id
)
903 error ("Face id out of range");
905 FOR_EACH_FRAME (rest
, frame
)
907 if (FRAME_WIN32_P (XFRAME (frame
)))
908 ensure_face_ready (XFRAME (frame
), id
);
914 DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal
,
915 Sset_face_attribute_internal
, 4, 4, 0, "")
916 (face_id
, attr_name
, attr_value
, frame
)
917 Lisp_Object face_id
, attr_name
, attr_value
, frame
;
925 CHECK_FRAME (frame
, 0);
926 CHECK_NUMBER (face_id
, 0);
927 CHECK_SYMBOL (attr_name
, 0);
931 if (id
< 0 || id
>= next_face_id
)
932 error ("Face id out of range");
934 if (! FRAME_WIN32_P (f
))
937 ensure_face_ready (f
, id
);
938 face
= FRAME_PARAM_FACES (f
) [XFASTINT (face_id
)];
940 if (EQ (attr_name
, intern ("font")))
942 XFontStruct
*font
= load_font (f
, attr_value
);
943 if (face
->font
!= f
->output_data
.win32
->font
)
944 unload_font (f
, face
->font
);
946 if (frame_update_line_height (f
))
947 x_set_window_size (f
, 0, f
->width
, f
->height
);
948 /* Must clear cache, since it might contain the font
949 we just got rid of. */
952 else if (EQ (attr_name
, intern ("foreground")))
954 unsigned long new_color
= load_color (f
, attr_value
);
955 unload_color (f
, face
->foreground
);
956 face
->foreground
= new_color
;
959 else if (EQ (attr_name
, intern ("background")))
961 unsigned long new_color
= load_color (f
, attr_value
);
962 unload_color (f
, face
->background
);
963 face
->background
= new_color
;
966 else if (EQ (attr_name
, intern ("background-pixmap")))
969 unsigned long new_pixmap
= load_pixmap (f
, attr_value
, &w
, &h
);
970 x_destroy_bitmap (f
, face
->stipple
);
971 face
->stipple
= (Pixmap
) new_pixmap
;
976 else if (EQ (attr_name
, intern ("underline")))
978 int new = !NILP (attr_value
);
979 face
->underline
= new;
982 error ("unknown face attribute");
984 if (id
== 0 || id
== 1)
985 recompute_basic_faces (f
);
987 /* We must redraw the frame whenever any face font or color changes,
988 because it's possible that a merged (display) face
989 contains the font or color we just replaced.
990 And we must inhibit any Expose events until the redraw is done,
991 since they would try to use the invalid display faces. */
993 SET_FRAME_GARBAGED (f
);
998 DEFUN ("internal-next-face-id", Finternal_next_face_id
, Sinternal_next_face_id
,
1002 return make_number (next_face_id
++);
1005 /* Return the face id for name NAME on frame FRAME.
1006 (It should be the same for all frames,
1007 but it's as easy to use the "right" frame to look it up
1008 as to use any other one.) */
1011 face_name_id_number (f
, name
)
1017 tem
= Fcdr (assq_no_quit (name
, f
->face_alist
));
1020 CHECK_VECTOR (tem
, 0);
1021 tem
= XVECTOR (tem
)->contents
[2];
1022 CHECK_NUMBER (tem
, 0);
1026 /* Emacs initialization. */
1029 syms_of_win32faces ()
1031 Qface
= intern ("face");
1033 Qmouse_face
= intern ("mouse-face");
1034 staticpro (&Qmouse_face
);
1035 Qpixmap_spec_p
= intern ("pixmap-spec-p");
1036 staticpro (&Qpixmap_spec_p
);
1038 DEFVAR_INT ("region-face", ®ion_face
,
1039 "Face number to use to highlight the region\n\
1040 The region is highlighted with this face\n\
1041 when Transient Mark mode is enabled and the mark is active.");
1043 defsubr (&Spixmap_spec_p
);
1044 defsubr (&Sframe_face_alist
);
1045 defsubr (&Sset_frame_face_alist
);
1046 defsubr (&Smake_face_internal
);
1047 defsubr (&Sset_face_attribute_internal
);
1048 defsubr (&Sinternal_next_face_id
);