Mercurial > pidgin
annotate src/buddyicon.c @ 11052:8a68c933a5dd
[gaim-migrate @ 12990]
Patch #1227165 from sadrul
This patch probes plugins when the plugin page is loaded in preferences. This allows users to activate newly installed plugins without restarting Gaim.
The only way I can see this being a problem is if you installed a plugin which was version-compatible but binary incompatible. (For example, you're working on Gaim HEAD and change a public struct in a way that's binary backwards incompatible, build a plugin against it, install the plugin, and open the preferences page of a running copy of Gaim from before the change.) Even then, depending on the particular plugin and binary incompatibility, you might have to activate the plugin before Gaim would crash.
So, unless I'm missing something, this should be safe. Let's see how it goes.
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Sun, 03 Jul 2005 05:28:57 +0000 |
parents | 3428ad6f5049 |
children | 096020ae09a9 |
rev | line source |
---|---|
6846 | 1 /** |
2 * @file icon.c Buddy Icon API | |
3 * @ingroup core | |
4 * | |
5 * gaim | |
6 * | |
8046 | 7 * Gaim is the legal property of its developers, whose names are too numerous |
8 * to list here. Please refer to the COPYRIGHT file distributed with this | |
9 * source distribution. | |
6846 | 10 * |
11 * This program is free software; you can redistribute it and/or modify | |
12 * it under the terms of the GNU General Public License as published by | |
13 * the Free Software Foundation; either version 2 of the License, or | |
14 * (at your option) any later version. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
24 */ | |
25 #include "internal.h" | |
26 #include "buddyicon.h" | |
27 #include "conversation.h" | |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
28 #include "debug.h" |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
29 #include "util.h" |
6846 | 30 |
31 static GHashTable *account_cache = NULL; | |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
32 static char *cache_dir = NULL; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
33 static gboolean icon_caching = TRUE; |
6846 | 34 |
9396 | 35 static GaimBuddyIcon * |
36 gaim_buddy_icon_create(GaimAccount *account, const char *username) | |
37 { | |
38 GaimBuddyIcon *icon; | |
39 GHashTable *icon_cache; | |
40 | |
41 icon = g_new0(GaimBuddyIcon, 1); | |
42 | |
43 gaim_buddy_icon_set_account(icon, account); | |
44 gaim_buddy_icon_set_username(icon, username); | |
45 | |
46 icon_cache = g_hash_table_lookup(account_cache, account); | |
47 | |
48 if (icon_cache == NULL) | |
49 { | |
50 icon_cache = g_hash_table_new(g_str_hash, g_str_equal); | |
51 | |
52 g_hash_table_insert(account_cache, account, icon_cache); | |
53 } | |
54 | |
55 g_hash_table_insert(icon_cache, | |
56 (char *)gaim_buddy_icon_get_username(icon), icon); | |
57 return icon; | |
58 } | |
59 | |
6846 | 60 GaimBuddyIcon * |
61 gaim_buddy_icon_new(GaimAccount *account, const char *username, | |
62 void *icon_data, size_t icon_len) | |
63 { | |
64 GaimBuddyIcon *icon; | |
65 | |
66 g_return_val_if_fail(account != NULL, NULL); | |
67 g_return_val_if_fail(username != NULL, NULL); | |
68 g_return_val_if_fail(icon_data != NULL, NULL); | |
69 g_return_val_if_fail(icon_len > 0, NULL); | |
70 | |
71 icon = gaim_buddy_icons_find(account, username); | |
72 | |
73 if (icon == NULL) | |
9396 | 74 icon = gaim_buddy_icon_create(account, username); |
6846 | 75 |
9327 | 76 gaim_buddy_icon_ref(icon); |
6846 | 77 gaim_buddy_icon_set_data(icon, icon_data, icon_len); |
9327 | 78 gaim_buddy_icon_unref(icon); |
6846 | 79 |
9327 | 80 /* We don't take a reference here. gaim_buddy_icon_set_data() makes blist.c or |
81 conversation.c, or both, do that for us. | |
9323 | 82 */ |
6846 | 83 return icon; |
84 } | |
85 | |
86 void | |
87 gaim_buddy_icon_destroy(GaimBuddyIcon *icon) | |
88 { | |
7311
1c8830db0189
[gaim-migrate @ 7895]
Christian Hammond <chipx86@chipx86.com>
parents:
7125
diff
changeset
|
89 GaimConversation *conv; |
1c8830db0189
[gaim-migrate @ 7895]
Christian Hammond <chipx86@chipx86.com>
parents:
7125
diff
changeset
|
90 GaimAccount *account; |
6846 | 91 GHashTable *icon_cache; |
7311
1c8830db0189
[gaim-migrate @ 7895]
Christian Hammond <chipx86@chipx86.com>
parents:
7125
diff
changeset
|
92 const char *username; |
9305
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
93 GSList *sl, *list; |
6846 | 94 |
95 g_return_if_fail(icon != NULL); | |
96 | |
97 if (icon->ref_count > 0) | |
98 { | |
9323 | 99 /* If the ref count is greater than 0, then we weren't called from |
100 * gaim_buddy_icon_unref(). So we go through and ask everyone to | |
101 * unref us. Then we return, since we know somewhere along the | |
102 * line we got called recursively by one of the unrefs, and the | |
103 * icon is already destroyed. | |
104 */ | |
105 account = gaim_buddy_icon_get_account(icon); | |
106 username = gaim_buddy_icon_get_username(icon); | |
107 | |
10246 | 108 conv = gaim_find_conversation_with_account(GAIM_CONV_IM, username, account); |
109 if (conv != NULL) | |
9323 | 110 gaim_conv_im_set_icon(GAIM_CONV_IM(conv), NULL); |
111 | |
112 for (list = sl = gaim_find_buddies(account, username); sl != NULL; | |
113 sl = sl->next) | |
114 { | |
115 GaimBuddy *buddy = (GaimBuddy *)sl->data; | |
116 | |
117 gaim_buddy_set_icon(buddy, NULL); | |
118 } | |
119 | |
120 g_slist_free(list); | |
6846 | 121 |
122 return; | |
123 } | |
124 | |
125 icon_cache = g_hash_table_lookup(account_cache, | |
126 gaim_buddy_icon_get_account(icon)); | |
127 | |
128 if (icon_cache != NULL) | |
129 g_hash_table_remove(icon_cache, gaim_buddy_icon_get_username(icon)); | |
130 | |
131 if (icon->username != NULL) | |
132 g_free(icon->username); | |
133 | |
134 if (icon->data != NULL) | |
135 g_free(icon->data); | |
136 | |
137 g_free(icon); | |
138 } | |
139 | |
140 GaimBuddyIcon * | |
141 gaim_buddy_icon_ref(GaimBuddyIcon *icon) | |
142 { | |
143 g_return_val_if_fail(icon != NULL, NULL); | |
144 | |
145 icon->ref_count++; | |
146 | |
147 return icon; | |
148 } | |
149 | |
150 GaimBuddyIcon * | |
151 gaim_buddy_icon_unref(GaimBuddyIcon *icon) | |
152 { | |
153 g_return_val_if_fail(icon != NULL, NULL); | |
154 | |
155 if (icon->ref_count <= 0) | |
156 return NULL; | |
157 | |
158 icon->ref_count--; | |
159 | |
160 if (icon->ref_count == 0) | |
161 { | |
162 gaim_buddy_icon_destroy(icon); | |
163 | |
164 return NULL; | |
165 } | |
166 | |
167 return icon; | |
168 } | |
169 | |
170 void | |
171 gaim_buddy_icon_update(GaimBuddyIcon *icon) | |
172 { | |
173 GaimConversation *conv; | |
174 GaimAccount *account; | |
175 const char *username; | |
8550 | 176 GSList *sl, *list; |
6846 | 177 |
178 g_return_if_fail(icon != NULL); | |
179 | |
180 account = gaim_buddy_icon_get_account(icon); | |
181 username = gaim_buddy_icon_get_username(icon); | |
182 | |
9305
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
183 for (list = sl = gaim_find_buddies(account, username); sl != NULL; |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
184 sl = sl->next) |
6846 | 185 { |
186 GaimBuddy *buddy = (GaimBuddy *)sl->data; | |
187 | |
188 gaim_buddy_set_icon(buddy, icon); | |
189 } | |
190 | |
8550 | 191 g_slist_free(list); |
192 | |
10246 | 193 conv = gaim_find_conversation_with_account(GAIM_CONV_IM, username, account); |
6846 | 194 |
10246 | 195 if (conv != NULL) |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6886
diff
changeset
|
196 gaim_conv_im_set_icon(GAIM_CONV_IM(conv), icon); |
6846 | 197 } |
198 | |
11040
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
199 static void |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
200 delete_icon_cache_file(const char *dirname, const char *old_icon) |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
201 { |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
202 struct stat st; |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
203 |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
204 g_return_if_fail(dirname != NULL); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
205 g_return_if_fail(old_icon != NULL); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
206 |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
207 if (g_stat(old_icon, &st) == 0) |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
208 g_unlink(old_icon); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
209 else |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
210 { |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
211 char *filename = g_build_filename(dirname, old_icon, NULL); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
212 if (g_stat(filename, &st) == 0) |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
213 g_unlink(filename); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
214 g_free(filename); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
215 } |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
216 } |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
217 |
6846 | 218 void |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
219 gaim_buddy_icon_cache(GaimBuddyIcon *icon, GaimBuddy *buddy) |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
220 { |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
221 const void *data; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
222 const char *dirname; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
223 char *random; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
224 char *filename; |
7125 | 225 const char *old_icon; |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
226 size_t len; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
227 FILE *file = NULL; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
228 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
229 g_return_if_fail(icon != NULL); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
230 g_return_if_fail(buddy != NULL); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
231 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
232 if (!gaim_buddy_icons_is_caching()) |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
233 return; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
234 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
235 data = gaim_buddy_icon_get_data(icon, &len); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
236 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
237 random = g_strdup_printf("%x", g_random_int()); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
238 dirname = gaim_buddy_icons_get_cache_dir(); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
239 filename = g_build_filename(dirname, random, NULL); |
7721 | 240 old_icon = gaim_blist_node_get_string((GaimBlistNode*)buddy, "buddy_icon"); |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
241 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
242 if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
243 { |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
244 gaim_debug_info("buddy icons", "Creating icon cache directory.\n"); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
245 |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10523
diff
changeset
|
246 if (g_mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0) |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
247 { |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
248 gaim_debug_error("buddy icons", |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
249 "Unable to create directory %s: %s\n", |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
250 dirname, strerror(errno)); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
251 } |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
252 } |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
253 |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10523
diff
changeset
|
254 if ((file = g_fopen(filename, "wb")) != NULL) |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
255 { |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
256 fwrite(data, 1, len, file); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
257 fclose(file); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
258 } |
11021 | 259 else |
260 { | |
261 gaim_debug_error("buddy icons", "Unable to create file %s: %s\n", | |
262 filename, strerror(errno)); | |
263 } | |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
264 |
10934 | 265 gaim_signal_emit(gaim_buddy_icons_get_handle(), "buddy-icon-cached", |
266 icon, buddy, filename, old_icon); | |
267 | |
9747 | 268 g_free(filename); |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
269 |
9747 | 270 if (old_icon != NULL) |
11040
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
271 delete_icon_cache_file(dirname, old_icon); |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
272 |
9747 | 273 gaim_blist_node_set_string((GaimBlistNode *)buddy, "buddy_icon", random); |
274 | |
275 g_free(random); | |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
276 } |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
277 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
278 void |
11040
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
279 gaim_buddy_icon_uncache(GaimBuddy *buddy) |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
280 { |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
281 const char *old_icon; |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
282 |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
283 g_return_if_fail(buddy != NULL); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
284 |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
285 old_icon = gaim_blist_node_get_string((GaimBlistNode *)buddy, "buddy_icon"); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
286 |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
287 if (old_icon != NULL) |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
288 delete_icon_cache_file(gaim_buddy_icons_get_cache_dir(), old_icon); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
289 |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
290 gaim_blist_node_remove_setting((GaimBlistNode *)buddy, "buddy_icon"); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
291 |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
292 /* Unset the icon in case this function is called from |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
293 * something other than gaim_buddy_set_icon(). */ |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
294 if (buddy->icon != NULL) |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
295 { |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
296 gaim_buddy_icon_unref(buddy->icon); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
297 buddy->icon = NULL; |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
298 } |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
299 } |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
300 |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
301 void |
6846 | 302 gaim_buddy_icon_set_account(GaimBuddyIcon *icon, GaimAccount *account) |
303 { | |
304 g_return_if_fail(icon != NULL); | |
305 g_return_if_fail(account != NULL); | |
306 | |
307 icon->account = account; | |
308 } | |
309 | |
310 void | |
311 gaim_buddy_icon_set_username(GaimBuddyIcon *icon, const char *username) | |
312 { | |
313 g_return_if_fail(icon != NULL); | |
314 g_return_if_fail(username != NULL); | |
315 | |
316 if (icon->username != NULL) | |
317 g_free(icon->username); | |
318 | |
319 icon->username = g_strdup(username); | |
320 } | |
321 | |
322 void | |
323 gaim_buddy_icon_set_data(GaimBuddyIcon *icon, void *data, size_t len) | |
324 { | |
325 g_return_if_fail(icon != NULL); | |
326 | |
327 if (icon->data != NULL) | |
328 g_free(icon->data); | |
329 | |
330 if (data != NULL && len > 0) | |
331 { | |
332 icon->data = g_memdup(data, len); | |
333 icon->len = len; | |
334 } | |
335 else | |
336 { | |
337 icon->data = NULL; | |
338 icon->len = 0; | |
339 } | |
340 | |
341 gaim_buddy_icon_update(icon); | |
342 } | |
343 | |
344 GaimAccount * | |
345 gaim_buddy_icon_get_account(const GaimBuddyIcon *icon) | |
346 { | |
347 g_return_val_if_fail(icon != NULL, NULL); | |
348 | |
349 return icon->account; | |
350 } | |
351 | |
352 const char * | |
353 gaim_buddy_icon_get_username(const GaimBuddyIcon *icon) | |
354 { | |
355 g_return_val_if_fail(icon != NULL, NULL); | |
356 | |
357 return icon->username; | |
358 } | |
359 | |
360 const void * | |
361 gaim_buddy_icon_get_data(const GaimBuddyIcon *icon, size_t *len) | |
362 { | |
363 g_return_val_if_fail(icon != NULL, NULL); | |
364 | |
365 if (len != NULL) | |
366 *len = icon->len; | |
367 | |
368 return icon->data; | |
369 } | |
370 | |
10953 | 371 const char * |
372 gaim_buddy_icon_get_type(const GaimBuddyIcon *icon) | |
373 { | |
374 const void *data; | |
375 size_t len; | |
376 | |
377 g_return_val_if_fail(icon != NULL, NULL); | |
378 | |
379 data = gaim_buddy_icon_get_data(icon, &len); | |
380 | |
381 /* TODO: Find a way to do this with GDK */ | |
382 if (len >= 4) | |
383 { | |
384 if (!strncmp(data, "BM", 2)) | |
385 return "bmp"; | |
386 else if (!strncmp(data, "GIF8", 4)) | |
387 return "gif"; | |
388 else if (!strncmp(data, "\xff\xd8\xff\xe0", 4)) | |
389 return "jpg"; | |
390 else if (!strncmp(data, "\x89PNG", 4)) | |
391 return "png"; | |
392 } | |
393 | |
394 return NULL; | |
395 } | |
396 | |
6846 | 397 void |
398 gaim_buddy_icons_set_for_user(GaimAccount *account, const char *username, | |
399 void *icon_data, size_t icon_len) | |
400 { | |
401 g_return_if_fail(account != NULL); | |
402 g_return_if_fail(username != NULL); | |
403 | |
9305
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
404 if (icon_data == NULL || icon_len == 0) |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
405 { |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
406 GaimBuddyIcon *buddy_icon; |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
407 |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
408 buddy_icon = gaim_buddy_icons_find(account, username); |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
409 |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
410 if (buddy_icon != NULL) |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
411 gaim_buddy_icon_destroy(buddy_icon); |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
412 } |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
413 else |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
414 { |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
415 gaim_buddy_icon_new(account, username, icon_data, icon_len); |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
416 } |
6846 | 417 } |
418 | |
419 GaimBuddyIcon * | |
9396 | 420 gaim_buddy_icons_find(GaimAccount *account, const char *username) |
6846 | 421 { |
422 GHashTable *icon_cache; | |
9396 | 423 GaimBuddyIcon *ret = NULL; |
9747 | 424 char *filename = NULL; |
6846 | 425 |
426 g_return_val_if_fail(account != NULL, NULL); | |
427 g_return_val_if_fail(username != NULL, NULL); | |
428 | |
429 icon_cache = g_hash_table_lookup(account_cache, account); | |
430 | |
9396 | 431 if ((icon_cache == NULL) || ((ret = g_hash_table_lookup(icon_cache, username)) == NULL)) { |
432 const char *file; | |
433 struct stat st; | |
434 GaimBuddy *b = gaim_find_buddy(account, username); | |
435 | |
436 if (!b) | |
437 return NULL; | |
438 | |
439 if ((file = gaim_blist_node_get_string((GaimBlistNode*)b, "buddy_icon")) == NULL) | |
440 return NULL; | |
6846 | 441 |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10523
diff
changeset
|
442 if (!g_stat(file, &st)) |
9747 | 443 filename = g_strdup(file); |
444 else | |
445 filename = g_build_filename(gaim_buddy_icons_get_cache_dir(), file, NULL); | |
446 | |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10523
diff
changeset
|
447 if (!g_stat(filename, &st)) { |
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10523
diff
changeset
|
448 FILE *f = g_fopen(filename, "rb"); |
9396 | 449 if (f) { |
450 char *data = g_malloc(st.st_size); | |
451 fread(data, 1, st.st_size, f); | |
452 fclose(f); | |
453 ret = gaim_buddy_icon_create(account, username); | |
454 gaim_buddy_icon_ref(ret); | |
455 gaim_buddy_icon_set_data(ret, data, st.st_size); | |
456 gaim_buddy_icon_unref(ret); | |
457 g_free(data); | |
9747 | 458 g_free(filename); |
9396 | 459 return ret; |
460 } | |
461 } | |
9747 | 462 g_free(filename); |
9396 | 463 } |
464 | |
465 return ret; | |
6846 | 466 } |
467 | |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
468 void |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
469 gaim_buddy_icons_set_caching(gboolean caching) |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
470 { |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
471 icon_caching = caching; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
472 } |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
473 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
474 gboolean |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
475 gaim_buddy_icons_is_caching(void) |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
476 { |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
477 return icon_caching; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
478 } |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
479 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
480 void |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
481 gaim_buddy_icons_set_cache_dir(const char *dir) |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
482 { |
10811
dc59482c8d37
[gaim-migrate @ 12464]
Luke Schierer <lschiere@pidgin.im>
parents:
10589
diff
changeset
|
483 g_return_if_fail(dir != NULL); |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
484 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
485 if (cache_dir != NULL) |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
486 g_free(cache_dir); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
487 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
488 cache_dir = g_strdup(dir); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
489 } |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
490 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
491 const char * |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
492 gaim_buddy_icons_get_cache_dir(void) |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
493 { |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
494 return cache_dir; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
495 } |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
496 |
6846 | 497 void * |
498 gaim_buddy_icons_get_handle() | |
499 { | |
500 static int handle; | |
501 | |
502 return &handle; | |
503 } | |
504 | |
505 void | |
506 gaim_buddy_icons_init() | |
507 { | |
11033
50224ac8184d
[gaim-migrate @ 12919]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11021
diff
changeset
|
508 gaim_debug_register_category("buddy icons"); |
50224ac8184d
[gaim-migrate @ 12919]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11021
diff
changeset
|
509 |
6846 | 510 account_cache = g_hash_table_new_full( |
511 g_direct_hash, g_direct_equal, | |
512 NULL, (GFreeFunc)g_hash_table_destroy); | |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
513 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
514 cache_dir = g_build_filename(gaim_user_dir(), "icons", NULL); |
10934 | 515 |
516 gaim_signal_register(gaim_buddy_icons_get_handle(), "buddy-icon-cached", | |
517 gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER, NULL, 4, | |
518 gaim_value_new(GAIM_TYPE_SUBTYPE, | |
519 GAIM_SUBTYPE_BUDDY_ICON), | |
520 gaim_value_new(GAIM_TYPE_SUBTYPE, | |
11033
50224ac8184d
[gaim-migrate @ 12919]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11021
diff
changeset
|
521 GAIM_SUBTYPE_BLIST_BUDDY), |
10934 | 522 gaim_value_new(GAIM_TYPE_STRING), |
523 gaim_value_new(GAIM_TYPE_STRING)); | |
6846 | 524 } |
525 | |
526 void | |
527 gaim_buddy_icons_uninit() | |
528 { | |
529 g_hash_table_destroy(account_cache); | |
11033
50224ac8184d
[gaim-migrate @ 12919]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11021
diff
changeset
|
530 |
50224ac8184d
[gaim-migrate @ 12919]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11021
diff
changeset
|
531 gaim_debug_unregister_category("buddy icons"); |
6846 | 532 } |
10483 | 533 |
534 void gaim_buddy_icon_get_scale_size(GaimBuddyIconSpec *spec, int *width, int *height) | |
535 { | |
536 if(spec && spec->scale_rules & GAIM_ICON_SCALE_DISPLAY) { | |
10523 | 537 int new_width, new_height; |
538 | |
539 new_width = *width; | |
540 new_height = *height; | |
541 | |
10483 | 542 if(*width < spec->min_width) |
10523 | 543 new_width = spec->min_width; |
10483 | 544 else if(*width > spec->max_width) |
10523 | 545 new_width = spec->max_width; |
10483 | 546 |
547 if(*height < spec->min_height) | |
10523 | 548 new_height = spec->min_height; |
10483 | 549 else if(*height > spec->max_height) |
10523 | 550 new_height = spec->max_height; |
551 | |
552 /* preserve aspect ratio */ | |
553 if ((double)*height * (double)new_width > | |
554 (double)*width * (double)new_height) { | |
555 new_width = 0.5 + (double)*width * (double)new_height / (double)*height; | |
556 } else { | |
557 new_height = 0.5 + (double)*height * (double)new_width / (double)*width; | |
558 } | |
559 | |
560 *width = new_width; | |
561 *height = new_height; | |
10483 | 562 } |
563 } | |
564 |