comparison pidgin/gtkblist.c @ 21756:abd0cd2b712a

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.
author Daniel Atallah <daniel.atallah@gmail.com>
date Tue, 04 Dec 2007 05:15:49 +0000
parents 9c2230fe2217
children 92ae7b2c95ed
comparison
equal deleted inserted replaced
21755:5b0d9e08992d 21756:abd0cd2b712a
3369 "drawing-tooltip", node, str, full); 3369 "drawing-tooltip", node, str, full);
3370 3370
3371 return g_string_free(str, FALSE); 3371 return g_string_free(str, FALSE);
3372 } 3372 }
3373 3373
3374 static GHashTable *cached_emblems;
3375
3376 static void _cleanup_cached_emblem(gpointer data, GObject *obj) {
3377 g_hash_table_remove(cached_emblems, data);
3378 }
3379
3380 static GdkPixbuf * _pidgin_blist_get_cached_emblem(gchar *path) {
3381 GdkPixbuf *pb = g_hash_table_lookup(cached_emblems, path);
3382
3383 if (pb != NULL) {
3384 /* The caller gets a reference */
3385 g_object_ref(pb);
3386 g_free(path);
3387 } else {
3388 pb = gdk_pixbuf_new_from_file(path, NULL);
3389 if (pb != NULL) {
3390 /* We don't want to own a ref to the pixbuf, but we need to keep clean up. */
3391 /* I'm not sure if it would be better to just keep our ref and not let the emblem ever be destroyed */
3392 g_object_weak_ref(G_OBJECT(pb), _cleanup_cached_emblem, path);
3393 g_hash_table_insert(cached_emblems, path, pb);
3394 } else
3395 g_free(path);
3396 }
3397
3398 return pb;
3399 }
3400
3401
3374 GdkPixbuf * 3402 GdkPixbuf *
3375 pidgin_blist_get_emblem(PurpleBlistNode *node) 3403 pidgin_blist_get_emblem(PurpleBlistNode *node)
3376 { 3404 {
3377 PurpleBuddy *buddy = NULL; 3405 PurpleBuddy *buddy = NULL;
3378 struct _pidgin_blist_node *gtknode = node->ui_data; 3406 struct _pidgin_blist_node *gtknode = node->ui_data;
3379 struct _pidgin_blist_node *gtkbuddynode = NULL; 3407 struct _pidgin_blist_node *gtkbuddynode = NULL;
3380 PurplePlugin *prpl; 3408 PurplePlugin *prpl;
3381 PurplePluginProtocolInfo *prpl_info; 3409 PurplePluginProtocolInfo *prpl_info;
3382 const char *name = NULL; 3410 const char *name = NULL;
3383 char *filename, *path; 3411 char *filename, *path;
3384 GdkPixbuf *ret;
3385 PurplePresence *p; 3412 PurplePresence *p;
3386 3413
3387 if(PURPLE_BLIST_NODE_IS_CONTACT(node)) { 3414 if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
3388 if(!gtknode->contact_expanded) { 3415 if(!gtknode->contact_expanded) {
3389 buddy = purple_contact_get_priority_buddy((PurpleContact*)node); 3416 buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
3392 } else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) { 3419 } else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
3393 buddy = (PurpleBuddy*)node; 3420 buddy = (PurpleBuddy*)node;
3394 gtkbuddynode = node->ui_data; 3421 gtkbuddynode = node->ui_data;
3395 p = purple_buddy_get_presence(buddy); 3422 p = purple_buddy_get_presence(buddy);
3396 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) { 3423 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) {
3397 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", 3424 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems",
3398 "16", "mobile.png", NULL); 3425 "16", "mobile.png", NULL);
3399 ret = gdk_pixbuf_new_from_file(path, NULL); 3426 return _pidgin_blist_get_cached_emblem(path);
3400 g_free(path);
3401 return ret;
3402 } 3427 }
3403 3428
3404 if (((struct _pidgin_blist_node*)(node->parent->ui_data))->contact_expanded) { 3429 if (((struct _pidgin_blist_node*)(node->parent->ui_data))->contact_expanded) {
3405 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons")) 3430 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"))
3406 return NULL; 3431 return NULL;
3408 } 3433 }
3409 } else { 3434 } else {
3410 return NULL; 3435 return NULL;
3411 } 3436 }
3412 3437
3438 g_return_val_if_fail(buddy != NULL, NULL);
3439
3413 if (!purple_privacy_check(buddy->account, purple_buddy_get_name(buddy))) { 3440 if (!purple_privacy_check(buddy->account, purple_buddy_get_name(buddy))) {
3414 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "blocked.png", NULL); 3441 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "blocked.png", NULL);
3415 ret = gdk_pixbuf_new_from_file(path, NULL); 3442 return _pidgin_blist_get_cached_emblem(path);
3416 g_free(path);
3417 return ret;
3418 } 3443 }
3419 3444
3420 p = purple_buddy_get_presence(buddy); 3445 p = purple_buddy_get_presence(buddy);
3421 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) { 3446 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) {
3422 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "mobile.png", NULL); 3447 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "mobile.png", NULL);
3423 ret = gdk_pixbuf_new_from_file(path, NULL); 3448 return _pidgin_blist_get_cached_emblem(path);
3424 g_free(path);
3425 return ret;
3426 } 3449 }
3427 3450
3428 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_TUNE)) { 3451 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_TUNE)) {
3429 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "music.png", NULL); 3452 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "music.png", NULL);
3430 ret = gdk_pixbuf_new_from_file(path, NULL); 3453 return _pidgin_blist_get_cached_emblem(path);
3431 g_free(path);
3432 return ret;
3433 } 3454 }
3434 3455
3435 prpl = purple_find_prpl(purple_account_get_protocol_id(buddy->account)); 3456 prpl = purple_find_prpl(purple_account_get_protocol_id(buddy->account));
3436 if (!prpl) 3457 if (!prpl)
3437 return NULL; 3458 return NULL;
3444 return NULL; 3465 return NULL;
3445 3466
3446 filename = g_strdup_printf("%s.png", name); 3467 filename = g_strdup_printf("%s.png", name);
3447 3468
3448 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", filename, NULL); 3469 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", filename, NULL);
3449 ret = gdk_pixbuf_new_from_file(path, NULL);
3450
3451 g_free(filename); 3470 g_free(filename);
3452 g_free(path); 3471
3453 3472 /* _pidgin_blist_get_cached_emblem() assumes ownership of path */
3454 return ret; 3473 return _pidgin_blist_get_cached_emblem(path);
3455 } 3474 }
3456 3475
3457 3476
3458 GdkPixbuf * 3477 GdkPixbuf *
3459 pidgin_blist_get_status_icon(PurpleBlistNode *node, PidginStatusIconSize size) 3478 pidgin_blist_get_status_icon(PurpleBlistNode *node, PidginStatusIconSize size)
6895 6914
6896 void pidgin_blist_init(void) 6915 void pidgin_blist_init(void)
6897 { 6916 {
6898 void *gtk_blist_handle = pidgin_blist_get_handle(); 6917 void *gtk_blist_handle = pidgin_blist_get_handle();
6899 6918
6919 cached_emblems = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
6920
6900 purple_signal_connect(purple_connections_get_handle(), "signed-on", 6921 purple_signal_connect(purple_connections_get_handle(), "signed-on",
6901 gtk_blist_handle, PURPLE_CALLBACK(account_signon_cb), 6922 gtk_blist_handle, PURPLE_CALLBACK(account_signon_cb),
6902 NULL); 6923 NULL);
6903 6924
6904 /* Initialize prefs */ 6925 /* Initialize prefs */
6946 purple_signal_connect(purple_blist_get_handle(), "buddy-privacy-changed", gtk_blist_handle, PURPLE_CALLBACK(pidgin_blist_update_privacy_cb), NULL); 6967 purple_signal_connect(purple_blist_get_handle(), "buddy-privacy-changed", gtk_blist_handle, PURPLE_CALLBACK(pidgin_blist_update_privacy_cb), NULL);
6947 } 6968 }
6948 6969
6949 void 6970 void
6950 pidgin_blist_uninit(void) { 6971 pidgin_blist_uninit(void) {
6972 g_hash_table_destroy(cached_emblems);
6973
6951 purple_signals_unregister_by_instance(pidgin_blist_get_handle()); 6974 purple_signals_unregister_by_instance(pidgin_blist_get_handle());
6952 purple_signals_disconnect_by_handle(pidgin_blist_get_handle()); 6975 purple_signals_disconnect_by_handle(pidgin_blist_get_handle());
6953 } 6976 }
6954 6977
6955 /********************************************************************* 6978 /*********************************************************************