Mercurial > hg > xemacs-beta
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 |