1 /* |
|
2 * gabble-roster-channel.c - Source for GabbleRosterChannel |
|
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
19 */ |
|
20 |
|
21 #include <dbus/dbus-glib.h> |
|
22 #include <stdio.h> |
|
23 #include <stdlib.h> |
|
24 |
|
25 #define DEBUG_FLAG GABBLE_DEBUG_ROSTER |
|
26 |
|
27 #include "debug.h" |
|
28 #include "gabble-connection.h" |
|
29 #include "gintset.h" |
|
30 #include "group-mixin.h" |
|
31 #include "handle-set.h" |
|
32 #include "roster.h" |
|
33 #include "telepathy-errors.h" |
|
34 #include "telepathy-helpers.h" |
|
35 #include "telepathy-interfaces.h" |
|
36 #include "tp-channel-iface.h" |
|
37 #include "util.h" |
|
38 |
|
39 #include "gabble-roster-channel.h" |
|
40 #include "gabble-roster-channel-glue.h" |
|
41 #include "gabble-roster-channel-signals-marshal.h" |
|
42 |
|
43 #include "gabble_enums.h" |
|
44 |
|
45 #ifndef EMULATOR |
|
46 G_DEFINE_TYPE_WITH_CODE (GabbleRosterChannel, gabble_roster_channel, |
|
47 G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL)); |
|
48 #endif |
|
49 |
|
50 /* signal enum */ |
|
51 enum |
|
52 { |
|
53 CLOSED, |
|
54 GROUP_FLAGS_CHANGED, |
|
55 MEMBERS_CHANGED, |
|
56 LAST_SIGNAL |
|
57 #ifdef EMULATOR |
|
58 = LAST_SIGNAL_ROS_CHNL |
|
59 #endif |
|
60 |
|
61 }; |
|
62 |
|
63 |
|
64 #ifdef EMULATOR |
|
65 #include "libgabble_wsd_solution.h" |
|
66 |
|
67 GET_STATIC_ARRAY_FROM_TLS(signals,gabble_ros_chnl,guint) |
|
68 #define signals (GET_WSD_VAR_NAME(signals,gabble_ros_chnl, s)()) |
|
69 |
|
70 GET_STATIC_VAR_FROM_TLS(gabble_roster_channel_parent_class,gabble_ros_chnl,gpointer) |
|
71 #define gabble_roster_channel_parent_class (*GET_WSD_VAR_NAME(gabble_roster_channel_parent_class,gabble_ros_chnl,s)()) |
|
72 |
|
73 GET_STATIC_VAR_FROM_TLS(g_define_type_id,gabble_ros_chnl,GType) |
|
74 #define g_define_type_id (*GET_WSD_VAR_NAME(g_define_type_id,gabble_ros_chnl,s)()) |
|
75 |
|
76 static void gabble_roster_channel_init (GabbleRosterChannel *self); |
|
77 static void gabble_roster_channel_class_init (GabbleRosterChannelClass *klass); |
|
78 static void gabble_roster_channel_class_intern_init (gpointer klass) |
|
79 { |
|
80 gabble_roster_channel_parent_class = g_type_class_peek_parent (klass); |
|
81 gabble_roster_channel_class_init ((GabbleRosterChannelClass*) klass); |
|
82 } |
|
83 |
|
84 EXPORT_C GType gabble_roster_channel_get_type (void) |
|
85 { |
|
86 if ((g_define_type_id == 0)) { static const GTypeInfo g_define_type_info = { sizeof (GabbleRosterChannelClass), (GBaseInitFunc) ((void *)0), (GBaseFinalizeFunc) ((void *)0), (GClassInitFunc) gabble_roster_channel_class_intern_init, (GClassFinalizeFunc) ((void *)0), ((void *)0), sizeof (GabbleRosterChannel), 0, (GInstanceInitFunc) gabble_roster_channel_init, ((void *)0) }; g_define_type_id = g_type_register_static ( ((GType) ((20) << (2))), g_intern_static_string ("GabbleRosterChannel"), &g_define_type_info, (GTypeFlags) 0); { { static const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc) ((void *)0) }; g_type_add_interface_static (g_define_type_id, tp_channel_iface_get_type(), &g_implement_interface_info); } ; } } return g_define_type_id; } ; |
|
87 |
|
88 #else |
|
89 |
|
90 static guint signals[LAST_SIGNAL] = {0}; |
|
91 |
|
92 #endif |
|
93 |
|
94 |
|
95 |
|
96 /* properties */ |
|
97 enum |
|
98 { |
|
99 PROP_OBJECT_PATH = 1, |
|
100 PROP_CHANNEL_TYPE, |
|
101 PROP_HANDLE_TYPE, |
|
102 PROP_HANDLE, |
|
103 PROP_CONNECTION, |
|
104 LAST_PROPERTY |
|
105 }; |
|
106 |
|
107 /* private structure */ |
|
108 typedef struct _GabbleRosterChannelPrivate GabbleRosterChannelPrivate; |
|
109 |
|
110 struct _GabbleRosterChannelPrivate |
|
111 { |
|
112 GabbleConnection *conn; |
|
113 char *object_path; |
|
114 GabbleHandle handle; |
|
115 |
|
116 gboolean dispose_has_run; |
|
117 }; |
|
118 |
|
119 #define GABBLE_ROSTER_CHANNEL_GET_PRIVATE(obj) \ |
|
120 ((GabbleRosterChannelPrivate *)obj->priv) |
|
121 |
|
122 static void |
|
123 gabble_roster_channel_init (GabbleRosterChannel *self) |
|
124 { |
|
125 GabbleRosterChannelPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, |
|
126 GABBLE_TYPE_ROSTER_CHANNEL, GabbleRosterChannelPrivate); |
|
127 |
|
128 self->priv = priv; |
|
129 |
|
130 /* allocate any data required by the object here */ |
|
131 } |
|
132 |
|
133 static GObject * |
|
134 gabble_roster_channel_constructor (GType type, guint n_props, |
|
135 GObjectConstructParam *props) |
|
136 { |
|
137 GObject *obj; |
|
138 GabbleRosterChannelPrivate *priv; |
|
139 DBusGConnection *bus; |
|
140 GabbleHandleRepo *handles; |
|
141 gboolean valid; |
|
142 GabbleHandle self_handle; |
|
143 |
|
144 obj = G_OBJECT_CLASS (gabble_roster_channel_parent_class)-> |
|
145 constructor (type, n_props, props); |
|
146 priv = GABBLE_ROSTER_CHANNEL_GET_PRIVATE (GABBLE_ROSTER_CHANNEL (obj)); |
|
147 handles = priv->conn->handles; |
|
148 self_handle = priv->conn->self_handle; |
|
149 |
|
150 /* register object on the bus */ |
|
151 bus = tp_get_bus (); |
|
152 dbus_g_connection_register_g_object (bus, priv->object_path, obj); |
|
153 |
|
154 /* ref our list handle */ |
|
155 valid = gabble_handle_ref (handles, TP_HANDLE_TYPE_LIST, priv->handle); |
|
156 g_assert (valid); |
|
157 |
|
158 /* initialize group mixin */ |
|
159 gabble_group_mixin_init (obj, G_STRUCT_OFFSET (GabbleRosterChannel, group), |
|
160 handles, self_handle); |
|
161 |
|
162 if (GABBLE_LIST_HANDLE_PUBLISH == priv->handle) |
|
163 { |
|
164 gabble_group_mixin_change_flags (obj, |
|
165 TP_CHANNEL_GROUP_FLAG_CAN_REMOVE | |
|
166 TP_CHANNEL_GROUP_FLAG_MESSAGE_ACCEPT | |
|
167 TP_CHANNEL_GROUP_FLAG_MESSAGE_REMOVE, |
|
168 0); |
|
169 } |
|
170 else if (GABBLE_LIST_HANDLE_SUBSCRIBE == priv->handle) |
|
171 { |
|
172 gabble_group_mixin_change_flags (obj, |
|
173 TP_CHANNEL_GROUP_FLAG_CAN_ADD | |
|
174 TP_CHANNEL_GROUP_FLAG_CAN_REMOVE | |
|
175 TP_CHANNEL_GROUP_FLAG_CAN_RESCIND | |
|
176 TP_CHANNEL_GROUP_FLAG_MESSAGE_ADD | |
|
177 TP_CHANNEL_GROUP_FLAG_MESSAGE_REMOVE | |
|
178 TP_CHANNEL_GROUP_FLAG_MESSAGE_RESCIND, |
|
179 0); |
|
180 } |
|
181 else if (GABBLE_LIST_HANDLE_KNOWN == priv->handle) |
|
182 { |
|
183 gabble_group_mixin_change_flags (obj, |
|
184 TP_CHANNEL_GROUP_FLAG_CAN_REMOVE, |
|
185 0); |
|
186 } |
|
187 else if (GABBLE_LIST_HANDLE_DENY == priv->handle) |
|
188 { |
|
189 gabble_group_mixin_change_flags (obj, |
|
190 TP_CHANNEL_GROUP_FLAG_CAN_ADD | |
|
191 TP_CHANNEL_GROUP_FLAG_CAN_REMOVE, |
|
192 0); |
|
193 } |
|
194 else |
|
195 { |
|
196 g_assert_not_reached (); |
|
197 } |
|
198 |
|
199 return obj; |
|
200 } |
|
201 |
|
202 static void |
|
203 gabble_roster_channel_get_property (GObject *object, |
|
204 guint property_id, |
|
205 GValue *value, |
|
206 GParamSpec *pspec) |
|
207 { |
|
208 GabbleRosterChannel *chan = GABBLE_ROSTER_CHANNEL (object); |
|
209 GabbleRosterChannelPrivate *priv = GABBLE_ROSTER_CHANNEL_GET_PRIVATE (chan); |
|
210 |
|
211 switch (property_id) { |
|
212 case PROP_OBJECT_PATH: |
|
213 g_value_set_string (value, priv->object_path); |
|
214 break; |
|
215 case PROP_CHANNEL_TYPE: |
|
216 g_value_set_static_string (value, TP_IFACE_CHANNEL_TYPE_CONTACT_LIST); |
|
217 break; |
|
218 case PROP_HANDLE_TYPE: |
|
219 g_value_set_uint (value, TP_HANDLE_TYPE_LIST); |
|
220 break; |
|
221 case PROP_HANDLE: |
|
222 g_value_set_uint (value, priv->handle); |
|
223 break; |
|
224 case PROP_CONNECTION: |
|
225 g_value_set_object (value, priv->conn); |
|
226 break; |
|
227 default: |
|
228 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); |
|
229 break; |
|
230 } |
|
231 } |
|
232 |
|
233 static void |
|
234 gabble_roster_channel_set_property (GObject *object, |
|
235 guint property_id, |
|
236 const GValue *value, |
|
237 GParamSpec *pspec) |
|
238 { |
|
239 GabbleRosterChannel *chan = GABBLE_ROSTER_CHANNEL (object); |
|
240 GabbleRosterChannelPrivate *priv = GABBLE_ROSTER_CHANNEL_GET_PRIVATE (chan); |
|
241 |
|
242 switch (property_id) { |
|
243 case PROP_OBJECT_PATH: |
|
244 g_free (priv->object_path); |
|
245 priv->object_path = g_value_dup_string (value); |
|
246 break; |
|
247 case PROP_HANDLE: |
|
248 priv->handle = g_value_get_uint (value); |
|
249 break; |
|
250 case PROP_CONNECTION: |
|
251 priv->conn = g_value_get_object (value); |
|
252 break; |
|
253 default: |
|
254 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); |
|
255 break; |
|
256 } |
|
257 } |
|
258 |
|
259 static void gabble_roster_channel_dispose (GObject *object); |
|
260 static void gabble_roster_channel_finalize (GObject *object); |
|
261 |
|
262 static gboolean _gabble_roster_channel_add_member_cb (GObject *obj, GabbleHandle handle, const gchar *message, GError **error); |
|
263 static gboolean _gabble_roster_channel_remove_member_cb (GObject *obj, GabbleHandle handle, const gchar *message, GError **error); |
|
264 |
|
265 static void |
|
266 gabble_roster_channel_class_init (GabbleRosterChannelClass *gabble_roster_channel_class) |
|
267 { |
|
268 GObjectClass *object_class = G_OBJECT_CLASS (gabble_roster_channel_class); |
|
269 GParamSpec *param_spec; |
|
270 |
|
271 g_type_class_add_private (gabble_roster_channel_class, sizeof (GabbleRosterChannelPrivate)); |
|
272 |
|
273 object_class->constructor = gabble_roster_channel_constructor; |
|
274 |
|
275 object_class->get_property = gabble_roster_channel_get_property; |
|
276 object_class->set_property = gabble_roster_channel_set_property; |
|
277 |
|
278 object_class->dispose = gabble_roster_channel_dispose; |
|
279 object_class->finalize = gabble_roster_channel_finalize; |
|
280 |
|
281 param_spec = g_param_spec_object ("connection", "GabbleConnection object", |
|
282 "Gabble connection object that owns this " |
|
283 "Roster channel object.", |
|
284 GABBLE_TYPE_CONNECTION, |
|
285 G_PARAM_CONSTRUCT_ONLY | |
|
286 G_PARAM_READWRITE | |
|
287 G_PARAM_STATIC_NICK | |
|
288 G_PARAM_STATIC_BLURB); |
|
289 g_object_class_install_property (object_class, PROP_CONNECTION, param_spec); |
|
290 |
|
291 g_object_class_override_property (object_class, PROP_OBJECT_PATH, "object-path"); |
|
292 g_object_class_override_property (object_class, PROP_CHANNEL_TYPE, "channel-type"); |
|
293 g_object_class_override_property (object_class, PROP_HANDLE_TYPE, "handle-type"); |
|
294 g_object_class_override_property (object_class, PROP_HANDLE, "handle"); |
|
295 |
|
296 signals[CLOSED] = |
|
297 g_signal_new ("closed", |
|
298 G_OBJECT_CLASS_TYPE (gabble_roster_channel_class), |
|
299 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, |
|
300 0, |
|
301 NULL, NULL, |
|
302 g_cclosure_marshal_VOID__VOID, |
|
303 G_TYPE_NONE, 0); |
|
304 |
|
305 gabble_group_mixin_class_init (object_class, |
|
306 G_STRUCT_OFFSET (GabbleRosterChannelClass, group_class), |
|
307 _gabble_roster_channel_add_member_cb, |
|
308 _gabble_roster_channel_remove_member_cb); |
|
309 |
|
310 dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (gabble_roster_channel_class), &dbus_glib_gabble_roster_channel_object_info); |
|
311 } |
|
312 |
|
313 void |
|
314 gabble_roster_channel_dispose (GObject *object) |
|
315 { |
|
316 GabbleRosterChannel *self = GABBLE_ROSTER_CHANNEL (object); |
|
317 GabbleRosterChannelPrivate *priv = GABBLE_ROSTER_CHANNEL_GET_PRIVATE (self); |
|
318 |
|
319 if (priv->dispose_has_run) |
|
320 return; |
|
321 |
|
322 priv->dispose_has_run = TRUE; |
|
323 |
|
324 g_signal_emit(self, signals[CLOSED], 0); |
|
325 |
|
326 /* release any references held by the object here */ |
|
327 |
|
328 if (G_OBJECT_CLASS (gabble_roster_channel_parent_class)->dispose) |
|
329 G_OBJECT_CLASS (gabble_roster_channel_parent_class)->dispose (object); |
|
330 } |
|
331 |
|
332 void |
|
333 gabble_roster_channel_finalize (GObject *object) |
|
334 { |
|
335 GabbleRosterChannel *self = GABBLE_ROSTER_CHANNEL (object); |
|
336 GabbleRosterChannelPrivate *priv = GABBLE_ROSTER_CHANNEL_GET_PRIVATE (self); |
|
337 |
|
338 /* free any data held directly by the object here */ |
|
339 |
|
340 g_free (priv->object_path); |
|
341 |
|
342 gabble_handle_unref (priv->conn->handles, TP_HANDLE_TYPE_LIST, priv->handle); |
|
343 |
|
344 gabble_group_mixin_finalize (object); |
|
345 |
|
346 G_OBJECT_CLASS (gabble_roster_channel_parent_class)->finalize (object); |
|
347 } |
|
348 |
|
349 |
|
350 static gboolean |
|
351 _gabble_roster_channel_send_presence (GabbleRosterChannel *chan, |
|
352 LmMessageSubType sub_type, |
|
353 GabbleHandle handle, |
|
354 const gchar *status, |
|
355 GError **error) |
|
356 { |
|
357 GabbleRosterChannelPrivate *priv; |
|
358 GabbleHandleRepo *repo; |
|
359 const char *contact; |
|
360 LmMessage *message; |
|
361 gboolean result; |
|
362 |
|
363 priv = GABBLE_ROSTER_CHANNEL_GET_PRIVATE (chan); |
|
364 repo = priv->conn->handles; |
|
365 contact = gabble_handle_inspect (repo, TP_HANDLE_TYPE_CONTACT, handle); |
|
366 |
|
367 message = lm_message_new_with_sub_type (contact, |
|
368 LM_MESSAGE_TYPE_PRESENCE, |
|
369 sub_type); |
|
370 |
|
371 if (LM_MESSAGE_SUB_TYPE_SUBSCRIBE == sub_type) |
|
372 lm_message_node_add_own_nick (message->node, priv->conn); |
|
373 |
|
374 if (status != NULL && status[0] != '\0') |
|
375 lm_message_node_add_child (message->node, "status", status); |
|
376 |
|
377 result = _gabble_connection_send (priv->conn, message, error); |
|
378 |
|
379 lm_message_unref (message); |
|
380 |
|
381 return result; |
|
382 } |
|
383 |
|
384 |
|
385 /** |
|
386 * _gabble_roster_channel_add_member_cb |
|
387 * |
|
388 * Called by the group mixin to add one member. |
|
389 */ |
|
390 static gboolean |
|
391 _gabble_roster_channel_add_member_cb (GObject *obj, |
|
392 GabbleHandle handle, |
|
393 const gchar *message, |
|
394 GError **error) |
|
395 { |
|
396 GabbleRosterChannelPrivate *priv; |
|
397 GabbleHandleRepo *repo; |
|
398 gboolean ret = FALSE; |
|
399 |
|
400 priv = GABBLE_ROSTER_CHANNEL_GET_PRIVATE (GABBLE_ROSTER_CHANNEL (obj)); |
|
401 |
|
402 repo = priv->conn->handles; |
|
403 |
|
404 gabble_debug (DEBUG_FLAG, "called on %s with handle %u (%s) \"%s\"", gabble_handle_inspect (repo, TP_HANDLE_TYPE_LIST, priv->handle), handle, |
|
405 gabble_handle_inspect (repo, TP_HANDLE_TYPE_CONTACT, handle), message); |
|
406 |
|
407 /* publish list */ |
|
408 if (GABBLE_LIST_HANDLE_PUBLISH == priv->handle) |
|
409 { |
|
410 /* send <presence type="subscribed"> */ |
|
411 ret = _gabble_roster_channel_send_presence (GABBLE_ROSTER_CHANNEL (obj), |
|
412 LM_MESSAGE_SUB_TYPE_SUBSCRIBED, handle, message, error); |
|
413 } |
|
414 /* subscribe list */ |
|
415 else if (GABBLE_LIST_HANDLE_SUBSCRIBE == priv->handle) |
|
416 { |
|
417 /* add item to the roster (GTalk depends on this, clearing the H flag) */ |
|
418 gabble_roster_handle_add (priv->conn->roster, handle, NULL); |
|
419 |
|
420 /* send <presence type="subscribe"> */ |
|
421 ret = _gabble_roster_channel_send_presence (GABBLE_ROSTER_CHANNEL (obj), |
|
422 LM_MESSAGE_SUB_TYPE_SUBSCRIBE, handle, message, error); |
|
423 } |
|
424 /* deny list */ |
|
425 else if (GABBLE_LIST_HANDLE_DENY == priv->handle) |
|
426 { |
|
427 /* block contact */ |
|
428 ret = gabble_roster_handle_set_blocked (priv->conn->roster, handle, TRUE, |
|
429 error); |
|
430 } |
|
431 else |
|
432 { |
|
433 g_assert_not_reached (); |
|
434 } |
|
435 |
|
436 return ret; |
|
437 } |
|
438 |
|
439 |
|
440 /** |
|
441 * _gabble_roster_channel_remove_member_cb |
|
442 * |
|
443 * Called by the group mixin to remove one member. |
|
444 */ |
|
445 static gboolean |
|
446 _gabble_roster_channel_remove_member_cb (GObject *obj, |
|
447 GabbleHandle handle, |
|
448 const gchar *message, |
|
449 GError **error) |
|
450 { |
|
451 GabbleRosterChannelPrivate *priv; |
|
452 GabbleHandleRepo *repo; |
|
453 gboolean ret = FALSE; |
|
454 |
|
455 priv = GABBLE_ROSTER_CHANNEL_GET_PRIVATE (GABBLE_ROSTER_CHANNEL (obj)); |
|
456 |
|
457 repo = priv->conn->handles; |
|
458 |
|
459 gabble_debug (DEBUG_FLAG, "called on %s with handle %u (%s) \"%s\"", gabble_handle_inspect (repo, TP_HANDLE_TYPE_LIST, priv->handle), handle, |
|
460 gabble_handle_inspect (repo, TP_HANDLE_TYPE_CONTACT, handle), message); |
|
461 |
|
462 /* publish list */ |
|
463 if (GABBLE_LIST_HANDLE_PUBLISH == priv->handle) |
|
464 { |
|
465 /* send <presence type="unsubscribed"> */ |
|
466 ret = _gabble_roster_channel_send_presence (GABBLE_ROSTER_CHANNEL (obj), |
|
467 LM_MESSAGE_SUB_TYPE_UNSUBSCRIBED, handle, message, error); |
|
468 |
|
469 /* remove it from local_pending here, because roster callback doesn't |
|
470 know if it can (subscription='none' is used both during request and |
|
471 when it's rejected) */ |
|
472 if (handle_set_is_member (GABBLE_ROSTER_CHANNEL (obj)->group.local_pending, handle)) |
|
473 { |
|
474 GIntSet *rem = g_intset_new (); |
|
475 |
|
476 g_intset_add (rem, handle); |
|
477 gabble_group_mixin_change_members (obj, "", NULL, rem, NULL, NULL, |
|
478 0, 0); |
|
479 |
|
480 g_intset_destroy (rem); |
|
481 } |
|
482 } |
|
483 /* subscribe list */ |
|
484 else if (GABBLE_LIST_HANDLE_SUBSCRIBE == priv->handle) |
|
485 { |
|
486 /* send <presence type="unsubscribe"> */ |
|
487 ret = _gabble_roster_channel_send_presence (GABBLE_ROSTER_CHANNEL (obj), |
|
488 LM_MESSAGE_SUB_TYPE_UNSUBSCRIBE, handle, message, error); |
|
489 } |
|
490 /* known list */ |
|
491 else if (GABBLE_LIST_HANDLE_KNOWN == priv->handle) |
|
492 { |
|
493 /* send roster subscription=remove IQ */ |
|
494 ret = gabble_roster_handle_remove (priv->conn->roster, handle, error); |
|
495 } |
|
496 /* deny list */ |
|
497 else if (GABBLE_LIST_HANDLE_DENY == priv->handle) |
|
498 { |
|
499 /* unblock contact */ |
|
500 ret = gabble_roster_handle_set_blocked (priv->conn->roster, handle, FALSE, |
|
501 error); |
|
502 } |
|
503 else |
|
504 { |
|
505 g_assert_not_reached (); |
|
506 } |
|
507 |
|
508 return ret; |
|
509 } |
|
510 |
|
511 |
|
512 /** |
|
513 * gabble_roster_channel_add_members |
|
514 * |
|
515 * Implements D-Bus method AddMembers |
|
516 * on interface org.freedesktop.Telepathy.Channel.Interface.Group |
|
517 * |
|
518 * @error: Used to return a pointer to a GError detailing any error |
|
519 * that occurred, D-Bus will throw the error only if this |
|
520 * function returns FALSE. |
|
521 * |
|
522 * Returns: TRUE if successful, FALSE if an error was thrown. |
|
523 */ |
|
524 gboolean |
|
525 gabble_roster_channel_add_members (GabbleRosterChannel *self, |
|
526 const GArray *contacts, |
|
527 const gchar *message, |
|
528 GError **error) |
|
529 { |
|
530 return gabble_group_mixin_add_members (G_OBJECT (self), contacts, message, |
|
531 error); |
|
532 } |
|
533 |
|
534 |
|
535 /** |
|
536 * gabble_roster_channel_close |
|
537 * |
|
538 * Implements D-Bus method Close |
|
539 * on interface org.freedesktop.Telepathy.Channel |
|
540 * |
|
541 * @error: Used to return a pointer to a GError detailing any error |
|
542 * that occurred, D-Bus will throw the error only if this |
|
543 * function returns FALSE. |
|
544 * |
|
545 * Returns: TRUE if successful, FALSE if an error was thrown. |
|
546 */ |
|
547 gboolean |
|
548 gabble_roster_channel_close (GabbleRosterChannel *self, |
|
549 GError **error) |
|
550 { |
|
551 g_set_error (error, TELEPATHY_ERRORS, NotImplemented, |
|
552 "you may not close contact list channels"); |
|
553 |
|
554 return FALSE; |
|
555 } |
|
556 |
|
557 |
|
558 /** |
|
559 * gabble_roster_channel_get_all_members |
|
560 * |
|
561 * Implements D-Bus method GetAllMembers |
|
562 * on interface org.freedesktop.Telepathy.Channel.Interface.Group |
|
563 * |
|
564 * @error: Used to return a pointer to a GError detailing any error |
|
565 * that occurred, D-Bus will throw the error only if this |
|
566 * function returns FALSE. |
|
567 * |
|
568 * Returns: TRUE if successful, FALSE if an error was thrown. |
|
569 */ |
|
570 gboolean |
|
571 gabble_roster_channel_get_all_members (GabbleRosterChannel *self, |
|
572 GArray **ret, |
|
573 GArray **ret1, |
|
574 GArray **ret2, |
|
575 GError **error) |
|
576 { |
|
577 return gabble_group_mixin_get_all_members (G_OBJECT (self), ret, ret1, ret2, |
|
578 error); |
|
579 } |
|
580 |
|
581 |
|
582 /** |
|
583 * gabble_roster_channel_get_channel_type |
|
584 * |
|
585 * Implements D-Bus method GetChannelType |
|
586 * on interface org.freedesktop.Telepathy.Channel |
|
587 * |
|
588 * @error: Used to return a pointer to a GError detailing any error |
|
589 * that occurred, D-Bus will throw the error only if this |
|
590 * function returns FALSE. |
|
591 * |
|
592 * Returns: TRUE if successful, FALSE if an error was thrown. |
|
593 */ |
|
594 gboolean |
|
595 gabble_roster_channel_get_channel_type (GabbleRosterChannel *self, |
|
596 gchar **ret, |
|
597 GError **error) |
|
598 { |
|
599 *ret = g_strdup (TP_IFACE_CHANNEL_TYPE_CONTACT_LIST); |
|
600 |
|
601 return TRUE; |
|
602 } |
|
603 |
|
604 |
|
605 /** |
|
606 * gabble_roster_channel_get_group_flags |
|
607 * |
|
608 * Implements D-Bus method GetGroupFlags |
|
609 * on interface org.freedesktop.Telepathy.Channel.Interface.Group |
|
610 * |
|
611 * @error: Used to return a pointer to a GError detailing any error |
|
612 * that occurred, D-Bus will throw the error only if this |
|
613 * function returns FALSE. |
|
614 * |
|
615 * Returns: TRUE if successful, FALSE if an error was thrown. |
|
616 */ |
|
617 gboolean |
|
618 gabble_roster_channel_get_group_flags (GabbleRosterChannel *self, |
|
619 guint *ret, |
|
620 GError **error) |
|
621 { |
|
622 return gabble_group_mixin_get_group_flags (G_OBJECT (self), ret, error); |
|
623 } |
|
624 |
|
625 |
|
626 /** |
|
627 * gabble_roster_channel_get_handle |
|
628 * |
|
629 * Implements D-Bus method GetHandle |
|
630 * on interface org.freedesktop.Telepathy.Channel |
|
631 * |
|
632 * @error: Used to return a pointer to a GError detailing any error |
|
633 * that occurred, D-Bus will throw the error only if this |
|
634 * function returns FALSE. |
|
635 * |
|
636 * Returns: TRUE if successful, FALSE if an error was thrown. |
|
637 */ |
|
638 gboolean |
|
639 gabble_roster_channel_get_handle (GabbleRosterChannel *self, |
|
640 guint *ret, |
|
641 guint *ret1, |
|
642 GError **error) |
|
643 { |
|
644 GabbleRosterChannelPrivate *priv; |
|
645 |
|
646 g_assert (GABBLE_IS_ROSTER_CHANNEL (self)); |
|
647 |
|
648 priv = GABBLE_ROSTER_CHANNEL_GET_PRIVATE (self); |
|
649 |
|
650 *ret = TP_HANDLE_TYPE_LIST; |
|
651 *ret1 = priv->handle; |
|
652 |
|
653 return TRUE; |
|
654 } |
|
655 |
|
656 |
|
657 /** |
|
658 * gabble_roster_channel_get_handle_owners |
|
659 * |
|
660 * Implements D-Bus method GetHandleOwners |
|
661 * on interface org.freedesktop.Telepathy.Channel.Interface.Group |
|
662 * |
|
663 * @error: Used to return a pointer to a GError detailing any error |
|
664 * that occurred, D-Bus will throw the error only if this |
|
665 * function returns FALSE. |
|
666 * |
|
667 * Returns: TRUE if successful, FALSE if an error was thrown. |
|
668 */ |
|
669 gboolean |
|
670 gabble_roster_channel_get_handle_owners (GabbleRosterChannel *self, |
|
671 const GArray *handles, |
|
672 GArray **ret, |
|
673 GError **error) |
|
674 { |
|
675 return gabble_group_mixin_get_handle_owners (G_OBJECT (self), handles, ret, |
|
676 error); |
|
677 } |
|
678 |
|
679 |
|
680 /** |
|
681 * gabble_roster_channel_get_interfaces |
|
682 * |
|
683 * Implements D-Bus method GetInterfaces |
|
684 * on interface org.freedesktop.Telepathy.Channel |
|
685 * |
|
686 * @error: Used to return a pointer to a GError detailing any error |
|
687 * that occurred, D-Bus will throw the error only if this |
|
688 * function returns FALSE. |
|
689 * |
|
690 * Returns: TRUE if successful, FALSE if an error was thrown. |
|
691 */ |
|
692 gboolean |
|
693 gabble_roster_channel_get_interfaces (GabbleRosterChannel *self, |
|
694 gchar ***ret, |
|
695 GError **error) |
|
696 { |
|
697 const char *interfaces[] = { TP_IFACE_CHANNEL_INTERFACE_GROUP, NULL }; |
|
698 |
|
699 *ret = g_strdupv ((gchar **) interfaces); |
|
700 |
|
701 return TRUE; |
|
702 } |
|
703 |
|
704 |
|
705 /** |
|
706 * gabble_roster_channel_get_local_pending_members |
|
707 * |
|
708 * Implements D-Bus method GetLocalPendingMembers |
|
709 * on interface org.freedesktop.Telepathy.Channel.Interface.Group |
|
710 * |
|
711 * @error: Used to return a pointer to a GError detailing any error |
|
712 * that occurred, D-Bus will throw the error only if this |
|
713 * function returns FALSE. |
|
714 * |
|
715 * Returns: TRUE if successful, FALSE if an error was thrown. |
|
716 */ |
|
717 gboolean |
|
718 gabble_roster_channel_get_local_pending_members (GabbleRosterChannel *self, |
|
719 GArray **ret, |
|
720 GError **error) |
|
721 { |
|
722 return gabble_group_mixin_get_local_pending_members (G_OBJECT (self), ret, |
|
723 error); |
|
724 } |
|
725 |
|
726 |
|
727 /** |
|
728 * gabble_roster_channel_get_members |
|
729 * |
|
730 * Implements D-Bus method GetMembers |
|
731 * on interface org.freedesktop.Telepathy.Channel.Interface.Group |
|
732 * |
|
733 * @error: Used to return a pointer to a GError detailing any error |
|
734 * that occurred, D-Bus will throw the error only if this |
|
735 * function returns FALSE. |
|
736 * |
|
737 * Returns: TRUE if successful, FALSE if an error was thrown. |
|
738 */ |
|
739 gboolean |
|
740 gabble_roster_channel_get_members (GabbleRosterChannel *self, |
|
741 GArray **ret, |
|
742 GError **error) |
|
743 { |
|
744 return gabble_group_mixin_get_members (G_OBJECT (self), ret, error); |
|
745 } |
|
746 |
|
747 |
|
748 /** |
|
749 * gabble_roster_channel_get_remote_pending_members |
|
750 * |
|
751 * Implements D-Bus method GetRemotePendingMembers |
|
752 * on interface org.freedesktop.Telepathy.Channel.Interface.Group |
|
753 * |
|
754 * @error: Used to return a pointer to a GError detailing any error |
|
755 * that occurred, D-Bus will throw the error only if this |
|
756 * function returns FALSE. |
|
757 * |
|
758 * Returns: TRUE if successful, FALSE if an error was thrown. |
|
759 */ |
|
760 gboolean |
|
761 gabble_roster_channel_get_remote_pending_members (GabbleRosterChannel *self, |
|
762 GArray **ret, |
|
763 GError **error) |
|
764 { |
|
765 return gabble_group_mixin_get_remote_pending_members (G_OBJECT (self), ret, |
|
766 error); |
|
767 } |
|
768 |
|
769 |
|
770 /** |
|
771 * gabble_roster_channel_get_self_handle |
|
772 * |
|
773 * Implements D-Bus method GetSelfHandle |
|
774 * on interface org.freedesktop.Telepathy.Channel.Interface.Group |
|
775 * |
|
776 * @error: Used to return a pointer to a GError detailing any error |
|
777 * that occurred, D-Bus will throw the error only if this |
|
778 * function returns FALSE. |
|
779 * |
|
780 * Returns: TRUE if successful, FALSE if an error was thrown. |
|
781 */ |
|
782 gboolean |
|
783 gabble_roster_channel_get_self_handle (GabbleRosterChannel *self, |
|
784 guint *ret, |
|
785 GError **error) |
|
786 { |
|
787 return gabble_group_mixin_get_self_handle (G_OBJECT (self), ret, error); |
|
788 } |
|
789 |
|
790 |
|
791 /** |
|
792 * gabble_roster_channel_remove_members |
|
793 * |
|
794 * Implements D-Bus method RemoveMembers |
|
795 * on interface org.freedesktop.Telepathy.Channel.Interface.Group |
|
796 * |
|
797 * @error: Used to return a pointer to a GError detailing any error |
|
798 * that occurred, D-Bus will throw the error only if this |
|
799 * function returns FALSE. |
|
800 * |
|
801 * Returns: TRUE if successful, FALSE if an error was thrown. |
|
802 */ |
|
803 gboolean |
|
804 gabble_roster_channel_remove_members (GabbleRosterChannel *self, |
|
805 const GArray *contacts, |
|
806 const gchar *message, |
|
807 GError **error) |
|
808 { |
|
809 return gabble_group_mixin_remove_members (G_OBJECT (self), contacts, message, |
|
810 error); |
|
811 } |
|
812 |
|