Mercurial > hg > xemacs-beta
comparison src/glyphs.c @ 398:74fd4e045ea6 r21-2-29
Import from CVS: tag r21-2-29
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:13:30 +0200 |
parents | aabb7f5b1c81 |
children | a86b2b5e0111 |
comparison
equal
deleted
inserted
replaced
397:f4aeb21a5bad | 398:74fd4e045ea6 |
---|---|
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 Ben Wing |
5 Copyright (C) 1995 Sun Microsystems | 5 Copyright (C) 1995 Sun Microsystems |
6 Copyright (C) 1998 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 |
10 XEmacs is free software; you can redistribute it and/or modify it | 10 XEmacs is free software; you can redistribute it and/or modify it |
11 under the terms of the GNU General Public License as published by the | 11 under the terms of the GNU General Public License as published by the |
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
23 Boston, MA 02111-1307, USA. */ | 23 Boston, MA 02111-1307, USA. */ |
24 | 24 |
25 /* Synched up with: Not in FSF. */ | 25 /* Synched up with: Not in FSF. */ |
26 | 26 |
27 /* Written by Ben Wing and Chuck Thompson */ | 27 /* Written by Ben Wing and Chuck Thompson. Heavily modified / |
28 rewritten by Andy Piper. */ | |
28 | 29 |
29 #include <config.h> | 30 #include <config.h> |
30 #include "lisp.h" | 31 #include "lisp.h" |
31 | 32 |
32 #include "buffer.h" | 33 #include "buffer.h" |
40 #include "redisplay.h" | 41 #include "redisplay.h" |
41 #include "window.h" | 42 #include "window.h" |
42 #include "frame.h" | 43 #include "frame.h" |
43 #include "chartab.h" | 44 #include "chartab.h" |
44 #include "rangetab.h" | 45 #include "rangetab.h" |
46 #include "blocktype.h" | |
45 | 47 |
46 #ifdef HAVE_XPM | 48 #ifdef HAVE_XPM |
47 #include <X11/xpm.h> | 49 #include <X11/xpm.h> |
48 #endif | 50 #endif |
49 | 51 |
54 Lisp_Object Qnothing_image_instance_p, Qtext_image_instance_p; | 56 Lisp_Object Qnothing_image_instance_p, Qtext_image_instance_p; |
55 Lisp_Object Qmono_pixmap_image_instance_p; | 57 Lisp_Object Qmono_pixmap_image_instance_p; |
56 Lisp_Object Qcolor_pixmap_image_instance_p; | 58 Lisp_Object Qcolor_pixmap_image_instance_p; |
57 Lisp_Object Qpointer_image_instance_p; | 59 Lisp_Object Qpointer_image_instance_p; |
58 Lisp_Object Qsubwindow_image_instance_p; | 60 Lisp_Object Qsubwindow_image_instance_p; |
61 Lisp_Object Qlayout_image_instance_p; | |
59 Lisp_Object Qwidget_image_instance_p; | 62 Lisp_Object Qwidget_image_instance_p; |
60 Lisp_Object Qconst_glyph_variable; | 63 Lisp_Object Qconst_glyph_variable; |
61 Lisp_Object Qmono_pixmap, Qcolor_pixmap, Qsubwindow; | 64 Lisp_Object Qmono_pixmap, Qcolor_pixmap, Qsubwindow; |
62 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; |
63 Lisp_Object Qformatted_string; | 66 Lisp_Object Qformatted_string; |
68 Lisp_Object Vthe_nothing_vector; | 71 Lisp_Object Vthe_nothing_vector; |
69 Lisp_Object Vimage_instantiator_format_list; | 72 Lisp_Object Vimage_instantiator_format_list; |
70 Lisp_Object Vimage_instance_type_list; | 73 Lisp_Object Vimage_instance_type_list; |
71 Lisp_Object Vglyph_type_list; | 74 Lisp_Object Vglyph_type_list; |
72 | 75 |
76 int disable_animated_pixmaps; | |
77 | |
73 DEFINE_IMAGE_INSTANTIATOR_FORMAT (nothing); | 78 DEFINE_IMAGE_INSTANTIATOR_FORMAT (nothing); |
74 DEFINE_IMAGE_INSTANTIATOR_FORMAT (inherit); | 79 DEFINE_IMAGE_INSTANTIATOR_FORMAT (inherit); |
75 DEFINE_IMAGE_INSTANTIATOR_FORMAT (string); | 80 DEFINE_IMAGE_INSTANTIATOR_FORMAT (string); |
76 DEFINE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); | 81 DEFINE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); |
77 DEFINE_IMAGE_INSTANTIATOR_FORMAT (subwindow); | 82 DEFINE_IMAGE_INSTANTIATOR_FORMAT (subwindow); |
83 DEFINE_IMAGE_INSTANTIATOR_FORMAT (text); | |
78 | 84 |
79 #ifdef HAVE_WINDOW_SYSTEM | 85 #ifdef HAVE_WINDOW_SYSTEM |
80 DEFINE_IMAGE_INSTANTIATOR_FORMAT (xbm); | 86 DEFINE_IMAGE_INSTANTIATOR_FORMAT (xbm); |
81 Lisp_Object Qxbm; | 87 Lisp_Object Qxbm; |
82 | 88 |
115 } image_instantiator_format_entry_dynarr; | 121 } image_instantiator_format_entry_dynarr; |
116 | 122 |
117 image_instantiator_format_entry_dynarr * | 123 image_instantiator_format_entry_dynarr * |
118 the_image_instantiator_format_entry_dynarr; | 124 the_image_instantiator_format_entry_dynarr; |
119 | 125 |
120 static Lisp_Object allocate_image_instance (Lisp_Object device); | 126 static Lisp_Object allocate_image_instance (Lisp_Object device, Lisp_Object glyph); |
121 static void image_validate (Lisp_Object instantiator); | 127 static void image_validate (Lisp_Object instantiator); |
122 static void glyph_property_was_changed (Lisp_Object glyph, | 128 static void glyph_property_was_changed (Lisp_Object glyph, |
123 Lisp_Object property, | 129 Lisp_Object property, |
124 Lisp_Object locale); | 130 Lisp_Object locale); |
131 static void set_image_instance_dirty_p (Lisp_Object instance, int dirty); | |
132 static void register_ignored_expose (struct frame* f, int x, int y, int width, int height); | |
133 /* Unfortunately windows and X are different. In windows BeginPaint() | |
134 will prevent WM_PAINT messages being generated so it is unnecessary | |
135 to register exposures as they will not occur. Under X they will | |
136 always occur. */ | |
137 int hold_ignored_expose_registration; | |
138 | |
125 EXFUN (Fimage_instance_type, 1); | 139 EXFUN (Fimage_instance_type, 1); |
126 EXFUN (Fglyph_type, 1); | 140 EXFUN (Fglyph_type, 1); |
127 | 141 |
128 | 142 |
129 /**************************************************************************** | 143 /**************************************************************************** |
153 Lisp_Object d = Dynarr_at (the_image_instantiator_format_entry_dynarr, i). | 167 Lisp_Object d = Dynarr_at (the_image_instantiator_format_entry_dynarr, i). |
154 device; | 168 device; |
155 if ((NILP (d) && NILP (device)) | 169 if ((NILP (d) && NILP (device)) |
156 || | 170 || |
157 (!NILP (device) && | 171 (!NILP (device) && |
158 EQ (CONSOLE_TYPE (XCONSOLE | 172 EQ (CONSOLE_TYPE (XCONSOLE |
159 (DEVICE_CONSOLE (XDEVICE (device)))), d))) | 173 (DEVICE_CONSOLE (XDEVICE (device)))), d))) |
160 return Dynarr_at (the_image_instantiator_format_entry_dynarr, i).meths; | 174 return Dynarr_at (the_image_instantiator_format_entry_dynarr, i).meths; |
161 } | 175 } |
162 } | 176 } |
163 | 177 |
172 { | 186 { |
173 return decode_device_ii_format (Qnil, format, errb); | 187 return decode_device_ii_format (Qnil, format, errb); |
174 } | 188 } |
175 | 189 |
176 static int | 190 static int |
177 valid_image_instantiator_format_p (Lisp_Object format) | 191 valid_image_instantiator_format_p (Lisp_Object format, Lisp_Object locale) |
178 { | 192 { |
179 return (decode_image_instantiator_format (format, ERROR_ME_NOT) != 0); | 193 int i; |
194 struct image_instantiator_methods* meths = | |
195 decode_image_instantiator_format (format, ERROR_ME_NOT); | |
196 Lisp_Object contype = Qnil; | |
197 /* mess with the locale */ | |
198 if (!NILP (locale) && SYMBOLP (locale)) | |
199 contype = locale; | |
200 else | |
201 { | |
202 struct console* console = decode_console (locale); | |
203 contype = console ? CONSOLE_TYPE (console) : locale; | |
204 } | |
205 /* nothing is valid in all locales */ | |
206 if (EQ (format, Qnothing)) | |
207 return 1; | |
208 /* reject unknown formats */ | |
209 else if (NILP (contype) || !meths) | |
210 return 0; | |
211 | |
212 for (i = 0; i < Dynarr_length (meths->consoles); i++) | |
213 if (EQ (contype, Dynarr_at (meths->consoles, i).symbol)) | |
214 return 1; | |
215 return 0; | |
180 } | 216 } |
181 | 217 |
182 DEFUN ("valid-image-instantiator-format-p", Fvalid_image_instantiator_format_p, | 218 DEFUN ("valid-image-instantiator-format-p", Fvalid_image_instantiator_format_p, |
183 1, 1, 0, /* | 219 1, 2, 0, /* |
184 Given an IMAGE-INSTANTIATOR-FORMAT, return non-nil if it is valid. | 220 Given an IMAGE-INSTANTIATOR-FORMAT, return non-nil if it is valid. |
221 If LOCALE is non-nil then the format is checked in that domain. | |
222 If LOCALE is nil the current console is used. | |
185 Valid formats are some subset of 'nothing, 'string, 'formatted-string, | 223 Valid formats are some subset of 'nothing, 'string, 'formatted-string, |
186 'xpm, 'xbm, 'xface, 'gif, 'jpeg, 'png, 'tiff, 'cursor-font, 'font, | 224 'xpm, 'xbm, 'xface, 'gif, 'jpeg, 'png, 'tiff, 'cursor-font, 'font, |
187 'autodetect, 'widget and 'subwindow, depending on how XEmacs was compiled. | 225 'autodetect, 'widget and 'subwindow, depending on how XEmacs was compiled. |
188 */ | 226 */ |
189 (image_instantiator_format)) | 227 (image_instantiator_format, locale)) |
190 { | 228 { |
191 return valid_image_instantiator_format_p (image_instantiator_format) ? | 229 return valid_image_instantiator_format_p (image_instantiator_format, locale) ? |
192 Qt : Qnil; | 230 Qt : Qnil; |
193 } | 231 } |
194 | 232 |
195 DEFUN ("image-instantiator-format-list", Fimage_instantiator_format_list, | 233 DEFUN ("image-instantiator-format-list", Fimage_instantiator_format_list, |
196 0, 0, 0, /* | 234 0, 0, 0, /* |
524 { | 562 { |
525 struct gcpro gcpro1; | 563 struct gcpro gcpro1; |
526 struct image_instantiator_methods *meths; | 564 struct image_instantiator_methods *meths; |
527 | 565 |
528 GCPRO1 (instantiator); | 566 GCPRO1 (instantiator); |
529 | 567 |
530 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], | 568 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], |
531 ERROR_ME); | 569 ERROR_ME); |
532 RETURN_UNGCPRO (IIFORMAT_METH_OR_GIVEN (meths, normalize, | 570 RETURN_UNGCPRO (IIFORMAT_METH_OR_GIVEN (meths, normalize, |
533 (instantiator, contype), | 571 (instantiator, contype), |
534 instantiator)); | 572 instantiator)); |
537 | 575 |
538 static Lisp_Object | 576 static Lisp_Object |
539 instantiate_image_instantiator (Lisp_Object device, Lisp_Object domain, | 577 instantiate_image_instantiator (Lisp_Object device, Lisp_Object domain, |
540 Lisp_Object instantiator, | 578 Lisp_Object instantiator, |
541 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 579 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
542 int dest_mask) | 580 int dest_mask, Lisp_Object glyph) |
543 { | 581 { |
544 Lisp_Object ii = allocate_image_instance (device); | 582 Lisp_Object ii = allocate_image_instance (device, glyph); |
545 struct image_instantiator_methods *meths; | 583 struct image_instantiator_methods *meths; |
546 struct gcpro gcpro1; | 584 struct gcpro gcpro1; |
547 int methp = 0; | 585 int methp = 0; |
548 | 586 |
549 GCPRO1 (ii); | 587 GCPRO1 (ii); |
588 if (!valid_image_instantiator_format_p (XVECTOR_DATA (instantiator)[0], device)) | |
589 signal_simple_error | |
590 ("Image instantiator format is invalid in this locale.", | |
591 instantiator); | |
592 | |
550 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], | 593 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], |
551 ERROR_ME); | 594 ERROR_ME); |
552 methp = (int)HAS_IIFORMAT_METH_P (meths, instantiate); | 595 methp = (int)HAS_IIFORMAT_METH_P (meths, instantiate); |
553 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg, | 596 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg, |
554 pointer_bg, dest_mask, domain)); | 597 pointer_bg, dest_mask, domain)); |
555 | 598 |
556 /* now do device specific instantiation */ | 599 /* now do device specific instantiation */ |
557 meths = decode_device_ii_format (device, XVECTOR_DATA (instantiator)[0], | 600 meths = decode_device_ii_format (device, XVECTOR_DATA (instantiator)[0], |
558 ERROR_ME_NOT); | 601 ERROR_ME_NOT); |
559 | 602 |
560 if (!methp && (!meths || !HAS_IIFORMAT_METH_P (meths, instantiate))) | 603 if (!methp && (!meths || !HAS_IIFORMAT_METH_P (meths, instantiate))) |
574 ****************************************************************************/ | 617 ****************************************************************************/ |
575 | 618 |
576 Lisp_Object Qimage_instancep; | 619 Lisp_Object Qimage_instancep; |
577 | 620 |
578 static Lisp_Object | 621 static Lisp_Object |
579 mark_image_instance (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 622 mark_image_instance (Lisp_Object obj) |
580 { | 623 { |
581 struct Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); | 624 Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); |
582 | 625 |
583 markobj (i->name); | 626 mark_object (i->name); |
627 /* We don't mark the glyph reference since that would create a | |
628 circularity preventing GC. */ | |
584 switch (IMAGE_INSTANCE_TYPE (i)) | 629 switch (IMAGE_INSTANCE_TYPE (i)) |
585 { | 630 { |
586 case IMAGE_TEXT: | 631 case IMAGE_TEXT: |
587 markobj (IMAGE_INSTANCE_TEXT_STRING (i)); | 632 mark_object (IMAGE_INSTANCE_TEXT_STRING (i)); |
588 break; | 633 break; |
589 case IMAGE_MONO_PIXMAP: | 634 case IMAGE_MONO_PIXMAP: |
590 case IMAGE_COLOR_PIXMAP: | 635 case IMAGE_COLOR_PIXMAP: |
591 markobj (IMAGE_INSTANCE_PIXMAP_FILENAME (i)); | 636 mark_object (IMAGE_INSTANCE_PIXMAP_FILENAME (i)); |
592 markobj (IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (i)); | 637 mark_object (IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (i)); |
593 markobj (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i)); | 638 mark_object (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i)); |
594 markobj (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i)); | 639 mark_object (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i)); |
595 markobj (IMAGE_INSTANCE_PIXMAP_FG (i)); | 640 mark_object (IMAGE_INSTANCE_PIXMAP_FG (i)); |
596 markobj (IMAGE_INSTANCE_PIXMAP_BG (i)); | 641 mark_object (IMAGE_INSTANCE_PIXMAP_BG (i)); |
597 break; | 642 break; |
598 | 643 |
599 case IMAGE_WIDGET: | 644 case IMAGE_WIDGET: |
600 markobj (IMAGE_INSTANCE_WIDGET_TYPE (i)); | 645 case IMAGE_LAYOUT: |
601 markobj (IMAGE_INSTANCE_WIDGET_PROPS (i)); | 646 mark_object (IMAGE_INSTANCE_WIDGET_TYPE (i)); |
602 markobj (IMAGE_INSTANCE_WIDGET_FACE (i)); | 647 mark_object (IMAGE_INSTANCE_WIDGET_PROPS (i)); |
603 mark_gui_item (&IMAGE_INSTANCE_WIDGET_ITEM (i), markobj); | 648 mark_object (IMAGE_INSTANCE_WIDGET_FACE (i)); |
649 mark_object (IMAGE_INSTANCE_WIDGET_ITEMS (i)); | |
604 case IMAGE_SUBWINDOW: | 650 case IMAGE_SUBWINDOW: |
605 markobj (IMAGE_INSTANCE_SUBWINDOW_FRAME (i)); | 651 mark_object (IMAGE_INSTANCE_SUBWINDOW_FRAME (i)); |
606 break; | 652 break; |
607 | 653 |
608 default: | 654 default: |
609 break; | 655 break; |
610 } | 656 } |
611 | 657 |
612 MAYBE_DEVMETH (XDEVICE (i->device), mark_image_instance, (i, markobj)); | 658 MAYBE_DEVMETH (XDEVICE (i->device), mark_image_instance, (i)); |
613 | 659 |
614 return i->device; | 660 return i->device; |
615 } | 661 } |
616 | 662 |
617 static void | 663 static void |
618 print_image_instance (Lisp_Object obj, Lisp_Object printcharfun, | 664 print_image_instance (Lisp_Object obj, Lisp_Object printcharfun, |
619 int escapeflag) | 665 int escapeflag) |
620 { | 666 { |
621 char buf[100]; | 667 char buf[100]; |
622 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (obj); | 668 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (obj); |
623 | 669 |
624 if (print_readably) | 670 if (print_readably) |
625 error ("printing unreadable object #<image-instance 0x%x>", | 671 error ("printing unreadable object #<image-instance 0x%x>", |
626 ii->header.uid); | 672 ii->header.uid); |
627 write_c_string ("#<image-instance (", printcharfun); | 673 write_c_string ("#<image-instance (", printcharfun); |
705 write_c_string (")", printcharfun); | 751 write_c_string (")", printcharfun); |
706 } | 752 } |
707 break; | 753 break; |
708 | 754 |
709 case IMAGE_WIDGET: | 755 case IMAGE_WIDGET: |
710 if (!NILP (IMAGE_INSTANCE_WIDGET_CALLBACK (ii))) | |
711 { | |
712 print_internal (IMAGE_INSTANCE_WIDGET_CALLBACK (ii), printcharfun, 0); | |
713 write_c_string (", ", printcharfun); | |
714 } | |
715 if (!NILP (IMAGE_INSTANCE_WIDGET_FACE (ii))) | 756 if (!NILP (IMAGE_INSTANCE_WIDGET_FACE (ii))) |
716 { | 757 { |
717 write_c_string (" (", printcharfun); | 758 write_c_string (" (", printcharfun); |
718 print_internal | 759 print_internal |
719 (IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0); | 760 (IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0); |
722 | 763 |
723 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii))) | 764 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii))) |
724 print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 0); | 765 print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 0); |
725 | 766 |
726 case IMAGE_SUBWINDOW: | 767 case IMAGE_SUBWINDOW: |
768 case IMAGE_LAYOUT: | |
727 sprintf (buf, " %dx%d", IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii), | 769 sprintf (buf, " %dx%d", IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii), |
728 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); | 770 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); |
729 write_c_string (buf, printcharfun); | 771 write_c_string (buf, printcharfun); |
730 | 772 |
731 /* This is stolen from frame.c. Subwindows are strange in that they | 773 /* This is stolen from frame.c. Subwindows are strange in that they |
733 description what that frame is. */ | 775 description what that frame is. */ |
734 | 776 |
735 write_c_string (" on #<", printcharfun); | 777 write_c_string (" on #<", printcharfun); |
736 { | 778 { |
737 struct frame* f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); | 779 struct frame* f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); |
738 | 780 |
739 if (!FRAME_LIVE_P (f)) | 781 if (!FRAME_LIVE_P (f)) |
740 write_c_string ("dead", printcharfun); | 782 write_c_string ("dead", printcharfun); |
741 else | 783 else |
742 write_c_string (DEVICE_TYPE_NAME (XDEVICE (FRAME_DEVICE (f))), | 784 write_c_string (DEVICE_TYPE_NAME (XDEVICE (FRAME_DEVICE (f))), |
743 printcharfun); | 785 printcharfun); |
744 | 786 |
745 write_c_string ("-frame ", printcharfun); | 787 write_c_string ("-frame ", printcharfun); |
746 } | 788 } |
747 write_c_string (">", printcharfun); | 789 write_c_string (">", printcharfun); |
748 sprintf (buf, " 0x%p", IMAGE_INSTANCE_SUBWINDOW_ID (ii)); | 790 sprintf (buf, " 0x%p", IMAGE_INSTANCE_SUBWINDOW_ID (ii)); |
749 write_c_string (buf, printcharfun); | 791 write_c_string (buf, printcharfun); |
750 | 792 |
751 break; | 793 break; |
752 | 794 |
753 default: | 795 default: |
754 abort (); | 796 abort (); |
755 } | 797 } |
761 } | 803 } |
762 | 804 |
763 static void | 805 static void |
764 finalize_image_instance (void *header, int for_disksave) | 806 finalize_image_instance (void *header, int for_disksave) |
765 { | 807 { |
766 struct Lisp_Image_Instance *i = (struct Lisp_Image_Instance *) header; | 808 Lisp_Image_Instance *i = (Lisp_Image_Instance *) header; |
767 | 809 |
768 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_NOTHING) | 810 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_NOTHING) |
769 /* objects like this exist at dump time, so don't bomb out. */ | 811 /* objects like this exist at dump time, so don't bomb out. */ |
770 return; | 812 return; |
771 if (for_disksave) finalose (i); | 813 if (for_disksave) finalose (i); |
772 | 814 |
773 /* do this so that the cachels get reset */ | 815 /* do this so that the cachels get reset */ |
774 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_WIDGET | 816 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_WIDGET |
775 || | 817 || |
818 IMAGE_INSTANCE_TYPE (i) == IMAGE_SUBWINDOW | |
819 || | |
776 IMAGE_INSTANCE_TYPE (i) == IMAGE_SUBWINDOW) | 820 IMAGE_INSTANCE_TYPE (i) == IMAGE_SUBWINDOW) |
777 { | 821 { |
778 MARK_FRAME_GLYPHS_CHANGED | 822 MARK_FRAME_SUBWINDOWS_CHANGED |
779 (XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (i))); | 823 (XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (i))); |
780 } | 824 } |
781 | 825 |
782 MAYBE_DEVMETH (XDEVICE (i->device), finalize_image_instance, (i)); | 826 MAYBE_DEVMETH (XDEVICE (i->device), finalize_image_instance, (i)); |
783 } | 827 } |
784 | 828 |
785 static int | 829 static int |
786 image_instance_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) | 830 image_instance_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) |
787 { | 831 { |
788 struct Lisp_Image_Instance *i1 = XIMAGE_INSTANCE (obj1); | 832 Lisp_Image_Instance *i1 = XIMAGE_INSTANCE (obj1); |
789 struct Lisp_Image_Instance *i2 = XIMAGE_INSTANCE (obj2); | 833 Lisp_Image_Instance *i2 = XIMAGE_INSTANCE (obj2); |
790 struct device *d1 = XDEVICE (i1->device); | 834 struct device *d1 = XDEVICE (i1->device); |
791 struct device *d2 = XDEVICE (i2->device); | 835 struct device *d2 = XDEVICE (i2->device); |
792 | 836 |
793 if (d1 != d2) | 837 if (d1 != d2) |
794 return 0; | 838 return 0; |
795 if (IMAGE_INSTANCE_TYPE (i1) != IMAGE_INSTANCE_TYPE (i2)) | 839 if (IMAGE_INSTANCE_TYPE (i1) != IMAGE_INSTANCE_TYPE (i2) |
840 || IMAGE_INSTANCE_WIDTH (i1) != IMAGE_INSTANCE_WIDTH (i2) | |
841 || IMAGE_INSTANCE_HEIGHT (i1) != IMAGE_INSTANCE_HEIGHT (i2) | |
842 || IMAGE_INSTANCE_XOFFSET (i1) != IMAGE_INSTANCE_XOFFSET (i2) | |
843 || IMAGE_INSTANCE_YOFFSET (i1) != IMAGE_INSTANCE_YOFFSET (i2)) | |
796 return 0; | 844 return 0; |
797 if (!internal_equal (IMAGE_INSTANCE_NAME (i1), IMAGE_INSTANCE_NAME (i2), | 845 if (!internal_equal (IMAGE_INSTANCE_NAME (i1), IMAGE_INSTANCE_NAME (i2), |
798 depth + 1)) | 846 depth + 1)) |
799 return 0; | 847 return 0; |
800 | 848 |
811 break; | 859 break; |
812 | 860 |
813 case IMAGE_MONO_PIXMAP: | 861 case IMAGE_MONO_PIXMAP: |
814 case IMAGE_COLOR_PIXMAP: | 862 case IMAGE_COLOR_PIXMAP: |
815 case IMAGE_POINTER: | 863 case IMAGE_POINTER: |
816 if (!(IMAGE_INSTANCE_PIXMAP_WIDTH (i1) == | 864 if (!(IMAGE_INSTANCE_PIXMAP_DEPTH (i1) == |
817 IMAGE_INSTANCE_PIXMAP_WIDTH (i2) && | |
818 IMAGE_INSTANCE_PIXMAP_HEIGHT (i1) == | |
819 IMAGE_INSTANCE_PIXMAP_HEIGHT (i2) && | |
820 IMAGE_INSTANCE_PIXMAP_DEPTH (i1) == | |
821 IMAGE_INSTANCE_PIXMAP_DEPTH (i2) && | 865 IMAGE_INSTANCE_PIXMAP_DEPTH (i2) && |
866 IMAGE_INSTANCE_PIXMAP_SLICE (i1) == | |
867 IMAGE_INSTANCE_PIXMAP_SLICE (i2) && | |
822 EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i1), | 868 EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i1), |
823 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i2)) && | 869 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i2)) && |
824 EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i1), | 870 EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i1), |
825 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i2)) && | 871 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i2)) && |
826 internal_equal (IMAGE_INSTANCE_PIXMAP_FILENAME (i1), | 872 internal_equal (IMAGE_INSTANCE_PIXMAP_FILENAME (i1), |
831 depth + 1))) | 877 depth + 1))) |
832 return 0; | 878 return 0; |
833 break; | 879 break; |
834 | 880 |
835 case IMAGE_WIDGET: | 881 case IMAGE_WIDGET: |
882 case IMAGE_LAYOUT: | |
836 if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1), | 883 if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1), |
837 IMAGE_INSTANCE_WIDGET_TYPE (i2)) && | 884 IMAGE_INSTANCE_WIDGET_TYPE (i2)) |
838 EQ (IMAGE_INSTANCE_WIDGET_CALLBACK (i1), | 885 && IMAGE_INSTANCE_SUBWINDOW_ID (i1) == |
839 IMAGE_INSTANCE_WIDGET_CALLBACK (i2)) | 886 IMAGE_INSTANCE_SUBWINDOW_ID (i2) |
887 && internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (i1), | |
888 IMAGE_INSTANCE_WIDGET_ITEMS (i2), | |
889 depth + 1) | |
840 && internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1), | 890 && internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1), |
841 IMAGE_INSTANCE_WIDGET_PROPS (i2), | 891 IMAGE_INSTANCE_WIDGET_PROPS (i2), |
842 depth + 1) | 892 depth + 1) |
843 && internal_equal (IMAGE_INSTANCE_WIDGET_TEXT (i1), | 893 )) |
844 IMAGE_INSTANCE_WIDGET_TEXT (i2), | |
845 depth + 1))) | |
846 return 0; | 894 return 0; |
895 break; | |
896 | |
847 case IMAGE_SUBWINDOW: | 897 case IMAGE_SUBWINDOW: |
848 if (!(IMAGE_INSTANCE_SUBWINDOW_WIDTH (i1) == | 898 if (!(IMAGE_INSTANCE_SUBWINDOW_ID (i1) == |
849 IMAGE_INSTANCE_SUBWINDOW_WIDTH (i2) && | |
850 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i1) == | |
851 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i2) && | |
852 IMAGE_INSTANCE_SUBWINDOW_ID (i1) == | |
853 IMAGE_INSTANCE_SUBWINDOW_ID (i2))) | 899 IMAGE_INSTANCE_SUBWINDOW_ID (i2))) |
854 return 0; | 900 return 0; |
855 break; | 901 break; |
856 | 902 |
857 default: | 903 default: |
862 } | 908 } |
863 | 909 |
864 static unsigned long | 910 static unsigned long |
865 image_instance_hash (Lisp_Object obj, int depth) | 911 image_instance_hash (Lisp_Object obj, int depth) |
866 { | 912 { |
867 struct Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); | 913 Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); |
868 struct device *d = XDEVICE (i->device); | 914 struct device *d = XDEVICE (i->device); |
869 unsigned long hash = (unsigned long) d; | 915 unsigned long hash = HASH3 ((unsigned long) d, |
916 IMAGE_INSTANCE_WIDTH (i), | |
917 IMAGE_INSTANCE_HEIGHT (i)); | |
870 | 918 |
871 switch (IMAGE_INSTANCE_TYPE (i)) | 919 switch (IMAGE_INSTANCE_TYPE (i)) |
872 { | 920 { |
873 case IMAGE_NOTHING: | 921 case IMAGE_NOTHING: |
874 break; | 922 break; |
879 break; | 927 break; |
880 | 928 |
881 case IMAGE_MONO_PIXMAP: | 929 case IMAGE_MONO_PIXMAP: |
882 case IMAGE_COLOR_PIXMAP: | 930 case IMAGE_COLOR_PIXMAP: |
883 case IMAGE_POINTER: | 931 case IMAGE_POINTER: |
884 hash = HASH5 (hash, IMAGE_INSTANCE_PIXMAP_WIDTH (i), | 932 hash = HASH4 (hash, IMAGE_INSTANCE_PIXMAP_DEPTH (i), |
885 IMAGE_INSTANCE_PIXMAP_HEIGHT (i), | 933 IMAGE_INSTANCE_PIXMAP_SLICE (i), |
886 IMAGE_INSTANCE_PIXMAP_DEPTH (i), | |
887 internal_hash (IMAGE_INSTANCE_PIXMAP_FILENAME (i), | 934 internal_hash (IMAGE_INSTANCE_PIXMAP_FILENAME (i), |
888 depth + 1)); | 935 depth + 1)); |
889 break; | 936 break; |
890 | 937 |
891 case IMAGE_WIDGET: | 938 case IMAGE_WIDGET: |
892 hash = HASH4 (hash, | 939 case IMAGE_LAYOUT: |
940 hash = HASH4 (hash, | |
893 internal_hash (IMAGE_INSTANCE_WIDGET_TYPE (i), depth + 1), | 941 internal_hash (IMAGE_INSTANCE_WIDGET_TYPE (i), depth + 1), |
894 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1), | 942 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1), |
895 internal_hash (IMAGE_INSTANCE_WIDGET_CALLBACK (i), depth + 1)); | 943 internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1)); |
896 case IMAGE_SUBWINDOW: | 944 case IMAGE_SUBWINDOW: |
897 hash = HASH4 (hash, IMAGE_INSTANCE_SUBWINDOW_WIDTH (i), | 945 hash = HASH2 (hash, (int) IMAGE_INSTANCE_SUBWINDOW_ID (i)); |
898 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i), | |
899 (int) IMAGE_INSTANCE_SUBWINDOW_ID (i)); | |
900 break; | 946 break; |
901 | 947 |
902 default: | 948 default: |
903 abort (); | 949 abort (); |
904 } | 950 } |
908 } | 954 } |
909 | 955 |
910 DEFINE_LRECORD_IMPLEMENTATION ("image-instance", image_instance, | 956 DEFINE_LRECORD_IMPLEMENTATION ("image-instance", image_instance, |
911 mark_image_instance, print_image_instance, | 957 mark_image_instance, print_image_instance, |
912 finalize_image_instance, image_instance_equal, | 958 finalize_image_instance, image_instance_equal, |
913 image_instance_hash, | 959 image_instance_hash, 0, |
914 struct Lisp_Image_Instance); | 960 Lisp_Image_Instance); |
915 | 961 |
916 static Lisp_Object | 962 static Lisp_Object |
917 allocate_image_instance (Lisp_Object device) | 963 allocate_image_instance (Lisp_Object device, Lisp_Object glyph) |
918 { | 964 { |
919 struct Lisp_Image_Instance *lp = | 965 Lisp_Image_Instance *lp = |
920 alloc_lcrecord_type (struct Lisp_Image_Instance, lrecord_image_instance); | 966 alloc_lcrecord_type (Lisp_Image_Instance, &lrecord_image_instance); |
921 Lisp_Object val; | 967 Lisp_Object val; |
922 | 968 |
923 zero_lcrecord (lp); | 969 zero_lcrecord (lp); |
924 lp->device = device; | 970 lp->device = device; |
925 lp->type = IMAGE_NOTHING; | 971 lp->type = IMAGE_NOTHING; |
926 lp->name = Qnil; | 972 lp->name = Qnil; |
973 lp->x_offset = 0; | |
974 lp->y_offset = 0; | |
975 lp->width = 0; | |
976 lp->height = 0; | |
977 lp->parent = glyph; | |
978 /* So that layouts get done. */ | |
979 lp->layout_changed = 1; | |
980 lp->dirty = 1; | |
981 | |
927 XSETIMAGE_INSTANCE (val, lp); | 982 XSETIMAGE_INSTANCE (val, lp); |
983 MARK_GLYPHS_CHANGED; | |
984 | |
928 return val; | 985 return val; |
929 } | 986 } |
930 | 987 |
931 static enum image_instance_type | 988 static enum image_instance_type |
932 decode_image_instance_type (Lisp_Object type, Error_behavior errb) | 989 decode_image_instance_type (Lisp_Object type, Error_behavior errb) |
939 if (EQ (type, Qmono_pixmap)) return IMAGE_MONO_PIXMAP; | 996 if (EQ (type, Qmono_pixmap)) return IMAGE_MONO_PIXMAP; |
940 if (EQ (type, Qcolor_pixmap)) return IMAGE_COLOR_PIXMAP; | 997 if (EQ (type, Qcolor_pixmap)) return IMAGE_COLOR_PIXMAP; |
941 if (EQ (type, Qpointer)) return IMAGE_POINTER; | 998 if (EQ (type, Qpointer)) return IMAGE_POINTER; |
942 if (EQ (type, Qsubwindow)) return IMAGE_SUBWINDOW; | 999 if (EQ (type, Qsubwindow)) return IMAGE_SUBWINDOW; |
943 if (EQ (type, Qwidget)) return IMAGE_WIDGET; | 1000 if (EQ (type, Qwidget)) return IMAGE_WIDGET; |
1001 if (EQ (type, Qlayout)) return IMAGE_LAYOUT; | |
944 | 1002 |
945 maybe_signal_simple_error ("Invalid image-instance type", type, | 1003 maybe_signal_simple_error ("Invalid image-instance type", type, |
946 Qimage, errb); | 1004 Qimage, errb); |
947 | 1005 |
948 return IMAGE_UNKNOWN; /* not reached */ | 1006 return IMAGE_UNKNOWN; /* not reached */ |
958 case IMAGE_MONO_PIXMAP: return Qmono_pixmap; | 1016 case IMAGE_MONO_PIXMAP: return Qmono_pixmap; |
959 case IMAGE_COLOR_PIXMAP: return Qcolor_pixmap; | 1017 case IMAGE_COLOR_PIXMAP: return Qcolor_pixmap; |
960 case IMAGE_POINTER: return Qpointer; | 1018 case IMAGE_POINTER: return Qpointer; |
961 case IMAGE_SUBWINDOW: return Qsubwindow; | 1019 case IMAGE_SUBWINDOW: return Qsubwindow; |
962 case IMAGE_WIDGET: return Qwidget; | 1020 case IMAGE_WIDGET: return Qwidget; |
1021 case IMAGE_LAYOUT: return Qlayout; | |
963 default: | 1022 default: |
964 abort (); | 1023 abort (); |
965 } | 1024 } |
966 | 1025 |
967 return Qnil; /* not reached */ | 1026 return Qnil; /* not reached */ |
970 static int | 1029 static int |
971 image_instance_type_to_mask (enum image_instance_type type) | 1030 image_instance_type_to_mask (enum image_instance_type type) |
972 { | 1031 { |
973 /* This depends on the fact that enums are assigned consecutive | 1032 /* This depends on the fact that enums are assigned consecutive |
974 integers starting at 0. (Remember that IMAGE_UNKNOWN is the | 1033 integers starting at 0. (Remember that IMAGE_UNKNOWN is the |
975 first enum.) I'm fairly sure this behavior in ANSI-mandated, | 1034 first enum.) I'm fairly sure this behavior is ANSI-mandated, |
976 so there should be no portability problems here. */ | 1035 so there should be no portability problems here. */ |
977 return (1 << ((int) (type) - 1)); | 1036 return (1 << ((int) (type) - 1)); |
978 } | 1037 } |
979 | 1038 |
980 static int | 1039 static int |
1027 { | 1086 { |
1028 signal_error | 1087 signal_error |
1029 (Qerror, | 1088 (Qerror, |
1030 list2 | 1089 list2 |
1031 (emacs_doprnt_string_lisp_2 | 1090 (emacs_doprnt_string_lisp_2 |
1032 ((CONST Bufbyte *) | 1091 ((const Bufbyte *) |
1033 "No compatible image-instance types given: wanted one of %s, got %s", | 1092 "No compatible image-instance types given: wanted one of %s, got %s", |
1034 Qnil, -1, 2, | 1093 Qnil, -1, 2, |
1035 encode_image_instance_type_list (desired_dest_mask), | 1094 encode_image_instance_type_list (desired_dest_mask), |
1036 encode_image_instance_type_list (given_dest_mask)), | 1095 encode_image_instance_type_list (given_dest_mask)), |
1037 instantiator)); | 1096 instantiator)); |
1079 else | 1138 else |
1080 { | 1139 { |
1081 assert (ERRB_EQ (errb, ERROR_ME_WARN)); | 1140 assert (ERRB_EQ (errb, ERROR_ME_WARN)); |
1082 return Qwarning; | 1141 return Qwarning; |
1083 } | 1142 } |
1143 } | |
1144 | |
1145 /* Recurse up the hierarchy looking for the topmost glyph. This means | |
1146 that instances in layouts will inherit face properties from their | |
1147 parent. */ | |
1148 Lisp_Object image_instance_parent_glyph (Lisp_Image_Instance* ii) | |
1149 { | |
1150 if (IMAGE_INSTANCEP (IMAGE_INSTANCE_PARENT (ii))) | |
1151 { | |
1152 return image_instance_parent_glyph | |
1153 (XIMAGE_INSTANCE (IMAGE_INSTANCE_PARENT (ii))); | |
1154 } | |
1155 return IMAGE_INSTANCE_PARENT (ii); | |
1084 } | 1156 } |
1085 | 1157 |
1086 static Lisp_Object | 1158 static Lisp_Object |
1087 make_image_instance_1 (Lisp_Object data, Lisp_Object device, | 1159 make_image_instance_1 (Lisp_Object data, Lisp_Object device, |
1088 Lisp_Object dest_types) | 1160 Lisp_Object dest_types) |
1102 make_int (dest_mask)); | 1174 make_int (dest_mask)); |
1103 GCPRO1 (data); | 1175 GCPRO1 (data); |
1104 if (VECTORP (data) && EQ (XVECTOR_DATA (data)[0], Qinherit)) | 1176 if (VECTORP (data) && EQ (XVECTOR_DATA (data)[0], Qinherit)) |
1105 signal_simple_error ("Inheritance not allowed here", data); | 1177 signal_simple_error ("Inheritance not allowed here", data); |
1106 ii = instantiate_image_instantiator (device, device, data, | 1178 ii = instantiate_image_instantiator (device, device, data, |
1107 Qnil, Qnil, dest_mask); | 1179 Qnil, Qnil, dest_mask, Qnil); |
1108 RETURN_UNGCPRO (ii); | 1180 RETURN_UNGCPRO (ii); |
1109 } | 1181 } |
1110 | 1182 |
1111 DEFUN ("make-image-instance", Fmake_image_instance, 1, 4, 0, /* | 1183 DEFUN ("make-image-instance", Fmake_image_instance, 1, 4, 0, /* |
1112 Return a new `image-instance' object. | 1184 Return a new `image-instance' object. |
1141 'pointer | 1213 'pointer |
1142 Used as the mouse pointer for a window. | 1214 Used as the mouse pointer for a window. |
1143 'subwindow | 1215 'subwindow |
1144 A child window that is treated as an image. This allows (e.g.) | 1216 A child window that is treated as an image. This allows (e.g.) |
1145 another program to be responsible for drawing into the window. | 1217 another program to be responsible for drawing into the window. |
1146 Not currently implemented. | 1218 'widget |
1219 A child window that contains a window-system widget, e.g. a push | |
1220 button. | |
1147 | 1221 |
1148 The DEST-TYPES list is unordered. If multiple destination types | 1222 The DEST-TYPES list is unordered. If multiple destination types |
1149 are possible for a given instantiator, the "most natural" type | 1223 are possible for a given instantiator, the "most natural" type |
1150 for the instantiator's format is chosen. (For XBM, the most natural | 1224 for the instantiator's format is chosen. (For XBM, the most natural |
1151 types are `mono-pixmap', followed by `color-pixmap', followed by | 1225 types are `mono-pixmap', followed by `color-pixmap', followed by |
1218 else | 1292 else |
1219 return Qnil; | 1293 return Qnil; |
1220 } | 1294 } |
1221 | 1295 |
1222 DEFUN ("image-instance-property", Fimage_instance_property, 2, 2, 0, /* | 1296 DEFUN ("image-instance-property", Fimage_instance_property, 2, 2, 0, /* |
1223 Return the given property of the given image instance. | 1297 Return the given property of the given image instance. |
1224 Returns nil if the property or the property method do not exist for | 1298 Returns nil if the property or the property method do not exist for |
1225 the image instance in the domain. | 1299 the image instance in the domain. |
1226 */ | 1300 */ |
1227 (image_instance, prop)) | 1301 (image_instance, prop)) |
1228 { | 1302 { |
1229 struct Lisp_Image_Instance* ii; | 1303 Lisp_Image_Instance* ii; |
1230 Lisp_Object type, ret; | 1304 Lisp_Object type, ret; |
1231 struct image_instantiator_methods* meths; | 1305 struct image_instantiator_methods* meths; |
1232 | 1306 |
1233 CHECK_IMAGE_INSTANCE (image_instance); | 1307 CHECK_IMAGE_INSTANCE (image_instance); |
1234 CHECK_SYMBOL (prop); | 1308 CHECK_SYMBOL (prop); |
1235 ii = XIMAGE_INSTANCE (image_instance); | 1309 ii = XIMAGE_INSTANCE (image_instance); |
1236 | 1310 |
1237 /* ... then try device specific methods ... */ | 1311 /* ... then try device specific methods ... */ |
1238 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); | 1312 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); |
1239 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), | 1313 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), |
1240 type, ERROR_ME_NOT); | 1314 type, ERROR_ME_NOT); |
1241 if (meths && HAS_IIFORMAT_METH_P (meths, property) | 1315 if (meths && HAS_IIFORMAT_METH_P (meths, property) |
1242 && | 1316 && |
1243 !UNBOUNDP (ret = IIFORMAT_METH (meths, property, (image_instance, prop)))) | 1317 !UNBOUNDP (ret = IIFORMAT_METH (meths, property, (image_instance, prop)))) |
1244 { | 1318 { |
1245 return ret; | 1319 return ret; |
1246 } | 1320 } |
1247 /* ... then format specific methods ... */ | 1321 /* ... then format specific methods ... */ |
1255 /* ... then fail */ | 1329 /* ... then fail */ |
1256 return Qnil; | 1330 return Qnil; |
1257 } | 1331 } |
1258 | 1332 |
1259 DEFUN ("set-image-instance-property", Fset_image_instance_property, 3, 3, 0, /* | 1333 DEFUN ("set-image-instance-property", Fset_image_instance_property, 3, 3, 0, /* |
1260 Set the given property of the given image instance. | 1334 Set the given property of the given image instance. |
1261 Does nothing if the property or the property method do not exist for | 1335 Does nothing if the property or the property method do not exist for |
1262 the image instance in the domain. | 1336 the image instance in the domain. |
1263 */ | 1337 */ |
1264 (image_instance, prop, val)) | 1338 (image_instance, prop, val)) |
1265 { | 1339 { |
1266 struct Lisp_Image_Instance* ii; | 1340 Lisp_Image_Instance* ii; |
1267 Lisp_Object type, ret; | 1341 Lisp_Object type, ret; |
1268 struct image_instantiator_methods* meths; | 1342 struct image_instantiator_methods* meths; |
1269 | 1343 |
1270 CHECK_IMAGE_INSTANCE (image_instance); | 1344 CHECK_IMAGE_INSTANCE (image_instance); |
1271 CHECK_SYMBOL (prop); | 1345 CHECK_SYMBOL (prop); |
1272 ii = XIMAGE_INSTANCE (image_instance); | 1346 ii = XIMAGE_INSTANCE (image_instance); |
1273 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); | 1347 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); |
1274 /* try device specific methods first ... */ | 1348 /* try device specific methods first ... */ |
1275 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), | 1349 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), |
1276 type, ERROR_ME_NOT); | 1350 type, ERROR_ME_NOT); |
1277 if (meths && HAS_IIFORMAT_METH_P (meths, set_property) | 1351 if (meths && HAS_IIFORMAT_METH_P (meths, set_property) |
1278 && | 1352 && |
1279 !UNBOUNDP (ret = | 1353 !UNBOUNDP (ret = |
1280 IIFORMAT_METH (meths, set_property, (image_instance, prop, val)))) | 1354 IIFORMAT_METH (meths, set_property, (image_instance, prop, val)))) |
1281 { | 1355 { |
1282 return ret; | 1356 val = ret; |
1283 } | 1357 } |
1284 /* ... then format specific methods ... */ | 1358 else |
1285 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); | 1359 { |
1286 if (meths && HAS_IIFORMAT_METH_P (meths, set_property) | 1360 /* ... then format specific methods ... */ |
1287 && | 1361 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); |
1288 !UNBOUNDP (ret = | 1362 if (meths && HAS_IIFORMAT_METH_P (meths, set_property) |
1289 IIFORMAT_METH (meths, set_property, (image_instance, prop, val)))) | 1363 && |
1290 { | 1364 !UNBOUNDP (ret = |
1291 return ret; | 1365 IIFORMAT_METH (meths, set_property, (image_instance, prop, val)))) |
1292 } | 1366 { |
1367 val = ret; | |
1368 } | |
1369 else | |
1370 { | |
1371 val = Qnil; | |
1372 } | |
1373 } | |
1374 | |
1375 /* Make sure the image instance gets redisplayed. */ | |
1376 set_image_instance_dirty_p (image_instance, 1); | |
1377 /* Force the glyph to be laid out again. */ | |
1378 IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 1; | |
1379 | |
1380 MARK_SUBWINDOWS_STATE_CHANGED; | |
1381 MARK_GLYPHS_CHANGED; | |
1293 | 1382 |
1294 return val; | 1383 return val; |
1295 } | 1384 } |
1296 | 1385 |
1297 DEFUN ("image-instance-file-name", Fimage_instance_file_name, 1, 1, 0, /* | 1386 DEFUN ("image-instance-file-name", Fimage_instance_file_name, 1, 1, 0, /* |
1362 switch (XIMAGE_INSTANCE_TYPE (image_instance)) | 1451 switch (XIMAGE_INSTANCE_TYPE (image_instance)) |
1363 { | 1452 { |
1364 case IMAGE_MONO_PIXMAP: | 1453 case IMAGE_MONO_PIXMAP: |
1365 case IMAGE_COLOR_PIXMAP: | 1454 case IMAGE_COLOR_PIXMAP: |
1366 case IMAGE_POINTER: | 1455 case IMAGE_POINTER: |
1367 return make_int (XIMAGE_INSTANCE_PIXMAP_HEIGHT (image_instance)); | |
1368 | |
1369 case IMAGE_SUBWINDOW: | 1456 case IMAGE_SUBWINDOW: |
1370 case IMAGE_WIDGET: | 1457 case IMAGE_WIDGET: |
1371 return make_int (XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (image_instance)); | 1458 case IMAGE_LAYOUT: |
1459 return make_int (XIMAGE_INSTANCE_HEIGHT (image_instance)); | |
1372 | 1460 |
1373 default: | 1461 default: |
1374 return Qnil; | 1462 return Qnil; |
1375 } | 1463 } |
1376 } | 1464 } |
1385 switch (XIMAGE_INSTANCE_TYPE (image_instance)) | 1473 switch (XIMAGE_INSTANCE_TYPE (image_instance)) |
1386 { | 1474 { |
1387 case IMAGE_MONO_PIXMAP: | 1475 case IMAGE_MONO_PIXMAP: |
1388 case IMAGE_COLOR_PIXMAP: | 1476 case IMAGE_COLOR_PIXMAP: |
1389 case IMAGE_POINTER: | 1477 case IMAGE_POINTER: |
1390 return make_int (XIMAGE_INSTANCE_PIXMAP_WIDTH (image_instance)); | |
1391 | |
1392 case IMAGE_SUBWINDOW: | 1478 case IMAGE_SUBWINDOW: |
1393 case IMAGE_WIDGET: | 1479 case IMAGE_WIDGET: |
1394 return make_int (XIMAGE_INSTANCE_SUBWINDOW_WIDTH (image_instance)); | 1480 case IMAGE_LAYOUT: |
1481 return make_int (XIMAGE_INSTANCE_WIDTH (image_instance)); | |
1395 | 1482 |
1396 default: | 1483 default: |
1397 return Qnil; | 1484 return Qnil; |
1398 } | 1485 } |
1399 } | 1486 } |
1463 return XIMAGE_INSTANCE_PIXMAP_FG (image_instance); | 1550 return XIMAGE_INSTANCE_PIXMAP_FG (image_instance); |
1464 | 1551 |
1465 case IMAGE_WIDGET: | 1552 case IMAGE_WIDGET: |
1466 return FACE_FOREGROUND ( | 1553 return FACE_FOREGROUND ( |
1467 XIMAGE_INSTANCE_WIDGET_FACE (image_instance), | 1554 XIMAGE_INSTANCE_WIDGET_FACE (image_instance), |
1468 XIMAGE_INSTANCE_SUBWINDOW_FRAME | 1555 XIMAGE_INSTANCE_SUBWINDOW_FRAME |
1469 (image_instance)); | 1556 (image_instance)); |
1470 | 1557 |
1471 default: | 1558 default: |
1472 return Qnil; | 1559 return Qnil; |
1473 } | 1560 } |
1490 return XIMAGE_INSTANCE_PIXMAP_BG (image_instance); | 1577 return XIMAGE_INSTANCE_PIXMAP_BG (image_instance); |
1491 | 1578 |
1492 case IMAGE_WIDGET: | 1579 case IMAGE_WIDGET: |
1493 return FACE_BACKGROUND ( | 1580 return FACE_BACKGROUND ( |
1494 XIMAGE_INSTANCE_WIDGET_FACE (image_instance), | 1581 XIMAGE_INSTANCE_WIDGET_FACE (image_instance), |
1495 XIMAGE_INSTANCE_SUBWINDOW_FRAME | 1582 XIMAGE_INSTANCE_SUBWINDOW_FRAME |
1496 (image_instance)); | 1583 (image_instance)); |
1497 | 1584 |
1498 default: | 1585 default: |
1499 return Qnil; | 1586 return Qnil; |
1500 } | 1587 } |
1519 | 1606 |
1520 device = XIMAGE_INSTANCE_DEVICE (image_instance); | 1607 device = XIMAGE_INSTANCE_DEVICE (image_instance); |
1521 if (!HAS_DEVMETH_P (XDEVICE (device), colorize_image_instance)) | 1608 if (!HAS_DEVMETH_P (XDEVICE (device), colorize_image_instance)) |
1522 return image_instance; | 1609 return image_instance; |
1523 | 1610 |
1524 new = allocate_image_instance (device); | 1611 /* #### There should be a copy_image_instance(), which calls a |
1612 device-specific method to copy the window-system subobject. */ | |
1613 new = allocate_image_instance (device, Qnil); | |
1525 copy_lcrecord (XIMAGE_INSTANCE (new), XIMAGE_INSTANCE (image_instance)); | 1614 copy_lcrecord (XIMAGE_INSTANCE (new), XIMAGE_INSTANCE (image_instance)); |
1526 /* note that if this method returns non-zero, this method MUST | 1615 /* note that if this method returns non-zero, this method MUST |
1527 copy any window-system resources, so that when one image instance is | 1616 copy any window-system resources, so that when one image instance is |
1528 freed, the other one is not hosed. */ | 1617 freed, the other one is not hosed. */ |
1529 if (!DEVMETH (XDEVICE (device), colorize_image_instance, (new, foreground, | 1618 if (!DEVMETH (XDEVICE (device), colorize_image_instance, (new, foreground, |
1530 background))) | 1619 background))) |
1531 return image_instance; | 1620 return image_instance; |
1532 return new; | 1621 return new; |
1533 } | 1622 } |
1534 | 1623 |
1624 | |
1625 /************************************************************************/ | |
1626 /* Geometry calculations */ | |
1627 /************************************************************************/ | |
1628 | |
1629 /* Find out desired geometry of the image instance. If there is no | |
1630 special function then just return the width and / or height. */ | |
1631 void | |
1632 image_instance_query_geometry (Lisp_Object image_instance, | |
1633 unsigned int* width, unsigned int* height, | |
1634 enum image_instance_geometry disp, | |
1635 Lisp_Object domain) | |
1636 { | |
1637 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); | |
1638 Lisp_Object type; | |
1639 struct image_instantiator_methods* meths; | |
1640 | |
1641 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); | |
1642 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); | |
1643 | |
1644 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry)) | |
1645 { | |
1646 IIFORMAT_METH (meths, query_geometry, (image_instance, width, height, | |
1647 disp, domain)); | |
1648 } | |
1649 else | |
1650 { | |
1651 if (width) | |
1652 *width = IMAGE_INSTANCE_WIDTH (ii); | |
1653 if (height) | |
1654 *height = IMAGE_INSTANCE_HEIGHT (ii); | |
1655 } | |
1656 } | |
1657 | |
1658 /* Layout the image instance using the provided dimensions. Layout | |
1659 widgets are going to do different kinds of calculations to | |
1660 determine what size to give things so we could make the layout | |
1661 function relatively simple to take account of that. An alternative | |
1662 approach is to consider separately the two cases, one where you | |
1663 don't mind what size you have (normal widgets) and one where you | |
1664 want to specifiy something (layout widgets). */ | |
1665 void | |
1666 image_instance_layout (Lisp_Object image_instance, | |
1667 unsigned int width, unsigned int height, | |
1668 Lisp_Object domain) | |
1669 { | |
1670 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); | |
1671 Lisp_Object type; | |
1672 struct image_instantiator_methods* meths; | |
1673 | |
1674 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); | |
1675 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); | |
1676 | |
1677 /* If geometry is unspecified then get some reasonable values for it. */ | |
1678 if (width == IMAGE_UNSPECIFIED_GEOMETRY | |
1679 || | |
1680 height == IMAGE_UNSPECIFIED_GEOMETRY) | |
1681 { | |
1682 unsigned int dwidth, dheight; | |
1683 | |
1684 /* Get the desired geometry. */ | |
1685 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry)) | |
1686 { | |
1687 IIFORMAT_METH (meths, query_geometry, (image_instance, &dwidth, &dheight, | |
1688 IMAGE_DESIRED_GEOMETRY, | |
1689 domain)); | |
1690 } | |
1691 else | |
1692 { | |
1693 dwidth = IMAGE_INSTANCE_WIDTH (ii); | |
1694 dheight = IMAGE_INSTANCE_HEIGHT (ii); | |
1695 } | |
1696 | |
1697 /* Compare with allowed geometry. */ | |
1698 if (width == IMAGE_UNSPECIFIED_GEOMETRY) | |
1699 width = dwidth; | |
1700 if (height == IMAGE_UNSPECIFIED_GEOMETRY) | |
1701 height = dheight; | |
1702 } | |
1703 | |
1704 /* At this point width and height should contain sane values. Thus | |
1705 we set the glyph geometry and lay it out. */ | |
1706 if (IMAGE_INSTANCE_WIDTH (ii) != width | |
1707 || | |
1708 IMAGE_INSTANCE_HEIGHT (ii) != height) | |
1709 { | |
1710 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 1; | |
1711 } | |
1712 | |
1713 IMAGE_INSTANCE_WIDTH (ii) = width; | |
1714 IMAGE_INSTANCE_HEIGHT (ii) = height; | |
1715 | |
1716 if (meths && HAS_IIFORMAT_METH_P (meths, layout)) | |
1717 { | |
1718 IIFORMAT_METH (meths, layout, (image_instance, width, height, domain)); | |
1719 } | |
1720 /* else no change to the geometry. */ | |
1721 | |
1722 /* Do not clear the dirty flag here - redisplay will do this for | |
1723 us at the end. */ | |
1724 IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 0; | |
1725 } | |
1726 | |
1727 /* | |
1728 * Mark image instance in W as dirty if (a) W's faces have changed and | |
1729 * (b) GLYPH_OR_II instance in W is a string. | |
1730 * | |
1731 * Return non-zero if instance has been marked dirty. | |
1732 */ | |
1733 int | |
1734 invalidate_glyph_geometry_maybe (Lisp_Object glyph_or_ii, struct window* w) | |
1735 { | |
1736 if (XFRAME(WINDOW_FRAME(w))->faces_changed) | |
1737 { | |
1738 Lisp_Object image = glyph_or_ii; | |
1739 | |
1740 if (GLYPHP (glyph_or_ii)) | |
1741 { | |
1742 Lisp_Object window; | |
1743 XSETWINDOW (window, w); | |
1744 image = glyph_image_instance (glyph_or_ii, window, ERROR_ME_NOT, 1); | |
1745 } | |
1746 | |
1747 if (TEXT_IMAGE_INSTANCEP (image)) | |
1748 { | |
1749 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image); | |
1750 IMAGE_INSTANCE_DIRTYP (ii) = 1; | |
1751 IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 1; | |
1752 if (GLYPHP (glyph_or_ii)) | |
1753 XGLYPH_DIRTYP (glyph_or_ii) = 1; | |
1754 return 1; | |
1755 } | |
1756 } | |
1757 | |
1758 return 0; | |
1759 } | |
1760 | |
1535 | 1761 |
1536 /************************************************************************/ | 1762 /************************************************************************/ |
1537 /* error helpers */ | 1763 /* error helpers */ |
1538 /************************************************************************/ | 1764 /************************************************************************/ |
1539 DOESNT_RETURN | 1765 DOESNT_RETURN |
1540 signal_image_error (CONST char *reason, Lisp_Object frob) | 1766 signal_image_error (const char *reason, Lisp_Object frob) |
1541 { | 1767 { |
1542 signal_error (Qimage_conversion_error, | 1768 signal_error (Qimage_conversion_error, |
1543 list2 (build_translated_string (reason), frob)); | 1769 list2 (build_translated_string (reason), frob)); |
1544 } | 1770 } |
1545 | 1771 |
1546 DOESNT_RETURN | 1772 DOESNT_RETURN |
1547 signal_image_error_2 (CONST char *reason, Lisp_Object frob0, Lisp_Object frob1) | 1773 signal_image_error_2 (const char *reason, Lisp_Object frob0, Lisp_Object frob1) |
1548 { | 1774 { |
1549 signal_error (Qimage_conversion_error, | 1775 signal_error (Qimage_conversion_error, |
1550 list3 (build_translated_string (reason), frob0, frob1)); | 1776 list3 (build_translated_string (reason), frob0, frob1)); |
1551 } | 1777 } |
1552 | 1778 |
1563 static void | 1789 static void |
1564 nothing_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | 1790 nothing_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, |
1565 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 1791 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
1566 int dest_mask, Lisp_Object domain) | 1792 int dest_mask, Lisp_Object domain) |
1567 { | 1793 { |
1568 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | 1794 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
1569 | 1795 |
1570 if (dest_mask & IMAGE_NOTHING_MASK) | 1796 if (dest_mask & IMAGE_NOTHING_MASK) |
1571 IMAGE_INSTANCE_TYPE (ii) = IMAGE_NOTHING; | 1797 IMAGE_INSTANCE_TYPE (ii) = IMAGE_NOTHING; |
1572 else | 1798 else |
1573 incompatible_image_types (instantiator, dest_mask, IMAGE_NOTHING_MASK); | 1799 incompatible_image_types (instantiator, dest_mask, IMAGE_NOTHING_MASK); |
1626 string_possible_dest_types (void) | 1852 string_possible_dest_types (void) |
1627 { | 1853 { |
1628 return IMAGE_TEXT_MASK; | 1854 return IMAGE_TEXT_MASK; |
1629 } | 1855 } |
1630 | 1856 |
1631 /* called from autodetect_instantiate() */ | 1857 /* Called from autodetect_instantiate() */ |
1632 void | 1858 void |
1633 string_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | 1859 string_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, |
1634 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 1860 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
1635 int dest_mask, Lisp_Object domain) | 1861 int dest_mask, Lisp_Object domain) |
1636 { | 1862 { |
1637 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | 1863 Lisp_Object string = find_keyword_in_vector (instantiator, Q_data); |
1638 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | 1864 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
1639 | 1865 |
1640 assert (!NILP (data)); | 1866 /* Should never get here with a domain other than a window. */ |
1867 assert (!NILP (string) && WINDOWP (domain)); | |
1641 if (dest_mask & IMAGE_TEXT_MASK) | 1868 if (dest_mask & IMAGE_TEXT_MASK) |
1642 { | 1869 { |
1643 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT; | 1870 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT; |
1644 IMAGE_INSTANCE_TEXT_STRING (ii) = data; | 1871 IMAGE_INSTANCE_TEXT_STRING (ii) = string; |
1645 } | 1872 } |
1646 else | 1873 else |
1647 incompatible_image_types (instantiator, dest_mask, IMAGE_TEXT_MASK); | 1874 incompatible_image_types (instantiator, dest_mask, IMAGE_TEXT_MASK); |
1875 } | |
1876 | |
1877 /* Sort out the size of the text that is being displayed. Calculating | |
1878 it dynamically allows us to change the text and still see | |
1879 everything. Note that the following methods are for text not string | |
1880 since that is what the instantiated type is. The first method is a | |
1881 helper that is used elsewhere for calculating text geometry. */ | |
1882 void | |
1883 query_string_geometry (Lisp_Object string, Lisp_Object face, | |
1884 unsigned int* width, unsigned int* height, | |
1885 unsigned int* descent, Lisp_Object domain) | |
1886 { | |
1887 struct font_metric_info fm; | |
1888 unsigned char charsets[NUM_LEADING_BYTES]; | |
1889 struct face_cachel frame_cachel; | |
1890 struct face_cachel *cachel; | |
1891 Lisp_Object frame = FW_FRAME (domain); | |
1892 | |
1893 /* Compute height */ | |
1894 if (height) | |
1895 { | |
1896 /* Compute string metric info */ | |
1897 find_charsets_in_bufbyte_string (charsets, | |
1898 XSTRING_DATA (string), | |
1899 XSTRING_LENGTH (string)); | |
1900 | |
1901 /* Fallback to the default face if none was provided. */ | |
1902 if (!NILP (face)) | |
1903 { | |
1904 reset_face_cachel (&frame_cachel); | |
1905 update_face_cachel_data (&frame_cachel, frame, face); | |
1906 cachel = &frame_cachel; | |
1907 } | |
1908 else | |
1909 { | |
1910 cachel = WINDOW_FACE_CACHEL (XWINDOW (domain), DEFAULT_INDEX); | |
1911 } | |
1912 | |
1913 ensure_face_cachel_complete (cachel, domain, charsets); | |
1914 face_cachel_charset_font_metric_info (cachel, charsets, &fm); | |
1915 | |
1916 *height = fm.ascent + fm.descent; | |
1917 /* #### descent only gets set if we query the height as well. */ | |
1918 if (descent) | |
1919 *descent = fm.descent; | |
1920 } | |
1921 | |
1922 /* Compute width */ | |
1923 if (width) | |
1924 { | |
1925 if (!NILP (face)) | |
1926 *width = redisplay_frame_text_width_string (XFRAME (frame), | |
1927 face, | |
1928 0, string, 0, -1); | |
1929 else | |
1930 *width = redisplay_frame_text_width_string (XFRAME (frame), | |
1931 Vdefault_face, | |
1932 0, string, 0, -1); | |
1933 } | |
1934 } | |
1935 | |
1936 Lisp_Object | |
1937 query_string_font (Lisp_Object string, Lisp_Object face, Lisp_Object domain) | |
1938 { | |
1939 unsigned char charsets[NUM_LEADING_BYTES]; | |
1940 struct face_cachel frame_cachel; | |
1941 struct face_cachel *cachel; | |
1942 int i; | |
1943 Lisp_Object frame = FW_FRAME (domain); | |
1944 | |
1945 /* Compute string font info */ | |
1946 find_charsets_in_bufbyte_string (charsets, | |
1947 XSTRING_DATA (string), | |
1948 XSTRING_LENGTH (string)); | |
1949 | |
1950 reset_face_cachel (&frame_cachel); | |
1951 update_face_cachel_data (&frame_cachel, frame, face); | |
1952 cachel = &frame_cachel; | |
1953 | |
1954 ensure_face_cachel_complete (cachel, domain, charsets); | |
1955 | |
1956 for (i = 0; i < NUM_LEADING_BYTES; i++) | |
1957 { | |
1958 if (charsets[i]) | |
1959 { | |
1960 return FACE_CACHEL_FONT (cachel, | |
1961 CHARSET_BY_LEADING_BYTE (i + | |
1962 MIN_LEADING_BYTE)); | |
1963 | |
1964 } | |
1965 } | |
1966 | |
1967 return Qnil; /* NOT REACHED */ | |
1968 } | |
1969 | |
1970 static void | |
1971 text_query_geometry (Lisp_Object image_instance, | |
1972 unsigned int* width, unsigned int* height, | |
1973 enum image_instance_geometry disp, Lisp_Object domain) | |
1974 { | |
1975 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
1976 unsigned int descent = 0; | |
1977 | |
1978 query_string_geometry (IMAGE_INSTANCE_TEXT_STRING (ii), | |
1979 IMAGE_INSTANCE_FACE (ii), | |
1980 width, height, &descent, domain); | |
1981 | |
1982 /* The descent gets set as a side effect of querying the | |
1983 geometry. */ | |
1984 IMAGE_INSTANCE_TEXT_DESCENT (ii) = descent; | |
1985 } | |
1986 | |
1987 /* set the properties of a string */ | |
1988 static Lisp_Object | |
1989 text_set_property (Lisp_Object image_instance, Lisp_Object prop, | |
1990 Lisp_Object val) | |
1991 { | |
1992 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
1993 | |
1994 if (EQ (prop, Q_data)) | |
1995 { | |
1996 CHECK_STRING (val); | |
1997 IMAGE_INSTANCE_TEXT_STRING (ii) = val; | |
1998 | |
1999 return Qt; | |
2000 } | |
2001 return Qunbound; | |
1648 } | 2002 } |
1649 | 2003 |
1650 | 2004 |
1651 /**************************************************************************** | 2005 /**************************************************************************** |
1652 * formatted-string * | 2006 * formatted-string * |
1668 formatted_string_instantiate (Lisp_Object image_instance, | 2022 formatted_string_instantiate (Lisp_Object image_instance, |
1669 Lisp_Object instantiator, | 2023 Lisp_Object instantiator, |
1670 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 2024 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
1671 int dest_mask, Lisp_Object domain) | 2025 int dest_mask, Lisp_Object domain) |
1672 { | 2026 { |
1673 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
1674 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
1675 | |
1676 assert (!NILP (data)); | |
1677 /* #### implement this */ | 2027 /* #### implement this */ |
1678 warn_when_safe (Qunimplemented, Qnotice, | 2028 warn_when_safe (Qunimplemented, Qnotice, |
1679 "`formatted-string' not yet implemented; assuming `string'"); | 2029 "`formatted-string' not yet implemented; assuming `string'"); |
1680 if (dest_mask & IMAGE_TEXT_MASK) | 2030 |
1681 { | 2031 string_instantiate (image_instance, instantiator, |
1682 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT; | 2032 pointer_fg, pointer_bg, dest_mask, domain); |
1683 IMAGE_INSTANCE_TEXT_STRING (ii) = data; | |
1684 } | |
1685 else | |
1686 incompatible_image_types (instantiator, dest_mask, IMAGE_TEXT_MASK); | |
1687 } | 2033 } |
1688 | 2034 |
1689 | 2035 |
1690 /************************************************************************/ | 2036 /************************************************************************/ |
1691 /* pixmap file functions */ | 2037 /* pixmap file functions */ |
1845 int ok_if_data_invalid) | 2191 int ok_if_data_invalid) |
1846 { | 2192 { |
1847 unsigned int w, h; | 2193 unsigned int w, h; |
1848 Extbyte *data; | 2194 Extbyte *data; |
1849 int result; | 2195 int result; |
1850 CONST char *filename_ext; | 2196 const char *filename_ext; |
1851 | 2197 |
1852 GET_C_STRING_FILENAME_DATA_ALLOCA (name, filename_ext); | 2198 TO_EXTERNAL_FORMAT (LISP_STRING, name, |
2199 C_STRING_ALLOCA, filename_ext, | |
2200 Qfile_name); | |
1853 result = read_bitmap_data_from_file (filename_ext, &w, &h, | 2201 result = read_bitmap_data_from_file (filename_ext, &w, &h, |
1854 &data, xhot, yhot); | 2202 &data, xhot, yhot); |
1855 | 2203 |
1856 if (result == BitmapSuccess) | 2204 if (result == BitmapSuccess) |
1857 { | 2205 { |
1858 Lisp_Object retval; | 2206 Lisp_Object retval; |
1859 int len = (w + 7) / 8 * h; | 2207 int len = (w + 7) / 8 * h; |
1860 | 2208 |
1861 retval = list3 (make_int (w), make_int (h), | 2209 retval = list3 (make_int (w), make_int (h), |
1862 make_ext_string (data, len, FORMAT_BINARY)); | 2210 make_ext_string (data, len, Qbinary)); |
1863 XFree ((char *) data); | 2211 XFree ((char *) data); |
1864 return retval; | 2212 return retval; |
1865 } | 2213 } |
1866 | 2214 |
1867 switch (result) | 2215 switch (result) |
2090 pixmap_to_lisp_data (Lisp_Object name, int ok_if_data_invalid) | 2438 pixmap_to_lisp_data (Lisp_Object name, int ok_if_data_invalid) |
2091 { | 2439 { |
2092 char **data; | 2440 char **data; |
2093 int result; | 2441 int result; |
2094 char *fname = 0; | 2442 char *fname = 0; |
2095 | 2443 |
2096 GET_C_STRING_FILENAME_DATA_ALLOCA (name, fname); | 2444 TO_EXTERNAL_FORMAT (LISP_STRING, name, |
2445 C_STRING_ALLOCA, fname, | |
2446 Qfile_name); | |
2097 result = XpmReadFileToData (fname, &data); | 2447 result = XpmReadFileToData (fname, &data); |
2098 | 2448 |
2099 if (result == XpmSuccess) | 2449 if (result == XpmSuccess) |
2100 { | 2450 { |
2101 Lisp_Object retval = Qnil; | 2451 Lisp_Object retval = Qnil; |
2301 DEFINE_SPECIFIER_TYPE (image); | 2651 DEFINE_SPECIFIER_TYPE (image); |
2302 | 2652 |
2303 static void | 2653 static void |
2304 image_create (Lisp_Object obj) | 2654 image_create (Lisp_Object obj) |
2305 { | 2655 { |
2306 struct Lisp_Specifier *image = XIMAGE_SPECIFIER (obj); | 2656 Lisp_Specifier *image = XIMAGE_SPECIFIER (obj); |
2307 | 2657 |
2308 IMAGE_SPECIFIER_ALLOWED (image) = ~0; /* all are allowed */ | 2658 IMAGE_SPECIFIER_ALLOWED (image) = ~0; /* all are allowed */ |
2309 IMAGE_SPECIFIER_ATTACHEE (image) = Qnil; | 2659 IMAGE_SPECIFIER_ATTACHEE (image) = Qnil; |
2310 IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image) = Qnil; | 2660 IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image) = Qnil; |
2311 } | 2661 } |
2312 | 2662 |
2313 static void | 2663 static void |
2314 image_mark (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 2664 image_mark (Lisp_Object obj) |
2315 { | 2665 { |
2316 struct Lisp_Specifier *image = XIMAGE_SPECIFIER (obj); | 2666 Lisp_Specifier *image = XIMAGE_SPECIFIER (obj); |
2317 | 2667 |
2318 markobj (IMAGE_SPECIFIER_ATTACHEE (image)); | 2668 mark_object (IMAGE_SPECIFIER_ATTACHEE (image)); |
2319 markobj (IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image)); | 2669 mark_object (IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image)); |
2320 } | 2670 } |
2321 | 2671 |
2322 static Lisp_Object | 2672 static Lisp_Object |
2323 image_instantiate_cache_result (Lisp_Object locative) | 2673 image_instantiate_cache_result (Lisp_Object locative) |
2324 { | 2674 { |
2338 Lisp_Object domain, Lisp_Object instantiator, | 2688 Lisp_Object domain, Lisp_Object instantiator, |
2339 Lisp_Object depth) | 2689 Lisp_Object depth) |
2340 { | 2690 { |
2341 Lisp_Object device = DFW_DEVICE (domain); | 2691 Lisp_Object device = DFW_DEVICE (domain); |
2342 struct device *d = XDEVICE (device); | 2692 struct device *d = XDEVICE (device); |
2693 Lisp_Object glyph = IMAGE_SPECIFIER_ATTACHEE (XIMAGE_SPECIFIER (specifier)); | |
2343 int dest_mask = XIMAGE_SPECIFIER_ALLOWED (specifier); | 2694 int dest_mask = XIMAGE_SPECIFIER_ALLOWED (specifier); |
2344 int pointerp = dest_mask & image_instance_type_to_mask (IMAGE_POINTER); | 2695 int pointerp = dest_mask & image_instance_type_to_mask (IMAGE_POINTER); |
2345 | 2696 |
2346 if (IMAGE_INSTANCEP (instantiator)) | 2697 if (IMAGE_INSTANCEP (instantiator)) |
2347 { | 2698 { |
2391 if (UNBOUNDP (subtable)) | 2742 if (UNBOUNDP (subtable)) |
2392 { | 2743 { |
2393 /* For the image instance cache, we do comparisons with EQ rather | 2744 /* For the image instance cache, we do comparisons with EQ rather |
2394 than with EQUAL, as we do for color and font names. | 2745 than with EQUAL, as we do for color and font names. |
2395 The reasons are: | 2746 The reasons are: |
2396 | 2747 |
2397 1) pixmap data can be very long, and thus the hashing and | 2748 1) pixmap data can be very long, and thus the hashing and |
2398 comparing will take awhile. | 2749 comparing will take awhile. |
2399 2) It's not so likely that we'll run into things that are EQUAL | 2750 2) It's not so likely that we'll run into things that are EQUAL |
2400 but not EQ (that can happen a lot with faces, because their | 2751 but not EQ (that can happen a lot with faces, because their |
2401 specifiers are copied around); but pixmaps tend not to be | 2752 specifiers are copied around); but pixmaps tend not to be |
2427 will occur most of the time so this probably slows things | 2778 will occur most of the time so this probably slows things |
2428 down. But with the current design I don't see anyway | 2779 down. But with the current design I don't see anyway |
2429 round it. */ | 2780 round it. */ |
2430 if (UNBOUNDP (instance) | 2781 if (UNBOUNDP (instance) |
2431 && | 2782 && |
2432 dest_mask & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK)) | 2783 dest_mask & (IMAGE_SUBWINDOW_MASK |
2784 | IMAGE_WIDGET_MASK | |
2785 | IMAGE_TEXT_MASK)) | |
2433 { | 2786 { |
2434 if (!WINDOWP (domain)) | 2787 if (!WINDOWP (domain)) |
2435 signal_simple_error ("Can't instantiate subwindow outside a window", | 2788 signal_simple_error ("Can't instantiate text or subwindow outside a window", |
2436 instantiator); | 2789 instantiator); |
2437 instance = Fgethash (instantiator, | 2790 instance = Fgethash (instantiator, |
2438 XWINDOW (domain)->subwindow_instance_cache, | 2791 XWINDOW (domain)->subwindow_instance_cache, |
2439 Qunbound); | 2792 Qunbound); |
2440 } | 2793 } |
2441 } | 2794 } |
2442 | 2795 |
2443 if (UNBOUNDP (instance)) | 2796 if (UNBOUNDP (instance)) |
2445 Lisp_Object locative = | 2798 Lisp_Object locative = |
2446 noseeum_cons (Qnil, | 2799 noseeum_cons (Qnil, |
2447 noseeum_cons (pointerp ? ls3 : instantiator, | 2800 noseeum_cons (pointerp ? ls3 : instantiator, |
2448 subtable)); | 2801 subtable)); |
2449 int speccount = specpdl_depth (); | 2802 int speccount = specpdl_depth (); |
2450 | 2803 |
2451 /* make sure we cache the failures, too. | 2804 /* make sure we cache the failures, too. |
2452 Use an unwind-protect to catch such errors. | 2805 Use an unwind-protect to catch such errors. |
2453 If we fail, the unwind-protect records nil in | 2806 If we fail, the unwind-protect records nil in |
2454 the hash table. If we succeed, we change the | 2807 the hash table. If we succeed, we change the |
2455 car of the locative to the resulting instance, | 2808 car of the locative to the resulting instance, |
2458 locative); | 2811 locative); |
2459 instance = instantiate_image_instantiator (device, | 2812 instance = instantiate_image_instantiator (device, |
2460 domain, | 2813 domain, |
2461 instantiator, | 2814 instantiator, |
2462 pointer_fg, pointer_bg, | 2815 pointer_fg, pointer_bg, |
2463 dest_mask); | 2816 dest_mask, |
2464 | 2817 glyph); |
2818 | |
2465 Fsetcar (locative, instance); | 2819 Fsetcar (locative, instance); |
2466 /* only after the image has been instantiated do we know | 2820 /* only after the image has been instantiated do we know |
2467 whether we need to put it in the per-window image instance | 2821 whether we need to put it in the per-window image instance |
2468 cache. */ | 2822 cache. */ |
2469 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance)) | 2823 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance)) |
2471 (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK)) | 2825 (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK)) |
2472 { | 2826 { |
2473 if (!WINDOWP (domain)) | 2827 if (!WINDOWP (domain)) |
2474 signal_simple_error ("Can't instantiate subwindow outside a window", | 2828 signal_simple_error ("Can't instantiate subwindow outside a window", |
2475 instantiator); | 2829 instantiator); |
2476 | 2830 |
2477 Fsetcdr (XCDR (locative), XWINDOW (domain)->subwindow_instance_cache ); | 2831 Fsetcdr (XCDR (locative), XWINDOW (domain)->subwindow_instance_cache ); |
2478 } | 2832 } |
2479 unbind_to (speccount, Qnil); | 2833 unbind_to (speccount, Qnil); |
2480 } | 2834 } |
2481 else | 2835 else |
2569 | 2923 |
2570 void | 2924 void |
2571 set_image_attached_to (Lisp_Object obj, Lisp_Object face_or_glyph, | 2925 set_image_attached_to (Lisp_Object obj, Lisp_Object face_or_glyph, |
2572 Lisp_Object property) | 2926 Lisp_Object property) |
2573 { | 2927 { |
2574 struct Lisp_Specifier *image = XIMAGE_SPECIFIER (obj); | 2928 Lisp_Specifier *image = XIMAGE_SPECIFIER (obj); |
2575 | 2929 |
2576 IMAGE_SPECIFIER_ATTACHEE (image) = face_or_glyph; | 2930 IMAGE_SPECIFIER_ATTACHEE (image) = face_or_glyph; |
2577 IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image) = property; | 2931 IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image) = property; |
2578 } | 2932 } |
2579 | 2933 |
2622 } | 2976 } |
2623 | 2977 |
2624 UNGCPRO; | 2978 UNGCPRO; |
2625 | 2979 |
2626 return retlist; | 2980 return retlist; |
2981 } | |
2982 | |
2983 /* Copy an image instantiator. We can't use Fcopy_tree since widgets | |
2984 may contain circular references which would send Fcopy_tree into | |
2985 infloop death. */ | |
2986 static Lisp_Object | |
2987 image_copy_vector_instantiator (Lisp_Object instantiator) | |
2988 { | |
2989 int i; | |
2990 struct image_instantiator_methods *meths; | |
2991 Lisp_Object *elt; | |
2992 int instantiator_len; | |
2993 | |
2994 CHECK_VECTOR (instantiator); | |
2995 | |
2996 instantiator = Fcopy_sequence (instantiator); | |
2997 elt = XVECTOR_DATA (instantiator); | |
2998 instantiator_len = XVECTOR_LENGTH (instantiator); | |
2999 | |
3000 meths = decode_image_instantiator_format (elt[0], ERROR_ME); | |
3001 | |
3002 for (i = 1; i < instantiator_len; i += 2) | |
3003 { | |
3004 int j; | |
3005 Lisp_Object keyword = elt[i]; | |
3006 Lisp_Object value = elt[i+1]; | |
3007 | |
3008 /* Find the keyword entry. */ | |
3009 for (j = 0; j < Dynarr_length (meths->keywords); j++) | |
3010 { | |
3011 if (EQ (keyword, Dynarr_at (meths->keywords, j).keyword)) | |
3012 break; | |
3013 } | |
3014 | |
3015 /* Only copy keyword values that should be copied. */ | |
3016 if (Dynarr_at (meths->keywords, j).copy_p | |
3017 && | |
3018 (CONSP (value) || VECTORP (value))) | |
3019 { | |
3020 elt [i+1] = Fcopy_tree (value, Qt); | |
3021 } | |
3022 } | |
3023 | |
3024 return instantiator; | |
3025 } | |
3026 | |
3027 static Lisp_Object | |
3028 image_copy_instantiator (Lisp_Object arg) | |
3029 { | |
3030 if (CONSP (arg)) | |
3031 { | |
3032 Lisp_Object rest; | |
3033 rest = arg = Fcopy_sequence (arg); | |
3034 while (CONSP (rest)) | |
3035 { | |
3036 Lisp_Object elt = XCAR (rest); | |
3037 if (CONSP (elt)) | |
3038 XCAR (rest) = Fcopy_tree (elt, Qt); | |
3039 else if (VECTORP (elt)) | |
3040 XCAR (rest) = image_copy_vector_instantiator (elt); | |
3041 if (VECTORP (XCDR (rest))) /* hack for (a b . [c d]) */ | |
3042 XCDR (rest) = Fcopy_tree (XCDR (rest), Qt); | |
3043 rest = XCDR (rest); | |
3044 } | |
3045 } | |
3046 else if (VECTORP (arg)) | |
3047 { | |
3048 arg = image_copy_vector_instantiator (arg); | |
3049 } | |
3050 return arg; | |
2627 } | 3051 } |
2628 | 3052 |
2629 DEFUN ("image-specifier-p", Fimage_specifier_p, 1, 1, 0, /* | 3053 DEFUN ("image-specifier-p", Fimage_specifier_p, 1, 1, 0, /* |
2630 Return non-nil if OBJECT is an image specifier. | 3054 Return non-nil if OBJECT is an image specifier. |
2631 | 3055 |
2708 (A glyph from a font; i.e. the name of a font, and glyph index into it | 3132 (A glyph from a font; i.e. the name of a font, and glyph index into it |
2709 of the form "FONT fontname index [[mask-font] mask-index]". | 3133 of the form "FONT fontname index [[mask-font] mask-index]". |
2710 Currently can only be instanced as `pointer', although this should | 3134 Currently can only be instanced as `pointer', although this should |
2711 probably be fixed.) | 3135 probably be fixed.) |
2712 'subwindow | 3136 'subwindow |
2713 (An embedded X window; not currently implemented.) | 3137 (An embedded windowing system window.) |
2714 'widget | 3138 'edit-field |
2715 (A widget control, for instance text field or radio button.) | 3139 (A text editing widget glyph.) |
3140 'button | |
3141 (A button widget glyph; either a push button, radio button or toggle button.) | |
3142 'tab-control | |
3143 (A tab widget glyph; a series of user selectable tabs.) | |
3144 'progress-gauge | |
3145 (A sliding widget glyph, for showing progress.) | |
3146 'combo-box | |
3147 (A drop list of selectable items in a widget glyph, for editing text.) | |
3148 'label | |
3149 (A static, text-only, widget glyph; for displaying text.) | |
3150 'tree-view | |
3151 (A folding widget glyph.) | |
2716 'autodetect | 3152 'autodetect |
2717 (XEmacs tries to guess what format the data is in. If X support | 3153 (XEmacs tries to guess what format the data is in. If X support |
2718 exists, the data string will be checked to see if it names a filename. | 3154 exists, the data string will be checked to see if it names a filename. |
2719 If so, and this filename contains XBM or XPM data, the appropriate | 3155 If so, and this filename contains XBM or XPM data, the appropriate |
2720 sort of pixmap or pointer will be created. [This includes picking up | 3156 sort of pixmap or pointer will be created. [This includes picking up |
2772 that specify symbolic color names to the actual color to be used | 3208 that specify symbolic color names to the actual color to be used |
2773 for that symbolic color (in the form of a string or a color-specifier | 3209 for that symbolic color (in the form of a string or a color-specifier |
2774 object). If this is not specified, the contents of `xpm-color-symbols' | 3210 object). If this is not specified, the contents of `xpm-color-symbols' |
2775 are used to generate the alist.) | 3211 are used to generate the alist.) |
2776 :face | 3212 :face |
2777 (Only for `inherit'. This specifies the face to inherit from.) | 3213 (Only for `inherit'. This specifies the face to inherit from. |
3214 For widget glyphs this also specifies the face to use for | |
3215 display. It defaults to gui-element-face.) | |
3216 | |
3217 Keywords accepted as menu item specs are also accepted by widget | |
3218 glyphs. These are `:selected', `:active', `:suffix', `:keys', | |
3219 `:style', `:filter', `:config', `:included', `:key-sequence', | |
3220 `:accelerator', `:label' and `:callback'. | |
2778 | 3221 |
2779 If instead of a vector, the instantiator is a string, it will be | 3222 If instead of a vector, the instantiator is a string, it will be |
2780 converted into a vector by looking it up according to the specs in the | 3223 converted into a vector by looking it up according to the specs in the |
2781 `console-type-image-conversion-list' (q.v.) for the console type of | 3224 `console-type-image-conversion-list' (q.v.) for the console type of |
2782 the domain (usually a window; sometimes a frame or device) over which | 3225 the domain (usually a window; sometimes a frame or device) over which |
2800 /**************************************************************************** | 3243 /**************************************************************************** |
2801 * Glyph Object * | 3244 * Glyph Object * |
2802 ****************************************************************************/ | 3245 ****************************************************************************/ |
2803 | 3246 |
2804 static Lisp_Object | 3247 static Lisp_Object |
2805 mark_glyph (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 3248 mark_glyph (Lisp_Object obj) |
2806 { | 3249 { |
2807 struct Lisp_Glyph *glyph = XGLYPH (obj); | 3250 Lisp_Glyph *glyph = XGLYPH (obj); |
2808 | 3251 |
2809 markobj (glyph->image); | 3252 mark_object (glyph->image); |
2810 markobj (glyph->contrib_p); | 3253 mark_object (glyph->contrib_p); |
2811 markobj (glyph->baseline); | 3254 mark_object (glyph->baseline); |
2812 markobj (glyph->face); | 3255 mark_object (glyph->face); |
2813 | 3256 |
2814 return glyph->plist; | 3257 return glyph->plist; |
2815 } | 3258 } |
2816 | 3259 |
2817 static void | 3260 static void |
2818 print_glyph (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | 3261 print_glyph (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) |
2819 { | 3262 { |
2820 struct Lisp_Glyph *glyph = XGLYPH (obj); | 3263 Lisp_Glyph *glyph = XGLYPH (obj); |
2821 char buf[20]; | 3264 char buf[20]; |
2822 | 3265 |
2823 if (print_readably) | 3266 if (print_readably) |
2824 error ("printing unreadable object #<glyph 0x%x>", glyph->header.uid); | 3267 error ("printing unreadable object #<glyph 0x%x>", glyph->header.uid); |
2825 | 3268 |
2838 This isn't concerned with "unspecified" attributes, that's what | 3281 This isn't concerned with "unspecified" attributes, that's what |
2839 #'glyph-differs-from-default-p is for. */ | 3282 #'glyph-differs-from-default-p is for. */ |
2840 static int | 3283 static int |
2841 glyph_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) | 3284 glyph_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) |
2842 { | 3285 { |
2843 struct Lisp_Glyph *g1 = XGLYPH (obj1); | 3286 Lisp_Glyph *g1 = XGLYPH (obj1); |
2844 struct Lisp_Glyph *g2 = XGLYPH (obj2); | 3287 Lisp_Glyph *g2 = XGLYPH (obj2); |
2845 | 3288 |
2846 depth++; | 3289 depth++; |
2847 | 3290 |
2848 return (internal_equal (g1->image, g2->image, depth) && | 3291 return (internal_equal (g1->image, g2->image, depth) && |
2849 internal_equal (g1->contrib_p, g2->contrib_p, depth) && | 3292 internal_equal (g1->contrib_p, g2->contrib_p, depth) && |
2864 } | 3307 } |
2865 | 3308 |
2866 static Lisp_Object | 3309 static Lisp_Object |
2867 glyph_getprop (Lisp_Object obj, Lisp_Object prop) | 3310 glyph_getprop (Lisp_Object obj, Lisp_Object prop) |
2868 { | 3311 { |
2869 struct Lisp_Glyph *g = XGLYPH (obj); | 3312 Lisp_Glyph *g = XGLYPH (obj); |
2870 | 3313 |
2871 if (EQ (prop, Qimage)) return g->image; | 3314 if (EQ (prop, Qimage)) return g->image; |
2872 if (EQ (prop, Qcontrib_p)) return g->contrib_p; | 3315 if (EQ (prop, Qcontrib_p)) return g->contrib_p; |
2873 if (EQ (prop, Qbaseline)) return g->baseline; | 3316 if (EQ (prop, Qbaseline)) return g->baseline; |
2874 if (EQ (prop, Qface)) return g->face; | 3317 if (EQ (prop, Qface)) return g->face; |
2877 } | 3320 } |
2878 | 3321 |
2879 static int | 3322 static int |
2880 glyph_putprop (Lisp_Object obj, Lisp_Object prop, Lisp_Object value) | 3323 glyph_putprop (Lisp_Object obj, Lisp_Object prop, Lisp_Object value) |
2881 { | 3324 { |
2882 if ((EQ (prop, Qimage)) || | 3325 if (EQ (prop, Qimage) || |
2883 (EQ (prop, Qcontrib_p)) || | 3326 EQ (prop, Qcontrib_p) || |
2884 (EQ (prop, Qbaseline))) | 3327 EQ (prop, Qbaseline)) |
2885 return 0; | 3328 return 0; |
2886 | 3329 |
2887 if (EQ (prop, Qface)) | 3330 if (EQ (prop, Qface)) |
2888 { | 3331 { |
2889 XGLYPH (obj)->face = Fget_face (value); | 3332 XGLYPH (obj)->face = Fget_face (value); |
2895 } | 3338 } |
2896 | 3339 |
2897 static int | 3340 static int |
2898 glyph_remprop (Lisp_Object obj, Lisp_Object prop) | 3341 glyph_remprop (Lisp_Object obj, Lisp_Object prop) |
2899 { | 3342 { |
2900 if ((EQ (prop, Qimage)) || | 3343 if (EQ (prop, Qimage) || |
2901 (EQ (prop, Qcontrib_p)) || | 3344 EQ (prop, Qcontrib_p) || |
2902 (EQ (prop, Qbaseline))) | 3345 EQ (prop, Qbaseline)) |
2903 return -1; | 3346 return -1; |
2904 | 3347 |
2905 if (EQ (prop, Qface)) | 3348 if (EQ (prop, Qface)) |
2906 { | 3349 { |
2907 XGLYPH (obj)->face = Qnil; | 3350 XGLYPH (obj)->face = Qnil; |
2912 } | 3355 } |
2913 | 3356 |
2914 static Lisp_Object | 3357 static Lisp_Object |
2915 glyph_plist (Lisp_Object obj) | 3358 glyph_plist (Lisp_Object obj) |
2916 { | 3359 { |
2917 struct Lisp_Glyph *glyph = XGLYPH (obj); | 3360 Lisp_Glyph *glyph = XGLYPH (obj); |
2918 Lisp_Object result = glyph->plist; | 3361 Lisp_Object result = glyph->plist; |
2919 | 3362 |
2920 result = cons3 (Qface, glyph->face, result); | 3363 result = cons3 (Qface, glyph->face, result); |
2921 result = cons3 (Qbaseline, glyph->baseline, result); | 3364 result = cons3 (Qbaseline, glyph->baseline, result); |
2922 result = cons3 (Qcontrib_p, glyph->contrib_p, result); | 3365 result = cons3 (Qcontrib_p, glyph->contrib_p, result); |
2923 result = cons3 (Qimage, glyph->image, result); | 3366 result = cons3 (Qimage, glyph->image, result); |
2924 | 3367 |
2925 return result; | 3368 return result; |
2926 } | 3369 } |
2927 | 3370 |
3371 static const struct lrecord_description glyph_description[] = { | |
3372 { XD_LISP_OBJECT, offsetof (Lisp_Glyph, image) }, | |
3373 { XD_LISP_OBJECT, offsetof (Lisp_Glyph, contrib_p) }, | |
3374 { XD_LISP_OBJECT, offsetof (Lisp_Glyph, baseline) }, | |
3375 { XD_LISP_OBJECT, offsetof (Lisp_Glyph, face) }, | |
3376 { XD_LISP_OBJECT, offsetof (Lisp_Glyph, plist) }, | |
3377 { XD_END } | |
3378 }; | |
3379 | |
2928 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("glyph", glyph, | 3380 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("glyph", glyph, |
2929 mark_glyph, print_glyph, 0, | 3381 mark_glyph, print_glyph, 0, |
2930 glyph_equal, glyph_hash, | 3382 glyph_equal, glyph_hash, glyph_description, |
2931 glyph_getprop, glyph_putprop, | 3383 glyph_getprop, glyph_putprop, |
2932 glyph_remprop, glyph_plist, | 3384 glyph_remprop, glyph_plist, |
2933 struct Lisp_Glyph); | 3385 Lisp_Glyph); |
2934 | 3386 |
2935 Lisp_Object | 3387 Lisp_Object |
2936 allocate_glyph (enum glyph_type type, | 3388 allocate_glyph (enum glyph_type type, |
2937 void (*after_change) (Lisp_Object glyph, Lisp_Object property, | 3389 void (*after_change) (Lisp_Object glyph, Lisp_Object property, |
2938 Lisp_Object locale)) | 3390 Lisp_Object locale)) |
2939 { | 3391 { |
2940 /* This function can GC */ | 3392 /* This function can GC */ |
2941 Lisp_Object obj = Qnil; | 3393 Lisp_Object obj = Qnil; |
2942 struct Lisp_Glyph *g = | 3394 Lisp_Glyph *g = alloc_lcrecord_type (Lisp_Glyph, &lrecord_glyph); |
2943 alloc_lcrecord_type (struct Lisp_Glyph, lrecord_glyph); | |
2944 | 3395 |
2945 g->type = type; | 3396 g->type = type; |
2946 g->image = Fmake_specifier (Qimage); /* This function can GC */ | 3397 g->image = Fmake_specifier (Qimage); /* This function can GC */ |
3398 g->dirty = 0; | |
2947 switch (g->type) | 3399 switch (g->type) |
2948 { | 3400 { |
2949 case GLYPH_BUFFER: | 3401 case GLYPH_BUFFER: |
2950 XIMAGE_SPECIFIER_ALLOWED (g->image) = | 3402 XIMAGE_SPECIFIER_ALLOWED (g->image) = |
2951 IMAGE_NOTHING_MASK | IMAGE_TEXT_MASK | 3403 IMAGE_NOTHING_MASK | IMAGE_TEXT_MASK |
2952 | IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK | 3404 | IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK |
2953 | IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK; | 3405 | IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK |
3406 | IMAGE_LAYOUT_MASK; | |
2954 break; | 3407 break; |
2955 case GLYPH_POINTER: | 3408 case GLYPH_POINTER: |
2956 XIMAGE_SPECIFIER_ALLOWED (g->image) = | 3409 XIMAGE_SPECIFIER_ALLOWED (g->image) = |
2957 IMAGE_NOTHING_MASK | IMAGE_POINTER_MASK; | 3410 IMAGE_NOTHING_MASK | IMAGE_POINTER_MASK; |
2958 break; | 3411 break; |
2959 case GLYPH_ICON: | 3412 case GLYPH_ICON: |
2960 XIMAGE_SPECIFIER_ALLOWED (g->image) = | 3413 XIMAGE_SPECIFIER_ALLOWED (g->image) = |
2961 IMAGE_NOTHING_MASK | IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK; | 3414 IMAGE_NOTHING_MASK | IMAGE_MONO_PIXMAP_MASK |
3415 | IMAGE_COLOR_PIXMAP_MASK; | |
2962 break; | 3416 break; |
2963 default: | 3417 default: |
2964 abort (); | 3418 abort (); |
2965 } | 3419 } |
2966 | 3420 |
3089 case GLYPH_POINTER: return Qpointer; | 3543 case GLYPH_POINTER: return Qpointer; |
3090 case GLYPH_ICON: return Qicon; | 3544 case GLYPH_ICON: return Qicon; |
3091 } | 3545 } |
3092 } | 3546 } |
3093 | 3547 |
3548 Lisp_Object | |
3549 glyph_image_instance (Lisp_Object glyph, Lisp_Object domain, | |
3550 Error_behavior errb, int no_quit) | |
3551 { | |
3552 Lisp_Object specifier = GLYPH_IMAGE (XGLYPH (glyph)); | |
3553 | |
3554 /* This can never return Qunbound. All glyphs have 'nothing as | |
3555 a fallback. */ | |
3556 Lisp_Object image_instance = specifier_instance (specifier, Qunbound, | |
3557 domain, errb, no_quit, 0, | |
3558 Qzero); | |
3559 assert (!UNBOUNDP (image_instance)); | |
3560 | |
3561 return image_instance; | |
3562 } | |
3563 | |
3564 static Lisp_Object | |
3565 glyph_image_instance_maybe (Lisp_Object glyph_or_image, Lisp_Object window) | |
3566 { | |
3567 Lisp_Object instance = glyph_or_image; | |
3568 | |
3569 if (GLYPHP (glyph_or_image)) | |
3570 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1); | |
3571 | |
3572 return instance; | |
3573 } | |
3574 | |
3094 /***************************************************************************** | 3575 /***************************************************************************** |
3095 glyph_width | 3576 glyph_width |
3096 | 3577 |
3097 Return the width of the given GLYPH on the given WINDOW. If the | 3578 Return the width of the given GLYPH on the given WINDOW. |
3098 instance is a string then the width is calculated using the font of | 3579 Calculations are done based on recursively querying the geometry of |
3099 the given FACE, unless a face is defined by the glyph itself. | 3580 the associated image instances. |
3100 ****************************************************************************/ | 3581 ****************************************************************************/ |
3101 unsigned short | 3582 unsigned short |
3102 glyph_width (Lisp_Object glyph, Lisp_Object frame_face, | 3583 glyph_width (Lisp_Object glyph_or_image, Lisp_Object domain) |
3103 face_index window_findex, Lisp_Object window) | 3584 { |
3104 { | 3585 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image, |
3105 Lisp_Object instance; | 3586 domain); |
3106 Lisp_Object frame = XWINDOW (window)->frame; | |
3107 | |
3108 /* #### We somehow need to distinguish between the user causing this | |
3109 error condition and a bug causing it. */ | |
3110 if (!GLYPHP (glyph)) | |
3111 return 0; | |
3112 else | |
3113 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); | |
3114 | |
3115 if (!IMAGE_INSTANCEP (instance)) | 3587 if (!IMAGE_INSTANCEP (instance)) |
3116 return 0; | 3588 return 0; |
3117 | 3589 |
3118 switch (XIMAGE_INSTANCE_TYPE (instance)) | 3590 if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance)) |
3119 { | 3591 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY, |
3120 case IMAGE_TEXT: | 3592 IMAGE_UNSPECIFIED_GEOMETRY, domain); |
3121 { | 3593 |
3122 Lisp_Object str = XIMAGE_INSTANCE_TEXT_STRING (instance); | 3594 return XIMAGE_INSTANCE_WIDTH (instance); |
3123 Lisp_Object private_face = XGLYPH_FACE(glyph); | |
3124 | |
3125 if (!NILP (private_face)) | |
3126 return redisplay_frame_text_width_string (XFRAME (frame), | |
3127 private_face, | |
3128 0, str, 0, -1); | |
3129 else | |
3130 if (!NILP (frame_face)) | |
3131 return redisplay_frame_text_width_string (XFRAME (frame), | |
3132 frame_face, | |
3133 0, str, 0, -1); | |
3134 else | |
3135 return redisplay_text_width_string (XWINDOW (window), | |
3136 window_findex, | |
3137 0, str, 0, -1); | |
3138 } | |
3139 | |
3140 case IMAGE_MONO_PIXMAP: | |
3141 case IMAGE_COLOR_PIXMAP: | |
3142 case IMAGE_POINTER: | |
3143 return XIMAGE_INSTANCE_PIXMAP_WIDTH (instance); | |
3144 | |
3145 case IMAGE_NOTHING: | |
3146 return 0; | |
3147 | |
3148 case IMAGE_SUBWINDOW: | |
3149 case IMAGE_WIDGET: | |
3150 return XIMAGE_INSTANCE_SUBWINDOW_WIDTH (instance); | |
3151 | |
3152 default: | |
3153 abort (); | |
3154 return 0; | |
3155 } | |
3156 } | 3595 } |
3157 | 3596 |
3158 DEFUN ("glyph-width", Fglyph_width, 1, 2, 0, /* | 3597 DEFUN ("glyph-width", Fglyph_width, 1, 2, 0, /* |
3159 Return the width of GLYPH on WINDOW. | 3598 Return the width of GLYPH on WINDOW. |
3160 This may not be exact as it does not take into account all of the context | 3599 This may not be exact as it does not take into account all of the context |
3163 (glyph, window)) | 3602 (glyph, window)) |
3164 { | 3603 { |
3165 XSETWINDOW (window, decode_window (window)); | 3604 XSETWINDOW (window, decode_window (window)); |
3166 CHECK_GLYPH (glyph); | 3605 CHECK_GLYPH (glyph); |
3167 | 3606 |
3168 return make_int (glyph_width (glyph, Qnil, DEFAULT_INDEX, window)); | 3607 return make_int (glyph_width (glyph, window)); |
3169 } | 3608 } |
3170 | 3609 |
3171 #define RETURN_ASCENT 0 | 3610 unsigned short |
3172 #define RETURN_DESCENT 1 | 3611 glyph_ascent (Lisp_Object glyph_or_image, Lisp_Object domain) |
3173 #define RETURN_HEIGHT 2 | 3612 { |
3174 | 3613 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image, |
3175 Lisp_Object | 3614 domain); |
3176 glyph_image_instance (Lisp_Object glyph, Lisp_Object domain, | |
3177 Error_behavior errb, int no_quit) | |
3178 { | |
3179 Lisp_Object specifier = GLYPH_IMAGE (XGLYPH (glyph)); | |
3180 | |
3181 /* This can never return Qunbound. All glyphs have 'nothing as | |
3182 a fallback. */ | |
3183 return specifier_instance (specifier, Qunbound, domain, errb, no_quit, 0, | |
3184 Qzero); | |
3185 } | |
3186 | |
3187 static unsigned short | |
3188 glyph_height_internal (Lisp_Object glyph, Lisp_Object frame_face, | |
3189 face_index window_findex, Lisp_Object window, | |
3190 int function) | |
3191 { | |
3192 Lisp_Object instance; | |
3193 Lisp_Object frame = XWINDOW (window)->frame; | |
3194 | |
3195 if (!GLYPHP (glyph)) | |
3196 return 0; | |
3197 else | |
3198 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); | |
3199 | |
3200 if (!IMAGE_INSTANCEP (instance)) | 3615 if (!IMAGE_INSTANCEP (instance)) |
3201 return 0; | 3616 return 0; |
3202 | 3617 |
3203 switch (XIMAGE_INSTANCE_TYPE (instance)) | 3618 if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance)) |
3204 { | 3619 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY, |
3205 case IMAGE_TEXT: | 3620 IMAGE_UNSPECIFIED_GEOMETRY, domain); |
3206 { | 3621 |
3207 struct font_metric_info fm; | 3622 if (XIMAGE_INSTANCE_TYPE (instance) == IMAGE_TEXT) |
3208 Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance); | 3623 return XIMAGE_INSTANCE_TEXT_ASCENT (instance); |
3209 unsigned char charsets[NUM_LEADING_BYTES]; | 3624 else |
3210 struct face_cachel frame_cachel; | 3625 return XIMAGE_INSTANCE_HEIGHT (instance); |
3211 struct face_cachel *cachel; | |
3212 | |
3213 find_charsets_in_bufbyte_string (charsets, | |
3214 XSTRING_DATA (string), | |
3215 XSTRING_LENGTH (string)); | |
3216 | |
3217 if (!NILP (frame_face)) | |
3218 { | |
3219 reset_face_cachel (&frame_cachel); | |
3220 update_face_cachel_data (&frame_cachel, frame, frame_face); | |
3221 cachel = &frame_cachel; | |
3222 } | |
3223 else | |
3224 cachel = WINDOW_FACE_CACHEL (XWINDOW (window), window_findex); | |
3225 ensure_face_cachel_complete (cachel, window, charsets); | |
3226 | |
3227 face_cachel_charset_font_metric_info (cachel, charsets, &fm); | |
3228 | |
3229 switch (function) | |
3230 { | |
3231 case RETURN_ASCENT: return fm.ascent; | |
3232 case RETURN_DESCENT: return fm.descent; | |
3233 case RETURN_HEIGHT: return fm.ascent + fm.descent; | |
3234 default: | |
3235 abort (); | |
3236 return 0; /* not reached */ | |
3237 } | |
3238 } | |
3239 | |
3240 case IMAGE_MONO_PIXMAP: | |
3241 case IMAGE_COLOR_PIXMAP: | |
3242 case IMAGE_POINTER: | |
3243 /* #### Ugh ugh ugh -- temporary crap */ | |
3244 if (function == RETURN_ASCENT || function == RETURN_HEIGHT) | |
3245 return XIMAGE_INSTANCE_PIXMAP_HEIGHT (instance); | |
3246 else | |
3247 return 0; | |
3248 | |
3249 case IMAGE_NOTHING: | |
3250 return 0; | |
3251 | |
3252 case IMAGE_SUBWINDOW: | |
3253 case IMAGE_WIDGET: | |
3254 /* #### Ugh ugh ugh -- temporary crap */ | |
3255 if (function == RETURN_ASCENT || function == RETURN_HEIGHT) | |
3256 return XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (instance); | |
3257 else | |
3258 return 0; | |
3259 | |
3260 default: | |
3261 abort (); | |
3262 return 0; | |
3263 } | |
3264 } | 3626 } |
3265 | 3627 |
3266 unsigned short | 3628 unsigned short |
3267 glyph_ascent (Lisp_Object glyph, Lisp_Object frame_face, | 3629 glyph_descent (Lisp_Object glyph_or_image, Lisp_Object domain) |
3268 face_index window_findex, Lisp_Object window) | 3630 { |
3269 { | 3631 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image, |
3270 return glyph_height_internal (glyph, frame_face, window_findex, window, | 3632 domain); |
3271 RETURN_ASCENT); | 3633 if (!IMAGE_INSTANCEP (instance)) |
3272 } | 3634 return 0; |
3273 | 3635 |
3274 unsigned short | 3636 if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance)) |
3275 glyph_descent (Lisp_Object glyph, Lisp_Object frame_face, | 3637 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY, |
3276 face_index window_findex, Lisp_Object window) | 3638 IMAGE_UNSPECIFIED_GEOMETRY, domain); |
3277 { | 3639 |
3278 return glyph_height_internal (glyph, frame_face, window_findex, window, | 3640 if (XIMAGE_INSTANCE_TYPE (instance) == IMAGE_TEXT) |
3279 RETURN_DESCENT); | 3641 return XIMAGE_INSTANCE_TEXT_DESCENT (instance); |
3642 else | |
3643 return 0; | |
3280 } | 3644 } |
3281 | 3645 |
3282 /* strictly a convenience function. */ | 3646 /* strictly a convenience function. */ |
3283 unsigned short | 3647 unsigned short |
3284 glyph_height (Lisp_Object glyph, Lisp_Object frame_face, | 3648 glyph_height (Lisp_Object glyph_or_image, Lisp_Object domain) |
3285 face_index window_findex, Lisp_Object window) | 3649 { |
3286 { | 3650 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image, |
3287 return glyph_height_internal (glyph, frame_face, window_findex, window, | 3651 domain); |
3288 RETURN_HEIGHT); | 3652 |
3653 if (!IMAGE_INSTANCEP (instance)) | |
3654 return 0; | |
3655 | |
3656 if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance)) | |
3657 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY, | |
3658 IMAGE_UNSPECIFIED_GEOMETRY, domain); | |
3659 | |
3660 return XIMAGE_INSTANCE_HEIGHT (instance); | |
3289 } | 3661 } |
3290 | 3662 |
3291 DEFUN ("glyph-ascent", Fglyph_ascent, 1, 2, 0, /* | 3663 DEFUN ("glyph-ascent", Fglyph_ascent, 1, 2, 0, /* |
3292 Return the ascent value of GLYPH on WINDOW. | 3664 Return the ascent value of GLYPH on WINDOW. |
3293 This may not be exact as it does not take into account all of the context | 3665 This may not be exact as it does not take into account all of the context |
3296 (glyph, window)) | 3668 (glyph, window)) |
3297 { | 3669 { |
3298 XSETWINDOW (window, decode_window (window)); | 3670 XSETWINDOW (window, decode_window (window)); |
3299 CHECK_GLYPH (glyph); | 3671 CHECK_GLYPH (glyph); |
3300 | 3672 |
3301 return make_int (glyph_ascent (glyph, Qnil, DEFAULT_INDEX, window)); | 3673 return make_int (glyph_ascent (glyph, window)); |
3302 } | 3674 } |
3303 | 3675 |
3304 DEFUN ("glyph-descent", Fglyph_descent, 1, 2, 0, /* | 3676 DEFUN ("glyph-descent", Fglyph_descent, 1, 2, 0, /* |
3305 Return the descent value of GLYPH on WINDOW. | 3677 Return the descent value of GLYPH on WINDOW. |
3306 This may not be exact as it does not take into account all of the context | 3678 This may not be exact as it does not take into account all of the context |
3309 (glyph, window)) | 3681 (glyph, window)) |
3310 { | 3682 { |
3311 XSETWINDOW (window, decode_window (window)); | 3683 XSETWINDOW (window, decode_window (window)); |
3312 CHECK_GLYPH (glyph); | 3684 CHECK_GLYPH (glyph); |
3313 | 3685 |
3314 return make_int (glyph_descent (glyph, Qnil, DEFAULT_INDEX, window)); | 3686 return make_int (glyph_descent (glyph, window)); |
3315 } | 3687 } |
3316 | 3688 |
3317 /* This is redundant but I bet a lot of people expect it to exist. */ | 3689 /* This is redundant but I bet a lot of people expect it to exist. */ |
3318 DEFUN ("glyph-height", Fglyph_height, 1, 2, 0, /* | 3690 DEFUN ("glyph-height", Fglyph_height, 1, 2, 0, /* |
3319 Return the height of GLYPH on WINDOW. | 3691 Return the height of GLYPH on WINDOW. |
3323 (glyph, window)) | 3695 (glyph, window)) |
3324 { | 3696 { |
3325 XSETWINDOW (window, decode_window (window)); | 3697 XSETWINDOW (window, decode_window (window)); |
3326 CHECK_GLYPH (glyph); | 3698 CHECK_GLYPH (glyph); |
3327 | 3699 |
3328 return make_int (glyph_height (glyph, Qnil, DEFAULT_INDEX, window)); | 3700 return make_int (glyph_height (glyph, window)); |
3329 } | 3701 } |
3330 | 3702 |
3331 #undef RETURN_ASCENT | 3703 static void |
3332 #undef RETURN_DESCENT | 3704 set_glyph_dirty_p (Lisp_Object glyph_or_image, Lisp_Object window, int dirty) |
3333 #undef RETURN_HEIGHT | 3705 { |
3706 Lisp_Object instance = glyph_or_image; | |
3707 | |
3708 if (!NILP (glyph_or_image)) | |
3709 { | |
3710 if (GLYPHP (glyph_or_image)) | |
3711 { | |
3712 instance = glyph_image_instance (glyph_or_image, window, | |
3713 ERROR_ME_NOT, 1); | |
3714 XGLYPH_DIRTYP (glyph_or_image) = dirty; | |
3715 } | |
3716 | |
3717 XIMAGE_INSTANCE_DIRTYP (instance) = dirty; | |
3718 } | |
3719 } | |
3720 | |
3721 static void | |
3722 set_image_instance_dirty_p (Lisp_Object instance, int dirty) | |
3723 { | |
3724 if (IMAGE_INSTANCEP (instance)) | |
3725 { | |
3726 XIMAGE_INSTANCE_DIRTYP (instance) = dirty; | |
3727 /* Now cascade up the hierarchy. */ | |
3728 set_image_instance_dirty_p (XIMAGE_INSTANCE_PARENT (instance), | |
3729 dirty); | |
3730 } | |
3731 else if (GLYPHP (instance)) | |
3732 { | |
3733 XGLYPH_DIRTYP (instance) = dirty; | |
3734 } | |
3735 } | |
3334 | 3736 |
3335 /* #### do we need to cache this info to speed things up? */ | 3737 /* #### do we need to cache this info to speed things up? */ |
3336 | 3738 |
3337 Lisp_Object | 3739 Lisp_Object |
3338 glyph_baseline (Lisp_Object glyph, Lisp_Object domain) | 3740 glyph_baseline (Lisp_Object glyph, Lisp_Object domain) |
3384 { | 3786 { |
3385 if (XGLYPH (glyph)->after_change) | 3787 if (XGLYPH (glyph)->after_change) |
3386 (XGLYPH (glyph)->after_change) (glyph, property, locale); | 3788 (XGLYPH (glyph)->after_change) (glyph, property, locale); |
3387 } | 3789 } |
3388 | 3790 |
3791 #if 0 /* Not used for now */ | |
3792 static void | |
3793 glyph_query_geometry (Lisp_Object glyph_or_image, Lisp_Object window, | |
3794 unsigned int* width, unsigned int* height, | |
3795 enum image_instance_geometry disp, Lisp_Object domain) | |
3796 { | |
3797 Lisp_Object instance = glyph_or_image; | |
3798 | |
3799 if (GLYPHP (glyph_or_image)) | |
3800 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1); | |
3801 | |
3802 image_instance_query_geometry (instance, width, height, disp, domain); | |
3803 } | |
3804 | |
3805 static void | |
3806 glyph_layout (Lisp_Object glyph_or_image, Lisp_Object window, | |
3807 unsigned int width, unsigned int height, Lisp_Object domain) | |
3808 { | |
3809 Lisp_Object instance = glyph_or_image; | |
3810 | |
3811 if (GLYPHP (glyph_or_image)) | |
3812 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1); | |
3813 | |
3814 image_instance_layout (instance, width, height, domain); | |
3815 } | |
3816 #endif | |
3817 | |
3389 | 3818 |
3390 /***************************************************************************** | 3819 /***************************************************************************** |
3391 * glyph cachel functions * | 3820 * glyph cachel functions * |
3392 *****************************************************************************/ | 3821 *****************************************************************************/ |
3393 | 3822 |
3394 /* | 3823 /* #### All of this is 95% copied from face cachels. Consider |
3395 #### All of this is 95% copied from face cachels. | 3824 consolidating. |
3396 Consider consolidating. | 3825 |
3397 #### We need to add a dirty flag to the glyphs. | 3826 Why do we need glyph_cachels? Simply because a glyph_cachel captures |
3398 */ | 3827 per-window information about a particular glyph. A glyph itself is |
3399 | 3828 not created in any particular context, so if we were to rely on a |
3829 glyph to tell us about its dirtiness we would not be able to reset | |
3830 the dirty flag after redisplaying it as it may exist in other | |
3831 contexts. When we have redisplayed we need to know which glyphs to | |
3832 reset the dirty flags on - the glyph_cachels give us a nice list we | |
3833 can iterate through doing this. */ | |
3400 void | 3834 void |
3401 mark_glyph_cachels (glyph_cachel_dynarr *elements, | 3835 mark_glyph_cachels (glyph_cachel_dynarr *elements) |
3402 void (*markobj) (Lisp_Object)) | |
3403 { | 3836 { |
3404 int elt; | 3837 int elt; |
3405 | 3838 |
3406 if (!elements) | 3839 if (!elements) |
3407 return; | 3840 return; |
3408 | 3841 |
3409 for (elt = 0; elt < Dynarr_length (elements); elt++) | 3842 for (elt = 0; elt < Dynarr_length (elements); elt++) |
3410 { | 3843 { |
3411 struct glyph_cachel *cachel = Dynarr_atp (elements, elt); | 3844 struct glyph_cachel *cachel = Dynarr_atp (elements, elt); |
3412 markobj (cachel->glyph); | 3845 mark_object (cachel->glyph); |
3413 } | 3846 } |
3414 } | 3847 } |
3415 | 3848 |
3416 static void | 3849 static void |
3417 update_glyph_cachel_data (struct window *w, Lisp_Object glyph, | 3850 update_glyph_cachel_data (struct window *w, Lisp_Object glyph, |
3418 struct glyph_cachel *cachel) | 3851 struct glyph_cachel *cachel) |
3419 { | 3852 { |
3420 /* #### This should be || !cachel->updated */ | 3853 if (!cachel->updated || NILP (cachel->glyph) || !EQ (cachel->glyph, glyph) |
3421 if (NILP (cachel->glyph) || !EQ (cachel->glyph, glyph)) | 3854 || XGLYPH_DIRTYP (cachel->glyph) |
3422 { | 3855 || XFRAME(WINDOW_FRAME(w))->faces_changed) |
3423 Lisp_Object window; | 3856 { |
3857 Lisp_Object window, instance; | |
3424 | 3858 |
3425 XSETWINDOW (window, w); | 3859 XSETWINDOW (window, w); |
3426 | 3860 |
3427 /* #### This could be sped up if we redid things to grab the glyph | |
3428 instantiation and passed it to the size functions. */ | |
3429 cachel->glyph = glyph; | 3861 cachel->glyph = glyph; |
3430 cachel->width = glyph_width (glyph, Qnil, DEFAULT_INDEX, window); | 3862 /* Speed things up slightly by grabbing the glyph instantiation |
3431 cachel->ascent = glyph_ascent (glyph, Qnil, DEFAULT_INDEX, window); | 3863 and passing it to the size functions. */ |
3432 cachel->descent = glyph_descent (glyph, Qnil, DEFAULT_INDEX, window); | 3864 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); |
3865 | |
3866 /* Mark text instance of the glyph dirty if faces have changed, | |
3867 because its geometry might have changed. */ | |
3868 invalidate_glyph_geometry_maybe (instance, w); | |
3869 | |
3870 /* #### Do the following 2 lines buy us anything? --kkm */ | |
3871 XGLYPH_DIRTYP (glyph) = XIMAGE_INSTANCE_DIRTYP (instance); | |
3872 cachel->dirty = XGLYPH_DIRTYP (glyph); | |
3873 cachel->width = glyph_width (instance, window); | |
3874 cachel->ascent = glyph_ascent (instance, window); | |
3875 cachel->descent = glyph_descent (instance, window); | |
3433 } | 3876 } |
3434 | 3877 |
3435 cachel->updated = 1; | 3878 cachel->updated = 1; |
3436 } | 3879 } |
3437 | 3880 |
3445 | 3888 |
3446 update_glyph_cachel_data (w, glyph, &new_cachel); | 3889 update_glyph_cachel_data (w, glyph, &new_cachel); |
3447 Dynarr_add (w->glyph_cachels, new_cachel); | 3890 Dynarr_add (w->glyph_cachels, new_cachel); |
3448 } | 3891 } |
3449 | 3892 |
3450 static glyph_index | 3893 glyph_index |
3451 get_glyph_cachel_index (struct window *w, Lisp_Object glyph) | 3894 get_glyph_cachel_index (struct window *w, Lisp_Object glyph) |
3452 { | 3895 { |
3453 int elt; | 3896 int elt; |
3454 | 3897 |
3455 if (noninteractive) | 3898 if (noninteractive) |
3460 struct glyph_cachel *cachel = | 3903 struct glyph_cachel *cachel = |
3461 Dynarr_atp (w->glyph_cachels, elt); | 3904 Dynarr_atp (w->glyph_cachels, elt); |
3462 | 3905 |
3463 if (EQ (cachel->glyph, glyph) && !NILP (glyph)) | 3906 if (EQ (cachel->glyph, glyph) && !NILP (glyph)) |
3464 { | 3907 { |
3465 if (!cachel->updated) | 3908 update_glyph_cachel_data (w, glyph, cachel); |
3466 update_glyph_cachel_data (w, glyph, cachel); | |
3467 return elt; | 3909 return elt; |
3468 } | 3910 } |
3469 } | 3911 } |
3470 | 3912 |
3471 /* If we didn't find the glyph, add it and then return its index. */ | 3913 /* If we didn't find the glyph, add it and then return its index. */ |
3504 FROB (Voctal_escape_glyph, OCT_ESC_GLYPH_INDEX); | 3946 FROB (Voctal_escape_glyph, OCT_ESC_GLYPH_INDEX); |
3505 FROB (Vinvisible_text_glyph, INVIS_GLYPH_INDEX); | 3947 FROB (Vinvisible_text_glyph, INVIS_GLYPH_INDEX); |
3506 #undef FROB | 3948 #undef FROB |
3507 | 3949 |
3508 for (elt = 0; elt < Dynarr_length (w->glyph_cachels); elt++) | 3950 for (elt = 0; elt < Dynarr_length (w->glyph_cachels); elt++) |
3509 Dynarr_atp (w->glyph_cachels, elt)->updated = 0; | 3951 { |
3952 Dynarr_atp (w->glyph_cachels, elt)->updated = 0; | |
3953 } | |
3954 } | |
3955 | |
3956 /* Unset the dirty bit on all the glyph cachels that have it. */ | |
3957 void | |
3958 mark_glyph_cachels_as_clean (struct window* w) | |
3959 { | |
3960 int elt; | |
3961 Lisp_Object window; | |
3962 XSETWINDOW (window, w); | |
3963 for (elt = 0; elt < Dynarr_length (w->glyph_cachels); elt++) | |
3964 { | |
3965 struct glyph_cachel *cachel = Dynarr_atp (w->glyph_cachels, elt); | |
3966 cachel->dirty = 0; | |
3967 set_glyph_dirty_p (cachel->glyph, window, 0); | |
3968 } | |
3510 } | 3969 } |
3511 | 3970 |
3512 #ifdef MEMORY_USAGE_STATS | 3971 #ifdef MEMORY_USAGE_STATS |
3513 | 3972 |
3514 int | 3973 int |
3528 | 3987 |
3529 | 3988 |
3530 /***************************************************************************** | 3989 /***************************************************************************** |
3531 * subwindow cachel functions * | 3990 * subwindow cachel functions * |
3532 *****************************************************************************/ | 3991 *****************************************************************************/ |
3533 /* subwindows are curious in that you have to physically unmap them to | 3992 /* Subwindows are curious in that you have to physically unmap them to |
3534 not display them. It is problematic deciding what to do in | 3993 not display them. It is problematic deciding what to do in |
3535 redisplay. We have two caches - a per-window instance cache that | 3994 redisplay. We have two caches - a per-window instance cache that |
3536 keeps track of subwindows on a window, these are linked to their | 3995 keeps track of subwindows on a window, these are linked to their |
3537 instantiator in the hashtable and when the instantiator goes away | 3996 instantiator in the hashtable and when the instantiator goes away |
3538 we want the instance to go away also. However we also have a | 3997 we want the instance to go away also. However we also have a |
3539 per-frame instance cache that we use to determine if a subwindow is | 3998 per-frame instance cache that we use to determine if a subwindow is |
3540 obscuring an area that we want to clear. We need to be able to flip | 3999 obscuring an area that we want to clear. We need to be able to flip |
3541 through this quickly so a hashtable is not suitable hence the | 4000 through this quickly so a hashtable is not suitable hence the |
3542 subwindow_cachels. The question is should we just not mark | 4001 subwindow_cachels. The question is should we just not mark |
3543 instances in the subwindow_cachelsnor should we try and invalidate | 4002 instances in the subwindow_cachels or should we try and invalidate |
3544 the cache at suitable points in redisplay? If we don't invalidate | 4003 the cache at suitable points in redisplay? If we don't invalidate |
3545 the cache it will fill up with crud that will only get removed when | 4004 the cache it will fill up with crud that will only get removed when |
3546 the frame is deleted. So invalidation is good, the question is when | 4005 the frame is deleted. So invalidation is good, the question is when |
3547 and whether we mark as well. Go for the simple option - don't mark, | 4006 and whether we mark as well. Go for the simple option - don't mark, |
3548 MARK_SUBWINDOWS_CHANGED when a subwindow gets deleted. */ | 4007 MARK_SUBWINDOWS_CHANGED when a subwindow gets deleted. */ |
3549 | 4008 |
3550 void | 4009 void |
3551 mark_subwindow_cachels (subwindow_cachel_dynarr *elements, | 4010 mark_subwindow_cachels (subwindow_cachel_dynarr *elements) |
3552 void (*markobj) (Lisp_Object)) | |
3553 { | 4011 { |
3554 int elt; | 4012 int elt; |
3555 | 4013 |
3556 if (!elements) | 4014 if (!elements) |
3557 return; | 4015 return; |
3558 | 4016 |
3559 for (elt = 0; elt < Dynarr_length (elements); elt++) | 4017 for (elt = 0; elt < Dynarr_length (elements); elt++) |
3560 { | 4018 { |
3561 struct subwindow_cachel *cachel = Dynarr_atp (elements, elt); | 4019 struct subwindow_cachel *cachel = Dynarr_atp (elements, elt); |
3562 markobj (cachel->subwindow); | 4020 mark_object (cachel->subwindow); |
3563 } | 4021 } |
3564 } | 4022 } |
3565 | 4023 |
3566 static void | 4024 static void |
3567 update_subwindow_cachel_data (struct frame *f, Lisp_Object subwindow, | 4025 update_subwindow_cachel_data (struct frame *f, Lisp_Object subwindow, |
3568 struct subwindow_cachel *cachel) | 4026 struct subwindow_cachel *cachel) |
3569 { | 4027 { |
3570 if (NILP (cachel->subwindow) || !EQ (cachel->subwindow, subwindow)) | 4028 cachel->subwindow = subwindow; |
3571 { | 4029 cachel->width = XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow); |
3572 cachel->subwindow = subwindow; | 4030 cachel->height = XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow); |
3573 cachel->width = XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow); | |
3574 cachel->height = XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow); | |
3575 } | |
3576 | |
3577 cachel->updated = 1; | 4031 cachel->updated = 1; |
3578 } | 4032 } |
3579 | 4033 |
3580 static void | 4034 static void |
3581 add_subwindow_cachel (struct frame *f, Lisp_Object subwindow) | 4035 add_subwindow_cachel (struct frame *f, Lisp_Object subwindow) |
3614 } | 4068 } |
3615 | 4069 |
3616 /* If we didn't find the glyph, add it and then return its index. */ | 4070 /* If we didn't find the glyph, add it and then return its index. */ |
3617 add_subwindow_cachel (f, subwindow); | 4071 add_subwindow_cachel (f, subwindow); |
3618 return elt; | 4072 return elt; |
4073 } | |
4074 | |
4075 static void | |
4076 update_subwindow_cachel (Lisp_Object subwindow) | |
4077 { | |
4078 struct frame* f; | |
4079 int elt; | |
4080 | |
4081 if (NILP (subwindow)) | |
4082 return; | |
4083 | |
4084 f = XFRAME ( XIMAGE_INSTANCE_SUBWINDOW_FRAME (subwindow)); | |
4085 | |
4086 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) | |
4087 { | |
4088 struct subwindow_cachel *cachel = | |
4089 Dynarr_atp (f->subwindow_cachels, elt); | |
4090 | |
4091 if (EQ (cachel->subwindow, subwindow) && !NILP (subwindow)) | |
4092 { | |
4093 update_subwindow_cachel_data (f, subwindow, cachel); | |
4094 } | |
4095 } | |
3619 } | 4096 } |
3620 | 4097 |
3621 /* redisplay in general assumes that drawing something will erase | 4098 /* redisplay in general assumes that drawing something will erase |
3622 what was there before. unfortunately this does not apply to | 4099 what was there before. unfortunately this does not apply to |
3623 subwindows that need to be specifically unmapped in order to | 4100 subwindows that need to be specifically unmapped in order to |
3632 struct subwindow_cachel *cachel = | 4109 struct subwindow_cachel *cachel = |
3633 Dynarr_atp (f->subwindow_cachels, elt); | 4110 Dynarr_atp (f->subwindow_cachels, elt); |
3634 | 4111 |
3635 if (!NILP (cachel->subwindow) && cachel->being_displayed) | 4112 if (!NILP (cachel->subwindow) && cachel->being_displayed) |
3636 { | 4113 { |
3637 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (cachel->subwindow); | 4114 cachel->updated = 1; |
3638 MAYBE_DEVMETH (XDEVICE (f->device), unmap_subwindow, (ii)); | 4115 /* #### This is not optimal as update_subwindow will search |
4116 the cachels for ourselves as well. We could easily optimize. */ | |
4117 unmap_subwindow (cachel->subwindow); | |
3639 } | 4118 } |
3640 } | 4119 } |
3641 Dynarr_reset (f->subwindow_cachels); | 4120 Dynarr_reset (f->subwindow_cachels); |
3642 } | 4121 } |
3643 | 4122 |
3646 { | 4125 { |
3647 int elt; | 4126 int elt; |
3648 | 4127 |
3649 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) | 4128 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) |
3650 Dynarr_atp (f->subwindow_cachels, elt)->updated = 0; | 4129 Dynarr_atp (f->subwindow_cachels, elt)->updated = 0; |
4130 } | |
4131 | |
4132 | |
4133 | |
4134 /***************************************************************************** | |
4135 * subwindow exposure ignorance * | |
4136 *****************************************************************************/ | |
4137 /* when we unmap subwindows the associated window system will generate | |
4138 expose events. This we do not want as redisplay already copes with | |
4139 the repainting necessary. Worse, we can get in an endless cycle of | |
4140 redisplay if we are not careful. Thus we keep a per-frame list of | |
4141 expose events that are going to come and ignore them as | |
4142 required. */ | |
4143 | |
4144 struct expose_ignore_blocktype | |
4145 { | |
4146 Blocktype_declare (struct expose_ignore); | |
4147 } *the_expose_ignore_blocktype; | |
4148 | |
4149 int | |
4150 check_for_ignored_expose (struct frame* f, int x, int y, int width, int height) | |
4151 { | |
4152 struct expose_ignore *ei, *prev; | |
4153 /* the ignore list is FIFO so we should generally get a match with | |
4154 the first element in the list */ | |
4155 for (ei = f->subwindow_exposures, prev = 0; ei; ei = ei->next) | |
4156 { | |
4157 /* Checking for exact matches just isn't good enough as we | |
4158 mighte get exposures for partially obscure subwindows, thus | |
4159 we have to check for overlaps. Being conservative we will | |
4160 check for exposures wholly contained by the subwindow, this | |
4161 might give us what we want.*/ | |
4162 if (ei->x <= x && ei->y <= y | |
4163 && ei->x + ei->width >= x + width | |
4164 && ei->y + ei->height >= y + height) | |
4165 { | |
4166 #ifdef DEBUG_WIDGETS | |
4167 stderr_out ("ignored %d+%d, %dx%d for exposure %d+%d, %dx%d\n", | |
4168 x, y, width, height, ei->x, ei->y, ei->width, ei->height); | |
4169 #endif | |
4170 if (!prev) | |
4171 f->subwindow_exposures = ei->next; | |
4172 else | |
4173 prev->next = ei->next; | |
4174 | |
4175 if (ei == f->subwindow_exposures_tail) | |
4176 f->subwindow_exposures_tail = prev; | |
4177 | |
4178 Blocktype_free (the_expose_ignore_blocktype, ei); | |
4179 return 1; | |
4180 } | |
4181 prev = ei; | |
4182 } | |
4183 return 0; | |
4184 } | |
4185 | |
4186 static void | |
4187 register_ignored_expose (struct frame* f, int x, int y, int width, int height) | |
4188 { | |
4189 if (!hold_ignored_expose_registration) | |
4190 { | |
4191 struct expose_ignore *ei; | |
4192 | |
4193 ei = Blocktype_alloc (the_expose_ignore_blocktype); | |
4194 | |
4195 ei->next = NULL; | |
4196 ei->x = x; | |
4197 ei->y = y; | |
4198 ei->width = width; | |
4199 ei->height = height; | |
4200 | |
4201 /* we have to add the exposure to the end of the list, since we | |
4202 want to check the oldest events first. for speed we keep a record | |
4203 of the end so that we can add right to it. */ | |
4204 if (f->subwindow_exposures_tail) | |
4205 { | |
4206 f->subwindow_exposures_tail->next = ei; | |
4207 } | |
4208 if (!f->subwindow_exposures) | |
4209 { | |
4210 f->subwindow_exposures = ei; | |
4211 } | |
4212 f->subwindow_exposures_tail = ei; | |
4213 } | |
4214 } | |
4215 | |
4216 /**************************************************************************** | |
4217 find_matching_subwindow | |
4218 | |
4219 See if there is a subwindow that completely encloses the requested | |
4220 area. | |
4221 ****************************************************************************/ | |
4222 int find_matching_subwindow (struct frame* f, int x, int y, int width, int height) | |
4223 { | |
4224 int elt; | |
4225 | |
4226 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) | |
4227 { | |
4228 struct subwindow_cachel *cachel = | |
4229 Dynarr_atp (f->subwindow_cachels, elt); | |
4230 | |
4231 if (cachel->being_displayed | |
4232 && | |
4233 cachel->x <= x && cachel->y <= y | |
4234 && | |
4235 cachel->x + cachel->width >= x + width | |
4236 && | |
4237 cachel->y + cachel->height >= y + height) | |
4238 { | |
4239 return 1; | |
4240 } | |
4241 } | |
4242 return 0; | |
3651 } | 4243 } |
3652 | 4244 |
3653 | 4245 |
3654 /***************************************************************************** | 4246 /***************************************************************************** |
3655 * subwindow functions * | 4247 * subwindow functions * |
3656 *****************************************************************************/ | 4248 *****************************************************************************/ |
3657 | 4249 |
3658 /* update the displayed characteristics of a subwindow */ | 4250 /* update the displayed characteristics of a subwindow */ |
3659 static void | 4251 void |
3660 update_subwindow (Lisp_Object subwindow) | 4252 update_subwindow (Lisp_Object subwindow) |
3661 { | 4253 { |
3662 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); | 4254 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); |
3663 | 4255 |
3664 if (!IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET | 4256 if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET |
3665 || | 4257 || |
3666 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) | 4258 IMAGE_INSTANCE_TYPE (ii) == IMAGE_LAYOUT) |
3667 return; | 4259 { |
3668 | 4260 if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET) |
3669 MAYBE_DEVMETH (XDEVICE (ii->device), update_subwindow, (ii)); | 4261 update_widget (subwindow); |
3670 } | 4262 /* Reset the changed flags. */ |
3671 | 4263 IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) = 0; |
4264 IMAGE_INSTANCE_WIDGET_PERCENT_CHANGED (ii) = 0; | |
4265 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0; | |
4266 IMAGE_INSTANCE_TEXT_CHANGED (ii) = 0; | |
4267 } | |
4268 else if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW | |
4269 && | |
4270 !NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) | |
4271 { | |
4272 MAYBE_DEVMETH (XDEVICE (ii->device), update_subwindow, (ii)); | |
4273 } | |
4274 | |
4275 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 0; | |
4276 } | |
4277 | |
4278 /* Update all the subwindows on a frame. */ | |
3672 void | 4279 void |
3673 update_frame_subwindows (struct frame *f) | 4280 update_frame_subwindows (struct frame *f) |
3674 { | 4281 { |
3675 int elt; | 4282 int elt; |
3676 | 4283 |
3677 if (f->subwindows_changed || f->glyphs_changed) | 4284 /* #### Checking all of these might be overkill now that we update |
4285 subwindows in the actual redisplay code. */ | |
4286 if (f->subwindows_changed || f->subwindows_state_changed || f->faces_changed) | |
3678 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) | 4287 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) |
3679 { | 4288 { |
3680 struct subwindow_cachel *cachel = | 4289 struct subwindow_cachel *cachel = |
3681 Dynarr_atp (f->subwindow_cachels, elt); | 4290 Dynarr_atp (f->subwindow_cachels, elt); |
3682 | 4291 |
3683 if (cachel->being_displayed) | 4292 if (cachel->being_displayed) |
3684 { | 4293 { |
3685 update_subwindow (cachel->subwindow); | 4294 update_subwindow (cachel->subwindow); |
3686 } | 4295 } |
3687 } | 4296 } |
3688 } | 4297 } |
3689 | 4298 |
3690 /* remove a subwindow from its frame */ | 4299 /* remove a subwindow from its frame */ |
3691 void unmap_subwindow (Lisp_Object subwindow) | 4300 void unmap_subwindow (Lisp_Object subwindow) |
3692 { | 4301 { |
3693 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); | 4302 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); |
3694 int elt; | 4303 int elt; |
3695 struct subwindow_cachel* cachel; | 4304 struct subwindow_cachel* cachel; |
3696 struct frame* f; | 4305 struct frame* f; |
3697 | 4306 |
3698 if (!(IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET | 4307 if (!(IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET |
3699 || | 4308 || |
3700 IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW) | 4309 IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW) |
3701 || | 4310 || |
3702 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) | 4311 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) |
3703 return; | 4312 return; |
3704 | 4313 #ifdef DEBUG_WIDGETS |
4314 stderr_out ("unmapping subwindow %d\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii)); | |
4315 #endif | |
3705 f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); | 4316 f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); |
3706 elt = get_subwindow_cachel_index (f, subwindow); | 4317 elt = get_subwindow_cachel_index (f, subwindow); |
3707 cachel = Dynarr_atp (f->subwindow_cachels, elt); | 4318 cachel = Dynarr_atp (f->subwindow_cachels, elt); |
3708 | 4319 |
3709 cachel->x = -1; | 4320 /* make sure we don't get expose events */ |
3710 cachel->y = -1; | 4321 register_ignored_expose (f, cachel->x, cachel->y, cachel->width, cachel->height); |
4322 cachel->x = ~0; | |
4323 cachel->y = ~0; | |
3711 cachel->being_displayed = 0; | 4324 cachel->being_displayed = 0; |
3712 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; | 4325 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; |
3713 | 4326 |
3714 MAYBE_DEVMETH (XDEVICE (ii->device), unmap_subwindow, (ii)); | 4327 MAYBE_DEVMETH (XDEVICE (ii->device), unmap_subwindow, (ii)); |
3715 } | 4328 } |
3716 | 4329 |
3717 /* show a subwindow in its frame */ | 4330 /* show a subwindow in its frame */ |
3718 void map_subwindow (Lisp_Object subwindow, int x, int y) | 4331 void map_subwindow (Lisp_Object subwindow, int x, int y, |
3719 { | 4332 struct display_glyph_area *dga) |
3720 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); | 4333 { |
3721 int elt; | 4334 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); |
4335 int elt; | |
3722 struct subwindow_cachel* cachel; | 4336 struct subwindow_cachel* cachel; |
3723 struct frame* f; | 4337 struct frame* f; |
3724 | 4338 |
3725 if (!(IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET | 4339 if (!(IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET |
3726 || | 4340 || |
3727 IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW) | 4341 IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW) |
3728 || | 4342 || |
3729 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) | 4343 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) |
3730 return; | 4344 return; |
3731 | 4345 |
4346 #ifdef DEBUG_WIDGETS | |
4347 stderr_out ("mapping subwindow %d, %dx%d@%d+%d\n", | |
4348 IMAGE_INSTANCE_SUBWINDOW_ID (ii), | |
4349 dga->width, dga->height, x, y); | |
4350 #endif | |
3732 f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); | 4351 f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); |
3733 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 1; | 4352 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 1; |
3734 elt = get_subwindow_cachel_index (f, subwindow); | 4353 elt = get_subwindow_cachel_index (f, subwindow); |
3735 cachel = Dynarr_atp (f->subwindow_cachels, elt); | 4354 cachel = Dynarr_atp (f->subwindow_cachels, elt); |
3736 cachel->x = x; | 4355 cachel->x = x; |
3737 cachel->y = y; | 4356 cachel->y = y; |
4357 cachel->width = dga->width; | |
4358 cachel->height = dga->height; | |
3738 cachel->being_displayed = 1; | 4359 cachel->being_displayed = 1; |
3739 | 4360 |
3740 MAYBE_DEVMETH (XDEVICE (ii->device), map_subwindow, (ii, x, y)); | 4361 #if 0 |
4362 /* This forces any pending display changes to happen to the image | |
4363 before we show it. I'm not sure whether or not we need mark as | |
4364 clean here, but for now we will. */ | |
4365 if (IMAGE_INSTANCE_DIRTYP (ii)) | |
4366 { | |
4367 update_subwindow (subwindow); | |
4368 IMAGE_INSTANCE_DIRTYP (ii) = 0; | |
4369 } | |
4370 #endif | |
4371 | |
4372 MAYBE_DEVMETH (XDEVICE (ii->device), map_subwindow, (ii, x, y, dga)); | |
3741 } | 4373 } |
3742 | 4374 |
3743 static int | 4375 static int |
3744 subwindow_possible_dest_types (void) | 4376 subwindow_possible_dest_types (void) |
3745 { | 4377 { |
3750 void | 4382 void |
3751 subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | 4383 subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, |
3752 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 4384 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
3753 int dest_mask, Lisp_Object domain) | 4385 int dest_mask, Lisp_Object domain) |
3754 { | 4386 { |
3755 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | 4387 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
3756 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | 4388 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); |
3757 Lisp_Object frame = FW_FRAME (domain); | 4389 Lisp_Object frame = FW_FRAME (domain); |
3758 Lisp_Object width = find_keyword_in_vector (instantiator, Q_pixel_width); | 4390 Lisp_Object width = find_keyword_in_vector (instantiator, Q_pixel_width); |
3759 Lisp_Object height = find_keyword_in_vector (instantiator, Q_pixel_height); | 4391 Lisp_Object height = find_keyword_in_vector (instantiator, Q_pixel_height); |
3760 | 4392 |
3761 if (NILP (frame)) | 4393 if (NILP (frame)) |
3762 signal_simple_error ("No selected frame", device); | 4394 signal_simple_error ("No selected frame", device); |
3763 | 4395 |
3764 if (!(dest_mask & IMAGE_SUBWINDOW_MASK)) | 4396 if (!(dest_mask & IMAGE_SUBWINDOW_MASK)) |
3765 incompatible_image_types (instantiator, dest_mask, IMAGE_SUBWINDOW_MASK); | 4397 incompatible_image_types (instantiator, dest_mask, IMAGE_SUBWINDOW_MASK); |
3766 | 4398 |
3767 ii->data = 0; | 4399 ii->data = 0; |
3768 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0; | 4400 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0; |
3769 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = Qnil; | |
3770 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; | 4401 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; |
3771 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = frame; | 4402 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = frame; |
3772 | 4403 |
3773 /* this stuff may get overidden by the widget code */ | 4404 /* #### This stuff may get overidden by the widget code and is |
4405 actually really dumb now that we have dynamic geometry | |
4406 calculations. What should really happen is that the subwindow | |
4407 should query its child for an appropriate geometry. */ | |
3774 if (NILP (width)) | 4408 if (NILP (width)) |
3775 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = 20; | 4409 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = 20; |
3776 else | 4410 else |
3777 { | 4411 { |
3778 int w = 1; | 4412 int w = 1; |
3806 Return the window id of SUBWINDOW as a number. | 4440 Return the window id of SUBWINDOW as a number. |
3807 */ | 4441 */ |
3808 (subwindow)) | 4442 (subwindow)) |
3809 { | 4443 { |
3810 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); | 4444 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); |
3811 return make_int ((int) (XIMAGE_INSTANCE_SUBWINDOW_ID (subwindow))); | 4445 return make_int ((int) XIMAGE_INSTANCE_SUBWINDOW_ID (subwindow)); |
3812 } | 4446 } |
3813 | 4447 |
3814 DEFUN ("resize-subwindow", Fresize_subwindow, 1, 3, 0, /* | 4448 DEFUN ("resize-subwindow", Fresize_subwindow, 1, 3, 0, /* |
3815 Resize SUBWINDOW to WIDTH x HEIGHT. | 4449 Resize SUBWINDOW to WIDTH x HEIGHT. |
3816 If a value is nil that parameter is not changed. | 4450 If a value is nil that parameter is not changed. |
3817 */ | 4451 */ |
3818 (subwindow, width, height)) | 4452 (subwindow, width, height)) |
3819 { | 4453 { |
3820 int neww, newh; | 4454 int neww, newh; |
4455 Lisp_Image_Instance* ii; | |
3821 | 4456 |
3822 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); | 4457 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); |
4458 ii = XIMAGE_INSTANCE (subwindow); | |
3823 | 4459 |
3824 if (NILP (width)) | 4460 if (NILP (width)) |
3825 neww = XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow); | 4461 neww = IMAGE_INSTANCE_WIDTH (ii); |
3826 else | 4462 else |
3827 neww = XINT (width); | 4463 neww = XINT (width); |
3828 | 4464 |
3829 if (NILP (height)) | 4465 if (NILP (height)) |
3830 newh = XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow); | 4466 newh = IMAGE_INSTANCE_HEIGHT (ii); |
3831 else | 4467 else |
3832 newh = XINT (height); | 4468 newh = XINT (height); |
3833 | 4469 |
3834 | 4470 /* The actual resizing gets done asychronously by |
3835 MAYBE_DEVMETH (XDEVICE (XIMAGE_INSTANCE_DEVICE (subwindow)), | 4471 update_subwindow. */ |
3836 resize_subwindow, (XIMAGE_INSTANCE (subwindow), neww, newh)); | 4472 IMAGE_INSTANCE_HEIGHT (ii) = newh; |
3837 | 4473 IMAGE_INSTANCE_WIDTH (ii) = neww; |
3838 XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow) = newh; | 4474 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 1; |
3839 XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow) = neww; | 4475 |
4476 /* need to update the cachels as redisplay will not do this */ | |
4477 update_subwindow_cachel (subwindow); | |
3840 | 4478 |
3841 return subwindow; | 4479 return subwindow; |
3842 } | 4480 } |
3843 | 4481 |
3844 DEFUN ("force-subwindow-map", Fforce_subwindow_map, 1, 1, 0, /* | 4482 DEFUN ("force-subwindow-map", Fforce_subwindow_map, 1, 1, 0, /* |
3845 Generate a Map event for SUBWINDOW. | 4483 Generate a Map event for SUBWINDOW. |
3846 */ | 4484 */ |
3847 (subwindow)) | 4485 (subwindow)) |
3848 { | 4486 { |
3849 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); | 4487 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); |
3850 | 4488 #if 0 |
3851 map_subwindow (subwindow, 0, 0); | 4489 map_subwindow (subwindow, 0, 0); |
3852 | 4490 #endif |
3853 return subwindow; | 4491 return subwindow; |
3854 } | 4492 } |
3855 | 4493 |
3856 | 4494 |
3857 /***************************************************************************** | 4495 /***************************************************************************** |
3933 } | 4571 } |
3934 else | 4572 else |
3935 abort (); | 4573 abort (); |
3936 } | 4574 } |
3937 } | 4575 } |
4576 | |
4577 /***************************************************************************** | |
4578 * timeouts for animated glyphs * | |
4579 *****************************************************************************/ | |
4580 static Lisp_Object Qglyph_animated_timeout_handler; | |
4581 | |
4582 DEFUN ("glyph-animated-timeout-handler", Fglyph_animated_timeout_handler, 1, 1, 0, /* | |
4583 Callback function for updating animated images. | |
4584 Don't use this. | |
4585 */ | |
4586 (arg)) | |
4587 { | |
4588 CHECK_WEAK_LIST (arg); | |
4589 | |
4590 if (!NILP (XWEAK_LIST_LIST (arg)) && !NILP (XCAR (XWEAK_LIST_LIST (arg)))) | |
4591 { | |
4592 Lisp_Object value = XCAR (XWEAK_LIST_LIST (arg)); | |
4593 | |
4594 if (IMAGE_INSTANCEP (value)) | |
4595 { | |
4596 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (value); | |
4597 | |
4598 if (COLOR_PIXMAP_IMAGE_INSTANCEP (value) | |
4599 && | |
4600 IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) > 1 | |
4601 && | |
4602 !disable_animated_pixmaps) | |
4603 { | |
4604 /* Increment the index of the image slice we are currently | |
4605 viewing. */ | |
4606 IMAGE_INSTANCE_PIXMAP_SLICE (ii) = | |
4607 (IMAGE_INSTANCE_PIXMAP_SLICE (ii) + 1) | |
4608 % IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii); | |
4609 /* We might need to kick redisplay at this point - but we | |
4610 also might not. */ | |
4611 MARK_DEVICE_FRAMES_GLYPHS_CHANGED | |
4612 (XDEVICE (IMAGE_INSTANCE_DEVICE (ii))); | |
4613 /* Cascade dirtiness so that we can have an animated glyph in a layout | |
4614 for instance. */ | |
4615 set_image_instance_dirty_p (value, 1); | |
4616 } | |
4617 } | |
4618 } | |
4619 return Qnil; | |
4620 } | |
4621 | |
4622 Lisp_Object add_glyph_animated_timeout (EMACS_INT tickms, Lisp_Object image) | |
4623 { | |
4624 Lisp_Object ret = Qnil; | |
4625 | |
4626 if (tickms > 0 && IMAGE_INSTANCEP (image)) | |
4627 { | |
4628 double ms = ((double)tickms) / 1000.0; | |
4629 struct gcpro gcpro1; | |
4630 Lisp_Object holder = make_weak_list (WEAK_LIST_SIMPLE); | |
4631 | |
4632 GCPRO1 (holder); | |
4633 XWEAK_LIST_LIST (holder) = Fcons (image, Qnil); | |
4634 | |
4635 ret = Fadd_timeout (make_float (ms), | |
4636 Qglyph_animated_timeout_handler, | |
4637 holder, make_float (ms)); | |
4638 | |
4639 UNGCPRO; | |
4640 } | |
4641 return ret; | |
4642 } | |
4643 | |
4644 void disable_glyph_animated_timeout (int i) | |
4645 { | |
4646 Lisp_Object id; | |
4647 XSETINT (id, i); | |
4648 | |
4649 Fdisable_timeout (id); | |
4650 } | |
4651 | |
3938 | 4652 |
3939 /***************************************************************************** | 4653 /***************************************************************************** |
3940 * initialization * | 4654 * initialization * |
3941 *****************************************************************************/ | 4655 *****************************************************************************/ |
3942 | 4656 |
3981 defsymbol (&Qmono_pixmap_image_instance_p, "mono-pixmap-image-instance-p"); | 4695 defsymbol (&Qmono_pixmap_image_instance_p, "mono-pixmap-image-instance-p"); |
3982 defsymbol (&Qcolor_pixmap_image_instance_p, "color-pixmap-image-instance-p"); | 4696 defsymbol (&Qcolor_pixmap_image_instance_p, "color-pixmap-image-instance-p"); |
3983 defsymbol (&Qpointer_image_instance_p, "pointer-image-instance-p"); | 4697 defsymbol (&Qpointer_image_instance_p, "pointer-image-instance-p"); |
3984 defsymbol (&Qwidget_image_instance_p, "widget-image-instance-p"); | 4698 defsymbol (&Qwidget_image_instance_p, "widget-image-instance-p"); |
3985 defsymbol (&Qsubwindow_image_instance_p, "subwindow-image-instance-p"); | 4699 defsymbol (&Qsubwindow_image_instance_p, "subwindow-image-instance-p"); |
4700 defsymbol (&Qlayout_image_instance_p, "layout-image-instance-p"); | |
3986 | 4701 |
3987 DEFSUBR (Fmake_image_instance); | 4702 DEFSUBR (Fmake_image_instance); |
3988 DEFSUBR (Fimage_instance_p); | 4703 DEFSUBR (Fimage_instance_p); |
3989 DEFSUBR (Fimage_instance_type); | 4704 DEFSUBR (Fimage_instance_type); |
3990 DEFSUBR (Fvalid_image_instance_type_p); | 4705 DEFSUBR (Fvalid_image_instance_type_p); |
4039 DEFSUBR (Fglyph_height); | 4754 DEFSUBR (Fglyph_height); |
4040 | 4755 |
4041 /* Qbuffer defined in general.c. */ | 4756 /* Qbuffer defined in general.c. */ |
4042 /* Qpointer defined above */ | 4757 /* Qpointer defined above */ |
4043 | 4758 |
4759 /* Unfortunately, timeout handlers must be lisp functions. This is | |
4760 for animated glyphs. */ | |
4761 defsymbol (&Qglyph_animated_timeout_handler, | |
4762 "glyph-animated-timeout-handler"); | |
4763 DEFSUBR (Fglyph_animated_timeout_handler); | |
4764 | |
4044 /* Errors */ | 4765 /* Errors */ |
4045 deferror (&Qimage_conversion_error, | 4766 deferror (&Qimage_conversion_error, |
4046 "image-conversion-error", | 4767 "image-conversion-error", |
4047 "image-conversion error", Qio_error); | 4768 "image-conversion error", Qio_error); |
4048 | 4769 |
4049 } | 4770 } |
4771 | |
4772 static const struct lrecord_description image_specifier_description[] = { | |
4773 { XD_LISP_OBJECT, specifier_data_offset + offsetof (struct image_specifier, attachee) }, | |
4774 { XD_LISP_OBJECT, specifier_data_offset + offsetof (struct image_specifier, attachee_property) }, | |
4775 { XD_END } | |
4776 }; | |
4050 | 4777 |
4051 void | 4778 void |
4052 specifier_type_create_image (void) | 4779 specifier_type_create_image (void) |
4053 { | 4780 { |
4054 /* image specifiers */ | 4781 /* image specifiers */ |
4059 SPECIFIER_HAS_METHOD (image, mark); | 4786 SPECIFIER_HAS_METHOD (image, mark); |
4060 SPECIFIER_HAS_METHOD (image, instantiate); | 4787 SPECIFIER_HAS_METHOD (image, instantiate); |
4061 SPECIFIER_HAS_METHOD (image, validate); | 4788 SPECIFIER_HAS_METHOD (image, validate); |
4062 SPECIFIER_HAS_METHOD (image, after_change); | 4789 SPECIFIER_HAS_METHOD (image, after_change); |
4063 SPECIFIER_HAS_METHOD (image, going_to_add); | 4790 SPECIFIER_HAS_METHOD (image, going_to_add); |
4064 } | 4791 SPECIFIER_HAS_METHOD (image, copy_instantiator); |
4792 } | |
4793 | |
4794 void | |
4795 reinit_specifier_type_create_image (void) | |
4796 { | |
4797 REINITIALIZE_SPECIFIER_TYPE (image); | |
4798 } | |
4799 | |
4800 | |
4801 static const struct lrecord_description iike_description_1[] = { | |
4802 { XD_LISP_OBJECT, offsetof (ii_keyword_entry, keyword) }, | |
4803 { XD_END } | |
4804 }; | |
4805 | |
4806 static const struct struct_description iike_description = { | |
4807 sizeof (ii_keyword_entry), | |
4808 iike_description_1 | |
4809 }; | |
4810 | |
4811 static const struct lrecord_description iiked_description_1[] = { | |
4812 XD_DYNARR_DESC (ii_keyword_entry_dynarr, &iike_description), | |
4813 { XD_END } | |
4814 }; | |
4815 | |
4816 static const struct struct_description iiked_description = { | |
4817 sizeof (ii_keyword_entry_dynarr), | |
4818 iiked_description_1 | |
4819 }; | |
4820 | |
4821 static const struct lrecord_description iife_description_1[] = { | |
4822 { XD_LISP_OBJECT, offsetof (image_instantiator_format_entry, symbol) }, | |
4823 { XD_LISP_OBJECT, offsetof (image_instantiator_format_entry, device) }, | |
4824 { XD_STRUCT_PTR, offsetof (image_instantiator_format_entry, meths), 1, &iim_description }, | |
4825 { XD_END } | |
4826 }; | |
4827 | |
4828 static const struct struct_description iife_description = { | |
4829 sizeof (image_instantiator_format_entry), | |
4830 iife_description_1 | |
4831 }; | |
4832 | |
4833 static const struct lrecord_description iifed_description_1[] = { | |
4834 XD_DYNARR_DESC (image_instantiator_format_entry_dynarr, &iife_description), | |
4835 { XD_END } | |
4836 }; | |
4837 | |
4838 static const struct struct_description iifed_description = { | |
4839 sizeof (image_instantiator_format_entry_dynarr), | |
4840 iifed_description_1 | |
4841 }; | |
4842 | |
4843 static const struct lrecord_description iim_description_1[] = { | |
4844 { XD_LISP_OBJECT, offsetof (struct image_instantiator_methods, symbol) }, | |
4845 { XD_LISP_OBJECT, offsetof (struct image_instantiator_methods, device) }, | |
4846 { XD_STRUCT_PTR, offsetof (struct image_instantiator_methods, keywords), 1, &iiked_description }, | |
4847 { XD_STRUCT_PTR, offsetof (struct image_instantiator_methods, consoles), 1, &cted_description }, | |
4848 { XD_END } | |
4849 }; | |
4850 | |
4851 const struct struct_description iim_description = { | |
4852 sizeof(struct image_instantiator_methods), | |
4853 iim_description_1 | |
4854 }; | |
4065 | 4855 |
4066 void | 4856 void |
4067 image_instantiator_format_create (void) | 4857 image_instantiator_format_create (void) |
4068 { | 4858 { |
4069 /* image instantiators */ | 4859 /* image instantiators */ |
4071 the_image_instantiator_format_entry_dynarr = | 4861 the_image_instantiator_format_entry_dynarr = |
4072 Dynarr_new (image_instantiator_format_entry); | 4862 Dynarr_new (image_instantiator_format_entry); |
4073 | 4863 |
4074 Vimage_instantiator_format_list = Qnil; | 4864 Vimage_instantiator_format_list = Qnil; |
4075 staticpro (&Vimage_instantiator_format_list); | 4865 staticpro (&Vimage_instantiator_format_list); |
4866 | |
4867 dumpstruct (&the_image_instantiator_format_entry_dynarr, &iifed_description); | |
4076 | 4868 |
4077 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (nothing, "nothing"); | 4869 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (nothing, "nothing"); |
4078 | 4870 |
4079 IIFORMAT_HAS_METHOD (nothing, possible_dest_types); | 4871 IIFORMAT_HAS_METHOD (nothing, possible_dest_types); |
4080 IIFORMAT_HAS_METHOD (nothing, instantiate); | 4872 IIFORMAT_HAS_METHOD (nothing, instantiate); |
4093 IIFORMAT_HAS_METHOD (string, validate); | 4885 IIFORMAT_HAS_METHOD (string, validate); |
4094 IIFORMAT_HAS_METHOD (string, possible_dest_types); | 4886 IIFORMAT_HAS_METHOD (string, possible_dest_types); |
4095 IIFORMAT_HAS_METHOD (string, instantiate); | 4887 IIFORMAT_HAS_METHOD (string, instantiate); |
4096 | 4888 |
4097 IIFORMAT_VALID_KEYWORD (string, Q_data, check_valid_string); | 4889 IIFORMAT_VALID_KEYWORD (string, Q_data, check_valid_string); |
4890 /* Do this so we can set strings. */ | |
4891 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (text, "text"); | |
4892 IIFORMAT_HAS_METHOD (text, set_property); | |
4893 IIFORMAT_HAS_METHOD (text, query_geometry); | |
4098 | 4894 |
4099 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (formatted_string, "formatted-string"); | 4895 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (formatted_string, "formatted-string"); |
4100 | 4896 |
4101 IIFORMAT_HAS_METHOD (formatted_string, validate); | 4897 IIFORMAT_HAS_METHOD (formatted_string, validate); |
4102 IIFORMAT_HAS_METHOD (formatted_string, possible_dest_types); | 4898 IIFORMAT_HAS_METHOD (formatted_string, possible_dest_types); |
4103 IIFORMAT_HAS_METHOD (formatted_string, instantiate); | 4899 IIFORMAT_HAS_METHOD (formatted_string, instantiate); |
4104 | |
4105 IIFORMAT_VALID_KEYWORD (formatted_string, Q_data, check_valid_string); | 4900 IIFORMAT_VALID_KEYWORD (formatted_string, Q_data, check_valid_string); |
4106 | 4901 |
4107 /* subwindows */ | 4902 /* subwindows */ |
4108 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (subwindow, "subwindow"); | 4903 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (subwindow, "subwindow"); |
4109 IIFORMAT_HAS_METHOD (subwindow, possible_dest_types); | 4904 IIFORMAT_HAS_METHOD (subwindow, possible_dest_types); |
4155 IIFORMAT_VALID_KEYWORD (xpm, Q_color_symbols, check_valid_xpm_color_symbols); | 4950 IIFORMAT_VALID_KEYWORD (xpm, Q_color_symbols, check_valid_xpm_color_symbols); |
4156 #endif /* HAVE_XPM */ | 4951 #endif /* HAVE_XPM */ |
4157 } | 4952 } |
4158 | 4953 |
4159 void | 4954 void |
4955 reinit_vars_of_glyphs (void) | |
4956 { | |
4957 the_expose_ignore_blocktype = | |
4958 Blocktype_new (struct expose_ignore_blocktype); | |
4959 | |
4960 hold_ignored_expose_registration = 0; | |
4961 } | |
4962 | |
4963 | |
4964 void | |
4160 vars_of_glyphs (void) | 4965 vars_of_glyphs (void) |
4161 { | 4966 { |
4967 reinit_vars_of_glyphs (); | |
4968 | |
4162 Vthe_nothing_vector = vector1 (Qnothing); | 4969 Vthe_nothing_vector = vector1 (Qnothing); |
4163 staticpro (&Vthe_nothing_vector); | 4970 staticpro (&Vthe_nothing_vector); |
4164 | 4971 |
4165 /* image instances */ | 4972 /* image instances */ |
4166 | 4973 |
4167 Vimage_instance_type_list = Fcons (Qnothing, | 4974 Vimage_instance_type_list = Fcons (Qnothing, |
4168 list6 (Qtext, Qmono_pixmap, Qcolor_pixmap, | 4975 list6 (Qtext, Qmono_pixmap, Qcolor_pixmap, |
4169 Qpointer, Qsubwindow, Qwidget)); | 4976 Qpointer, Qsubwindow, Qwidget)); |
4170 staticpro (&Vimage_instance_type_list); | 4977 staticpro (&Vimage_instance_type_list); |
4171 | 4978 |
4172 /* glyphs */ | 4979 /* glyphs */ |
4173 | 4980 |
4222 Vxpm_color_symbols = Qnil; /* initialized in x-faces.el */ | 5029 Vxpm_color_symbols = Qnil; /* initialized in x-faces.el */ |
4223 #endif /* HAVE_XPM */ | 5030 #endif /* HAVE_XPM */ |
4224 #ifdef HAVE_XFACE | 5031 #ifdef HAVE_XFACE |
4225 Fprovide (Qxface); | 5032 Fprovide (Qxface); |
4226 #endif | 5033 #endif |
5034 | |
5035 DEFVAR_BOOL ("disable-animated-pixmaps", &disable_animated_pixmaps /* | |
5036 Whether animated pixmaps should be animated. | |
5037 Default is t. | |
5038 */); | |
5039 disable_animated_pixmaps = 0; | |
4227 } | 5040 } |
4228 | 5041 |
4229 void | 5042 void |
4230 specifier_vars_of_glyphs (void) | 5043 specifier_vars_of_glyphs (void) |
4231 { | 5044 { |
4245 */ ); | 5058 */ ); |
4246 Vcurrent_display_table = Fmake_specifier (Qdisplay_table); | 5059 Vcurrent_display_table = Fmake_specifier (Qdisplay_table); |
4247 set_specifier_fallback (Vcurrent_display_table, | 5060 set_specifier_fallback (Vcurrent_display_table, |
4248 list1 (Fcons (Qnil, Qnil))); | 5061 list1 (Fcons (Qnil, Qnil))); |
4249 set_specifier_caching (Vcurrent_display_table, | 5062 set_specifier_caching (Vcurrent_display_table, |
4250 slot_offset (struct window, | 5063 offsetof (struct window, display_table), |
4251 display_table), | |
4252 some_window_value_changed, | 5064 some_window_value_changed, |
4253 0, 0); | 5065 0, 0); |
4254 } | 5066 } |
4255 | 5067 |
4256 void | 5068 void |