Re: [GnomeMeeting-devel-list] DBUS component



Le jeudi 21 octobre 2004 à 17:43 +0200, PUYDT Julien a écrit :
> I probably won't have the time to comment it further before next week ;
> but there are already some light comments.

I added a little more comments, and updated the events patch (only fuzzy
changes).

Snark
diff -urN gnomemeeting.events/configure.in gnomemeeting.patched/configure.in
--- gnomemeeting.events/configure.in	2004-10-25 11:52:07 +0200
+++ gnomemeeting.patched/configure.in	2004-10-25 11:53:00 +0200
@@ -406,6 +406,27 @@
 AC_CHECK_TYPES(xmlSAXHandlerV1,,, [#include <libxml/SAX.h>])
 CPPFLAGS="$CPPFLAGS_save"
 
+dnl #########################################################################
+dnl   Check for DBUS
+dnl #########################################################################
+AC_ARG_ENABLE(dbus,
+	[  --enable-dbus       Enable the DBUS component.],
+	enable_dbus=yes, enable_dbus=no)
+
+AC_MSG_CHECKING(whether the DBUS component should be compiled in)
+if test x"${enable_dbus}" = xyes ; then
+   AC_MSG_RESULT([yes])
+else
+   AC_MSG_RESULT([no])
+fi
+
+if test x"${enable_dbus}" = xyes ; then
+   PKG_CHECK_MODULES(DBUS,  dbus-1 = 0.22 dbus-glib-1 = 0.22)
+   GNOMEMEETING_CFLAGS="$GNOMEMEETING_CFLAGS $DBUS_CFLAGS -DHAS_DBUS"
+   GNOMEMEETING_LIBS="$GNOMEMEETING_LIBS $DBUS_LIBS"
+fi
+AM_CONDITIONAL(HAS_DBUS, test x"${enable_dbus}" = xyes)
+AM_CONDITIONAL(DBUS_SERVICES_INSTALL, test x"${enable_dbus}" = xyes)
 
 dnl ###########################################################################
 dnl  The various CFLAGS are merged into GNOMEMEETING_CFLAGS and 
@@ -463,6 +484,7 @@
 Makefile
 src/gnomemeeting-config-tool
 gnomemeeting.schemas.in
+gnomemeeting.service
 lib/Makefile
 lib/about/Makefile
 lib/druid/Makefile
diff -urN gnomemeeting.events/gnomemeeting.service.in gnomemeeting.patched/gnomemeeting.service.in
--- gnomemeeting.events/gnomemeeting.service.in	1970-01-01 01:00:00 +0100
+++ gnomemeeting.patched/gnomemeeting.service.in	2004-10-25 11:53:00 +0200
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=org.gnomemeeting.CallService
+Exec= prefix@/bin/gnomemeeting
+
diff -urN gnomemeeting.events/Makefile.am gnomemeeting.patched/Makefile.am
--- gnomemeeting.events/Makefile.am	2004-10-25 11:52:07 +0200
+++ gnomemeeting.patched/Makefile.am	2004-10-25 11:53:01 +0200
@@ -36,8 +36,15 @@
 	GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) gconftool-2 --makefile-install-rule $(SCHEMAS_FILE) 2>&1 > /dev/null
 	gconftool-2 --shutdown
 
+install-services: gnomemeeting.service
+	cp gnomemeeting.service $(libdir)/dbus-1.0/services/
+
 if GCONF_SCHEMAS_INSTALL
 install-data-local: install-schemas 
 else
 install-data-local:
 endif
+
+if DBUS_SERVICES_INSTALL
+install-data-local: install-services
+endif
diff -urN gnomemeeting.events/src/dbus_component.cpp gnomemeeting.patched/src/dbus_component.cpp
--- gnomemeeting.events/src/dbus_component.cpp	1970-01-01 01:00:00 +0100
+++ gnomemeeting.patched/src/dbus_component.cpp	2004-10-25 14:50:26 +0200
@@ -0,0 +1,643 @@
+#include "dbus_component.h"
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "gm_conf.h"
+
+#include "common.h"
+#include "gnomemeeting.h"
+#include "endpoint.h"
+
+/* declaration of the GObject 
+ * this is pretty stupid/standard code
+ */
+
+
+#define DBUS_COMPONENT_TYPE dbus_component_get_type ()
+
+
+#define DBUS_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+                             DBUS_COMPONENT_TYPE, DBusComponent))
+
+
+#define DBUS_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
+                                     DBUS_COMPONENT_TYPE, DBusComponentClass))
+
+
+#define IS_DBUS_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
+			        DBUS_COMPONENT_TYPE))
+
+
+#define DBUS_COMPONENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+                                       DBUS_COMPONENT_TYPE, \
+                                       DBusComponentClass)) 
+
+
+typedef struct _DBusComponent DBusComponent;
+
+
+typedef struct _DBusComponentClass DBusComponentClass;
+
+
+struct _DBusComponent
+{
+  GObject parent;
+
+  GMH323EndPoint *endpoint; /* gnomemeeting's end of the bridge */
+  DBusConnection *connection; /* DBUS' end of the bridge */
+  gboolean is_registered; /* are we the first gnomemeeting known to DBUS? */
+  gboolean owns_the_service; /* did we manage to own the DBUS service? */
+};
+
+
+struct _DBusComponentClass
+{
+  GObjectClass parent;
+};
+
+
+static GType dbus_component_get_type();
+
+
+static void dbus_component_finalize (GObject *self);
+
+
+static void dbus_component_init (DBusComponent *self);
+
+
+static void dbus_component_class_init (DBusComponentClass *klass);
+
+
+/* declaration of various helpers */
+
+/* turns the endpoint state into a string, easier to move around */
+static const gchar *state_to_string (GMH323EndPoint::CallingState);
+
+/* this function connects/reconnects the component to DBUS
+ * it has that signature because it is also called through a timer, when
+ * we lose the connection
+ */
+static gboolean connect_component (gpointer user_data);
+
+
+/* declaration of the signal callbacks
+ * those are for the signals that the endpoint emits on the component, and that
+ * it will then broadcast on DBUS.
+ */
+
+
+static void call_begin_cb (GObject *self,
+			   gchar *call_token,
+			   gpointer user_data);
+
+
+static void call_end_cb (GObject *self,
+			 gchar *call_token,
+			 gpointer user_data);
+
+
+static void endpoint_state_changed_cb (GObject *self,
+				       GMH323EndPoint::CallingState new_state,
+				       gpointer user_data);
+
+
+/* declaration of the DBUS helper functions */
+
+
+/* this function is called by DBUS when a watched type of message
+ * arrives ; it is only used to know if we're still connected to the bus
+ */
+static DBusHandlerResult filter_func (DBusConnection *connection,
+				      DBusMessage *message,
+				      void *user_data);
+
+
+
+/* this function is called by DBUS when a message directed at the
+ * GM_DBUS_OBJECT_PATH arrives (provided we're the registered instance!)
+ * it routes the message to the correct handler
+ */
+static DBusHandlerResult path_message_func (DBusConnection *connection,
+					    DBusMessage *message,
+					    void *user_data);
+
+/* the rest of those DBUS helpers, with name "handle_<method call>_message",
+ * are used to handle the various method calls. They get their arguments
+ * directly from path_message_func.
+ */
+static void handle_connect_to_message (DBusConnection *connection,
+				       DBusMessage *message);
+
+
+static void handle_get_state_message (DBusConnection *connection,
+				      DBusMessage *message);
+
+
+static void handle_disconnect_message (DBusConnection *connection,
+				       DBusMessage *message);
+
+
+static void handle_get_calls_list_message (DBusConnection *connection,
+					   DBusMessage *message);
+
+
+static void handle_get_call_info_message (DBusConnection *connection,
+					  DBusMessage *message);
+
+
+/* definition of some helper DBUS-related data */
+
+
+static DBusObjectPathVTable call_vtable = {
+  NULL,
+  path_message_func,
+  NULL,
+};
+
+
+/* Implementation of the GObject */
+
+
+static GType
+dbus_component_get_type()
+{
+  static GType my_type = 0; 
+  
+  if (!my_type) {
+    static const GTypeInfo my_info = {
+      sizeof (DBusComponentClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) dbus_component_class_init,
+      NULL,
+      NULL,
+      sizeof(DBusComponent),
+      0,
+      (GInstanceInitFunc) dbus_component_init
+    };
+    my_type = g_type_register_static (G_TYPE_OBJECT ,
+				      "DBusComponent", &my_info, 
+				      (GTypeFlags)0);
+  }
+  
+  return my_type;
+}
+
+
+static void
+dbus_component_finalize (GObject *object)
+{
+  DBusComponent *self = NULL;
+  GObjectClass *parent_class = NULL;
+
+  g_return_if_fail (IS_DBUS_COMPONENT (object));
+
+  self = DBUS_COMPONENT (object);
+
+  if (self->connection != NULL) {
+    dbus_connection_disconnect (self->connection);
+    dbus_connection_unref (self->connection);
+  }
+ 
+  parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (DBUS_COMPONENT_GET_CLASS (self)));
+
+  parent_class->finalize (G_OBJECT(self));
+}
+
+
+static void
+dbus_component_init (DBusComponent *self)
+{
+  self->endpoint = NULL;
+  self->connection = NULL;
+  self->is_registered = FALSE;
+  self->owns_the_service = FALSE;
+
+  g_signal_connect (G_OBJECT (self),
+		    "call-begin",
+		    G_CALLBACK (call_begin_cb),
+		    NULL);
+  g_signal_connect (G_OBJECT (self),
+		    "call-end",
+		    G_CALLBACK (call_end_cb),
+		    NULL);
+  g_signal_connect (G_OBJECT (self),
+		    "endpoint-state-changed",
+		    G_CALLBACK (endpoint_state_changed_cb),
+		    NULL);
+}
+
+
+static void dbus_component_class_init (DBusComponentClass *klass)
+{
+  GObjectClass *object_klass = G_OBJECT_CLASS (klass);
+
+  object_klass->finalize = dbus_component_finalize;
+}
+
+
+/* implementation of various helpers */
+
+
+static const gchar*
+state_to_string (GMH323EndPoint::CallingState state)
+{
+  const gchar *result;
+
+  switch (state) {
+  case GMH323EndPoint::Standby:
+    result = "Standby";
+    break;
+  case GMH323EndPoint::Calling:
+    result = "Calling";
+    break;
+  case GMH323EndPoint::Connected:
+    result  = "Connected";
+    break;
+  case GMH323EndPoint::Called:
+    result = "Called";
+    break;
+  default:
+    result = "Bogus";
+  }
+  
+  return result;
+} 
+
+
+static gboolean
+connect_component (gpointer user_data)
+{
+  DBusComponent *self = NULL;
+  
+  g_return_val_if_fail (IS_DBUS_COMPONENT (user_data), TRUE);
+
+  self = DBUS_COMPONENT (user_data);
+
+  if (self->connection == NULL) { /* we lost contact with the server */
+    self->connection = dbus_bus_get (DBUS_BUS_SESSION, NULL);
+    if (self->connection != NULL) {
+      if (dbus_connection_add_filter (self->connection, 
+				      filter_func,
+				      self, NULL))
+ 	dbus_connection_setup_with_g_main (self->connection, NULL);
+      else {
+	dbus_connection_disconnect (self->connection);
+	self->connection = NULL;
+      }
+    }
+  }
+
+  if (self->connection != NULL) {  
+    /* we have a contact with the server, check the rest */
+    if (self->is_registered == FALSE)
+      self->is_registered 
+	= dbus_connection_register_object_path (self->connection,
+						GM_DBUS_OBJECT_PATH,
+						&call_vtable, self);
+    
+    if (self->owns_the_service == FALSE)
+      self->owns_the_service 
+	= (dbus_bus_acquire_service (self->connection, 
+				     GM_DBUS_SERVICE, 0, NULL) >= 0);
+    
+ 
+  }
+
+  return self->connection != NULL && self->is_registered && self->owns_the_service;
+}
+
+
+/* implementation of the signal callbacks */
+
+
+static void
+call_begin_cb (GObject *object,
+	       gchar *call_token,
+	       gpointer user_data)
+{
+  DBusComponent *self = NULL;
+  DBusMessage *message = NULL;
+
+  g_return_if_fail (IS_DBUS_COMPONENT (object));
+
+  self = DBUS_COMPONENT (object);
+
+  if (self->connection == NULL)
+    return;
+
+  message = dbus_message_new_signal (GM_DBUS_OBJECT_PATH,
+				     GM_DBUS_INTERFACE, "AddCall");
+
+  if (dbus_message_append_args (message,
+				DBUS_TYPE_STRING, call_token,
+				DBUS_TYPE_INVALID)) {
+    (void)dbus_connection_send (self->connection, message, NULL);
+    dbus_connection_flush (self->connection);
+  }
+  dbus_message_unref (message);
+}
+
+
+static void
+call_end_cb (GObject *object,
+	     gchar *call_token,
+	     gpointer user_data)
+{
+  DBusComponent *self = NULL;
+  DBusMessage *message = NULL;
+
+  g_return_if_fail (IS_DBUS_COMPONENT (object));
+
+  self = DBUS_COMPONENT (object);
+
+  if (self->connection == NULL)
+    return;
+
+  message = dbus_message_new_signal (GM_DBUS_OBJECT_PATH,
+				     GM_DBUS_INTERFACE, "DeleteCall");
+
+  if (dbus_message_append_args (message,
+				DBUS_TYPE_STRING, call_token,
+				DBUS_TYPE_INVALID)) {
+    (void)dbus_connection_send (self->connection, message, NULL);
+    dbus_connection_flush (self->connection);
+  }
+  dbus_message_unref (message);
+}
+
+
+static void
+endpoint_state_changed_cb (GObject *object,
+			   GMH323EndPoint::CallingState new_state,
+			   gpointer user_data)
+{
+  DBusComponent *self = NULL;
+  DBusMessage *message = NULL;
+
+  g_return_if_fail (IS_DBUS_COMPONENT (object));
+
+  self = DBUS_COMPONENT (object);
+
+  if (self->connection == NULL)
+    return;
+
+  message = dbus_message_new_signal (GM_DBUS_OBJECT_PATH,
+				     GM_DBUS_INTERFACE, "StateChanged");
+
+  if (dbus_message_append_args (message,
+				DBUS_TYPE_STRING, state_to_string (new_state),
+				DBUS_TYPE_INVALID)) {
+    (void)dbus_connection_send (self->connection, message, NULL);
+    dbus_connection_flush (self->connection);
+  }
+  dbus_message_unref (message);
+}
+
+
+/* implementation of the DBUS helpers */
+
+
+static DBusHandlerResult
+filter_func (DBusConnection *connection,
+	     DBusMessage *message,
+	     void *user_data)
+{
+  DBusComponent *self = NULL;
+
+  g_return_val_if_fail (user_data != NULL,
+			DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+
+  self = DBUS_COMPONENT (user_data);
+
+  g_return_val_if_fail (self->connection == connection,
+			DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+
+  if (dbus_message_is_signal (message,
+                              DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
+                              "Disconnected"))
+    {
+      dbus_connection_unref (self->connection);
+      self->connection = NULL;
+      self->is_registered = FALSE;
+      self->owns_the_service = FALSE;
+      g_timeout_add (3000, connect_component, (gpointer)self);
+
+      return DBUS_HANDLER_RESULT_HANDLED;
+    }
+
+  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+
+static DBusHandlerResult
+path_message_func (DBusConnection *connection,
+                   DBusMessage *message,
+                   void *user_data)
+{
+  DBusComponent *self = NULL;
+  DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+  self = DBUS_COMPONENT (user_data);
+  if (dbus_message_is_method_call (message,
+                                   GM_DBUS_SERVICE,
+                                   "ConnectTo")) {
+    handle_connect_to_message (connection, message);
+    result = DBUS_HANDLER_RESULT_HANDLED;
+  }
+  else if (dbus_message_is_method_call (message,
+					GM_DBUS_SERVICE,
+					"GetState")) {
+    handle_get_state_message (connection, message);
+    result = DBUS_HANDLER_RESULT_HANDLED;
+  }
+  else if (dbus_message_is_method_call (message,
+					GM_DBUS_SERVICE,
+					"Disconnect")) {
+    handle_disconnect_message (connection, message);
+    result = DBUS_HANDLER_RESULT_HANDLED;
+  }
+  else if (dbus_message_is_method_call (message,
+					GM_DBUS_SERVICE,
+					"GetCallsList")) {
+    handle_get_calls_list_message (connection, message);
+    result = DBUS_HANDLER_RESULT_HANDLED;
+  }
+  else if (dbus_message_is_method_call (message,
+					GM_DBUS_SERVICE,
+					"GetCallInfo")) {
+    handle_get_call_info_message (connection, message);
+    result = DBUS_HANDLER_RESULT_HANDLED;
+  }
+  
+  return result;
+}
+
+
+static void
+handle_connect_to_message (DBusConnection *connection,
+			   DBusMessage *message)
+{
+  gchar *address = NULL;
+
+  if (dbus_message_get_args (message, NULL,
+			     DBUS_TYPE_STRING, &address,
+			     DBUS_TYPE_INVALID)) {
+    GnomeMeeting::Process ()->Connect (address);
+  }
+}
+
+
+static void
+handle_get_state_message (DBusConnection *connection,
+			  DBusMessage *message)
+{
+  DBusMessage *reply = NULL;
+  const gchar *state = NULL;
+  GMH323EndPoint *ep = NULL;
+
+  ep = GnomeMeeting::Process ()->Endpoint ();
+  
+  reply = dbus_message_new_method_return (message);
+  state = state_to_string (ep->GetCallingState ());
+  if (dbus_message_append_args (reply,
+				DBUS_TYPE_STRING, state,
+				DBUS_TYPE_INVALID)) {
+    (void)dbus_connection_send (connection, reply, NULL);
+    dbus_connection_flush (connection);
+  }
+  dbus_message_unref (reply);
+}
+
+
+static void
+handle_disconnect_message (DBusConnection *connection,
+			   DBusMessage *message)
+{
+  gchar *call_token = NULL;
+  if (dbus_message_get_args (message, NULL,
+			     DBUS_TYPE_STRING, &call_token,
+			     DBUS_TYPE_INVALID)) {  
+    /* FIXME: should use call_token, when gnomemeeting will support it! */
+    GnomeMeeting::Process ()->Disconnect ();
+  }
+}
+
+
+static void
+handle_get_calls_list_message (DBusConnection *connection,
+			       DBusMessage *message)
+{
+  DBusMessage *reply = NULL;
+  const char *call_token = NULL;
+  GMH323EndPoint *ep = NULL;
+
+  ep = GnomeMeeting::Process ()->Endpoint ();
+  
+  reply = dbus_message_new_method_return (message);
+  call_token = (const char *)ep->GetCurrentCallToken ();
+  if (dbus_message_append_args (reply,
+				DBUS_TYPE_STRING, call_token,
+				DBUS_TYPE_INVALID)) {
+    (void)dbus_connection_send (connection, reply, NULL);
+    dbus_connection_flush (connection);
+  }
+  dbus_message_unref (reply);
+}
+
+
+static void
+handle_get_call_info_message (DBusConnection *connection,
+			      DBusMessage *message)
+{
+  DBusMessage *reply = NULL;
+  const char *call_token = NULL;
+  GMH323EndPoint *ep = NULL;
+  H323Connection *h323connection = NULL;
+  gchar *name = NULL;
+  gchar *url = NULL;
+  gchar *app = NULL;
+
+  ep = GnomeMeeting::Process ()->Endpoint ();
+
+  if (dbus_message_get_args (message, NULL,
+			     DBUS_TYPE_STRING, &call_token,
+			     DBUS_TYPE_INVALID)) {  
+    h323connection = ep->FindConnectionWithLock((PString)call_token);
+    if (h323connection) {
+      ep->GetRemoteConnectionInfo (*h323connection, name, app, url);
+      h323connection->Unlock ();
+    }
+    reply = dbus_message_new_method_return (message);
+    if (dbus_message_append_args (reply,
+				  DBUS_TYPE_STRING, name,
+				  DBUS_TYPE_STRING, url,
+				  DBUS_TYPE_STRING, app,
+				  DBUS_TYPE_INVALID)) {
+      (void)dbus_connection_send (connection, reply, NULL);
+      dbus_connection_flush (connection);
+    }
+    dbus_message_unref (reply);
+  }
+}
+
+
+/* implementation of the externally-visible api */
+
+
+GObject*
+dbus_component_new(GMH323EndPoint *endpoint)
+{
+  DBusComponent *result = NULL;
+
+  result = DBUS_COMPONENT (g_object_new (DBUS_COMPONENT_TYPE, NULL));
+
+  result->endpoint = endpoint;
+  result->endpoint->AddObserver (G_OBJECT (result));
+
+  (void)connect_component ((gpointer)result);
+
+  return G_OBJECT (result);
+}
+
+
+gboolean
+dbus_component_is_first_instance (GObject *object)
+{
+  g_return_val_if_fail (IS_DBUS_COMPONENT (object), FALSE);
+
+  return DBUS_COMPONENT (object)->is_registered;
+}
+
+
+void
+dbus_component_call_address (GObject *object, 
+			     gchar *address)
+{
+  DBusMessage *message = NULL;
+  DBusComponent *self = NULL;
+
+  g_return_if_fail (IS_DBUS_COMPONENT (object));
+ 
+  self = DBUS_COMPONENT (object);
+ 
+  if (self->connection == NULL)
+    return;
+
+  message = dbus_message_new_method_call (GM_DBUS_SERVICE,
+					  GM_DBUS_OBJECT_PATH,
+					  GM_DBUS_INTERFACE, "Call");
+
+  dbus_message_set_no_reply (message, TRUE);
+  
+  if (dbus_message_append_args (message,
+				DBUS_TYPE_STRING, address,
+				DBUS_TYPE_INVALID)) {
+    
+    (void)dbus_connection_send (self->connection,
+				message, NULL);
+    dbus_connection_flush (self->connection);
+  }
+  dbus_message_unref (message);
+}
diff -urN gnomemeeting.events/src/dbus_component.h gnomemeeting.patched/src/dbus_component.h
--- gnomemeeting.events/src/dbus_component.h	1970-01-01 01:00:00 +0100
+++ gnomemeeting.patched/src/dbus_component.h	2004-10-25 12:20:12 +0200
@@ -0,0 +1,115 @@
+#ifndef _DBUS_COMPONENT_H_
+#define _DBUS_COMPONENT_H_
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "endpoint.h"
+
+/*
+ * This code makes gnomemeeting 'remote' controlled by DBUS
+ * 
+ * It provides two main types of functionality:
+ * 1) it receives messages to DBUS, and makes gnomemeeting react to it
+ * (get the list of connections, make or stop a call, etc) ; those work by
+ * directly calling the endpoint's api.
+ * 2) it sends messages to DBUS to notify from various events
+ * (new call, call end, etc). Those work by getting signals from the events
+ * dispatcher.
+ *
+ * It is a sort of bridge between a DBUS daemon and a gnomemeeting endpoint.
+ */
+
+/* Here is the description of DBUS messages understood by this component:
+ *
+ * Method calls:
+ * =============
+ *
+ * "ConnectTo"
+ * in    : string (url)
+ * out   : nil
+ * action: makes gnomemeeting call the given url
+ *
+ * "GetState"
+ * in    : nil
+ * out   : string (describes gnomemeeting's state: Standby, Calling, etc)
+ * action: none
+ *
+ * "Disconnect"
+ * in    : string (call token)
+ * out   : nil
+ * action: gnomemeeting disconnects the given call
+ *
+ * "GetCallsList"
+ * in    : nil
+ * out   : list of strings (call tokens, iterate to get them)
+ * action: none
+ *
+ * "GetCallInfo"
+ * in    : string (call token)
+ * out   : string (name), string (url) and string (application)
+ * action: none
+ *
+ * Signals:
+ * ========
+ *
+ * "StateChanged"
+ * data: string (state)
+ * goal: gnomemeeting's state changed
+ *
+ * "AddCall"
+ * data: string (call token)
+ * goal: gnomemeeting manages a new call
+ *
+ * "DeleteCall"
+ * data: string (call token)
+ * goal: gnomemeeting closed a call (ie: the call token isn't valid anymore!)
+ *
+ */
+
+/* Here are gnomemeeting's signals received by this component:
+ * (those are described in lib/gm_events.h)
+ * "call-begin" ;
+ * "call-end" ;
+ * "endpoint-state-changed".
+ */
+
+#define GM_DBUS_OBJECT_PATH "/org/gnomemeeting/Endpoint"
+#define GM_DBUS_INTERFACE "org.gnomemeeting.CallService"
+#define GM_DBUS_SERVICE "org.gnomemeeting.CallService"
+
+
+G_BEGIN_DECLS
+
+
+/* DESCRIPTION  : /
+ * BEHAVIOR     : Returns a valid DBUS component casted as a GObject
+ * PRE          : a valid endpoint
+ */
+GObject *dbus_component_new(GMH323EndPoint *endpoint);
+
+
+/* the two following functions, currently unused, could be used by Damien
+ * to make so that if gnomemeeting is called with "-c url", then if there's
+ * already another instance, pass it the call and exit.
+ */
+
+/* DESCRIPTION  : /
+ * BEHAVIOR     : Returns TRUE if there's no other gnomemeeting registered
+ *                on DBUS.
+ * PRE          : A non-NULL DBUS component casted as a GObject
+ */
+gboolean dbus_component_is_first_instance (GObject *object);
+
+
+/* DESCRIPTION  : /
+ * BEHAVIOR     : Makes the gnomemeeting registered on DBUS call the given
+ *                url.
+ * PRE          : A non-NULL DBUS component casted as a GObject, and an URL
+ */
+void dbus_component_call_address (GObject *object, gchar *url);
+
+
+G_END_DECLS
+
+#endif
diff -urN gnomemeeting.events/src/gnomemeeting.cpp gnomemeeting.patched/src/gnomemeeting.cpp
--- gnomemeeting.events/src/gnomemeeting.cpp	2004-10-25 11:52:07 +0200
+++ gnomemeeting.patched/src/gnomemeeting.cpp	2004-10-25 11:53:01 +0200
@@ -52,6 +52,9 @@
 #include "log_window.h"
 #include "main_window.h"
 #include "misc.h"
+#ifdef HAS_DBUS
+#include "dbus_component.h"
+#endif
 
 #include "dialog.h"
 #include "e-splash.h"
@@ -137,6 +140,8 @@
     gtk_widget_destroy (main_window);
   if (druid_window)
     gtk_widget_destroy (druid_window);
+  if (dbus_component)
+    g_object_unref (dbus_component);
 }
 
 
@@ -417,6 +422,11 @@
 #ifndef WIN32
   tray = gm_tray_new ();
 #endif
+#ifdef HAS_DBUS
+  dbus_component = dbus_component_new (endpoint);
+#else
+  dbus_component = NULL;
+#endif
   main_window = gm_main_window_new ();
 
 
diff -urN gnomemeeting.events/src/gnomemeeting.h gnomemeeting.patched/src/gnomemeeting.h
--- gnomemeeting.events/src/gnomemeeting.h	2004-10-25 11:52:06 +0200
+++ gnomemeeting.patched/src/gnomemeeting.h	2004-10-25 11:53:01 +0200
@@ -274,6 +274,9 @@
   GtkWidget *pc2phone_window;
   GtkWidget *tray;
 
+  /* other things */
+  GObject *dbus_component;
+
   static GnomeMeeting *GM;
 };
 
diff -urN gnomemeeting.events/src/Makefile.am gnomemeeting.patched/src/Makefile.am
--- gnomemeeting.events/src/Makefile.am	2004-10-25 11:52:06 +0200
+++ gnomemeeting.patched/src/Makefile.am	2004-10-25 11:53:01 +0200
@@ -61,6 +61,10 @@
 gnomemeeting_SOURCES += bonobo_component.cpp bonobo_component.h
 endif
 
+if HAS_DBUS 
+gnomemeeting_SOURCES += dbus_component.cpp dbus_component.h
+endif
+
 gnomemeeting_LDADD = \
 	@GNOMEMEETING_LIBS@ \
 	$(top_builddir)/lib/libgnomemeeting.la
diff -urN gnomemeeting/lib/Makefile.am gnomemeeting.events/lib/Makefile.am
--- gnomemeeting/lib/Makefile.am	2004-10-16 20:04:37 +0200
+++ gnomemeeting.events/lib/Makefile.am	2004-10-25 11:52:15 +0200
@@ -29,7 +29,9 @@
 	eggtrayicon.h					\
 	eggtrayicon.c					\
 	stats_drawing_area.h				\
-	stats_drawing_area.c				
+	stats_drawing_area.c				\
+	gm_events.h					\
+	gm_events.c
 
 if DISABLE_GNOME
 libgnomemeeting_la_SOURCES += gm_conf-glib.c
diff -urN gnomemeeting/src/endpoint.cpp gnomemeeting.events/src/endpoint.cpp
--- gnomemeeting/src/endpoint.cpp	2004-10-25 09:23:37 +0200
+++ gnomemeeting.events/src/endpoint.cpp	2004-10-25 11:52:15 +0200
@@ -57,6 +57,7 @@
 
 #include "dialog.h"
 #include "gm_conf.h"
+#include "gm_events.h"
 
 #include <h261codec.h>
 
@@ -107,6 +108,8 @@
 
   missed_calls = 0;
 
+  dispatcher = gm_events_dispatcher_new ();
+
   last_audio_octets_received = 0;
   last_video_octets_received = 0;
   last_audio_octets_transmitted = 0;
@@ -139,6 +142,9 @@
   if (ils_client)
     delete (ils_client);
 
+  if (dispatcher)
+    g_object_unref (dispatcher);
+
   /* Create a new one to unregister */
   if (ils_registered) {
     
@@ -321,6 +327,9 @@
   PWaitAndSignal m(cs_access_mutex);
   
   calling_state = i;
+  /* FIXME: holding a mutex!? */
+  if (dispatcher)
+    g_signal_emit_by_name (dispatcher, "endpoint-state-changed", i);
 }
 
 
@@ -1083,6 +1092,8 @@
   gm_tray_update_calling_state (tray, GMH323EndPoint::Connected);
   gm_tray_update (tray, GMH323EndPoint::Connected, icm, forward_on_busy);
   gnomemeeting_threads_leave ();
+  if (dispatcher)
+    g_signal_emit_by_name (dispatcher, "call-begin", (const gchar *)token);
 
   
   /* Update ILS if needed */
@@ -1347,6 +1358,9 @@
   gnomemeeting_text_chat_call_stop_notification (chat_window);
   gm_main_window_flash_message (main_window, msg_reason);
   gnomemeeting_threads_leave ();
+  if (dispatcher)
+    g_signal_emit_by_name (dispatcher, "call-end",
+			   (const gchar *)clearedCallToken);
 
   g_free (utf8_app);
   g_free (utf8_name);
@@ -2708,6 +2722,13 @@
   return missed_calls;
 }
 
