Bonobo Unique Application v2



  Attached is an update of the Unique Application code for libbonobo. 
This time it is a single patch, against the new merged
bonobo-activation/libbonobo.
  Changes: 
    - a possible bug was fixed;
    - added a gtk-doc comment header to document
bonobo_register_active_server_ext();
    - changed the POAManager to the 'holding' state around emission of
the 'message' signal to avoid reentrancy problems.  Notes:
        1. Michael, is there a better way to obtain the POAManager from
the servant without ORBit2 internal API?
        2. Alexander, emission in an idle handler is not possible
because of the return value.  Unless I remove the return value, but I
prefer to keep it if possible.

  It is safe to install this, since the changes are API/ABI backwards
compatible.

  Don't be afraid to criticize. :)

-- 
Gustavo Carneiro

? autom4te.cache
? stamp-h1
? activation-server/test-performance
? bonobo-activation/bonobo-activation-2.0.pc
? tests/test-uniqapp
Index: libbonobo.h
===================================================================
RCS file: /cvs/gnome/libbonobo/libbonobo.h,v
retrieving revision 1.60
diff -u -r1.60 libbonobo.h
--- libbonobo.h	19 Nov 2001 00:13:33 -0000	1.60
+++ libbonobo.h	12 Apr 2003 20:16:57 -0000
@@ -44,6 +44,8 @@
 
 #include <bonobo/bonobo-storage.h>
 #include <bonobo/bonobo-storage-memory.h>
+#include <bonobo/bonobo-application.h>
+#include <bonobo/bonobo-app-client.h>
 
 G_END_DECLS
 
Index: activation-server/activation-server-main.c
===================================================================
RCS file: /cvs/gnome/libbonobo/activation-server/activation-server-main.c,v
retrieving revision 1.48
diff -u -r1.48 activation-server-main.c
--- activation-server/activation-server-main.c	7 Apr 2003 11:33:29 -0000	1.48
+++ activation-server/activation-server-main.c	12 Apr 2003 20:16:58 -0000
@@ -218,7 +218,7 @@
         PortableServer_POA            root_poa;
         CORBA_ORB                     orb;
         CORBA_Environment             real_ev, *ev;
-        CORBA_Object                  naming_service;
+        CORBA_Object                  naming_service, existing;
         Bonobo_ActivationEnvironment  environment;
         Bonobo_ObjectDirectory        od;
         poptContext                   ctx;
@@ -280,7 +280,9 @@
         if (naming_service == NULL)
                 g_warning ("Failed to create naming service");
         Bonobo_ObjectDirectory_register_new 
