Mercurial > pidgin
comparison libpurple/disco.c @ 26974:c2cd559e034f
propagate from branch 'im.pidgin.pidgin' (head 97fbf033d9afea69a6eabaac94698b3c051584cf)
to branch 'im.pidgin.cpw.darkrain42.xmpp.disco' (head d1274de628e3e7c76742ebf0941b7d104e19dceb)
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sat, 23 May 2009 22:46:28 +0000 |
parents | ba99ee519926 |
children |
comparison
equal
deleted
inserted
replaced
26942:7957a5ed53bb | 26974:c2cd559e034f |
---|---|
1 /** | |
2 * @file disco.c Service Discovery API | |
3 * @ingroup core | |
4 */ | |
5 | |
6 /* purple | |
7 * | |
8 * Purple is the legal property of its developers, whose names are too numerous | |
9 * to list here. Please refer to the COPYRIGHT file distributed with this | |
10 * source distribution. | |
11 * | |
12 * This program is free software; you can redistribute it and/or modify | |
13 * it under the terms of the GNU General Public License as published by | |
14 * the Free Software Foundation; either version 2 of the License, or | |
15 * (at your option) any later version. | |
16 * | |
17 * This program is distributed in the hope that it will be useful, | |
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 * GNU General Public License for more details. | |
21 * | |
22 * You should have received a copy of the GNU General Public License | |
23 * along with this program; if not, write to the Free Software | |
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA | |
25 */ | |
26 | |
27 #include "internal.h" | |
28 #include "debug.h" | |
29 | |
30 #include "disco.h" | |
31 | |
32 /**************************************************************************/ | |
33 /* Main structures, members and constants */ | |
34 /**************************************************************************/ | |
35 | |
36 /** | |
37 * Represents a list of services for a given connection on a given protocol. | |
38 */ | |
39 struct _PurpleDiscoList { | |
40 PurpleAccount *account; /**< The account this list belongs to. */ | |
41 GList *services; /**< The list of services. */ | |
42 | |
43 gboolean in_progress; | |
44 | |
45 gpointer ui_data; /**< UI private data. */ | |
46 gpointer proto_data; /**< Prpl private data. */ | |
47 guint ref; /**< The reference count. */ | |
48 | |
49 struct { | |
50 PurpleDiscoCancelFunc cancel_cb; | |
51 PurpleDiscoCloseFunc close_cb; /**< Callback to free the prpl data */ | |
52 PurpleDiscoServiceCloseFunc service_close_cb; | |
53 PurpleDiscoServiceExpandFunc expand_cb; /**< Expand a service (iteratively | |
54 look for things that are | |
55 "sub-elements" in the tree */ | |
56 PurpleDiscoRegisterFunc register_cb; | |
57 } ops; | |
58 }; | |
59 | |
60 /** | |
61 * Represents a list of services for a given connection on a given protocol. | |
62 */ | |
63 struct _PurpleDiscoService { | |
64 PurpleDiscoList *list; | |
65 gchar *name; /**< The name of the service. */ | |
66 gchar *description; /**< The name of the service. */ | |
67 | |
68 gpointer proto_data; | |
69 | |
70 gchar *gateway_type; /**< The type of the gateway service. */ | |
71 PurpleDiscoServiceType type; /**< The type of service. */ | |
72 PurpleDiscoServiceFlags flags; | |
73 }; | |
74 | |
75 static PurpleDiscoUiOps *ops = NULL; | |
76 | |
77 PurpleDiscoList *purple_disco_list_new(PurpleAccount *account) | |
78 { | |
79 PurpleDiscoList *list; | |
80 | |
81 g_return_val_if_fail(account != NULL, NULL); | |
82 | |
83 list = g_new0(PurpleDiscoList, 1); | |
84 list->account = account; | |
85 list->ref = 1; | |
86 | |
87 if (ops && ops->create) | |
88 ops->create(list); | |
89 | |
90 return list; | |
91 } | |
92 | |
93 PurpleDiscoList *purple_disco_list_ref(PurpleDiscoList *list) | |
94 { | |
95 g_return_val_if_fail(list != NULL, NULL); | |
96 | |
97 list->ref++; | |
98 purple_debug_misc("disco", "reffing list, ref count now %d\n", list->ref); | |
99 | |
100 return list; | |
101 } | |
102 | |
103 static void purple_disco_list_service_destroy(PurpleDiscoList *list, PurpleDiscoService *r) | |
104 { | |
105 if (list->ops.service_close_cb) | |
106 list->ops.service_close_cb(r); | |
107 | |
108 g_free(r->name); | |
109 g_free(r->description); | |
110 g_free(r->gateway_type); | |
111 g_free(r); | |
112 } | |
113 | |
114 static void purple_disco_list_destroy(PurpleDiscoList *list) | |
115 { | |
116 GList *l; | |
117 | |
118 purple_debug_misc("disco", "destroying list %p\n", list); | |
119 | |
120 if (ops && ops->destroy) | |
121 ops->destroy(list); | |
122 | |
123 if (list->ops.close_cb) | |
124 list->ops.close_cb(list); | |
125 | |
126 for (l = list->services; l; l = l->next) { | |
127 PurpleDiscoService *s = l->data; | |
128 purple_disco_list_service_destroy(list, s); | |
129 } | |
130 g_list_free(list->services); | |
131 | |
132 g_free(list); | |
133 } | |
134 | |
135 void purple_disco_list_unref(PurpleDiscoList *list) | |
136 { | |
137 g_return_if_fail(list != NULL); | |
138 g_return_if_fail(list->ref > 0); | |
139 | |
140 list->ref--; | |
141 | |
142 purple_debug_misc("disco", "unreffing list, ref count now %d\n", list->ref); | |
143 if (list->ref == 0) | |
144 purple_disco_list_destroy(list); | |
145 } | |
146 | |
147 void purple_disco_list_service_add(PurpleDiscoList *list, | |
148 PurpleDiscoService *service, | |
149 PurpleDiscoService *parent) | |
150 { | |
151 g_return_if_fail(list != NULL); | |
152 g_return_if_fail(service != NULL); | |
153 | |
154 list->services = g_list_append(list->services, service); | |
155 service->list = list; | |
156 | |
157 if (ops && ops->add_service) | |
158 ops->add_service(list, service, parent); | |
159 } | |
160 | |
161 PurpleDiscoService *purple_disco_list_service_new(PurpleDiscoServiceType type, | |
162 const gchar *name, const gchar *description, | |
163 PurpleDiscoServiceFlags flags, gpointer proto_data) | |
164 { | |
165 PurpleDiscoService *s; | |
166 | |
167 g_return_val_if_fail(name != NULL, NULL); | |
168 g_return_val_if_fail(type != PURPLE_DISCO_SERVICE_TYPE_UNSET, NULL); | |
169 | |
170 s = g_new0(PurpleDiscoService, 1); | |
171 s->name = g_strdup(name); | |
172 s->type = type; | |
173 s->description = g_strdup(description); | |
174 s->flags = flags; | |
175 s->proto_data = proto_data; | |
176 | |
177 return s; | |
178 } | |
179 | |
180 PurpleDiscoList *purple_disco_get_list(PurpleConnection *pc) | |
181 { | |
182 PurplePlugin *prpl = NULL; | |
183 PurplePluginProtocolInfo *prpl_info = NULL; | |
184 | |
185 g_return_val_if_fail(pc != NULL, NULL); | |
186 | |
187 prpl = purple_connection_get_prpl(pc); | |
188 if (prpl != NULL) | |
189 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); | |
190 | |
191 if (prpl_info && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, disco_get_list)) | |
192 return prpl_info->disco_get_list(pc); | |
193 | |
194 return NULL; | |
195 } | |
196 | |
197 void purple_disco_cancel_get_list(PurpleDiscoList *list) | |
198 { | |
199 PurpleConnection *pc; | |
200 | |
201 g_return_if_fail(list != NULL); | |
202 | |
203 pc = purple_account_get_connection(list->account); | |
204 | |
205 g_return_if_fail(pc != NULL); | |
206 | |
207 if (list->ops.cancel_cb) | |
208 list->ops.cancel_cb(list); | |
209 | |
210 purple_disco_list_set_in_progress(list, FALSE); | |
211 } | |
212 | |
213 void purple_disco_service_expand(PurpleDiscoService *service) | |
214 { | |
215 PurpleDiscoList *list; | |
216 PurpleConnection *pc; | |
217 | |
218 g_return_if_fail(service != NULL); | |
219 g_return_if_fail((service->flags & PURPLE_DISCO_BROWSE)); | |
220 | |
221 list = service->list; | |
222 pc = purple_account_get_connection(list->account); | |
223 | |
224 g_return_if_fail(pc != NULL); | |
225 | |
226 purple_disco_list_set_in_progress(list, TRUE); | |
227 | |
228 if (list->ops.expand_cb) | |
229 list->ops.expand_cb(list, service); | |
230 else | |
231 purple_debug_warning("disco", "Cannot expand %s for account %s, " | |
232 "protocol did not provide expand op.\n", | |
233 service->name, | |
234 purple_account_get_username(list->account)); | |
235 } | |
236 | |
237 void purple_disco_service_register(PurpleDiscoService *service) | |
238 { | |
239 PurpleDiscoList *list; | |
240 PurpleConnection *pc; | |
241 | |
242 g_return_if_fail(service != NULL); | |
243 | |
244 list = service->list; | |
245 pc = purple_account_get_connection(list->account); | |
246 | |
247 g_return_if_fail(pc != NULL); | |
248 | |
249 if (list->ops.register_cb) | |
250 list->ops.register_cb(pc, service); | |
251 else | |
252 purple_debug_warning("disco", "Cannot register to %s for account %s, " | |
253 "protocol did not provide register op.\n", | |
254 service->name, | |
255 purple_account_get_username(list->account)); | |
256 } | |
257 | |
258 const gchar *purple_disco_service_get_name(PurpleDiscoService *service) | |
259 { | |
260 g_return_val_if_fail(service != NULL, NULL); | |
261 | |
262 return service->name; | |
263 } | |
264 | |
265 const gchar *purple_disco_service_get_description(PurpleDiscoService *service) | |
266 { | |
267 g_return_val_if_fail(service != NULL, NULL); | |
268 | |
269 return service->description; | |
270 } | |
271 | |
272 gpointer | |
273 purple_disco_service_get_protocol_data(PurpleDiscoService *service) | |
274 { | |
275 g_return_val_if_fail(service != NULL, NULL); | |
276 | |
277 return service->proto_data; | |
278 } | |
279 | |
280 PurpleDiscoServiceType | |
281 purple_disco_service_get_type(PurpleDiscoService *service) | |
282 { | |
283 g_return_val_if_fail(service != NULL, PURPLE_DISCO_SERVICE_TYPE_UNSET); | |
284 | |
285 return service->type; | |
286 } | |
287 | |
288 PurpleDiscoServiceFlags | |
289 purple_disco_service_get_flags(PurpleDiscoService *service) | |
290 { | |
291 g_return_val_if_fail(service != NULL, PURPLE_DISCO_NONE); | |
292 | |
293 return service->flags; | |
294 } | |
295 | |
296 void purple_disco_service_set_gateway_type(PurpleDiscoService *service, const gchar *type) | |
297 { | |
298 g_return_if_fail(service != NULL); | |
299 | |
300 g_free(service->gateway_type); | |
301 service->gateway_type = g_strdup(type); | |
302 } | |
303 | |
304 const gchar *purple_disco_service_get_gateway_type(PurpleDiscoService *service) | |
305 { | |
306 g_return_val_if_fail(service != NULL, NULL); | |
307 | |
308 return service->gateway_type; | |
309 } | |
310 | |
311 PurpleAccount* purple_disco_list_get_account(PurpleDiscoList *list) | |
312 { | |
313 g_return_val_if_fail(list != NULL, NULL); | |
314 | |
315 return list->account; | |
316 } | |
317 | |
318 GList* purple_disco_list_get_services(PurpleDiscoList *list) | |
319 { | |
320 g_return_val_if_fail(list != NULL, NULL); | |
321 | |
322 return list->services; | |
323 } | |
324 | |
325 void purple_disco_list_set_ui_data(PurpleDiscoList *list, gpointer ui_data) | |
326 { | |
327 g_return_if_fail(list != NULL); | |
328 | |
329 list->ui_data = ui_data; | |
330 } | |
331 | |
332 gpointer purple_disco_list_get_ui_data(PurpleDiscoList *list) | |
333 { | |
334 g_return_val_if_fail(list != NULL, NULL); | |
335 | |
336 return list->ui_data; | |
337 } | |
338 | |
339 void purple_disco_list_set_in_progress(PurpleDiscoList *list, | |
340 gboolean in_progress) | |
341 { | |
342 g_return_if_fail(list != NULL); | |
343 | |
344 list->in_progress = in_progress; | |
345 | |
346 if (ops && ops->in_progress) | |
347 ops->in_progress(list, in_progress); | |
348 } | |
349 | |
350 gboolean purple_disco_list_get_in_progress(PurpleDiscoList *list) | |
351 { | |
352 g_return_val_if_fail(list != NULL, FALSE); | |
353 | |
354 return list->in_progress; | |
355 } | |
356 | |
357 void purple_disco_list_set_protocol_data(PurpleDiscoList *list, | |
358 gpointer proto_data, | |
359 PurpleDiscoCloseFunc cb) | |
360 { | |
361 g_return_if_fail(list != NULL); | |
362 | |
363 list->proto_data = proto_data; | |
364 list->ops.close_cb = cb; | |
365 } | |
366 | |
367 gpointer purple_disco_list_get_protocol_data(PurpleDiscoList *list) | |
368 { | |
369 g_return_val_if_fail(list != NULL, NULL); | |
370 | |
371 return list->proto_data; | |
372 } | |
373 | |
374 void purple_disco_list_set_service_close_func(PurpleDiscoList *list, | |
375 PurpleDiscoServiceCloseFunc cb) | |
376 { | |
377 g_return_if_fail(list != NULL); | |
378 | |
379 list->ops.service_close_cb = cb; | |
380 } | |
381 | |
382 void purple_disco_list_set_cancel_func(PurpleDiscoList *list, PurpleDiscoCancelFunc cb) | |
383 { | |
384 g_return_if_fail(list != NULL); | |
385 | |
386 list->ops.cancel_cb = cb; | |
387 } | |
388 | |
389 void purple_disco_list_set_expand_func(PurpleDiscoList *list, PurpleDiscoServiceExpandFunc cb) | |
390 { | |
391 g_return_if_fail(list != NULL); | |
392 | |
393 list->ops.expand_cb = cb; | |
394 } | |
395 | |
396 void purple_disco_list_set_register_func(PurpleDiscoList *list, PurpleDiscoRegisterFunc cb) | |
397 { | |
398 g_return_if_fail(list != NULL); | |
399 | |
400 list->ops.register_cb = cb; | |
401 } | |
402 | |
403 void purple_disco_set_ui_ops(PurpleDiscoUiOps *ui_ops) | |
404 { | |
405 ops = ui_ops; | |
406 } | |
407 | |
408 PurpleDiscoUiOps *purple_disco_get_ui_ops(void) | |
409 { | |
410 return ops; | |
411 } |