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 */ );
142 static void merge_face_list ( /* FRAME_PTR, struct face *, Lisp_Object */ );
144 extern Lisp_Object Qforeground_color
, Qbackground_color
;
146 /* Allocating, copying, and comparing struct faces. */
148 /* Allocate a new face */
152 struct face
*result
= (struct face
*) xmalloc (sizeof (struct face
));
153 bzero (result
, sizeof (struct face
));
154 result
->font
= (XFontStruct
*) FACE_DEFAULT
;
155 result
->foreground
= FACE_DEFAULT
;
156 result
->background
= FACE_DEFAULT
;
157 result
->stipple
= FACE_DEFAULT
;
161 /* Make a new face that's a copy of an existing one. */
166 struct face
*result
= allocate_face ();
168 result
->font
= face
->font
;
169 result
->foreground
= face
->foreground
;
170 result
->background
= face
->background
;
171 result
->stipple
= face
->stipple
;
172 result
->underline
= face
->underline
;
173 result
->pixmap_h
= face
->pixmap_h
;
174 result
->pixmap_w
= face
->pixmap_w
;
180 face_eql (face1
, face2
)
181 struct face
*face1
, *face2
;
183 return ( face1
->font
== face2
->font
184 && face1
->foreground
== face2
->foreground
185 && face1
->background
== face2
->background
186 && face1
->stipple
== face2
->stipple
187 && face1
->underline
== face2
->underline
);
190 /* Managing graphics contexts of faces. */
192 /* Given a computed face, construct its graphics context if necessary. */
195 intern_face (f
, face
)
204 /* Clear out all graphics contexts for all computed faces
205 except for the default and mode line faces.
206 This should be done from time to time just to avoid
207 keeping too many graphics contexts that are no longer needed. */
215 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps.
217 These functions operate on param faces only.
218 Computed faces get their fonts, colors and pixmaps
219 by merging param faces. */
229 return (XFontStruct
*) FACE_DEFAULT
;
231 CHECK_STRING (name
, 0);
233 font
= w32_load_font (FRAME_W32_DISPLAY_INFO (f
), (char *) XSTRING (name
)->data
);
237 Fsignal (Qerror
, Fcons (build_string ("undefined font"),
238 Fcons (name
, Qnil
)));
243 unload_font (f
, font
)
247 if (!font
|| font
== ((XFontStruct
*) FACE_DEFAULT
))
251 w32_unload_font (FRAME_W32_DISPLAY_INFO (f
), font
);
266 CHECK_STRING (name
, 0);
267 /* if the colormap is full, defined_color will return a best match
268 to the values in an an existing cell. */
269 result
= defined_color(f
, (char *) XSTRING (name
)->data
, &color
, 1);
271 Fsignal (Qerror
, Fcons (build_string ("undefined color"),
272 Fcons (name
, Qnil
)));
273 return (unsigned long) color
;
277 unload_color (f
, pixel
)
283 DEFUN ("pixmap-spec-p", Fpixmap_spec_p
, Spixmap_spec_p
, 1, 1, 0,
284 "Return t if ARG is a valid pixmap specification.")
288 Lisp_Object height
, width
;
290 return ((STRINGP (arg
)
292 && CONSP (XCONS (arg
)->cdr
)
293 && CONSP (XCONS (XCONS (arg
)->cdr
)->cdr
)
294 && NILP (XCONS (XCONS (XCONS (arg
)->cdr
)->cdr
)->cdr
)
295 && (width
= XCONS (arg
)->car
, INTEGERP (width
))
296 && (height
= XCONS (XCONS (arg
)->cdr
)->car
, INTEGERP (height
))
297 && STRINGP (XCONS (XCONS (XCONS (arg
)->cdr
)->cdr
)->car
)
300 /* The string must have enough bits for width * height. */
301 && ((XSTRING (XCONS (XCONS (XCONS (arg
)->cdr
)->cdr
)->car
)->size
302 * (BITS_PER_INT
/ sizeof (int)))
303 >= XFASTINT (width
) * XFASTINT (height
))))
307 /* Load a bitmap according to NAME (which is either a file name
308 or a pixmap spec). Return the bitmap_id (see xfns.c)
309 or get an error if NAME is invalid.
311 Store the bitmap width in *W_PTR and height in *H_PTR. */
314 load_pixmap (f
, name
, w_ptr
, h_ptr
)
317 unsigned int *w_ptr
, *h_ptr
;
325 tem
= Fpixmap_spec_p (name
);
327 wrong_type_argument (Qpixmap_spec_p
, name
);
333 /* Decode a bitmap spec into a bitmap. */
338 w
= XINT (Fcar (name
));
339 h
= XINT (Fcar (Fcdr (name
)));
340 bits
= Fcar (Fcdr (Fcdr (name
)));
342 bitmap_id
= x_create_bitmap_from_data (f
, XSTRING (bits
)->data
,
347 /* It must be a string -- a file name. */
348 bitmap_id
= x_create_bitmap_from_file (f
, name
);
353 Fsignal (Qerror
, Fcons (build_string ("invalid or undefined bitmap"),
354 Fcons (name
, Qnil
)));
356 *w_ptr
= x_bitmap_width (f
, bitmap_id
);
357 *h_ptr
= x_bitmap_height (f
, bitmap_id
);
363 /* Managing parameter face arrays for frames. */
369 ensure_face_ready (f
, 0);
370 ensure_face_ready (f
, 1);
372 FRAME_N_COMPUTED_FACES (f
) = 0;
373 FRAME_SIZE_COMPUTED_FACES (f
) = 0;
375 new_computed_face (f
, FRAME_PARAM_FACES (f
)[0]);
376 new_computed_face (f
, FRAME_PARAM_FACES (f
)[1]);
377 recompute_basic_faces (f
);
379 /* Find another frame. */
381 Lisp_Object tail
, frame
, result
;
384 FOR_EACH_FRAME (tail
, frame
)
385 if (FRAME_W32_P (XFRAME (frame
))
386 && XFRAME (frame
) != f
)
392 /* If we didn't find any X frames other than f, then we don't need
393 any faces other than 0 and 1, so we're okay. Otherwise, make
394 sure that all faces valid on the selected frame are also valid
395 on this new frame. */
399 int n_faces
= FRAME_N_PARAM_FACES (XFRAME (result
));
400 struct face
**faces
= FRAME_PARAM_FACES (XFRAME (result
));
402 for (i
= 2; i
< n_faces
; i
++)
404 ensure_face_ready (f
, i
);
410 /* Called from Fdelete_frame. */
420 for (i
= 0; i
< FRAME_N_PARAM_FACES (f
); i
++)
422 struct face
*face
= FRAME_PARAM_FACES (f
) [i
];
425 unload_font (f
, face
->font
);
426 unload_color (f
, face
->foreground
);
427 unload_color (f
, face
->background
);
428 x_destroy_bitmap (f
, face
->stipple
);
432 xfree (FRAME_PARAM_FACES (f
));
433 FRAME_PARAM_FACES (f
) = 0;
434 FRAME_N_PARAM_FACES (f
) = 0;
436 /* All faces in FRAME_COMPUTED_FACES use resources copied from
437 FRAME_PARAM_FACES; we can free them without fuss.
438 But we do free the GCs and the face objects themselves. */
439 for (i
= 0; i
< FRAME_N_COMPUTED_FACES (f
); i
++)
441 struct face
*face
= FRAME_COMPUTED_FACES (f
) [i
];
447 xfree (FRAME_COMPUTED_FACES (f
));
448 FRAME_COMPUTED_FACES (f
) = 0;
449 FRAME_N_COMPUTED_FACES (f
) = 0;
454 /* Interning faces in a frame's face array. */
457 new_computed_face (f
, new_face
)
459 struct face
*new_face
;
461 int i
= FRAME_N_COMPUTED_FACES (f
);
463 if (i
>= FRAME_SIZE_COMPUTED_FACES (f
))
465 int new_size
= i
+ 32;
467 FRAME_COMPUTED_FACES (f
)
468 = (struct face
**) (FRAME_SIZE_COMPUTED_FACES (f
) == 0
469 ? xmalloc (new_size
* sizeof (struct face
*))
470 : xrealloc (FRAME_COMPUTED_FACES (f
),
471 new_size
* sizeof (struct face
*)));
472 FRAME_SIZE_COMPUTED_FACES (f
) = new_size
;
475 i
= FRAME_N_COMPUTED_FACES (f
)++;
476 FRAME_COMPUTED_FACES (f
)[i
] = copy_face (new_face
);
481 /* Find a match for NEW_FACE in a FRAME's computed face array, and add
482 it if we don't find one. */
484 intern_computed_face (f
, new_face
)
486 struct face
*new_face
;
488 int len
= FRAME_N_COMPUTED_FACES (f
);
491 /* Search for a computed face already on F equivalent to FACE. */
492 for (i
= 0; i
< len
; i
++)
494 if (! FRAME_COMPUTED_FACES (f
)[i
])
496 if (face_eql (new_face
, FRAME_COMPUTED_FACES (f
)[i
]))
500 /* We didn't find one; add a new one. */
501 return new_computed_face (f
, new_face
);
504 /* Make parameter face id ID valid on frame F. */
507 ensure_face_ready (f
, id
)
511 if (FRAME_N_PARAM_FACES (f
) <= id
)
515 if (!FRAME_N_PARAM_FACES (f
))
516 FRAME_PARAM_FACES (f
)
517 = (struct face
**) xmalloc (sizeof (struct face
*) * n
);
519 FRAME_PARAM_FACES (f
)
520 = (struct face
**) xrealloc (FRAME_PARAM_FACES (f
),
521 sizeof (struct face
*) * n
);
523 bzero (FRAME_PARAM_FACES (f
) + FRAME_N_PARAM_FACES (f
),
524 (n
- FRAME_N_PARAM_FACES (f
)) * sizeof (struct face
*));
525 FRAME_N_PARAM_FACES (f
) = n
;
528 if (FRAME_PARAM_FACES (f
) [id
] == 0)
529 FRAME_PARAM_FACES (f
) [id
] = allocate_face ();
532 /* Return non-zero if FONT1 and FONT2 have the same width.
533 We do not check the height, because we can now deal with
535 We assume that they're both character-cell fonts. */
538 same_size_fonts (font1
, font2
)
539 XFontStruct
*font1
, *font2
;
541 return (FONT_WIDTH(font1
) == FONT_WIDTH(font2
));
544 /* Update the line_height of frame F according to the biggest font in
545 any face. Return nonzero if if line_height changes. */
548 frame_update_line_height (f
)
552 int biggest
= FONT_HEIGHT (f
->output_data
.w32
->font
);
554 for (i
= 0; i
< f
->output_data
.w32
->n_param_faces
; i
++)
555 if (f
->output_data
.w32
->param_faces
[i
] != 0
556 && f
->output_data
.w32
->param_faces
[i
]->font
!= (XFontStruct
*) FACE_DEFAULT
)
558 int height
= FONT_HEIGHT (f
->output_data
.w32
->param_faces
[i
]->font
);
559 if (height
> biggest
)
563 if (biggest
== f
->output_data
.w32
->line_height
)
566 f
->output_data
.w32
->line_height
= biggest
;
570 /* Modify face TO by copying from FROM all properties which have
571 nondefault settings. */
574 merge_faces (from
, to
)
575 struct face
*from
, *to
;
577 /* Only merge the font if it's the same width as the base font.
578 Otherwise ignore it, since we can't handle it properly. */
579 if (from
->font
!= (XFontStruct
*) FACE_DEFAULT
580 && same_size_fonts (from
->font
, to
->font
))
581 to
->font
= from
->font
;
582 if (from
->foreground
!= FACE_DEFAULT
)
583 to
->foreground
= from
->foreground
;
584 if (from
->background
!= FACE_DEFAULT
)
585 to
->background
= from
->background
;
586 if (from
->stipple
!= FACE_DEFAULT
)
588 to
->stipple
= from
->stipple
;
589 to
->pixmap_h
= from
->pixmap_h
;
590 to
->pixmap_w
= from
->pixmap_w
;
593 to
->underline
= from
->underline
;
596 /* Set up the basic set of facial parameters, based on the frame's
597 data; all faces are deltas applied to this. */
600 compute_base_face (f
, face
)
605 face
->foreground
= FRAME_FOREGROUND_PIXEL (f
);
606 face
->background
= FRAME_BACKGROUND_PIXEL (f
);
607 face
->font
= FRAME_FONT (f
);
612 /* Return the face ID to use to display a special glyph which selects
613 FACE_CODE as the face ID, assuming that ordinarily the face would
614 be CURRENT_FACE. F is the frame. */
617 compute_glyph_face (f
, face_code
, current_face
)
619 int face_code
, current_face
;
623 face
= *FRAME_COMPUTED_FACES (f
)[current_face
];
625 if (face_code
>= 0 && face_code
< FRAME_N_PARAM_FACES (f
)
626 && FRAME_PARAM_FACES (f
) [face_code
] != 0)
627 merge_faces (FRAME_PARAM_FACES (f
) [face_code
], &face
);
629 return intern_computed_face (f
, &face
);
632 /* Return the face ID to use to display a special glyph which selects
633 FACE_CODE as the face ID, assuming that ordinarily the face would
634 be CURRENT_FACE. F is the frame. */
637 compute_glyph_face_1 (f
, face_name
, current_face
)
639 Lisp_Object face_name
;
644 face
= *FRAME_COMPUTED_FACES (f
)[current_face
];
646 if (!NILP (face_name
))
648 int facecode
= face_name_id_number (f
, face_name
);
649 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
650 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
651 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], &face
);
654 return intern_computed_face (f
, &face
);
657 /* Return the face ID associated with a buffer position POS.
658 Store into *ENDPTR the position at which a different face is needed.
659 This does not take account of glyphs that specify their own face codes.
660 F is the frame in use for display, and W is a window displaying
663 REGION_BEG, REGION_END delimit the region, so it can be highlighted.
665 LIMIT is a position not to scan beyond. That is to limit
666 the time this function can take.
668 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
);
751 merge_face_list (f
, &face
, prop
);
753 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
755 /* Now merge the overlay data in that order. */
756 for (i
= 0; i
< noverlays
; i
++)
761 prop
= Foverlay_get (overlay_vec
[i
], propname
);
762 merge_face_list (f
, &face
, prop
);
764 oend
= OVERLAY_END (overlay_vec
[i
]);
765 oendpos
= OVERLAY_POSITION (oend
);
766 if (oendpos
< endpos
)
770 if (pos
>= region_beg
&& pos
< region_end
)
772 if (region_end
< endpos
)
774 if (region_face
>= 0 && region_face
< next_face_id
)
775 merge_faces (FRAME_PARAM_FACES (f
)[region_face
], &face
);
780 return intern_computed_face (f
, &face
);
784 merge_face_list (f
, face
, prop
)
795 && ! STRINGP (XCONS (prop
)->cdr
))
797 /* We have a list of faces, merge them in reverse order. */
799 length
= Fsafe_length (prop
);
800 len
= XFASTINT (length
);
802 /* Put them into an array. */
803 faces
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
804 for (j
= 0; j
< len
; j
++)
806 faces
[j
] = Fcar (prop
);
809 /* So that we can merge them in the reverse order. */
813 faces
= (Lisp_Object
*) alloca (sizeof (Lisp_Object
));
818 for (j
= len
- 1; j
>= 0; j
--)
820 if (CONSP (faces
[j
]))
822 if (EQ (XCONS (faces
[j
])->car
, Qbackground_color
))
823 face
->background
= load_color (f
, XCONS (faces
[j
])->cdr
);
824 if (EQ (XCONS (faces
[j
])->car
, Qforeground_color
))
825 face
->foreground
= load_color (f
, XCONS (faces
[j
])->cdr
);
829 int facecode
= face_name_id_number (f
, faces
[j
]);
830 if (facecode
>= 0 && facecode
< FRAME_N_PARAM_FACES (f
)
831 && FRAME_PARAM_FACES (f
) [facecode
] != 0)
832 merge_faces (FRAME_PARAM_FACES (f
) [facecode
], face
);
838 /* Recompute the GC's for the default and modeline faces.
839 We call this after changing frame parameters on which those GC's
843 recompute_basic_faces (f
)
846 /* If the frame's faces haven't been initialized yet, don't worry about
848 if (FRAME_N_PARAM_FACES (f
) < 2)
853 compute_base_face (f
, FRAME_DEFAULT_FACE (f
));
854 compute_base_face (f
, FRAME_MODE_LINE_FACE (f
));
856 merge_faces (FRAME_DEFAULT_PARAM_FACE (f
), FRAME_DEFAULT_FACE (f
));
857 merge_faces (FRAME_MODE_LINE_PARAM_FACE (f
), FRAME_MODE_LINE_FACE (f
));
859 intern_face (f
, FRAME_DEFAULT_FACE (f
));
860 intern_face (f
, FRAME_MODE_LINE_FACE (f
));
867 /* Lisp interface. */
869 DEFUN ("frame-face-alist", Fframe_face_alist
, Sframe_face_alist
, 1, 1, 0,
874 CHECK_FRAME (frame
, 0);
875 return XFRAME (frame
)->face_alist
;
878 DEFUN ("set-frame-face-alist", Fset_frame_face_alist
, Sset_frame_face_alist
,
881 Lisp_Object frame
, value
;
883 CHECK_FRAME (frame
, 0);
884 XFRAME (frame
)->face_alist
= value
;
889 DEFUN ("make-face-internal", Fmake_face_internal
, Smake_face_internal
, 1, 1, 0,
890 "Create face number FACE-ID on all frames.")
894 Lisp_Object rest
, frame
;
895 int id
= XINT (face_id
);
897 CHECK_NUMBER (face_id
, 0);
898 if (id
< 0 || id
>= next_face_id
)
899 error ("Face id out of range");
901 FOR_EACH_FRAME (rest
, frame
)
903 if (FRAME_W32_P (XFRAME (frame
)))
904 ensure_face_ready (XFRAME (frame
), id
);
910 DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal
,
911 Sset_face_attribute_internal
, 4, 4, 0, "")
912 (face_id
, attr_name
, attr_value
, frame
)
913 Lisp_Object face_id
, attr_name
, attr_value
, frame
;
921 CHECK_FRAME (frame
, 0);
922 CHECK_NUMBER (face_id
, 0);
923 CHECK_SYMBOL (attr_name
, 0);
927 if (id
< 0 || id
>= next_face_id
)
928 error ("Face id out of range");
930 if (! FRAME_W32_P (f
))
933 ensure_face_ready (f
, id
);
934 face
= FRAME_PARAM_FACES (f
) [XFASTINT (face_id
)];
936 if (EQ (attr_name
, intern ("font")))
938 XFontStruct
*font
= load_font (f
, attr_value
);
939 if (face
->font
!= f
->output_data
.w32
->font
)
940 unload_font (f
, face
->font
);
942 if (frame_update_line_height (f
))
943 x_set_window_size (f
, 0, f
->width
, f
->height
);
944 /* Must clear cache, since it might contain the font
945 we just got rid of. */
948 else if (EQ (attr_name
, intern ("foreground")))
950 unsigned long new_color
= load_color (f
, attr_value
);
951 unload_color (f
, face
->foreground
);
952 face
->foreground
= new_color
;
955 else if (EQ (attr_name
, intern ("background")))
957 unsigned long new_color
= load_color (f
, attr_value
);
958 unload_color (f
, face
->background
);
959 face
->background
= new_color
;
962 else if (EQ (attr_name
, intern ("background-pixmap")))
965 unsigned long new_pixmap
= load_pixmap (f
, attr_value
, &w
, &h
);
966 x_destroy_bitmap (f
, face
->stipple
);
967 face
->stipple
= (Pixmap
) new_pixmap
;
972 else if (EQ (attr_name
, intern ("underline")))
974 int new = !NILP (attr_value
);
975 face
->underline
= new;
978 error ("unknown face attribute");
980 if (id
== 0 || id
== 1)
981 recompute_basic_faces (f
);
983 /* We must redraw the frame whenever any face font or color changes,
984 because it's possible that a merged (display) face
985 contains the font or color we just replaced.
986 And we must inhibit any Expose events until the redraw is done,
987 since they would try to use the invalid display faces. */
989 SET_FRAME_GARBAGED (f
);
994 DEFUN ("internal-next-face-id", Finternal_next_face_id
, Sinternal_next_face_id
,
998 return make_number (next_face_id
++);
1001 /* Return the face id for name NAME on frame FRAME.
1002 (It should be the same for all frames,
1003 but it's as easy to use the "right" frame to look it up
1004 as to use any other one.) */
1007 face_name_id_number (f
, name
)
1013 tem
= Fcdr (assq_no_quit (name
, f
->face_alist
));
1016 CHECK_VECTOR (tem
, 0);
1017 tem
= XVECTOR (tem
)->contents
[2];
1018 CHECK_NUMBER (tem
, 0);
1022 /* Emacs initialization. */
1027 Qface
= intern ("face");
1029 Qmouse_face
= intern ("mouse-face");
1030 staticpro (&Qmouse_face
);
1031 Qpixmap_spec_p
= intern ("pixmap-spec-p");
1032 staticpro (&Qpixmap_spec_p
);
1034 DEFVAR_INT ("region-face", ®ion_face
,
1035 "Face number to use to highlight the region\n\
1036 The region is highlighted with this face\n\
1037 when Transient Mark mode is enabled and the mark is active.");
1039 defsubr (&Spixmap_spec_p
);
1040 defsubr (&Sframe_face_alist
);
1041 defsubr (&Sset_frame_face_alist
);
1042 defsubr (&Smake_face_internal
);
1043 defsubr (&Sset_face_attribute_internal
);
1044 defsubr (&Sinternal_next_face_id
);