Index: src/glyphs.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs.c,v retrieving revision 1.23.2.54 diff -u -r1.23.2.54 glyphs.c --- src/glyphs.c 2000/02/23 22:29:40 1.23.2.54 +++ src/glyphs.c 2000/03/08 15:04:53 @@ -899,6 +899,9 @@ IMAGE_INSTANCE_WIDGET_TYPE (i2)) && IMAGE_INSTANCE_SUBWINDOW_ID (i1) == IMAGE_INSTANCE_SUBWINDOW_ID (i2) + && + EQ (IMAGE_INSTANCE_WIDGET_FACE (i1), + IMAGE_INSTANCE_WIDGET_TYPE (i2)) && internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (i1), IMAGE_INSTANCE_WIDGET_ITEMS (i2), depth + 1) @@ -4279,6 +4282,7 @@ dirty. The only other time it gets called is if subwindow state changed, when we can't actually tell whether its going to be dirty or not. + #### I suspect what we should really do is re-evaluate all the gui slots that could affect this and then mark the instance as dirty. Right now, updating everything is safe but expensive. */ @@ -4287,6 +4291,7 @@ { Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); int count = specpdl_depth (); + unsigned long display_hash = internal_hash (subwindow, 0); /* The update method is allowed to call eval. Since it is quite common for this function to get called from somewhere in @@ -4298,8 +4303,14 @@ || IMAGE_INSTANCE_TYPE (ii) == IMAGE_LAYOUT) { - if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET) - update_widget (subwindow); + if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET + && + (display_hash != IMAGE_INSTANCE_DISPLAY_HASH (ii) + || + IMAGE_INSTANCE_DISPLAY_HASH (ii) == 0)) + { + update_widget (subwindow); + } /* Reset the changed flags. */ IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) = 0; IMAGE_INSTANCE_WIDGET_PERCENT_CHANGED (ii) = 0; @@ -4314,6 +4325,16 @@ } IMAGE_INSTANCE_SIZE_CHANGED (ii) = 0; + /* This function is typically called by redisplay just before + outputting the information to the screen. Thus we record a hash + of the output to determine whether on-screen is the same as + recorded structure. This approach has limitations in there is a + good chance that hash values will be different for the same + visual appearance. However, we would rather that then the other + way round - it simply means that we will get more displays than + we might need. We can get better hashing by making the depth + negative - currently it will recurse down 5 levels.*/ + IMAGE_INSTANCE_DISPLAY_HASH (ii) = display_hash; unbind_to (count, Qnil); } Index: src/glyphs.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs.h,v retrieving revision 1.18.2.39 diff -u -r1.18.2.39 glyphs.h --- src/glyphs.h 2000/02/25 09:51:41 1.18.2.39 +++ src/glyphs.h 2000/03/08 15:04:56 @@ -497,6 +497,9 @@ enum image_instance_type type; unsigned int x_offset, y_offset; /* for layout purposes */ unsigned int width, height; + unsigned long display_hash; /* Hash value representing the structure + of the image_instance when it was + last displayed. */ unsigned int dirty : 1; unsigned int size_changed : 1; unsigned int text_changed : 1; @@ -571,6 +574,7 @@ #define IMAGE_INSTANCE_YOFFSET(i) ((i)->y_offset) #define IMAGE_INSTANCE_WIDTH(i) ((i)->width) #define IMAGE_INSTANCE_HEIGHT(i) ((i)->height) +#define IMAGE_INSTANCE_DISPLAY_HASH(i) ((i)->display_hash) #define IMAGE_INSTANCE_PIXMAP_TYPE_P(i) \ ((IMAGE_INSTANCE_TYPE (i) == IMAGE_MONO_PIXMAP) \ || (IMAGE_INSTANCE_TYPE (i) == IMAGE_COLOR_PIXMAP)) @@ -675,6 +679,8 @@ IMAGE_INSTANCE_PARENT (XIMAGE_INSTANCE (i)) #define XIMAGE_INSTANCE_TYPE(i) \ IMAGE_INSTANCE_TYPE (XIMAGE_INSTANCE (i)) +#define XIMAGE_INSTANCE_DISPLAY_HASH(i) \ + IMAGE_INSTANCE_DISPLAY_HASH (XIMAGE_INSTANCE (i)) #define XIMAGE_INSTANCE_XOFFSET(i) \ IMAGE_INSTANCE_XOFFSET (XIMAGE_INSTANCE (i)) #define XIMAGE_INSTANCE_YOFFSET(i) \ Index: src/gutter.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/Attic/gutter.c,v retrieving revision 1.1.2.25 diff -u -r1.1.2.25 gutter.c --- src/gutter.c 2000/03/05 15:39:38 1.1.2.25 +++ src/gutter.c 2000/03/08 15:05:00 @@ -292,6 +292,20 @@ cdla_len != Dynarr_length (ddla) || (f->extents_changed && w->gutter_extent_modiff[pos])) { +#ifdef DEBUG_GUTTERS + printf ("gutter redisplay triggered by %s\n", force ? "force" : + f->faces_changed ? "f->faces_changed" : + f->frame_changed ? "f->frame_changed" : + f->gutter_changed ? "f->gutter_changed" : + f->glyphs_changed ? "f->glyphs_changed" : + f->size_changed ? "f->size_changed" : + f->subwindows_changed ? "f->subwindows_changed" : + w->windows_changed ? "w->windows_changed" : + f->windows_structure_changed ? "f->windows_structure_changed" : + cdla_len != Dynarr_length (ddla) ? "different display structures" : + f->extents_changed && w->gutter_extent_modiff[pos] ? + "f->extents_changed && w->gutter_extent_modiff[pos]" : ""); +#endif /* Output each line. */ for (line = 0; line < Dynarr_length (ddla); line++) { Index: src/redisplay-output.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay-output.c,v retrieving revision 1.11.2.29 diff -u -r1.11.2.29 redisplay-output.c --- src/redisplay-output.c 2000/03/04 16:53:34 1.11.2.29 +++ src/redisplay-output.c 2000/03/08 15:05:08 @@ -238,7 +238,23 @@ else if (crb->type == RUNE_DGLYPH && XFRAME (w->frame)->glyphs_changed && XGLYPH_DIRTYP (crb->object.dglyph.glyph)) - return 0; + { + Lisp_Object window, image; + XSETWINDOW (window, w); + image = glyph_image_instance (crb->object.dglyph.glyph, + window, ERROR_ME_NOT, 1); + /* It is quite common of the two glyphs to be EQ since in many + cases they will actually be the same object. This does not + mean, however, that nothing has changed. We therefore need to + check the current hash of the glyph against the last recorded + display hash. See update_subwindow (). */ + if (XIMAGE_INSTANCE_DISPLAY_HASH (image) == 0 + || + XIMAGE_INSTANCE_DISPLAY_HASH (image) != internal_hash (image, 0)) + return 0; + else + return 1; + } else return 1; }