Update FSF's address in the preamble.
[bpt/emacs.git] / src / w32faces.c
1 /* "Face" primitives.
2 Copyright (C) 1993, 1994, 1995 Free Software Foundation.
3
4 This file is part of GNU Emacs.
5
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.
10
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.
15
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. */
20
21 /* Ported xfaces.c for win32 - Kevin Gallo */
22
23 #include <sys/types.h>
24 #include <sys/stat.h>
25
26 #include <config.h>
27 #include "lisp.h"
28
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"
36
37 \f
38 /* An explanation of the face data structures. */
39
40 /* ========================= Face Data Structures =========================
41
42 Let FACE-NAME be a symbol naming a face.
43
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.)
61
62 (assq FACE-NAME global-face-data) returns a vector describing the
63 global parameters for that face.
64
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.)
76
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.
89
90 Each computed face belongs to a particular frame.
91
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.
98
99 Constraints:
100
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.
104
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.
109
110 Some subtleties:
111
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. */
119 \f
120 /* Definitions and declarations. */
121
122 /* The number of face-id's in use (same for all frames). */
123 static int next_face_id;
124
125 /* The number of the face to use to indicate the region. */
126 static int region_face;
127
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)
131
132 Lisp_Object Qface, Qmouse_face;
133 Lisp_Object Qpixmap_spec_p;
134
135 int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ );
136
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 \f
143 /* Allocating, copying, and comparing struct faces. */
144
145 /* Allocate a new face */
146 static struct face *
147 allocate_face ()
148 {
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;
156 }
157
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;
162 {
163 struct face *result = allocate_face ();
164
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;
172
173 return result;
174 }
175
176 static int
177 face_eql (face1, face2)
178 struct face *face1, *face2;
179 {
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);
185 }
186 \f
187 /* Managing graphics contexts of faces. */
188
189 /* Given a computed face, construct its graphics context if necessary. */
190
191 struct face *
192 intern_face (f, face)
193 struct frame *f;
194 struct face *face;
195 {
196 face->gc = NULL;
197
198 return face;
199 }
200
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. */
205
206 void
207 clear_face_cache ()
208 {
209 /* Nothing extra */
210 }
211 \f
212 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps.
213
214 These functions operate on param faces only.
215 Computed faces get their fonts, colors and pixmaps
216 by merging param faces. */
217
218 static XFontStruct *
219 load_font (f, name)
220 struct frame *f;
221 Lisp_Object name;
222 {
223 XFontStruct *font;
224
225 if (NILP (name))
226 return (XFontStruct *) FACE_DEFAULT;
227
228 CHECK_STRING (name, 0);
229 BLOCK_INPUT;
230 font = win32_load_font (FRAME_WIN32_DISPLAY_INFO (f), (char *) XSTRING (name)->data);
231 UNBLOCK_INPUT;
232
233 if (! font)
234 Fsignal (Qerror, Fcons (build_string ("undefined font"),
235 Fcons (name, Qnil)));
236 return font;
237 }
238
239 static void
240 unload_font (f, font)
241 struct frame *f;
242 XFontStruct *font;
243 {
244 if (!font || font == ((XFontStruct *) FACE_DEFAULT))
245 return;
246
247 BLOCK_INPUT;
248 win32_unload_font (FRAME_WIN32_DISPLAY_INFO (f), font);
249 UNBLOCK_INPUT;
250 }
251
252 static unsigned long
253 load_color (f, name)
254 struct frame *f;
255 Lisp_Object name;
256 {
257 COLORREF color;
258 int result;
259
260 if (NILP (name))
261 return FACE_DEFAULT;
262
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;
271 }
272
273 static void
274 unload_color (f, pixel)
275 struct frame *f;
276 unsigned long pixel;
277 {
278 }
279
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;
284 {
285 Lisp_Object height, width;
286
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);
302 }
303
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.
307
308 Store the bitmap width in *W_PTR and height in *H_PTR. */
309
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;
315 {
316 int bitmap_id;
317 Lisp_Object tem;
318
319 if (NILP (name))
320 return FACE_DEFAULT;
321
322 tem = Fpixmap_spec_p (name);
323 if (NILP (tem))
324 wrong_type_argument (Qpixmap_spec_p, name);
325
326 BLOCK_INPUT;
327
328 if (CONSP (name))
329 {
330 /* Decode a bitmap spec into a bitmap. */
331
332 int h, w;
333 Lisp_Object bits;
334
335 w = XINT (Fcar (name));
336 h = XINT (Fcar (Fcdr (name)));
337 bits = Fcar (Fcdr (Fcdr (name)));
338
339 bitmap_id = x_create_bitmap_from_data (f, XSTRING (bits)->data,
340 w, h);
341 }
342 else
343 {
344 /* It must be a string -- a file name. */
345 bitmap_id = x_create_bitmap_from_file (f, name);
346 }
347 UNBLOCK_INPUT;
348
349 if (bitmap_id < 0)
350 Fsignal (Qerror, Fcons (build_string ("invalid or undefined bitmap"),
351 Fcons (name, Qnil)));
352
353 *w_ptr = x_bitmap_width (f, bitmap_id);
354 *h_ptr = x_bitmap_height (f, bitmap_id);
355
356 return bitmap_id;
357 }
358
359 \f
360 /* Managing parameter face arrays for frames. */
361
362 void
363 init_frame_faces (f)
364 FRAME_PTR f;
365 {
366 ensure_face_ready (f, 0);
367 ensure_face_ready (f, 1);
368
369 FRAME_N_COMPUTED_FACES (f) = 0;
370 FRAME_SIZE_COMPUTED_FACES (f) = 0;
371
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);
375
376 #ifdef MULTI_FRAME
377 /* Find another frame. */
378 {
379 Lisp_Object tail, frame, result;
380
381 result = Qnil;
382 FOR_EACH_FRAME (tail, frame)
383 if (FRAME_WIN32_P (XFRAME (frame))
384 && XFRAME (frame) != f)
385 {
386 result = frame;
387 break;
388 }
389
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. */
394 if (FRAMEP (result))
395 {
396 int i;
397 int n_faces = FRAME_N_PARAM_FACES (XFRAME (result));
398 struct face **faces = FRAME_PARAM_FACES (XFRAME (result));
399
400 for (i = 2; i < n_faces; i++)
401 if (faces[i])
402 ensure_face_ready (f, i);
403 }
404 }
405 #endif /* MULTI_FRAME */
406 }
407
408
409 /* Called from Fdelete_frame. */
410
411 void
412 free_frame_faces (f)
413 struct frame *f;
414 {
415 int i;
416
417 BLOCK_INPUT;
418
419 for (i = 0; i < FRAME_N_PARAM_FACES (f); i++)
420 {
421 struct face *face = FRAME_PARAM_FACES (f) [i];
422 if (face)
423 {
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);
428 xfree (face);
429 }
430 }
431 xfree (FRAME_PARAM_FACES (f));
432 FRAME_PARAM_FACES (f) = 0;
433 FRAME_N_PARAM_FACES (f) = 0;
434
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++)
439 {
440 struct face *face = FRAME_COMPUTED_FACES (f) [i];
441 if (face)
442 {
443 xfree (face);
444 }
445 }
446 xfree (FRAME_COMPUTED_FACES (f));
447 FRAME_COMPUTED_FACES (f) = 0;
448 FRAME_N_COMPUTED_FACES (f) = 0;
449
450 UNBLOCK_INPUT;
451 }
452 \f
453 /* Interning faces in a frame's face array. */
454
455 static int
456 new_computed_face (f, new_face)
457 struct frame *f;
458 struct face *new_face;
459 {
460 int i = FRAME_N_COMPUTED_FACES (f);
461
462 if (i >= FRAME_SIZE_COMPUTED_FACES (f))
463 {
464 int new_size = i + 32;
465
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;
472 }
473
474 i = FRAME_N_COMPUTED_FACES (f)++;
475 FRAME_COMPUTED_FACES (f)[i] = copy_face (new_face);
476 return i;
477 }
478
479
480 /* Find a match for NEW_FACE in a FRAME's computed face array, and add
481 it if we don't find one. */
482 static int
483 intern_computed_face (f, new_face)
484 struct frame *f;
485 struct face *new_face;
486 {
487 int len = FRAME_N_COMPUTED_FACES (f);
488 int i;
489
490 /* Search for a computed face already on F equivalent to FACE. */
491 for (i = 0; i < len; i++)
492 {
493 if (! FRAME_COMPUTED_FACES (f)[i])
494 abort ();
495 if (face_eql (new_face, FRAME_COMPUTED_FACES (f)[i]))
496 return i;
497 }
498
499 /* We didn't find one; add a new one. */
500 return new_computed_face (f, new_face);
501 }
502
503 /* Make parameter face id ID valid on frame F. */
504
505 static void
506 ensure_face_ready (f, id)
507 struct frame *f;
508 int id;
509 {
510 if (FRAME_N_PARAM_FACES (f) <= id)
511 {
512 int n = id + 10;
513 int i;
514 if (!FRAME_N_PARAM_FACES (f))
515 FRAME_PARAM_FACES (f)
516 = (struct face **) xmalloc (sizeof (struct face *) * n);
517 else
518 FRAME_PARAM_FACES (f)
519 = (struct face **) xrealloc (FRAME_PARAM_FACES (f),
520 sizeof (struct face *) * n);
521
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;
525 }
526
527 if (FRAME_PARAM_FACES (f) [id] == 0)
528 FRAME_PARAM_FACES (f) [id] = allocate_face ();
529 }
530 \f
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
533 different heights.
534 We assume that they're both character-cell fonts. */
535
536 int
537 same_size_fonts (font1, font2)
538 XFontStruct *font1, *font2;
539 {
540 return (FONT_WIDTH(font1) == FONT_WIDTH(font2));
541 }
542
543 /* Update the line_height of frame F according to the biggest font in
544 any face. Return nonzero if if line_height changes. */
545
546 int
547 frame_update_line_height (f)
548 FRAME_PTR f;
549 {
550 int i;
551 int biggest = FONT_HEIGHT (f->output_data.win32->font);
552
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)
556 {
557 int height = FONT_HEIGHT (f->output_data.win32->param_faces[i]->font);
558 if (height > biggest)
559 biggest = height;
560 }
561
562 if (biggest == f->output_data.win32->line_height)
563 return 0;
564
565 f->output_data.win32->line_height = biggest;
566 return 1;
567 }
568 \f
569 /* Modify face TO by copying from FROM all properties which have
570 nondefault settings. */
571
572 static void
573 merge_faces (from, to)
574 struct face *from, *to;
575 {
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)
586 {
587 to->stipple = from->stipple;
588 to->pixmap_h = from->pixmap_h;
589 to->pixmap_w = from->pixmap_w;
590 }
591 if (from->underline)
592 to->underline = from->underline;
593 }
594
595 /* Set up the basic set of facial parameters, based on the frame's
596 data; all faces are deltas applied to this. */
597
598 static void
599 compute_base_face (f, face)
600 FRAME_PTR f;
601 struct face *face;
602 {
603 face->gc = 0;
604 face->foreground = FRAME_FOREGROUND_PIXEL (f);
605 face->background = FRAME_BACKGROUND_PIXEL (f);
606 face->font = FRAME_FONT (f);
607 face->stipple = 0;
608 face->underline = 0;
609 }
610
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. */
614
615 int
616 compute_glyph_face (f, face_code, current_face)
617 struct frame *f;
618 int face_code, current_face;
619 {
620 struct face face;
621
622 face = *FRAME_COMPUTED_FACES (f)[current_face];
623
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);
627
628 return intern_computed_face (f, &face);
629 }
630
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. */
634
635 int
636 compute_glyph_face_1 (f, face_name, current_face)
637 struct frame *f;
638 Lisp_Object face_name;
639 int current_face;
640 {
641 struct face face;
642
643 face = *FRAME_COMPUTED_FACES (f)[current_face];
644
645 if (!NILP (face_name))
646 {
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);
651 }
652
653 return intern_computed_face (f, &face);
654 }
655 \f
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
660 the current buffer.
661
662 REGION_BEG, REGION_END delimit the region, so it can be highlighted.
663
664 LIMIT is a position not to scan beyond. That is to limit
665 the time this function can take.
666
667 If MOUSE is nonzero, use the character's mouse-face, not its face. */
668
669 int
670 compute_char_face (f, w, pos, region_beg, region_end, endptr, limit, mouse)
671 struct frame *f;
672 struct window *w;
673 int pos;
674 int region_beg, region_end;
675 int *endptr;
676 int limit;
677 int mouse;
678 {
679 struct face face;
680 Lisp_Object prop, position;
681 int i, j, noverlays;
682 int facecode;
683 Lisp_Object *overlay_vec;
684 Lisp_Object frame;
685 int endpos;
686 Lisp_Object propname;
687
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)
691 abort ();
692
693 XSETFRAME (frame, f);
694
695 endpos = ZV;
696 if (pos < region_beg && region_beg < endpos)
697 endpos = region_beg;
698
699 XSETFASTINT (position, pos);
700
701 if (mouse)
702 propname = Qmouse_face;
703 else
704 propname = Qface;
705
706 prop = Fget_text_property (position, propname, w->buffer);
707
708 {
709 Lisp_Object limit1, end;
710
711 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
712 end = Fnext_single_property_change (position, propname, w->buffer, limit1);
713 if (INTEGERP (end))
714 endpos = XINT (end);
715 }
716
717 {
718 int next_overlay;
719 int len;
720
721 /* First try with room for 40 overlays. */
722 len = 40;
723 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
724
725 noverlays = overlays_at (pos, 0, &overlay_vec, &len,
726 &next_overlay, (int *) 0);
727
728 /* If there are more than 40,
729 make enough space for all, and try again. */
730 if (noverlays > len)
731 {
732 len = noverlays;
733 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
734 noverlays = overlays_at (pos, 0, &overlay_vec, &len,
735 &next_overlay, (int *) 0);
736 }
737
738 if (next_overlay < endpos)
739 endpos = next_overlay;
740 }
741
742 *endptr = endpos;
743
744 /* Optimize the default case. */
745 if (noverlays == 0 && NILP (prop)
746 && !(pos >= region_beg && pos < region_end))
747 return 0;
748
749 compute_base_face (f, &face);
750
751 if (CONSP (prop))
752 {
753 /* We have a list of faces, merge them in reverse order */
754 Lisp_Object length = Flength (prop);
755 int len = XINT (length);
756 Lisp_Object *faces;
757
758 /* Put them into an array */
759 faces = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
760 for (j = 0; j < len; j++)
761 {
762 faces[j] = Fcar (prop);
763 prop = Fcdr (prop);
764 }
765 /* So that we can merge them in the reverse order */
766 for (j = len - 1; j >= 0; j--)
767 {
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);
772 }
773 }
774 else if (!NILP (prop))
775 {
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);
780 }
781
782 noverlays = sort_overlays (overlay_vec, noverlays, w);
783
784 /* Now merge the overlay data in that order. */
785 for (i = 0; i < noverlays; i++)
786 {
787 prop = Foverlay_get (overlay_vec[i], propname);
788 if (CONSP (prop))
789 {
790 /* We have a list of faces, merge them in reverse order */
791 Lisp_Object length = Flength (prop);
792 int len = XINT (length);
793 Lisp_Object *faces;
794 int i;
795
796 /* Put them into an array */
797 faces = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
798 for (j = 0; j < len; j++)
799 {
800 faces[j] = Fcar (prop);
801 prop = Fcdr (prop);
802 }
803 /* So that we can merge them in the reverse order */
804 for (j = len - 1; j >= 0; j--)
805 {
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);
810 }
811 }
812 else if (!NILP (prop))
813 {
814 Lisp_Object oend;
815 int oendpos;
816
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);
821
822 oend = OVERLAY_END (overlay_vec[i]);
823 oendpos = OVERLAY_POSITION (oend);
824 if (oendpos < endpos)
825 endpos = oendpos;
826 }
827 }
828
829 if (pos >= region_beg && pos < region_end)
830 {
831 if (region_end < endpos)
832 endpos = region_end;
833 if (region_face >= 0 && region_face < next_face_id)
834 merge_faces (FRAME_PARAM_FACES (f)[region_face], &face);
835 }
836
837 *endptr = endpos;
838
839 return intern_computed_face (f, &face);
840 }
841 \f
842 /* Recompute the GC's for the default and modeline faces.
843 We call this after changing frame parameters on which those GC's
844 depend. */
845
846 void
847 recompute_basic_faces (f)
848 FRAME_PTR f;
849 {
850 /* If the frame's faces haven't been initialized yet, don't worry about
851 this stuff. */
852 if (FRAME_N_PARAM_FACES (f) < 2)
853 return;
854
855 BLOCK_INPUT;
856
857 compute_base_face (f, FRAME_DEFAULT_FACE (f));
858 compute_base_face (f, FRAME_MODE_LINE_FACE (f));
859
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));
862
863 intern_face (f, FRAME_DEFAULT_FACE (f));
864 intern_face (f, FRAME_MODE_LINE_FACE (f));
865
866 UNBLOCK_INPUT;
867 }
868
869
870 \f
871 /* Lisp interface. */
872
873 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist, 1, 1, 0,
874 "")
875 (frame)
876 Lisp_Object frame;
877 {
878 CHECK_FRAME (frame, 0);
879 return XFRAME (frame)->face_alist;
880 }
881
882 DEFUN ("set-frame-face-alist", Fset_frame_face_alist, Sset_frame_face_alist,
883 2, 2, 0, "")
884 (frame, value)
885 Lisp_Object frame, value;
886 {
887 CHECK_FRAME (frame, 0);
888 XFRAME (frame)->face_alist = value;
889 return value;
890 }
891
892
893 DEFUN ("make-face-internal", Fmake_face_internal, Smake_face_internal, 1, 1, 0,
894 "Create face number FACE-ID on all frames.")
895 (face_id)
896 Lisp_Object face_id;
897 {
898 Lisp_Object rest, frame;
899 int id = XINT (face_id);
900
901 CHECK_NUMBER (face_id, 0);
902 if (id < 0 || id >= next_face_id)
903 error ("Face id out of range");
904
905 FOR_EACH_FRAME (rest, frame)
906 {
907 if (FRAME_WIN32_P (XFRAME (frame)))
908 ensure_face_ready (XFRAME (frame), id);
909 }
910 return Qnil;
911 }
912
913
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;
918 {
919 struct face *face;
920 struct frame *f;
921 int magic_p;
922 int id;
923 int garbaged = 0;
924
925 CHECK_FRAME (frame, 0);
926 CHECK_NUMBER (face_id, 0);
927 CHECK_SYMBOL (attr_name, 0);
928
929 f = XFRAME (frame);
930 id = XINT (face_id);
931 if (id < 0 || id >= next_face_id)
932 error ("Face id out of range");
933
934 if (! FRAME_WIN32_P (f))
935 return Qnil;
936
937 ensure_face_ready (f, id);
938 face = FRAME_PARAM_FACES (f) [XFASTINT (face_id)];
939
940 if (EQ (attr_name, intern ("font")))
941 {
942 XFontStruct *font = load_font (f, attr_value);
943 if (face->font != f->output_data.win32->font)
944 unload_font (f, face->font);
945 face->font = 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. */
950 garbaged = 1;
951 }
952 else if (EQ (attr_name, intern ("foreground")))
953 {
954 unsigned long new_color = load_color (f, attr_value);
955 unload_color (f, face->foreground);
956 face->foreground = new_color;
957 garbaged = 1;
958 }
959 else if (EQ (attr_name, intern ("background")))
960 {
961 unsigned long new_color = load_color (f, attr_value);
962 unload_color (f, face->background);
963 face->background = new_color;
964 garbaged = 1;
965 }
966 else if (EQ (attr_name, intern ("background-pixmap")))
967 {
968 unsigned int w, h;
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;
972 face->pixmap_w = w;
973 face->pixmap_h = h;
974 garbaged = 1;
975 }
976 else if (EQ (attr_name, intern ("underline")))
977 {
978 int new = !NILP (attr_value);
979 face->underline = new;
980 }
981 else
982 error ("unknown face attribute");
983
984 if (id == 0 || id == 1)
985 recompute_basic_faces (f);
986
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. */
992 if (garbaged)
993 SET_FRAME_GARBAGED (f);
994
995 return Qnil;
996 }
997
998 DEFUN ("internal-next-face-id", Finternal_next_face_id, Sinternal_next_face_id,
999 0, 0, 0, "")
1000 ()
1001 {
1002 return make_number (next_face_id++);
1003 }
1004
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.) */
1009
1010 int
1011 face_name_id_number (f, name)
1012 FRAME_PTR f;
1013 Lisp_Object name;
1014 {
1015 Lisp_Object tem;
1016
1017 tem = Fcdr (assq_no_quit (name, f->face_alist));
1018 if (NILP (tem))
1019 return 0;
1020 CHECK_VECTOR (tem, 0);
1021 tem = XVECTOR (tem)->contents[2];
1022 CHECK_NUMBER (tem, 0);
1023 return XINT (tem);
1024 }
1025 \f
1026 /* Emacs initialization. */
1027
1028 void
1029 syms_of_win32faces ()
1030 {
1031 Qface = intern ("face");
1032 staticpro (&Qface);
1033 Qmouse_face = intern ("mouse-face");
1034 staticpro (&Qmouse_face);
1035 Qpixmap_spec_p = intern ("pixmap-spec-p");
1036 staticpro (&Qpixmap_spec_p);
1037
1038 DEFVAR_INT ("region-face", &region_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.");
1042
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);
1049 }