]> git.0d.be Git - empathy.git/blob - libempathy/empathy-tp-contact-factory.c
tp-chat: use tp_text_channel_get_chat_state()
[empathy.git] / libempathy / empathy-tp-contact-factory.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2007-2009 Collabora Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library 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  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  *
19  * Authors: Xavier Claessens <xclaesse@gmail.com>
20  */
21
22 #include <config.h>
23
24 #include "empathy-tp-contact-factory.h"
25
26 #define DEBUG_FLAG EMPATHY_DEBUG_TP | EMPATHY_DEBUG_CONTACT
27 #include "empathy-debug.h"
28
29 static TpContactFeature contact_features[] = {
30         TP_CONTACT_FEATURE_ALIAS,
31         TP_CONTACT_FEATURE_AVATAR_DATA,
32         TP_CONTACT_FEATURE_PRESENCE,
33         TP_CONTACT_FEATURE_LOCATION,
34         TP_CONTACT_FEATURE_CAPABILITIES,
35         TP_CONTACT_FEATURE_CLIENT_TYPES,
36 };
37
38 typedef union {
39         EmpathyTpContactFactoryContactCb contact_cb;
40 } GetContactsCb;
41
42 typedef struct {
43         TpConnection *connection;
44         GetContactsCb callback;
45         gpointer user_data;
46         GDestroyNotify destroy;
47 } GetContactsData;
48
49 static void
50 get_contacts_data_free (gpointer user_data)
51 {
52         GetContactsData *data = user_data;
53
54         if (data->destroy) {
55                 data->destroy (data->user_data);
56         }
57         g_object_unref (data->connection);
58
59         g_slice_free (GetContactsData, data);
60 }
61
62 static void
63 get_contact_by_id_cb (TpConnection *connection,
64                       guint n_contacts,
65                       TpContact * const *contacts,
66                       const gchar * const *requested_ids,
67                       GHashTable *failed_id_errors,
68                       const GError *error,
69                       gpointer user_data,
70                       GObject *weak_object)
71 {
72         GetContactsData *data = user_data;
73         EmpathyContact  *contact = NULL;
74
75         if (n_contacts == 1) {
76                 contact = empathy_contact_dup_from_tp_contact (contacts[0]);
77         }
78         else if (error == NULL) {
79                 GHashTableIter iter;
80                 gpointer       value;
81
82                 g_hash_table_iter_init (&iter, failed_id_errors);
83                 while (g_hash_table_iter_next (&iter, NULL, &value)) {
84                         if (value) {
85                                 error = value;
86                                 break;
87                         }
88                 }
89         }
90
91         if (data->callback.contact_cb) {
92                 data->callback.contact_cb (data->connection,
93                                            contact,
94                                            error,
95                                            data->user_data, weak_object);
96         }
97
98         if (contact != NULL)
99                 g_object_unref (contact);
100 }
101
102 /* The callback is NOT given a reference to the EmpathyContact objects */
103 void
104 empathy_tp_contact_factory_get_from_id (TpConnection            *connection,
105                                         const gchar             *id,
106                                         EmpathyTpContactFactoryContactCb callback,
107                                         gpointer                 user_data,
108                                         GDestroyNotify           destroy,
109                                         GObject                 *weak_object)
110 {
111         GetContactsData *data;
112
113         g_return_if_fail (TP_IS_CONNECTION (connection));
114         g_return_if_fail (id != NULL);
115
116         data = g_slice_new (GetContactsData);
117         data->callback.contact_cb = callback;
118         data->user_data = user_data;
119         data->destroy = destroy;
120         data->connection = g_object_ref (connection);
121         tp_connection_get_contacts_by_id (connection,
122                                           1, &id,
123                                           G_N_ELEMENTS (contact_features),
124                                           contact_features,
125                                           get_contact_by_id_cb,
126                                           data,
127                                           (GDestroyNotify) get_contacts_data_free,
128                                           weak_object);
129 }
130
131 /* The callback is NOT given a reference to the EmpathyContact objects */
132 static void
133 get_contact_by_handle_cb (TpConnection *connection,
134                           guint n_contacts,
135                           TpContact * const *contacts,
136                           guint n_failed,
137                           const TpHandle *failed,
138                           const GError *error,
139                           gpointer user_data,
140                           GObject *weak_object)
141 {
142         GetContactsData *data = user_data;
143         EmpathyContact  *contact = NULL;
144         GError *err = NULL;
145
146         if (n_contacts == 1) {
147                 contact = empathy_contact_dup_from_tp_contact (contacts[0]);
148         }
149         else {
150                 if (error == NULL) {
151                         /* tp-glib will provide an error only if the whole operation failed,
152                          * but not if, for example, the handle was invalid. We create an error
153                          * so the caller of empathy_tp_contact_factory_get_from_handle can
154                          * rely on the error to check if the operation succeeded or not. */
155
156                         err = g_error_new_literal (TP_ERROR, TP_ERROR_INVALID_HANDLE,
157                                                       "handle is invalid");
158                 }
159                 else {
160                         err = g_error_copy (error);
161                 }
162         }
163
164         if (data->callback.contact_cb) {
165                 data->callback.contact_cb (data->connection,
166                                            contact,
167                                            err,
168                                            data->user_data, weak_object);
169         }
170
171         g_clear_error (&err);
172         if (contact != NULL)
173                 g_object_unref (contact);
174 }
175
176 void
177 empathy_tp_contact_factory_get_from_handle (TpConnection            *connection,
178                                             TpHandle                 handle,
179                                             EmpathyTpContactFactoryContactCb callback,
180                                             gpointer                 user_data,
181                                             GDestroyNotify           destroy,
182                                             GObject                 *weak_object)
183 {
184         GetContactsData *data;
185
186         g_return_if_fail (TP_IS_CONNECTION (connection));
187
188         data = g_slice_new (GetContactsData);
189         data->callback.contact_cb = callback;
190         data->user_data = user_data;
191         data->destroy = destroy;
192         data->connection = g_object_ref (connection);
193         tp_connection_get_contacts_by_handle (connection,
194                                               1, &handle,
195                                               G_N_ELEMENTS (contact_features),
196                                               contact_features,
197                                               get_contact_by_handle_cb,
198                                               data,
199                                               (GDestroyNotify) get_contacts_data_free,
200                                               weak_object);
201 }
202