comparison src/glyphs.c @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 8de8e3f6228a
children 576fb035e263
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
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 Ben Wing 4 Copyright (C) 1995, 1996, 2000 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, 1999, 2000 Andy Piper
7 7
8 This file is part of XEmacs. 8 This file is part of XEmacs.
9 9
28 rewritten by Andy Piper. */ 28 rewritten by Andy Piper. */
29 29
30 #include <config.h> 30 #include <config.h>
31 #include "lisp.h" 31 #include "lisp.h"
32 32
33 #include "blocktype.h"
33 #include "buffer.h" 34 #include "buffer.h"
35 #include "chartab.h"
34 #include "device.h" 36 #include "device.h"
35 #include "elhash.h" 37 #include "elhash.h"
36 #include "faces.h" 38 #include "faces.h"
37 #include "frame.h" 39 #include "frame.h"
40 #include "glyphs.h"
38 #include "insdel.h" 41 #include "insdel.h"
42 #include "objects.h"
39 #include "opaque.h" 43 #include "opaque.h"
40 #include "objects.h" 44 #include "rangetab.h"
41 #include "redisplay.h" 45 #include "redisplay.h"
46 #include "specifier.h"
42 #include "window.h" 47 #include "window.h"
43 #include "frame.h"
44 #include "chartab.h"
45 #include "rangetab.h"
46 #include "blocktype.h"
47 48
48 #ifdef HAVE_XPM 49 #ifdef HAVE_XPM
49 #include <X11/xpm.h> 50 #include <X11/xpm.h>
50 #endif 51 #endif
51 52
56 Lisp_Object Qnothing_image_instance_p, Qtext_image_instance_p; 57 Lisp_Object Qnothing_image_instance_p, Qtext_image_instance_p;
57 Lisp_Object Qmono_pixmap_image_instance_p; 58 Lisp_Object Qmono_pixmap_image_instance_p;
58 Lisp_Object Qcolor_pixmap_image_instance_p; 59 Lisp_Object Qcolor_pixmap_image_instance_p;
59 Lisp_Object Qpointer_image_instance_p; 60 Lisp_Object Qpointer_image_instance_p;
60 Lisp_Object Qsubwindow_image_instance_p; 61 Lisp_Object Qsubwindow_image_instance_p;
61 Lisp_Object Qlayout_image_instance_p;
62 Lisp_Object Qwidget_image_instance_p; 62 Lisp_Object Qwidget_image_instance_p;
63 Lisp_Object Qconst_glyph_variable; 63 Lisp_Object Qconst_glyph_variable;
64 Lisp_Object Qmono_pixmap, Qcolor_pixmap, Qsubwindow; 64 Lisp_Object Qmono_pixmap, Qcolor_pixmap, Qsubwindow;
65 Lisp_Object Q_file, Q_data, Q_face, Q_pixel_width, Q_pixel_height; 65 Lisp_Object Q_file, Q_data, Q_face, Q_pixel_width, Q_pixel_height;
66 Lisp_Object Qformatted_string; 66 Lisp_Object Qformatted_string;
79 DEFINE_IMAGE_INSTANTIATOR_FORMAT (inherit); 79 DEFINE_IMAGE_INSTANTIATOR_FORMAT (inherit);
80 DEFINE_IMAGE_INSTANTIATOR_FORMAT (string); 80 DEFINE_IMAGE_INSTANTIATOR_FORMAT (string);
81 DEFINE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); 81 DEFINE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
82 DEFINE_IMAGE_INSTANTIATOR_FORMAT (subwindow); 82 DEFINE_IMAGE_INSTANTIATOR_FORMAT (subwindow);
83 DEFINE_IMAGE_INSTANTIATOR_FORMAT (text); 83 DEFINE_IMAGE_INSTANTIATOR_FORMAT (text);
84 DEFINE_IMAGE_INSTANTIATOR_FORMAT (pointer);
84 85
85 #ifdef HAVE_WINDOW_SYSTEM 86 #ifdef HAVE_WINDOW_SYSTEM
86 DEFINE_IMAGE_INSTANTIATOR_FORMAT (xbm); 87 DEFINE_IMAGE_INSTANTIATOR_FORMAT (xbm);
87 Lisp_Object Qxbm; 88 Lisp_Object Qxbm;
88 89
118 typedef struct 119 typedef struct
119 { 120 {
120 Dynarr_declare (struct image_instantiator_format_entry); 121 Dynarr_declare (struct image_instantiator_format_entry);
121 } image_instantiator_format_entry_dynarr; 122 } image_instantiator_format_entry_dynarr;
122 123
124 /* This contains one entry per format, per device it's defined on. */
123 image_instantiator_format_entry_dynarr * 125 image_instantiator_format_entry_dynarr *
124 the_image_instantiator_format_entry_dynarr; 126 the_image_instantiator_format_entry_dynarr;
125 127
126 static Lisp_Object allocate_image_instance (Lisp_Object device, Lisp_Object glyph); 128 static Lisp_Object allocate_image_instance (Lisp_Object governing_domain,
129 Lisp_Object parent,
130 Lisp_Object instantiator);
127 static void image_validate (Lisp_Object instantiator); 131 static void image_validate (Lisp_Object instantiator);
128 static void glyph_property_was_changed (Lisp_Object glyph, 132 static void glyph_property_was_changed (Lisp_Object glyph,
129 Lisp_Object property, 133 Lisp_Object property,
130 Lisp_Object locale); 134 Lisp_Object locale);
135 static void set_image_instance_dirty_p (Lisp_Object instance, int dirty);
131 static void register_ignored_expose (struct frame* f, int x, int y, int width, int height); 136 static void register_ignored_expose (struct frame* f, int x, int y, int width, int height);
137 static void cache_subwindow_instance_in_frame_maybe (Lisp_Object instance);
138 static void update_image_instance (Lisp_Object image_instance,
139 Lisp_Object instantiator);
132 /* Unfortunately windows and X are different. In windows BeginPaint() 140 /* Unfortunately windows and X are different. In windows BeginPaint()
133 will prevent WM_PAINT messages being generated so it is unnecessary 141 will prevent WM_PAINT messages being generated so it is unnecessary
134 to register exposures as they will not occur. Under X they will 142 to register exposures as they will not occur. Under X they will
135 always occur. */ 143 always occur. */
136 int hold_ignored_expose_registration; 144 int hold_ignored_expose_registration;
137 145
138 EXFUN (Fimage_instance_type, 1); 146 EXFUN (Fimage_instance_type, 1);
139 EXFUN (Fglyph_type, 1); 147 EXFUN (Fglyph_type, 1);
148 EXFUN (Fnext_window, 4);
140 149
141 150
142 /**************************************************************************** 151 /****************************************************************************
143 * Image Instantiators * 152 * Image Instantiators *
144 ****************************************************************************/ 153 ****************************************************************************/
217 DEFUN ("valid-image-instantiator-format-p", Fvalid_image_instantiator_format_p, 226 DEFUN ("valid-image-instantiator-format-p", Fvalid_image_instantiator_format_p,
218 1, 2, 0, /* 227 1, 2, 0, /*
219 Given an IMAGE-INSTANTIATOR-FORMAT, return non-nil if it is valid. 228 Given an IMAGE-INSTANTIATOR-FORMAT, return non-nil if it is valid.
220 If LOCALE is non-nil then the format is checked in that domain. 229 If LOCALE is non-nil then the format is checked in that domain.
221 If LOCALE is nil the current console is used. 230 If LOCALE is nil the current console is used.
231
222 Valid formats are some subset of 'nothing, 'string, 'formatted-string, 232 Valid formats are some subset of 'nothing, 'string, 'formatted-string,
223 'xpm, 'xbm, 'xface, 'gif, 'jpeg, 'png, 'tiff, 'cursor-font, 'font, 233 'xpm, 'xbm, 'xface, 'gif, 'jpeg, 'png, 'tiff, 'cursor-font, 'font,
224 'autodetect, 'widget and 'subwindow, depending on how XEmacs was compiled. 234 'autodetect, 'subwindow, 'inherit, 'mswindows-resource, 'bmp,
235 'native-layout, 'layout, 'label, 'tab-control, 'tree-view,
236 'progress-gauge, 'scrollbar, 'combo-box, 'edit-field, 'button,
237 'widget, 'pointer, and 'text, depending on how XEmacs was compiled.
225 */ 238 */
226 (image_instantiator_format, locale)) 239 (image_instantiator_format, locale))
227 { 240 {
228 return valid_image_instantiator_format_p (image_instantiator_format, locale) ? 241 return valid_image_instantiator_format_p (image_instantiator_format,
242 locale) ?
229 Qt : Qnil; 243 Qt : Qnil;
230 } 244 }
231 245
232 DEFUN ("image-instantiator-format-list", Fimage_instantiator_format_list, 246 DEFUN ("image-instantiator-format-list", Fimage_instantiator_format_list,
233 0, 0, 0, /* 247 0, 0, 0, /*
246 260
247 entry.symbol = symbol; 261 entry.symbol = symbol;
248 entry.device = device; 262 entry.device = device;
249 entry.meths = meths; 263 entry.meths = meths;
250 Dynarr_add (the_image_instantiator_format_entry_dynarr, entry); 264 Dynarr_add (the_image_instantiator_format_entry_dynarr, entry);
251 Vimage_instantiator_format_list = 265 if (NILP (memq_no_quit (symbol, Vimage_instantiator_format_list)))
252 Fcons (symbol, Vimage_instantiator_format_list); 266 Vimage_instantiator_format_list =
267 Fcons (symbol, Vimage_instantiator_format_list);
253 } 268 }
254 269
255 void 270 void
256 add_entry_to_image_instantiator_format_list (Lisp_Object symbol, 271 add_entry_to_image_instantiator_format_list (Lisp_Object symbol,
257 struct 272 struct
419 find_keyword_in_vector (Lisp_Object vector, Lisp_Object keyword) 434 find_keyword_in_vector (Lisp_Object vector, Lisp_Object keyword)
420 { 435 {
421 return find_keyword_in_vector_or_given (vector, keyword, Qnil); 436 return find_keyword_in_vector_or_given (vector, keyword, Qnil);
422 } 437 }
423 438
439 static Lisp_Object
440 find_instantiator_differences (Lisp_Object new, Lisp_Object old)
441 {
442 Lisp_Object alist = Qnil;
443 Lisp_Object *elt = XVECTOR_DATA (new);
444 Lisp_Object *old_elt = XVECTOR_DATA (old);
445 int len = XVECTOR_LENGTH (new);
446 struct gcpro gcpro1;
447
448 /* If the vector length has changed then consider everything
449 changed. We could try and figure out what properties have
450 disappeared or been added, but this code is only used as an
451 optimization anyway so lets not bother. */
452 if (len != XVECTOR_LENGTH (old))
453 return new;
454
455 GCPRO1 (alist);
456
457 for (len -= 2; len >= 1; len -= 2)
458 {
459 /* Keyword comparisons can be done with eq, the value must be
460 done with equal.
461 #### Note that this does not optimize re-ordering. */
462 if (!EQ (elt[len], old_elt[len])
463 || !internal_equal (elt[len+1], old_elt[len+1], 0))
464 alist = Fcons (Fcons (elt[len], elt[len+1]), alist);
465 }
466
467 {
468 Lisp_Object result = alist_to_tagged_vector (elt[0], alist);
469 free_alist (alist);
470 RETURN_UNGCPRO (result);
471 }
472 }
473
474 DEFUN ("set-instantiator-property", Fset_instantiator_property,
475 3, 3, 0, /*
476 Destructively set the property KEYWORD of INSTANTIATOR to VAL.
477 If the property is not set then it is added to a copy of the
478 instantiator and the new instantiator returned.
479 Use `set-glyph-image' on glyphs to register instantiator changes. */
480 (instantiator, keyword, val))
481 {
482 Lisp_Object *elt;
483 int len;
484
485 CHECK_VECTOR (instantiator);
486 if (!KEYWORDP (keyword))
487 signal_simple_error ("instantiator property must be a keyword", keyword);
488
489 elt = XVECTOR_DATA (instantiator);
490 len = XVECTOR_LENGTH (instantiator);
491
492 for (len -= 2; len >= 1; len -= 2)
493 {
494 if (EQ (elt[len], keyword))
495 {
496 elt[len+1] = val;
497 break;
498 }
499 }
500
501 /* Didn't find it so add it. */
502 if (len < 1)
503 {
504 Lisp_Object alist = Qnil, result;
505 struct gcpro gcpro1;
506
507 GCPRO1 (alist);
508 alist = tagged_vector_to_alist (instantiator);
509 alist = Fcons (Fcons (keyword, val), alist);
510 result = alist_to_tagged_vector (elt[0], alist);
511 free_alist (alist);
512 RETURN_UNGCPRO (result);
513 }
514
515 return instantiator;
516 }
517
424 void 518 void
425 check_valid_string (Lisp_Object data) 519 check_valid_string (Lisp_Object data)
426 { 520 {
427 CHECK_STRING (data); 521 CHECK_STRING (data);
428 } 522 }
537 } 631 }
538 632
539 return Fvector (len, elt); 633 return Fvector (len, elt);
540 } 634 }
541 635
636 #ifdef ERROR_CHECK_GLYPHS
637 static int
638 check_instance_cache_mapper (Lisp_Object key, Lisp_Object value,
639 void *flag_closure)
640 {
641 /* This function can GC */
642 /* value can be nil; we cache failures as well as successes */
643 if (!NILP (value))
644 {
645 Lisp_Object window;
646 VOID_TO_LISP (window, flag_closure);
647 assert (EQ (XIMAGE_INSTANCE_DOMAIN (value), window));
648 }
649
650 return 0;
651 }
652
653 void
654 check_window_subwindow_cache (struct window* w)
655 {
656 Lisp_Object window;
657
658 XSETWINDOW (window, w);
659
660 assert (!NILP (w->subwindow_instance_cache));
661 elisp_maphash (check_instance_cache_mapper,
662 w->subwindow_instance_cache,
663 LISP_TO_VOID (window));
664 }
665
666 void
667 check_image_instance_structure (Lisp_Object instance)
668 {
669 /* Weird nothing images exist at startup when the console is
670 deleted. */
671 if (!NOTHING_IMAGE_INSTANCEP (instance))
672 {
673 assert (DOMAIN_LIVE_P (instance));
674 assert (VECTORP (XIMAGE_INSTANCE_INSTANTIATOR (instance)));
675 }
676 if (WINDOWP (XIMAGE_INSTANCE_DOMAIN (instance)))
677 check_window_subwindow_cache
678 (XWINDOW (XIMAGE_INSTANCE_DOMAIN (instance)));
679 }
680 #endif
681
682 /* Determine what kind of domain governs the image instance.
683 Verify that the given domain is at least as specific, and extract
684 the governing domain from it. */
542 static Lisp_Object 685 static Lisp_Object
686 get_image_instantiator_governing_domain (Lisp_Object instantiator,
687 Lisp_Object domain)
688 {
689 int governing_domain;
690
691 struct image_instantiator_methods *meths =
692 decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
693 ERROR_ME);
694 governing_domain = IIFORMAT_METH_OR_GIVEN (meths, governing_domain, (),
695 GOVERNING_DOMAIN_DEVICE);
696
697 if (governing_domain == GOVERNING_DOMAIN_WINDOW
698 && NILP (DOMAIN_WINDOW (domain)))
699 signal_simple_error_2 ("Domain for this instantiator must be resolvable to a window",
700 instantiator, domain);
701 else if (governing_domain == GOVERNING_DOMAIN_FRAME
702 && NILP (DOMAIN_FRAME (domain)))
703 signal_simple_error_2
704 ("Domain for this instantiator must be resolvable to a frame",
705 instantiator, domain);
706
707 if (governing_domain == GOVERNING_DOMAIN_WINDOW)
708 domain = DOMAIN_WINDOW (domain);
709 else if (governing_domain == GOVERNING_DOMAIN_FRAME)
710 domain = DOMAIN_FRAME (domain);
711 else if (governing_domain == GOVERNING_DOMAIN_DEVICE)
712 domain = DOMAIN_DEVICE (domain);
713 else
714 abort ();
715
716 return domain;
717 }
718
719 Lisp_Object
543 normalize_image_instantiator (Lisp_Object instantiator, 720 normalize_image_instantiator (Lisp_Object instantiator,
544 Lisp_Object contype, 721 Lisp_Object contype,
545 Lisp_Object dest_mask) 722 Lisp_Object dest_mask)
546 { 723 {
547 if (IMAGE_INSTANCEP (instantiator)) 724 if (IMAGE_INSTANCEP (instantiator))
548 return instantiator; 725 return instantiator;
549 726
550 if (STRINGP (instantiator)) 727 if (STRINGP (instantiator))
551 instantiator = process_image_string_instantiator (instantiator, contype, 728 instantiator = process_image_string_instantiator (instantiator, contype,
552 XINT (dest_mask)); 729 XINT (dest_mask));
553 730 /* Subsequent validation will pick this up. */
554 assert (VECTORP (instantiator)); 731 if (!VECTORP (instantiator))
732 return instantiator;
555 /* We have to always store the actual pixmap data and not the 733 /* We have to always store the actual pixmap data and not the
556 filename even though this is a potential memory pig. We have to 734 filename even though this is a potential memory pig. We have to
557 do this because it is quite possible that we will need to 735 do this because it is quite possible that we will need to
558 instantiate a new instance of the pixmap and the file will no 736 instantiate a new instance of the pixmap and the file will no
559 longer exist (e.g. w3 pixmaps are almost always from temporary 737 longer exist (e.g. w3 pixmaps are almost always from temporary
565 GCPRO1 (instantiator); 743 GCPRO1 (instantiator);
566 744
567 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], 745 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
568 ERROR_ME); 746 ERROR_ME);
569 RETURN_UNGCPRO (IIFORMAT_METH_OR_GIVEN (meths, normalize, 747 RETURN_UNGCPRO (IIFORMAT_METH_OR_GIVEN (meths, normalize,
570 (instantiator, contype), 748 (instantiator, contype, dest_mask),
571 instantiator)); 749 instantiator));
572 } 750 }
573 } 751 }
574 752
575 static Lisp_Object 753 static Lisp_Object
576 instantiate_image_instantiator (Lisp_Object device, Lisp_Object domain, 754 instantiate_image_instantiator (Lisp_Object governing_domain,
755 Lisp_Object domain,
577 Lisp_Object instantiator, 756 Lisp_Object instantiator,
578 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 757 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
579 int dest_mask, Lisp_Object glyph) 758 int dest_mask, Lisp_Object glyph)
580 { 759 {
581 Lisp_Object ii = allocate_image_instance (device, glyph); 760 Lisp_Object ii = allocate_image_instance (governing_domain,
582 struct image_instantiator_methods *meths; 761 IMAGE_INSTANCEP (domain) ?
762 domain : glyph, instantiator);
763 Lisp_Image_Instance* p = XIMAGE_INSTANCE (ii);
764 struct image_instantiator_methods *meths, *device_meths;
583 struct gcpro gcpro1; 765 struct gcpro gcpro1;
584 int methp = 0;
585 766
586 GCPRO1 (ii); 767 GCPRO1 (ii);
587 if (!valid_image_instantiator_format_p (XVECTOR_DATA (instantiator)[0], device)) 768 if (!valid_image_instantiator_format_p (XVECTOR_DATA (instantiator)[0],
769 DOMAIN_DEVICE (governing_domain)))
588 signal_simple_error 770 signal_simple_error
589 ("Image instantiator format is invalid in this locale.", 771 ("Image instantiator format is invalid in this locale.",
590 instantiator); 772 instantiator);
591 773
592 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], 774 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
593 ERROR_ME); 775 ERROR_ME);
594 methp = (int)HAS_IIFORMAT_METH_P (meths, instantiate);
595 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg, 776 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg,
596 pointer_bg, dest_mask, domain)); 777 pointer_bg, dest_mask, domain));
597 778
598 /* now do device specific instantiation */ 779 /* Now do device specific instantiation. */
599 meths = decode_device_ii_format (device, XVECTOR_DATA (instantiator)[0], 780 device_meths = decode_device_ii_format (DOMAIN_DEVICE (governing_domain),
600 ERROR_ME_NOT); 781 XVECTOR_DATA (instantiator)[0],
601 782 ERROR_ME_NOT);
602 if (!methp && (!meths || !HAS_IIFORMAT_METH_P (meths, instantiate))) 783
784 if (!HAS_IIFORMAT_METH_P (meths, instantiate)
785 && (!device_meths || !HAS_IIFORMAT_METH_P (device_meths, instantiate)))
603 signal_simple_error 786 signal_simple_error
604 ("Don't know how to instantiate this image instantiator?", 787 ("Don't know how to instantiate this image instantiator?",
605 instantiator); 788 instantiator);
606 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg, 789
607 pointer_bg, dest_mask, domain)); 790 /* In general native window system methods will require sane
608 UNGCPRO; 791 geometry values, thus the instance needs to have been laid-out
609 792 before they get called. */
610 return ii; 793 image_instance_layout (ii, XIMAGE_INSTANCE_WIDTH (ii),
794 XIMAGE_INSTANCE_HEIGHT (ii),
795 IMAGE_UNCHANGED_GEOMETRY,
796 IMAGE_UNCHANGED_GEOMETRY, domain);
797
798 MAYBE_IIFORMAT_METH (device_meths, instantiate, (ii, instantiator, pointer_fg,
799 pointer_bg, dest_mask, domain));
800 /* Do post instantiation. */
801 MAYBE_IIFORMAT_METH (meths, post_instantiate, (ii, instantiator, domain));
802 MAYBE_IIFORMAT_METH (device_meths, post_instantiate, (ii, instantiator, domain));
803
804 /* We're done. */
805 IMAGE_INSTANCE_INITIALIZED (p) = 1;
806 /* Now that we're done verify that we really are laid out. */
807 if (IMAGE_INSTANCE_LAYOUT_CHANGED (p))
808 image_instance_layout (ii, XIMAGE_INSTANCE_WIDTH (ii),
809 XIMAGE_INSTANCE_HEIGHT (ii),
810 IMAGE_UNCHANGED_GEOMETRY,
811 IMAGE_UNCHANGED_GEOMETRY, domain);
812
813 /* We *must* have a clean image at this point. */
814 IMAGE_INSTANCE_TEXT_CHANGED (p) = 0;
815 IMAGE_INSTANCE_SIZE_CHANGED (p) = 0;
816 IMAGE_INSTANCE_LAYOUT_CHANGED (p) = 0;
817 IMAGE_INSTANCE_DIRTYP (p) = 0;
818
819 assert ( XIMAGE_INSTANCE_HEIGHT (ii) >= 0
820 && XIMAGE_INSTANCE_WIDTH (ii) >= 0 );
821
822 ERROR_CHECK_IMAGE_INSTANCE (ii);
823
824 RETURN_UNGCPRO (ii);
611 } 825 }
612 826
613 827
614 /**************************************************************************** 828 /****************************************************************************
615 * Image-Instance Object * 829 * Image-Instance Object *
620 static Lisp_Object 834 static Lisp_Object
621 mark_image_instance (Lisp_Object obj) 835 mark_image_instance (Lisp_Object obj)
622 { 836 {
623 Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); 837 Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj);
624 838
839 /* #### I want to check the instance here, but there are way too
840 many instances of the instance being marked while the domain is
841 dead. For instance you can get marked through an event when using
842 callback_ex.*/
843 #if 0
844 ERROR_CHECK_IMAGE_INSTANCE (obj);
845 #endif
846
625 mark_object (i->name); 847 mark_object (i->name);
848 mark_object (i->instantiator);
849 /* Is this legal in marking? We may get in the situation where the
850 domain has been deleted - making the instance unusable. It seems
851 better to remove the domain so that it can be finalized. */
852 if (!DOMAIN_LIVE_P (i->domain))
853 i->domain = Qnil;
854 else
855 mark_object (i->domain);
856
626 /* We don't mark the glyph reference since that would create a 857 /* We don't mark the glyph reference since that would create a
627 circularity preventing GC. */ 858 circularity preventing GC. Ditto the instantiator. */
628 switch (IMAGE_INSTANCE_TYPE (i)) 859 switch (IMAGE_INSTANCE_TYPE (i))
629 { 860 {
630 case IMAGE_TEXT: 861 case IMAGE_TEXT:
631 mark_object (IMAGE_INSTANCE_TEXT_STRING (i)); 862 mark_object (IMAGE_INSTANCE_TEXT_STRING (i));
632 break; 863 break;
639 mark_object (IMAGE_INSTANCE_PIXMAP_FG (i)); 870 mark_object (IMAGE_INSTANCE_PIXMAP_FG (i));
640 mark_object (IMAGE_INSTANCE_PIXMAP_BG (i)); 871 mark_object (IMAGE_INSTANCE_PIXMAP_BG (i));
641 break; 872 break;
642 873
643 case IMAGE_WIDGET: 874 case IMAGE_WIDGET:
644 case IMAGE_LAYOUT:
645 mark_object (IMAGE_INSTANCE_WIDGET_TYPE (i)); 875 mark_object (IMAGE_INSTANCE_WIDGET_TYPE (i));
646 mark_object (IMAGE_INSTANCE_WIDGET_PROPS (i)); 876 mark_object (IMAGE_INSTANCE_WIDGET_PROPS (i));
647 mark_object (IMAGE_INSTANCE_WIDGET_FACE (i)); 877 mark_object (IMAGE_INSTANCE_SUBWINDOW_FACE (i));
648 mark_object (IMAGE_INSTANCE_WIDGET_ITEMS (i)); 878 mark_object (IMAGE_INSTANCE_WIDGET_ITEMS (i));
879 mark_object (IMAGE_INSTANCE_LAYOUT_CHILDREN (i));
880 mark_object (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (i));
881 mark_object (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (i));
882 mark_object (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (i));
649 case IMAGE_SUBWINDOW: 883 case IMAGE_SUBWINDOW:
650 mark_object (IMAGE_INSTANCE_SUBWINDOW_FRAME (i));
651 break; 884 break;
652 885
653 default: 886 default:
654 break; 887 break;
655 } 888 }
656 889
657 MAYBE_DEVMETH (XDEVICE (i->device), mark_image_instance, (i)); 890 /* The image may have been previously finalized (yes that's weird,
891 see Fdelete_frame() and mark_window_as_deleted()), in which case
892 the domain will be nil, so cope with this. */
893 if (!NILP (IMAGE_INSTANCE_DEVICE (i)))
894 MAYBE_DEVMETH (XDEVICE (IMAGE_INSTANCE_DEVICE (i)),
895 mark_image_instance, (i));
658 896
659 return i->device; 897 return i->device;
660 } 898 }
661 899
662 static void 900 static void
676 { 914 {
677 print_internal (ii->name, printcharfun, 1); 915 print_internal (ii->name, printcharfun, 1);
678 write_c_string (" ", printcharfun); 916 write_c_string (" ", printcharfun);
679 } 917 }
680 write_c_string ("on ", printcharfun); 918 write_c_string ("on ", printcharfun);
681 print_internal (ii->device, printcharfun, 0); 919 print_internal (ii->domain, printcharfun, 0);
682 write_c_string (" ", printcharfun); 920 write_c_string (" ", printcharfun);
683 switch (IMAGE_INSTANCE_TYPE (ii)) 921 switch (IMAGE_INSTANCE_TYPE (ii))
684 { 922 {
685 case IMAGE_NOTHING: 923 case IMAGE_NOTHING:
686 break; 924 break;
750 write_c_string (")", printcharfun); 988 write_c_string (")", printcharfun);
751 } 989 }
752 break; 990 break;
753 991
754 case IMAGE_WIDGET: 992 case IMAGE_WIDGET:
993 print_internal (IMAGE_INSTANCE_WIDGET_TYPE (ii), printcharfun, 0);
994
995 if (GUI_ITEMP (IMAGE_INSTANCE_WIDGET_ITEM (ii)))
996 {
997 write_c_string (" ", printcharfun);
998 print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 1);
999 }
1000
755 if (!NILP (IMAGE_INSTANCE_WIDGET_FACE (ii))) 1001 if (!NILP (IMAGE_INSTANCE_WIDGET_FACE (ii)))
756 { 1002 {
757 write_c_string (" (", printcharfun); 1003 write_c_string (" face=", printcharfun);
758 print_internal 1004 print_internal
759 (IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0); 1005 (IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0);
760 write_c_string (")", printcharfun);
761 } 1006 }
762 1007
763 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
764 print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 0);
765 1008
766 case IMAGE_SUBWINDOW: 1009 case IMAGE_SUBWINDOW:
767 case IMAGE_LAYOUT: 1010 sprintf (buf, " %dx%d", IMAGE_INSTANCE_WIDTH (ii),
768 sprintf (buf, " %dx%d", IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii), 1011 IMAGE_INSTANCE_HEIGHT (ii));
769 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii));
770 write_c_string (buf, printcharfun); 1012 write_c_string (buf, printcharfun);
771 1013
772 /* This is stolen from frame.c. Subwindows are strange in that they 1014 /* This is stolen from frame.c. Subwindows are strange in that they
773 are specific to a particular frame so we want to print in their 1015 are specific to a particular frame so we want to print in their
774 description what that frame is. */ 1016 description what that frame is. */
775 1017
776 write_c_string (" on #<", printcharfun); 1018 write_c_string (" on #<", printcharfun);
777 { 1019 {
778 struct frame* f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); 1020 struct frame* f = XFRAME (IMAGE_INSTANCE_FRAME (ii));
779 1021
780 if (!FRAME_LIVE_P (f)) 1022 if (!FRAME_LIVE_P (f))
781 write_c_string ("dead", printcharfun); 1023 write_c_string ("dead", printcharfun);
782 else 1024 else
783 write_c_string (DEVICE_TYPE_NAME (XDEVICE (FRAME_DEVICE (f))), 1025 write_c_string (DEVICE_TYPE_NAME (XDEVICE (FRAME_DEVICE (f))),
784 printcharfun); 1026 printcharfun);
785
786 write_c_string ("-frame ", printcharfun);
787 } 1027 }
788 write_c_string (">", printcharfun); 1028 write_c_string ("-frame>", printcharfun);
789 sprintf (buf, " 0x%p", IMAGE_INSTANCE_SUBWINDOW_ID (ii)); 1029 sprintf (buf, " 0x%p", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
790 write_c_string (buf, printcharfun); 1030 write_c_string (buf, printcharfun);
791 1031
792 break; 1032 break;
793 1033
794 default: 1034 default:
795 abort (); 1035 abort ();
796 } 1036 }
797 1037
798 MAYBE_DEVMETH (XDEVICE (ii->device), print_image_instance, 1038 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), print_image_instance,
799 (ii, printcharfun, escapeflag)); 1039 (ii, printcharfun, escapeflag));
800 sprintf (buf, " 0x%x>", ii->header.uid); 1040 sprintf (buf, " 0x%x>", ii->header.uid);
801 write_c_string (buf, printcharfun); 1041 write_c_string (buf, printcharfun);
802 } 1042 }
803 1043
804 static void 1044 static void
805 finalize_image_instance (void *header, int for_disksave) 1045 finalize_image_instance (void *header, int for_disksave)
806 { 1046 {
807 Lisp_Image_Instance *i = (Lisp_Image_Instance *) header; 1047 Lisp_Image_Instance *i = (Lisp_Image_Instance *) header;
808 1048
809 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_NOTHING) 1049 /* objects like this exist at dump time, so don't bomb out. */
810 /* objects like this exist at dump time, so don't bomb out. */ 1050 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_NOTHING
1051 ||
1052 NILP (IMAGE_INSTANCE_DEVICE (i)))
811 return; 1053 return;
812 if (for_disksave) finalose (i); 1054 if (for_disksave) finalose (i);
813 1055
814 /* do this so that the cachels get reset */ 1056 /* We can't use the domain here, because it might have
815 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_WIDGET 1057 disappeared. */
816 || 1058 MAYBE_DEVMETH (XDEVICE (IMAGE_INSTANCE_DEVICE (i)),
817 IMAGE_INSTANCE_TYPE (i) == IMAGE_SUBWINDOW) 1059 finalize_image_instance, (i));
818 { 1060
819 MARK_FRAME_SUBWINDOWS_CHANGED 1061 /* Make sure we don't try this twice. */
820 (XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (i))); 1062 IMAGE_INSTANCE_DEVICE (i) = Qnil;
821 }
822
823 MAYBE_DEVMETH (XDEVICE (i->device), finalize_image_instance, (i));
824 } 1063 }
825 1064
826 static int 1065 static int
827 image_instance_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) 1066 image_instance_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
828 { 1067 {
829 Lisp_Image_Instance *i1 = XIMAGE_INSTANCE (obj1); 1068 Lisp_Image_Instance *i1 = XIMAGE_INSTANCE (obj1);
830 Lisp_Image_Instance *i2 = XIMAGE_INSTANCE (obj2); 1069 Lisp_Image_Instance *i2 = XIMAGE_INSTANCE (obj2);
831 struct device *d1 = XDEVICE (i1->device); 1070
832 struct device *d2 = XDEVICE (i2->device); 1071 ERROR_CHECK_IMAGE_INSTANCE (obj1);
833 1072 ERROR_CHECK_IMAGE_INSTANCE (obj2);
834 if (d1 != d2) 1073
835 return 0; 1074 if (!EQ (IMAGE_INSTANCE_DOMAIN (i1),
836 if (IMAGE_INSTANCE_TYPE (i1) != IMAGE_INSTANCE_TYPE (i2) 1075 IMAGE_INSTANCE_DOMAIN (i2))
1076 || IMAGE_INSTANCE_TYPE (i1) != IMAGE_INSTANCE_TYPE (i2)
837 || IMAGE_INSTANCE_WIDTH (i1) != IMAGE_INSTANCE_WIDTH (i2) 1077 || IMAGE_INSTANCE_WIDTH (i1) != IMAGE_INSTANCE_WIDTH (i2)
1078 || IMAGE_INSTANCE_MARGIN_WIDTH (i1) !=
1079 IMAGE_INSTANCE_MARGIN_WIDTH (i2)
838 || IMAGE_INSTANCE_HEIGHT (i1) != IMAGE_INSTANCE_HEIGHT (i2) 1080 || IMAGE_INSTANCE_HEIGHT (i1) != IMAGE_INSTANCE_HEIGHT (i2)
839 || IMAGE_INSTANCE_XOFFSET (i1) != IMAGE_INSTANCE_XOFFSET (i2) 1081 || IMAGE_INSTANCE_XOFFSET (i1) != IMAGE_INSTANCE_XOFFSET (i2)
840 || IMAGE_INSTANCE_YOFFSET (i1) != IMAGE_INSTANCE_YOFFSET (i2)) 1082 || IMAGE_INSTANCE_YOFFSET (i1) != IMAGE_INSTANCE_YOFFSET (i2))
841 return 0; 1083 return 0;
842 if (!internal_equal (IMAGE_INSTANCE_NAME (i1), IMAGE_INSTANCE_NAME (i2), 1084 if (!internal_equal (IMAGE_INSTANCE_NAME (i1), IMAGE_INSTANCE_NAME (i2),
1085 depth + 1))
1086 return 0;
1087 if (!internal_equal (IMAGE_INSTANCE_INSTANTIATOR (i1),
1088 IMAGE_INSTANCE_INSTANTIATOR (i2),
843 depth + 1)) 1089 depth + 1))
844 return 0; 1090 return 0;
845 1091
846 switch (IMAGE_INSTANCE_TYPE (i1)) 1092 switch (IMAGE_INSTANCE_TYPE (i1))
847 { 1093 {
874 depth + 1))) 1120 depth + 1)))
875 return 0; 1121 return 0;
876 break; 1122 break;
877 1123
878 case IMAGE_WIDGET: 1124 case IMAGE_WIDGET:
879 case IMAGE_LAYOUT:
880 if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1), 1125 if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1),
881 IMAGE_INSTANCE_WIDGET_TYPE (i2)) 1126 IMAGE_INSTANCE_WIDGET_TYPE (i2))
882 && IMAGE_INSTANCE_SUBWINDOW_ID (i1) == 1127 && IMAGE_INSTANCE_SUBWINDOW_ID (i1) ==
883 IMAGE_INSTANCE_SUBWINDOW_ID (i2) 1128 IMAGE_INSTANCE_SUBWINDOW_ID (i2)
1129 &&
1130 EQ (IMAGE_INSTANCE_WIDGET_FACE (i1),
1131 IMAGE_INSTANCE_WIDGET_TYPE (i2))
884 && internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (i1), 1132 && internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (i1),
885 IMAGE_INSTANCE_WIDGET_ITEMS (i2), 1133 IMAGE_INSTANCE_WIDGET_ITEMS (i2),
886 depth + 1) 1134 depth + 1)
1135 && internal_equal (IMAGE_INSTANCE_LAYOUT_CHILDREN (i1),
1136 IMAGE_INSTANCE_LAYOUT_CHILDREN (i2),
1137 depth + 1)
887 && internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1), 1138 && internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1),
888 IMAGE_INSTANCE_WIDGET_PROPS (i2), 1139 IMAGE_INSTANCE_WIDGET_PROPS (i2),
1140 depth + 1)
1141 && internal_equal (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (i1),
1142 IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (i2),
1143 depth + 1)
1144 && internal_equal (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (i1),
1145 IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (i2),
889 depth + 1) 1146 depth + 1)
890 )) 1147 ))
891 return 0; 1148 return 0;
892 break; 1149 break;
893 1150
899 1156
900 default: 1157 default:
901 abort (); 1158 abort ();
902 } 1159 }
903 1160
904 return DEVMETH_OR_GIVEN (d1, image_instance_equal, (i1, i2, depth), 1); 1161 return DEVMETH_OR_GIVEN (DOMAIN_XDEVICE (i1->domain),
1162 image_instance_equal, (i1, i2, depth), 1);
1163 }
1164
1165 /* Image instance domain manipulators. We can't error check in these
1166 otherwise we get into infinite recursion. */
1167 Lisp_Object
1168 image_instance_device (Lisp_Object instance)
1169 {
1170 return XIMAGE_INSTANCE_DEVICE (instance);
1171 }
1172
1173 Lisp_Object
1174 image_instance_frame (Lisp_Object instance)
1175 {
1176 return XIMAGE_INSTANCE_FRAME (instance);
1177 }
1178
1179 Lisp_Object
1180 image_instance_window (Lisp_Object instance)
1181 {
1182 return DOMAIN_WINDOW (XIMAGE_INSTANCE_DOMAIN (instance));
1183 }
1184
1185 int
1186 image_instance_live_p (Lisp_Object instance)
1187 {
1188 return DOMAIN_LIVE_P (XIMAGE_INSTANCE_DOMAIN (instance));
905 } 1189 }
906 1190
907 static unsigned long 1191 static unsigned long
908 image_instance_hash (Lisp_Object obj, int depth) 1192 image_instance_hash (Lisp_Object obj, int depth)
909 { 1193 {
910 Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); 1194 Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj);
911 struct device *d = XDEVICE (i->device); 1195 unsigned long hash = HASH5 (LISP_HASH (IMAGE_INSTANCE_DOMAIN (i)),
912 unsigned long hash = HASH3 ((unsigned long) d,
913 IMAGE_INSTANCE_WIDTH (i), 1196 IMAGE_INSTANCE_WIDTH (i),
914 IMAGE_INSTANCE_HEIGHT (i)); 1197 IMAGE_INSTANCE_MARGIN_WIDTH (i),
1198 IMAGE_INSTANCE_HEIGHT (i),
1199 internal_hash (IMAGE_INSTANCE_INSTANTIATOR (i),
1200 depth + 1));
1201
1202 ERROR_CHECK_IMAGE_INSTANCE (obj);
915 1203
916 switch (IMAGE_INSTANCE_TYPE (i)) 1204 switch (IMAGE_INSTANCE_TYPE (i))
917 { 1205 {
918 case IMAGE_NOTHING: 1206 case IMAGE_NOTHING:
919 break; 1207 break;
931 internal_hash (IMAGE_INSTANCE_PIXMAP_FILENAME (i), 1219 internal_hash (IMAGE_INSTANCE_PIXMAP_FILENAME (i),
932 depth + 1)); 1220 depth + 1));
933 break; 1221 break;
934 1222
935 case IMAGE_WIDGET: 1223 case IMAGE_WIDGET:
936 case IMAGE_LAYOUT: 1224 /* We need the hash to be equivalent to what should be
937 hash = HASH4 (hash, 1225 displayed. */
938 internal_hash (IMAGE_INSTANCE_WIDGET_TYPE (i), depth + 1), 1226 hash = HASH5 (hash,
1227 LISP_HASH (IMAGE_INSTANCE_WIDGET_TYPE (i)),
939 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1), 1228 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1),
940 internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1)); 1229 internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1),
1230 internal_hash (IMAGE_INSTANCE_LAYOUT_CHILDREN (i),
1231 depth + 1));
941 case IMAGE_SUBWINDOW: 1232 case IMAGE_SUBWINDOW:
942 hash = HASH2 (hash, (int) IMAGE_INSTANCE_SUBWINDOW_ID (i)); 1233 hash = HASH2 (hash, (EMACS_INT) IMAGE_INSTANCE_SUBWINDOW_ID (i));
943 break; 1234 break;
944 1235
945 default: 1236 default:
946 abort (); 1237 abort ();
947 } 1238 }
948 1239
949 return HASH2 (hash, DEVMETH_OR_GIVEN (d, image_instance_hash, (i, depth), 1240 return HASH2 (hash, DEVMETH_OR_GIVEN
950 0)); 1241 (XDEVICE (image_instance_device (obj)),
1242 image_instance_hash, (i, depth),
1243 0));
951 } 1244 }
952 1245
953 DEFINE_LRECORD_IMPLEMENTATION ("image-instance", image_instance, 1246 DEFINE_LRECORD_IMPLEMENTATION ("image-instance", image_instance,
954 mark_image_instance, print_image_instance, 1247 mark_image_instance, print_image_instance,
955 finalize_image_instance, image_instance_equal, 1248 finalize_image_instance, image_instance_equal,
956 image_instance_hash, 0, 1249 image_instance_hash, 0,
957 Lisp_Image_Instance); 1250 Lisp_Image_Instance);
958 1251
959 static Lisp_Object 1252 static Lisp_Object
960 allocate_image_instance (Lisp_Object device, Lisp_Object glyph) 1253 allocate_image_instance (Lisp_Object governing_domain, Lisp_Object parent,
1254 Lisp_Object instantiator)
961 { 1255 {
962 Lisp_Image_Instance *lp = 1256 Lisp_Image_Instance *lp =
963 alloc_lcrecord_type (Lisp_Image_Instance, &lrecord_image_instance); 1257 alloc_lcrecord_type (Lisp_Image_Instance, &lrecord_image_instance);
964 Lisp_Object val; 1258 Lisp_Object val;
965 1259
966 zero_lcrecord (lp); 1260 zero_lcrecord (lp);
967 lp->device = device; 1261 /* It's not possible to simply keep a record of the domain in which
1262 the instance was instantiated. This is because caching may mean
1263 that the domain becomes invalid but the instance remains
1264 valid. However, the only truly relevant domain is the domain in
1265 which the instance is cached since this is the one that will be
1266 common to the instances. */
1267 lp->domain = governing_domain;
1268 /* The cache domain is not quite sufficient since the domain can get
1269 deleted before the image instance does. We need to know the
1270 domain device in order to finalize the image instance
1271 properly. We therefore record the device also. */
1272 lp->device = DOMAIN_DEVICE (governing_domain);
968 lp->type = IMAGE_NOTHING; 1273 lp->type = IMAGE_NOTHING;
969 lp->name = Qnil; 1274 lp->name = Qnil;
970 lp->x_offset = 0; 1275 lp->x_offset = 0;
971 lp->y_offset = 0; 1276 lp->y_offset = 0;
972 lp->width = 0; 1277 lp->width = IMAGE_UNSPECIFIED_GEOMETRY;
973 lp->height = 0; 1278 lp->margin_width = 0;
974 lp->glyph = glyph; 1279 lp->height = IMAGE_UNSPECIFIED_GEOMETRY;
975 MARK_IMAGE_INSTANCE_CHANGED (lp); /* So that layouts get done. */ 1280 lp->parent = parent;
1281 lp->instantiator = instantiator;
1282 /* So that layouts get done. */
1283 lp->layout_changed = 1;
1284 lp->initialized = 0;
1285
976 XSETIMAGE_INSTANCE (val, lp); 1286 XSETIMAGE_INSTANCE (val, lp);
977 MARK_GLYPHS_CHANGED; /* So that the dirty flag gets reset. */ 1287 MARK_GLYPHS_CHANGED;
1288
978 return val; 1289 return val;
979 } 1290 }
980 1291
981 static enum image_instance_type 1292 static enum image_instance_type
982 decode_image_instance_type (Lisp_Object type, Error_behavior errb) 1293 decode_image_instance_type (Lisp_Object type, Error_behavior errb)
989 if (EQ (type, Qmono_pixmap)) return IMAGE_MONO_PIXMAP; 1300 if (EQ (type, Qmono_pixmap)) return IMAGE_MONO_PIXMAP;
990 if (EQ (type, Qcolor_pixmap)) return IMAGE_COLOR_PIXMAP; 1301 if (EQ (type, Qcolor_pixmap)) return IMAGE_COLOR_PIXMAP;
991 if (EQ (type, Qpointer)) return IMAGE_POINTER; 1302 if (EQ (type, Qpointer)) return IMAGE_POINTER;
992 if (EQ (type, Qsubwindow)) return IMAGE_SUBWINDOW; 1303 if (EQ (type, Qsubwindow)) return IMAGE_SUBWINDOW;
993 if (EQ (type, Qwidget)) return IMAGE_WIDGET; 1304 if (EQ (type, Qwidget)) return IMAGE_WIDGET;
994 if (EQ (type, Qlayout)) return IMAGE_LAYOUT;
995 1305
996 maybe_signal_simple_error ("Invalid image-instance type", type, 1306 maybe_signal_simple_error ("Invalid image-instance type", type,
997 Qimage, errb); 1307 Qimage, errb);
998 1308
999 return IMAGE_UNKNOWN; /* not reached */ 1309 return IMAGE_UNKNOWN; /* not reached */
1009 case IMAGE_MONO_PIXMAP: return Qmono_pixmap; 1319 case IMAGE_MONO_PIXMAP: return Qmono_pixmap;
1010 case IMAGE_COLOR_PIXMAP: return Qcolor_pixmap; 1320 case IMAGE_COLOR_PIXMAP: return Qcolor_pixmap;
1011 case IMAGE_POINTER: return Qpointer; 1321 case IMAGE_POINTER: return Qpointer;
1012 case IMAGE_SUBWINDOW: return Qsubwindow; 1322 case IMAGE_SUBWINDOW: return Qsubwindow;
1013 case IMAGE_WIDGET: return Qwidget; 1323 case IMAGE_WIDGET: return Qwidget;
1014 case IMAGE_LAYOUT: return Qlayout;
1015 default: 1324 default:
1016 abort (); 1325 abort ();
1017 } 1326 }
1018 1327
1019 return Qnil; /* not reached */ 1328 return Qnil; /* not reached */
1020 }
1021
1022 static int
1023 image_instance_type_to_mask (enum image_instance_type type)
1024 {
1025 /* This depends on the fact that enums are assigned consecutive
1026 integers starting at 0. (Remember that IMAGE_UNKNOWN is the
1027 first enum.) I'm fairly sure this behavior is ANSI-mandated,
1028 so there should be no portability problems here. */
1029 return (1 << ((int) (type) - 1));
1030 } 1329 }
1031 1330
1032 static int 1331 static int
1033 decode_image_instance_type_list (Lisp_Object list) 1332 decode_image_instance_type_list (Lisp_Object list)
1034 { 1333 {
1079 { 1378 {
1080 signal_error 1379 signal_error
1081 (Qerror, 1380 (Qerror,
1082 list2 1381 list2
1083 (emacs_doprnt_string_lisp_2 1382 (emacs_doprnt_string_lisp_2
1084 ((CONST Bufbyte *) 1383 ((const Bufbyte *)
1085 "No compatible image-instance types given: wanted one of %s, got %s", 1384 "No compatible image-instance types given: wanted one of %s, got %s",
1086 Qnil, -1, 2, 1385 Qnil, -1, 2,
1087 encode_image_instance_type_list (desired_dest_mask), 1386 encode_image_instance_type_list (desired_dest_mask),
1088 encode_image_instance_type_list (given_dest_mask)), 1387 encode_image_instance_type_list (given_dest_mask)),
1089 instantiator)); 1388 instantiator));
1096 } 1395 }
1097 1396
1098 DEFUN ("valid-image-instance-type-p", Fvalid_image_instance_type_p, 1, 1, 0, /* 1397 DEFUN ("valid-image-instance-type-p", Fvalid_image_instance_type_p, 1, 1, 0, /*
1099 Given an IMAGE-INSTANCE-TYPE, return non-nil if it is valid. 1398 Given an IMAGE-INSTANCE-TYPE, return non-nil if it is valid.
1100 Valid types are some subset of 'nothing, 'text, 'mono-pixmap, 'color-pixmap, 1399 Valid types are some subset of 'nothing, 'text, 'mono-pixmap, 'color-pixmap,
1101 'pointer, and 'subwindow, depending on how XEmacs was compiled. 1400 'pointer, 'subwindow, and 'widget, depending on how XEmacs was compiled.
1102 */ 1401 */
1103 (image_instance_type)) 1402 (image_instance_type))
1104 { 1403 {
1105 return valid_image_instance_type_p (image_instance_type) ? Qt : Qnil; 1404 return valid_image_instance_type_p (image_instance_type) ? Qt : Qnil;
1106 } 1405 }
1133 assert (ERRB_EQ (errb, ERROR_ME_WARN)); 1432 assert (ERRB_EQ (errb, ERROR_ME_WARN));
1134 return Qwarning; 1433 return Qwarning;
1135 } 1434 }
1136 } 1435 }
1137 1436
1437 /* Recurse up the hierarchy looking for the topmost glyph. This means
1438 that instances in layouts will inherit face properties from their
1439 parent. */
1440 Lisp_Object image_instance_parent_glyph (Lisp_Image_Instance* ii)
1441 {
1442 if (IMAGE_INSTANCEP (IMAGE_INSTANCE_PARENT (ii)))
1443 {
1444 return image_instance_parent_glyph
1445 (XIMAGE_INSTANCE (IMAGE_INSTANCE_PARENT (ii)));
1446 }
1447 return IMAGE_INSTANCE_PARENT (ii);
1448 }
1449
1138 static Lisp_Object 1450 static Lisp_Object
1139 make_image_instance_1 (Lisp_Object data, Lisp_Object device, 1451 make_image_instance_1 (Lisp_Object data, Lisp_Object domain,
1140 Lisp_Object dest_types) 1452 Lisp_Object dest_types)
1141 { 1453 {
1142 Lisp_Object ii; 1454 Lisp_Object ii;
1143 struct gcpro gcpro1; 1455 struct gcpro gcpro1;
1144 int dest_mask; 1456 int dest_mask;
1145 1457 Lisp_Object governing_domain;
1146 XSETDEVICE (device, decode_device (device)); 1458
1147 /* instantiate_image_instantiator() will abort if given an
1148 image instance ... */
1149 if (IMAGE_INSTANCEP (data)) 1459 if (IMAGE_INSTANCEP (data))
1150 signal_simple_error ("Image instances not allowed here", data); 1460 signal_simple_error ("Image instances not allowed here", data);
1151 image_validate (data); 1461 image_validate (data);
1462 domain = decode_domain (domain);
1463 /* instantiate_image_instantiator() will abort if given an
1464 image instance ... */
1152 dest_mask = decode_image_instance_type_list (dest_types); 1465 dest_mask = decode_image_instance_type_list (dest_types);
1153 data = normalize_image_instantiator (data, DEVICE_TYPE (XDEVICE (device)), 1466 data = normalize_image_instantiator (data,
1467 DEVICE_TYPE (DOMAIN_XDEVICE (domain)),
1154 make_int (dest_mask)); 1468 make_int (dest_mask));
1155 GCPRO1 (data); 1469 GCPRO1 (data);
1156 if (VECTORP (data) && EQ (XVECTOR_DATA (data)[0], Qinherit)) 1470 /* After normalizing the data, it's always either an image instance (which
1471 we filtered out above) or a vector. */
1472 if (EQ (XVECTOR_DATA (data)[0], Qinherit))
1157 signal_simple_error ("Inheritance not allowed here", data); 1473 signal_simple_error ("Inheritance not allowed here", data);
1158 ii = instantiate_image_instantiator (device, device, data, 1474 governing_domain =
1475 get_image_instantiator_governing_domain (data, domain);
1476 ii = instantiate_image_instantiator (governing_domain, domain, data,
1159 Qnil, Qnil, dest_mask, Qnil); 1477 Qnil, Qnil, dest_mask, Qnil);
1160 RETURN_UNGCPRO (ii); 1478 RETURN_UNGCPRO (ii);
1161 } 1479 }
1162 1480
1163 DEFUN ("make-image-instance", Fmake_image_instance, 1, 4, 0, /* 1481 DEFUN ("make-image-instance", Fmake_image_instance, 1, 4, 0, /*
1168 do not need to directly create image instances; use a glyph instead. 1486 do not need to directly create image instances; use a glyph instead.
1169 However, it may occasionally be useful to explicitly create image 1487 However, it may occasionally be useful to explicitly create image
1170 instances, if you want more control over the instantiation process. 1488 instances, if you want more control over the instantiation process.
1171 1489
1172 DATA is an image instantiator, which describes the image; see 1490 DATA is an image instantiator, which describes the image; see
1173 `image-specifier-p' for a description of the allowed values. 1491 `make-image-specifier' for a description of the allowed values.
1174 1492
1175 DEST-TYPES should be a list of allowed image instance types that can 1493 DEST-TYPES should be a list of allowed image instance types that can
1176 be generated. The recognized image instance types are 1494 be generated. The recognized image instance types are
1177 1495
1178 'nothing 1496 'nothing
1195 'subwindow 1513 'subwindow
1196 A child window that is treated as an image. This allows (e.g.) 1514 A child window that is treated as an image. This allows (e.g.)
1197 another program to be responsible for drawing into the window. 1515 another program to be responsible for drawing into the window.
1198 'widget 1516 'widget
1199 A child window that contains a window-system widget, e.g. a push 1517 A child window that contains a window-system widget, e.g. a push
1200 button. 1518 button, text field, or slider.
1201 1519
1202 The DEST-TYPES list is unordered. If multiple destination types 1520 The DEST-TYPES list is unordered. If multiple destination types are
1203 are possible for a given instantiator, the "most natural" type 1521 possible for a given instantiator, the "most natural" type for the
1204 for the instantiator's format is chosen. (For XBM, the most natural 1522 instantiator's format is chosen. (For XBM, the most natural types are
1205 types are `mono-pixmap', followed by `color-pixmap', followed by 1523 `mono-pixmap', followed by `color-pixmap', followed by `pointer'. For
1206 `pointer'. For the other normal image formats, the most natural 1524 the other normal image formats, the most natural types are
1207 types are `color-pixmap', followed by `mono-pixmap', followed by 1525 `color-pixmap', followed by `mono-pixmap', followed by `pointer'. For
1208 `pointer'. For the string and formatted-string formats, the most 1526 the string and formatted-string formats, the most natural types are
1209 natural types are `text', followed by `mono-pixmap' (not currently 1527 `text', followed by `mono-pixmap' (not currently implemented),
1210 implemented), followed by `color-pixmap' (not currently implemented). 1528 followed by `color-pixmap' (not currently implemented). For MS
1211 The other formats can only be instantiated as one type. (If you 1529 Windows resources, the most natural type for pointer resources is
1212 want to control more specifically the order of the types into which 1530 `pointer', and for the others it's `color-pixmap'. The other formats
1213 an image is instantiated, just call `make-image-instance' repeatedly 1531 can only be instantiated as one type. (If you want to control more
1214 until it succeeds, passing less and less preferred destination types 1532 specifically the order of the types into which an image is
1215 each time. 1533 instantiated, just call `make-image-instance' repeatedly until it
1534 succeeds, passing less and less preferred destination types each
1535 time.)
1536
1537 See `make-image-specifier' for a description of the different image
1538 instantiator formats.
1216 1539
1217 If DEST-TYPES is omitted, all possible types are allowed. 1540 If DEST-TYPES is omitted, all possible types are allowed.
1541
1542 DOMAIN specifies the domain to which the image instance will be attached.
1543 This domain is termed the \"governing domain\". The type of the governing
1544 domain depends on the image instantiator format. (Although, more correctly,
1545 it should probably depend on the image instance type.) For example, pixmap
1546 image instances are specific to a device, but widget image instances are
1547 specific to a particular XEmacs window because in order to display such a
1548 widget when two windows onto the same buffer want to display the widget,
1549 two separate underlying widgets must be created. (That's because a widget
1550 is actually a child window-system window, and all window-system windows have
1551 a unique existence on the screen.) This means that the governing domain for
1552 a pixmap image instance will be some device (most likely, the only existing
1553 device), whereas the governing domain for a widget image instance will be
1554 some XEmacs window.
1555
1556 If you specify an overly general DOMAIN (e.g. a frame when a window was
1557 wanted), an error is signaled. If you specify an overly specific DOMAIN
1558 \(e.g. a window when a device was wanted), the corresponding general domain
1559 is fetched and used instead. For `make-image-instance', it makes no
1560 difference whether you specify an overly specific domain or the properly
1561 general domain derived from it. However, it does matter when creating an
1562 image instance by instantiating a specifier or glyph (e.g. with
1563 `glyph-image-instance'), because the more specific domain causes spec lookup
1564 to start there and proceed to more general domains. (It would also matter
1565 when creating an image instance with an instantiator format of `inherit',
1566 but we currently disallow this. #### We should fix this.)
1567
1568 If omitted, DOMAIN defaults to the selected window.
1218 1569
1219 NO-ERROR controls what happens when the image cannot be generated. 1570 NO-ERROR controls what happens when the image cannot be generated.
1220 If nil, an error message is generated. If t, no messages are 1571 If nil, an error message is generated. If t, no messages are
1221 generated and this function returns nil. If anything else, a warning 1572 generated and this function returns nil. If anything else, a warning
1222 message is generated and this function returns nil. 1573 message is generated and this function returns nil.
1223 */ 1574 */
1224 (data, device, dest_types, no_error)) 1575 (data, domain, dest_types, no_error))
1225 { 1576 {
1226 Error_behavior errb = decode_error_behavior_flag (no_error); 1577 Error_behavior errb = decode_error_behavior_flag (no_error);
1227 1578
1228 return call_with_suspended_errors ((lisp_fn_t) make_image_instance_1, 1579 return call_with_suspended_errors ((lisp_fn_t) make_image_instance_1,
1229 Qnil, Qimage, errb, 1580 Qnil, Qimage, errb,
1230 3, data, device, dest_types); 1581 3, data, domain, dest_types);
1231 } 1582 }
1232 1583
1233 DEFUN ("image-instance-p", Fimage_instance_p, 1, 1, 0, /* 1584 DEFUN ("image-instance-p", Fimage_instance_p, 1, 1, 0, /*
1234 Return non-nil if OBJECT is an image instance. 1585 Return non-nil if OBJECT is an image instance.
1235 */ 1586 */
1244 'color-pixmap, 'pointer, or 'subwindow. 1595 'color-pixmap, 'pointer, or 'subwindow.
1245 */ 1596 */
1246 (image_instance)) 1597 (image_instance))
1247 { 1598 {
1248 CHECK_IMAGE_INSTANCE (image_instance); 1599 CHECK_IMAGE_INSTANCE (image_instance);
1600 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1249 return encode_image_instance_type (XIMAGE_INSTANCE_TYPE (image_instance)); 1601 return encode_image_instance_type (XIMAGE_INSTANCE_TYPE (image_instance));
1250 } 1602 }
1251 1603
1252 DEFUN ("image-instance-name", Fimage_instance_name, 1, 1, 0, /* 1604 DEFUN ("image-instance-name", Fimage_instance_name, 1, 1, 0, /*
1253 Return the name of the given image instance. 1605 Return the name of the given image instance.
1254 */ 1606 */
1255 (image_instance)) 1607 (image_instance))
1256 { 1608 {
1257 CHECK_IMAGE_INSTANCE (image_instance); 1609 CHECK_IMAGE_INSTANCE (image_instance);
1258 return XIMAGE_INSTANCE_NAME (image_instance); 1610 return XIMAGE_INSTANCE_NAME (image_instance);
1611 }
1612
1613 DEFUN ("image-instance-domain", Fimage_instance_domain, 1, 1, 0, /*
1614 Return the governing domain of the given image instance.
1615 The governing domain of an image instance is the domain that the image
1616 instance is specific to. It is NOT necessarily the domain that was
1617 given to the call to `specifier-instance' that resulted in the creation
1618 of this image instance. See `make-image-instance' for more information
1619 on governing domains.
1620 */
1621 (image_instance))
1622 {
1623 CHECK_IMAGE_INSTANCE (image_instance);
1624 return XIMAGE_INSTANCE_DOMAIN (image_instance);
1259 } 1625 }
1260 1626
1261 DEFUN ("image-instance-string", Fimage_instance_string, 1, 1, 0, /* 1627 DEFUN ("image-instance-string", Fimage_instance_string, 1, 1, 0, /*
1262 Return the string of the given image instance. 1628 Return the string of the given image instance.
1263 This will only be non-nil for text image instances and widgets. 1629 This will only be non-nil for text image instances and widgets.
1283 Lisp_Image_Instance* ii; 1649 Lisp_Image_Instance* ii;
1284 Lisp_Object type, ret; 1650 Lisp_Object type, ret;
1285 struct image_instantiator_methods* meths; 1651 struct image_instantiator_methods* meths;
1286 1652
1287 CHECK_IMAGE_INSTANCE (image_instance); 1653 CHECK_IMAGE_INSTANCE (image_instance);
1654 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1288 CHECK_SYMBOL (prop); 1655 CHECK_SYMBOL (prop);
1289 ii = XIMAGE_INSTANCE (image_instance); 1656 ii = XIMAGE_INSTANCE (image_instance);
1290 1657
1291 /* ... then try device specific methods ... */ 1658 /* ... then try device specific methods ... */
1292 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); 1659 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
1293 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), 1660 meths = decode_device_ii_format (image_instance_device (image_instance),
1294 type, ERROR_ME_NOT); 1661 type, ERROR_ME_NOT);
1295 if (meths && HAS_IIFORMAT_METH_P (meths, property) 1662 if (meths && HAS_IIFORMAT_METH_P (meths, property)
1296 && 1663 &&
1297 !UNBOUNDP (ret = IIFORMAT_METH (meths, property, (image_instance, prop)))) 1664 !UNBOUNDP (ret = IIFORMAT_METH (meths, property, (image_instance, prop))))
1298 { 1665 {
1308 } 1675 }
1309 /* ... then fail */ 1676 /* ... then fail */
1310 return Qnil; 1677 return Qnil;
1311 } 1678 }
1312 1679
1313 DEFUN ("set-image-instance-property", Fset_image_instance_property, 3, 3, 0, /*
1314 Set the given property of the given image instance.
1315 Does nothing if the property or the property method do not exist for
1316 the image instance in the domain.
1317 */
1318 (image_instance, prop, val))
1319 {
1320 Lisp_Image_Instance* ii;
1321 Lisp_Object type, ret;
1322 struct image_instantiator_methods* meths;
1323
1324 CHECK_IMAGE_INSTANCE (image_instance);
1325 CHECK_SYMBOL (prop);
1326 ii = XIMAGE_INSTANCE (image_instance);
1327 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
1328 /* try device specific methods first ... */
1329 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii),
1330 type, ERROR_ME_NOT);
1331 if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
1332 &&
1333 !UNBOUNDP (ret =
1334 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
1335 {
1336 val = ret;
1337 }
1338 else
1339 {
1340 /* ... then format specific methods ... */
1341 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
1342 if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
1343 &&
1344 !UNBOUNDP (ret =
1345 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
1346 {
1347 val = ret;
1348 }
1349 else
1350 {
1351 val = Qnil;
1352 }
1353 }
1354
1355 /* Make sure the image instance gets redisplayed.
1356
1357 ### This currently does not change the dirty state of an
1358 enclosing layout which may be bad. */
1359 MARK_IMAGE_INSTANCE_CHANGED (ii);
1360 MARK_SUBWINDOWS_STATE_CHANGED;
1361 MARK_GLYPHS_CHANGED;
1362
1363 return val;
1364 }
1365
1366 DEFUN ("image-instance-file-name", Fimage_instance_file_name, 1, 1, 0, /* 1680 DEFUN ("image-instance-file-name", Fimage_instance_file_name, 1, 1, 0, /*
1367 Return the file name from which IMAGE-INSTANCE was read, if known. 1681 Return the file name from which IMAGE-INSTANCE was read, if known.
1368 */ 1682 */
1369 (image_instance)) 1683 (image_instance))
1370 { 1684 {
1371 CHECK_IMAGE_INSTANCE (image_instance); 1685 CHECK_IMAGE_INSTANCE (image_instance);
1686 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1372 1687
1373 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1688 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1374 { 1689 {
1375 case IMAGE_MONO_PIXMAP: 1690 case IMAGE_MONO_PIXMAP:
1376 case IMAGE_COLOR_PIXMAP: 1691 case IMAGE_COLOR_PIXMAP:
1386 Return the file name from which IMAGE-INSTANCE's mask was read, if known. 1701 Return the file name from which IMAGE-INSTANCE's mask was read, if known.
1387 */ 1702 */
1388 (image_instance)) 1703 (image_instance))
1389 { 1704 {
1390 CHECK_IMAGE_INSTANCE (image_instance); 1705 CHECK_IMAGE_INSTANCE (image_instance);
1706 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1391 1707
1392 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1708 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1393 { 1709 {
1394 case IMAGE_MONO_PIXMAP: 1710 case IMAGE_MONO_PIXMAP:
1395 case IMAGE_COLOR_PIXMAP: 1711 case IMAGE_COLOR_PIXMAP:
1406 This is 0 for a bitmap, or a positive integer for a pixmap. 1722 This is 0 for a bitmap, or a positive integer for a pixmap.
1407 */ 1723 */
1408 (image_instance)) 1724 (image_instance))
1409 { 1725 {
1410 CHECK_IMAGE_INSTANCE (image_instance); 1726 CHECK_IMAGE_INSTANCE (image_instance);
1727 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1411 1728
1412 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1729 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1413 { 1730 {
1414 case IMAGE_MONO_PIXMAP: 1731 case IMAGE_MONO_PIXMAP:
1415 case IMAGE_COLOR_PIXMAP: 1732 case IMAGE_COLOR_PIXMAP:
1425 Return the height of the image instance, in pixels. 1742 Return the height of the image instance, in pixels.
1426 */ 1743 */
1427 (image_instance)) 1744 (image_instance))
1428 { 1745 {
1429 CHECK_IMAGE_INSTANCE (image_instance); 1746 CHECK_IMAGE_INSTANCE (image_instance);
1747 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1430 1748
1431 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1749 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1432 { 1750 {
1433 case IMAGE_MONO_PIXMAP: 1751 case IMAGE_MONO_PIXMAP:
1434 case IMAGE_COLOR_PIXMAP: 1752 case IMAGE_COLOR_PIXMAP:
1435 case IMAGE_POINTER: 1753 case IMAGE_POINTER:
1436 case IMAGE_SUBWINDOW: 1754 case IMAGE_SUBWINDOW:
1437 case IMAGE_WIDGET: 1755 case IMAGE_WIDGET:
1438 case IMAGE_LAYOUT:
1439 return make_int (XIMAGE_INSTANCE_HEIGHT (image_instance)); 1756 return make_int (XIMAGE_INSTANCE_HEIGHT (image_instance));
1440 1757
1441 default: 1758 default:
1442 return Qnil; 1759 return Qnil;
1443 } 1760 }
1447 Return the width of the image instance, in pixels. 1764 Return the width of the image instance, in pixels.
1448 */ 1765 */
1449 (image_instance)) 1766 (image_instance))
1450 { 1767 {
1451 CHECK_IMAGE_INSTANCE (image_instance); 1768 CHECK_IMAGE_INSTANCE (image_instance);
1769 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1452 1770
1453 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1771 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1454 { 1772 {
1455 case IMAGE_MONO_PIXMAP: 1773 case IMAGE_MONO_PIXMAP:
1456 case IMAGE_COLOR_PIXMAP: 1774 case IMAGE_COLOR_PIXMAP:
1457 case IMAGE_POINTER: 1775 case IMAGE_POINTER:
1458 case IMAGE_SUBWINDOW: 1776 case IMAGE_SUBWINDOW:
1459 case IMAGE_WIDGET: 1777 case IMAGE_WIDGET:
1460 case IMAGE_LAYOUT:
1461 return make_int (XIMAGE_INSTANCE_WIDTH (image_instance)); 1778 return make_int (XIMAGE_INSTANCE_WIDTH (image_instance));
1462 1779
1463 default: 1780 default:
1464 return Qnil; 1781 return Qnil;
1465 } 1782 }
1474 This will always be nil for a non-pointer image instance. 1791 This will always be nil for a non-pointer image instance.
1475 */ 1792 */
1476 (image_instance)) 1793 (image_instance))
1477 { 1794 {
1478 CHECK_IMAGE_INSTANCE (image_instance); 1795 CHECK_IMAGE_INSTANCE (image_instance);
1796 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1479 1797
1480 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1798 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1481 { 1799 {
1482 case IMAGE_MONO_PIXMAP: 1800 case IMAGE_MONO_PIXMAP:
1483 case IMAGE_COLOR_PIXMAP: 1801 case IMAGE_COLOR_PIXMAP:
1498 This will always be nil for a non-pointer image instance. 1816 This will always be nil for a non-pointer image instance.
1499 */ 1817 */
1500 (image_instance)) 1818 (image_instance))
1501 { 1819 {
1502 CHECK_IMAGE_INSTANCE (image_instance); 1820 CHECK_IMAGE_INSTANCE (image_instance);
1821 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1503 1822
1504 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1823 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1505 { 1824 {
1506 case IMAGE_MONO_PIXMAP: 1825 case IMAGE_MONO_PIXMAP:
1507 case IMAGE_COLOR_PIXMAP: 1826 case IMAGE_COLOR_PIXMAP:
1519 colorized mono pixmaps and for pointers.) 1838 colorized mono pixmaps and for pointers.)
1520 */ 1839 */
1521 (image_instance)) 1840 (image_instance))
1522 { 1841 {
1523 CHECK_IMAGE_INSTANCE (image_instance); 1842 CHECK_IMAGE_INSTANCE (image_instance);
1843 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1524 1844
1525 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1845 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1526 { 1846 {
1527 case IMAGE_MONO_PIXMAP: 1847 case IMAGE_MONO_PIXMAP:
1528 case IMAGE_COLOR_PIXMAP: 1848 case IMAGE_COLOR_PIXMAP:
1530 return XIMAGE_INSTANCE_PIXMAP_FG (image_instance); 1850 return XIMAGE_INSTANCE_PIXMAP_FG (image_instance);
1531 1851
1532 case IMAGE_WIDGET: 1852 case IMAGE_WIDGET:
1533 return FACE_FOREGROUND ( 1853 return FACE_FOREGROUND (
1534 XIMAGE_INSTANCE_WIDGET_FACE (image_instance), 1854 XIMAGE_INSTANCE_WIDGET_FACE (image_instance),
1535 XIMAGE_INSTANCE_SUBWINDOW_FRAME 1855 XIMAGE_INSTANCE_FRAME
1536 (image_instance)); 1856 (image_instance));
1537 1857
1538 default: 1858 default:
1539 return Qnil; 1859 return Qnil;
1540 } 1860 }
1546 colorized mono pixmaps and for pointers.) 1866 colorized mono pixmaps and for pointers.)
1547 */ 1867 */
1548 (image_instance)) 1868 (image_instance))
1549 { 1869 {
1550 CHECK_IMAGE_INSTANCE (image_instance); 1870 CHECK_IMAGE_INSTANCE (image_instance);
1871 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1551 1872
1552 switch (XIMAGE_INSTANCE_TYPE (image_instance)) 1873 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1553 { 1874 {
1554 case IMAGE_MONO_PIXMAP: 1875 case IMAGE_MONO_PIXMAP:
1555 case IMAGE_COLOR_PIXMAP: 1876 case IMAGE_COLOR_PIXMAP:
1557 return XIMAGE_INSTANCE_PIXMAP_BG (image_instance); 1878 return XIMAGE_INSTANCE_PIXMAP_BG (image_instance);
1558 1879
1559 case IMAGE_WIDGET: 1880 case IMAGE_WIDGET:
1560 return FACE_BACKGROUND ( 1881 return FACE_BACKGROUND (
1561 XIMAGE_INSTANCE_WIDGET_FACE (image_instance), 1882 XIMAGE_INSTANCE_WIDGET_FACE (image_instance),
1562 XIMAGE_INSTANCE_SUBWINDOW_FRAME 1883 XIMAGE_INSTANCE_FRAME
1563 (image_instance)); 1884 (image_instance));
1564 1885
1565 default: 1886 default:
1566 return Qnil; 1887 return Qnil;
1567 } 1888 }
1579 { 1900 {
1580 Lisp_Object new; 1901 Lisp_Object new;
1581 Lisp_Object device; 1902 Lisp_Object device;
1582 1903
1583 CHECK_IMAGE_INSTANCE (image_instance); 1904 CHECK_IMAGE_INSTANCE (image_instance);
1905 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1584 CHECK_COLOR_INSTANCE (foreground); 1906 CHECK_COLOR_INSTANCE (foreground);
1585 CHECK_COLOR_INSTANCE (background); 1907 CHECK_COLOR_INSTANCE (background);
1586 1908
1587 device = XIMAGE_INSTANCE_DEVICE (image_instance); 1909 device = image_instance_device (image_instance);
1588 if (!HAS_DEVMETH_P (XDEVICE (device), colorize_image_instance)) 1910 if (!HAS_DEVMETH_P (XDEVICE (device), colorize_image_instance))
1589 return image_instance; 1911 return image_instance;
1590 1912
1591 /* #### There should be a copy_image_instance(), which calls a 1913 /* #### There should be a copy_image_instance(), which calls a
1592 device-specific method to copy the window-system subobject. */ 1914 device-specific method to copy the window-system subobject. */
1593 new = allocate_image_instance (device, Qnil); 1915 new = allocate_image_instance (XIMAGE_INSTANCE_DOMAIN (image_instance),
1916 Qnil, Qnil);
1594 copy_lcrecord (XIMAGE_INSTANCE (new), XIMAGE_INSTANCE (image_instance)); 1917 copy_lcrecord (XIMAGE_INSTANCE (new), XIMAGE_INSTANCE (image_instance));
1595 /* note that if this method returns non-zero, this method MUST 1918 /* note that if this method returns non-zero, this method MUST
1596 copy any window-system resources, so that when one image instance is 1919 copy any window-system resources, so that when one image instance is
1597 freed, the other one is not hosed. */ 1920 freed, the other one is not hosed. */
1598 if (!DEVMETH (XDEVICE (device), colorize_image_instance, (new, foreground, 1921 if (!DEVMETH (XDEVICE (device), colorize_image_instance, (new, foreground,
1608 1931
1609 /* Find out desired geometry of the image instance. If there is no 1932 /* Find out desired geometry of the image instance. If there is no
1610 special function then just return the width and / or height. */ 1933 special function then just return the width and / or height. */
1611 void 1934 void
1612 image_instance_query_geometry (Lisp_Object image_instance, 1935 image_instance_query_geometry (Lisp_Object image_instance,
1613 unsigned int* width, unsigned int* height, 1936 int* width, int* height,
1614 enum image_instance_geometry disp, 1937 enum image_instance_geometry disp,
1615 Lisp_Object domain) 1938 Lisp_Object domain)
1616 { 1939 {
1617 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); 1940 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
1618 Lisp_Object type; 1941 Lisp_Object type;
1619 struct image_instantiator_methods* meths; 1942 struct image_instantiator_methods* meths;
1943 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1620 1944
1621 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); 1945 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
1622 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); 1946 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
1623 1947
1624 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry)) 1948 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry))
1639 widgets are going to do different kinds of calculations to 1963 widgets are going to do different kinds of calculations to
1640 determine what size to give things so we could make the layout 1964 determine what size to give things so we could make the layout
1641 function relatively simple to take account of that. An alternative 1965 function relatively simple to take account of that. An alternative
1642 approach is to consider separately the two cases, one where you 1966 approach is to consider separately the two cases, one where you
1643 don't mind what size you have (normal widgets) and one where you 1967 don't mind what size you have (normal widgets) and one where you
1644 want to specifiy something (layout widgets). */ 1968 want to specify something (layout widgets). */
1645 void 1969 void
1646 image_instance_layout (Lisp_Object image_instance, 1970 image_instance_layout (Lisp_Object image_instance,
1647 unsigned int width, unsigned int height, 1971 int width, int height,
1972 int xoffset, int yoffset,
1648 Lisp_Object domain) 1973 Lisp_Object domain)
1649 { 1974 {
1650 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); 1975 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
1651 Lisp_Object type; 1976 Lisp_Object type;
1652 struct image_instantiator_methods* meths; 1977 struct image_instantiator_methods* meths;
1978
1979 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
1980
1981 /* Nothing is as nothing does. */
1982 if (NOTHING_IMAGE_INSTANCEP (image_instance))
1983 return;
1984
1985 /* We don't want carefully calculated offsets to be mucked up by
1986 random layouts. */
1987 if (xoffset != IMAGE_UNCHANGED_GEOMETRY)
1988 XIMAGE_INSTANCE_XOFFSET (image_instance) = xoffset;
1989 if (yoffset != IMAGE_UNCHANGED_GEOMETRY)
1990 XIMAGE_INSTANCE_YOFFSET (image_instance) = yoffset;
1991
1992 assert (XIMAGE_INSTANCE_YOFFSET (image_instance) >= 0
1993 && XIMAGE_INSTANCE_XOFFSET (image_instance) >= 0);
1653 1994
1654 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); 1995 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
1655 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); 1996 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
1656 1997
1657 /* If geometry is unspecified then get some reasonable values for it. */ 1998 /* If geometry is unspecified then get some reasonable values for it. */
1658 if (width == IMAGE_UNSPECIFIED_GEOMETRY 1999 if (width == IMAGE_UNSPECIFIED_GEOMETRY
1659 || 2000 ||
1660 height == IMAGE_UNSPECIFIED_GEOMETRY) 2001 height == IMAGE_UNSPECIFIED_GEOMETRY)
1661 { 2002 {
1662 unsigned int dwidth, dheight; 2003 int dwidth = IMAGE_UNSPECIFIED_GEOMETRY;
2004 int dheight = IMAGE_UNSPECIFIED_GEOMETRY;
1663 2005
1664 /* Get the desired geometry. */ 2006 /* Get the desired geometry. */
1665 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry)) 2007 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry))
1666 { 2008 {
1667 IIFORMAT_METH (meths, query_geometry, (image_instance, &dwidth, &dheight, 2009 IIFORMAT_METH (meths, query_geometry, (image_instance, &dwidth, &dheight,
1679 width = dwidth; 2021 width = dwidth;
1680 if (height == IMAGE_UNSPECIFIED_GEOMETRY) 2022 if (height == IMAGE_UNSPECIFIED_GEOMETRY)
1681 height = dheight; 2023 height = dheight;
1682 } 2024 }
1683 2025
2026 /* If we don't have sane values then we cannot layout at this point and
2027 must just return. */
2028 if (width == IMAGE_UNSPECIFIED_GEOMETRY
2029 ||
2030 height == IMAGE_UNSPECIFIED_GEOMETRY)
2031 return;
2032
1684 /* At this point width and height should contain sane values. Thus 2033 /* At this point width and height should contain sane values. Thus
1685 we set the glyph geometry and lay it out. */ 2034 we set the glyph geometry and lay it out. */
2035 if (IMAGE_INSTANCE_WIDTH (ii) != width
2036 ||
2037 IMAGE_INSTANCE_HEIGHT (ii) != height)
2038 {
2039 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 1;
2040 }
2041
1686 IMAGE_INSTANCE_WIDTH (ii) = width; 2042 IMAGE_INSTANCE_WIDTH (ii) = width;
1687 IMAGE_INSTANCE_HEIGHT (ii) = height; 2043 IMAGE_INSTANCE_HEIGHT (ii) = height;
1688 2044
1689 if (meths && HAS_IIFORMAT_METH_P (meths, layout)) 2045 if (IIFORMAT_METH_OR_GIVEN (meths, layout,
1690 { 2046 (image_instance, width, height, xoffset, yoffset,
1691 IIFORMAT_METH (meths, layout, (image_instance, width, height, domain)); 2047 domain), 1))
1692 } 2048 /* Do not clear the dirty flag here - redisplay will do this for
1693 /* else no change to the geometry. */ 2049 us at the end. */
1694 2050 IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 0;
1695 XIMAGE_INSTANCE_DIRTYP (image_instance) = 0; 2051 }
2052
2053 /* Update an image instance from its changed instantiator. */
2054 static void
2055 update_image_instance (Lisp_Object image_instance,
2056 Lisp_Object instantiator)
2057 {
2058 struct image_instantiator_methods* meths;
2059 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2060
2061 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
2062
2063 if (NOTHING_IMAGE_INSTANCEP (image_instance))
2064 return;
2065
2066 assert (!internal_equal (IMAGE_INSTANCE_INSTANTIATOR (ii), instantiator, 0)
2067 || (internal_equal (IMAGE_INSTANCE_INSTANTIATOR (ii), instantiator, 0)
2068 && internal_equal (IMAGE_INSTANCE_INSTANTIATOR (ii), instantiator, -10)));
2069
2070 /* If the instantiator is identical then do nothing. We must use
2071 equal here because the specifier code copies the instantiator. */
2072 if (!internal_equal (IMAGE_INSTANCE_INSTANTIATOR (ii), instantiator, 0))
2073 {
2074 /* Extract the changed properties so that device / format
2075 methods only have to cope with these. We assume that
2076 normalization has already been done. */
2077 Lisp_Object diffs = find_instantiator_differences
2078 (instantiator,
2079 IMAGE_INSTANCE_INSTANTIATOR (ii));
2080 Lisp_Object type = encode_image_instance_type
2081 (IMAGE_INSTANCE_TYPE (ii));
2082 struct gcpro gcpro1;
2083 GCPRO1 (diffs);
2084
2085 /* try device specific methods first ... */
2086 meths = decode_device_ii_format (image_instance_device (image_instance),
2087 type, ERROR_ME_NOT);
2088 MAYBE_IIFORMAT_METH (meths, update, (image_instance, diffs));
2089 /* ... then format specific methods ... */
2090 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
2091 MAYBE_IIFORMAT_METH (meths, update, (image_instance, diffs));
2092
2093 /* Instance and therefore glyph has changed so mark as dirty.
2094 If we don't do this output optimizations will assume the
2095 glyph is unchanged. */
2096 set_image_instance_dirty_p (image_instance, 1);
2097 /* Structure has changed. */
2098 IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 1;
2099
2100 UNGCPRO;
2101 }
2102 /* We should now have a consistent instantiator so keep a record of
2103 it. It is important that we don't actually update the window
2104 system widgets here - we must do that when redisplay tells us
2105 to.
2106
2107 #### should we delay doing this until the display is up-to-date
2108 also? */
2109 IMAGE_INSTANCE_INSTANTIATOR (ii) = instantiator;
1696 } 2110 }
1697 2111
1698 /* 2112 /*
1699 * Mark image instance in W as dirty if (a) W's faces have changed and 2113 * Mark image instance in W as dirty if (a) W's faces have changed and
1700 * (b) GLYPH_OR_II instance in W is a string. 2114 * (b) GLYPH_OR_II instance in W is a string.
1715 image = glyph_image_instance (glyph_or_ii, window, ERROR_ME_NOT, 1); 2129 image = glyph_image_instance (glyph_or_ii, window, ERROR_ME_NOT, 1);
1716 } 2130 }
1717 2131
1718 if (TEXT_IMAGE_INSTANCEP (image)) 2132 if (TEXT_IMAGE_INSTANCEP (image))
1719 { 2133 {
1720 XIMAGE_INSTANCE_DIRTYP (image) = 1; 2134 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image);
2135 IMAGE_INSTANCE_DIRTYP (ii) = 1;
2136 IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 1;
1721 if (GLYPHP (glyph_or_ii)) 2137 if (GLYPHP (glyph_or_ii))
1722 XGLYPH_DIRTYP (glyph_or_ii) = 1; 2138 XGLYPH_DIRTYP (glyph_or_ii) = 1;
1723 return 1; 2139 return 1;
1724 } 2140 }
1725 } 2141 }
1730 2146
1731 /************************************************************************/ 2147 /************************************************************************/
1732 /* error helpers */ 2148 /* error helpers */
1733 /************************************************************************/ 2149 /************************************************************************/
1734 DOESNT_RETURN 2150 DOESNT_RETURN
1735 signal_image_error (CONST char *reason, Lisp_Object frob) 2151 signal_image_error (const char *reason, Lisp_Object frob)
1736 { 2152 {
1737 signal_error (Qimage_conversion_error, 2153 signal_error (Qimage_conversion_error,
1738 list2 (build_translated_string (reason), frob)); 2154 list2 (build_translated_string (reason), frob));
1739 } 2155 }
1740 2156
1741 DOESNT_RETURN 2157 DOESNT_RETURN
1742 signal_image_error_2 (CONST char *reason, Lisp_Object frob0, Lisp_Object frob1) 2158 signal_image_error_2 (const char *reason, Lisp_Object frob0, Lisp_Object frob1)
1743 { 2159 {
1744 signal_error (Qimage_conversion_error, 2160 signal_error (Qimage_conversion_error,
1745 list3 (build_translated_string (reason), frob0, frob1)); 2161 list3 (build_translated_string (reason), frob0, frob1));
1746 } 2162 }
1747 2163
1761 int dest_mask, Lisp_Object domain) 2177 int dest_mask, Lisp_Object domain)
1762 { 2178 {
1763 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 2179 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1764 2180
1765 if (dest_mask & IMAGE_NOTHING_MASK) 2181 if (dest_mask & IMAGE_NOTHING_MASK)
1766 IMAGE_INSTANCE_TYPE (ii) = IMAGE_NOTHING; 2182 {
2183 IMAGE_INSTANCE_TYPE (ii) = IMAGE_NOTHING;
2184 IMAGE_INSTANCE_HEIGHT (ii) = 0;
2185 IMAGE_INSTANCE_WIDTH (ii) = 0;
2186 }
1767 else 2187 else
1768 incompatible_image_types (instantiator, dest_mask, IMAGE_NOTHING_MASK); 2188 incompatible_image_types (instantiator, dest_mask, IMAGE_NOTHING_MASK);
1769 } 2189 }
1770 2190
1771 2191
1778 { 2198 {
1779 face_must_be_present (instantiator); 2199 face_must_be_present (instantiator);
1780 } 2200 }
1781 2201
1782 static Lisp_Object 2202 static Lisp_Object
1783 inherit_normalize (Lisp_Object inst, Lisp_Object console_type) 2203 inherit_normalize (Lisp_Object inst, Lisp_Object console_type,
2204 Lisp_Object dest_mask)
1784 { 2205 {
1785 Lisp_Object face; 2206 Lisp_Object face;
1786 2207
1787 assert (XVECTOR_LENGTH (inst) == 3); 2208 assert (XVECTOR_LENGTH (inst) == 3);
1788 face = XVECTOR_DATA (inst)[2]; 2209 face = XVECTOR_DATA (inst)[2];
1831 { 2252 {
1832 Lisp_Object string = find_keyword_in_vector (instantiator, Q_data); 2253 Lisp_Object string = find_keyword_in_vector (instantiator, Q_data);
1833 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 2254 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1834 2255
1835 /* Should never get here with a domain other than a window. */ 2256 /* Should never get here with a domain other than a window. */
1836 assert (!NILP (string) && WINDOWP (domain)); 2257 assert (!NILP (string) && WINDOWP (DOMAIN_WINDOW (domain)));
1837 if (dest_mask & IMAGE_TEXT_MASK) 2258 if (dest_mask & IMAGE_TEXT_MASK)
1838 { 2259 {
1839 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT; 2260 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT;
1840 IMAGE_INSTANCE_TEXT_STRING (ii) = string; 2261 IMAGE_INSTANCE_TEXT_STRING (ii) = string;
1841 } 2262 }
1848 everything. Note that the following methods are for text not string 2269 everything. Note that the following methods are for text not string
1849 since that is what the instantiated type is. The first method is a 2270 since that is what the instantiated type is. The first method is a
1850 helper that is used elsewhere for calculating text geometry. */ 2271 helper that is used elsewhere for calculating text geometry. */
1851 void 2272 void
1852 query_string_geometry (Lisp_Object string, Lisp_Object face, 2273 query_string_geometry (Lisp_Object string, Lisp_Object face,
1853 unsigned int* width, unsigned int* height, 2274 int* width, int* height, int* descent, Lisp_Object domain)
1854 unsigned int* descent, Lisp_Object domain)
1855 { 2275 {
1856 struct font_metric_info fm; 2276 struct font_metric_info fm;
1857 unsigned char charsets[NUM_LEADING_BYTES]; 2277 unsigned char charsets[NUM_LEADING_BYTES];
1858 struct face_cachel frame_cachel; 2278 struct face_cachel frame_cachel;
1859 struct face_cachel *cachel; 2279 struct face_cachel *cachel;
1860 Lisp_Object frame = FW_FRAME (domain); 2280 Lisp_Object frame = DOMAIN_FRAME (domain);
1861 2281
1862 /* Compute height */ 2282 /* Compute height */
1863 if (height) 2283 if (height)
1864 { 2284 {
1865 /* Compute string metric info */ 2285 /* Compute string metric info */
1874 update_face_cachel_data (&frame_cachel, frame, face); 2294 update_face_cachel_data (&frame_cachel, frame, face);
1875 cachel = &frame_cachel; 2295 cachel = &frame_cachel;
1876 } 2296 }
1877 else 2297 else
1878 { 2298 {
1879 cachel = WINDOW_FACE_CACHEL (XWINDOW (domain), DEFAULT_INDEX); 2299 cachel = WINDOW_FACE_CACHEL (DOMAIN_XWINDOW (domain),
2300 DEFAULT_INDEX);
1880 } 2301 }
1881 2302
1882 ensure_face_cachel_complete (cachel, domain, charsets); 2303 ensure_face_cachel_complete (cachel, domain, charsets);
1883 face_cachel_charset_font_metric_info (cachel, charsets, &fm); 2304 face_cachel_charset_font_metric_info (cachel, charsets, &fm);
1884 2305
1907 { 2328 {
1908 unsigned char charsets[NUM_LEADING_BYTES]; 2329 unsigned char charsets[NUM_LEADING_BYTES];
1909 struct face_cachel frame_cachel; 2330 struct face_cachel frame_cachel;
1910 struct face_cachel *cachel; 2331 struct face_cachel *cachel;
1911 int i; 2332 int i;
1912 Lisp_Object frame = FW_FRAME (domain); 2333 Lisp_Object frame = DOMAIN_FRAME (domain);
1913 2334
1914 /* Compute string font info */ 2335 /* Compute string font info */
1915 find_charsets_in_bufbyte_string (charsets, 2336 find_charsets_in_bufbyte_string (charsets,
1916 XSTRING_DATA (string), 2337 XSTRING_DATA (string),
1917 XSTRING_LENGTH (string)); 2338 XSTRING_LENGTH (string));
1936 return Qnil; /* NOT REACHED */ 2357 return Qnil; /* NOT REACHED */
1937 } 2358 }
1938 2359
1939 static void 2360 static void
1940 text_query_geometry (Lisp_Object image_instance, 2361 text_query_geometry (Lisp_Object image_instance,
1941 unsigned int* width, unsigned int* height, 2362 int* width, int* height,
1942 enum image_instance_geometry disp, Lisp_Object domain) 2363 enum image_instance_geometry disp, Lisp_Object domain)
1943 { 2364 {
1944 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 2365 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1945 unsigned int descent = 0; 2366 int descent = 0;
1946 2367
1947 query_string_geometry (IMAGE_INSTANCE_TEXT_STRING (ii), 2368 query_string_geometry (IMAGE_INSTANCE_TEXT_STRING (ii),
1948 IMAGE_INSTANCE_FACE (ii), 2369 IMAGE_INSTANCE_FACE (ii),
1949 width, height, &descent, domain); 2370 width, height, &descent, domain);
1950 2371
1952 geometry. */ 2373 geometry. */
1953 IMAGE_INSTANCE_TEXT_DESCENT (ii) = descent; 2374 IMAGE_INSTANCE_TEXT_DESCENT (ii) = descent;
1954 } 2375 }
1955 2376
1956 /* set the properties of a string */ 2377 /* set the properties of a string */
1957 static Lisp_Object 2378 static void
1958 text_set_property (Lisp_Object image_instance, Lisp_Object prop, 2379 text_update (Lisp_Object image_instance, Lisp_Object instantiator)
1959 Lisp_Object val) 2380 {
1960 { 2381 Lisp_Object val = find_keyword_in_vector (instantiator, Q_data);
1961 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 2382
1962 2383 if (!NILP (val))
1963 if (EQ (prop, Q_data))
1964 { 2384 {
1965 CHECK_STRING (val); 2385 CHECK_STRING (val);
1966 IMAGE_INSTANCE_TEXT_STRING (ii) = val; 2386 XIMAGE_INSTANCE_TEXT_STRING (image_instance) = val;
1967 2387 }
1968 return Qt;
1969 }
1970 return Qunbound;
1971 } 2388 }
1972 2389
1973 2390
1974 /**************************************************************************** 2391 /****************************************************************************
1975 * formatted-string * 2392 * formatted-string *
2160 int ok_if_data_invalid) 2577 int ok_if_data_invalid)
2161 { 2578 {
2162 unsigned int w, h; 2579 unsigned int w, h;
2163 Extbyte *data; 2580 Extbyte *data;
2164 int result; 2581 int result;
2165 CONST char *filename_ext; 2582 const char *filename_ext;
2166 2583
2167 TO_EXTERNAL_FORMAT (LISP_STRING, name, 2584 LISP_STRING_TO_EXTERNAL (name, filename_ext, Qfile_name);
2168 C_STRING_ALLOCA, filename_ext,
2169 Qfile_name);
2170 result = read_bitmap_data_from_file (filename_ext, &w, &h, 2585 result = read_bitmap_data_from_file (filename_ext, &w, &h,
2171 &data, xhot, yhot); 2586 &data, xhot, yhot);
2172 2587
2173 if (result == BitmapSuccess) 2588 if (result == BitmapSuccess)
2174 { 2589 {
2250 } 2665 }
2251 2666
2252 /* Normalize method for XBM's. */ 2667 /* Normalize method for XBM's. */
2253 2668
2254 static Lisp_Object 2669 static Lisp_Object
2255 xbm_normalize (Lisp_Object inst, Lisp_Object console_type) 2670 xbm_normalize (Lisp_Object inst, Lisp_Object console_type,
2671 Lisp_Object dest_mask)
2256 { 2672 {
2257 Lisp_Object file = Qnil, mask_file = Qnil; 2673 Lisp_Object file = Qnil, mask_file = Qnil;
2258 struct gcpro gcpro1, gcpro2, gcpro3; 2674 struct gcpro gcpro1, gcpro2, gcpro3;
2259 Lisp_Object alist = Qnil; 2675 Lisp_Object alist = Qnil;
2260 2676
2333 { 2749 {
2334 file_or_data_must_be_present (instantiator); 2750 file_or_data_must_be_present (instantiator);
2335 } 2751 }
2336 2752
2337 static Lisp_Object 2753 static Lisp_Object
2338 xface_normalize (Lisp_Object inst, Lisp_Object console_type) 2754 xface_normalize (Lisp_Object inst, Lisp_Object console_type,
2755 Lisp_Object dest_mask)
2339 { 2756 {
2340 /* This function can call lisp */ 2757 /* This function can call lisp */
2341 Lisp_Object file = Qnil, mask_file = Qnil; 2758 Lisp_Object file = Qnil, mask_file = Qnil;
2342 struct gcpro gcpro1, gcpro2, gcpro3; 2759 struct gcpro gcpro1, gcpro2, gcpro3;
2343 Lisp_Object alist = Qnil; 2760 Lisp_Object alist = Qnil;
2408 { 2825 {
2409 char **data; 2826 char **data;
2410 int result; 2827 int result;
2411 char *fname = 0; 2828 char *fname = 0;
2412 2829
2413 TO_EXTERNAL_FORMAT (LISP_STRING, name, 2830 LISP_STRING_TO_EXTERNAL (name, fname, Qfile_name);
2414 C_STRING_ALLOCA, fname,
2415 Qfile_name);
2416 result = XpmReadFileToData (fname, &data); 2831 result = XpmReadFileToData (fname, &data);
2417 2832
2418 if (result == XpmSuccess) 2833 if (result == XpmSuccess)
2419 { 2834 {
2420 Lisp_Object retval = Qnil; 2835 Lisp_Object retval = Qnil;
2542 UNGCPRO; /* no more evaluation */ 2957 UNGCPRO; /* no more evaluation */
2543 return results; 2958 return results;
2544 } 2959 }
2545 2960
2546 static Lisp_Object 2961 static Lisp_Object
2547 xpm_normalize (Lisp_Object inst, Lisp_Object console_type) 2962 xpm_normalize (Lisp_Object inst, Lisp_Object console_type,
2963 Lisp_Object dest_mask)
2548 { 2964 {
2549 Lisp_Object file = Qnil; 2965 Lisp_Object file = Qnil;
2550 Lisp_Object color_symbols; 2966 Lisp_Object color_symbols;
2551 struct gcpro gcpro1, gcpro2; 2967 struct gcpro gcpro1, gcpro2;
2552 Lisp_Object alist = Qnil; 2968 Lisp_Object alist = Qnil;
2639 } 3055 }
2640 3056
2641 static Lisp_Object 3057 static Lisp_Object
2642 image_instantiate_cache_result (Lisp_Object locative) 3058 image_instantiate_cache_result (Lisp_Object locative)
2643 { 3059 {
2644 /* locative = (instance instantiator . subtable) */ 3060 /* locative = (instance instantiator . subtable)
3061
3062 So we are using the instantiator as the key and the instance as
3063 the value. Since the hashtable is key-weak this means that the
3064 image instance will stay around as long as the instantiator stays
3065 around. The instantiator is stored in the `image' slot of the
3066 glyph, so as long as the glyph is marked the instantiator will be
3067 as well and hence the cached image instance also.*/
2645 Fputhash (XCAR (XCDR (locative)), XCAR (locative), XCDR (XCDR (locative))); 3068 Fputhash (XCAR (XCDR (locative)), XCAR (locative), XCDR (XCDR (locative)));
2646 free_cons (XCONS (XCDR (locative))); 3069 free_cons (XCONS (XCDR (locative)));
2647 free_cons (XCONS (locative)); 3070 free_cons (XCONS (locative));
2648 return Qnil; 3071 return Qnil;
2649 } 3072 }
2655 static Lisp_Object 3078 static Lisp_Object
2656 image_instantiate (Lisp_Object specifier, Lisp_Object matchspec, 3079 image_instantiate (Lisp_Object specifier, Lisp_Object matchspec,
2657 Lisp_Object domain, Lisp_Object instantiator, 3080 Lisp_Object domain, Lisp_Object instantiator,
2658 Lisp_Object depth) 3081 Lisp_Object depth)
2659 { 3082 {
2660 Lisp_Object device = DFW_DEVICE (domain);
2661 struct device *d = XDEVICE (device);
2662 Lisp_Object glyph = IMAGE_SPECIFIER_ATTACHEE (XIMAGE_SPECIFIER (specifier)); 3083 Lisp_Object glyph = IMAGE_SPECIFIER_ATTACHEE (XIMAGE_SPECIFIER (specifier));
2663 int dest_mask = XIMAGE_SPECIFIER_ALLOWED (specifier); 3084 int dest_mask = XIMAGE_SPECIFIER_ALLOWED (specifier);
2664 int pointerp = dest_mask & image_instance_type_to_mask (IMAGE_POINTER); 3085 int pointerp = dest_mask & image_instance_type_to_mask (IMAGE_POINTER);
2665 3086
2666 if (IMAGE_INSTANCEP (instantiator)) 3087 if (IMAGE_INSTANCEP (instantiator))
2667 { 3088 {
2668 /* make sure that the image instance's device and type are 3089 /* make sure that the image instance's governing domain and type are
2669 matching. */ 3090 matching. */
2670 3091 Lisp_Object governing_domain = XIMAGE_INSTANCE_DOMAIN (instantiator);
2671 if (EQ (device, XIMAGE_INSTANCE_DEVICE (instantiator))) 3092
3093 if ((DEVICEP (governing_domain)
3094 && EQ (governing_domain, DOMAIN_DEVICE (domain)))
3095 || (FRAMEP (governing_domain)
3096 && EQ (governing_domain, DOMAIN_FRAME (domain)))
3097 || (WINDOWP (governing_domain)
3098 && EQ (governing_domain, DOMAIN_WINDOW (domain))))
2672 { 3099 {
2673 int mask = 3100 int mask =
2674 image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instantiator)); 3101 image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instantiator));
2675 if (mask & dest_mask) 3102 if (mask & dest_mask)
2676 return instantiator; 3103 return instantiator;
2677 else 3104 else
2678 signal_simple_error ("Type of image instance not allowed here", 3105 signal_simple_error ("Type of image instance not allowed here",
2679 instantiator); 3106 instantiator);
2680 } 3107 }
2681 else 3108 else
2682 signal_simple_error_2 ("Wrong device for image instance", 3109 signal_simple_error_2 ("Wrong domain for image instance",
2683 instantiator, device); 3110 instantiator, domain);
2684 } 3111 }
2685 else if (VECTORP (instantiator) 3112 else if (VECTORP (instantiator)
2686 && EQ (XVECTOR_DATA (instantiator)[0], Qinherit)) 3113 && EQ (XVECTOR_DATA (instantiator)[0], Qinherit))
2687 { 3114 {
2688 assert (XVECTOR_LENGTH (instantiator) == 3); 3115 assert (XVECTOR_LENGTH (instantiator) == 3);
2690 (Fget_face (XVECTOR_DATA (instantiator)[2]), 3117 (Fget_face (XVECTOR_DATA (instantiator)[2]),
2691 Qbackground_pixmap, domain, 0, depth)); 3118 Qbackground_pixmap, domain, 0, depth));
2692 } 3119 }
2693 else 3120 else
2694 { 3121 {
2695 Lisp_Object instance; 3122 Lisp_Object instance = Qnil;
2696 Lisp_Object subtable; 3123 Lisp_Object subtable = Qnil;
2697 Lisp_Object ls3 = Qnil; 3124 Lisp_Object ls3 = Qnil;
2698 Lisp_Object pointer_fg = Qnil; 3125 Lisp_Object pointer_fg = Qnil;
2699 Lisp_Object pointer_bg = Qnil; 3126 Lisp_Object pointer_bg = Qnil;
3127 Lisp_Object governing_domain =
3128 get_image_instantiator_governing_domain (instantiator, domain);
3129 struct gcpro gcpro1;
3130
3131 GCPRO1 (instance);
3132
3133 /* We have to put subwindow, widget and text image instances in
3134 a per-window cache so that we can see the same glyph in
3135 different windows. We use governing_domain to determine the type
3136 of image_instance that will be created. */
2700 3137
2701 if (pointerp) 3138 if (pointerp)
2702 { 3139 {
2703 pointer_fg = FACE_FOREGROUND (Vpointer_face, domain); 3140 pointer_fg = FACE_FOREGROUND (Vpointer_face, domain);
2704 pointer_bg = FACE_BACKGROUND (Vpointer_face, domain); 3141 pointer_bg = FACE_BACKGROUND (Vpointer_face, domain);
2705 ls3 = list3 (instantiator, pointer_fg, pointer_bg); 3142 ls3 = list3 (glyph, pointer_fg, pointer_bg);
2706 } 3143 }
2707 3144
2708 /* First look in the hash table. */ 3145 /* First look in the device cache. */
2709 subtable = Fgethash (make_int (dest_mask), d->image_instance_cache, 3146 if (DEVICEP (governing_domain))
2710 Qunbound);
2711 if (UNBOUNDP (subtable))
2712 { 3147 {
2713 /* For the image instance cache, we do comparisons with EQ rather 3148 subtable = Fgethash (make_int (dest_mask),
2714 than with EQUAL, as we do for color and font names. 3149 XDEVICE (governing_domain)->
2715 The reasons are: 3150 image_instance_cache,
2716 3151 Qunbound);
2717 1) pixmap data can be very long, and thus the hashing and 3152 if (UNBOUNDP (subtable))
2718 comparing will take awhile. 3153 {
2719 2) It's not so likely that we'll run into things that are EQUAL 3154 /* For the image instance cache, we do comparisons with
2720 but not EQ (that can happen a lot with faces, because their 3155 EQ rather than with EQUAL, as we do for color and
2721 specifiers are copied around); but pixmaps tend not to be 3156 font names. The reasons are:
2722 in faces. 3157
2723 3158 1) pixmap data can be very long, and thus the hashing
2724 However, if the image-instance could be a pointer, we have to 3159 and comparing will take awhile.
2725 use EQUAL because we massaged the instantiator into a cons3 3160
2726 also containing the foreground and background of the 3161 2) It's not so likely that we'll run into things that
2727 pointer face. 3162 are EQUAL but not EQ (that can happen a lot with
2728 */ 3163 faces, because their specifiers are copied around);
2729 3164 but pixmaps tend not to be in faces.
2730 subtable = make_lisp_hash_table (20, 3165
2731 pointerp ? HASH_TABLE_KEY_CAR_WEAK 3166 However, if the image-instance could be a pointer, we
2732 : HASH_TABLE_KEY_WEAK, 3167 have to use EQUAL because we massaged the
2733 pointerp ? HASH_TABLE_EQUAL 3168 instantiator into a cons3 also containing the
2734 : HASH_TABLE_EQ); 3169 foreground and background of the pointer face. */
2735 Fputhash (make_int (dest_mask), subtable, 3170
2736 d->image_instance_cache); 3171 subtable = make_lisp_hash_table
2737 instance = Qunbound; 3172 (20, pointerp ? HASH_TABLE_KEY_CAR_WEAK
3173 : HASH_TABLE_KEY_WEAK,
3174 pointerp ? HASH_TABLE_EQUAL
3175 : HASH_TABLE_EQ);
3176 Fputhash (make_int (dest_mask), subtable,
3177 XDEVICE (governing_domain)->image_instance_cache);
3178 instance = Qunbound;
3179 }
3180 else
3181 {
3182 instance = Fgethash (pointerp ? ls3 : glyph,
3183 subtable, Qunbound);
3184 }
3185 }
3186 else if (WINDOWP (governing_domain))
3187 {
3188 /* Subwindows have a per-window cache and have to be treated
3189 differently. */
3190 instance =
3191 Fgethash (pointerp ? ls3 : glyph,
3192 XWINDOW (governing_domain)->subwindow_instance_cache,
3193 Qunbound);
2738 } 3194 }
2739 else 3195 else
2740 { 3196 abort (); /* We're not allowed anything else currently. */
2741 instance = Fgethash (pointerp ? ls3 : instantiator, 3197
2742 subtable, Qunbound); 3198 /* If we don't have an instance at this point then create
2743 /* subwindows have a per-window cache and have to be treated 3199 one. */
2744 differently. dest_mask can be a bitwise OR of all image
2745 types so we will only catch someone possibly trying to
2746 instantiate a subwindow type thing. Unfortunately, this
2747 will occur most of the time so this probably slows things
2748 down. But with the current design I don't see anyway
2749 round it. */
2750 if (UNBOUNDP (instance)
2751 &&
2752 dest_mask & (IMAGE_SUBWINDOW_MASK
2753 | IMAGE_WIDGET_MASK
2754 | IMAGE_TEXT_MASK))
2755 {
2756 if (!WINDOWP (domain))
2757 signal_simple_error ("Can't instantiate text or subwindow outside a window",
2758 instantiator);
2759 instance = Fgethash (instantiator,
2760 XWINDOW (domain)->subwindow_instance_cache,
2761 Qunbound);
2762 }
2763 }
2764
2765 if (UNBOUNDP (instance)) 3200 if (UNBOUNDP (instance))
2766 { 3201 {
2767 Lisp_Object locative = 3202 Lisp_Object locative =
2768 noseeum_cons (Qnil, 3203 noseeum_cons (Qnil,
2769 noseeum_cons (pointerp ? ls3 : instantiator, 3204 noseeum_cons (pointerp ? ls3 : glyph,
2770 subtable)); 3205 DEVICEP (governing_domain) ? subtable
3206 : XWINDOW (governing_domain)
3207 ->subwindow_instance_cache));
2771 int speccount = specpdl_depth (); 3208 int speccount = specpdl_depth ();
2772 3209
2773 /* make sure we cache the failures, too. 3210 /* Make sure we cache the failures, too. Use an
2774 Use an unwind-protect to catch such errors. 3211 unwind-protect to catch such errors. If we fail, the
2775 If we fail, the unwind-protect records nil in 3212 unwind-protect records nil in the hash table. If we
2776 the hash table. If we succeed, we change the 3213 succeed, we change the car of the locative to the
2777 car of the locative to the resulting instance, 3214 resulting instance, which gets recorded instead. */
2778 which gets recorded instead. */
2779 record_unwind_protect (image_instantiate_cache_result, 3215 record_unwind_protect (image_instantiate_cache_result,
2780 locative); 3216 locative);
2781 instance = instantiate_image_instantiator (device, 3217 instance =
2782 domain, 3218 instantiate_image_instantiator (governing_domain,
2783 instantiator, 3219 domain, instantiator,
2784 pointer_fg, pointer_bg, 3220 pointer_fg, pointer_bg,
2785 dest_mask, 3221 dest_mask, glyph);
2786 glyph); 3222
3223 /* We need a per-frame cache for redisplay. */
3224 cache_subwindow_instance_in_frame_maybe (instance);
2787 3225
2788 Fsetcar (locative, instance); 3226 Fsetcar (locative, instance);
2789 /* only after the image has been instantiated do we know 3227 #ifdef ERROR_CHECK_GLYPHS
2790 whether we need to put it in the per-window image instance
2791 cache. */
2792 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance)) 3228 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
2793 & 3229 & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK))
2794 (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK)) 3230 assert (EQ (XIMAGE_INSTANCE_FRAME (instance),
2795 { 3231 DOMAIN_FRAME (domain)));
2796 if (!WINDOWP (domain)) 3232 #endif
2797 signal_simple_error ("Can't instantiate subwindow outside a window",
2798 instantiator);
2799
2800 Fsetcdr (XCDR (locative), XWINDOW (domain)->subwindow_instance_cache );
2801 }
2802 unbind_to (speccount, Qnil); 3233 unbind_to (speccount, Qnil);
3234 #ifdef ERROR_CHECK_GLYPHS
3235 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
3236 & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK))
3237 assert (EQ (Fgethash ((pointerp ? ls3 : glyph),
3238 XWINDOW (governing_domain)
3239 ->subwindow_instance_cache,
3240 Qunbound), instance));
3241 #endif
2803 } 3242 }
2804 else 3243 else if (NILP (instance))
2805 free_list (ls3);
2806
2807 if (NILP (instance))
2808 signal_simple_error ("Can't instantiate image (probably cached)", 3244 signal_simple_error ("Can't instantiate image (probably cached)",
2809 instantiator); 3245 instantiator);
2810 return instance; 3246 /* We found an instance. However, because we are using the glyph
3247 as the hash key instead of the instantiator, the current
3248 instantiator may not be the same as the original. Thus we
3249 must update the instance based on the new
3250 instantiator. Preserving instance identity like this is
3251 important to stop excessive window system widget creation and
3252 deletion - and hence flashing. */
3253 else
3254 {
3255 /* #### This function should be able to cope with *all*
3256 changes to the instantiator, but currently only copes
3257 with the most used properties. This means that it is
3258 possible to make changes that don't get reflected in the
3259 display. */
3260 update_image_instance (instance, instantiator);
3261 free_list (ls3);
3262 }
3263
3264 #ifdef ERROR_CHECK_GLYPHS
3265 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
3266 & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK))
3267 assert (EQ (XIMAGE_INSTANCE_FRAME (instance),
3268 DOMAIN_FRAME (domain)));
3269 #endif
3270 ERROR_CHECK_IMAGE_INSTANCE (instance);
3271 RETURN_UNGCPRO (instance);
2811 } 3272 }
2812 3273
2813 abort (); 3274 abort ();
2814 return Qnil; /* not reached */ 3275 return Qnil; /* not reached */
2815 } 3276 }
3019 return arg; 3480 return arg;
3020 } 3481 }
3021 3482
3022 DEFUN ("image-specifier-p", Fimage_specifier_p, 1, 1, 0, /* 3483 DEFUN ("image-specifier-p", Fimage_specifier_p, 1, 1, 0, /*
3023 Return non-nil if OBJECT is an image specifier. 3484 Return non-nil if OBJECT is an image specifier.
3024 3485 See `make-image-specifier' for a description of image instantiators.
3025 An image specifier is used for images (pixmaps and the like). It is used
3026 to describe the actual image in a glyph. It is instanced as an image-
3027 instance.
3028
3029 Image instantiators come in many formats: `xbm', `xpm', `gif', `jpeg',
3030 etc. This describes the format of the data describing the image. The
3031 resulting image instances also come in many types -- `mono-pixmap',
3032 `color-pixmap', `text', `pointer', etc. This refers to the behavior of
3033 the image and the sorts of places it can appear. (For example, a
3034 color-pixmap image has fixed colors specified for it, while a
3035 mono-pixmap image comes in two unspecified shades "foreground" and
3036 "background" that are determined from the face of the glyph or
3037 surrounding text; a text image appears as a string of text and has an
3038 unspecified foreground, background, and font; a pointer image behaves
3039 like a mono-pixmap image but can only be used as a mouse pointer
3040 \[mono-pixmap images cannot be used as mouse pointers]; etc.) It is
3041 important to keep the distinction between image instantiator format and
3042 image instance type in mind. Typically, a given image instantiator
3043 format can result in many different image instance types (for example,
3044 `xpm' can be instanced as `color-pixmap', `mono-pixmap', or `pointer';
3045 whereas `cursor-font' can be instanced only as `pointer'), and a
3046 particular image instance type can be generated by many different
3047 image instantiator formats (e.g. `color-pixmap' can be generated by `xpm',
3048 `gif', `jpeg', etc.).
3049
3050 See `make-image-instance' for a more detailed discussion of image
3051 instance types.
3052
3053 An image instantiator should be a string or a vector of the form
3054
3055 [FORMAT :KEYWORD VALUE ...]
3056
3057 i.e. a format symbol followed by zero or more alternating keyword-value
3058 pairs. FORMAT should be one of
3059
3060 'nothing
3061 (Don't display anything; no keywords are valid for this.
3062 Can only be instanced as `nothing'.)
3063 'string
3064 (Display this image as a text string. Can only be instanced
3065 as `text', although support for instancing as `mono-pixmap'
3066 should be added.)
3067 'formatted-string
3068 (Display this image as a text string, with replaceable fields;
3069 not currently implemented.)
3070 'xbm
3071 (An X bitmap; only if X or Windows support was compiled into this XEmacs.
3072 Can be instanced as `mono-pixmap', `color-pixmap', or `pointer'.)
3073 'xpm
3074 (An XPM pixmap; only if XPM support was compiled into this XEmacs.
3075 Can be instanced as `color-pixmap', `mono-pixmap', or `pointer'.)
3076 'xface
3077 (An X-Face bitmap, used to encode people's faces in e-mail messages;
3078 only if X-Face support was compiled into this XEmacs. Can be
3079 instanced as `mono-pixmap', `color-pixmap', or `pointer'.)
3080 'gif
3081 (A GIF87 or GIF89 image; only if GIF support was compiled into this
3082 XEmacs. NOTE: only the first frame of animated gifs will be displayed.
3083 Can be instanced as `color-pixmap'.)
3084 'jpeg
3085 (A JPEG image; only if JPEG support was compiled into this XEmacs.
3086 Can be instanced as `color-pixmap'.)
3087 'png
3088 (A PNG image; only if PNG support was compiled into this XEmacs.
3089 Can be instanced as `color-pixmap'.)
3090 'tiff
3091 (A TIFF image; only if TIFF support was compiled into this XEmacs.
3092 Can be instanced as `color-pixmap'.)
3093 'cursor-font
3094 (One of the standard cursor-font names, such as "watch" or
3095 "right_ptr" under X. Under X, this is, more specifically, any
3096 of the standard cursor names from appendix B of the Xlib manual
3097 [also known as the file <X11/cursorfont.h>] minus the XC_ prefix.
3098 On other window systems, the valid names will be specific to the
3099 type of window system. Can only be instanced as `pointer'.)
3100 'font
3101 (A glyph from a font; i.e. the name of a font, and glyph index into it
3102 of the form "FONT fontname index [[mask-font] mask-index]".
3103 Currently can only be instanced as `pointer', although this should
3104 probably be fixed.)
3105 'subwindow
3106 (An embedded windowing system window.)
3107 'edit-field
3108 (A text editing widget glyph.)
3109 'button
3110 (A button widget glyph; either a push button, radio button or toggle button.)
3111 'tab-control
3112 (A tab widget glyph; a series of user selectable tabs.)
3113 'progress-gauge
3114 (A sliding widget glyph, for showing progress.)
3115 'combo-box
3116 (A drop list of selectable items in a widget glyph, for editing text.)
3117 'label
3118 (A static, text-only, widget glyph; for displaying text.)
3119 'tree-view
3120 (A folding widget glyph.)
3121 'autodetect
3122 (XEmacs tries to guess what format the data is in. If X support
3123 exists, the data string will be checked to see if it names a filename.
3124 If so, and this filename contains XBM or XPM data, the appropriate
3125 sort of pixmap or pointer will be created. [This includes picking up
3126 any specified hotspot or associated mask file.] Otherwise, if `pointer'
3127 is one of the allowable image-instance types and the string names a
3128 valid cursor-font name, the image will be created as a pointer.
3129 Otherwise, the image will be displayed as text. If no X support
3130 exists, the image will always be displayed as text.)
3131 'inherit
3132 Inherit from the background-pixmap property of a face.
3133
3134 The valid keywords are:
3135
3136 :data
3137 (Inline data. For most formats above, this should be a string. For
3138 XBM images, this should be a list of three elements: width, height, and
3139 a string of bit data. This keyword is not valid for instantiator
3140 formats `nothing' and `inherit'.)
3141 :file
3142 (Data is contained in a file. The value is the name of this file.
3143 If both :data and :file are specified, the image is created from
3144 what is specified in :data and the string in :file becomes the
3145 value of the `image-instance-file-name' function when applied to
3146 the resulting image-instance. This keyword is not valid for
3147 instantiator formats `nothing', `string', `formatted-string',
3148 `cursor-font', `font', `autodetect', and `inherit'.)
3149 :foreground
3150 :background
3151 (For `xbm', `xface', `cursor-font', `widget' and `font'. These keywords
3152 allow you to explicitly specify foreground and background colors.
3153 The argument should be anything acceptable to `make-color-instance'.
3154 This will cause what would be a `mono-pixmap' to instead be colorized
3155 as a two-color color-pixmap, and specifies the foreground and/or
3156 background colors for a pointer instead of black and white.)
3157 :mask-data
3158 (For `xbm' and `xface'. This specifies a mask to be used with the
3159 bitmap. The format is a list of width, height, and bits, like for
3160 :data.)
3161 :mask-file
3162 (For `xbm' and `xface'. This specifies a file containing the mask data.
3163 If neither a mask file nor inline mask data is given for an XBM image,
3164 and the XBM image comes from a file, XEmacs will look for a mask file
3165 with the same name as the image file but with "Mask" or "msk"
3166 appended. For example, if you specify the XBM file "left_ptr"
3167 [usually located in "/usr/include/X11/bitmaps"], the associated
3168 mask file "left_ptrmsk" will automatically be picked up.)
3169 :hotspot-x
3170 :hotspot-y
3171 (For `xbm' and `xface'. These keywords specify a hotspot if the image
3172 is instantiated as a `pointer'. Note that if the XBM image file
3173 specifies a hotspot, it will automatically be picked up if no
3174 explicit hotspot is given.)
3175 :color-symbols
3176 (Only for `xpm'. This specifies an alist that maps strings
3177 that specify symbolic color names to the actual color to be used
3178 for that symbolic color (in the form of a string or a color-specifier
3179 object). If this is not specified, the contents of `xpm-color-symbols'
3180 are used to generate the alist.)
3181 :face
3182 (Only for `inherit'. This specifies the face to inherit from.
3183 For widget glyphs this also specifies the face to use for
3184 display. It defaults to gui-element-face.)
3185
3186 Keywords accepted as menu item specs are also accepted by widget
3187 glyphs. These are `:selected', `:active', `:suffix', `:keys',
3188 `:style', `:filter', `:config', `:included', `:key-sequence',
3189 `:accelerator', `:label' and `:callback'.
3190
3191 If instead of a vector, the instantiator is a string, it will be
3192 converted into a vector by looking it up according to the specs in the
3193 `console-type-image-conversion-list' (q.v.) for the console type of
3194 the domain (usually a window; sometimes a frame or device) over which
3195 the image is being instantiated.
3196
3197 If the instantiator specifies data from a file, the data will be read
3198 in at the time that the instantiator is added to the image (which may
3199 be well before when the image is actually displayed), and the
3200 instantiator will be converted into one of the inline-data forms, with
3201 the filename retained using a :file keyword. This implies that the
3202 file must exist when the instantiator is added to the image, but does
3203 not need to exist at any other time (e.g. it may safely be a temporary
3204 file).
3205 */ 3486 */
3206 (object)) 3487 (object))
3207 { 3488 {
3208 return IMAGE_SPECIFIERP (object) ? Qt : Qnil; 3489 return IMAGE_SPECIFIERP (object) ? Qt : Qnil;
3209 } 3490 }
3369 { 3650 {
3370 case GLYPH_BUFFER: 3651 case GLYPH_BUFFER:
3371 XIMAGE_SPECIFIER_ALLOWED (g->image) = 3652 XIMAGE_SPECIFIER_ALLOWED (g->image) =
3372 IMAGE_NOTHING_MASK | IMAGE_TEXT_MASK 3653 IMAGE_NOTHING_MASK | IMAGE_TEXT_MASK
3373 | IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK 3654 | IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
3374 | IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK 3655 | IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK;
3375 | IMAGE_LAYOUT_MASK;
3376 break; 3656 break;
3377 case GLYPH_POINTER: 3657 case GLYPH_POINTER:
3378 XIMAGE_SPECIFIER_ALLOWED (g->image) = 3658 XIMAGE_SPECIFIER_ALLOWED (g->image) =
3379 IMAGE_NOTHING_MASK | IMAGE_POINTER_MASK; 3659 IMAGE_NOTHING_MASK | IMAGE_POINTER_MASK;
3380 break; 3660 break;
3456 { 3736 {
3457 return Fcopy_sequence (Vglyph_type_list); 3737 return Fcopy_sequence (Vglyph_type_list);
3458 } 3738 }
3459 3739
3460 DEFUN ("make-glyph-internal", Fmake_glyph_internal, 0, 1, 0, /* 3740 DEFUN ("make-glyph-internal", Fmake_glyph_internal, 0, 1, 0, /*
3461 Create and return a new uninitialized glyph or type TYPE. 3741 Create and return a new uninitialized glyph of type TYPE.
3462 3742
3463 TYPE specifies the type of the glyph; this should be one of `buffer', 3743 TYPE specifies the type of the glyph; this should be one of `buffer',
3464 `pointer', or `icon', and defaults to `buffer'. The type of the glyph 3744 `pointer', or `icon', and defaults to `buffer'. The type of the glyph
3465 specifies in which contexts the glyph can be used, and controls the 3745 specifies in which contexts the glyph can be used, and controls the
3466 allowable image types into which the glyph's image can be 3746 allowable image types into which the glyph's image can be
3485 } 3765 }
3486 3766
3487 DEFUN ("glyphp", Fglyphp, 1, 1, 0, /* 3767 DEFUN ("glyphp", Fglyphp, 1, 1, 0, /*
3488 Return non-nil if OBJECT is a glyph. 3768 Return non-nil if OBJECT is a glyph.
3489 3769
3490 A glyph is an object used for pixmaps and the like. It is used 3770 A glyph is an object used for pixmaps, widgets and the like. It is used
3491 in begin-glyphs and end-glyphs attached to extents, in marginal and textual 3771 in begin-glyphs and end-glyphs attached to extents, in marginal and textual
3492 annotations, in overlay arrows (overlay-arrow-* variables), in toolbar 3772 annotations, in overlay arrows (overlay-arrow-* variables), in toolbar
3493 buttons, and the like. Its image is described using an image specifier -- 3773 buttons, and the like. Much more detailed information can be found at
3494 see `image-specifier-p'. 3774 `make-glyph'. Its image is described using an image specifier --
3775 see `make-image-specifier'. See also `make-image-instance' for further
3776 information.
3495 */ 3777 */
3496 (object)) 3778 (object))
3497 { 3779 {
3498 return GLYPHP (object) ? Qt : Qnil; 3780 return GLYPHP (object) ? Qt : Qnil;
3499 } 3781 }
3524 a fallback. */ 3806 a fallback. */
3525 Lisp_Object image_instance = specifier_instance (specifier, Qunbound, 3807 Lisp_Object image_instance = specifier_instance (specifier, Qunbound,
3526 domain, errb, no_quit, 0, 3808 domain, errb, no_quit, 0,
3527 Qzero); 3809 Qzero);
3528 assert (!UNBOUNDP (image_instance)); 3810 assert (!UNBOUNDP (image_instance));
3811 ERROR_CHECK_IMAGE_INSTANCE (image_instance);
3529 3812
3530 return image_instance; 3813 return image_instance;
3531 } 3814 }
3532 3815
3533 static Lisp_Object 3816 static Lisp_Object
3554 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image, 3837 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image,
3555 domain); 3838 domain);
3556 if (!IMAGE_INSTANCEP (instance)) 3839 if (!IMAGE_INSTANCEP (instance))
3557 return 0; 3840 return 0;
3558 3841
3559 if (XIMAGE_INSTANCE_DIRTYP (instance)) 3842 if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance))
3560 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY, 3843 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY,
3561 IMAGE_UNSPECIFIED_GEOMETRY, domain); 3844 IMAGE_UNSPECIFIED_GEOMETRY,
3845 IMAGE_UNCHANGED_GEOMETRY,
3846 IMAGE_UNCHANGED_GEOMETRY, domain);
3562 3847
3563 return XIMAGE_INSTANCE_WIDTH (instance); 3848 return XIMAGE_INSTANCE_WIDTH (instance);
3564 } 3849 }
3565 3850
3566 DEFUN ("glyph-width", Fglyph_width, 1, 2, 0, /* 3851 DEFUN ("glyph-width", Fglyph_width, 1, 2, 0, /*
3582 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image, 3867 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image,
3583 domain); 3868 domain);
3584 if (!IMAGE_INSTANCEP (instance)) 3869 if (!IMAGE_INSTANCEP (instance))
3585 return 0; 3870 return 0;
3586 3871
3587 if (XIMAGE_INSTANCE_DIRTYP (instance)) 3872 if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance))
3588 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY, 3873 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY,
3589 IMAGE_UNSPECIFIED_GEOMETRY, domain); 3874 IMAGE_UNSPECIFIED_GEOMETRY,
3875 IMAGE_UNCHANGED_GEOMETRY,
3876 IMAGE_UNCHANGED_GEOMETRY, domain);
3590 3877
3591 if (XIMAGE_INSTANCE_TYPE (instance) == IMAGE_TEXT) 3878 if (XIMAGE_INSTANCE_TYPE (instance) == IMAGE_TEXT)
3592 return XIMAGE_INSTANCE_TEXT_ASCENT (instance); 3879 return XIMAGE_INSTANCE_TEXT_ASCENT (instance);
3593 else 3880 else
3594 return XIMAGE_INSTANCE_HEIGHT (instance); 3881 return XIMAGE_INSTANCE_HEIGHT (instance);
3600 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image, 3887 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image,
3601 domain); 3888 domain);
3602 if (!IMAGE_INSTANCEP (instance)) 3889 if (!IMAGE_INSTANCEP (instance))
3603 return 0; 3890 return 0;
3604 3891
3605 if (XIMAGE_INSTANCE_DIRTYP (instance)) 3892 if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance))
3606 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY, 3893 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY,
3607 IMAGE_UNSPECIFIED_GEOMETRY, domain); 3894 IMAGE_UNSPECIFIED_GEOMETRY,
3895 IMAGE_UNCHANGED_GEOMETRY,
3896 IMAGE_UNCHANGED_GEOMETRY, domain);
3608 3897
3609 if (XIMAGE_INSTANCE_TYPE (instance) == IMAGE_TEXT) 3898 if (XIMAGE_INSTANCE_TYPE (instance) == IMAGE_TEXT)
3610 return XIMAGE_INSTANCE_TEXT_DESCENT (instance); 3899 return XIMAGE_INSTANCE_TEXT_DESCENT (instance);
3611 else 3900 else
3612 return 0; 3901 return 0;
3620 domain); 3909 domain);
3621 3910
3622 if (!IMAGE_INSTANCEP (instance)) 3911 if (!IMAGE_INSTANCEP (instance))
3623 return 0; 3912 return 0;
3624 3913
3625 if (XIMAGE_INSTANCE_DIRTYP (instance)) 3914 if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance))
3626 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY, 3915 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY,
3627 IMAGE_UNSPECIFIED_GEOMETRY, domain); 3916 IMAGE_UNSPECIFIED_GEOMETRY,
3917 IMAGE_UNCHANGED_GEOMETRY,
3918 IMAGE_UNCHANGED_GEOMETRY, domain);
3628 3919
3629 return XIMAGE_INSTANCE_HEIGHT (instance); 3920 return XIMAGE_INSTANCE_HEIGHT (instance);
3630 } 3921 }
3631 3922
3632 DEFUN ("glyph-ascent", Fglyph_ascent, 1, 2, 0, /* 3923 DEFUN ("glyph-ascent", Fglyph_ascent, 1, 2, 0, /*
3681 instance = glyph_image_instance (glyph_or_image, window, 3972 instance = glyph_image_instance (glyph_or_image, window,
3682 ERROR_ME_NOT, 1); 3973 ERROR_ME_NOT, 1);
3683 XGLYPH_DIRTYP (glyph_or_image) = dirty; 3974 XGLYPH_DIRTYP (glyph_or_image) = dirty;
3684 } 3975 }
3685 3976
3977 if (!IMAGE_INSTANCEP (instance))
3978 return;
3979
3686 XIMAGE_INSTANCE_DIRTYP (instance) = dirty; 3980 XIMAGE_INSTANCE_DIRTYP (instance) = dirty;
3981 }
3982 }
3983
3984 static void
3985 set_image_instance_dirty_p (Lisp_Object instance, int dirty)
3986 {
3987 if (IMAGE_INSTANCEP (instance))
3988 {
3989 XIMAGE_INSTANCE_DIRTYP (instance) = dirty;
3990 /* Now cascade up the hierarchy. */
3991 set_image_instance_dirty_p (XIMAGE_INSTANCE_PARENT (instance),
3992 dirty);
3993 }
3994 else if (GLYPHP (instance))
3995 {
3996 XGLYPH_DIRTYP (instance) = dirty;
3687 } 3997 }
3688 } 3998 }
3689 3999
3690 /* #### do we need to cache this info to speed things up? */ 4000 /* #### do we need to cache this info to speed things up? */
3691 4001
3739 { 4049 {
3740 if (XGLYPH (glyph)->after_change) 4050 if (XGLYPH (glyph)->after_change)
3741 (XGLYPH (glyph)->after_change) (glyph, property, locale); 4051 (XGLYPH (glyph)->after_change) (glyph, property, locale);
3742 } 4052 }
3743 4053
3744 #if 0 /* Not used for now */ 4054 void
3745 static void 4055 glyph_query_geometry (Lisp_Object glyph_or_image, int* width, int* height,
3746 glyph_query_geometry (Lisp_Object glyph_or_image, Lisp_Object window,
3747 unsigned int* width, unsigned int* height,
3748 enum image_instance_geometry disp, Lisp_Object domain) 4056 enum image_instance_geometry disp, Lisp_Object domain)
3749 { 4057 {
3750 Lisp_Object instance = glyph_or_image; 4058 Lisp_Object instance = glyph_or_image;
3751 4059
3752 if (GLYPHP (glyph_or_image)) 4060 if (GLYPHP (glyph_or_image))
3753 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1); 4061 instance = glyph_image_instance (glyph_or_image, domain, ERROR_ME_NOT, 1);
3754 4062
3755 image_instance_query_geometry (instance, width, height, disp, domain); 4063 image_instance_query_geometry (instance, width, height, disp, domain);
3756 } 4064 }
3757 4065
3758 static void 4066 void
3759 glyph_layout (Lisp_Object glyph_or_image, Lisp_Object window, 4067 glyph_do_layout (Lisp_Object glyph_or_image, int width, int height,
3760 unsigned int width, unsigned int height, Lisp_Object domain) 4068 int xoffset, int yoffset, Lisp_Object domain)
3761 { 4069 {
3762 Lisp_Object instance = glyph_or_image; 4070 Lisp_Object instance = glyph_or_image;
3763 4071
3764 if (GLYPHP (glyph_or_image)) 4072 if (GLYPHP (glyph_or_image))
3765 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1); 4073 instance = glyph_image_instance (glyph_or_image, domain, ERROR_ME_NOT, 1);
3766 4074
3767 image_instance_layout (instance, width, height, domain); 4075 image_instance_layout (instance, width, height, xoffset, yoffset, domain);
3768 } 4076 }
3769 #endif
3770 4077
3771 4078
3772 /***************************************************************************** 4079 /*****************************************************************************
3773 * glyph cachel functions * 4080 * glyph cachel functions *
3774 *****************************************************************************/ 4081 *****************************************************************************/
3775 4082
3776 /* 4083 /* #### All of this is 95% copied from face cachels. Consider
3777 #### All of this is 95% copied from face cachels. 4084 consolidating.
3778 Consider consolidating. 4085
3779 */ 4086 Why do we need glyph_cachels? Simply because a glyph_cachel captures
3780 4087 per-window information about a particular glyph. A glyph itself is
4088 not created in any particular context, so if we were to rely on a
4089 glyph to tell us about its dirtiness we would not be able to reset
4090 the dirty flag after redisplaying it as it may exist in other
4091 contexts. When we have redisplayed we need to know which glyphs to
4092 reset the dirty flags on - the glyph_cachels give us a nice list we
4093 can iterate through doing this. */
3781 void 4094 void
3782 mark_glyph_cachels (glyph_cachel_dynarr *elements) 4095 mark_glyph_cachels (glyph_cachel_dynarr *elements)
3783 { 4096 {
3784 int elt; 4097 int elt;
3785 4098
3807 4120
3808 cachel->glyph = glyph; 4121 cachel->glyph = glyph;
3809 /* Speed things up slightly by grabbing the glyph instantiation 4122 /* Speed things up slightly by grabbing the glyph instantiation
3810 and passing it to the size functions. */ 4123 and passing it to the size functions. */
3811 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); 4124 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1);
4125
4126 if (!IMAGE_INSTANCEP (instance))
4127 return;
3812 4128
3813 /* Mark text instance of the glyph dirty if faces have changed, 4129 /* Mark text instance of the glyph dirty if faces have changed,
3814 because its geometry might have changed. */ 4130 because its geometry might have changed. */
3815 invalidate_glyph_geometry_maybe (instance, w); 4131 invalidate_glyph_geometry_maybe (instance, w);
3816 4132
3943 instantiator in the hashtable and when the instantiator goes away 4259 instantiator in the hashtable and when the instantiator goes away
3944 we want the instance to go away also. However we also have a 4260 we want the instance to go away also. However we also have a
3945 per-frame instance cache that we use to determine if a subwindow is 4261 per-frame instance cache that we use to determine if a subwindow is
3946 obscuring an area that we want to clear. We need to be able to flip 4262 obscuring an area that we want to clear. We need to be able to flip
3947 through this quickly so a hashtable is not suitable hence the 4263 through this quickly so a hashtable is not suitable hence the
3948 subwindow_cachels. The question is should we just not mark 4264 subwindow_cachels. This is a weak list so unreference instances
3949 instances in the subwindow_cachels or should we try and invalidate 4265 will get deleted properly. */
3950 the cache at suitable points in redisplay? If we don't invalidate
3951 the cache it will fill up with crud that will only get removed when
3952 the frame is deleted. So invalidation is good, the question is when
3953 and whether we mark as well. Go for the simple option - don't mark,
3954 MARK_SUBWINDOWS_CHANGED when a subwindow gets deleted. */
3955
3956 void
3957 mark_subwindow_cachels (subwindow_cachel_dynarr *elements)
3958 {
3959 int elt;
3960
3961 if (!elements)
3962 return;
3963
3964 for (elt = 0; elt < Dynarr_length (elements); elt++)
3965 {
3966 struct subwindow_cachel *cachel = Dynarr_atp (elements, elt);
3967 mark_object (cachel->subwindow);
3968 }
3969 }
3970
3971 static void
3972 update_subwindow_cachel_data (struct frame *f, Lisp_Object subwindow,
3973 struct subwindow_cachel *cachel)
3974 {
3975 cachel->subwindow = subwindow;
3976 cachel->width = XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow);
3977 cachel->height = XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow);
3978 cachel->updated = 1;
3979 }
3980
3981 static void
3982 add_subwindow_cachel (struct frame *f, Lisp_Object subwindow)
3983 {
3984 struct subwindow_cachel new_cachel;
3985
3986 xzero (new_cachel);
3987 new_cachel.subwindow = Qnil;
3988 new_cachel.x=0;
3989 new_cachel.y=0;
3990 new_cachel.being_displayed=0;
3991
3992 update_subwindow_cachel_data (f, subwindow, &new_cachel);
3993 Dynarr_add (f->subwindow_cachels, new_cachel);
3994 }
3995
3996 static int
3997 get_subwindow_cachel_index (struct frame *f, Lisp_Object subwindow)
3998 {
3999 int elt;
4000
4001 if (noninteractive)
4002 return 0;
4003
4004 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
4005 {
4006 struct subwindow_cachel *cachel =
4007 Dynarr_atp (f->subwindow_cachels, elt);
4008
4009 if (EQ (cachel->subwindow, subwindow) && !NILP (subwindow))
4010 {
4011 if (!cachel->updated)
4012 update_subwindow_cachel_data (f, subwindow, cachel);
4013 return elt;
4014 }
4015 }
4016
4017 /* If we didn't find the glyph, add it and then return its index. */
4018 add_subwindow_cachel (f, subwindow);
4019 return elt;
4020 }
4021
4022 static void
4023 update_subwindow_cachel (Lisp_Object subwindow)
4024 {
4025 struct frame* f;
4026 int elt;
4027
4028 if (NILP (subwindow))
4029 return;
4030
4031 f = XFRAME ( XIMAGE_INSTANCE_SUBWINDOW_FRAME (subwindow));
4032
4033 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
4034 {
4035 struct subwindow_cachel *cachel =
4036 Dynarr_atp (f->subwindow_cachels, elt);
4037
4038 if (EQ (cachel->subwindow, subwindow) && !NILP (subwindow))
4039 {
4040 update_subwindow_cachel_data (f, subwindow, cachel);
4041 }
4042 }
4043 }
4044 4266
4045 /* redisplay in general assumes that drawing something will erase 4267 /* redisplay in general assumes that drawing something will erase
4046 what was there before. unfortunately this does not apply to 4268 what was there before. unfortunately this does not apply to
4047 subwindows that need to be specifically unmapped in order to 4269 subwindows that need to be specifically unmapped in order to
4048 disappear. we take a brute force approach - on the basis that its 4270 disappear. we take a brute force approach - on the basis that its
4049 cheap - and unmap all subwindows in a display line */ 4271 cheap - and unmap all subwindows in a display line */
4272
4273 /* Put new instances in the frame subwindow cache. This is less costly than
4274 doing it every time something gets mapped, and deleted instances will be
4275 removed automatically. */
4276 static void
4277 cache_subwindow_instance_in_frame_maybe (Lisp_Object instance)
4278 {
4279 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (instance);
4280 if (!NILP (DOMAIN_FRAME (IMAGE_INSTANCE_DOMAIN (ii))))
4281 {
4282 struct frame* f = DOMAIN_XFRAME (IMAGE_INSTANCE_DOMAIN (ii));
4283 XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))
4284 = Fcons (instance, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)));
4285 }
4286 }
4287
4288 /* Unmap and finalize all subwindow instances in the frame cache. This
4289 is necessary because GC will not guarantee the order things get
4290 deleted in and moreover, frame finalization deletes the window
4291 system windows before deleting XEmacs windows, and hence
4292 subwindows. */
4293 int
4294 unmap_subwindow_instance_cache_mapper (Lisp_Object key, Lisp_Object value,
4295 void* finalize)
4296 {
4297 /* value can be nil; we cache failures as well as successes */
4298 if (!NILP (value))
4299 {
4300 struct frame* f = XFRAME (XIMAGE_INSTANCE_FRAME (value));
4301 unmap_subwindow (value);
4302 if (finalize)
4303 {
4304 /* In case GC doesn't catch up fast enough, remove from the frame
4305 cache also. Otherwise code that checks the sanity of the instance
4306 will fail. */
4307 XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))
4308 = delq_no_quit (value,
4309 XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)));
4310 finalize_image_instance (XIMAGE_INSTANCE (value), 0);
4311 }
4312 }
4313 return 0;
4314 }
4315
4316 static void
4317 finalize_all_subwindow_instances (struct window *w)
4318 {
4319 if (!NILP (w->next)) finalize_all_subwindow_instances (XWINDOW (w->next));
4320 if (!NILP (w->vchild)) finalize_all_subwindow_instances (XWINDOW (w->vchild));
4321 if (!NILP (w->hchild)) finalize_all_subwindow_instances (XWINDOW (w->hchild));
4322
4323 elisp_maphash (unmap_subwindow_instance_cache_mapper,
4324 w->subwindow_instance_cache, (void*)1);
4325 }
4326
4050 void 4327 void
4051 reset_subwindow_cachels (struct frame *f) 4328 free_frame_subwindow_instances (struct frame* f)
4052 { 4329 {
4053 int elt; 4330 /* Make sure all instances are finalized. We have to do this via the
4054 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) 4331 instance cache since some instances may be extant but not
4055 { 4332 displayed (and hence not in the frame cache). */
4056 struct subwindow_cachel *cachel = 4333 finalize_all_subwindow_instances (XWINDOW (f->root_window));
4057 Dynarr_atp (f->subwindow_cachels, elt); 4334 }
4058 4335
4059 if (!NILP (cachel->subwindow) && cachel->being_displayed) 4336 /* Unmap all instances in the frame cache. */
4060 {
4061 cachel->updated = 1;
4062 /* #### This is not optimal as update_subwindow will search
4063 the cachels for ourselves as well. We could easily optimize. */
4064 unmap_subwindow (cachel->subwindow);
4065 }
4066 }
4067 Dynarr_reset (f->subwindow_cachels);
4068 }
4069
4070 void 4337 void
4071 mark_subwindow_cachels_as_not_updated (struct frame *f) 4338 reset_frame_subwindow_instance_cache (struct frame* f)
4072 { 4339 {
4073 int elt; 4340 Lisp_Object rest;
4074 4341
4075 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) 4342 LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))
4076 Dynarr_atp (f->subwindow_cachels, elt)->updated = 0; 4343 {
4077 } 4344 Lisp_Object value = XCAR (rest);
4078 4345 unmap_subwindow (value);
4079 4346 }
4347 }
4080 4348
4081 /***************************************************************************** 4349 /*****************************************************************************
4082 * subwindow exposure ignorance * 4350 * subwindow exposure ignorance *
4083 *****************************************************************************/ 4351 *****************************************************************************/
4084 /* when we unmap subwindows the associated window system will generate 4352 /* when we unmap subwindows the associated window system will generate
4100 /* the ignore list is FIFO so we should generally get a match with 4368 /* the ignore list is FIFO so we should generally get a match with
4101 the first element in the list */ 4369 the first element in the list */
4102 for (ei = f->subwindow_exposures, prev = 0; ei; ei = ei->next) 4370 for (ei = f->subwindow_exposures, prev = 0; ei; ei = ei->next)
4103 { 4371 {
4104 /* Checking for exact matches just isn't good enough as we 4372 /* Checking for exact matches just isn't good enough as we
4105 mighte get exposures for partially obscure subwindows, thus 4373 might get exposures for partially obscured subwindows, thus
4106 we have to check for overlaps. Being conservative we will 4374 we have to check for overlaps. Being conservative, we will
4107 check for exposures wholly contained by the subwindow, this 4375 check for exposures wholly contained by the subwindow - this
4108 might give us what we want.*/ 4376 might give us what we want.*/
4109 if (ei->x <= x && ei->y <= y 4377 if (ei->x <= x && ei->y <= y
4110 && ei->x + ei->width >= x + width 4378 && ei->x + ei->width >= x + width
4111 && ei->y + ei->height >= y + height) 4379 && ei->y + ei->height >= y + height)
4112 { 4380 {
4166 See if there is a subwindow that completely encloses the requested 4434 See if there is a subwindow that completely encloses the requested
4167 area. 4435 area.
4168 ****************************************************************************/ 4436 ****************************************************************************/
4169 int find_matching_subwindow (struct frame* f, int x, int y, int width, int height) 4437 int find_matching_subwindow (struct frame* f, int x, int y, int width, int height)
4170 { 4438 {
4171 int elt; 4439 Lisp_Object rest;
4172 4440
4173 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) 4441 LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))
4174 { 4442 {
4175 struct subwindow_cachel *cachel = 4443 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (XCAR (rest));
4176 Dynarr_atp (f->subwindow_cachels, elt); 4444
4177 4445 if (IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii)
4178 if (cachel->being_displayed
4179 && 4446 &&
4180 cachel->x <= x && cachel->y <= y 4447 IMAGE_INSTANCE_DISPLAY_X (ii) <= x
4181 && 4448 &&
4182 cachel->x + cachel->width >= x + width 4449 IMAGE_INSTANCE_DISPLAY_Y (ii) <= y
4183 && 4450 &&
4184 cachel->y + cachel->height >= y + height) 4451 IMAGE_INSTANCE_DISPLAY_X (ii)
4452 + IMAGE_INSTANCE_DISPLAY_WIDTH (ii) >= x + width
4453 &&
4454 IMAGE_INSTANCE_DISPLAY_Y (ii)
4455 + IMAGE_INSTANCE_DISPLAY_HEIGHT (ii) >= y + height)
4185 { 4456 {
4186 return 1; 4457 return 1;
4187 } 4458 }
4188 } 4459 }
4189 return 0; 4460 return 0;
4192 4463
4193 /***************************************************************************** 4464 /*****************************************************************************
4194 * subwindow functions * 4465 * subwindow functions *
4195 *****************************************************************************/ 4466 *****************************************************************************/
4196 4467
4197 /* update the displayed characteristics of a subwindow */ 4468 /* Update the displayed characteristics of a subwindow. This function
4198 static void 4469 should generally only get called if the subwindow is actually
4199 update_subwindow (Lisp_Object subwindow) 4470 dirty. */
4471 void
4472 redisplay_subwindow (Lisp_Object subwindow)
4200 { 4473 {
4201 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); 4474 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
4202 4475 int count = specpdl_depth ();
4203 if (!IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET 4476
4204 || 4477 /* The update method is allowed to call eval. Since it is quite
4205 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) 4478 common for this function to get called from somewhere in
4206 return; 4479 redisplay we need to make sure that quits are ignored. Otherwise
4207 4480 Fsignal will abort. */
4208 MAYBE_DEVMETH (XDEVICE (ii->device), update_subwindow, (ii)); 4481 specbind (Qinhibit_quit, Qt);
4209 /* We must update the window's size as it may have been changed by 4482
4210 the the layout routines. We also do this here so that explicit resizing 4483 ERROR_CHECK_IMAGE_INSTANCE (subwindow);
4211 from lisp does not result in synchronous updates. */ 4484
4212 MAYBE_DEVMETH (XDEVICE (ii->device), resize_subwindow, (ii, 4485 if (WIDGET_IMAGE_INSTANCEP (subwindow))
4213 IMAGE_INSTANCE_WIDTH (ii), 4486 {
4214 IMAGE_INSTANCE_HEIGHT (ii))); 4487 if (image_instance_changed (subwindow))
4488 redisplay_widget (subwindow);
4489 /* Reset the changed flags. */
4490 IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) = 0;
4491 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
4492 IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii) = 0;
4493 IMAGE_INSTANCE_TEXT_CHANGED (ii) = 0;
4494 }
4495 else if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW
4496 &&
4497 !NILP (IMAGE_INSTANCE_FRAME (ii)))
4498 {
4499 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
4500 redisplay_subwindow, (ii));
4501 }
4502
4503 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 0;
4504 /* This function is typically called by redisplay just before
4505 outputting the information to the screen. Thus we record a hash
4506 of the output to determine whether on-screen is the same as
4507 recorded structure. This approach has limitations in there is a
4508 good chance that hash values will be different for the same
4509 visual appearance. However, we would rather that then the other
4510 way round - it simply means that we will get more displays than
4511 we might need. We can get better hashing by making the depth
4512 negative - currently it will recurse down 7 levels.*/
4513 IMAGE_INSTANCE_DISPLAY_HASH (ii) = internal_hash (subwindow,
4514 IMAGE_INSTANCE_HASH_DEPTH);
4515
4516 unbind_to (count, Qnil);
4517 }
4518
4519 /* Determine whether an image_instance has changed structurally and
4520 hence needs redisplaying in some way.
4521
4522 #### This should just look at the instantiator differences when we
4523 get rid of the stored items altogether. In fact we should probably
4524 store the new instantiator as well as the old - as we do with
4525 gui_items currently - and then pick-up the new on the next
4526 redisplay. This would obviate the need for any of this trickery
4527 with hashcodes. */
4528 int
4529 image_instance_changed (Lisp_Object subwindow)
4530 {
4531 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
4532
4533 if (internal_hash (subwindow, IMAGE_INSTANCE_HASH_DEPTH) !=
4534 IMAGE_INSTANCE_DISPLAY_HASH (ii))
4535 return 1;
4536 /* #### I think there is probably a bug here. This gets called for
4537 layouts - and yet the pending items are always nil for
4538 layouts. We are saved by layout optimization, but I'm undecided
4539 as to what the correct fix is. */
4540 else if (WIDGET_IMAGE_INSTANCEP (subwindow)
4541 && (!internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (ii),
4542 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii), 0)
4543 || !NILP (IMAGE_INSTANCE_LAYOUT_CHILDREN (ii))
4544 || IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii)))
4545 return 1;
4546 else
4547 return 0;
4215 } 4548 }
4216 4549
4217 /* Update all the subwindows on a frame. */ 4550 /* Update all the subwindows on a frame. */
4218 void 4551 void
4219 update_frame_subwindows (struct frame *f) 4552 update_widget_instances (Lisp_Object frame)
4220 { 4553 {
4221 int elt; 4554 struct frame* f;
4222 4555 Lisp_Object rest;
4223 if (f->subwindows_changed || f->subwindows_state_changed || f->faces_changed) 4556
4224 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) 4557 /* Its possible for the preceding callback to have deleted the
4225 { 4558 frame, so cope with this. */
4226 struct subwindow_cachel *cachel = 4559 if (!FRAMEP (frame) || !FRAME_LIVE_P (XFRAME (frame)))
4227 Dynarr_atp (f->subwindow_cachels, elt); 4560 return;
4228 4561
4229 if (cachel->being_displayed) 4562 CHECK_FRAME (frame);
4230 { 4563 f = XFRAME (frame);
4231 update_subwindow (cachel->subwindow); 4564
4232 } 4565 /* If we get called we know something has changed. */
4233 } 4566 LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))
4567 {
4568 Lisp_Object widget = XCAR (rest);
4569
4570 if (XIMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (widget)
4571 &&
4572 image_instance_changed (widget))
4573 {
4574 set_image_instance_dirty_p (widget, 1);
4575 MARK_FRAME_GLYPHS_CHANGED (f);
4576 }
4577 }
4234 } 4578 }
4235 4579
4236 /* remove a subwindow from its frame */ 4580 /* remove a subwindow from its frame */
4237 void unmap_subwindow (Lisp_Object subwindow) 4581 void unmap_subwindow (Lisp_Object subwindow)
4238 { 4582 {
4239 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); 4583 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
4240 int elt;
4241 struct subwindow_cachel* cachel;
4242 struct frame* f; 4584 struct frame* f;
4243 4585
4244 if (!(IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET 4586 ERROR_CHECK_IMAGE_INSTANCE (subwindow);
4245 || 4587
4246 IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW) 4588 if (!image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (ii))
4589 & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK)
4247 || 4590 ||
4248 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) 4591 !IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii))
4249 return; 4592 return;
4593
4250 #ifdef DEBUG_WIDGETS 4594 #ifdef DEBUG_WIDGETS
4251 stderr_out ("unmapping subwindow %d\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii)); 4595 stderr_out ("unmapping subwindow %p\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
4252 #endif 4596 #endif
4253 f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); 4597 f = XFRAME (IMAGE_INSTANCE_FRAME (ii));
4254 elt = get_subwindow_cachel_index (f, subwindow);
4255 cachel = Dynarr_atp (f->subwindow_cachels, elt);
4256 4598
4257 /* make sure we don't get expose events */ 4599 /* make sure we don't get expose events */
4258 register_ignored_expose (f, cachel->x, cachel->y, cachel->width, cachel->height); 4600 register_ignored_expose (f, IMAGE_INSTANCE_DISPLAY_X (ii),
4259 cachel->x = ~0; 4601 IMAGE_INSTANCE_DISPLAY_Y (ii),
4260 cachel->y = ~0; 4602 IMAGE_INSTANCE_DISPLAY_WIDTH (ii),
4261 cachel->being_displayed = 0; 4603 IMAGE_INSTANCE_DISPLAY_HEIGHT (ii));
4262 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; 4604 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0;
4263 4605
4264 MAYBE_DEVMETH (XDEVICE (ii->device), unmap_subwindow, (ii)); 4606 MAYBE_DEVMETH (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)),
4607 unmap_subwindow, (ii));
4265 } 4608 }
4266 4609
4267 /* show a subwindow in its frame */ 4610 /* show a subwindow in its frame */
4268 void map_subwindow (Lisp_Object subwindow, int x, int y, 4611 void map_subwindow (Lisp_Object subwindow, int x, int y,
4269 struct display_glyph_area *dga) 4612 struct display_glyph_area *dga)
4270 { 4613 {
4271 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); 4614 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
4272 int elt;
4273 struct subwindow_cachel* cachel;
4274 struct frame* f; 4615 struct frame* f;
4275 4616
4276 if (!(IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET 4617 ERROR_CHECK_IMAGE_INSTANCE (subwindow);
4277 || 4618
4278 IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW) 4619 if (!image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (ii))
4279 || 4620 & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK))
4280 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))
4281 return; 4621 return;
4282 4622
4283 #ifdef DEBUG_WIDGETS 4623 #ifdef DEBUG_WIDGETS
4284 stderr_out ("mapping subwindow %d, %dx%d@%d+%d\n", 4624 stderr_out ("mapping subwindow %p, %dx%d@%d+%d\n",
4285 IMAGE_INSTANCE_SUBWINDOW_ID (ii), 4625 IMAGE_INSTANCE_SUBWINDOW_ID (ii),
4286 dga->width, dga->height, x, y); 4626 dga->width, dga->height, x, y);
4287 #endif 4627 #endif
4288 f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); 4628 f = XFRAME (IMAGE_INSTANCE_FRAME (ii));
4629 IMAGE_INSTANCE_DISPLAY_X (ii) = x;
4630 IMAGE_INSTANCE_DISPLAY_Y (ii) = y;
4631 IMAGE_INSTANCE_DISPLAY_WIDTH (ii) = dga->width;
4632 IMAGE_INSTANCE_DISPLAY_HEIGHT (ii) = dga->height;
4633
4634 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
4635 map_subwindow, (ii, x, y, dga));
4289 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 1; 4636 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 1;
4290 elt = get_subwindow_cachel_index (f, subwindow);
4291 cachel = Dynarr_atp (f->subwindow_cachels, elt);
4292 cachel->x = x;
4293 cachel->y = y;
4294 cachel->width = dga->width;
4295 cachel->height = dga->height;
4296 cachel->being_displayed = 1;
4297
4298 /* This forces any pending display changes to happen to the image
4299 before we show it. I'm not sure whether or not we need mark as
4300 clean here, but for now we will. */
4301 if (IMAGE_INSTANCE_DIRTYP (ii))
4302 {
4303 update_subwindow (subwindow);
4304 IMAGE_INSTANCE_DIRTYP (ii) = 0;
4305 }
4306
4307 MAYBE_DEVMETH (XDEVICE (ii->device), map_subwindow, (ii, x, y, dga));
4308 } 4637 }
4309 4638
4310 static int 4639 static int
4311 subwindow_possible_dest_types (void) 4640 subwindow_possible_dest_types (void)
4312 { 4641 {
4313 return IMAGE_SUBWINDOW_MASK; 4642 return IMAGE_SUBWINDOW_MASK;
4643 }
4644
4645 int
4646 subwindow_governing_domain (void)
4647 {
4648 return GOVERNING_DOMAIN_WINDOW;
4314 } 4649 }
4315 4650
4316 /* Partially instantiate a subwindow. */ 4651 /* Partially instantiate a subwindow. */
4317 void 4652 void
4318 subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, 4653 subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
4319 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 4654 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
4320 int dest_mask, Lisp_Object domain) 4655 int dest_mask, Lisp_Object domain)
4321 { 4656 {
4322 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 4657 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
4323 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); 4658 Lisp_Object device = image_instance_device (image_instance);
4324 Lisp_Object frame = FW_FRAME (domain); 4659 Lisp_Object frame = DOMAIN_FRAME (domain);
4325 Lisp_Object width = find_keyword_in_vector (instantiator, Q_pixel_width); 4660 Lisp_Object width = find_keyword_in_vector (instantiator, Q_pixel_width);
4326 Lisp_Object height = find_keyword_in_vector (instantiator, Q_pixel_height); 4661 Lisp_Object height = find_keyword_in_vector (instantiator, Q_pixel_height);
4327 4662
4328 if (NILP (frame)) 4663 if (NILP (frame))
4329 signal_simple_error ("No selected frame", device); 4664 signal_simple_error ("No selected frame", device);
4332 incompatible_image_types (instantiator, dest_mask, IMAGE_SUBWINDOW_MASK); 4667 incompatible_image_types (instantiator, dest_mask, IMAGE_SUBWINDOW_MASK);
4333 4668
4334 ii->data = 0; 4669 ii->data = 0;
4335 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0; 4670 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0;
4336 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; 4671 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0;
4337 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = frame; 4672
4338 4673 if (INTP (width))
4339 /* #### This stuff may get overidden by the widget code and is
4340 actually really dumb now that we have dynamic geometry
4341 calculations. What should really happen is that the subwindow
4342 should query its child for an appropriate geometry. */
4343 if (NILP (width))
4344 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = 20;
4345 else
4346 { 4674 {
4347 int w = 1; 4675 int w = 1;
4348 CHECK_INT (width);
4349 if (XINT (width) > 1) 4676 if (XINT (width) > 1)
4350 w = XINT (width); 4677 w = XINT (width);
4351 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = w; 4678 IMAGE_INSTANCE_WIDTH (ii) = w;
4352 } 4679 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0;
4353 if (NILP (height)) 4680 }
4354 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = 20; 4681
4355 else 4682 if (INTP (height))
4356 { 4683 {
4357 int h = 1; 4684 int h = 1;
4358 CHECK_INT (height);
4359 if (XINT (height) > 1) 4685 if (XINT (height) > 1)
4360 h = XINT (height); 4686 h = XINT (height);
4361 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = h; 4687 IMAGE_INSTANCE_HEIGHT (ii) = h;
4362 } 4688 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0;
4689 }
4690 }
4691
4692 /* This is just a backup in case no-one has assigned a suitable geometry.
4693 #### It should really query the enclose window for geometry. */
4694 static void
4695 subwindow_query_geometry (Lisp_Object image_instance, int* width,
4696 int* height, enum image_instance_geometry disp,
4697 Lisp_Object domain)
4698 {
4699 if (width) *width = 20;
4700 if (height) *height = 20;
4363 } 4701 }
4364 4702
4365 DEFUN ("subwindowp", Fsubwindowp, 1, 1, 0, /* 4703 DEFUN ("subwindowp", Fsubwindowp, 1, 1, 0, /*
4366 Return non-nil if OBJECT is a subwindow. 4704 Return non-nil if OBJECT is a subwindow.
4367 */ 4705 */
4375 Return the window id of SUBWINDOW as a number. 4713 Return the window id of SUBWINDOW as a number.
4376 */ 4714 */
4377 (subwindow)) 4715 (subwindow))
4378 { 4716 {
4379 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); 4717 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow);
4380 return make_int ((int) XIMAGE_INSTANCE_SUBWINDOW_ID (subwindow)); 4718 return make_int ((EMACS_INT) XIMAGE_INSTANCE_SUBWINDOW_ID (subwindow));
4381 } 4719 }
4382 4720
4383 DEFUN ("resize-subwindow", Fresize_subwindow, 1, 3, 0, /* 4721 DEFUN ("resize-subwindow", Fresize_subwindow, 1, 3, 0, /*
4384 Resize SUBWINDOW to WIDTH x HEIGHT. 4722 Resize SUBWINDOW to WIDTH x HEIGHT.
4385 If a value is nil that parameter is not changed. 4723 If a value is nil that parameter is not changed.
4386 */ 4724 */
4387 (subwindow, width, height)) 4725 (subwindow, width, height))
4388 { 4726 {
4389 int neww, newh; 4727 int neww, newh;
4728 Lisp_Image_Instance* ii;
4390 4729
4391 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); 4730 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow);
4731 ii = XIMAGE_INSTANCE (subwindow);
4392 4732
4393 if (NILP (width)) 4733 if (NILP (width))
4394 neww = XIMAGE_INSTANCE_WIDTH (subwindow); 4734 neww = IMAGE_INSTANCE_WIDTH (ii);
4395 else 4735 else
4396 neww = XINT (width); 4736 neww = XINT (width);
4397 4737
4398 if (NILP (height)) 4738 if (NILP (height))
4399 newh = XIMAGE_INSTANCE_HEIGHT (subwindow); 4739 newh = IMAGE_INSTANCE_HEIGHT (ii);
4400 else 4740 else
4401 newh = XINT (height); 4741 newh = XINT (height);
4402 4742
4403 /* The actual resizing gets done asychronously by 4743 /* The actual resizing gets done asynchronously by
4404 update_subwindow. */ 4744 update_subwindow. */
4405 XIMAGE_INSTANCE_HEIGHT (subwindow) = newh; 4745 IMAGE_INSTANCE_HEIGHT (ii) = newh;
4406 XIMAGE_INSTANCE_WIDTH (subwindow) = neww; 4746 IMAGE_INSTANCE_WIDTH (ii) = neww;
4407 4747 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 1;
4408 /* need to update the cachels as redisplay will not do this */
4409 update_subwindow_cachel (subwindow);
4410 4748
4411 return subwindow; 4749 return subwindow;
4412 } 4750 }
4413 4751
4414 DEFUN ("force-subwindow-map", Fforce_subwindow_map, 1, 1, 0, /* 4752 DEFUN ("force-subwindow-map", Fforce_subwindow_map, 1, 1, 0, /*
4539 (IMAGE_INSTANCE_PIXMAP_SLICE (ii) + 1) 4877 (IMAGE_INSTANCE_PIXMAP_SLICE (ii) + 1)
4540 % IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii); 4878 % IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii);
4541 /* We might need to kick redisplay at this point - but we 4879 /* We might need to kick redisplay at this point - but we
4542 also might not. */ 4880 also might not. */
4543 MARK_DEVICE_FRAMES_GLYPHS_CHANGED 4881 MARK_DEVICE_FRAMES_GLYPHS_CHANGED
4544 (XDEVICE (IMAGE_INSTANCE_DEVICE (ii))); 4882 (XDEVICE (image_instance_device (value)));
4545 MARK_IMAGE_INSTANCE_CHANGED (ii); 4883 /* Cascade dirtiness so that we can have an animated glyph in a layout
4884 for instance. */
4885 set_image_instance_dirty_p (value, 1);
4546 } 4886 }
4547 } 4887 }
4548 } 4888 }
4549 return Qnil; 4889 return Qnil;
4550 } 4890 }
4585 *****************************************************************************/ 4925 *****************************************************************************/
4586 4926
4587 void 4927 void
4588 syms_of_glyphs (void) 4928 syms_of_glyphs (void)
4589 { 4929 {
4930 INIT_LRECORD_IMPLEMENTATION (glyph);
4931 INIT_LRECORD_IMPLEMENTATION (image_instance);
4932
4590 /* image instantiators */ 4933 /* image instantiators */
4591 4934
4592 DEFSUBR (Fimage_instantiator_format_list); 4935 DEFSUBR (Fimage_instantiator_format_list);
4593 DEFSUBR (Fvalid_image_instantiator_format_p); 4936 DEFSUBR (Fvalid_image_instantiator_format_p);
4594 DEFSUBR (Fset_console_type_image_conversion_list); 4937 DEFSUBR (Fset_console_type_image_conversion_list);
4595 DEFSUBR (Fconsole_type_image_conversion_list); 4938 DEFSUBR (Fconsole_type_image_conversion_list);
4596 4939
4597 defkeyword (&Q_file, ":file"); 4940 DEFKEYWORD (Q_file);
4598 defkeyword (&Q_data, ":data"); 4941 DEFKEYWORD (Q_data);
4599 defkeyword (&Q_face, ":face"); 4942 DEFKEYWORD (Q_face);
4600 defkeyword (&Q_pixel_height, ":pixel-height"); 4943 DEFKEYWORD (Q_pixel_height);
4601 defkeyword (&Q_pixel_width, ":pixel-width"); 4944 DEFKEYWORD (Q_pixel_width);
4602 4945
4603 #ifdef HAVE_XPM 4946 #ifdef HAVE_XPM
4604 defkeyword (&Q_color_symbols, ":color-symbols"); 4947 DEFKEYWORD (Q_color_symbols);
4605 #endif 4948 #endif
4606 #ifdef HAVE_WINDOW_SYSTEM 4949 #ifdef HAVE_WINDOW_SYSTEM
4607 defkeyword (&Q_mask_file, ":mask-file"); 4950 DEFKEYWORD (Q_mask_file);
4608 defkeyword (&Q_mask_data, ":mask-data"); 4951 DEFKEYWORD (Q_mask_data);
4609 defkeyword (&Q_hotspot_x, ":hotspot-x"); 4952 DEFKEYWORD (Q_hotspot_x);
4610 defkeyword (&Q_hotspot_y, ":hotspot-y"); 4953 DEFKEYWORD (Q_hotspot_y);
4611 defkeyword (&Q_foreground, ":foreground"); 4954 DEFKEYWORD (Q_foreground);
4612 defkeyword (&Q_background, ":background"); 4955 DEFKEYWORD (Q_background);
4613 #endif 4956 #endif
4614 /* image specifiers */ 4957 /* image specifiers */
4615 4958
4616 DEFSUBR (Fimage_specifier_p); 4959 DEFSUBR (Fimage_specifier_p);
4617 /* Qimage in general.c */ 4960 /* Qimage in general.c */
4618 4961
4619 /* image instances */ 4962 /* image instances */
4620 4963
4621 defsymbol (&Qimage_instancep, "image-instance-p"); 4964 defsymbol (&Qimage_instancep, "image-instance-p");
4622 4965
4623 defsymbol (&Qnothing_image_instance_p, "nothing-image-instance-p"); 4966 DEFSYMBOL (Qnothing_image_instance_p);
4624 defsymbol (&Qtext_image_instance_p, "text-image-instance-p"); 4967 DEFSYMBOL (Qtext_image_instance_p);
4625 defsymbol (&Qmono_pixmap_image_instance_p, "mono-pixmap-image-instance-p"); 4968 DEFSYMBOL (Qmono_pixmap_image_instance_p);
4626 defsymbol (&Qcolor_pixmap_image_instance_p, "color-pixmap-image-instance-p"); 4969 DEFSYMBOL (Qcolor_pixmap_image_instance_p);
4627 defsymbol (&Qpointer_image_instance_p, "pointer-image-instance-p"); 4970 DEFSYMBOL (Qpointer_image_instance_p);
4628 defsymbol (&Qwidget_image_instance_p, "widget-image-instance-p"); 4971 DEFSYMBOL (Qwidget_image_instance_p);
4629 defsymbol (&Qsubwindow_image_instance_p, "subwindow-image-instance-p"); 4972 DEFSYMBOL (Qsubwindow_image_instance_p);
4630 defsymbol (&Qlayout_image_instance_p, "layout-image-instance-p");
4631 4973
4632 DEFSUBR (Fmake_image_instance); 4974 DEFSUBR (Fmake_image_instance);
4633 DEFSUBR (Fimage_instance_p); 4975 DEFSUBR (Fimage_instance_p);
4634 DEFSUBR (Fimage_instance_type); 4976 DEFSUBR (Fimage_instance_type);
4635 DEFSUBR (Fvalid_image_instance_type_p); 4977 DEFSUBR (Fvalid_image_instance_type_p);
4636 DEFSUBR (Fimage_instance_type_list); 4978 DEFSUBR (Fimage_instance_type_list);
4637 DEFSUBR (Fimage_instance_name); 4979 DEFSUBR (Fimage_instance_name);
4980 DEFSUBR (Fimage_instance_domain);
4638 DEFSUBR (Fimage_instance_string); 4981 DEFSUBR (Fimage_instance_string);
4639 DEFSUBR (Fimage_instance_file_name); 4982 DEFSUBR (Fimage_instance_file_name);
4640 DEFSUBR (Fimage_instance_mask_file_name); 4983 DEFSUBR (Fimage_instance_mask_file_name);
4641 DEFSUBR (Fimage_instance_depth); 4984 DEFSUBR (Fimage_instance_depth);
4642 DEFSUBR (Fimage_instance_height); 4985 DEFSUBR (Fimage_instance_height);
4644 DEFSUBR (Fimage_instance_hotspot_x); 4987 DEFSUBR (Fimage_instance_hotspot_x);
4645 DEFSUBR (Fimage_instance_hotspot_y); 4988 DEFSUBR (Fimage_instance_hotspot_y);
4646 DEFSUBR (Fimage_instance_foreground); 4989 DEFSUBR (Fimage_instance_foreground);
4647 DEFSUBR (Fimage_instance_background); 4990 DEFSUBR (Fimage_instance_background);
4648 DEFSUBR (Fimage_instance_property); 4991 DEFSUBR (Fimage_instance_property);
4649 DEFSUBR (Fset_image_instance_property);
4650 DEFSUBR (Fcolorize_image_instance); 4992 DEFSUBR (Fcolorize_image_instance);
4651 /* subwindows */ 4993 /* subwindows */
4652 DEFSUBR (Fsubwindowp); 4994 DEFSUBR (Fsubwindowp);
4653 DEFSUBR (Fimage_instance_subwindow_id); 4995 DEFSUBR (Fimage_instance_subwindow_id);
4654 DEFSUBR (Fresize_subwindow); 4996 DEFSUBR (Fresize_subwindow);
4655 DEFSUBR (Fforce_subwindow_map); 4997 DEFSUBR (Fforce_subwindow_map);
4656 4998
4657 /* Qnothing defined as part of the "nothing" image-instantiator 4999 /* Qnothing defined as part of the "nothing" image-instantiator
4658 type. */ 5000 type. */
4659 /* Qtext defined in general.c */ 5001 /* Qtext defined in general.c */
4660 defsymbol (&Qmono_pixmap, "mono-pixmap"); 5002 DEFSYMBOL (Qmono_pixmap);
4661 defsymbol (&Qcolor_pixmap, "color-pixmap"); 5003 DEFSYMBOL (Qcolor_pixmap);
4662 /* Qpointer defined in general.c */ 5004 /* Qpointer defined in general.c */
4663 5005
4664 /* glyphs */ 5006 /* glyphs */
4665 5007
4666 defsymbol (&Qglyphp, "glyphp"); 5008 DEFSYMBOL (Qglyphp);
4667 defsymbol (&Qcontrib_p, "contrib-p"); 5009 DEFSYMBOL (Qcontrib_p);
4668 defsymbol (&Qbaseline, "baseline"); 5010 DEFSYMBOL (Qbaseline);
4669 5011
4670 defsymbol (&Qbuffer_glyph_p, "buffer-glyph-p"); 5012 DEFSYMBOL (Qbuffer_glyph_p);
4671 defsymbol (&Qpointer_glyph_p, "pointer-glyph-p"); 5013 DEFSYMBOL (Qpointer_glyph_p);
4672 defsymbol (&Qicon_glyph_p, "icon-glyph-p"); 5014 DEFSYMBOL (Qicon_glyph_p);
4673 5015
4674 defsymbol (&Qconst_glyph_variable, "const-glyph-variable"); 5016 DEFSYMBOL (Qconst_glyph_variable);
4675 5017
4676 DEFSUBR (Fglyph_type); 5018 DEFSUBR (Fglyph_type);
4677 DEFSUBR (Fvalid_glyph_type_p); 5019 DEFSUBR (Fvalid_glyph_type_p);
4678 DEFSUBR (Fglyph_type_list); 5020 DEFSUBR (Fglyph_type_list);
4679 DEFSUBR (Fglyphp); 5021 DEFSUBR (Fglyphp);
4680 DEFSUBR (Fmake_glyph_internal); 5022 DEFSUBR (Fmake_glyph_internal);
4681 DEFSUBR (Fglyph_width); 5023 DEFSUBR (Fglyph_width);
4682 DEFSUBR (Fglyph_ascent); 5024 DEFSUBR (Fglyph_ascent);
4683 DEFSUBR (Fglyph_descent); 5025 DEFSUBR (Fglyph_descent);
4684 DEFSUBR (Fglyph_height); 5026 DEFSUBR (Fglyph_height);
5027 DEFSUBR (Fset_instantiator_property);
4685 5028
4686 /* Qbuffer defined in general.c. */ 5029 /* Qbuffer defined in general.c. */
4687 /* Qpointer defined above */ 5030 /* Qpointer defined above */
4688 5031
4689 /* Unfortunately, timeout handlers must be lisp functions. This is 5032 /* Unfortunately, timeout handlers must be lisp functions. This is
4690 for animated glyphs. */ 5033 for animated glyphs. */
4691 defsymbol (&Qglyph_animated_timeout_handler, 5034 DEFSYMBOL (Qglyph_animated_timeout_handler);
4692 "glyph-animated-timeout-handler");
4693 DEFSUBR (Fglyph_animated_timeout_handler); 5035 DEFSUBR (Fglyph_animated_timeout_handler);
4694 5036
4695 /* Errors */ 5037 /* Errors */
4696 deferror (&Qimage_conversion_error, 5038 DEFERROR_STANDARD (Qimage_conversion_error, Qio_error);
4697 "image-conversion-error",
4698 "image-conversion error", Qio_error);
4699
4700 } 5039 }
4701 5040
4702 static const struct lrecord_description image_specifier_description[] = { 5041 static const struct lrecord_description image_specifier_description[] = {
4703 { XD_LISP_OBJECT, specifier_data_offset + offsetof (struct image_specifier, attachee) }, 5042 { XD_LISP_OBJECT, specifier_data_offset + offsetof (struct image_specifier, attachee) },
4704 { XD_LISP_OBJECT, specifier_data_offset + offsetof (struct image_specifier, attachee_property) }, 5043 { XD_LISP_OBJECT, specifier_data_offset + offsetof (struct image_specifier, attachee_property) },
4777 { XD_STRUCT_PTR, offsetof (struct image_instantiator_methods, consoles), 1, &cted_description }, 5116 { XD_STRUCT_PTR, offsetof (struct image_instantiator_methods, consoles), 1, &cted_description },
4778 { XD_END } 5117 { XD_END }
4779 }; 5118 };
4780 5119
4781 const struct struct_description iim_description = { 5120 const struct struct_description iim_description = {
4782 sizeof(struct image_instantiator_methods), 5121 sizeof (struct image_instantiator_methods),
4783 iim_description_1 5122 iim_description_1
4784 }; 5123 };
4785 5124
4786 void 5125 void
4787 image_instantiator_format_create (void) 5126 image_instantiator_format_create (void)
4811 IIFORMAT_VALID_KEYWORD (inherit, Q_face, check_valid_face); 5150 IIFORMAT_VALID_KEYWORD (inherit, Q_face, check_valid_face);
4812 5151
4813 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (string, "string"); 5152 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (string, "string");
4814 5153
4815 IIFORMAT_HAS_METHOD (string, validate); 5154 IIFORMAT_HAS_METHOD (string, validate);
5155 IIFORMAT_HAS_SHARED_METHOD (string, governing_domain, subwindow);
4816 IIFORMAT_HAS_METHOD (string, possible_dest_types); 5156 IIFORMAT_HAS_METHOD (string, possible_dest_types);
4817 IIFORMAT_HAS_METHOD (string, instantiate); 5157 IIFORMAT_HAS_METHOD (string, instantiate);
4818 5158
4819 IIFORMAT_VALID_KEYWORD (string, Q_data, check_valid_string); 5159 IIFORMAT_VALID_KEYWORD (string, Q_data, check_valid_string);
4820 /* Do this so we can set strings. */ 5160 /* Do this so we can set strings. */
5161 /* #### Andy, what is this? This is a bogus format and should not be
5162 visible to the user. */
4821 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (text, "text"); 5163 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (text, "text");
4822 IIFORMAT_HAS_METHOD (text, set_property); 5164 IIFORMAT_HAS_METHOD (text, update);
4823 IIFORMAT_HAS_METHOD (text, query_geometry); 5165 IIFORMAT_HAS_METHOD (text, query_geometry);
4824 5166
4825 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (formatted_string, "formatted-string"); 5167 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (formatted_string, "formatted-string");
4826 5168
4827 IIFORMAT_HAS_METHOD (formatted_string, validate); 5169 IIFORMAT_HAS_METHOD (formatted_string, validate);
4828 IIFORMAT_HAS_METHOD (formatted_string, possible_dest_types); 5170 IIFORMAT_HAS_METHOD (formatted_string, possible_dest_types);
4829 IIFORMAT_HAS_METHOD (formatted_string, instantiate); 5171 IIFORMAT_HAS_METHOD (formatted_string, instantiate);
4830 IIFORMAT_VALID_KEYWORD (formatted_string, Q_data, check_valid_string); 5172 IIFORMAT_VALID_KEYWORD (formatted_string, Q_data, check_valid_string);
4831 5173
5174 /* Do this so pointers have geometry. */
5175 /* #### Andy, what is this? This is a bogus format and should not be
5176 visible to the user. */
5177 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (pointer, "pointer");
5178 IIFORMAT_HAS_SHARED_METHOD (pointer, query_geometry, subwindow);
5179
4832 /* subwindows */ 5180 /* subwindows */
4833 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (subwindow, "subwindow"); 5181 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (subwindow, "subwindow");
4834 IIFORMAT_HAS_METHOD (subwindow, possible_dest_types); 5182 IIFORMAT_HAS_METHOD (subwindow, possible_dest_types);
5183 IIFORMAT_HAS_METHOD (subwindow, governing_domain);
4835 IIFORMAT_HAS_METHOD (subwindow, instantiate); 5184 IIFORMAT_HAS_METHOD (subwindow, instantiate);
5185 IIFORMAT_HAS_METHOD (subwindow, query_geometry);
4836 IIFORMAT_VALID_KEYWORD (subwindow, Q_pixel_width, check_valid_int); 5186 IIFORMAT_VALID_KEYWORD (subwindow, Q_pixel_width, check_valid_int);
4837 IIFORMAT_VALID_KEYWORD (subwindow, Q_pixel_height, check_valid_int); 5187 IIFORMAT_VALID_KEYWORD (subwindow, Q_pixel_height, check_valid_int);
4838 5188
4839 #ifdef HAVE_WINDOW_SYSTEM 5189 #ifdef HAVE_WINDOW_SYSTEM
4840 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xbm, "xbm"); 5190 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xbm, "xbm");
4977 /* display tables */ 5327 /* display tables */
4978 5328
4979 DEFVAR_SPECIFIER ("current-display-table", &Vcurrent_display_table /* 5329 DEFVAR_SPECIFIER ("current-display-table", &Vcurrent_display_table /*
4980 *The display table currently in use. 5330 *The display table currently in use.
4981 This is a specifier; use `set-specifier' to change it. 5331 This is a specifier; use `set-specifier' to change it.
4982 The display table is a vector created with `make-display-table'. 5332
4983 The 256 elements control how to display each possible text character. 5333 Display tables are used to control how characters are displayed. Each
4984 Each value should be a string, a glyph, a vector or nil. 5334 time that redisplay processes a character, it is looked up in all the
4985 If a value is a vector it must be composed only of strings and glyphs. 5335 display tables that apply (obtained by calling `specifier-instance' on
4986 nil means display the character in the default fashion. 5336 `current-display-table' and any overriding display tables specified in
4987 Faces can have their own, overriding display table. 5337 currently active faces). The first entry found that matches the
5338 character determines how the character is displayed. If there is no
5339 matching entry, the default display method is used. (Non-control
5340 characters are displayed as themselves and control characters are
5341 displayed according to the buffer-local variable `ctl-arrow'. Control
5342 characters are further affected by `control-arrow-glyph' and
5343 `octal-escape-glyph'.)
5344
5345 Each instantiator in this specifier and the display-table specifiers
5346 in faces is a display table or a list of such tables. If a list, each
5347 table will be searched in turn for an entry matching a particular
5348 character. Each display table is one of
5349
5350 -- a vector, specifying values for characters starting at 0
5351 -- a char table, either of type `char' or `generic'
5352 -- a range table
5353
5354 Each entry in a display table should be one of
5355
5356 -- nil (this entry is ignored and the search continues)
5357 -- a character (use this character; if it happens to be the same as
5358 the original character, default processing happens, otherwise
5359 redisplay attempts to display this character directly;
5360 #### At some point recursive display-table lookup will be
5361 implemented.)
5362 -- a string (display each character in the string directly;
5363 #### At some point recursive display-table lookup will be
5364 implemented.)
5365 -- a glyph (display the glyph;
5366 #### At some point recursive display-table lookup will be
5367 implemented when a string glyph is being processed.)
5368 -- a cons of the form (format "STRING") where STRING is a printf-like
5369 spec used to process the character. #### Unfortunately no
5370 formatting directives other than %% are implemented.
5371 -- a vector (each element of the vector is processed recursively;
5372 in such a case, nil elements in the vector are simply ignored)
5373
5374 #### At some point in the near future, display tables are likely to
5375 be expanded to include other features, such as referencing characters
5376 in particular fonts and allowing the character search to continue
5377 all the way up the chain of specifier instantiators. These features
5378 are necessary to properly display Unicode characters.
4988 */ ); 5379 */ );
4989 Vcurrent_display_table = Fmake_specifier (Qdisplay_table); 5380 Vcurrent_display_table = Fmake_specifier (Qdisplay_table);
4990 set_specifier_fallback (Vcurrent_display_table, 5381 set_specifier_fallback (Vcurrent_display_table,
4991 list1 (Fcons (Qnil, Qnil))); 5382 list1 (Fcons (Qnil, Qnil)));
4992 set_specifier_caching (Vcurrent_display_table, 5383 set_specifier_caching (Vcurrent_display_table,