Bonobo Unique Application v3

Gustavo J A M Carneiro <[email protected]>
Newsgroups gmane.comp.gnome.components
Organization INESC
Message-ID <[email protected]>
  Changes:
	1- removed POAManager holding state stuff;
	2- Create a customm  POA for BonoboApplication with the idle threading
policy;
	
  	Please update/recompile ORBit2 before testing.
	Also note that if you install this, some programs will stop working,
unless they link to the new libbonobo-activation, since the CORBA
interface to the b-a-s changes a bit.

  Next I will add some message discovery capabilities, thought I'm not
really sure how useful that will be...

-- 
Gustavo J. A. M. Carneiro
<[email protected]> <[email protected]>
bonobo-uniqapp-v3.diff (text/x-patch, 31.2 KB)
Index: libbonobo.h
===================================================================
RCS file: /cvs/gnome/libbonobo/libbonobo.h,v
retrieving revision 1.60
diff -u -p -u -p -r1.60 libbonobo.h
--- libbonobo.h	19 Nov 2001 00:13:33 -0000	1.60
+++ libbonobo.h	18 Apr 2003 15:29:42 -0000
@@ -44,6 +44,8 @@ G_BEGIN_DECLS
 
 #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 -p -u -p -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	18 Apr 2003 15:29:44 -0000
@@ -218,7 +218,7 @@ main (int argc, char *argv[])
         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 @@ main (int argc, char *argv[])
         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 -p -u -p -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	18 Apr 2003 15:29:45 -0000
@@ -702,21 +702,26 @@ impl_Bonobo_ObjectDirectory_register_new
 	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.72
