1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
3 * Copyright (C) 2004 Imendio AB
4 * Copyright (C) 2007-2008 Collabora Ltd.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
21 * Authors: Mikael Hallendal <micke@imendio.com>
22 * Martyn Russell <martyn@imendio.com>
23 * Xavier Claessens <xclaesse@gmail.com>
24 * Sjoerd Simons <sjoerd.simons@collabora.co.uk>
31 #include <glib/gi18n-lib.h>
33 #include <telepathy-glib/util.h>
34 #include <libmissioncontrol/mc-enum-types.h>
36 #include "empathy-contact.h"
37 #include "empathy-contact-factory.h"
38 #include "empathy-utils.h"
39 #include "empathy-enum-types.h"
40 #include "empathy-marshal.h"
42 #define DEBUG_FLAG EMPATHY_DEBUG_CONTACT
43 #include "empathy-debug.h"
45 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyContact)
47 EmpathyContactFactory *factory;
50 EmpathyAvatar *avatar;
53 gchar *presence_message;
55 EmpathyCapabilities capabilities;
58 EmpathyContactReady ready;
59 GList *ready_callbacks;
63 EmpathyContactReady ready;
64 EmpathyContactReadyCb *callback;
66 GDestroyNotify destroy;
70 static void contact_finalize (GObject *object);
71 static void contact_get_property (GObject *object, guint param_id,
72 GValue *value, GParamSpec *pspec);
73 static void contact_set_property (GObject *object, guint param_id,
74 const GValue *value, GParamSpec *pspec);
76 G_DEFINE_TYPE (EmpathyContact, empathy_contact, G_TYPE_OBJECT);
86 PROP_PRESENCE_MESSAGE,
98 static guint signals[LAST_SIGNAL];
101 contact_dispose (GObject *object)
103 EmpathyContactPriv *priv = GET_PRIV (object);
106 g_object_unref (priv->account);
107 priv->account = NULL;
110 g_object_unref (priv->factory);
111 priv->factory = NULL;
113 G_OBJECT_CLASS (empathy_contact_parent_class)->dispose (object);
117 empathy_contact_class_init (EmpathyContactClass *class)
119 GObjectClass *object_class;
121 object_class = G_OBJECT_CLASS (class);
123 object_class->finalize = contact_finalize;
124 object_class->dispose = contact_dispose;
125 object_class->get_property = contact_get_property;
126 object_class->set_property = contact_set_property;
128 g_object_class_install_property (object_class,
130 g_param_spec_string ("id",
132 "String identifying contact",
136 g_object_class_install_property (object_class,
138 g_param_spec_string ("name",
140 "The name of the contact",
144 g_object_class_install_property (object_class,
146 g_param_spec_boxed ("avatar",
152 g_object_class_install_property (object_class,
154 g_param_spec_object ("account",
156 "The account associated with the contact",
160 g_object_class_install_property (object_class,
162 g_param_spec_uint ("presence",
164 "Presence of contact",
170 g_object_class_install_property (object_class,
171 PROP_PRESENCE_MESSAGE,
172 g_param_spec_string ("presence-message",
173 "Contact presence message",
174 "Presence message of contact",
178 g_object_class_install_property (object_class,
180 g_param_spec_uint ("handle",
182 "The handle of the contact",
188 g_object_class_install_property (object_class,
190 g_param_spec_flags ("capabilities",
191 "Contact Capabilities",
192 "Capabilities of the contact",
193 EMPATHY_TYPE_CAPABILITIES,
194 EMPATHY_CAPABILITIES_UNKNOWN,
195 G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
197 g_object_class_install_property (object_class,
199 g_param_spec_boolean ("is-user",
201 "Is contact the user",
205 g_object_class_install_property (object_class,
207 g_param_spec_flags ("ready",
208 "Contact ready flags",
209 "Flags for ready properties",
210 EMPATHY_TYPE_CONTACT_READY,
211 EMPATHY_CONTACT_READY_NONE,
214 signals[PRESENCE_CHANGED] =
215 g_signal_new ("presence-changed",
216 G_TYPE_FROM_CLASS (class),
220 _empathy_marshal_VOID__ENUM_ENUM,
225 g_type_class_add_private (object_class, sizeof (EmpathyContactPriv));
229 empathy_contact_init (EmpathyContact *contact)
231 EmpathyContactPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (contact,
232 EMPATHY_TYPE_CONTACT, EmpathyContactPriv);
234 contact->priv = priv;
236 /* Keep a ref to the factory to be sure it is not finalized while there is
237 * still contacts alive. */
238 priv->factory = empathy_contact_factory_dup_singleton ();
242 contact_finalize (GObject *object)
244 EmpathyContactPriv *priv;
247 priv = GET_PRIV (object);
249 DEBUG ("finalize: %p", object);
253 g_free (priv->presence_message);
255 for (l = priv->ready_callbacks; l != NULL; l = g_list_next (l))
257 ReadyCbData *d = (ReadyCbData *)l->data;
259 if (d->destroy != NULL)
260 d->destroy (d->user_data);
261 g_slice_free (ReadyCbData, d);
264 g_list_free (priv->ready_callbacks);
265 priv->ready_callbacks = NULL;
268 empathy_avatar_unref (priv->avatar);
270 G_OBJECT_CLASS (empathy_contact_parent_class)->finalize (object);
274 contact_get_property (GObject *object,
279 EmpathyContactPriv *priv;
281 priv = GET_PRIV (object);
286 g_value_set_string (value, priv->id);
289 g_value_set_string (value,
290 empathy_contact_get_name (EMPATHY_CONTACT (object)));
293 g_value_set_boxed (value, priv->avatar);
296 g_value_set_object (value, priv->account);
299 g_value_set_uint (value, priv->presence);
301 case PROP_PRESENCE_MESSAGE:
302 g_value_set_string (value, priv->presence_message);
305 g_value_set_uint (value, priv->handle);
307 case PROP_CAPABILITIES:
308 g_value_set_flags (value, priv->capabilities);
311 g_value_set_boolean (value, priv->is_user);
314 g_value_set_flags (value, priv->ready);
317 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
323 contact_set_property (GObject *object,
328 EmpathyContactPriv *priv;
330 priv = GET_PRIV (object);
335 empathy_contact_set_id (EMPATHY_CONTACT (object),
336 g_value_get_string (value));
339 empathy_contact_set_name (EMPATHY_CONTACT (object),
340 g_value_get_string (value));
343 empathy_contact_set_avatar (EMPATHY_CONTACT (object),
344 g_value_get_boxed (value));
347 empathy_contact_set_account (EMPATHY_CONTACT (object),
348 MC_ACCOUNT (g_value_get_object (value)));
351 empathy_contact_set_presence (EMPATHY_CONTACT (object),
352 g_value_get_uint (value));
354 case PROP_PRESENCE_MESSAGE:
355 empathy_contact_set_presence_message (EMPATHY_CONTACT (object),
356 g_value_get_string (value));
359 empathy_contact_set_handle (EMPATHY_CONTACT (object),
360 g_value_get_uint (value));
362 case PROP_CAPABILITIES:
363 empathy_contact_set_capabilities (EMPATHY_CONTACT (object),
364 g_value_get_flags (value));
367 empathy_contact_set_is_user (EMPATHY_CONTACT (object),
368 g_value_get_boolean (value));
371 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
377 contact_is_ready (EmpathyContact *contact, EmpathyContactReady ready)
379 EmpathyContactPriv *priv = GET_PRIV (contact);
381 /* When the name is NULL, empathy_contact_get_name() fallback to the id.
382 * When the caller want to wait the name to be ready, it also want to wait
383 * the id to be ready in case of fallback. */
384 if ((ready & EMPATHY_CONTACT_READY_NAME) && EMP_STR_EMPTY (priv->name))
385 ready |= EMPATHY_CONTACT_READY_ID;
387 return (priv->ready & ready) == ready;
391 contact_weak_object_notify (gpointer data, GObject *old_object)
393 EmpathyContact *contact = EMPATHY_CONTACT (data);
394 EmpathyContactPriv *priv = GET_PRIV (contact);
398 for (l = priv->ready_callbacks ; l != NULL ; l = ln )
400 ReadyCbData *d = (ReadyCbData *)l->data;
401 ln = g_list_next (l);
403 if (d->weak_object == old_object)
405 if (d->destroy != NULL)
406 d->destroy (d->user_data);
408 priv->ready_callbacks = g_list_delete_link (priv->ready_callbacks,
411 g_slice_free (ReadyCbData, d);
417 contact_call_ready_callback (EmpathyContact *contact, const GError *error,
420 data->callback (contact, error, data->user_data, data->weak_object);
421 if (data->destroy != NULL)
422 data->destroy (data->user_data);
424 if (data->weak_object)
425 g_object_weak_unref (data->weak_object,
426 contact_weak_object_notify, contact);
431 contact_set_ready_flag (EmpathyContact *contact,
432 EmpathyContactReady flag)
434 EmpathyContactPriv *priv = GET_PRIV (contact);
436 if (!(priv->ready & flag))
441 g_object_notify (G_OBJECT (contact), "ready");
443 for (l = priv->ready_callbacks ; l != NULL ; l = ln )
445 ReadyCbData *d = (ReadyCbData *)l->data;
446 ln = g_list_next (l);
448 if (contact_is_ready (contact, d->ready))
450 contact_call_ready_callback (contact, NULL, d);
451 priv->ready_callbacks = g_list_delete_link
452 (priv->ready_callbacks, l);
453 g_slice_free (ReadyCbData, d);
460 empathy_contact_new (McAccount *account)
462 return g_object_new (EMPATHY_TYPE_CONTACT,
468 empathy_contact_new_full (McAccount *account,
472 return g_object_new (EMPATHY_TYPE_CONTACT,
480 empathy_contact_get_id (EmpathyContact *contact)
482 EmpathyContactPriv *priv;
484 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
486 priv = GET_PRIV (contact);
492 empathy_contact_set_id (EmpathyContact *contact,
495 EmpathyContactPriv *priv;
497 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
498 g_return_if_fail (id != NULL);
500 priv = GET_PRIV (contact);
502 /* We temporally ref the contact because it could be destroyed
503 * during the signal emition */
504 g_object_ref (contact);
505 if (tp_strdiff (id, priv->id))
508 priv->id = g_strdup (id);
510 g_object_notify (G_OBJECT (contact), "id");
511 if (EMP_STR_EMPTY (priv->name))
512 g_object_notify (G_OBJECT (contact), "name");
514 contact_set_ready_flag (contact, EMPATHY_CONTACT_READY_ID);
516 g_object_unref (contact);
520 empathy_contact_get_name (EmpathyContact *contact)
522 EmpathyContactPriv *priv;
524 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
526 priv = GET_PRIV (contact);
528 if (EMP_STR_EMPTY (priv->name))
529 return empathy_contact_get_id (contact);
535 empathy_contact_set_name (EmpathyContact *contact,
538 EmpathyContactPriv *priv;
540 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
542 priv = GET_PRIV (contact);
544 g_object_ref (contact);
545 if (tp_strdiff (name, priv->name))
548 priv->name = g_strdup (name);
549 g_object_notify (G_OBJECT (contact), "name");
551 contact_set_ready_flag (contact, EMPATHY_CONTACT_READY_NAME);
552 g_object_unref (contact);
556 empathy_contact_get_avatar (EmpathyContact *contact)
558 EmpathyContactPriv *priv;
560 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
562 priv = GET_PRIV (contact);
568 empathy_contact_set_avatar (EmpathyContact *contact,
569 EmpathyAvatar *avatar)
571 EmpathyContactPriv *priv;
573 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
575 priv = GET_PRIV (contact);
577 if (priv->avatar == avatar)
582 empathy_avatar_unref (priv->avatar);
587 priv->avatar = empathy_avatar_ref (avatar);
589 g_object_notify (G_OBJECT (contact), "avatar");
593 empathy_contact_get_account (EmpathyContact *contact)
595 EmpathyContactPriv *priv;
597 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
599 priv = GET_PRIV (contact);
601 return priv->account;
605 empathy_contact_set_account (EmpathyContact *contact,
608 EmpathyContactPriv *priv;
610 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
611 g_return_if_fail (MC_IS_ACCOUNT (account));
613 priv = GET_PRIV (contact);
615 if (account == priv->account)
619 g_object_unref (priv->account);
620 priv->account = g_object_ref (account);
622 g_object_notify (G_OBJECT (contact), "account");
626 empathy_contact_get_presence (EmpathyContact *contact)
628 EmpathyContactPriv *priv;
630 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), MC_PRESENCE_UNSET);
632 priv = GET_PRIV (contact);
634 return priv->presence;
638 empathy_contact_set_presence (EmpathyContact *contact,
641 EmpathyContactPriv *priv;
642 McPresence old_presence;
644 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
646 priv = GET_PRIV (contact);
648 if (presence == priv->presence)
651 old_presence = priv->presence;
652 priv->presence = presence;
654 g_signal_emit (contact, signals[PRESENCE_CHANGED], 0, presence, old_presence);
656 g_object_notify (G_OBJECT (contact), "presence");
660 empathy_contact_get_presence_message (EmpathyContact *contact)
662 EmpathyContactPriv *priv;
664 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
666 priv = GET_PRIV (contact);
668 return priv->presence_message;
672 empathy_contact_set_presence_message (EmpathyContact *contact,
673 const gchar *message)
675 EmpathyContactPriv *priv = GET_PRIV (contact);
677 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
679 if (!tp_strdiff (message, priv->presence_message))
682 g_free (priv->presence_message);
683 priv->presence_message = g_strdup (message);
685 g_object_notify (G_OBJECT (contact), "presence-message");
689 empathy_contact_get_handle (EmpathyContact *contact)
691 EmpathyContactPriv *priv;
693 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), 0);
695 priv = GET_PRIV (contact);
701 empathy_contact_set_handle (EmpathyContact *contact,
704 EmpathyContactPriv *priv;
706 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
708 priv = GET_PRIV (contact);
710 g_object_ref (contact);
711 if (handle != priv->handle)
713 priv->handle = handle;
714 g_object_notify (G_OBJECT (contact), "handle");
716 contact_set_ready_flag (contact, EMPATHY_CONTACT_READY_HANDLE);
717 g_object_unref (contact);
721 empathy_contact_get_capabilities (EmpathyContact *contact)
723 EmpathyContactPriv *priv;
725 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), 0);
727 priv = GET_PRIV (contact);
729 return priv->capabilities;
733 empathy_contact_set_capabilities (EmpathyContact *contact,
734 EmpathyCapabilities capabilities)
736 EmpathyContactPriv *priv;
738 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
740 priv = GET_PRIV (contact);
742 if (priv->capabilities == capabilities)
745 priv->capabilities = capabilities;
747 g_object_notify (G_OBJECT (contact), "capabilities");
751 empathy_contact_is_user (EmpathyContact *contact)
753 EmpathyContactPriv *priv;
755 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
757 priv = GET_PRIV (contact);
759 return priv->is_user;
763 empathy_contact_set_is_user (EmpathyContact *contact,
766 EmpathyContactPriv *priv;
768 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
770 priv = GET_PRIV (contact);
772 if (priv->is_user == is_user)
775 priv->is_user = is_user;
777 g_object_notify (G_OBJECT (contact), "is-user");
781 empathy_contact_is_online (EmpathyContact *contact)
783 EmpathyContactPriv *priv;
785 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
787 priv = GET_PRIV (contact);
789 return (priv->presence > MC_PRESENCE_OFFLINE);
793 empathy_contact_get_status (EmpathyContact *contact)
795 EmpathyContactPriv *priv;
797 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), "");
799 priv = GET_PRIV (contact);
801 if (priv->presence_message)
802 return priv->presence_message;
804 return empathy_presence_get_default_message (priv->presence);
808 empathy_contact_can_voip (EmpathyContact *contact)
810 EmpathyContactPriv *priv;
812 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
814 priv = GET_PRIV (contact);
816 return priv->capabilities & (EMPATHY_CAPABILITIES_AUDIO |
817 EMPATHY_CAPABILITIES_VIDEO);
821 empathy_contact_can_send_files (EmpathyContact *contact)
823 EmpathyContactPriv *priv;
825 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
827 priv = GET_PRIV (contact);
829 return priv->capabilities & EMPATHY_CAPABILITIES_FT;
833 empathy_contact_get_ready (EmpathyContact *contact)
835 EmpathyContactPriv *priv;
837 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
839 priv = GET_PRIV (contact);
845 empathy_contact_equal (gconstpointer v1,
848 McAccount *account_a;
849 McAccount *account_b;
853 g_return_val_if_fail (EMPATHY_IS_CONTACT (v1), FALSE);
854 g_return_val_if_fail (EMPATHY_IS_CONTACT (v2), FALSE);
856 account_a = empathy_contact_get_account (EMPATHY_CONTACT (v1));
857 account_b = empathy_contact_get_account (EMPATHY_CONTACT (v2));
859 id_a = empathy_contact_get_id (EMPATHY_CONTACT (v1));
860 id_b = empathy_contact_get_id (EMPATHY_CONTACT (v2));
862 return empathy_account_equal (account_a, account_b) &&
863 !tp_strdiff (id_a, id_b);
867 empathy_contact_hash (gconstpointer key)
869 EmpathyContactPriv *priv;
871 g_return_val_if_fail (EMPATHY_IS_CONTACT (key), +1);
873 priv = GET_PRIV (EMPATHY_CONTACT (key));
877 priv->hash = empathy_account_hash (priv->account) ^
878 g_str_hash (priv->id);
884 void empathy_contact_call_when_ready (EmpathyContact *contact,
885 EmpathyContactReady ready, EmpathyContactReadyCb *callback,
886 gpointer user_data, GDestroyNotify destroy, GObject *weak_object)
888 EmpathyContactPriv *priv = GET_PRIV (contact);
890 g_return_if_fail (contact != NULL);
891 g_return_if_fail (callback != NULL);
893 if (contact_is_ready (contact, ready))
895 callback (contact, NULL, user_data, weak_object);
901 ReadyCbData *d = g_slice_new0 (ReadyCbData);
903 d->callback = callback;
904 d->user_data = user_data;
905 d->destroy = destroy;
906 d->weak_object = weak_object;
908 if (weak_object != NULL)
909 g_object_weak_ref (weak_object, contact_weak_object_notify, contact);
911 priv->ready_callbacks = g_list_prepend (priv->ready_callbacks, d);
916 contact_is_ready_func (GObject *contact,
919 return contact_is_ready (EMPATHY_CONTACT (contact),
920 GPOINTER_TO_UINT (user_data));
924 empathy_contact_run_until_ready (EmpathyContact *contact,
925 EmpathyContactReady ready,
928 empathy_run_until_ready_full (contact, "notify::ready",
929 contact_is_ready_func, GUINT_TO_POINTER (ready),
934 contact_get_avatar_filename (EmpathyContact *contact,
937 EmpathyContactPriv *priv = GET_PRIV (contact);
940 gchar *token_escaped;
941 gchar *contact_escaped;
943 if (EMP_STR_EMPTY (priv->id))
946 contact_escaped = tp_escape_as_identifier (priv->id);
947 token_escaped = tp_escape_as_identifier (token);
949 avatar_path = g_build_filename (g_get_user_cache_dir (),
952 mc_account_get_unique_name (priv->account),
955 g_mkdir_with_parents (avatar_path, 0700);
957 avatar_file = g_build_filename (avatar_path, token_escaped, NULL);
959 g_free (contact_escaped);
960 g_free (token_escaped);
961 g_free (avatar_path);
967 empathy_contact_load_avatar_data (EmpathyContact *contact,
973 EmpathyAvatar *avatar;
975 GError *error = NULL;
977 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
978 g_return_if_fail (data != NULL);
979 g_return_if_fail (len > 0);
980 g_return_if_fail (format != NULL);
981 g_return_if_fail (!EMP_STR_EMPTY (token));
983 /* Load and set the avatar */
984 avatar = empathy_avatar_new (g_memdup (data, len), len, g_strdup (format),
986 empathy_contact_set_avatar (contact, avatar);
987 empathy_avatar_unref (avatar);
989 /* Save to cache if not yet in it */
990 filename = contact_get_avatar_filename (contact, token);
991 if (filename && !g_file_test (filename, G_FILE_TEST_EXISTS))
993 if (!empathy_avatar_save_to_file (avatar, filename, &error))
995 DEBUG ("Failed to save avatar in cache: %s",
996 error ? error->message : "No error given");
997 g_clear_error (&error);
1000 DEBUG ("Avatar saved to %s", filename);
1006 empathy_contact_load_avatar_cache (EmpathyContact *contact,
1009 EmpathyAvatar *avatar = NULL;
1013 GError *error = NULL;
1015 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
1016 g_return_val_if_fail (!EMP_STR_EMPTY (token), FALSE);
1018 /* Load the avatar from file if it exists */
1019 filename = contact_get_avatar_filename (contact, token);
1020 if (filename && g_file_test (filename, G_FILE_TEST_EXISTS))
1022 if (!g_file_get_contents (filename, &data, &len, &error))
1024 DEBUG ("Failed to load avatar from cache: %s",
1025 error ? error->message : "No error given");
1026 g_clear_error (&error);
1032 DEBUG ("Avatar loaded from %s", filename);
1033 avatar = empathy_avatar_new (data, len, NULL, g_strdup (token));
1034 empathy_contact_set_avatar (contact, avatar);
1035 empathy_avatar_unref (avatar);
1040 return data != NULL;
1044 empathy_avatar_get_type (void)
1046 static GType type_id = 0;
1050 type_id = g_boxed_type_register_static ("EmpathyAvatar",
1051 (GBoxedCopyFunc) empathy_avatar_ref,
1052 (GBoxedFreeFunc) empathy_avatar_unref);
1059 empathy_avatar_new (guchar *data,
1064 EmpathyAvatar *avatar;
1066 avatar = g_slice_new0 (EmpathyAvatar);
1067 avatar->data = data;
1069 avatar->format = format;
1070 avatar->token = token;
1071 avatar->refcount = 1;
1077 empathy_avatar_unref (EmpathyAvatar *avatar)
1079 g_return_if_fail (avatar != NULL);
1082 if (avatar->refcount == 0)
1084 g_free (avatar->data);
1085 g_free (avatar->format);
1086 g_free (avatar->token);
1087 g_slice_free (EmpathyAvatar, avatar);
1092 empathy_avatar_ref (EmpathyAvatar *avatar)
1094 g_return_val_if_fail (avatar != NULL, NULL);
1102 * empathy_avatar_save_to_file:
1103 * @avatar: the avatar
1104 * @filename: name of a file to write avatar to
1105 * @error: return location for a GError, or NULL
1107 * Save the avatar to a file named filename
1109 * Returns: %TRUE on success, %FALSE if an error occurred
1112 empathy_avatar_save_to_file (EmpathyAvatar *self,
1113 const gchar *filename,
1116 return g_file_set_contents (filename, self->data, self->len, error);