+void
+GMH323EndPoint::AddObserver (GObject *observer)
+{
+  g_return_if_fail (observer != NULL);
+
+  gm_events_dispatcher_add_observer (dispatcher, observer);
+}
 
 PString
 GMH323EndPoint::GetLastCallAddress ()
diff -urN gnomemeeting/src/endpoint.h gnomemeeting.events/src/endpoint.h
--- gnomemeeting/src/endpoint.h	2004-10-25 09:23:38 +0200
+++ gnomemeeting.events/src/endpoint.h	2004-10-25 11:52:15 +0200
@@ -730,6 +730,7 @@
   H323ListenerTCP *listener;  
 
   CallingState calling_state; 
+  GObject *dispatcher;
 
   PTimer ILSTimer;
   PTimer RTPTimer;
diff -urN gnomemeeting/src/main_window.cpp gnomemeeting.events/src/main_window.cpp
--- gnomemeeting/src/main_window.cpp	2004-10-22 18:48:48 +0200
+++ gnomemeeting.events/src/main_window.cpp	2004-10-25 11:52:15 +0200
@@ -49,6 +49,7 @@
 #include "lid.h"
 #include "sound_handling.h"
 #include "urlhandler.h"
+#include "gm_events.h"
 
 #include <dialog.h>
 #include <gmentrydialog.h>
@@ -4156,7 +4157,7 @@
   xmlInitParser ();
 
   gm_conf_init (argc, argv);
-  
+  gm_events_init ();
   
   /* Upgrade the preferences */
   gnomemeeting_conf_upgrade ();


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