Mercurial > pidgin.yaz
comparison 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 |
comparison
equal
deleted
inserted
replaced
6845:5de4d9a4e0e2 | 6846:8ab95f4c9800 |
---|---|
1 /** | |
2 * @file icon.c Buddy Icon API | |
3 * @ingroup core | |
4 * | |
5 * gaim | |
6 * | |
7 * Copyright (C) 2003 Christian Hammond <chipx86@gnupdate.org> | |
8 * | |
9 * This program is free software; you can redistribute it and/or modify | |
10 * it under the terms of the GNU General Public License as published by | |
11 * the Free Software Foundation; either version 2 of the License, or | |
12 * (at your option) any later version. | |
13 * | |
14 * This program is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 * GNU General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU General Public License | |
20 * along with this program; if not, write to the Free Software | |
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
22 */ | |
23 #include "internal.h" | |
24 #include "buddyicon.h" | |
25 #include "conversation.h" | |
26 | |
27 static GHashTable *account_cache = NULL; | |
28 | |
29 GaimBuddyIcon * | |
30 gaim_buddy_icon_new(GaimAccount *account, const char *username, | |
31 void *icon_data, size_t icon_len) | |
32 { | |
33 GaimBuddyIcon *icon; | |
34 | |
35 g_return_val_if_fail(account != NULL, NULL); | |
36 g_return_val_if_fail(username != NULL, NULL); | |
37 g_return_val_if_fail(icon_data != NULL, NULL); | |
38 g_return_val_if_fail(icon_len > 0, NULL); | |
39 | |
40 icon = gaim_buddy_icons_find(account, username); | |
41 | |
42 if (icon == NULL) | |
43 { | |
44 GHashTable *icon_cache; | |
45 | |
46 icon = g_new0(GaimBuddyIcon, 1); | |
47 | |
48 gaim_buddy_icon_set_account(icon, account); | |
49 gaim_buddy_icon_set_username(icon, username); | |
50 | |
51 icon_cache = g_hash_table_lookup(account_cache, account); | |
52 | |
53 if (icon_cache == NULL) | |
54 { | |
55 icon_cache = g_hash_table_new(g_str_hash, g_str_equal); | |
56 | |
57 g_hash_table_insert(account_cache, account, icon_cache); | |
58 } | |
59 | |
60 g_hash_table_insert(icon_cache, | |
61 (char *)gaim_buddy_icon_get_username(icon), icon); | |
62 } | |
63 | |
64 gaim_buddy_icon_set_data(icon, icon_data, icon_len); | |
65 | |
66 gaim_buddy_icon_ref(icon); | |
67 | |
68 return icon; | |
69 } | |
70 | |
71 void | |
72 gaim_buddy_icon_destroy(GaimBuddyIcon *icon) | |
73 { | |
74 GHashTable *icon_cache; | |
75 | |
76 g_return_if_fail(icon != NULL); | |
77 | |
78 if (icon->ref_count > 0) | |
79 { | |
80 gaim_buddy_icon_unref(icon); | |
81 | |
82 return; | |
83 } | |
84 | |
85 icon_cache = g_hash_table_lookup(account_cache, | |
86 gaim_buddy_icon_get_account(icon)); | |
87 | |
88 if (icon_cache != NULL) | |
89 g_hash_table_remove(icon_cache, gaim_buddy_icon_get_username(icon)); | |
90 | |
91 if (icon->username != NULL) | |
92 g_free(icon->username); | |
93 | |
94 if (icon->data != NULL) | |
95 g_free(icon->data); | |
96 | |
97 g_free(icon); | |
98 } | |
99 | |
100 GaimBuddyIcon * | |
101 gaim_buddy_icon_ref(GaimBuddyIcon *icon) | |
102 { | |
103 g_return_val_if_fail(icon != NULL, NULL); | |
104 | |
105 icon->ref_count++; | |
106 | |
107 return icon; | |
108 } | |
109 | |
110 GaimBuddyIcon * | |
111 gaim_buddy_icon_unref(GaimBuddyIcon *icon) | |
112 { | |
113 g_return_val_if_fail(icon != NULL, NULL); | |
114 | |
115 if (icon->ref_count <= 0) | |
116 return NULL; | |
117 | |
118 icon->ref_count--; | |
119 | |
120 if (icon->ref_count == 0) | |
121 { | |
122 gaim_buddy_icon_destroy(icon); | |
123 | |
124 return NULL; | |
125 } | |
126 | |
127 return icon; | |
128 } | |
129 | |
130 void | |
131 gaim_buddy_icon_update(GaimBuddyIcon *icon) | |
132 { | |
133 GaimConversation *conv; | |
134 GaimAccount *account; | |
135 const char *username; | |
136 GSList *sl; | |
137 | |
138 g_return_if_fail(icon != NULL); | |
139 | |
140 account = gaim_buddy_icon_get_account(icon); | |
141 username = gaim_buddy_icon_get_username(icon); | |
142 | |
143 for (sl = gaim_find_buddies(account, username); sl != NULL; sl = sl->next) | |
144 { | |
145 GaimBuddy *buddy = (GaimBuddy *)sl->data; | |
146 | |
147 gaim_buddy_set_icon(buddy, icon); | |
148 } | |
149 | |
150 conv = gaim_find_conversation_with_account(username, account); | |
151 | |
152 if (conv != NULL && gaim_conversation_get_type(conv) == GAIM_CONV_IM) | |
153 gaim_im_set_icon(GAIM_IM(conv), icon); | |
154 } | |
155 | |
156 void | |
157 gaim_buddy_icon_set_account(GaimBuddyIcon *icon, GaimAccount *account) | |
158 { | |
159 g_return_if_fail(icon != NULL); | |
160 g_return_if_fail(account != NULL); | |
161 | |
162 icon->account = account; | |
163 } | |
164 | |
165 void | |
166 gaim_buddy_icon_set_username(GaimBuddyIcon *icon, const char *username) | |
167 { | |
168 g_return_if_fail(icon != NULL); | |
169 g_return_if_fail(username != NULL); | |
170 | |
171 if (icon->username != NULL) | |
172 g_free(icon->username); | |
173 | |
174 icon->username = g_strdup(username); | |
175 } | |
176 | |
177 void | |
178 gaim_buddy_icon_set_data(GaimBuddyIcon *icon, void *data, size_t len) | |
179 { | |
180 g_return_if_fail(icon != NULL); | |
181 | |
182 if (icon->data != NULL) | |
183 g_free(icon->data); | |
184 | |
185 if (data != NULL && len > 0) | |
186 { | |
187 icon->data = g_memdup(data, len); | |
188 icon->len = len; | |
189 } | |
190 else | |
191 { | |
192 icon->data = NULL; | |
193 icon->len = 0; | |
194 } | |
195 | |
196 gaim_buddy_icon_update(icon); | |
197 } | |
198 | |
199 GaimAccount * | |
200 gaim_buddy_icon_get_account(const GaimBuddyIcon *icon) | |
201 { | |
202 g_return_val_if_fail(icon != NULL, NULL); | |
203 | |
204 return icon->account; | |
205 } | |
206 | |
207 const char * | |
208 gaim_buddy_icon_get_username(const GaimBuddyIcon *icon) | |
209 { | |
210 g_return_val_if_fail(icon != NULL, NULL); | |
211 | |
212 return icon->username; | |
213 } | |
214 | |
215 const void * | |
216 gaim_buddy_icon_get_data(const GaimBuddyIcon *icon, size_t *len) | |
217 { | |
218 g_return_val_if_fail(icon != NULL, NULL); | |
219 | |
220 if (len != NULL) | |
221 *len = icon->len; | |
222 | |
223 return icon->data; | |
224 } | |
225 | |
226 void | |
227 gaim_buddy_icons_set_for_user(GaimAccount *account, const char *username, | |
228 void *icon_data, size_t icon_len) | |
229 { | |
230 g_return_if_fail(account != NULL); | |
231 g_return_if_fail(username != NULL); | |
232 | |
233 gaim_buddy_icon_new(account, username, icon_data, icon_len); | |
234 } | |
235 | |
236 GaimBuddyIcon * | |
237 gaim_buddy_icons_find(const GaimAccount *account, const char *username) | |
238 { | |
239 GHashTable *icon_cache; | |
240 | |
241 g_return_val_if_fail(account != NULL, NULL); | |
242 g_return_val_if_fail(username != NULL, NULL); | |
243 | |
244 icon_cache = g_hash_table_lookup(account_cache, account); | |
245 | |
246 if (icon_cache == NULL) | |
247 return NULL; | |
248 | |
249 return g_hash_table_lookup(icon_cache, username); | |
250 } | |
251 | |
252 void * | |
253 gaim_buddy_icons_get_handle() | |
254 { | |
255 static int handle; | |
256 | |
257 return &handle; | |
258 } | |
259 | |
260 void | |
261 gaim_buddy_icons_init() | |
262 { | |
263 account_cache = g_hash_table_new_full( | |
264 g_direct_hash, g_direct_equal, | |
265 NULL, (GFreeFunc)g_hash_table_destroy); | |
266 } | |
267 | |
268 void | |
269 gaim_buddy_icons_uninit() | |
270 { | |
271 g_hash_table_destroy(account_cache); | |
272 } |