Mercurial > hg > xemacs-beta
comparison src/glyphs.c @ 424:11054d720c21 r21-2-20
Import from CVS: tag r21-2-20
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:26:11 +0200 |
parents | 41dbb7a9d5f2 |
children |
comparison
equal
deleted
inserted
replaced
423:28d9c139be4c | 424:11054d720c21 |
---|---|
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 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. */ |
28 | 28 |
29 #include <config.h> | 29 #include <config.h> |
30 #include "lisp.h" | 30 #include "lisp.h" |
31 | 31 |
32 #include "buffer.h" | 32 #include "buffer.h" |
40 #include "redisplay.h" | 40 #include "redisplay.h" |
41 #include "window.h" | 41 #include "window.h" |
42 #include "frame.h" | 42 #include "frame.h" |
43 #include "chartab.h" | 43 #include "chartab.h" |
44 #include "rangetab.h" | 44 #include "rangetab.h" |
45 #include "blocktype.h" | |
45 | 46 |
46 #ifdef HAVE_XPM | 47 #ifdef HAVE_XPM |
47 #include <X11/xpm.h> | 48 #include <X11/xpm.h> |
48 #endif | 49 #endif |
49 | 50 |
54 Lisp_Object Qnothing_image_instance_p, Qtext_image_instance_p; | 55 Lisp_Object Qnothing_image_instance_p, Qtext_image_instance_p; |
55 Lisp_Object Qmono_pixmap_image_instance_p; | 56 Lisp_Object Qmono_pixmap_image_instance_p; |
56 Lisp_Object Qcolor_pixmap_image_instance_p; | 57 Lisp_Object Qcolor_pixmap_image_instance_p; |
57 Lisp_Object Qpointer_image_instance_p; | 58 Lisp_Object Qpointer_image_instance_p; |
58 Lisp_Object Qsubwindow_image_instance_p; | 59 Lisp_Object Qsubwindow_image_instance_p; |
60 Lisp_Object Qlayout_image_instance_p; | |
59 Lisp_Object Qwidget_image_instance_p; | 61 Lisp_Object Qwidget_image_instance_p; |
60 Lisp_Object Qconst_glyph_variable; | 62 Lisp_Object Qconst_glyph_variable; |
61 Lisp_Object Qmono_pixmap, Qcolor_pixmap, Qsubwindow; | 63 Lisp_Object Qmono_pixmap, Qcolor_pixmap, Qsubwindow; |
62 Lisp_Object Q_file, Q_data, Q_face, Q_pixel_width, Q_pixel_height; | 64 Lisp_Object Q_file, Q_data, Q_face, Q_pixel_width, Q_pixel_height; |
63 Lisp_Object Qformatted_string; | 65 Lisp_Object Qformatted_string; |
68 Lisp_Object Vthe_nothing_vector; | 70 Lisp_Object Vthe_nothing_vector; |
69 Lisp_Object Vimage_instantiator_format_list; | 71 Lisp_Object Vimage_instantiator_format_list; |
70 Lisp_Object Vimage_instance_type_list; | 72 Lisp_Object Vimage_instance_type_list; |
71 Lisp_Object Vglyph_type_list; | 73 Lisp_Object Vglyph_type_list; |
72 | 74 |
75 int disable_animated_pixmaps; | |
76 | |
73 DEFINE_IMAGE_INSTANTIATOR_FORMAT (nothing); | 77 DEFINE_IMAGE_INSTANTIATOR_FORMAT (nothing); |
74 DEFINE_IMAGE_INSTANTIATOR_FORMAT (inherit); | 78 DEFINE_IMAGE_INSTANTIATOR_FORMAT (inherit); |
75 DEFINE_IMAGE_INSTANTIATOR_FORMAT (string); | 79 DEFINE_IMAGE_INSTANTIATOR_FORMAT (string); |
76 DEFINE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); | 80 DEFINE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); |
77 DEFINE_IMAGE_INSTANTIATOR_FORMAT (subwindow); | 81 DEFINE_IMAGE_INSTANTIATOR_FORMAT (subwindow); |
82 DEFINE_IMAGE_INSTANTIATOR_FORMAT (text); | |
78 | 83 |
79 #ifdef HAVE_WINDOW_SYSTEM | 84 #ifdef HAVE_WINDOW_SYSTEM |
80 DEFINE_IMAGE_INSTANTIATOR_FORMAT (xbm); | 85 DEFINE_IMAGE_INSTANTIATOR_FORMAT (xbm); |
81 Lisp_Object Qxbm; | 86 Lisp_Object Qxbm; |
82 | 87 |
120 static Lisp_Object allocate_image_instance (Lisp_Object device); | 125 static Lisp_Object allocate_image_instance (Lisp_Object device); |
121 static void image_validate (Lisp_Object instantiator); | 126 static void image_validate (Lisp_Object instantiator); |
122 static void glyph_property_was_changed (Lisp_Object glyph, | 127 static void glyph_property_was_changed (Lisp_Object glyph, |
123 Lisp_Object property, | 128 Lisp_Object property, |
124 Lisp_Object locale); | 129 Lisp_Object locale); |
130 static void register_ignored_expose (struct frame* f, int x, int y, int width, int height); | |
131 /* Unfortunately windows and X are different. In windows BeginPaint() | |
132 will prevent WM_PAINT messages being generated so it is unnecessary | |
133 to register exposures as they will not occur. Under X they will | |
134 always occur. */ | |
135 int hold_ignored_expose_registration; | |
136 | |
125 EXFUN (Fimage_instance_type, 1); | 137 EXFUN (Fimage_instance_type, 1); |
126 EXFUN (Fglyph_type, 1); | 138 EXFUN (Fglyph_type, 1); |
127 | 139 |
128 | 140 |
129 /**************************************************************************** | 141 /**************************************************************************** |
177 valid_image_instantiator_format_p (Lisp_Object format, Lisp_Object locale) | 189 valid_image_instantiator_format_p (Lisp_Object format, Lisp_Object locale) |
178 { | 190 { |
179 int i; | 191 int i; |
180 struct image_instantiator_methods* meths = | 192 struct image_instantiator_methods* meths = |
181 decode_image_instantiator_format (format, ERROR_ME_NOT); | 193 decode_image_instantiator_format (format, ERROR_ME_NOT); |
182 struct console* console = decode_console (locale); | 194 Lisp_Object contype = Qnil; |
183 Lisp_Object contype = console ? CONSOLE_TYPE (console) : locale; | 195 /* mess with the locale */ |
196 if (!NILP (locale) && SYMBOLP (locale)) | |
197 contype = locale; | |
198 else | |
199 { | |
200 struct console* console = decode_console (locale); | |
201 contype = console ? CONSOLE_TYPE (console) : locale; | |
202 } | |
184 /* nothing is valid in all locales */ | 203 /* nothing is valid in all locales */ |
185 if (EQ (format, Qnothing)) | 204 if (EQ (format, Qnothing)) |
186 return 1; | 205 return 1; |
187 /* reject unknown formats */ | 206 /* reject unknown formats */ |
188 else if (!console || !meths) | 207 else if (NILP (contype) || !meths) |
189 return 0; | 208 return 0; |
190 | 209 |
191 for (i = 0; i < Dynarr_length (meths->consoles); i++) | 210 for (i = 0; i < Dynarr_length (meths->consoles); i++) |
192 if (EQ (contype, Dynarr_at (meths->consoles, i).symbol)) | 211 if (EQ (contype, Dynarr_at (meths->consoles, i).symbol)) |
193 return 1; | 212 return 1; |
596 ****************************************************************************/ | 615 ****************************************************************************/ |
597 | 616 |
598 Lisp_Object Qimage_instancep; | 617 Lisp_Object Qimage_instancep; |
599 | 618 |
600 static Lisp_Object | 619 static Lisp_Object |
601 mark_image_instance (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 620 mark_image_instance (Lisp_Object obj) |
602 { | 621 { |
603 struct Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); | 622 struct Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); |
604 | 623 |
605 markobj (i->name); | 624 mark_object (i->name); |
606 switch (IMAGE_INSTANCE_TYPE (i)) | 625 switch (IMAGE_INSTANCE_TYPE (i)) |
607 { | 626 { |
608 case IMAGE_TEXT: | 627 case IMAGE_TEXT: |
609 markobj (IMAGE_INSTANCE_TEXT_STRING (i)); | 628 mark_object (IMAGE_INSTANCE_TEXT_STRING (i)); |
610 break; | 629 break; |
611 case IMAGE_MONO_PIXMAP: | 630 case IMAGE_MONO_PIXMAP: |
612 case IMAGE_COLOR_PIXMAP: | 631 case IMAGE_COLOR_PIXMAP: |
613 markobj (IMAGE_INSTANCE_PIXMAP_FILENAME (i)); | 632 mark_object (IMAGE_INSTANCE_PIXMAP_FILENAME (i)); |
614 markobj (IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (i)); | 633 mark_object (IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (i)); |
615 markobj (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i)); | 634 mark_object (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i)); |
616 markobj (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i)); | 635 mark_object (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i)); |
617 markobj (IMAGE_INSTANCE_PIXMAP_FG (i)); | 636 mark_object (IMAGE_INSTANCE_PIXMAP_FG (i)); |
618 markobj (IMAGE_INSTANCE_PIXMAP_BG (i)); | 637 mark_object (IMAGE_INSTANCE_PIXMAP_BG (i)); |
619 break; | 638 break; |
620 | 639 |
621 case IMAGE_WIDGET: | 640 case IMAGE_WIDGET: |
622 markobj (IMAGE_INSTANCE_WIDGET_TYPE (i)); | 641 mark_object (IMAGE_INSTANCE_WIDGET_TYPE (i)); |
623 markobj (IMAGE_INSTANCE_WIDGET_PROPS (i)); | 642 mark_object (IMAGE_INSTANCE_WIDGET_PROPS (i)); |
624 markobj (IMAGE_INSTANCE_WIDGET_FACE (i)); | 643 mark_object (IMAGE_INSTANCE_WIDGET_FACE (i)); |
625 markobj (IMAGE_INSTANCE_WIDGET_ITEM (i)); | 644 mark_object (IMAGE_INSTANCE_WIDGET_ITEMS (i)); |
626 case IMAGE_SUBWINDOW: | 645 case IMAGE_SUBWINDOW: |
627 markobj (IMAGE_INSTANCE_SUBWINDOW_FRAME (i)); | 646 mark_object (IMAGE_INSTANCE_SUBWINDOW_FRAME (i)); |
647 break; | |
648 | |
649 case IMAGE_LAYOUT: | |
650 mark_object (IMAGE_INSTANCE_LAYOUT_CHILDREN (i)); | |
651 mark_object (IMAGE_INSTANCE_LAYOUT_BORDER (i)); | |
652 mark_object (IMAGE_INSTANCE_SUBWINDOW_FRAME (i)); | |
628 break; | 653 break; |
629 | 654 |
630 default: | 655 default: |
631 break; | 656 break; |
632 } | 657 } |
633 | 658 |
634 MAYBE_DEVMETH (XDEVICE (i->device), mark_image_instance, (i, markobj)); | 659 MAYBE_DEVMETH (XDEVICE (i->device), mark_image_instance, (i)); |
635 | 660 |
636 return i->device; | 661 return i->device; |
637 } | 662 } |
638 | 663 |
639 static void | 664 static void |
746 | 771 |
747 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii))) | 772 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii))) |
748 print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 0); | 773 print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 0); |
749 | 774 |
750 case IMAGE_SUBWINDOW: | 775 case IMAGE_SUBWINDOW: |
776 case IMAGE_LAYOUT: | |
751 sprintf (buf, " %dx%d", IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii), | 777 sprintf (buf, " %dx%d", IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii), |
752 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); | 778 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); |
753 write_c_string (buf, printcharfun); | 779 write_c_string (buf, printcharfun); |
754 | 780 |
755 /* This is stolen from frame.c. Subwindows are strange in that they | 781 /* This is stolen from frame.c. Subwindows are strange in that they |
797 /* do this so that the cachels get reset */ | 823 /* do this so that the cachels get reset */ |
798 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_WIDGET | 824 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_WIDGET |
799 || | 825 || |
800 IMAGE_INSTANCE_TYPE (i) == IMAGE_SUBWINDOW) | 826 IMAGE_INSTANCE_TYPE (i) == IMAGE_SUBWINDOW) |
801 { | 827 { |
802 MARK_FRAME_GLYPHS_CHANGED | 828 MARK_FRAME_SUBWINDOWS_CHANGED |
803 (XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (i))); | 829 (XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (i))); |
804 } | 830 } |
805 | 831 |
806 MAYBE_DEVMETH (XDEVICE (i->device), finalize_image_instance, (i)); | 832 MAYBE_DEVMETH (XDEVICE (i->device), finalize_image_instance, (i)); |
807 } | 833 } |
841 IMAGE_INSTANCE_PIXMAP_WIDTH (i2) && | 867 IMAGE_INSTANCE_PIXMAP_WIDTH (i2) && |
842 IMAGE_INSTANCE_PIXMAP_HEIGHT (i1) == | 868 IMAGE_INSTANCE_PIXMAP_HEIGHT (i1) == |
843 IMAGE_INSTANCE_PIXMAP_HEIGHT (i2) && | 869 IMAGE_INSTANCE_PIXMAP_HEIGHT (i2) && |
844 IMAGE_INSTANCE_PIXMAP_DEPTH (i1) == | 870 IMAGE_INSTANCE_PIXMAP_DEPTH (i1) == |
845 IMAGE_INSTANCE_PIXMAP_DEPTH (i2) && | 871 IMAGE_INSTANCE_PIXMAP_DEPTH (i2) && |
872 IMAGE_INSTANCE_PIXMAP_SLICE (i1) == | |
873 IMAGE_INSTANCE_PIXMAP_SLICE (i2) && | |
846 EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i1), | 874 EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i1), |
847 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i2)) && | 875 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i2)) && |
848 EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i1), | 876 EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i1), |
849 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i2)) && | 877 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i2)) && |
850 internal_equal (IMAGE_INSTANCE_PIXMAP_FILENAME (i1), | 878 internal_equal (IMAGE_INSTANCE_PIXMAP_FILENAME (i1), |
857 break; | 885 break; |
858 | 886 |
859 case IMAGE_WIDGET: | 887 case IMAGE_WIDGET: |
860 if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1), | 888 if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1), |
861 IMAGE_INSTANCE_WIDGET_TYPE (i2)) | 889 IMAGE_INSTANCE_WIDGET_TYPE (i2)) |
862 && internal_equal (IMAGE_INSTANCE_WIDGET_ITEM (i1), | 890 && internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (i1), |
863 IMAGE_INSTANCE_WIDGET_ITEM (i2), | 891 IMAGE_INSTANCE_WIDGET_ITEMS (i2), |
864 depth + 1) | 892 depth + 1) |
865 && internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1), | 893 && internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1), |
866 IMAGE_INSTANCE_WIDGET_PROPS (i2), | 894 IMAGE_INSTANCE_WIDGET_PROPS (i2), |
867 depth + 1) | 895 depth + 1) |
868 )) | 896 )) |
897 return 0; | |
898 case IMAGE_LAYOUT: | |
899 if (IMAGE_INSTANCE_TYPE (i1) == IMAGE_LAYOUT | |
900 && | |
901 !(EQ (IMAGE_INSTANCE_LAYOUT_BORDER (i1), | |
902 IMAGE_INSTANCE_LAYOUT_BORDER (i2)) | |
903 && | |
904 internal_equal (IMAGE_INSTANCE_LAYOUT_CHILDREN (i1), | |
905 IMAGE_INSTANCE_LAYOUT_CHILDREN (i2), | |
906 depth + 1))) | |
869 return 0; | 907 return 0; |
870 case IMAGE_SUBWINDOW: | 908 case IMAGE_SUBWINDOW: |
871 if (!(IMAGE_INSTANCE_SUBWINDOW_WIDTH (i1) == | 909 if (!(IMAGE_INSTANCE_SUBWINDOW_WIDTH (i1) == |
872 IMAGE_INSTANCE_SUBWINDOW_WIDTH (i2) && | 910 IMAGE_INSTANCE_SUBWINDOW_WIDTH (i2) && |
873 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i1) == | 911 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i1) == |
902 break; | 940 break; |
903 | 941 |
904 case IMAGE_MONO_PIXMAP: | 942 case IMAGE_MONO_PIXMAP: |
905 case IMAGE_COLOR_PIXMAP: | 943 case IMAGE_COLOR_PIXMAP: |
906 case IMAGE_POINTER: | 944 case IMAGE_POINTER: |
907 hash = HASH5 (hash, IMAGE_INSTANCE_PIXMAP_WIDTH (i), | 945 hash = HASH6 (hash, IMAGE_INSTANCE_PIXMAP_WIDTH (i), |
908 IMAGE_INSTANCE_PIXMAP_HEIGHT (i), | 946 IMAGE_INSTANCE_PIXMAP_HEIGHT (i), |
909 IMAGE_INSTANCE_PIXMAP_DEPTH (i), | 947 IMAGE_INSTANCE_PIXMAP_DEPTH (i), |
948 IMAGE_INSTANCE_PIXMAP_SLICE (i), | |
910 internal_hash (IMAGE_INSTANCE_PIXMAP_FILENAME (i), | 949 internal_hash (IMAGE_INSTANCE_PIXMAP_FILENAME (i), |
911 depth + 1)); | 950 depth + 1)); |
912 break; | 951 break; |
913 | 952 |
914 case IMAGE_WIDGET: | 953 case IMAGE_WIDGET: |
915 hash = HASH4 (hash, | 954 hash = HASH4 (hash, |
916 internal_hash (IMAGE_INSTANCE_WIDGET_TYPE (i), depth + 1), | 955 internal_hash (IMAGE_INSTANCE_WIDGET_TYPE (i), depth + 1), |
917 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1), | 956 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1), |
918 internal_hash (IMAGE_INSTANCE_WIDGET_ITEM (i), depth + 1)); | 957 internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1)); |
958 case IMAGE_LAYOUT: | |
959 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_LAYOUT) | |
960 hash = HASH3 (hash, | |
961 internal_hash (IMAGE_INSTANCE_LAYOUT_BORDER (i), depth + 1), | |
962 internal_hash (IMAGE_INSTANCE_LAYOUT_CHILDREN (i), | |
963 depth + 1)); | |
919 case IMAGE_SUBWINDOW: | 964 case IMAGE_SUBWINDOW: |
920 hash = HASH4 (hash, IMAGE_INSTANCE_SUBWINDOW_WIDTH (i), | 965 hash = HASH4 (hash, IMAGE_INSTANCE_SUBWINDOW_WIDTH (i), |
921 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i), | 966 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i), |
922 (int) IMAGE_INSTANCE_SUBWINDOW_ID (i)); | 967 (int) IMAGE_INSTANCE_SUBWINDOW_ID (i)); |
923 break; | 968 break; |
945 | 990 |
946 zero_lcrecord (lp); | 991 zero_lcrecord (lp); |
947 lp->device = device; | 992 lp->device = device; |
948 lp->type = IMAGE_NOTHING; | 993 lp->type = IMAGE_NOTHING; |
949 lp->name = Qnil; | 994 lp->name = Qnil; |
995 lp->x_offset = 0; | |
996 lp->y_offset = 0; | |
950 XSETIMAGE_INSTANCE (val, lp); | 997 XSETIMAGE_INSTANCE (val, lp); |
951 return val; | 998 return val; |
952 } | 999 } |
953 | 1000 |
954 static enum image_instance_type | 1001 static enum image_instance_type |
962 if (EQ (type, Qmono_pixmap)) return IMAGE_MONO_PIXMAP; | 1009 if (EQ (type, Qmono_pixmap)) return IMAGE_MONO_PIXMAP; |
963 if (EQ (type, Qcolor_pixmap)) return IMAGE_COLOR_PIXMAP; | 1010 if (EQ (type, Qcolor_pixmap)) return IMAGE_COLOR_PIXMAP; |
964 if (EQ (type, Qpointer)) return IMAGE_POINTER; | 1011 if (EQ (type, Qpointer)) return IMAGE_POINTER; |
965 if (EQ (type, Qsubwindow)) return IMAGE_SUBWINDOW; | 1012 if (EQ (type, Qsubwindow)) return IMAGE_SUBWINDOW; |
966 if (EQ (type, Qwidget)) return IMAGE_WIDGET; | 1013 if (EQ (type, Qwidget)) return IMAGE_WIDGET; |
1014 if (EQ (type, Qlayout)) return IMAGE_LAYOUT; | |
967 | 1015 |
968 maybe_signal_simple_error ("Invalid image-instance type", type, | 1016 maybe_signal_simple_error ("Invalid image-instance type", type, |
969 Qimage, errb); | 1017 Qimage, errb); |
970 | 1018 |
971 return IMAGE_UNKNOWN; /* not reached */ | 1019 return IMAGE_UNKNOWN; /* not reached */ |
981 case IMAGE_MONO_PIXMAP: return Qmono_pixmap; | 1029 case IMAGE_MONO_PIXMAP: return Qmono_pixmap; |
982 case IMAGE_COLOR_PIXMAP: return Qcolor_pixmap; | 1030 case IMAGE_COLOR_PIXMAP: return Qcolor_pixmap; |
983 case IMAGE_POINTER: return Qpointer; | 1031 case IMAGE_POINTER: return Qpointer; |
984 case IMAGE_SUBWINDOW: return Qsubwindow; | 1032 case IMAGE_SUBWINDOW: return Qsubwindow; |
985 case IMAGE_WIDGET: return Qwidget; | 1033 case IMAGE_WIDGET: return Qwidget; |
1034 case IMAGE_LAYOUT: return Qlayout; | |
986 default: | 1035 default: |
987 abort (); | 1036 abort (); |
988 } | 1037 } |
989 | 1038 |
990 return Qnil; /* not reached */ | 1039 return Qnil; /* not reached */ |
993 static int | 1042 static int |
994 image_instance_type_to_mask (enum image_instance_type type) | 1043 image_instance_type_to_mask (enum image_instance_type type) |
995 { | 1044 { |
996 /* This depends on the fact that enums are assigned consecutive | 1045 /* This depends on the fact that enums are assigned consecutive |
997 integers starting at 0. (Remember that IMAGE_UNKNOWN is the | 1046 integers starting at 0. (Remember that IMAGE_UNKNOWN is the |
998 first enum.) I'm fairly sure this behavior in ANSI-mandated, | 1047 first enum.) I'm fairly sure this behavior is ANSI-mandated, |
999 so there should be no portability problems here. */ | 1048 so there should be no portability problems here. */ |
1000 return (1 << ((int) (type) - 1)); | 1049 return (1 << ((int) (type) - 1)); |
1001 } | 1050 } |
1002 | 1051 |
1003 static int | 1052 static int |
1164 'pointer | 1213 'pointer |
1165 Used as the mouse pointer for a window. | 1214 Used as the mouse pointer for a window. |
1166 'subwindow | 1215 'subwindow |
1167 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.) |
1168 another program to be responsible for drawing into the window. | 1217 another program to be responsible for drawing into the window. |
1169 Not currently implemented. | 1218 'widget |
1219 A child window that contains a window-system widget, e.g. a push | |
1220 button. | |
1170 | 1221 |
1171 The DEST-TYPES list is unordered. If multiple destination types | 1222 The DEST-TYPES list is unordered. If multiple destination types |
1172 are possible for a given instantiator, the "most natural" type | 1223 are possible for a given instantiator, the "most natural" type |
1173 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 |
1174 types are `mono-pixmap', followed by `color-pixmap', followed by | 1225 types are `mono-pixmap', followed by `color-pixmap', followed by |
1186 If DEST-TYPES is omitted, all possible types are allowed. | 1237 If DEST-TYPES is omitted, all possible types are allowed. |
1187 | 1238 |
1188 NO-ERROR controls what happens when the image cannot be generated. | 1239 NO-ERROR controls what happens when the image cannot be generated. |
1189 If nil, an error message is generated. If t, no messages are | 1240 If nil, an error message is generated. If t, no messages are |
1190 generated and this function returns nil. If anything else, a warning | 1241 generated and this function returns nil. If anything else, a warning |
1191 message is generated and this function returns nil. | 1242 message is generated and this function returns nil. |
1192 */ | 1243 */ |
1193 (data, device, dest_types, no_error)) | 1244 (data, device, dest_types, no_error)) |
1194 { | 1245 { |
1195 Error_behavior errb = decode_error_behavior_flag (no_error); | 1246 Error_behavior errb = decode_error_behavior_flag (no_error); |
1196 | 1247 |
1300 if (meths && HAS_IIFORMAT_METH_P (meths, set_property) | 1351 if (meths && HAS_IIFORMAT_METH_P (meths, set_property) |
1301 && | 1352 && |
1302 !UNBOUNDP (ret = | 1353 !UNBOUNDP (ret = |
1303 IIFORMAT_METH (meths, set_property, (image_instance, prop, val)))) | 1354 IIFORMAT_METH (meths, set_property, (image_instance, prop, val)))) |
1304 { | 1355 { |
1305 return ret; | 1356 val = ret; |
1306 } | 1357 } |
1307 /* ... then format specific methods ... */ | 1358 else |
1308 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); | 1359 { |
1309 if (meths && HAS_IIFORMAT_METH_P (meths, set_property) | 1360 /* ... then format specific methods ... */ |
1310 && | 1361 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); |
1311 !UNBOUNDP (ret = | 1362 if (meths && HAS_IIFORMAT_METH_P (meths, set_property) |
1312 IIFORMAT_METH (meths, set_property, (image_instance, prop, val)))) | 1363 && |
1313 { | 1364 !UNBOUNDP (ret = |
1314 return ret; | 1365 IIFORMAT_METH (meths, set_property, (image_instance, prop, val)))) |
1315 } | 1366 { |
1367 val = ret; | |
1368 } | |
1369 else | |
1370 { | |
1371 val = Qnil; | |
1372 } | |
1373 } | |
1374 | |
1375 /* Make sure the image instance gets redisplayed. */ | |
1376 MARK_IMAGE_INSTANCE_CHANGED (ii); | |
1377 MARK_SUBWINDOWS_STATE_CHANGED; | |
1378 MARK_GLYPHS_CHANGED; | |
1316 | 1379 |
1317 return val; | 1380 return val; |
1318 } | 1381 } |
1319 | 1382 |
1320 DEFUN ("image-instance-file-name", Fimage_instance_file_name, 1, 1, 0, /* | 1383 DEFUN ("image-instance-file-name", Fimage_instance_file_name, 1, 1, 0, /* |
1389 case IMAGE_POINTER: | 1452 case IMAGE_POINTER: |
1390 return make_int (XIMAGE_INSTANCE_PIXMAP_HEIGHT (image_instance)); | 1453 return make_int (XIMAGE_INSTANCE_PIXMAP_HEIGHT (image_instance)); |
1391 | 1454 |
1392 case IMAGE_SUBWINDOW: | 1455 case IMAGE_SUBWINDOW: |
1393 case IMAGE_WIDGET: | 1456 case IMAGE_WIDGET: |
1457 case IMAGE_LAYOUT: | |
1394 return make_int (XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (image_instance)); | 1458 return make_int (XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (image_instance)); |
1395 | 1459 |
1396 default: | 1460 default: |
1397 return Qnil; | 1461 return Qnil; |
1398 } | 1462 } |
1412 case IMAGE_POINTER: | 1476 case IMAGE_POINTER: |
1413 return make_int (XIMAGE_INSTANCE_PIXMAP_WIDTH (image_instance)); | 1477 return make_int (XIMAGE_INSTANCE_PIXMAP_WIDTH (image_instance)); |
1414 | 1478 |
1415 case IMAGE_SUBWINDOW: | 1479 case IMAGE_SUBWINDOW: |
1416 case IMAGE_WIDGET: | 1480 case IMAGE_WIDGET: |
1481 case IMAGE_LAYOUT: | |
1417 return make_int (XIMAGE_INSTANCE_SUBWINDOW_WIDTH (image_instance)); | 1482 return make_int (XIMAGE_INSTANCE_SUBWINDOW_WIDTH (image_instance)); |
1418 | 1483 |
1419 default: | 1484 default: |
1420 return Qnil; | 1485 return Qnil; |
1421 } | 1486 } |
1666 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT; | 1731 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT; |
1667 IMAGE_INSTANCE_TEXT_STRING (ii) = data; | 1732 IMAGE_INSTANCE_TEXT_STRING (ii) = data; |
1668 } | 1733 } |
1669 else | 1734 else |
1670 incompatible_image_types (instantiator, dest_mask, IMAGE_TEXT_MASK); | 1735 incompatible_image_types (instantiator, dest_mask, IMAGE_TEXT_MASK); |
1736 } | |
1737 | |
1738 /* set the properties of a string */ | |
1739 static Lisp_Object | |
1740 text_set_property (Lisp_Object image_instance, Lisp_Object prop, | |
1741 Lisp_Object val) | |
1742 { | |
1743 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
1744 | |
1745 if (EQ (prop, Q_data)) | |
1746 { | |
1747 CHECK_STRING (val); | |
1748 IMAGE_INSTANCE_TEXT_STRING (ii) = val; | |
1749 | |
1750 return Qt; | |
1751 } | |
1752 return Qunbound; | |
1671 } | 1753 } |
1672 | 1754 |
1673 | 1755 |
1674 /**************************************************************************** | 1756 /**************************************************************************** |
1675 * formatted-string * | 1757 * formatted-string * |
2332 IMAGE_SPECIFIER_ATTACHEE (image) = Qnil; | 2414 IMAGE_SPECIFIER_ATTACHEE (image) = Qnil; |
2333 IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image) = Qnil; | 2415 IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image) = Qnil; |
2334 } | 2416 } |
2335 | 2417 |
2336 static void | 2418 static void |
2337 image_mark (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 2419 image_mark (Lisp_Object obj) |
2338 { | 2420 { |
2339 struct Lisp_Specifier *image = XIMAGE_SPECIFIER (obj); | 2421 struct Lisp_Specifier *image = XIMAGE_SPECIFIER (obj); |
2340 | 2422 |
2341 markobj (IMAGE_SPECIFIER_ATTACHEE (image)); | 2423 mark_object (IMAGE_SPECIFIER_ATTACHEE (image)); |
2342 markobj (IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image)); | 2424 mark_object (IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image)); |
2343 } | 2425 } |
2344 | 2426 |
2345 static Lisp_Object | 2427 static Lisp_Object |
2346 image_instantiate_cache_result (Lisp_Object locative) | 2428 image_instantiate_cache_result (Lisp_Object locative) |
2347 { | 2429 { |
2731 (A glyph from a font; i.e. the name of a font, and glyph index into it | 2813 (A glyph from a font; i.e. the name of a font, and glyph index into it |
2732 of the form "FONT fontname index [[mask-font] mask-index]". | 2814 of the form "FONT fontname index [[mask-font] mask-index]". |
2733 Currently can only be instanced as `pointer', although this should | 2815 Currently can only be instanced as `pointer', although this should |
2734 probably be fixed.) | 2816 probably be fixed.) |
2735 'subwindow | 2817 'subwindow |
2736 (An embedded X window; not currently implemented.) | 2818 (An embedded windowing system window.) |
2737 'widget | 2819 'edit-field |
2738 (A widget control, for instance text field or radio button.) | 2820 (A text editing widget glyph.) |
2821 'button | |
2822 (A button widget glyph; either a push button, radio button or toggle button.) | |
2823 'tab-control | |
2824 (A tab widget glyph; a series of user selectable tabs.) | |
2825 'progress-gauge | |
2826 (A sliding widget glyph, for showing progress.) | |
2827 'combo-box | |
2828 (A drop list of selectable items in a widget glyph, for editing text.) | |
2829 'label | |
2830 (A static, text-only, widget glyph; for displaying text.) | |
2831 'tree-view | |
2832 (A folding widget glyph.) | |
2739 'autodetect | 2833 'autodetect |
2740 (XEmacs tries to guess what format the data is in. If X support | 2834 (XEmacs tries to guess what format the data is in. If X support |
2741 exists, the data string will be checked to see if it names a filename. | 2835 exists, the data string will be checked to see if it names a filename. |
2742 If so, and this filename contains XBM or XPM data, the appropriate | 2836 If so, and this filename contains XBM or XPM data, the appropriate |
2743 sort of pixmap or pointer will be created. [This includes picking up | 2837 sort of pixmap or pointer will be created. [This includes picking up |
2795 that specify symbolic color names to the actual color to be used | 2889 that specify symbolic color names to the actual color to be used |
2796 for that symbolic color (in the form of a string or a color-specifier | 2890 for that symbolic color (in the form of a string or a color-specifier |
2797 object). If this is not specified, the contents of `xpm-color-symbols' | 2891 object). If this is not specified, the contents of `xpm-color-symbols' |
2798 are used to generate the alist.) | 2892 are used to generate the alist.) |
2799 :face | 2893 :face |
2800 (Only for `inherit'. This specifies the face to inherit from.) | 2894 (Only for `inherit'. This specifies the face to inherit from. |
2895 For widget glyphs this also specifies the face to use for | |
2896 display. It defaults to gui-element-face.) | |
2897 | |
2898 Keywords accepted as menu item specs are also accepted by widget | |
2899 glyphs. These are `:selected', `:active', `:suffix', `:keys', | |
2900 `:style', `:filter', `:config', `:included', `:key-sequence', | |
2901 `:accelerator', `:label' and `:callback'. | |
2801 | 2902 |
2802 If instead of a vector, the instantiator is a string, it will be | 2903 If instead of a vector, the instantiator is a string, it will be |
2803 converted into a vector by looking it up according to the specs in the | 2904 converted into a vector by looking it up according to the specs in the |
2804 `console-type-image-conversion-list' (q.v.) for the console type of | 2905 `console-type-image-conversion-list' (q.v.) for the console type of |
2805 the domain (usually a window; sometimes a frame or device) over which | 2906 the domain (usually a window; sometimes a frame or device) over which |
2823 /**************************************************************************** | 2924 /**************************************************************************** |
2824 * Glyph Object * | 2925 * Glyph Object * |
2825 ****************************************************************************/ | 2926 ****************************************************************************/ |
2826 | 2927 |
2827 static Lisp_Object | 2928 static Lisp_Object |
2828 mark_glyph (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 2929 mark_glyph (Lisp_Object obj) |
2829 { | 2930 { |
2830 struct Lisp_Glyph *glyph = XGLYPH (obj); | 2931 struct Lisp_Glyph *glyph = XGLYPH (obj); |
2831 | 2932 |
2832 markobj (glyph->image); | 2933 mark_object (glyph->image); |
2833 markobj (glyph->contrib_p); | 2934 mark_object (glyph->contrib_p); |
2834 markobj (glyph->baseline); | 2935 mark_object (glyph->baseline); |
2835 markobj (glyph->face); | 2936 mark_object (glyph->face); |
2836 | 2937 |
2837 return glyph->plist; | 2938 return glyph->plist; |
2838 } | 2939 } |
2839 | 2940 |
2840 static void | 2941 static void |
2900 } | 3001 } |
2901 | 3002 |
2902 static int | 3003 static int |
2903 glyph_putprop (Lisp_Object obj, Lisp_Object prop, Lisp_Object value) | 3004 glyph_putprop (Lisp_Object obj, Lisp_Object prop, Lisp_Object value) |
2904 { | 3005 { |
2905 if ((EQ (prop, Qimage)) || | 3006 if (EQ (prop, Qimage) || |
2906 (EQ (prop, Qcontrib_p)) || | 3007 EQ (prop, Qcontrib_p) || |
2907 (EQ (prop, Qbaseline))) | 3008 EQ (prop, Qbaseline)) |
2908 return 0; | 3009 return 0; |
2909 | 3010 |
2910 if (EQ (prop, Qface)) | 3011 if (EQ (prop, Qface)) |
2911 { | 3012 { |
2912 XGLYPH (obj)->face = Fget_face (value); | 3013 XGLYPH (obj)->face = Fget_face (value); |
2918 } | 3019 } |
2919 | 3020 |
2920 static int | 3021 static int |
2921 glyph_remprop (Lisp_Object obj, Lisp_Object prop) | 3022 glyph_remprop (Lisp_Object obj, Lisp_Object prop) |
2922 { | 3023 { |
2923 if ((EQ (prop, Qimage)) || | 3024 if (EQ (prop, Qimage) || |
2924 (EQ (prop, Qcontrib_p)) || | 3025 EQ (prop, Qcontrib_p) || |
2925 (EQ (prop, Qbaseline))) | 3026 EQ (prop, Qbaseline)) |
2926 return -1; | 3027 return -1; |
2927 | 3028 |
2928 if (EQ (prop, Qface)) | 3029 if (EQ (prop, Qface)) |
2929 { | 3030 { |
2930 XGLYPH (obj)->face = Qnil; | 3031 XGLYPH (obj)->face = Qnil; |
2970 struct Lisp_Glyph *g = | 3071 struct Lisp_Glyph *g = |
2971 alloc_lcrecord_type (struct Lisp_Glyph, &lrecord_glyph); | 3072 alloc_lcrecord_type (struct Lisp_Glyph, &lrecord_glyph); |
2972 | 3073 |
2973 g->type = type; | 3074 g->type = type; |
2974 g->image = Fmake_specifier (Qimage); /* This function can GC */ | 3075 g->image = Fmake_specifier (Qimage); /* This function can GC */ |
3076 g->dirty = 0; | |
2975 switch (g->type) | 3077 switch (g->type) |
2976 { | 3078 { |
2977 case GLYPH_BUFFER: | 3079 case GLYPH_BUFFER: |
2978 XIMAGE_SPECIFIER_ALLOWED (g->image) = | 3080 XIMAGE_SPECIFIER_ALLOWED (g->image) = |
2979 IMAGE_NOTHING_MASK | IMAGE_TEXT_MASK | 3081 IMAGE_NOTHING_MASK | IMAGE_TEXT_MASK |
2980 | IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK | 3082 | IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK |
2981 | IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK; | 3083 | IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK |
3084 | IMAGE_LAYOUT_MASK; | |
2982 break; | 3085 break; |
2983 case GLYPH_POINTER: | 3086 case GLYPH_POINTER: |
2984 XIMAGE_SPECIFIER_ALLOWED (g->image) = | 3087 XIMAGE_SPECIFIER_ALLOWED (g->image) = |
2985 IMAGE_NOTHING_MASK | IMAGE_POINTER_MASK; | 3088 IMAGE_NOTHING_MASK | IMAGE_POINTER_MASK; |
2986 break; | 3089 break; |
3125 Return the width of the given GLYPH on the given WINDOW. If the | 3228 Return the width of the given GLYPH on the given WINDOW. If the |
3126 instance is a string then the width is calculated using the font of | 3229 instance is a string then the width is calculated using the font of |
3127 the given FACE, unless a face is defined by the glyph itself. | 3230 the given FACE, unless a face is defined by the glyph itself. |
3128 ****************************************************************************/ | 3231 ****************************************************************************/ |
3129 unsigned short | 3232 unsigned short |
3130 glyph_width (Lisp_Object glyph, Lisp_Object frame_face, | 3233 glyph_width (Lisp_Object glyph_or_image, Lisp_Object frame_face, |
3131 face_index window_findex, Lisp_Object window) | 3234 face_index window_findex, Lisp_Object window) |
3132 { | 3235 { |
3133 Lisp_Object instance; | 3236 Lisp_Object instance = glyph_or_image; |
3134 Lisp_Object frame = XWINDOW (window)->frame; | 3237 Lisp_Object frame = XWINDOW (window)->frame; |
3135 | 3238 |
3136 /* #### We somehow need to distinguish between the user causing this | 3239 /* #### We somehow need to distinguish between the user causing this |
3137 error condition and a bug causing it. */ | 3240 error condition and a bug causing it. */ |
3138 if (!GLYPHP (glyph)) | 3241 if (GLYPHP (glyph_or_image)) |
3139 return 0; | 3242 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1); |
3140 else | |
3141 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); | |
3142 | 3243 |
3143 if (!IMAGE_INSTANCEP (instance)) | 3244 if (!IMAGE_INSTANCEP (instance)) |
3144 return 0; | 3245 return 0; |
3145 | 3246 |
3146 switch (XIMAGE_INSTANCE_TYPE (instance)) | 3247 switch (XIMAGE_INSTANCE_TYPE (instance)) |
3147 { | 3248 { |
3148 case IMAGE_TEXT: | 3249 case IMAGE_TEXT: |
3149 { | 3250 { |
3150 Lisp_Object str = XIMAGE_INSTANCE_TEXT_STRING (instance); | 3251 Lisp_Object str = XIMAGE_INSTANCE_TEXT_STRING (instance); |
3151 Lisp_Object private_face = XGLYPH_FACE(glyph); | 3252 Lisp_Object private_face = Qnil; |
3253 | |
3254 if (GLYPHP (glyph_or_image)) | |
3255 private_face = XGLYPH_FACE(glyph_or_image); | |
3152 | 3256 |
3153 if (!NILP (private_face)) | 3257 if (!NILP (private_face)) |
3154 return redisplay_frame_text_width_string (XFRAME (frame), | 3258 return redisplay_frame_text_width_string (XFRAME (frame), |
3155 private_face, | 3259 private_face, |
3156 0, str, 0, -1); | 3260 0, str, 0, -1); |
3173 case IMAGE_NOTHING: | 3277 case IMAGE_NOTHING: |
3174 return 0; | 3278 return 0; |
3175 | 3279 |
3176 case IMAGE_SUBWINDOW: | 3280 case IMAGE_SUBWINDOW: |
3177 case IMAGE_WIDGET: | 3281 case IMAGE_WIDGET: |
3282 case IMAGE_LAYOUT: | |
3178 return XIMAGE_INSTANCE_SUBWINDOW_WIDTH (instance); | 3283 return XIMAGE_INSTANCE_SUBWINDOW_WIDTH (instance); |
3179 | 3284 |
3180 default: | 3285 default: |
3181 abort (); | 3286 abort (); |
3182 return 0; | 3287 return 0; |
3211 return specifier_instance (specifier, Qunbound, domain, errb, no_quit, 0, | 3316 return specifier_instance (specifier, Qunbound, domain, errb, no_quit, 0, |
3212 Qzero); | 3317 Qzero); |
3213 } | 3318 } |
3214 | 3319 |
3215 static unsigned short | 3320 static unsigned short |
3216 glyph_height_internal (Lisp_Object glyph, Lisp_Object frame_face, | 3321 glyph_height_internal (Lisp_Object glyph_or_image, Lisp_Object frame_face, |
3217 face_index window_findex, Lisp_Object window, | 3322 face_index window_findex, Lisp_Object window, |
3218 int function) | 3323 int function) |
3219 { | 3324 { |
3220 Lisp_Object instance; | 3325 Lisp_Object instance = glyph_or_image; |
3221 Lisp_Object frame = XWINDOW (window)->frame; | 3326 Lisp_Object frame = XWINDOW (window)->frame; |
3222 | 3327 |
3223 if (!GLYPHP (glyph)) | 3328 if (GLYPHP (glyph_or_image)) |
3224 return 0; | 3329 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1); |
3225 else | |
3226 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); | |
3227 | 3330 |
3228 if (!IMAGE_INSTANCEP (instance)) | 3331 if (!IMAGE_INSTANCEP (instance)) |
3229 return 0; | 3332 return 0; |
3230 | 3333 |
3231 switch (XIMAGE_INSTANCE_TYPE (instance)) | 3334 switch (XIMAGE_INSTANCE_TYPE (instance)) |
3277 case IMAGE_NOTHING: | 3380 case IMAGE_NOTHING: |
3278 return 0; | 3381 return 0; |
3279 | 3382 |
3280 case IMAGE_SUBWINDOW: | 3383 case IMAGE_SUBWINDOW: |
3281 case IMAGE_WIDGET: | 3384 case IMAGE_WIDGET: |
3385 case IMAGE_LAYOUT: | |
3282 /* #### Ugh ugh ugh -- temporary crap */ | 3386 /* #### Ugh ugh ugh -- temporary crap */ |
3283 if (function == RETURN_ASCENT || function == RETURN_HEIGHT) | 3387 if (function == RETURN_ASCENT || function == RETURN_HEIGHT) |
3284 return XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (instance); | 3388 return XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (instance); |
3285 else | 3389 else |
3286 return 0; | 3390 return 0; |
3357 } | 3461 } |
3358 | 3462 |
3359 #undef RETURN_ASCENT | 3463 #undef RETURN_ASCENT |
3360 #undef RETURN_DESCENT | 3464 #undef RETURN_DESCENT |
3361 #undef RETURN_HEIGHT | 3465 #undef RETURN_HEIGHT |
3466 | |
3467 static unsigned int | |
3468 glyph_dirty_p (Lisp_Object glyph_or_image, Lisp_Object window) | |
3469 { | |
3470 Lisp_Object instance = glyph_or_image; | |
3471 | |
3472 if (GLYPHP (glyph_or_image)) | |
3473 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1); | |
3474 | |
3475 return XIMAGE_INSTANCE_DIRTYP (instance); | |
3476 } | |
3477 | |
3478 static void | |
3479 set_glyph_dirty_p (Lisp_Object glyph_or_image, Lisp_Object window, int dirty) | |
3480 { | |
3481 Lisp_Object instance = glyph_or_image; | |
3482 | |
3483 if (!NILP (glyph_or_image)) | |
3484 { | |
3485 if (GLYPHP (glyph_or_image)) | |
3486 { | |
3487 instance = glyph_image_instance (glyph_or_image, window, | |
3488 ERROR_ME_NOT, 1); | |
3489 XGLYPH_DIRTYP (glyph_or_image) = dirty; | |
3490 } | |
3491 | |
3492 XIMAGE_INSTANCE_DIRTYP (instance) = dirty; | |
3493 } | |
3494 } | |
3362 | 3495 |
3363 /* #### do we need to cache this info to speed things up? */ | 3496 /* #### do we need to cache this info to speed things up? */ |
3364 | 3497 |
3365 Lisp_Object | 3498 Lisp_Object |
3366 glyph_baseline (Lisp_Object glyph, Lisp_Object domain) | 3499 glyph_baseline (Lisp_Object glyph, Lisp_Object domain) |
3420 *****************************************************************************/ | 3553 *****************************************************************************/ |
3421 | 3554 |
3422 /* | 3555 /* |
3423 #### All of this is 95% copied from face cachels. | 3556 #### All of this is 95% copied from face cachels. |
3424 Consider consolidating. | 3557 Consider consolidating. |
3425 #### We need to add a dirty flag to the glyphs. | |
3426 */ | 3558 */ |
3427 | 3559 |
3428 void | 3560 void |
3429 mark_glyph_cachels (glyph_cachel_dynarr *elements, | 3561 mark_glyph_cachels (glyph_cachel_dynarr *elements) |
3430 void (*markobj) (Lisp_Object)) | |
3431 { | 3562 { |
3432 int elt; | 3563 int elt; |
3433 | 3564 |
3434 if (!elements) | 3565 if (!elements) |
3435 return; | 3566 return; |
3436 | 3567 |
3437 for (elt = 0; elt < Dynarr_length (elements); elt++) | 3568 for (elt = 0; elt < Dynarr_length (elements); elt++) |
3438 { | 3569 { |
3439 struct glyph_cachel *cachel = Dynarr_atp (elements, elt); | 3570 struct glyph_cachel *cachel = Dynarr_atp (elements, elt); |
3440 markobj (cachel->glyph); | 3571 mark_object (cachel->glyph); |
3441 } | 3572 } |
3442 } | 3573 } |
3443 | 3574 |
3444 static void | 3575 static void |
3445 update_glyph_cachel_data (struct window *w, Lisp_Object glyph, | 3576 update_glyph_cachel_data (struct window *w, Lisp_Object glyph, |
3446 struct glyph_cachel *cachel) | 3577 struct glyph_cachel *cachel) |
3447 { | 3578 { |
3448 /* #### This should be || !cachel->updated */ | 3579 if (!cachel->updated || NILP (cachel->glyph) || !EQ (cachel->glyph, glyph) |
3449 if (NILP (cachel->glyph) || !EQ (cachel->glyph, glyph)) | 3580 || XGLYPH_DIRTYP (cachel->glyph)) |
3450 { | 3581 { |
3451 Lisp_Object window; | 3582 Lisp_Object window, instance; |
3452 | 3583 |
3453 XSETWINDOW (window, w); | 3584 XSETWINDOW (window, w); |
3454 | 3585 |
3455 /* #### This could be sped up if we redid things to grab the glyph | |
3456 instantiation and passed it to the size functions. */ | |
3457 cachel->glyph = glyph; | 3586 cachel->glyph = glyph; |
3458 cachel->width = glyph_width (glyph, Qnil, DEFAULT_INDEX, window); | 3587 /* Speed things up slightly by grabbing the glyph instantiation |
3459 cachel->ascent = glyph_ascent (glyph, Qnil, DEFAULT_INDEX, window); | 3588 and passing it to the size functions. */ |
3460 cachel->descent = glyph_descent (glyph, Qnil, DEFAULT_INDEX, window); | 3589 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); |
3590 cachel->dirty = XGLYPH_DIRTYP (glyph) = glyph_dirty_p (glyph, window); | |
3591 cachel->width = glyph_width (instance, Qnil, DEFAULT_INDEX, window); | |
3592 cachel->ascent = glyph_ascent (instance, Qnil, DEFAULT_INDEX, window); | |
3593 cachel->descent = glyph_descent (instance, Qnil, DEFAULT_INDEX, window); | |
3461 } | 3594 } |
3462 | 3595 |
3463 cachel->updated = 1; | 3596 cachel->updated = 1; |
3464 } | 3597 } |
3465 | 3598 |
3473 | 3606 |
3474 update_glyph_cachel_data (w, glyph, &new_cachel); | 3607 update_glyph_cachel_data (w, glyph, &new_cachel); |
3475 Dynarr_add (w->glyph_cachels, new_cachel); | 3608 Dynarr_add (w->glyph_cachels, new_cachel); |
3476 } | 3609 } |
3477 | 3610 |
3478 static glyph_index | 3611 glyph_index |
3479 get_glyph_cachel_index (struct window *w, Lisp_Object glyph) | 3612 get_glyph_cachel_index (struct window *w, Lisp_Object glyph) |
3480 { | 3613 { |
3481 int elt; | 3614 int elt; |
3482 | 3615 |
3483 if (noninteractive) | 3616 if (noninteractive) |
3488 struct glyph_cachel *cachel = | 3621 struct glyph_cachel *cachel = |
3489 Dynarr_atp (w->glyph_cachels, elt); | 3622 Dynarr_atp (w->glyph_cachels, elt); |
3490 | 3623 |
3491 if (EQ (cachel->glyph, glyph) && !NILP (glyph)) | 3624 if (EQ (cachel->glyph, glyph) && !NILP (glyph)) |
3492 { | 3625 { |
3493 if (!cachel->updated) | 3626 update_glyph_cachel_data (w, glyph, cachel); |
3494 update_glyph_cachel_data (w, glyph, cachel); | |
3495 return elt; | 3627 return elt; |
3496 } | 3628 } |
3497 } | 3629 } |
3498 | 3630 |
3499 /* If we didn't find the glyph, add it and then return its index. */ | 3631 /* If we didn't find the glyph, add it and then return its index. */ |
3532 FROB (Voctal_escape_glyph, OCT_ESC_GLYPH_INDEX); | 3664 FROB (Voctal_escape_glyph, OCT_ESC_GLYPH_INDEX); |
3533 FROB (Vinvisible_text_glyph, INVIS_GLYPH_INDEX); | 3665 FROB (Vinvisible_text_glyph, INVIS_GLYPH_INDEX); |
3534 #undef FROB | 3666 #undef FROB |
3535 | 3667 |
3536 for (elt = 0; elt < Dynarr_length (w->glyph_cachels); elt++) | 3668 for (elt = 0; elt < Dynarr_length (w->glyph_cachels); elt++) |
3537 Dynarr_atp (w->glyph_cachels, elt)->updated = 0; | 3669 { |
3670 Dynarr_atp (w->glyph_cachels, elt)->updated = 0; | |
3671 } | |
3672 } | |
3673 | |
3674 /* Unset the dirty bit on all the glyph cachels that have it. */ | |
3675 void | |
3676 mark_glyph_cachels_as_clean (struct window* w) | |
3677 { | |
3678 int elt; | |
3679 Lisp_Object window; | |
3680 XSETWINDOW (window, w); | |
3681 for (elt = 0; elt < Dynarr_length (w->glyph_cachels); elt++) | |
3682 { | |
3683 struct glyph_cachel *cachel = Dynarr_atp (w->glyph_cachels, elt); | |
3684 cachel->dirty = 0; | |
3685 set_glyph_dirty_p (cachel->glyph, window, 0); | |
3686 } | |
3538 } | 3687 } |
3539 | 3688 |
3540 #ifdef MEMORY_USAGE_STATS | 3689 #ifdef MEMORY_USAGE_STATS |
3541 | 3690 |
3542 int | 3691 int |
3566 we want the instance to go away also. However we also have a | 3715 we want the instance to go away also. However we also have a |
3567 per-frame instance cache that we use to determine if a subwindow is | 3716 per-frame instance cache that we use to determine if a subwindow is |
3568 obscuring an area that we want to clear. We need to be able to flip | 3717 obscuring an area that we want to clear. We need to be able to flip |
3569 through this quickly so a hashtable is not suitable hence the | 3718 through this quickly so a hashtable is not suitable hence the |
3570 subwindow_cachels. The question is should we just not mark | 3719 subwindow_cachels. The question is should we just not mark |
3571 instances in the subwindow_cachelsnor should we try and invalidate | 3720 instances in the subwindow_cachels or should we try and invalidate |
3572 the cache at suitable points in redisplay? If we don't invalidate | 3721 the cache at suitable points in redisplay? If we don't invalidate |
3573 the cache it will fill up with crud that will only get removed when | 3722 the cache it will fill up with crud that will only get removed when |
3574 the frame is deleted. So invalidation is good, the question is when | 3723 the frame is deleted. So invalidation is good, the question is when |
3575 and whether we mark as well. Go for the simple option - don't mark, | 3724 and whether we mark as well. Go for the simple option - don't mark, |
3576 MARK_SUBWINDOWS_CHANGED when a subwindow gets deleted. */ | 3725 MARK_SUBWINDOWS_CHANGED when a subwindow gets deleted. */ |
3577 | 3726 |
3578 void | 3727 void |
3579 mark_subwindow_cachels (subwindow_cachel_dynarr *elements, | 3728 mark_subwindow_cachels (subwindow_cachel_dynarr *elements) |
3580 void (*markobj) (Lisp_Object)) | |
3581 { | 3729 { |
3582 int elt; | 3730 int elt; |
3583 | 3731 |
3584 if (!elements) | 3732 if (!elements) |
3585 return; | 3733 return; |
3586 | 3734 |
3587 for (elt = 0; elt < Dynarr_length (elements); elt++) | 3735 for (elt = 0; elt < Dynarr_length (elements); elt++) |
3588 { | 3736 { |
3589 struct subwindow_cachel *cachel = Dynarr_atp (elements, elt); | 3737 struct subwindow_cachel *cachel = Dynarr_atp (elements, elt); |
3590 markobj (cachel->subwindow); | 3738 mark_object (cachel->subwindow); |
3591 } | 3739 } |
3592 } | 3740 } |
3593 | 3741 |
3594 static void | 3742 static void |
3595 update_subwindow_cachel_data (struct frame *f, Lisp_Object subwindow, | 3743 update_subwindow_cachel_data (struct frame *f, Lisp_Object subwindow, |
3596 struct subwindow_cachel *cachel) | 3744 struct subwindow_cachel *cachel) |
3597 { | 3745 { |
3598 if (NILP (cachel->subwindow) || !EQ (cachel->subwindow, subwindow)) | 3746 cachel->subwindow = subwindow; |
3599 { | 3747 cachel->width = XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow); |
3600 cachel->subwindow = subwindow; | 3748 cachel->height = XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow); |
3601 cachel->width = XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow); | |
3602 cachel->height = XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow); | |
3603 } | |
3604 | |
3605 cachel->updated = 1; | 3749 cachel->updated = 1; |
3606 } | 3750 } |
3607 | 3751 |
3608 static void | 3752 static void |
3609 add_subwindow_cachel (struct frame *f, Lisp_Object subwindow) | 3753 add_subwindow_cachel (struct frame *f, Lisp_Object subwindow) |
3642 } | 3786 } |
3643 | 3787 |
3644 /* If we didn't find the glyph, add it and then return its index. */ | 3788 /* If we didn't find the glyph, add it and then return its index. */ |
3645 add_subwindow_cachel (f, subwindow); | 3789 add_subwindow_cachel (f, subwindow); |
3646 return elt; | 3790 return elt; |
3791 } | |
3792 | |
3793 static void | |
3794 update_subwindow_cachel (Lisp_Object subwindow) | |
3795 { | |
3796 struct frame* f; | |
3797 int elt; | |
3798 | |
3799 if (NILP (subwindow)) | |
3800 return; | |
3801 | |
3802 f = XFRAME ( XIMAGE_INSTANCE_SUBWINDOW_FRAME (subwindow)); | |
3803 | |
3804 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) | |
3805 { | |
3806 struct subwindow_cachel *cachel = | |
3807 Dynarr_atp (f->subwindow_cachels, elt); | |
3808 | |
3809 if (EQ (cachel->subwindow, subwindow) && !NILP (subwindow)) | |
3810 { | |
3811 update_subwindow_cachel_data (f, subwindow, cachel); | |
3812 } | |
3813 } | |
3647 } | 3814 } |
3648 | 3815 |
3649 /* redisplay in general assumes that drawing something will erase | 3816 /* redisplay in general assumes that drawing something will erase |
3650 what was there before. unfortunately this does not apply to | 3817 what was there before. unfortunately this does not apply to |
3651 subwindows that need to be specifically unmapped in order to | 3818 subwindows that need to be specifically unmapped in order to |
3660 struct subwindow_cachel *cachel = | 3827 struct subwindow_cachel *cachel = |
3661 Dynarr_atp (f->subwindow_cachels, elt); | 3828 Dynarr_atp (f->subwindow_cachels, elt); |
3662 | 3829 |
3663 if (!NILP (cachel->subwindow) && cachel->being_displayed) | 3830 if (!NILP (cachel->subwindow) && cachel->being_displayed) |
3664 { | 3831 { |
3665 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (cachel->subwindow); | 3832 cachel->updated = 1; |
3666 MAYBE_DEVMETH (XDEVICE (f->device), unmap_subwindow, (ii)); | 3833 /* #### This is not optimal as update_subwindow will search |
3834 the cachels for ourselves as well. We could easily optimize. */ | |
3835 unmap_subwindow (cachel->subwindow); | |
3667 } | 3836 } |
3668 } | 3837 } |
3669 Dynarr_reset (f->subwindow_cachels); | 3838 Dynarr_reset (f->subwindow_cachels); |
3670 } | 3839 } |
3671 | 3840 |
3674 { | 3843 { |
3675 int elt; | 3844 int elt; |
3676 | 3845 |
3677 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) | 3846 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) |
3678 Dynarr_atp (f->subwindow_cachels, elt)->updated = 0; | 3847 Dynarr_atp (f->subwindow_cachels, elt)->updated = 0; |
3848 } | |
3849 | |
3850 | |
3851 | |
3852 /***************************************************************************** | |
3853 * subwindow exposure ignorance * | |
3854 *****************************************************************************/ | |
3855 /* when we unmap subwindows the associated window system will generate | |
3856 expose events. This we do not want as redisplay already copes with | |
3857 the repainting necessary. Worse, we can get in an endless cycle of | |
3858 redisplay if we are not careful. Thus we keep a per-frame list of | |
3859 expose events that are going to come and ignore them as | |
3860 required. */ | |
3861 | |
3862 struct expose_ignore_blocktype | |
3863 { | |
3864 Blocktype_declare (struct expose_ignore); | |
3865 } *the_expose_ignore_blocktype; | |
3866 | |
3867 int | |
3868 check_for_ignored_expose (struct frame* f, int x, int y, int width, int height) | |
3869 { | |
3870 struct expose_ignore *ei, *prev; | |
3871 /* the ignore list is FIFO so we should generally get a match with | |
3872 the first element in the list */ | |
3873 for (ei = f->subwindow_exposures, prev = 0; ei; ei = ei->next) | |
3874 { | |
3875 /* Checking for exact matches just isn't good enough as we | |
3876 mighte get exposures for partially obscure subwindows, thus | |
3877 we have to check for overlaps. Being conservative we will | |
3878 check for exposures wholly contained by the subwindow, this | |
3879 might give us what we want.*/ | |
3880 if (ei->x <= x && ei->y <= y | |
3881 && ei->x + ei->width >= x + width | |
3882 && ei->y + ei->height >= y + height) | |
3883 { | |
3884 #ifdef DEBUG_WIDGETS | |
3885 stderr_out ("ignored %d+%d, %dx%d for exposure %d+%d, %dx%d\n", | |
3886 x, y, width, height, ei->x, ei->y, ei->width, ei->height); | |
3887 #endif | |
3888 if (!prev) | |
3889 f->subwindow_exposures = ei->next; | |
3890 else | |
3891 prev->next = ei->next; | |
3892 | |
3893 if (ei == f->subwindow_exposures_tail) | |
3894 f->subwindow_exposures_tail = prev; | |
3895 | |
3896 Blocktype_free (the_expose_ignore_blocktype, ei); | |
3897 return 1; | |
3898 } | |
3899 prev = ei; | |
3900 } | |
3901 return 0; | |
3902 } | |
3903 | |
3904 static void | |
3905 register_ignored_expose (struct frame* f, int x, int y, int width, int height) | |
3906 { | |
3907 if (!hold_ignored_expose_registration) | |
3908 { | |
3909 struct expose_ignore *ei; | |
3910 | |
3911 ei = Blocktype_alloc (the_expose_ignore_blocktype); | |
3912 | |
3913 ei->next = NULL; | |
3914 ei->x = x; | |
3915 ei->y = y; | |
3916 ei->width = width; | |
3917 ei->height = height; | |
3918 | |
3919 /* we have to add the exposure to the end of the list, since we | |
3920 want to check the oldest events first. for speed we keep a record | |
3921 of the end so that we can add right to it. */ | |
3922 if (f->subwindow_exposures_tail) | |
3923 { | |
3924 f->subwindow_exposures_tail->next = ei; | |
3925 } | |
3926 if (!f->subwindow_exposures) | |
3927 { | |
3928 f->subwindow_exposures = ei; | |
3929 } | |
3930 f->subwindow_exposures_tail = ei; | |
3931 } | |
3932 } | |
3933 | |
3934 /**************************************************************************** | |
3935 find_matching_subwindow | |
3936 | |
3937 See if there is a subwindow that completely encloses the requested | |
3938 area. | |
3939 ****************************************************************************/ | |
3940 int find_matching_subwindow (struct frame* f, int x, int y, int width, int height) | |
3941 { | |
3942 int elt; | |
3943 | |
3944 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) | |
3945 { | |
3946 struct subwindow_cachel *cachel = | |
3947 Dynarr_atp (f->subwindow_cachels, elt); | |
3948 | |
3949 if (cachel->being_displayed | |
3950 && | |
3951 cachel->x <= x && cachel->y <= y | |
3952 && | |
3953 cachel->x + cachel->width >= x + width | |
3954 && | |
3955 cachel->y + cachel->height >= y + height) | |
3956 { | |
3957 return 1; | |
3958 } | |
3959 } | |
3960 return 0; | |
3679 } | 3961 } |
3680 | 3962 |
3681 | 3963 |
3682 /***************************************************************************** | 3964 /***************************************************************************** |
3683 * subwindow functions * | 3965 * subwindow functions * |
3700 void | 3982 void |
3701 update_frame_subwindows (struct frame *f) | 3983 update_frame_subwindows (struct frame *f) |
3702 { | 3984 { |
3703 int elt; | 3985 int elt; |
3704 | 3986 |
3705 if (f->subwindows_changed || f->glyphs_changed) | 3987 if (f->subwindows_changed || f->subwindows_state_changed || f->faces_changed) |
3706 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) | 3988 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) |
3707 { | 3989 { |
3708 struct subwindow_cachel *cachel = | 3990 struct subwindow_cachel *cachel = |
3709 Dynarr_atp (f->subwindow_cachels, elt); | 3991 Dynarr_atp (f->subwindow_cachels, elt); |
3710 | 3992 |
3727 || | 4009 || |
3728 IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW) | 4010 IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW) |
3729 || | 4011 || |
3730 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) | 4012 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) |
3731 return; | 4013 return; |
3732 | 4014 #ifdef DEBUG_WIDGETS |
4015 stderr_out ("unmapping subwindow %d\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii)); | |
4016 #endif | |
3733 f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); | 4017 f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); |
3734 elt = get_subwindow_cachel_index (f, subwindow); | 4018 elt = get_subwindow_cachel_index (f, subwindow); |
3735 cachel = Dynarr_atp (f->subwindow_cachels, elt); | 4019 cachel = Dynarr_atp (f->subwindow_cachels, elt); |
3736 | 4020 |
4021 /* make sure we don't get expose events */ | |
4022 register_ignored_expose (f, cachel->x, cachel->y, cachel->width, cachel->height); | |
3737 cachel->x = -1; | 4023 cachel->x = -1; |
3738 cachel->y = -1; | 4024 cachel->y = -1; |
3739 cachel->being_displayed = 0; | 4025 cachel->being_displayed = 0; |
3740 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; | 4026 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; |
3741 | 4027 |
3742 MAYBE_DEVMETH (XDEVICE (ii->device), unmap_subwindow, (ii)); | 4028 MAYBE_DEVMETH (XDEVICE (ii->device), unmap_subwindow, (ii)); |
3743 } | 4029 } |
3744 | 4030 |
3745 /* show a subwindow in its frame */ | 4031 /* show a subwindow in its frame */ |
3746 void map_subwindow (Lisp_Object subwindow, int x, int y) | 4032 void map_subwindow (Lisp_Object subwindow, int x, int y, |
4033 struct display_glyph_area *dga) | |
3747 { | 4034 { |
3748 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); | 4035 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); |
3749 int elt; | 4036 int elt; |
3750 struct subwindow_cachel* cachel; | 4037 struct subwindow_cachel* cachel; |
3751 struct frame* f; | 4038 struct frame* f; |
3755 IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW) | 4042 IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW) |
3756 || | 4043 || |
3757 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) | 4044 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) |
3758 return; | 4045 return; |
3759 | 4046 |
4047 #ifdef DEBUG_WIDGETS | |
4048 stderr_out ("mapping subwindow %d, %dx%d@%d+%d\n", | |
4049 IMAGE_INSTANCE_SUBWINDOW_ID (ii), | |
4050 dga->width, dga->height, x, y); | |
4051 #endif | |
3760 f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); | 4052 f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); |
3761 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 1; | 4053 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 1; |
3762 elt = get_subwindow_cachel_index (f, subwindow); | 4054 elt = get_subwindow_cachel_index (f, subwindow); |
3763 cachel = Dynarr_atp (f->subwindow_cachels, elt); | 4055 cachel = Dynarr_atp (f->subwindow_cachels, elt); |
3764 cachel->x = x; | 4056 cachel->x = x; |
3765 cachel->y = y; | 4057 cachel->y = y; |
4058 cachel->width = dga->width; | |
4059 cachel->height = dga->height; | |
3766 cachel->being_displayed = 1; | 4060 cachel->being_displayed = 1; |
3767 | 4061 |
3768 MAYBE_DEVMETH (XDEVICE (ii->device), map_subwindow, (ii, x, y)); | 4062 MAYBE_DEVMETH (XDEVICE (ii->device), map_subwindow, (ii, x, y, dga)); |
3769 } | 4063 } |
3770 | 4064 |
3771 static int | 4065 static int |
3772 subwindow_possible_dest_types (void) | 4066 subwindow_possible_dest_types (void) |
3773 { | 4067 { |
3792 if (!(dest_mask & IMAGE_SUBWINDOW_MASK)) | 4086 if (!(dest_mask & IMAGE_SUBWINDOW_MASK)) |
3793 incompatible_image_types (instantiator, dest_mask, IMAGE_SUBWINDOW_MASK); | 4087 incompatible_image_types (instantiator, dest_mask, IMAGE_SUBWINDOW_MASK); |
3794 | 4088 |
3795 ii->data = 0; | 4089 ii->data = 0; |
3796 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0; | 4090 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0; |
3797 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = Qnil; | |
3798 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; | 4091 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; |
3799 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = frame; | 4092 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = frame; |
3800 | 4093 |
3801 /* this stuff may get overidden by the widget code */ | 4094 /* this stuff may get overidden by the widget code */ |
3802 if (NILP (width)) | 4095 if (NILP (width)) |
3834 Return the window id of SUBWINDOW as a number. | 4127 Return the window id of SUBWINDOW as a number. |
3835 */ | 4128 */ |
3836 (subwindow)) | 4129 (subwindow)) |
3837 { | 4130 { |
3838 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); | 4131 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); |
3839 return make_int ((int) (XIMAGE_INSTANCE_SUBWINDOW_ID (subwindow))); | 4132 return make_int ((int) XIMAGE_INSTANCE_SUBWINDOW_ID (subwindow)); |
3840 } | 4133 } |
3841 | 4134 |
3842 DEFUN ("resize-subwindow", Fresize_subwindow, 1, 3, 0, /* | 4135 DEFUN ("resize-subwindow", Fresize_subwindow, 1, 3, 0, /* |
3843 Resize SUBWINDOW to WIDTH x HEIGHT. | 4136 Resize SUBWINDOW to WIDTH x HEIGHT. |
3844 If a value is nil that parameter is not changed. | 4137 If a value is nil that parameter is not changed. |
3864 resize_subwindow, (XIMAGE_INSTANCE (subwindow), neww, newh)); | 4157 resize_subwindow, (XIMAGE_INSTANCE (subwindow), neww, newh)); |
3865 | 4158 |
3866 XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow) = newh; | 4159 XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow) = newh; |
3867 XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow) = neww; | 4160 XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow) = neww; |
3868 | 4161 |
4162 /* need to update the cachels as redisplay will not do this */ | |
4163 update_subwindow_cachel (subwindow); | |
4164 | |
3869 return subwindow; | 4165 return subwindow; |
3870 } | 4166 } |
3871 | 4167 |
3872 DEFUN ("force-subwindow-map", Fforce_subwindow_map, 1, 1, 0, /* | 4168 DEFUN ("force-subwindow-map", Fforce_subwindow_map, 1, 1, 0, /* |
3873 Generate a Map event for SUBWINDOW. | 4169 Generate a Map event for SUBWINDOW. |
3874 */ | 4170 */ |
3875 (subwindow)) | 4171 (subwindow)) |
3876 { | 4172 { |
3877 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); | 4173 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); |
3878 | 4174 #if 0 |
3879 map_subwindow (subwindow, 0, 0); | 4175 map_subwindow (subwindow, 0, 0); |
3880 | 4176 #endif |
3881 return subwindow; | 4177 return subwindow; |
3882 } | 4178 } |
3883 | 4179 |
3884 | 4180 |
3885 /***************************************************************************** | 4181 /***************************************************************************** |
3961 } | 4257 } |
3962 else | 4258 else |
3963 abort (); | 4259 abort (); |
3964 } | 4260 } |
3965 } | 4261 } |
4262 | |
4263 /***************************************************************************** | |
4264 * timeouts for animated glyphs * | |
4265 *****************************************************************************/ | |
4266 static Lisp_Object Qglyph_animated_timeout_handler; | |
4267 | |
4268 DEFUN ("glyph-animated-timeout-handler", Fglyph_animated_timeout_handler, 1, 1, 0, /* | |
4269 Callback function for updating animated images. | |
4270 Don't use this. | |
4271 */ | |
4272 (arg)) | |
4273 { | |
4274 CHECK_WEAK_LIST (arg); | |
4275 | |
4276 if (!NILP (XWEAK_LIST_LIST (arg)) && !NILP (XCAR (XWEAK_LIST_LIST (arg)))) | |
4277 { | |
4278 Lisp_Object value = XCAR (XWEAK_LIST_LIST (arg)); | |
4279 | |
4280 if (IMAGE_INSTANCEP (value)) | |
4281 { | |
4282 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (value); | |
4283 | |
4284 if (COLOR_PIXMAP_IMAGE_INSTANCEP (value) | |
4285 && | |
4286 IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) > 1 | |
4287 && | |
4288 !disable_animated_pixmaps) | |
4289 { | |
4290 /* Increment the index of the image slice we are currently | |
4291 viewing. */ | |
4292 IMAGE_INSTANCE_PIXMAP_SLICE (ii) = | |
4293 (IMAGE_INSTANCE_PIXMAP_SLICE (ii) + 1) | |
4294 % IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii); | |
4295 /* We might need to kick redisplay at this point - but we | |
4296 also might not. */ | |
4297 MARK_DEVICE_FRAMES_GLYPHS_CHANGED | |
4298 (XDEVICE (IMAGE_INSTANCE_DEVICE (ii))); | |
4299 IMAGE_INSTANCE_DIRTYP (ii) = 1; | |
4300 } | |
4301 } | |
4302 } | |
4303 return Qnil; | |
4304 } | |
4305 | |
4306 Lisp_Object add_glyph_animated_timeout (EMACS_INT tickms, Lisp_Object image) | |
4307 { | |
4308 Lisp_Object ret = Qnil; | |
4309 | |
4310 if (tickms > 0 && IMAGE_INSTANCEP (image)) | |
4311 { | |
4312 double ms = ((double)tickms) / 1000.0; | |
4313 struct gcpro gcpro1; | |
4314 Lisp_Object holder = make_weak_list (WEAK_LIST_SIMPLE); | |
4315 | |
4316 GCPRO1 (holder); | |
4317 XWEAK_LIST_LIST (holder) = Fcons (image, Qnil); | |
4318 | |
4319 ret = Fadd_timeout (make_float (ms), | |
4320 Qglyph_animated_timeout_handler, | |
4321 holder, make_float (ms)); | |
4322 | |
4323 UNGCPRO; | |
4324 } | |
4325 return ret; | |
4326 } | |
4327 | |
4328 void disable_glyph_animated_timeout (int i) | |
4329 { | |
4330 Lisp_Object id; | |
4331 XSETINT (id, i); | |
4332 | |
4333 Fdisable_timeout (id); | |
4334 } | |
4335 | |
3966 | 4336 |
3967 /***************************************************************************** | 4337 /***************************************************************************** |
3968 * initialization * | 4338 * initialization * |
3969 *****************************************************************************/ | 4339 *****************************************************************************/ |
3970 | 4340 |
4009 defsymbol (&Qmono_pixmap_image_instance_p, "mono-pixmap-image-instance-p"); | 4379 defsymbol (&Qmono_pixmap_image_instance_p, "mono-pixmap-image-instance-p"); |
4010 defsymbol (&Qcolor_pixmap_image_instance_p, "color-pixmap-image-instance-p"); | 4380 defsymbol (&Qcolor_pixmap_image_instance_p, "color-pixmap-image-instance-p"); |
4011 defsymbol (&Qpointer_image_instance_p, "pointer-image-instance-p"); | 4381 defsymbol (&Qpointer_image_instance_p, "pointer-image-instance-p"); |
4012 defsymbol (&Qwidget_image_instance_p, "widget-image-instance-p"); | 4382 defsymbol (&Qwidget_image_instance_p, "widget-image-instance-p"); |
4013 defsymbol (&Qsubwindow_image_instance_p, "subwindow-image-instance-p"); | 4383 defsymbol (&Qsubwindow_image_instance_p, "subwindow-image-instance-p"); |
4384 defsymbol (&Qlayout_image_instance_p, "layout-image-instance-p"); | |
4014 | 4385 |
4015 DEFSUBR (Fmake_image_instance); | 4386 DEFSUBR (Fmake_image_instance); |
4016 DEFSUBR (Fimage_instance_p); | 4387 DEFSUBR (Fimage_instance_p); |
4017 DEFSUBR (Fimage_instance_type); | 4388 DEFSUBR (Fimage_instance_type); |
4018 DEFSUBR (Fvalid_image_instance_type_p); | 4389 DEFSUBR (Fvalid_image_instance_type_p); |
4067 DEFSUBR (Fglyph_height); | 4438 DEFSUBR (Fglyph_height); |
4068 | 4439 |
4069 /* Qbuffer defined in general.c. */ | 4440 /* Qbuffer defined in general.c. */ |
4070 /* Qpointer defined above */ | 4441 /* Qpointer defined above */ |
4071 | 4442 |
4443 /* Unfortunately, timeout handlers must be lisp functions. This is | |
4444 for animated glyphs. */ | |
4445 defsymbol (&Qglyph_animated_timeout_handler, | |
4446 "glyph-animated-timeout-handler"); | |
4447 DEFSUBR (Fglyph_animated_timeout_handler); | |
4448 | |
4072 /* Errors */ | 4449 /* Errors */ |
4073 deferror (&Qimage_conversion_error, | 4450 deferror (&Qimage_conversion_error, |
4074 "image-conversion-error", | 4451 "image-conversion-error", |
4075 "image-conversion error", Qio_error); | 4452 "image-conversion error", Qio_error); |
4076 | 4453 |
4077 } | 4454 } |
4455 | |
4456 static const struct lrecord_description image_specifier_description[] = { | |
4457 { XD_LISP_OBJECT, specifier_data_offset + offsetof(struct image_specifier, attachee), 2 }, | |
4458 { XD_END } | |
4459 }; | |
4078 | 4460 |
4079 void | 4461 void |
4080 specifier_type_create_image (void) | 4462 specifier_type_create_image (void) |
4081 { | 4463 { |
4082 /* image specifiers */ | 4464 /* image specifiers */ |
4090 SPECIFIER_HAS_METHOD (image, after_change); | 4472 SPECIFIER_HAS_METHOD (image, after_change); |
4091 SPECIFIER_HAS_METHOD (image, going_to_add); | 4473 SPECIFIER_HAS_METHOD (image, going_to_add); |
4092 } | 4474 } |
4093 | 4475 |
4094 void | 4476 void |
4477 reinit_specifier_type_create_image (void) | |
4478 { | |
4479 REINITIALIZE_SPECIFIER_TYPE (image); | |
4480 } | |
4481 | |
4482 | |
4483 static const struct lrecord_description iike_description_1[] = { | |
4484 { XD_LISP_OBJECT, offsetof(ii_keyword_entry, keyword), 1 }, | |
4485 { XD_END } | |
4486 }; | |
4487 | |
4488 static const struct struct_description iike_description = { | |
4489 sizeof(ii_keyword_entry), | |
4490 iike_description_1 | |
4491 }; | |
4492 | |
4493 static const struct lrecord_description iiked_description_1[] = { | |
4494 XD_DYNARR_DESC(ii_keyword_entry_dynarr, &iike_description), | |
4495 { XD_END } | |
4496 }; | |
4497 | |
4498 static const struct struct_description iiked_description = { | |
4499 sizeof(ii_keyword_entry_dynarr), | |
4500 iiked_description_1 | |
4501 }; | |
4502 | |
4503 static const struct lrecord_description iife_description_1[] = { | |
4504 { XD_LISP_OBJECT, offsetof(image_instantiator_format_entry, symbol), 2 }, | |
4505 { XD_STRUCT_PTR, offsetof(image_instantiator_format_entry, meths), 1, &iim_description }, | |
4506 { XD_END } | |
4507 }; | |
4508 | |
4509 static const struct struct_description iife_description = { | |
4510 sizeof(image_instantiator_format_entry), | |
4511 iife_description_1 | |
4512 }; | |
4513 | |
4514 static const struct lrecord_description iifed_description_1[] = { | |
4515 XD_DYNARR_DESC(image_instantiator_format_entry_dynarr, &iife_description), | |
4516 { XD_END } | |
4517 }; | |
4518 | |
4519 static const struct struct_description iifed_description = { | |
4520 sizeof(image_instantiator_format_entry_dynarr), | |
4521 iifed_description_1 | |
4522 }; | |
4523 | |
4524 static const struct lrecord_description iim_description_1[] = { | |
4525 { XD_LISP_OBJECT, offsetof(struct image_instantiator_methods, symbol), 2 }, | |
4526 { XD_STRUCT_PTR, offsetof(struct image_instantiator_methods, keywords), 1, &iiked_description }, | |
4527 { XD_STRUCT_PTR, offsetof(struct image_instantiator_methods, consoles), 1, &cted_description }, | |
4528 { XD_END } | |
4529 }; | |
4530 | |
4531 const struct struct_description iim_description = { | |
4532 sizeof(struct image_instantiator_methods), | |
4533 iim_description_1 | |
4534 }; | |
4535 | |
4536 void | |
4095 image_instantiator_format_create (void) | 4537 image_instantiator_format_create (void) |
4096 { | 4538 { |
4097 /* image instantiators */ | 4539 /* image instantiators */ |
4098 | 4540 |
4099 the_image_instantiator_format_entry_dynarr = | 4541 the_image_instantiator_format_entry_dynarr = |
4100 Dynarr_new (image_instantiator_format_entry); | 4542 Dynarr_new (image_instantiator_format_entry); |
4101 | 4543 |
4102 Vimage_instantiator_format_list = Qnil; | 4544 Vimage_instantiator_format_list = Qnil; |
4103 staticpro (&Vimage_instantiator_format_list); | 4545 staticpro (&Vimage_instantiator_format_list); |
4546 | |
4547 dumpstruct (&the_image_instantiator_format_entry_dynarr, &iifed_description); | |
4104 | 4548 |
4105 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (nothing, "nothing"); | 4549 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (nothing, "nothing"); |
4106 | 4550 |
4107 IIFORMAT_HAS_METHOD (nothing, possible_dest_types); | 4551 IIFORMAT_HAS_METHOD (nothing, possible_dest_types); |
4108 IIFORMAT_HAS_METHOD (nothing, instantiate); | 4552 IIFORMAT_HAS_METHOD (nothing, instantiate); |
4121 IIFORMAT_HAS_METHOD (string, validate); | 4565 IIFORMAT_HAS_METHOD (string, validate); |
4122 IIFORMAT_HAS_METHOD (string, possible_dest_types); | 4566 IIFORMAT_HAS_METHOD (string, possible_dest_types); |
4123 IIFORMAT_HAS_METHOD (string, instantiate); | 4567 IIFORMAT_HAS_METHOD (string, instantiate); |
4124 | 4568 |
4125 IIFORMAT_VALID_KEYWORD (string, Q_data, check_valid_string); | 4569 IIFORMAT_VALID_KEYWORD (string, Q_data, check_valid_string); |
4570 /* Do this so we can set strings. */ | |
4571 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (text, "text"); | |
4572 IIFORMAT_HAS_METHOD (text, set_property); | |
4126 | 4573 |
4127 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (formatted_string, "formatted-string"); | 4574 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (formatted_string, "formatted-string"); |
4128 | 4575 |
4129 IIFORMAT_HAS_METHOD (formatted_string, validate); | 4576 IIFORMAT_HAS_METHOD (formatted_string, validate); |
4130 IIFORMAT_HAS_METHOD (formatted_string, possible_dest_types); | 4577 IIFORMAT_HAS_METHOD (formatted_string, possible_dest_types); |
4182 IIFORMAT_VALID_KEYWORD (xpm, Q_color_symbols, check_valid_xpm_color_symbols); | 4629 IIFORMAT_VALID_KEYWORD (xpm, Q_color_symbols, check_valid_xpm_color_symbols); |
4183 #endif /* HAVE_XPM */ | 4630 #endif /* HAVE_XPM */ |
4184 } | 4631 } |
4185 | 4632 |
4186 void | 4633 void |
4634 reinit_vars_of_glyphs (void) | |
4635 { | |
4636 the_expose_ignore_blocktype = | |
4637 Blocktype_new (struct expose_ignore_blocktype); | |
4638 | |
4639 hold_ignored_expose_registration = 0; | |
4640 } | |
4641 | |
4642 | |
4643 void | |
4187 vars_of_glyphs (void) | 4644 vars_of_glyphs (void) |
4188 { | 4645 { |
4646 reinit_vars_of_glyphs (); | |
4647 | |
4189 Vthe_nothing_vector = vector1 (Qnothing); | 4648 Vthe_nothing_vector = vector1 (Qnothing); |
4190 staticpro (&Vthe_nothing_vector); | 4649 staticpro (&Vthe_nothing_vector); |
4191 | 4650 |
4192 /* image instances */ | 4651 /* image instances */ |
4193 | 4652 |
4249 Vxpm_color_symbols = Qnil; /* initialized in x-faces.el */ | 4708 Vxpm_color_symbols = Qnil; /* initialized in x-faces.el */ |
4250 #endif /* HAVE_XPM */ | 4709 #endif /* HAVE_XPM */ |
4251 #ifdef HAVE_XFACE | 4710 #ifdef HAVE_XFACE |
4252 Fprovide (Qxface); | 4711 Fprovide (Qxface); |
4253 #endif | 4712 #endif |
4713 | |
4714 DEFVAR_BOOL ("disable-animated-pixmaps", &disable_animated_pixmaps /* | |
4715 Whether animated pixmaps should be animated. | |
4716 Default is t. | |
4717 */); | |
4718 disable_animated_pixmaps = 0; | |
4254 } | 4719 } |
4255 | 4720 |
4256 void | 4721 void |
4257 specifier_vars_of_glyphs (void) | 4722 specifier_vars_of_glyphs (void) |
4258 { | 4723 { |