comparison src/glyphs.c @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents de805c49cfc1
children e804706bfb8c
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
1 /* Generic glyph/image implementation + display tables 1 /* Generic glyph/image implementation + display tables
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. 2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
3 Copyright (C) 1995 Tinker Systems 3 Copyright (C) 1995 Tinker Systems
4 Copyright (C) 1995, 1996, 2000 Ben Wing 4 Copyright (C) 1995, 1996 Ben Wing
5 Copyright (C) 1995 Sun Microsystems 5 Copyright (C) 1995 Sun Microsystems
6 Copyright (C) 1998, 1999, 2000 Andy Piper 6 Copyright (C) 1998 Andy Piper
7 7
8 This file is part of XEmacs. 8 This file is part of XEmacs.
9 9
10 XEmacs is free software; you can redistribute it and/or modify it 10 XEmacs is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the 11 under the terms of the GNU General Public License as published by the
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */ 23 Boston, MA 02111-1307, USA. */
24 24
25 /* Synched up with: Not in FSF. */ 25 /* Synched up with: Not in FSF. */
26 26
27 /* Written by Ben Wing and Chuck Thompson. Heavily modified / 27 /* Written by Ben Wing and Chuck Thompson */
28 rewritten by Andy Piper. */
29 28
30 #include <config.h> 29 #include <config.h>
31 #include "lisp.h" 30 #include "lisp.h"
32 31
33 #include "blocktype.h"
34 #include "buffer.h" 32 #include "buffer.h"
35 #include "chartab.h"
36 #include "device.h" 33 #include "device.h"
37 #include "elhash.h" 34 #include "elhash.h"
38 #include "faces.h" 35 #include "faces.h"
39 #include "frame.h" 36 #include "frame.h"
40 #include "glyphs.h"
41 #include "insdel.h" 37 #include "insdel.h"
38 #include "opaque.h"
42 #include "objects.h" 39 #include "objects.h"
43 #include "opaque.h" 40 #include "redisplay.h"
41 #include "window.h"
42 #include "frame.h"
43 #include "chartab.h"
44 #include "rangetab.h" 44 #include "rangetab.h"
45 #include "redisplay.h"
46 #include "specifier.h"
47 #include "window.h"
48 45
49 #ifdef HAVE_XPM 46 #ifdef HAVE_XPM
50 #include <X11/xpm.h> 47 #include <X11/xpm.h>
51 #endif 48 #endif
52 49
71 Lisp_Object Vthe_nothing_vector; 68 Lisp_Object Vthe_nothing_vector;
72 Lisp_Object Vimage_instantiator_format_list; 69 Lisp_Object Vimage_instantiator_format_list;
73 Lisp_Object Vimage_instance_type_list; 70 Lisp_Object Vimage_instance_type_list;
74 Lisp_Object Vglyph_type_list; 71 Lisp_Object Vglyph_type_list;
75 72
76 int disable_animated_pixmaps;
77
78 DEFINE_IMAGE_INSTANTIATOR_FORMAT (nothing); 73 DEFINE_IMAGE_INSTANTIATOR_FORMAT (nothing);
79 DEFINE_IMAGE_INSTANTIATOR_FORMAT (inherit); 74 DEFINE_IMAGE_INSTANTIATOR_FORMAT (inherit);
80 DEFINE_IMAGE_INSTANTIATOR_FORMAT (string); 75 DEFINE_IMAGE_INSTANTIATOR_FORMAT (string);
81 DEFINE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); 76 DEFINE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
82 DEFINE_IMAGE_INSTANTIATOR_FORMAT (subwindow); 77 DEFINE_IMAGE_INSTANTIATOR_FORMAT (subwindow);
83 DEFINE_IMAGE_INSTANTIATOR_FORMAT (text);
84 DEFINE_IMAGE_INSTANTIATOR_FORMAT (pointer);
85 78
86 #ifdef HAVE_WINDOW_SYSTEM 79 #ifdef HAVE_WINDOW_SYSTEM
87 DEFINE_IMAGE_INSTANTIATOR_FORMAT (xbm); 80 DEFINE_IMAGE_INSTANTIATOR_FORMAT (xbm);
88 Lisp_Object Qxbm; 81 Lisp_Object Qxbm;
89 82
119 typedef struct 112 typedef struct
120 { 113 {
121 Dynarr_declare (struct image_instantiator_format_entry); 114 Dynarr_declare (struct image_instantiator_format_entry);
122 } image_instantiator_format_entry_dynarr; 115 } image_instantiator_format_entry_dynarr;
123 116
124 /* This contains one entry per format, per device it's defined on. */
125 image_instantiator_format_entry_dynarr * 117 image_instantiator_format_entry_dynarr *
126 the_image_instantiator_format_entry_dynarr; 118 the_image_instantiator_format_entry_dynarr;
127 119
128 static Lisp_Object allocate_image_instance (Lisp_Object governing_domain, 120 static Lisp_Object allocate_image_instance (Lisp_Object device);
129 Lisp_Object glyph);
130 static void image_validate (Lisp_Object instantiator); 121 static void image_validate (Lisp_Object instantiator);
131 static void glyph_property_was_changed (Lisp_Object glyph, 122 static void glyph_property_was_changed (Lisp_Object glyph,
132 Lisp_Object property, 123 Lisp_Object property,
133 Lisp_Object locale); 124 Lisp_Object locale);
134 static void set_image_instance_dirty_p (Lisp_Object instance, int dirty);
135 static void register_ignored_expose (struct frame* f, int x, int y, int width, int height);
136 static void cache_subwindow_instance_in_frame_maybe (Lisp_Object instance);
137 /* Unfortunately windows and X are different. In windows BeginPaint()
138 will prevent WM_PAINT messages being generated so it is unnecessary
139 to register exposures as they will not occur. Under X they will
140 always occur. */
141 int hold_ignored_expose_registration;
142
143 EXFUN (Fimage_instance_type, 1); 125 EXFUN (Fimage_instance_type, 1);
144 EXFUN (Fglyph_type, 1); 126 EXFUN (Fglyph_type, 1);
145 EXFUN (Fnext_window, 4);
146 127
147 128
148 /**************************************************************************** 129 /****************************************************************************
149 * Image Instantiators * 130 * Image Instantiators *
150 ****************************************************************************/ 131 ****************************************************************************/
172 Lisp_Object d = Dynarr_at (the_image_instantiator_format_entry_dynarr, i). 153 Lisp_Object d = Dynarr_at (the_image_instantiator_format_entry_dynarr, i).
173 device; 154 device;
174 if ((NILP (d) && NILP (device)) 155 if ((NILP (d) && NILP (device))
175 || 156 ||
176 (!NILP (device) && 157 (!NILP (device) &&
177 EQ (CONSOLE_TYPE (XCONSOLE 158 EQ (CONSOLE_TYPE (XCONSOLE
178 (DEVICE_CONSOLE (XDEVICE (device)))), d))) 159 (DEVICE_CONSOLE (XDEVICE (device)))), d)))
179 return Dynarr_at (the_image_instantiator_format_entry_dynarr, i).meths; 160 return Dynarr_at (the_image_instantiator_format_entry_dynarr, i).meths;
180 } 161 }
181 } 162 }
182 163
191 { 172 {
192 return decode_device_ii_format (Qnil, format, errb); 173 return decode_device_ii_format (Qnil, format, errb);
193 } 174 }
194 175
195 static int 176 static int
196 valid_image_instantiator_format_p (Lisp_Object format, Lisp_Object locale) 177 valid_image_instantiator_format_p (Lisp_Object format)
197 { 178 {
198 int i; 179 return (decode_image_instantiator_format (format, ERROR_ME_NOT) != 0);
199 struct image_instantiator_methods* meths =
200 decode_image_instantiator_format (format, ERROR_ME_NOT);
201 Lisp_Object contype = Qnil;
202 /* mess with the locale */
203 if (!NILP (locale) && SYMBOLP (locale))
204 contype = locale;
205 else
206 {
207 struct console* console = decode_console (locale);
208 contype = console ? CONSOLE_TYPE (console) : locale;
209 }
210 /* nothing is valid in all locales */
211 if (EQ (format, Qnothing))
212 return 1;
213 /* reject unknown formats */
214 else if (NILP (contype) || !meths)
215 return 0;
216
217 for (i = 0; i < Dynarr_length (meths->consoles); i++)
218 if (EQ (contype, Dynarr_at (meths->consoles, i).symbol))
219 return 1;
220 return 0;
221 } 180 }
222 181
223 DEFUN ("valid-image-instantiator-format-p", Fvalid_image_instantiator_format_p, 182 DEFUN ("valid-image-instantiator-format-p", Fvalid_image_instantiator_format_p,
224 1, 2, 0, /* 183 1, 1, 0, /*
225 Given an IMAGE-INSTANTIATOR-FORMAT, return non-nil if it is valid. 184 Given an IMAGE-INSTANTIATOR-FORMAT, return non-nil if it is valid.
226 If LOCALE is non-nil then the format is checked in that domain.
227 If LOCALE is nil the current console is used.
228
229 Valid formats are some subset of 'nothing, 'string, 'formatted-string, 185 Valid formats are some subset of 'nothing, 'string, 'formatted-string,
230 'xpm, 'xbm, 'xface, 'gif, 'jpeg, 'png, 'tiff, 'cursor-font, 'font, 186 'xpm, 'xbm, 'xface, 'gif, 'jpeg, 'png, 'tiff, 'cursor-font, 'font,
231 'autodetect, 'subwindow, 'inherit, 'mswindows-resource, 'bmp, 187 'autodetect, 'widget and 'subwindow, depending on how XEmacs was compiled.
232 'native-layout, 'layout, 'label, 'tab-control, 'tree-view,
233 'progress-gauge, 'scrollbar, 'combo-box, 'edit-field, 'button,
234 'widget, 'pointer, and 'text, depending on how XEmacs was compiled.
235 */ 188 */
236 (image_instantiator_format, locale)) 189 (image_instantiator_format))
237 { 190 {
238 return valid_image_instantiator_format_p (image_instantiator_format, 191 return valid_image_instantiator_format_p (image_instantiator_format) ?
239 locale) ?
240 Qt : Qnil; 192 Qt : Qnil;
241 } 193 }
242 194
243 DEFUN ("image-instantiator-format-list", Fimage_instantiator_format_list, 195 DEFUN ("image-instantiator-format-list", Fimage_instantiator_format_list,
244 0, 0, 0, /* 196 0, 0, 0, /*
257 209
258 entry.symbol = symbol; 210 entry.symbol = symbol;
259 entry.device = device; 211 entry.device = device;
260 entry.meths = meths; 212 entry.meths = meths;
261 Dynarr_add (the_image_instantiator_format_entry_dynarr, entry); 213 Dynarr_add (the_image_instantiator_format_entry_dynarr, entry);
262 if (NILP (memq_no_quit (symbol, Vimage_instantiator_format_list))) 214 Vimage_instantiator_format_list =
263 Vimage_instantiator_format_list = 215 Fcons (symbol, Vimage_instantiator_format_list);
264 Fcons (symbol, Vimage_instantiator_format_list);
265 } 216 }
266 217
267 void 218 void
268 add_entry_to_image_instantiator_format_list (Lisp_Object symbol, 219 add_entry_to_image_instantiator_format_list (Lisp_Object symbol,
269 struct 220 struct
549 } 500 }
550 501
551 return Fvector (len, elt); 502 return Fvector (len, elt);
552 } 503 }
553 504
554 #ifdef ERROR_CHECK_GLYPHS
555 static int
556 check_instance_cache_mapper (Lisp_Object key, Lisp_Object value,
557 void *flag_closure)
558 {
559 /* This function can GC */
560 /* value can be nil; we cache failures as well as successes */
561 if (!NILP (value))
562 {
563 Lisp_Object window;
564 VOID_TO_LISP (window, flag_closure);
565 assert (EQ (XIMAGE_INSTANCE_DOMAIN (value), window));
566 }
567
568 return 0;
569 }
570
571 void
572 check_window_subwindow_cache (struct window* w)
573 {
574 Lisp_Object window;
575
576 XSETWINDOW (window, w);
577
578 assert (!NILP (w->subwindow_instance_cache));
579 elisp_maphash (check_instance_cache_mapper,
580 w->subwindow_instance_cache,
581 LISP_TO_VOID (window));
582 }
583
584 void
585 check_image_instance_structure (Lisp_Object instance)
586 {
587 /* Weird nothing images exist at startup when the console is
588 deleted. */
589 if (!NOTHING_IMAGE_INSTANCEP (instance))
590 assert (DOMAIN_LIVE_P (instance));
591 if (WINDOWP (XIMAGE_INSTANCE_DOMAIN (instance)))
592 check_window_subwindow_cache
593 (XWINDOW (XIMAGE_INSTANCE_DOMAIN (instance)));
594 }
595 #endif
596
597 /* Determine what kind of domain governs the image instance.
598 Verify that the given domain is at least as specific, and extract
599 the governing domain from it. */
600 static Lisp_Object
601 get_image_instantiator_governing_domain (Lisp_Object instantiator,
602 Lisp_Object domain)
603 {
604 int governing_domain;
605
606 struct image_instantiator_methods *meths =
607 decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
608 ERROR_ME);
609 governing_domain = IIFORMAT_METH_OR_GIVEN (meths, governing_domain, (),
610 GOVERNING_DOMAIN_DEVICE);
611
612 if (governing_domain == GOVERNING_DOMAIN_WINDOW
613 && NILP (DOMAIN_WINDOW (domain)))
614 signal_simple_error_2 ("Domain for this instantiator must be resolvable to a window",
615 instantiator, domain);
616 else if (governing_domain == GOVERNING_DOMAIN_FRAME
617 && NILP (DOMAIN_FRAME (domain)))
618 signal_simple_error_2
619 ("Domain for this instantiator must be resolvable to a frame",
620 instantiator, domain);
621
622 if (governing_domain == GOVERNING_DOMAIN_WINDOW)
623 domain = DOMAIN_WINDOW (domain);
624 else if (governing_domain == GOVERNING_DOMAIN_FRAME)
625 domain = DOMAIN_FRAME (domain);
626 else if (governing_domain == GOVERNING_DOMAIN_DEVICE)
627 domain = DOMAIN_DEVICE (domain);
628 else
629 abort ();
630
631 return domain;
632 }
633
634 static Lisp_Object 505 static Lisp_Object
635 normalize_image_instantiator (Lisp_Object instantiator, 506 normalize_image_instantiator (Lisp_Object instantiator,
636 Lisp_Object contype, 507 Lisp_Object contype,
637 Lisp_Object dest_mask) 508 Lisp_Object dest_mask)
638 { 509 {
653 { 524 {
654 struct gcpro gcpro1; 525 struct gcpro gcpro1;
655 struct image_instantiator_methods *meths; 526 struct image_instantiator_methods *meths;
656 527
657 GCPRO1 (instantiator); 528 GCPRO1 (instantiator);
658 529
659 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], 530 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
660 ERROR_ME); 531 ERROR_ME);
661 RETURN_UNGCPRO (IIFORMAT_METH_OR_GIVEN (meths, normalize, 532 RETURN_UNGCPRO (IIFORMAT_METH_OR_GIVEN (meths, normalize,
662 (instantiator, contype), 533 (instantiator, contype),
663 instantiator)); 534 instantiator));
664 } 535 }
665 } 536 }
666 537
667 static Lisp_Object 538 static Lisp_Object
668 instantiate_image_instantiator (Lisp_Object governing_domain, 539 instantiate_image_instantiator (Lisp_Object device, Lisp_Object domain,
669 Lisp_Object domain,
670 Lisp_Object instantiator, 540 Lisp_Object instantiator,
671 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 541 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
672 int dest_mask, Lisp_Object glyph) 542 int dest_mask)
673 { 543 {
674 Lisp_Object ii = allocate_image_instance (governing_domain, glyph); 544 Lisp_Object ii = allocate_image_instance (device);
675 Lisp_Image_Instance* p = XIMAGE_INSTANCE (ii); 545 struct image_instantiator_methods *meths;
676 struct image_instantiator_methods *meths, *device_meths;
677 struct gcpro gcpro1; 546 struct gcpro gcpro1;
547 int methp = 0;
678 548
679 GCPRO1 (ii); 549 GCPRO1 (ii);
680 if (!valid_image_instantiator_format_p (XVECTOR_DATA (instantiator)[0],
681 DOMAIN_DEVICE (governing_domain)))
682 signal_simple_error
683 ("Image instantiator format is invalid in this locale.",
684 instantiator);
685
686 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], 550 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
687 ERROR_ME); 551 ERROR_ME);
552 methp = (int)HAS_IIFORMAT_METH_P (meths, instantiate);
688 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg, 553 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg,
689 pointer_bg, dest_mask, domain)); 554 pointer_bg, dest_mask, domain));
690 555
691 /* Now do device specific instantiation. */ 556 /* now do device specific instantiation */
692 device_meths = decode_device_ii_format (DOMAIN_DEVICE (governing_domain), 557 meths = decode_device_ii_format (device, XVECTOR_DATA (instantiator)[0],
693 XVECTOR_DATA (instantiator)[0], 558 ERROR_ME_NOT);
694 ERROR_ME_NOT); 559
695 560 if (!methp && (!meths || !HAS_IIFORMAT_METH_P (meths, instantiate)))
696 if (!HAS_IIFORMAT_METH_P (meths, instantiate)
697 && (!device_meths || !HAS_IIFORMAT_METH_P (device_meths, instantiate)))
698 signal_simple_error 561 signal_simple_error
699 ("Don't know how to instantiate this image instantiator?", 562 ("Don't know how to instantiate this image instantiator?",
700 instantiator); 563 instantiator);
701 564 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg,
702 /* In general native window system methods will require sane 565 pointer_bg, dest_mask, domain));
703 geometry values, thus the instance needs to have been laid-out 566 UNGCPRO;
704 before they get called. */ 567
705 image_instance_layout (ii, XIMAGE_INSTANCE_WIDTH (ii), 568 return ii;
706 XIMAGE_INSTANCE_HEIGHT (ii), domain);
707
708 MAYBE_IIFORMAT_METH (device_meths, instantiate, (ii, instantiator, pointer_fg,
709 pointer_bg, dest_mask, domain));
710 /* Do post instantiation. */
711 MAYBE_IIFORMAT_METH (meths, post_instantiate, (ii, instantiator, domain));
712 MAYBE_IIFORMAT_METH (device_meths, post_instantiate, (ii, instantiator, domain));
713
714 /* We're done. */
715 IMAGE_INSTANCE_INITIALIZED (p) = 1;
716 /* Now that we're done verify that we really are laid out. */
717 if (IMAGE_INSTANCE_LAYOUT_CHANGED (p))
718 image_instance_layout (ii, XIMAGE_INSTANCE_WIDTH (ii),
719 XIMAGE_INSTANCE_HEIGHT (ii), domain);
720
721 /* We *must* have a clean image at this point. */
722 IMAGE_INSTANCE_TEXT_CHANGED (p) = 0;
723 IMAGE_INSTANCE_SIZE_CHANGED (p) = 0;
724 IMAGE_INSTANCE_LAYOUT_CHANGED (p) = 0;
725 IMAGE_INSTANCE_DIRTYP (p) = 0;
726
727 assert ( XIMAGE_INSTANCE_HEIGHT (ii) >= 0
728 && XIMAGE_INSTANCE_WIDTH (ii) >= 0 );
729
730 ERROR_CHECK_IMAGE_INSTANCE (ii);
731
732 RETURN_UNGCPRO (ii);
733 } 569 }
734 570
735 571
736 /**************************************************************************** 572 /****************************************************************************
737 * Image-Instance Object * 573 * Image-Instance Object *
738 ****************************************************************************/ 574 ****************************************************************************/
739 575
740 Lisp_Object Qimage_instancep; 576 Lisp_Object Qimage_instancep;
741 577
742 static Lisp_Object 578 static Lisp_Object
743 mark_image_instance (Lisp_Object obj) 579 mark_image_instance (Lisp_Object obj, void (*markobj) (Lisp_Object))
744 { 580 {
745 Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); 581 struct Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj);
746 582
747 /* #### I want to check the instance here, but there are way too 583 markobj (i->name);
748 many instances of the instance being marked while the domain is
749 dead. For instance you can get marked through an event when using
750 callback_ex.*/
751 #if 0
752 ERROR_CHECK_IMAGE_INSTANCE (obj);
753 #endif
754
755 mark_object (i->name);
756 /* Is this legal in marking? We may get in the situation where the
757 domain has been deleted - making the instance unusable. It seems
758 better to remove the domain so that it can be finalized. */
759 if (!DOMAIN_LIVE_P (i->domain))
760 i->domain = Qnil;
761 else
762 mark_object (i->domain);
763
764 /* We don't mark the glyph reference since that would create a
765 circularity preventing GC. */
766 switch (IMAGE_INSTANCE_TYPE (i)) 584 switch (IMAGE_INSTANCE_TYPE (i))
767 { 585 {
768 case IMAGE_TEXT: 586 case IMAGE_TEXT:
769 mark_object (IMAGE_INSTANCE_TEXT_STRING (i)); 587 markobj (IMAGE_INSTANCE_TEXT_STRING (i));
770 break; 588 break;
771 case IMAGE_MONO_PIXMAP: 589 case IMAGE_MONO_PIXMAP:
772 case IMAGE_COLOR_PIXMAP: 590 case IMAGE_COLOR_PIXMAP:
773 mark_object (IMAGE_INSTANCE_PIXMAP_FILENAME (i)); 591 markobj (IMAGE_INSTANCE_PIXMAP_FILENAME (i));
774 mark_object (IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (i)); 592 markobj (IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (i));
775 mark_object (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i)); 593 markobj (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i));
776 mark_object (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i)); 594 markobj (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i));
777 mark_object (IMAGE_INSTANCE_PIXMAP_FG (i)); 595 markobj (IMAGE_INSTANCE_PIXMAP_FG (i));
778 mark_object (IMAGE_INSTANCE_PIXMAP_BG (i)); 596 markobj (IMAGE_INSTANCE_PIXMAP_BG (i));
779 break; 597 break;
780 598
781 case IMAGE_WIDGET: 599 case IMAGE_WIDGET:
782 mark_object (IMAGE_INSTANCE_WIDGET_TYPE (i)); 600 markobj (IMAGE_INSTANCE_WIDGET_TYPE (i));
783 mark_object (IMAGE_INSTANCE_WIDGET_PROPS (i)); 601 markobj (IMAGE_INSTANCE_WIDGET_PROPS (i));
784 mark_object (IMAGE_INSTANCE_WIDGET_FACE (i)); 602 markobj (IMAGE_INSTANCE_WIDGET_FACE (i));
785 mark_object (IMAGE_INSTANCE_WIDGET_ITEMS (i)); 603 mark_gui_item (&IMAGE_INSTANCE_WIDGET_ITEM (i), markobj);
786 mark_object (IMAGE_INSTANCE_LAYOUT_CHILDREN (i));
787 mark_object (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (i));
788 mark_object (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (i));
789 mark_object (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (i));
790 case IMAGE_SUBWINDOW: 604 case IMAGE_SUBWINDOW:
605 markobj (IMAGE_INSTANCE_SUBWINDOW_FRAME (i));
791 break; 606 break;
792 607
793 default: 608 default:
794 break; 609 break;
795 } 610 }
796 611
797 /* The image may have been previously finalized (yes that's wierd, 612 MAYBE_DEVMETH (XDEVICE (i->device), mark_image_instance, (i, markobj));
798 see Fdelete_frame() and mark_window_as_deleted()), in which case
799 the domain will be nil, so cope with this. */
800 if (!NILP (IMAGE_INSTANCE_DEVICE (i)))
801 MAYBE_DEVMETH (XDEVICE (IMAGE_INSTANCE_DEVICE (i)),
802 mark_image_instance, (i));
803 613
804 return i->device; 614 return i->device;
805 } 615 }
806 616
807 static void 617 static void
808 print_image_instance (Lisp_Object obj, Lisp_Object printcharfun, 618 print_image_instance (Lisp_Object obj, Lisp_Object printcharfun,
809 int escapeflag) 619 int escapeflag)
810 { 620 {
811 char buf[100]; 621 char buf[100];
812 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (obj); 622 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (obj);
813 623
814 if (print_readably) 624 if (print_readably)
815 error ("printing unreadable object #<image-instance 0x%x>", 625 error ("printing unreadable object #<image-instance 0x%x>",
816 ii->header.uid); 626 ii->header.uid);
817 write_c_string ("#<image-instance (", printcharfun); 627 write_c_string ("#<image-instance (", printcharfun);
821 { 631 {
822 print_internal (ii->name, printcharfun, 1); 632 print_internal (ii->name, printcharfun, 1);
823 write_c_string (" ", printcharfun); 633 write_c_string (" ", printcharfun);
824 } 634 }
825 write_c_string ("on ", printcharfun); 635 write_c_string ("on ", printcharfun);
826 print_internal (ii->domain, printcharfun, 0); 636 print_internal (ii->device, printcharfun, 0);
827 write_c_string (" ", printcharfun); 637 write_c_string (" ", printcharfun);
828 switch (IMAGE_INSTANCE_TYPE (ii)) 638 switch (IMAGE_INSTANCE_TYPE (ii))
829 { 639 {
830 case IMAGE_NOTHING: 640 case IMAGE_NOTHING:
831 break; 641 break;
895 write_c_string (")", printcharfun); 705 write_c_string (")", printcharfun);
896 } 706 }
897 break; 707 break;
898 708
899 case IMAGE_WIDGET: 709 case IMAGE_WIDGET:
900 print_internal (IMAGE_INSTANCE_WIDGET_TYPE (ii), printcharfun, 0); 710 if (!NILP (IMAGE_INSTANCE_WIDGET_CALLBACK (ii)))
901
902 if (GUI_ITEMP (IMAGE_INSTANCE_WIDGET_ITEM (ii)))
903 { 711 {
904 write_c_string (" ", printcharfun); 712 print_internal (IMAGE_INSTANCE_WIDGET_CALLBACK (ii), printcharfun, 0);
905 print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 1); 713 write_c_string (", ", printcharfun);
906 } 714 }
907
908 if (!NILP (IMAGE_INSTANCE_WIDGET_FACE (ii))) 715 if (!NILP (IMAGE_INSTANCE_WIDGET_FACE (ii)))
909 { 716 {
910 write_c_string (" face=", printcharfun); 717 write_c_string (" (", printcharfun);
911 print_internal 718 print_internal
912 (IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0); 719 (IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0);
720 write_c_string (")", printcharfun);
913 } 721 }
914 722
723 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
724 print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 0);
915 725
916 case IMAGE_SUBWINDOW: 726 case IMAGE_SUBWINDOW:
917 sprintf (buf, " %dx%d", IMAGE_INSTANCE_WIDTH (ii), 727 sprintf (buf, " %dx%d", IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii),
918 IMAGE_INSTANCE_HEIGHT (ii)); 728 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii));
919 write_c_string (buf, printcharfun); 729 write_c_string (buf, printcharfun);
920 730
921 /* This is stolen from frame.c. Subwindows are strange in that they 731 /* This is stolen from frame.c. Subwindows are strange in that they
922 are specific to a particular frame so we want to print in their 732 are specific to a particular frame so we want to print in their
923 description what that frame is. */ 733 description what that frame is. */
924 734
925 write_c_string (" on #<", printcharfun); 735 write_c_string (" on #<", printcharfun);
926 { 736 {
927 struct frame* f = XFRAME (IMAGE_INSTANCE_FRAME (ii)); 737 struct frame* f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
928 738
929 if (!FRAME_LIVE_P (f)) 739 if (!FRAME_LIVE_P (f))
930 write_c_string ("dead", printcharfun); 740 write_c_string ("dead", printcharfun);
931 else 741 else
932 write_c_string (DEVICE_TYPE_NAME (XDEVICE (FRAME_DEVICE (f))), 742 write_c_string (DEVICE_TYPE_NAME (XDEVICE (FRAME_DEVICE (f))),
933 printcharfun); 743 printcharfun);
744
745 write_c_string ("-frame ", printcharfun);
934 } 746 }
935 write_c_string ("-frame>", printcharfun); 747 write_c_string (">", printcharfun);
936 sprintf (buf, " 0x%p", IMAGE_INSTANCE_SUBWINDOW_ID (ii)); 748 sprintf (buf, " 0x%p", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
937 write_c_string (buf, printcharfun); 749 write_c_string (buf, printcharfun);
938 750
939 break; 751 break;
940 752
941 default: 753 default:
942 abort (); 754 abort ();
943 } 755 }
944 756
945 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), print_image_instance, 757 MAYBE_DEVMETH (XDEVICE (ii->device), print_image_instance,
946 (ii, printcharfun, escapeflag)); 758 (ii, printcharfun, escapeflag));
947 sprintf (buf, " 0x%x>", ii->header.uid); 759 sprintf (buf, " 0x%x>", ii->header.uid);
948 write_c_string (buf, printcharfun); 760 write_c_string (buf, printcharfun);
949 } 761 }
950 762
951 static void 763 static void
952 finalize_image_instance (void *header, int for_disksave) 764 finalize_image_instance (void *header, int for_disksave)
953 { 765 {
954 Lisp_Image_Instance *i = (Lisp_Image_Instance *) header; 766 struct Lisp_Image_Instance *i = (struct Lisp_Image_Instance *) header;
955 767
956 /* objects like this exist at dump time, so don't bomb out. */ 768 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_NOTHING)
957 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_NOTHING 769 /* objects like this exist at dump time, so don't bomb out. */
958 ||
959 NILP (IMAGE_INSTANCE_DEVICE (i)))
960 return; 770 return;
961 if (for_disksave) finalose (i); 771 if (for_disksave) finalose (i);
962 772
963 /* We can't use the domain here, because it might have 773 /* do this so that the cachels get reset */
964 disappeared. */ 774 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_WIDGET
965 MAYBE_DEVMETH (XDEVICE (IMAGE_INSTANCE_DEVICE (i)), 775 ||
966 finalize_image_instance, (i)); 776 IMAGE_INSTANCE_TYPE (i) == IMAGE_SUBWINDOW)
967 777 {
968 /* Make sure we don't try this twice. */ 778 MARK_FRAME_GLYPHS_CHANGED
969 IMAGE_INSTANCE_DEVICE (i) = Qnil; 779 (XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (i)));
780 }
781
782 MAYBE_DEVMETH (XDEVICE (i->device), finalize_image_instance, (i));
970 } 783 }
971 784
972 static int 785 static int
973 image_instance_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) 786 image_instance_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
974 { 787 {
975 Lisp_Image_Instance *i1 = XIMAGE_INSTANCE (obj1); 788 struct Lisp_Image_Instance *i1 = XIMAGE_INSTANCE (obj1);
976 Lisp_Image_Instance *i2 = XIMAGE_INSTANCE (obj2); 789 struct Lisp_Image_Instance *i2 = XIMAGE_INSTANCE (obj2);
977 790 struct device *d1 = XDEVICE (i1->device);
978 ERROR_CHECK_IMAGE_INSTANCE (obj1); 791 struct device *d2 = XDEVICE (i2->device);
979 ERROR_CHECK_IMAGE_INSTANCE (obj2); 792
980 793 if (d1 != d2)
981 if (!EQ (IMAGE_INSTANCE_DOMAIN (i1), 794 return 0;
982 IMAGE_INSTANCE_DOMAIN (i2)) 795 if (IMAGE_INSTANCE_TYPE (i1) != IMAGE_INSTANCE_TYPE (i2))
983 || IMAGE_INSTANCE_TYPE (i1) != IMAGE_INSTANCE_TYPE (i2)
984 || IMAGE_INSTANCE_WIDTH (i1) != IMAGE_INSTANCE_WIDTH (i2)
985 || IMAGE_INSTANCE_MARGIN_WIDTH (i1) !=
986 IMAGE_INSTANCE_MARGIN_WIDTH (i2)
987 || IMAGE_INSTANCE_HEIGHT (i1) != IMAGE_INSTANCE_HEIGHT (i2)
988 || IMAGE_INSTANCE_XOFFSET (i1) != IMAGE_INSTANCE_XOFFSET (i2)
989 || IMAGE_INSTANCE_YOFFSET (i1) != IMAGE_INSTANCE_YOFFSET (i2))
990 return 0; 796 return 0;
991 if (!internal_equal (IMAGE_INSTANCE_NAME (i1), IMAGE_INSTANCE_NAME (i2), 797 if (!internal_equal (IMAGE_INSTANCE_NAME (i1), IMAGE_INSTANCE_NAME (i2),
992 depth + 1)) 798 depth + 1))
993 return 0; 799 return 0;
994 800
1005 break; 811 break;
1006 812
1007 case IMAGE_MONO_PIXMAP: 813 case IMAGE_MONO_PIXMAP:
1008 case IMAGE_COLOR_PIXMAP: 814 case IMAGE_COLOR_PIXMAP:
1009 case IMAGE_POINTER: 815 case IMAGE_POINTER:
1010 if (!(IMAGE_INSTANCE_PIXMAP_DEPTH (i1) == 816 if (!(IMAGE_INSTANCE_PIXMAP_WIDTH (i1) ==
817 IMAGE_INSTANCE_PIXMAP_WIDTH (i2) &&
818 IMAGE_INSTANCE_PIXMAP_HEIGHT (i1) ==
819 IMAGE_INSTANCE_PIXMAP_HEIGHT (i2) &&
820 IMAGE_INSTANCE_PIXMAP_DEPTH (i1) ==
1011 IMAGE_INSTANCE_PIXMAP_DEPTH (i2) && 821 IMAGE_INSTANCE_PIXMAP_DEPTH (i2) &&
1012 IMAGE_INSTANCE_PIXMAP_SLICE (i1) ==
1013 IMAGE_INSTANCE_PIXMAP_SLICE (i2) &&
1014 EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i1), 822 EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i1),
1015 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i2)) && 823 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i2)) &&
1016 EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i1), 824 EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i1),
1017 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i2)) && 825 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i2)) &&
1018 internal_equal (IMAGE_INSTANCE_PIXMAP_FILENAME (i1), 826 internal_equal (IMAGE_INSTANCE_PIXMAP_FILENAME (i1),
1024 return 0; 832 return 0;
1025 break; 833 break;
1026 834
1027 case IMAGE_WIDGET: 835 case IMAGE_WIDGET:
1028 if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1), 836 if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1),
1029 IMAGE_INSTANCE_WIDGET_TYPE (i2)) 837 IMAGE_INSTANCE_WIDGET_TYPE (i2)) &&
1030 && IMAGE_INSTANCE_SUBWINDOW_ID (i1) == 838 EQ (IMAGE_INSTANCE_WIDGET_CALLBACK (i1),
1031 IMAGE_INSTANCE_SUBWINDOW_ID (i2) 839 IMAGE_INSTANCE_WIDGET_CALLBACK (i2))
1032 &&
1033 EQ (IMAGE_INSTANCE_WIDGET_FACE (i1),
1034 IMAGE_INSTANCE_WIDGET_TYPE (i2))
1035 && internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (i1),
1036 IMAGE_INSTANCE_WIDGET_ITEMS (i2),
1037 depth + 1)
1038 && internal_equal (IMAGE_INSTANCE_LAYOUT_CHILDREN (i1),
1039 IMAGE_INSTANCE_LAYOUT_CHILDREN (i2),
1040 depth + 1)
1041 && internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1), 840 && internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1),
1042 IMAGE_INSTANCE_WIDGET_PROPS (i2), 841 IMAGE_INSTANCE_WIDGET_PROPS (i2),
1043 depth + 1) 842 depth + 1)
1044 && internal_equal (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (i1), 843 && internal_equal (IMAGE_INSTANCE_WIDGET_TEXT (i1),
1045 IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (i2), 844 IMAGE_INSTANCE_WIDGET_TEXT (i2),
1046 depth + 1) 845 depth + 1)))
1047 && internal_equal (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (i1),
1048 IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (i2),
1049 depth + 1)
1050 ))
1051 return 0; 846 return 0;
1052 break;
1053
1054 case IMAGE_SUBWINDOW: 847 case IMAGE_SUBWINDOW:
1055 if (!(IMAGE_INSTANCE_SUBWINDOW_ID (i1) == 848 if (!(IMAGE_INSTANCE_SUBWINDOW_WIDTH (i1) ==
849 IMAGE_INSTANCE_SUBWINDOW_WIDTH (i2) &&
850 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i1) ==
851 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i2) &&
852 IMAGE_INSTANCE_SUBWINDOW_ID (i1) ==
1056 IMAGE_INSTANCE_SUBWINDOW_ID (i2))) 853 IMAGE_INSTANCE_SUBWINDOW_ID (i2)))
1057 return 0; 854 return 0;
1058 break; 855 break;
1059 856
1060 default: 857 default:
1061 abort (); 858 abort ();
1062 } 859 }
1063 860
1064 return DEVMETH_OR_GIVEN (DOMAIN_XDEVICE (i1->domain), 861 return DEVMETH_OR_GIVEN (d1, image_instance_equal, (i1, i2, depth), 1);
1065 image_instance_equal, (i1, i2, depth), 1);
1066 }
1067
1068 /* Image instance domain manipulators. We can't error check in these
1069 otherwise we get into infinite recursion. */
1070 Lisp_Object
1071 image_instance_device (Lisp_Object instance)
1072 {
1073 return XIMAGE_INSTANCE_DEVICE (instance);
1074 }
1075
1076 Lisp_Object
1077 image_instance_frame (Lisp_Object instance)
1078 {
1079 return XIMAGE_INSTANCE_FRAME (instance);
1080 }
1081
1082 Lisp_Object
1083 image_instance_window (Lisp_Object instance)
1084 {
1085 return DOMAIN_WINDOW (XIMAGE_INSTANCE_DOMAIN (instance));
1086 }
1087
1088 int
1089 image_instance_live_p (Lisp_Object instance)
1090 {
1091 return DOMAIN_LIVE_P (XIMAGE_INSTANCE_DOMAIN (instance));
1092 } 862 }
1093 863
1094 static unsigned long 864 static unsigned long
1095 image_instance_hash (Lisp_Object obj, int depth) 865 image_instance_hash (Lisp_Object obj, int depth)
1096 { 866 {
1097 Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); 867 struct Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj);
1098 unsigned long hash = HASH4 (LISP_HASH (IMAGE_INSTANCE_DOMAIN (i)), 868 struct device *d = XDEVICE (i->device);
1099 IMAGE_INSTANCE_WIDTH (i), 869 unsigned long hash = (unsigned long) d;
1100 IMAGE_INSTANCE_MARGIN_WIDTH (i),
1101 IMAGE_INSTANCE_HEIGHT (i));
1102
1103 ERROR_CHECK_IMAGE_INSTANCE (obj);
1104 870
1105 switch (IMAGE_INSTANCE_TYPE (i)) 871 switch (IMAGE_INSTANCE_TYPE (i))
1106 { 872 {
1107 case IMAGE_NOTHING: 873 case IMAGE_NOTHING:
1108 break; 874 break;
1113 break; 879 break;
1114 880
1115 case IMAGE_MONO_PIXMAP: 881 case IMAGE_MONO_PIXMAP:
1116 case IMAGE_COLOR_PIXMAP: 882 case IMAGE_COLOR_PIXMAP:
1117 case IMAGE_POINTER: 883 case IMAGE_POINTER:
1118 hash = HASH4 (hash, IMAGE_INSTANCE_PIXMAP_DEPTH (i), 884 hash = HASH5 (hash, IMAGE_INSTANCE_PIXMAP_WIDTH (i),
1119 IMAGE_INSTANCE_PIXMAP_SLICE (i), 885 IMAGE_INSTANCE_PIXMAP_HEIGHT (i),
886 IMAGE_INSTANCE_PIXMAP_DEPTH (i),
1120 internal_hash (IMAGE_INSTANCE_PIXMAP_FILENAME (i), 887 internal_hash (IMAGE_INSTANCE_PIXMAP_FILENAME (i),
1121 depth + 1)); 888 depth + 1));
1122 break; 889 break;
1123 890
1124 case IMAGE_WIDGET: 891 case IMAGE_WIDGET:
1125 /* We need the hash to be equivalent to what should be 892 hash = HASH4 (hash,
1126 displayed. */ 893 internal_hash (IMAGE_INSTANCE_WIDGET_TYPE (i), depth + 1),
1127 hash = HASH5 (hash,
1128 LISP_HASH (IMAGE_INSTANCE_WIDGET_TYPE (i)),
1129 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1), 894 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1),
1130 internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1), 895 internal_hash (IMAGE_INSTANCE_WIDGET_CALLBACK (i), depth + 1));
1131 internal_hash (IMAGE_INSTANCE_LAYOUT_CHILDREN (i),
1132 depth + 1));
1133 case IMAGE_SUBWINDOW: 896 case IMAGE_SUBWINDOW:
1134 hash = HASH2 (hash, (int) IMAGE_INSTANCE_SUBWINDOW_ID (i)); 897 hash = HASH4 (hash, IMAGE_INSTANCE_SUBWINDOW_WIDTH (i),
898 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i),
899 (int) IMAGE_INSTANCE_SUBWINDOW_ID (i));
1135 break; 900 break;
1136 901
1137 default: 902 default:
1138 abort (); 903 abort ();
1139 } 904 }
1140 905
1141 return HASH2 (hash, DEVMETH_OR_GIVEN 906 return HASH2 (hash, DEVMETH_OR_GIVEN (d, image_instance_hash, (i, depth),
1142 (XDEVICE (image_instance_device (obj)), 907 0));
1143 image_instance_hash, (i, depth),
1144 0));
1145 } 908 }
1146 909
1147 DEFINE_LRECORD_IMPLEMENTATION ("image-instance", image_instance, 910 DEFINE_LRECORD_IMPLEMENTATION ("image-instance", image_instance,
1148 mark_image_instance, print_image_instance, 911 mark_image_instance, print_image_instance,
1149 finalize_image_instance, image_instance_equal, 912 finalize_image_instance, image_instance_equal,
1150 image_instance_hash, 0, 913 image_instance_hash,
1151 Lisp_Image_Instance); 914 struct Lisp_Image_Instance);
1152 915
1153 static Lisp_Object 916 static Lisp_Object
1154 allocate_image_instance (Lisp_Object governing_domain, Lisp_Object glyph) 917 allocate_image_instance (Lisp_Object device)
1155 { 918 {
1156 Lisp_Image_Instance *lp = 919 struct Lisp_Image_Instance *lp =
1157 alloc_lcrecord_type (Lisp_Image_Instance, &lrecord_image_instance); 920 alloc_lcrecord_type (struct Lisp_Image_Instance, &lrecord_image_instance);
1158 Lisp_Object val; 921 Lisp_Object val;
1159 922
1160 zero_lcrecord (lp); 923 zero_lcrecord (lp);
1161 /* It's not possible to simply keep a record of the domain in which 924 lp->device = device;
1162 the instance was instantiated. This is because caching may mean
1163 that the domain becomes invalid but the instance remains
1164 valid. However, the only truly relevant domain is the domain in
1165 which the instance is cached since this is the one that will be
1166 common to the instances. */
1167 lp->domain = governing_domain;
1168 /* The cache domain is not quite sufficient since the domain can get
1169 deleted before the image instance does. We need to know the
1170 domain device in order to finalize the image instance
1171 properly. We therefore record the device also. */
1172 lp->device = DOMAIN_DEVICE (governing_domain);
1173 lp->type = IMAGE_NOTHING; 925 lp->type = IMAGE_NOTHING;
1174 lp->name = Qnil; 926 lp->name = Qnil;
1175 lp->x_offset = 0;
1176 lp->y_offset = 0;
1177 lp->width = IMAGE_UNSPECIFIED_GEOMETRY;
1178 lp->margin_width = 0;
1179 lp->height = IMAGE_UNSPECIFIED_GEOMETRY;
1180 lp->parent = glyph;
1181 /* So that layouts get done. */
1182 lp->layout_changed = 1;
1183 lp->initialized = 0;
1184
1185 XSETIMAGE_INSTANCE (val, lp); 927 XSETIMAGE_INSTANCE (val, lp);
1186 MARK_GLYPHS_CHANGED;
1187
1188 return val; 928 return val;
1189 } 929 }
1190 930
1191 static enum image_instance_type 931 static enum image_instance_type
1192 decode_image_instance_type (Lisp_Object type, Error_behavior errb) 932 decode_image_instance_type (Lisp_Object type, Error_behavior errb)
1226 966
1227 return Qnil; /* not reached */ 967 return Qnil; /* not reached */
1228 } 968 }
1229 969
1230 static int 970 static int
971 image_instance_type_to_mask (enum image_instance_type type)
972 {
973 /* This depends on the fact that enums are assigned consecutive
974 integers starting at 0. (Remember that IMAGE_UNKNOWN is the
975 first enum.) I'm fairly sure this behavior in ANSI-mandated,
976 so there should be no portability problems here. */
977 return (1 << ((int) (type) - 1));
978 }
979
980 static int
1231 decode_image_instance_type_list (Lisp_Object list) 981 decode_image_instance_type_list (Lisp_Object list)
1232 { 982 {
1233 Lisp_Object rest; 983 Lisp_Object rest;
1234 int mask = 0; 984 int mask = 0;
1235 985
1277 { 1027 {
1278 signal_error 1028 signal_error
1279 (Qerror, 1029 (Qerror,
1280 list2 1030 list2
1281 (emacs_doprnt_string_lisp_2 1031 (emacs_doprnt_string_lisp_2
1282 ((const Bufbyte *) 1032 ((CONST Bufbyte *)
1283 "No compatible image-instance types given: wanted one of %s, got %s", 1033 "No compatible image-instance types given: wanted one of %s, got %s",
1284 Qnil, -1, 2, 1034 Qnil, -1, 2,
1285 encode_image_instance_type_list (desired_dest_mask), 1035 encode_image_instance_type_list (desired_dest_mask),
1286 encode_image_instance_type_list (given_dest_mask)), 1036 encode_image_instance_type_list (given_dest_mask)),
1287 instantiator)); 1037 instantiator));
1294 } 1044 }
1295 1045
1296 DEFUN ("valid-image-instance-type-p", Fvalid_image_instance_type_p, 1, 1, 0, /* 1046 DEFUN ("valid-image-instance-type-p", Fvalid_image_instance_type_p, 1, 1, 0, /*
1297 Given an IMAGE-INSTANCE-TYPE, return non-nil if it is valid. 1047 Given an IMAGE-INSTANCE-TYPE, return non-nil if it is valid.
1298 Valid types are some subset of 'nothing, 'text, 'mono-pixmap, 'color-pixmap, 1048 Valid types are some subset of 'nothing, 'text, 'mono-pixmap, 'color-pixmap,
1299 'pointer, 'subwindow, and 'widget, depending on how XEmacs was compiled. 1049 'pointer, and 'subwindow, depending on how XEmacs was compiled.
1300 */ 1050 */
1301 (image_instance_type)) 1051 (image_instance_type))
1302 { 1052 {
1303 return valid_image_instance_type_p (image_instance_type) ? Qt : Qnil; 1053 return valid_image_instance_type_p (image_instance_type) ? Qt : Qnil;
1304 } 1054 }
1331 assert (ERRB_EQ (errb, ERROR_ME_WARN)); 1081 assert (ERRB_EQ (errb, ERROR_ME_WARN));
1332 return Qwarning; 1082 return Qwarning;
1333 } 1083 }
1334 } 1084 }
1335 1085
1336 /* Recurse up the hierarchy looking for the topmost glyph. This means
1337 that instances in layouts will inherit face properties from their
1338 parent. */
1339 Lisp_Object image_instance_parent_glyph (Lisp_Image_Instance* ii)
1340 {
1341 if (IMAGE_INSTANCEP (IMAGE_INSTANCE_PARENT (ii)))
1342 {
1343 return image_instance_parent_glyph
1344 (XIMAGE_INSTANCE (IMAGE_INSTANCE_PARENT (ii)));
1345 }
1346 return IMAGE_INSTANCE_PARENT (ii);
1347 }
1348
1349 static Lisp_Object 1086 static Lisp_Object
1350 make_image_instance_1 (Lisp_Object data, Lisp_Object domain, 1087 make_image_instance_1 (Lisp_Object data, Lisp_Object device,
1351 Lisp_Object dest_types) 1088 Lisp_Object dest_types)
1352 { 1089 {
1353 Lisp_Object ii; 1090 Lisp_Object ii;
1354 struct gcpro gcpro1; 1091 struct gcpro gcpro1;
1355 int dest_mask; 1092 int dest_mask;
1356 Lisp_Object governing_domain; 1093
1357 1094 XSETDEVICE (device, decode_device (device));
1095 /* instantiate_image_instantiator() will abort if given an
1096 image instance ... */
1358 if (IMAGE_INSTANCEP (data)) 1097 if (IMAGE_INSTANCEP (data))
1359 signal_simple_error ("Image instances not allowed here", data); 1098 signal_simple_error ("Image instances not allowed here", data);
1360 image_validate (data); 1099 image_validate (data);
1361 domain = decode_domain (domain);
1362 /* instantiate_image_instantiator() will abort if given an
1363 image instance ... */
1364 dest_mask = decode_image_instance_type_list (dest_types); 1100 dest_mask = decode_image_instance_type_list (dest_types);
1365 data = normalize_image_instantiator (data, 1101 data = normalize_image_instantiator (data, DEVICE_TYPE (XDEVICE (device)),
1366 DEVICE_TYPE (DOMAIN_XDEVICE (domain)),
1367 make_int (dest_mask)); 1102 make_int (dest_mask));
1368 GCPRO1 (data); 1103 GCPRO1 (data);
1369 /* After normalizing the data, it's always either an image instance (which 1104 if (VECTORP (data) && EQ (XVECTOR_DATA (data)[0], Qinherit))
1370 we filtered out above) or a vector. */
1371 if (EQ (XVECTOR_DATA (data)[0], Qinherit))
1372 signal_simple_error ("Inheritance not allowed here", data); 1105 signal_simple_error ("Inheritance not allowed here", data);
1373 governing_domain = 1106 ii = instantiate_image_instantiator (device, device, data,
1374 get_image_instantiator_governing_domain (data, domain); 1107 Qnil, Qnil, dest_mask);
1375 ii = instantiate_image_instantiator (governing_domain, domain, data,
1376 Qnil, Qnil, dest_mask, Qnil);
1377 RETURN_UNGCPRO (ii); 1108 RETURN_UNGCPRO (ii);
1378 } 1109 }
1379 1110
1380 DEFUN ("make-image-instance", Fmake_image_instance, 1, 4, 0, /* 1111 DEFUN ("make-image-instance", Fmake_image_instance, 1, 4, 0, /*
1381 Return a new `image-instance' object. 1112 Return a new `image-instance' object.
1385 do not need to directly create image instances; use a glyph instead. 1116 do not need to directly create image instances; use a glyph instead.
1386 However, it may occasionally be useful to explicitly create image 1117 However, it may occasionally be useful to explicitly create image
1387 instances, if you want more control over the instantiation process. 1118 instances, if you want more control over the instantiation process.
1388 1119
1389 DATA is an image instantiator, which describes the image; see 1120 DATA is an image instantiator, which describes the image; see
1390 `make-image-specifier' for a description of the allowed values. 1121 `image-specifier-p' for a description of the allowed values.
1391 1122
1392 DEST-TYPES should be a list of allowed image instance types that can 1123 DEST-TYPES should be a list of allowed image instance types that can
1393 be generated. The recognized image instance types are 1124 be generated. The recognized image instance types are
1394 1125
1395 'nothing 1126 'nothing
1410 'pointer 1141 'pointer
1411 Used as the mouse pointer for a window. 1142 Used as the mouse pointer for a window.
1412 'subwindow 1143 'subwindow
1413 A child window that is treated as an image. This allows (e.g.) 1144 A child window that is treated as an image. This allows (e.g.)
1414 another program to be responsible for drawing into the window. 1145 another program to be responsible for drawing into the window.
1415 'widget 1146 Not currently implemented.
1416 A child window that contains a window-system widget, e.g. a push 1147
1417 button, text field, or slider. 1148 The DEST-TYPES list is unordered. If multiple destination types
1418 1149 are possible for a given instantiator, the "most natural" type
1419 The DEST-TYPES list is unordered. If multiple destination types are 1150 for the instantiator's format is chosen. (For XBM, the most natural
1420 possible for a given instantiator, the "most natural" type for the 1151 types are `mono-pixmap', followed by `color-pixmap', followed by
1421 instantiator's format is chosen. (For XBM, the most natural types are 1152 `pointer'. For the other normal image formats, the most natural
1422 `mono-pixmap', followed by `color-pixmap', followed by `pointer'. For 1153 types are `color-pixmap', followed by `mono-pixmap', followed by
1423 the other normal image formats, the most natural types are 1154 `pointer'. For the string and formatted-string formats, the most
1424 `color-pixmap', followed by `mono-pixmap', followed by `pointer'. For 1155 natural types are `text', followed by `mono-pixmap' (not currently
1425 the string and formatted-string formats, the most natural types are 1156 implemented), followed by `color-pixmap' (not currently implemented).
1426 `text', followed by `mono-pixmap' (not currently implemented), 1157 The other formats can only be instantiated as one type. (If you
1427 followed by `color-pixmap' (not currently implemented). For MS 1158 want to control more specifically the order of the types into which
1428 Windows resources, the most natural type for pointer resources is 1159 an image is instantiated, just call `make-image-instance' repeatedly
1429 `pointer', and for the others it's `color-pixmap'. The other formats 1160 until it succeeds, passing less and less preferred destination types
1430 can only be instantiated as one type. (If you want to control more 1161 each time.
1431 specifically the order of the types into which an image is
1432 instantiated, just call `make-image-instance' repeatedly until it
1433 succeeds, passing less and less preferred destination types each
1434 time.)
1435
1436 See `make-image-specifier' for a description of the different image
1437 instantiator formats.
1438 1162
1439 If DEST-TYPES is omitted, all possible types are allowed. 1163 If DEST-TYPES is omitted, all possible types are allowed.
1440
1441 DOMAIN specifies the domain to which the image instance will be attached.
1442 This domain is termed the \"governing domain\". The type of the governing
1443 domain depends on the image instantiator format. (Although, more correctly,
1444 it should probably depend on the image instance type.) For example, pixmap
1445 image instances are specific to a device, but widget image instances are
1446 specific to a particular XEmacs window because in order to display such a
1447 widget when two windows onto the same buffer want to display the widget,
1448 two separate underlying widgets must be created. (That's because a widget
1449 is actually a child window-system window, and all window-system windows have
1450 a unique existence on the screen.) This means that the governing domain for
1451 a pixmap image instance will be some device (most likely, the only existing
1452 device), whereas the governing domain for a widget image instance will be
1453 some XEmacs window.
1454
1455 If you specify an overly general DOMAIN (e.g. a frame when a window was
1456 wanted), an error is signaled. If you specify an overly specific DOMAIN
1457 \(e.g. a window when a device was wanted), the corresponding general domain
1458 is fetched and used instead. For `make-image-instance', it makes no
1459 difference whether you specify an overly specific domain or the properly
1460 general domain derived from it. However, it does matter when creating an
1461 image instance by instantiating a specifier or glyph (e.g. with
1462 `glyph-image-instance'), because the more specific domain causes spec lookup
1463 to start there and proceed to more general domains. (It would also matter
1464 when creating an image instance with an instantiator format of `inherit',
1465 but we currently disallow this. #### We should fix this.)
1466
1467 If omitted, DOMAIN defaults to the selected window.
1468 1164
1469 NO-ERROR controls what happens when the image cannot be generated. 1165 NO-ERROR controls what happens when the image cannot be generated.
1470 If nil, an error message is generated. If t, no messages are 1166 If nil, an error message is generated. If t, no messages are
1471 generated and this function returns nil. If anything else, a warning 1167 generated and this function returns nil. If anything else, a warning
1472 message is generated and this function returns nil. 1168 message is generated and this function returns nil.
1473 */ 1169 */
1474 (data, domain, dest_types, no_error)) 1170 (data, device, dest_types, no_error))
1475 { 1171 {
1476 Error_behavior errb = decode_error_behavior_flag (no_error); 1172 Error_behavior errb = decode_error_behavior_flag (no_error);
1477 1173
1478 return call_with_suspended_errors ((lisp_fn_t) make_image_instance_1, 1174 return call_with_suspended_errors ((lisp_fn_t) make_image_instance_1,
1479 Qnil, Qimage, errb, 1175 Qnil, Qimage, errb,
1480 3, data, domain, dest_types); 1176 3, data, device, dest_types);
1481 } 1177 }
1482 1178
1483 DEFUN ("image-instance-p", Fimage_instance_p, 1, 1, 0, /* 1179 DEFUN ("image-instance-p", Fimage_instance_p, 1, 1, 0, /*
1484 Return non-nil if OBJECT is an image instance. 1180 Return non-nil if OBJECT is an image instance.
1485 */ 1181 */
1494 'color-pixmap, 'pointer, or 'subwindow. 1190 'color-pixmap, 'pointer, or 'subwindow.
1495 */ 1191 */
1496 (image_instance)) 1192 (image_instance))
1497 { 1193 {
1498 CHECK_IMAGE_INSTANCE (image_instance); 1194 CHECK_IMAGE_INSTANCE (image_instance);
1499 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1500 return encode_image_instance_type (XIMAGE_INSTANCE_TYPE (image_instance)); 1195 return encode_image_instance_type (XIMAGE_INSTANCE_TYPE (image_instance));
1501 } 1196 }
1502 1197
1503 DEFUN ("image-instance-name", Fimage_instance_name, 1, 1, 0, /* 1198 DEFUN ("image-instance-name", Fimage_instance_name, 1, 1, 0, /*
1504 Return the name of the given image instance. 1199 Return the name of the given image instance.
1505 */ 1200 */
1506 (image_instance)) 1201 (image_instance))
1507 { 1202 {
1508 CHECK_IMAGE_INSTANCE (image_instance); 1203 CHECK_IMAGE_INSTANCE (image_instance);
1509 return XIMAGE_INSTANCE_NAME (image_instance); 1204 return XIMAGE_INSTANCE_NAME (image_instance);
1510 }
1511
1512 DEFUN ("image-instance-domain", Fimage_instance_domain, 1, 1, 0, /*
1513 Return the governing domain of the given image instance.
1514 The governing domain of an image instance is the domain that the image
1515 instance is specific to. It is NOT necessarily the domain that was
1516 given to the call to `specifier-instance' that resulted in the creation
1517 of this image instance. See `make-image-instance' for more information
1518 on governing domains.
1519 */
1520 (image_instance))
1521 {
1522 CHECK_IMAGE_INSTANCE (image_instance);
1523 return XIMAGE_INSTANCE_DOMAIN (image_instance);
1524 } 1205 }
1525 1206
1526 DEFUN ("image-instance-string", Fimage_instance_string, 1, 1, 0, /* 1207 DEFUN ("image-instance-string", Fimage_instance_string, 1, 1, 0, /*
1527 Return the string of the given image instance. 1208 Return the string of the given image instance.
1528 This will only be non-nil for text image instances and widgets. 1209 This will only be non-nil for text image instances and widgets.
1537 else 1218 else
1538 return Qnil; 1219 return Qnil;
1539 } 1220 }
1540 1221
1541 DEFUN ("image-instance-property", Fimage_instance_property, 2, 2, 0, /* 1222 DEFUN ("image-instance-property", Fimage_instance_property, 2, 2, 0, /*
1542 Return the given property of the given image instance. 1223 Return the given property of the given image instance.
1543 Returns nil if the property or the property method do not exist for 1224 Returns nil if the property or the property method do not exist for
1544 the image instance in the domain. 1225 the image instance in the domain.
1545 */ 1226 */
1546 (image_instance, prop)) 1227 (image_instance, prop))
1547 { 1228 {
1548 Lisp_Image_Instance* ii; 1229 struct Lisp_Image_Instance* ii;
1549 Lisp_Object type, ret; 1230 Lisp_Object type, ret;
1550 struct image_instantiator_methods* meths; 1231 struct image_instantiator_methods* meths;
1551 1232
1552 CHECK_IMAGE_INSTANCE (image_instance); 1233 CHECK_IMAGE_INSTANCE (image_instance);
1553 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1554 CHECK_SYMBOL (prop); 1234 CHECK_SYMBOL (prop);
1555 ii = XIMAGE_INSTANCE (image_instance); 1235 ii = XIMAGE_INSTANCE (image_instance);
1556 1236
1557 /* ... then try device specific methods ... */ 1237 /* ... then try device specific methods ... */
1558 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); 1238 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
1559 meths = decode_device_ii_format (image_instance_device (image_instance), 1239 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii),
1560 type, ERROR_ME_NOT); 1240 type, ERROR_ME_NOT);
1561 if (meths && HAS_IIFORMAT_METH_P (meths, property) 1241 if (meths && HAS_IIFORMAT_METH_P (meths, property)
1562 && 1242 &&
1563 !UNBOUNDP (ret = IIFORMAT_METH (meths, property, (image_instance, prop)))) 1243 !UNBOUNDP (ret = IIFORMAT_METH (meths, property, (image_instance, prop))))
1564 { 1244 {
1565 return ret; 1245 return ret;
1566 } 1246 }
1567 /* ... then format specific methods ... */ 1247 /* ... then format specific methods ... */
1575 /* ... then fail */ 1255 /* ... then fail */
1576 return Qnil; 1256 return Qnil;
1577 } 1257 }
1578 1258
1579 DEFUN ("set-image-instance-property", Fset_image_instance_property, 3, 3, 0, /* 1259 DEFUN ("set-image-instance-property", Fset_image_instance_property, 3, 3, 0, /*
1580 Set the given property of the given image instance. 1260 Set the given property of the given image instance.
1581 Does nothing if the property or the property method do not exist for 1261 Does nothing if the property or the property method do not exist for
1582 the image instance in the domain. 1262 the image instance in the domain.
1583 1263 */
1584 WARNING: If you are thinking about using this function, think again.
1585 You probably want to be using `set-glyph-image' to change the glyph's
1586 specifier. Be especially wary if you are thinking of calling this
1587 function after having called `glyph-image-instance'. Unless you are
1588 absolutely sure what you're doing, pretty much the only legitimate
1589 uses for this function are setting user-specified info in a widget,
1590 such as text in a text field. */
1591 (image_instance, prop, val)) 1264 (image_instance, prop, val))
1592 { 1265 {
1593 Lisp_Image_Instance* ii; 1266 struct Lisp_Image_Instance* ii;
1594 Lisp_Object type, ret; 1267 Lisp_Object type, ret;
1595 struct image_instantiator_methods* meths; 1268 struct image_instantiator_methods* meths;
1596 1269
1597 CHECK_IMAGE_INSTANCE (image_instance); 1270 CHECK_IMAGE_INSTANCE (image_instance);
1598 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1599 CHECK_SYMBOL (prop); 1271 CHECK_SYMBOL (prop);
1600 ii = XIMAGE_INSTANCE (image_instance); 1272 ii = XIMAGE_INSTANCE (image_instance);
1601 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); 1273 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
1602 /* try device specific methods first ... */ 1274 /* try device specific methods first ... */
1603 meths = decode_device_ii_format (image_instance_device (image_instance), 1275 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii),
1604 type, ERROR_ME_NOT); 1276 type, ERROR_ME_NOT);
1605 if (meths && HAS_IIFORMAT_METH_P (meths, set_property) 1277 if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
1606 && 1278 &&
1607 !UNBOUNDP (ret = 1279 !UNBOUNDP (ret =
1608 IIFORMAT_METH (meths, set_property, (image_instance, prop, val)))) 1280 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
1609 { 1281 {
1610 val = ret; 1282 return ret;
1611 } 1283 }
1612 else 1284 /* ... then format specific methods ... */
1613 { 1285 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
1614 /* ... then format specific methods ... */ 1286 if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
1615 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); 1287 &&
1616 if (meths && HAS_IIFORMAT_METH_P (meths, set_property) 1288 !UNBOUNDP (ret =
1617 && 1289 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
1618 !UNBOUNDP (ret = 1290 {
1619 IIFORMAT_METH (meths, set_property, (image_instance, prop, val)))) 1291 return ret;
1620 { 1292 }
1621 val = ret;
1622 }
1623 else
1624 {
1625 val = Qnil;
1626 }
1627 }
1628
1629 /* Make sure the image instance gets redisplayed. */
1630 set_image_instance_dirty_p (image_instance, 1);
1631 /* Force the glyph to be laid out again. */
1632 IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 1;
1633
1634 MARK_SUBWINDOWS_STATE_CHANGED;
1635 MARK_GLYPHS_CHANGED;
1636 1293
1637 return val; 1294 return val;
1638 } 1295 }
1639 1296
1640 DEFUN ("image-instance-file-name", Fimage_instance_file_name, 1, 1, 0, /* 1297 DEFUN ("image-instance-file-name", Fimage_instance_file_name, 1, 1, 0, /*
1641 Return the file name from which IMAGE-INSTANCE was read, if known. 1298 Return the file name from which IMAGE-INSTANCE was read, if known.
1642 */ 1299 */
1643 (image_instance)) 1300 (image_instance))
1644 { 1301 {
1645 CHECK_IMAGE_INSTANCE (image_instance); 1302 CHECK_IMAGE_INSTANCE (image_instance);
1646 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1647 1303
1648 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1304 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1649 { 1305 {
1650 case IMAGE_MONO_PIXMAP: 1306 case IMAGE_MONO_PIXMAP:
1651 case IMAGE_COLOR_PIXMAP: 1307 case IMAGE_COLOR_PIXMAP:
1661 Return the file name from which IMAGE-INSTANCE's mask was read, if known. 1317 Return the file name from which IMAGE-INSTANCE's mask was read, if known.
1662 */ 1318 */
1663 (image_instance)) 1319 (image_instance))
1664 { 1320 {
1665 CHECK_IMAGE_INSTANCE (image_instance); 1321 CHECK_IMAGE_INSTANCE (image_instance);
1666 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1667 1322
1668 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1323 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1669 { 1324 {
1670 case IMAGE_MONO_PIXMAP: 1325 case IMAGE_MONO_PIXMAP:
1671 case IMAGE_COLOR_PIXMAP: 1326 case IMAGE_COLOR_PIXMAP:
1682 This is 0 for a bitmap, or a positive integer for a pixmap. 1337 This is 0 for a bitmap, or a positive integer for a pixmap.
1683 */ 1338 */
1684 (image_instance)) 1339 (image_instance))
1685 { 1340 {
1686 CHECK_IMAGE_INSTANCE (image_instance); 1341 CHECK_IMAGE_INSTANCE (image_instance);
1687 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1688 1342
1689 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1343 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1690 { 1344 {
1691 case IMAGE_MONO_PIXMAP: 1345 case IMAGE_MONO_PIXMAP:
1692 case IMAGE_COLOR_PIXMAP: 1346 case IMAGE_COLOR_PIXMAP:
1702 Return the height of the image instance, in pixels. 1356 Return the height of the image instance, in pixels.
1703 */ 1357 */
1704 (image_instance)) 1358 (image_instance))
1705 { 1359 {
1706 CHECK_IMAGE_INSTANCE (image_instance); 1360 CHECK_IMAGE_INSTANCE (image_instance);
1707 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1708 1361
1709 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1362 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1710 { 1363 {
1711 case IMAGE_MONO_PIXMAP: 1364 case IMAGE_MONO_PIXMAP:
1712 case IMAGE_COLOR_PIXMAP: 1365 case IMAGE_COLOR_PIXMAP:
1713 case IMAGE_POINTER: 1366 case IMAGE_POINTER:
1367 return make_int (XIMAGE_INSTANCE_PIXMAP_HEIGHT (image_instance));
1368
1714 case IMAGE_SUBWINDOW: 1369 case IMAGE_SUBWINDOW:
1715 case IMAGE_WIDGET: 1370 case IMAGE_WIDGET:
1716 return make_int (XIMAGE_INSTANCE_HEIGHT (image_instance)); 1371 return make_int (XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (image_instance));
1717 1372
1718 default: 1373 default:
1719 return Qnil; 1374 return Qnil;
1720 } 1375 }
1721 } 1376 }
1724 Return the width of the image instance, in pixels. 1379 Return the width of the image instance, in pixels.
1725 */ 1380 */
1726 (image_instance)) 1381 (image_instance))
1727 { 1382 {
1728 CHECK_IMAGE_INSTANCE (image_instance); 1383 CHECK_IMAGE_INSTANCE (image_instance);
1729 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1730 1384
1731 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1385 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1732 { 1386 {
1733 case IMAGE_MONO_PIXMAP: 1387 case IMAGE_MONO_PIXMAP:
1734 case IMAGE_COLOR_PIXMAP: 1388 case IMAGE_COLOR_PIXMAP:
1735 case IMAGE_POINTER: 1389 case IMAGE_POINTER:
1390 return make_int (XIMAGE_INSTANCE_PIXMAP_WIDTH (image_instance));
1391
1736 case IMAGE_SUBWINDOW: 1392 case IMAGE_SUBWINDOW:
1737 case IMAGE_WIDGET: 1393 case IMAGE_WIDGET:
1738 return make_int (XIMAGE_INSTANCE_WIDTH (image_instance)); 1394 return make_int (XIMAGE_INSTANCE_SUBWINDOW_WIDTH (image_instance));
1739 1395
1740 default: 1396 default:
1741 return Qnil; 1397 return Qnil;
1742 } 1398 }
1743 } 1399 }
1751 This will always be nil for a non-pointer image instance. 1407 This will always be nil for a non-pointer image instance.
1752 */ 1408 */
1753 (image_instance)) 1409 (image_instance))
1754 { 1410 {
1755 CHECK_IMAGE_INSTANCE (image_instance); 1411 CHECK_IMAGE_INSTANCE (image_instance);
1756 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1757 1412
1758 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1413 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1759 { 1414 {
1760 case IMAGE_MONO_PIXMAP: 1415 case IMAGE_MONO_PIXMAP:
1761 case IMAGE_COLOR_PIXMAP: 1416 case IMAGE_COLOR_PIXMAP:
1776 This will always be nil for a non-pointer image instance. 1431 This will always be nil for a non-pointer image instance.
1777 */ 1432 */
1778 (image_instance)) 1433 (image_instance))
1779 { 1434 {
1780 CHECK_IMAGE_INSTANCE (image_instance); 1435 CHECK_IMAGE_INSTANCE (image_instance);
1781 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1782 1436
1783 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1437 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1784 { 1438 {
1785 case IMAGE_MONO_PIXMAP: 1439 case IMAGE_MONO_PIXMAP:
1786 case IMAGE_COLOR_PIXMAP: 1440 case IMAGE_COLOR_PIXMAP:
1798 colorized mono pixmaps and for pointers.) 1452 colorized mono pixmaps and for pointers.)
1799 */ 1453 */
1800 (image_instance)) 1454 (image_instance))
1801 { 1455 {
1802 CHECK_IMAGE_INSTANCE (image_instance); 1456 CHECK_IMAGE_INSTANCE (image_instance);
1803 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1804 1457
1805 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1458 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1806 { 1459 {
1807 case IMAGE_MONO_PIXMAP: 1460 case IMAGE_MONO_PIXMAP:
1808 case IMAGE_COLOR_PIXMAP: 1461 case IMAGE_COLOR_PIXMAP:
1810 return XIMAGE_INSTANCE_PIXMAP_FG (image_instance); 1463 return XIMAGE_INSTANCE_PIXMAP_FG (image_instance);
1811 1464
1812 case IMAGE_WIDGET: 1465 case IMAGE_WIDGET:
1813 return FACE_FOREGROUND ( 1466 return FACE_FOREGROUND (
1814 XIMAGE_INSTANCE_WIDGET_FACE (image_instance), 1467 XIMAGE_INSTANCE_WIDGET_FACE (image_instance),
1815 XIMAGE_INSTANCE_FRAME 1468 XIMAGE_INSTANCE_SUBWINDOW_FRAME
1816 (image_instance)); 1469 (image_instance));
1817 1470
1818 default: 1471 default:
1819 return Qnil; 1472 return Qnil;
1820 } 1473 }
1826 colorized mono pixmaps and for pointers.) 1479 colorized mono pixmaps and for pointers.)
1827 */ 1480 */
1828 (image_instance)) 1481 (image_instance))
1829 { 1482 {
1830 CHECK_IMAGE_INSTANCE (image_instance); 1483 CHECK_IMAGE_INSTANCE (image_instance);
1831 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1832 1484
1833 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1485 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1834 { 1486 {
1835 case IMAGE_MONO_PIXMAP: 1487 case IMAGE_MONO_PIXMAP:
1836 case IMAGE_COLOR_PIXMAP: 1488 case IMAGE_COLOR_PIXMAP:
1838 return XIMAGE_INSTANCE_PIXMAP_BG (image_instance); 1490 return XIMAGE_INSTANCE_PIXMAP_BG (image_instance);
1839 1491
1840 case IMAGE_WIDGET: 1492 case IMAGE_WIDGET:
1841 return FACE_BACKGROUND ( 1493 return FACE_BACKGROUND (
1842 XIMAGE_INSTANCE_WIDGET_FACE (image_instance), 1494 XIMAGE_INSTANCE_WIDGET_FACE (image_instance),
1843 XIMAGE_INSTANCE_FRAME 1495 XIMAGE_INSTANCE_SUBWINDOW_FRAME
1844 (image_instance)); 1496 (image_instance));
1845 1497
1846 default: 1498 default:
1847 return Qnil; 1499 return Qnil;
1848 } 1500 }
1860 { 1512 {
1861 Lisp_Object new; 1513 Lisp_Object new;
1862 Lisp_Object device; 1514 Lisp_Object device;
1863 1515
1864 CHECK_IMAGE_INSTANCE (image_instance); 1516 CHECK_IMAGE_INSTANCE (image_instance);
1865 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1866 CHECK_COLOR_INSTANCE (foreground); 1517 CHECK_COLOR_INSTANCE (foreground);
1867 CHECK_COLOR_INSTANCE (background); 1518 CHECK_COLOR_INSTANCE (background);
1868 1519
1869 device = image_instance_device (image_instance); 1520 device = XIMAGE_INSTANCE_DEVICE (image_instance);
1870 if (!HAS_DEVMETH_P (XDEVICE (device), colorize_image_instance)) 1521 if (!HAS_DEVMETH_P (XDEVICE (device), colorize_image_instance))
1871 return image_instance; 1522 return image_instance;
1872 1523
1873 /* #### There should be a copy_image_instance(), which calls a 1524 new = allocate_image_instance (device);
1874 device-specific method to copy the window-system subobject. */
1875 new = allocate_image_instance (XIMAGE_INSTANCE_DOMAIN (image_instance),
1876 Qnil);
1877 copy_lcrecord (XIMAGE_INSTANCE (new), XIMAGE_INSTANCE (image_instance)); 1525 copy_lcrecord (XIMAGE_INSTANCE (new), XIMAGE_INSTANCE (image_instance));
1878 /* note that if this method returns non-zero, this method MUST 1526 /* note that if this method returns non-zero, this method MUST
1879 copy any window-system resources, so that when one image instance is 1527 copy any window-system resources, so that when one image instance is
1880 freed, the other one is not hosed. */ 1528 freed, the other one is not hosed. */
1881 if (!DEVMETH (XDEVICE (device), colorize_image_instance, (new, foreground, 1529 if (!DEVMETH (XDEVICE (device), colorize_image_instance, (new, foreground,
1882 background))) 1530 background)))
1883 return image_instance; 1531 return image_instance;
1884 return new; 1532 return new;
1885 } 1533 }
1886 1534
1887
1888 /************************************************************************/
1889 /* Geometry calculations */
1890 /************************************************************************/
1891
1892 /* Find out desired geometry of the image instance. If there is no
1893 special function then just return the width and / or height. */
1894 void
1895 image_instance_query_geometry (Lisp_Object image_instance,
1896 int* width, int* height,
1897 enum image_instance_geometry disp,
1898 Lisp_Object domain)
1899 {
1900 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
1901 Lisp_Object type;
1902 struct image_instantiator_methods* meths;
1903 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1904
1905 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
1906 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
1907
1908 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry))
1909 {
1910 IIFORMAT_METH (meths, query_geometry, (image_instance, width, height,
1911 disp, domain));
1912 }
1913 else
1914 {
1915 if (width)
1916 *width = IMAGE_INSTANCE_WIDTH (ii);
1917 if (height)
1918 *height = IMAGE_INSTANCE_HEIGHT (ii);
1919 }
1920 }
1921
1922 /* Layout the image instance using the provided dimensions. Layout
1923 widgets are going to do different kinds of calculations to
1924 determine what size to give things so we could make the layout
1925 function relatively simple to take account of that. An alternative
1926 approach is to consider separately the two cases, one where you
1927 don't mind what size you have (normal widgets) and one where you
1928 want to specifiy something (layout widgets). */
1929 void
1930 image_instance_layout (Lisp_Object image_instance,
1931 int width, int height, Lisp_Object domain)
1932 {
1933 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
1934 Lisp_Object type;
1935 struct image_instantiator_methods* meths;
1936
1937 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1938
1939 /* Nothing is as nothing does. */
1940 if (NOTHING_IMAGE_INSTANCEP (image_instance))
1941 return;
1942
1943 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
1944 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
1945
1946 /* If geometry is unspecified then get some reasonable values for it. */
1947 if (width == IMAGE_UNSPECIFIED_GEOMETRY
1948 ||
1949 height == IMAGE_UNSPECIFIED_GEOMETRY)
1950 {
1951 int dwidth = IMAGE_UNSPECIFIED_GEOMETRY;
1952 int dheight = IMAGE_UNSPECIFIED_GEOMETRY;
1953
1954 /* Get the desired geometry. */
1955 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry))
1956 {
1957 IIFORMAT_METH (meths, query_geometry, (image_instance, &dwidth, &dheight,
1958 IMAGE_DESIRED_GEOMETRY,
1959 domain));
1960 }
1961 else
1962 {
1963 dwidth = IMAGE_INSTANCE_WIDTH (ii);
1964 dheight = IMAGE_INSTANCE_HEIGHT (ii);
1965 }
1966
1967 /* Compare with allowed geometry. */
1968 if (width == IMAGE_UNSPECIFIED_GEOMETRY)
1969 width = dwidth;
1970 if (height == IMAGE_UNSPECIFIED_GEOMETRY)
1971 height = dheight;
1972 }
1973
1974 /* If we don't have sane values then we cannot layout at this point and
1975 must just return. */
1976 if (width == IMAGE_UNSPECIFIED_GEOMETRY
1977 ||
1978 height == IMAGE_UNSPECIFIED_GEOMETRY)
1979 return;
1980
1981 /* At this point width and height should contain sane values. Thus
1982 we set the glyph geometry and lay it out. */
1983 if (IMAGE_INSTANCE_WIDTH (ii) != width
1984 ||
1985 IMAGE_INSTANCE_HEIGHT (ii) != height)
1986 {
1987 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 1;
1988 }
1989
1990 IMAGE_INSTANCE_WIDTH (ii) = width;
1991 IMAGE_INSTANCE_HEIGHT (ii) = height;
1992
1993 if (IIFORMAT_METH_OR_GIVEN (meths, layout,
1994 (image_instance, width, height, domain), 1))
1995 /* Do not clear the dirty flag here - redisplay will do this for
1996 us at the end. */
1997 IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 0;
1998 }
1999
2000 /*
2001 * Mark image instance in W as dirty if (a) W's faces have changed and
2002 * (b) GLYPH_OR_II instance in W is a string.
2003 *
2004 * Return non-zero if instance has been marked dirty.
2005 */
2006 int
2007 invalidate_glyph_geometry_maybe (Lisp_Object glyph_or_ii, struct window* w)
2008 {
2009 if (XFRAME(WINDOW_FRAME(w))->faces_changed)
2010 {
2011 Lisp_Object image = glyph_or_ii;
2012
2013 if (GLYPHP (glyph_or_ii))
2014 {
2015 Lisp_Object window;
2016 XSETWINDOW (window, w);
2017 image = glyph_image_instance (glyph_or_ii, window, ERROR_ME_NOT, 1);
2018 }
2019
2020 if (TEXT_IMAGE_INSTANCEP (image))
2021 {
2022 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image);
2023 IMAGE_INSTANCE_DIRTYP (ii) = 1;
2024 IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 1;
2025 if (GLYPHP (glyph_or_ii))
2026 XGLYPH_DIRTYP (glyph_or_ii) = 1;
2027 return 1;
2028 }
2029 }
2030
2031 return 0;
2032 }
2033
2034 1535
2035 /************************************************************************/ 1536 /************************************************************************/
2036 /* error helpers */ 1537 /* error helpers */
2037 /************************************************************************/ 1538 /************************************************************************/
2038 DOESNT_RETURN 1539 DOESNT_RETURN
2039 signal_image_error (const char *reason, Lisp_Object frob) 1540 signal_image_error (CONST char *reason, Lisp_Object frob)
2040 { 1541 {
2041 signal_error (Qimage_conversion_error, 1542 signal_error (Qimage_conversion_error,
2042 list2 (build_translated_string (reason), frob)); 1543 list2 (build_translated_string (reason), frob));
2043 } 1544 }
2044 1545
2045 DOESNT_RETURN 1546 DOESNT_RETURN
2046 signal_image_error_2 (const char *reason, Lisp_Object frob0, Lisp_Object frob1) 1547 signal_image_error_2 (CONST char *reason, Lisp_Object frob0, Lisp_Object frob1)
2047 { 1548 {
2048 signal_error (Qimage_conversion_error, 1549 signal_error (Qimage_conversion_error,
2049 list3 (build_translated_string (reason), frob0, frob1)); 1550 list3 (build_translated_string (reason), frob0, frob1));
2050 } 1551 }
2051 1552
2062 static void 1563 static void
2063 nothing_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, 1564 nothing_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2064 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 1565 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2065 int dest_mask, Lisp_Object domain) 1566 int dest_mask, Lisp_Object domain)
2066 { 1567 {
2067 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 1568 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2068 1569
2069 if (dest_mask & IMAGE_NOTHING_MASK) 1570 if (dest_mask & IMAGE_NOTHING_MASK)
2070 { 1571 IMAGE_INSTANCE_TYPE (ii) = IMAGE_NOTHING;
2071 IMAGE_INSTANCE_TYPE (ii) = IMAGE_NOTHING;
2072 IMAGE_INSTANCE_HEIGHT (ii) = 0;
2073 IMAGE_INSTANCE_WIDTH (ii) = 0;
2074 }
2075 else 1572 else
2076 incompatible_image_types (instantiator, dest_mask, IMAGE_NOTHING_MASK); 1573 incompatible_image_types (instantiator, dest_mask, IMAGE_NOTHING_MASK);
2077 } 1574 }
2078 1575
2079 1576
2129 string_possible_dest_types (void) 1626 string_possible_dest_types (void)
2130 { 1627 {
2131 return IMAGE_TEXT_MASK; 1628 return IMAGE_TEXT_MASK;
2132 } 1629 }
2133 1630
2134 /* Called from autodetect_instantiate() */ 1631 /* called from autodetect_instantiate() */
2135 void 1632 void
2136 string_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, 1633 string_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2137 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 1634 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2138 int dest_mask, Lisp_Object domain) 1635 int dest_mask, Lisp_Object domain)
2139 { 1636 {
2140 Lisp_Object string = find_keyword_in_vector (instantiator, Q_data); 1637 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
2141 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 1638 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2142 1639
2143 /* Should never get here with a domain other than a window. */ 1640 assert (!NILP (data));
2144 assert (!NILP (string) && WINDOWP (DOMAIN_WINDOW (domain)));
2145 if (dest_mask & IMAGE_TEXT_MASK) 1641 if (dest_mask & IMAGE_TEXT_MASK)
2146 { 1642 {
2147 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT; 1643 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT;
2148 IMAGE_INSTANCE_TEXT_STRING (ii) = string; 1644 IMAGE_INSTANCE_TEXT_STRING (ii) = data;
2149 } 1645 }
2150 else 1646 else
2151 incompatible_image_types (instantiator, dest_mask, IMAGE_TEXT_MASK); 1647 incompatible_image_types (instantiator, dest_mask, IMAGE_TEXT_MASK);
2152 }
2153
2154 /* Sort out the size of the text that is being displayed. Calculating
2155 it dynamically allows us to change the text and still see
2156 everything. Note that the following methods are for text not string
2157 since that is what the instantiated type is. The first method is a
2158 helper that is used elsewhere for calculating text geometry. */
2159 void
2160 query_string_geometry (Lisp_Object string, Lisp_Object face,
2161 int* width, int* height, int* descent, Lisp_Object domain)
2162 {
2163 struct font_metric_info fm;
2164 unsigned char charsets[NUM_LEADING_BYTES];
2165 struct face_cachel frame_cachel;
2166 struct face_cachel *cachel;
2167 Lisp_Object frame = DOMAIN_FRAME (domain);
2168
2169 /* Compute height */
2170 if (height)
2171 {
2172 /* Compute string metric info */
2173 find_charsets_in_bufbyte_string (charsets,
2174 XSTRING_DATA (string),
2175 XSTRING_LENGTH (string));
2176
2177 /* Fallback to the default face if none was provided. */
2178 if (!NILP (face))
2179 {
2180 reset_face_cachel (&frame_cachel);
2181 update_face_cachel_data (&frame_cachel, frame, face);
2182 cachel = &frame_cachel;
2183 }
2184 else
2185 {
2186 cachel = WINDOW_FACE_CACHEL (DOMAIN_XWINDOW (domain),
2187 DEFAULT_INDEX);
2188 }
2189
2190 ensure_face_cachel_complete (cachel, domain, charsets);
2191 face_cachel_charset_font_metric_info (cachel, charsets, &fm);
2192
2193 *height = fm.ascent + fm.descent;
2194 /* #### descent only gets set if we query the height as well. */
2195 if (descent)
2196 *descent = fm.descent;
2197 }
2198
2199 /* Compute width */
2200 if (width)
2201 {
2202 if (!NILP (face))
2203 *width = redisplay_frame_text_width_string (XFRAME (frame),
2204 face,
2205 0, string, 0, -1);
2206 else
2207 *width = redisplay_frame_text_width_string (XFRAME (frame),
2208 Vdefault_face,
2209 0, string, 0, -1);
2210 }
2211 }
2212
2213 Lisp_Object
2214 query_string_font (Lisp_Object string, Lisp_Object face, Lisp_Object domain)
2215 {
2216 unsigned char charsets[NUM_LEADING_BYTES];
2217 struct face_cachel frame_cachel;
2218 struct face_cachel *cachel;
2219 int i;
2220 Lisp_Object frame = DOMAIN_FRAME (domain);
2221
2222 /* Compute string font info */
2223 find_charsets_in_bufbyte_string (charsets,
2224 XSTRING_DATA (string),
2225 XSTRING_LENGTH (string));
2226
2227 reset_face_cachel (&frame_cachel);
2228 update_face_cachel_data (&frame_cachel, frame, face);
2229 cachel = &frame_cachel;
2230
2231 ensure_face_cachel_complete (cachel, domain, charsets);
2232
2233 for (i = 0; i < NUM_LEADING_BYTES; i++)
2234 {
2235 if (charsets[i])
2236 {
2237 return FACE_CACHEL_FONT (cachel,
2238 CHARSET_BY_LEADING_BYTE (i +
2239 MIN_LEADING_BYTE));
2240
2241 }
2242 }
2243
2244 return Qnil; /* NOT REACHED */
2245 }
2246
2247 static void
2248 text_query_geometry (Lisp_Object image_instance,
2249 int* width, int* height,
2250 enum image_instance_geometry disp, Lisp_Object domain)
2251 {
2252 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2253 int descent = 0;
2254
2255 query_string_geometry (IMAGE_INSTANCE_TEXT_STRING (ii),
2256 IMAGE_INSTANCE_FACE (ii),
2257 width, height, &descent, domain);
2258
2259 /* The descent gets set as a side effect of querying the
2260 geometry. */
2261 IMAGE_INSTANCE_TEXT_DESCENT (ii) = descent;
2262 }
2263
2264 /* set the properties of a string */
2265 static Lisp_Object
2266 text_set_property (Lisp_Object image_instance, Lisp_Object prop,
2267 Lisp_Object val)
2268 {
2269 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2270
2271 if (EQ (prop, Q_data))
2272 {
2273 CHECK_STRING (val);
2274 IMAGE_INSTANCE_TEXT_STRING (ii) = val;
2275
2276 return Qt;
2277 }
2278 return Qunbound;
2279 } 1648 }
2280 1649
2281 1650
2282 /**************************************************************************** 1651 /****************************************************************************
2283 * formatted-string * 1652 * formatted-string *
2299 formatted_string_instantiate (Lisp_Object image_instance, 1668 formatted_string_instantiate (Lisp_Object image_instance,
2300 Lisp_Object instantiator, 1669 Lisp_Object instantiator,
2301 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 1670 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2302 int dest_mask, Lisp_Object domain) 1671 int dest_mask, Lisp_Object domain)
2303 { 1672 {
1673 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1674 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1675
1676 assert (!NILP (data));
2304 /* #### implement this */ 1677 /* #### implement this */
2305 warn_when_safe (Qunimplemented, Qnotice, 1678 warn_when_safe (Qunimplemented, Qnotice,
2306 "`formatted-string' not yet implemented; assuming `string'"); 1679 "`formatted-string' not yet implemented; assuming `string'");
2307 1680 if (dest_mask & IMAGE_TEXT_MASK)
2308 string_instantiate (image_instance, instantiator, 1681 {
2309 pointer_fg, pointer_bg, dest_mask, domain); 1682 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT;
1683 IMAGE_INSTANCE_TEXT_STRING (ii) = data;
1684 }
1685 else
1686 incompatible_image_types (instantiator, dest_mask, IMAGE_TEXT_MASK);
2310 } 1687 }
2311 1688
2312 1689
2313 /************************************************************************/ 1690 /************************************************************************/
2314 /* pixmap file functions */ 1691 /* pixmap file functions */
2468 int ok_if_data_invalid) 1845 int ok_if_data_invalid)
2469 { 1846 {
2470 unsigned int w, h; 1847 unsigned int w, h;
2471 Extbyte *data; 1848 Extbyte *data;
2472 int result; 1849 int result;
2473 const char *filename_ext; 1850 CONST char *filename_ext;
2474 1851
2475 TO_EXTERNAL_FORMAT (LISP_STRING, name, 1852 GET_C_STRING_FILENAME_DATA_ALLOCA (name, filename_ext);
2476 C_STRING_ALLOCA, filename_ext,
2477 Qfile_name);
2478 result = read_bitmap_data_from_file (filename_ext, &w, &h, 1853 result = read_bitmap_data_from_file (filename_ext, &w, &h,
2479 &data, xhot, yhot); 1854 &data, xhot, yhot);
2480 1855
2481 if (result == BitmapSuccess) 1856 if (result == BitmapSuccess)
2482 { 1857 {
2483 Lisp_Object retval; 1858 Lisp_Object retval;
2484 int len = (w + 7) / 8 * h; 1859 int len = (w + 7) / 8 * h;
2485 1860
2486 retval = list3 (make_int (w), make_int (h), 1861 retval = list3 (make_int (w), make_int (h),
2487 make_ext_string (data, len, Qbinary)); 1862 make_ext_string (data, len, FORMAT_BINARY));
2488 XFree ((char *) data); 1863 XFree ((char *) data);
2489 return retval; 1864 return retval;
2490 } 1865 }
2491 1866
2492 switch (result) 1867 switch (result)
2715 pixmap_to_lisp_data (Lisp_Object name, int ok_if_data_invalid) 2090 pixmap_to_lisp_data (Lisp_Object name, int ok_if_data_invalid)
2716 { 2091 {
2717 char **data; 2092 char **data;
2718 int result; 2093 int result;
2719 char *fname = 0; 2094 char *fname = 0;
2720 2095
2721 TO_EXTERNAL_FORMAT (LISP_STRING, name, 2096 GET_C_STRING_FILENAME_DATA_ALLOCA (name, fname);
2722 C_STRING_ALLOCA, fname,
2723 Qfile_name);
2724 result = XpmReadFileToData (fname, &data); 2097 result = XpmReadFileToData (fname, &data);
2725 2098
2726 if (result == XpmSuccess) 2099 if (result == XpmSuccess)
2727 { 2100 {
2728 Lisp_Object retval = Qnil; 2101 Lisp_Object retval = Qnil;
2928 DEFINE_SPECIFIER_TYPE (image); 2301 DEFINE_SPECIFIER_TYPE (image);
2929 2302
2930 static void 2303 static void
2931 image_create (Lisp_Object obj) 2304 image_create (Lisp_Object obj)
2932 { 2305 {
2933 Lisp_Specifier *image = XIMAGE_SPECIFIER (obj); 2306 struct Lisp_Specifier *image = XIMAGE_SPECIFIER (obj);
2934 2307
2935 IMAGE_SPECIFIER_ALLOWED (image) = ~0; /* all are allowed */ 2308 IMAGE_SPECIFIER_ALLOWED (image) = ~0; /* all are allowed */
2936 IMAGE_SPECIFIER_ATTACHEE (image) = Qnil; 2309 IMAGE_SPECIFIER_ATTACHEE (image) = Qnil;
2937 IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image) = Qnil; 2310 IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image) = Qnil;
2938 } 2311 }
2939 2312
2940 static void 2313 static void
2941 image_mark (Lisp_Object obj) 2314 image_mark (Lisp_Object obj, void (*markobj) (Lisp_Object))
2942 { 2315 {
2943 Lisp_Specifier *image = XIMAGE_SPECIFIER (obj); 2316 struct Lisp_Specifier *image = XIMAGE_SPECIFIER (obj);
2944 2317
2945 mark_object (IMAGE_SPECIFIER_ATTACHEE (image)); 2318 markobj (IMAGE_SPECIFIER_ATTACHEE (image));
2946 mark_object (IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image)); 2319 markobj (IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image));
2947 } 2320 }
2948 2321
2949 static Lisp_Object 2322 static Lisp_Object
2950 image_instantiate_cache_result (Lisp_Object locative) 2323 image_instantiate_cache_result (Lisp_Object locative)
2951 { 2324 {
2952 /* locative = (instance instantiator . subtable) 2325 /* locative = (instance instantiator . subtable) */
2953
2954 So we are using the instantiator as the key and the instance as
2955 the value. Since the hashtable is key-weak this means that the
2956 image instance will stay around as long as the instantiator stays
2957 around. The instantiator is stored in the `image' slot of the
2958 glyph, so as long as the glyph is marked the instantiator will be
2959 as well and hence the cached image instance also.*/
2960 Fputhash (XCAR (XCDR (locative)), XCAR (locative), XCDR (XCDR (locative))); 2326 Fputhash (XCAR (XCDR (locative)), XCAR (locative), XCDR (XCDR (locative)));
2961 free_cons (XCONS (XCDR (locative))); 2327 free_cons (XCONS (XCDR (locative)));
2962 free_cons (XCONS (locative)); 2328 free_cons (XCONS (locative));
2963 return Qnil; 2329 return Qnil;
2964 } 2330 }
2970 static Lisp_Object 2336 static Lisp_Object
2971 image_instantiate (Lisp_Object specifier, Lisp_Object matchspec, 2337 image_instantiate (Lisp_Object specifier, Lisp_Object matchspec,
2972 Lisp_Object domain, Lisp_Object instantiator, 2338 Lisp_Object domain, Lisp_Object instantiator,
2973 Lisp_Object depth) 2339 Lisp_Object depth)
2974 { 2340 {
2975 Lisp_Object glyph = IMAGE_SPECIFIER_ATTACHEE (XIMAGE_SPECIFIER (specifier)); 2341 Lisp_Object device = DFW_DEVICE (domain);
2342 struct device *d = XDEVICE (device);
2976 int dest_mask = XIMAGE_SPECIFIER_ALLOWED (specifier); 2343 int dest_mask = XIMAGE_SPECIFIER_ALLOWED (specifier);
2977 int pointerp = dest_mask & image_instance_type_to_mask (IMAGE_POINTER); 2344 int pointerp = dest_mask & image_instance_type_to_mask (IMAGE_POINTER);
2978 2345
2979 if (IMAGE_INSTANCEP (instantiator)) 2346 if (IMAGE_INSTANCEP (instantiator))
2980 { 2347 {
2981 /* make sure that the image instance's governing domain and type are 2348 /* make sure that the image instance's device and type are
2982 matching. */ 2349 matching. */
2983 Lisp_Object governing_domain = XIMAGE_INSTANCE_DOMAIN (instantiator); 2350
2984 2351 if (EQ (device, XIMAGE_INSTANCE_DEVICE (instantiator)))
2985 if ((DEVICEP (governing_domain)
2986 && EQ (governing_domain, DOMAIN_DEVICE (domain)))
2987 || (FRAMEP (governing_domain)
2988 && EQ (governing_domain, DOMAIN_FRAME (domain)))
2989 || (WINDOWP (governing_domain)
2990 && EQ (governing_domain, DOMAIN_WINDOW (domain))))
2991 { 2352 {
2992 int mask = 2353 int mask =
2993 image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instantiator)); 2354 image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instantiator));
2994 if (mask & dest_mask) 2355 if (mask & dest_mask)
2995 return instantiator; 2356 return instantiator;
2996 else 2357 else
2997 signal_simple_error ("Type of image instance not allowed here", 2358 signal_simple_error ("Type of image instance not allowed here",
2998 instantiator); 2359 instantiator);
2999 } 2360 }
3000 else 2361 else
3001 signal_simple_error_2 ("Wrong domain for image instance", 2362 signal_simple_error_2 ("Wrong device for image instance",
3002 instantiator, domain); 2363 instantiator, device);
3003 } 2364 }
3004 else if (VECTORP (instantiator) 2365 else if (VECTORP (instantiator)
3005 && EQ (XVECTOR_DATA (instantiator)[0], Qinherit)) 2366 && EQ (XVECTOR_DATA (instantiator)[0], Qinherit))
3006 { 2367 {
3007 assert (XVECTOR_LENGTH (instantiator) == 3); 2368 assert (XVECTOR_LENGTH (instantiator) == 3);
3009 (Fget_face (XVECTOR_DATA (instantiator)[2]), 2370 (Fget_face (XVECTOR_DATA (instantiator)[2]),
3010 Qbackground_pixmap, domain, 0, depth)); 2371 Qbackground_pixmap, domain, 0, depth));
3011 } 2372 }
3012 else 2373 else
3013 { 2374 {
3014 Lisp_Object instance = Qnil; 2375 Lisp_Object instance;
3015 Lisp_Object subtable = Qnil; 2376 Lisp_Object subtable;
3016 Lisp_Object ls3 = Qnil; 2377 Lisp_Object ls3 = Qnil;
3017 Lisp_Object pointer_fg = Qnil; 2378 Lisp_Object pointer_fg = Qnil;
3018 Lisp_Object pointer_bg = Qnil; 2379 Lisp_Object pointer_bg = Qnil;
3019 Lisp_Object governing_domain =
3020 get_image_instantiator_governing_domain (instantiator, domain);
3021 struct gcpro gcpro1;
3022
3023 GCPRO1 (instance);
3024
3025 /* We have to put subwindow, widget and text image instances in
3026 a per-window cache so that we can see the same glyph in
3027 different windows. We use governing_domain to determine the type
3028 of image_instance that will be created. */
3029 2380
3030 if (pointerp) 2381 if (pointerp)
3031 { 2382 {
3032 pointer_fg = FACE_FOREGROUND (Vpointer_face, domain); 2383 pointer_fg = FACE_FOREGROUND (Vpointer_face, domain);
3033 pointer_bg = FACE_BACKGROUND (Vpointer_face, domain); 2384 pointer_bg = FACE_BACKGROUND (Vpointer_face, domain);
3034 ls3 = list3 (instantiator, pointer_fg, pointer_bg); 2385 ls3 = list3 (instantiator, pointer_fg, pointer_bg);
3035 } 2386 }
3036 2387
3037 /* First look in the device cache. */ 2388 /* First look in the hash table. */
3038 if (DEVICEP (governing_domain)) 2389 subtable = Fgethash (make_int (dest_mask), d->image_instance_cache,
2390 Qunbound);
2391 if (UNBOUNDP (subtable))
3039 { 2392 {
3040 subtable = Fgethash (make_int (dest_mask), 2393 /* For the image instance cache, we do comparisons with EQ rather
3041 XDEVICE (governing_domain)-> 2394 than with EQUAL, as we do for color and font names.
3042 image_instance_cache, 2395 The reasons are:
3043 Qunbound); 2396
3044 if (UNBOUNDP (subtable)) 2397 1) pixmap data can be very long, and thus the hashing and
2398 comparing will take awhile.
2399 2) It's not so likely that we'll run into things that are EQUAL
2400 but not EQ (that can happen a lot with faces, because their
2401 specifiers are copied around); but pixmaps tend not to be
2402 in faces.
2403
2404 However, if the image-instance could be a pointer, we have to
2405 use EQUAL because we massaged the instantiator into a cons3
2406 also containing the foreground and background of the
2407 pointer face.
2408 */
2409
2410 subtable = make_lisp_hash_table (20,
2411 pointerp ? HASH_TABLE_KEY_CAR_WEAK
2412 : HASH_TABLE_KEY_WEAK,
2413 pointerp ? HASH_TABLE_EQUAL
2414 : HASH_TABLE_EQ);
2415 Fputhash (make_int (dest_mask), subtable,
2416 d->image_instance_cache);
2417 instance = Qunbound;
2418 }
2419 else
2420 {
2421 instance = Fgethash (pointerp ? ls3 : instantiator,
2422 subtable, Qunbound);
2423 /* subwindows have a per-window cache and have to be treated
2424 differently. dest_mask can be a bitwise OR of all image
2425 types so we will only catch someone possibly trying to
2426 instantiate a subwindow type thing. Unfortunately, this
2427 will occur most of the time so this probably slows things
2428 down. But with the current design I don't see anyway
2429 round it. */
2430 if (UNBOUNDP (instance)
2431 &&
2432 dest_mask & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK))
3045 { 2433 {
3046 /* For the image instance cache, we do comparisons with 2434 if (!WINDOWP (domain))
3047 EQ rather than with EQUAL, as we do for color and 2435 signal_simple_error ("Can't instantiate subwindow outside a window",
3048 font names. The reasons are: 2436 instantiator);
3049 2437 instance = Fgethash (instantiator,
3050 1) pixmap data can be very long, and thus the hashing 2438 XWINDOW (domain)->subwindow_instance_cache,
3051 and comparing will take awhile. 2439 Qunbound);
3052
3053 2) It's not so likely that we'll run into things that
3054 are EQUAL but not EQ (that can happen a lot with
3055 faces, because their specifiers are copied around);
3056 but pixmaps tend not to be in faces.
3057
3058 However, if the image-instance could be a pointer, we
3059 have to use EQUAL because we massaged the
3060 instantiator into a cons3 also containing the
3061 foreground and background of the pointer face. */
3062
3063 subtable = make_lisp_hash_table
3064 (20, pointerp ? HASH_TABLE_KEY_CAR_WEAK
3065 : HASH_TABLE_KEY_WEAK,
3066 pointerp ? HASH_TABLE_EQUAL
3067 : HASH_TABLE_EQ);
3068 Fputhash (make_int (dest_mask), subtable,
3069 XDEVICE (governing_domain)->image_instance_cache);
3070 instance = Qunbound;
3071 }
3072 else
3073 {
3074 instance = Fgethash (pointerp ? ls3 : instantiator,
3075 subtable, Qunbound);
3076 } 2440 }
3077 } 2441 }
3078 else if (WINDOWP (governing_domain)) 2442
3079 {
3080 /* Subwindows have a per-window cache and have to be treated
3081 differently. */
3082 instance =
3083 Fgethash (instantiator,
3084 XWINDOW (governing_domain)->subwindow_instance_cache,
3085 Qunbound);
3086 }
3087 else
3088 abort (); /* We're not allowed anything else currently. */
3089
3090 /* If we don't have an instance at this point then create
3091 one. */
3092 if (UNBOUNDP (instance)) 2443 if (UNBOUNDP (instance))
3093 { 2444 {
3094 Lisp_Object locative = 2445 Lisp_Object locative =
3095 noseeum_cons (Qnil, 2446 noseeum_cons (Qnil,
3096 noseeum_cons (pointerp ? ls3 : instantiator, 2447 noseeum_cons (pointerp ? ls3 : instantiator,
3097 DEVICEP (governing_domain) ? subtable 2448 subtable));
3098 : XWINDOW (governing_domain)
3099 ->subwindow_instance_cache));
3100 int speccount = specpdl_depth (); 2449 int speccount = specpdl_depth ();
3101 2450
3102 /* Make sure we cache the failures, too. Use an 2451 /* make sure we cache the failures, too.
3103 unwind-protect to catch such errors. If we fail, the 2452 Use an unwind-protect to catch such errors.
3104 unwind-protect records nil in the hash table. If we 2453 If we fail, the unwind-protect records nil in
3105 succeed, we change the car of the locative to the 2454 the hash table. If we succeed, we change the
3106 resulting instance, which gets recorded instead. */ 2455 car of the locative to the resulting instance,
2456 which gets recorded instead. */
3107 record_unwind_protect (image_instantiate_cache_result, 2457 record_unwind_protect (image_instantiate_cache_result,
3108 locative); 2458 locative);
3109 instance = 2459 instance = instantiate_image_instantiator (device,
3110 instantiate_image_instantiator (governing_domain, 2460 domain,
3111 domain, instantiator, 2461 instantiator,
3112 pointer_fg, pointer_bg, 2462 pointer_fg, pointer_bg,
3113 dest_mask, glyph); 2463 dest_mask);
3114 2464
3115 /* We need a per-frame cache for redisplay. */
3116 cache_subwindow_instance_in_frame_maybe (instance);
3117
3118 Fsetcar (locative, instance); 2465 Fsetcar (locative, instance);
3119 #ifdef ERROR_CHECK_GLYPHS 2466 /* only after the image has been instantiated do we know
2467 whether we need to put it in the per-window image instance
2468 cache. */
3120 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance)) 2469 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
3121 & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK)) 2470 &
3122 assert (EQ (XIMAGE_INSTANCE_FRAME (instance), 2471 (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK))
3123 DOMAIN_FRAME (domain))); 2472 {
3124 #endif 2473 if (!WINDOWP (domain))
2474 signal_simple_error ("Can't instantiate subwindow outside a window",
2475 instantiator);
2476
2477 Fsetcdr (XCDR (locative), XWINDOW (domain)->subwindow_instance_cache );
2478 }
3125 unbind_to (speccount, Qnil); 2479 unbind_to (speccount, Qnil);
3126 #ifdef ERROR_CHECK_GLYPHS
3127 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
3128 & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK))
3129 assert (EQ (Fgethash ((pointerp ? ls3 : instantiator),
3130 XWINDOW (governing_domain)
3131 ->subwindow_instance_cache,
3132 Qunbound), instance));
3133 #endif
3134 } 2480 }
3135 else 2481 else
3136 free_list (ls3); 2482 free_list (ls3);
3137 2483
3138 if (NILP (instance)) 2484 if (NILP (instance))
3139 signal_simple_error ("Can't instantiate image (probably cached)", 2485 signal_simple_error ("Can't instantiate image (probably cached)",
3140 instantiator); 2486 instantiator);
3141 #ifdef ERROR_CHECK_GLYPHS 2487 return instance;
3142 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
3143 & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK))
3144 assert (EQ (XIMAGE_INSTANCE_FRAME (instance),
3145 DOMAIN_FRAME (domain)));
3146 #endif
3147 ERROR_CHECK_IMAGE_INSTANCE (instance);
3148 RETURN_UNGCPRO (instance);
3149 } 2488 }
3150 2489
3151 abort (); 2490 abort ();
3152 return Qnil; /* not reached */ 2491 return Qnil; /* not reached */
3153 } 2492 }
3230 2569
3231 void 2570 void
3232 set_image_attached_to (Lisp_Object obj, Lisp_Object face_or_glyph, 2571 set_image_attached_to (Lisp_Object obj, Lisp_Object face_or_glyph,
3233 Lisp_Object property) 2572 Lisp_Object property)
3234 { 2573 {
3235 Lisp_Specifier *image = XIMAGE_SPECIFIER (obj); 2574 struct Lisp_Specifier *image = XIMAGE_SPECIFIER (obj);
3236 2575
3237 IMAGE_SPECIFIER_ATTACHEE (image) = face_or_glyph; 2576 IMAGE_SPECIFIER_ATTACHEE (image) = face_or_glyph;
3238 IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image) = property; 2577 IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image) = property;
3239 } 2578 }
3240 2579
3285 UNGCPRO; 2624 UNGCPRO;
3286 2625
3287 return retlist; 2626 return retlist;
3288 } 2627 }
3289 2628
3290 /* Copy an image instantiator. We can't use Fcopy_tree since widgets
3291 may contain circular references which would send Fcopy_tree into
3292 infloop death. */
3293 static Lisp_Object
3294 image_copy_vector_instantiator (Lisp_Object instantiator)
3295 {
3296 int i;
3297 struct image_instantiator_methods *meths;
3298 Lisp_Object *elt;
3299 int instantiator_len;
3300
3301 CHECK_VECTOR (instantiator);
3302
3303 instantiator = Fcopy_sequence (instantiator);
3304 elt = XVECTOR_DATA (instantiator);
3305 instantiator_len = XVECTOR_LENGTH (instantiator);
3306
3307 meths = decode_image_instantiator_format (elt[0], ERROR_ME);
3308
3309 for (i = 1; i < instantiator_len; i += 2)
3310 {
3311 int j;
3312 Lisp_Object keyword = elt[i];
3313 Lisp_Object value = elt[i+1];
3314
3315 /* Find the keyword entry. */
3316 for (j = 0; j < Dynarr_length (meths->keywords); j++)
3317 {
3318 if (EQ (keyword, Dynarr_at (meths->keywords, j).keyword))
3319 break;
3320 }
3321
3322 /* Only copy keyword values that should be copied. */
3323 if (Dynarr_at (meths->keywords, j).copy_p
3324 &&
3325 (CONSP (value) || VECTORP (value)))
3326 {
3327 elt [i+1] = Fcopy_tree (value, Qt);
3328 }
3329 }
3330
3331 return instantiator;
3332 }
3333
3334 static Lisp_Object
3335 image_copy_instantiator (Lisp_Object arg)
3336 {
3337 if (CONSP (arg))
3338 {
3339 Lisp_Object rest;
3340 rest = arg = Fcopy_sequence (arg);
3341 while (CONSP (rest))
3342 {
3343 Lisp_Object elt = XCAR (rest);
3344 if (CONSP (elt))
3345 XCAR (rest) = Fcopy_tree (elt, Qt);
3346 else if (VECTORP (elt))
3347 XCAR (rest) = image_copy_vector_instantiator (elt);
3348 if (VECTORP (XCDR (rest))) /* hack for (a b . [c d]) */
3349 XCDR (rest) = Fcopy_tree (XCDR (rest), Qt);
3350 rest = XCDR (rest);
3351 }
3352 }
3353 else if (VECTORP (arg))
3354 {
3355 arg = image_copy_vector_instantiator (arg);
3356 }
3357 return arg;
3358 }
3359
3360 DEFUN ("image-specifier-p", Fimage_specifier_p, 1, 1, 0, /* 2629 DEFUN ("image-specifier-p", Fimage_specifier_p, 1, 1, 0, /*
3361 Return non-nil if OBJECT is an image specifier. 2630 Return non-nil if OBJECT is an image specifier.
3362 See `make-image-specifier' for a description of image instantiators. 2631
2632 An image specifier is used for images (pixmaps and the like). It is used
2633 to describe the actual image in a glyph. It is instanced as an image-
2634 instance.
2635
2636 Image instantiators come in many formats: `xbm', `xpm', `gif', `jpeg',
2637 etc. This describes the format of the data describing the image. The
2638 resulting image instances also come in many types -- `mono-pixmap',
2639 `color-pixmap', `text', `pointer', etc. This refers to the behavior of
2640 the image and the sorts of places it can appear. (For example, a
2641 color-pixmap image has fixed colors specified for it, while a
2642 mono-pixmap image comes in two unspecified shades "foreground" and
2643 "background" that are determined from the face of the glyph or
2644 surrounding text; a text image appears as a string of text and has an
2645 unspecified foreground, background, and font; a pointer image behaves
2646 like a mono-pixmap image but can only be used as a mouse pointer
2647 \[mono-pixmap images cannot be used as mouse pointers]; etc.) It is
2648 important to keep the distinction between image instantiator format and
2649 image instance type in mind. Typically, a given image instantiator
2650 format can result in many different image instance types (for example,
2651 `xpm' can be instanced as `color-pixmap', `mono-pixmap', or `pointer';
2652 whereas `cursor-font' can be instanced only as `pointer'), and a
2653 particular image instance type can be generated by many different
2654 image instantiator formats (e.g. `color-pixmap' can be generated by `xpm',
2655 `gif', `jpeg', etc.).
2656
2657 See `make-image-instance' for a more detailed discussion of image
2658 instance types.
2659
2660 An image instantiator should be a string or a vector of the form
2661
2662 [FORMAT :KEYWORD VALUE ...]
2663
2664 i.e. a format symbol followed by zero or more alternating keyword-value
2665 pairs. FORMAT should be one of
2666
2667 'nothing
2668 (Don't display anything; no keywords are valid for this.
2669 Can only be instanced as `nothing'.)
2670 'string
2671 (Display this image as a text string. Can only be instanced
2672 as `text', although support for instancing as `mono-pixmap'
2673 should be added.)
2674 'formatted-string
2675 (Display this image as a text string, with replaceable fields;
2676 not currently implemented.)
2677 'xbm
2678 (An X bitmap; only if X or Windows support was compiled into this XEmacs.
2679 Can be instanced as `mono-pixmap', `color-pixmap', or `pointer'.)
2680 'xpm
2681 (An XPM pixmap; only if XPM support was compiled into this XEmacs.
2682 Can be instanced as `color-pixmap', `mono-pixmap', or `pointer'.)
2683 'xface
2684 (An X-Face bitmap, used to encode people's faces in e-mail messages;
2685 only if X-Face support was compiled into this XEmacs. Can be
2686 instanced as `mono-pixmap', `color-pixmap', or `pointer'.)
2687 'gif
2688 (A GIF87 or GIF89 image; only if GIF support was compiled into this
2689 XEmacs. NOTE: only the first frame of animated gifs will be displayed.
2690 Can be instanced as `color-pixmap'.)
2691 'jpeg
2692 (A JPEG image; only if JPEG support was compiled into this XEmacs.
2693 Can be instanced as `color-pixmap'.)
2694 'png
2695 (A PNG image; only if PNG support was compiled into this XEmacs.
2696 Can be instanced as `color-pixmap'.)
2697 'tiff
2698 (A TIFF image; only if TIFF support was compiled into this XEmacs.
2699 Can be instanced as `color-pixmap'.)
2700 'cursor-font
2701 (One of the standard cursor-font names, such as "watch" or
2702 "right_ptr" under X. Under X, this is, more specifically, any
2703 of the standard cursor names from appendix B of the Xlib manual
2704 [also known as the file <X11/cursorfont.h>] minus the XC_ prefix.
2705 On other window systems, the valid names will be specific to the
2706 type of window system. Can only be instanced as `pointer'.)
2707 'font
2708 (A glyph from a font; i.e. the name of a font, and glyph index into it
2709 of the form "FONT fontname index [[mask-font] mask-index]".
2710 Currently can only be instanced as `pointer', although this should
2711 probably be fixed.)
2712 'subwindow
2713 (An embedded X window; not currently implemented.)
2714 'widget
2715 (A widget control, for instance text field or radio button.)
2716 'autodetect
2717 (XEmacs tries to guess what format the data is in. If X support
2718 exists, the data string will be checked to see if it names a filename.
2719 If so, and this filename contains XBM or XPM data, the appropriate
2720 sort of pixmap or pointer will be created. [This includes picking up
2721 any specified hotspot or associated mask file.] Otherwise, if `pointer'
2722 is one of the allowable image-instance types and the string names a
2723 valid cursor-font name, the image will be created as a pointer.
2724 Otherwise, the image will be displayed as text. If no X support
2725 exists, the image will always be displayed as text.)
2726 'inherit
2727 Inherit from the background-pixmap property of a face.
2728
2729 The valid keywords are:
2730
2731 :data
2732 (Inline data. For most formats above, this should be a string. For
2733 XBM images, this should be a list of three elements: width, height, and
2734 a string of bit data. This keyword is not valid for instantiator
2735 formats `nothing' and `inherit'.)
2736 :file
2737 (Data is contained in a file. The value is the name of this file.
2738 If both :data and :file are specified, the image is created from
2739 what is specified in :data and the string in :file becomes the
2740 value of the `image-instance-file-name' function when applied to
2741 the resulting image-instance. This keyword is not valid for
2742 instantiator formats `nothing', `string', `formatted-string',
2743 `cursor-font', `font', `autodetect', and `inherit'.)
2744 :foreground
2745 :background
2746 (For `xbm', `xface', `cursor-font', `widget' and `font'. These keywords
2747 allow you to explicitly specify foreground and background colors.
2748 The argument should be anything acceptable to `make-color-instance'.
2749 This will cause what would be a `mono-pixmap' to instead be colorized
2750 as a two-color color-pixmap, and specifies the foreground and/or
2751 background colors for a pointer instead of black and white.)
2752 :mask-data
2753 (For `xbm' and `xface'. This specifies a mask to be used with the
2754 bitmap. The format is a list of width, height, and bits, like for
2755 :data.)
2756 :mask-file
2757 (For `xbm' and `xface'. This specifies a file containing the mask data.
2758 If neither a mask file nor inline mask data is given for an XBM image,
2759 and the XBM image comes from a file, XEmacs will look for a mask file
2760 with the same name as the image file but with "Mask" or "msk"
2761 appended. For example, if you specify the XBM file "left_ptr"
2762 [usually located in "/usr/include/X11/bitmaps"], the associated
2763 mask file "left_ptrmsk" will automatically be picked up.)
2764 :hotspot-x
2765 :hotspot-y
2766 (For `xbm' and `xface'. These keywords specify a hotspot if the image
2767 is instantiated as a `pointer'. Note that if the XBM image file
2768 specifies a hotspot, it will automatically be picked up if no
2769 explicit hotspot is given.)
2770 :color-symbols
2771 (Only for `xpm'. This specifies an alist that maps strings
2772 that specify symbolic color names to the actual color to be used
2773 for that symbolic color (in the form of a string or a color-specifier
2774 object). If this is not specified, the contents of `xpm-color-symbols'
2775 are used to generate the alist.)
2776 :face
2777 (Only for `inherit'. This specifies the face to inherit from.)
2778
2779 If instead of a vector, the instantiator is a string, it will be
2780 converted into a vector by looking it up according to the specs in the
2781 `console-type-image-conversion-list' (q.v.) for the console type of
2782 the domain (usually a window; sometimes a frame or device) over which
2783 the image is being instantiated.
2784
2785 If the instantiator specifies data from a file, the data will be read
2786 in at the time that the instantiator is added to the image (which may
2787 be well before when the image is actually displayed), and the
2788 instantiator will be converted into one of the inline-data forms, with
2789 the filename retained using a :file keyword. This implies that the
2790 file must exist when the instantiator is added to the image, but does
2791 not need to exist at any other time (e.g. it may safely be a temporary
2792 file).
3363 */ 2793 */
3364 (object)) 2794 (object))
3365 { 2795 {
3366 return IMAGE_SPECIFIERP (object) ? Qt : Qnil; 2796 return IMAGE_SPECIFIERP (object) ? Qt : Qnil;
3367 } 2797 }
3370 /**************************************************************************** 2800 /****************************************************************************
3371 * Glyph Object * 2801 * Glyph Object *
3372 ****************************************************************************/ 2802 ****************************************************************************/
3373 2803
3374 static Lisp_Object 2804 static Lisp_Object
3375 mark_glyph (Lisp_Object obj) 2805 mark_glyph (Lisp_Object obj, void (*markobj) (Lisp_Object))
3376 { 2806 {
3377 Lisp_Glyph *glyph = XGLYPH (obj); 2807 struct Lisp_Glyph *glyph = XGLYPH (obj);
3378 2808
3379 mark_object (glyph->image); 2809 markobj (glyph->image);
3380 mark_object (glyph->contrib_p); 2810 markobj (glyph->contrib_p);
3381 mark_object (glyph->baseline); 2811 markobj (glyph->baseline);
3382 mark_object (glyph->face); 2812 markobj (glyph->face);
3383 2813
3384 return glyph->plist; 2814 return glyph->plist;
3385 } 2815 }
3386 2816
3387 static void 2817 static void
3388 print_glyph (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) 2818 print_glyph (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
3389 { 2819 {
3390 Lisp_Glyph *glyph = XGLYPH (obj); 2820 struct Lisp_Glyph *glyph = XGLYPH (obj);
3391 char buf[20]; 2821 char buf[20];
3392 2822
3393 if (print_readably) 2823 if (print_readably)
3394 error ("printing unreadable object #<glyph 0x%x>", glyph->header.uid); 2824 error ("printing unreadable object #<glyph 0x%x>", glyph->header.uid);
3395 2825
3408 This isn't concerned with "unspecified" attributes, that's what 2838 This isn't concerned with "unspecified" attributes, that's what
3409 #'glyph-differs-from-default-p is for. */ 2839 #'glyph-differs-from-default-p is for. */
3410 static int 2840 static int
3411 glyph_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) 2841 glyph_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
3412 { 2842 {
3413 Lisp_Glyph *g1 = XGLYPH (obj1); 2843 struct Lisp_Glyph *g1 = XGLYPH (obj1);
3414 Lisp_Glyph *g2 = XGLYPH (obj2); 2844 struct Lisp_Glyph *g2 = XGLYPH (obj2);
3415 2845
3416 depth++; 2846 depth++;
3417 2847
3418 return (internal_equal (g1->image, g2->image, depth) && 2848 return (internal_equal (g1->image, g2->image, depth) &&
3419 internal_equal (g1->contrib_p, g2->contrib_p, depth) && 2849 internal_equal (g1->contrib_p, g2->contrib_p, depth) &&
3434 } 2864 }
3435 2865
3436 static Lisp_Object 2866 static Lisp_Object
3437 glyph_getprop (Lisp_Object obj, Lisp_Object prop) 2867 glyph_getprop (Lisp_Object obj, Lisp_Object prop)
3438 { 2868 {
3439 Lisp_Glyph *g = XGLYPH (obj); 2869 struct Lisp_Glyph *g = XGLYPH (obj);
3440 2870
3441 if (EQ (prop, Qimage)) return g->image; 2871 if (EQ (prop, Qimage)) return g->image;
3442 if (EQ (prop, Qcontrib_p)) return g->contrib_p; 2872 if (EQ (prop, Qcontrib_p)) return g->contrib_p;
3443 if (EQ (prop, Qbaseline)) return g->baseline; 2873 if (EQ (prop, Qbaseline)) return g->baseline;
3444 if (EQ (prop, Qface)) return g->face; 2874 if (EQ (prop, Qface)) return g->face;
3447 } 2877 }
3448 2878
3449 static int 2879 static int
3450 glyph_putprop (Lisp_Object obj, Lisp_Object prop, Lisp_Object value) 2880 glyph_putprop (Lisp_Object obj, Lisp_Object prop, Lisp_Object value)
3451 { 2881 {
3452 if (EQ (prop, Qimage) || 2882 if ((EQ (prop, Qimage)) ||
3453 EQ (prop, Qcontrib_p) || 2883 (EQ (prop, Qcontrib_p)) ||
3454 EQ (prop, Qbaseline)) 2884 (EQ (prop, Qbaseline)))
3455 return 0; 2885 return 0;
3456 2886
3457 if (EQ (prop, Qface)) 2887 if (EQ (prop, Qface))
3458 { 2888 {
3459 XGLYPH (obj)->face = Fget_face (value); 2889 XGLYPH (obj)->face = Fget_face (value);
3465 } 2895 }
3466 2896
3467 static int 2897 static int
3468 glyph_remprop (Lisp_Object obj, Lisp_Object prop) 2898 glyph_remprop (Lisp_Object obj, Lisp_Object prop)
3469 { 2899 {
3470 if (EQ (prop, Qimage) || 2900 if ((EQ (prop, Qimage)) ||
3471 EQ (prop, Qcontrib_p) || 2901 (EQ (prop, Qcontrib_p)) ||
3472 EQ (prop, Qbaseline)) 2902 (EQ (prop, Qbaseline)))
3473 return -1; 2903 return -1;
3474 2904
3475 if (EQ (prop, Qface)) 2905 if (EQ (prop, Qface))
3476 { 2906 {
3477 XGLYPH (obj)->face = Qnil; 2907 XGLYPH (obj)->face = Qnil;
3482 } 2912 }
3483 2913
3484 static Lisp_Object 2914 static Lisp_Object
3485 glyph_plist (Lisp_Object obj) 2915 glyph_plist (Lisp_Object obj)
3486 { 2916 {
3487 Lisp_Glyph *glyph = XGLYPH (obj); 2917 struct Lisp_Glyph *glyph = XGLYPH (obj);
3488 Lisp_Object result = glyph->plist; 2918 Lisp_Object result = glyph->plist;
3489 2919
3490 result = cons3 (Qface, glyph->face, result); 2920 result = cons3 (Qface, glyph->face, result);
3491 result = cons3 (Qbaseline, glyph->baseline, result); 2921 result = cons3 (Qbaseline, glyph->baseline, result);
3492 result = cons3 (Qcontrib_p, glyph->contrib_p, result); 2922 result = cons3 (Qcontrib_p, glyph->contrib_p, result);
3493 result = cons3 (Qimage, glyph->image, result); 2923 result = cons3 (Qimage, glyph->image, result);
3494 2924
3495 return result; 2925 return result;
3496 } 2926 }
3497 2927
3498 static const struct lrecord_description glyph_description[] = {
3499 { XD_LISP_OBJECT, offsetof (Lisp_Glyph, image) },
3500 { XD_LISP_OBJECT, offsetof (Lisp_Glyph, contrib_p) },
3501 { XD_LISP_OBJECT, offsetof (Lisp_Glyph, baseline) },
3502 { XD_LISP_OBJECT, offsetof (Lisp_Glyph, face) },
3503 { XD_LISP_OBJECT, offsetof (Lisp_Glyph, plist) },
3504 { XD_END }
3505 };
3506
3507 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("glyph", glyph, 2928 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("glyph", glyph,
3508 mark_glyph, print_glyph, 0, 2929 mark_glyph, print_glyph, 0,
3509 glyph_equal, glyph_hash, glyph_description, 2930 glyph_equal, glyph_hash,
3510 glyph_getprop, glyph_putprop, 2931 glyph_getprop, glyph_putprop,
3511 glyph_remprop, glyph_plist, 2932 glyph_remprop, glyph_plist,
3512 Lisp_Glyph); 2933 struct Lisp_Glyph);
3513 2934
3514 Lisp_Object 2935 Lisp_Object
3515 allocate_glyph (enum glyph_type type, 2936 allocate_glyph (enum glyph_type type,
3516 void (*after_change) (Lisp_Object glyph, Lisp_Object property, 2937 void (*after_change) (Lisp_Object glyph, Lisp_Object property,
3517 Lisp_Object locale)) 2938 Lisp_Object locale))
3518 { 2939 {
3519 /* This function can GC */ 2940 /* This function can GC */
3520 Lisp_Object obj = Qnil; 2941 Lisp_Object obj = Qnil;
3521 Lisp_Glyph *g = alloc_lcrecord_type (Lisp_Glyph, &lrecord_glyph); 2942 struct Lisp_Glyph *g =
2943 alloc_lcrecord_type (struct Lisp_Glyph, &lrecord_glyph);
3522 2944
3523 g->type = type; 2945 g->type = type;
3524 g->image = Fmake_specifier (Qimage); /* This function can GC */ 2946 g->image = Fmake_specifier (Qimage); /* This function can GC */
3525 g->dirty = 0;
3526 switch (g->type) 2947 switch (g->type)
3527 { 2948 {
3528 case GLYPH_BUFFER: 2949 case GLYPH_BUFFER:
3529 XIMAGE_SPECIFIER_ALLOWED (g->image) = 2950 XIMAGE_SPECIFIER_ALLOWED (g->image) =
3530 IMAGE_NOTHING_MASK | IMAGE_TEXT_MASK 2951 IMAGE_NOTHING_MASK | IMAGE_TEXT_MASK
3531 | IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK 2952 | IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
3532 | IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK; 2953 | IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK;
3533 break; 2954 break;
3534 case GLYPH_POINTER: 2955 case GLYPH_POINTER:
3535 XIMAGE_SPECIFIER_ALLOWED (g->image) = 2956 XIMAGE_SPECIFIER_ALLOWED (g->image) =
3536 IMAGE_NOTHING_MASK | IMAGE_POINTER_MASK; 2957 IMAGE_NOTHING_MASK | IMAGE_POINTER_MASK;
3537 break; 2958 break;
3538 case GLYPH_ICON: 2959 case GLYPH_ICON:
3539 XIMAGE_SPECIFIER_ALLOWED (g->image) = 2960 XIMAGE_SPECIFIER_ALLOWED (g->image) =
3540 IMAGE_NOTHING_MASK | IMAGE_MONO_PIXMAP_MASK 2961 IMAGE_NOTHING_MASK | IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK;
3541 | IMAGE_COLOR_PIXMAP_MASK;
3542 break; 2962 break;
3543 default: 2963 default:
3544 abort (); 2964 abort ();
3545 } 2965 }
3546 2966
3642 } 3062 }
3643 3063
3644 DEFUN ("glyphp", Fglyphp, 1, 1, 0, /* 3064 DEFUN ("glyphp", Fglyphp, 1, 1, 0, /*
3645 Return non-nil if OBJECT is a glyph. 3065 Return non-nil if OBJECT is a glyph.
3646 3066
3647 A glyph is an object used for pixmaps, widgets and the like. It is used 3067 A glyph is an object used for pixmaps and the like. It is used
3648 in begin-glyphs and end-glyphs attached to extents, in marginal and textual 3068 in begin-glyphs and end-glyphs attached to extents, in marginal and textual
3649 annotations, in overlay arrows (overlay-arrow-* variables), in toolbar 3069 annotations, in overlay arrows (overlay-arrow-* variables), in toolbar
3650 buttons, and the like. Much more detailed information can be found at 3070 buttons, and the like. Its image is described using an image specifier --
3651 `make-glyph'. Its image is described using an image specifier -- 3071 see `image-specifier-p'.
3652 see `make-image-specifier'. See also `make-image-instance' for further
3653 information.
3654 */ 3072 */
3655 (object)) 3073 (object))
3656 { 3074 {
3657 return GLYPHP (object) ? Qt : Qnil; 3075 return GLYPHP (object) ? Qt : Qnil;
3658 } 3076 }
3671 case GLYPH_POINTER: return Qpointer; 3089 case GLYPH_POINTER: return Qpointer;
3672 case GLYPH_ICON: return Qicon; 3090 case GLYPH_ICON: return Qicon;
3673 } 3091 }
3674 } 3092 }
3675 3093
3676 Lisp_Object
3677 glyph_image_instance (Lisp_Object glyph, Lisp_Object domain,
3678 Error_behavior errb, int no_quit)
3679 {
3680 Lisp_Object specifier = GLYPH_IMAGE (XGLYPH (glyph));
3681
3682 /* This can never return Qunbound. All glyphs have 'nothing as
3683 a fallback. */
3684 Lisp_Object image_instance = specifier_instance (specifier, Qunbound,
3685 domain, errb, no_quit, 0,
3686 Qzero);
3687 assert (!UNBOUNDP (image_instance));
3688 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
3689
3690 return image_instance;
3691 }
3692
3693 static Lisp_Object
3694 glyph_image_instance_maybe (Lisp_Object glyph_or_image, Lisp_Object window)
3695 {
3696 Lisp_Object instance = glyph_or_image;
3697
3698 if (GLYPHP (glyph_or_image))
3699 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1);
3700
3701 return instance;
3702 }
3703
3704 /***************************************************************************** 3094 /*****************************************************************************
3705 glyph_width 3095 glyph_width
3706 3096
3707 Return the width of the given GLYPH on the given WINDOW. 3097 Return the width of the given GLYPH on the given WINDOW. If the
3708 Calculations are done based on recursively querying the geometry of 3098 instance is a string then the width is calculated using the font of
3709 the associated image instances. 3099 the given FACE, unless a face is defined by the glyph itself.
3710 ****************************************************************************/ 3100 ****************************************************************************/
3711 unsigned short 3101 unsigned short
3712 glyph_width (Lisp_Object glyph_or_image, Lisp_Object domain) 3102 glyph_width (Lisp_Object glyph, Lisp_Object frame_face,
3713 { 3103 face_index window_findex, Lisp_Object window)
3714 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image, 3104 {
3715 domain); 3105 Lisp_Object instance;
3106 Lisp_Object frame = XWINDOW (window)->frame;
3107
3108 /* #### We somehow need to distinguish between the user causing this
3109 error condition and a bug causing it. */
3110 if (!GLYPHP (glyph))
3111 return 0;
3112 else
3113 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1);
3114
3716 if (!IMAGE_INSTANCEP (instance)) 3115 if (!IMAGE_INSTANCEP (instance))
3717 return 0; 3116 return 0;
3718 3117
3719 if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance)) 3118 switch (XIMAGE_INSTANCE_TYPE (instance))
3720 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY, 3119 {
3721 IMAGE_UNSPECIFIED_GEOMETRY, domain); 3120 case IMAGE_TEXT:
3722 3121 {
3723 return XIMAGE_INSTANCE_WIDTH (instance); 3122 Lisp_Object str = XIMAGE_INSTANCE_TEXT_STRING (instance);
3123 Lisp_Object private_face = XGLYPH_FACE(glyph);
3124
3125 if (!NILP (private_face))
3126 return redisplay_frame_text_width_string (XFRAME (frame),
3127 private_face,
3128 0, str, 0, -1);
3129 else
3130 if (!NILP (frame_face))
3131 return redisplay_frame_text_width_string (XFRAME (frame),
3132 frame_face,
3133 0, str, 0, -1);
3134 else
3135 return redisplay_text_width_string (XWINDOW (window),
3136 window_findex,
3137 0, str, 0, -1);
3138 }
3139
3140 case IMAGE_MONO_PIXMAP:
3141 case IMAGE_COLOR_PIXMAP:
3142 case IMAGE_POINTER:
3143 return XIMAGE_INSTANCE_PIXMAP_WIDTH (instance);
3144
3145 case IMAGE_NOTHING:
3146 return 0;
3147
3148 case IMAGE_SUBWINDOW:
3149 case IMAGE_WIDGET:
3150 return XIMAGE_INSTANCE_SUBWINDOW_WIDTH (instance);
3151
3152 default:
3153 abort ();
3154 return 0;
3155 }
3724 } 3156 }
3725 3157
3726 DEFUN ("glyph-width", Fglyph_width, 1, 2, 0, /* 3158 DEFUN ("glyph-width", Fglyph_width, 1, 2, 0, /*
3727 Return the width of GLYPH on WINDOW. 3159 Return the width of GLYPH on WINDOW.
3728 This may not be exact as it does not take into account all of the context 3160 This may not be exact as it does not take into account all of the context
3731 (glyph, window)) 3163 (glyph, window))
3732 { 3164 {
3733 XSETWINDOW (window, decode_window (window)); 3165 XSETWINDOW (window, decode_window (window));
3734 CHECK_GLYPH (glyph); 3166 CHECK_GLYPH (glyph);
3735 3167
3736 return make_int (glyph_width (glyph, window)); 3168 return make_int (glyph_width (glyph, Qnil, DEFAULT_INDEX, window));
3737 } 3169 }
3738 3170
3739 unsigned short 3171 #define RETURN_ASCENT 0
3740 glyph_ascent (Lisp_Object glyph_or_image, Lisp_Object domain) 3172 #define RETURN_DESCENT 1
3741 { 3173 #define RETURN_HEIGHT 2
3742 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image, 3174
3743 domain); 3175 Lisp_Object
3176 glyph_image_instance (Lisp_Object glyph, Lisp_Object domain,
3177 Error_behavior errb, int no_quit)
3178 {
3179 Lisp_Object specifier = GLYPH_IMAGE (XGLYPH (glyph));
3180
3181 /* This can never return Qunbound. All glyphs have 'nothing as
3182 a fallback. */
3183 return specifier_instance (specifier, Qunbound, domain, errb, no_quit, 0,
3184 Qzero);
3185 }
3186
3187 static unsigned short
3188 glyph_height_internal (Lisp_Object glyph, Lisp_Object frame_face,
3189 face_index window_findex, Lisp_Object window,
3190 int function)
3191 {
3192 Lisp_Object instance;
3193 Lisp_Object frame = XWINDOW (window)->frame;
3194
3195 if (!GLYPHP (glyph))
3196 return 0;
3197 else
3198 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1);
3199
3744 if (!IMAGE_INSTANCEP (instance)) 3200 if (!IMAGE_INSTANCEP (instance))
3745 return 0; 3201 return 0;
3746 3202
3747 if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance)) 3203 switch (XIMAGE_INSTANCE_TYPE (instance))
3748 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY, 3204 {
3749 IMAGE_UNSPECIFIED_GEOMETRY, domain); 3205 case IMAGE_TEXT:
3750 3206 {
3751 if (XIMAGE_INSTANCE_TYPE (instance) == IMAGE_TEXT) 3207 struct font_metric_info fm;
3752 return XIMAGE_INSTANCE_TEXT_ASCENT (instance); 3208 Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance);
3753 else 3209 unsigned char charsets[NUM_LEADING_BYTES];
3754 return XIMAGE_INSTANCE_HEIGHT (instance); 3210 struct face_cachel frame_cachel;
3211 struct face_cachel *cachel;
3212
3213 find_charsets_in_bufbyte_string (charsets,
3214 XSTRING_DATA (string),
3215 XSTRING_LENGTH (string));
3216
3217 if (!NILP (frame_face))
3218 {
3219 reset_face_cachel (&frame_cachel);
3220 update_face_cachel_data (&frame_cachel, frame, frame_face);
3221 cachel = &frame_cachel;
3222 }
3223 else
3224 cachel = WINDOW_FACE_CACHEL (XWINDOW (window), window_findex);
3225 ensure_face_cachel_complete (cachel, window, charsets);
3226
3227 face_cachel_charset_font_metric_info (cachel, charsets, &fm);
3228
3229 switch (function)
3230 {
3231 case RETURN_ASCENT: return fm.ascent;
3232 case RETURN_DESCENT: return fm.descent;
3233 case RETURN_HEIGHT: return fm.ascent + fm.descent;
3234 default:
3235 abort ();
3236 return 0; /* not reached */
3237 }
3238 }
3239
3240 case IMAGE_MONO_PIXMAP:
3241 case IMAGE_COLOR_PIXMAP:
3242 case IMAGE_POINTER:
3243 /* #### Ugh ugh ugh -- temporary crap */
3244 if (function == RETURN_ASCENT || function == RETURN_HEIGHT)
3245 return XIMAGE_INSTANCE_PIXMAP_HEIGHT (instance);
3246 else
3247 return 0;
3248
3249 case IMAGE_NOTHING:
3250 return 0;
3251
3252 case IMAGE_SUBWINDOW:
3253 case IMAGE_WIDGET:
3254 /* #### Ugh ugh ugh -- temporary crap */
3255 if (function == RETURN_ASCENT || function == RETURN_HEIGHT)
3256 return XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (instance);
3257 else
3258 return 0;
3259
3260 default:
3261 abort ();
3262 return 0;
3263 }
3755 } 3264 }
3756 3265
3757 unsigned short 3266 unsigned short
3758 glyph_descent (Lisp_Object glyph_or_image, Lisp_Object domain) 3267 glyph_ascent (Lisp_Object glyph, Lisp_Object frame_face,
3759 { 3268 face_index window_findex, Lisp_Object window)
3760 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image, 3269 {
3761 domain); 3270 return glyph_height_internal (glyph, frame_face, window_findex, window,
3762 if (!IMAGE_INSTANCEP (instance)) 3271 RETURN_ASCENT);
3763 return 0; 3272 }
3764 3273
3765 if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance)) 3274 unsigned short
3766 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY, 3275 glyph_descent (Lisp_Object glyph, Lisp_Object frame_face,
3767 IMAGE_UNSPECIFIED_GEOMETRY, domain); 3276 face_index window_findex, Lisp_Object window)
3768 3277 {
3769 if (XIMAGE_INSTANCE_TYPE (instance) == IMAGE_TEXT) 3278 return glyph_height_internal (glyph, frame_face, window_findex, window,
3770 return XIMAGE_INSTANCE_TEXT_DESCENT (instance); 3279 RETURN_DESCENT);
3771 else
3772 return 0;
3773 } 3280 }
3774 3281
3775 /* strictly a convenience function. */ 3282 /* strictly a convenience function. */
3776 unsigned short 3283 unsigned short
3777 glyph_height (Lisp_Object glyph_or_image, Lisp_Object domain) 3284 glyph_height (Lisp_Object glyph, Lisp_Object frame_face,
3778 { 3285 face_index window_findex, Lisp_Object window)
3779 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image, 3286 {
3780 domain); 3287 return glyph_height_internal (glyph, frame_face, window_findex, window,
3781 3288 RETURN_HEIGHT);
3782 if (!IMAGE_INSTANCEP (instance))
3783 return 0;
3784
3785 if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance))
3786 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY,
3787 IMAGE_UNSPECIFIED_GEOMETRY, domain);
3788
3789 return XIMAGE_INSTANCE_HEIGHT (instance);
3790 } 3289 }
3791 3290
3792 DEFUN ("glyph-ascent", Fglyph_ascent, 1, 2, 0, /* 3291 DEFUN ("glyph-ascent", Fglyph_ascent, 1, 2, 0, /*
3793 Return the ascent value of GLYPH on WINDOW. 3292 Return the ascent value of GLYPH on WINDOW.
3794 This may not be exact as it does not take into account all of the context 3293 This may not be exact as it does not take into account all of the context
3797 (glyph, window)) 3296 (glyph, window))
3798 { 3297 {
3799 XSETWINDOW (window, decode_window (window)); 3298 XSETWINDOW (window, decode_window (window));
3800 CHECK_GLYPH (glyph); 3299 CHECK_GLYPH (glyph);
3801 3300
3802 return make_int (glyph_ascent (glyph, window)); 3301 return make_int (glyph_ascent (glyph, Qnil, DEFAULT_INDEX, window));
3803 } 3302 }
3804 3303
3805 DEFUN ("glyph-descent", Fglyph_descent, 1, 2, 0, /* 3304 DEFUN ("glyph-descent", Fglyph_descent, 1, 2, 0, /*
3806 Return the descent value of GLYPH on WINDOW. 3305 Return the descent value of GLYPH on WINDOW.
3807 This may not be exact as it does not take into account all of the context 3306 This may not be exact as it does not take into account all of the context
3810 (glyph, window)) 3309 (glyph, window))
3811 { 3310 {
3812 XSETWINDOW (window, decode_window (window)); 3311 XSETWINDOW (window, decode_window (window));
3813 CHECK_GLYPH (glyph); 3312 CHECK_GLYPH (glyph);
3814 3313
3815 return make_int (glyph_descent (glyph, window)); 3314 return make_int (glyph_descent (glyph, Qnil, DEFAULT_INDEX, window));
3816 } 3315 }
3817 3316
3818 /* This is redundant but I bet a lot of people expect it to exist. */ 3317 /* This is redundant but I bet a lot of people expect it to exist. */
3819 DEFUN ("glyph-height", Fglyph_height, 1, 2, 0, /* 3318 DEFUN ("glyph-height", Fglyph_height, 1, 2, 0, /*
3820 Return the height of GLYPH on WINDOW. 3319 Return the height of GLYPH on WINDOW.
3824 (glyph, window)) 3323 (glyph, window))
3825 { 3324 {
3826 XSETWINDOW (window, decode_window (window)); 3325 XSETWINDOW (window, decode_window (window));
3827 CHECK_GLYPH (glyph); 3326 CHECK_GLYPH (glyph);
3828 3327
3829 return make_int (glyph_height (glyph, window)); 3328 return make_int (glyph_height (glyph, Qnil, DEFAULT_INDEX, window));
3830 } 3329 }
3831 3330
3832 static void 3331 #undef RETURN_ASCENT
3833 set_glyph_dirty_p (Lisp_Object glyph_or_image, Lisp_Object window, int dirty) 3332 #undef RETURN_DESCENT
3834 { 3333 #undef RETURN_HEIGHT
3835 Lisp_Object instance = glyph_or_image;
3836
3837 if (!NILP (glyph_or_image))
3838 {
3839 if (GLYPHP (glyph_or_image))
3840 {
3841 instance = glyph_image_instance (glyph_or_image, window,
3842 ERROR_ME_NOT, 1);
3843 XGLYPH_DIRTYP (glyph_or_image) = dirty;
3844 }
3845
3846 if (!IMAGE_INSTANCEP (instance))
3847 return;
3848
3849 XIMAGE_INSTANCE_DIRTYP (instance) = dirty;
3850 }
3851 }
3852
3853 static void
3854 set_image_instance_dirty_p (Lisp_Object instance, int dirty)
3855 {
3856 if (IMAGE_INSTANCEP (instance))
3857 {
3858 XIMAGE_INSTANCE_DIRTYP (instance) = dirty;
3859 /* Now cascade up the hierarchy. */
3860 set_image_instance_dirty_p (XIMAGE_INSTANCE_PARENT (instance),
3861 dirty);
3862 }
3863 else if (GLYPHP (instance))
3864 {
3865 XGLYPH_DIRTYP (instance) = dirty;
3866 }
3867 }
3868 3334
3869 /* #### do we need to cache this info to speed things up? */ 3335 /* #### do we need to cache this info to speed things up? */
3870 3336
3871 Lisp_Object 3337 Lisp_Object
3872 glyph_baseline (Lisp_Object glyph, Lisp_Object domain) 3338 glyph_baseline (Lisp_Object glyph, Lisp_Object domain)
3918 { 3384 {
3919 if (XGLYPH (glyph)->after_change) 3385 if (XGLYPH (glyph)->after_change)
3920 (XGLYPH (glyph)->after_change) (glyph, property, locale); 3386 (XGLYPH (glyph)->after_change) (glyph, property, locale);
3921 } 3387 }
3922 3388
3923 #if 0 /* Not used for now */
3924 static void
3925 glyph_query_geometry (Lisp_Object glyph_or_image, Lisp_Object window,
3926 unsigned int* width, unsigned int* height,
3927 enum image_instance_geometry disp, Lisp_Object domain)
3928 {
3929 Lisp_Object instance = glyph_or_image;
3930
3931 if (GLYPHP (glyph_or_image))
3932 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1);
3933
3934 image_instance_query_geometry (instance, width, height, disp, domain);
3935 }
3936
3937 static void
3938 glyph_layout (Lisp_Object glyph_or_image, Lisp_Object window,
3939 unsigned int width, unsigned int height, Lisp_Object domain)
3940 {
3941 Lisp_Object instance = glyph_or_image;
3942
3943 if (GLYPHP (glyph_or_image))
3944 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1);
3945
3946 image_instance_layout (instance, width, height, domain);
3947 }
3948 #endif
3949
3950 3389
3951 /***************************************************************************** 3390 /*****************************************************************************
3952 * glyph cachel functions * 3391 * glyph cachel functions *
3953 *****************************************************************************/ 3392 *****************************************************************************/
3954 3393
3955 /* #### All of this is 95% copied from face cachels. Consider 3394 /*
3956 consolidating. 3395 #### All of this is 95% copied from face cachels.
3957 3396 Consider consolidating.
3958 Why do we need glyph_cachels? Simply because a glyph_cachel captures 3397 #### We need to add a dirty flag to the glyphs.
3959 per-window information about a particular glyph. A glyph itself is 3398 */
3960 not created in any particular context, so if we were to rely on a 3399
3961 glyph to tell us about its dirtiness we would not be able to reset
3962 the dirty flag after redisplaying it as it may exist in other
3963 contexts. When we have redisplayed we need to know which glyphs to
3964 reset the dirty flags on - the glyph_cachels give us a nice list we
3965 can iterate through doing this. */
3966 void 3400 void
3967 mark_glyph_cachels (glyph_cachel_dynarr *elements) 3401 mark_glyph_cachels (glyph_cachel_dynarr *elements,
3402 void (*markobj) (Lisp_Object))
3968 { 3403 {
3969 int elt; 3404 int elt;
3970 3405
3971 if (!elements) 3406 if (!elements)
3972 return; 3407 return;
3973 3408
3974 for (elt = 0; elt < Dynarr_length (elements); elt++) 3409 for (elt = 0; elt < Dynarr_length (elements); elt++)
3975 { 3410 {
3976 struct glyph_cachel *cachel = Dynarr_atp (elements, elt); 3411 struct glyph_cachel *cachel = Dynarr_atp (elements, elt);
3977 mark_object (cachel->glyph); 3412 markobj (cachel->glyph);
3978 } 3413 }
3979 } 3414 }
3980 3415
3981 static void 3416 static void
3982 update_glyph_cachel_data (struct window *w, Lisp_Object glyph, 3417 update_glyph_cachel_data (struct window *w, Lisp_Object glyph,
3983 struct glyph_cachel *cachel) 3418 struct glyph_cachel *cachel)
3984 { 3419 {
3985 if (!cachel->updated || NILP (cachel->glyph) || !EQ (cachel->glyph, glyph) 3420 /* #### This should be || !cachel->updated */
3986 || XGLYPH_DIRTYP (cachel->glyph) 3421 if (NILP (cachel->glyph) || !EQ (cachel->glyph, glyph))
3987 || XFRAME(WINDOW_FRAME(w))->faces_changed) 3422 {
3988 { 3423 Lisp_Object window;
3989 Lisp_Object window, instance;
3990 3424
3991 XSETWINDOW (window, w); 3425 XSETWINDOW (window, w);
3992 3426
3427 /* #### This could be sped up if we redid things to grab the glyph
3428 instantiation and passed it to the size functions. */
3993 cachel->glyph = glyph; 3429 cachel->glyph = glyph;
3994 /* Speed things up slightly by grabbing the glyph instantiation 3430 cachel->width = glyph_width (glyph, Qnil, DEFAULT_INDEX, window);
3995 and passing it to the size functions. */ 3431 cachel->ascent = glyph_ascent (glyph, Qnil, DEFAULT_INDEX, window);
3996 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); 3432 cachel->descent = glyph_descent (glyph, Qnil, DEFAULT_INDEX, window);
3997
3998 if (!IMAGE_INSTANCEP (instance))
3999 return;
4000
4001 /* Mark text instance of the glyph dirty if faces have changed,
4002 because its geometry might have changed. */
4003 invalidate_glyph_geometry_maybe (instance, w);
4004
4005 /* #### Do the following 2 lines buy us anything? --kkm */
4006 XGLYPH_DIRTYP (glyph) = XIMAGE_INSTANCE_DIRTYP (instance);
4007 cachel->dirty = XGLYPH_DIRTYP (glyph);
4008 cachel->width = glyph_width (instance, window);
4009 cachel->ascent = glyph_ascent (instance, window);
4010 cachel->descent = glyph_descent (instance, window);
4011 } 3433 }
4012 3434
4013 cachel->updated = 1; 3435 cachel->updated = 1;
4014 } 3436 }
4015 3437
4023 3445
4024 update_glyph_cachel_data (w, glyph, &new_cachel); 3446 update_glyph_cachel_data (w, glyph, &new_cachel);
4025 Dynarr_add (w->glyph_cachels, new_cachel); 3447 Dynarr_add (w->glyph_cachels, new_cachel);
4026 } 3448 }
4027 3449
4028 glyph_index 3450 static glyph_index
4029 get_glyph_cachel_index (struct window *w, Lisp_Object glyph) 3451 get_glyph_cachel_index (struct window *w, Lisp_Object glyph)
4030 { 3452 {
4031 int elt; 3453 int elt;
4032 3454
4033 if (noninteractive) 3455 if (noninteractive)
4038 struct glyph_cachel *cachel = 3460 struct glyph_cachel *cachel =
4039 Dynarr_atp (w->glyph_cachels, elt); 3461 Dynarr_atp (w->glyph_cachels, elt);
4040 3462
4041 if (EQ (cachel->glyph, glyph) && !NILP (glyph)) 3463 if (EQ (cachel->glyph, glyph) && !NILP (glyph))
4042 { 3464 {
4043 update_glyph_cachel_data (w, glyph, cachel); 3465 if (!cachel->updated)
3466 update_glyph_cachel_data (w, glyph, cachel);
4044 return elt; 3467 return elt;
4045 } 3468 }
4046 } 3469 }
4047 3470
4048 /* If we didn't find the glyph, add it and then return its index. */ 3471 /* If we didn't find the glyph, add it and then return its index. */
4081 FROB (Voctal_escape_glyph, OCT_ESC_GLYPH_INDEX); 3504 FROB (Voctal_escape_glyph, OCT_ESC_GLYPH_INDEX);
4082 FROB (Vinvisible_text_glyph, INVIS_GLYPH_INDEX); 3505 FROB (Vinvisible_text_glyph, INVIS_GLYPH_INDEX);
4083 #undef FROB 3506 #undef FROB
4084 3507
4085 for (elt = 0; elt < Dynarr_length (w->glyph_cachels); elt++) 3508 for (elt = 0; elt < Dynarr_length (w->glyph_cachels); elt++)
4086 { 3509 Dynarr_atp (w->glyph_cachels, elt)->updated = 0;
4087 Dynarr_atp (w->glyph_cachels, elt)->updated = 0;
4088 }
4089 }
4090
4091 /* Unset the dirty bit on all the glyph cachels that have it. */
4092 void
4093 mark_glyph_cachels_as_clean (struct window* w)
4094 {
4095 int elt;
4096 Lisp_Object window;
4097 XSETWINDOW (window, w);
4098 for (elt = 0; elt < Dynarr_length (w->glyph_cachels); elt++)
4099 {
4100 struct glyph_cachel *cachel = Dynarr_atp (w->glyph_cachels, elt);
4101 cachel->dirty = 0;
4102 set_glyph_dirty_p (cachel->glyph, window, 0);
4103 }
4104 } 3510 }
4105 3511
4106 #ifdef MEMORY_USAGE_STATS 3512 #ifdef MEMORY_USAGE_STATS
4107 3513
4108 int 3514 int
4122 3528
4123 3529
4124 /***************************************************************************** 3530 /*****************************************************************************
4125 * subwindow cachel functions * 3531 * subwindow cachel functions *
4126 *****************************************************************************/ 3532 *****************************************************************************/
4127 /* Subwindows are curious in that you have to physically unmap them to 3533 /* subwindows are curious in that you have to physically unmap them to
4128 not display them. It is problematic deciding what to do in 3534 not display them. It is problematic deciding what to do in
4129 redisplay. We have two caches - a per-window instance cache that 3535 redisplay. We have two caches - a per-window instance cache that
4130 keeps track of subwindows on a window, these are linked to their 3536 keeps track of subwindows on a window, these are linked to their
4131 instantiator in the hashtable and when the instantiator goes away 3537 instantiator in the hashtable and when the instantiator goes away
4132 we want the instance to go away also. However we also have a 3538 we want the instance to go away also. However we also have a
4133 per-frame instance cache that we use to determine if a subwindow is 3539 per-frame instance cache that we use to determine if a subwindow is
4134 obscuring an area that we want to clear. We need to be able to flip 3540 obscuring an area that we want to clear. We need to be able to flip
4135 through this quickly so a hashtable is not suitable hence the 3541 through this quickly so a hashtable is not suitable hence the
4136 subwindow_cachels. This is a weak list so unreference instances 3542 subwindow_cachels. The question is should we just not mark
4137 will get deleted properly. */ 3543 instances in the subwindow_cachelsnor should we try and invalidate
3544 the cache at suitable points in redisplay? If we don't invalidate
3545 the cache it will fill up with crud that will only get removed when
3546 the frame is deleted. So invalidation is good, the question is when
3547 and whether we mark as well. Go for the simple option - don't mark,
3548 MARK_SUBWINDOWS_CHANGED when a subwindow gets deleted. */
3549
3550 void
3551 mark_subwindow_cachels (subwindow_cachel_dynarr *elements,
3552 void (*markobj) (Lisp_Object))
3553 {
3554 int elt;
3555
3556 if (!elements)
3557 return;
3558
3559 for (elt = 0; elt < Dynarr_length (elements); elt++)
3560 {
3561 struct subwindow_cachel *cachel = Dynarr_atp (elements, elt);
3562 markobj (cachel->subwindow);
3563 }
3564 }
3565
3566 static void
3567 update_subwindow_cachel_data (struct frame *f, Lisp_Object subwindow,
3568 struct subwindow_cachel *cachel)
3569 {
3570 if (NILP (cachel->subwindow) || !EQ (cachel->subwindow, subwindow))
3571 {
3572 cachel->subwindow = subwindow;
3573 cachel->width = XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow);
3574 cachel->height = XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow);
3575 }
3576
3577 cachel->updated = 1;
3578 }
3579
3580 static void
3581 add_subwindow_cachel (struct frame *f, Lisp_Object subwindow)
3582 {
3583 struct subwindow_cachel new_cachel;
3584
3585 xzero (new_cachel);
3586 new_cachel.subwindow = Qnil;
3587 new_cachel.x=0;
3588 new_cachel.y=0;
3589 new_cachel.being_displayed=0;
3590
3591 update_subwindow_cachel_data (f, subwindow, &new_cachel);
3592 Dynarr_add (f->subwindow_cachels, new_cachel);
3593 }
3594
3595 static int
3596 get_subwindow_cachel_index (struct frame *f, Lisp_Object subwindow)
3597 {
3598 int elt;
3599
3600 if (noninteractive)
3601 return 0;
3602
3603 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
3604 {
3605 struct subwindow_cachel *cachel =
3606 Dynarr_atp (f->subwindow_cachels, elt);
3607
3608 if (EQ (cachel->subwindow, subwindow) && !NILP (subwindow))
3609 {
3610 if (!cachel->updated)
3611 update_subwindow_cachel_data (f, subwindow, cachel);
3612 return elt;
3613 }
3614 }
3615
3616 /* If we didn't find the glyph, add it and then return its index. */
3617 add_subwindow_cachel (f, subwindow);
3618 return elt;
3619 }
4138 3620
4139 /* redisplay in general assumes that drawing something will erase 3621 /* redisplay in general assumes that drawing something will erase
4140 what was there before. unfortunately this does not apply to 3622 what was there before. unfortunately this does not apply to
4141 subwindows that need to be specifically unmapped in order to 3623 subwindows that need to be specifically unmapped in order to
4142 disappear. we take a brute force approach - on the basis that its 3624 disappear. we take a brute force approach - on the basis that its
4143 cheap - and unmap all subwindows in a display line */ 3625 cheap - and unmap all subwindows in a display line */
4144
4145 /* Put new instances in the frame subwindow cache. This is less costly than
4146 doing it every time something gets mapped, and deleted instances will be
4147 removed automatically. */
4148 static void
4149 cache_subwindow_instance_in_frame_maybe (Lisp_Object instance)
4150 {
4151 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (instance);
4152 if (!NILP (DOMAIN_FRAME (IMAGE_INSTANCE_DOMAIN (ii))))
4153 {
4154 struct frame* f = DOMAIN_XFRAME (IMAGE_INSTANCE_DOMAIN (ii));
4155 XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))
4156 = Fcons (instance, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)));
4157 }
4158 }
4159
4160 /* Unmap and finalize all subwindow instances in the frame cache. This
4161 is necessary because GC will not guarantee the order things get
4162 deleted in and moreover, frame finalization deletes the window
4163 system windows before deleting XEmacs windows, and hence
4164 subwindows. */
4165 void 3626 void
4166 free_frame_subwindow_instance_cache (struct frame* f) 3627 reset_subwindow_cachels (struct frame *f)
4167 { 3628 {
4168 Lisp_Object rest; 3629 int elt;
4169 3630 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
4170 LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))) 3631 {
4171 { 3632 struct subwindow_cachel *cachel =
4172 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (XCAR (rest)); 3633 Dynarr_atp (f->subwindow_cachels, elt);
4173 /* Make sure that the subwindow is unmapped so that window 3634
4174 deletion will not try and do it again. */ 3635 if (!NILP (cachel->subwindow) && cachel->being_displayed)
4175 unmap_subwindow (XCAR (rest)); 3636 {
4176 finalize_image_instance (ii, 0); 3637 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (cachel->subwindow);
4177 } 3638 MAYBE_DEVMETH (XDEVICE (f->device), unmap_subwindow, (ii));
4178 } 3639 }
4179 3640 }
4180 /* Unmap and remove all instances from the frame cache. */ 3641 Dynarr_reset (f->subwindow_cachels);
3642 }
3643
4181 void 3644 void
4182 reset_frame_subwindow_instance_cache (struct frame* f) 3645 mark_subwindow_cachels_as_not_updated (struct frame *f)
4183 { 3646 {
4184 Lisp_Object rest; 3647 int elt;
4185 3648
4186 LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))) 3649 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
4187 { 3650 Dynarr_atp (f->subwindow_cachels, elt)->updated = 0;
4188 Lisp_Object value = XCAR (rest);
4189 /* Make sure that the subwindow is unmapped so that window
4190 deletion will not try and do it again. */
4191 unmap_subwindow (value);
4192 XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))
4193 = delq_no_quit (value, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)));
4194 }
4195 }
4196
4197 /*****************************************************************************
4198 * subwindow exposure ignorance *
4199 *****************************************************************************/
4200 /* when we unmap subwindows the associated window system will generate
4201 expose events. This we do not want as redisplay already copes with
4202 the repainting necessary. Worse, we can get in an endless cycle of
4203 redisplay if we are not careful. Thus we keep a per-frame list of
4204 expose events that are going to come and ignore them as
4205 required. */
4206
4207 struct expose_ignore_blocktype
4208 {
4209 Blocktype_declare (struct expose_ignore);
4210 } *the_expose_ignore_blocktype;
4211
4212 int
4213 check_for_ignored_expose (struct frame* f, int x, int y, int width, int height)
4214 {
4215 struct expose_ignore *ei, *prev;
4216 /* the ignore list is FIFO so we should generally get a match with
4217 the first element in the list */
4218 for (ei = f->subwindow_exposures, prev = 0; ei; ei = ei->next)
4219 {
4220 /* Checking for exact matches just isn't good enough as we
4221 mighte get exposures for partially obscure subwindows, thus
4222 we have to check for overlaps. Being conservative we will
4223 check for exposures wholly contained by the subwindow, this
4224 might give us what we want.*/
4225 if (ei->x <= x && ei->y <= y
4226 && ei->x + ei->width >= x + width
4227 && ei->y + ei->height >= y + height)
4228 {
4229 #ifdef DEBUG_WIDGETS
4230 stderr_out ("ignored %d+%d, %dx%d for exposure %d+%d, %dx%d\n",
4231 x, y, width, height, ei->x, ei->y, ei->width, ei->height);
4232 #endif
4233 if (!prev)
4234 f->subwindow_exposures = ei->next;
4235 else
4236 prev->next = ei->next;
4237
4238 if (ei == f->subwindow_exposures_tail)
4239 f->subwindow_exposures_tail = prev;
4240
4241 Blocktype_free (the_expose_ignore_blocktype, ei);
4242 return 1;
4243 }
4244 prev = ei;
4245 }
4246 return 0;
4247 }
4248
4249 static void
4250 register_ignored_expose (struct frame* f, int x, int y, int width, int height)
4251 {
4252 if (!hold_ignored_expose_registration)
4253 {
4254 struct expose_ignore *ei;
4255
4256 ei = Blocktype_alloc (the_expose_ignore_blocktype);
4257
4258 ei->next = NULL;
4259 ei->x = x;
4260 ei->y = y;
4261 ei->width = width;
4262 ei->height = height;
4263
4264 /* we have to add the exposure to the end of the list, since we
4265 want to check the oldest events first. for speed we keep a record
4266 of the end so that we can add right to it. */
4267 if (f->subwindow_exposures_tail)
4268 {
4269 f->subwindow_exposures_tail->next = ei;
4270 }
4271 if (!f->subwindow_exposures)
4272 {
4273 f->subwindow_exposures = ei;
4274 }
4275 f->subwindow_exposures_tail = ei;
4276 }
4277 }
4278
4279 /****************************************************************************
4280 find_matching_subwindow
4281
4282 See if there is a subwindow that completely encloses the requested
4283 area.
4284 ****************************************************************************/
4285 int find_matching_subwindow (struct frame* f, int x, int y, int width, int height)
4286 {
4287 Lisp_Object rest;
4288
4289 LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))
4290 {
4291 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (XCAR (rest));
4292
4293 if (IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii)
4294 &&
4295 IMAGE_INSTANCE_DISPLAY_X (ii) <= x
4296 &&
4297 IMAGE_INSTANCE_DISPLAY_Y (ii) <= y
4298 &&
4299 IMAGE_INSTANCE_DISPLAY_X (ii)
4300 + IMAGE_INSTANCE_DISPLAY_WIDTH (ii) >= x + width
4301 &&
4302 IMAGE_INSTANCE_DISPLAY_Y (ii)
4303 + IMAGE_INSTANCE_DISPLAY_HEIGHT (ii) >= y + height)
4304 {
4305 return 1;
4306 }
4307 }
4308 return 0;
4309 } 3651 }
4310 3652
4311 3653
4312 /***************************************************************************** 3654 /*****************************************************************************
4313 * subwindow functions * 3655 * subwindow functions *
4314 *****************************************************************************/ 3656 *****************************************************************************/
4315 3657
4316 /* Update the displayed characteristics of a subwindow. This function 3658 /* update the displayed characteristics of a subwindow */
4317 should generally only get called if the subwindow is actually 3659 static void
4318 dirty. */ 3660 update_subwindow (Lisp_Object subwindow)
3661 {
3662 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
3663
3664 if (!IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET
3665 ||
3666 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))
3667 return;
3668
3669 MAYBE_DEVMETH (XDEVICE (ii->device), update_subwindow, (ii));
3670 }
3671
4319 void 3672 void
4320 update_subwindow (Lisp_Object subwindow) 3673 update_frame_subwindows (struct frame *f)
4321 { 3674 {
4322 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); 3675 int elt;
4323 int count = specpdl_depth (); 3676
4324 3677 if (f->subwindows_changed || f->glyphs_changed)
4325 /* The update method is allowed to call eval. Since it is quite 3678 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
4326 common for this function to get called from somewhere in 3679 {
4327 redisplay we need to make sure that quits are ignored. Otherwise 3680 struct subwindow_cachel *cachel =
4328 Fsignal will abort. */ 3681 Dynarr_atp (f->subwindow_cachels, elt);
4329 specbind (Qinhibit_quit, Qt); 3682
4330 3683 if (cachel->being_displayed)
4331 ERROR_CHECK_IMAGE_INSTANCE (subwindow); 3684 {
4332 3685 update_subwindow (cachel->subwindow);
4333 if (WIDGET_IMAGE_INSTANCEP (subwindow)) 3686 }
4334 { 3687 }
4335 if (image_instance_changed (subwindow))
4336 update_widget (subwindow);
4337 /* Reset the changed flags. */
4338 IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) = 0;
4339 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
4340 IMAGE_INSTANCE_TEXT_CHANGED (ii) = 0;
4341 }
4342 else if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW
4343 &&
4344 !NILP (IMAGE_INSTANCE_FRAME (ii)))
4345 {
4346 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
4347 update_subwindow, (ii));
4348 }
4349
4350 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 0;
4351 /* This function is typically called by redisplay just before
4352 outputting the information to the screen. Thus we record a hash
4353 of the output to determine whether on-screen is the same as
4354 recorded structure. This approach has limitations in there is a
4355 good chance that hash values will be different for the same
4356 visual appearance. However, we would rather that then the other
4357 way round - it simply means that we will get more displays than
4358 we might need. We can get better hashing by making the depth
4359 negative - currently it will recurse down 7 levels.*/
4360 IMAGE_INSTANCE_DISPLAY_HASH (ii) = internal_hash (subwindow,
4361 IMAGE_INSTANCE_HASH_DEPTH);
4362
4363 unbind_to (count, Qnil);
4364 }
4365
4366 int
4367 image_instance_changed (Lisp_Object subwindow)
4368 {
4369 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
4370
4371 if (internal_hash (subwindow, IMAGE_INSTANCE_HASH_DEPTH) !=
4372 IMAGE_INSTANCE_DISPLAY_HASH (ii))
4373 return 1;
4374 /* #### I think there is probably a bug here. This gets called for
4375 layouts - and yet the pending items are always nil for
4376 layouts. We are saved by layout optimization, but I'm undecided
4377 as to what the correct fix is. */
4378 else if (WIDGET_IMAGE_INSTANCEP (subwindow)
4379 && (!internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (ii),
4380 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii), 0)
4381 || !NILP (IMAGE_INSTANCE_LAYOUT_CHILDREN (ii))))
4382 return 1;
4383 else
4384 return 0;
4385 }
4386
4387 /* Update all the subwindows on a frame. */
4388 void
4389 update_widget_instances (Lisp_Object frame)
4390 {
4391 struct frame* f;
4392 Lisp_Object rest;
4393
4394 /* Its possible for the preceeding callback to have deleted the
4395 frame, so cope with this. */
4396 if (!FRAMEP (frame) || !FRAME_LIVE_P (XFRAME (frame)))
4397 return;
4398
4399 CHECK_FRAME (frame);
4400 f = XFRAME (frame);
4401
4402 /* If we get called we know something has changed. */
4403 LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))
4404 {
4405 Lisp_Object widget = XCAR (rest);
4406
4407 if (XIMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (widget)
4408 &&
4409 image_instance_changed (widget))
4410 {
4411 set_image_instance_dirty_p (widget, 1);
4412 MARK_FRAME_GLYPHS_CHANGED (f);
4413 }
4414 }
4415 } 3688 }
4416 3689
4417 /* remove a subwindow from its frame */ 3690 /* remove a subwindow from its frame */
4418 void unmap_subwindow (Lisp_Object subwindow) 3691 void unmap_subwindow (Lisp_Object subwindow)
4419 { 3692 {
4420 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); 3693 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
3694 int elt;
3695 struct subwindow_cachel* cachel;
4421 struct frame* f; 3696 struct frame* f;
4422 3697
4423 ERROR_CHECK_IMAGE_INSTANCE (subwindow); 3698 if (!(IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET
4424 3699 ||
4425 if (!image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (ii)) 3700 IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW)
4426 & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK)
4427 || 3701 ||
4428 !IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii)) 3702 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))
4429 return; 3703 return;
4430 3704
4431 #ifdef DEBUG_WIDGETS 3705 f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
4432 stderr_out ("unmapping subwindow %d\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii)); 3706 elt = get_subwindow_cachel_index (f, subwindow);
4433 #endif 3707 cachel = Dynarr_atp (f->subwindow_cachels, elt);
4434 f = XFRAME (IMAGE_INSTANCE_FRAME (ii)); 3708
4435 3709 cachel->x = -1;
4436 /* make sure we don't get expose events */ 3710 cachel->y = -1;
4437 register_ignored_expose (f, IMAGE_INSTANCE_DISPLAY_X (ii), 3711 cachel->being_displayed = 0;
4438 IMAGE_INSTANCE_DISPLAY_Y (ii),
4439 IMAGE_INSTANCE_DISPLAY_WIDTH (ii),
4440 IMAGE_INSTANCE_DISPLAY_HEIGHT (ii));
4441 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; 3712 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0;
4442 3713
4443 MAYBE_DEVMETH (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)), 3714 MAYBE_DEVMETH (XDEVICE (ii->device), unmap_subwindow, (ii));
4444 unmap_subwindow, (ii));
4445 } 3715 }
4446 3716
4447 /* show a subwindow in its frame */ 3717 /* show a subwindow in its frame */
4448 void map_subwindow (Lisp_Object subwindow, int x, int y, 3718 void map_subwindow (Lisp_Object subwindow, int x, int y)
4449 struct display_glyph_area *dga) 3719 {
4450 { 3720 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
4451 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); 3721 int elt;
3722 struct subwindow_cachel* cachel;
4452 struct frame* f; 3723 struct frame* f;
4453 3724
4454 ERROR_CHECK_IMAGE_INSTANCE (subwindow); 3725 if (!(IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET
4455 3726 ||
4456 if (!image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (ii)) 3727 IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW)
4457 & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK)) 3728 ||
3729 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))
4458 return; 3730 return;
4459 3731
4460 #ifdef DEBUG_WIDGETS 3732 f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
4461 stderr_out ("mapping subwindow %d, %dx%d@%d+%d\n",
4462 IMAGE_INSTANCE_SUBWINDOW_ID (ii),
4463 dga->width, dga->height, x, y);
4464 #endif
4465 f = XFRAME (IMAGE_INSTANCE_FRAME (ii));
4466 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 1; 3733 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 1;
4467 IMAGE_INSTANCE_DISPLAY_X (ii) = x; 3734 elt = get_subwindow_cachel_index (f, subwindow);
4468 IMAGE_INSTANCE_DISPLAY_Y (ii) = y; 3735 cachel = Dynarr_atp (f->subwindow_cachels, elt);
4469 IMAGE_INSTANCE_DISPLAY_WIDTH (ii) = dga->width; 3736 cachel->x = x;
4470 IMAGE_INSTANCE_DISPLAY_HEIGHT (ii) = dga->height; 3737 cachel->y = y;
4471 3738 cachel->being_displayed = 1;
4472 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), 3739
4473 map_subwindow, (ii, x, y, dga)); 3740 MAYBE_DEVMETH (XDEVICE (ii->device), map_subwindow, (ii, x, y));
4474 } 3741 }
4475 3742
4476 static int 3743 static int
4477 subwindow_possible_dest_types (void) 3744 subwindow_possible_dest_types (void)
4478 { 3745 {
4479 return IMAGE_SUBWINDOW_MASK; 3746 return IMAGE_SUBWINDOW_MASK;
4480 }
4481
4482 int
4483 subwindow_governing_domain (void)
4484 {
4485 return GOVERNING_DOMAIN_WINDOW;
4486 } 3747 }
4487 3748
4488 /* Partially instantiate a subwindow. */ 3749 /* Partially instantiate a subwindow. */
4489 void 3750 void
4490 subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, 3751 subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
4491 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 3752 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
4492 int dest_mask, Lisp_Object domain) 3753 int dest_mask, Lisp_Object domain)
4493 { 3754 {
4494 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 3755 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
4495 Lisp_Object device = image_instance_device (image_instance); 3756 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
4496 Lisp_Object frame = DOMAIN_FRAME (domain); 3757 Lisp_Object frame = FW_FRAME (domain);
4497 Lisp_Object width = find_keyword_in_vector (instantiator, Q_pixel_width); 3758 Lisp_Object width = find_keyword_in_vector (instantiator, Q_pixel_width);
4498 Lisp_Object height = find_keyword_in_vector (instantiator, Q_pixel_height); 3759 Lisp_Object height = find_keyword_in_vector (instantiator, Q_pixel_height);
4499 3760
4500 if (NILP (frame)) 3761 if (NILP (frame))
4501 signal_simple_error ("No selected frame", device); 3762 signal_simple_error ("No selected frame", device);
4502 3763
4503 if (!(dest_mask & IMAGE_SUBWINDOW_MASK)) 3764 if (!(dest_mask & IMAGE_SUBWINDOW_MASK))
4504 incompatible_image_types (instantiator, dest_mask, IMAGE_SUBWINDOW_MASK); 3765 incompatible_image_types (instantiator, dest_mask, IMAGE_SUBWINDOW_MASK);
4505 3766
4506 ii->data = 0; 3767 ii->data = 0;
4507 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0; 3768 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0;
3769 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = Qnil;
4508 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; 3770 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0;
4509 3771 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = frame;
4510 if (INTP (width)) 3772
3773 /* this stuff may get overidden by the widget code */
3774 if (NILP (width))
3775 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = 20;
3776 else
4511 { 3777 {
4512 int w = 1; 3778 int w = 1;
3779 CHECK_INT (width);
4513 if (XINT (width) > 1) 3780 if (XINT (width) > 1)
4514 w = XINT (width); 3781 w = XINT (width);
4515 IMAGE_INSTANCE_WIDTH (ii) = w; 3782 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = w;
4516 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0; 3783 }
4517 } 3784 if (NILP (height))
4518 3785 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = 20;
4519 if (INTP (height)) 3786 else
4520 { 3787 {
4521 int h = 1; 3788 int h = 1;
3789 CHECK_INT (height);
4522 if (XINT (height) > 1) 3790 if (XINT (height) > 1)
4523 h = XINT (height); 3791 h = XINT (height);
4524 IMAGE_INSTANCE_HEIGHT (ii) = h; 3792 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = h;
4525 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0; 3793 }
4526 }
4527 }
4528
4529 /* This is just a backup in case no-one has assigned a suitable geometry.
4530 #### It should really query the enclose window for geometry. */
4531 static void
4532 subwindow_query_geometry (Lisp_Object image_instance, int* width,
4533 int* height, enum image_instance_geometry disp,
4534 Lisp_Object domain)
4535 {
4536 if (width) *width = 20;
4537 if (height) *height = 20;
4538 } 3794 }
4539 3795
4540 DEFUN ("subwindowp", Fsubwindowp, 1, 1, 0, /* 3796 DEFUN ("subwindowp", Fsubwindowp, 1, 1, 0, /*
4541 Return non-nil if OBJECT is a subwindow. 3797 Return non-nil if OBJECT is a subwindow.
4542 */ 3798 */
4550 Return the window id of SUBWINDOW as a number. 3806 Return the window id of SUBWINDOW as a number.
4551 */ 3807 */
4552 (subwindow)) 3808 (subwindow))
4553 { 3809 {
4554 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); 3810 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow);
4555 return make_int ((int) XIMAGE_INSTANCE_SUBWINDOW_ID (subwindow)); 3811 return make_int ((int) (XIMAGE_INSTANCE_SUBWINDOW_ID (subwindow)));
4556 } 3812 }
4557 3813
4558 DEFUN ("resize-subwindow", Fresize_subwindow, 1, 3, 0, /* 3814 DEFUN ("resize-subwindow", Fresize_subwindow, 1, 3, 0, /*
4559 Resize SUBWINDOW to WIDTH x HEIGHT. 3815 Resize SUBWINDOW to WIDTH x HEIGHT.
4560 If a value is nil that parameter is not changed. 3816 If a value is nil that parameter is not changed.
4561 */ 3817 */
4562 (subwindow, width, height)) 3818 (subwindow, width, height))
4563 { 3819 {
4564 int neww, newh; 3820 int neww, newh;
4565 Lisp_Image_Instance* ii;
4566 3821
4567 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); 3822 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow);
4568 ii = XIMAGE_INSTANCE (subwindow);
4569 3823
4570 if (NILP (width)) 3824 if (NILP (width))
4571 neww = IMAGE_INSTANCE_WIDTH (ii); 3825 neww = XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow);
4572 else 3826 else
4573 neww = XINT (width); 3827 neww = XINT (width);
4574 3828
4575 if (NILP (height)) 3829 if (NILP (height))
4576 newh = IMAGE_INSTANCE_HEIGHT (ii); 3830 newh = XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow);
4577 else 3831 else
4578 newh = XINT (height); 3832 newh = XINT (height);
4579 3833
4580 /* The actual resizing gets done asychronously by 3834
4581 update_subwindow. */ 3835 MAYBE_DEVMETH (XDEVICE (XIMAGE_INSTANCE_DEVICE (subwindow)),
4582 IMAGE_INSTANCE_HEIGHT (ii) = newh; 3836 resize_subwindow, (XIMAGE_INSTANCE (subwindow), neww, newh));
4583 IMAGE_INSTANCE_WIDTH (ii) = neww; 3837
4584 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 1; 3838 XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow) = newh;
3839 XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow) = neww;
4585 3840
4586 return subwindow; 3841 return subwindow;
4587 } 3842 }
4588 3843
4589 DEFUN ("force-subwindow-map", Fforce_subwindow_map, 1, 1, 0, /* 3844 DEFUN ("force-subwindow-map", Fforce_subwindow_map, 1, 1, 0, /*
4590 Generate a Map event for SUBWINDOW. 3845 Generate a Map event for SUBWINDOW.
4591 */ 3846 */
4592 (subwindow)) 3847 (subwindow))
4593 { 3848 {
4594 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); 3849 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow);
4595 #if 0 3850
4596 map_subwindow (subwindow, 0, 0); 3851 map_subwindow (subwindow, 0, 0);
4597 #endif 3852
4598 return subwindow; 3853 return subwindow;
4599 } 3854 }
4600 3855
4601 3856
4602 /***************************************************************************** 3857 /*****************************************************************************
4678 } 3933 }
4679 else 3934 else
4680 abort (); 3935 abort ();
4681 } 3936 }
4682 } 3937 }
4683
4684 /*****************************************************************************
4685 * timeouts for animated glyphs *
4686 *****************************************************************************/
4687 static Lisp_Object Qglyph_animated_timeout_handler;
4688
4689 DEFUN ("glyph-animated-timeout-handler", Fglyph_animated_timeout_handler, 1, 1, 0, /*
4690 Callback function for updating animated images.
4691 Don't use this.
4692 */
4693 (arg))
4694 {
4695 CHECK_WEAK_LIST (arg);
4696
4697 if (!NILP (XWEAK_LIST_LIST (arg)) && !NILP (XCAR (XWEAK_LIST_LIST (arg))))
4698 {
4699 Lisp_Object value = XCAR (XWEAK_LIST_LIST (arg));
4700
4701 if (IMAGE_INSTANCEP (value))
4702 {
4703 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (value);
4704
4705 if (COLOR_PIXMAP_IMAGE_INSTANCEP (value)
4706 &&
4707 IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) > 1
4708 &&
4709 !disable_animated_pixmaps)
4710 {
4711 /* Increment the index of the image slice we are currently
4712 viewing. */
4713 IMAGE_INSTANCE_PIXMAP_SLICE (ii) =
4714 (IMAGE_INSTANCE_PIXMAP_SLICE (ii) + 1)
4715 % IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii);
4716 /* We might need to kick redisplay at this point - but we
4717 also might not. */
4718 MARK_DEVICE_FRAMES_GLYPHS_CHANGED
4719 (XDEVICE (image_instance_device (value)));
4720 /* Cascade dirtiness so that we can have an animated glyph in a layout
4721 for instance. */
4722 set_image_instance_dirty_p (value, 1);
4723 }
4724 }
4725 }
4726 return Qnil;
4727 }
4728
4729 Lisp_Object add_glyph_animated_timeout (EMACS_INT tickms, Lisp_Object image)
4730 {
4731 Lisp_Object ret = Qnil;
4732
4733 if (tickms > 0 && IMAGE_INSTANCEP (image))
4734 {
4735 double ms = ((double)tickms) / 1000.0;
4736 struct gcpro gcpro1;
4737 Lisp_Object holder = make_weak_list (WEAK_LIST_SIMPLE);
4738
4739 GCPRO1 (holder);
4740 XWEAK_LIST_LIST (holder) = Fcons (image, Qnil);
4741
4742 ret = Fadd_timeout (make_float (ms),
4743 Qglyph_animated_timeout_handler,
4744 holder, make_float (ms));
4745
4746 UNGCPRO;
4747 }
4748 return ret;
4749 }
4750
4751 void disable_glyph_animated_timeout (int i)
4752 {
4753 Lisp_Object id;
4754 XSETINT (id, i);
4755
4756 Fdisable_timeout (id);
4757 }
4758
4759 3938
4760 /***************************************************************************** 3939 /*****************************************************************************
4761 * initialization * 3940 * initialization *
4762 *****************************************************************************/ 3941 *****************************************************************************/
4763 3942
4764 void 3943 void
4765 syms_of_glyphs (void) 3944 syms_of_glyphs (void)
4766 { 3945 {
4767 INIT_LRECORD_IMPLEMENTATION (glyph);
4768 INIT_LRECORD_IMPLEMENTATION (image_instance);
4769
4770 /* image instantiators */ 3946 /* image instantiators */
4771 3947
4772 DEFSUBR (Fimage_instantiator_format_list); 3948 DEFSUBR (Fimage_instantiator_format_list);
4773 DEFSUBR (Fvalid_image_instantiator_format_p); 3949 DEFSUBR (Fvalid_image_instantiator_format_p);
4774 DEFSUBR (Fset_console_type_image_conversion_list); 3950 DEFSUBR (Fset_console_type_image_conversion_list);
4812 DEFSUBR (Fimage_instance_p); 3988 DEFSUBR (Fimage_instance_p);
4813 DEFSUBR (Fimage_instance_type); 3989 DEFSUBR (Fimage_instance_type);
4814 DEFSUBR (Fvalid_image_instance_type_p); 3990 DEFSUBR (Fvalid_image_instance_type_p);
4815 DEFSUBR (Fimage_instance_type_list); 3991 DEFSUBR (Fimage_instance_type_list);
4816 DEFSUBR (Fimage_instance_name); 3992 DEFSUBR (Fimage_instance_name);
4817 DEFSUBR (Fimage_instance_domain);
4818 DEFSUBR (Fimage_instance_string); 3993 DEFSUBR (Fimage_instance_string);
4819 DEFSUBR (Fimage_instance_file_name); 3994 DEFSUBR (Fimage_instance_file_name);
4820 DEFSUBR (Fimage_instance_mask_file_name); 3995 DEFSUBR (Fimage_instance_mask_file_name);
4821 DEFSUBR (Fimage_instance_depth); 3996 DEFSUBR (Fimage_instance_depth);
4822 DEFSUBR (Fimage_instance_height); 3997 DEFSUBR (Fimage_instance_height);
4864 DEFSUBR (Fglyph_height); 4039 DEFSUBR (Fglyph_height);
4865 4040
4866 /* Qbuffer defined in general.c. */ 4041 /* Qbuffer defined in general.c. */
4867 /* Qpointer defined above */ 4042 /* Qpointer defined above */
4868 4043
4869 /* Unfortunately, timeout handlers must be lisp functions. This is
4870 for animated glyphs. */
4871 defsymbol (&Qglyph_animated_timeout_handler,
4872 "glyph-animated-timeout-handler");
4873 DEFSUBR (Fglyph_animated_timeout_handler);
4874
4875 /* Errors */ 4044 /* Errors */
4876 deferror (&Qimage_conversion_error, 4045 deferror (&Qimage_conversion_error,
4877 "image-conversion-error", 4046 "image-conversion-error",
4878 "image-conversion error", Qio_error); 4047 "image-conversion error", Qio_error);
4879 4048
4880 } 4049 }
4881
4882 static const struct lrecord_description image_specifier_description[] = {
4883 { XD_LISP_OBJECT, specifier_data_offset + offsetof (struct image_specifier, attachee) },
4884 { XD_LISP_OBJECT, specifier_data_offset + offsetof (struct image_specifier, attachee_property) },
4885 { XD_END }
4886 };
4887 4050
4888 void 4051 void
4889 specifier_type_create_image (void) 4052 specifier_type_create_image (void)
4890 { 4053 {
4891 /* image specifiers */ 4054 /* image specifiers */
4896 SPECIFIER_HAS_METHOD (image, mark); 4059 SPECIFIER_HAS_METHOD (image, mark);
4897 SPECIFIER_HAS_METHOD (image, instantiate); 4060 SPECIFIER_HAS_METHOD (image, instantiate);
4898 SPECIFIER_HAS_METHOD (image, validate); 4061 SPECIFIER_HAS_METHOD (image, validate);
4899 SPECIFIER_HAS_METHOD (image, after_change); 4062 SPECIFIER_HAS_METHOD (image, after_change);
4900 SPECIFIER_HAS_METHOD (image, going_to_add); 4063 SPECIFIER_HAS_METHOD (image, going_to_add);
4901 SPECIFIER_HAS_METHOD (image, copy_instantiator); 4064 }
4902 }
4903
4904 void
4905 reinit_specifier_type_create_image (void)
4906 {
4907 REINITIALIZE_SPECIFIER_TYPE (image);
4908 }
4909
4910
4911 static const struct lrecord_description iike_description_1[] = {
4912 { XD_LISP_OBJECT, offsetof (ii_keyword_entry, keyword) },
4913 { XD_END }
4914 };
4915
4916 static const struct struct_description iike_description = {
4917 sizeof (ii_keyword_entry),
4918 iike_description_1
4919 };
4920
4921 static const struct lrecord_description iiked_description_1[] = {
4922 XD_DYNARR_DESC (ii_keyword_entry_dynarr, &iike_description),
4923 { XD_END }
4924 };
4925
4926 static const struct struct_description iiked_description = {
4927 sizeof (ii_keyword_entry_dynarr),
4928 iiked_description_1
4929 };
4930
4931 static const struct lrecord_description iife_description_1[] = {
4932 { XD_LISP_OBJECT, offsetof (image_instantiator_format_entry, symbol) },
4933 { XD_LISP_OBJECT, offsetof (image_instantiator_format_entry, device) },
4934 { XD_STRUCT_PTR, offsetof (image_instantiator_format_entry, meths), 1, &iim_description },
4935 { XD_END }
4936 };
4937
4938 static const struct struct_description iife_description = {
4939 sizeof (image_instantiator_format_entry),
4940 iife_description_1
4941 };
4942
4943 static const struct lrecord_description iifed_description_1[] = {
4944 XD_DYNARR_DESC (image_instantiator_format_entry_dynarr, &iife_description),
4945 { XD_END }
4946 };
4947
4948 static const struct struct_description iifed_description = {
4949 sizeof (image_instantiator_format_entry_dynarr),
4950 iifed_description_1
4951 };
4952
4953 static const struct lrecord_description iim_description_1[] = {
4954 { XD_LISP_OBJECT, offsetof (struct image_instantiator_methods, symbol) },
4955 { XD_LISP_OBJECT, offsetof (struct image_instantiator_methods, device) },
4956 { XD_STRUCT_PTR, offsetof (struct image_instantiator_methods, keywords), 1, &iiked_description },
4957 { XD_STRUCT_PTR, offsetof (struct image_instantiator_methods, consoles), 1, &cted_description },
4958 { XD_END }
4959 };
4960
4961 const struct struct_description iim_description = {
4962 sizeof(struct image_instantiator_methods),
4963 iim_description_1
4964 };
4965 4065
4966 void 4066 void
4967 image_instantiator_format_create (void) 4067 image_instantiator_format_create (void)
4968 { 4068 {
4969 /* image instantiators */ 4069 /* image instantiators */
4971 the_image_instantiator_format_entry_dynarr = 4071 the_image_instantiator_format_entry_dynarr =
4972 Dynarr_new (image_instantiator_format_entry); 4072 Dynarr_new (image_instantiator_format_entry);
4973 4073
4974 Vimage_instantiator_format_list = Qnil; 4074 Vimage_instantiator_format_list = Qnil;
4975 staticpro (&Vimage_instantiator_format_list); 4075 staticpro (&Vimage_instantiator_format_list);
4976
4977 dumpstruct (&the_image_instantiator_format_entry_dynarr, &iifed_description);
4978 4076
4979 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (nothing, "nothing"); 4077 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (nothing, "nothing");
4980 4078
4981 IIFORMAT_HAS_METHOD (nothing, possible_dest_types); 4079 IIFORMAT_HAS_METHOD (nothing, possible_dest_types);
4982 IIFORMAT_HAS_METHOD (nothing, instantiate); 4080 IIFORMAT_HAS_METHOD (nothing, instantiate);
4991 IIFORMAT_VALID_KEYWORD (inherit, Q_face, check_valid_face); 4089 IIFORMAT_VALID_KEYWORD (inherit, Q_face, check_valid_face);
4992 4090
4993 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (string, "string"); 4091 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (string, "string");
4994 4092
4995 IIFORMAT_HAS_METHOD (string, validate); 4093 IIFORMAT_HAS_METHOD (string, validate);
4996 IIFORMAT_HAS_SHARED_METHOD (string, governing_domain, subwindow);
4997 IIFORMAT_HAS_METHOD (string, possible_dest_types); 4094 IIFORMAT_HAS_METHOD (string, possible_dest_types);
4998 IIFORMAT_HAS_METHOD (string, instantiate); 4095 IIFORMAT_HAS_METHOD (string, instantiate);
4999 4096
5000 IIFORMAT_VALID_KEYWORD (string, Q_data, check_valid_string); 4097 IIFORMAT_VALID_KEYWORD (string, Q_data, check_valid_string);
5001 /* Do this so we can set strings. */
5002 /* #### Andy, what is this? This is a bogus format and should not be
5003 visible to the user. */
5004 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (text, "text");
5005 IIFORMAT_HAS_METHOD (text, set_property);
5006 IIFORMAT_HAS_METHOD (text, query_geometry);
5007 4098
5008 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (formatted_string, "formatted-string"); 4099 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (formatted_string, "formatted-string");
5009 4100
5010 IIFORMAT_HAS_METHOD (formatted_string, validate); 4101 IIFORMAT_HAS_METHOD (formatted_string, validate);
5011 IIFORMAT_HAS_METHOD (formatted_string, possible_dest_types); 4102 IIFORMAT_HAS_METHOD (formatted_string, possible_dest_types);
5012 IIFORMAT_HAS_METHOD (formatted_string, instantiate); 4103 IIFORMAT_HAS_METHOD (formatted_string, instantiate);
4104
5013 IIFORMAT_VALID_KEYWORD (formatted_string, Q_data, check_valid_string); 4105 IIFORMAT_VALID_KEYWORD (formatted_string, Q_data, check_valid_string);
5014
5015 /* Do this so pointers have geometry. */
5016 /* #### Andy, what is this? This is a bogus format and should not be
5017 visible to the user. */
5018 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (pointer, "pointer");
5019 IIFORMAT_HAS_SHARED_METHOD (pointer, query_geometry, subwindow);
5020 4106
5021 /* subwindows */ 4107 /* subwindows */
5022 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (subwindow, "subwindow"); 4108 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (subwindow, "subwindow");
5023 IIFORMAT_HAS_METHOD (subwindow, possible_dest_types); 4109 IIFORMAT_HAS_METHOD (subwindow, possible_dest_types);
5024 IIFORMAT_HAS_METHOD (subwindow, governing_domain);
5025 IIFORMAT_HAS_METHOD (subwindow, instantiate); 4110 IIFORMAT_HAS_METHOD (subwindow, instantiate);
5026 IIFORMAT_HAS_METHOD (subwindow, query_geometry);
5027 IIFORMAT_VALID_KEYWORD (subwindow, Q_pixel_width, check_valid_int); 4111 IIFORMAT_VALID_KEYWORD (subwindow, Q_pixel_width, check_valid_int);
5028 IIFORMAT_VALID_KEYWORD (subwindow, Q_pixel_height, check_valid_int); 4112 IIFORMAT_VALID_KEYWORD (subwindow, Q_pixel_height, check_valid_int);
5029 4113
5030 #ifdef HAVE_WINDOW_SYSTEM 4114 #ifdef HAVE_WINDOW_SYSTEM
5031 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xbm, "xbm"); 4115 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xbm, "xbm");
5071 IIFORMAT_VALID_KEYWORD (xpm, Q_color_symbols, check_valid_xpm_color_symbols); 4155 IIFORMAT_VALID_KEYWORD (xpm, Q_color_symbols, check_valid_xpm_color_symbols);
5072 #endif /* HAVE_XPM */ 4156 #endif /* HAVE_XPM */
5073 } 4157 }
5074 4158
5075 void 4159 void
5076 reinit_vars_of_glyphs (void)
5077 {
5078 the_expose_ignore_blocktype =
5079 Blocktype_new (struct expose_ignore_blocktype);
5080
5081 hold_ignored_expose_registration = 0;
5082 }
5083
5084
5085 void
5086 vars_of_glyphs (void) 4160 vars_of_glyphs (void)
5087 { 4161 {
5088 reinit_vars_of_glyphs ();
5089
5090 Vthe_nothing_vector = vector1 (Qnothing); 4162 Vthe_nothing_vector = vector1 (Qnothing);
5091 staticpro (&Vthe_nothing_vector); 4163 staticpro (&Vthe_nothing_vector);
5092 4164
5093 /* image instances */ 4165 /* image instances */
5094 4166
5095 Vimage_instance_type_list = Fcons (Qnothing, 4167 Vimage_instance_type_list = Fcons (Qnothing,
5096 list6 (Qtext, Qmono_pixmap, Qcolor_pixmap, 4168 list6 (Qtext, Qmono_pixmap, Qcolor_pixmap,
5097 Qpointer, Qsubwindow, Qwidget)); 4169 Qpointer, Qsubwindow, Qwidget));
5098 staticpro (&Vimage_instance_type_list); 4170 staticpro (&Vimage_instance_type_list);
5099 4171
5100 /* glyphs */ 4172 /* glyphs */
5101 4173
5150 Vxpm_color_symbols = Qnil; /* initialized in x-faces.el */ 4222 Vxpm_color_symbols = Qnil; /* initialized in x-faces.el */
5151 #endif /* HAVE_XPM */ 4223 #endif /* HAVE_XPM */
5152 #ifdef HAVE_XFACE 4224 #ifdef HAVE_XFACE
5153 Fprovide (Qxface); 4225 Fprovide (Qxface);
5154 #endif 4226 #endif
5155
5156 DEFVAR_BOOL ("disable-animated-pixmaps", &disable_animated_pixmaps /*
5157 Whether animated pixmaps should be animated.
5158 Default is t.
5159 */);
5160 disable_animated_pixmaps = 0;
5161 } 4227 }
5162 4228
5163 void 4229 void
5164 specifier_vars_of_glyphs (void) 4230 specifier_vars_of_glyphs (void)
5165 { 4231 {
5168 /* display tables */ 4234 /* display tables */
5169 4235
5170 DEFVAR_SPECIFIER ("current-display-table", &Vcurrent_display_table /* 4236 DEFVAR_SPECIFIER ("current-display-table", &Vcurrent_display_table /*
5171 *The display table currently in use. 4237 *The display table currently in use.
5172 This is a specifier; use `set-specifier' to change it. 4238 This is a specifier; use `set-specifier' to change it.
5173 4239 The display table is a vector created with `make-display-table'.
5174 Display tables are used to control how characters are displayed. Each 4240 The 256 elements control how to display each possible text character.
5175 time that redisplay processes a character, it is looked up in all the 4241 Each value should be a string, a glyph, a vector or nil.
5176 display tables that apply (obtained by calling `specifier-instance' on 4242 If a value is a vector it must be composed only of strings and glyphs.
5177 `current-display-table' and any overriding display tables specified in 4243 nil means display the character in the default fashion.
5178 currently active faces). The first entry found that matches the 4244 Faces can have their own, overriding display table.
5179 character determines how the character is displayed. If there is no
5180 matching entry, the default display method is used. (Non-control
5181 characters are displayed as themselves and control characters are
5182 displayed according to the buffer-local variable `ctl-arrow'. Control
5183 characters are further affected by `control-arrow-glyph' and
5184 `octal-escape-glyph'.)
5185
5186 Each instantiator in this specifier and the display-table specifiers
5187 in faces is a display table or a list of such tables. If a list, each
5188 table will be searched in turn for an entry matching a particular
5189 character. Each display table is one of
5190
5191 -- a vector, specifying values for characters starting at 0
5192 -- a char table, either of type `char' or `generic'
5193 -- a range table
5194
5195 Each entry in a display table should be one of
5196
5197 -- nil (this entry is ignored and the search continues)
5198 -- a character (use this character; if it happens to be the same as
5199 the original character, default processing happens, otherwise
5200 redisplay attempts to display this character directly;
5201 #### At some point recursive display-table lookup will be
5202 implemented.)
5203 -- a string (display each character in the string directly;
5204 #### At some point recursive display-table lookup will be
5205 implemented.)
5206 -- a glyph (display the glyph;
5207 #### At some point recursive display-table lookup will be
5208 implemented when a string glyph is being processed.)
5209 -- a cons of the form (format "STRING") where STRING is a printf-like
5210 spec used to process the character. #### Unfortunately no
5211 formatting directives other than %% are implemented.
5212 -- a vector (each element of the vector is processed recursively;
5213 in such a case, nil elements in the vector are simply ignored)
5214
5215 #### At some point in the near future, display tables are likely to
5216 be expanded to include other features, such as referencing characters
5217 in particular fonts and allowing the character search to continue
5218 all the way up the chain of specifier instantiators. These features
5219 are necessary to properly display Unicode characters.
5220 */ ); 4245 */ );
5221 Vcurrent_display_table = Fmake_specifier (Qdisplay_table); 4246 Vcurrent_display_table = Fmake_specifier (Qdisplay_table);
5222 set_specifier_fallback (Vcurrent_display_table, 4247 set_specifier_fallback (Vcurrent_display_table,
5223 list1 (Fcons (Qnil, Qnil))); 4248 list1 (Fcons (Qnil, Qnil)));
5224 set_specifier_caching (Vcurrent_display_table, 4249 set_specifier_caching (Vcurrent_display_table,
5225 offsetof (struct window, display_table), 4250 slot_offset (struct window,
4251 display_table),
5226 some_window_value_changed, 4252 some_window_value_changed,
5227 0, 0); 4253 0, 0);
5228 } 4254 }
5229 4255
5230 void 4256 void