]> code.delx.au - gnu-emacs/blob - src/w32faces.c
(Fmake_indirect_buffer, Fset_buffer_major_mode, Fpop_to_buffer,
[gnu-emacs] / 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 /* Ported xfaces.c for win32 - Kevin Gallo */
21
22 #include <sys/types.h>
23 #include <sys/stat.h>
24
25 #include <config.h>
26 #include "lisp.h"
27
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"
35
36 \f
37 /* An explanation of the face data structures. */
38
39 /* ========================= Face Data Structures =========================
40
41 Let FACE-NAME be a symbol naming a face.
42
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.)
60
61 (assq FACE-NAME global-face-data) returns a vector describing the
62 global parameters for that face.
63
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 definition of struct face.
73 lisp/faces.el maintains the isomorphism between face_alist and
74 param_faces.)
75
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.
88
89 Each computed face belongs to a particular frame.
90
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.
97
98 Constraints:
99
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.
103
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.
108
109 Some subtleties:
110
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. */
118 \f
119 /* Definitions and declarations. */
120
121 /* The number of face-id's in use (same for all frames). */
122 static int next_face_id;
123
124 /* The number of the face to use to indicate the region. */
125 static int region_face;
126
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)
130
131 Lisp_Object Qface, Qmouse_face;
132 Lisp_Object Qpixmap_spec_p;
133
134 int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ );
135
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 */ );
141 \f
142 /* Allocating, copying, and comparing struct faces. */
143
144 /* Allocate a new face */
145 static struct face *
146 allocate_face ()
147 {
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;
155 }
156
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;
161 {
162 struct face *result = allocate_face ();
163
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;
171
172 return result;
173 }
174
175 static int
176 face_eql (face1, face2)
177 struct face *face1, *face2;
178 {
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);
184 }
185 \f
186 /* Managing graphics contexts of faces. */
187
188 /* Given a computed face, construct its graphics context if necessary. */
189
190 struct face *
191 intern_face (f, face)
192 struct frame *f;
193 struct face *face;
194 {
195 face->gc = NULL;
196
197 return face;
198 }
199
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. */
204
205 void
206 clear_face_cache ()
207 {
208 /* Nothing extra */
209 }
210 \f
211 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps.
212
213 These functions operate on param faces only.
214 Computed faces get their fonts, colors and pixmaps
215 by merging param faces. */
216
217 static XFontStruct *
218 load_font (f, name)
219 struct frame *f;
220 Lisp_Object name;
221 {
222 XFontStruct *font;
223
224 if (NILP (name))
225 return (XFontStruct *) FACE_DEFAULT;
226
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;
231
232 if (! font)
233 Fsignal (Qerror, Fcons (build_string ("undefined font"),
234 Fcons (name, Qnil)));
235 return font;
236 }
237
238 static void
239 unload_font (f, font)
240 struct frame *f;
241 XFontStruct *font;
242 {
243 if (!font || font == ((XFontStruct *) FACE_DEFAULT))
244 return;
245
246 BLOCK_INPUT;
247 win32_unload_font (FRAME_WIN32_DISPLAY_INFO (f), font);
248 UNBLOCK_INPUT;
249 }
250
251 static unsigned long
252 load_color (f, name)
253 struct frame *f;
254 Lisp_Object name;
255 {
256 COLORREF color;
257 int result;
258
259 if (NILP (name))
260 return FACE_DEFAULT;
261
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;
270 }
271
272 static void
273 unload_color (f, pixel)
274 struct frame *f;
275 unsigned long pixel;
276 {
277 }
278
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;
283 {
284 Lisp_Object height, width;
285
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);
301 }
302
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.
306
307 Store the bitmap width in *W_PTR and height in *H_PTR. */
308
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;
314 {
315 int bitmap_id;
316 Lisp_Object tem;
317
318 if (NILP (name))
319 return FACE_DEFAULT;
320
321 tem = Fpixmap_spec_p (name);
322 if (NILP (tem))
323 wrong_type_argument (Qpixmap_spec_p, name);
324
325 BLOCK_INPUT;
326
327 if (CONSP (name))
328 {
329 /* Decode a bitmap spec into a bitmap. */
330
331 int h, w;
332 Lisp_Object bits;
333
334 w = XINT (Fcar (name));
335 h = XINT (Fcar (Fcdr (name)));
336 bits = Fcar (Fcdr (Fcdr (name)));
337
338 bitmap_id = x_create_bitmap_from_data (f, XSTRING (bits)->data,
339 w, h);
340 }
341 else
342 {
343 /* It must be a string -- a file name. */
344 bitmap_id = x_create_bitmap_from_file (f, name);
345 }
346 UNBLOCK_INPUT;
347
348 if (bitmap_id < 0)
349 Fsignal (Qerror, Fcons (build_string ("invalid or undefined bitmap"),
350 Fcons (name, Qnil)));
351
352 *w_ptr = x_bitmap_width (f, bitmap_id);
353 *h_ptr = x_bitmap_height (f, bitmap_id);
354
355 return bitmap_id;
356 }
357
358 \f
359 /* Managing parameter face arrays for frames. */
360
361 void
362 init_frame_faces (f)
363 FRAME_PTR f;
364 {
365 ensure_face_ready (f, 0);
366 ensure_face_ready (f, 1);
367
368 FRAME_N_COMPUTED_FACES (f) = 0;
369 FRAME_SIZE_COMPUTED_FACES (f) = 0;
370
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);
374
375 #ifdef MULTI_FRAME
376 /* Find another frame. */
377 {
378 Lisp_Object tail, frame, result;
379
380 result = Qnil;
381 FOR_EACH_FRAME (tail, frame)
382 if (FRAME_WIN32_P (XFRAME (frame))
383 && XFRAME (frame) != f)
384 {
385 result = frame;
386 break;
387 }
388
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))
394 {
395 int i;
396 int n_faces = FRAME_N_PARAM_FACES (XFRAME (result));
397 struct face **faces = FRAME_PARAM_FACES (XFRAME (result));
398
399 for (i = 2; i < n_faces; i++)
400 if (faces[i])
401 ensure_face_ready (f, i);
402 }
403 }
404 #endif /* MULTI_FRAME */
405 }
406
407
408 /* Called from Fdelete_frame. */
409
410 void
411 free_frame_faces (f)
412 struct frame *f;
413 {
414 int i;
415
416 BLOCK_INPUT;
417
418 for (i = 0; i < FRAME_N_PARAM_FACES (f); i++)
419 {
420 struct face *face = FRAME_PARAM_FACES (f) [i];
421 if (face)
422 {
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);
428 }
429 }
430 xfree (FRAME_PARAM_FACES (f));
431 FRAME_PARAM_FACES (f) = 0;
432 FRAME_N_PARAM_FACES (f) = 0;
433
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++)
438 {
439 struct face *face = FRAME_COMPUTED_FACES (f) [i];
440 if (face)
441 {
442 xfree (face);
443 }
444 }
445 xfree (FRAME_COMPUTED_FACES (f));
446 FRAME_COMPUTED_FACES (f) = 0;
447 FRAME_N_COMPUTED_FACES (f) = 0;
448
449 UNBLOCK_INPUT;
450 }
451 \f
452 /* Interning faces in a frame's face array. */
453
454 static int
455 new_computed_face (f, new_face)
456 struct frame *f;
457 struct face *new_face;
458 {
459 int i = FRAME_N_COMPUTED_FACES (f);
460
461 if (i >= FRAME_SIZE_COMPUTED_FACES (f))
462 {
463 int new_size = i + 32;
464
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;
471 }
472
473 i = FRAME_N_COMPUTED_FACES (f)++;
474 FRAME_COMPUTED_FACES (f)[i] = copy_face (new_face);
475 return i;
476 }
477
478
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;
485 {
486 int len = FRAME_N_COMPUTED_FACES (f);
487 int i;
488
489 /* Search for a computed face already on F equivalent to FACE. */
490 for (i = 0; i < len; i++)
491 {
492 if (! FRAME_COMPUTED_FACES (f)[i])
493 abort ();
494 if (face_eql (new_face, FRAME_COMPUTED_FACES (f)[i]))
495 return i;
496 }
497
498 /* We didn't find one; add a new one. */
499 return new_computed_face (f, new_face);
500 }
501
502 /* Make parameter face id ID valid on frame F. */
503
504 static void
505 ensure_face_ready (f, id)
506 struct frame *f;
507 int id;
508 {
509 if (FRAME_N_PARAM_FACES (f) <= id)
510 {
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);
520
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;
524 }
525
526 if (FRAME_PARAM_FACES (f) [id] == 0)
527 FRAME_PARAM_FACES (f) [id] = allocate_face ();
528 }
529 \f
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. */
534
535 int
536 same_size_fonts (font1, font2)
537 XFontStruct *font1, *font2;
538 {
539 return (FONT_WIDTH(font1) == FONT_WIDTH(font2));
540 }
541
542 /* Update the line_height of frame F according to the biggest font in
543 any face. Return nonzero if if line_height changes. */
544
545 int
546 frame_update_line_height (f)
547 FRAME_PTR f;
548 {
549 int i;
550 int biggest = FONT_HEIGHT (f->output_data.win32->font);
551
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)
555 {
556 int height = FONT_HEIGHT (f->output_data.win32->param_faces[i]->font);
557 if (height > biggest)
558 biggest = height;
559 }
560
561 if (biggest == f->output_data.win32->line_height)
562 return 0;
563
564 f->output_data.win32->line_height = biggest;
565 return 1;
566 }
567 \f
568 /* Modify face TO by copying from FROM all properties which have
569 nondefault settings. */
570
571 static void
572 merge_faces (from, to)
573 struct face *from, *to;
574 {
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)
585 {
586 to->stipple = from->stipple;
587 to->pixmap_h = from->pixmap_h;
588 to->pixmap_w = from->pixmap_w;
589 }
590 if (from->underline)
591 to->underline = from->underline;
592 }
593
594 /* Set up the basic set of facial parameters, based on the frame's
595 data; all faces are deltas applied to this. */
596
597 static void
598 compute_base_face (f, face)
599 FRAME_PTR f;
600 struct face *face;
601 {
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;
608 }
609
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. */
613
614 int
615 compute_glyph_face (f, face_code, current_face)
616 struct frame *f;
617 int face_code, current_face;
618 {
619 struct face face;
620
621 face = *FRAME_COMPUTED_FACES (f)[current_face];
622
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);
626
627 return intern_computed_face (f, &face);
628 }
629
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. */
633
634 int
635 compute_glyph_face_1 (f, face_name, current_face)
636 struct frame *f;
637 Lisp_Object face_name;
638 int current_face;
639 {
640 struct face face;
641
642 face = *FRAME_COMPUTED_FACES (f)[current_face];
643
644 if (!NILP (face_name))
645 {
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);
650 }
651
652 return intern_computed_face (f, &face);
653 }
654 \f
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.
660
661 REGION_BEG, REGION_END delimit the region, so it can be highlighted.
662
663 LIMIT is a position not to scan beyond. That is to limit
664 the time this function can take.
665
666 If MOUSE is nonzero, use the character's mouse-face, not its face. */
667
668 int
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;
677 {
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;
686
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 ();
691
692 XSETFRAME (frame, f);
693
694 endpos = ZV;
695 if (pos < region_beg && region_beg < endpos)
696 endpos = region_beg;
697
698 XSETFASTINT (position, pos);
699
700 if (mouse)
701 propname = Qmouse_face;
702 else
703 propname = Qface;
704
705 prop = Fget_text_property (position, propname, w->buffer);
706
707 {
708 Lisp_Object limit1, end;
709
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);
714 }
715
716 {
717 int next_overlay;
718 int len;
719
720 /* First try with room for 40 overlays. */
721 len = 40;
722 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
723
724 noverlays = overlays_at (pos, 0, &overlay_vec, &len,
725 &next_overlay, (int *) 0);
726
727 /* If there are more than 40,
728 make enough space for all, and try again. */
729 if (noverlays > len)
730 {
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);
735 }
736
737 if (next_overlay < endpos)
738 endpos = next_overlay;
739 }
740
741 *endptr = endpos;
742
743 /* Optimize the default case. */
744 if (noverlays == 0 && NILP (prop)
745 && !(pos >= region_beg && pos < region_end))
746 return 0;
747
748 compute_base_face (f, &face);
749
750 if (CONSP (prop))
751 {
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;
756
757 /* Put them into an array */
758 faces = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
759 for (j = 0; j < len; j++)
760 {
761 faces[j] = Fcar (prop);
762 prop = Fcdr (prop);
763 }
764 /* So that we can merge them in the reverse order */
765 for (j = len - 1; j >= 0; j--)
766 {
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);
771 }
772 }
773 else if (!NILP (prop))
774 {
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);
779 }
780
781 noverlays = sort_overlays (overlay_vec, noverlays, w);
782
783 /* Now merge the overlay data in that order. */
784 for (i = 0; i < noverlays; i++)
785 {
786 prop = Foverlay_get (overlay_vec[i], propname);
787 if (CONSP (prop))
788 {
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;
794
795 /* Put them into an array */
796 faces = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
797 for (j = 0; j < len; j++)
798 {
799 faces[j] = Fcar (prop);
800 prop = Fcdr (prop);
801 }
802 /* So that we can merge them in the reverse order */
803 for (j = len - 1; j >= 0; j--)
804 {
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);
809 }
810 }
811 else if (!NILP (prop))
812 {
813 Lisp_Object oend;
814 int oendpos;
815
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);
820
821 oend = OVERLAY_END (overlay_vec[i]);
822 oendpos = OVERLAY_POSITION (oend);
823 if (oendpos < endpos)
824 endpos = oendpos;
825 }
826 }
827
828 if (pos >= region_beg && pos < region_end)
829 {
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);
834 }
835
836 *endptr = endpos;
837
838 return intern_computed_face (f, &face);
839 }
840 \f
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. */
844
845 void
846 recompute_basic_faces (f)
847 FRAME_PTR f;
848 {
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;
853
854 BLOCK_INPUT;
855
856 compute_base_face (f, FRAME_DEFAULT_FACE (f));
857 compute_base_face (f, FRAME_MODE_LINE_FACE (f));
858
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));
861
862 intern_face (f, FRAME_DEFAULT_FACE (f));
863 intern_face (f, FRAME_MODE_LINE_FACE (f));
864
865 UNBLOCK_INPUT;
866 }
867
868
869 \f
870 /* Lisp interface. */
871
872 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist, 1, 1, 0,
873 "")
874 (frame)
875 Lisp_Object frame;
876 {
877 CHECK_FRAME (frame, 0);
878 return XFRAME (frame)->face_alist;
879 }
880
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;
885 {
886 CHECK_FRAME (frame, 0);
887 XFRAME (frame)->face_alist = value;
888 return value;
889 }
890
891
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;
896 {
897 Lisp_Object rest, frame;
898 int id = XINT (face_id);
899
900 CHECK_NUMBER (face_id, 0);
901 if (id < 0 || id >= next_face_id)
902 error ("Face id out of range");
903
904 FOR_EACH_FRAME (rest, frame)
905 {
906 if (FRAME_WIN32_P (XFRAME (frame)))
907 ensure_face_ready (XFRAME (frame), id);
908 }
909 return Qnil;
910 }
911
912
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;
917 {
918 struct face *face;
919 struct frame *f;
920 int magic_p;
921 int id;
922 int garbaged = 0;
923
924 CHECK_FRAME (frame, 0);
925 CHECK_NUMBER (face_id, 0);
926 CHECK_SYMBOL (attr_name, 0);
927
928 f = XFRAME (frame);
929 id = XINT (face_id);
930 if (id < 0 || id >= next_face_id)
931 error ("Face id out of range");
932
933 if (! FRAME_WIN32_P (f))
934 return Qnil;
935
936 ensure_face_ready (f, id);
937 face = FRAME_PARAM_FACES (f) [XFASTINT (face_id)];
938
939 if (EQ (attr_name, intern ("font")))
940 {
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;
950 }
951 else if (EQ (attr_name, intern ("foreground")))
952 {
953 unsigned long new_color = load_color (f, attr_value);
954 unload_color (f, face->foreground);
955 face->foreground = new_color;
956 garbaged = 1;
957 }
958 else if (EQ (attr_name, intern ("background")))
959 {
960 unsigned long new_color = load_color (f, attr_value);
961 unload_color (f, face->background);
962 face->background = new_color;
963 garbaged = 1;
964 }
965 else if (EQ (attr_name, intern ("background-pixmap")))
966 {
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;
974 }
975 else if (EQ (attr_name, intern ("underline")))
976 {
977 int new = !NILP (attr_value);
978 face->underline = new;
979 }
980 else
981 error ("unknown face attribute");
982
983 if (id == 0 || id == 1)
984 recompute_basic_faces (f);
985
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);
993
994 return Qnil;
995 }
996
997 DEFUN ("internal-next-face-id", Finternal_next_face_id, Sinternal_next_face_id,
998 0, 0, 0, "")
999 ()
1000 {
1001 return make_number (next_face_id++);
1002 }
1003
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.) */
1008
1009 int
1010 face_name_id_number (f, name)
1011 FRAME_PTR f;
1012 Lisp_Object name;
1013 {
1014 Lisp_Object tem;
1015
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);
1023 }
1024 \f
1025 /* Emacs initialization. */
1026
1027 void
1028 syms_of_win32faces ()
1029 {
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);
1036
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.");
1041
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);
1048 }