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_TOKEN
,
32 TP_CONTACT_FEATURE_AVATAR_DATA
,
33 TP_CONTACT_FEATURE_PRESENCE
,
34 TP_CONTACT_FEATURE_LOCATION
,
35 TP_CONTACT_FEATURE_CAPABILITIES
,
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
,