aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSjoerd Simons <sjoerd.simons@collabora.co.uk>2009-01-10 00:13:45 +0800
committerXavier Claessens <xclaesse@src.gnome.org>2009-01-10 00:13:45 +0800
commit0d1f7a91769775a85a3d201fade513978f23557a (patch)
treea997ed93110285f13857e1a9881d1f047e74e098
parentd971d3e84d6c6f5791b3de7557a5708f4d110044 (diff)
downloadgsoc2013-empathy-0d1f7a91769775a85a3d201fade513978f23557a.tar
gsoc2013-empathy-0d1f7a91769775a85a3d201fade513978f23557a.tar.gz
gsoc2013-empathy-0d1f7a91769775a85a3d201fade513978f23557a.tar.bz2
gsoc2013-empathy-0d1f7a91769775a85a3d201fade513978f23557a.tar.lz
gsoc2013-empathy-0d1f7a91769775a85a3d201fade513978f23557a.tar.xz
gsoc2013-empathy-0d1f7a91769775a85a3d201fade513978f23557a.tar.zst
gsoc2013-empathy-0d1f7a91769775a85a3d201fade513978f23557a.zip
Add EmpathyTubeDispatcher as a helper for dispatching tubes
Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk> svn path=/trunk/; revision=2157
-rw-r--r--src/Makefile.am46
-rw-r--r--src/empathy-tube-dispatch.c377
-rw-r--r--src/empathy-tube-dispatch.h75
3 files changed, 498 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index d9c2b2aa4..faf9cd474 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,6 +13,13 @@ bin_PROGRAMS = \
empathy \
empathy-logs
+BUILT_SOURCES= \
+ empathy-marshal.h \
+ empathy-marshal.c \
+ empathy-marshal.list \
+ empathy-tube-dispatch-enumtypes.h \
+ empathy-tube-dispatch-enumtypes.c
+
empathy_SOURCES = \
bacon-message-connection.c bacon-message-connection.h \
empathy.c \
@@ -29,8 +36,11 @@ empathy_SOURCES = \
empathy-new-chatroom-dialog.c empathy-new-chatroom-dialog.h \
empathy-preferences.c empathy-preferences.h \
empathy-status-icon.c empathy-status-icon.h \
+ empathy-tube-dispatch.c empathy-tube-dispatch.h \
ephy-spinner.c ephy-spinner.h
+nodist_empathy_SOURCES = $(BUILT_SOURCES)
+
empathy_logs_SOURCES = empathy-logs.c
gladedir = $(datadir)/empathy
@@ -49,6 +59,42 @@ glade_DATA = \
dist_man_MANS = \
empathy.1
+empathy-marshal.list: $(empathy_SOURCES) Makefile.am
+ ( cd $(srcdir) && \
+ sed -n -e 's/.*empathy_marshal_\([[:upper:][:digit:]]*__[[:upper:][:digit:]_]*\).*/\1/p' \
+ $(empathy_SOURCES) ) \
+ | sed -e 's/__/:/' -e 'y/_/,/' | sort -u > $@.tmp
+ if cmp -s $@.tmp $@; then \
+ rm $@.tmp; \
+ else \
+ mv $@.tmp $@; \
+ fi
+
+%-marshal.h: %-marshal.list Makefile
+ $(GLIB_GENMARSHAL) --header --prefix=_$(subst -,_,$*)_marshal $< > $*-marshal.h
+
+%-marshal.c: %-marshal.list Makefile
+ echo "#include \"empathy-marshal.h\"" > $@ && \
+ $(GLIB_GENMARSHAL) --body --prefix=_$(subst -,_,$*)_marshal $< >> $*-marshal.c
+
+# rules for making the glib enum objects
+%-enumtypes.h: %.h Makefile.in
+ glib-mkenums \
+ --fhead "#ifndef __$(shell echo $* | tr [:lower:]- [:upper:]_)_ENUM_TYPES_H__\n#define __$(shell echo $* | tr [:lower:]- [:upper:]_)_ENUM_TYPES_H__\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n" \
+ --fprod "/* enumerations from \"@filename@\" */\n" \
+ --vhead "GType @enum_name@_get_type (void);\n#define $(shell echo $* | tr [:lower:]- [:upper:]_ | sed 's/_.*//')_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \
+ --ftail "G_END_DECLS\n\n#endif /* __$(shell echo $* | tr [:lower:]- [:upper:]_)_ENUM_TYPES_H__ */" \
+ $< > $@
+
+%-enumtypes.c: %.h Makefile.in
+ glib-mkenums \
+ --fhead "#include <$*.h>\n#include <$*-enumtypes.h>" \
+ --fprod "\n/* enumerations from \"@filename@\" */" \
+ --vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@VALUENAME@\" }," \
+ --vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \
+ $< > $@
+
EXTRA_DIST = \
$(autostart_DATA) \
$(glade_DATA)
diff --git a/src/empathy-tube-dispatch.c b/src/empathy-tube-dispatch.c
new file mode 100644
index 000000000..5c162bb27
--- /dev/null
+++ b/src/empathy-tube-dispatch.c
@@ -0,0 +1,377 @@
+/*
+ * empathy-tube-dispatch.c - Source for EmpathyTubeDispatch
+ * Copyright (C) 2008 Collabora Ltd.
+ * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/util.h>
+#include <telepathy-glib/proxy-subclass.h>
+
+#include <libempathy/empathy-tube-handler.h>
+#include <extensions/extensions.h>
+
+#include "empathy-tube-dispatch.h"
+#include "empathy-tube-dispatch-enumtypes.h"
+
+
+G_DEFINE_TYPE(EmpathyTubeDispatch, empathy_tube_dispatch, G_TYPE_OBJECT)
+
+static void empathy_tube_dispatch_set_ability (
+ EmpathyTubeDispatch *tube_dispatch,
+ EmpathyTubeDispatchAbility dispatchability);
+
+/* private structure */
+typedef struct _EmpathyTubeDispatchPriv EmpathyTubeDispatchPriv;
+
+/* properties */
+enum {
+ PROP_OPERATION = 1,
+ PROP_DISPATCHABILITY
+};
+
+
+struct _EmpathyTubeDispatchPriv
+{
+ gboolean dispose_has_run;
+ EmpathyDispatchOperation *operation;
+ EmpathyTubeDispatchAbility dispatchability;
+ gchar *bus_name;
+ gchar *object_path;
+ TpDBusDaemon *dbus;
+};
+
+#define GET_PRIV(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
+ EMPATHY_TYPE_TUBE_DISPATCH, EmpathyTubeDispatchPriv))
+
+static void
+empathy_tube_dispatch_init (EmpathyTubeDispatch *obj)
+{
+ EmpathyTubeDispatchPriv *priv = GET_PRIV (obj);
+
+ priv->dispatchability = EMPATHY_TUBE_DISPATCHABILITY_UNKNOWN;
+}
+
+static void empathy_tube_dispatch_dispose (GObject *object);
+static void empathy_tube_dispatch_finalize (GObject *object);
+
+static void
+empathy_tube_dispatch_list_activatable_names_cb (TpDBusDaemon *proxy,
+ const gchar **names, const GError *error, gpointer user_data,
+ GObject *object)
+{
+ EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object);
+ EmpathyTubeDispatchPriv *priv = GET_PRIV (self);
+ gchar **name;
+
+ for (name = (gchar **) names; *name != NULL; name++)
+ {
+ if (!tp_strdiff (*name, priv->bus_name))
+ {
+ empathy_tube_dispatch_set_ability (self,
+ EMPATHY_TUBE_DISPATCHABILITY_POSSIBLE);
+ return;
+ }
+ }
+
+ empathy_tube_dispatch_set_ability (self,
+ EMPATHY_TUBE_DISPATCHABILITY_IMPOSSIBLE);
+}
+
+static void
+empathy_tube_dispatch_name_has_owner_cb (TpDBusDaemon *proxy,
+ gboolean has_owner, const GError *error, gpointer user_data,
+ GObject *object)
+{
+ EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object);
+ EmpathyTubeDispatchPriv *priv = GET_PRIV (self);
+
+ if (error != NULL)
+ {
+ empathy_tube_dispatch_set_ability (self,
+ EMPATHY_TUBE_DISPATCHABILITY_IMPOSSIBLE);
+ return;
+ }
+
+ if (has_owner)
+ {
+ empathy_tube_dispatch_set_ability (self,
+ EMPATHY_TUBE_DISPATCHABILITY_POSSIBLE);
+ }
+ else
+ {
+ tp_cli_dbus_daemon_call_list_activatable_names (priv->dbus, -1,
+ empathy_tube_dispatch_list_activatable_names_cb, NULL, NULL,
+ G_OBJECT (self));
+ }
+}
+
+static void
+empathy_tube_dispatch_constructed (GObject *object)
+{
+ EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object);
+ EmpathyTubeDispatchPriv *priv = GET_PRIV (self);
+ TpChannel *channel;
+ GHashTable *properties;
+ const gchar *service;
+
+ priv->dbus = tp_dbus_daemon_new (tp_get_bus());
+
+ channel = empathy_dispatch_operation_get_channel (priv->operation);
+ properties = tp_channel_borrow_immutable_properties (channel);
+
+ service = tp_asv_get_string (properties,
+ EMP_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service");
+
+
+ if (service == NULL)
+ goto failed;
+
+ priv->bus_name = empathy_tube_handler_build_bus_name (
+ TP_TUBE_TYPE_STREAM, service);
+ priv->object_path =
+ empathy_tube_handler_build_object_path (TP_TUBE_TYPE_STREAM, service);
+
+ tp_cli_dbus_daemon_call_name_has_owner (priv->dbus, -1, priv->bus_name,
+ empathy_tube_dispatch_name_has_owner_cb, NULL, NULL, G_OBJECT (self));
+
+
+ g_object_unref (channel);
+ return;
+
+failed:
+ empathy_tube_dispatch_set_ability (self,
+ EMPATHY_TUBE_DISPATCHABILITY_IMPOSSIBLE);
+}
+
+static void
+empathy_tube_dispatch_set_property (GObject *object,
+ guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ EmpathyTubeDispatch *tube_dispatch = EMPATHY_TUBE_DISPATCH (object);
+ EmpathyTubeDispatchPriv *priv = GET_PRIV (tube_dispatch);
+
+ switch (property_id)
+ {
+ case PROP_OPERATION:
+ priv->operation = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+empathy_tube_dispatch_get_property (GObject *object,
+ guint property_id, GValue *value, GParamSpec *pspec)
+{
+ EmpathyTubeDispatch *tube_dispatch = EMPATHY_TUBE_DISPATCH (object);
+ EmpathyTubeDispatchPriv *priv = GET_PRIV (tube_dispatch);
+
+ switch (property_id)
+ {
+ case PROP_OPERATION:
+ g_value_set_object (value, priv->operation);
+ break;
+ case PROP_DISPATCHABILITY:
+ g_value_set_enum (value, priv->dispatchability);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+empathy_tube_dispatch_class_init (
+ EmpathyTubeDispatchClass *empathy_tube_dispatch_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (empathy_tube_dispatch_class);
+ GParamSpec *param_spec;
+
+ g_type_class_add_private (empathy_tube_dispatch_class,
+ sizeof (EmpathyTubeDispatchPriv));
+
+ object_class->set_property = empathy_tube_dispatch_set_property;
+ object_class->get_property = empathy_tube_dispatch_get_property;
+
+ object_class->constructed = empathy_tube_dispatch_constructed;
+ object_class->dispose = empathy_tube_dispatch_dispose;
+ object_class->finalize = empathy_tube_dispatch_finalize;
+
+ param_spec = g_param_spec_object ("operation",
+ "operation", "The telepathy connection",
+ EMPATHY_TYPE_DISPATCH_OPERATION,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_OPERATION, param_spec);
+
+ param_spec = g_param_spec_enum ("dispatchability",
+ "dispatchability",
+ "Whether or not there is a handler to dispatch the operation to",
+ EMPATHY_TYPE_TUBE_DISPATCH_ABILITY, EMPATHY_TUBE_DISPATCHABILITY_UNKNOWN,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_DISPATCHABILITY,
+ param_spec);
+
+}
+
+void
+empathy_tube_dispatch_dispose (GObject *object)
+{
+ EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object);
+ EmpathyTubeDispatchPriv *priv = GET_PRIV (self);
+
+ if (priv->dispose_has_run)
+ return;
+
+ priv->dispose_has_run = TRUE;
+
+ /* release any references held by the object here */
+ if (priv->operation != NULL)
+ g_object_unref (priv->operation);
+
+ priv->operation = NULL;
+
+ if (priv->dbus != NULL)
+ g_object_unref (priv->dbus);
+
+ priv->dbus = NULL;
+
+
+ if (G_OBJECT_CLASS (empathy_tube_dispatch_parent_class)->dispose)
+ G_OBJECT_CLASS (empathy_tube_dispatch_parent_class)->dispose (object);
+}
+
+void
+empathy_tube_dispatch_finalize (GObject *object)
+{
+ EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object);
+ EmpathyTubeDispatchPriv *priv = GET_PRIV (self);
+
+ g_free (priv->bus_name);
+ g_free (priv->object_path);
+
+ /* free any data held directly by the object here */
+
+ G_OBJECT_CLASS (empathy_tube_dispatch_parent_class)->finalize (object);
+}
+
+EmpathyTubeDispatch *
+empathy_tube_dispatch_new (EmpathyDispatchOperation *operation)
+{
+ return EMPATHY_TUBE_DISPATCH (g_object_new (EMPATHY_TYPE_TUBE_DISPATCH,
+ "operation", operation, NULL));
+}
+
+EmpathyTubeDispatchAbility
+empathy_tube_dispatch_is_dispatchable (EmpathyTubeDispatch *tube_dispatch)
+{
+ EmpathyTubeDispatchPriv *priv = GET_PRIV (tube_dispatch);
+
+ return priv->dispatchability;
+}
+
+static void
+empathy_tube_dispatch_set_ability (EmpathyTubeDispatch *tube_dispatch,
+ EmpathyTubeDispatchAbility dispatchability)
+{
+ EmpathyTubeDispatchPriv *priv = GET_PRIV (tube_dispatch);
+
+ if (priv->dispatchability == dispatchability)
+ return;
+
+ priv->dispatchability = dispatchability;
+ g_object_notify (G_OBJECT (tube_dispatch), "dispatchability");
+}
+
+static void
+empathy_tube_do_dispatch (EmpathyTubeDispatch *self)
+{
+ EmpathyTubeDispatchPriv *priv = GET_PRIV (self);
+ TpChannel *channel;
+ TpProxy *connection;
+ TpProxy *thandler;
+ gchar *object_path;
+ guint handle_type;
+ guint handle;
+
+ channel = empathy_dispatch_operation_get_channel (priv->operation);
+
+
+ /* Create the proxy for the tube handler */
+ thandler = g_object_new (TP_TYPE_PROXY,
+ "dbus-connection", tp_get_bus (),
+ "bus-name", priv->bus_name,
+ "object-path", priv->object_path,
+ NULL);
+
+ tp_proxy_add_interface_by_id (thandler, EMP_IFACE_QUARK_TUBE_HANDLER);
+
+ /* Give the tube to the handler */
+ g_object_get (channel,
+ "connection", &connection,
+ "object-path", &object_path,
+ "handle_type", &handle_type,
+ "handle", &handle,
+ NULL);
+
+ emp_cli_tube_handler_call_handle_tube (thandler, -1,
+ connection->bus_name, connection->object_path,
+ object_path, handle_type, handle, NULL, NULL, NULL, NULL);
+
+ g_object_unref (channel);
+ g_object_unref (thandler);
+ g_object_unref (connection);
+ g_free (object_path);
+}
+
+void
+empathy_tube_dispatch_handle (EmpathyTubeDispatch *tube_dispatch)
+{
+ EmpathyTubeDispatchPriv *priv = GET_PRIV (tube_dispatch);
+
+ /* Keep ourselves alive untill the dispatching is finished */
+ g_object_ref (tube_dispatch);
+
+ /* If we can't claim it, don't do anything */
+ if (!empathy_dispatch_operation_claim (priv->operation))
+ goto done;
+
+ if (priv->dispatchability != EMPATHY_TUBE_DISPATCHABILITY_POSSIBLE)
+ {
+ TpChannel *channel = empathy_dispatch_operation_get_channel (
+ priv->operation);
+
+ tp_cli_channel_call_close (channel, -1, NULL, NULL, NULL, NULL);
+
+ g_object_unref (channel);
+ goto done;
+ }
+
+ empathy_tube_do_dispatch (tube_dispatch);
+
+ return;
+done:
+ g_object_unref (tube_dispatch);
+}
+
diff --git a/src/empathy-tube-dispatch.h b/src/empathy-tube-dispatch.h
new file mode 100644
index 000000000..f1328bb68
--- /dev/null
+++ b/src/empathy-tube-dispatch.h
@@ -0,0 +1,75 @@
+/*
+ * empathy-tube-dispatch.h - Header for EmpathyTubeDispatch
+ * Copyright (C) 2008 Collabora Ltd.
+ * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __EMPATHY_TUBE_DISPATCH_H__
+#define __EMPATHY_TUBE_DISPATCH_H__
+
+#include <glib-object.h>
+
+#include <libempathy/empathy-dispatch-operation.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+ EMPATHY_TUBE_DISPATCHABILITY_UNKNOWN,
+ EMPATHY_TUBE_DISPATCHABILITY_POSSIBLE,
+ EMPATHY_TUBE_DISPATCHABILITY_IMPOSSIBLE,
+} EmpathyTubeDispatchAbility;
+
+typedef struct _EmpathyTubeDispatch EmpathyTubeDispatch;
+typedef struct _EmpathyTubeDispatchClass EmpathyTubeDispatchClass;
+
+struct _EmpathyTubeDispatchClass {
+ GObjectClass parent_class;
+};
+
+struct _EmpathyTubeDispatch {
+ GObject parent;
+};
+
+GType empathy_tube_dispatch_get_type(void);
+
+/* TYPE MACROS */
+#define EMPATHY_TYPE_TUBE_DISPATCH \
+ (empathy_tube_dispatch_get_type())
+#define EMPATHY_TUBE_DISPATCH(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_TUBE_DISPATCH, \
+ EmpathyTubeDispatch))
+#define EMPATHY_TUBE_DISPATCH_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_TUBE_DISPATCH, \
+ EmpathyTubeDispatchClass))
+#define EMPATHY_IS_TUBE_DISPATCH(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_TUBE_DISPATCH))
+#define EMPATHY_IS_TUBE_DISPATCH_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_TUBE_DISPATCH))
+#define EMPATHY_TUBE_DISPATCH_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_TUBE_DISPATCH, \
+ EmpathyTubeDispatchClass))
+
+EmpathyTubeDispatch * empathy_tube_dispatch_new (
+ EmpathyDispatchOperation *operation);
+
+EmpathyTubeDispatchAbility empathy_tube_dispatch_is_dispatchable (
+ EmpathyTubeDispatch *tube_dispatch);
+void empathy_tube_dispatch_handle (EmpathyTubeDispatch *tube_dispatch);
+
+G_END_DECLS
+
+#endif /* #ifndef __EMPATHY_TUBE_DISPATCH_H__*/