# HG changeset patch # User Kevin Stange # Date 1196747279 0 # Node ID 6360da6f3cc1cce9dd2e2e4ccf4f3224c45f75d0 # Parent 4308279228283eb31b6b8cd56f3f500524898fd5# Parent abd0cd2b712a736dba3cf96f15c7dfd9ad6e230d merge of '65fe5060e09daeac78c60bf74d157d7c2330ea74' and 'fd241751ba7c5d47fe66c0b96787eae776d435af' diff -r 430827922828 -r 6360da6f3cc1 pidgin/gtkblist.c --- a/pidgin/gtkblist.c Tue Dec 04 05:43:15 2007 +0000 +++ b/pidgin/gtkblist.c Tue Dec 04 05:47:59 2007 +0000 @@ -3371,6 +3371,34 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 *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 @@ 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()); } diff -r 430827922828 -r 6360da6f3cc1 pidgin/gtkutils.c --- a/pidgin/gtkutils.c Tue Dec 04 05:43:15 2007 +0000 +++ b/pidgin/gtkutils.c Tue Dec 04 05:47:59 2007 +0000 @@ -2451,7 +2451,13 @@ g_signal_connect(G_OBJECT(dialog->icon_filesel), "destroy", G_CALLBACK(icon_filesel_delete_cb), dialog); #endif /* FILECHOOSER */ - return dialog->icon_filesel; + +#ifdef _WIN32 + g_signal_connect(G_OBJECT(dialog->icon_filesel), "show", + G_CALLBACK(winpidgin_ensure_onscreen), dialog->icon_filesel); +#endif + + return dialog->icon_filesel; }