Mercurial > pidgin
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 /********************************************************************* |