(Fmake_local_variable): Call find_symbol_value
[emacs.git] / src / w32faces.c
blobdd0cbbaa8a7c441bb775c27aba6fa5f075a1b134
1 /* "Face" primitives.
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* Ported xfaces.c for win32 - Kevin Gallo */
22 #include <sys/types.h>
23 #include <sys/stat.h>
25 #include <config.h>
26 #include "lisp.h"
28 #include "w32term.h"
29 #include "buffer.h"
30 #include "dispextern.h"
31 #include "frame.h"
32 #include "blockinput.h"
33 #include "window.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]
46 where
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
50 the face,
51 FONT, FOREGROUND, and BACKGROUND are strings naming the fonts and colors
52 to use with the face,
53 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't
54 use right now, and
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
74 param_faces.)
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.
98 Constraints:
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.
109 Some subtleties:
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
117 on all frames. */
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 */
145 static struct face *
146 allocate_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;
154 return result;
157 /* Make a new face that's a copy of an existing one. */
158 static struct face *
159 copy_face (face)
160 struct face *face;
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;
172 return result;
175 static int
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. */
190 struct face *
191 intern_face (f, face)
192 struct frame *f;
193 struct face *face;
195 face->gc = NULL;
197 return 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. */
205 void
206 clear_face_cache ()
208 /* Nothing extra */
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. */
217 static XFontStruct *
218 load_font (f, name)
219 struct frame *f;
220 Lisp_Object name;
222 XFontStruct *font;
224 if (NILP (name))
225 return (XFontStruct *) FACE_DEFAULT;
227 CHECK_STRING (name, 0);
228 BLOCK_INPUT;
229 font = win32_load_font (FRAME_WIN32_DISPLAY_INFO (f), (char *) XSTRING (name)->data);
230 UNBLOCK_INPUT;
232 if (! font)
233 Fsignal (Qerror, Fcons (build_string ("undefined font"),
234 Fcons (name, Qnil)));
235 return font;
238 static void
239 unload_font (f, font)
240 struct frame *f;
241 XFontStruct *font;
243 if (!font || font == ((XFontStruct *) FACE_DEFAULT))
244 return;
246 BLOCK_INPUT;
247 win32_unload_font (FRAME_WIN32_DISPLAY_INFO (f), font);
248 UNBLOCK_INPUT;
251 static unsigned long
252 load_color (f, name)
253 struct frame *f;
254 Lisp_Object name;
256 COLORREF color;
257 int result;
259 if (NILP (name))
260 return FACE_DEFAULT;
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);
266 if (! result)
267 Fsignal (Qerror, Fcons (build_string ("undefined color"),
268 Fcons (name, Qnil)));
269 return (unsigned long) color;
272 static void
273 unload_color (f, pixel)
274 struct frame *f;
275 unsigned long 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.")
281 (arg)
282 Lisp_Object arg;
284 Lisp_Object height, width;
286 return ((STRINGP (arg)
287 || (CONSP (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)
294 && XINT (width) > 0
295 && XINT (height) > 0
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))))
300 ? Qt : Qnil);
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. */
309 static long
310 load_pixmap (f, name, w_ptr, h_ptr)
311 FRAME_PTR f;
312 Lisp_Object name;
313 unsigned int *w_ptr, *h_ptr;
315 int bitmap_id;
316 Lisp_Object tem;
318 if (NILP (name))
319 return FACE_DEFAULT;
321 tem = Fpixmap_spec_p (name);
322 if (NILP (tem))
323 wrong_type_argument (Qpixmap_spec_p, name);
325 BLOCK_INPUT;
327 if (CONSP (name))
329 /* Decode a bitmap spec into a bitmap. */
331 int h, w;
332 Lisp_Object bits;
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,
339 w, h);
341 else
343 /* It must be a string -- a file name. */
344 bitmap_id = x_create_bitmap_from_file (f, name);
346 UNBLOCK_INPUT;
348 if (bitmap_id < 0)
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);
355 return bitmap_id;
359 /* Managing parameter face arrays for frames. */
361 void
362 init_frame_faces (f)
363 FRAME_PTR f;
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);
375 #ifdef MULTI_FRAME
376 /* Find another frame. */
378 Lisp_Object tail, frame, result;
380 result = Qnil;
381 FOR_EACH_FRAME (tail, frame)
382 if (FRAME_WIN32_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);
404 #endif /* MULTI_FRAME */
408 /* Called from Fdelete_frame. */
410 void
411 free_frame_faces (f)
412 struct frame *f;
414 int i;
416 BLOCK_INPUT;
418 for (i = 0; i < FRAME_N_PARAM_FACES (f); i++)
420 struct face *face = FRAME_PARAM_FACES (f) [i];
421 if (face)
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);
427 xfree (face);
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];
440 if (face)
442 xfree (face);
445 xfree (FRAME_COMPUTED_FACES (f));
446 FRAME_COMPUTED_FACES (f) = 0;
447 FRAME_N_COMPUTED_FACES (f) = 0;
449 UNBLOCK_INPUT;
452 /* Interning faces in a frame's face array. */
454 static int
455 new_computed_face (f, new_face)
456 struct frame *f;
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);
475 return i;
479 /* Find a match for NEW_FACE in a FRAME's computed face array, and add
480 it if we don't find one. */
481 static int
482 intern_computed_face (f, new_face)
483 struct frame *f;
484 struct face *new_face;
486 int len = FRAME_N_COMPUTED_FACES (f);
487 int i;
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])
493 abort ();
494 if (face_eql (new_face, FRAME_COMPUTED_FACES (f)[i]))
495 return 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. */
504 static void
505 ensure_face_ready (f, id)
506 struct frame *f;
507 int id;
509 if (FRAME_N_PARAM_FACES (f) <= id)
511 int n = id + 10;
512 int i;
513 if (!FRAME_N_PARAM_FACES (f))
514 FRAME_PARAM_FACES (f)
515 = (struct face **) xmalloc (sizeof (struct face *) * n);
516 else
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
532 different heights.
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)
547 FRAME_PTR f;
549 int i;
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)
558 biggest = height;
561 if (biggest == f->output_data.win32->line_height)
562 return 0;
564 f->output_data.win32->line_height = biggest;
565 return 1;
568 /* Modify face TO by copying from FROM all properties which have
569 nondefault settings. */
571 static void
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;
590 if (from->underline)
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. */
597 static void
598 compute_base_face (f, face)
599 FRAME_PTR f;
600 struct face *face;
602 face->gc = 0;
603 face->foreground = FRAME_FOREGROUND_PIXEL (f);
604 face->background = FRAME_BACKGROUND_PIXEL (f);
605 face->font = FRAME_FONT (f);
606 face->stipple = 0;
607 face->underline = 0;
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)
616 struct frame *f;
617 int face_code, current_face;
619 struct face 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)
636 struct frame *f;
637 Lisp_Object face_name;
638 int current_face;
640 struct face face;
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
659 the current buffer.
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)
670 struct frame *f;
671 struct window *w;
672 int pos;
673 int region_beg, region_end;
674 int *endptr;
675 int limit;
676 int mouse;
678 struct face face;
679 Lisp_Object prop, position;
680 int i, j, noverlays;
681 int facecode;
682 Lisp_Object *overlay_vec;
683 Lisp_Object frame;
684 int endpos;
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)
690 abort ();
692 XSETFRAME (frame, f);
694 endpos = ZV;
695 if (pos < region_beg && region_beg < endpos)
696 endpos = region_beg;
698 XSETFASTINT (position, pos);
700 if (mouse)
701 propname = Qmouse_face;
702 else
703 propname = Qface;
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);
712 if (INTEGERP (end))
713 endpos = XINT (end);
717 int next_overlay;
718 int len;
720 /* First try with room for 40 overlays. */
721 len = 40;
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. */
729 if (noverlays > len)
731 len = noverlays;
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;
741 *endptr = endpos;
743 /* Optimize the default case. */
744 if (noverlays == 0 && NILP (prop)
745 && !(pos >= region_beg && pos < region_end))
746 return 0;
748 compute_base_face (f, &face);
750 if (CONSP (prop))
752 /* We have a list of faces, merge them in reverse order */
753 Lisp_Object length = Flength (prop);
754 int len = XINT (length);
755 Lisp_Object *faces;
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);
762 prop = Fcdr (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);
787 if (CONSP (prop))
789 /* We have a list of faces, merge them in reverse order */
790 Lisp_Object length = Flength (prop);
791 int len = XINT (length);
792 Lisp_Object *faces;
793 int i;
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);
800 prop = Fcdr (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))
813 Lisp_Object oend;
814 int oendpos;
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)
824 endpos = oendpos;
828 if (pos >= region_beg && pos < region_end)
830 if (region_end < endpos)
831 endpos = region_end;
832 if (region_face >= 0 && region_face < next_face_id)
833 merge_faces (FRAME_PARAM_FACES (f)[region_face], &face);
836 *endptr = endpos;
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
843 depend. */
845 void
846 recompute_basic_faces (f)
847 FRAME_PTR f;
849 /* If the frame's faces haven't been initialized yet, don't worry about
850 this stuff. */
851 if (FRAME_N_PARAM_FACES (f) < 2)
852 return;
854 BLOCK_INPUT;
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));
865 UNBLOCK_INPUT;
870 /* Lisp interface. */
872 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist, 1, 1, 0,
874 (frame)
875 Lisp_Object frame;
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,
882 2, 2, 0, "")
883 (frame, value)
884 Lisp_Object frame, value;
886 CHECK_FRAME (frame, 0);
887 XFRAME (frame)->face_alist = value;
888 return value;
892 DEFUN ("make-face-internal", Fmake_face_internal, Smake_face_internal, 1, 1, 0,
893 "Create face number FACE-ID on all frames.")
894 (face_id)
895 Lisp_Object face_id;
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);
909 return Qnil;
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;
918 struct face *face;
919 struct frame *f;
920 int magic_p;
921 int id;
922 int garbaged = 0;
924 CHECK_FRAME (frame, 0);
925 CHECK_NUMBER (face_id, 0);
926 CHECK_SYMBOL (attr_name, 0);
928 f = XFRAME (frame);
929 id = XINT (face_id);
930 if (id < 0 || id >= next_face_id)
931 error ("Face id out of range");
933 if (! FRAME_WIN32_P (f))
934 return Qnil;
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);
944 face->font = 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. */
949 garbaged = 1;
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;
956 garbaged = 1;
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;
963 garbaged = 1;
965 else if (EQ (attr_name, intern ("background-pixmap")))
967 unsigned int w, h;
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;
971 face->pixmap_w = w;
972 face->pixmap_h = h;
973 garbaged = 1;
975 else if (EQ (attr_name, intern ("underline")))
977 int new = !NILP (attr_value);
978 face->underline = new;
980 else
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. */
991 if (garbaged)
992 SET_FRAME_GARBAGED (f);
994 return Qnil;
997 DEFUN ("internal-next-face-id", Finternal_next_face_id, Sinternal_next_face_id,
998 0, 0, 0, "")
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)
1011 FRAME_PTR f;
1012 Lisp_Object name;
1014 Lisp_Object tem;
1016 tem = Fcdr (assq_no_quit (name, f->face_alist));
1017 if (NILP (tem))
1018 return 0;
1019 CHECK_VECTOR (tem, 0);
1020 tem = XVECTOR (tem)->contents[2];
1021 CHECK_NUMBER (tem, 0);
1022 return XINT (tem);
1025 /* Emacs initialization. */
1027 void
1028 syms_of_win32faces ()
1030 Qface = intern ("face");
1031 staticpro (&Qface);
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", &region_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);