empathy r2157 - trunk/src



Author: xclaesse
Date: Fri Jan  9 16:13:45 2009
New Revision: 2157
URL: http://svn.gnome.org/viewvc/empathy?rev=2157&view=rev

Log:
Add EmpathyTubeDispatcher as a helper for dispatching tubes

Signed-off-by: Sjoerd Simons <sjoerd simons collabora co uk>

Added:
   trunk/src/empathy-tube-dispatch.c
   trunk/src/empathy-tube-dispatch.h
Modified:
   trunk/src/Makefile.am

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Fri Jan  9 16:13:45 2009
@@ -13,6 +13,13 @@
 	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-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 @@
 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)

Added: trunk/src/empathy-tube-dispatch.c
==============================================================================
--- (empty file)
+++ trunk/src/empathy-tube-dispatch.c	Fri Jan  9 16:13:45 2009
@@ -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);
+}
+

Added: trunk/src/empathy-tube-dispatch.h
==============================================================================
--- (empty file)
+++ trunk/src/empathy-tube-dispatch.h	Fri Jan  9 16:13:45 2009
@@ -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__*/



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]