build: remove -enumtypes rules
[empathy-mirror.git] / libempathy / empathy-tp-contact-factory.c
blob681c882eec72e6753eba8af23c6824bb7bf62a59
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
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>
22 #include <config.h>
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,
38 typedef union {
39 EmpathyTpContactFactoryContactsByIdCb ids_cb;
40 EmpathyTpContactFactoryContactsByHandleCb handles_cb;
41 EmpathyTpContactFactoryContactCb contact_cb;
42 } GetContactsCb;
44 typedef struct {
45 TpConnection *connection;
46 GetContactsCb callback;
47 gpointer user_data;
48 GDestroyNotify destroy;
49 } GetContactsData;
51 static void
52 get_contacts_data_free (gpointer user_data)
54 GetContactsData *data = user_data;
56 if (data->destroy) {
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)
68 EmpathyContact **ret;
69 guint i;
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]);
76 return ret;
79 static void
80 contacts_array_free (guint n_contacts,
81 EmpathyContact **contacts)
83 guint i;
85 for (i = 0; i < n_contacts; i++) {
86 g_object_unref (contacts[i]);
88 g_free (contacts);
91 static void
92 get_contacts_by_id_cb (TpConnection *connection,
93 guint n_contacts,
94 TpContact * const *contacts,
95 const gchar * const *requested_ids,
96 GHashTable *failed_id_errors,
97 const GError *error,
98 gpointer user_data,
99 GObject *weak_object)
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,
108 requested_ids,
109 failed_id_errors,
110 error,
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 */
118 void
119 empathy_tp_contact_factory_get_from_ids (TpConnection *connection,
120 guint n_ids,
121 const gchar * const *ids,
122 EmpathyTpContactFactoryContactsByIdCb callback,
123 gpointer user_data,
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,
138 n_ids, ids,
139 G_N_ELEMENTS (contact_features),
140 contact_features,
141 get_contacts_by_id_cb,
142 data,
143 (GDestroyNotify) get_contacts_data_free,
144 weak_object);
147 static void
148 get_contact_by_id_cb (TpConnection *connection,
149 guint n_contacts,
150 TpContact * const *contacts,
151 const gchar * const *requested_ids,
152 GHashTable *failed_id_errors,
153 const GError *error,
154 gpointer user_data,
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) {
164 GHashTableIter iter;
165 gpointer value;
167 g_hash_table_iter_init (&iter, failed_id_errors);
168 while (g_hash_table_iter_next (&iter, NULL, &value)) {
169 if (value) {
170 error = value;
171 break;
176 if (data->callback.contact_cb) {
177 data->callback.contact_cb (data->connection,
178 contact,
179 error,
180 data->user_data, weak_object);
183 if (contact != NULL)
184 g_object_unref (contact);
187 /* The callback is NOT given a reference to the EmpathyContact objects */
188 void
189 empathy_tp_contact_factory_get_from_id (TpConnection *connection,
190 const gchar *id,
191 EmpathyTpContactFactoryContactCb callback,
192 gpointer user_data,
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,
207 1, &id,
208 G_N_ELEMENTS (contact_features),
209 contact_features,
210 get_contact_by_id_cb,
211 data,
212 (GDestroyNotify) get_contacts_data_free,
213 weak_object);
216 static void
217 get_contacts_by_handle_cb (TpConnection *connection,
218 guint n_contacts,
219 TpContact * const *contacts,
220 guint n_failed,
221 const TpHandle *failed,
222 const GError *error,
223 gpointer user_data,
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,
233 n_failed, failed,
234 error,
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 */
242 void
243 empathy_tp_contact_factory_get_from_handles (TpConnection *connection,
244 guint n_handles,
245 const TpHandle *handles,
246 EmpathyTpContactFactoryContactsByHandleCb callback,
247 gpointer user_data,
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);
255 return;
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,
267 n_handles, handles,
268 G_N_ELEMENTS (contact_features),
269 contact_features,
270 get_contacts_by_handle_cb,
271 data,
272 (GDestroyNotify) get_contacts_data_free,
273 weak_object);
276 /* The callback is NOT given a reference to the EmpathyContact objects */
277 static void
278 get_contact_by_handle_cb (TpConnection *connection,
279 guint n_contacts,
280 TpContact * const *contacts,
281 guint n_failed,
282 const TpHandle *failed,
283 const GError *error,
284 gpointer user_data,
285 GObject *weak_object)
287 GetContactsData *data = user_data;
288 EmpathyContact *contact = NULL;
289 GError *err = NULL;
291 if (n_contacts == 1) {
292 contact = empathy_contact_dup_from_tp_contact (contacts[0]);
294 else {
295 if (error == NULL) {
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");
304 else {
305 err = g_error_copy (error);
309 if (data->callback.contact_cb) {
310 data->callback.contact_cb (data->connection,
311 contact,
312 err,
313 data->user_data, weak_object);
316 g_clear_error (&err);
317 if (contact != NULL)
318 g_object_unref (contact);
321 void
322 empathy_tp_contact_factory_get_from_handle (TpConnection *connection,
323 TpHandle handle,
324 EmpathyTpContactFactoryContactCb callback,
325 gpointer user_data,
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,
339 1, &handle,
340 G_N_ELEMENTS (contact_features),
341 contact_features,
342 get_contact_by_handle_cb,
343 data,
344 (GDestroyNotify) get_contacts_data_free,
345 weak_object);