1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2007-2009 Collabora Ltd.
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.
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.
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
19 * Authors: Xavier Claessens <xclaesse@gmail.com>
24 #include "empathy-tp-contact-factory.h"
26 #define DEBUG_FLAG EMPATHY_DEBUG_TP | EMPATHY_DEBUG_CONTACT
27 #include "empathy-debug.h"
29 static TpContactFeature contact_features[] = {
30 TP_CONTACT_FEATURE_ALIAS,
31 TP_CONTACT_FEATURE_PRESENCE,
32 TP_CONTACT_FEATURE_LOCATION,
33 TP_CONTACT_FEATURE_CAPABILITIES,
34 TP_CONTACT_FEATURE_CLIENT_TYPES,
38 EmpathyTpContactFactoryContactsByIdCb ids_cb;
39 EmpathyTpContactFactoryContactsByHandleCb handles_cb;
40 EmpathyTpContactFactoryContactCb contact_cb;
44 TpConnection *connection;
45 GetContactsCb callback;
47 GDestroyNotify destroy;
51 get_contacts_data_free (gpointer user_data)
53 GetContactsData *data = user_data;
56 data->destroy (data->user_data);
58 g_object_unref (data->connection);
60 g_slice_free (GetContactsData, data);
63 static EmpathyContact **
64 contacts_array_new (guint n_contacts,
65 TpContact * const * contacts)
70 ret = g_new0 (EmpathyContact *, n_contacts);
71 for (i = 0; i < n_contacts; i++) {
72 ret[i] = empathy_contact_dup_from_tp_contact (contacts[i]);
79 contacts_array_free (guint n_contacts,
80 EmpathyContact **contacts)
84 for (i = 0; i < n_contacts; i++) {
85 g_object_unref (contacts[i]);
91 get_contacts_by_id_cb (TpConnection *connection,
93 TpContact * const *contacts,
94 const gchar * const *requested_ids,
95 GHashTable *failed_id_errors,
100 GetContactsData *data = user_data;
101 EmpathyContact **empathy_contacts;
103 empathy_contacts = contacts_array_new (n_contacts, contacts);
104 if (data->callback.ids_cb) {
105 data->callback.ids_cb (data->connection,
106 n_contacts, empathy_contacts,
110 data->user_data, weak_object);
113 contacts_array_free (n_contacts, empathy_contacts);
116 /* The callback is NOT given a reference to the EmpathyContact objects */
118 empathy_tp_contact_factory_get_from_ids (TpConnection *connection,
120 const gchar * const *ids,
121 EmpathyTpContactFactoryContactsByIdCb callback,
123 GDestroyNotify destroy,
124 GObject *weak_object)
126 GetContactsData *data;
128 g_return_if_fail (TP_IS_CONNECTION (connection));
129 g_return_if_fail (ids != NULL);
131 data = g_slice_new (GetContactsData);
132 data->callback.ids_cb = callback;
133 data->user_data = user_data;
134 data->destroy = destroy;
135 data->connection = g_object_ref (connection);
136 tp_connection_get_contacts_by_id (connection,
138 G_N_ELEMENTS (contact_features),
140 get_contacts_by_id_cb,
142 (GDestroyNotify) get_contacts_data_free,
147 get_contact_by_id_cb (TpConnection *connection,
149 TpContact * const *contacts,
150 const gchar * const *requested_ids,
151 GHashTable *failed_id_errors,
154 GObject *weak_object)
156 GetContactsData *data = user_data;
157 EmpathyContact *contact = NULL;
159 if (n_contacts == 1) {
160 contact = empathy_contact_dup_from_tp_contact (contacts[0]);
162 else if (error == NULL) {
166 g_hash_table_iter_init (&iter, failed_id_errors);
167 while (g_hash_table_iter_next (&iter, NULL, &value)) {
175 if (data->callback.contact_cb) {
176 data->callback.contact_cb (data->connection,
179 data->user_data, weak_object);
183 g_object_unref (contact);
186 /* The callback is NOT given a reference to the EmpathyContact objects */
188 empathy_tp_contact_factory_get_from_id (TpConnection *connection,
190 EmpathyTpContactFactoryContactCb callback,
192 GDestroyNotify destroy,
193 GObject *weak_object)
195 GetContactsData *data;
197 g_return_if_fail (TP_IS_CONNECTION (connection));
198 g_return_if_fail (id != NULL);
200 data = g_slice_new (GetContactsData);
201 data->callback.contact_cb = callback;
202 data->user_data = user_data;
203 data->destroy = destroy;
204 data->connection = g_object_ref (connection);
205 tp_connection_get_contacts_by_id (connection,
207 G_N_ELEMENTS (contact_features),
209 get_contact_by_id_cb,
211 (GDestroyNotify) get_contacts_data_free,
216 get_contacts_by_handle_cb (TpConnection *connection,
218 TpContact * const *contacts,
220 const TpHandle *failed,
223 GObject *weak_object)
225 GetContactsData *data = user_data;
226 EmpathyContact **empathy_contacts;
228 empathy_contacts = contacts_array_new (n_contacts, contacts);
229 if (data->callback.handles_cb) {
230 data->callback.handles_cb (data->connection,
231 n_contacts, empathy_contacts,
234 data->user_data, weak_object);
237 contacts_array_free (n_contacts, empathy_contacts);
240 /* The callback is NOT given a reference to the EmpathyContact objects */
242 empathy_tp_contact_factory_get_from_handles (TpConnection *connection,
244 const TpHandle *handles,
245 EmpathyTpContactFactoryContactsByHandleCb callback,
247 GDestroyNotify destroy,
248 GObject *weak_object)
250 GetContactsData *data;
252 if (n_handles == 0) {
253 callback (connection, 0, NULL, 0, NULL, NULL, user_data, weak_object);
257 g_return_if_fail (TP_IS_CONNECTION (connection));
258 g_return_if_fail (handles != NULL);
260 data = g_slice_new (GetContactsData);
261 data->callback.handles_cb = callback;
262 data->user_data = user_data;
263 data->destroy = destroy;
264 data->connection = g_object_ref (connection);
265 tp_connection_get_contacts_by_handle (connection,
267 G_N_ELEMENTS (contact_features),
269 get_contacts_by_handle_cb,
271 (GDestroyNotify) get_contacts_data_free,
275 /* The callback is NOT given a reference to the EmpathyContact objects */
277 get_contact_by_handle_cb (TpConnection *connection,
279 TpContact * const *contacts,
281 const TpHandle *failed,
284 GObject *weak_object)
286 GetContactsData *data = user_data;
287 EmpathyContact *contact = NULL;
290 if (n_contacts == 1) {
291 contact = empathy_contact_dup_from_tp_contact (contacts[0]);
295 /* tp-glib will provide an error only if the whole operation failed,
296 * but not if, for example, the handle was invalid. We create an error
297 * so the caller of empathy_tp_contact_factory_get_from_handle can
298 * rely on the error to check if the operation succeeded or not. */
300 err = g_error_new_literal (TP_ERRORS, TP_ERROR_INVALID_HANDLE,
301 "handle is invalid");
304 err = g_error_copy (error);
308 if (data->callback.contact_cb) {
309 data->callback.contact_cb (data->connection,
312 data->user_data, weak_object);
315 g_clear_error (&err);
317 g_object_unref (contact);
321 empathy_tp_contact_factory_get_from_handle (TpConnection *connection,
323 EmpathyTpContactFactoryContactCb callback,
325 GDestroyNotify destroy,
326 GObject *weak_object)
328 GetContactsData *data;
330 g_return_if_fail (TP_IS_CONNECTION (connection));
332 data = g_slice_new (GetContactsData);
333 data->callback.contact_cb = callback;
334 data->user_data = user_data;
335 data->destroy = destroy;
336 data->connection = g_object_ref (connection);
337 tp_connection_get_contacts_by_handle (connection,
339 G_N_ELEMENTS (contact_features),
341 get_contact_by_handle_cb,
343 (GDestroyNotify) get_contacts_data_free,