Mercurial > pidgin
annotate src/buddyicon.c @ 13623:51d436a267ac
[gaim-migrate @ 16009]
Use the GSlice allocator (for logs and log sets) when compiling with glib 2.10 or greater and eliminate some unnecessary memory zeroing. This cuts the log loading time in half for one of Luke's contacts.
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Tue, 11 Apr 2006 16:06:24 +0000 |
parents | 52985bb3ec70 |
children | d1da27a099d2 |
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" | |
13554
52985bb3ec70
[gaim-migrate @ 15932]
Richard Laager <rlaager@wiktel.com>
parents:
12996
diff
changeset
|
28 #include "dbus-maybe.h" |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
29 #include "debug.h" |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
30 #include "util.h" |
6846 | 31 |
32 static GHashTable *account_cache = NULL; | |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
33 static char *cache_dir = NULL; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
34 static gboolean icon_caching = TRUE; |
6846 | 35 |
9396 | 36 static GaimBuddyIcon * |
37 gaim_buddy_icon_create(GaimAccount *account, const char *username) | |
38 { | |
39 GaimBuddyIcon *icon; | |
40 GHashTable *icon_cache; | |
41 | |
42 icon = g_new0(GaimBuddyIcon, 1); | |
13554
52985bb3ec70
[gaim-migrate @ 15932]
Richard Laager <rlaager@wiktel.com>
parents:
12996
diff
changeset
|
43 GAIM_DBUS_REGISTER_POINTER(icon, GaimBuddyIcon); |
9396 | 44 |
45 gaim_buddy_icon_set_account(icon, account); | |
46 gaim_buddy_icon_set_username(icon, username); | |
47 | |
48 icon_cache = g_hash_table_lookup(account_cache, account); | |
49 | |
50 if (icon_cache == NULL) | |
51 { | |
52 icon_cache = g_hash_table_new(g_str_hash, g_str_equal); | |
53 | |
54 g_hash_table_insert(account_cache, account, icon_cache); | |
55 } | |
56 | |
57 g_hash_table_insert(icon_cache, | |
58 (char *)gaim_buddy_icon_get_username(icon), icon); | |
59 return icon; | |
60 } | |
61 | |
6846 | 62 GaimBuddyIcon * |
63 gaim_buddy_icon_new(GaimAccount *account, const char *username, | |
64 void *icon_data, size_t icon_len) | |
65 { | |
66 GaimBuddyIcon *icon; | |
67 | |
68 g_return_val_if_fail(account != NULL, NULL); | |
69 g_return_val_if_fail(username != NULL, NULL); | |
70 g_return_val_if_fail(icon_data != NULL, NULL); | |
71 g_return_val_if_fail(icon_len > 0, NULL); | |
72 | |
73 icon = gaim_buddy_icons_find(account, username); | |
74 | |
75 if (icon == NULL) | |
9396 | 76 icon = gaim_buddy_icon_create(account, username); |
6846 | 77 |
9327 | 78 gaim_buddy_icon_ref(icon); |
6846 | 79 gaim_buddy_icon_set_data(icon, icon_data, icon_len); |
80 | |
11423
202a3b3c5a88
[gaim-migrate @ 13660]
Richard Laager <rlaager@wiktel.com>
parents:
11338
diff
changeset
|
81 /* gaim_buddy_icon_set_data() makes blist.c or |
202a3b3c5a88
[gaim-migrate @ 13660]
Richard Laager <rlaager@wiktel.com>
parents:
11338
diff
changeset
|
82 * conversation.c, or both, take a reference. |
202a3b3c5a88
[gaim-migrate @ 13660]
Richard Laager <rlaager@wiktel.com>
parents:
11338
diff
changeset
|
83 * |
202a3b3c5a88
[gaim-migrate @ 13660]
Richard Laager <rlaager@wiktel.com>
parents:
11338
diff
changeset
|
84 * Plus, we leave one for the caller of this function. |
9323 | 85 */ |
11423
202a3b3c5a88
[gaim-migrate @ 13660]
Richard Laager <rlaager@wiktel.com>
parents:
11338
diff
changeset
|
86 |
6846 | 87 return icon; |
88 } | |
89 | |
90 void | |
91 gaim_buddy_icon_destroy(GaimBuddyIcon *icon) | |
92 { | |
7311
1c8830db0189
[gaim-migrate @ 7895]
Christian Hammond <chipx86@chipx86.com>
parents:
7125
diff
changeset
|
93 GaimConversation *conv; |
1c8830db0189
[gaim-migrate @ 7895]
Christian Hammond <chipx86@chipx86.com>
parents:
7125
diff
changeset
|
94 GaimAccount *account; |
6846 | 95 GHashTable *icon_cache; |
7311
1c8830db0189
[gaim-migrate @ 7895]
Christian Hammond <chipx86@chipx86.com>
parents:
7125
diff
changeset
|
96 const char *username; |
9305
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
97 GSList *sl, *list; |
6846 | 98 |
99 g_return_if_fail(icon != NULL); | |
100 | |
101 if (icon->ref_count > 0) | |
102 { | |
9323 | 103 /* If the ref count is greater than 0, then we weren't called from |
104 * gaim_buddy_icon_unref(). So we go through and ask everyone to | |
105 * unref us. Then we return, since we know somewhere along the | |
106 * line we got called recursively by one of the unrefs, and the | |
107 * icon is already destroyed. | |
108 */ | |
109 account = gaim_buddy_icon_get_account(icon); | |
110 username = gaim_buddy_icon_get_username(icon); | |
111 | |
11338 | 112 conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, username, account); |
10246 | 113 if (conv != NULL) |
9323 | 114 gaim_conv_im_set_icon(GAIM_CONV_IM(conv), NULL); |
115 | |
116 for (list = sl = gaim_find_buddies(account, username); sl != NULL; | |
117 sl = sl->next) | |
118 { | |
119 GaimBuddy *buddy = (GaimBuddy *)sl->data; | |
120 | |
121 gaim_buddy_set_icon(buddy, NULL); | |
122 } | |
123 | |
124 g_slist_free(list); | |
6846 | 125 |
126 return; | |
127 } | |
128 | |
129 icon_cache = g_hash_table_lookup(account_cache, | |
130 gaim_buddy_icon_get_account(icon)); | |
131 | |
132 if (icon_cache != NULL) | |
133 g_hash_table_remove(icon_cache, gaim_buddy_icon_get_username(icon)); | |
134 | |
135 if (icon->username != NULL) | |
136 g_free(icon->username); | |
137 | |
138 if (icon->data != NULL) | |
139 g_free(icon->data); | |
140 | |
13554
52985bb3ec70
[gaim-migrate @ 15932]
Richard Laager <rlaager@wiktel.com>
parents:
12996
diff
changeset
|
141 GAIM_DBUS_UNREGISTER_POINTER(icon); |
6846 | 142 g_free(icon); |
143 } | |
144 | |
145 GaimBuddyIcon * | |
146 gaim_buddy_icon_ref(GaimBuddyIcon *icon) | |
147 { | |
148 g_return_val_if_fail(icon != NULL, NULL); | |
149 | |
150 icon->ref_count++; | |
151 | |
152 return icon; | |
153 } | |
154 | |
155 GaimBuddyIcon * | |
156 gaim_buddy_icon_unref(GaimBuddyIcon *icon) | |
157 { | |
158 g_return_val_if_fail(icon != NULL, NULL); | |
12250
5e2a365af01b
[gaim-migrate @ 14552]
Richard Laager <rlaager@wiktel.com>
parents:
12097
diff
changeset
|
159 g_return_val_if_fail(icon->ref_count > 0, NULL); |
6846 | 160 |
161 icon->ref_count--; | |
162 | |
163 if (icon->ref_count == 0) | |
164 { | |
165 gaim_buddy_icon_destroy(icon); | |
166 | |
167 return NULL; | |
168 } | |
169 | |
170 return icon; | |
171 } | |
172 | |
173 void | |
174 gaim_buddy_icon_update(GaimBuddyIcon *icon) | |
175 { | |
176 GaimConversation *conv; | |
177 GaimAccount *account; | |
178 const char *username; | |
8550 | 179 GSList *sl, *list; |
6846 | 180 |
181 g_return_if_fail(icon != NULL); | |
182 | |
183 account = gaim_buddy_icon_get_account(icon); | |
184 username = gaim_buddy_icon_get_username(icon); | |
185 | |
9305
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
186 for (list = sl = gaim_find_buddies(account, username); sl != NULL; |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
187 sl = sl->next) |
6846 | 188 { |
189 GaimBuddy *buddy = (GaimBuddy *)sl->data; | |
190 | |
191 gaim_buddy_set_icon(buddy, icon); | |
192 } | |
193 | |
8550 | 194 g_slist_free(list); |
195 | |
11338 | 196 conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, username, account); |
6846 | 197 |
10246 | 198 if (conv != NULL) |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6886
diff
changeset
|
199 gaim_conv_im_set_icon(GAIM_CONV_IM(conv), icon); |
6846 | 200 } |
201 | |
11040
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
202 static void |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
203 delete_icon_cache_file(const char *dirname, const char *old_icon) |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
204 { |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
205 struct stat st; |
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 g_return_if_fail(dirname != NULL); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
208 g_return_if_fail(old_icon != NULL); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
209 |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
210 if (g_stat(old_icon, &st) == 0) |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
211 g_unlink(old_icon); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
212 else |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
213 { |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
214 char *filename = g_build_filename(dirname, old_icon, NULL); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
215 if (g_stat(filename, &st) == 0) |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
216 g_unlink(filename); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
217 g_free(filename); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
218 } |
12996
fbdc9e7ef77a
[gaim-migrate @ 15349]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12995
diff
changeset
|
219 gaim_debug_info("buddyicon", "Uncached file %s\n", old_icon); |
11040
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
220 } |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
221 |
6846 | 222 void |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
223 gaim_buddy_icon_cache(GaimBuddyIcon *icon, GaimBuddy *buddy) |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
224 { |
11137 | 225 const guchar *data; |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
226 const char *dirname; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
227 char *random; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
228 char *filename; |
7125 | 229 const char *old_icon; |
12995
595f690399e4
[gaim-migrate @ 15348]
Richard Laager <rlaager@wiktel.com>
parents:
12250
diff
changeset
|
230 size_t len = 0; |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
231 FILE *file = NULL; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
232 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
233 g_return_if_fail(icon != NULL); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
234 g_return_if_fail(buddy != NULL); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
235 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
236 if (!gaim_buddy_icons_is_caching()) |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
237 return; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
238 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
239 data = gaim_buddy_icon_get_data(icon, &len); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
240 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
241 random = g_strdup_printf("%x", g_random_int()); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
242 dirname = gaim_buddy_icons_get_cache_dir(); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
243 filename = g_build_filename(dirname, random, NULL); |
7721 | 244 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
|
245 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
246 if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
247 { |
12996
fbdc9e7ef77a
[gaim-migrate @ 15349]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12995
diff
changeset
|
248 gaim_debug_info("buddyicon", "Creating icon cache directory.\n"); |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
249 |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10523
diff
changeset
|
250 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
|
251 { |
12996
fbdc9e7ef77a
[gaim-migrate @ 15349]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12995
diff
changeset
|
252 gaim_debug_error("buddyicon", |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
253 "Unable to create directory %s: %s\n", |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
254 dirname, strerror(errno)); |
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 } |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
257 |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10523
diff
changeset
|
258 if ((file = g_fopen(filename, "wb")) != NULL) |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
259 { |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
260 fwrite(data, 1, len, file); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
261 fclose(file); |
12996
fbdc9e7ef77a
[gaim-migrate @ 15349]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12995
diff
changeset
|
262 gaim_debug_info("buddyicon", "Wrote file %s\n", filename); |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
263 } |
11021 | 264 else |
265 { | |
12996
fbdc9e7ef77a
[gaim-migrate @ 15349]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12995
diff
changeset
|
266 gaim_debug_error("buddyicon", "Unable to create file %s: %s\n", |
11021 | 267 filename, strerror(errno)); |
268 } | |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
269 |
9747 | 270 g_free(filename); |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
271 |
9747 | 272 if (old_icon != NULL) |
11040
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
273 delete_icon_cache_file(dirname, old_icon); |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
274 |
9747 | 275 gaim_blist_node_set_string((GaimBlistNode *)buddy, "buddy_icon", random); |
276 | |
277 g_free(random); | |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
278 } |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
279 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
280 void |
11040
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
281 gaim_buddy_icon_uncache(GaimBuddy *buddy) |
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 const char *old_icon; |
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 g_return_if_fail(buddy != NULL); |
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 old_icon = gaim_blist_node_get_string((GaimBlistNode *)buddy, "buddy_icon"); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
288 |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
289 if (old_icon != NULL) |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
290 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
|
291 |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
292 gaim_blist_node_remove_setting((GaimBlistNode *)buddy, "buddy_icon"); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
293 |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
294 /* Unset the icon in case this function is called from |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
295 * something other than gaim_buddy_set_icon(). */ |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
296 if (buddy->icon != NULL) |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
297 { |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
298 gaim_buddy_icon_unref(buddy->icon); |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
299 buddy->icon = NULL; |
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 } |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
302 |
3428ad6f5049
[gaim-migrate @ 12940]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
303 void |
6846 | 304 gaim_buddy_icon_set_account(GaimBuddyIcon *icon, GaimAccount *account) |
305 { | |
306 g_return_if_fail(icon != NULL); | |
307 g_return_if_fail(account != NULL); | |
308 | |
309 icon->account = account; | |
310 } | |
311 | |
312 void | |
313 gaim_buddy_icon_set_username(GaimBuddyIcon *icon, const char *username) | |
314 { | |
315 g_return_if_fail(icon != NULL); | |
316 g_return_if_fail(username != NULL); | |
317 | |
318 if (icon->username != NULL) | |
319 g_free(icon->username); | |
320 | |
321 icon->username = g_strdup(username); | |
322 } | |
323 | |
324 void | |
325 gaim_buddy_icon_set_data(GaimBuddyIcon *icon, void *data, size_t len) | |
326 { | |
327 g_return_if_fail(icon != NULL); | |
328 | |
329 if (icon->data != NULL) | |
330 g_free(icon->data); | |
331 | |
332 if (data != NULL && len > 0) | |
333 { | |
334 icon->data = g_memdup(data, len); | |
335 icon->len = len; | |
336 } | |
337 else | |
338 { | |
339 icon->data = NULL; | |
340 icon->len = 0; | |
341 } | |
342 | |
343 gaim_buddy_icon_update(icon); | |
344 } | |
345 | |
346 GaimAccount * | |
347 gaim_buddy_icon_get_account(const GaimBuddyIcon *icon) | |
348 { | |
349 g_return_val_if_fail(icon != NULL, NULL); | |
350 | |
351 return icon->account; | |
352 } | |
353 | |
354 const char * | |
355 gaim_buddy_icon_get_username(const GaimBuddyIcon *icon) | |
356 { | |
357 g_return_val_if_fail(icon != NULL, NULL); | |
358 | |
359 return icon->username; | |
360 } | |
361 | |
11137 | 362 const guchar * |
6846 | 363 gaim_buddy_icon_get_data(const GaimBuddyIcon *icon, size_t *len) |
364 { | |
365 g_return_val_if_fail(icon != NULL, NULL); | |
366 | |
367 if (len != NULL) | |
368 *len = icon->len; | |
369 | |
370 return icon->data; | |
371 } | |
372 | |
10953 | 373 const char * |
374 gaim_buddy_icon_get_type(const GaimBuddyIcon *icon) | |
375 { | |
376 const void *data; | |
377 size_t len; | |
378 | |
379 g_return_val_if_fail(icon != NULL, NULL); | |
380 | |
381 data = gaim_buddy_icon_get_data(icon, &len); | |
382 | |
383 /* TODO: Find a way to do this with GDK */ | |
384 if (len >= 4) | |
385 { | |
386 if (!strncmp(data, "BM", 2)) | |
387 return "bmp"; | |
388 else if (!strncmp(data, "GIF8", 4)) | |
389 return "gif"; | |
390 else if (!strncmp(data, "\xff\xd8\xff\xe0", 4)) | |
391 return "jpg"; | |
392 else if (!strncmp(data, "\x89PNG", 4)) | |
393 return "png"; | |
394 } | |
395 | |
396 return NULL; | |
397 } | |
398 | |
6846 | 399 void |
400 gaim_buddy_icons_set_for_user(GaimAccount *account, const char *username, | |
401 void *icon_data, size_t icon_len) | |
402 { | |
403 g_return_if_fail(account != NULL); | |
404 g_return_if_fail(username != NULL); | |
405 | |
9305
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
406 if (icon_data == NULL || icon_len == 0) |
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 GaimBuddyIcon *buddy_icon; |
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 buddy_icon = gaim_buddy_icons_find(account, username); |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
411 |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
412 if (buddy_icon != NULL) |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
413 gaim_buddy_icon_destroy(buddy_icon); |
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 else |
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
416 { |
11423
202a3b3c5a88
[gaim-migrate @ 13660]
Richard Laager <rlaager@wiktel.com>
parents:
11338
diff
changeset
|
417 GaimBuddyIcon *icon = gaim_buddy_icon_new(account, username, icon_data, icon_len); |
202a3b3c5a88
[gaim-migrate @ 13660]
Richard Laager <rlaager@wiktel.com>
parents:
11338
diff
changeset
|
418 gaim_buddy_icon_unref(icon); |
9305
0c201a2386c7
[gaim-migrate @ 10113]
Christian Hammond <chipx86@chipx86.com>
parents:
9285
diff
changeset
|
419 } |
6846 | 420 } |
421 | |
422 GaimBuddyIcon * | |
9396 | 423 gaim_buddy_icons_find(GaimAccount *account, const char *username) |
6846 | 424 { |
425 GHashTable *icon_cache; | |
9396 | 426 GaimBuddyIcon *ret = NULL; |
9747 | 427 char *filename = NULL; |
6846 | 428 |
429 g_return_val_if_fail(account != NULL, NULL); | |
430 g_return_val_if_fail(username != NULL, NULL); | |
431 | |
432 icon_cache = g_hash_table_lookup(account_cache, account); | |
433 | |
9396 | 434 if ((icon_cache == NULL) || ((ret = g_hash_table_lookup(icon_cache, username)) == NULL)) { |
435 const char *file; | |
436 struct stat st; | |
437 GaimBuddy *b = gaim_find_buddy(account, username); | |
438 | |
439 if (!b) | |
440 return NULL; | |
441 | |
442 if ((file = gaim_blist_node_get_string((GaimBlistNode*)b, "buddy_icon")) == NULL) | |
443 return NULL; | |
6846 | 444 |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10523
diff
changeset
|
445 if (!g_stat(file, &st)) |
9747 | 446 filename = g_strdup(file); |
447 else | |
448 filename = g_build_filename(gaim_buddy_icons_get_cache_dir(), file, NULL); | |
449 | |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10523
diff
changeset
|
450 if (!g_stat(filename, &st)) { |
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10523
diff
changeset
|
451 FILE *f = g_fopen(filename, "rb"); |
9396 | 452 if (f) { |
453 char *data = g_malloc(st.st_size); | |
454 fread(data, 1, st.st_size, f); | |
455 fclose(f); | |
456 ret = gaim_buddy_icon_create(account, username); | |
457 gaim_buddy_icon_ref(ret); | |
458 gaim_buddy_icon_set_data(ret, data, st.st_size); | |
459 gaim_buddy_icon_unref(ret); | |
460 g_free(data); | |
9747 | 461 g_free(filename); |
9396 | 462 return ret; |
463 } | |
464 } | |
9747 | 465 g_free(filename); |
9396 | 466 } |
467 | |
468 return ret; | |
6846 | 469 } |
470 | |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
471 void |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
472 gaim_buddy_icons_set_caching(gboolean caching) |
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 icon_caching = caching; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
475 } |
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 gboolean |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
478 gaim_buddy_icons_is_caching(void) |
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 return icon_caching; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
481 } |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
482 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
483 void |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
484 gaim_buddy_icons_set_cache_dir(const char *dir) |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
485 { |
10811
dc59482c8d37
[gaim-migrate @ 12464]
Luke Schierer <lschiere@pidgin.im>
parents:
10589
diff
changeset
|
486 g_return_if_fail(dir != NULL); |
6886
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 if (cache_dir != NULL) |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
489 g_free(cache_dir); |
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 cache_dir = g_strdup(dir); |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
492 } |
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 const char * |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
495 gaim_buddy_icons_get_cache_dir(void) |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
496 { |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
497 return cache_dir; |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
498 } |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
499 |
11303
10066662176a
[gaim-migrate @ 13503]
Richard Laager <rlaager@wiktel.com>
parents:
11256
diff
changeset
|
500 char *gaim_buddy_icons_get_full_path(const char *icon) { |
10066662176a
[gaim-migrate @ 13503]
Richard Laager <rlaager@wiktel.com>
parents:
11256
diff
changeset
|
501 struct stat st; |
10066662176a
[gaim-migrate @ 13503]
Richard Laager <rlaager@wiktel.com>
parents:
11256
diff
changeset
|
502 |
10066662176a
[gaim-migrate @ 13503]
Richard Laager <rlaager@wiktel.com>
parents:
11256
diff
changeset
|
503 if (icon == NULL) |
10066662176a
[gaim-migrate @ 13503]
Richard Laager <rlaager@wiktel.com>
parents:
11256
diff
changeset
|
504 return NULL; |
10066662176a
[gaim-migrate @ 13503]
Richard Laager <rlaager@wiktel.com>
parents:
11256
diff
changeset
|
505 |
10066662176a
[gaim-migrate @ 13503]
Richard Laager <rlaager@wiktel.com>
parents:
11256
diff
changeset
|
506 if (g_stat(icon, &st) == 0) |
10066662176a
[gaim-migrate @ 13503]
Richard Laager <rlaager@wiktel.com>
parents:
11256
diff
changeset
|
507 return g_strdup(icon); |
10066662176a
[gaim-migrate @ 13503]
Richard Laager <rlaager@wiktel.com>
parents:
11256
diff
changeset
|
508 else |
10066662176a
[gaim-migrate @ 13503]
Richard Laager <rlaager@wiktel.com>
parents:
11256
diff
changeset
|
509 return g_build_filename(gaim_buddy_icons_get_cache_dir(), icon, NULL); |
10066662176a
[gaim-migrate @ 13503]
Richard Laager <rlaager@wiktel.com>
parents:
11256
diff
changeset
|
510 } |
10066662176a
[gaim-migrate @ 13503]
Richard Laager <rlaager@wiktel.com>
parents:
11256
diff
changeset
|
511 |
6846 | 512 void * |
513 gaim_buddy_icons_get_handle() | |
514 { | |
515 static int handle; | |
516 | |
517 return &handle; | |
518 } | |
519 | |
520 void | |
521 gaim_buddy_icons_init() | |
522 { | |
523 account_cache = g_hash_table_new_full( | |
524 g_direct_hash, g_direct_equal, | |
525 NULL, (GFreeFunc)g_hash_table_destroy); | |
6886
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
526 |
b5fb1d5282e5
[gaim-migrate @ 7432]
Christian Hammond <chipx86@chipx86.com>
parents:
6846
diff
changeset
|
527 cache_dir = g_build_filename(gaim_user_dir(), "icons", NULL); |
6846 | 528 } |
529 | |
530 void | |
531 gaim_buddy_icons_uninit() | |
532 { | |
533 g_hash_table_destroy(account_cache); | |
534 } | |
10483 | 535 |
536 void gaim_buddy_icon_get_scale_size(GaimBuddyIconSpec *spec, int *width, int *height) | |
537 { | |
538 if(spec && spec->scale_rules & GAIM_ICON_SCALE_DISPLAY) { | |
10523 | 539 int new_width, new_height; |
540 | |
541 new_width = *width; | |
542 new_height = *height; | |
543 | |
10483 | 544 if(*width < spec->min_width) |
10523 | 545 new_width = spec->min_width; |
10483 | 546 else if(*width > spec->max_width) |
10523 | 547 new_width = spec->max_width; |
10483 | 548 |
549 if(*height < spec->min_height) | |
10523 | 550 new_height = spec->min_height; |
10483 | 551 else if(*height > spec->max_height) |
10523 | 552 new_height = spec->max_height; |
553 | |
554 /* preserve aspect ratio */ | |
555 if ((double)*height * (double)new_width > | |
556 (double)*width * (double)new_height) { | |
557 new_width = 0.5 + (double)*width * (double)new_height / (double)*height; | |
558 } else { | |
559 new_height = 0.5 + (double)*height * (double)new_width / (double)*width; | |
560 } | |
561 | |
562 *width = new_width; | |
563 *height = new_height; | |
10483 | 564 } |
565 } | |
566 |