-                (od, NAMING_CONTEXT_IID, &environment, naming_service, ev);
+                (od, NAMING_CONTEXT_IID, &environment, naming_service, 0, &existing, ev);
+	if (existing != CORBA_OBJECT_NIL)
+		CORBA_Object_release (existing, NULL);
 
         if (ior_fd < 0 && !server_ac)
                 g_error ("\n\n-- \nThe bonobo-activation-server must be forked by\n"
Index: activation-server/object-directory-corba.c
===================================================================
RCS file: /cvs/gnome/libbonobo/activation-server/object-directory-corba.c,v
retrieving revision 1.56
diff -u -r1.56 object-directory-corba.c
--- activation-server/object-directory-corba.c	24 Feb 2003 11:51:10 -0000	1.56
+++ activation-server/object-directory-corba.c	12 Apr 2003 20:17:00 -0000
@@ -702,21 +702,26 @@
 	const CORBA_char                   *iid,
 	const Bonobo_ActivationEnvironment *environment,
 	const CORBA_Object                  obj,
+        Bonobo_RegistrationFlags            flags,
+        CORBA_Object                       *existing,
 	CORBA_Environment                  *ev)
 {
 	impl_POA_Bonobo_ObjectDirectory *servant = _servant;
 	CORBA_Object                     oldobj;
 
 	oldobj = od_get_active_server (servant, iid, environment);
+        *existing = oldobj;
 
 	if (oldobj != CORBA_OBJECT_NIL) {
-		CORBA_Object_release (oldobj, NULL);
-		if (!CORBA_Object_non_existent (oldobj, ev))
+		if (!CORBA_Object_non_existent (oldobj, ev)) {
 			return Bonobo_ACTIVATION_REG_ALREADY_ACTIVE;
+                }
 	}
 
-	if (!g_hash_table_lookup (servant->by_iid, iid))
-		return Bonobo_ACTIVATION_REG_NOT_LISTED;
+        if (!g_hash_table_lookup (servant->by_iid, iid)) {
+                if (!(flags&Bonobo_REGISTRATION_FLAG_NO_SERVERINFO))
+                        return Bonobo_ACTIVATION_REG_NOT_LISTED;
+        }
 
 #ifdef BONOBO_ACTIVATION_DEBUG
         g_warning ("Server register. '%s' : %p", iid, obj);
Index: bonobo/Makefile.am
===================================================================
RCS file: /cvs/gnome/libbonobo/bonobo/Makefile.am,v
retrieving revision 1.69
diff -u -r1.69 Makefile.am
--- bonobo/Makefile.am	8 Apr 2003 18:18:46 -0000	1.69
+++ bonobo/Makefile.am	12 Apr 2003 20:17:00 -0000
@@ -39,6 +39,7 @@
 	$(top_srcdir)/idl/Bonobo_UI.idl			\
 	$(top_srcdir)/idl/Bonobo_Zoomable.idl		\
 	$(top_srcdir)/idl/Bonobo_Exception.idl		\
+	$(top_srcdir)/idl/Bonobo_Application.idl	\
 	$(top_srcdir)/idl/Bonobo_Clipboard.idl
 
 idl_flags = -I$(top_srcdir)/idl -I $(BONOBO_ACTIVATION_IDL_DIR) -D__Bonobo_COMPILATION
@@ -85,6 +86,8 @@
 	bonobo-storage-memory.h		\
 	bonobo-xobject.h		\
 	bonobo-i18n.h			\
+	bonobo-application.h		\
+	bonobo-app-client.h		\
 	bonobo-types.h
 
 noinst_HEADERS =			\
@@ -121,6 +124,8 @@
 	bonobo-stream-memory.c		\
 	bonobo-storage-memory.c		\
 	bonobo-running-context.c	\
+	bonobo-application.c		\
+	bonobo-app-client.c		\
 	bonobo-types.c			\
 	bonobo-debug.c			\
 	bonobo-debug.h
Index: bonobo/bonobo-app-client.c
===================================================================
RCS file: bonobo/bonobo-app-client.c
diff -N bonobo/bonobo-app-client.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ bonobo/bonobo-app-client.c	12 Apr 2003 20:17:00 -0000
@@ -0,0 +1,148 @@
+  /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#include <string.h>
+#include <gobject/gvaluecollector.h>
+#include "bonobo-app-client.h"
+#include "bonobo-arg.h"
+#include "bonobo-exception.h"
+
+
+static void bonobo_app_client_class_init (BonoboAppClientClass *klass);
+static void bonobo_app_client_init       (BonoboAppClient      *app_client);
+
+
+GType
+bonobo_app_client_get_type (void)
+{
+	static GType app_client_type = 0;
+
+	if (!app_client_type)
+	{
+		static const GTypeInfo app_client_info =
+			{
+				sizeof (BonoboAppClientClass),
+				NULL,		/* base_init */
+				NULL,		/* base_finalize */
+				(GClassInitFunc) bonobo_app_client_class_init,
+				NULL,		/* class_finalize */
+				NULL,		/* class_data */
+				sizeof (BonoboAppClient),
+				0,		/* n_preallocs */
+				(GInstanceInitFunc) bonobo_app_client_init,
+			};
+		
+		app_client_type = g_type_register_static
+			(G_TYPE_OBJECT, "BonoboAppClient", &app_client_info, 0);
+	}
+
+	return app_client_type;
+}
+
+
+static void
+bonobo_app_client_class_init (BonoboAppClientClass *class)
+{
+
+}
+
+
+static void
+bonobo_app_client_init (BonoboAppClient *app_client)
+{
+
+}
+
+
+/**
+ * bonobo_app_client_new:
+
+ * @app_server: object reference to a Bonobo::Application; this
+ * function takes ownership of this reference (use
+ * bonobo_object_dup_ref if you want to keep your own reference.)
+ * 
+ * Create an application client object connected to the remote (or
+ * local) Bonobo::Application object.
+ * 
+ * Return value: a #BonoboAppClient object.
+ **/
+BonoboAppClient *
+bonobo_app_client_new (Bonobo_Application app_server)
+{
+	BonoboAppClient *app_client;
+
+	app_client = g_object_new (BONOBO_TYPE_APP_CLIENT, NULL);
+
+	app_client->app_server = app_server;
+
+	return app_client;
+}
+
+
+GValue *
+bonobo_app_client_msg_send_valist (BonoboAppClient *app_client,
+				   const char      *message,
+				   va_list          var_args)
+{
+	CORBA_any                  *ret;
+	Bonobo_Application_ArgList *args;
+	GValue                     *value, *rv;
+	GPtrArray                  *argv;
+	GType                       type;
+	gchar                      *err;
+	CORBA_Environment           ev;
+	int                         i;
+
+	g_return_val_if_fail (app_client, NULL);
+	g_return_val_if_fail (BONOBO_IS_APP_CLIENT (app_client), NULL);
+
+	argv = g_ptr_array_new ();
+	while ((type = va_arg (var_args, GType)) != G_TYPE_NONE)
+	{
+		value = g_new0 (GValue, 1);
+		g_value_init (value, type);
+		G_VALUE_COLLECT(value, var_args, 0, &err);
+		if (err) g_error("error collecting value: %s", err);
+		g_ptr_array_add (argv, value);
+	}
+	args = Bonobo_Application_ArgList__alloc ();
+	args->_length = argv->len;
+	args->_buffer = Bonobo_Application_ArgList_allocbuf (argv->len);
+	for (i = 0; i < argv->len; ++i) {
+		value = g_ptr_array_index (argv, i);
+		bonobo_arg_from_gvalue (&args->_buffer[i], value);
+		g_value_unset (value);
+		g_free (value);
+	}
+	CORBA_sequence_set_release (args, CORBA_TRUE);
+	g_ptr_array_free (argv, TRUE);
+
+	CORBA_exception_init (&ev);
+	ret = Bonobo_Application_message (app_client->app_server, message, args, &ev);
+	CORBA_free (args);
+	if (ev._major != CORBA_NO_EXCEPTION) {
+		g_warning ("error while sending message to application server: %s",
+			   bonobo_exception_get_text (&ev));
+		CORBA_exception_free (&ev);
+		return NULL;
+	}
+	CORBA_exception_free (&ev);
+	
+	rv = g_new0 (GValue, 1);
+	bonobo_arg_to_gvalue (rv, ret);
+	CORBA_free (ret);
+	return rv;
+}
+
+
+GValue *
+bonobo_app_client_msg_send (BonoboAppClient *app_client,
+			    const char      *message,
+			    ...)
+{
+	GValue  *rv;
+	va_list  var_args;
+	
+	va_start (var_args, message);
+	rv = bonobo_app_client_msg_send_valist (app_client, message, var_args);
+	va_end (var_args);
+	return rv;
+}
Index: bonobo/bonobo-app-client.h
===================================================================
RCS file: bonobo/bonobo-app-client.h
diff -N bonobo/bonobo-app-client.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ bonobo/bonobo-app-client.h	12 Apr 2003 20:17:00 -0000
@@ -0,0 +1,50 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#ifndef __BONOBO_APP_CLIENT_H__
+#define __BONOBO_APP_CLIENT_H__
+
+#include <glib-object.h>
+#include <bonobo/Bonobo.h>
+
+G_BEGIN_DECLS
+
+#define BONOBO_TYPE_APP_CLIENT            (bonobo_app_client_get_type ())
+#define BONOBO_APP_CLIENT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                           BONOBO_TYPE_APP_CLIENT, BonoboAppClient))
+#define BONOBO_APP_CLIENT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),\
+                                           BONOBO_TYPE_APP_CLIENT, BonoboAppClientClass))
+#define BONOBO_IS_APP_CLIENT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+                                           BONOBO_TYPE_APP_CLIENT))
+#define BONOBO_IS_APP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
+                                           BONOBO_TYPE_APP_CLIENT))
+#define BONOBO_APP_CLIENT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),\
+                                           BONOBO_TYPE_APP_CLIENT, BonoboAppClientClass))
+
+typedef struct _BonoboAppClient	      BonoboAppClient;
+typedef struct _BonoboAppClientClass  BonoboAppClientClass;
+
+struct _BonoboAppClient
+{
+	GObject            parent_instance;
+	  /*< private >*/
+	Bonobo_Application app_server;
+};
+
+struct _BonoboAppClientClass
+{
+	GObjectClass parent_class;
+  
+};
+
+
+GType	         bonobo_app_client_get_type        (void) G_GNUC_CONST;
+BonoboAppClient* bonobo_app_client_new             (Bonobo_Application  app_server);
+GValue*          bonobo_app_client_msg_send_valist (BonoboAppClient    *app_client,
+						    const char         *message,
+						    va_list             var_args);
+GValue*          bonobo_app_client_msg_send        (BonoboAppClient    *app_client,
+						    const char         *message,
+						    ...);
+
+G_END_DECLS
+
+#endif /* __BONOBO_APP_CLIENT_H__ */
Index: bonobo/bonobo-application.c
===================================================================
RCS file: bonobo/bonobo-application.c
diff -N bonobo/bonobo-application.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ bonobo/bonobo-application.c	12 Apr 2003 20:17:01 -0000
@@ -0,0 +1,166 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#define ORBIT2_INTERNAL_API
+#include "config.h"
+#include "bonobo-application.h"
+#include "bonobo-app-client.h"
+#include <bonobo-exception.h>
+#include "bonobo-marshal.h"
+#include "bonobo-arg.h"
+#include <string.h>
+
+
+enum SIGNALS {
+	MESSAGE,
+	LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+
+
+/*
+ * A pointer to our parent object class
+ */
+static GObjectClass *bonobo_application_parent_class;
+
+
+static void
+bonobo_application_object_finalize (GObject *object)
+{
+	/* BonoboApplication *bonobo_application = BONOBO_APPLICATION (object); */
+
+	  /* ... */
+
+	bonobo_application_parent_class->finalize (object);
+}
+
+
+static CORBA_any *
+impl_Bonobo_Application_message (PortableServer_Servant            servant,
+				 const CORBA_char                 *msg,
+				 const Bonobo_Application_ArgList *args,
+				 CORBA_Environment                *ev)
+{
+	BonoboApplication  *app = BONOBO_APPLICATION (bonobo_object (servant));
+	GValue             *signal_return = NULL;
+	GValueArray        *signal_args;
+	int                 i;
+	CORBA_any          *rv;
+	GValue              value;
+	PortableServer_POA  poa;
+
+	  /* FIXME: How can I obtain the POAManager in a standard way,
+	   * without #define ORBIT2_INTERNAL_API ?? */
+	poa = PortableServer_ServantBase__default_POA (servant, NULL);
+	PortableServer_POAManager_hold_requests (poa->poa_manager,
+						 CORBA_TRUE, NULL);
+
+
+	signal_args = g_value_array_new (args->_length);
+	memset (&value, 0, sizeof (value));
+	for (i = 0; i < args->_length; ++i) {
+		bonobo_arg_to_gvalue (&value, &args->_buffer [i]);
+		g_value_array_append (signal_args, &value);
+		g_value_unset (&value);
+	}
+
+	g_signal_emit (app, signals [MESSAGE], 0,
+		       msg, signal_args, &signal_return);
+
+	g_value_array_free (signal_args);
+	rv = CORBA_any__alloc ();
+	bonobo_arg_from_gvalue (rv, signal_return);
+	g_value_unset (signal_return);
+	g_free (signal_return);
+
+	PortableServer_POAManager_activate (poa->poa_manager, NULL);
+
+	return rv;
+}
+
+
+
+static void
+bonobo_application_class_init (BonoboApplicationClass *klass)
+{
+	GObjectClass *object_class = (GObjectClass *) klass;
+	POA_Bonobo_Application__epv *epv = &klass->epv;
+
+	bonobo_application_parent_class = g_type_class_peek_parent (klass);
+
+	object_class->finalize = bonobo_application_object_finalize;
+
+
+	signals [MESSAGE] = g_signal_new (
+		"message", BONOBO_TYPE_APPLICATION, G_SIGNAL_RUN_LAST,
+		G_STRUCT_OFFSET (BonoboApplicationClass, message),
+		NULL, NULL,	/* accumulator and accumulator data */
+		bonobo_marshal_BOXED__STRING_BOXED,
+		G_TYPE_VALUE, 2, /* return_type, nparams */
+		G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
+		G_TYPE_VALUE_ARRAY);
+
+	epv->message = impl_Bonobo_Application_message;
+}
+
+static void
+bonobo_application_init (BonoboApplication *bonobo_application)
+{
+	  /* ... */
+}
+
+BONOBO_TYPE_FUNC_FULL (BonoboApplication,
+		       Bonobo_Application,
+		       BONOBO_TYPE_OBJECT,
+		       bonobo_application);
+
+
+/**
+ * bonobo_register_unique_application:
+ * @name: Unique name of the application, eg. "GNOME_Terminal".
+ * 
+ * Try to register the running application, or check for an existing
+ * application already registered and get a reference to it.
+ * Applications already running but on different environments (that
+ * usually means different displays, or whatever is environment is set
+ * with bonobo_activation_registration_env_set) than this one are
+ * ignored and do not interfere.
+ * 
+ * Return value: either a BonoboApplication object representing the
+ * current process, if this process was the first to register, or a
+ * BonoboAppClient which acts as client to another process that has
+ * registered earlier with the same name.
+ **/
+GObject *
+bonobo_register_unique_application (const gchar *name)
+{
+	GObject                   *gobj;
+	BonoboObject              *bobj;
+	BonoboApplication         *app;
+	Bonobo_RegistrationResult  reg_res;
+	gchar                     *iid;
+	CORBA_Object               remote_obj = CORBA_OBJECT_NIL;
+
+	g_return_val_if_fail (name, NULL);
+
+	gobj = g_object_new (BONOBO_TYPE_APPLICATION, NULL);
+	bobj = BONOBO_OBJECT (gobj);
+	app  = BONOBO_APPLICATION (bobj);
+
+	iid     = g_strdup_printf ("OAFIID:%s", name);
+	reg_res = bonobo_activation_register_active_server_ext
+		(iid, bonobo_object_corba_objref (bobj), NULL,
+		 Bonobo_REGISTRATION_FLAG_NO_SERVERINFO, &remote_obj);
+	g_free (iid);
+	if (reg_res == Bonobo_ACTIVATION_REG_SUCCESS)
+		return gobj;
+	else if (reg_res == Bonobo_ACTIVATION_REG_ALREADY_ACTIVE) {
+		bonobo_object_unref (bobj);
+		return G_OBJECT (bonobo_app_client_new ((Bonobo_Application) remote_obj));
+	} else {
+		g_warning ("bonobo_register_unique_application failed"
+			   " with error code %i", reg_res);
+		bonobo_object_unref (bobj);
+		return NULL;
+	}
+}
+
Index: bonobo/bonobo-application.h
===================================================================
RCS file: bonobo/bonobo-application.h
diff -N bonobo/bonobo-application.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ bonobo/bonobo-application.h	12 Apr 2003 20:17:01 -0000
@@ -0,0 +1,46 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#ifndef _BONOBO_APPLICATION_H_
+#define _BONOBO_APPLICATION_H_
+
+#include <bonobo/bonobo-object.h>
+
+G_BEGIN_DECLS
+
+#define BONOBO_TYPE_APPLICATION        (bonobo_application_get_type ())
+#define BONOBO_APPLICATION(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o),\
+				        BONOBO_TYPE_APPLICATION, BonoboApplication))
+#define BONOBO_APPLICATION_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k),\
+                                        BONOBO_TYPE_APPLICATION, BonoboApplicationClass))
+#define BONOBO_IS_APPLICATION(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o),\
+				        BONOBO_TYPE_APPLICATION))
+#define BONOBO_IS_APPLICATION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k),\
+					BONOBO_TYPE_APPLICATION))
+#define BONOBO_APPLICATION_GET_CLASS(o)(G_TYPE_INSTANCE_GET_CLASS ((o),\
+				        BONOBO_TYPE_APPLICATION, BonoboApplicationClass))
+
+typedef struct _BonoboApplication      BonoboApplication;
+typedef struct _BonoboApplicationClass BonoboApplicationClass;
+
+
+struct _BonoboApplication {
+	BonoboObject parent;
+
+};
+
+struct _BonoboApplicationClass {
+	BonoboObjectClass parent_class;
+
+	GValue (*message) (const char *name, GValueArray *args);
+
+	POA_Bonobo_Application__epv epv;
+};
+
+
+GType    bonobo_application_get_type        (void) G_GNUC_CONST;
+GObject* bonobo_register_unique_application (const gchar *name);
+
+
+G_END_DECLS
+
+#endif /* _BONOBO_APPLICATION_H_ */
+
Index: bonobo/bonobo-arg.c
===================================================================
RCS file: /cvs/gnome/libbonobo/bonobo/bonobo-arg.c,v
retrieving revision 1.27
diff -u -r1.27 bonobo-arg.c
--- bonobo/bonobo-arg.c	21 Nov 2001 02:16:33 -0000	1.27
+++ bonobo/bonobo-arg.c	12 Apr 2003 20:17:02 -0000
@@ -192,6 +192,9 @@
 
 #define MAKE_FROM_GVALUE(gtype,gtypename,tcid,unionid,corbatype,corbakind)	\
 	case G_TYPE_##gtype:							\
