comparison src/glyphs.c @ 404:2f8bb876ab1d r21-2-32

Import from CVS: tag r21-2-32
author cvs
date Mon, 13 Aug 2007 11:16:07 +0200
parents a86b2b5e0111
children b8cc9ab3f761
comparison
equal deleted inserted replaced
403:9f011ab08d48 404:2f8bb876ab1d
57 Lisp_Object Qmono_pixmap_image_instance_p; 57 Lisp_Object Qmono_pixmap_image_instance_p;
58 Lisp_Object Qcolor_pixmap_image_instance_p; 58 Lisp_Object Qcolor_pixmap_image_instance_p;
59 Lisp_Object Qpointer_image_instance_p; 59 Lisp_Object Qpointer_image_instance_p;
60 Lisp_Object Qsubwindow_image_instance_p; 60 Lisp_Object Qsubwindow_image_instance_p;
61 Lisp_Object Qlayout_image_instance_p; 61 Lisp_Object Qlayout_image_instance_p;
62 Lisp_Object Qupdate_widget_instances;
62 Lisp_Object Qwidget_image_instance_p; 63 Lisp_Object Qwidget_image_instance_p;
63 Lisp_Object Qconst_glyph_variable; 64 Lisp_Object Qconst_glyph_variable;
64 Lisp_Object Qmono_pixmap, Qcolor_pixmap, Qsubwindow; 65 Lisp_Object Qmono_pixmap, Qcolor_pixmap, Qsubwindow;
65 Lisp_Object Q_file, Q_data, Q_face, Q_pixel_width, Q_pixel_height; 66 Lisp_Object Q_file, Q_data, Q_face, Q_pixel_width, Q_pixel_height;
66 Lisp_Object Qformatted_string; 67 Lisp_Object Qformatted_string;
136 always occur. */ 137 always occur. */
137 int hold_ignored_expose_registration; 138 int hold_ignored_expose_registration;
138 139
139 EXFUN (Fimage_instance_type, 1); 140 EXFUN (Fimage_instance_type, 1);
140 EXFUN (Fglyph_type, 1); 141 EXFUN (Fglyph_type, 1);
142 EXFUN (Fnext_window, 4);
141 143
142 144
143 /**************************************************************************** 145 /****************************************************************************
144 * Image Instantiators * 146 * Image Instantiators *
145 ****************************************************************************/ 147 ****************************************************************************/
658 case IMAGE_LAYOUT: 660 case IMAGE_LAYOUT:
659 mark_object (IMAGE_INSTANCE_WIDGET_TYPE (i)); 661 mark_object (IMAGE_INSTANCE_WIDGET_TYPE (i));
660 mark_object (IMAGE_INSTANCE_WIDGET_PROPS (i)); 662 mark_object (IMAGE_INSTANCE_WIDGET_PROPS (i));
661 mark_object (IMAGE_INSTANCE_WIDGET_FACE (i)); 663 mark_object (IMAGE_INSTANCE_WIDGET_FACE (i));
662 mark_object (IMAGE_INSTANCE_WIDGET_ITEMS (i)); 664 mark_object (IMAGE_INSTANCE_WIDGET_ITEMS (i));
665 mark_object (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (i));
666 mark_object (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (i));
667 mark_object (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (i));
663 case IMAGE_SUBWINDOW: 668 case IMAGE_SUBWINDOW:
664 mark_object (IMAGE_INSTANCE_SUBWINDOW_FRAME (i)); 669 mark_object (IMAGE_INSTANCE_SUBWINDOW_FRAME (i));
665 break; 670 break;
666 671
667 default: 672 default:
895 case IMAGE_LAYOUT: 900 case IMAGE_LAYOUT:
896 if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1), 901 if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1),
897 IMAGE_INSTANCE_WIDGET_TYPE (i2)) 902 IMAGE_INSTANCE_WIDGET_TYPE (i2))
898 && IMAGE_INSTANCE_SUBWINDOW_ID (i1) == 903 && IMAGE_INSTANCE_SUBWINDOW_ID (i1) ==
899 IMAGE_INSTANCE_SUBWINDOW_ID (i2) 904 IMAGE_INSTANCE_SUBWINDOW_ID (i2)
905 &&
906 EQ (IMAGE_INSTANCE_WIDGET_FACE (i1),
907 IMAGE_INSTANCE_WIDGET_TYPE (i2))
900 && internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (i1), 908 && internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (i1),
901 IMAGE_INSTANCE_WIDGET_ITEMS (i2), 909 IMAGE_INSTANCE_WIDGET_ITEMS (i2),
902 depth + 1) 910 depth + 1)
903 && internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1), 911 && internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1),
904 IMAGE_INSTANCE_WIDGET_PROPS (i2), 912 IMAGE_INSTANCE_WIDGET_PROPS (i2),
905 depth + 1) 913 depth + 1)
914 && internal_equal (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (i1),
915 IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (i2),
916 depth + 1)
917 && internal_equal (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (i1),
918 IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (i2),
919 depth + 1)
906 )) 920 ))
907 return 0; 921 return 0;
908 break; 922 break;
909 923
910 case IMAGE_SUBWINDOW: 924 case IMAGE_SUBWINDOW:
916 default: 930 default:
917 abort (); 931 abort ();
918 } 932 }
919 933
920 return DEVMETH_OR_GIVEN (d1, image_instance_equal, (i1, i2, depth), 1); 934 return DEVMETH_OR_GIVEN (d1, image_instance_equal, (i1, i2, depth), 1);
935 }
936
937 static unsigned long
938 full_list_hash (Lisp_Object obj, int depth)
939 {
940 unsigned long hash = 0;
941 Lisp_Object rest;
942
943 if (!CONSP (obj))
944 return internal_hash (obj, depth + 1);
945
946 LIST_LOOP (rest, obj)
947 {
948 hash = HASH2 (internal_hash (XCAR (rest), depth + 1), hash);
949 }
950 return hash;
921 } 951 }
922 952
923 static unsigned long 953 static unsigned long
924 image_instance_hash (Lisp_Object obj, int depth) 954 image_instance_hash (Lisp_Object obj, int depth)
925 { 955 {
948 depth + 1)); 978 depth + 1));
949 break; 979 break;
950 980
951 case IMAGE_WIDGET: 981 case IMAGE_WIDGET:
952 case IMAGE_LAYOUT: 982 case IMAGE_LAYOUT:
983 /* We need the hash to be equivalent to what should be
984 displayed. */
953 hash = HASH4 (hash, 985 hash = HASH4 (hash,
954 internal_hash (IMAGE_INSTANCE_WIDGET_TYPE (i), depth + 1), 986 LISP_HASH (IMAGE_INSTANCE_WIDGET_TYPE (i)),
955 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1), 987 full_list_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1),
956 internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1)); 988 full_list_hash
989 (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (i))
990 ? IMAGE_INSTANCE_WIDGET_ITEMS (i)
991 : IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (i),
992 depth + 1));
957 case IMAGE_SUBWINDOW: 993 case IMAGE_SUBWINDOW:
958 hash = HASH2 (hash, (int) IMAGE_INSTANCE_SUBWINDOW_ID (i)); 994 hash = HASH2 (hash, (int) IMAGE_INSTANCE_SUBWINDOW_ID (i));
959 break; 995 break;
960 996
961 default: 997 default:
2746 Lisp_Object subtable; 2782 Lisp_Object subtable;
2747 Lisp_Object ls3 = Qnil; 2783 Lisp_Object ls3 = Qnil;
2748 Lisp_Object pointer_fg = Qnil; 2784 Lisp_Object pointer_fg = Qnil;
2749 Lisp_Object pointer_bg = Qnil; 2785 Lisp_Object pointer_bg = Qnil;
2750 2786
2787 if (dest_mask & (IMAGE_SUBWINDOW_MASK
2788 | IMAGE_WIDGET_MASK
2789 | IMAGE_TEXT_MASK))
2790 {
2791 if (!WINDOWP (domain))
2792 signal_simple_error ("Can't instantiate text or subwindow outside a window",
2793 instantiator);
2794 else if ((dest_mask & (IMAGE_SUBWINDOW_MASK
2795 | IMAGE_WIDGET_MASK))
2796 && MINI_WINDOW_P (XWINDOW (domain)))
2797 domain = Fnext_window (domain, Qnil, Qnil, Qnil);
2798 }
2799
2751 if (pointerp) 2800 if (pointerp)
2752 { 2801 {
2753 pointer_fg = FACE_FOREGROUND (Vpointer_face, domain); 2802 pointer_fg = FACE_FOREGROUND (Vpointer_face, domain);
2754 pointer_bg = FACE_BACKGROUND (Vpointer_face, domain); 2803 pointer_bg = FACE_BACKGROUND (Vpointer_face, domain);
2755 ls3 = list3 (instantiator, pointer_fg, pointer_bg); 2804 ls3 = list3 (instantiator, pointer_fg, pointer_bg);
2801 && 2850 &&
2802 dest_mask & (IMAGE_SUBWINDOW_MASK 2851 dest_mask & (IMAGE_SUBWINDOW_MASK
2803 | IMAGE_WIDGET_MASK 2852 | IMAGE_WIDGET_MASK
2804 | IMAGE_TEXT_MASK)) 2853 | IMAGE_TEXT_MASK))
2805 { 2854 {
2806 if (!WINDOWP (domain))
2807 signal_simple_error ("Can't instantiate text or subwindow outside a window",
2808 instantiator);
2809 instance = Fgethash (instantiator, 2855 instance = Fgethash (instantiator,
2810 XWINDOW (domain)->subwindow_instance_cache, 2856 XWINDOW (domain)->subwindow_instance_cache,
2811 Qunbound); 2857 Qunbound);
2812 } 2858 }
2813 } 2859 }
2839 /* only after the image has been instantiated do we know 2885 /* only after the image has been instantiated do we know
2840 whether we need to put it in the per-window image instance 2886 whether we need to put it in the per-window image instance
2841 cache. */ 2887 cache. */
2842 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance)) 2888 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
2843 & 2889 &
2844 (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK)) 2890 (IMAGE_SUBWINDOW_MASK
2891 | IMAGE_WIDGET_MASK
2892 | IMAGE_TEXT_MASK ))
2845 { 2893 {
2846 if (!WINDOWP (domain)) 2894 Fsetcdr (XCDR (locative), XWINDOW (domain)->subwindow_instance_cache);
2847 signal_simple_error ("Can't instantiate subwindow outside a window",
2848 instantiator);
2849
2850 Fsetcdr (XCDR (locative), XWINDOW (domain)->subwindow_instance_cache );
2851 } 2895 }
2852 unbind_to (speccount, Qnil); 2896 unbind_to (speccount, Qnil);
2853 } 2897 }
2854 else 2898 else
2855 free_list (ls3); 2899 free_list (ls3);
4266 * subwindow functions * 4310 * subwindow functions *
4267 *****************************************************************************/ 4311 *****************************************************************************/
4268 4312
4269 /* Update the displayed characteristics of a subwindow. This function 4313 /* Update the displayed characteristics of a subwindow. This function
4270 should generally only get called if the subwindow is actually 4314 should generally only get called if the subwindow is actually
4271 dirty. The only other time it gets called is if subwindow state 4315 dirty. */
4272 changed, when we can't actually tell whether its going to be dirty
4273 or not.
4274 #### I suspect what we should really do is re-evaluate all the
4275 gui slots that could affect this and then mark the instance as
4276 dirty. Right now, updating everything is safe but expensive. */
4277 void 4316 void
4278 update_subwindow (Lisp_Object subwindow) 4317 update_subwindow (Lisp_Object subwindow)
4279 { 4318 {
4280 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); 4319 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
4281 int count = specpdl_depth (); 4320 int count = specpdl_depth ();
4321 unsigned long display_hash = internal_hash (subwindow,
4322 IMAGE_INSTANCE_HASH_DEPTH);
4282 4323
4283 /* The update method is allowed to call eval. Since it is quite 4324 /* The update method is allowed to call eval. Since it is quite
4284 common for this function to get called from somewhere in 4325 common for this function to get called from somewhere in
4285 redisplay we need to make sure that quits are ignored. Otherwise 4326 redisplay we need to make sure that quits are ignored. Otherwise
4286 Fsignal will abort. */ 4327 Fsignal will abort. */
4288 4329
4289 if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET 4330 if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET
4290 || 4331 ||
4291 IMAGE_INSTANCE_TYPE (ii) == IMAGE_LAYOUT) 4332 IMAGE_INSTANCE_TYPE (ii) == IMAGE_LAYOUT)
4292 { 4333 {
4293 if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET) 4334 if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET
4294 update_widget (subwindow); 4335 &&
4336 (display_hash != IMAGE_INSTANCE_DISPLAY_HASH (ii)
4337 ||
4338 IMAGE_INSTANCE_DISPLAY_HASH (ii) == 0))
4339 {
4340 update_widget (subwindow);
4341 }
4295 /* Reset the changed flags. */ 4342 /* Reset the changed flags. */
4296 IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) = 0; 4343 IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) = 0;
4297 IMAGE_INSTANCE_WIDGET_PERCENT_CHANGED (ii) = 0; 4344 IMAGE_INSTANCE_WIDGET_PERCENT_CHANGED (ii) = 0;
4298 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0; 4345 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
4299 IMAGE_INSTANCE_TEXT_CHANGED (ii) = 0; 4346 IMAGE_INSTANCE_TEXT_CHANGED (ii) = 0;
4304 { 4351 {
4305 MAYBE_DEVMETH (XDEVICE (ii->device), update_subwindow, (ii)); 4352 MAYBE_DEVMETH (XDEVICE (ii->device), update_subwindow, (ii));
4306 } 4353 }
4307 4354
4308 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 0; 4355 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 0;
4356 /* This function is typically called by redisplay just before
4357 outputting the information to the screen. Thus we record a hash
4358 of the output to determine whether on-screen is the same as
4359 recorded structure. This approach has limitations in there is a
4360 good chance that hash values will be different for the same
4361 visual appearance. However, we would rather that then the other
4362 way round - it simply means that we will get more displays than
4363 we might need. We can get better hashing by making the depth
4364 negative - currently it will recurse down 5 levels.*/
4365 IMAGE_INSTANCE_DISPLAY_HASH (ii) = display_hash;
4309 4366
4310 unbind_to (count, Qnil); 4367 unbind_to (count, Qnil);
4311 } 4368 }
4312 4369
4313 /* Update all the subwindows on a frame. */ 4370 /* Update all the subwindows on a frame. */
4314 void 4371 DEFUN ("update-widget-instances", Fupdate_widget_instances,1, 1, 0, /*
4315 update_frame_subwindows (struct frame *f) 4372 Given a FRAME, re-evaluate the display hash code for all widgets in the frame.
4373 Don't use this.
4374 */
4375 (frame))
4316 { 4376 {
4317 int elt; 4377 int elt;
4318 4378 struct frame* f;
4319 /* #### Checking all of these might be overkill now that we update 4379 CHECK_FRAME (frame);
4320 subwindows in the actual redisplay code. */ 4380 f = XFRAME (frame);
4321 if (f->subwindows_changed || f->subwindows_state_changed || f->faces_changed) 4381
4322 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) 4382 /* If we get called we know something has changed. */
4383 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
4323 { 4384 {
4324 struct subwindow_cachel *cachel = 4385 struct subwindow_cachel *cachel =
4325 Dynarr_atp (f->subwindow_cachels, elt); 4386 Dynarr_atp (f->subwindow_cachels, elt);
4326 4387
4327 if (cachel->being_displayed 4388 if (cachel->being_displayed &&
4328 && 4389 XIMAGE_INSTANCE_TYPE (cachel->subwindow)
4329 /* We only want to update if something has really 4390 == IMAGE_WIDGET)
4330 changed. */
4331 (f->subwindows_state_changed
4332 ||
4333 XIMAGE_INSTANCE_DIRTYP (cachel->subwindow)))
4334 { 4391 {
4335 update_subwindow (cachel->subwindow); 4392 /* If a subwindow hash changed mark it so that redisplay
4393 will fix it. */
4394 if (internal_hash (cachel->subwindow,
4395 IMAGE_INSTANCE_HASH_DEPTH) !=
4396 XIMAGE_INSTANCE_DISPLAY_HASH (cachel->subwindow))
4397 {
4398 set_image_instance_dirty_p (cachel->subwindow, 1);
4399 MARK_FRAME_GLYPHS_CHANGED (f);
4400 }
4336 } 4401 }
4337 } 4402 }
4403 return Qnil;
4338 } 4404 }
4339 4405
4340 /* remove a subwindow from its frame */ 4406 /* remove a subwindow from its frame */
4341 void unmap_subwindow (Lisp_Object subwindow) 4407 void unmap_subwindow (Lisp_Object subwindow)
4342 { 4408 {
4433 4499
4434 /* #### This stuff may get overidden by the widget code and is 4500 /* #### This stuff may get overidden by the widget code and is
4435 actually really dumb now that we have dynamic geometry 4501 actually really dumb now that we have dynamic geometry
4436 calculations. What should really happen is that the subwindow 4502 calculations. What should really happen is that the subwindow
4437 should query its child for an appropriate geometry. */ 4503 should query its child for an appropriate geometry. */
4438 if (NILP (width)) 4504 if (INTP (width))
4439 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = 20;
4440 else
4441 { 4505 {
4442 int w = 1; 4506 int w = 1;
4443 CHECK_INT (width);
4444 if (XINT (width) > 1) 4507 if (XINT (width) > 1)
4445 w = XINT (width); 4508 w = XINT (width);
4446 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = w; 4509 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = w;
4447 } 4510 }
4448 if (NILP (height))
4449 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = 20;
4450 else 4511 else
4512 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = 20;
4513
4514 if (INTP (height))
4451 { 4515 {
4452 int h = 1; 4516 int h = 1;
4453 CHECK_INT (height);
4454 if (XINT (height) > 1) 4517 if (XINT (height) > 1)
4455 h = XINT (height); 4518 h = XINT (height);
4456 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = h; 4519 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = h;
4457 } 4520 }
4521 else
4522 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = 20;
4458 } 4523 }
4459 4524
4460 DEFUN ("subwindowp", Fsubwindowp, 1, 1, 0, /* 4525 DEFUN ("subwindowp", Fsubwindowp, 1, 1, 0, /*
4461 Return non-nil if OBJECT is a subwindow. 4526 Return non-nil if OBJECT is a subwindow.
4462 */ 4527 */
4694 4759
4695 DEFSUBR (Fimage_instantiator_format_list); 4760 DEFSUBR (Fimage_instantiator_format_list);
4696 DEFSUBR (Fvalid_image_instantiator_format_p); 4761 DEFSUBR (Fvalid_image_instantiator_format_p);
4697 DEFSUBR (Fset_console_type_image_conversion_list); 4762 DEFSUBR (Fset_console_type_image_conversion_list);
4698 DEFSUBR (Fconsole_type_image_conversion_list); 4763 DEFSUBR (Fconsole_type_image_conversion_list);
4764 DEFSUBR (Fupdate_widget_instances);
4699 4765
4700 defkeyword (&Q_file, ":file"); 4766 defkeyword (&Q_file, ":file");
4701 defkeyword (&Q_data, ":data"); 4767 defkeyword (&Q_data, ":data");
4702 defkeyword (&Q_face, ":face"); 4768 defkeyword (&Q_face, ":face");
4703 defkeyword (&Q_pixel_height, ":pixel-height"); 4769 defkeyword (&Q_pixel_height, ":pixel-height");
4729 defsymbol (&Qcolor_pixmap_image_instance_p, "color-pixmap-image-instance-p"); 4795 defsymbol (&Qcolor_pixmap_image_instance_p, "color-pixmap-image-instance-p");
4730 defsymbol (&Qpointer_image_instance_p, "pointer-image-instance-p"); 4796 defsymbol (&Qpointer_image_instance_p, "pointer-image-instance-p");
4731 defsymbol (&Qwidget_image_instance_p, "widget-image-instance-p"); 4797 defsymbol (&Qwidget_image_instance_p, "widget-image-instance-p");
4732 defsymbol (&Qsubwindow_image_instance_p, "subwindow-image-instance-p"); 4798 defsymbol (&Qsubwindow_image_instance_p, "subwindow-image-instance-p");
4733 defsymbol (&Qlayout_image_instance_p, "layout-image-instance-p"); 4799 defsymbol (&Qlayout_image_instance_p, "layout-image-instance-p");
4800 defsymbol (&Qupdate_widget_instances, "update-widget-instances");
4734 4801
4735 DEFSUBR (Fmake_image_instance); 4802 DEFSUBR (Fmake_image_instance);
4736 DEFSUBR (Fimage_instance_p); 4803 DEFSUBR (Fimage_instance_p);
4737 DEFSUBR (Fimage_instance_type); 4804 DEFSUBR (Fimage_instance_type);
4738 DEFSUBR (Fvalid_image_instance_type_p); 4805 DEFSUBR (Fvalid_image_instance_type_p);