2 * empathy-tube-dispatch.c - Source for EmpathyTubeDispatch
3 * Copyright (C) 2008 Collabora Ltd.
4 * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
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.
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.
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
25 #include <telepathy-glib/dbus.h>
26 #include <telepathy-glib/util.h>
27 #include <telepathy-glib/proxy-subclass.h>
29 #include <libempathy/empathy-tube-handler.h>
30 #include <extensions/extensions.h>
32 #include "empathy-tube-dispatch.h"
33 #include "empathy-tube-dispatch-enumtypes.h"
36 G_DEFINE_TYPE(EmpathyTubeDispatch, empathy_tube_dispatch, G_TYPE_OBJECT)
38 static void empathy_tube_dispatch_set_ability (
39 EmpathyTubeDispatch *tube_dispatch,
40 EmpathyTubeDispatchAbility dispatchability);
42 /* private structure */
43 typedef struct _EmpathyTubeDispatchPriv EmpathyTubeDispatchPriv;
52 struct _EmpathyTubeDispatchPriv
54 gboolean dispose_has_run;
55 EmpathyDispatchOperation *operation;
56 EmpathyTubeDispatchAbility dispatchability;
63 (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
64 EMPATHY_TYPE_TUBE_DISPATCH, EmpathyTubeDispatchPriv))
67 empathy_tube_dispatch_init (EmpathyTubeDispatch *obj)
69 EmpathyTubeDispatchPriv *priv = GET_PRIV (obj);
71 priv->dispatchability = EMPATHY_TUBE_DISPATCHABILITY_UNKNOWN;
74 static void empathy_tube_dispatch_dispose (GObject *object);
75 static void empathy_tube_dispatch_finalize (GObject *object);
78 empathy_tube_dispatch_list_activatable_names_cb (TpDBusDaemon *proxy,
79 const gchar **names, const GError *error, gpointer user_data,
82 EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object);
83 EmpathyTubeDispatchPriv *priv = GET_PRIV (self);
86 for (name = (gchar **) names; *name != NULL; name++)
88 if (!tp_strdiff (*name, priv->bus_name))
90 empathy_tube_dispatch_set_ability (self,
91 EMPATHY_TUBE_DISPATCHABILITY_POSSIBLE);
96 empathy_tube_dispatch_set_ability (self,
97 EMPATHY_TUBE_DISPATCHABILITY_IMPOSSIBLE);
101 empathy_tube_dispatch_name_has_owner_cb (TpDBusDaemon *proxy,
102 gboolean has_owner, const GError *error, gpointer user_data,
105 EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object);
106 EmpathyTubeDispatchPriv *priv = GET_PRIV (self);
110 empathy_tube_dispatch_set_ability (self,
111 EMPATHY_TUBE_DISPATCHABILITY_IMPOSSIBLE);
117 empathy_tube_dispatch_set_ability (self,
118 EMPATHY_TUBE_DISPATCHABILITY_POSSIBLE);
122 tp_cli_dbus_daemon_call_list_activatable_names (priv->dbus, -1,
123 empathy_tube_dispatch_list_activatable_names_cb, NULL, NULL,
129 empathy_tube_dispatch_constructed (GObject *object)
131 EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object);
132 EmpathyTubeDispatchPriv *priv = GET_PRIV (self);
134 GHashTable *properties;
135 const gchar *service;
137 priv->dbus = tp_dbus_daemon_new (tp_get_bus());
139 channel = empathy_dispatch_operation_get_channel (priv->operation);
140 properties = tp_channel_borrow_immutable_properties (channel);
142 service = tp_asv_get_string (properties,
143 EMP_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service");
149 priv->bus_name = empathy_tube_handler_build_bus_name (
150 TP_TUBE_TYPE_STREAM, service);
152 empathy_tube_handler_build_object_path (TP_TUBE_TYPE_STREAM, service);
154 tp_cli_dbus_daemon_call_name_has_owner (priv->dbus, -1, priv->bus_name,
155 empathy_tube_dispatch_name_has_owner_cb, NULL, NULL, G_OBJECT (self));
158 g_object_unref (channel);
162 empathy_tube_dispatch_set_ability (self,
163 EMPATHY_TUBE_DISPATCHABILITY_IMPOSSIBLE);
167 empathy_tube_dispatch_set_property (GObject *object,
168 guint property_id, const GValue *value, GParamSpec *pspec)
170 EmpathyTubeDispatch *tube_dispatch = EMPATHY_TUBE_DISPATCH (object);
171 EmpathyTubeDispatchPriv *priv = GET_PRIV (tube_dispatch);
176 priv->operation = g_value_dup_object (value);
179 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
185 empathy_tube_dispatch_get_property (GObject *object,
186 guint property_id, GValue *value, GParamSpec *pspec)
188 EmpathyTubeDispatch *tube_dispatch = EMPATHY_TUBE_DISPATCH (object);
189 EmpathyTubeDispatchPriv *priv = GET_PRIV (tube_dispatch);
194 g_value_set_object (value, priv->operation);
196 case PROP_DISPATCHABILITY:
197 g_value_set_enum (value, priv->dispatchability);
200 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
206 empathy_tube_dispatch_class_init (
207 EmpathyTubeDispatchClass *empathy_tube_dispatch_class)
209 GObjectClass *object_class = G_OBJECT_CLASS (empathy_tube_dispatch_class);
210 GParamSpec *param_spec;
212 g_type_class_add_private (empathy_tube_dispatch_class,
213 sizeof (EmpathyTubeDispatchPriv));
215 object_class->set_property = empathy_tube_dispatch_set_property;
216 object_class->get_property = empathy_tube_dispatch_get_property;
218 object_class->constructed = empathy_tube_dispatch_constructed;
219 object_class->dispose = empathy_tube_dispatch_dispose;
220 object_class->finalize = empathy_tube_dispatch_finalize;
222 param_spec = g_param_spec_object ("operation",
223 "operation", "The telepathy connection",
224 EMPATHY_TYPE_DISPATCH_OPERATION,
225 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
226 g_object_class_install_property (object_class, PROP_OPERATION, param_spec);
228 param_spec = g_param_spec_enum ("dispatchability",
230 "Whether or not there is a handler to dispatch the operation to",
231 EMPATHY_TYPE_TUBE_DISPATCH_ABILITY, EMPATHY_TUBE_DISPATCHABILITY_UNKNOWN,
232 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
233 g_object_class_install_property (object_class, PROP_DISPATCHABILITY,
239 empathy_tube_dispatch_dispose (GObject *object)
241 EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object);
242 EmpathyTubeDispatchPriv *priv = GET_PRIV (self);
244 if (priv->dispose_has_run)
247 priv->dispose_has_run = TRUE;
249 /* release any references held by the object here */
250 if (priv->operation != NULL)
251 g_object_unref (priv->operation);
253 priv->operation = NULL;
255 if (priv->dbus != NULL)
256 g_object_unref (priv->dbus);
261 if (G_OBJECT_CLASS (empathy_tube_dispatch_parent_class)->dispose)
262 G_OBJECT_CLASS (empathy_tube_dispatch_parent_class)->dispose (object);
266 empathy_tube_dispatch_finalize (GObject *object)
268 EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object);
269 EmpathyTubeDispatchPriv *priv = GET_PRIV (self);
271 g_free (priv->bus_name);
272 g_free (priv->object_path);
274 /* free any data held directly by the object here */
276 G_OBJECT_CLASS (empathy_tube_dispatch_parent_class)->finalize (object);
279 EmpathyTubeDispatch *
280 empathy_tube_dispatch_new (EmpathyDispatchOperation *operation)
282 return EMPATHY_TUBE_DISPATCH (g_object_new (EMPATHY_TYPE_TUBE_DISPATCH,
283 "operation", operation, NULL));
286 EmpathyTubeDispatchAbility
287 empathy_tube_dispatch_is_dispatchable (EmpathyTubeDispatch *tube_dispatch)
289 EmpathyTubeDispatchPriv *priv = GET_PRIV (tube_dispatch);
291 return priv->dispatchability;
295 empathy_tube_dispatch_set_ability (EmpathyTubeDispatch *tube_dispatch,
296 EmpathyTubeDispatchAbility dispatchability)
298 EmpathyTubeDispatchPriv *priv = GET_PRIV (tube_dispatch);
300 if (priv->dispatchability == dispatchability)
303 priv->dispatchability = dispatchability;
304 g_object_notify (G_OBJECT (tube_dispatch), "dispatchability");
308 empathy_tube_do_dispatch (EmpathyTubeDispatch *self)
310 EmpathyTubeDispatchPriv *priv = GET_PRIV (self);
318 channel = empathy_dispatch_operation_get_channel (priv->operation);
321 /* Create the proxy for the tube handler */
322 thandler = g_object_new (TP_TYPE_PROXY,
323 "dbus-connection", tp_get_bus (),
324 "bus-name", priv->bus_name,
325 "object-path", priv->object_path,
328 tp_proxy_add_interface_by_id (thandler, EMP_IFACE_QUARK_TUBE_HANDLER);
330 /* Give the tube to the handler */
331 g_object_get (channel,
332 "connection", &connection,
333 "object-path", &object_path,
334 "handle_type", &handle_type,
338 emp_cli_tube_handler_call_handle_tube (thandler, -1,
339 connection->bus_name, connection->object_path,
340 object_path, handle_type, handle, NULL, NULL, NULL, NULL);
342 g_object_unref (channel);
343 g_object_unref (thandler);
344 g_object_unref (connection);
345 g_free (object_path);
349 empathy_tube_dispatch_handle (EmpathyTubeDispatch *tube_dispatch)
351 EmpathyTubeDispatchPriv *priv = GET_PRIV (tube_dispatch);
353 /* Keep ourselves alive untill the dispatching is finished */
354 g_object_ref (tube_dispatch);
356 /* If we can't claim it, don't do anything */
357 if (!empathy_dispatch_operation_claim (priv->operation))
360 if (priv->dispatchability != EMPATHY_TUBE_DISPATCHABILITY_POSSIBLE)
362 TpChannel *channel = empathy_dispatch_operation_get_channel (
365 tp_cli_channel_call_close (channel, -1, NULL, NULL, NULL, NULL);
367 g_object_unref (channel);
371 empathy_tube_do_dispatch (tube_dispatch);
375 g_object_unref (tube_dispatch);