+		a->_value = ORBit_alloc_tcval(tcid, 1);				\
+		a->_type = tcid;						\
+		a->_release = CORBA_TRUE;					\
 		*((corbatype *)a->_value) = (corbatype)g_value_get_##gtypename (value);	\
 		break;
 
@@ -258,6 +261,7 @@
 
 #define MAKE_TO_GVALUE(gtype,gtypename,tcid,unionid,corbatype,corbakind)	\
 	case corbakind:								\
+		g_value_init (value, G_TYPE_##gtype);				\
 		g_value_set_##gtypename (value, *((corbatype *)arg->_value));	\
 		break;
 
Index: bonobo/bonobo-marshal.list
===================================================================
RCS file: /cvs/gnome/libbonobo/bonobo/bonobo-marshal.list,v
retrieving revision 1.10
diff -u -r1.10 bonobo-marshal.list
--- bonobo/bonobo-marshal.list	30 Oct 2001 02:32:09 -0000	1.10
+++ bonobo/bonobo-marshal.list	12 Apr 2003 20:17:02 -0000
@@ -2,3 +2,4 @@
 VOID:STRING,BOXED,BOXED
 VOID:BOXED,UINT,BOXED
 OBJECT:STRING
+BOXED:STRING,BOXED
Index: bonobo-activation/Makefile.am
===================================================================
RCS file: /cvs/gnome/libbonobo/bonobo-activation/Makefile.am,v
retrieving revision 1.46
diff -u -r1.46 Makefile.am
--- bonobo-activation/Makefile.am	7 Apr 2003 10:21:52 -0000	1.46
+++ bonobo-activation/Makefile.am	12 Apr 2003 20:17:02 -0000
@@ -12,7 +12,7 @@
 	-DG_DISABLE_DEPRECATED			\
 	$(NULL)
 
-LDFLAGS=					\
+AM_LDFLAGS=					\
 	$(LIBBONOBO_LIBS)			\
 	$(BONOBO_ACTIVATION_LT_VERSION_INFO)	\
 	$(NULL)
Index: bonobo-activation/bonobo-activation-register.c
===================================================================
RCS file: /cvs/gnome/libbonobo/bonobo-activation/bonobo-activation-register.c,v
retrieving revision 1.36
diff -u -r1.36 bonobo-activation-register.c
--- bonobo-activation/bonobo-activation-register.c	17 Dec 2002 11:02:07 -0000	1.36
+++ bonobo-activation/bonobo-activation-register.c	12 Apr 2003 20:17:03 -0000
@@ -217,11 +217,55 @@
 					  CORBA_Object  obj,
 					  GSList       *reg_env)
 {
+        Bonobo_RegistrationResult rv;
+        CORBA_Object              existing;
+        rv = bonobo_activation_register_active_server_ext
+                (iid, obj, reg_env, 0, &existing);
+	if (existing != CORBA_OBJECT_NIL)
+		CORBA_Object_release (existing, NULL);
+        return rv;
+}
+
+/**
+ * bonobo_activation_register_active_server_ext:
+ * @iid: IID of the server to register.
+ * @obj: CORBA::Object to register.
+ * @reg_env: the registration environment.
+ * @flags: registration flags
+ * @existing: in case an object with the same IID has already been
+ * registered, *existing will contain a reference to the existing
+ * object.
+ * 
+ * This function is the same as
+ * bonobo_activation_register_active_server(), except that: 1. you can
+ * specify registration flags; 2. in case registration fails because
+ * there is already an object registered with that IID, a reference to
+ * the first object registered is returned.
+ *
+ * At the moment, only the only flag available is
+ * Bonobo_REGISTRATION_FLAG_NO_SERVERINFO, which means to allow
+ * registration of an active server which doesn't have a corresponding
+ * .server.  Note that bonobo activation queries will ignore objects
+ * registered this way.  This feature is not meant to be used directly
+ * by applications, so beware!
+ * 
+ * Return value: status of the registration.
+ **/
+Bonobo_RegistrationResult
+bonobo_activation_register_active_server_ext (const char               *iid,
+                                              CORBA_Object              obj,
+                                              GSList                   *reg_env,
+                                              Bonobo_RegistrationFlags  flags,
+                                              CORBA_Object             *existing)
+{
 	Bonobo_ObjectDirectory     od;
 	CORBA_Environment          ev;
 	Bonobo_RegistrationResult  retval;
 	const char                *actid;
 
+        g_return_val_if_fail(existing != NULL, Bonobo_ACTIVATION_REG_ERROR);
+        *existing = CORBA_OBJECT_NIL;
+
 	CORBA_exception_init (&ev);
 
 #ifdef BONOBO_ACTIVATION_DEBUG
@@ -251,7 +295,7 @@
                 retval = Bonobo_ObjectDirectory_register_new (
 					od, iid,
 					reg_env ? &environment : &global_reg_env,
-				        obj, &ev);
+				        obj, flags, existing, &ev);
 
 		if (reg_env)
 			CORBA_free (environment._buffer);
