changeset 20566:3ef40e8de6ab

Fix some crashes with animated smileys. Fixes #3179, #938, #3134, #2872, #1594
author Daniel Atallah <daniel.atallah@gmail.com>
date Thu, 20 Sep 2007 03:05:54 +0000
parents dc08f2fa9a66
children b4a141f9294a
files pidgin/gtkimhtml.c
diffstat 1 files changed, 30 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/pidgin/gtkimhtml.c	Thu Sep 20 02:41:42 2007 +0000
+++ b/pidgin/gtkimhtml.c	Thu Sep 20 03:05:54 2007 +0000
@@ -3211,24 +3211,25 @@
 	im_image = data;
 
 	/* Update the pointer to this GdkPixbuf frame of the animation */
-	g_object_unref(G_OBJECT(im_image->pixbuf));
-	gdk_pixbuf_animation_iter_advance(GTK_IMHTML_ANIMATION(im_image)->iter, NULL);
-	im_image->pixbuf = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter);
-	g_object_ref(G_OBJECT(im_image->pixbuf));
-
-	/* Update the displayed GtkImage */
-	width = gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image));
-	height = gdk_pixbuf_get_height(gtk_image_get_pixbuf(im_image->image));
-	if (width > 0 && height > 0)
-	{
-		/* Need to scale the new frame to the same size as the old frame */
-		GdkPixbuf *tmp;
-		tmp = gdk_pixbuf_scale_simple(im_image->pixbuf, width, height, GDK_INTERP_BILINEAR);
-		gtk_image_set_from_pixbuf(im_image->image, tmp);
-		g_object_unref(G_OBJECT(tmp));
-	} else {
-		/* Display at full-size */
-		gtk_image_set_from_pixbuf(im_image->image, im_image->pixbuf);
+	if (gdk_pixbuf_animation_iter_advance(GTK_IMHTML_ANIMATION(im_image)->iter, NULL)) {
+		GdkPixbuf *pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter);
+		g_object_unref(G_OBJECT(im_image->pixbuf));
+		im_image->pixbuf = gdk_pixbuf_copy(pb);
+
+		/* Update the displayed GtkImage */
+		width = gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image));
+		height = gdk_pixbuf_get_height(gtk_image_get_pixbuf(im_image->image));
+		if (width > 0 && height > 0)
+		{
+			/* Need to scale the new frame to the same size as the old frame */
+			GdkPixbuf *tmp;
+			tmp = gdk_pixbuf_scale_simple(im_image->pixbuf, width, height, GDK_INTERP_BILINEAR);
+			gtk_image_set_from_pixbuf(im_image->image, tmp);
+			g_object_unref(G_OBJECT(tmp));
+		} else {
+			/* Display at full-size */
+			gtk_image_set_from_pixbuf(im_image->image, im_image->pixbuf);
+		}
 	}
 
 	delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100);
@@ -3249,11 +3250,14 @@
 	if (gdk_pixbuf_animation_is_static_image(anim)) {
 		GTK_IMHTML_ANIMATION(im_image)->iter = NULL;
 		im_image->pixbuf = gdk_pixbuf_animation_get_static_image(anim);
+		g_object_ref(im_image->pixbuf);
 		GTK_IMHTML_ANIMATION(im_image)->timer = 0;
 	} else {
 		int delay;
+		GdkPixbuf *pb;
 		GTK_IMHTML_ANIMATION(im_image)->iter = gdk_pixbuf_animation_get_iter(anim, NULL);
-		im_image->pixbuf = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter);
+		pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter);
+		im_image->pixbuf = gdk_pixbuf_copy(pb);
 		delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100);
 		GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image);
 	}
@@ -3266,7 +3270,6 @@
 	im_image->filesel = NULL;
 
 	g_object_ref(anim);
-	g_object_ref(im_image->pixbuf);
 
 	return GTK_IMHTML_SCALABLE(im_image);
 }
@@ -4606,10 +4609,15 @@
 				if (imhtml->num_animations == 20) {
 					GtkImage *image = GTK_IMAGE(g_queue_pop_head(imhtml->animations));
 					GdkPixbufAnimation *anim = gtk_image_get_animation(image);
+					g_signal_handlers_disconnect_matched(G_OBJECT(image), G_SIGNAL_MATCH_FUNC,
+							 0, 0, NULL, G_CALLBACK(animated_smiley_destroy_cb), NULL);
 					if (anim) {
 						GdkPixbuf *pb = gdk_pixbuf_animation_get_static_image(anim);
-						gtk_image_set_from_pixbuf(image, pb);
-						g_object_unref(G_OBJECT(pb));
+						if (pb != NULL) {
+							GdkPixbuf *copy = gdk_pixbuf_copy(pb);
+							gtk_image_set_from_pixbuf(image, copy);
+							g_object_unref(G_OBJECT(copy));
+						}
 					}
 				} else {
  					imhtml->num_animations++;