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_AVATAR_DATA,
32 TP_CONTACT_FEATURE_PRESENCE,
33 TP_CONTACT_FEATURE_LOCATION,
34 TP_CONTACT_FEATURE_CAPABILITIES,
35 TP_CONTACT_FEATURE_CLIENT_TYPES,
39 EmpathyTpContactFactoryContactsByIdCb ids_cb;
40 EmpathyTpContactFactoryContactsByHandleCb handles_cb;
41 EmpathyTpContactFactoryContactCb contact_cb;
45 TpConnection *connection;
46 GetContactsCb callback;
48 GDestroyNotify destroy;
52 get_contacts_data_free (gpointer user_data)
54 GetContactsData *data = user_data;
57 data->destroy (data->user_data);
59 g_object_unref (data->connection);
61 g_slice_free (GetContactsData, data);
64 static EmpathyContact **
65 contacts_array_new (guint n_contacts,
66 TpContact * const * contacts)
71 ret = g_new0 (EmpathyContact *, n_contacts);
72 for (i = 0; i < n_contacts; i++) {
73 ret[i] = empathy_contact_dup_from_tp_contact (contacts[i]);
80 contacts_array_free (guint n_contacts,
81 EmpathyContact **contacts)
85 for (i = 0; i < n_contacts; i++) {
86 g_object_unref (contacts[i]);
92 get_contacts_by_id_cb (TpConnection *connection,
94 TpContact * const *contacts,
95 const gchar * const *requested_ids,
96 GHashTable *failed_id_errors,
101 GetContactsData *data = user_data;
102 EmpathyContact **empathy_contacts;
104 empathy_contacts = contacts_array_new (n_contacts, contacts);
105 if (data->callback.ids_cb) {
106 data->callback.ids_cb (data->connection,
107 n_contacts, empathy_contacts,
111 data->user_data, weak_object);
114 contacts_array_free (n_contacts, empathy_contacts);
117 /* The callback is NOT given a reference to the EmpathyContact objects */
119 empathy_tp_contact_factory_get_from_ids (TpConnection *connection,
121 const gchar * const *ids,
122 EmpathyTpContactFactoryContactsByIdCb callback,
124 GDestroyNotify destroy,
125 GObject *weak_object)
127 GetContactsData *data;
129 g_return_if_fail (TP_IS_CONNECTION (connection));
130 g_return_if_fail (ids != NULL);
132 data = g_slice_new (GetContactsData);
133 data->callback.ids_cb = callback;
134 data->user_data = user_data;
135 data->destroy = destroy;
136 data->connection = g_object_ref (connection);
137 tp_connection_get_contacts_by_id (connection,
139 G_N_ELEMENTS (contact_features),
141 get_contacts_by_id_cb,
143 (GDestroyNotify) get_contacts_data_free,
148 get_contact_by_id_cb (TpConnection *connection,
150 TpContact * const *contacts,
151 const gchar * const *requested_ids,
152 GHashTable *failed_id_errors,
155 GObject *weak_object)
157 GetContactsData *data = user_data;
158 EmpathyContact *contact = NULL;
160 if (n_contacts == 1) {
161 contact = empathy_contact_dup_from_tp_contact (contacts[0]);
163 else if (error == NULL) {
167 g_hash_table_iter_init (&iter, failed_id_errors);
168 while (g_hash_table_iter_next (&iter, NULL, &value)) {
176 if (data->callback.contact_cb) {
177 data->callback.contact_cb (data->connection,
180 data->user_data, weak_object);
184 g_object_unref (contact);
187 /* The callback is NOT given a reference to the EmpathyContact objects */
189 empathy_tp_contact_factory_get_from_id (TpConnection *connection,
191 EmpathyTpContactFactoryContactCb callback,
193 GDestroyNotify destroy,
194 GObject *weak_object)
196 GetContactsData *data;
198 g_return_if_fail (TP_IS_CONNECTION (connection));
199 g_return_if_fail (id != NULL);
201 data = g_slice_new (GetContactsData);
202 data->callback.contact_cb = callback;
203 data->user_data = user_data;
204 data->destroy = destroy;
205 data->connection = g_object_ref (connection);
206 tp_connection_get_contacts_by_id (connection,
208 G_N_ELEMENTS (contact_features),
210 get_contact_by_id_cb,
212 (GDestroyNotify) get_contacts_data_free,
217 get_contacts_by_handle_cb (TpConnection *connection,
219 TpContact * const *contacts,
221 const TpHandle *failed,
224 GObject *weak_object)
226 GetContactsData *data = user_data;
227 EmpathyContact **empathy_contacts;
229 empathy_contacts = contacts_array_new (n_contacts, contacts);
230 if (data->callback.handles_cb) {
231 data->callback.handles_cb (data->connection,
232 n_contacts, empathy_contacts,
235 data->user_data, weak_object);
238 contacts_array_free (n_contacts, empathy_contacts);
241 /* The callback is NOT given a reference to the EmpathyContact objects */
243 empathy_tp_contact_factory_get_from_handles (TpConnection *connection,
245 const TpHandle *handles,
246 EmpathyTpContactFactoryContactsByHandleCb callback,
248 GDestroyNotify destroy,
249 GObject *weak_object)
251 GetContactsData *data;
253 if (n_handles == 0) {
254 callback (connection, 0, NULL, 0, NULL, NULL, user_data, weak_object);
258 g_return_if_fail (TP_IS_CONNECTION (connection));
259 g_return_if_fail (handles != NULL);
261 data = g_slice_new (GetContactsData);
262 data->callback.handles_cb = callback;
263 data->user_data = user_data;
264 data->destroy = destroy;
265 data->connection = g_object_ref (connection);
266 tp_connection_get_contacts_by_handle (connection,
268 G_N_ELEMENTS (contact_features),
270 get_contacts_by_handle_cb,
272 (GDestroyNotify) get_contacts_data_free,
276 /* The callback is NOT given a reference to the EmpathyContact objects */
278 get_contact_by_handle_cb (TpConnection *connection,
280 TpContact * const *contacts,
282 const TpHandle *failed,
285 GObject *weak_object)
287 GetContactsData *data = user_data;
288 EmpathyContact *contact = NULL;
291 if (n_contacts == 1) {
292 contact = empathy_contact_dup_from_tp_contact (contacts[0]);
296 /* tp-glib will provide an error only if the whole operation failed,
297 * but not if, for example, the handle was invalid. We create an error
298 * so the caller of empathy_tp_contact_factory_get_from_handle can
299 * rely on the error to check if the operation succeeded or not. */
301 err = g_error_new_literal (TP_ERRORS, TP_ERROR_INVALID_HANDLE,
302 "handle is invalid");
305 err = g_error_copy (error);
309 if (data->callback.contact_cb) {
310 data->callback.contact_cb (data->connection,
313 data->user_data, weak_object);
316 g_clear_error (&err);
318 g_object_unref (contact);
322 empathy_tp_contact_factory_get_from_handle (TpConnection *connection,
324 EmpathyTpContactFactoryContactCb callback,
326 GDestroyNotify destroy,
327 GObject *weak_object)
329 GetContactsData *data;
331 g_return_if_fail (TP_IS_CONNECTION (connection));
333 data = g_slice_new (GetContactsData);
334 data->callback.contact_cb = callback;
335 data->user_data = user_data;
336 data->destroy = destroy;
337 data->connection = g_object_ref (connection);
338 tp_connection_get_contacts_by_handle (connection,
340 G_N_ELEMENTS (contact_features),
342 get_contact_by_handle_cb,
344 (GDestroyNotify) get_contacts_data_free,