Index: bonobo-activation/bonobo-activation-register.h
===================================================================
RCS file: /cvs/gnome/libbonobo/bonobo-activation/bonobo-activation-register.h,v
retrieving revision 1.8
diff -u -r1.8 bonobo-activation-register.h
--- bonobo-activation/bonobo-activation-register.h	13 Mar 2003 10:48:55 -0000	1.8
+++ bonobo-activation/bonobo-activation-register.h	12 Apr 2003 20:17:03 -0000
@@ -33,6 +33,12 @@
 	bonobo_activation_register_active_server      (const char   *iid,
 						       CORBA_Object  obj,
 						       GSList       *reg_env);
+Bonobo_RegistrationResult
+        bonobo_activation_register_active_server_ext  (const char               *iid,
+                                                       CORBA_Object              obj,
+                                                       GSList                   *reg_env,
+                                                       Bonobo_RegistrationFlags  flags,
+                                                       CORBA_Object             *existing);
 void    bonobo_activation_unregister_active_server    (const char   *iid, 
 						       CORBA_Object  obj);
 
Index: idl/Bonobo.idl
===================================================================
RCS file: /cvs/gnome/libbonobo/idl/Bonobo.idl,v
retrieving revision 1.55
diff -u -r1.55 Bonobo.idl
--- idl/Bonobo.idl	7 Mar 2003 12:09:42 -0000	1.55
+++ idl/Bonobo.idl	12 Apr 2003 20:17:04 -0000
@@ -49,6 +49,8 @@
 /* Clipboard */
 #include <Bonobo_Clipboard.idl>
 