diff -u -p -u -p -r1.72 Makefile.am
--- bonobo/Makefile.am	16 Apr 2003 19:10:51 -0000	1.72
+++ bonobo/Makefile.am	18 Apr 2003 15:29:45 -0000
@@ -39,6 +39,7 @@ idls =							\
 	$(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 -D__Bonobo_COMPILATION
@@ -88,6 +89,8 @@ libbonoboinclude_HEADERS =		\
 	bonobo-storage-memory.h		\
 	bonobo-xobject.h		\
 	bonobo-i18n.h			\
+	bonobo-application.h		\
+	bonobo-app-client.h		\
 	bonobo-types.h
 
 noinst_HEADERS =			\
@@ -125,6 +128,8 @@ libbonobo_src =				\
 	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	18 Apr 2003 15:29:46 -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	18 Apr 2003 15:29:46 -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	18 Apr 2003 15:29:46 -0000
@@ -0,0 +1,214 @@
+/* -*- 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 "bonobo-main.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;
+
+	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);
+
+	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);
+
+
+static PortableServer_POA
+get_custom_poa(void)
+{
+	PortableServer_POA  poa;
+	CORBA_Environment   ev;
+	CORBA_PolicyList   *policies;
+
+	CORBA_exception_init (&ev);
+
+	/* (Copy-paste from ORBit2/test/poa/poatest-basic08.c) */
+
+	/*
+	 * Create child POA with MULTIPLE_ID Object Id Uniqueness policy and
+	 * IMLICIT_ACTIVATION Implicit Activation policy.
+	 */
+	policies           = CORBA_PolicyList__alloc ();
+	policies->_maximum = 2;
+	policies->_length  = 2;
+	policies->_buffer  = CORBA_PolicyList_allocbuf (2);
+	CORBA_sequence_set_release (policies, CORBA_TRUE);
+	policies->_buffer[0] = (CORBA_Policy)
+		PortableServer_POA_create_id_uniqueness_policy (
+			bonobo_poa (),
+			PortableServer_MULTIPLE_ID,
+			&ev);
+	policies->_buffer[1] = (CORBA_Policy)
+		PortableServer_POA_create_implicit_activation_policy (
+			bonobo_poa (),
+			PortableServer_IMPLICIT_ACTIVATION,
+			&ev);
+
+	poa = PortableServer_POA_create_POA (bonobo_poa (), "BonoboApplicationPOA",
+					     bonobo_poa_manager (), policies, &ev);
+	CORBA_free (policies);
+
+	if (ev._major == CORBA_NO_EXCEPTION) {
+		ORBit_ObjectAdaptor_set_thread_hint ((ORBit_ObjectAdaptor) poa,
+						     ORBIT_THREAD_HINT_ALL_AT_IDLE);
+	} else {
+		if (strcmp (CORBA_exception_id (&ev),
+			    ex_PortableServer_POA_AdapterAlreadyExists) == 0)
+		{
+			CORBA_exception_free (&ev);
+			poa = PortableServer_POA_find_POA (bonobo_poa (),
+							   "BonoboApplicationPOA",
+							   CORBA_FALSE, &ev);
+		}
+	}
+	CORBA_exception_free (&ev);
+	if (!poa)
+		g_warning ("Could not create/get BonoboApplicationPOA");
+	return poa;
+}
+
+/**
+ * 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;
+	PortableServer_POA         poa;
+
+	g_return_val_if_fail (name, NULL);
+	
+	poa = get_custom_poa ();
+	g_return_val_if_fail (poa, NULL);
+	gobj = g_object_new (BONOBO_TYPE_APPLICATION, "poa", poa, 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	18 Apr 2003 15:29:46 -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 -p -u -p -r1.27 bonobo-arg.c
--- bonobo/bonobo-arg.c	21 Nov 2001 02:16:33 -0000	1.27
+++ bonobo/bonobo-arg.c	18 Apr 2003 15:29:47 -0000
@@ -192,6 +192,9 @@ bonobo_arg_type_to_gtype (BonoboArgType 
 
 #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 @@ bonobo_arg_from_gvalue (BonoboArg *a, co
 
 #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 -p -u -p -r1.10 bonobo-marshal.list
--- bonobo/bonobo-marshal.list	30 Oct 2001 02:32:09 -0000	1.10
+++ bonobo/bonobo-marshal.list	18 Apr 2003 15:29:47 -0000
@@ -2,3 +2,4 @@ BOXED:STRING,BOOLEAN,BOXED
 VOID:STRING,BOXED,BOXED
 VOID:BOXED,UINT,BOXED
 OBJECT:STRING
+BOXED:STRING,BOXED
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 -p -u -p -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	18 Apr 2003 15:29:49 -0000
@@ -217,11 +217,55 @@ bonobo_activation_register_active_server
 					  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 @@ bonobo_activation_register_active_server
                 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 -p -u -p -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	18 Apr 2003 15:29:49 -0000
@@ -33,6 +33,12 @@ Bonobo_RegistrationResult
 	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 -p -u -p -r1.55 Bonobo.idl
--- idl/Bonobo.idl	7 Mar 2003 12:09:42 -0000	1.55
+++ idl/Bonobo.idl	18 Apr 2003 15:29:49 -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 -p -u -p -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	18 Apr 2003 15:29:49 -0000
@@ -39,6 +39,8 @@ module Bonobo {
         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	18 Apr 2003 15:29:49 -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 -p -u -p -r1.7 Bonobo_ObjectDirectory.idl
--- idl/Bonobo_ObjectDirectory.idl	17 Oct 2002 23:11:01 -0000	1.7
+++ idl/Bonobo_ObjectDirectory.idl	18 Apr 2003 15:29:49 -0000
@@ -73,9 +73,11 @@ module Bonobo {
                                  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.52
diff -u -p -u -p -r1.52 Makefile.am
--- idl/Makefile.am	16 Apr 2003 19:10:52 -0000	1.52
+++ idl/Makefile.am	18 Apr 2003 15:29:49 -0000
@@ -20,6 +20,7 @@ idl_DATA =				\
 	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 -p -u -p -r1.18 Makefile.am
--- tests/Makefile.am	7 Apr 2003 10:31:12 -0000	1.18
+++ tests/Makefile.am	18 Apr 2003 15:29:50 -0000
@@ -7,7 +7,8 @@ noinst_PROGRAMS =		\
 	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_event_source_SOURCES = test-event-s
 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	18 Apr 2003 15:29:50 -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 ();
+}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.