1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2007 Collabora Ltd.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Authors: Xavier Claessens <xclaesse@gmail.com>
27 #include <libtelepathy/tp-conn.h>
28 #include <libtelepathy/tp-conn-iface-aliasing-gen.h>
29 #include <libtelepathy/tp-conn-iface-presence-gen.h>
30 #include <libtelepathy/tp-conn-iface-avatars-gen.h>
31 #include <libmissioncontrol/mission-control.h>
33 #include "empathy-contact-factory.h"
34 #include "empathy-utils.h"
35 #include "empathy-debug.h"
37 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
38 EMPATHY_TYPE_CONTACT_FACTORY, EmpathyContactFactoryPriv))
40 #define DEBUG_DOMAIN "ContactFactory"
42 struct _EmpathyContactFactoryPriv {
48 EmpathyContactFactory *factory;
50 guint nb_pending_calls;
53 DBusGProxy *aliasing_iface;
54 DBusGProxy *avatars_iface;
55 DBusGProxy *presence_iface;
59 } ContactFactoryAccountData;
62 ContactFactoryAccountData *account_data;
67 ContactFactoryAccountData *account_data;
72 ContactFactoryAccountData *account_data;
73 EmpathyContact *contact;
76 static void empathy_contact_factory_class_init (EmpathyContactFactoryClass *klass);
77 static void empathy_contact_factory_init (EmpathyContactFactory *factory);
79 G_DEFINE_TYPE (EmpathyContactFactory, empathy_contact_factory, G_TYPE_OBJECT);
82 contact_factory_find_by_handle (gconstpointer a,
85 EmpathyContact *contact;
88 contact = EMPATHY_CONTACT (a);
89 handle = GPOINTER_TO_UINT (b);
91 return handle - empathy_contact_get_handle (contact);
94 static EmpathyContact *
95 contact_factory_account_data_find_by_handle (ContactFactoryAccountData *account_data,
100 l = g_list_find_custom (account_data->contacts,
101 GUINT_TO_POINTER (handle),
102 contact_factory_find_by_handle);
104 return l ? l->data : NULL;
108 contact_factory_find_by_id (gconstpointer a,
111 EmpathyContact *contact;
114 contact = EMPATHY_CONTACT (a);
116 return strcmp (id, empathy_contact_get_id (contact));
119 static EmpathyContact *
120 contact_factory_account_data_find_by_id (ContactFactoryAccountData *account_data,
125 l = g_list_find_custom (account_data->contacts,
127 contact_factory_find_by_id);
129 return l ? l->data : NULL;
132 static void contact_factory_account_data_free (gpointer data);
135 contact_factory_account_data_return_call (ContactFactoryAccountData *account_data)
137 if (--account_data->nb_pending_calls == 0 &&
138 account_data->contacts == NULL) {
139 contact_factory_account_data_free (account_data);
144 contact_factory_presences_table_foreach (const gchar *state_str,
145 GHashTable *presences_table,
146 EmpathyPresence **presence)
149 const GValue *message;
151 state = empathy_presence_state_from_str (state_str);
152 if (state == MC_PRESENCE_UNSET) {
157 g_object_unref (*presence);
161 *presence = empathy_presence_new ();
162 empathy_presence_set_state (*presence, state);
164 message = g_hash_table_lookup (presences_table, "message");
165 if (message != NULL) {
166 empathy_presence_set_status (*presence,
167 g_value_get_string (message));
172 contact_factory_parse_presence_foreach (guint handle,
173 GValueArray *presence_struct,
174 ContactFactoryAccountData *account_data)
176 GHashTable *presences_table;
177 EmpathyContact *contact;
178 EmpathyPresence *presence = NULL;
180 contact = contact_factory_account_data_find_by_handle (account_data,
186 presences_table = g_value_get_boxed (g_value_array_get_nth (presence_struct, 1));
188 g_hash_table_foreach (presences_table,
189 (GHFunc) contact_factory_presences_table_foreach,
192 empathy_debug (DEBUG_DOMAIN, "Changing presence for contact %s (%d) to %s (%d)",
193 empathy_contact_get_id (contact),
195 presence ? empathy_presence_get_status (presence) : "unset",
196 presence ? empathy_presence_get_state (presence) : MC_PRESENCE_UNSET);
198 empathy_contact_set_presence (contact, presence);
202 contact_factory_get_presence_cb (DBusGProxy *proxy,
203 GHashTable *handle_table,
207 ContactFactoryAccountData *account_data = user_data;
210 empathy_debug (DEBUG_DOMAIN, "Error requesting aliases: %s",
215 g_hash_table_foreach (handle_table,
216 (GHFunc) contact_factory_parse_presence_foreach,
219 contact_factory_account_data_return_call (account_data);
223 contact_factory_presence_update_cb (DBusGProxy *proxy,
224 GHashTable *handle_table,
225 ContactFactoryAccountData *account_data)
227 g_hash_table_foreach (handle_table,
228 (GHFunc) contact_factory_parse_presence_foreach,
233 contact_factory_set_aliases_cb (DBusGProxy *proxy,
237 ContactFactoryAccountData *account_data = user_data;
240 empathy_debug (DEBUG_DOMAIN, "Error setting alias: %s",
244 contact_factory_account_data_return_call (account_data);
248 contact_factory_request_aliases_cb (DBusGProxy *proxy,
249 gchar **contact_names,
253 RequestAliasesData *data = user_data;
258 empathy_debug (DEBUG_DOMAIN, "Error requesting aliases: %s",
263 for (name = contact_names; *name; name++) {
264 EmpathyContact *contact;
266 contact = contact_factory_account_data_find_by_handle (data->account_data,
272 empathy_debug (DEBUG_DOMAIN, "Renaming contact %s (%d) to %s (request cb)",
273 empathy_contact_get_id (contact),
274 data->handles[i], *name);
276 empathy_contact_set_name (contact, *name);
282 contact_factory_account_data_return_call (data->account_data);
283 g_free (data->handles);
284 g_slice_free (RequestAliasesData, data);
288 contact_factory_aliases_changed_cb (DBusGProxy *proxy,
289 GPtrArray *renamed_handlers,
292 ContactFactoryAccountData *account_data = user_data;
295 for (i = 0; renamed_handlers->len > i; i++) {
298 GValueArray *renamed_struct;
299 EmpathyContact *contact;
301 renamed_struct = g_ptr_array_index (renamed_handlers, i);
302 handle = g_value_get_uint(g_value_array_get_nth (renamed_struct, 0));
303 alias = g_value_get_string(g_value_array_get_nth (renamed_struct, 1));
304 contact = contact_factory_account_data_find_by_handle (account_data, handle);
307 /* We don't know this contact, skip */
311 if (G_STR_EMPTY (alias)) {
315 empathy_debug (DEBUG_DOMAIN, "Renaming contact %s (%d) to %s (changed cb)",
316 empathy_contact_get_id (contact),
319 empathy_contact_set_name (contact, alias);
324 contact_factory_request_avatars_cb (DBusGProxy *proxy,
328 ContactFactoryAccountData *account_data = user_data;
331 empathy_debug (DEBUG_DOMAIN, "Error requesting avatars: %s",
335 contact_factory_account_data_return_call (account_data);
339 contact_factory_request_avatar_cb (DBusGProxy *proxy,
345 RequestAvatarData *data = user_data;
346 EmpathyAvatar *avatar;
349 empathy_debug (DEBUG_DOMAIN, "Error requesting avatar: %s",
354 empathy_debug (DEBUG_DOMAIN, "Avatar received for %s (%d)",
355 empathy_contact_get_id (data->contact),
356 empathy_contact_get_handle (data->contact));
358 avatar = empathy_avatar_new (avatar_data->data,
361 empathy_contact_set_avatar (data->contact, avatar);
362 empathy_avatar_unref (avatar);
365 g_object_unref (data->contact);
366 contact_factory_account_data_return_call (data->account_data);
367 g_slice_free (RequestAvatarData, data);
371 contact_factory_avatar_updated_cb (DBusGProxy *proxy,
376 ContactFactoryAccountData *account_data = user_data;
377 RequestAvatarData *data;
378 EmpathyContact *contact;
380 contact = contact_factory_account_data_find_by_handle (account_data,
386 account_data->nb_pending_calls++;
387 data = g_slice_new0 (RequestAvatarData);
388 data->account_data = account_data;
389 data->contact = g_object_ref (contact);
390 tp_conn_iface_avatars_request_avatar_async (account_data->avatars_iface,
392 contact_factory_request_avatar_cb,
397 contact_factory_avatar_retrieved_cb (DBusGProxy *proxy,
404 ContactFactoryAccountData *account_data = user_data;
405 EmpathyContact *contact;
406 EmpathyAvatar *avatar;
408 contact = contact_factory_account_data_find_by_handle (account_data,
414 avatar = empathy_avatar_new (avatar_data->data,
417 empathy_contact_set_avatar (contact, avatar);
418 empathy_avatar_unref (avatar);
422 contact_factory_request_everything (ContactFactoryAccountData *account_data,
425 if (account_data->presence_iface) {
426 account_data->nb_pending_calls++;
427 tp_conn_iface_presence_get_presence_async (account_data->presence_iface,
429 contact_factory_get_presence_cb,
433 if (account_data->aliasing_iface) {
434 RequestAliasesData *data;
436 account_data->nb_pending_calls++;
437 data = g_slice_new (RequestAliasesData);
438 data->account_data = account_data;
439 data->handles = g_memdup (handles->data, handles->len * sizeof (guint));
441 tp_conn_iface_aliasing_request_aliases_async (account_data->aliasing_iface,
443 contact_factory_request_aliases_cb,
447 if (account_data->avatars_iface) {
448 account_data->nb_pending_calls++;
449 tp_conn_iface_avatars_request_avatars_async (account_data->avatars_iface,
451 contact_factory_request_avatars_cb,
457 contact_factory_request_handles_cb (DBusGProxy *proxy,
462 RequestHandlesData *data = user_data;
467 empathy_debug (DEBUG_DOMAIN, "Failed to request handles: %s",
472 for (l = data->contacts; l; l = l->next) {
475 handle = g_array_index (handles, guint, i);
476 empathy_contact_set_handle (l->data, handle);
477 if (handle == data->account_data->self_handle) {
478 empathy_contact_set_is_user (l->data, TRUE);
484 contact_factory_request_everything (data->account_data, handles);
487 g_list_foreach (data->contacts, (GFunc) g_object_unref, NULL);
488 g_list_free (data->contacts);
489 contact_factory_account_data_return_call (data->account_data);
490 g_slice_free (RequestHandlesData, data);
494 contact_factory_disconnect_contact_foreach (gpointer data,
497 EmpathyContact *contact = data;
499 empathy_contact_set_presence (contact, NULL);
500 empathy_contact_set_handle (contact, 0);
504 contact_factory_destroy_cb (TpConn *tp_conn,
505 ContactFactoryAccountData *account_data)
507 empathy_debug (DEBUG_DOMAIN, "Account disconnected or CM crashed");
509 g_object_unref (account_data->tp_conn);
510 account_data->tp_conn = NULL;
511 account_data->aliasing_iface = NULL;
512 account_data->avatars_iface = NULL;
513 account_data->presence_iface = NULL;
515 g_list_foreach (account_data->contacts,
516 contact_factory_disconnect_contact_foreach,
521 contact_factory_account_data_disconnect (ContactFactoryAccountData *account_data)
523 if (account_data->aliasing_iface) {
524 dbus_g_proxy_disconnect_signal (account_data->aliasing_iface,
526 G_CALLBACK (contact_factory_aliases_changed_cb),
529 if (account_data->avatars_iface) {
530 dbus_g_proxy_disconnect_signal (account_data->avatars_iface,
532 G_CALLBACK (contact_factory_avatar_updated_cb),
534 dbus_g_proxy_disconnect_signal (account_data->avatars_iface,
536 G_CALLBACK (contact_factory_avatar_retrieved_cb),
539 if (account_data->presence_iface) {
540 dbus_g_proxy_disconnect_signal (account_data->presence_iface,
542 G_CALLBACK (contact_factory_presence_update_cb),
545 if (account_data->tp_conn) {
546 g_signal_handlers_disconnect_by_func (account_data->tp_conn,
547 contact_factory_destroy_cb,
553 contact_factory_account_data_update (ContactFactoryAccountData *account_data)
555 EmpathyContactFactory *factory = account_data->factory;
556 EmpathyContactFactoryPriv *priv = GET_PRIV (factory);
557 McAccount *account = account_data->account;
558 TpConn *tp_conn = NULL;
559 RequestHandlesData *data;
560 const gchar **contact_ids;
565 if (account_data->account) {
568 /* status == 0 means the status is CONNECTED */
569 status = mission_control_get_connection_status (priv->mc,
572 tp_conn = mission_control_get_connection (priv->mc,
578 /* We are not connected anymore, remove the old connection */
579 contact_factory_account_data_disconnect (account_data);
580 if (account_data->tp_conn) {
581 contact_factory_destroy_cb (account_data->tp_conn,
586 else if (account_data->tp_conn) {
587 /* We were connected and we still are connected, nothing
588 * changed so nothing to do. */
589 g_object_unref (tp_conn);
593 /* We got a new connection */
594 account_data->tp_conn = tp_conn;
595 account_data->aliasing_iface = tp_conn_get_interface (tp_conn,
596 TELEPATHY_CONN_IFACE_ALIASING_QUARK);
597 account_data->avatars_iface = tp_conn_get_interface (tp_conn,
598 TELEPATHY_CONN_IFACE_AVATARS_QUARK);
599 account_data->presence_iface = tp_conn_get_interface (tp_conn,
600 TELEPATHY_CONN_IFACE_PRESENCE_QUARK);
602 /* Connect signals */
603 if (account_data->aliasing_iface) {
604 dbus_g_proxy_connect_signal (account_data->aliasing_iface,
606 G_CALLBACK (contact_factory_aliases_changed_cb),
609 if (account_data->avatars_iface) {
610 dbus_g_proxy_connect_signal (account_data->avatars_iface,
612 G_CALLBACK (contact_factory_avatar_updated_cb),
614 dbus_g_proxy_connect_signal (account_data->avatars_iface,
616 G_CALLBACK (contact_factory_avatar_retrieved_cb),
619 if (account_data->presence_iface) {
620 dbus_g_proxy_connect_signal (account_data->presence_iface,
622 G_CALLBACK (contact_factory_presence_update_cb),
625 g_signal_connect (tp_conn, "destroy",
626 G_CALLBACK (contact_factory_destroy_cb),
629 /* Get our own handle */
630 if (!tp_conn_get_self_handle (DBUS_G_PROXY (account_data->tp_conn),
631 &account_data->self_handle,
633 empathy_debug (DEBUG_DOMAIN, "GetSelfHandle Error: %s",
634 error ? error->message : "No error given");
635 g_clear_error (&error);
638 /* Request new handles for all contacts */
639 if (account_data->contacts) {
640 data = g_slice_new (RequestHandlesData);
641 data->account_data = account_data;
642 data->contacts = g_list_copy (account_data->contacts);
643 g_list_foreach (data->contacts, (GFunc) g_object_ref, NULL);
645 i = g_list_length (data->contacts);
646 contact_ids = g_new0 (const gchar*, i + 1);
648 for (l = data->contacts; l; l = l->next) {
649 contact_ids[i] = empathy_contact_get_id (l->data);
653 account_data->nb_pending_calls++;
654 tp_conn_request_handles_async (DBUS_G_PROXY (account_data->tp_conn),
655 TP_HANDLE_TYPE_CONTACT,
657 contact_factory_request_handles_cb,
659 g_free (contact_ids);
664 contact_factory_weak_notify (gpointer data,
665 GObject *where_the_object_was)
667 ContactFactoryAccountData *account_data = data;
669 empathy_debug (DEBUG_DOMAIN, "Remove finalized contact %p",
670 where_the_object_was);
672 account_data->contacts = g_list_remove (account_data->contacts,
673 where_the_object_was);
674 if (!account_data->contacts) {
675 EmpathyContactFactoryPriv *priv;
677 priv = GET_PRIV (account_data->factory);
679 g_hash_table_remove (priv->accounts, account_data->account);
684 contact_factory_remove_foreach (gpointer data,
687 ContactFactoryAccountData *account_data = user_data;
688 EmpathyContact *contact = data;
690 g_object_weak_unref (G_OBJECT (contact),
691 contact_factory_weak_notify,
695 static ContactFactoryAccountData *
696 contact_factory_account_data_new (EmpathyContactFactory *factory,
699 ContactFactoryAccountData *account_data;
701 account_data = g_slice_new0 (ContactFactoryAccountData);
702 account_data->factory = factory;
703 account_data->account = g_object_ref (account);
705 contact_factory_account_data_update (account_data);
711 contact_factory_account_data_free (gpointer data)
713 ContactFactoryAccountData *account_data = data;
715 contact_factory_account_data_disconnect (account_data);
717 if (account_data->contacts) {
718 g_list_foreach (account_data->contacts,
719 contact_factory_remove_foreach,
721 g_list_free (account_data->contacts);
722 account_data->contacts = NULL;
725 if (account_data->account) {
726 g_object_unref (account_data->account);
727 account_data->account = NULL;
730 if (account_data->tp_conn) {
731 g_object_unref (account_data->tp_conn);
732 account_data->tp_conn = NULL;
733 account_data->aliasing_iface = NULL;
734 account_data->avatars_iface = NULL;
735 account_data->presence_iface = NULL;
738 /* Keep the struct alive if we have calls in flight, it will be
739 * destroyed once all calls returned. */
740 if (account_data->nb_pending_calls == 0) {
741 g_slice_free (ContactFactoryAccountData, account_data);
746 contact_factory_status_changed_cb (MissionControl *mc,
747 TelepathyConnectionStatus status,
749 TelepathyConnectionStatusReason reason,
750 const gchar *unique_name,
751 EmpathyContactFactory *factory)
753 EmpathyContactFactoryPriv *priv = GET_PRIV (factory);
754 ContactFactoryAccountData *account_data;
757 account = mc_account_lookup (unique_name);
758 account_data = g_hash_table_lookup (priv->accounts, account);
760 contact_factory_account_data_update (account_data);
762 g_object_unref (account);
765 static ContactFactoryAccountData *
766 contact_factory_account_data_get (EmpathyContactFactory *factory,
769 EmpathyContactFactoryPriv *priv = GET_PRIV (factory);
770 ContactFactoryAccountData *account_data;
772 account_data = g_hash_table_lookup (priv->accounts, account);
774 account_data = contact_factory_account_data_new (factory, account);
775 g_hash_table_insert (priv->accounts,
776 g_object_ref (account),
784 contact_factory_account_data_add_contact (ContactFactoryAccountData *account_data,
785 EmpathyContact *contact)
787 g_object_weak_ref (G_OBJECT (contact),
788 contact_factory_weak_notify,
790 account_data->contacts = g_list_prepend (account_data->contacts, contact);
792 if (!account_data->presence_iface) {
793 EmpathyPresence *presence;
795 /* We have no presence iface, set default presence
797 presence = empathy_presence_new_full (MC_PRESENCE_AVAILABLE,
800 empathy_contact_set_presence (contact, presence);
801 g_object_unref (presence);
804 empathy_debug (DEBUG_DOMAIN, "Contact added: %s (%d)",
805 empathy_contact_get_id (contact),
806 empathy_contact_get_handle (contact));
810 contact_factory_hold_handles_cb (DBusGProxy *proxy,
815 empathy_debug (DEBUG_DOMAIN, "Failed to hold handles: %s",
821 empathy_contact_factory_get_user (EmpathyContactFactory *factory,
824 ContactFactoryAccountData *account_data;
826 g_return_val_if_fail (EMPATHY_IS_CONTACT_FACTORY (factory), NULL);
827 g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
829 account_data = contact_factory_account_data_get (factory, account);
831 return empathy_contact_factory_get_from_handle (factory, account,
832 account_data->self_handle);
836 empathy_contact_factory_get_from_id (EmpathyContactFactory *factory,
840 ContactFactoryAccountData *account_data;
841 EmpathyContact *contact;
843 g_return_val_if_fail (EMPATHY_IS_CONTACT_FACTORY (factory), NULL);
844 g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
845 g_return_val_if_fail (id != NULL, NULL);
847 /* Check if the contact already exists */
848 account_data = contact_factory_account_data_get (factory, account);
849 contact = contact_factory_account_data_find_by_id (account_data, id);
851 return g_object_ref (contact);
854 /* Create new contact */
855 contact = g_object_new (EMPATHY_TYPE_CONTACT,
859 contact_factory_account_data_add_contact (account_data, contact);
861 /* If the account is connected, request contact's handle */
862 if (account_data->tp_conn) {
863 RequestHandlesData *data;
864 const gchar *contact_ids[] = {id, NULL};
866 account_data->nb_pending_calls++;
867 data = g_slice_new (RequestHandlesData);
868 data->account_data = account_data;
869 data->contacts = g_list_prepend (NULL, g_object_ref (contact));
870 tp_conn_request_handles_async (DBUS_G_PROXY (account_data->tp_conn),
871 TP_HANDLE_TYPE_CONTACT,
873 contact_factory_request_handles_cb,
881 empathy_contact_factory_get_from_handle (EmpathyContactFactory *factory,
885 EmpathyContact *contact;
889 g_return_val_if_fail (EMPATHY_IS_CONTACT_FACTORY (factory), NULL);
890 g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
892 handles = g_array_new (FALSE, FALSE, sizeof (guint));
893 g_array_append_val (handles, handle);
895 contacts = empathy_contact_factory_get_from_handles (factory, account, handles);
896 g_array_free (handles, TRUE);
898 contact = contacts ? contacts->data : NULL;
899 g_list_free (contacts);
905 empathy_contact_factory_get_from_handles (EmpathyContactFactory *factory,
909 ContactFactoryAccountData *account_data;
910 GList *contacts = NULL;
912 gchar **handles_names;
914 GError *error = NULL;
916 g_return_val_if_fail (EMPATHY_IS_CONTACT_FACTORY (factory), NULL);
917 g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
918 g_return_val_if_fail (handles != NULL, NULL);
920 /* Search all contacts we already have */
921 account_data = contact_factory_account_data_get (factory, account);
922 new_handles = g_array_new (FALSE, FALSE, sizeof (guint));
923 for (i = 0; i < handles->len; i++) {
924 EmpathyContact *contact;
927 handle = g_array_index (handles, guint, i);
932 contact = contact_factory_account_data_find_by_handle (account_data, handle);
934 contacts = g_list_prepend (contacts, g_object_ref (contact));
936 g_array_append_val (new_handles, handle);
940 if (new_handles->len == 0) {
941 g_array_free (new_handles, TRUE);
945 /* Get the IDs of all new handles */
946 if (!tp_conn_inspect_handles (DBUS_G_PROXY (account_data->tp_conn),
947 TP_HANDLE_TYPE_CONTACT,
951 empathy_debug (DEBUG_DOMAIN,
952 "Couldn't inspect contact: %s",
953 error ? error->message : "No error given");
954 g_clear_error (&error);
955 g_array_free (new_handles, TRUE);
959 /* Create new contacts */
960 for (i = 0; i < new_handles->len; i++) {
961 EmpathyContact *contact;
966 id = handles_names[i];
967 handle = g_array_index (new_handles, guint, i);
969 is_user = (handle == account_data->self_handle);
970 contact = g_object_new (EMPATHY_TYPE_CONTACT,
976 contact_factory_account_data_add_contact (account_data,
978 contacts = g_list_prepend (contacts, contact);
981 g_free (handles_names);
983 /* Hold all new handles. */
984 tp_conn_hold_handles_async (DBUS_G_PROXY (account_data->tp_conn),
985 TP_HANDLE_TYPE_CONTACT,
987 contact_factory_hold_handles_cb,
990 contact_factory_request_everything (account_data, new_handles);
992 g_array_free (new_handles, TRUE);
998 empathy_contact_factory_set_name (EmpathyContactFactory *factory,
999 EmpathyContact *contact,
1002 ContactFactoryAccountData *account_data;
1004 GHashTable *new_alias;
1007 g_return_if_fail (EMPATHY_IS_CONTACT_FACTORY (factory));
1008 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
1010 account = empathy_contact_get_account (contact);
1011 account_data = contact_factory_account_data_get (factory, account);
1013 if (!account_data->aliasing_iface) {
1017 handle = empathy_contact_get_handle (contact);
1019 empathy_debug (DEBUG_DOMAIN, "Setting alias for contact %s (%d) to %s",
1020 empathy_contact_get_id (contact),
1023 new_alias = g_hash_table_new_full (g_direct_hash,
1028 g_hash_table_insert (new_alias,
1029 GUINT_TO_POINTER (handle),
1032 account_data->nb_pending_calls++;
1033 tp_conn_iface_aliasing_set_aliases_async (account_data->aliasing_iface,
1035 contact_factory_set_aliases_cb,
1038 g_hash_table_destroy (new_alias);
1042 contact_factory_finalize (GObject *object)
1044 EmpathyContactFactoryPriv *priv;
1046 priv = GET_PRIV (object);
1048 dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->mc),
1049 "AccountStatusChanged",
1050 G_CALLBACK (contact_factory_status_changed_cb),
1053 g_hash_table_destroy (priv->accounts);
1054 g_object_unref (priv->mc);
1056 G_OBJECT_CLASS (empathy_contact_factory_parent_class)->finalize (object);
1060 empathy_contact_factory_class_init (EmpathyContactFactoryClass *klass)
1062 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1064 object_class->finalize = contact_factory_finalize;
1066 g_type_class_add_private (object_class, sizeof (EmpathyContactFactoryPriv));
1070 empathy_contact_factory_init (EmpathyContactFactory *factory)
1072 EmpathyContactFactoryPriv *priv;
1074 priv = GET_PRIV (factory);
1076 priv->mc = empathy_mission_control_new ();
1077 priv->accounts = g_hash_table_new_full (empathy_account_hash,
1078 empathy_account_equal,
1080 contact_factory_account_data_free);
1082 dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->mc),
1083 "AccountStatusChanged",
1084 G_CALLBACK (contact_factory_status_changed_cb),
1088 EmpathyContactFactory *
1089 empathy_contact_factory_new (void)
1091 static EmpathyContactFactory *factory = NULL;
1094 factory = g_object_new (EMPATHY_TYPE_CONTACT_FACTORY, NULL);
1095 g_object_add_weak_pointer (G_OBJECT (factory), (gpointer) &factory);
1097 g_object_ref (factory);