+#include <Bonobo_Application.idl>
+
 #ifndef __Bonobo_COMPILATION
 #ifdef __ORBIT_IDL__
 #pragma inhibit pop
Index: idl/Bonobo_Activation_types.idl
===================================================================
RCS file: /cvs/gnome/libbonobo/idl/Bonobo_Activation_types.idl,v
retrieving revision 1.5
diff -u -r1.5 Bonobo_Activation_types.idl
--- idl/Bonobo_Activation_types.idl	17 Oct 2002 23:11:01 -0000	1.5
+++ idl/Bonobo_Activation_types.idl	12 Apr 2003 20:17:04 -0000
@@ -39,6 +39,8 @@
         const ActivationFlags ACTIVATION_FLAG_NO_LOCAL = 1<<0; // No shared libraries
         const ActivationFlags ACTIVATION_FLAG_PRIVATE = 1<<1; // start a new server and don't register it
         const ActivationFlags ACTIVATION_FLAG_EXISTING_ONLY = 1<<2; // don't start the server if not started
+        typedef long RegistrationFlags;
+        const RegistrationFlags REGISTRATION_FLAG_NO_SERVERINFO = 1<<0; // no .server file
 
 	struct ActivationEnvValue {
 		string  name;
Index: idl/Bonobo_Application.idl
===================================================================
RCS file: idl/Bonobo_Application.idl
diff -N idl/Bonobo_Application.idl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ idl/Bonobo_Application.idl	12 Apr 2003 20:17:04 -0000
@@ -0,0 +1,25 @@
+/* -*- Mode: idl; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/*
+ * Bonobo_Application.idl: Unique application support (some would call
+ * it--or can be used for--Automation).
+ *
+ */
+
+#ifndef BONOBO_APPLICATION_IDL
+#define BONOBO_APPLICATION_IDL
+
+#include "Bonobo_Unknown.idl"
+
+module Bonobo {
+  
+	interface Application : Bonobo::Unknown {
+                typedef sequence<any> ArgList;
+                  // Send a message to the application
+	        any message (in string msg, in ArgList args);
+
+  	};
+
+};
+
+#endif /* BONOBO_APPLICATION_IDL */
+
Index: idl/Bonobo_ObjectDirectory.idl
===================================================================
RCS file: /cvs/gnome/libbonobo/idl/Bonobo_ObjectDirectory.idl,v
retrieving revision 1.7
diff -u -r1.7 Bonobo_ObjectDirectory.idl
--- idl/Bonobo_ObjectDirectory.idl	17 Oct 2002 23:11:01 -0000	1.7
+++ idl/Bonobo_ObjectDirectory.idl	12 Apr 2003 20:17:04 -0000
@@ -73,9 +73,11 @@
                                  in ActivationFlags               flags)
                         context ("username", "hostname");
 
