Mercurial > pidgin
diff src/buddyicon.c @ 6846:8ab95f4c9800
[gaim-migrate @ 7391]
Added new buddy icon caching code. Each GaimBuddy has its own icon, and the
complete list of all icons is now stored in a set of hashtables for quick
retrieval. Buddy icons now live much happier in the core, with the magma
and tooth fairies (that's where they really live).
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Mon, 15 Sep 2003 07:35:49 +0000 |
parents | |
children | b5fb1d5282e5 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/buddyicon.c Mon Sep 15 07:35:49 2003 +0000 @@ -0,0 +1,272 @@ +/** + * @file icon.c Buddy Icon API + * @ingroup core + * + * gaim + * + * Copyright (C) 2003 Christian Hammond <chipx86@gnupdate.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "internal.h" +#include "buddyicon.h" +#include "conversation.h" + +static GHashTable *account_cache = NULL; + +GaimBuddyIcon * +gaim_buddy_icon_new(GaimAccount *account, const char *username, + void *icon_data, size_t icon_len) +{ + GaimBuddyIcon *icon; + + g_return_val_if_fail(account != NULL, NULL); + g_return_val_if_fail(username != NULL, NULL); + g_return_val_if_fail(icon_data != NULL, NULL); + g_return_val_if_fail(icon_len > 0, NULL); + + icon = gaim_buddy_icons_find(account, username); + + if (icon == NULL) + { + GHashTable *icon_cache; + + icon = g_new0(GaimBuddyIcon, 1); + + gaim_buddy_icon_set_account(icon, account); + gaim_buddy_icon_set_username(icon, username); + + icon_cache = g_hash_table_lookup(account_cache, account); + + if (icon_cache == NULL) + { + icon_cache = g_hash_table_new(g_str_hash, g_str_equal); + + g_hash_table_insert(account_cache, account, icon_cache); + } + + g_hash_table_insert(icon_cache, + (char *)gaim_buddy_icon_get_username(icon), icon); + } + + gaim_buddy_icon_set_data(icon, icon_data, icon_len); + + gaim_buddy_icon_ref(icon); + + return icon; +} + +void +gaim_buddy_icon_destroy(GaimBuddyIcon *icon) +{ + GHashTable *icon_cache; + + g_return_if_fail(icon != NULL); + + if (icon->ref_count > 0) + { + gaim_buddy_icon_unref(icon); + + return; + } + + icon_cache = g_hash_table_lookup(account_cache, + gaim_buddy_icon_get_account(icon)); + + if (icon_cache != NULL) + g_hash_table_remove(icon_cache, gaim_buddy_icon_get_username(icon)); + + if (icon->username != NULL) + g_free(icon->username); + + if (icon->data != NULL) + g_free(icon->data); + + g_free(icon); +} + +GaimBuddyIcon * +gaim_buddy_icon_ref(GaimBuddyIcon *icon) +{ + g_return_val_if_fail(icon != NULL, NULL); + + icon->ref_count++; + + return icon; +} + +GaimBuddyIcon * +gaim_buddy_icon_unref(GaimBuddyIcon *icon) +{ + g_return_val_if_fail(icon != NULL, NULL); + + if (icon->ref_count <= 0) + return NULL; + + icon->ref_count--; + + if (icon->ref_count == 0) + { + gaim_buddy_icon_destroy(icon); + + return NULL; + } + + return icon; +} + +void +gaim_buddy_icon_update(GaimBuddyIcon *icon) +{ + GaimConversation *conv; + GaimAccount *account; + const char *username; + GSList *sl; + + g_return_if_fail(icon != NULL); + + account = gaim_buddy_icon_get_account(icon); + username = gaim_buddy_icon_get_username(icon); + + for (sl = gaim_find_buddies(account, username); sl != NULL; sl = sl->next) + { + GaimBuddy *buddy = (GaimBuddy *)sl->data; + + gaim_buddy_set_icon(buddy, icon); + } + + conv = gaim_find_conversation_with_account(username, account); + + if (conv != NULL && gaim_conversation_get_type(conv) == GAIM_CONV_IM) + gaim_im_set_icon(GAIM_IM(conv), icon); +} + +void +gaim_buddy_icon_set_account(GaimBuddyIcon *icon, GaimAccount *account) +{ + g_return_if_fail(icon != NULL); + g_return_if_fail(account != NULL); + + icon->account = account; +} + +void +gaim_buddy_icon_set_username(GaimBuddyIcon *icon, const char *username) +{ + g_return_if_fail(icon != NULL); + g_return_if_fail(username != NULL); + + if (icon->username != NULL) + g_free(icon->username); + + icon->username = g_strdup(username); +} + +void +gaim_buddy_icon_set_data(GaimBuddyIcon *icon, void *data, size_t len) +{ + g_return_if_fail(icon != NULL); + + if (icon->data != NULL) + g_free(icon->data); + + if (data != NULL && len > 0) + { + icon->data = g_memdup(data, len); + icon->len = len; + } + else + { + icon->data = NULL; + icon->len = 0; + } + + gaim_buddy_icon_update(icon); +} + +GaimAccount * +gaim_buddy_icon_get_account(const GaimBuddyIcon *icon) +{ + g_return_val_if_fail(icon != NULL, NULL); + + return icon->account; +} + +const char * +gaim_buddy_icon_get_username(const GaimBuddyIcon *icon) +{ + g_return_val_if_fail(icon != NULL, NULL); + + return icon->username; +} + +const void * +gaim_buddy_icon_get_data(const GaimBuddyIcon *icon, size_t *len) +{ + g_return_val_if_fail(icon != NULL, NULL); + + if (len != NULL) + *len = icon->len; + + return icon->data; +} + +void +gaim_buddy_icons_set_for_user(GaimAccount *account, const char *username, + void *icon_data, size_t icon_len) +{ + g_return_if_fail(account != NULL); + g_return_if_fail(username != NULL); + + gaim_buddy_icon_new(account, username, icon_data, icon_len); +} + +GaimBuddyIcon * +gaim_buddy_icons_find(const GaimAccount *account, const char *username) +{ + GHashTable *icon_cache; + + g_return_val_if_fail(account != NULL, NULL); + g_return_val_if_fail(username != NULL, NULL); + + icon_cache = g_hash_table_lookup(account_cache, account); + + if (icon_cache == NULL) + return NULL; + + return g_hash_table_lookup(icon_cache, username); +} + +void * +gaim_buddy_icons_get_handle() +{ + static int handle; + + return &handle; +} + +void +gaim_buddy_icons_init() +{ + account_cache = g_hash_table_new_full( + g_direct_hash, g_direct_equal, + NULL, (GFreeFunc)g_hash_table_destroy); +} + +void +gaim_buddy_icons_uninit() +{ + g_hash_table_destroy(account_cache); +}