Mercurial > hg > xemacs-beta
comparison src/glyphs.c @ 408:501cfd01ee6d r21-2-34
Import from CVS: tag r21-2-34
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:18:11 +0200 |
parents | b8cc9ab3f761 |
children | de805c49cfc1 |
comparison
equal
deleted
inserted
replaced
407:ed6218a7d4d3 | 408:501cfd01ee6d |
---|---|
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 Qupdate_widget_instances; | |
63 Lisp_Object Qwidget_image_instance_p; | 62 Lisp_Object Qwidget_image_instance_p; |
64 Lisp_Object Qconst_glyph_variable; | 63 Lisp_Object Qconst_glyph_variable; |
65 Lisp_Object Qmono_pixmap, Qcolor_pixmap, Qsubwindow; | 64 Lisp_Object Qmono_pixmap, Qcolor_pixmap, Qsubwindow; |
66 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; |
67 Lisp_Object Qformatted_string; | 66 Lisp_Object Qformatted_string; |
80 DEFINE_IMAGE_INSTANTIATOR_FORMAT (inherit); | 79 DEFINE_IMAGE_INSTANTIATOR_FORMAT (inherit); |
81 DEFINE_IMAGE_INSTANTIATOR_FORMAT (string); | 80 DEFINE_IMAGE_INSTANTIATOR_FORMAT (string); |
82 DEFINE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); | 81 DEFINE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); |
83 DEFINE_IMAGE_INSTANTIATOR_FORMAT (subwindow); | 82 DEFINE_IMAGE_INSTANTIATOR_FORMAT (subwindow); |
84 DEFINE_IMAGE_INSTANTIATOR_FORMAT (text); | 83 DEFINE_IMAGE_INSTANTIATOR_FORMAT (text); |
84 DEFINE_IMAGE_INSTANTIATOR_FORMAT (pointer); | |
85 | 85 |
86 #ifdef HAVE_WINDOW_SYSTEM | 86 #ifdef HAVE_WINDOW_SYSTEM |
87 DEFINE_IMAGE_INSTANTIATOR_FORMAT (xbm); | 87 DEFINE_IMAGE_INSTANTIATOR_FORMAT (xbm); |
88 Lisp_Object Qxbm; | 88 Lisp_Object Qxbm; |
89 | 89 |
119 typedef struct | 119 typedef struct |
120 { | 120 { |
121 Dynarr_declare (struct image_instantiator_format_entry); | 121 Dynarr_declare (struct image_instantiator_format_entry); |
122 } image_instantiator_format_entry_dynarr; | 122 } image_instantiator_format_entry_dynarr; |
123 | 123 |
124 /* This contains one entry per format, per device it's defined on. */ | |
124 image_instantiator_format_entry_dynarr * | 125 image_instantiator_format_entry_dynarr * |
125 the_image_instantiator_format_entry_dynarr; | 126 the_image_instantiator_format_entry_dynarr; |
126 | 127 |
127 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 glyph); | |
128 static void image_validate (Lisp_Object instantiator); | 130 static void image_validate (Lisp_Object instantiator); |
129 static void glyph_property_was_changed (Lisp_Object glyph, | 131 static void glyph_property_was_changed (Lisp_Object glyph, |
130 Lisp_Object property, | 132 Lisp_Object property, |
131 Lisp_Object locale); | 133 Lisp_Object locale); |
132 static void set_image_instance_dirty_p (Lisp_Object instance, int dirty); | 134 static void set_image_instance_dirty_p (Lisp_Object instance, int dirty); |
133 static void register_ignored_expose (struct frame* f, int x, int y, int width, int height); | 135 static void register_ignored_expose (struct frame* f, int x, int y, int width, int height); |
136 static void cache_subwindow_instance_in_frame_maybe (Lisp_Object instance); | |
134 /* Unfortunately windows and X are different. In windows BeginPaint() | 137 /* Unfortunately windows and X are different. In windows BeginPaint() |
135 will prevent WM_PAINT messages being generated so it is unnecessary | 138 will prevent WM_PAINT messages being generated so it is unnecessary |
136 to register exposures as they will not occur. Under X they will | 139 to register exposures as they will not occur. Under X they will |
137 always occur. */ | 140 always occur. */ |
138 int hold_ignored_expose_registration; | 141 int hold_ignored_expose_registration; |
220 DEFUN ("valid-image-instantiator-format-p", Fvalid_image_instantiator_format_p, | 223 DEFUN ("valid-image-instantiator-format-p", Fvalid_image_instantiator_format_p, |
221 1, 2, 0, /* | 224 1, 2, 0, /* |
222 Given an IMAGE-INSTANTIATOR-FORMAT, return non-nil if it is valid. | 225 Given an IMAGE-INSTANTIATOR-FORMAT, return non-nil if it is valid. |
223 If LOCALE is non-nil then the format is checked in that domain. | 226 If LOCALE is non-nil then the format is checked in that domain. |
224 If LOCALE is nil the current console is used. | 227 If LOCALE is nil the current console is used. |
228 | |
225 Valid formats are some subset of 'nothing, 'string, 'formatted-string, | 229 Valid formats are some subset of 'nothing, 'string, 'formatted-string, |
226 'xpm, 'xbm, 'xface, 'gif, 'jpeg, 'png, 'tiff, 'cursor-font, 'font, | 230 'xpm, 'xbm, 'xface, 'gif, 'jpeg, 'png, 'tiff, 'cursor-font, 'font, |
227 'autodetect, 'widget and 'subwindow, depending on how XEmacs was compiled. | 231 'autodetect, 'subwindow, 'inherit, 'mswindows-resource, 'bmp, |
232 'native-layout, 'layout, 'label, 'tab-control, 'tree-view, | |
233 'progress-gauge, 'scrollbar, 'combo-box, 'edit-field, 'button, | |
234 'widget, 'pointer, and 'text, depending on how XEmacs was compiled. | |
228 */ | 235 */ |
229 (image_instantiator_format, locale)) | 236 (image_instantiator_format, locale)) |
230 { | 237 { |
231 return valid_image_instantiator_format_p (image_instantiator_format, locale) ? | 238 return valid_image_instantiator_format_p (image_instantiator_format, |
239 locale) ? | |
232 Qt : Qnil; | 240 Qt : Qnil; |
233 } | 241 } |
234 | 242 |
235 DEFUN ("image-instantiator-format-list", Fimage_instantiator_format_list, | 243 DEFUN ("image-instantiator-format-list", Fimage_instantiator_format_list, |
236 0, 0, 0, /* | 244 0, 0, 0, /* |
249 | 257 |
250 entry.symbol = symbol; | 258 entry.symbol = symbol; |
251 entry.device = device; | 259 entry.device = device; |
252 entry.meths = meths; | 260 entry.meths = meths; |
253 Dynarr_add (the_image_instantiator_format_entry_dynarr, entry); | 261 Dynarr_add (the_image_instantiator_format_entry_dynarr, entry); |
254 Vimage_instantiator_format_list = | 262 if (NILP (memq_no_quit (symbol, Vimage_instantiator_format_list))) |
255 Fcons (symbol, Vimage_instantiator_format_list); | 263 Vimage_instantiator_format_list = |
264 Fcons (symbol, Vimage_instantiator_format_list); | |
256 } | 265 } |
257 | 266 |
258 void | 267 void |
259 add_entry_to_image_instantiator_format_list (Lisp_Object symbol, | 268 add_entry_to_image_instantiator_format_list (Lisp_Object symbol, |
260 struct | 269 struct |
540 } | 549 } |
541 | 550 |
542 return Fvector (len, elt); | 551 return Fvector (len, elt); |
543 } | 552 } |
544 | 553 |
554 #ifdef ERROR_CHECK_GLYPHS | |
555 static int | |
556 check_instance_cache_mapper (Lisp_Object key, Lisp_Object value, | |
557 void *flag_closure) | |
558 { | |
559 /* This function can GC */ | |
560 /* value can be nil; we cache failures as well as successes */ | |
561 if (!NILP (value)) | |
562 { | |
563 Lisp_Object window; | |
564 VOID_TO_LISP (window, flag_closure); | |
565 assert (EQ (XIMAGE_INSTANCE_DOMAIN (value), window)); | |
566 } | |
567 | |
568 return 0; | |
569 } | |
570 | |
571 void | |
572 check_window_subwindow_cache (struct window* w) | |
573 { | |
574 Lisp_Object window; | |
575 | |
576 XSETWINDOW (window, w); | |
577 | |
578 assert (!NILP (w->subwindow_instance_cache)); | |
579 elisp_maphash (check_instance_cache_mapper, | |
580 w->subwindow_instance_cache, | |
581 LISP_TO_VOID (window)); | |
582 } | |
583 | |
584 void | |
585 check_image_instance_structure (Lisp_Object instance) | |
586 { | |
587 /* Weird nothing images exist at startup when the console is | |
588 deleted. */ | |
589 if (!NOTHING_IMAGE_INSTANCEP (instance)) | |
590 assert (DOMAIN_LIVE_P (instance)); | |
591 if (WINDOWP (XIMAGE_INSTANCE_DOMAIN (instance))) | |
592 check_window_subwindow_cache | |
593 (XWINDOW (XIMAGE_INSTANCE_DOMAIN (instance))); | |
594 } | |
595 #endif | |
596 | |
597 /* Determine what kind of domain governs the image instance. | |
598 Verify that the given domain is at least as specific, and extract | |
599 the governing domain from it. */ | |
600 static Lisp_Object | |
601 get_image_instantiator_governing_domain (Lisp_Object instantiator, | |
602 Lisp_Object domain) | |
603 { | |
604 int governing_domain; | |
605 | |
606 struct image_instantiator_methods *meths = | |
607 decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], | |
608 ERROR_ME); | |
609 governing_domain = IIFORMAT_METH_OR_GIVEN (meths, governing_domain, (), | |
610 GOVERNING_DOMAIN_DEVICE); | |
611 | |
612 if (governing_domain == GOVERNING_DOMAIN_WINDOW | |
613 && NILP (DOMAIN_WINDOW (domain))) | |
614 signal_simple_error_2 ("Domain for this instantiator must be resolvable to a window", | |
615 instantiator, domain); | |
616 else if (governing_domain == GOVERNING_DOMAIN_FRAME | |
617 && NILP (DOMAIN_FRAME (domain))) | |
618 signal_simple_error_2 | |
619 ("Domain for this instantiator must be resolvable to a frame", | |
620 instantiator, domain); | |
621 | |
622 if (governing_domain == GOVERNING_DOMAIN_WINDOW) | |
623 domain = DOMAIN_WINDOW (domain); | |
624 else if (governing_domain == GOVERNING_DOMAIN_FRAME) | |
625 domain = DOMAIN_FRAME (domain); | |
626 else if (governing_domain == GOVERNING_DOMAIN_DEVICE) | |
627 domain = DOMAIN_DEVICE (domain); | |
628 else | |
629 abort (); | |
630 | |
631 return domain; | |
632 } | |
633 | |
545 static Lisp_Object | 634 static Lisp_Object |
546 normalize_image_instantiator (Lisp_Object instantiator, | 635 normalize_image_instantiator (Lisp_Object instantiator, |
547 Lisp_Object contype, | 636 Lisp_Object contype, |
548 Lisp_Object dest_mask) | 637 Lisp_Object dest_mask) |
549 { | 638 { |
574 instantiator)); | 663 instantiator)); |
575 } | 664 } |
576 } | 665 } |
577 | 666 |
578 static Lisp_Object | 667 static Lisp_Object |
579 instantiate_image_instantiator (Lisp_Object device, Lisp_Object domain, | 668 instantiate_image_instantiator (Lisp_Object governing_domain, |
669 Lisp_Object domain, | |
580 Lisp_Object instantiator, | 670 Lisp_Object instantiator, |
581 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 671 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
582 int dest_mask, Lisp_Object glyph) | 672 int dest_mask, Lisp_Object glyph) |
583 { | 673 { |
584 Lisp_Object ii = allocate_image_instance (device, glyph); | 674 Lisp_Object ii = allocate_image_instance (governing_domain, glyph); |
585 Lisp_Image_Instance* p = XIMAGE_INSTANCE (ii); | 675 Lisp_Image_Instance* p = XIMAGE_INSTANCE (ii); |
586 struct image_instantiator_methods *meths; | 676 struct image_instantiator_methods *meths, *device_meths; |
587 struct gcpro gcpro1; | 677 struct gcpro gcpro1; |
588 int methp = 0; | |
589 | 678 |
590 GCPRO1 (ii); | 679 GCPRO1 (ii); |
591 if (!valid_image_instantiator_format_p (XVECTOR_DATA (instantiator)[0], device)) | 680 if (!valid_image_instantiator_format_p (XVECTOR_DATA (instantiator)[0], |
681 DOMAIN_DEVICE (governing_domain))) | |
592 signal_simple_error | 682 signal_simple_error |
593 ("Image instantiator format is invalid in this locale.", | 683 ("Image instantiator format is invalid in this locale.", |
594 instantiator); | 684 instantiator); |
595 | 685 |
596 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], | 686 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], |
597 ERROR_ME); | 687 ERROR_ME); |
598 methp = (int)HAS_IIFORMAT_METH_P (meths, instantiate); | |
599 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg, | 688 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg, |
600 pointer_bg, dest_mask, domain)); | 689 pointer_bg, dest_mask, domain)); |
601 | 690 |
602 /* now do device specific instantiation */ | 691 /* Now do device specific instantiation. */ |
603 meths = decode_device_ii_format (device, XVECTOR_DATA (instantiator)[0], | 692 device_meths = decode_device_ii_format (DOMAIN_DEVICE (governing_domain), |
604 ERROR_ME_NOT); | 693 XVECTOR_DATA (instantiator)[0], |
605 | 694 ERROR_ME_NOT); |
606 if (!methp && (!meths || !HAS_IIFORMAT_METH_P (meths, instantiate))) | 695 |
696 if (!HAS_IIFORMAT_METH_P (meths, instantiate) | |
697 && (!device_meths || !HAS_IIFORMAT_METH_P (device_meths, instantiate))) | |
607 signal_simple_error | 698 signal_simple_error |
608 ("Don't know how to instantiate this image instantiator?", | 699 ("Don't know how to instantiate this image instantiator?", |
609 instantiator); | 700 instantiator); |
610 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg, | 701 |
611 pointer_bg, dest_mask, domain)); | 702 /* In general native window system methods will require sane |
612 UNGCPRO; | 703 geometry values, thus the instance needs to have been laid-out |
613 | 704 before they get called. */ |
614 /* Some code may have already laid out the widget, if not then do it | 705 image_instance_layout (ii, XIMAGE_INSTANCE_WIDTH (ii), |
615 here. */ | 706 XIMAGE_INSTANCE_HEIGHT (ii), domain); |
707 | |
708 MAYBE_IIFORMAT_METH (device_meths, instantiate, (ii, instantiator, pointer_fg, | |
709 pointer_bg, dest_mask, domain)); | |
710 /* Do post instantiation. */ | |
711 MAYBE_IIFORMAT_METH (meths, post_instantiate, (ii, instantiator, domain)); | |
712 MAYBE_IIFORMAT_METH (device_meths, post_instantiate, (ii, instantiator, domain)); | |
713 | |
714 /* We're done. */ | |
715 IMAGE_INSTANCE_INITIALIZED (p) = 1; | |
716 /* Now that we're done verify that we really are laid out. */ | |
616 if (IMAGE_INSTANCE_LAYOUT_CHANGED (p)) | 717 if (IMAGE_INSTANCE_LAYOUT_CHANGED (p)) |
617 image_instance_layout (ii, IMAGE_UNSPECIFIED_GEOMETRY, | 718 image_instance_layout (ii, XIMAGE_INSTANCE_WIDTH (ii), |
618 IMAGE_UNSPECIFIED_GEOMETRY, domain); | 719 XIMAGE_INSTANCE_HEIGHT (ii), domain); |
619 | 720 |
620 /* We *must* have a clean image at this point. */ | 721 /* We *must* have a clean image at this point. */ |
621 IMAGE_INSTANCE_TEXT_CHANGED (p) = 0; | 722 IMAGE_INSTANCE_TEXT_CHANGED (p) = 0; |
622 IMAGE_INSTANCE_SIZE_CHANGED (p) = 0; | 723 IMAGE_INSTANCE_SIZE_CHANGED (p) = 0; |
623 IMAGE_INSTANCE_LAYOUT_CHANGED (p) = 0; | 724 IMAGE_INSTANCE_LAYOUT_CHANGED (p) = 0; |
624 IMAGE_INSTANCE_DIRTYP (p) = 0; | 725 IMAGE_INSTANCE_DIRTYP (p) = 0; |
625 | 726 |
626 return ii; | 727 assert ( XIMAGE_INSTANCE_HEIGHT (ii) |
728 != IMAGE_UNSPECIFIED_GEOMETRY | |
729 && XIMAGE_INSTANCE_WIDTH (ii) | |
730 != IMAGE_UNSPECIFIED_GEOMETRY); | |
731 | |
732 ERROR_CHECK_IMAGE_INSTANCE (ii); | |
733 | |
734 RETURN_UNGCPRO (ii); | |
627 } | 735 } |
628 | 736 |
629 | 737 |
630 /**************************************************************************** | 738 /**************************************************************************** |
631 * Image-Instance Object * | 739 * Image-Instance Object * |
636 static Lisp_Object | 744 static Lisp_Object |
637 mark_image_instance (Lisp_Object obj) | 745 mark_image_instance (Lisp_Object obj) |
638 { | 746 { |
639 Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); | 747 Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); |
640 | 748 |
749 /* #### I want to check the instance here, but there are way too | |
750 many instances of the instance being marked while the domain is | |
751 dead. For instance you can get marked through an event when using | |
752 callback_ex.*/ | |
753 #if 0 | |
754 ERROR_CHECK_IMAGE_INSTANCE (obj); | |
755 #endif | |
756 | |
641 mark_object (i->name); | 757 mark_object (i->name); |
758 /* Is this legal in marking? We may get in the situation where the | |
759 domain has been deleted - making the instance unusable. It seems | |
760 better to remove the domain so that it can be finalized. */ | |
761 if (!DOMAIN_LIVE_P (i->domain)) | |
762 i->domain = Qnil; | |
763 else | |
764 mark_object (i->domain); | |
765 | |
642 /* We don't mark the glyph reference since that would create a | 766 /* We don't mark the glyph reference since that would create a |
643 circularity preventing GC. */ | 767 circularity preventing GC. */ |
644 switch (IMAGE_INSTANCE_TYPE (i)) | 768 switch (IMAGE_INSTANCE_TYPE (i)) |
645 { | 769 { |
646 case IMAGE_TEXT: | 770 case IMAGE_TEXT: |
655 mark_object (IMAGE_INSTANCE_PIXMAP_FG (i)); | 779 mark_object (IMAGE_INSTANCE_PIXMAP_FG (i)); |
656 mark_object (IMAGE_INSTANCE_PIXMAP_BG (i)); | 780 mark_object (IMAGE_INSTANCE_PIXMAP_BG (i)); |
657 break; | 781 break; |
658 | 782 |
659 case IMAGE_WIDGET: | 783 case IMAGE_WIDGET: |
660 case IMAGE_LAYOUT: | |
661 mark_object (IMAGE_INSTANCE_WIDGET_TYPE (i)); | 784 mark_object (IMAGE_INSTANCE_WIDGET_TYPE (i)); |
662 mark_object (IMAGE_INSTANCE_WIDGET_PROPS (i)); | 785 mark_object (IMAGE_INSTANCE_WIDGET_PROPS (i)); |
663 mark_object (IMAGE_INSTANCE_WIDGET_FACE (i)); | 786 mark_object (IMAGE_INSTANCE_WIDGET_FACE (i)); |
664 mark_object (IMAGE_INSTANCE_WIDGET_ITEMS (i)); | 787 mark_object (IMAGE_INSTANCE_WIDGET_ITEMS (i)); |
788 mark_object (IMAGE_INSTANCE_LAYOUT_CHILDREN (i)); | |
665 mark_object (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (i)); | 789 mark_object (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (i)); |
666 mark_object (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (i)); | 790 mark_object (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (i)); |
667 mark_object (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (i)); | 791 mark_object (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (i)); |
668 case IMAGE_SUBWINDOW: | 792 case IMAGE_SUBWINDOW: |
669 mark_object (IMAGE_INSTANCE_SUBWINDOW_FRAME (i)); | |
670 break; | 793 break; |
671 | 794 |
672 default: | 795 default: |
673 break; | 796 break; |
674 } | 797 } |
675 | 798 |
676 MAYBE_DEVMETH (XDEVICE (i->device), mark_image_instance, (i)); | 799 /* The image may have been previously finalized (yes that's wierd, |
800 see Fdelete_frame() and mark_window_as_deleted()), in which case | |
801 the domain will be nil, so cope with this. */ | |
802 if (!NILP (IMAGE_INSTANCE_DEVICE (i))) | |
803 MAYBE_DEVMETH (XDEVICE (IMAGE_INSTANCE_DEVICE (i)), | |
804 mark_image_instance, (i)); | |
677 | 805 |
678 return i->device; | 806 return i->device; |
679 } | 807 } |
680 | 808 |
681 static void | 809 static void |
695 { | 823 { |
696 print_internal (ii->name, printcharfun, 1); | 824 print_internal (ii->name, printcharfun, 1); |
697 write_c_string (" ", printcharfun); | 825 write_c_string (" ", printcharfun); |
698 } | 826 } |
699 write_c_string ("on ", printcharfun); | 827 write_c_string ("on ", printcharfun); |
700 print_internal (ii->device, printcharfun, 0); | 828 print_internal (ii->domain, printcharfun, 0); |
701 write_c_string (" ", printcharfun); | 829 write_c_string (" ", printcharfun); |
702 switch (IMAGE_INSTANCE_TYPE (ii)) | 830 switch (IMAGE_INSTANCE_TYPE (ii)) |
703 { | 831 { |
704 case IMAGE_NOTHING: | 832 case IMAGE_NOTHING: |
705 break; | 833 break; |
771 break; | 899 break; |
772 | 900 |
773 case IMAGE_WIDGET: | 901 case IMAGE_WIDGET: |
774 print_internal (IMAGE_INSTANCE_WIDGET_TYPE (ii), printcharfun, 0); | 902 print_internal (IMAGE_INSTANCE_WIDGET_TYPE (ii), printcharfun, 0); |
775 | 903 |
776 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii))) | 904 if (GUI_ITEMP (IMAGE_INSTANCE_WIDGET_ITEM (ii))) |
777 { | 905 { |
778 write_c_string (" ", printcharfun); | 906 write_c_string (" ", printcharfun); |
779 print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 1); | 907 print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 1); |
780 } | 908 } |
781 | 909 |
786 (IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0); | 914 (IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0); |
787 } | 915 } |
788 | 916 |
789 | 917 |
790 case IMAGE_SUBWINDOW: | 918 case IMAGE_SUBWINDOW: |
791 case IMAGE_LAYOUT: | 919 sprintf (buf, " %dx%d", IMAGE_INSTANCE_WIDTH (ii), |
792 sprintf (buf, " %dx%d", IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii), | 920 IMAGE_INSTANCE_HEIGHT (ii)); |
793 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); | |
794 write_c_string (buf, printcharfun); | 921 write_c_string (buf, printcharfun); |
795 | 922 |
796 /* This is stolen from frame.c. Subwindows are strange in that they | 923 /* This is stolen from frame.c. Subwindows are strange in that they |
797 are specific to a particular frame so we want to print in their | 924 are specific to a particular frame so we want to print in their |
798 description what that frame is. */ | 925 description what that frame is. */ |
799 | 926 |
800 write_c_string (" on #<", printcharfun); | 927 write_c_string (" on #<", printcharfun); |
801 { | 928 { |
802 struct frame* f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); | 929 struct frame* f = XFRAME (IMAGE_INSTANCE_FRAME (ii)); |
803 | 930 |
804 if (!FRAME_LIVE_P (f)) | 931 if (!FRAME_LIVE_P (f)) |
805 write_c_string ("dead", printcharfun); | 932 write_c_string ("dead", printcharfun); |
806 else | 933 else |
807 write_c_string (DEVICE_TYPE_NAME (XDEVICE (FRAME_DEVICE (f))), | 934 write_c_string (DEVICE_TYPE_NAME (XDEVICE (FRAME_DEVICE (f))), |
815 | 942 |
816 default: | 943 default: |
817 abort (); | 944 abort (); |
818 } | 945 } |
819 | 946 |
820 MAYBE_DEVMETH (XDEVICE (ii->device), print_image_instance, | 947 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), print_image_instance, |
821 (ii, printcharfun, escapeflag)); | 948 (ii, printcharfun, escapeflag)); |
822 sprintf (buf, " 0x%x>", ii->header.uid); | 949 sprintf (buf, " 0x%x>", ii->header.uid); |
823 write_c_string (buf, printcharfun); | 950 write_c_string (buf, printcharfun); |
824 } | 951 } |
825 | 952 |
826 static void | 953 static void |
827 finalize_image_instance (void *header, int for_disksave) | 954 finalize_image_instance (void *header, int for_disksave) |
828 { | 955 { |
829 Lisp_Image_Instance *i = (Lisp_Image_Instance *) header; | 956 Lisp_Image_Instance *i = (Lisp_Image_Instance *) header; |
830 | 957 |
831 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_NOTHING) | 958 /* objects like this exist at dump time, so don't bomb out. */ |
832 /* objects like this exist at dump time, so don't bomb out. */ | 959 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_NOTHING |
960 || | |
961 NILP (IMAGE_INSTANCE_DEVICE (i))) | |
833 return; | 962 return; |
834 if (for_disksave) finalose (i); | 963 if (for_disksave) finalose (i); |
835 | 964 |
836 /* do this so that the cachels get reset */ | 965 /* We can't use the domain here, because it might have |
837 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_WIDGET | 966 disappeared. */ |
838 || | 967 MAYBE_DEVMETH (XDEVICE (IMAGE_INSTANCE_DEVICE (i)), |
839 IMAGE_INSTANCE_TYPE (i) == IMAGE_SUBWINDOW | 968 finalize_image_instance, (i)); |
840 || | 969 |
841 IMAGE_INSTANCE_TYPE (i) == IMAGE_SUBWINDOW) | 970 /* Make sure we don't try this twice. */ |
842 { | 971 IMAGE_INSTANCE_DEVICE (i) = Qnil; |
843 MARK_FRAME_SUBWINDOWS_CHANGED | |
844 (XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (i))); | |
845 } | |
846 | |
847 MAYBE_DEVMETH (XDEVICE (i->device), finalize_image_instance, (i)); | |
848 } | 972 } |
849 | 973 |
850 static int | 974 static int |
851 image_instance_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) | 975 image_instance_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) |
852 { | 976 { |
853 Lisp_Image_Instance *i1 = XIMAGE_INSTANCE (obj1); | 977 Lisp_Image_Instance *i1 = XIMAGE_INSTANCE (obj1); |
854 Lisp_Image_Instance *i2 = XIMAGE_INSTANCE (obj2); | 978 Lisp_Image_Instance *i2 = XIMAGE_INSTANCE (obj2); |
855 struct device *d1 = XDEVICE (i1->device); | 979 |
856 struct device *d2 = XDEVICE (i2->device); | 980 ERROR_CHECK_IMAGE_INSTANCE (obj1); |
857 | 981 ERROR_CHECK_IMAGE_INSTANCE (obj2); |
858 if (d1 != d2) | 982 |
859 return 0; | 983 if (!EQ (IMAGE_INSTANCE_DOMAIN (i1), |
860 if (IMAGE_INSTANCE_TYPE (i1) != IMAGE_INSTANCE_TYPE (i2) | 984 IMAGE_INSTANCE_DOMAIN (i2)) |
985 || IMAGE_INSTANCE_TYPE (i1) != IMAGE_INSTANCE_TYPE (i2) | |
861 || IMAGE_INSTANCE_WIDTH (i1) != IMAGE_INSTANCE_WIDTH (i2) | 986 || IMAGE_INSTANCE_WIDTH (i1) != IMAGE_INSTANCE_WIDTH (i2) |
987 || IMAGE_INSTANCE_MARGIN_WIDTH (i1) != | |
988 IMAGE_INSTANCE_MARGIN_WIDTH (i2) | |
862 || IMAGE_INSTANCE_HEIGHT (i1) != IMAGE_INSTANCE_HEIGHT (i2) | 989 || IMAGE_INSTANCE_HEIGHT (i1) != IMAGE_INSTANCE_HEIGHT (i2) |
863 || IMAGE_INSTANCE_XOFFSET (i1) != IMAGE_INSTANCE_XOFFSET (i2) | 990 || IMAGE_INSTANCE_XOFFSET (i1) != IMAGE_INSTANCE_XOFFSET (i2) |
864 || IMAGE_INSTANCE_YOFFSET (i1) != IMAGE_INSTANCE_YOFFSET (i2)) | 991 || IMAGE_INSTANCE_YOFFSET (i1) != IMAGE_INSTANCE_YOFFSET (i2)) |
865 return 0; | 992 return 0; |
866 if (!internal_equal (IMAGE_INSTANCE_NAME (i1), IMAGE_INSTANCE_NAME (i2), | 993 if (!internal_equal (IMAGE_INSTANCE_NAME (i1), IMAGE_INSTANCE_NAME (i2), |
898 depth + 1))) | 1025 depth + 1))) |
899 return 0; | 1026 return 0; |
900 break; | 1027 break; |
901 | 1028 |
902 case IMAGE_WIDGET: | 1029 case IMAGE_WIDGET: |
903 case IMAGE_LAYOUT: | |
904 if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1), | 1030 if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1), |
905 IMAGE_INSTANCE_WIDGET_TYPE (i2)) | 1031 IMAGE_INSTANCE_WIDGET_TYPE (i2)) |
906 && IMAGE_INSTANCE_SUBWINDOW_ID (i1) == | 1032 && IMAGE_INSTANCE_SUBWINDOW_ID (i1) == |
907 IMAGE_INSTANCE_SUBWINDOW_ID (i2) | 1033 IMAGE_INSTANCE_SUBWINDOW_ID (i2) |
908 && | 1034 && |
909 EQ (IMAGE_INSTANCE_WIDGET_FACE (i1), | 1035 EQ (IMAGE_INSTANCE_WIDGET_FACE (i1), |
910 IMAGE_INSTANCE_WIDGET_TYPE (i2)) | 1036 IMAGE_INSTANCE_WIDGET_TYPE (i2)) |
911 && internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (i1), | 1037 && internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (i1), |
912 IMAGE_INSTANCE_WIDGET_ITEMS (i2), | 1038 IMAGE_INSTANCE_WIDGET_ITEMS (i2), |
1039 depth + 1) | |
1040 && internal_equal (IMAGE_INSTANCE_LAYOUT_CHILDREN (i1), | |
1041 IMAGE_INSTANCE_LAYOUT_CHILDREN (i2), | |
913 depth + 1) | 1042 depth + 1) |
914 && internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1), | 1043 && internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1), |
915 IMAGE_INSTANCE_WIDGET_PROPS (i2), | 1044 IMAGE_INSTANCE_WIDGET_PROPS (i2), |
916 depth + 1) | 1045 depth + 1) |
917 && internal_equal (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (i1), | 1046 && internal_equal (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (i1), |
932 | 1061 |
933 default: | 1062 default: |
934 abort (); | 1063 abort (); |
935 } | 1064 } |
936 | 1065 |
937 return DEVMETH_OR_GIVEN (d1, image_instance_equal, (i1, i2, depth), 1); | 1066 return DEVMETH_OR_GIVEN (DOMAIN_XDEVICE (i1->domain), |
938 } | 1067 image_instance_equal, (i1, i2, depth), 1); |
939 | 1068 } |
940 #if 0 | 1069 |
941 /* internal_hash will not go very far down a list because of the way | 1070 /* Image instance domain manipulators. We can't error check in these |
942 its written. For items we need to hash all elements so we provide | 1071 otherwise we get into infinite recursion. */ |
943 our own list hashing function. */ | 1072 Lisp_Object |
944 static unsigned long | 1073 image_instance_device (Lisp_Object instance) |
945 full_list_hash (Lisp_Object obj, int depth) | 1074 { |
946 { | 1075 return XIMAGE_INSTANCE_DEVICE (instance); |
947 unsigned long hash = 0; | 1076 } |
948 Lisp_Object rest; | 1077 |
949 | 1078 Lisp_Object |
950 if (!CONSP (obj)) | 1079 image_instance_frame (Lisp_Object instance) |
951 return internal_hash (obj, depth + 1); | 1080 { |
952 | 1081 return XIMAGE_INSTANCE_FRAME (instance); |
953 hash = LISP_HASH (XCAR (obj)); | 1082 } |
954 LIST_LOOP (rest, XCDR (obj)) | 1083 |
955 { | 1084 Lisp_Object |
956 hash = HASH2 (hash, internal_hash (XCAR (rest), depth + 1)); | 1085 image_instance_window (Lisp_Object instance) |
957 } | 1086 { |
958 return hash; | 1087 return DOMAIN_WINDOW (XIMAGE_INSTANCE_DOMAIN (instance)); |
959 } | 1088 } |
960 #endif | 1089 |
1090 int | |
1091 image_instance_live_p (Lisp_Object instance) | |
1092 { | |
1093 return DOMAIN_LIVE_P (XIMAGE_INSTANCE_DOMAIN (instance)); | |
1094 } | |
961 | 1095 |
962 static unsigned long | 1096 static unsigned long |
963 image_instance_hash (Lisp_Object obj, int depth) | 1097 image_instance_hash (Lisp_Object obj, int depth) |
964 { | 1098 { |
965 Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); | 1099 Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); |
966 struct device *d = XDEVICE (i->device); | 1100 unsigned long hash = HASH4 (LISP_HASH (IMAGE_INSTANCE_DOMAIN (i)), |
967 unsigned long hash = HASH3 ((unsigned long) d, | |
968 IMAGE_INSTANCE_WIDTH (i), | 1101 IMAGE_INSTANCE_WIDTH (i), |
1102 IMAGE_INSTANCE_MARGIN_WIDTH (i), | |
969 IMAGE_INSTANCE_HEIGHT (i)); | 1103 IMAGE_INSTANCE_HEIGHT (i)); |
1104 | |
1105 ERROR_CHECK_IMAGE_INSTANCE (obj); | |
970 | 1106 |
971 switch (IMAGE_INSTANCE_TYPE (i)) | 1107 switch (IMAGE_INSTANCE_TYPE (i)) |
972 { | 1108 { |
973 case IMAGE_NOTHING: | 1109 case IMAGE_NOTHING: |
974 break; | 1110 break; |
986 internal_hash (IMAGE_INSTANCE_PIXMAP_FILENAME (i), | 1122 internal_hash (IMAGE_INSTANCE_PIXMAP_FILENAME (i), |
987 depth + 1)); | 1123 depth + 1)); |
988 break; | 1124 break; |
989 | 1125 |
990 case IMAGE_WIDGET: | 1126 case IMAGE_WIDGET: |
991 case IMAGE_LAYOUT: | |
992 /* We need the hash to be equivalent to what should be | 1127 /* We need the hash to be equivalent to what should be |
993 displayed. */ | 1128 displayed. */ |
994 hash = HASH4 (hash, | 1129 hash = HASH5 (hash, |
995 LISP_HASH (IMAGE_INSTANCE_WIDGET_TYPE (i)), | 1130 LISP_HASH (IMAGE_INSTANCE_WIDGET_TYPE (i)), |
996 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1), | 1131 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1), |
997 internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1)); | 1132 internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1), |
1133 internal_hash (IMAGE_INSTANCE_LAYOUT_CHILDREN (i), | |
1134 depth + 1)); | |
998 case IMAGE_SUBWINDOW: | 1135 case IMAGE_SUBWINDOW: |
999 hash = HASH2 (hash, (int) IMAGE_INSTANCE_SUBWINDOW_ID (i)); | 1136 hash = HASH2 (hash, (int) IMAGE_INSTANCE_SUBWINDOW_ID (i)); |
1000 break; | 1137 break; |
1001 | 1138 |
1002 default: | 1139 default: |
1003 abort (); | 1140 abort (); |
1004 } | 1141 } |
1005 | 1142 |
1006 return HASH2 (hash, DEVMETH_OR_GIVEN (d, image_instance_hash, (i, depth), | 1143 return HASH2 (hash, DEVMETH_OR_GIVEN |
1007 0)); | 1144 (XDEVICE (image_instance_device (obj)), |
1145 image_instance_hash, (i, depth), | |
1146 0)); | |
1008 } | 1147 } |
1009 | 1148 |
1010 DEFINE_LRECORD_IMPLEMENTATION ("image-instance", image_instance, | 1149 DEFINE_LRECORD_IMPLEMENTATION ("image-instance", image_instance, |
1011 mark_image_instance, print_image_instance, | 1150 mark_image_instance, print_image_instance, |
1012 finalize_image_instance, image_instance_equal, | 1151 finalize_image_instance, image_instance_equal, |
1013 image_instance_hash, 0, | 1152 image_instance_hash, 0, |
1014 Lisp_Image_Instance); | 1153 Lisp_Image_Instance); |
1015 | 1154 |
1016 static Lisp_Object | 1155 static Lisp_Object |
1017 allocate_image_instance (Lisp_Object device, Lisp_Object glyph) | 1156 allocate_image_instance (Lisp_Object governing_domain, Lisp_Object glyph) |
1018 { | 1157 { |
1019 Lisp_Image_Instance *lp = | 1158 Lisp_Image_Instance *lp = |
1020 alloc_lcrecord_type (Lisp_Image_Instance, &lrecord_image_instance); | 1159 alloc_lcrecord_type (Lisp_Image_Instance, &lrecord_image_instance); |
1021 Lisp_Object val; | 1160 Lisp_Object val; |
1022 | 1161 |
1023 zero_lcrecord (lp); | 1162 zero_lcrecord (lp); |
1024 lp->device = device; | 1163 /* It's not possible to simply keep a record of the domain in which |
1164 the instance was instantiated. This is because caching may mean | |
1165 that the domain becomes invalid but the instance remains | |
1166 valid. However, the only truly relevant domain is the domain in | |
1167 which the instance is cached since this is the one that will be | |
1168 common to the instances. */ | |
1169 lp->domain = governing_domain; | |
1170 /* The cache domain is not quite sufficient since the domain can get | |
1171 deleted before the image instance does. We need to know the | |
1172 domain device in order to finalize the image instance | |
1173 properly. We therefore record the device also. */ | |
1174 lp->device = DOMAIN_DEVICE (governing_domain); | |
1025 lp->type = IMAGE_NOTHING; | 1175 lp->type = IMAGE_NOTHING; |
1026 lp->name = Qnil; | 1176 lp->name = Qnil; |
1027 lp->x_offset = 0; | 1177 lp->x_offset = 0; |
1028 lp->y_offset = 0; | 1178 lp->y_offset = 0; |
1029 lp->width = 0; | 1179 lp->width = IMAGE_UNSPECIFIED_GEOMETRY; |
1030 lp->height = 0; | 1180 lp->margin_width = 0; |
1181 lp->height = IMAGE_UNSPECIFIED_GEOMETRY; | |
1031 lp->parent = glyph; | 1182 lp->parent = glyph; |
1032 /* So that layouts get done. */ | 1183 /* So that layouts get done. */ |
1033 lp->layout_changed = 1; | 1184 lp->layout_changed = 1; |
1185 lp->initialized = 0; | |
1034 | 1186 |
1035 XSETIMAGE_INSTANCE (val, lp); | 1187 XSETIMAGE_INSTANCE (val, lp); |
1036 MARK_GLYPHS_CHANGED; | 1188 MARK_GLYPHS_CHANGED; |
1037 | 1189 |
1038 return val; | 1190 return val; |
1049 if (EQ (type, Qmono_pixmap)) return IMAGE_MONO_PIXMAP; | 1201 if (EQ (type, Qmono_pixmap)) return IMAGE_MONO_PIXMAP; |
1050 if (EQ (type, Qcolor_pixmap)) return IMAGE_COLOR_PIXMAP; | 1202 if (EQ (type, Qcolor_pixmap)) return IMAGE_COLOR_PIXMAP; |
1051 if (EQ (type, Qpointer)) return IMAGE_POINTER; | 1203 if (EQ (type, Qpointer)) return IMAGE_POINTER; |
1052 if (EQ (type, Qsubwindow)) return IMAGE_SUBWINDOW; | 1204 if (EQ (type, Qsubwindow)) return IMAGE_SUBWINDOW; |
1053 if (EQ (type, Qwidget)) return IMAGE_WIDGET; | 1205 if (EQ (type, Qwidget)) return IMAGE_WIDGET; |
1054 if (EQ (type, Qlayout)) return IMAGE_LAYOUT; | |
1055 | 1206 |
1056 maybe_signal_simple_error ("Invalid image-instance type", type, | 1207 maybe_signal_simple_error ("Invalid image-instance type", type, |
1057 Qimage, errb); | 1208 Qimage, errb); |
1058 | 1209 |
1059 return IMAGE_UNKNOWN; /* not reached */ | 1210 return IMAGE_UNKNOWN; /* not reached */ |
1069 case IMAGE_MONO_PIXMAP: return Qmono_pixmap; | 1220 case IMAGE_MONO_PIXMAP: return Qmono_pixmap; |
1070 case IMAGE_COLOR_PIXMAP: return Qcolor_pixmap; | 1221 case IMAGE_COLOR_PIXMAP: return Qcolor_pixmap; |
1071 case IMAGE_POINTER: return Qpointer; | 1222 case IMAGE_POINTER: return Qpointer; |
1072 case IMAGE_SUBWINDOW: return Qsubwindow; | 1223 case IMAGE_SUBWINDOW: return Qsubwindow; |
1073 case IMAGE_WIDGET: return Qwidget; | 1224 case IMAGE_WIDGET: return Qwidget; |
1074 case IMAGE_LAYOUT: return Qlayout; | |
1075 default: | 1225 default: |
1076 abort (); | 1226 abort (); |
1077 } | 1227 } |
1078 | 1228 |
1079 return Qnil; /* not reached */ | 1229 return Qnil; /* not reached */ |
1080 } | |
1081 | |
1082 static int | |
1083 image_instance_type_to_mask (enum image_instance_type type) | |
1084 { | |
1085 /* This depends on the fact that enums are assigned consecutive | |
1086 integers starting at 0. (Remember that IMAGE_UNKNOWN is the | |
1087 first enum.) I'm fairly sure this behavior is ANSI-mandated, | |
1088 so there should be no portability problems here. */ | |
1089 return (1 << ((int) (type) - 1)); | |
1090 } | 1230 } |
1091 | 1231 |
1092 static int | 1232 static int |
1093 decode_image_instance_type_list (Lisp_Object list) | 1233 decode_image_instance_type_list (Lisp_Object list) |
1094 { | 1234 { |
1156 } | 1296 } |
1157 | 1297 |
1158 DEFUN ("valid-image-instance-type-p", Fvalid_image_instance_type_p, 1, 1, 0, /* | 1298 DEFUN ("valid-image-instance-type-p", Fvalid_image_instance_type_p, 1, 1, 0, /* |
1159 Given an IMAGE-INSTANCE-TYPE, return non-nil if it is valid. | 1299 Given an IMAGE-INSTANCE-TYPE, return non-nil if it is valid. |
1160 Valid types are some subset of 'nothing, 'text, 'mono-pixmap, 'color-pixmap, | 1300 Valid types are some subset of 'nothing, 'text, 'mono-pixmap, 'color-pixmap, |
1161 'pointer, and 'subwindow, depending on how XEmacs was compiled. | 1301 'pointer, 'subwindow, and 'widget, depending on how XEmacs was compiled. |
1162 */ | 1302 */ |
1163 (image_instance_type)) | 1303 (image_instance_type)) |
1164 { | 1304 { |
1165 return valid_image_instance_type_p (image_instance_type) ? Qt : Qnil; | 1305 return valid_image_instance_type_p (image_instance_type) ? Qt : Qnil; |
1166 } | 1306 } |
1207 } | 1347 } |
1208 return IMAGE_INSTANCE_PARENT (ii); | 1348 return IMAGE_INSTANCE_PARENT (ii); |
1209 } | 1349 } |
1210 | 1350 |
1211 static Lisp_Object | 1351 static Lisp_Object |
1212 make_image_instance_1 (Lisp_Object data, Lisp_Object device, | 1352 make_image_instance_1 (Lisp_Object data, Lisp_Object domain, |
1213 Lisp_Object dest_types) | 1353 Lisp_Object dest_types) |
1214 { | 1354 { |
1215 Lisp_Object ii; | 1355 Lisp_Object ii; |
1216 struct gcpro gcpro1; | 1356 struct gcpro gcpro1; |
1217 int dest_mask; | 1357 int dest_mask; |
1218 | 1358 Lisp_Object governing_domain; |
1219 XSETDEVICE (device, decode_device (device)); | 1359 |
1220 /* instantiate_image_instantiator() will abort if given an | |
1221 image instance ... */ | |
1222 if (IMAGE_INSTANCEP (data)) | 1360 if (IMAGE_INSTANCEP (data)) |
1223 signal_simple_error ("Image instances not allowed here", data); | 1361 signal_simple_error ("Image instances not allowed here", data); |
1224 image_validate (data); | 1362 image_validate (data); |
1363 domain = decode_domain (domain); | |
1364 /* instantiate_image_instantiator() will abort if given an | |
1365 image instance ... */ | |
1225 dest_mask = decode_image_instance_type_list (dest_types); | 1366 dest_mask = decode_image_instance_type_list (dest_types); |
1226 data = normalize_image_instantiator (data, DEVICE_TYPE (XDEVICE (device)), | 1367 data = normalize_image_instantiator (data, |
1368 DEVICE_TYPE (DOMAIN_XDEVICE (domain)), | |
1227 make_int (dest_mask)); | 1369 make_int (dest_mask)); |
1228 GCPRO1 (data); | 1370 GCPRO1 (data); |
1229 if (VECTORP (data) && EQ (XVECTOR_DATA (data)[0], Qinherit)) | 1371 /* After normalizing the data, it's always either an image instance (which |
1372 we filtered out above) or a vector. */ | |
1373 if (EQ (XVECTOR_DATA (data)[0], Qinherit)) | |
1230 signal_simple_error ("Inheritance not allowed here", data); | 1374 signal_simple_error ("Inheritance not allowed here", data); |
1231 ii = instantiate_image_instantiator (device, device, data, | 1375 governing_domain = |
1376 get_image_instantiator_governing_domain (data, domain); | |
1377 ii = instantiate_image_instantiator (governing_domain, domain, data, | |
1232 Qnil, Qnil, dest_mask, Qnil); | 1378 Qnil, Qnil, dest_mask, Qnil); |
1233 RETURN_UNGCPRO (ii); | 1379 RETURN_UNGCPRO (ii); |
1234 } | 1380 } |
1235 | 1381 |
1236 DEFUN ("make-image-instance", Fmake_image_instance, 1, 4, 0, /* | 1382 DEFUN ("make-image-instance", Fmake_image_instance, 1, 4, 0, /* |
1241 do not need to directly create image instances; use a glyph instead. | 1387 do not need to directly create image instances; use a glyph instead. |
1242 However, it may occasionally be useful to explicitly create image | 1388 However, it may occasionally be useful to explicitly create image |
1243 instances, if you want more control over the instantiation process. | 1389 instances, if you want more control over the instantiation process. |
1244 | 1390 |
1245 DATA is an image instantiator, which describes the image; see | 1391 DATA is an image instantiator, which describes the image; see |
1246 `image-specifier-p' for a description of the allowed values. | 1392 `make-image-specifier' for a description of the allowed values. |
1247 | 1393 |
1248 DEST-TYPES should be a list of allowed image instance types that can | 1394 DEST-TYPES should be a list of allowed image instance types that can |
1249 be generated. The recognized image instance types are | 1395 be generated. The recognized image instance types are |
1250 | 1396 |
1251 'nothing | 1397 'nothing |
1268 'subwindow | 1414 'subwindow |
1269 A child window that is treated as an image. This allows (e.g.) | 1415 A child window that is treated as an image. This allows (e.g.) |
1270 another program to be responsible for drawing into the window. | 1416 another program to be responsible for drawing into the window. |
1271 'widget | 1417 'widget |
1272 A child window that contains a window-system widget, e.g. a push | 1418 A child window that contains a window-system widget, e.g. a push |
1273 button. | 1419 button, text field, or slider. |
1274 | 1420 |
1275 The DEST-TYPES list is unordered. If multiple destination types | 1421 The DEST-TYPES list is unordered. If multiple destination types are |
1276 are possible for a given instantiator, the "most natural" type | 1422 possible for a given instantiator, the "most natural" type for the |
1277 for the instantiator's format is chosen. (For XBM, the most natural | 1423 instantiator's format is chosen. (For XBM, the most natural types are |
1278 types are `mono-pixmap', followed by `color-pixmap', followed by | 1424 `mono-pixmap', followed by `color-pixmap', followed by `pointer'. For |
1279 `pointer'. For the other normal image formats, the most natural | 1425 the other normal image formats, the most natural types are |
1280 types are `color-pixmap', followed by `mono-pixmap', followed by | 1426 `color-pixmap', followed by `mono-pixmap', followed by `pointer'. For |
1281 `pointer'. For the string and formatted-string formats, the most | 1427 the string and formatted-string formats, the most natural types are |
1282 natural types are `text', followed by `mono-pixmap' (not currently | 1428 `text', followed by `mono-pixmap' (not currently implemented), |
1283 implemented), followed by `color-pixmap' (not currently implemented). | 1429 followed by `color-pixmap' (not currently implemented). For MS |
1284 The other formats can only be instantiated as one type. (If you | 1430 Windows resources, the most natural type for pointer resources is |
1285 want to control more specifically the order of the types into which | 1431 `pointer', and for the others it's `color-pixmap'. The other formats |
1286 an image is instantiated, just call `make-image-instance' repeatedly | 1432 can only be instantiated as one type. (If you want to control more |
1287 until it succeeds, passing less and less preferred destination types | 1433 specifically the order of the types into which an image is |
1288 each time. | 1434 instantiated, just call `make-image-instance' repeatedly until it |
1435 succeeds, passing less and less preferred destination types each | |
1436 time.) | |
1437 | |
1438 See `make-image-specifier' for a description of the different image | |
1439 instantiator formats. | |
1289 | 1440 |
1290 If DEST-TYPES is omitted, all possible types are allowed. | 1441 If DEST-TYPES is omitted, all possible types are allowed. |
1442 | |
1443 DOMAIN specifies the domain to which the image instance will be attached. | |
1444 This domain is termed the \"governing domain\". The type of the governing | |
1445 domain depends on the image instantiator format. (Although, more correctly, | |
1446 it should probably depend on the image instance type.) For example, pixmap | |
1447 image instances are specific to a device, but widget image instances are | |
1448 specific to a particular XEmacs window because in order to display such a | |
1449 widget when two windows onto the same buffer want to display the widget, | |
1450 two separate underlying widgets must be created. (That's because a widget | |
1451 is actually a child window-system window, and all window-system windows have | |
1452 a unique existence on the screen.) This means that the governing domain for | |
1453 a pixmap image instance will be some device (most likely, the only existing | |
1454 device), whereas the governing domain for a widget image instance will be | |
1455 some XEmacs window. | |
1456 | |
1457 If you specify an overly general DOMAIN (e.g. a frame when a window was | |
1458 wanted), an error is signaled. If you specify an overly specific DOMAIN | |
1459 \(e.g. a window when a device was wanted), the corresponding general domain | |
1460 is fetched and used instead. For `make-image-instance', it makes no | |
1461 difference whether you specify an overly specific domain or the properly | |
1462 general domain derived from it. However, it does matter when creating an | |
1463 image instance by instantiating a specifier or glyph (e.g. with | |
1464 `glyph-image-instance'), because the more specific domain causes spec lookup | |
1465 to start there and proceed to more general domains. (It would also matter | |
1466 when creating an image instance with an instantiator format of `inherit', | |
1467 but we currently disallow this. #### We should fix this.) | |
1468 | |
1469 If omitted, DOMAIN defaults to the selected window. | |
1291 | 1470 |
1292 NO-ERROR controls what happens when the image cannot be generated. | 1471 NO-ERROR controls what happens when the image cannot be generated. |
1293 If nil, an error message is generated. If t, no messages are | 1472 If nil, an error message is generated. If t, no messages are |
1294 generated and this function returns nil. If anything else, a warning | 1473 generated and this function returns nil. If anything else, a warning |
1295 message is generated and this function returns nil. | 1474 message is generated and this function returns nil. |
1296 */ | 1475 */ |
1297 (data, device, dest_types, no_error)) | 1476 (data, domain, dest_types, no_error)) |
1298 { | 1477 { |
1299 Error_behavior errb = decode_error_behavior_flag (no_error); | 1478 Error_behavior errb = decode_error_behavior_flag (no_error); |
1300 | 1479 |
1301 return call_with_suspended_errors ((lisp_fn_t) make_image_instance_1, | 1480 return call_with_suspended_errors ((lisp_fn_t) make_image_instance_1, |
1302 Qnil, Qimage, errb, | 1481 Qnil, Qimage, errb, |
1303 3, data, device, dest_types); | 1482 3, data, domain, dest_types); |
1304 } | 1483 } |
1305 | 1484 |
1306 DEFUN ("image-instance-p", Fimage_instance_p, 1, 1, 0, /* | 1485 DEFUN ("image-instance-p", Fimage_instance_p, 1, 1, 0, /* |
1307 Return non-nil if OBJECT is an image instance. | 1486 Return non-nil if OBJECT is an image instance. |
1308 */ | 1487 */ |
1317 'color-pixmap, 'pointer, or 'subwindow. | 1496 'color-pixmap, 'pointer, or 'subwindow. |
1318 */ | 1497 */ |
1319 (image_instance)) | 1498 (image_instance)) |
1320 { | 1499 { |
1321 CHECK_IMAGE_INSTANCE (image_instance); | 1500 CHECK_IMAGE_INSTANCE (image_instance); |
1501 ERROR_CHECK_IMAGE_INSTANCE (image_instance); | |
1322 return encode_image_instance_type (XIMAGE_INSTANCE_TYPE (image_instance)); | 1502 return encode_image_instance_type (XIMAGE_INSTANCE_TYPE (image_instance)); |
1323 } | 1503 } |
1324 | 1504 |
1325 DEFUN ("image-instance-name", Fimage_instance_name, 1, 1, 0, /* | 1505 DEFUN ("image-instance-name", Fimage_instance_name, 1, 1, 0, /* |
1326 Return the name of the given image instance. | 1506 Return the name of the given image instance. |
1327 */ | 1507 */ |
1328 (image_instance)) | 1508 (image_instance)) |
1329 { | 1509 { |
1330 CHECK_IMAGE_INSTANCE (image_instance); | 1510 CHECK_IMAGE_INSTANCE (image_instance); |
1331 return XIMAGE_INSTANCE_NAME (image_instance); | 1511 return XIMAGE_INSTANCE_NAME (image_instance); |
1512 } | |
1513 | |
1514 DEFUN ("image-instance-domain", Fimage_instance_domain, 1, 1, 0, /* | |
1515 Return the governing domain of the given image instance. | |
1516 The governing domain of an image instance is the domain that the image | |
1517 instance is specific to. It is NOT necessarily the domain that was | |
1518 given to the call to `specifier-instance' that resulted in the creation | |
1519 of this image instance. See `make-image-instance' for more information | |
1520 on governing domains. | |
1521 */ | |
1522 (image_instance)) | |
1523 { | |
1524 CHECK_IMAGE_INSTANCE (image_instance); | |
1525 return XIMAGE_INSTANCE_DOMAIN (image_instance); | |
1332 } | 1526 } |
1333 | 1527 |
1334 DEFUN ("image-instance-string", Fimage_instance_string, 1, 1, 0, /* | 1528 DEFUN ("image-instance-string", Fimage_instance_string, 1, 1, 0, /* |
1335 Return the string of the given image instance. | 1529 Return the string of the given image instance. |
1336 This will only be non-nil for text image instances and widgets. | 1530 This will only be non-nil for text image instances and widgets. |
1356 Lisp_Image_Instance* ii; | 1550 Lisp_Image_Instance* ii; |
1357 Lisp_Object type, ret; | 1551 Lisp_Object type, ret; |
1358 struct image_instantiator_methods* meths; | 1552 struct image_instantiator_methods* meths; |
1359 | 1553 |
1360 CHECK_IMAGE_INSTANCE (image_instance); | 1554 CHECK_IMAGE_INSTANCE (image_instance); |
1555 ERROR_CHECK_IMAGE_INSTANCE (image_instance); | |
1361 CHECK_SYMBOL (prop); | 1556 CHECK_SYMBOL (prop); |
1362 ii = XIMAGE_INSTANCE (image_instance); | 1557 ii = XIMAGE_INSTANCE (image_instance); |
1363 | 1558 |
1364 /* ... then try device specific methods ... */ | 1559 /* ... then try device specific methods ... */ |
1365 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); | 1560 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); |
1366 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), | 1561 meths = decode_device_ii_format (image_instance_device (image_instance), |
1367 type, ERROR_ME_NOT); | 1562 type, ERROR_ME_NOT); |
1368 if (meths && HAS_IIFORMAT_METH_P (meths, property) | 1563 if (meths && HAS_IIFORMAT_METH_P (meths, property) |
1369 && | 1564 && |
1370 !UNBOUNDP (ret = IIFORMAT_METH (meths, property, (image_instance, prop)))) | 1565 !UNBOUNDP (ret = IIFORMAT_METH (meths, property, (image_instance, prop)))) |
1371 { | 1566 { |
1385 | 1580 |
1386 DEFUN ("set-image-instance-property", Fset_image_instance_property, 3, 3, 0, /* | 1581 DEFUN ("set-image-instance-property", Fset_image_instance_property, 3, 3, 0, /* |
1387 Set the given property of the given image instance. | 1582 Set the given property of the given image instance. |
1388 Does nothing if the property or the property method do not exist for | 1583 Does nothing if the property or the property method do not exist for |
1389 the image instance in the domain. | 1584 the image instance in the domain. |
1390 */ | 1585 |
1586 WARNING: If you are thinking about using this function, think again. | |
1587 You probably want to be using `set-glyph-image' to change the glyph's | |
1588 specifier. Be especially wary if you are thinking of calling this | |
1589 function after having called `glyph-image-instance'. Unless you are | |
1590 absolutely sure what you're doing, pretty much the only legitimate | |
1591 uses for this function are setting user-specified info in a widget, | |
1592 such as text in a text field. */ | |
1391 (image_instance, prop, val)) | 1593 (image_instance, prop, val)) |
1392 { | 1594 { |
1393 Lisp_Image_Instance* ii; | 1595 Lisp_Image_Instance* ii; |
1394 Lisp_Object type, ret; | 1596 Lisp_Object type, ret; |
1395 struct image_instantiator_methods* meths; | 1597 struct image_instantiator_methods* meths; |
1396 | 1598 |
1397 CHECK_IMAGE_INSTANCE (image_instance); | 1599 CHECK_IMAGE_INSTANCE (image_instance); |
1600 ERROR_CHECK_IMAGE_INSTANCE (image_instance); | |
1398 CHECK_SYMBOL (prop); | 1601 CHECK_SYMBOL (prop); |
1399 ii = XIMAGE_INSTANCE (image_instance); | 1602 ii = XIMAGE_INSTANCE (image_instance); |
1400 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); | 1603 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); |
1401 /* try device specific methods first ... */ | 1604 /* try device specific methods first ... */ |
1402 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), | 1605 meths = decode_device_ii_format (image_instance_device (image_instance), |
1403 type, ERROR_ME_NOT); | 1606 type, ERROR_ME_NOT); |
1404 if (meths && HAS_IIFORMAT_METH_P (meths, set_property) | 1607 if (meths && HAS_IIFORMAT_METH_P (meths, set_property) |
1405 && | 1608 && |
1406 !UNBOUNDP (ret = | 1609 !UNBOUNDP (ret = |
1407 IIFORMAT_METH (meths, set_property, (image_instance, prop, val)))) | 1610 IIFORMAT_METH (meths, set_property, (image_instance, prop, val)))) |
1440 Return the file name from which IMAGE-INSTANCE was read, if known. | 1643 Return the file name from which IMAGE-INSTANCE was read, if known. |
1441 */ | 1644 */ |
1442 (image_instance)) | 1645 (image_instance)) |
1443 { | 1646 { |
1444 CHECK_IMAGE_INSTANCE (image_instance); | 1647 CHECK_IMAGE_INSTANCE (image_instance); |
1648 ERROR_CHECK_IMAGE_INSTANCE (image_instance); | |
1445 | 1649 |
1446 switch (XIMAGE_INSTANCE_TYPE (image_instance)) | 1650 switch (XIMAGE_INSTANCE_TYPE (image_instance)) |
1447 { | 1651 { |
1448 case IMAGE_MONO_PIXMAP: | 1652 case IMAGE_MONO_PIXMAP: |
1449 case IMAGE_COLOR_PIXMAP: | 1653 case IMAGE_COLOR_PIXMAP: |
1459 Return the file name from which IMAGE-INSTANCE's mask was read, if known. | 1663 Return the file name from which IMAGE-INSTANCE's mask was read, if known. |
1460 */ | 1664 */ |
1461 (image_instance)) | 1665 (image_instance)) |
1462 { | 1666 { |
1463 CHECK_IMAGE_INSTANCE (image_instance); | 1667 CHECK_IMAGE_INSTANCE (image_instance); |
1668 ERROR_CHECK_IMAGE_INSTANCE (image_instance); | |
1464 | 1669 |
1465 switch (XIMAGE_INSTANCE_TYPE (image_instance)) | 1670 switch (XIMAGE_INSTANCE_TYPE (image_instance)) |
1466 { | 1671 { |
1467 case IMAGE_MONO_PIXMAP: | 1672 case IMAGE_MONO_PIXMAP: |
1468 case IMAGE_COLOR_PIXMAP: | 1673 case IMAGE_COLOR_PIXMAP: |
1479 This is 0 for a bitmap, or a positive integer for a pixmap. | 1684 This is 0 for a bitmap, or a positive integer for a pixmap. |
1480 */ | 1685 */ |
1481 (image_instance)) | 1686 (image_instance)) |
1482 { | 1687 { |
1483 CHECK_IMAGE_INSTANCE (image_instance); | 1688 CHECK_IMAGE_INSTANCE (image_instance); |
1689 ERROR_CHECK_IMAGE_INSTANCE (image_instance); | |
1484 | 1690 |
1485 switch (XIMAGE_INSTANCE_TYPE (image_instance)) | 1691 switch (XIMAGE_INSTANCE_TYPE (image_instance)) |
1486 { | 1692 { |
1487 case IMAGE_MONO_PIXMAP: | 1693 case IMAGE_MONO_PIXMAP: |
1488 case IMAGE_COLOR_PIXMAP: | 1694 case IMAGE_COLOR_PIXMAP: |
1498 Return the height of the image instance, in pixels. | 1704 Return the height of the image instance, in pixels. |
1499 */ | 1705 */ |
1500 (image_instance)) | 1706 (image_instance)) |
1501 { | 1707 { |
1502 CHECK_IMAGE_INSTANCE (image_instance); | 1708 CHECK_IMAGE_INSTANCE (image_instance); |
1709 ERROR_CHECK_IMAGE_INSTANCE (image_instance); | |
1503 | 1710 |
1504 switch (XIMAGE_INSTANCE_TYPE (image_instance)) | 1711 switch (XIMAGE_INSTANCE_TYPE (image_instance)) |
1505 { | 1712 { |
1506 case IMAGE_MONO_PIXMAP: | 1713 case IMAGE_MONO_PIXMAP: |
1507 case IMAGE_COLOR_PIXMAP: | 1714 case IMAGE_COLOR_PIXMAP: |
1508 case IMAGE_POINTER: | 1715 case IMAGE_POINTER: |
1509 case IMAGE_SUBWINDOW: | 1716 case IMAGE_SUBWINDOW: |
1510 case IMAGE_WIDGET: | 1717 case IMAGE_WIDGET: |
1511 case IMAGE_LAYOUT: | |
1512 return make_int (XIMAGE_INSTANCE_HEIGHT (image_instance)); | 1718 return make_int (XIMAGE_INSTANCE_HEIGHT (image_instance)); |
1513 | 1719 |
1514 default: | 1720 default: |
1515 return Qnil; | 1721 return Qnil; |
1516 } | 1722 } |
1520 Return the width of the image instance, in pixels. | 1726 Return the width of the image instance, in pixels. |
1521 */ | 1727 */ |
1522 (image_instance)) | 1728 (image_instance)) |
1523 { | 1729 { |
1524 CHECK_IMAGE_INSTANCE (image_instance); | 1730 CHECK_IMAGE_INSTANCE (image_instance); |
1731 ERROR_CHECK_IMAGE_INSTANCE (image_instance); | |
1525 | 1732 |
1526 switch (XIMAGE_INSTANCE_TYPE (image_instance)) | 1733 switch (XIMAGE_INSTANCE_TYPE (image_instance)) |
1527 { | 1734 { |
1528 case IMAGE_MONO_PIXMAP: | 1735 case IMAGE_MONO_PIXMAP: |
1529 case IMAGE_COLOR_PIXMAP: | 1736 case IMAGE_COLOR_PIXMAP: |
1530 case IMAGE_POINTER: | 1737 case IMAGE_POINTER: |
1531 case IMAGE_SUBWINDOW: | 1738 case IMAGE_SUBWINDOW: |
1532 case IMAGE_WIDGET: | 1739 case IMAGE_WIDGET: |
1533 case IMAGE_LAYOUT: | |
1534 return make_int (XIMAGE_INSTANCE_WIDTH (image_instance)); | 1740 return make_int (XIMAGE_INSTANCE_WIDTH (image_instance)); |
1535 | 1741 |
1536 default: | 1742 default: |
1537 return Qnil; | 1743 return Qnil; |
1538 } | 1744 } |
1547 This will always be nil for a non-pointer image instance. | 1753 This will always be nil for a non-pointer image instance. |
1548 */ | 1754 */ |
1549 (image_instance)) | 1755 (image_instance)) |
1550 { | 1756 { |
1551 CHECK_IMAGE_INSTANCE (image_instance); | 1757 CHECK_IMAGE_INSTANCE (image_instance); |
1758 ERROR_CHECK_IMAGE_INSTANCE (image_instance); | |
1552 | 1759 |
1553 switch (XIMAGE_INSTANCE_TYPE (image_instance)) | 1760 switch (XIMAGE_INSTANCE_TYPE (image_instance)) |
1554 { | 1761 { |
1555 case IMAGE_MONO_PIXMAP: | 1762 case IMAGE_MONO_PIXMAP: |
1556 case IMAGE_COLOR_PIXMAP: | 1763 case IMAGE_COLOR_PIXMAP: |
1571 This will always be nil for a non-pointer image instance. | 1778 This will always be nil for a non-pointer image instance. |
1572 */ | 1779 */ |
1573 (image_instance)) | 1780 (image_instance)) |
1574 { | 1781 { |
1575 CHECK_IMAGE_INSTANCE (image_instance); | 1782 CHECK_IMAGE_INSTANCE (image_instance); |
1783 ERROR_CHECK_IMAGE_INSTANCE (image_instance); | |
1576 | 1784 |
1577 switch (XIMAGE_INSTANCE_TYPE (image_instance)) | 1785 switch (XIMAGE_INSTANCE_TYPE (image_instance)) |
1578 { | 1786 { |
1579 case IMAGE_MONO_PIXMAP: | 1787 case IMAGE_MONO_PIXMAP: |
1580 case IMAGE_COLOR_PIXMAP: | 1788 case IMAGE_COLOR_PIXMAP: |
1592 colorized mono pixmaps and for pointers.) | 1800 colorized mono pixmaps and for pointers.) |
1593 */ | 1801 */ |
1594 (image_instance)) | 1802 (image_instance)) |
1595 { | 1803 { |
1596 CHECK_IMAGE_INSTANCE (image_instance); | 1804 CHECK_IMAGE_INSTANCE (image_instance); |
1805 ERROR_CHECK_IMAGE_INSTANCE (image_instance); | |
1597 | 1806 |
1598 switch (XIMAGE_INSTANCE_TYPE (image_instance)) | 1807 switch (XIMAGE_INSTANCE_TYPE (image_instance)) |
1599 { | 1808 { |
1600 case IMAGE_MONO_PIXMAP: | 1809 case IMAGE_MONO_PIXMAP: |
1601 case IMAGE_COLOR_PIXMAP: | 1810 case IMAGE_COLOR_PIXMAP: |
1603 return XIMAGE_INSTANCE_PIXMAP_FG (image_instance); | 1812 return XIMAGE_INSTANCE_PIXMAP_FG (image_instance); |
1604 | 1813 |
1605 case IMAGE_WIDGET: | 1814 case IMAGE_WIDGET: |
1606 return FACE_FOREGROUND ( | 1815 return FACE_FOREGROUND ( |
1607 XIMAGE_INSTANCE_WIDGET_FACE (image_instance), | 1816 XIMAGE_INSTANCE_WIDGET_FACE (image_instance), |
1608 XIMAGE_INSTANCE_SUBWINDOW_FRAME | 1817 XIMAGE_INSTANCE_FRAME |
1609 (image_instance)); | 1818 (image_instance)); |
1610 | 1819 |
1611 default: | 1820 default: |
1612 return Qnil; | 1821 return Qnil; |
1613 } | 1822 } |
1619 colorized mono pixmaps and for pointers.) | 1828 colorized mono pixmaps and for pointers.) |
1620 */ | 1829 */ |
1621 (image_instance)) | 1830 (image_instance)) |
1622 { | 1831 { |
1623 CHECK_IMAGE_INSTANCE (image_instance); | 1832 CHECK_IMAGE_INSTANCE (image_instance); |
1833 ERROR_CHECK_IMAGE_INSTANCE (image_instance); | |
1624 | 1834 |
1625 switch (XIMAGE_INSTANCE_TYPE (image_instance)) | 1835 switch (XIMAGE_INSTANCE_TYPE (image_instance)) |
1626 { | 1836 { |
1627 case IMAGE_MONO_PIXMAP: | 1837 case IMAGE_MONO_PIXMAP: |
1628 case IMAGE_COLOR_PIXMAP: | 1838 case IMAGE_COLOR_PIXMAP: |
1630 return XIMAGE_INSTANCE_PIXMAP_BG (image_instance); | 1840 return XIMAGE_INSTANCE_PIXMAP_BG (image_instance); |
1631 | 1841 |
1632 case IMAGE_WIDGET: | 1842 case IMAGE_WIDGET: |
1633 return FACE_BACKGROUND ( | 1843 return FACE_BACKGROUND ( |
1634 XIMAGE_INSTANCE_WIDGET_FACE (image_instance), | 1844 XIMAGE_INSTANCE_WIDGET_FACE (image_instance), |
1635 XIMAGE_INSTANCE_SUBWINDOW_FRAME | 1845 XIMAGE_INSTANCE_FRAME |
1636 (image_instance)); | 1846 (image_instance)); |
1637 | 1847 |
1638 default: | 1848 default: |
1639 return Qnil; | 1849 return Qnil; |
1640 } | 1850 } |
1652 { | 1862 { |
1653 Lisp_Object new; | 1863 Lisp_Object new; |
1654 Lisp_Object device; | 1864 Lisp_Object device; |
1655 | 1865 |
1656 CHECK_IMAGE_INSTANCE (image_instance); | 1866 CHECK_IMAGE_INSTANCE (image_instance); |
1867 ERROR_CHECK_IMAGE_INSTANCE (image_instance); | |
1657 CHECK_COLOR_INSTANCE (foreground); | 1868 CHECK_COLOR_INSTANCE (foreground); |
1658 CHECK_COLOR_INSTANCE (background); | 1869 CHECK_COLOR_INSTANCE (background); |
1659 | 1870 |
1660 device = XIMAGE_INSTANCE_DEVICE (image_instance); | 1871 device = image_instance_device (image_instance); |
1661 if (!HAS_DEVMETH_P (XDEVICE (device), colorize_image_instance)) | 1872 if (!HAS_DEVMETH_P (XDEVICE (device), colorize_image_instance)) |
1662 return image_instance; | 1873 return image_instance; |
1663 | 1874 |
1664 /* #### There should be a copy_image_instance(), which calls a | 1875 /* #### There should be a copy_image_instance(), which calls a |
1665 device-specific method to copy the window-system subobject. */ | 1876 device-specific method to copy the window-system subobject. */ |
1666 new = allocate_image_instance (device, Qnil); | 1877 new = allocate_image_instance (XIMAGE_INSTANCE_DOMAIN (image_instance), |
1878 Qnil); | |
1667 copy_lcrecord (XIMAGE_INSTANCE (new), XIMAGE_INSTANCE (image_instance)); | 1879 copy_lcrecord (XIMAGE_INSTANCE (new), XIMAGE_INSTANCE (image_instance)); |
1668 /* note that if this method returns non-zero, this method MUST | 1880 /* note that if this method returns non-zero, this method MUST |
1669 copy any window-system resources, so that when one image instance is | 1881 copy any window-system resources, so that when one image instance is |
1670 freed, the other one is not hosed. */ | 1882 freed, the other one is not hosed. */ |
1671 if (!DEVMETH (XDEVICE (device), colorize_image_instance, (new, foreground, | 1883 if (!DEVMETH (XDEVICE (device), colorize_image_instance, (new, foreground, |
1688 Lisp_Object domain) | 1900 Lisp_Object domain) |
1689 { | 1901 { |
1690 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); | 1902 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); |
1691 Lisp_Object type; | 1903 Lisp_Object type; |
1692 struct image_instantiator_methods* meths; | 1904 struct image_instantiator_methods* meths; |
1905 ERROR_CHECK_IMAGE_INSTANCE (image_instance); | |
1693 | 1906 |
1694 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); | 1907 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); |
1695 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); | 1908 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); |
1696 | 1909 |
1697 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry)) | 1910 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry)) |
1722 { | 1935 { |
1723 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); | 1936 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); |
1724 Lisp_Object type; | 1937 Lisp_Object type; |
1725 struct image_instantiator_methods* meths; | 1938 struct image_instantiator_methods* meths; |
1726 | 1939 |
1940 ERROR_CHECK_IMAGE_INSTANCE (image_instance); | |
1941 | |
1942 /* Nothing is as nothing does. */ | |
1943 if (NOTHING_IMAGE_INSTANCEP (image_instance)) | |
1944 return; | |
1945 | |
1727 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); | 1946 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); |
1728 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); | 1947 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); |
1729 | 1948 |
1730 /* If geometry is unspecified then get some reasonable values for it. */ | 1949 /* If geometry is unspecified then get some reasonable values for it. */ |
1731 if (width == IMAGE_UNSPECIFIED_GEOMETRY | 1950 if (width == IMAGE_UNSPECIFIED_GEOMETRY |
1732 || | 1951 || |
1733 height == IMAGE_UNSPECIFIED_GEOMETRY) | 1952 height == IMAGE_UNSPECIFIED_GEOMETRY) |
1734 { | 1953 { |
1735 unsigned int dwidth, dheight; | 1954 unsigned int dwidth = IMAGE_UNSPECIFIED_GEOMETRY, |
1955 dheight = IMAGE_UNSPECIFIED_GEOMETRY; | |
1736 | 1956 |
1737 /* Get the desired geometry. */ | 1957 /* Get the desired geometry. */ |
1738 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry)) | 1958 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry)) |
1739 { | 1959 { |
1740 IIFORMAT_METH (meths, query_geometry, (image_instance, &dwidth, &dheight, | 1960 IIFORMAT_METH (meths, query_geometry, (image_instance, &dwidth, &dheight, |
1752 width = dwidth; | 1972 width = dwidth; |
1753 if (height == IMAGE_UNSPECIFIED_GEOMETRY) | 1973 if (height == IMAGE_UNSPECIFIED_GEOMETRY) |
1754 height = dheight; | 1974 height = dheight; |
1755 } | 1975 } |
1756 | 1976 |
1977 /* If we don't have sane values then we cannot layout at this point and | |
1978 must just return. */ | |
1979 if (width == IMAGE_UNSPECIFIED_GEOMETRY | |
1980 || | |
1981 height == IMAGE_UNSPECIFIED_GEOMETRY) | |
1982 return; | |
1983 | |
1757 /* At this point width and height should contain sane values. Thus | 1984 /* At this point width and height should contain sane values. Thus |
1758 we set the glyph geometry and lay it out. */ | 1985 we set the glyph geometry and lay it out. */ |
1759 if (IMAGE_INSTANCE_WIDTH (ii) != width | 1986 if (IMAGE_INSTANCE_WIDTH (ii) != width |
1760 || | 1987 || |
1761 IMAGE_INSTANCE_HEIGHT (ii) != height) | 1988 IMAGE_INSTANCE_HEIGHT (ii) != height) |
1764 } | 1991 } |
1765 | 1992 |
1766 IMAGE_INSTANCE_WIDTH (ii) = width; | 1993 IMAGE_INSTANCE_WIDTH (ii) = width; |
1767 IMAGE_INSTANCE_HEIGHT (ii) = height; | 1994 IMAGE_INSTANCE_HEIGHT (ii) = height; |
1768 | 1995 |
1769 if (meths && HAS_IIFORMAT_METH_P (meths, layout)) | 1996 if (IIFORMAT_METH_OR_GIVEN (meths, layout, |
1770 { | 1997 (image_instance, width, height, domain), 1)) |
1771 IIFORMAT_METH (meths, layout, (image_instance, width, height, domain)); | 1998 /* Do not clear the dirty flag here - redisplay will do this for |
1772 } | 1999 us at the end. */ |
1773 /* else no change to the geometry. */ | 2000 IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 0; |
1774 | |
1775 /* Do not clear the dirty flag here - redisplay will do this for | |
1776 us at the end. */ | |
1777 IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 0; | |
1778 } | 2001 } |
1779 | 2002 |
1780 /* | 2003 /* |
1781 * Mark image instance in W as dirty if (a) W's faces have changed and | 2004 * Mark image instance in W as dirty if (a) W's faces have changed and |
1782 * (b) GLYPH_OR_II instance in W is a string. | 2005 * (b) GLYPH_OR_II instance in W is a string. |
1845 int dest_mask, Lisp_Object domain) | 2068 int dest_mask, Lisp_Object domain) |
1846 { | 2069 { |
1847 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | 2070 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
1848 | 2071 |
1849 if (dest_mask & IMAGE_NOTHING_MASK) | 2072 if (dest_mask & IMAGE_NOTHING_MASK) |
1850 IMAGE_INSTANCE_TYPE (ii) = IMAGE_NOTHING; | 2073 { |
2074 IMAGE_INSTANCE_TYPE (ii) = IMAGE_NOTHING; | |
2075 IMAGE_INSTANCE_HEIGHT (ii) = 0; | |
2076 IMAGE_INSTANCE_WIDTH (ii) = 0; | |
2077 } | |
1851 else | 2078 else |
1852 incompatible_image_types (instantiator, dest_mask, IMAGE_NOTHING_MASK); | 2079 incompatible_image_types (instantiator, dest_mask, IMAGE_NOTHING_MASK); |
1853 } | 2080 } |
1854 | 2081 |
1855 | 2082 |
1915 { | 2142 { |
1916 Lisp_Object string = find_keyword_in_vector (instantiator, Q_data); | 2143 Lisp_Object string = find_keyword_in_vector (instantiator, Q_data); |
1917 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | 2144 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
1918 | 2145 |
1919 /* Should never get here with a domain other than a window. */ | 2146 /* Should never get here with a domain other than a window. */ |
1920 assert (!NILP (string) && WINDOWP (domain)); | 2147 assert (!NILP (string) && WINDOWP (DOMAIN_WINDOW (domain))); |
1921 if (dest_mask & IMAGE_TEXT_MASK) | 2148 if (dest_mask & IMAGE_TEXT_MASK) |
1922 { | 2149 { |
1923 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT; | 2150 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT; |
1924 IMAGE_INSTANCE_TEXT_STRING (ii) = string; | 2151 IMAGE_INSTANCE_TEXT_STRING (ii) = string; |
1925 } | 2152 } |
1939 { | 2166 { |
1940 struct font_metric_info fm; | 2167 struct font_metric_info fm; |
1941 unsigned char charsets[NUM_LEADING_BYTES]; | 2168 unsigned char charsets[NUM_LEADING_BYTES]; |
1942 struct face_cachel frame_cachel; | 2169 struct face_cachel frame_cachel; |
1943 struct face_cachel *cachel; | 2170 struct face_cachel *cachel; |
1944 Lisp_Object frame = FW_FRAME (domain); | 2171 Lisp_Object frame = DOMAIN_FRAME (domain); |
1945 | 2172 |
1946 /* Compute height */ | 2173 /* Compute height */ |
1947 if (height) | 2174 if (height) |
1948 { | 2175 { |
1949 /* Compute string metric info */ | 2176 /* Compute string metric info */ |
1958 update_face_cachel_data (&frame_cachel, frame, face); | 2185 update_face_cachel_data (&frame_cachel, frame, face); |
1959 cachel = &frame_cachel; | 2186 cachel = &frame_cachel; |
1960 } | 2187 } |
1961 else | 2188 else |
1962 { | 2189 { |
1963 cachel = WINDOW_FACE_CACHEL (XWINDOW (domain), DEFAULT_INDEX); | 2190 cachel = WINDOW_FACE_CACHEL (DOMAIN_XWINDOW (domain), |
2191 DEFAULT_INDEX); | |
1964 } | 2192 } |
1965 | 2193 |
1966 ensure_face_cachel_complete (cachel, domain, charsets); | 2194 ensure_face_cachel_complete (cachel, domain, charsets); |
1967 face_cachel_charset_font_metric_info (cachel, charsets, &fm); | 2195 face_cachel_charset_font_metric_info (cachel, charsets, &fm); |
1968 | 2196 |
1991 { | 2219 { |
1992 unsigned char charsets[NUM_LEADING_BYTES]; | 2220 unsigned char charsets[NUM_LEADING_BYTES]; |
1993 struct face_cachel frame_cachel; | 2221 struct face_cachel frame_cachel; |
1994 struct face_cachel *cachel; | 2222 struct face_cachel *cachel; |
1995 int i; | 2223 int i; |
1996 Lisp_Object frame = FW_FRAME (domain); | 2224 Lisp_Object frame = DOMAIN_FRAME (domain); |
1997 | 2225 |
1998 /* Compute string font info */ | 2226 /* Compute string font info */ |
1999 find_charsets_in_bufbyte_string (charsets, | 2227 find_charsets_in_bufbyte_string (charsets, |
2000 XSTRING_DATA (string), | 2228 XSTRING_DATA (string), |
2001 XSTRING_LENGTH (string)); | 2229 XSTRING_LENGTH (string)); |
2746 static Lisp_Object | 2974 static Lisp_Object |
2747 image_instantiate (Lisp_Object specifier, Lisp_Object matchspec, | 2975 image_instantiate (Lisp_Object specifier, Lisp_Object matchspec, |
2748 Lisp_Object domain, Lisp_Object instantiator, | 2976 Lisp_Object domain, Lisp_Object instantiator, |
2749 Lisp_Object depth) | 2977 Lisp_Object depth) |
2750 { | 2978 { |
2751 Lisp_Object device = DFW_DEVICE (domain); | |
2752 struct device *d = XDEVICE (device); | |
2753 Lisp_Object glyph = IMAGE_SPECIFIER_ATTACHEE (XIMAGE_SPECIFIER (specifier)); | 2979 Lisp_Object glyph = IMAGE_SPECIFIER_ATTACHEE (XIMAGE_SPECIFIER (specifier)); |
2754 int dest_mask = XIMAGE_SPECIFIER_ALLOWED (specifier); | 2980 int dest_mask = XIMAGE_SPECIFIER_ALLOWED (specifier); |
2755 int pointerp = dest_mask & image_instance_type_to_mask (IMAGE_POINTER); | 2981 int pointerp = dest_mask & image_instance_type_to_mask (IMAGE_POINTER); |
2756 | 2982 |
2757 if (IMAGE_INSTANCEP (instantiator)) | 2983 if (IMAGE_INSTANCEP (instantiator)) |
2758 { | 2984 { |
2759 /* make sure that the image instance's device and type are | 2985 /* make sure that the image instance's governing domain and type are |
2760 matching. */ | 2986 matching. */ |
2761 | 2987 Lisp_Object governing_domain = XIMAGE_INSTANCE_DOMAIN (instantiator); |
2762 if (EQ (device, XIMAGE_INSTANCE_DEVICE (instantiator))) | 2988 |
2989 if ((DEVICEP (governing_domain) | |
2990 && EQ (governing_domain, DOMAIN_DEVICE (domain))) | |
2991 || (FRAMEP (governing_domain) | |
2992 && EQ (governing_domain, DOMAIN_FRAME (domain))) | |
2993 || (WINDOWP (governing_domain) | |
2994 && EQ (governing_domain, DOMAIN_WINDOW (domain)))) | |
2763 { | 2995 { |
2764 int mask = | 2996 int mask = |
2765 image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instantiator)); | 2997 image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instantiator)); |
2766 if (mask & dest_mask) | 2998 if (mask & dest_mask) |
2767 return instantiator; | 2999 return instantiator; |
2768 else | 3000 else |
2769 signal_simple_error ("Type of image instance not allowed here", | 3001 signal_simple_error ("Type of image instance not allowed here", |
2770 instantiator); | 3002 instantiator); |
2771 } | 3003 } |
2772 else | 3004 else |
2773 signal_simple_error_2 ("Wrong device for image instance", | 3005 signal_simple_error_2 ("Wrong domain for image instance", |
2774 instantiator, device); | 3006 instantiator, domain); |
2775 } | 3007 } |
2776 else if (VECTORP (instantiator) | 3008 else if (VECTORP (instantiator) |
2777 && EQ (XVECTOR_DATA (instantiator)[0], Qinherit)) | 3009 && EQ (XVECTOR_DATA (instantiator)[0], Qinherit)) |
2778 { | 3010 { |
2779 assert (XVECTOR_LENGTH (instantiator) == 3); | 3011 assert (XVECTOR_LENGTH (instantiator) == 3); |
2786 Lisp_Object instance; | 3018 Lisp_Object instance; |
2787 Lisp_Object subtable; | 3019 Lisp_Object subtable; |
2788 Lisp_Object ls3 = Qnil; | 3020 Lisp_Object ls3 = Qnil; |
2789 Lisp_Object pointer_fg = Qnil; | 3021 Lisp_Object pointer_fg = Qnil; |
2790 Lisp_Object pointer_bg = Qnil; | 3022 Lisp_Object pointer_bg = Qnil; |
3023 Lisp_Object governing_domain = | |
3024 get_image_instantiator_governing_domain (instantiator, domain); | |
2791 | 3025 |
2792 /* We have to put subwindow, widget and text image instances in | 3026 /* We have to put subwindow, widget and text image instances in |
2793 a per-window cache so that we can see the same glyph in | 3027 a per-window cache so that we can see the same glyph in |
2794 different windows. Unfortunately we do not know the type of | 3028 different windows. We use governing_domain to determine the type |
2795 image_instance until after it has been created. We thus need | 3029 of image_instance that will be created. */ |
2796 to be really careful how we place things. */ | |
2797 | 3030 |
2798 if (pointerp) | 3031 if (pointerp) |
2799 { | 3032 { |
2800 pointer_fg = FACE_FOREGROUND (Vpointer_face, domain); | 3033 pointer_fg = FACE_FOREGROUND (Vpointer_face, domain); |
2801 pointer_bg = FACE_BACKGROUND (Vpointer_face, domain); | 3034 pointer_bg = FACE_BACKGROUND (Vpointer_face, domain); |
2802 ls3 = list3 (instantiator, pointer_fg, pointer_bg); | 3035 ls3 = list3 (instantiator, pointer_fg, pointer_bg); |
2803 } | 3036 } |
2804 | 3037 |
2805 /* First look in the hash table. */ | 3038 /* First look in the device cache. */ |
2806 subtable = Fgethash (make_int (dest_mask), d->image_instance_cache, | 3039 if (DEVICEP (governing_domain)) |
2807 Qunbound); | |
2808 if (UNBOUNDP (subtable)) | |
2809 { | 3040 { |
2810 /* For the image instance cache, we do comparisons with EQ rather | 3041 subtable = Fgethash (make_int (dest_mask), |
2811 than with EQUAL, as we do for color and font names. | 3042 XDEVICE (governing_domain)-> |
2812 The reasons are: | 3043 image_instance_cache, |
2813 | 3044 Qunbound); |
2814 1) pixmap data can be very long, and thus the hashing and | 3045 if (UNBOUNDP (subtable)) |
2815 comparing will take awhile. | 3046 { |
2816 2) It's not so likely that we'll run into things that are EQUAL | 3047 /* For the image instance cache, we do comparisons with |
2817 but not EQ (that can happen a lot with faces, because their | 3048 EQ rather than with EQUAL, as we do for color and |
2818 specifiers are copied around); but pixmaps tend not to be | 3049 font names. The reasons are: |
2819 in faces. | 3050 |
2820 | 3051 1) pixmap data can be very long, and thus the hashing |
2821 However, if the image-instance could be a pointer, we have to | 3052 and comparing will take awhile. |
2822 use EQUAL because we massaged the instantiator into a cons3 | 3053 |
2823 also containing the foreground and background of the | 3054 2) It's not so likely that we'll run into things that |
2824 pointer face. | 3055 are EQUAL but not EQ (that can happen a lot with |
2825 */ | 3056 faces, because their specifiers are copied around); |
2826 | 3057 but pixmaps tend not to be in faces. |
2827 subtable = make_lisp_hash_table (20, | 3058 |
2828 pointerp ? HASH_TABLE_KEY_CAR_WEAK | 3059 However, if the image-instance could be a pointer, we |
2829 : HASH_TABLE_KEY_WEAK, | 3060 have to use EQUAL because we massaged the |
2830 pointerp ? HASH_TABLE_EQUAL | 3061 instantiator into a cons3 also containing the |
2831 : HASH_TABLE_EQ); | 3062 foreground and background of the pointer face. */ |
2832 Fputhash (make_int (dest_mask), subtable, | 3063 |
2833 d->image_instance_cache); | 3064 subtable = make_lisp_hash_table |
2834 instance = Qunbound; | 3065 (20, pointerp ? HASH_TABLE_KEY_CAR_WEAK |
3066 : HASH_TABLE_KEY_WEAK, | |
3067 pointerp ? HASH_TABLE_EQUAL | |
3068 : HASH_TABLE_EQ); | |
3069 Fputhash (make_int (dest_mask), subtable, | |
3070 XDEVICE (governing_domain)->image_instance_cache); | |
3071 instance = Qunbound; | |
3072 } | |
3073 else | |
3074 { | |
3075 instance = Fgethash (pointerp ? ls3 : instantiator, | |
3076 subtable, Qunbound); | |
3077 } | |
3078 } | |
3079 else if (WINDOWP (governing_domain)) | |
3080 { | |
3081 /* Subwindows have a per-window cache and have to be treated | |
3082 differently. */ | |
3083 instance = | |
3084 Fgethash (instantiator, | |
3085 XWINDOW (governing_domain)->subwindow_instance_cache, | |
3086 Qunbound); | |
2835 } | 3087 } |
2836 else | 3088 else |
2837 { | 3089 abort (); /* We're not allowed anything else currently. */ |
2838 instance = Fgethash (pointerp ? ls3 : instantiator, | 3090 |
2839 subtable, Qunbound); | 3091 /* If we don't have an instance at this point then create |
2840 /* subwindows have a per-window cache and have to be treated | 3092 one. */ |
2841 differently. dest_mask can be a bitwise OR of all image | |
2842 types so we will only catch someone possibly trying to | |
2843 instantiate a subwindow type thing. Unfortunately, this | |
2844 will occur most of the time so this probably slows things | |
2845 down. But with the current design I don't see anyway | |
2846 round it. */ | |
2847 if (UNBOUNDP (instance) | |
2848 && | |
2849 dest_mask & (IMAGE_SUBWINDOW_MASK | |
2850 | IMAGE_WIDGET_MASK | |
2851 | IMAGE_LAYOUT_MASK | |
2852 | IMAGE_TEXT_MASK) | |
2853 && WINDOWP (domain)) | |
2854 { | |
2855 instance = Fgethash (instantiator, | |
2856 XWINDOW (domain)->subwindow_instance_cache, | |
2857 Qunbound); | |
2858 } | |
2859 } | |
2860 | |
2861 if (UNBOUNDP (instance)) | 3093 if (UNBOUNDP (instance)) |
2862 { | 3094 { |
2863 Lisp_Object locative = | 3095 Lisp_Object locative = |
2864 noseeum_cons (Qnil, | 3096 noseeum_cons (Qnil, |
2865 noseeum_cons (pointerp ? ls3 : instantiator, | 3097 noseeum_cons (pointerp ? ls3 : instantiator, |
2866 subtable)); | 3098 DEVICEP (governing_domain) ? subtable |
3099 : XWINDOW (governing_domain) | |
3100 ->subwindow_instance_cache)); | |
2867 int speccount = specpdl_depth (); | 3101 int speccount = specpdl_depth (); |
2868 | 3102 |
2869 /* make sure we cache the failures, too. | 3103 /* Make sure we cache the failures, too. Use an |
2870 Use an unwind-protect to catch such errors. | 3104 unwind-protect to catch such errors. If we fail, the |
2871 If we fail, the unwind-protect records nil in | 3105 unwind-protect records nil in the hash table. If we |
2872 the hash table. If we succeed, we change the | 3106 succeed, we change the car of the locative to the |
2873 car of the locative to the resulting instance, | 3107 resulting instance, which gets recorded instead. */ |
2874 which gets recorded instead. */ | |
2875 record_unwind_protect (image_instantiate_cache_result, | 3108 record_unwind_protect (image_instantiate_cache_result, |
2876 locative); | 3109 locative); |
2877 instance = instantiate_image_instantiator (device, | 3110 instance = |
2878 domain, | 3111 instantiate_image_instantiator (governing_domain, |
2879 instantiator, | 3112 domain, instantiator, |
2880 pointer_fg, pointer_bg, | 3113 pointer_fg, pointer_bg, |
2881 dest_mask, | 3114 dest_mask, glyph); |
2882 glyph); | 3115 |
3116 /* We need a per-frame cache for redisplay. */ | |
3117 cache_subwindow_instance_in_frame_maybe (instance); | |
2883 | 3118 |
2884 Fsetcar (locative, instance); | 3119 Fsetcar (locative, instance); |
2885 /* only after the image has been instantiated do we know | 3120 #ifdef ERROR_CHECK_GLYPHS |
2886 whether we need to put it in the per-window image instance | |
2887 cache. */ | |
2888 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance)) | 3121 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance)) |
2889 & | 3122 & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK)) |
2890 (IMAGE_SUBWINDOW_MASK | 3123 assert (EQ (XIMAGE_INSTANCE_FRAME (instance), |
2891 | IMAGE_WIDGET_MASK | 3124 DOMAIN_FRAME (domain))); |
2892 | IMAGE_LAYOUT_MASK | |
2893 | IMAGE_TEXT_MASK )) | |
2894 { | |
2895 #ifdef ERROR_CHECK_GLYPHS | |
2896 if (XIMAGE_INSTANCE_TYPE (instance) != IMAGE_TEXT) | |
2897 assert (EQ (XIMAGE_INSTANCE_SUBWINDOW_FRAME (instance), | |
2898 FW_FRAME (domain))); | |
2899 #endif | 3125 #endif |
2900 if (!WINDOWP (domain)) | |
2901 signal_simple_error ("Can't instantiate text or subwindow outside a window", | |
2902 instantiator); | |
2903 #ifdef ERROR_CHECK_GLYPHS | |
2904 if (XIMAGE_INSTANCE_TYPE (instance) != IMAGE_TEXT) | |
2905 assert (EQ (XIMAGE_INSTANCE_SUBWINDOW_FRAME (instance), | |
2906 FW_FRAME (domain))); | |
2907 #endif | |
2908 Fsetcdr (XCDR (locative), XWINDOW (domain)->subwindow_instance_cache); | |
2909 } | |
2910 unbind_to (speccount, Qnil); | 3126 unbind_to (speccount, Qnil); |
2911 #ifdef ERROR_CHECK_GLYPHS | 3127 #ifdef ERROR_CHECK_GLYPHS |
2912 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance)) | 3128 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance)) |
2913 & | 3129 & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK)) |
2914 (IMAGE_SUBWINDOW_MASK | |
2915 | IMAGE_WIDGET_MASK | |
2916 | IMAGE_LAYOUT_MASK | |
2917 | IMAGE_TEXT_MASK )) | |
2918 assert (EQ (Fgethash ((pointerp ? ls3 : instantiator), | 3130 assert (EQ (Fgethash ((pointerp ? ls3 : instantiator), |
2919 XWINDOW (domain)->subwindow_instance_cache, | 3131 XWINDOW (governing_domain) |
3132 ->subwindow_instance_cache, | |
2920 Qunbound), instance)); | 3133 Qunbound), instance)); |
2921 #endif | 3134 #endif |
2922 } | 3135 } |
2923 else | 3136 else |
2924 free_list (ls3); | 3137 free_list (ls3); |
2927 signal_simple_error ("Can't instantiate image (probably cached)", | 3140 signal_simple_error ("Can't instantiate image (probably cached)", |
2928 instantiator); | 3141 instantiator); |
2929 #ifdef ERROR_CHECK_GLYPHS | 3142 #ifdef ERROR_CHECK_GLYPHS |
2930 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance)) | 3143 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance)) |
2931 & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK)) | 3144 & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK)) |
2932 assert (EQ (XIMAGE_INSTANCE_SUBWINDOW_FRAME (instance), | 3145 assert (EQ (XIMAGE_INSTANCE_FRAME (instance), |
2933 FW_FRAME (domain))); | 3146 DOMAIN_FRAME (domain))); |
2934 #endif | 3147 #endif |
3148 ERROR_CHECK_IMAGE_INSTANCE (instance); | |
2935 return instance; | 3149 return instance; |
2936 } | 3150 } |
2937 | 3151 |
2938 abort (); | 3152 abort (); |
2939 return Qnil; /* not reached */ | 3153 return Qnil; /* not reached */ |
3144 return arg; | 3358 return arg; |
3145 } | 3359 } |
3146 | 3360 |
3147 DEFUN ("image-specifier-p", Fimage_specifier_p, 1, 1, 0, /* | 3361 DEFUN ("image-specifier-p", Fimage_specifier_p, 1, 1, 0, /* |
3148 Return non-nil if OBJECT is an image specifier. | 3362 Return non-nil if OBJECT is an image specifier. |
3149 | 3363 See `make-image-specifier' for a description of image instantiators. |
3150 An image specifier is used for images (pixmaps and the like). It is used | |
3151 to describe the actual image in a glyph. It is instanced as an image- | |
3152 instance. | |
3153 | |
3154 Image instantiators come in many formats: `xbm', `xpm', `gif', `jpeg', | |
3155 etc. This describes the format of the data describing the image. The | |
3156 resulting image instances also come in many types -- `mono-pixmap', | |
3157 `color-pixmap', `text', `pointer', etc. This refers to the behavior of | |
3158 the image and the sorts of places it can appear. (For example, a | |
3159 color-pixmap image has fixed colors specified for it, while a | |
3160 mono-pixmap image comes in two unspecified shades "foreground" and | |
3161 "background" that are determined from the face of the glyph or | |
3162 surrounding text; a text image appears as a string of text and has an | |
3163 unspecified foreground, background, and font; a pointer image behaves | |
3164 like a mono-pixmap image but can only be used as a mouse pointer | |
3165 \[mono-pixmap images cannot be used as mouse pointers]; etc.) It is | |
3166 important to keep the distinction between image instantiator format and | |
3167 image instance type in mind. Typically, a given image instantiator | |
3168 format can result in many different image instance types (for example, | |
3169 `xpm' can be instanced as `color-pixmap', `mono-pixmap', or `pointer'; | |
3170 whereas `cursor-font' can be instanced only as `pointer'), and a | |
3171 particular image instance type can be generated by many different | |
3172 image instantiator formats (e.g. `color-pixmap' can be generated by `xpm', | |
3173 `gif', `jpeg', etc.). | |
3174 | |
3175 See `make-image-instance' for a more detailed discussion of image | |
3176 instance types. | |
3177 | |
3178 An image instantiator should be a string or a vector of the form | |
3179 | |
3180 [FORMAT :KEYWORD VALUE ...] | |
3181 | |
3182 i.e. a format symbol followed by zero or more alternating keyword-value | |
3183 pairs. FORMAT should be one of | |
3184 | |
3185 'nothing | |
3186 (Don't display anything; no keywords are valid for this. | |
3187 Can only be instanced as `nothing'.) | |
3188 'string | |
3189 (Display this image as a text string. Can only be instanced | |
3190 as `text', although support for instancing as `mono-pixmap' | |
3191 should be added.) | |
3192 'formatted-string | |
3193 (Display this image as a text string, with replaceable fields; | |
3194 not currently implemented.) | |
3195 'xbm | |
3196 (An X bitmap; only if X or Windows support was compiled into this XEmacs. | |
3197 Can be instanced as `mono-pixmap', `color-pixmap', or `pointer'.) | |
3198 'xpm | |
3199 (An XPM pixmap; only if XPM support was compiled into this XEmacs. | |
3200 Can be instanced as `color-pixmap', `mono-pixmap', or `pointer'.) | |
3201 'xface | |
3202 (An X-Face bitmap, used to encode people's faces in e-mail messages; | |
3203 only if X-Face support was compiled into this XEmacs. Can be | |
3204 instanced as `mono-pixmap', `color-pixmap', or `pointer'.) | |
3205 'gif | |
3206 (A GIF87 or GIF89 image; only if GIF support was compiled into this | |
3207 XEmacs. NOTE: only the first frame of animated gifs will be displayed. | |
3208 Can be instanced as `color-pixmap'.) | |
3209 'jpeg | |
3210 (A JPEG image; only if JPEG support was compiled into this XEmacs. | |
3211 Can be instanced as `color-pixmap'.) | |
3212 'png | |
3213 (A PNG image; only if PNG support was compiled into this XEmacs. | |
3214 Can be instanced as `color-pixmap'.) | |
3215 'tiff | |
3216 (A TIFF image; only if TIFF support was compiled into this XEmacs. | |
3217 Can be instanced as `color-pixmap'.) | |
3218 'cursor-font | |
3219 (One of the standard cursor-font names, such as "watch" or | |
3220 "right_ptr" under X. Under X, this is, more specifically, any | |
3221 of the standard cursor names from appendix B of the Xlib manual | |
3222 [also known as the file <X11/cursorfont.h>] minus the XC_ prefix. | |
3223 On other window systems, the valid names will be specific to the | |
3224 type of window system. Can only be instanced as `pointer'.) | |
3225 'font | |
3226 (A glyph from a font; i.e. the name of a font, and glyph index into it | |
3227 of the form "FONT fontname index [[mask-font] mask-index]". | |
3228 Currently can only be instanced as `pointer', although this should | |
3229 probably be fixed.) | |
3230 'subwindow | |
3231 (An embedded windowing system window.) | |
3232 'edit-field | |
3233 (A text editing widget glyph.) | |
3234 'button | |
3235 (A button widget glyph; either a push button, radio button or toggle button.) | |
3236 'tab-control | |
3237 (A tab widget glyph; a series of user selectable tabs.) | |
3238 'progress-gauge | |
3239 (A sliding widget glyph, for showing progress.) | |
3240 'combo-box | |
3241 (A drop list of selectable items in a widget glyph, for editing text.) | |
3242 'label | |
3243 (A static, text-only, widget glyph; for displaying text.) | |
3244 'tree-view | |
3245 (A folding widget glyph.) | |
3246 'autodetect | |
3247 (XEmacs tries to guess what format the data is in. If X support | |
3248 exists, the data string will be checked to see if it names a filename. | |
3249 If so, and this filename contains XBM or XPM data, the appropriate | |
3250 sort of pixmap or pointer will be created. [This includes picking up | |
3251 any specified hotspot or associated mask file.] Otherwise, if `pointer' | |
3252 is one of the allowable image-instance types and the string names a | |
3253 valid cursor-font name, the image will be created as a pointer. | |
3254 Otherwise, the image will be displayed as text. If no X support | |
3255 exists, the image will always be displayed as text.) | |
3256 'inherit | |
3257 Inherit from the background-pixmap property of a face. | |
3258 | |
3259 The valid keywords are: | |
3260 | |
3261 :data | |
3262 (Inline data. For most formats above, this should be a string. For | |
3263 XBM images, this should be a list of three elements: width, height, and | |
3264 a string of bit data. This keyword is not valid for instantiator | |
3265 formats `nothing' and `inherit'.) | |
3266 :file | |
3267 (Data is contained in a file. The value is the name of this file. | |
3268 If both :data and :file are specified, the image is created from | |
3269 what is specified in :data and the string in :file becomes the | |
3270 value of the `image-instance-file-name' function when applied to | |
3271 the resulting image-instance. This keyword is not valid for | |
3272 instantiator formats `nothing', `string', `formatted-string', | |
3273 `cursor-font', `font', `autodetect', and `inherit'.) | |
3274 :foreground | |
3275 :background | |
3276 (For `xbm', `xface', `cursor-font', `widget' and `font'. These keywords | |
3277 allow you to explicitly specify foreground and background colors. | |
3278 The argument should be anything acceptable to `make-color-instance'. | |
3279 This will cause what would be a `mono-pixmap' to instead be colorized | |
3280 as a two-color color-pixmap, and specifies the foreground and/or | |
3281 background colors for a pointer instead of black and white.) | |
3282 :mask-data | |
3283 (For `xbm' and `xface'. This specifies a mask to be used with the | |
3284 bitmap. The format is a list of width, height, and bits, like for | |
3285 :data.) | |
3286 :mask-file | |
3287 (For `xbm' and `xface'. This specifies a file containing the mask data. | |
3288 If neither a mask file nor inline mask data is given for an XBM image, | |
3289 and the XBM image comes from a file, XEmacs will look for a mask file | |
3290 with the same name as the image file but with "Mask" or "msk" | |
3291 appended. For example, if you specify the XBM file "left_ptr" | |
3292 [usually located in "/usr/include/X11/bitmaps"], the associated | |
3293 mask file "left_ptrmsk" will automatically be picked up.) | |
3294 :hotspot-x | |
3295 :hotspot-y | |
3296 (For `xbm' and `xface'. These keywords specify a hotspot if the image | |
3297 is instantiated as a `pointer'. Note that if the XBM image file | |
3298 specifies a hotspot, it will automatically be picked up if no | |
3299 explicit hotspot is given.) | |
3300 :color-symbols | |
3301 (Only for `xpm'. This specifies an alist that maps strings | |
3302 that specify symbolic color names to the actual color to be used | |
3303 for that symbolic color (in the form of a string or a color-specifier | |
3304 object). If this is not specified, the contents of `xpm-color-symbols' | |
3305 are used to generate the alist.) | |
3306 :face | |
3307 (Only for `inherit'. This specifies the face to inherit from. | |
3308 For widget glyphs this also specifies the face to use for | |
3309 display. It defaults to gui-element-face.) | |
3310 | |
3311 Keywords accepted as menu item specs are also accepted by widget | |
3312 glyphs. These are `:selected', `:active', `:suffix', `:keys', | |
3313 `:style', `:filter', `:config', `:included', `:key-sequence', | |
3314 `:accelerator', `:label' and `:callback'. | |
3315 | |
3316 If instead of a vector, the instantiator is a string, it will be | |
3317 converted into a vector by looking it up according to the specs in the | |
3318 `console-type-image-conversion-list' (q.v.) for the console type of | |
3319 the domain (usually a window; sometimes a frame or device) over which | |
3320 the image is being instantiated. | |
3321 | |
3322 If the instantiator specifies data from a file, the data will be read | |
3323 in at the time that the instantiator is added to the image (which may | |
3324 be well before when the image is actually displayed), and the | |
3325 instantiator will be converted into one of the inline-data forms, with | |
3326 the filename retained using a :file keyword. This implies that the | |
3327 file must exist when the instantiator is added to the image, but does | |
3328 not need to exist at any other time (e.g. it may safely be a temporary | |
3329 file). | |
3330 */ | 3364 */ |
3331 (object)) | 3365 (object)) |
3332 { | 3366 { |
3333 return IMAGE_SPECIFIERP (object) ? Qt : Qnil; | 3367 return IMAGE_SPECIFIERP (object) ? Qt : Qnil; |
3334 } | 3368 } |
3494 { | 3528 { |
3495 case GLYPH_BUFFER: | 3529 case GLYPH_BUFFER: |
3496 XIMAGE_SPECIFIER_ALLOWED (g->image) = | 3530 XIMAGE_SPECIFIER_ALLOWED (g->image) = |
3497 IMAGE_NOTHING_MASK | IMAGE_TEXT_MASK | 3531 IMAGE_NOTHING_MASK | IMAGE_TEXT_MASK |
3498 | IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK | 3532 | IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK |
3499 | IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK | 3533 | IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK; |
3500 | IMAGE_LAYOUT_MASK; | |
3501 break; | 3534 break; |
3502 case GLYPH_POINTER: | 3535 case GLYPH_POINTER: |
3503 XIMAGE_SPECIFIER_ALLOWED (g->image) = | 3536 XIMAGE_SPECIFIER_ALLOWED (g->image) = |
3504 IMAGE_NOTHING_MASK | IMAGE_POINTER_MASK; | 3537 IMAGE_NOTHING_MASK | IMAGE_POINTER_MASK; |
3505 break; | 3538 break; |
3610 } | 3643 } |
3611 | 3644 |
3612 DEFUN ("glyphp", Fglyphp, 1, 1, 0, /* | 3645 DEFUN ("glyphp", Fglyphp, 1, 1, 0, /* |
3613 Return non-nil if OBJECT is a glyph. | 3646 Return non-nil if OBJECT is a glyph. |
3614 | 3647 |
3615 A glyph is an object used for pixmaps and the like. It is used | 3648 A glyph is an object used for pixmaps, widgets and the like. It is used |
3616 in begin-glyphs and end-glyphs attached to extents, in marginal and textual | 3649 in begin-glyphs and end-glyphs attached to extents, in marginal and textual |
3617 annotations, in overlay arrows (overlay-arrow-* variables), in toolbar | 3650 annotations, in overlay arrows (overlay-arrow-* variables), in toolbar |
3618 buttons, and the like. Its image is described using an image specifier -- | 3651 buttons, and the like. Much more detailed information can be found at |
3619 see `image-specifier-p'. | 3652 `make-glyph'. Its image is described using an image specifier -- |
3653 see `make-image-specifier'. See also `make-image-instance' for further | |
3654 information. | |
3620 */ | 3655 */ |
3621 (object)) | 3656 (object)) |
3622 { | 3657 { |
3623 return GLYPHP (object) ? Qt : Qnil; | 3658 return GLYPHP (object) ? Qt : Qnil; |
3624 } | 3659 } |
3649 a fallback. */ | 3684 a fallback. */ |
3650 Lisp_Object image_instance = specifier_instance (specifier, Qunbound, | 3685 Lisp_Object image_instance = specifier_instance (specifier, Qunbound, |
3651 domain, errb, no_quit, 0, | 3686 domain, errb, no_quit, 0, |
3652 Qzero); | 3687 Qzero); |
3653 assert (!UNBOUNDP (image_instance)); | 3688 assert (!UNBOUNDP (image_instance)); |
3689 ERROR_CHECK_IMAGE_INSTANCE (image_instance); | |
3654 | 3690 |
3655 return image_instance; | 3691 return image_instance; |
3656 } | 3692 } |
3657 | 3693 |
3658 static Lisp_Object | 3694 static Lisp_Object |
3805 { | 3841 { |
3806 instance = glyph_image_instance (glyph_or_image, window, | 3842 instance = glyph_image_instance (glyph_or_image, window, |
3807 ERROR_ME_NOT, 1); | 3843 ERROR_ME_NOT, 1); |
3808 XGLYPH_DIRTYP (glyph_or_image) = dirty; | 3844 XGLYPH_DIRTYP (glyph_or_image) = dirty; |
3809 } | 3845 } |
3846 | |
3847 if (!IMAGE_INSTANCEP (instance)) | |
3848 return; | |
3810 | 3849 |
3811 XIMAGE_INSTANCE_DIRTYP (instance) = dirty; | 3850 XIMAGE_INSTANCE_DIRTYP (instance) = dirty; |
3812 } | 3851 } |
3813 } | 3852 } |
3814 | 3853 |
3955 cachel->glyph = glyph; | 3994 cachel->glyph = glyph; |
3956 /* Speed things up slightly by grabbing the glyph instantiation | 3995 /* Speed things up slightly by grabbing the glyph instantiation |
3957 and passing it to the size functions. */ | 3996 and passing it to the size functions. */ |
3958 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); | 3997 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); |
3959 | 3998 |
3999 if (!IMAGE_INSTANCEP (instance)) | |
4000 return; | |
4001 | |
3960 /* Mark text instance of the glyph dirty if faces have changed, | 4002 /* Mark text instance of the glyph dirty if faces have changed, |
3961 because its geometry might have changed. */ | 4003 because its geometry might have changed. */ |
3962 invalidate_glyph_geometry_maybe (instance, w); | 4004 invalidate_glyph_geometry_maybe (instance, w); |
3963 | 4005 |
3964 /* #### Do the following 2 lines buy us anything? --kkm */ | 4006 /* #### Do the following 2 lines buy us anything? --kkm */ |
4090 instantiator in the hashtable and when the instantiator goes away | 4132 instantiator in the hashtable and when the instantiator goes away |
4091 we want the instance to go away also. However we also have a | 4133 we want the instance to go away also. However we also have a |
4092 per-frame instance cache that we use to determine if a subwindow is | 4134 per-frame instance cache that we use to determine if a subwindow is |
4093 obscuring an area that we want to clear. We need to be able to flip | 4135 obscuring an area that we want to clear. We need to be able to flip |
4094 through this quickly so a hashtable is not suitable hence the | 4136 through this quickly so a hashtable is not suitable hence the |
4095 subwindow_cachels. The question is should we just not mark | 4137 subwindow_cachels. This is a weak list so unreference instances |
4096 instances in the subwindow_cachels or should we try and invalidate | 4138 will get deleted properly. */ |
4097 the cache at suitable points in redisplay? If we don't invalidate | |
4098 the cache it will fill up with crud that will only get removed when | |
4099 the frame is deleted. So invalidation is good, the question is when | |
4100 and whether we mark as well. Go for the simple option - don't mark, | |
4101 MARK_SUBWINDOWS_CHANGED when a subwindow gets deleted. */ | |
4102 | |
4103 void | |
4104 mark_subwindow_cachels (subwindow_cachel_dynarr *elements) | |
4105 { | |
4106 int elt; | |
4107 | |
4108 if (!elements) | |
4109 return; | |
4110 | |
4111 for (elt = 0; elt < Dynarr_length (elements); elt++) | |
4112 { | |
4113 struct subwindow_cachel *cachel = Dynarr_atp (elements, elt); | |
4114 mark_object (cachel->subwindow); | |
4115 } | |
4116 } | |
4117 | |
4118 static void | |
4119 update_subwindow_cachel_data (struct frame *f, Lisp_Object subwindow, | |
4120 struct subwindow_cachel *cachel) | |
4121 { | |
4122 cachel->subwindow = subwindow; | |
4123 cachel->width = XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow); | |
4124 cachel->height = XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow); | |
4125 cachel->updated = 1; | |
4126 } | |
4127 | |
4128 static void | |
4129 add_subwindow_cachel (struct frame *f, Lisp_Object subwindow) | |
4130 { | |
4131 struct subwindow_cachel new_cachel; | |
4132 | |
4133 xzero (new_cachel); | |
4134 new_cachel.subwindow = Qnil; | |
4135 new_cachel.x=0; | |
4136 new_cachel.y=0; | |
4137 new_cachel.being_displayed=0; | |
4138 | |
4139 update_subwindow_cachel_data (f, subwindow, &new_cachel); | |
4140 Dynarr_add (f->subwindow_cachels, new_cachel); | |
4141 } | |
4142 | |
4143 static int | |
4144 get_subwindow_cachel_index (struct frame *f, Lisp_Object subwindow) | |
4145 { | |
4146 int elt; | |
4147 | |
4148 if (noninteractive) | |
4149 return 0; | |
4150 | |
4151 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) | |
4152 { | |
4153 struct subwindow_cachel *cachel = | |
4154 Dynarr_atp (f->subwindow_cachels, elt); | |
4155 | |
4156 if (EQ (cachel->subwindow, subwindow) && !NILP (subwindow)) | |
4157 { | |
4158 if (!cachel->updated) | |
4159 update_subwindow_cachel_data (f, subwindow, cachel); | |
4160 return elt; | |
4161 } | |
4162 } | |
4163 | |
4164 /* If we didn't find the glyph, add it and then return its index. */ | |
4165 add_subwindow_cachel (f, subwindow); | |
4166 return elt; | |
4167 } | |
4168 | |
4169 static void | |
4170 update_subwindow_cachel (Lisp_Object subwindow) | |
4171 { | |
4172 struct frame* f; | |
4173 int elt; | |
4174 | |
4175 if (NILP (subwindow)) | |
4176 return; | |
4177 | |
4178 f = XFRAME ( XIMAGE_INSTANCE_SUBWINDOW_FRAME (subwindow)); | |
4179 | |
4180 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) | |
4181 { | |
4182 struct subwindow_cachel *cachel = | |
4183 Dynarr_atp (f->subwindow_cachels, elt); | |
4184 | |
4185 if (EQ (cachel->subwindow, subwindow) && !NILP (subwindow)) | |
4186 { | |
4187 update_subwindow_cachel_data (f, subwindow, cachel); | |
4188 } | |
4189 } | |
4190 } | |
4191 | 4139 |
4192 /* redisplay in general assumes that drawing something will erase | 4140 /* redisplay in general assumes that drawing something will erase |
4193 what was there before. unfortunately this does not apply to | 4141 what was there before. unfortunately this does not apply to |
4194 subwindows that need to be specifically unmapped in order to | 4142 subwindows that need to be specifically unmapped in order to |
4195 disappear. we take a brute force approach - on the basis that its | 4143 disappear. we take a brute force approach - on the basis that its |
4196 cheap - and unmap all subwindows in a display line */ | 4144 cheap - and unmap all subwindows in a display line */ |
4145 | |
4146 /* Put new instances in the frame subwindow cache. This is less costly than | |
4147 doing it every time something gets mapped, and deleted instances will be | |
4148 removed automatically. */ | |
4149 static void | |
4150 cache_subwindow_instance_in_frame_maybe (Lisp_Object instance) | |
4151 { | |
4152 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (instance); | |
4153 if (image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (ii)) | |
4154 & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK)) | |
4155 { | |
4156 struct frame* f = DOMAIN_XFRAME (IMAGE_INSTANCE_DOMAIN (ii)); | |
4157 XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)) | |
4158 = Fcons (instance, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))); | |
4159 } | |
4160 } | |
4161 | |
4162 /* Unmap and finalize all subwindow instances in the frame cache. This | |
4163 is necessary because GC will not guarantee the order things get | |
4164 deleted in and moreover, frame finalization deletes the window | |
4165 system windows before deleting XEmacs windows, and hence | |
4166 subwindows. */ | |
4197 void | 4167 void |
4198 reset_subwindow_cachels (struct frame *f) | 4168 free_frame_subwindow_instance_cache (struct frame* f) |
4199 { | 4169 { |
4200 int elt; | 4170 Lisp_Object rest; |
4201 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) | 4171 |
4202 { | 4172 LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))) |
4203 struct subwindow_cachel *cachel = | 4173 { |
4204 Dynarr_atp (f->subwindow_cachels, elt); | 4174 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (XCAR (rest)); |
4205 | 4175 /* Make sure that the subwindow is unmapped so that window |
4206 if (!NILP (cachel->subwindow) && cachel->being_displayed) | 4176 deletion will not try and do it again. */ |
4207 { | 4177 unmap_subwindow (XCAR (rest)); |
4208 cachel->updated = 1; | 4178 finalize_image_instance (ii, 0); |
4209 /* #### This is not optimal as update_subwindow will search | 4179 } |
4210 the cachels for ourselves as well. We could easily optimize. */ | 4180 } |
4211 unmap_subwindow (cachel->subwindow); | 4181 |
4212 } | 4182 /* Unmap and remove all instances from the frame cache. */ |
4213 } | |
4214 Dynarr_reset (f->subwindow_cachels); | |
4215 } | |
4216 | |
4217 void | 4183 void |
4218 mark_subwindow_cachels_as_not_updated (struct frame *f) | 4184 reset_frame_subwindow_instance_cache (struct frame* f) |
4219 { | 4185 { |
4220 int elt; | 4186 Lisp_Object rest; |
4221 | 4187 |
4222 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) | 4188 LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))) |
4223 Dynarr_atp (f->subwindow_cachels, elt)->updated = 0; | 4189 { |
4224 } | 4190 Lisp_Object value = XCAR (rest); |
4225 | 4191 /* Make sure that the subwindow is unmapped so that window |
4226 | 4192 deletion will not try and do it again. */ |
4193 unmap_subwindow (value); | |
4194 XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)) | |
4195 = delq_no_quit (value, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))); | |
4196 } | |
4197 } | |
4227 | 4198 |
4228 /***************************************************************************** | 4199 /***************************************************************************** |
4229 * subwindow exposure ignorance * | 4200 * subwindow exposure ignorance * |
4230 *****************************************************************************/ | 4201 *****************************************************************************/ |
4231 /* when we unmap subwindows the associated window system will generate | 4202 /* when we unmap subwindows the associated window system will generate |
4313 See if there is a subwindow that completely encloses the requested | 4284 See if there is a subwindow that completely encloses the requested |
4314 area. | 4285 area. |
4315 ****************************************************************************/ | 4286 ****************************************************************************/ |
4316 int find_matching_subwindow (struct frame* f, int x, int y, int width, int height) | 4287 int find_matching_subwindow (struct frame* f, int x, int y, int width, int height) |
4317 { | 4288 { |
4318 int elt; | 4289 Lisp_Object rest; |
4319 | 4290 |
4320 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) | 4291 LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))) |
4321 { | 4292 { |
4322 struct subwindow_cachel *cachel = | 4293 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (XCAR (rest)); |
4323 Dynarr_atp (f->subwindow_cachels, elt); | 4294 |
4324 | 4295 if (IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) |
4325 if (cachel->being_displayed | |
4326 && | 4296 && |
4327 cachel->x <= x && cachel->y <= y | 4297 IMAGE_INSTANCE_DISPLAY_X (ii) <= x |
4298 && | |
4299 IMAGE_INSTANCE_DISPLAY_Y (ii) <= y | |
4328 && | 4300 && |
4329 cachel->x + cachel->width >= x + width | 4301 IMAGE_INSTANCE_DISPLAY_X (ii) |
4302 + IMAGE_INSTANCE_DISPLAY_WIDTH (ii) >= x + width | |
4330 && | 4303 && |
4331 cachel->y + cachel->height >= y + height) | 4304 IMAGE_INSTANCE_DISPLAY_Y (ii) |
4305 + IMAGE_INSTANCE_DISPLAY_HEIGHT (ii) >= y + height) | |
4332 { | 4306 { |
4333 return 1; | 4307 return 1; |
4334 } | 4308 } |
4335 } | 4309 } |
4336 return 0; | 4310 return 0; |
4354 common for this function to get called from somewhere in | 4328 common for this function to get called from somewhere in |
4355 redisplay we need to make sure that quits are ignored. Otherwise | 4329 redisplay we need to make sure that quits are ignored. Otherwise |
4356 Fsignal will abort. */ | 4330 Fsignal will abort. */ |
4357 specbind (Qinhibit_quit, Qt); | 4331 specbind (Qinhibit_quit, Qt); |
4358 | 4332 |
4359 if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET | 4333 ERROR_CHECK_IMAGE_INSTANCE (subwindow); |
4360 || | 4334 |
4361 IMAGE_INSTANCE_TYPE (ii) == IMAGE_LAYOUT) | 4335 if (WIDGET_IMAGE_INSTANCEP (subwindow)) |
4362 { | 4336 { |
4363 if (image_instance_changed (subwindow)) | 4337 if (image_instance_changed (subwindow)) |
4364 update_widget (subwindow); | 4338 update_widget (subwindow); |
4365 /* Reset the changed flags. */ | 4339 /* Reset the changed flags. */ |
4366 IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) = 0; | 4340 IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) = 0; |
4367 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0; | 4341 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0; |
4368 IMAGE_INSTANCE_TEXT_CHANGED (ii) = 0; | 4342 IMAGE_INSTANCE_TEXT_CHANGED (ii) = 0; |
4369 } | 4343 } |
4370 else if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW | 4344 else if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW |
4371 && | 4345 && |
4372 !NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) | 4346 !NILP (IMAGE_INSTANCE_FRAME (ii))) |
4373 { | 4347 { |
4374 MAYBE_DEVMETH (XDEVICE (ii->device), update_subwindow, (ii)); | 4348 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), |
4349 update_subwindow, (ii)); | |
4375 } | 4350 } |
4376 | 4351 |
4377 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 0; | 4352 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 0; |
4378 /* This function is typically called by redisplay just before | 4353 /* This function is typically called by redisplay just before |
4379 outputting the information to the screen. Thus we record a hash | 4354 outputting the information to the screen. Thus we record a hash |
4396 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); | 4371 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); |
4397 | 4372 |
4398 if (internal_hash (subwindow, IMAGE_INSTANCE_HASH_DEPTH) != | 4373 if (internal_hash (subwindow, IMAGE_INSTANCE_HASH_DEPTH) != |
4399 IMAGE_INSTANCE_DISPLAY_HASH (ii)) | 4374 IMAGE_INSTANCE_DISPLAY_HASH (ii)) |
4400 return 1; | 4375 return 1; |
4401 else if ((WIDGET_IMAGE_INSTANCEP (subwindow) | 4376 /* #### I think there is probably a bug here. This gets called for |
4402 || LAYOUT_IMAGE_INSTANCEP (subwindow)) | 4377 layouts - and yet the pending items are always nil for |
4403 && !internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (ii), | 4378 layouts. We are saved by layout optimization, but I'm undecided |
4404 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii), 0)) | 4379 as to what the correct fix is. */ |
4380 else if (WIDGET_IMAGE_INSTANCEP (subwindow) | |
4381 && (!internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (ii), | |
4382 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii), 0) | |
4383 || !NILP (IMAGE_INSTANCE_LAYOUT_CHILDREN (ii)))) | |
4405 return 1; | 4384 return 1; |
4406 else | 4385 else |
4407 return 0; | 4386 return 0; |
4408 } | 4387 } |
4409 | 4388 |
4410 /* Update all the subwindows on a frame. */ | 4389 /* Update all the subwindows on a frame. */ |
4411 DEFUN ("update-widget-instances", Fupdate_widget_instances,1, 1, 0, /* | 4390 void |
4412 Given a FRAME, re-evaluate the display hash code for all widgets in the frame. | 4391 update_widget_instances (Lisp_Object frame) |
4413 Don't use this. | 4392 { |
4414 */ | |
4415 (frame)) | |
4416 { | |
4417 int elt; | |
4418 struct frame* f; | 4393 struct frame* f; |
4394 Lisp_Object rest; | |
4395 | |
4396 /* Its possible for the preceeding callback to have deleted the | |
4397 frame, so cope with this. */ | |
4398 if (!FRAMEP (frame) || !FRAME_LIVE_P (XFRAME (frame))) | |
4399 return; | |
4400 | |
4419 CHECK_FRAME (frame); | 4401 CHECK_FRAME (frame); |
4420 f = XFRAME (frame); | 4402 f = XFRAME (frame); |
4421 | 4403 |
4422 /* If we get called we know something has changed. */ | 4404 /* If we get called we know something has changed. */ |
4423 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) | 4405 LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))) |
4424 { | 4406 { |
4425 struct subwindow_cachel *cachel = | 4407 Lisp_Object widget = XCAR (rest); |
4426 Dynarr_atp (f->subwindow_cachels, elt); | 4408 |
4427 | 4409 if (XIMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (widget) |
4428 if (cachel->being_displayed && | 4410 && |
4429 image_instance_changed (cachel->subwindow)) | 4411 image_instance_changed (widget)) |
4430 { | 4412 { |
4431 set_image_instance_dirty_p (cachel->subwindow, 1); | 4413 set_image_instance_dirty_p (widget, 1); |
4432 MARK_FRAME_GLYPHS_CHANGED (f); | 4414 MARK_FRAME_GLYPHS_CHANGED (f); |
4433 } | 4415 } |
4434 } | 4416 } |
4435 return Qnil; | |
4436 } | 4417 } |
4437 | 4418 |
4438 /* remove a subwindow from its frame */ | 4419 /* remove a subwindow from its frame */ |
4439 void unmap_subwindow (Lisp_Object subwindow) | 4420 void unmap_subwindow (Lisp_Object subwindow) |
4440 { | 4421 { |
4441 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); | 4422 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); |
4442 int elt; | |
4443 struct subwindow_cachel* cachel; | |
4444 struct frame* f; | 4423 struct frame* f; |
4445 | 4424 |
4446 if (!(IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET | 4425 ERROR_CHECK_IMAGE_INSTANCE (subwindow); |
4447 || | 4426 |
4448 IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW) | 4427 if (!image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (ii)) |
4428 & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK) | |
4449 || | 4429 || |
4450 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) | 4430 !IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii)) |
4451 return; | 4431 return; |
4432 | |
4452 #ifdef DEBUG_WIDGETS | 4433 #ifdef DEBUG_WIDGETS |
4453 stderr_out ("unmapping subwindow %d\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii)); | 4434 stderr_out ("unmapping subwindow %d\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii)); |
4454 #endif | 4435 #endif |
4455 f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); | 4436 f = XFRAME (IMAGE_INSTANCE_FRAME (ii)); |
4456 elt = get_subwindow_cachel_index (f, subwindow); | |
4457 cachel = Dynarr_atp (f->subwindow_cachels, elt); | |
4458 | 4437 |
4459 /* make sure we don't get expose events */ | 4438 /* make sure we don't get expose events */ |
4460 register_ignored_expose (f, cachel->x, cachel->y, cachel->width, cachel->height); | 4439 register_ignored_expose (f, IMAGE_INSTANCE_DISPLAY_X (ii), |
4461 cachel->x = ~0; | 4440 IMAGE_INSTANCE_DISPLAY_Y (ii), |
4462 cachel->y = ~0; | 4441 IMAGE_INSTANCE_DISPLAY_WIDTH (ii), |
4463 cachel->being_displayed = 0; | 4442 IMAGE_INSTANCE_DISPLAY_HEIGHT (ii)); |
4464 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; | 4443 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; |
4465 | 4444 |
4466 MAYBE_DEVMETH (XDEVICE (ii->device), unmap_subwindow, (ii)); | 4445 MAYBE_DEVMETH (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)), |
4446 unmap_subwindow, (ii)); | |
4467 } | 4447 } |
4468 | 4448 |
4469 /* show a subwindow in its frame */ | 4449 /* show a subwindow in its frame */ |
4470 void map_subwindow (Lisp_Object subwindow, int x, int y, | 4450 void map_subwindow (Lisp_Object subwindow, int x, int y, |
4471 struct display_glyph_area *dga) | 4451 struct display_glyph_area *dga) |
4472 { | 4452 { |
4473 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); | 4453 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); |
4474 int elt; | |
4475 struct subwindow_cachel* cachel; | |
4476 struct frame* f; | 4454 struct frame* f; |
4477 | 4455 |
4478 if (!(IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET | 4456 ERROR_CHECK_IMAGE_INSTANCE (subwindow); |
4479 || | 4457 |
4480 IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW) | 4458 if (!image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (ii)) |
4481 || | 4459 & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK)) |
4482 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) | |
4483 return; | 4460 return; |
4484 | 4461 |
4485 #ifdef DEBUG_WIDGETS | 4462 #ifdef DEBUG_WIDGETS |
4486 stderr_out ("mapping subwindow %d, %dx%d@%d+%d\n", | 4463 stderr_out ("mapping subwindow %d, %dx%d@%d+%d\n", |
4487 IMAGE_INSTANCE_SUBWINDOW_ID (ii), | 4464 IMAGE_INSTANCE_SUBWINDOW_ID (ii), |
4488 dga->width, dga->height, x, y); | 4465 dga->width, dga->height, x, y); |
4489 #endif | 4466 #endif |
4490 f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); | 4467 f = XFRAME (IMAGE_INSTANCE_FRAME (ii)); |
4491 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 1; | 4468 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 1; |
4492 elt = get_subwindow_cachel_index (f, subwindow); | 4469 IMAGE_INSTANCE_DISPLAY_X (ii) = x; |
4493 cachel = Dynarr_atp (f->subwindow_cachels, elt); | 4470 IMAGE_INSTANCE_DISPLAY_Y (ii) = y; |
4494 cachel->x = x; | 4471 IMAGE_INSTANCE_DISPLAY_WIDTH (ii) = dga->width; |
4495 cachel->y = y; | 4472 IMAGE_INSTANCE_DISPLAY_HEIGHT (ii) = dga->height; |
4496 cachel->width = dga->width; | 4473 |
4497 cachel->height = dga->height; | 4474 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), |
4498 cachel->being_displayed = 1; | 4475 map_subwindow, (ii, x, y, dga)); |
4499 | |
4500 MAYBE_DEVMETH (XDEVICE (ii->device), map_subwindow, (ii, x, y, dga)); | |
4501 } | 4476 } |
4502 | 4477 |
4503 static int | 4478 static int |
4504 subwindow_possible_dest_types (void) | 4479 subwindow_possible_dest_types (void) |
4505 { | 4480 { |
4506 return IMAGE_SUBWINDOW_MASK; | 4481 return IMAGE_SUBWINDOW_MASK; |
4482 } | |
4483 | |
4484 int | |
4485 subwindow_governing_domain (void) | |
4486 { | |
4487 return GOVERNING_DOMAIN_WINDOW; | |
4507 } | 4488 } |
4508 | 4489 |
4509 /* Partially instantiate a subwindow. */ | 4490 /* Partially instantiate a subwindow. */ |
4510 void | 4491 void |
4511 subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | 4492 subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, |
4512 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 4493 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
4513 int dest_mask, Lisp_Object domain) | 4494 int dest_mask, Lisp_Object domain) |
4514 { | 4495 { |
4515 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | 4496 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
4516 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | 4497 Lisp_Object device = image_instance_device (image_instance); |
4517 Lisp_Object frame = FW_FRAME (domain); | 4498 Lisp_Object frame = DOMAIN_FRAME (domain); |
4518 Lisp_Object width = find_keyword_in_vector (instantiator, Q_pixel_width); | 4499 Lisp_Object width = find_keyword_in_vector (instantiator, Q_pixel_width); |
4519 Lisp_Object height = find_keyword_in_vector (instantiator, Q_pixel_height); | 4500 Lisp_Object height = find_keyword_in_vector (instantiator, Q_pixel_height); |
4520 | 4501 |
4521 if (NILP (frame)) | 4502 if (NILP (frame)) |
4522 signal_simple_error ("No selected frame", device); | 4503 signal_simple_error ("No selected frame", device); |
4525 incompatible_image_types (instantiator, dest_mask, IMAGE_SUBWINDOW_MASK); | 4506 incompatible_image_types (instantiator, dest_mask, IMAGE_SUBWINDOW_MASK); |
4526 | 4507 |
4527 ii->data = 0; | 4508 ii->data = 0; |
4528 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0; | 4509 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0; |
4529 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; | 4510 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; |
4530 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = frame; | 4511 |
4531 | |
4532 /* #### This stuff may get overidden by the widget code and is | |
4533 actually really dumb now that we have dynamic geometry | |
4534 calculations. What should really happen is that the subwindow | |
4535 should query its child for an appropriate geometry. */ | |
4536 if (INTP (width)) | 4512 if (INTP (width)) |
4537 { | 4513 { |
4538 int w = 1; | 4514 int w = 1; |
4539 if (XINT (width) > 1) | 4515 if (XINT (width) > 1) |
4540 w = XINT (width); | 4516 w = XINT (width); |
4541 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = w; | 4517 IMAGE_INSTANCE_WIDTH (ii) = w; |
4542 } | 4518 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0; |
4543 else | 4519 } |
4544 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = 20; | |
4545 | 4520 |
4546 if (INTP (height)) | 4521 if (INTP (height)) |
4547 { | 4522 { |
4548 int h = 1; | 4523 int h = 1; |
4549 if (XINT (height) > 1) | 4524 if (XINT (height) > 1) |
4550 h = XINT (height); | 4525 h = XINT (height); |
4551 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = h; | 4526 IMAGE_INSTANCE_HEIGHT (ii) = h; |
4552 } | 4527 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0; |
4553 else | 4528 } |
4554 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = 20; | 4529 } |
4530 | |
4531 /* This is just a backup in case no-one has assigned a suitable geometry. | |
4532 #### It should really query the enclose window for geometry. */ | |
4533 static void | |
4534 subwindow_query_geometry (Lisp_Object image_instance, unsigned int* width, | |
4535 unsigned int* height, enum image_instance_geometry disp, | |
4536 Lisp_Object domain) | |
4537 { | |
4538 if (width) *width = 20; | |
4539 if (height) *height = 20; | |
4555 } | 4540 } |
4556 | 4541 |
4557 DEFUN ("subwindowp", Fsubwindowp, 1, 1, 0, /* | 4542 DEFUN ("subwindowp", Fsubwindowp, 1, 1, 0, /* |
4558 Return non-nil if OBJECT is a subwindow. | 4543 Return non-nil if OBJECT is a subwindow. |
4559 */ | 4544 */ |
4597 /* The actual resizing gets done asychronously by | 4582 /* The actual resizing gets done asychronously by |
4598 update_subwindow. */ | 4583 update_subwindow. */ |
4599 IMAGE_INSTANCE_HEIGHT (ii) = newh; | 4584 IMAGE_INSTANCE_HEIGHT (ii) = newh; |
4600 IMAGE_INSTANCE_WIDTH (ii) = neww; | 4585 IMAGE_INSTANCE_WIDTH (ii) = neww; |
4601 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 1; | 4586 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 1; |
4602 | |
4603 /* need to update the cachels as redisplay will not do this */ | |
4604 update_subwindow_cachel (subwindow); | |
4605 | 4587 |
4606 return subwindow; | 4588 return subwindow; |
4607 } | 4589 } |
4608 | 4590 |
4609 DEFUN ("force-subwindow-map", Fforce_subwindow_map, 1, 1, 0, /* | 4591 DEFUN ("force-subwindow-map", Fforce_subwindow_map, 1, 1, 0, /* |
4734 (IMAGE_INSTANCE_PIXMAP_SLICE (ii) + 1) | 4716 (IMAGE_INSTANCE_PIXMAP_SLICE (ii) + 1) |
4735 % IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii); | 4717 % IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii); |
4736 /* We might need to kick redisplay at this point - but we | 4718 /* We might need to kick redisplay at this point - but we |
4737 also might not. */ | 4719 also might not. */ |
4738 MARK_DEVICE_FRAMES_GLYPHS_CHANGED | 4720 MARK_DEVICE_FRAMES_GLYPHS_CHANGED |
4739 (XDEVICE (IMAGE_INSTANCE_DEVICE (ii))); | 4721 (XDEVICE (image_instance_device (value))); |
4740 /* Cascade dirtiness so that we can have an animated glyph in a layout | 4722 /* Cascade dirtiness so that we can have an animated glyph in a layout |
4741 for instance. */ | 4723 for instance. */ |
4742 set_image_instance_dirty_p (value, 1); | 4724 set_image_instance_dirty_p (value, 1); |
4743 } | 4725 } |
4744 } | 4726 } |
4791 | 4773 |
4792 DEFSUBR (Fimage_instantiator_format_list); | 4774 DEFSUBR (Fimage_instantiator_format_list); |
4793 DEFSUBR (Fvalid_image_instantiator_format_p); | 4775 DEFSUBR (Fvalid_image_instantiator_format_p); |
4794 DEFSUBR (Fset_console_type_image_conversion_list); | 4776 DEFSUBR (Fset_console_type_image_conversion_list); |
4795 DEFSUBR (Fconsole_type_image_conversion_list); | 4777 DEFSUBR (Fconsole_type_image_conversion_list); |
4796 DEFSUBR (Fupdate_widget_instances); | |
4797 | 4778 |
4798 defkeyword (&Q_file, ":file"); | 4779 defkeyword (&Q_file, ":file"); |
4799 defkeyword (&Q_data, ":data"); | 4780 defkeyword (&Q_data, ":data"); |
4800 defkeyword (&Q_face, ":face"); | 4781 defkeyword (&Q_face, ":face"); |
4801 defkeyword (&Q_pixel_height, ":pixel-height"); | 4782 defkeyword (&Q_pixel_height, ":pixel-height"); |
4826 defsymbol (&Qmono_pixmap_image_instance_p, "mono-pixmap-image-instance-p"); | 4807 defsymbol (&Qmono_pixmap_image_instance_p, "mono-pixmap-image-instance-p"); |
4827 defsymbol (&Qcolor_pixmap_image_instance_p, "color-pixmap-image-instance-p"); | 4808 defsymbol (&Qcolor_pixmap_image_instance_p, "color-pixmap-image-instance-p"); |
4828 defsymbol (&Qpointer_image_instance_p, "pointer-image-instance-p"); | 4809 defsymbol (&Qpointer_image_instance_p, "pointer-image-instance-p"); |
4829 defsymbol (&Qwidget_image_instance_p, "widget-image-instance-p"); | 4810 defsymbol (&Qwidget_image_instance_p, "widget-image-instance-p"); |
4830 defsymbol (&Qsubwindow_image_instance_p, "subwindow-image-instance-p"); | 4811 defsymbol (&Qsubwindow_image_instance_p, "subwindow-image-instance-p"); |
4831 defsymbol (&Qlayout_image_instance_p, "layout-image-instance-p"); | |
4832 defsymbol (&Qupdate_widget_instances, "update-widget-instances"); | |
4833 | 4812 |
4834 DEFSUBR (Fmake_image_instance); | 4813 DEFSUBR (Fmake_image_instance); |
4835 DEFSUBR (Fimage_instance_p); | 4814 DEFSUBR (Fimage_instance_p); |
4836 DEFSUBR (Fimage_instance_type); | 4815 DEFSUBR (Fimage_instance_type); |
4837 DEFSUBR (Fvalid_image_instance_type_p); | 4816 DEFSUBR (Fvalid_image_instance_type_p); |
4838 DEFSUBR (Fimage_instance_type_list); | 4817 DEFSUBR (Fimage_instance_type_list); |
4839 DEFSUBR (Fimage_instance_name); | 4818 DEFSUBR (Fimage_instance_name); |
4819 DEFSUBR (Fimage_instance_domain); | |
4840 DEFSUBR (Fimage_instance_string); | 4820 DEFSUBR (Fimage_instance_string); |
4841 DEFSUBR (Fimage_instance_file_name); | 4821 DEFSUBR (Fimage_instance_file_name); |
4842 DEFSUBR (Fimage_instance_mask_file_name); | 4822 DEFSUBR (Fimage_instance_mask_file_name); |
4843 DEFSUBR (Fimage_instance_depth); | 4823 DEFSUBR (Fimage_instance_depth); |
4844 DEFSUBR (Fimage_instance_height); | 4824 DEFSUBR (Fimage_instance_height); |
5013 IIFORMAT_VALID_KEYWORD (inherit, Q_face, check_valid_face); | 4993 IIFORMAT_VALID_KEYWORD (inherit, Q_face, check_valid_face); |
5014 | 4994 |
5015 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (string, "string"); | 4995 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (string, "string"); |
5016 | 4996 |
5017 IIFORMAT_HAS_METHOD (string, validate); | 4997 IIFORMAT_HAS_METHOD (string, validate); |
4998 IIFORMAT_HAS_SHARED_METHOD (string, governing_domain, subwindow); | |
5018 IIFORMAT_HAS_METHOD (string, possible_dest_types); | 4999 IIFORMAT_HAS_METHOD (string, possible_dest_types); |
5019 IIFORMAT_HAS_METHOD (string, instantiate); | 5000 IIFORMAT_HAS_METHOD (string, instantiate); |
5020 | 5001 |
5021 IIFORMAT_VALID_KEYWORD (string, Q_data, check_valid_string); | 5002 IIFORMAT_VALID_KEYWORD (string, Q_data, check_valid_string); |
5022 /* Do this so we can set strings. */ | 5003 /* Do this so we can set strings. */ |
5004 /* #### Andy, what is this? This is a bogus format and should not be | |
5005 visible to the user. */ | |
5023 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (text, "text"); | 5006 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (text, "text"); |
5024 IIFORMAT_HAS_METHOD (text, set_property); | 5007 IIFORMAT_HAS_METHOD (text, set_property); |
5025 IIFORMAT_HAS_METHOD (text, query_geometry); | 5008 IIFORMAT_HAS_METHOD (text, query_geometry); |
5026 | 5009 |
5027 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (formatted_string, "formatted-string"); | 5010 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (formatted_string, "formatted-string"); |
5029 IIFORMAT_HAS_METHOD (formatted_string, validate); | 5012 IIFORMAT_HAS_METHOD (formatted_string, validate); |
5030 IIFORMAT_HAS_METHOD (formatted_string, possible_dest_types); | 5013 IIFORMAT_HAS_METHOD (formatted_string, possible_dest_types); |
5031 IIFORMAT_HAS_METHOD (formatted_string, instantiate); | 5014 IIFORMAT_HAS_METHOD (formatted_string, instantiate); |
5032 IIFORMAT_VALID_KEYWORD (formatted_string, Q_data, check_valid_string); | 5015 IIFORMAT_VALID_KEYWORD (formatted_string, Q_data, check_valid_string); |
5033 | 5016 |
5017 /* Do this so pointers have geometry. */ | |
5018 /* #### Andy, what is this? This is a bogus format and should not be | |
5019 visible to the user. */ | |
5020 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (pointer, "pointer"); | |
5021 IIFORMAT_HAS_SHARED_METHOD (pointer, query_geometry, subwindow); | |
5022 | |
5034 /* subwindows */ | 5023 /* subwindows */ |
5035 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (subwindow, "subwindow"); | 5024 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (subwindow, "subwindow"); |
5036 IIFORMAT_HAS_METHOD (subwindow, possible_dest_types); | 5025 IIFORMAT_HAS_METHOD (subwindow, possible_dest_types); |
5026 IIFORMAT_HAS_METHOD (subwindow, governing_domain); | |
5037 IIFORMAT_HAS_METHOD (subwindow, instantiate); | 5027 IIFORMAT_HAS_METHOD (subwindow, instantiate); |
5028 IIFORMAT_HAS_METHOD (subwindow, query_geometry); | |
5038 IIFORMAT_VALID_KEYWORD (subwindow, Q_pixel_width, check_valid_int); | 5029 IIFORMAT_VALID_KEYWORD (subwindow, Q_pixel_width, check_valid_int); |
5039 IIFORMAT_VALID_KEYWORD (subwindow, Q_pixel_height, check_valid_int); | 5030 IIFORMAT_VALID_KEYWORD (subwindow, Q_pixel_height, check_valid_int); |
5040 | 5031 |
5041 #ifdef HAVE_WINDOW_SYSTEM | 5032 #ifdef HAVE_WINDOW_SYSTEM |
5042 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xbm, "xbm"); | 5033 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xbm, "xbm"); |
5179 /* display tables */ | 5170 /* display tables */ |
5180 | 5171 |
5181 DEFVAR_SPECIFIER ("current-display-table", &Vcurrent_display_table /* | 5172 DEFVAR_SPECIFIER ("current-display-table", &Vcurrent_display_table /* |
5182 *The display table currently in use. | 5173 *The display table currently in use. |
5183 This is a specifier; use `set-specifier' to change it. | 5174 This is a specifier; use `set-specifier' to change it. |
5184 The display table is a vector created with `make-display-table'. | 5175 |
5185 The 256 elements control how to display each possible text character. | 5176 Display tables are used to control how characters are displayed. Each |
5186 Each value should be a string, a glyph, a vector or nil. | 5177 time that redisplay processes a character, it is looked up in all the |
5187 If a value is a vector it must be composed only of strings and glyphs. | 5178 display tables that apply (obtained by calling `specifier-instance' on |
5188 nil means display the character in the default fashion. | 5179 `current-display-table' and any overriding display tables specified in |
5189 Faces can have their own, overriding display table. | 5180 currently active faces). The first entry found that matches the |
5181 character determines how the character is displayed. If there is no | |
5182 matching entry, the default display method is used. (Non-control | |
5183 characters are displayed as themselves and control characters are | |
5184 displayed according to the buffer-local variable `ctl-arrow'. Control | |
5185 characters are further affected by `control-arrow-glyph' and | |
5186 `octal-escape-glyph'.) | |
5187 | |
5188 Each instantiator in this specifier and the display-table specifiers | |
5189 in faces is a display table or a list of such tables. If a list, each | |
5190 table will be searched in turn for an entry matching a particular | |
5191 character. Each display table is one of | |
5192 | |
5193 -- a vector, specifying values for characters starting at 0 | |
5194 -- a char table, either of type `char' or `generic' | |
5195 -- a range table | |
5196 | |
5197 Each entry in a display table should be one of | |
5198 | |
5199 -- nil (this entry is ignored and the search continues) | |
5200 -- a character (use this character; if it happens to be the same as | |
5201 the original character, default processing happens, otherwise | |
5202 redisplay attempts to display this character directly; | |
5203 #### At some point recursive display-table lookup will be | |
5204 implemented.) | |
5205 -- a string (display each character in the string directly; | |
5206 #### At some point recursive display-table lookup will be | |
5207 implemented.) | |
5208 -- a glyph (display the glyph; | |
5209 #### At some point recursive display-table lookup will be | |
5210 implemented when a string glyph is being processed.) | |
5211 -- a cons of the form (format "STRING") where STRING is a printf-like | |
5212 spec used to process the character. #### Unfortunately no | |
5213 formatting directives other than %% are implemented. | |
5214 -- a vector (each element of the vector is processed recursively; | |
5215 in such a case, nil elements in the vector are simply ignored) | |
5216 | |
5217 #### At some point in the near future, display tables are likely to | |
5218 be expanded to include other features, such as referencing characters | |
5219 in particular fonts and allowing the character search to continue | |
5220 all the way up the chain of specifier instantiators. These features | |
5221 are necessary to properly display Unicode characters. | |
5190 */ ); | 5222 */ ); |
5191 Vcurrent_display_table = Fmake_specifier (Qdisplay_table); | 5223 Vcurrent_display_table = Fmake_specifier (Qdisplay_table); |
5192 set_specifier_fallback (Vcurrent_display_table, | 5224 set_specifier_fallback (Vcurrent_display_table, |
5193 list1 (Fcons (Qnil, Qnil))); | 5225 list1 (Fcons (Qnil, Qnil))); |
5194 set_specifier_caching (Vcurrent_display_table, | 5226 set_specifier_caching (Vcurrent_display_table, |