+typedef struct {
+ GdkPixbuf *pixbuf;
+ gchar *token;
+} AvatarData;
+
+static void
+chat_view_avatar_cache_data_free (gpointer ptr)
+{
+ AvatarData *data = ptr;
+
+ g_object_unref (data->pixbuf);
+ g_free (data->token);
+ g_slice_free (AvatarData, data);
+}
+
+static GdkPixbuf *
+chat_view_get_avatar_pixbuf_with_cache (EmpathyContact *contact)
+{
+ static GHashTable *avatar_cache = NULL;
+ AvatarData *data;
+ EmpathyAvatar *avatar;
+ GdkPixbuf *tmp_pixbuf;
+ GdkPixbuf *pixbuf = NULL;
+
+ /* Init avatar cache */
+ if (!avatar_cache) {
+ avatar_cache = g_hash_table_new_full (empathy_contact_hash,
+ empathy_contact_equal,
+ g_object_unref,
+ chat_view_avatar_cache_data_free);
+ }
+
+ /* Check if avatar is in cache and if it's up to date */
+ avatar = empathy_contact_get_avatar (contact);
+ data = g_hash_table_lookup (avatar_cache, contact);
+ if (data) {
+ if (avatar && !tp_strdiff (avatar->token, data->token)) {
+ /* We have the avatar in cache */
+ return data->pixbuf;
+ }
+
+ /* The cache is outdate */
+ g_hash_table_remove (avatar_cache, contact);
+ }
+
+ /* Avatar not in cache, create pixbuf */
+ tmp_pixbuf = empathy_pixbuf_avatar_from_contact_scaled (contact, 32, 32);
+ if (tmp_pixbuf) {
+ pixbuf = chat_view_pad_to_size (tmp_pixbuf, 32, 32, 6);
+ g_object_unref (tmp_pixbuf);
+ }
+ if (!pixbuf) {
+ return NULL;
+ }
+
+ /* Insert new pixbuf in cache */
+ data = g_slice_new0 (AvatarData);
+ data->token = g_strdup (avatar->token);
+ data->pixbuf = pixbuf;
+
+ g_hash_table_insert (avatar_cache,
+ g_object_ref (contact),
+ data);
+
+ return data->pixbuf;
+}
+