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,
37 EmpathyTpContactFactoryContactsByIdCb ids_cb;
38 EmpathyTpContactFactoryContactsByHandleCb handles_cb;
39 EmpathyTpContactFactoryContactCb contact_cb;
43 TpConnection *connection;
44 GetContactsCb callback;
46 GDestroyNotify destroy;
50 get_contacts_data_free (gpointer user_data)
52 GetContactsData *data = user_data;
55 data->destroy (data->user_data);
57 g_object_unref (data->connection);
59 g_slice_free (GetContactsData, data);
62 static EmpathyContact **
63 contacts_array_new (guint n_contacts,
64 TpContact * const * contacts)
69 ret = g_new0 (EmpathyContact *, n_contacts);
70 for (i = 0; i < n_contacts; i++) {
71 ret[i] = empathy_contact_dup_from_tp_contact (contacts[i]);
78 contacts_array_free (guint n_contacts,
79 EmpathyContact **contacts)
83 for (i = 0; i < n_contacts; i++) {
84 g_object_unref (contacts[i]);
90 get_contacts_by_id_cb (TpConnection *connection,
92 TpContact * const *contacts,
93 const gchar * const *requested_ids,
94 GHashTable *failed_id_errors,
99 GetContactsData *data = user_data;
100 EmpathyContact **empathy_contacts;
102 empathy_contacts = contacts_array_new (n_contacts, contacts);
103 if (data->callback.ids_cb) {
104 data->callback.ids_cb (data->connection,
105 n_contacts, empathy_contacts,
109 data->user_data, weak_object);
112 contacts_array_free (n_contacts, empathy_contacts);
115 /* The callback is NOT given a reference to the EmpathyContact objects */
117 empathy_tp_contact_factory_get_from_ids (TpConnection *connection,
119 const gchar * const *ids,
120 EmpathyTpContactFactoryContactsByIdCb callback,
122 GDestroyNotify destroy,
123 GObject *weak_object)
125 GetContactsData *data;
127 g_return_if_fail (TP_IS_CONNECTION (connection));
128 g_return_if_fail (ids != NULL);
130 data = g_slice_new (GetContactsData);
131 data->callback.ids_cb = callback;
132 data->user_data = user_data;
133 data->destroy = destroy;
134 data->connection = g_object_ref (connection);
135 tp_connection_get_contacts_by_id (connection,
137 G_N_ELEMENTS (contact_features),
139 get_contacts_by_id_cb,
141 (GDestroyNotify) get_contacts_data_free,
146 get_contact_by_id_cb (TpConnection *connection,
148 TpContact * const *contacts,
149 const gchar * const *requested_ids,
150 GHashTable *failed_id_errors,
153 GObject *weak_object)
155 GetContactsData *data = user_data;
156 EmpathyContact *contact = NULL;
158 if (n_contacts == 1) {
159 contact = empathy_contact_dup_from_tp_contact (contacts[0]);
161 else if (error == NULL) {
165 g_hash_table_iter_init (&iter, failed_id_errors);
166 while (g_hash_table_iter_next (&iter, NULL, &value)) {
174 if (data->callback.contact_cb) {
175 data->callback.contact_cb (data->connection,
178 data->user_data, weak_object);
182 g_object_unref (contact);
185 /* The callback is NOT given a reference to the EmpathyContact objects */
187 empathy_tp_contact_factory_get_from_id (TpConnection *connection,
189 EmpathyTpContactFactoryContactCb callback,
191 GDestroyNotify destroy,
192 GObject *weak_object)
194 GetContactsData *data;
196 g_return_if_fail (TP_IS_CONNECTION (connection));
197 g_return_if_fail (id != NULL);
199 data = g_slice_new (GetContactsData);
200 data->callback.contact_cb = callback;
201 data->user_data = user_data;
202 data->destroy = destroy;
203 data->connection = g_object_ref (connection);
204 tp_connection_get_contacts_by_id (connection,
206 G_N_ELEMENTS (contact_features),
208 get_contact_by_id_cb,
210 (GDestroyNotify) get_contacts_data_free,
215 get_contacts_by_handle_cb (TpConnection *connection,
217 TpContact * const *contacts,
219 const TpHandle *failed,
222 GObject *weak_object)
224 GetContactsData *data = user_data;
225 EmpathyContact **empathy_contacts;
227 empathy_contacts = contacts_array_new (n_contacts, contacts);
228 if (data->callback.handles_cb) {
229 data->callback.handles_cb (data->connection,
230 n_contacts, empathy_contacts,
233 data->user_data, weak_object);
236 contacts_array_free (n_contacts, empathy_contacts);
239 /* The callback is NOT given a reference to the EmpathyContact objects */
241 empathy_tp_contact_factory_get_from_handles (TpConnection *connection,
243 const TpHandle *handles,
244 EmpathyTpContactFactoryContactsByHandleCb callback,
246 GDestroyNotify destroy,
247 GObject *weak_object)
249 GetContactsData *data;
251 if (n_handles == 0) {
252 callback (connection, 0, NULL, 0, NULL, NULL, user_data, weak_object);
256 g_return_if_fail (TP_IS_CONNECTION (connection));
257 g_return_if_fail (handles != NULL);
259 data = g_slice_new (GetContactsData);
260 data->callback.handles_cb = callback;
261 data->user_data = user_data;
262 data->destroy = destroy;
263 data->connection = g_object_ref (connection);
264 tp_connection_get_contacts_by_handle (connection,
266 G_N_ELEMENTS (contact_features),
268 get_contacts_by_handle_cb,
270 (GDestroyNotify) get_contacts_data_free,
274 /* The callback is NOT given a reference to the EmpathyContact objects */
276 get_contact_by_handle_cb (TpConnection *connection,
278 TpContact * const *contacts,
280 const TpHandle *failed,
283 GObject *weak_object)
285 GetContactsData *data = user_data;
286 EmpathyContact *contact = NULL;
289 if (n_contacts == 1) {
290 contact = empathy_contact_dup_from_tp_contact (contacts[0]);
294 /* tp-glib will provide an error only if the whole operation failed,
295 * but not if, for example, the handle was invalid. We create an error
296 * so the caller of empathy_tp_contact_factory_get_from_handle can
297 * rely on the error to check if the operation succeeded or not. */
299 err = g_error_new_literal (TP_ERRORS, TP_ERROR_INVALID_HANDLE,
300 "handle is invalid");
303 err = g_error_copy (error);
307 if (data->callback.contact_cb) {
308 data->callback.contact_cb (data->connection,
311 data->user_data, weak_object);
314 g_clear_error (&err);
316 g_object_unref (contact);
320 empathy_tp_contact_factory_get_from_handle (TpConnection *connection,
322 EmpathyTpContactFactoryContactCb callback,
324 GDestroyNotify destroy,
325 GObject *weak_object)
327 GetContactsData *data;
329 g_return_if_fail (TP_IS_CONNECTION (connection));
331 data = g_slice_new (GetContactsData);
332 data->callback.contact_cb = callback;
333 data->user_data = user_data;
334 data->destroy = destroy;
335 data->connection = g_object_ref (connection);
336 tp_connection_get_contacts_by_handle (connection,
338 G_N_ELEMENTS (contact_features),
340 get_contact_by_handle_cb,
342 (GDestroyNotify) get_contacts_data_free,