-                RegistrationResult register_new (in ImplementationID              iid,
-                                                 in Bonobo::ActivationEnvironment environment,
-                                                 in Object                        obj);
+                RegistrationResult register_new (in  ImplementationID              iid,
+                                                 in  Bonobo::ActivationEnvironment environment,
+                                                 in  Object                        obj,
+						 in  RegistrationFlags             flags,
+                                                 out Object                        existing);
                 void               unregister   (in ImplementationID              iid,
                                                  in Object                        obj)
                         raises (NotRegistered);
Index: idl/Makefile.am
===================================================================
RCS file: /cvs/gnome/libbonobo/idl/Makefile.am,v
retrieving revision 1.50
diff -u -r1.50 Makefile.am
--- idl/Makefile.am	7 Apr 2003 09:43:03 -0000	1.50
+++ idl/Makefile.am	12 Apr 2003 20:17:04 -0000
@@ -20,6 +20,7 @@
 	Bonobo_Zoomable.idl		\
 	Bonobo_Exception.idl		\
 	Bonobo_Clipboard.idl		\
+	Bonobo_Application.idl		\
 	$(NULL)
 
 activation_idldir=$(datadir)/idl/bonobo-activation-2.0
Index: tests/Makefile.am
===================================================================
RCS file: /cvs/gnome/libbonobo/tests/Makefile.am,v
retrieving revision 1.18
diff -u -r1.18 Makefile.am
--- tests/Makefile.am	7 Apr 2003 10:31:12 -0000	1.18
+++ tests/Makefile.am	12 Apr 2003 20:17:05 -0000
@@ -7,7 +7,8 @@
 	test-event-source	\
 	test-object		\
 	test-stream-mem		\
