im.pidgin.pidgin: fd241751ba7c5d47fe66c0b96787eae776d435af

datallah at pidgin.im datallah at pidgin.im
Tue Dec 4 00:20:37 EST 2007


-----------------------------------------------------------------
Revision: fd241751ba7c5d47fe66c0b96787eae776d435af
Ancestor: 368132d2a2702cfb0e6fcf39ee11a35ca0eceba0
Author: datallah at pidgin.im
Date: 2007-12-04T05:15:49
Branch: im.pidgin.pidgin

Modified files:
        pidgin/gtkblist.c

ChangeLog: 

Add rudimentary caching for buddy list emblems. This avoids all the icons being duplicated in memory and constantly loaded.  A more complete solution would be preferable, but I think this is better than nothing.

-------------- next part --------------
============================================================
--- pidgin/gtkblist.c	5007ba7a2fc19838c55d37c086d991c079946d38
+++ pidgin/gtkblist.c	66b62cfbbaa5855822aac42279eda72e89e34bdf
@@ -3371,6 +3371,34 @@ static char *pidgin_get_tooltip_text(Pur
 	return g_string_free(str, FALSE);
 }
 
+static GHashTable *cached_emblems;
+
+static void _cleanup_cached_emblem(gpointer data, GObject *obj) {
+	g_hash_table_remove(cached_emblems, data);
+}
+
+static GdkPixbuf * _pidgin_blist_get_cached_emblem(gchar *path) {
+	GdkPixbuf *pb = g_hash_table_lookup(cached_emblems, path);
+
+	if (pb != NULL) {
+		/* The caller gets a reference */
+		g_object_ref(pb);
+		g_free(path);
+	} else {
+		pb = gdk_pixbuf_new_from_file(path, NULL);
+		if (pb != NULL) {
+			/* We don't want to own a ref to the pixbuf, but we need to keep clean up. */
+			/* I'm not sure if it would be better to just keep our ref and not let the emblem ever be destroyed */
+			g_object_weak_ref(G_OBJECT(pb), _cleanup_cached_emblem, path);
+			g_hash_table_insert(cached_emblems, path, pb);
+		} else
+			g_free(path);
+	}
+
+	return pb;
+}
+
+
 GdkPixbuf *
 pidgin_blist_get_emblem(PurpleBlistNode *node)
 {
@@ -3381,7 +3409,6 @@ pidgin_blist_get_emblem(PurpleBlistNode 
 	PurplePluginProtocolInfo *prpl_info;
 	const char *name = NULL;
 	char *filename, *path;
-	GdkPixbuf *ret;
 	PurplePresence *p;
 
 	if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
@@ -3394,11 +3421,9 @@ pidgin_blist_get_emblem(PurpleBlistNode 
 		gtkbuddynode = node->ui_data;
 		p = purple_buddy_get_presence(buddy);
 		if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) {
-			path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", 
+			path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems",
 						"16", "mobile.png", NULL);
-			ret = gdk_pixbuf_new_from_file(path, NULL);
-			g_free(path);
-			return ret;
+			return _pidgin_blist_get_cached_emblem(path);
 		}
 
 		if (((struct _pidgin_blist_node*)(node->parent->ui_data))->contact_expanded) {
@@ -3410,26 +3435,22 @@ pidgin_blist_get_emblem(PurpleBlistNode 
 		return NULL;
 	}
 
+	g_return_val_if_fail(buddy != NULL, NULL);
+
 	if (!purple_privacy_check(buddy->account, purple_buddy_get_name(buddy))) {
 		path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "blocked.png", NULL);
-		ret = gdk_pixbuf_new_from_file(path, NULL);
-		g_free(path);
-		return ret;
+		return _pidgin_blist_get_cached_emblem(path);
 	}
 
 	p = purple_buddy_get_presence(buddy);
 	if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) {
 		path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "mobile.png", NULL);
-		ret = gdk_pixbuf_new_from_file(path, NULL);
-		g_free(path);
-		return ret;
+		return _pidgin_blist_get_cached_emblem(path);
 	}
 
 	if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_TUNE)) {
 		path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "music.png", NULL);
-		ret = gdk_pixbuf_new_from_file(path, NULL);
-		g_free(path);
-		return ret;
+		return _pidgin_blist_get_cached_emblem(path);
 	}
 
 	prpl = purple_find_prpl(purple_account_get_protocol_id(buddy->account));
@@ -3446,12 +3467,10 @@ pidgin_blist_get_emblem(PurpleBlistNode 
 	filename = g_strdup_printf("%s.png", name);
 
 	path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", filename, NULL);
-	ret = gdk_pixbuf_new_from_file(path, NULL);
-
 	g_free(filename);
-	g_free(path);
 
-	return ret;
+	/* _pidgin_blist_get_cached_emblem() assumes ownership of path */
+	return _pidgin_blist_get_cached_emblem(path);
 }
 
 
@@ -6897,6 +6916,8 @@ void pidgin_blist_init(void)
 {
 	void *gtk_blist_handle = pidgin_blist_get_handle();
 
+	cached_emblems = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+
 	purple_signal_connect(purple_connections_get_handle(), "signed-on",
 						gtk_blist_handle, PURPLE_CALLBACK(account_signon_cb),
 						NULL);
@@ -6948,6 +6969,8 @@ pidgin_blist_uninit(void) {
 
 void
 pidgin_blist_uninit(void) {
+	g_hash_table_destroy(cached_emblems);
+
 	purple_signals_unregister_by_instance(pidgin_blist_get_handle());
 	purple_signals_disconnect_by_handle(pidgin_blist_get_handle());
 }


More information about the Commits mailing list