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 {