|
1 /* tp-chan.c |
|
2 * |
|
3 * Copyright (C) 2005 Collabora Ltd. |
|
4 * |
|
5 * |
|
6 * This library is free software; you can redistribute it and/or |
|
7 * modify it under the terms of the GNU Lesser General Public |
|
8 * License as published by the Free Software Foundation; either |
|
9 * version 2.1 of the License, or (at your option) any later version. |
|
10 * |
|
11 * This library is distributed in the hope that it will be useful, |
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 * Lesser General Public License for more details. |
|
15 * |
|
16 * You should have received a copy of the GNU Lesser General Public |
|
17 * License along with this library; if not, write to the Free Software |
|
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
19 * |
|
20 */ |
|
21 |
|
22 #include <string.h> |
|
23 #include "tp-chan.h" |
|
24 #include "tp-chan-signals-marshal.h" |
|
25 #include "tp-props-iface.h" |
|
26 #include "tp-helpers.h" |
|
27 |
|
28 #ifdef EMULATOR |
|
29 #include "libtelepathy_wsd_solution.h" |
|
30 #endif |
|
31 |
|
32 #ifdef EMULATOR |
|
33 |
|
34 GET_STATIC_VAR_FROM_TLS(parent_class,tp_chan,GObjectClass *) |
|
35 #define parent_class (*GET_WSD_VAR_NAME(parent_class,tp_chan,s)()) |
|
36 |
|
37 GET_STATIC_VAR_FROM_TLS(type1,tp_chan,GType) |
|
38 #define type1 (*GET_WSD_VAR_NAME(type1,tp_chan,s)()) |
|
39 |
|
40 GET_STATIC_VAR_FROM_TLS(ret1,tp_chan,GQuark) |
|
41 #define ret1 (*GET_WSD_VAR_NAME(ret1,tp_chan,s)()) |
|
42 |
|
43 GET_STATIC_VAR_FROM_TLS(ret2,tp_chan,GQuark) |
|
44 #define ret2 (*GET_WSD_VAR_NAME(ret2,tp_chan,s)()) |
|
45 |
|
46 GET_STATIC_VAR_FROM_TLS(ret3,tp_chan,GQuark) |
|
47 #define ret3 (*GET_WSD_VAR_NAME(ret3,tp_chan,s)()) |
|
48 |
|
49 GET_STATIC_VAR_FROM_TLS(ret4,tp_chan,GQuark) |
|
50 #define ret4 (*GET_WSD_VAR_NAME(ret4,tp_chan,s)()) |
|
51 |
|
52 GET_STATIC_VAR_FROM_TLS(ret5,tp_chan,GQuark) |
|
53 #define ret5 (*GET_WSD_VAR_NAME(ret5,tp_chan,s)()) |
|
54 |
|
55 GET_STATIC_VAR_FROM_TLS(ret6,tp_chan,GQuark) |
|
56 #define ret6 (*GET_WSD_VAR_NAME(ret6,tp_chan,s)()) |
|
57 |
|
58 GET_STATIC_VAR_FROM_TLS(ret7,tp_chan,GQuark) |
|
59 #define ret7 (*GET_WSD_VAR_NAME(ret7,tp_chan,s)()) |
|
60 |
|
61 GET_STATIC_VAR_FROM_TLS(ret8,tp_chan,GQuark) |
|
62 #define ret8 (*GET_WSD_VAR_NAME(ret8,tp_chan,s)()) |
|
63 |
|
64 GET_STATIC_VAR_FROM_TLS(ret9,tp_chan,GQuark) |
|
65 #define ret9 (*GET_WSD_VAR_NAME(ret9,tp_chan,s)()) |
|
66 |
|
67 GET_STATIC_VAR_FROM_TLS(ret10,tp_chan,GQuark) |
|
68 #define ret10 (*GET_WSD_VAR_NAME(ret10,tp_chan,s)()) |
|
69 |
|
70 GET_STATIC_VAR_FROM_TLS(ret11,tp_chan,GQuark) |
|
71 #define ret11 (*GET_WSD_VAR_NAME(ret11,tp_chan,s)()) |
|
72 |
|
73 |
|
74 #else |
|
75 static GObjectClass *parent_class = NULL; |
|
76 #endif |
|
77 |
|
78 static void synthesize_closed(TpChan *chan); |
|
79 |
|
80 static void _tp_chan_register_signal_marshallers() |
|
81 { |
|
82 /* Register marshaller for the Close signal */ |
|
83 dbus_g_object_register_marshaller(tp_chan_signals_marshal_VOID__VOID, |
|
84 G_TYPE_NONE, G_TYPE_INVALID); |
|
85 } |
|
86 |
|
87 static void _tp_chan_register_interface_signal_marshallers() |
|
88 { |
|
89 |
|
90 /* Register marshaller for ContactSearch interface signal |
|
91 SearchResultReceived*/ |
|
92 |
|
93 dbus_g_object_register_marshaller(tp_ifaces_signals_marshal_VOID__UINT_BOXED, |
|
94 G_TYPE_NONE, G_TYPE_UINT, G_TYPE_BOXED, G_TYPE_INVALID); |
|
95 |
|
96 /* Register marshaller for ContactSearch interface signal |
|
97 * SearchStateChanged */ |
|
98 |
|
99 dbus_g_object_register_marshaller(tp_ifaces_signals_marshal_VOID__UINT, |
|
100 G_TYPE_NONE, G_TYPE_UINT, G_TYPE_INVALID); |
|
101 |
|
102 /* Register marshaller for StreamedMedia interface signal |
|
103 ReceivedMediaParameters */ |
|
104 dbus_g_object_register_marshaller(tp_ifaces_signals_marshal_VOID__UINT_STRING_STRING, G_TYPE_NONE, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID); |
|
105 /* Register marshaller for StreamedMedia interface signal |
|
106 StreamStateChanged */ |
|
107 |
|
108 dbus_g_object_register_marshaller(tp_ifaces_signals_marshal_VOID__UINT_UINT_UINT, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID); |
|
109 |
|
110 /* Register marshaller for RoomList interface signal GotRooms */ |
|
111 |
|
112 dbus_g_object_register_marshaller(tp_ifaces_signals_marshal_VOID__BOXED, |
|
113 G_TYPE_NONE, G_TYPE_BOXED, G_TYPE_INVALID); |
|
114 |
|
115 /* Register marshaller for RoomList interface signal ListingRooms */ |
|
116 dbus_g_object_register_marshaller(tp_ifaces_signals_marshal_VOID__BOOLEAN, |
|
117 G_TYPE_NONE, G_TYPE_BOOLEAN, |
|
118 G_TYPE_INVALID); |
|
119 |
|
120 /* Register marshaller for channel type Text interface signal Received */ |
|
121 dbus_g_object_register_marshaller(tp_ifaces_signals_marshal_VOID__UINT_UINT_UINT_UINT_UINT_STRING, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, |
|
122 G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, |
|
123 G_TYPE_INVALID); |
|
124 |
|
125 /* Register marshaller for channel type Text interface Sent */ |
|
126 dbus_g_object_register_marshaller(tp_ifaces_signals_marshal_VOID__UINT_UINT_STRING, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID); |
|
127 |
|
128 /* Register marshaller used by the following iface/signal pairs: |
|
129 * DTFM/ReceivedDTMF, Group/GroupFlagsChanged, Hold/HoldStateChanged, |
|
130 * Password/PasswordFlagsChanged, Subject/SubjectFlagsChanged */ |
|
131 dbus_g_object_register_marshaller(tp_ifaces_signals_marshal_VOID__UINT_UINT, |
|
132 G_TYPE_NONE, G_TYPE_UINT, G_TYPE_UINT, |
|
133 G_TYPE_INVALID); |
|
134 /* Register marshaller for Group interface signal MembersChanged */ |
|
135 |
|
136 dbus_g_object_register_marshaller(tp_ifaces_signals_marshal_VOID__STRING_BOXED_BOXED_BOXED_BOXED_UINT_UINT, G_TYPE_NONE, G_TYPE_STRING, G_TYPE_BOXED, |
|
137 G_TYPE_BOXED, G_TYPE_BOXED, G_TYPE_BOXED, |
|
138 G_TYPE_UINT, G_TYPE_UINT,G_TYPE_INVALID); |
|
139 |
|
140 /* Register marshaller for Text Channel interface signal SendError */ |
|
141 dbus_g_object_register_marshaller(tp_ifaces_signals_marshal_VOID__UINT_UINT_UINT_STRING, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID); |
|
142 |
|
143 /* Register marshaller for IceSignalling interface signal |
|
144 NewIceSessionHandler */ |
|
145 |
|
146 dbus_g_object_register_marshaller(tp_ifaces_signals_marshal_VOID__OBJECT_STRING, G_TYPE_NONE, DBUS_TYPE_G_OBJECT_PATH, G_TYPE_STRING, G_TYPE_INVALID); |
|
147 |
|
148 } |
|
149 |
|
150 |
|
151 /* We initialize the list of signatures here, so that we can use |
|
152 * it to add them for new interface instances later.*/ |
|
153 |
|
154 /* FIXME: This should be replaced by a more automatic way of doing |
|
155 * this. The reason for using a set of function pointers is that there is no |
|
156 * apparent cleaner way of doing this, unless DBusGProxy gains a non-varargs |
|
157 * version of dbus_g_proxy_add_signal... |
|
158 */ |
|
159 |
|
160 |
|
161 static void _tp_chan_init_interface_signal_signatures(GData **signal_sigs) |
|
162 { |
|
163 g_datalist_init(signal_sigs); |
|
164 |
|
165 |
|
166 /* Create and store contact search iface signal signatures */ |
|
167 g_datalist_id_set_data(signal_sigs, TELEPATHY_CHAN_IFACE_CONTACTSEARCH_QUARK, |
|
168 (gpointer)tp_chan_set_contactsearch_signatures); |
|
169 |
|
170 /* Store streamed media iface signal signatures */ |
|
171 g_datalist_id_set_data(signal_sigs, |
|
172 TELEPATHY_CHAN_IFACE_STREAMED_QUARK, |
|
173 (gpointer)tp_chan_set_streamedmedia_signatures); |
|
174 /* Store roomlist signal iface signal parameters */ |
|
175 g_datalist_id_set_data(signal_sigs, TELEPATHY_CHAN_IFACE_ROOMLIST_QUARK, |
|
176 (gpointer)tp_chan_set_roomlist_signatures); |
|
177 /* Store text iface signal signatures */ |
|
178 g_datalist_id_set_data(signal_sigs, TELEPATHY_CHAN_IFACE_TEXT_QUARK, |
|
179 (gpointer)tp_chan_set_text_signatures); |
|
180 /* Store DTMF iface signal signatures */ |
|
181 g_datalist_id_set_data(signal_sigs, TELEPATHY_CHAN_IFACE_DTMF_QUARK, |
|
182 (gpointer)tp_chan_set_dtmf_signatures); |
|
183 /* Store group iface signal signatures */ |
|
184 g_datalist_id_set_data(signal_sigs, TELEPATHY_CHAN_IFACE_GROUP_QUARK, |
|
185 (gpointer)tp_chan_set_group_signatures); |
|
186 /* Store hold iface signatures */ |
|
187 g_datalist_id_set_data(signal_sigs, TELEPATHY_CHAN_IFACE_HOLD_QUARK, |
|
188 (gpointer)tp_chan_set_hold_signatures); |
|
189 /* Store password iface signatures */ |
|
190 g_datalist_id_set_data(signal_sigs, TELEPATHY_CHAN_IFACE_PASSWORD_QUARK, |
|
191 (gpointer)tp_chan_set_password_signatures); |
|
192 } |
|
193 |
|
194 static void tp_chan_init(GTypeInstance *instance, gpointer g_class) |
|
195 { |
|
196 TpChan *self = TELEPATHY_CHAN(instance); |
|
197 self->type = NULL; |
|
198 self->first_run = TRUE; |
|
199 } |
|
200 |
|
201 |
|
202 static void tp_chan_dispose(GObject *obj) |
|
203 { |
|
204 TpChan *self = TELEPATHY_CHAN(obj); |
|
205 |
|
206 if (self->first_run) |
|
207 { |
|
208 self->first_run = FALSE; |
|
209 synthesize_closed(self); |
|
210 g_datalist_clear(&(self->interface_list)); |
|
211 } |
|
212 |
|
213 /* Chain up to the parent class dispose */ |
|
214 if (G_OBJECT_CLASS(parent_class)->dispose) |
|
215 { |
|
216 G_OBJECT_CLASS(parent_class)->dispose(obj); |
|
217 } |
|
218 |
|
219 } |
|
220 |
|
221 |
|
222 static void tp_chan_finalize(GObject *obj) |
|
223 { |
|
224 TpChan *self = TELEPATHY_CHAN(obj); |
|
225 |
|
226 if (self->type) |
|
227 { |
|
228 g_free(self->type); |
|
229 } |
|
230 |
|
231 if (G_OBJECT_CLASS(parent_class)->finalize) |
|
232 { |
|
233 G_OBJECT_CLASS(parent_class)->finalize(obj); |
|
234 } |
|
235 } |
|
236 |
|
237 |
|
238 static void tp_chan_class_init(TpChanClass *klass) |
|
239 { |
|
240 GObjectClass *obj = G_OBJECT_CLASS(klass); |
|
241 parent_class = g_type_class_peek_parent(klass); |
|
242 |
|
243 obj->set_property = parent_class->set_property; |
|
244 obj->get_property = parent_class->get_property; |
|
245 obj->dispose = tp_chan_dispose; |
|
246 obj->finalize = tp_chan_finalize; |
|
247 _tp_chan_register_signal_marshallers(); |
|
248 _tp_chan_register_interface_signal_marshallers(); |
|
249 _tp_chan_init_interface_signal_signatures(&(klass->iface_signal_sigs)); |
|
250 } |
|
251 |
|
252 |
|
253 GType tp_chan_get_type(void) |
|
254 { |
|
255 #ifndef EMULATOR |
|
256 static GType type1 = 0; |
|
257 #endif |
|
258 |
|
259 if (type1 == 0) |
|
260 { |
|
261 static const GTypeInfo info = |
|
262 { |
|
263 sizeof(TpChanClass), |
|
264 NULL, |
|
265 NULL, |
|
266 (GClassInitFunc)tp_chan_class_init, |
|
267 NULL, |
|
268 NULL, |
|
269 sizeof(TpChan), |
|
270 0, |
|
271 (GInstanceInitFunc)tp_chan_init |
|
272 }; |
|
273 type1 = g_type_register_static(DBUS_TYPE_G_PROXY, |
|
274 "TpChan", &info, 0); |
|
275 } |
|
276 return type1; |
|
277 } |
|
278 |
|
279 |
|
280 |
|
281 /* Public functions begin */ |
|
282 |
|
283 GQuark tp_get_chan_interface() |
|
284 { |
|
285 #ifndef EMULATOR |
|
286 static GQuark ret1 = 0; |
|
287 #endif |
|
288 |
|
289 if (ret1 == 0) |
|
290 { |
|
291 ret1 = g_quark_from_static_string(TP_IFACE_CHANNEL_INTERFACE); |
|
292 } |
|
293 |
|
294 return ret1; |
|
295 } |
|
296 |
|
297 GQuark tp_get_chan_contactlist_interface() |
|
298 { |
|
299 #ifndef EMULATOR |
|
300 static GQuark ret2 = 0; |
|
301 #endif |
|
302 |
|
303 if (ret2 == 0) |
|
304 { |
|
305 ret2 = g_quark_from_static_string(TP_IFACE_CHANNEL_TYPE_CONTACT_LIST); |
|
306 } |
|
307 |
|
308 return ret2; |
|
309 } |
|
310 |
|
311 |
|
312 #ifdef SYMBIAN |
|
313 EXPORT_C |
|
314 #endif |
|
315 GQuark tp_get_chan_contactsearch_interface() |
|
316 { |
|
317 #ifndef EMULATOR |
|
318 static GQuark ret3 = 0; |
|
319 #endif |
|
320 |
|
321 if (ret3 == 0) |
|
322 { |
|
323 ret3 = g_quark_from_static_string(TP_IFACE_CHANNEL_TYPE_CONTACT_SEARCH); |
|
324 } |
|
325 |
|
326 return ret3; |
|
327 } |
|
328 |
|
329 |
|
330 GQuark tp_get_chan_streamed_interface() |
|
331 { |
|
332 #ifndef EMULATOR |
|
333 static GQuark ret4 = 0; |
|
334 #endif |
|
335 |
|
336 if (ret4 == 0) |
|
337 { |
|
338 ret4 = g_quark_from_static_string(TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA); |
|
339 } |
|
340 |
|
341 return ret4; |
|
342 } |
|
343 |
|
344 |
|
345 GQuark tp_get_chan_roomlist_interface() |
|
346 { |
|
347 #ifndef EMULATOR |
|
348 static GQuark ret5 = 0; |
|
349 #endif |
|
350 |
|
351 if (ret5 == 0) |
|
352 { |
|
353 ret5 = g_quark_from_static_string(TP_IFACE_CHANNEL_TYPE_ROOM_LIST); |
|
354 } |
|
355 |
|
356 return ret5; |
|
357 } |
|
358 |
|
359 #ifdef SYMBIAN |
|
360 EXPORT_C |
|
361 #endif |
|
362 GQuark tp_get_chan_text_interface() |
|
363 { |
|
364 #ifndef EMULATOR |
|
365 static GQuark ret6 = 0; |
|
366 #endif |
|
367 |
|
368 if (ret6 == 0) |
|
369 { |
|
370 ret6 = g_quark_from_static_string(TP_IFACE_CHANNEL_TYPE_TEXT); |
|
371 } |
|
372 |
|
373 return ret6; |
|
374 } |
|
375 |
|
376 |
|
377 GQuark tp_get_chan_dtmf_interface() |
|
378 { |
|
379 #ifndef EMULATOR |
|
380 static GQuark ret7 = 0; |
|
381 #endif |
|
382 |
|
383 if (ret7 == 0) |
|
384 { |
|
385 ret7 = g_quark_from_static_string(TP_IFACE_CHANNEL_INTERFACE_DTMF); |
|
386 } |
|
387 |
|
388 return ret7; |
|
389 } |
|
390 |
|
391 |
|
392 #ifdef SYMBIAN |
|
393 EXPORT_C |
|
394 #endif |
|
395 GQuark tp_get_chan_group_interface() |
|
396 { |
|
397 #ifndef EMULATOR |
|
398 static GQuark ret8 = 0; |
|
399 #endif |
|
400 |
|
401 if (ret8 == 0) |
|
402 { |
|
403 ret8 = g_quark_from_static_string(TP_IFACE_CHANNEL_INTERFACE_GROUP); |
|
404 } |
|
405 |
|
406 return ret8; |
|
407 } |
|
408 |
|
409 |
|
410 GQuark tp_get_chan_hold_interface() |
|
411 { |
|
412 #ifndef EMULATOR |
|
413 static GQuark ret9 = 0; |
|
414 #endif |
|
415 |
|
416 if (ret9 == 0) |
|
417 { |
|
418 ret9 = g_quark_from_static_string(TP_IFACE_CHANNEL_INTERFACE_HOLD); |
|
419 } |
|
420 |
|
421 return ret9; |
|
422 } |
|
423 |
|
424 |
|
425 GQuark tp_get_chan_password_interface() |
|
426 { |
|
427 #ifndef EMULATOR |
|
428 static GQuark ret10 = 0; |
|
429 #endif |
|
430 |
|
431 if (ret10 == 0) |
|
432 { |
|
433 ret10 = g_quark_from_static_string(TP_IFACE_CHANNEL_INTERFACE_PASSWORD); |
|
434 } |
|
435 |
|
436 return ret10; |
|
437 } |
|
438 |
|
439 GQuark tp_get_chan_transfer_interface() |
|
440 { |
|
441 #ifndef EMULATOR |
|
442 static GQuark ret11 = 0; |
|
443 #endif |
|
444 |
|
445 if (ret11 == 0) |
|
446 { |
|
447 ret11 = g_quark_from_static_string(TP_IFACE_CHANNEL_INTERFACE_TRANSFER); |
|
448 } |
|
449 |
|
450 return ret11; |
|
451 } |
|
452 |
|
453 |
|
454 #ifdef SYMBIAN |
|
455 EXPORT_C |
|
456 #endif |
|
457 TpChan *tp_chan_new(DBusGConnection *connection, const gchar *bus_name, |
|
458 const gchar *object_path, const gchar *type, |
|
459 guint handle_type, guint handle) |
|
460 { |
|
461 GError *error = NULL; |
|
462 gchar *unique_name; |
|
463 gchar **interfaces; |
|
464 TpChan *chan; |
|
465 g_return_val_if_fail(connection != NULL, NULL); |
|
466 g_return_val_if_fail(bus_name != NULL, NULL); |
|
467 g_return_val_if_fail(object_path != NULL, NULL); |
|
468 g_return_val_if_fail(type != NULL, NULL); |
|
469 |
|
470 if (!dbus_g_proxy_call (tp_get_bus_proxy (), |
|
471 "GetNameOwner", &error, G_TYPE_STRING, bus_name, |
|
472 G_TYPE_INVALID, G_TYPE_STRING, &unique_name, |
|
473 G_TYPE_INVALID)) |
|
474 { |
|
475 g_warning("tp_chan_new: getting unique name failed: %s", error->message); |
|
476 g_error_free(error); |
|
477 return NULL; |
|
478 } |
|
479 |
|
480 /* Create the channel object */ |
|
481 chan = g_object_new(TELEPATHY_CHAN_TYPE, |
|
482 "name", unique_name, "path", object_path, |
|
483 "interface", TP_IFACE_CHANNEL_INTERFACE, |
|
484 "connection", connection, NULL); |
|
485 |
|
486 g_free(unique_name); |
|
487 |
|
488 dbus_g_proxy_add_signal(DBUS_G_PROXY(chan), "Closed", G_TYPE_INVALID); |
|
489 |
|
490 g_datalist_init(&(chan->interface_list)); |
|
491 |
|
492 /* Store interface information for the channel */ |
|
493 if (tp_chan_get_interfaces(DBUS_G_PROXY(chan), &interfaces, &error)) |
|
494 { |
|
495 tp_chan_local_set_interfaces(chan, interfaces); |
|
496 |
|
497 /* Free the strings used for interface object creation */ |
|
498 g_strfreev(interfaces); |
|
499 } |
|
500 else |
|
501 { |
|
502 g_warning("GetInterfaces for channel failed: %s\n", error->message); |
|
503 g_error_free(error); |
|
504 } |
|
505 |
|
506 /* Store necessary information for this object */ |
|
507 chan->type = g_strdup(type); |
|
508 chan->handle_type = handle_type; |
|
509 chan->handle = handle; |
|
510 |
|
511 return chan; |
|
512 } |
|
513 |
|
514 |
|
515 void tp_chan_local_set_interfaces(TpChan *self, gchar **interfaces) |
|
516 { |
|
517 gchar **temp_ifaces; |
|
518 gchar *chan_type = NULL; |
|
519 GError *error = NULL; |
|
520 GData **sig_list = &(TELEPATHY_CHAN_GET_CLASS(self)->iface_signal_sigs); |
|
521 void (*signature_setter_func)(DBusGProxy *proxy); |
|
522 DBusGConnection *connection; |
|
523 /*const*/ gchar *name, *path; |
|
524 |
|
525 if (interfaces == NULL) |
|
526 { |
|
527 return; |
|
528 } |
|
529 |
|
530 /* Create and store proxy objects corresponding to the |
|
531 interfaces */ |
|
532 |
|
533 g_object_get (G_OBJECT(self), |
|
534 "connection", &connection, |
|
535 "name", &name, |
|
536 "path", &path, |
|
537 NULL); |
|
538 |
|
539 g_debug ("%s: %p, %s, %s", G_STRFUNC, connection, name, path); |
|
540 |
|
541 for (temp_ifaces = interfaces; *temp_ifaces; temp_ifaces++) |
|
542 { |
|
543 GQuark key = g_quark_from_string(*temp_ifaces); |
|
544 DBusGProxy *if_proxy; |
|
545 |
|
546 if (key == TELEPATHY_PROPS_IFACE_QUARK) |
|
547 { |
|
548 if_proxy = DBUS_G_PROXY (tp_props_iface_new (connection, name, path)); |
|
549 } |
|
550 else |
|
551 { |
|
552 if_proxy = dbus_g_proxy_new_for_name (connection, name, |
|
553 path, *temp_ifaces); |
|
554 |
|
555 if (if_proxy != NULL) |
|
556 { |
|
557 /* Does the interface have signals? If yes, add their signatures |
|
558 for the interface instance by calling the |
|
559 corresponding setter function */ |
|
560 |
|
561 signature_setter_func = |
|
562 g_datalist_id_get_data(sig_list, key); |
|
563 |
|
564 if (signature_setter_func != NULL) |
|
565 { |
|
566 (*signature_setter_func)(if_proxy); |
|
567 } |
|
568 } |
|
569 } |
|
570 if (if_proxy != NULL) |
|
571 { |
|
572 g_datalist_id_set_data_full(&(self->interface_list), key, |
|
573 if_proxy, g_object_unref); |
|
574 } |
|
575 } |
|
576 |
|
577 /* Finally, add the channel type interface */ |
|
578 |
|
579 if (!tp_chan_get_channel_type(DBUS_G_PROXY(self), &chan_type, &error)) |
|
580 { |
|
581 g_warning("GetChannelType failed: %s\n", error->message); |
|
582 g_error_free(error); |
|
583 } |
|
584 else |
|
585 { |
|
586 DBusGProxy *chan_proxy = |
|
587 dbus_g_proxy_new_from_proxy(DBUS_G_PROXY(self), chan_type, NULL); |
|
588 |
|
589 g_datalist_id_set_data(&(self->interface_list), |
|
590 g_quark_from_string(chan_type), chan_proxy); |
|
591 |
|
592 /* If the particular channel type interface has signals defined, |
|
593 call the corresponding setter function */ |
|
594 |
|
595 signature_setter_func = |
|
596 g_datalist_id_get_data(sig_list, g_quark_from_string(chan_type)); |
|
597 |
|
598 if (signature_setter_func != NULL) |
|
599 { |
|
600 (*signature_setter_func)(chan_proxy); |
|
601 } |
|
602 |
|
603 g_free(chan_type); |
|
604 } |
|
605 |
|
606 g_free (name); |
|
607 g_free (path); |
|
608 dbus_g_connection_unref (connection); |
|
609 } |
|
610 |
|
611 #ifdef SYMBIAN |
|
612 EXPORT_C |
|
613 #endif |
|
614 DBusGProxy *tp_chan_get_interface(TpChan *self, GQuark iface_quark) |
|
615 { |
|
616 DBusGProxy *iface_proxy = NULL; |
|
617 |
|
618 iface_proxy = (DBusGProxy *)g_datalist_id_get_data(&(self->interface_list), |
|
619 iface_quark); |
|
620 return iface_proxy; |
|
621 } |
|
622 |
|
623 static void synthesize_closed(TpChan *chan) |
|
624 { |
|
625 DBusMessage *msg = NULL; |
|
626 GArray *closed_signal_types = g_array_new(FALSE, FALSE, sizeof(GType)); |
|
627 |
|
628 if (!closed_signal_types) |
|
629 { |
|
630 g_warning("%s: Could not allocate the type array for Closed signal", |
|
631 G_STRFUNC); |
|
632 return; |
|
633 } |
|
634 |
|
635 msg = dbus_message_new_signal(dbus_g_proxy_get_path(DBUS_G_PROXY(chan)), |
|
636 TP_IFACE_CHANNEL_INTERFACE, "Closed"); |
|
637 if (!msg) |
|
638 { |
|
639 g_warning("%s: Could not create the synthetic Closed signal message.", |
|
640 G_STRFUNC); |
|
641 g_array_free(closed_signal_types, FALSE); |
|
642 return; |
|
643 } |
|
644 g_signal_emit_by_name(DBUS_G_PROXY(chan), |
|
645 TP_IFACE_CHAN_SIGNAL_CLOSED_SYNTHESIZED, msg, |
|
646 closed_signal_types); |
|
647 g_array_free(closed_signal_types, FALSE); |
|
648 dbus_message_unref(msg); |
|
649 } |