-	test-storage-mem
+	test-storage-mem	\
+	test-uniqapp
 
 INCLUDES =	\
         -DGNOMELOCALEDIR=\""$(datadir)/locale"\"        \
@@ -32,6 +33,8 @@
 test_stream_mem_SOURCES = test-stream-mem.c
 
 test_storage_mem_SOURCES = test-storage-mem.c
+
+test_uniqapp_SOURCES = test-uniqapp.c
 
 TESTS_ENVIRONMENT =					\
 	LD_LIBRARY_PATH="$(top_builddir)/bonobo/.libs:$$LD_LIBRARY_PATH"	\
Index: tests/test-uniqapp.c
===================================================================
RCS file: tests/test-uniqapp.c
diff -N tests/test-uniqapp.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/test-uniqapp.c	12 Apr 2003 20:17:05 -0000
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#include <config.h>
+#include <libbonobo.h>
+
+
+static GValue *
+message_cb (BonoboAppClient *app_client, const gchar *message, GValueArray *args)
+{
+	GValue *retval = g_new0 (GValue, 1);
+
+	g_message ("message_cb: %s", message);
+	g_value_init (retval, G_TYPE_FLOAT);
+	if (args->n_values == 1) {
+		g_value_set_float (retval, 2*g_value_get_float (
+					   g_value_array_get_nth (args, 0)));
+	} else {
+		g_warning ("Wrong arity!");
+		g_value_set_float (retval, 0);
+	}
+	return retval;
+}
+
+
+int
+main (int argc, char *argv [])
+{
+	GObject           *app;
+	const char        *msg = "Hail to you, Master!";
+	float              msg_arg = 3.141592654;
+
+	if (bonobo_init (&argc, argv) == FALSE)
+		g_error ("Can not bonobo_init");
+	bonobo_activate ();
+
+	app = bonobo_register_unique_application ("Libbonobo-Test-Uniqapp");
+
+	if (g_type_is_a (G_OBJECT_TYPE (app), BONOBO_TYPE_APP_CLIENT))
+	{
+		BonoboAppClient *client = BONOBO_APP_CLIENT (app);
+		GValue          *retval;
+
+		g_message ("I am an application client");
+		g_message ("Sending message string '%s' with argument %f",
+			   msg, msg_arg);
+		retval = bonobo_app_client_msg_send (client, msg,
+						     G_TYPE_FLOAT, msg_arg,
+						     G_TYPE_NONE);
+		g_message ("Return value: %f", g_value_get_float (retval));
+	} else if (g_type_is_a (G_OBJECT_TYPE (app), BONOBO_TYPE_APPLICATION)) {
+		g_message ("I am an application server");
+		g_signal_connect (app, "message",
+				  G_CALLBACK (message_cb), NULL);
+	} else
+		g_assert_not_reached ();
+
+	bonobo_main ();
+
+	return bonobo_debug_shutdown ();
+}


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