(*:Linux:*:*): Always use ${VENDOR}.
[emacs/old-mirror.git] / src / w32faces.c
blob1a229f4ff22cf76f791fa886764d99a0509ceaab
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)
9 any later version.
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>
24 #include <sys/stat.h>
26 #include <config.h>
27 #include "lisp.h"
29 #include "w32term.h"
30 #include "buffer.h"
31 #include "dispextern.h"
32 #include "frame.h"
33 #include "blockinput.h"
34 #include "window.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]
47 where
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
51 the face,
52 FONT, FOREGROUND, and BACKGROUND are strings naming the fonts and colors
53 to use with the face,
54 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't
55 use right now, and
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
75 param_faces.)
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.
99 Constraints:
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.
110 Some subtleties:
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
118 on all frames. */
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 */
146 static struct face *
147 allocate_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;
155 return result;
158 /* Make a new face that's a copy of an existing one. */
159 static struct face *
160 copy_face (face)
161 struct face *face;
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;
173 return result;
176 static int
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. */
191 struct face *
192 intern_face (f, face)
193 struct frame *f;
194 struct face *face;
196 face->gc = NULL;
198 return 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. */
206 void
207 clear_face_cache ()
209 /* Nothing extra */
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. */
218 static XFontStruct *
219 load_font (f, name)
220 struct frame *f;
221 Lisp_Object name;
223 XFontStruct *font;
225 if (NILP (name))
226 return (XFontStruct *) FACE_DEFAULT;
228 CHECK_STRING (name, 0);
229 BLOCK_INPUT;
230 font = w32_load_font (FRAME_W32_DISPLAY_INFO (f), (char *) XSTRING (name)->data);
231 UNBLOCK_INPUT;
233 if (! font)
234 Fsignal (Qerror, Fcons (build_string ("undefined font"),
235 Fcons (name, Qnil)));
236 return font;
239 static void
240 unload_font (f, font)
241 struct frame *f;
242 XFontStruct *font;
244 if (!font || font == ((XFontStruct *) FACE_DEFAULT))
245 return;
247 BLOCK_INPUT;
248 w32_unload_font (FRAME_W32_DISPLAY_INFO (f), font);
249 UNBLOCK_INPUT;
252 static unsigned long
253 load_color (f, name)
254 struct frame *f;
255 Lisp_Object name;
257 COLORREF color;
258 int result;
260 if (NILP (name))
261 return FACE_DEFAULT;
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);
267 if (! result)
268 Fsignal (Qerror, Fcons (build_string ("undefined color"),
269 Fcons (name, Qnil)));
270 return (unsigned long) color;
273 static void
274 unload_color (f, pixel)
275 struct frame *f;
276 unsigned long 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.")
282 (arg)
283 Lisp_Object arg;
285 Lisp_Object height, width;
287 return ((STRINGP (arg)
288 || (CONSP (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)
295 && XINT (width) > 0
296 && XINT (height) > 0
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))))
301 ? Qt : Qnil);
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. */
310 static long
311 load_pixmap (f, name, w_ptr, h_ptr)
312 FRAME_PTR f;
313 Lisp_Object name;
314 unsigned int *w_ptr, *h_ptr;
316 int bitmap_id;
317 Lisp_Object tem;
319 if (NILP (name))
320 return FACE_DEFAULT;
322 tem = Fpixmap_spec_p (name);
323 if (NILP (tem))
324 wrong_type_argument (Qpixmap_spec_p, name);
326 BLOCK_INPUT;
328 if (CONSP (name))
330 /* Decode a bitmap spec into a bitmap. */
332 int h, w;
333 Lisp_Object bits;
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,
340 w, h);
342 else
344 /* It must be a string -- a file name. */
345 bitmap_id = x_create_bitmap_from_file (f, name);
347 UNBLOCK_INPUT;
349 if (bitmap_id < 0)
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);
356 return bitmap_id;
360 /* Managing parameter face arrays for frames. */
362 void
363 init_frame_faces (f)
364 FRAME_PTR f;
366 ensure_face_ready (f, 0);
367 ensure_face_ready (f, 1);
369 FRAME_N_COMPUTED_FACES (f) = 0;
370 FRAME_SIZE_COMPUTED_FACES (f) = 0;
372 new_computed_face (f, FRAME_PARAM_FACES (f)[0]);
373 new_computed_face (f, FRAME_PARAM_FACES (f)[1]);
374 recompute_basic_faces (f);
376 /* Find another frame. */
378 Lisp_Object tail, frame, result;
380 result = Qnil;
381 FOR_EACH_FRAME (tail, frame)
382 if (FRAME_W32_P (XFRAME (frame))
383 && XFRAME (frame) != f)
385 result = frame;
386 break;
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. */
393 if (FRAMEP (result))
395 int i;
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++)
400 if (faces[i])
401 ensure_face_ready (f, i);
407 /* Called from Fdelete_frame. */
409 void
410 free_frame_faces (f)
411 struct frame *f;
413 int i;
415 BLOCK_INPUT;
417 for (i = 0; i < FRAME_N_PARAM_FACES (f); i++)
419 struct face *face = FRAME_PARAM_FACES (f) [i];
420 if (face)
422 unload_font (f, face->font);
423 unload_color (f, face->foreground);
424 unload_color (f, face->background);
425 x_destroy_bitmap (f, face->stipple);
426 xfree (face);
429 xfree (FRAME_PARAM_FACES (f));
430 FRAME_PARAM_FACES (f) = 0;
431 FRAME_N_PARAM_FACES (f) = 0;
433 /* All faces in FRAME_COMPUTED_FACES use resources copied from
434 FRAME_PARAM_FACES; we can free them without fuss.
435 But we do free the GCs and the face objects themselves. */
436 for (i = 0; i < FRAME_N_COMPUTED_FACES (f); i++)
438 struct face *face = FRAME_COMPUTED_FACES (f) [i];
439 if (face)
441 xfree (face);
444 xfree (FRAME_COMPUTED_FACES (f));
445 FRAME_COMPUTED_FACES (f) = 0;
446 FRAME_N_COMPUTED_FACES (f) = 0;
448 UNBLOCK_INPUT;
451 /* Interning faces in a frame's face array. */
453 static int
454 new_computed_face (f, new_face)
455 struct frame *f;
456 struct face *new_face;
458 int i = FRAME_N_COMPUTED_FACES (f);
460 if (i >= FRAME_SIZE_COMPUTED_FACES (f))
462 int new_size = i + 32;
464 FRAME_COMPUTED_FACES (f)
465 = (struct face **) (FRAME_SIZE_COMPUTED_FACES (f) == 0
466 ? xmalloc (new_size * sizeof (struct face *))
467 : xrealloc (FRAME_COMPUTED_FACES (f),
468 new_size * sizeof (struct face *)));
469 FRAME_SIZE_COMPUTED_FACES (f) = new_size;
472 i = FRAME_N_COMPUTED_FACES (f)++;
473 FRAME_COMPUTED_FACES (f)[i] = copy_face (new_face);
474 return i;
478 /* Find a match for NEW_FACE in a FRAME's computed face array, and add
479 it if we don't find one. */
480 static int
481 intern_computed_face (f, new_face)
482 struct frame *f;
483 struct face *new_face;
485 int len = FRAME_N_COMPUTED_FACES (f);
486 int i;
488 /* Search for a computed face already on F equivalent to FACE. */
489 for (i = 0; i < len; i++)
491 if (! FRAME_COMPUTED_FACES (f)[i])
492 abort ();
493 if (face_eql (new_face, FRAME_COMPUTED_FACES (f)[i]))
494 return i;
497 /* We didn't find one; add a new one. */
498 return new_computed_face (f, new_face);
501 /* Make parameter face id ID valid on frame F. */
503 static void
504 ensure_face_ready (f, id)
505 struct frame *f;
506 int id;
508 if (FRAME_N_PARAM_FACES (f) <= id)
510 int n = id + 10;
511 int i;
512 if (!FRAME_N_PARAM_FACES (f))
513 FRAME_PARAM_FACES (f)
514 = (struct face **) xmalloc (sizeof (struct face *) * n);
515 else
516 FRAME_PARAM_FACES (f)
517 = (struct face **) xrealloc (FRAME_PARAM_FACES (f),
518 sizeof (struct face *) * n);
520 bzero (FRAME_PARAM_FACES (f) + FRAME_N_PARAM_FACES (f),
521 (n - FRAME_N_PARAM_FACES (f)) * sizeof (struct face *));
522 FRAME_N_PARAM_FACES (f) = n;
525 if (FRAME_PARAM_FACES (f) [id] == 0)
526 FRAME_PARAM_FACES (f) [id] = allocate_face ();
529 /* Return non-zero if FONT1 and FONT2 have the same width.
530 We do not check the height, because we can now deal with
531 different heights.
532 We assume that they're both character-cell fonts. */
535 same_size_fonts (font1, font2)
536 XFontStruct *font1, *font2;
538 return (FONT_WIDTH(font1) == FONT_WIDTH(font2));
541 /* Update the line_height of frame F according to the biggest font in
542 any face. Return nonzero if if line_height changes. */
545 frame_update_line_height (f)
546 FRAME_PTR f;
548 int i;
549 int biggest = FONT_HEIGHT (f->output_data.w32->font);
551 for (i = 0; i < f->output_data.w32->n_param_faces; i++)
552 if (f->output_data.w32->param_faces[i] != 0
553 && f->output_data.w32->param_faces[i]->font != (XFontStruct *) FACE_DEFAULT)
555 int height = FONT_HEIGHT (f->output_data.w32->param_faces[i]->font);
556 if (height > biggest)
557 biggest = height;
560 if (biggest == f->output_data.w32->line_height)
561 return 0;
563 f->output_data.w32->line_height = biggest;
564 return 1;
567 /* Modify face TO by copying from FROM all properties which have
568 nondefault settings. */
570 static void
571 merge_faces (from, to)
572 struct face *from, *to;
574 /* Only merge the font if it's the same width as the base font.
575 Otherwise ignore it, since we can't handle it properly. */
576 if (from->font != (XFontStruct *) FACE_DEFAULT
577 && same_size_fonts (from->font, to->font))
578 to->font = from->font;
579 if (from->foreground != FACE_DEFAULT)
580 to->foreground = from->foreground;
581 if (from->background != FACE_DEFAULT)
582 to->background = from->background;
583 if (from->stipple != FACE_DEFAULT)
585 to->stipple = from->stipple;
586 to->pixmap_h = from->pixmap_h;
587 to->pixmap_w = from->pixmap_w;
589 if (from->underline)
590 to->underline = from->underline;
593 /* Set up the basic set of facial parameters, based on the frame's
594 data; all faces are deltas applied to this. */
596 static void
597 compute_base_face (f, face)
598 FRAME_PTR f;
599 struct face *face;
601 face->gc = 0;
602 face->foreground = FRAME_FOREGROUND_PIXEL (f);
603 face->background = FRAME_BACKGROUND_PIXEL (f);
604 face->font = FRAME_FONT (f);
605 face->stipple = 0;
606 face->underline = 0;
609 /* Return the face ID to use to display a special glyph which selects
610 FACE_CODE as the face ID, assuming that ordinarily the face would
611 be CURRENT_FACE. F is the frame. */
614 compute_glyph_face (f, face_code, current_face)
615 struct frame *f;
616 int face_code, current_face;
618 struct face face;
620 face = *FRAME_COMPUTED_FACES (f)[current_face];
622 if (face_code >= 0 && face_code < FRAME_N_PARAM_FACES (f)
623 && FRAME_PARAM_FACES (f) [face_code] != 0)
624 merge_faces (FRAME_PARAM_FACES (f) [face_code], &face);
626 return intern_computed_face (f, &face);
629 /* Return the face ID to use to display a special glyph which selects
630 FACE_CODE as the face ID, assuming that ordinarily the face would
631 be CURRENT_FACE. F is the frame. */
634 compute_glyph_face_1 (f, face_name, current_face)
635 struct frame *f;
636 Lisp_Object face_name;
637 int current_face;
639 struct face face;
641 face = *FRAME_COMPUTED_FACES (f)[current_face];
643 if (!NILP (face_name))
645 int facecode = face_name_id_number (f, face_name);
646 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
647 && FRAME_PARAM_FACES (f) [facecode] != 0)
648 merge_faces (FRAME_PARAM_FACES (f) [facecode], &face);
651 return intern_computed_face (f, &face);
654 /* Return the face ID associated with a buffer position POS.
655 Store into *ENDPTR the position at which a different face is needed.
656 This does not take account of glyphs that specify their own face codes.
657 F is the frame in use for display, and W is a window displaying
658 the current buffer.
660 REGION_BEG, REGION_END delimit the region, so it can be highlighted.
662 LIMIT is a position not to scan beyond. That is to limit
663 the time this function can take.
665 If MOUSE is nonzero, use the character's mouse-face, not its face. */
668 compute_char_face (f, w, pos, region_beg, region_end, endptr, limit, mouse)
669 struct frame *f;
670 struct window *w;
671 int pos;
672 int region_beg, region_end;
673 int *endptr;
674 int limit;
675 int mouse;
677 struct face face;
678 Lisp_Object prop, position;
679 int i, j, noverlays;
680 int facecode;
681 Lisp_Object *overlay_vec;
682 Lisp_Object frame;
683 int endpos;
684 Lisp_Object propname;
686 /* W must display the current buffer. We could write this function
687 to use the frame and buffer of W, but right now it doesn't. */
688 if (XBUFFER (w->buffer) != current_buffer)
689 abort ();
691 XSETFRAME (frame, f);
693 endpos = ZV;
694 if (pos < region_beg && region_beg < endpos)
695 endpos = region_beg;
697 XSETFASTINT (position, pos);
699 if (mouse)
700 propname = Qmouse_face;
701 else
702 propname = Qface;
704 prop = Fget_text_property (position, propname, w->buffer);
707 Lisp_Object limit1, end;
709 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
710 end = Fnext_single_property_change (position, propname, w->buffer, limit1);
711 if (INTEGERP (end))
712 endpos = XINT (end);
716 int next_overlay;
717 int len;
719 /* First try with room for 40 overlays. */
720 len = 40;
721 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
723 noverlays = overlays_at (pos, 0, &overlay_vec, &len,
724 &next_overlay, (int *) 0);
726 /* If there are more than 40,
727 make enough space for all, and try again. */
728 if (noverlays > len)
730 len = noverlays;
731 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
732 noverlays = overlays_at (pos, 0, &overlay_vec, &len,
733 &next_overlay, (int *) 0);
736 if (next_overlay < endpos)
737 endpos = next_overlay;
740 *endptr = endpos;
742 /* Optimize the default case. */
743 if (noverlays == 0 && NILP (prop)
744 && !(pos >= region_beg && pos < region_end))
745 return 0;
747 compute_base_face (f, &face);
749 if (CONSP (prop))
751 /* We have a list of faces, merge them in reverse order */
752 Lisp_Object length = Flength (prop);
753 int len = XINT (length);
754 Lisp_Object *faces;
756 /* Put them into an array */
757 faces = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
758 for (j = 0; j < len; j++)
760 faces[j] = Fcar (prop);
761 prop = Fcdr (prop);
763 /* So that we can merge them in the reverse order */
764 for (j = len - 1; j >= 0; j--)
766 facecode = face_name_id_number (f, faces[j]);
767 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
768 && FRAME_PARAM_FACES (f) [facecode] != 0)
769 merge_faces (FRAME_PARAM_FACES (f) [facecode], &face);
772 else if (!NILP (prop))
774 facecode = face_name_id_number (f, prop);
775 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
776 && FRAME_PARAM_FACES (f) [facecode] != 0)
777 merge_faces (FRAME_PARAM_FACES (f) [facecode], &face);
780 noverlays = sort_overlays (overlay_vec, noverlays, w);
782 /* Now merge the overlay data in that order. */
783 for (i = 0; i < noverlays; i++)
785 prop = Foverlay_get (overlay_vec[i], propname);
786 if (CONSP (prop))
788 /* We have a list of faces, merge them in reverse order */
789 Lisp_Object length = Flength (prop);
790 int len = XINT (length);
791 Lisp_Object *faces;
792 int i;
794 /* Put them into an array */
795 faces = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
796 for (j = 0; j < len; j++)
798 faces[j] = Fcar (prop);
799 prop = Fcdr (prop);
801 /* So that we can merge them in the reverse order */
802 for (j = len - 1; j >= 0; j--)
804 facecode = face_name_id_number (f, faces[j]);
805 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
806 && FRAME_PARAM_FACES (f) [facecode] != 0)
807 merge_faces (FRAME_PARAM_FACES (f) [facecode], &face);
810 else if (!NILP (prop))
812 Lisp_Object oend;
813 int oendpos;
815 facecode = face_name_id_number (f, prop);
816 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
817 && FRAME_PARAM_FACES (f) [facecode] != 0)
818 merge_faces (FRAME_PARAM_FACES (f)[facecode], &face);
820 oend = OVERLAY_END (overlay_vec[i]);
821 oendpos = OVERLAY_POSITION (oend);
822 if (oendpos < endpos)
823 endpos = oendpos;
827 if (pos >= region_beg && pos < region_end)
829 if (region_end < endpos)
830 endpos = region_end;
831 if (region_face >= 0 && region_face < next_face_id)
832 merge_faces (FRAME_PARAM_FACES (f)[region_face], &face);
835 *endptr = endpos;
837 return intern_computed_face (f, &face);
840 /* Recompute the GC's for the default and modeline faces.
841 We call this after changing frame parameters on which those GC's
842 depend. */
844 void
845 recompute_basic_faces (f)
846 FRAME_PTR f;
848 /* If the frame's faces haven't been initialized yet, don't worry about
849 this stuff. */
850 if (FRAME_N_PARAM_FACES (f) < 2)
851 return;
853 BLOCK_INPUT;
855 compute_base_face (f, FRAME_DEFAULT_FACE (f));
856 compute_base_face (f, FRAME_MODE_LINE_FACE (f));
858 merge_faces (FRAME_DEFAULT_PARAM_FACE (f), FRAME_DEFAULT_FACE (f));
859 merge_faces (FRAME_MODE_LINE_PARAM_FACE (f), FRAME_MODE_LINE_FACE (f));
861 intern_face (f, FRAME_DEFAULT_FACE (f));
862 intern_face (f, FRAME_MODE_LINE_FACE (f));
864 UNBLOCK_INPUT;
869 /* Lisp interface. */
871 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist, 1, 1, 0,
873 (frame)
874 Lisp_Object frame;
876 CHECK_FRAME (frame, 0);
877 return XFRAME (frame)->face_alist;
880 DEFUN ("set-frame-face-alist", Fset_frame_face_alist, Sset_frame_face_alist,
881 2, 2, 0, "")
882 (frame, value)
883 Lisp_Object frame, value;
885 CHECK_FRAME (frame, 0);
886 XFRAME (frame)->face_alist = value;
887 return value;
891 DEFUN ("make-face-internal", Fmake_face_internal, Smake_face_internal, 1, 1, 0,
892 "Create face number FACE-ID on all frames.")
893 (face_id)
894 Lisp_Object face_id;
896 Lisp_Object rest, frame;
897 int id = XINT (face_id);
899 CHECK_NUMBER (face_id, 0);
900 if (id < 0 || id >= next_face_id)
901 error ("Face id out of range");
903 FOR_EACH_FRAME (rest, frame)
905 if (FRAME_W32_P (XFRAME (frame)))
906 ensure_face_ready (XFRAME (frame), id);
908 return Qnil;
912 DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal,
913 Sset_face_attribute_internal, 4, 4, 0, "")
914 (face_id, attr_name, attr_value, frame)
915 Lisp_Object face_id, attr_name, attr_value, frame;
917 struct face *face;
918 struct frame *f;
919 int magic_p;
920 int id;
921 int garbaged = 0;
923 CHECK_FRAME (frame, 0);
924 CHECK_NUMBER (face_id, 0);
925 CHECK_SYMBOL (attr_name, 0);
927 f = XFRAME (frame);
928 id = XINT (face_id);
929 if (id < 0 || id >= next_face_id)
930 error ("Face id out of range");
932 if (! FRAME_W32_P (f))
933 return Qnil;
935 ensure_face_ready (f, id);
936 face = FRAME_PARAM_FACES (f) [XFASTINT (face_id)];
938 if (EQ (attr_name, intern ("font")))
940 XFontStruct *font = load_font (f, attr_value);
941 if (face->font != f->output_data.w32->font)
942 unload_font (f, face->font);
943 face->font = font;
944 if (frame_update_line_height (f))
945 x_set_window_size (f, 0, f->width, f->height);
946 /* Must clear cache, since it might contain the font
947 we just got rid of. */
948 garbaged = 1;
950 else if (EQ (attr_name, intern ("foreground")))
952 unsigned long new_color = load_color (f, attr_value);
953 unload_color (f, face->foreground);
954 face->foreground = new_color;
955 garbaged = 1;
957 else if (EQ (attr_name, intern ("background")))
959 unsigned long new_color = load_color (f, attr_value);
960 unload_color (f, face->background);
961 face->background = new_color;
962 garbaged = 1;
964 else if (EQ (attr_name, intern ("background-pixmap")))
966 unsigned int w, h;
967 unsigned long new_pixmap = load_pixmap (f, attr_value, &w, &h);
968 x_destroy_bitmap (f, face->stipple);
969 face->stipple = (Pixmap) new_pixmap;
970 face->pixmap_w = w;
971 face->pixmap_h = h;
972 garbaged = 1;
974 else if (EQ (attr_name, intern ("underline")))
976 int new = !NILP (attr_value);
977 face->underline = new;
979 else
980 error ("unknown face attribute");
982 if (id == 0 || id == 1)
983 recompute_basic_faces (f);
985 /* We must redraw the frame whenever any face font or color changes,
986 because it's possible that a merged (display) face
987 contains the font or color we just replaced.
988 And we must inhibit any Expose events until the redraw is done,
989 since they would try to use the invalid display faces. */
990 if (garbaged)
991 SET_FRAME_GARBAGED (f);
993 return Qnil;
996 DEFUN ("internal-next-face-id", Finternal_next_face_id, Sinternal_next_face_id,
997 0, 0, 0, "")
1000 return make_number (next_face_id++);
1003 /* Return the face id for name NAME on frame FRAME.
1004 (It should be the same for all frames,
1005 but it's as easy to use the "right" frame to look it up
1006 as to use any other one.) */
1009 face_name_id_number (f, name)
1010 FRAME_PTR f;
1011 Lisp_Object name;
1013 Lisp_Object tem;
1015 tem = Fcdr (assq_no_quit (name, f->face_alist));
1016 if (NILP (tem))
1017 return 0;
1018 CHECK_VECTOR (tem, 0);
1019 tem = XVECTOR (tem)->contents[2];
1020 CHECK_NUMBER (tem, 0);
1021 return XINT (tem);
1024 /* Emacs initialization. */
1026 void
1027 syms_of_w32faces ()
1029 Qface = intern ("face");
1030 staticpro (&Qface);
1031 Qmouse_face = intern ("mouse-face");
1032 staticpro (&Qmouse_face);
1033 Qpixmap_spec_p = intern ("pixmap-spec-p");
1034 staticpro (&Qpixmap_spec_p);
1036 DEFVAR_INT ("region-face", &region_face,
1037 "Face number to use to highlight the region\n\
1038 The region is highlighted with this face\n\
1039 when Transient Mark mode is enabled and the mark is active.");
1041 defsubr (&Spixmap_spec_p);
1042 defsubr (&Sframe_face_alist);
1043 defsubr (&Sset_frame_face_alist);
1044 defsubr (&Smake_face_internal);
1045 defsubr (&Sset_face_attribute_internal);
1046 defsubr (&Sinternal_next_face_id);