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 contact_remove_ready_flag (EmpathyContact *contact,
461 EmpathyContactReady flag)
463 EmpathyContactPriv *priv = GET_PRIV (contact);
465 if (priv->ready & flag)
468 g_object_notify (G_OBJECT (contact), "ready");
473 empathy_contact_new (McAccount *account)
475 return g_object_new (EMPATHY_TYPE_CONTACT,
481 empathy_contact_new_full (McAccount *account,
485 return g_object_new (EMPATHY_TYPE_CONTACT,
493 empathy_contact_get_id (EmpathyContact *contact)
495 EmpathyContactPriv *priv;
497 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
499 priv = GET_PRIV (contact);
505 empathy_contact_set_id (EmpathyContact *contact,
508 EmpathyContactPriv *priv;
510 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
511 g_return_if_fail (id != NULL);
513 priv = GET_PRIV (contact);
515 /* We temporally ref the contact because it could be destroyed
516 * during the signal emition */
517 g_object_ref (contact);
518 if (tp_strdiff (id, priv->id))
521 priv->id = g_strdup (id);
523 g_object_notify (G_OBJECT (contact), "id");
524 if (EMP_STR_EMPTY (priv->name))
525 g_object_notify (G_OBJECT (contact), "name");
527 contact_set_ready_flag (contact, EMPATHY_CONTACT_READY_ID);
529 g_object_unref (contact);
533 empathy_contact_get_name (EmpathyContact *contact)
535 EmpathyContactPriv *priv;
537 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
539 priv = GET_PRIV (contact);
541 if (EMP_STR_EMPTY (priv->name))
542 return empathy_contact_get_id (contact);
548 empathy_contact_set_name (EmpathyContact *contact,
551 EmpathyContactPriv *priv;
553 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
555 priv = GET_PRIV (contact);
557 g_object_ref (contact);
558 if (tp_strdiff (name, priv->name))
561 priv->name = g_strdup (name);
562 g_object_notify (G_OBJECT (contact), "name");
564 contact_set_ready_flag (contact, EMPATHY_CONTACT_READY_NAME);
565 g_object_unref (contact);
569 empathy_contact_get_avatar (EmpathyContact *contact)
571 EmpathyContactPriv *priv;
573 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
575 priv = GET_PRIV (contact);
581 empathy_contact_set_avatar (EmpathyContact *contact,
582 EmpathyAvatar *avatar)
584 EmpathyContactPriv *priv;
586 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
588 priv = GET_PRIV (contact);
590 if (priv->avatar == avatar)
595 empathy_avatar_unref (priv->avatar);
600 priv->avatar = empathy_avatar_ref (avatar);
602 g_object_notify (G_OBJECT (contact), "avatar");
606 empathy_contact_get_account (EmpathyContact *contact)
608 EmpathyContactPriv *priv;
610 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
612 priv = GET_PRIV (contact);
614 return priv->account;
618 empathy_contact_set_account (EmpathyContact *contact,
621 EmpathyContactPriv *priv;
623 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
624 g_return_if_fail (MC_IS_ACCOUNT (account));
626 priv = GET_PRIV (contact);
628 if (account == priv->account)
632 g_object_unref (priv->account);
633 priv->account = g_object_ref (account);
635 g_object_notify (G_OBJECT (contact), "account");
639 empathy_contact_get_presence (EmpathyContact *contact)
641 EmpathyContactPriv *priv;
643 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), MC_PRESENCE_UNSET);
645 priv = GET_PRIV (contact);
647 return priv->presence;
651 empathy_contact_set_presence (EmpathyContact *contact,
654 EmpathyContactPriv *priv;
655 McPresence old_presence;
657 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
659 priv = GET_PRIV (contact);
661 if (presence == priv->presence)
664 old_presence = priv->presence;
665 priv->presence = presence;
667 g_signal_emit (contact, signals[PRESENCE_CHANGED], 0, presence, old_presence);
669 g_object_notify (G_OBJECT (contact), "presence");
673 empathy_contact_get_presence_message (EmpathyContact *contact)
675 EmpathyContactPriv *priv;
677 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
679 priv = GET_PRIV (contact);
681 return priv->presence_message;
685 empathy_contact_set_presence_message (EmpathyContact *contact,
686 const gchar *message)
688 EmpathyContactPriv *priv = GET_PRIV (contact);
690 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
692 if (!tp_strdiff (message, priv->presence_message))
695 g_free (priv->presence_message);
696 priv->presence_message = g_strdup (message);
698 g_object_notify (G_OBJECT (contact), "presence-message");
702 empathy_contact_get_handle (EmpathyContact *contact)
704 EmpathyContactPriv *priv;
706 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), 0);
708 priv = GET_PRIV (contact);
714 empathy_contact_set_handle (EmpathyContact *contact,
717 EmpathyContactPriv *priv;
719 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
721 priv = GET_PRIV (contact);
723 g_object_ref (contact);
724 if (handle != priv->handle)
726 priv->handle = handle;
727 g_object_notify (G_OBJECT (contact), "handle");
731 contact_set_ready_flag (contact, EMPATHY_CONTACT_READY_HANDLE);
733 contact_remove_ready_flag (contact, EMPATHY_CONTACT_READY_HANDLE);
735 g_object_unref (contact);
739 empathy_contact_get_capabilities (EmpathyContact *contact)
741 EmpathyContactPriv *priv;
743 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), 0);
745 priv = GET_PRIV (contact);
747 return priv->capabilities;
751 empathy_contact_set_capabilities (EmpathyContact *contact,
752 EmpathyCapabilities capabilities)
754 EmpathyContactPriv *priv;
756 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
758 priv = GET_PRIV (contact);
760 if (priv->capabilities == capabilities)
763 priv->capabilities = capabilities;
765 g_object_notify (G_OBJECT (contact), "capabilities");
769 empathy_contact_is_user (EmpathyContact *contact)
771 EmpathyContactPriv *priv;
773 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
775 priv = GET_PRIV (contact);
777 return priv->is_user;
781 empathy_contact_set_is_user (EmpathyContact *contact,
784 EmpathyContactPriv *priv;
786 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
788 priv = GET_PRIV (contact);
790 if (priv->is_user == is_user)
793 priv->is_user = is_user;
795 g_object_notify (G_OBJECT (contact), "is-user");
799 empathy_contact_is_online (EmpathyContact *contact)
801 EmpathyContactPriv *priv;
803 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
805 priv = GET_PRIV (contact);
807 return (priv->presence > MC_PRESENCE_OFFLINE);
811 empathy_contact_get_status (EmpathyContact *contact)
813 EmpathyContactPriv *priv;
815 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), "");
817 priv = GET_PRIV (contact);
819 if (priv->presence_message)
820 return priv->presence_message;
822 return empathy_presence_get_default_message (priv->presence);
826 empathy_contact_can_voip (EmpathyContact *contact)
828 EmpathyContactPriv *priv;
830 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
832 priv = GET_PRIV (contact);
834 return priv->capabilities & (EMPATHY_CAPABILITIES_AUDIO |
835 EMPATHY_CAPABILITIES_VIDEO);
839 empathy_contact_can_send_files (EmpathyContact *contact)
841 EmpathyContactPriv *priv;
843 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
845 priv = GET_PRIV (contact);
847 return priv->capabilities & EMPATHY_CAPABILITIES_FT;
851 empathy_contact_get_ready (EmpathyContact *contact)
853 EmpathyContactPriv *priv;
855 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
857 priv = GET_PRIV (contact);
863 empathy_contact_equal (gconstpointer v1,
866 McAccount *account_a;
867 McAccount *account_b;
871 g_return_val_if_fail (EMPATHY_IS_CONTACT (v1), FALSE);
872 g_return_val_if_fail (EMPATHY_IS_CONTACT (v2), FALSE);
874 account_a = empathy_contact_get_account (EMPATHY_CONTACT (v1));
875 account_b = empathy_contact_get_account (EMPATHY_CONTACT (v2));
877 id_a = empathy_contact_get_id (EMPATHY_CONTACT (v1));
878 id_b = empathy_contact_get_id (EMPATHY_CONTACT (v2));
880 return empathy_account_equal (account_a, account_b) &&
881 !tp_strdiff (id_a, id_b);
885 empathy_contact_hash (gconstpointer key)
887 EmpathyContactPriv *priv;
889 g_return_val_if_fail (EMPATHY_IS_CONTACT (key), +1);
891 priv = GET_PRIV (EMPATHY_CONTACT (key));
895 priv->hash = empathy_account_hash (priv->account) ^
896 g_str_hash (priv->id);
902 void empathy_contact_call_when_ready (EmpathyContact *contact,
903 EmpathyContactReady ready, EmpathyContactReadyCb *callback,
904 gpointer user_data, GDestroyNotify destroy, GObject *weak_object)
906 EmpathyContactPriv *priv = GET_PRIV (contact);
908 g_return_if_fail (contact != NULL);
909 g_return_if_fail (callback != NULL);
911 if (contact_is_ready (contact, ready))
913 callback (contact, NULL, user_data, weak_object);
919 ReadyCbData *d = g_slice_new0 (ReadyCbData);
921 d->callback = callback;
922 d->user_data = user_data;
923 d->destroy = destroy;
924 d->weak_object = weak_object;
926 if (weak_object != NULL)
927 g_object_weak_ref (weak_object, contact_weak_object_notify, contact);
929 priv->ready_callbacks = g_list_prepend (priv->ready_callbacks, d);
934 contact_is_ready_func (GObject *contact,
937 return contact_is_ready (EMPATHY_CONTACT (contact),
938 GPOINTER_TO_UINT (user_data));
942 empathy_contact_run_until_ready (EmpathyContact *contact,
943 EmpathyContactReady ready,
946 empathy_run_until_ready_full (contact, "notify::ready",
947 contact_is_ready_func, GUINT_TO_POINTER (ready),
952 contact_get_avatar_filename (EmpathyContact *contact,
955 EmpathyContactPriv *priv = GET_PRIV (contact);
958 gchar *token_escaped;
959 gchar *contact_escaped;
961 if (EMP_STR_EMPTY (priv->id))
964 contact_escaped = tp_escape_as_identifier (priv->id);
965 token_escaped = tp_escape_as_identifier (token);
967 avatar_path = g_build_filename (g_get_user_cache_dir (),
970 mc_account_get_unique_name (priv->account),
973 g_mkdir_with_parents (avatar_path, 0700);
975 avatar_file = g_build_filename (avatar_path, token_escaped, NULL);
977 g_free (contact_escaped);
978 g_free (token_escaped);
979 g_free (avatar_path);
985 empathy_contact_load_avatar_data (EmpathyContact *contact,
991 EmpathyAvatar *avatar;
993 GError *error = NULL;
995 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
996 g_return_if_fail (data != NULL);
997 g_return_if_fail (len > 0);
998 g_return_if_fail (format != NULL);
999 g_return_if_fail (!EMP_STR_EMPTY (token));
1001 /* Load and set the avatar */
1002 avatar = empathy_avatar_new (g_memdup (data, len), len, g_strdup (format),
1004 empathy_contact_set_avatar (contact, avatar);
1005 empathy_avatar_unref (avatar);
1007 /* Save to cache if not yet in it */
1008 filename = contact_get_avatar_filename (contact, token);
1009 if (filename && !g_file_test (filename, G_FILE_TEST_EXISTS))
1011 if (!empathy_avatar_save_to_file (avatar, filename, &error))
1013 DEBUG ("Failed to save avatar in cache: %s",
1014 error ? error->message : "No error given");
1015 g_clear_error (&error);
1018 DEBUG ("Avatar saved to %s", filename);
1024 empathy_contact_load_avatar_cache (EmpathyContact *contact,
1027 EmpathyAvatar *avatar = NULL;
1031 GError *error = NULL;
1033 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
1034 g_return_val_if_fail (!EMP_STR_EMPTY (token), FALSE);
1036 /* Load the avatar from file if it exists */
1037 filename = contact_get_avatar_filename (contact, token);
1038 if (filename && g_file_test (filename, G_FILE_TEST_EXISTS))
1040 if (!g_file_get_contents (filename, &data, &len, &error))
1042 DEBUG ("Failed to load avatar from cache: %s",
1043 error ? error->message : "No error given");
1044 g_clear_error (&error);
1050 DEBUG ("Avatar loaded from %s", filename);
1051 avatar = empathy_avatar_new (data, len, NULL, g_strdup (token));
1052 empathy_contact_set_avatar (contact, avatar);
1053 empathy_avatar_unref (avatar);
1058 return data != NULL;
1062 empathy_avatar_get_type (void)
1064 static GType type_id = 0;
1068 type_id = g_boxed_type_register_static ("EmpathyAvatar",
1069 (GBoxedCopyFunc) empathy_avatar_ref,
1070 (GBoxedFreeFunc) empathy_avatar_unref);
1077 empathy_avatar_new (guchar *data,
1082 EmpathyAvatar *avatar;
1084 avatar = g_slice_new0 (EmpathyAvatar);
1085 avatar->data = data;
1087 avatar->format = format;
1088 avatar->token = token;
1089 avatar->refcount = 1;
1095 empathy_avatar_unref (EmpathyAvatar *avatar)
1097 g_return_if_fail (avatar != NULL);
1100 if (avatar->refcount == 0)
1102 g_free (avatar->data);
1103 g_free (avatar->format);
1104 g_free (avatar->token);
1105 g_slice_free (EmpathyAvatar, avatar);
1110 empathy_avatar_ref (EmpathyAvatar *avatar)
1112 g_return_val_if_fail (avatar != NULL, NULL);
1120 * empathy_avatar_save_to_file:
1121 * @avatar: the avatar
1122 * @filename: name of a file to write avatar to
1123 * @error: return location for a GError, or NULL
1125 * Save the avatar to a file named filename
1127 * Returns: %TRUE on success, %FALSE if an error occurred
1130 empathy_avatar_save_to_file (EmpathyAvatar *self,
1131 const gchar *filename,
1134 return g_file_set_contents (filename, self->data, self->len, error);