comparison src/glyphs.c @ 406:b8cc9ab3f761 r21-2-33

Import from CVS: tag r21-2-33
author cvs
date Mon, 13 Aug 2007 11:17:09 +0200
parents 2f8bb876ab1d
children 501cfd01ee6d
comparison
equal deleted inserted replaced
405:0e08f63c74d2 406:b8cc9ab3f761
769 write_c_string (")", printcharfun); 769 write_c_string (")", printcharfun);
770 } 770 }
771 break; 771 break;
772 772
773 case IMAGE_WIDGET: 773 case IMAGE_WIDGET:
774 print_internal (IMAGE_INSTANCE_WIDGET_TYPE (ii), printcharfun, 0);
775
776 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
777 {
778 write_c_string (" ", printcharfun);
779 print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 1);
780 }
781
774 if (!NILP (IMAGE_INSTANCE_WIDGET_FACE (ii))) 782 if (!NILP (IMAGE_INSTANCE_WIDGET_FACE (ii)))
775 { 783 {
776 write_c_string (" (", printcharfun); 784 write_c_string (" face=", printcharfun);
777 print_internal 785 print_internal
778 (IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0); 786 (IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0);
779 write_c_string (")", printcharfun);
780 } 787 }
781 788
782 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
783 print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 0);
784 789
785 case IMAGE_SUBWINDOW: 790 case IMAGE_SUBWINDOW:
786 case IMAGE_LAYOUT: 791 case IMAGE_LAYOUT:
787 sprintf (buf, " %dx%d", IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii), 792 sprintf (buf, " %dx%d", IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii),
788 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); 793 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii));
799 if (!FRAME_LIVE_P (f)) 804 if (!FRAME_LIVE_P (f))
800 write_c_string ("dead", printcharfun); 805 write_c_string ("dead", printcharfun);
801 else 806 else
802 write_c_string (DEVICE_TYPE_NAME (XDEVICE (FRAME_DEVICE (f))), 807 write_c_string (DEVICE_TYPE_NAME (XDEVICE (FRAME_DEVICE (f))),
803 printcharfun); 808 printcharfun);
804
805 write_c_string ("-frame ", printcharfun);
806 } 809 }
807 write_c_string (">", printcharfun); 810 write_c_string ("-frame>", printcharfun);
808 sprintf (buf, " 0x%p", IMAGE_INSTANCE_SUBWINDOW_ID (ii)); 811 sprintf (buf, " 0x%p", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
809 write_c_string (buf, printcharfun); 812 write_c_string (buf, printcharfun);
810 813
811 break; 814 break;
812 815
932 } 935 }
933 936
934 return DEVMETH_OR_GIVEN (d1, image_instance_equal, (i1, i2, depth), 1); 937 return DEVMETH_OR_GIVEN (d1, image_instance_equal, (i1, i2, depth), 1);
935 } 938 }
936 939
940 #if 0
941 /* internal_hash will not go very far down a list because of the way
942 its written. For items we need to hash all elements so we provide
943 our own list hashing function. */
937 static unsigned long 944 static unsigned long
938 full_list_hash (Lisp_Object obj, int depth) 945 full_list_hash (Lisp_Object obj, int depth)
939 { 946 {
940 unsigned long hash = 0; 947 unsigned long hash = 0;
941 Lisp_Object rest; 948 Lisp_Object rest;
942 949
943 if (!CONSP (obj)) 950 if (!CONSP (obj))
944 return internal_hash (obj, depth + 1); 951 return internal_hash (obj, depth + 1);
945 952
946 LIST_LOOP (rest, obj) 953 hash = LISP_HASH (XCAR (obj));
947 { 954 LIST_LOOP (rest, XCDR (obj))
948 hash = HASH2 (internal_hash (XCAR (rest), depth + 1), hash); 955 {
956 hash = HASH2 (hash, internal_hash (XCAR (rest), depth + 1));
949 } 957 }
950 return hash; 958 return hash;
951 } 959 }
960 #endif
952 961
953 static unsigned long 962 static unsigned long
954 image_instance_hash (Lisp_Object obj, int depth) 963 image_instance_hash (Lisp_Object obj, int depth)
955 { 964 {
956 Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); 965 Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj);
982 case IMAGE_LAYOUT: 991 case IMAGE_LAYOUT:
983 /* We need the hash to be equivalent to what should be 992 /* We need the hash to be equivalent to what should be
984 displayed. */ 993 displayed. */
985 hash = HASH4 (hash, 994 hash = HASH4 (hash,
986 LISP_HASH (IMAGE_INSTANCE_WIDGET_TYPE (i)), 995 LISP_HASH (IMAGE_INSTANCE_WIDGET_TYPE (i)),
987 full_list_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1), 996 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1),
988 full_list_hash 997 internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1));
989 (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (i))
990 ? IMAGE_INSTANCE_WIDGET_ITEMS (i)
991 : IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (i),
992 depth + 1));
993 case IMAGE_SUBWINDOW: 998 case IMAGE_SUBWINDOW:
994 hash = HASH2 (hash, (int) IMAGE_INSTANCE_SUBWINDOW_ID (i)); 999 hash = HASH2 (hash, (int) IMAGE_INSTANCE_SUBWINDOW_ID (i));
995 break; 1000 break;
996 1001
997 default: 1002 default:
2782 Lisp_Object subtable; 2787 Lisp_Object subtable;
2783 Lisp_Object ls3 = Qnil; 2788 Lisp_Object ls3 = Qnil;
2784 Lisp_Object pointer_fg = Qnil; 2789 Lisp_Object pointer_fg = Qnil;
2785 Lisp_Object pointer_bg = Qnil; 2790 Lisp_Object pointer_bg = Qnil;
2786 2791
2787 if (dest_mask & (IMAGE_SUBWINDOW_MASK 2792 /* We have to put subwindow, widget and text image instances in
2788 | IMAGE_WIDGET_MASK 2793 a per-window cache so that we can see the same glyph in
2789 | IMAGE_TEXT_MASK)) 2794 different windows. Unfortunately we do not know the type of
2790 { 2795 image_instance until after it has been created. We thus need
2791 if (!WINDOWP (domain)) 2796 to be really careful how we place things. */
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 2797
2800 if (pointerp) 2798 if (pointerp)
2801 { 2799 {
2802 pointer_fg = FACE_FOREGROUND (Vpointer_face, domain); 2800 pointer_fg = FACE_FOREGROUND (Vpointer_face, domain);
2803 pointer_bg = FACE_BACKGROUND (Vpointer_face, domain); 2801 pointer_bg = FACE_BACKGROUND (Vpointer_face, domain);
2848 round it. */ 2846 round it. */
2849 if (UNBOUNDP (instance) 2847 if (UNBOUNDP (instance)
2850 && 2848 &&
2851 dest_mask & (IMAGE_SUBWINDOW_MASK 2849 dest_mask & (IMAGE_SUBWINDOW_MASK
2852 | IMAGE_WIDGET_MASK 2850 | IMAGE_WIDGET_MASK
2853 | IMAGE_TEXT_MASK)) 2851 | IMAGE_LAYOUT_MASK
2852 | IMAGE_TEXT_MASK)
2853 && WINDOWP (domain))
2854 { 2854 {
2855 instance = Fgethash (instantiator, 2855 instance = Fgethash (instantiator,
2856 XWINDOW (domain)->subwindow_instance_cache, 2856 XWINDOW (domain)->subwindow_instance_cache,
2857 Qunbound); 2857 Qunbound);
2858 } 2858 }
2887 cache. */ 2887 cache. */
2888 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance)) 2888 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
2889 & 2889 &
2890 (IMAGE_SUBWINDOW_MASK 2890 (IMAGE_SUBWINDOW_MASK
2891 | IMAGE_WIDGET_MASK 2891 | IMAGE_WIDGET_MASK
2892 | IMAGE_LAYOUT_MASK
2892 | IMAGE_TEXT_MASK )) 2893 | IMAGE_TEXT_MASK ))
2893 { 2894 {
2895 #ifdef ERROR_CHECK_GLYPHS
2896 if (XIMAGE_INSTANCE_TYPE (instance) != IMAGE_TEXT)
2897 assert (EQ (XIMAGE_INSTANCE_SUBWINDOW_FRAME (instance),
2898 FW_FRAME (domain)));
2899 #endif
2900 if (!WINDOWP (domain))
2901 signal_simple_error ("Can't instantiate text or subwindow outside a window",
2902 instantiator);
2903 #ifdef ERROR_CHECK_GLYPHS
2904 if (XIMAGE_INSTANCE_TYPE (instance) != IMAGE_TEXT)
2905 assert (EQ (XIMAGE_INSTANCE_SUBWINDOW_FRAME (instance),
2906 FW_FRAME (domain)));
2907 #endif
2894 Fsetcdr (XCDR (locative), XWINDOW (domain)->subwindow_instance_cache); 2908 Fsetcdr (XCDR (locative), XWINDOW (domain)->subwindow_instance_cache);
2895 } 2909 }
2896 unbind_to (speccount, Qnil); 2910 unbind_to (speccount, Qnil);
2911 #ifdef ERROR_CHECK_GLYPHS
2912 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
2913 &
2914 (IMAGE_SUBWINDOW_MASK
2915 | IMAGE_WIDGET_MASK
2916 | IMAGE_LAYOUT_MASK
2917 | IMAGE_TEXT_MASK ))
2918 assert (EQ (Fgethash ((pointerp ? ls3 : instantiator),
2919 XWINDOW (domain)->subwindow_instance_cache,
2920 Qunbound), instance));
2921 #endif
2897 } 2922 }
2898 else 2923 else
2899 free_list (ls3); 2924 free_list (ls3);
2900 2925
2901 if (NILP (instance)) 2926 if (NILP (instance))
2902 signal_simple_error ("Can't instantiate image (probably cached)", 2927 signal_simple_error ("Can't instantiate image (probably cached)",
2903 instantiator); 2928 instantiator);
2929 #ifdef ERROR_CHECK_GLYPHS
2930 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
2931 & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK))
2932 assert (EQ (XIMAGE_INSTANCE_SUBWINDOW_FRAME (instance),
2933 FW_FRAME (domain)));
2934 #endif
2904 return instance; 2935 return instance;
2905 } 2936 }
2906 2937
2907 abort (); 2938 abort ();
2908 return Qnil; /* not reached */ 2939 return Qnil; /* not reached */
4316 void 4347 void
4317 update_subwindow (Lisp_Object subwindow) 4348 update_subwindow (Lisp_Object subwindow)
4318 { 4349 {
4319 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); 4350 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
4320 int count = specpdl_depth (); 4351 int count = specpdl_depth ();
4321 unsigned long display_hash = internal_hash (subwindow,
4322 IMAGE_INSTANCE_HASH_DEPTH);
4323 4352
4324 /* The update method is allowed to call eval. Since it is quite 4353 /* The update method is allowed to call eval. Since it is quite
4325 common for this function to get called from somewhere in 4354 common for this function to get called from somewhere in
4326 redisplay we need to make sure that quits are ignored. Otherwise 4355 redisplay we need to make sure that quits are ignored. Otherwise
4327 Fsignal will abort. */ 4356 Fsignal will abort. */
4329 4358
4330 if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET 4359 if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET
4331 || 4360 ||
4332 IMAGE_INSTANCE_TYPE (ii) == IMAGE_LAYOUT) 4361 IMAGE_INSTANCE_TYPE (ii) == IMAGE_LAYOUT)
4333 { 4362 {
4334 if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET 4363 if (image_instance_changed (subwindow))
4335 && 4364 update_widget (subwindow);
4336 (display_hash != IMAGE_INSTANCE_DISPLAY_HASH (ii)
4337 ||
4338 IMAGE_INSTANCE_DISPLAY_HASH (ii) == 0))
4339 {
4340 update_widget (subwindow);
4341 }
4342 /* Reset the changed flags. */ 4365 /* Reset the changed flags. */
4343 IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) = 0; 4366 IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) = 0;
4344 IMAGE_INSTANCE_WIDGET_PERCENT_CHANGED (ii) = 0;
4345 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0; 4367 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
4346 IMAGE_INSTANCE_TEXT_CHANGED (ii) = 0; 4368 IMAGE_INSTANCE_TEXT_CHANGED (ii) = 0;
4347 } 4369 }
4348 else if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW 4370 else if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW
4349 && 4371 &&
4359 recorded structure. This approach has limitations in there is a 4381 recorded structure. This approach has limitations in there is a
4360 good chance that hash values will be different for the same 4382 good chance that hash values will be different for the same
4361 visual appearance. However, we would rather that then the other 4383 visual appearance. However, we would rather that then the other
4362 way round - it simply means that we will get more displays than 4384 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 4385 we might need. We can get better hashing by making the depth
4364 negative - currently it will recurse down 5 levels.*/ 4386 negative - currently it will recurse down 7 levels.*/
4365 IMAGE_INSTANCE_DISPLAY_HASH (ii) = display_hash; 4387 IMAGE_INSTANCE_DISPLAY_HASH (ii) = internal_hash (subwindow,
4388 IMAGE_INSTANCE_HASH_DEPTH);
4366 4389
4367 unbind_to (count, Qnil); 4390 unbind_to (count, Qnil);
4391 }
4392
4393 int
4394 image_instance_changed (Lisp_Object subwindow)
4395 {
4396 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
4397
4398 if (internal_hash (subwindow, IMAGE_INSTANCE_HASH_DEPTH) !=
4399 IMAGE_INSTANCE_DISPLAY_HASH (ii))
4400 return 1;
4401 else if ((WIDGET_IMAGE_INSTANCEP (subwindow)
4402 || LAYOUT_IMAGE_INSTANCEP (subwindow))
4403 && !internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (ii),
4404 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii), 0))
4405 return 1;
4406 else
4407 return 0;
4368 } 4408 }
4369 4409
4370 /* Update all the subwindows on a frame. */ 4410 /* Update all the subwindows on a frame. */
4371 DEFUN ("update-widget-instances", Fupdate_widget_instances,1, 1, 0, /* 4411 DEFUN ("update-widget-instances", Fupdate_widget_instances,1, 1, 0, /*
4372 Given a FRAME, re-evaluate the display hash code for all widgets in the frame. 4412 Given a FRAME, re-evaluate the display hash code for all widgets in the frame.
4384 { 4424 {
4385 struct subwindow_cachel *cachel = 4425 struct subwindow_cachel *cachel =
4386 Dynarr_atp (f->subwindow_cachels, elt); 4426 Dynarr_atp (f->subwindow_cachels, elt);
4387 4427
4388 if (cachel->being_displayed && 4428 if (cachel->being_displayed &&
4389 XIMAGE_INSTANCE_TYPE (cachel->subwindow) 4429 image_instance_changed (cachel->subwindow))
4390 == IMAGE_WIDGET)
4391 { 4430 {
4392 /* If a subwindow hash changed mark it so that redisplay 4431 set_image_instance_dirty_p (cachel->subwindow, 1);
4393 will fix it. */ 4432 MARK_FRAME_GLYPHS_CHANGED (f);
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 }
4401 } 4433 }
4402 } 4434 }
4403 return Qnil; 4435 return Qnil;
4404 } 4436 }
4405 4437