Mercurial > pidgin.yaz
changeset 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 | 5de4d9a4e0e2 |
children | 7de1b559cbbb |
files | src/Makefile.am src/blist.c src/blist.h src/buddyicon.c src/buddyicon.h src/conversation.c src/conversation.h src/core.c src/dialogs.c src/gtkconv.c src/gtkutils.c src/protocols/oscar/oscar.c src/prpl.c src/prpl.h |
diffstat | 14 files changed, 668 insertions(+), 207 deletions(-) [+] |
line wrap: on
line diff
--- a/src/Makefile.am Mon Sep 15 02:23:58 2003 +0000 +++ b/src/Makefile.am Mon Sep 15 07:35:49 2003 +0000 @@ -52,6 +52,8 @@ accountopt.h \ blist.c \ blist.h \ + buddyicon.c \ + buddyicon.h \ connection.c \ connection.h \ conversation.c \
--- a/src/blist.c Mon Sep 15 02:23:58 2003 +0000 +++ b/src/blist.c Mon Sep 15 07:35:49 2003 +0000 @@ -37,6 +37,7 @@ struct gaim_buddy_list *gaimbuddylist = NULL; static struct gaim_blist_ui_ops *blist_ui_ops = NULL; + /***************************************************************************** * Private Utility functions * *****************************************************************************/ @@ -494,6 +495,84 @@ return b; } +static void +write_buddy_icon(GaimBuddy *buddy, GaimBuddyIcon *icon) +{ + const void *data; + size_t len; + char *random; + char *filename; + char *dirname; + char *old_icon; + FILE *file = NULL; + + data = gaim_buddy_icon_get_data(icon, &len); + + random = g_strdup_printf("%x", g_random_int()); + filename = g_build_filename(gaim_user_dir(), "icons", random, NULL); + dirname = g_build_filename(gaim_user_dir(), "icons", NULL); + old_icon = gaim_buddy_get_setting(buddy, "buddy_icon"); + + g_free(random); + + if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) + { + gaim_debug_info("buddy icons", "Creating icon cache directory.\n"); + + if (mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0) + { + gaim_debug_error("buddy icons", + "Unable to create directory %s: %s\n", + dirname, strerror(errno)); + } + } + + g_free(dirname); + + if ((file = fopen(filename, "wb")) != NULL) + { + fwrite(data, 1, len, file); + fclose(file); + } + + if (old_icon != NULL) + { + unlink(old_icon); + g_free(old_icon); + } + + gaim_buddy_set_setting(buddy, "buddy_icon", filename); + gaim_blist_save(); + + g_free(filename); +} + +void +gaim_buddy_set_icon(GaimBuddy *buddy, GaimBuddyIcon *icon) +{ + g_return_if_fail(buddy != NULL); + + if (buddy->icon == icon) + return; + + if (buddy->icon != NULL) + gaim_buddy_icon_unref(buddy->icon); + + buddy->icon = (icon == NULL ? NULL : gaim_buddy_icon_ref(icon)); + + write_buddy_icon(buddy, icon); + + gaim_blist_update_buddy_icon(buddy); +} + +GaimBuddyIcon * +gaim_buddy_get_icon(const GaimBuddy *buddy) +{ + g_return_val_if_fail(buddy != NULL, NULL); + + return buddy->icon; +} + void gaim_blist_add_chat(GaimBlistChat *chat, GaimGroup *group, GaimBlistNode *node) { GaimBlistNode *n = node, *cnode = (GaimBlistNode*)chat; @@ -977,6 +1056,9 @@ if(buddy->timer > 0) g_source_remove(buddy->timer); + if (buddy->icon != NULL) + gaim_buddy_icon_unref(buddy->icon); + ops->remove(gaimbuddylist, node); g_hash_table_destroy(buddy->settings); g_free(buddy->name);
--- a/src/blist.h Mon Sep 15 02:23:58 2003 +0000 +++ b/src/blist.h Mon Sep 15 07:35:49 2003 +0000 @@ -36,6 +36,7 @@ typedef struct _GaimBuddy GaimBuddy; #include "account.h" +#include "buddyicon.h" /**************************************************************************/ /* Enumerations */ @@ -96,6 +97,7 @@ int idle; /**< The time the buddy has been idle in minutes. */ int uc; /**< This is a cryptic bitmask that makes sense only to the prpl. This will get changed */ void *proto_data; /**< This allows the prpl to associate whatever data it wants with a buddy */ + GaimBuddyIcon *icon; /**< The buddy icon. */ GaimAccount *account; /**< the account this buddy belongs to */ GHashTable *settings; /**< per-buddy settings from the XML buddy list, set by plugins and the likes. */ guint timer; /**< The timer handle. */ @@ -262,8 +264,6 @@ */ void gaim_blist_update_buddy_icon(GaimBuddy *buddy); - - /** * Renames a buddy in the buddy list. * @@ -347,6 +347,28 @@ GaimBuddy *gaim_buddy_new(GaimAccount *account, const char *screenname, const char *alias); /** + * Sets a buddy's icon. + * + * This should only be called from within Gaim. You probably want to + * call gaim_buddy_icon_set_data(). + * + * @param buddy The buddy. + * @param icon The buddy icon. + * + * @see gaim_buddy_icon_set_data() + */ +void gaim_buddy_set_icon(GaimBuddy *buddy, GaimBuddyIcon *icon); + +/** + * Returns a buddy's icon. + * + * @param buddy The buddy. + * + * @return The buddy icon. + */ +GaimBuddyIcon *gaim_buddy_get_icon(const GaimBuddy *buddy); + +/** * Adds a new buddy to the buddy list. * * The buddy will be inserted right after node or prepended to the
--- /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); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/buddyicon.h Mon Sep 15 07:35:49 2003 +0000 @@ -0,0 +1,197 @@ +/** + * @file icon.h 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 + */ +#ifndef _GAIM_ICON_H_ +#define _GAIM_ICON_H_ + +typedef struct _GaimBuddyIcon GaimBuddyIcon; + +#include "account.h" + +struct _GaimBuddyIcon +{ + GaimAccount *account; /**< The account the user is on. */ + char *username; /**< The username the icon belongs to. */ + + void *data; /**< The buddy icon data. */ + size_t len; /**< The length of the buddy icon data. */ + + int ref_count; /**< The buddy icon reference count. */ +}; + +/**************************************************************************/ +/** @name Buddy Icon API */ +/**************************************************************************/ +/*@{*/ + +/** + * Creates a new buddy icon structure. + * + * @param account The account the user is on. + * @param username The username the icon belongs to. + * @param icon_data The buddy icon data. + * @param icon_len The buddy icon length. + * + * @return The buddy icon structure. + */ +GaimBuddyIcon *gaim_buddy_icon_new(GaimAccount *account, const char *username, + void *icon_data, size_t icon_len); + +/** + * Destroys a buddy icon structure. + * + * If the buddy icon's reference count is greater than 1, this will + * just decrease the reference count and return. + * + * @param icon The buddy icon structure to destroy. + */ +void gaim_buddy_icon_destroy(GaimBuddyIcon *icon); + +/** + * Increments the reference count on a buddy icon. + * + * @param icon The buddy icon. + * + * @return @a icon. + */ +GaimBuddyIcon *gaim_buddy_icon_ref(GaimBuddyIcon *icon); + +/** + * Decrements the reference count on a buddy icon. + * + * If the reference count reaches 0, the icon will be destroyed. + * + * @param icon The buddy icon. + * + * @return @a icon, or @c NULL if the reference count reached 0. + */ +GaimBuddyIcon *gaim_buddy_icon_unref(GaimBuddyIcon *icon); + +/** + * Updates every instance of this icon. + * + * @param icon The buddy icon. + */ +void gaim_buddy_icon_update(GaimBuddyIcon *icon); + +/** + * Sets the buddy icon's account. + * + * @param icon The buddy icon. + * @param account The account. + */ +void gaim_buddy_icon_set_account(GaimBuddyIcon *icon, GaimAccount *account); + +/** + * Sets the buddy icon's username. + * + * @param icon The buddy icon. + * @param username The username. + */ +void gaim_buddy_icon_set_username(GaimBuddyIcon *icon, const char *username); + +/** + * Sets the buddy icon's icon data. + * + * @param icon The buddy icon. + * @param data The buddy icon data. + * @param len The length of the icon data. + */ +void gaim_buddy_icon_set_data(GaimBuddyIcon *icon, void *data, size_t len); + +/** + * Returns the buddy icon's account. + * + * @param icon The buddy icon. + * + * @return The account. + */ +GaimAccount *gaim_buddy_icon_get_account(const GaimBuddyIcon *icon); + +/** + * Returns the buddy icon's username. + * + * @param icon The buddy icon. + * + * @return The username. + */ +const char *gaim_buddy_icon_get_username(const GaimBuddyIcon *icon); + +/** + * Returns the buddy icon's data. + * + * @param icon The buddy icon. + * @param len The returned icon length. + * + * @return The icon data. + */ +const void *gaim_buddy_icon_get_data(const GaimBuddyIcon *icon, size_t *len); + +/*@}*/ + +/**************************************************************************/ +/** @name Buddy Icon Subsystem API */ +/**************************************************************************/ +/*@{*/ + +/** + * Sets a buddy icon for a user. + * + * @param account The account the user is on. + * @param username The username of the user. + * @param icon_data The icon data. + * @param icon_len The length of the icon data. + */ +void gaim_buddy_icons_set_for_user(GaimAccount *account, const char *username, + void *icon_data, size_t icon_len); + +/** + * Returns the buddy icon information for a user. + * + * @param account The account the user is on. + * @param username The username of the user. + * + * @return The icon data if found, or @c NULL if not found. + */ +GaimBuddyIcon *gaim_buddy_icons_find(const GaimAccount *account, + const char *username); + +/** + * Returns the buddy icon subsystem handle. + * + * @return The subsystem handle. + */ +void *gaim_buddy_icons_get_handle(); + +/** + * Initializes the buddy icon subsystem. + */ +void gaim_buddy_icons_init(); + +/** + * Uninitializes the buddy icon subsystem. + */ +void gaim_buddy_icons_uninit(); + +/*@}*/ + +#endif /* _GAIM_ICON_H_ */
--- a/src/conversation.c Mon Sep 15 02:23:58 2003 +0000 +++ b/src/conversation.c Mon Sep 15 07:35:49 2003 +0000 @@ -980,7 +980,7 @@ gc = gaim_conversation_get_gc(conv); name = gaim_conversation_get_name(conv); - if (gc) { + if (gc != NULL) { /* Still connected */ prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); @@ -1052,6 +1052,9 @@ g_slist_free(conv->u.im->images); + if (conv->u.im->icon != NULL) + gaim_buddy_icon_unref(conv->u.im->icon); + g_free(conv->u.im); ims = g_list_remove(ims, conv); @@ -1573,6 +1576,31 @@ } void +gaim_im_set_icon(GaimIm *im, GaimBuddyIcon *icon) +{ + g_return_if_fail(im != NULL); + + if (im->icon == icon) + return; + + if (im->icon != NULL) + gaim_buddy_icon_unref(im->icon); + + im->icon = (icon == NULL ? NULL : gaim_buddy_icon_ref(icon)); + + gaim_conversation_update(gaim_im_get_conversation(im), + GAIM_CONV_UPDATE_ICON); +} + +GaimBuddyIcon * +gaim_im_get_icon(const GaimIm *im) +{ + g_return_val_if_fail(im != NULL, NULL); + + return im->icon; +} + +void gaim_im_set_typing_state(GaimIm *im, int state) { g_return_if_fail(im != NULL); @@ -2587,7 +2615,9 @@ { void *handle = gaim_conversations_get_handle(); - /* Register preferences */ + /********************************************************************** + * Register preferences + **********************************************************************/ /* Conversations */ gaim_prefs_add_none("/core/conversations"); @@ -2617,7 +2647,9 @@ update_titles_pref_cb, NULL); - /* Register signals */ + /********************************************************************** + * Register signals + **********************************************************************/ gaim_signal_register(handle, "displaying-im-msg", gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER, gaim_value_new(GAIM_TYPE_BOOLEAN), 3,
--- a/src/conversation.h Mon Sep 15 02:23:58 2003 +0000 +++ b/src/conversation.h Mon Sep 15 07:35:49 2003 +0000 @@ -82,7 +82,8 @@ */ GAIM_CONV_ACCOUNT_ONLINE, /**< One of the user's accounts went online. */ GAIM_CONV_ACCOUNT_OFFLINE, /**< One of the user's accounts went offline. */ - GAIM_CONV_UPDATE_AWAY /**< The other user went away. */ + GAIM_CONV_UPDATE_AWAY, /**< The other user went away. */ + GAIM_CONV_UPDATE_ICON /**< The other user's buddy icon changed. */ } GaimConvUpdateType; @@ -110,9 +111,11 @@ GAIM_MESSAGE_NICK = 0x0020, /**< Contains your nick. */ GAIM_MESSAGE_NO_LOG = 0x0040, /**< Do not log. */ GAIM_MESSAGE_WHISPER = 0x0080 /**< Whispered message. */ + } GaimMessageFlags; #include "account.h" +#include "buddyicon.h" #include "server.h" /** @@ -198,6 +201,8 @@ guint type_again_timeout; /**< The type again timer handle. */ GSList *images; /**< A list of images in the IM. */ + + GaimBuddyIcon *icon; /**< The buddy icon. */ }; /** @@ -804,6 +809,28 @@ GaimConversation *gaim_im_get_conversation(const GaimIm *im); /** + * Sets the IM's buddy icon. + * + * This should only be called from within Gaim. You probably want to + * call gaim_buddy_icon_set_data(). + * + * @param im The IM. + * @param icon The buddy icon. + * + * @see gaim_buddy_icon_set_data() + */ +void gaim_im_set_icon(GaimIm *im, GaimBuddyIcon *icon); + +/** + * Returns the IM's buddy icon. + * + * @param im The IM. + * + * @return The buddy icon. + */ +GaimBuddyIcon *gaim_im_get_icon(const GaimIm *im); + +/** * Sets the IM's typing state. * * @param im The IM.
--- a/src/core.c Mon Sep 15 02:23:58 2003 +0000 +++ b/src/core.c Mon Sep 15 07:35:49 2003 +0000 @@ -84,6 +84,7 @@ gaim_connections_init(); gaim_conversations_init(); gaim_blist_init(); + gaim_buddy_icons_init(); gaim_privacy_init(); gaim_pounces_init(); gaim_proxy_init(); @@ -128,6 +129,7 @@ gaim_blist_uninit(); gaim_conversations_uninit(); gaim_connections_uninit(); + gaim_buddy_icons_uninit(); gaim_accounts_uninit(); gaim_signals_uninit();
--- a/src/dialogs.c Mon Sep 15 02:23:58 2003 +0000 +++ b/src/dialogs.c Mon Sep 15 07:35:49 2003 +0000 @@ -832,9 +832,6 @@ GaimConversation *c; GaimBuddy *b; GaimGroup *g; - void *icon_data; - void *icon_data2; - int icon_len; if (resp == GTK_RESPONSE_OK) { @@ -852,15 +849,7 @@ serv_add_buddy(a->gc, who, g); if (c != NULL) - gaim_conversation_update(c, GAIM_CONV_UPDATE_ADD); - - icon_data = get_icon_data(a->gc, normalize(who), &icon_len); - - if(icon_data) { - icon_data2 = g_memdup(icon_data, icon_len); - set_icon_data(a->gc, who, icon_data2, icon_len); - g_free(icon_data2); - } + gaim_buddy_icon_update(gaim_im_get_icon(GAIM_IM(c))); gaim_blist_save(); }
--- a/src/gtkconv.c Mon Sep 15 02:23:58 2003 +0000 +++ b/src/gtkconv.c Mon Sep 15 07:35:49 2003 +0000 @@ -5019,11 +5019,15 @@ if (gaim_prefs_get_bool("/gaim/gtk/conversations/icons_on_tabs")) update_tab_icon(conv); } - else if(type == GAIM_CONV_UPDATE_ADD || - type == GAIM_CONV_UPDATE_REMOVE) { + else if (type == GAIM_CONV_UPDATE_ADD || + type == GAIM_CONV_UPDATE_REMOVE) { update_convo_add_button(conv); } + else if (type == GAIM_CONV_UPDATE_ICON) + { + gaim_gtkconv_update_buddy_icon(conv); + } } static GaimConversationUiOps conversation_ui_ops = @@ -5226,8 +5230,9 @@ GaimBuddy *buddy; - void *data; - int len, delay; + const void *data; + size_t len; + int delay; GdkPixbuf *buf; @@ -5265,10 +5270,12 @@ gtkconv->u.im->anim = gdk_pixbuf_animation_new_from_file(file, &err); g_free(file); } - } else { - data = get_icon_data(gaim_conversation_get_gc(conv), - normalize(gaim_conversation_get_name(conv)), - &len); + } + else + { + GaimBuddyIcon *icon = gaim_im_get_icon(GAIM_IM(conv)); + + data = gaim_buddy_icon_get_data(icon, &len); if (!data) return;
--- a/src/gtkutils.c Mon Sep 15 02:23:58 2003 +0000 +++ b/src/gtkutils.c Mon Sep 15 07:35:49 2003 +0000 @@ -266,7 +266,7 @@ GaimGtkConversation *gtkconv; FILE *file; const char *f; - + gtkconv = GAIM_GTK_CONVERSATION(c); f = gtk_file_selection_get_filename( @@ -276,10 +276,9 @@ return; if ((file = fopen(f, "w")) != NULL) { - int len; - void *data = get_icon_data(gaim_conversation_get_gc(c), - normalize(gaim_conversation_get_name(c)), - &len); + GaimBuddyIcon *icon = gaim_im_get_icon(GAIM_IM(c)); + size_t len; + const void *data = gaim_buddy_icon_get_data(icon, &len); if (data) fwrite(data, 1, len, file);
--- a/src/protocols/oscar/oscar.c Mon Sep 15 02:23:58 2003 +0000 +++ b/src/protocols/oscar/oscar.c Mon Sep 15 07:35:49 2003 +0000 @@ -28,6 +28,7 @@ #include "account.h" #include "accountopt.h" +#include "buddyicon.h" #include "conversation.h" #include "debug.h" #include "ft.h" @@ -2387,8 +2388,9 @@ } else if (args->reqclass & AIM_CAPS_GETFILE) { } else if (args->reqclass & AIM_CAPS_VOICE) { } else if (args->reqclass & AIM_CAPS_BUDDYICON) { - set_icon_data(gc, userinfo->sn, args->info.icon.icon, - args->info.icon.length); + gaim_buddy_icons_set_for_user(gaim_connection_get_account(gc), + userinfo->sn, args->info.icon.icon, + args->info.icon.length); } else if (args->reqclass & AIM_CAPS_IMIMAGE) { struct ask_direct *d = g_new0(struct ask_direct, 1); char buf[256]; @@ -3512,7 +3514,8 @@ if (iconlen > 0) { char *b16; GaimBuddy *b = gaim_find_buddy(gc->account, sn); - set_icon_data(gc, sn, icon, iconlen); + gaim_buddy_icons_set_for_user(gaim_connection_get_account(gc), + sn, icon, iconlen); b16 = tobase16(iconcsum, iconcsumlen); if (b16) { gaim_buddy_set_setting(b, "icon_checksum", b16);
--- a/src/prpl.c Mon Sep 15 02:23:58 2003 +0000 +++ b/src/prpl.c Mon Sep 15 07:35:49 2003 +0000 @@ -102,158 +102,6 @@ return NULL; } -struct icon_data { - GaimConnection *gc; - char *who; - void *data; - int len; -}; - -static GList *icons = NULL; - -static gint find_icon_data(gconstpointer a, gconstpointer b) -{ - const struct icon_data *x = a; - const struct icon_data *y = b; - - return ((x->gc != y->gc) || gaim_utf8_strcasecmp(x->who, y->who)); -} - -void set_icon_data(GaimConnection *gc, const char *who, void *data, int len) -{ - GaimConversation *conv; - struct icon_data tmp; - GList *l; - struct icon_data *id; - GaimBuddy *b; - /* i'm going to vent here a little bit about normalize(). normalize() - * uses a static buffer, so when we call functions that use normalize() from - * functions that use normalize(), whose parameters are the result of running - * normalize(), bad things happen. To prevent some of this, we're going - * to make a copy of what we get from normalize(), so we know nothing else - * touches it, and buddy icons don't go to the wrong person. Some day I - * will kill normalize(), and dance on its grave. That will be a very happy - * day for everyone. - * --ndw - */ - char *realwho = g_strdup(normalize(who)); - tmp.gc = gc; - tmp.who = realwho; - tmp.data=NULL; - tmp.len = 0; - l = g_list_find_custom(icons, &tmp, find_icon_data); - id = l ? l->data : NULL; - - if (id) { - g_free(id->data); - if (!data) { - icons = g_list_remove(icons, id); - g_free(id->who); - g_free(id); - g_free(realwho); - return; - } - } else if (data) { - id = g_new0(struct icon_data, 1); - icons = g_list_append(icons, id); - id->gc = gc; - id->who = g_strdup(realwho); - } else { - g_free(realwho); - return; - } - - gaim_debug(GAIM_DEBUG_MISC, "prpl", "Got icon for %s (length %d)\n", - realwho, len); - - id->data = g_memdup(data, len); - id->len = len; - - /* Update the buddy icon for this user. */ - conv = gaim_find_conversation_with_account(realwho, gc->account); - - /* XXX Buddy Icon should probalby be part of struct buddy instead of this weird global - * linked list stuff. */ - - if ((b = gaim_find_buddy(gc->account, realwho)) != NULL) { - char *random = g_strdup_printf("%x", g_random_int()); - char *filename = g_build_filename(gaim_user_dir(), "icons", random, - NULL); - char *dirname = g_build_filename(gaim_user_dir(), "icons", NULL); - char *old_icon = gaim_buddy_get_setting(b, "buddy_icon"); - FILE *file = NULL; - - g_free(random); - - if(!g_file_test(dirname, G_FILE_TEST_IS_DIR)) { - gaim_debug(GAIM_DEBUG_INFO, "buddy icons", - "Creating icon cache directory.\n"); - - if(mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0) - gaim_debug(GAIM_DEBUG_ERROR, "buddy icons", - "Unable to create directory %s: %s\n", - dirname, strerror(errno)); - } - - g_free(dirname); - - file = fopen(filename, "wb"); - if (file) { - fwrite(data, 1, len, file); - fclose(file); - } - - if(old_icon) { - unlink(old_icon); - g_free(old_icon); - } - - gaim_buddy_set_setting(b, "buddy_icon", filename); - gaim_blist_save(); - - g_free(filename); - - gaim_blist_update_buddy_icon(b); - } - - if (conv != NULL && gaim_conversation_get_gc(conv) == gc) - gaim_gtkconv_update_buddy_icon(conv); - - g_free(realwho); -} - -void remove_icon_data(GaimConnection *gc) -{ - GList *list = icons; - struct icon_data *id; - - while (list) { - id = list->data; - if (id->gc == gc) { - g_free(id->data); - g_free(id->who); - list = icons = g_list_remove(icons, id); - g_free(id); - } else - list = list->next; - } -} - -void *get_icon_data(GaimConnection *gc, const char *who, int *len) -{ - struct icon_data tmp = { gc, normalize(who), NULL, 0 }; - GList *l = g_list_find_custom(icons, &tmp, find_icon_data); - struct icon_data *id = l ? l->data : NULL; - - if (id) { - *len = id->len; - return id->data; - } - - *len = 0; - return NULL; -} - struct got_add { GaimConnection *gc; char *who;
--- a/src/prpl.h Mon Sep 15 02:23:58 2003 +0000 +++ b/src/prpl.h Mon Sep 15 07:35:49 2003 +0000 @@ -360,27 +360,6 @@ void show_got_added(GaimConnection *gc, const char *id, const char *who, const char *alias, const char *msg); -/** - * Retrieves and sets the new buddy icon for a user. - * - * @param gc The gaim connection. - * @param who The user. - * @param data The icon data. - * @param len The length of @a data. - */ -void set_icon_data(GaimConnection *gc, const char *who, void *data, int len); - -/** - * Retrieves the buddy icon data for a user. - * - * @param gc The gaim connection. - * @param who The user. - * @param len The returned length of the data. - * - * @return The buddy icon data. - */ -void *get_icon_data(GaimConnection *gc, const char *who, int *len); - #ifdef __cplusplus } #endif