public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [Bluez-devel] [PATCH] make bluez GNOME UIs singletons
@ 2007-10-16 18:38 Chris Rivera
  2007-10-17 14:24 ` Marcel Holtmann
  0 siblings, 1 reply; 13+ messages in thread
From: Chris Rivera @ 2007-10-16 18:38 UTC (permalink / raw)
  To: bluez-devel


[-- Attachment #1.1: Type: text/plain, Size: 423 bytes --]

Howdy folks.  The attached patch makes the applet, properties dialog, and
wizard singletons.  Currently, you can open several instances of these at a
time.  This is particularly annoying since you can launch the properties
dialog from the applet.  I also added a simple DBUS method (Present) to the
properties dialog and wizard that can be called by another instance to bring
the current instance to the foreground.

Chris

[-- Attachment #1.2: Type: text/html, Size: 454 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: bluez-gnome-singleton.patch --]
[-- Type: text/x-patch; name="bluez-gnome-singleton.patch", Size: 9733 bytes --]

Index: applet/main.c
===================================================================
RCS file: /cvsroot/bluez/gnome/applet/main.c,v
retrieving revision 1.87
diff -u -r1.87 main.c
--- applet/main.c	29 Aug 2007 20:42:18 -0000	1.87
+++ applet/main.c	16 Oct 2007 17:42:29 -0000
@@ -32,9 +32,9 @@
 #include <string.h>
 
 #include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
 #ifdef HAVE_HAL
-#include <dbus/dbus-glib-lowlevel.h>
 #include <hal/libhal.h>
 #endif
 
@@ -1788,6 +1784,10 @@
 	GtkWidget *menu;
 	GError *error = NULL;
 	char *str;
+	DBusGConnection *session_conn;
+	DBusGProxy *bus_proxy;
+	gboolean ret;
+	guint request_result;
 
 	bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
@@ -1807,6 +1807,41 @@
 		exit(EXIT_FAILURE);
 	}
 
+	session_conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+	if (error != NULL) {
+		g_printerr("Connecting to session bus failed: %s\n",
+					error->message);
+		g_error_free(error);
+		dbus_g_connection_unref(conn);
+		exit(EXIT_FAILURE);
+	}
+
+	bus_proxy = dbus_g_proxy_new_for_name(session_conn,
+										  DBUS_SERVICE_DBUS,
+										  DBUS_PATH_DBUS,
+										  DBUS_INTERFACE_DBUS);
+
+	ret = dbus_g_proxy_call(bus_proxy, "RequestName", NULL,
+							G_TYPE_STRING, "org.bluez.GnomeApplet",
+							G_TYPE_UINT, 0,
+							G_TYPE_INVALID,
+							G_TYPE_UINT, &request_result,
+							G_TYPE_INVALID);
+	g_object_unref(G_OBJECT(bus_proxy));
+	if (!ret) {
+		g_printerr("Failed to request name on the session bus\n");
+		dbus_g_connection_unref(conn);
+		dbus_g_connection_unref(session_conn);
+		exit(EXIT_FAILURE);
+	}
+
+	if (request_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+		g_print("Another instance is already running.\n");
+		dbus_g_connection_unref(conn);
+		dbus_g_connection_unref(session_conn);
+		exit(EXIT_SUCCESS);
+	}
+
 	gconf = gconf_client_get_default();
 
 #ifdef HAVE_HAL
@@ -1863,6 +1898,7 @@
 	g_list_foreach(adapter_list, adapter_free, NULL);
 
 	dbus_g_connection_unref(conn);
+	dbus_g_connection_unref(session_conn);
 
 	return 0;
 }
Index: properties/main.c
===================================================================
RCS file: /cvsroot/bluez/gnome/properties/main.c,v
retrieving revision 1.48
diff -u -r1.48 main.c
--- properties/main.c	31 Jul 2007 21:37:29 -0000	1.48
+++ properties/main.c	16 Oct 2007 17:42:29 -0000
@@ -32,6 +32,7 @@
 #include <string.h>
 
 #include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
 #include <glib/gi18n.h>
 
@@ -41,6 +42,9 @@
 #include "service.h"
 #include "adapter.h"
 
+#define PROPERTIES_DBUS_PATH "/org/bluez/GnomeProperties"
+#define PROPERTIES_DBUS_SERVICE "org.bluez.GnomeProperties"
+
 static void delete_callback(GtkWidget *window, GdkEvent *event,
 						gpointer user_data)
 {
@@ -58,7 +62,7 @@
 	gtk_main_quit();
 }
 
-static void create_window(GtkWidget *notebook)
+static GtkWidget *create_window(GtkWidget *notebook)
 {
 	GtkWidget *window;
 	GtkWidget *widget;
@@ -108,6 +112,7 @@
 						widget, _("General"));
 
 	gtk_widget_show_all(window);
+	return window;
 }
 
 static void name_owner_changed(DBusGProxy *object, const char *name,
@@ -139,12 +144,30 @@
 	return proxy;
 }
 
+static DBusHandlerResult MessageFunc (DBusConnection *c, DBusMessage *m, void *user_data)
+{
+	if (dbus_message_get_type(m) == DBUS_MESSAGE_TYPE_METHOD_CALL &&
+		!strncmp(PROPERTIES_DBUS_PATH, dbus_message_get_path(m), strlen(PROPERTIES_DBUS_PATH)) &&
+		!strncmp(PROPERTIES_DBUS_SERVICE, dbus_message_get_interface(m), strlen(PROPERTIES_DBUS_SERVICE)) &&
+		!strncmp("Present", dbus_message_get_member(m), 7)) {
+		GtkWindow *window = user_data;
+		gtk_window_present(window);
+	}
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
 int main(int argc, char *argv[])
 {
 	GtkWidget *notebook;
-	DBusGConnection *conn;
-	DBusGProxy *manager;
+	GtkWidget *window;
 	GError *error = NULL;
+	DBusGConnection *conn, *session_conn;
+	DBusGProxy *manager;
+	DBusGProxy *bus_proxy;
+	DBusObjectPathVTable vtable;
+	guint request_result;
+	gboolean ret;
 
 	bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
@@ -160,16 +183,61 @@
 		exit(EXIT_FAILURE);
 	}
 
+	session_conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+	if (error != NULL) {
+		g_printerr("Connecting to session bus failed: %s\n",
+					error->message);
+		g_error_free(error);
+		dbus_g_connection_unref(conn);
+		exit(EXIT_FAILURE);
+	}
+
+	bus_proxy = dbus_g_proxy_new_for_name(session_conn,
+										  DBUS_SERVICE_DBUS,
+										  DBUS_PATH_DBUS,
+										  DBUS_INTERFACE_DBUS);
+
+	ret = dbus_g_proxy_call(bus_proxy, "RequestName", NULL,
+   						G_TYPE_STRING, PROPERTIES_DBUS_SERVICE,
+							G_TYPE_UINT, 0,
+							G_TYPE_INVALID,
+							G_TYPE_UINT, &request_result,
+							G_TYPE_INVALID);
+	g_object_unref(G_OBJECT(bus_proxy));
+	if (!ret) {
+		g_printerr("Failed to request name on the session bus\n");
+		dbus_g_connection_unref(conn);
+		dbus_g_connection_unref(session_conn);
+		exit(EXIT_FAILURE);
+	}
+
+	if (request_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+		g_print("Another instance is already running.\n");
+		DBusGProxy *proxy = dbus_g_proxy_new_for_name(session_conn,
+													  PROPERTIES_DBUS_SERVICE,
+													  PROPERTIES_DBUS_PATH,
+													  PROPERTIES_DBUS_SERVICE);
+		dbus_g_proxy_call_no_reply(proxy, "Present", G_TYPE_INVALID, G_TYPE_INVALID);
+		g_object_unref(G_OBJECT(proxy));
+		dbus_g_connection_unref(conn);
+		dbus_g_connection_unref(session_conn);
+		exit(EXIT_SUCCESS);
+	}
+
 	setup_general();
 
 	notebook = gtk_notebook_new();
-
+    
 	assign_adapter(notebook);
 
 	manager = setup_manager(conn);
 
-	create_window(notebook);
+	window = create_window(notebook);
 
+	vtable.message_function = MessageFunc;
+	vtable.unregister_function = NULL;
+	dbus_connection_register_object_path(dbus_g_connection_get_connection (session_conn),
+										 "/org/bluez/GnomeProperties", &vtable, window);
 	gtk_main();
 
 	cleanup_adapter();
@@ -181,6 +249,7 @@
 	g_object_unref(manager);
 
 	dbus_g_connection_unref(conn);
+	dbus_g_connection_unref(session_conn);
 
 	return 0;
 }
Index: wizard/main.c
===================================================================
RCS file: /cvsroot/bluez/gnome/wizard/main.c,v
retrieving revision 1.23
diff -u -r1.23 main.c
--- wizard/main.c	15 Aug 2007 07:04:03 -0000	1.23
+++ wizard/main.c	16 Oct 2007 17:42:29 -0000
@@ -26,8 +26,10 @@
 #endif
 
 #include <string.h>
+#include <stdlib.h>
 
 #include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
 #include <glib/gi18n.h>
 
@@ -39,6 +41,9 @@
 
 #include "bluetooth-device-selection.h"
 
+#define WIZARD_DBUS_PATH "/org/bluez/GnomeWizard"
+#define WIZARD_DBUS_SERVICE "org.bluez.GnomeWizard"
+
 static BluetoothClient *client;
 
 static gchar *address = NULL;
@@ -387,7 +392,7 @@
 	page_summary = vbox;
 }
 
-static void create_wizard(void)
+static GtkWidget *create_wizard(void)
 {
 	GtkWidget *assistant;
 
@@ -430,23 +435,90 @@
 	gtk_widget_show_all(assistant);
 
 	gtk_assistant_update_buttons_state(GTK_ASSISTANT(assistant));
+	return assistant;
+}
+
+static DBusHandlerResult MessageFunc (DBusConnection *c, DBusMessage *m, void *user_data)
+{
+	if (dbus_message_get_type(m) == DBUS_MESSAGE_TYPE_METHOD_CALL &&
+		!strncmp(WIZARD_DBUS_PATH, dbus_message_get_path(m), strlen(WIZARD_DBUS_PATH)) &&
+		!strncmp(WIZARD_DBUS_SERVICE, dbus_message_get_interface(m), strlen(WIZARD_DBUS_SERVICE)) &&
+		!strncmp("Present", dbus_message_get_member(m), 7)) {
+		GtkWindow *window = user_data;
+		gtk_window_present(window);
+	}
+
+	return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 int main(int argc, char *argv[])
 {
-	bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
+	GtkWidget *window;
+	GError *error = NULL;
+	DBusGConnection *session_conn;
+	DBusGProxy *bus_proxy;
+	DBusObjectPathVTable vtable;
+	gboolean ret;
+	guint request_result;
+	
+	bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
 	textdomain(GETTEXT_PACKAGE);
 
 	gtk_init(&argc, &argv);
 
+	session_conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+	if (error != NULL) {
+		g_printerr("Connecting to session bus failed: %s\n",
+					error->message);
+		g_error_free(error);
+		exit(EXIT_FAILURE);
+	}
+
+	bus_proxy = dbus_g_proxy_new_for_name(session_conn,
+										  DBUS_SERVICE_DBUS,
+										  DBUS_PATH_DBUS,
+										  DBUS_INTERFACE_DBUS);
+
+	ret = dbus_g_proxy_call(bus_proxy, "RequestName", NULL,
+							G_TYPE_STRING, WIZARD_DBUS_SERVICE,
+							G_TYPE_UINT, 0,
+							G_TYPE_INVALID,
+							G_TYPE_UINT, &request_result,
+							G_TYPE_INVALID);
+	g_object_unref(G_OBJECT(bus_proxy));
+	if (!ret) {
+		g_printerr("Failed to request name on the session bus\n");
+		dbus_g_connection_unref(session_conn);
+		exit(EXIT_FAILURE);
+	}
+
+	if (request_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+		g_print("Another instance is already running.\n");
+		DBusGProxy *proxy = dbus_g_proxy_new_for_name(session_conn,
+       											  WIZARD_DBUS_SERVICE,
+													  WIZARD_DBUS_PATH,
+													  WIZARD_DBUS_SERVICE);
+		dbus_g_proxy_call_no_reply(proxy, "Present", G_TYPE_INVALID, G_TYPE_INVALID);
+		g_object_unref(G_OBJECT(proxy));
+		dbus_g_connection_unref(session_conn);
+		exit(EXIT_SUCCESS);
+	}
+
 	client = bluetooth_client_new();
 
-	create_wizard();
+	window = create_wizard();
+    
+	vtable.message_function = MessageFunc;
+	vtable.unregister_function = NULL;
+	dbus_connection_register_object_path(dbus_g_connection_get_connection (session_conn),
+										 WIZARD_DBUS_PATH, &vtable, window);
 
 	gtk_main();
 
 	g_object_unref(client);
+	
+	dbus_g_connection_unref(session_conn);
 
 	return 0;
 }

[-- Attachment #3: Type: text/plain, Size: 314 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Bluez-devel] [PATCH] make bluez GNOME UIs singletons
  2007-10-16 18:38 [Bluez-devel] [PATCH] make bluez GNOME UIs singletons Chris Rivera
@ 2007-10-17 14:24 ` Marcel Holtmann
  2007-10-17 14:48   ` Chris Rivera
  0 siblings, 1 reply; 13+ messages in thread
From: Marcel Holtmann @ 2007-10-17 14:24 UTC (permalink / raw)
  To: BlueZ development

Hi Chris,

> Howdy folks.  The attached patch makes the applet, properties dialog,
> and wizard singletons.  Currently, you can open several instances of
> these at a time.  This is particularly annoying since you can launch
> the properties dialog from the applet.  I also added a simple DBUS
> method (Present) to the properties dialog and wizard that can be
> called by another instance to bring the current instance to the
> foreground. 

actually the wizard and the properties applications are meant to be
_not_ singletons. They are designed in a way that multiple instances can
exist and work together.

For the applet, only one instance is useful. However for testing and
development purposes it is nice to start two of them.

Regards

Marcel



-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Bluez-devel] [PATCH] make bluez GNOME UIs singletons
  2007-10-17 14:24 ` Marcel Holtmann
@ 2007-10-17 14:48   ` Chris Rivera
  2007-10-17 15:11     ` Bastien Nocera
  0 siblings, 1 reply; 13+ messages in thread
From: Chris Rivera @ 2007-10-17 14:48 UTC (permalink / raw)
  To: BlueZ development


[-- Attachment #1.1: Type: text/plain, Size: 742 bytes --]

On 10/17/07, Marcel Holtmann <marcel@holtmann.org> wrote:

>
> actually the wizard and the properties applications are meant to be
> _not_ singletons. They are designed in a way that multiple instances can
> exist and work together.
>
> For the applet, only one instance is useful. However for testing and
> development purposes it is nice to start two of them.
>

The applet already has the ability to launch the properties dialog and I
think it should also have an entry to launch the wizard.   This makes it
very easy to get to a state where you have multiple copies open at once.  I
think it's confusing to users and it doesn't buy you anything.  Just in case
it's not clear, the patch allows for one instance per desktop session.

Chris

[-- Attachment #1.2: Type: text/html, Size: 1064 bytes --]

[-- Attachment #2: Type: text/plain, Size: 314 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

[-- Attachment #3: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Bluez-devel] [PATCH] make bluez GNOME UIs singletons
  2007-10-17 14:48   ` Chris Rivera
@ 2007-10-17 15:11     ` Bastien Nocera
  2007-10-18 10:15       ` Fabien Chevalier
  2007-10-24 19:54       ` Chris Rivera
  0 siblings, 2 replies; 13+ messages in thread
From: Bastien Nocera @ 2007-10-17 15:11 UTC (permalink / raw)
  To: BlueZ development


On Wed, 2007-10-17 at 10:48 -0400, Chris Rivera wrote:
> On 10/17/07, Marcel Holtmann <marcel@holtmann.org> wrote:
>         
>         actually the wizard and the properties applications are meant
>         to be
>         _not_ singletons. They are designed in a way that multiple
>         instances can
>         exist and work together.
>         
>         For the applet, only one instance is useful. However for
>         testing and 
>         development purposes it is nice to start two of them.
> 
> The applet already has the ability to launch the properties dialog and
> I think it should also have an entry to launch the wizard.   This
> makes it very easy to get to a state where you have multiple copies
> open at once.  I think it's confusing to users and it doesn't buy you
> anything.  Just in case it's not clear, the patch allows for one
> instance per desktop session. 

Both of you are right. Developers should be able to launch another
applet or prefs for testing, but users should only ever see one applet
and prefs dialogue.

Maybe a command-line flag or envvar to disable the singleton behaviour
in Chris' patch would be acceptable for Marcel?

Cheers


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Bluez-devel] [PATCH] make bluez GNOME UIs singletons
  2007-10-17 15:11     ` Bastien Nocera
@ 2007-10-18 10:15       ` Fabien Chevalier
  2007-10-31 16:14         ` Marcel Holtmann
  2007-10-24 19:54       ` Chris Rivera
  1 sibling, 1 reply; 13+ messages in thread
From: Fabien Chevalier @ 2007-10-18 10:15 UTC (permalink / raw)
  To: BlueZ development

Bastien Nocera wrote:
> On Wed, 2007-10-17 at 10:48 -0400, Chris Rivera wrote:
>> On 10/17/07, Marcel Holtmann <marcel@holtmann.org> wrote:
>>         
>>         actually the wizard and the properties applications are meant
>>         to be
>>         _not_ singletons. They are designed in a way that multiple
>>         instances can
>>         exist and work together.
>>         
>>         For the applet, only one instance is useful. However for
>>         testing and 
>>         development purposes it is nice to start two of them.
>>
>> The applet already has the ability to launch the properties dialog and
>> I think it should also have an entry to launch the wizard.   This
>> makes it very easy to get to a state where you have multiple copies
>> open at once.  I think it's confusing to users and it doesn't buy you
>> anything.  Just in case it's not clear, the patch allows for one
>> instance per desktop session. 
> 
> Both of you are right. Developers should be able to launch another
> applet or prefs for testing, but users should only ever see one applet
> and prefs dialogue.
> 
> Maybe a command-line flag or envvar to disable the singleton behaviour
> in Chris' patch would be acceptable for Marcel?
> 
> Cheers
> 

Bastien, i agree with you. :-)
 From the user experience perspective, having more than one instance of 
those windows is just plain wrong( in fact this was a remark one working 
collegue of mine just had when he discovered the bluez GUI for the first 
time :-) )
If Marcel wants to keep the old behaviour for testing purpose, i'm not 
against it, but i really think the singleton behavior should be the default.

Cheers,

Fabien

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Bluez-devel] [PATCH] make bluez GNOME UIs singletons
  2007-10-17 15:11     ` Bastien Nocera
  2007-10-18 10:15       ` Fabien Chevalier
@ 2007-10-24 19:54       ` Chris Rivera
  1 sibling, 0 replies; 13+ messages in thread
From: Chris Rivera @ 2007-10-24 19:54 UTC (permalink / raw)
  To: BlueZ development


[-- Attachment #1.1: Type: text/plain, Size: 522 bytes --]

Here's an updated patch that will ignore the singleton behavior if  the
BLUEZ_IGNORE_SINGLETON environment variable is set.  Marcel, is this
acceptable?

Chris

On 10/17/07, Bastien Nocera <hadess@hadess.net> wrote:
>
>
> Both of you are right. Developers should be able to launch another
> applet or prefs for testing, but users should only ever see one applet
> and prefs dialogue.
>
> Maybe a command-line flag or envvar to disable the singleton behaviour
> in Chris' patch would be acceptable for Marcel?
>
> Cheers
>

[-- Attachment #1.2: Type: text/html, Size: 830 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: bluez-gnome-singleton.patch --]
[-- Type: text/x-patch; name=bluez-gnome-singleton.patch, Size: 10244 bytes --]

Index: applet/main.c
===================================================================
RCS file: /cvsroot/bluez/gnome/applet/main.c,v
retrieving revision 1.87
diff -u -r1.87 main.c
--- applet/main.c	29 Aug 2007 20:42:18 -0000	1.87
+++ applet/main.c	24 Oct 2007 19:47:25 -0000
@@ -32,9 +32,9 @@
 #include <string.h>
 
 #include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
 #ifdef HAVE_HAL
-#include <dbus/dbus-glib-lowlevel.h>
 #include <hal/libhal.h>
 #endif
 
@@ -1783,11 +1779,62 @@
 		auto_authorize = gconf_value_get_bool(value);
 }
 
+static DBusGConnection *check_for_instance (int *retval)
+{
+	DBusGConnection *sc;
+	DBusGProxy *proxy;
+	GError *error = NULL;
+	guint request_result;
+	gboolean ret;
+
+	sc = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+	if (error != NULL) {
+		g_printerr("Connecting to session bus failed: %s\n",
+					error->message);
+		g_error_free(error);
+		*retval = 1;
+		return NULL;
+	}
+
+	proxy = dbus_g_proxy_new_for_name(sc,
+									  DBUS_SERVICE_DBUS,
+									  DBUS_PATH_DBUS,
+									  DBUS_INTERFACE_DBUS);
+
+	ret = dbus_g_proxy_call(proxy, "RequestName", NULL,
+							G_TYPE_STRING, "org.bluez.GnomeApplet",
+							G_TYPE_UINT, 0,
+							G_TYPE_INVALID,
+							G_TYPE_UINT, &request_result,
+							G_TYPE_INVALID);
+	g_object_unref(G_OBJECT(proxy));
+	if (!ret) {
+		g_printerr("Failed to request name on the session bus\n");
+		dbus_g_connection_unref(sc);
+		*retval = 1;
+		return NULL;
+	}
+
+	if (request_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+		*retval = 0;
+		
+		if (!g_getenv("BLUEZ_IGNORE_SINGLETON")) {
+			g_print("Another instance is already running.\n");
+			dbus_g_connection_unref(sc);
+			return NULL;
+		}
+	}
+
+	return sc;
+}
+
 int main(int argc, char *argv[])
 {
 	GtkWidget *menu;
 	GError *error = NULL;
 	char *str;
+	DBusGConnection *session_conn = NULL;
+	int retval = 0;
 
 	bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
@@ -1806,6 +1853,10 @@
 		g_error_free(error);
 		exit(EXIT_FAILURE);
 	}
+	
+	session_conn = check_for_instance(&retval);
+	if (!session_conn)
+		exit(retval);
 
 	gconf = gconf_client_get_default();
 
@@ -1863,6 +1914,7 @@
 	g_list_foreach(adapter_list, adapter_free, NULL);
 
 	dbus_g_connection_unref(conn);
+	dbus_g_connection_unref(session_conn);
 
 	return 0;
 }
Index: properties/main.c
===================================================================
RCS file: /cvsroot/bluez/gnome/properties/main.c,v
retrieving revision 1.48
diff -u -r1.48 main.c
--- properties/main.c	31 Jul 2007 21:37:29 -0000	1.48
+++ properties/main.c	24 Oct 2007 19:47:25 -0000
@@ -32,6 +32,7 @@
 #include <string.h>
 
 #include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
 #include <glib/gi18n.h>
 
@@ -41,6 +42,9 @@
 #include "service.h"
 #include "adapter.h"
 
+#define PROPERTIES_DBUS_PATH "/org/bluez/GnomeProperties"
+#define PROPERTIES_DBUS_SERVICE "org.bluez.GnomeProperties"
+
 static void delete_callback(GtkWidget *window, GdkEvent *event,
 						gpointer user_data)
 {
@@ -58,7 +62,7 @@
 	gtk_main_quit();
 }
 
-static void create_window(GtkWidget *notebook)
+static GtkWidget *create_window(GtkWidget *notebook)
 {
 	GtkWidget *window;
 	GtkWidget *widget;
@@ -108,6 +112,7 @@
 						widget, _("General"));
 
 	gtk_widget_show_all(window);
+	return window;
 }
 
 static void name_owner_changed(DBusGProxy *object, const char *name,
@@ -139,12 +144,82 @@
 	return proxy;
 }
 
+static DBusHandlerResult MessageFunc (DBusConnection *c, DBusMessage *m, void *user_data)
+{
+	if (dbus_message_get_type(m) == DBUS_MESSAGE_TYPE_METHOD_CALL &&
+		!strncmp(PROPERTIES_DBUS_PATH, dbus_message_get_path(m), strlen(PROPERTIES_DBUS_PATH)) &&
+		!strncmp(PROPERTIES_DBUS_SERVICE, dbus_message_get_interface(m), strlen(PROPERTIES_DBUS_SERVICE)) &&
+		!strncmp("Present", dbus_message_get_member(m), 7)) {
+		GtkWindow *window = user_data;
+		gtk_window_present(window);
+	}
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusGConnection *check_for_instance (int *retval)
+{
+	DBusGConnection *sc;
+	DBusGProxy *proxy;
+	GError *error = NULL;
+	guint request_result;
+	gboolean ret;
+
+	sc = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+	if (error != NULL) {
+		g_printerr("Connecting to session bus failed: %s\n",
+					error->message);
+		g_error_free(error);
+		*retval = 1;
+		return NULL;
+	}
+
+	proxy = dbus_g_proxy_new_for_name(sc,
+									  DBUS_SERVICE_DBUS,
+									  DBUS_PATH_DBUS,
+									  DBUS_INTERFACE_DBUS);
+
+	ret = dbus_g_proxy_call(proxy, "RequestName", NULL,
+							G_TYPE_STRING, PROPERTIES_DBUS_SERVICE,
+							G_TYPE_UINT, 0,
+							G_TYPE_INVALID,
+							G_TYPE_UINT, &request_result,
+							G_TYPE_INVALID);
+	g_object_unref(G_OBJECT(proxy));
+	if (!ret) {
+		g_printerr("Failed to request name on the session bus\n");
+		dbus_g_connection_unref(sc);
+		*retval = 1;
+		return NULL;
+	}
+
+	if (request_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER &&
+	    !g_getenv("BLUEZ_IGNORE_SINGLETON")) {
+		proxy = dbus_g_proxy_new_for_name(sc,
+										  PROPERTIES_DBUS_SERVICE,
+										  PROPERTIES_DBUS_PATH,
+										  PROPERTIES_DBUS_SERVICE);
+		dbus_g_proxy_call_no_reply(proxy, "Present", G_TYPE_INVALID, G_TYPE_INVALID);
+		g_object_unref(G_OBJECT(proxy));
+		*retval = 0;
+	
+		g_print("Another instance is already running.\n");
+		dbus_g_connection_unref(sc);
+		return NULL;
+	}
+
+	return sc;
+}
+
 int main(int argc, char *argv[])
 {
 	GtkWidget *notebook;
-	DBusGConnection *conn;
-	DBusGProxy *manager;
+	GtkWidget *window;
 	GError *error = NULL;
+	DBusGConnection *conn, *session_conn = NULL;
+	DBusGProxy *manager;
+	DBusObjectPathVTable vtable;
+	int retval = 0;
 
 	bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
@@ -160,15 +235,24 @@
 		exit(EXIT_FAILURE);
 	}
 
+	session_conn = check_for_instance(&retval);
+	if (!session_conn)
+		exit(retval);
+
 	setup_general();
 
 	notebook = gtk_notebook_new();
-
+    
 	assign_adapter(notebook);
 
 	manager = setup_manager(conn);
 
-	create_window(notebook);
+	window = create_window(notebook);
+
+	vtable.message_function = MessageFunc;
+	vtable.unregister_function = NULL;
+	dbus_connection_register_object_path(dbus_g_connection_get_connection (session_conn),
+										 "/org/bluez/GnomeProperties", &vtable, window);
 
 	gtk_main();
 
@@ -181,6 +265,7 @@
 	g_object_unref(manager);
 
 	dbus_g_connection_unref(conn);
+	dbus_g_connection_unref(session_conn);
 
 	return 0;
 }
Index: wizard/main.c
===================================================================
RCS file: /cvsroot/bluez/gnome/wizard/main.c,v
retrieving revision 1.23
diff -u -r1.23 main.c
--- wizard/main.c	15 Aug 2007 07:04:03 -0000	1.23
+++ wizard/main.c	24 Oct 2007 19:47:25 -0000
@@ -26,8 +26,10 @@
 #endif
 
 #include <string.h>
+#include <stdlib.h>
 
 #include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
 #include <glib/gi18n.h>
 
@@ -39,6 +41,9 @@
 
 #include "bluetooth-device-selection.h"
 
+#define WIZARD_DBUS_PATH "/org/bluez/GnomeWizard"
+#define WIZARD_DBUS_SERVICE "org.bluez.GnomeWizard"
+
 static BluetoothClient *client;
 
 static gchar *address = NULL;
@@ -387,7 +392,7 @@
 	page_summary = vbox;
 }
 
-static void create_wizard(void)
+static GtkWidget *create_wizard(void)
 {
 	GtkWidget *assistant;
 
@@ -430,23 +435,107 @@
 	gtk_widget_show_all(assistant);
 
 	gtk_assistant_update_buttons_state(GTK_ASSISTANT(assistant));
+	return assistant;
+}
+
+static DBusHandlerResult MessageFunc (DBusConnection *c, DBusMessage *m, void *user_data)
+{
+	if (dbus_message_get_type(m) == DBUS_MESSAGE_TYPE_METHOD_CALL &&
+		!strncmp(WIZARD_DBUS_PATH, dbus_message_get_path(m), strlen(WIZARD_DBUS_PATH)) &&
+		!strncmp(WIZARD_DBUS_SERVICE, dbus_message_get_interface(m), strlen(WIZARD_DBUS_SERVICE)) &&
+		!strncmp("Present", dbus_message_get_member(m), 7)) {
+		GtkWindow *window = user_data;
+		gtk_window_present(window);
+	}
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusGConnection *check_for_instance (int *retval)
+{
+	DBusGConnection *sc;
+	DBusGProxy *proxy;
+	GError *error = NULL;
+	guint request_result;
+	gboolean ret;
+
+	sc = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+	if (error != NULL) {
+		g_printerr("Connecting to session bus failed: %s\n",
+					error->message);
+		g_error_free(error);
+		*retval = 1;
+		return NULL;
+	}
+
+	proxy = dbus_g_proxy_new_for_name(sc,
+									  DBUS_SERVICE_DBUS,
+									  DBUS_PATH_DBUS,
+									  DBUS_INTERFACE_DBUS);
+
+	ret = dbus_g_proxy_call(proxy, "RequestName", NULL,
+							G_TYPE_STRING, WIZARD_DBUS_SERVICE,
+							G_TYPE_UINT, 0,
+							G_TYPE_INVALID,
+							G_TYPE_UINT, &request_result,
+							G_TYPE_INVALID);
+	g_object_unref(G_OBJECT(proxy));
+	if (!ret) {
+		g_printerr("Failed to request name on the session bus\n");
+		dbus_g_connection_unref(sc);
+		*retval = 1;
+		return NULL;
+	}
+
+	if (request_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER &&
+		!g_getenv("BLUEZ_IGNORE_SINGLETON")) {
+		proxy = dbus_g_proxy_new_for_name(sc,
+										  WIZARD_DBUS_SERVICE,
+										  WIZARD_DBUS_PATH,
+										  WIZARD_DBUS_SERVICE);
+		dbus_g_proxy_call_no_reply(proxy, "Present", G_TYPE_INVALID, G_TYPE_INVALID);
+		g_object_unref(G_OBJECT(proxy));
+		*retval = 0;
+		
+		g_print("Another instance is already running.\n");
+		dbus_g_connection_unref(sc);
+		return NULL;
+	}
+
+	return sc;
 }
 
 int main(int argc, char *argv[])
 {
+	GtkWidget *window;
+	DBusGConnection *session_conn = NULL;
+	DBusObjectPathVTable vtable;
+	int retval = 0;
+	
 	bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
 	textdomain(GETTEXT_PACKAGE);
 
 	gtk_init(&argc, &argv);
 
+	session_conn = check_for_instance(&retval);
+	if (!session_conn)
+		exit(retval);
+
 	client = bluetooth_client_new();
 
-	create_wizard();
+	window = create_wizard();
+    
+	vtable.message_function = MessageFunc;
+	vtable.unregister_function = NULL;
+	dbus_connection_register_object_path(dbus_g_connection_get_connection (session_conn),
+										 WIZARD_DBUS_PATH, &vtable, window);
 
 	gtk_main();
 
 	g_object_unref(client);
 
+	dbus_g_connection_unref(session_conn);
+
 	return 0;
 }

[-- Attachment #3: Type: text/plain, Size: 314 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Bluez-devel] [PATCH] make bluez GNOME UIs singletons
  2007-10-18 10:15       ` Fabien Chevalier
@ 2007-10-31 16:14         ` Marcel Holtmann
  2007-10-31 16:24           ` Bastien Nocera
  0 siblings, 1 reply; 13+ messages in thread
From: Marcel Holtmann @ 2007-10-31 16:14 UTC (permalink / raw)
  To: BlueZ development

Hi Fabien,

> >>         actually the wizard and the properties applications are meant
> >>         to be
> >>         _not_ singletons. They are designed in a way that multiple
> >>         instances can
> >>         exist and work together.
> >>         
> >>         For the applet, only one instance is useful. However for
> >>         testing and 
> >>         development purposes it is nice to start two of them.
> >>
> >> The applet already has the ability to launch the properties dialog and
> >> I think it should also have an entry to launch the wizard.   This
> >> makes it very easy to get to a state where you have multiple copies
> >> open at once.  I think it's confusing to users and it doesn't buy you
> >> anything.  Just in case it's not clear, the patch allows for one
> >> instance per desktop session. 
> > 
> > Both of you are right. Developers should be able to launch another
> > applet or prefs for testing, but users should only ever see one applet
> > and prefs dialogue.
> > 
> > Maybe a command-line flag or envvar to disable the singleton behaviour
> > in Chris' patch would be acceptable for Marcel?
>
> Bastien, i agree with you. :-)
>  From the user experience perspective, having more than one instance of 
> those windows is just plain wrong( in fact this was a remark one working 
> collegue of mine just had when he discovered the bluez GUI for the first 
> time :-) )
> If Marcel wants to keep the old behaviour for testing purpose, i'm not 
> against it, but i really think the singleton behavior should be the default.

actually I do think that the current behavior should be default. I
really want that behavior. There are corner cases that need to be
thought of and making it a singleton only hides these issues.

However having a special switch that makes it a singleton would be a
good enhancement and I agree with you that any application started by
the applet should only exists once. The applet can use that specific
switch easily and we don't break current behavior.

Regards

Marcel



-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Bluez-devel] [PATCH] make bluez GNOME UIs singletons
  2007-10-31 16:14         ` Marcel Holtmann
@ 2007-10-31 16:24           ` Bastien Nocera
  2007-10-31 16:36             ` Marcel Holtmann
  2007-11-13 16:24             ` Chris Rivera
  0 siblings, 2 replies; 13+ messages in thread
From: Bastien Nocera @ 2007-10-31 16:24 UTC (permalink / raw)
  To: BlueZ development


On Wed, 2007-10-31 at 17:14 +0100, Marcel Holtmann wrote:
<snip>
> actually I do think that the current behavior should be default. I
> really want that behavior. There are corner cases that need to be
> thought of and making it a singleton only hides these issues.
> 
> However having a special switch that makes it a singleton would be a
> good enhancement and I agree with you that any application started by
> the applet should only exists once. The applet can use that specific
> switch easily and we don't break current behavior.

As long as the switch exists, I don't mind. I'd probably make it the
default for Fedora, in the .desktop files, and it wouldn't break normal
development use.

Chris, can you update the patches for that?


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Bluez-devel] [PATCH] make bluez GNOME UIs singletons
  2007-10-31 16:24           ` Bastien Nocera
@ 2007-10-31 16:36             ` Marcel Holtmann
  2007-11-13 16:24             ` Chris Rivera
  1 sibling, 0 replies; 13+ messages in thread
From: Marcel Holtmann @ 2007-10-31 16:36 UTC (permalink / raw)
  To: BlueZ development

Hi Bastien,

> > actually I do think that the current behavior should be default. I
> > really want that behavior. There are corner cases that need to be
> > thought of and making it a singleton only hides these issues.
> > 
> > However having a special switch that makes it a singleton would be a
> > good enhancement and I agree with you that any application started by
> > the applet should only exists once. The applet can use that specific
> > switch easily and we don't break current behavior.
> 
> As long as the switch exists, I don't mind. I'd probably make it the
> default for Fedora, in the .desktop files, and it wouldn't break normal
> development use.

sorry I wasn't clear on this. Yes, in the .desktop it should be also
included. Only when calling it from the terminal it should keep the
current behavior, because that is what I expect when I type a command.

Regards

Marcel



-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Bluez-devel] [PATCH] make bluez GNOME UIs singletons
  2007-10-31 16:24           ` Bastien Nocera
  2007-10-31 16:36             ` Marcel Holtmann
@ 2007-11-13 16:24             ` Chris Rivera
  2007-11-13 16:30               ` Bastien Nocera
  1 sibling, 1 reply; 13+ messages in thread
From: Chris Rivera @ 2007-11-13 16:24 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 968 bytes --]

On Oct 31, 2007 11:24 AM, Bastien Nocera <hadess@hadess.net> wrote:
>
> On Wed, 2007-10-31 at 17:14 +0100, Marcel Holtmann wrote:
> <snip>
> > actually I do think that the current behavior should be default. I
> > really want that behavior. There are corner cases that need to be
> > thought of and making it a singleton only hides these issues.
> >
> > However having a special switch that makes it a singleton would be a
> > good enhancement and I agree with you that any application started by
> > the applet should only exists once. The applet can use that specific
> > switch easily and we don't break current behavior.
>
> As long as the switch exists, I don't mind. I'd probably make it the
> default for Fedora, in the .desktop files, and it wouldn't break normal
> development use.
>
> Chris, can you update the patches for that?

Sorry for the delayed response.  Attached is an updated patch that
adds a flag to enable the singleton behavior.

Thanks,
Chris

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: bluez-gnome-singleton.patch --]
[-- Type: text/x-patch; name=bluez-gnome-singleton.patch, Size: 13437 bytes --]

Index: applet/main.c
===================================================================
RCS file: /cvsroot/bluez/gnome/applet/main.c,v
retrieving revision 1.87
diff -u -p -r1.87 main.c
--- applet/main.c	29 Aug 2007 20:42:18 -0000	1.87
+++ applet/main.c	13 Nov 2007 16:16:54 -0000
@@ -32,9 +32,9 @@
 #include <string.h>
 
 #include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
 #ifdef HAVE_HAL
-#include <dbus/dbus-glib-lowlevel.h>
 #include <hal/libhal.h>
 #endif
 
@@ -1553,7 +1553,7 @@ static void about_callback(GtkWidget *it
 
 static void settings_callback(GObject *widget, gpointer user_data)
 {
-	const char *command = "bluetooth-properties";
+	const char *command = "bluetooth-properties --singleton";
 
 	if (!g_spawn_command_line_async(command, NULL))
 		g_printerr("Couldn't execute command: %s\n", command);
@@ -1642,7 +1642,7 @@ static void sendto_callback(GObject *wid
 #if 0
 static void wizard_callback(GObject *widget, gpointer user_data)
 {
-	const char *command = "bluetooth-wizard";
+	const char *command = "bluetooth-wizard --singleton";
 
 	if (!g_spawn_command_line_async(command, NULL))
 		g_printerr("Couldn't execute command: %s\n", command);
@@ -1783,11 +1779,70 @@ static void gconf_callback(GConfClient *
 		auto_authorize = gconf_value_get_bool(value);
 }
 
+static DBusGConnection *register_instance (int *retval, gboolean singleton)
+{
+	DBusGConnection *sc;
+	DBusGProxy *proxy;
+	GError *error = NULL;
+	guint request_result;
+	gboolean ret;
+
+	sc = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+	if (error != NULL) {
+		g_printerr("Connecting to session bus failed: %s\n",
+					error->message);
+		g_error_free(error);
+		*retval = 1;
+		return NULL;
+	}
+
+	proxy = dbus_g_proxy_new_for_name(sc,
+									  DBUS_SERVICE_DBUS,
+									  DBUS_PATH_DBUS,
+									  DBUS_INTERFACE_DBUS);
+
+	ret = dbus_g_proxy_call(proxy, "RequestName", NULL,
+							G_TYPE_STRING, "org.bluez.GnomeApplet",
+							G_TYPE_UINT, 0,
+							G_TYPE_INVALID,
+							G_TYPE_UINT, &request_result,
+							G_TYPE_INVALID);
+	g_object_unref(G_OBJECT(proxy));
+	if (!ret) {
+		g_printerr("Failed to request name on the session bus\n");
+		dbus_g_connection_unref(sc);
+		*retval = 1;
+		return NULL;
+	}
+
+	if (request_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+		*retval = 0;
+		
+		if (singleton) {
+			g_print("Another instance is already running.\n");
+			dbus_g_connection_unref(sc);
+			return NULL;
+		}
+	}
+
+	return sc;
+}
+
 int main(int argc, char *argv[])
 {
+	GOptionContext *ctx;
 	GtkWidget *menu;
 	GError *error = NULL;
+	DBusGConnection *session_conn = NULL;
 	char *str;
+	int retval = 0;
+	gboolean singleton = FALSE;
+
+	GOptionEntry entries[] = {
+        { "singleton", 0, 0, G_OPTION_ARG_NONE, &singleton,
+		  N_("Only allow one instance of this application"), NULL },
+        { NULL, 0, 0, 0, NULL, NULL, NULL }
+	};
 
 	bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
@@ -1795,6 +1850,15 @@ int main(int argc, char *argv[])
 
 	gtk_init(&argc, &argv);
 
+	ctx = g_option_context_new("");
+	g_option_context_add_main_entries(ctx, entries, NULL);
+	if (!g_option_context_parse(ctx, &argc, &argv, &error)) {
+		g_printerr(_("parsing failed: %s\n"), error->message);
+		g_error_free(error);
+		g_option_context_free(ctx);
+		return retval;
+	}
+
 #ifdef HAVE_LIBNOTIFY
 	notify_init("bluetooth-manager");
 #endif
@@ -1806,6 +1870,10 @@ int main(int argc, char *argv[])
 		g_error_free(error);
 		exit(EXIT_FAILURE);
 	}
+	
+	session_conn = register_instance(&retval, singleton);
+	if (!session_conn)
+		exit(retval);
 
 	gconf = gconf_client_get_default();
 
@@ -1863,6 +1931,9 @@ int main(int argc, char *argv[])
 	g_list_foreach(adapter_list, adapter_free, NULL);
 
 	dbus_g_connection_unref(conn);
+	dbus_g_connection_unref(session_conn);
 
+	g_option_context_free(ctx);
+	
 	return 0;
 }
Index: properties/main.c
===================================================================
RCS file: /cvsroot/bluez/gnome/properties/main.c,v
retrieving revision 1.48
diff -u -p -r1.48 main.c
--- properties/main.c	31 Jul 2007 21:37:29 -0000	1.48
+++ properties/main.c	13 Nov 2007 16:16:54 -0000
@@ -32,6 +32,7 @@
 #include <string.h>
 
 #include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
 #include <glib/gi18n.h>
 
@@ -41,6 +42,9 @@
 #include "service.h"
 #include "adapter.h"
 
+#define PROPERTIES_DBUS_PATH "/org/bluez/GnomeProperties"
+#define PROPERTIES_DBUS_SERVICE "org.bluez.GnomeProperties"
+
 static void delete_callback(GtkWidget *window, GdkEvent *event,
 						gpointer user_data)
 {
@@ -58,7 +62,7 @@ static void close_callback(GtkWidget *bu
 	gtk_main_quit();
 }
 
-static void create_window(GtkWidget *notebook)
+static GtkWidget *create_window(GtkWidget *notebook)
 {
 	GtkWidget *window;
 	GtkWidget *widget;
@@ -108,6 +112,7 @@ static void create_window(GtkWidget *not
 						widget, _("General"));
 
 	gtk_widget_show_all(window);
+	return window;
 }
 
 static void name_owner_changed(DBusGProxy *object, const char *name,
@@ -139,19 +144,105 @@ static DBusGProxy *setup_manager(DBusGCo
 	return proxy;
 }
 
+static DBusHandlerResult MessageFunc (DBusConnection *c, DBusMessage *m, void *user_data)
+{
+	if (dbus_message_get_type(m) == DBUS_MESSAGE_TYPE_METHOD_CALL &&
+		!strncmp(PROPERTIES_DBUS_PATH, dbus_message_get_path(m), strlen(PROPERTIES_DBUS_PATH)) &&
+		!strncmp(PROPERTIES_DBUS_SERVICE, dbus_message_get_interface(m), strlen(PROPERTIES_DBUS_SERVICE)) &&
+		!strncmp("Present", dbus_message_get_member(m), 7)) {
+		GtkWindow *window = user_data;
+		gtk_window_present(window);
+	}
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusGConnection *register_instance (int *retval, gboolean singleton)
+{
+	DBusGConnection *sc;
+	DBusGProxy *proxy;
+	GError *error = NULL;
+	guint request_result;
+	gboolean ret;
+
+	sc = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+	if (error != NULL) {
+		g_printerr("Connecting to session bus failed: %s\n",
+					error->message);
+		g_error_free(error);
+		*retval = 1;
+		return NULL;
+	}
+
+	proxy = dbus_g_proxy_new_for_name(sc,
+									  DBUS_SERVICE_DBUS,
+									  DBUS_PATH_DBUS,
+									  DBUS_INTERFACE_DBUS);
+
+	ret = dbus_g_proxy_call(proxy, "RequestName", NULL,
+							G_TYPE_STRING, PROPERTIES_DBUS_SERVICE,
+							G_TYPE_UINT, 0,
+							G_TYPE_INVALID,
+							G_TYPE_UINT, &request_result,
+							G_TYPE_INVALID);
+	g_object_unref(G_OBJECT(proxy));
+	if (!ret) {
+		g_printerr("Failed to request name on the session bus\n");
+		dbus_g_connection_unref(sc);
+		*retval = 1;
+		return NULL;
+	}
+
+	if (request_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER && singleton) {
+		proxy = dbus_g_proxy_new_for_name(sc,
+										  PROPERTIES_DBUS_SERVICE,
+										  PROPERTIES_DBUS_PATH,
+										  PROPERTIES_DBUS_SERVICE);
+		dbus_g_proxy_call_no_reply(proxy, "Present", G_TYPE_INVALID, G_TYPE_INVALID);
+		g_object_unref(G_OBJECT(proxy));
+		*retval = 0;
+	
+		g_print("Another instance is already running.\n");
+		dbus_g_connection_unref(sc);
+		return NULL;
+	}
+
+	return sc;
+}
+
 int main(int argc, char *argv[])
 {
+	GOptionContext *ctx;
 	GtkWidget *notebook;
-	DBusGConnection *conn;
-	DBusGProxy *manager;
+	GtkWidget *window;
 	GError *error = NULL;
-
+	DBusGConnection *conn, *session_conn = NULL;
+	DBusGProxy *manager;
+	DBusObjectPathVTable vtable;
+	int retval = 0;
+	gboolean singleton = FALSE;
+
+	GOptionEntry entries[] = {
+        { "singleton", 0, 0, G_OPTION_ARG_NONE, &singleton,
+		  N_("Only allow one instance of this application"), NULL },
+        { NULL, 0, 0, 0, NULL, NULL, NULL }
+	};
+	
 	bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
 	textdomain(GETTEXT_PACKAGE);
 
 	gtk_init(&argc, &argv);
 
+	ctx = g_option_context_new("");
+	g_option_context_add_main_entries(ctx, entries, NULL);
+	if (!g_option_context_parse(ctx, &argc, &argv, &error)) {
+		g_printerr(_("parsing failed: %s\n"), error->message);
+		g_error_free(error);
+		g_option_context_free(ctx);
+		return retval;
+	}
+	
 	conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
 	if (error != NULL) {
 		g_printerr("Connecting to system bus failed: %s\n",
@@ -160,15 +251,24 @@ int main(int argc, char *argv[])
 		exit(EXIT_FAILURE);
 	}
 
+	session_conn = register_instance(&retval, singleton);
+	if (!session_conn)
+		exit(retval);
+
 	setup_general();
 
 	notebook = gtk_notebook_new();
-
+    
 	assign_adapter(notebook);
 
 	manager = setup_manager(conn);
 
-	create_window(notebook);
+	window = create_window(notebook);
+
+	vtable.message_function = MessageFunc;
+	vtable.unregister_function = NULL;
+	dbus_connection_register_object_path(dbus_g_connection_get_connection (session_conn),
+										 "/org/bluez/GnomeProperties", &vtable, window);
 
 	gtk_main();
 
@@ -181,6 +281,9 @@ int main(int argc, char *argv[])
 	g_object_unref(manager);
 
 	dbus_g_connection_unref(conn);
+	dbus_g_connection_unref(session_conn);
 
+	g_option_context_free(ctx);
+	
 	return 0;
 }
Index: wizard/main.c
===================================================================
RCS file: /cvsroot/bluez/gnome/wizard/main.c,v
retrieving revision 1.23
diff -u -p -r1.23 main.c
--- wizard/main.c	15 Aug 2007 07:04:03 -0000	1.23
+++ wizard/main.c	13 Nov 2007 16:16:54 -0000
@@ -26,8 +26,10 @@
 #endif
 
 #include <string.h>
+#include <stdlib.h>
 
 #include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
 #include <glib/gi18n.h>
 
@@ -39,6 +41,9 @@
 
 #include "bluetooth-device-selection.h"
 
+#define WIZARD_DBUS_PATH "/org/bluez/GnomeWizard"
+#define WIZARD_DBUS_SERVICE "org.bluez.GnomeWizard"
+
 static BluetoothClient *client;
 
 static gchar *address = NULL;
@@ -387,7 +392,7 @@ static void create_summary(GtkWidget *as
 	page_summary = vbox;
 }
 
-static void create_wizard(void)
+static GtkWidget *create_wizard(void)
 {
 	GtkWidget *assistant;
 
@@ -430,23 +435,126 @@ static void create_wizard(void)
 	gtk_widget_show_all(assistant);
 
 	gtk_assistant_update_buttons_state(GTK_ASSISTANT(assistant));
+	return assistant;
+}
+
+static DBusHandlerResult MessageFunc (DBusConnection *c, DBusMessage *m, void *user_data)
+{
+	if (dbus_message_get_type(m) == DBUS_MESSAGE_TYPE_METHOD_CALL &&
+		!strncmp(WIZARD_DBUS_PATH, dbus_message_get_path(m), strlen(WIZARD_DBUS_PATH)) &&
+		!strncmp(WIZARD_DBUS_SERVICE, dbus_message_get_interface(m), strlen(WIZARD_DBUS_SERVICE)) &&
+		!strncmp("Present", dbus_message_get_member(m), 7)) {
+		GtkWindow *window = user_data;
+		gtk_window_present(window);
+	}
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusGConnection *register_instance (int *retval, gboolean singleton)
+{
+	DBusGConnection *sc;
+	DBusGProxy *proxy;
+	GError *error = NULL;
+	guint request_result;
+	gboolean ret;
+
+	sc = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+	if (error != NULL) {
+		g_printerr("Connecting to session bus failed: %s\n",
+					error->message);
+		g_error_free(error);
+		*retval = 1;
+		return NULL;
+	}
+
+	proxy = dbus_g_proxy_new_for_name(sc,
+									  DBUS_SERVICE_DBUS,
+									  DBUS_PATH_DBUS,
+									  DBUS_INTERFACE_DBUS);
+
+	ret = dbus_g_proxy_call(proxy, "RequestName", NULL,
+							G_TYPE_STRING, WIZARD_DBUS_SERVICE,
+							G_TYPE_UINT, 0,
+							G_TYPE_INVALID,
+							G_TYPE_UINT, &request_result,
+							G_TYPE_INVALID);
+	g_object_unref(G_OBJECT(proxy));
+	if (!ret) {
+		g_printerr("Failed to request name on the session bus\n");
+		dbus_g_connection_unref(sc);
+		*retval = 1;
+		return NULL;
+	}
+
+	if (request_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER && singleton) {
+		proxy = dbus_g_proxy_new_for_name(sc,
+										  WIZARD_DBUS_SERVICE,
+										  WIZARD_DBUS_PATH,
+										  WIZARD_DBUS_SERVICE);
+		dbus_g_proxy_call_no_reply(proxy, "Present", G_TYPE_INVALID, G_TYPE_INVALID);
+		g_object_unref(G_OBJECT(proxy));
+		*retval = 0;
+		
+		g_print("Another instance is already running.\n");
+		dbus_g_connection_unref(sc);
+		return NULL;
+	}
+
+	return sc;
 }
 
 int main(int argc, char *argv[])
 {
+	GOptionContext *ctx;
+	GtkWidget *window;
+	DBusGConnection *session_conn = NULL;
+	GError *error = NULL;
+	DBusObjectPathVTable vtable;
+	int retval = 0;
+	gboolean singleton = FALSE;
+
+	GOptionEntry entries[] = {
+        { "singleton", 0, 0, G_OPTION_ARG_NONE, &singleton,
+		  N_("Only allow one instance of this application"), NULL },
+        { NULL, 0, 0, 0, NULL, NULL, NULL }
+	};
+	
 	bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
 	textdomain(GETTEXT_PACKAGE);
 
 	gtk_init(&argc, &argv);
 
+	ctx = g_option_context_new("");
+	g_option_context_add_main_entries(ctx, entries, NULL);
+	if (!g_option_context_parse(ctx, &argc, &argv, &error)) {
+		g_printerr(_("parsing failed: %s\n"), error->message);
+		g_error_free(error);
+		g_option_context_free(ctx);
+		return retval;
+	}
+	
+	session_conn = register_instance(&retval, singleton);
+	if (!session_conn)
+		exit(retval);
+
 	client = bluetooth_client_new();
 
-	create_wizard();
+	window = create_wizard();
+    
+	vtable.message_function = MessageFunc;
+	vtable.unregister_function = NULL;
+	dbus_connection_register_object_path(dbus_g_connection_get_connection (session_conn),
+										 WIZARD_DBUS_PATH, &vtable, window);
 
 	gtk_main();
 
 	g_object_unref(client);
 
+	dbus_g_connection_unref(session_conn);
+
+	g_option_context_free(ctx);
+	
 	return 0;
 }

[-- Attachment #3: Type: text/plain, Size: 314 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Bluez-devel] [PATCH] make bluez GNOME UIs singletons
  2007-11-13 16:24             ` Chris Rivera
@ 2007-11-13 16:30               ` Bastien Nocera
  2007-11-13 17:06                 ` Chris Rivera
  0 siblings, 1 reply; 13+ messages in thread
From: Bastien Nocera @ 2007-11-13 16:30 UTC (permalink / raw)
  To: BlueZ development


On Tue, 2007-11-13 at 11:24 -0500, Chris Rivera wrote:
> On Oct 31, 2007 11:24 AM, Bastien Nocera <hadess@hadess.net> wrote:
> >
> > On Wed, 2007-10-31 at 17:14 +0100, Marcel Holtmann wrote:
> > <snip>
> > > actually I do think that the current behavior should be default. I
> > > really want that behavior. There are corner cases that need to be
> > > thought of and making it a singleton only hides these issues.
> > >
> > > However having a special switch that makes it a singleton would be a
> > > good enhancement and I agree with you that any application started by
> > > the applet should only exists once. The applet can use that specific
> > > switch easily and we don't break current behavior.
> >
> > As long as the switch exists, I don't mind. I'd probably make it the
> > default for Fedora, in the .desktop files, and it wouldn't break normal
> > development use.
> >
> > Chris, can you update the patches for that?
> 
> Sorry for the delayed response.  Attached is an updated patch that
> adds a flag to enable the singleton behavior.

Could you modify the .desktop file that starts the applet as well?


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Bluez-devel] [PATCH] make bluez GNOME UIs singletons
  2007-11-13 16:30               ` Bastien Nocera
@ 2007-11-13 17:06                 ` Chris Rivera
  2007-11-27 15:45                   ` Chris Rivera
  0 siblings, 1 reply; 13+ messages in thread
From: Chris Rivera @ 2007-11-13 17:06 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 199 bytes --]

On Nov 13, 2007 11:30 AM, Bastien Nocera <hadess@hadess.net> wrote:
> Could you modify the .desktop file that starts the applet as well?
>

Updated patch to include desktop file modification.

Chris

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: bluez-gnome-singleton.patch --]
[-- Type: text/x-patch; name=bluez-gnome-singleton.patch, Size: 14037 bytes --]

Index: applet/bluetooth-applet.desktop.in
===================================================================
RCS file: /cvsroot/bluez/gnome/applet/bluetooth-applet.desktop.in,v
retrieving revision 1.1
diff -u -p -r1.1 bluetooth-applet.desktop.in
--- applet/bluetooth-applet.desktop.in	3 Apr 2007 08:09:01 -0000	1.1
+++ applet/bluetooth-applet.desktop.in	13 Nov 2007 17:04:15 -0000
@@ -3,7 +3,7 @@ Encoding=UTF-8
 _Name=Bluetooth Manager
 _Comment=Bluetooth Manager applet
 Icon=stock_bluetooth
-Exec=bluetooth-applet
+Exec=bluetooth-applet --singleton
 Terminal=false
 Type=Application
 Categories=
Index: applet/main.c
===================================================================
RCS file: /cvsroot/bluez/gnome/applet/main.c,v
retrieving revision 1.87
diff -u -p -r1.87 main.c
--- applet/main.c	29 Aug 2007 20:42:18 -0000	1.87
+++ applet/main.c	13 Nov 2007 17:04:16 -0000
@@ -32,9 +32,9 @@
 #include <string.h>
 
 #include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
 #ifdef HAVE_HAL
-#include <dbus/dbus-glib-lowlevel.h>
 #include <hal/libhal.h>
 #endif
 
@@ -1553,7 +1553,7 @@ static void about_callback(GtkWidget *it
 
 static void settings_callback(GObject *widget, gpointer user_data)
 {
-	const char *command = "bluetooth-properties";
+	const char *command = "bluetooth-properties --singleton";
 
 	if (!g_spawn_command_line_async(command, NULL))
 		g_printerr("Couldn't execute command: %s\n", command);
@@ -1642,7 +1642,7 @@ static void sendto_callback(GObject *wid
 #if 0
 static void wizard_callback(GObject *widget, gpointer user_data)
 {
-	const char *command = "bluetooth-wizard";
+	const char *command = "bluetooth-wizard --singleton";
 
 	if (!g_spawn_command_line_async(command, NULL))
 		g_printerr("Couldn't execute command: %s\n", command);
@@ -1783,11 +1783,70 @@ static void gconf_callback(GConfClient *
 		auto_authorize = gconf_value_get_bool(value);
 }
 
+static DBusGConnection *register_instance (int *retval, gboolean singleton)
+{
+	DBusGConnection *sc;
+	DBusGProxy *proxy;
+	GError *error = NULL;
+	guint request_result;
+	gboolean ret;
+
+	sc = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+	if (error != NULL) {
+		g_printerr("Connecting to session bus failed: %s\n",
+					error->message);
+		g_error_free(error);
+		*retval = 1;
+		return NULL;
+	}
+
+	proxy = dbus_g_proxy_new_for_name(sc,
+									  DBUS_SERVICE_DBUS,
+									  DBUS_PATH_DBUS,
+									  DBUS_INTERFACE_DBUS);
+
+	ret = dbus_g_proxy_call(proxy, "RequestName", NULL,
+							G_TYPE_STRING, "org.bluez.GnomeApplet",
+							G_TYPE_UINT, 0,
+							G_TYPE_INVALID,
+							G_TYPE_UINT, &request_result,
+							G_TYPE_INVALID);
+	g_object_unref(G_OBJECT(proxy));
+	if (!ret) {
+		g_printerr("Failed to request name on the session bus\n");
+		dbus_g_connection_unref(sc);
+		*retval = 1;
+		return NULL;
+	}
+
+	if (request_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+		*retval = 0;
+		
+		if (singleton) {
+			g_print("Another instance is already running.\n");
+			dbus_g_connection_unref(sc);
+			return NULL;
+		}
+	}
+
+	return sc;
+}
+
 int main(int argc, char *argv[])
 {
+	GOptionContext *ctx;
 	GtkWidget *menu;
 	GError *error = NULL;
+	DBusGConnection *session_conn = NULL;
 	char *str;
+	int retval = 0;
+	gboolean singleton = FALSE;
+
+	GOptionEntry entries[] = {
+        { "singleton", 0, 0, G_OPTION_ARG_NONE, &singleton,
+		  N_("Only allow one instance of this application"), NULL },
+        { NULL, 0, 0, 0, NULL, NULL, NULL }
+	};
 
 	bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
@@ -1795,6 +1854,15 @@ int main(int argc, char *argv[])
 
 	gtk_init(&argc, &argv);
 
+	ctx = g_option_context_new("");
+	g_option_context_add_main_entries(ctx, entries, NULL);
+	if (!g_option_context_parse(ctx, &argc, &argv, &error)) {
+		g_printerr(_("parsing failed: %s\n"), error->message);
+		g_error_free(error);
+		g_option_context_free(ctx);
+		return retval;
+	}
+
 #ifdef HAVE_LIBNOTIFY
 	notify_init("bluetooth-manager");
 #endif
@@ -1806,6 +1874,10 @@ int main(int argc, char *argv[])
 		g_error_free(error);
 		exit(EXIT_FAILURE);
 	}
+	
+	session_conn = register_instance(&retval, singleton);
+	if (!session_conn)
+		exit(retval);
 
 	gconf = gconf_client_get_default();
 
@@ -1863,6 +1935,9 @@ int main(int argc, char *argv[])
 	g_list_foreach(adapter_list, adapter_free, NULL);
 
 	dbus_g_connection_unref(conn);
+	dbus_g_connection_unref(session_conn);
 
+	g_option_context_free(ctx);
+	
 	return 0;
 }
Index: properties/main.c
===================================================================
RCS file: /cvsroot/bluez/gnome/properties/main.c,v
retrieving revision 1.48
diff -u -p -r1.48 main.c
--- properties/main.c	31 Jul 2007 21:37:29 -0000	1.48
+++ properties/main.c	13 Nov 2007 17:04:16 -0000
@@ -32,6 +32,7 @@
 #include <string.h>
 
 #include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
 #include <glib/gi18n.h>
 
@@ -41,6 +42,9 @@
 #include "service.h"
 #include "adapter.h"
 
+#define PROPERTIES_DBUS_PATH "/org/bluez/GnomeProperties"
+#define PROPERTIES_DBUS_SERVICE "org.bluez.GnomeProperties"
+
 static void delete_callback(GtkWidget *window, GdkEvent *event,
 						gpointer user_data)
 {
@@ -58,7 +62,7 @@ static void close_callback(GtkWidget *bu
 	gtk_main_quit();
 }
 
-static void create_window(GtkWidget *notebook)
+static GtkWidget *create_window(GtkWidget *notebook)
 {
 	GtkWidget *window;
 	GtkWidget *widget;
@@ -108,6 +112,7 @@ static void create_window(GtkWidget *not
 						widget, _("General"));
 
 	gtk_widget_show_all(window);
+	return window;
 }
 
 static void name_owner_changed(DBusGProxy *object, const char *name,
@@ -139,19 +144,105 @@ static DBusGProxy *setup_manager(DBusGCo
 	return proxy;
 }
 
+static DBusHandlerResult MessageFunc (DBusConnection *c, DBusMessage *m, void *user_data)
+{
+	if (dbus_message_get_type(m) == DBUS_MESSAGE_TYPE_METHOD_CALL &&
+		!strncmp(PROPERTIES_DBUS_PATH, dbus_message_get_path(m), strlen(PROPERTIES_DBUS_PATH)) &&
+		!strncmp(PROPERTIES_DBUS_SERVICE, dbus_message_get_interface(m), strlen(PROPERTIES_DBUS_SERVICE)) &&
+		!strncmp("Present", dbus_message_get_member(m), 7)) {
+		GtkWindow *window = user_data;
+		gtk_window_present(window);
+	}
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusGConnection *register_instance (int *retval, gboolean singleton)
+{
+	DBusGConnection *sc;
+	DBusGProxy *proxy;
+	GError *error = NULL;
+	guint request_result;
+	gboolean ret;
+
+	sc = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+	if (error != NULL) {
+		g_printerr("Connecting to session bus failed: %s\n",
+					error->message);
+		g_error_free(error);
+		*retval = 1;
+		return NULL;
+	}
+
+	proxy = dbus_g_proxy_new_for_name(sc,
+									  DBUS_SERVICE_DBUS,
+									  DBUS_PATH_DBUS,
+									  DBUS_INTERFACE_DBUS);
+
+	ret = dbus_g_proxy_call(proxy, "RequestName", NULL,
+							G_TYPE_STRING, PROPERTIES_DBUS_SERVICE,
+							G_TYPE_UINT, 0,
+							G_TYPE_INVALID,
+							G_TYPE_UINT, &request_result,
+							G_TYPE_INVALID);
+	g_object_unref(G_OBJECT(proxy));
+	if (!ret) {
+		g_printerr("Failed to request name on the session bus\n");
+		dbus_g_connection_unref(sc);
+		*retval = 1;
+		return NULL;
+	}
+
+	if (request_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER && singleton) {
+		proxy = dbus_g_proxy_new_for_name(sc,
+										  PROPERTIES_DBUS_SERVICE,
+										  PROPERTIES_DBUS_PATH,
+										  PROPERTIES_DBUS_SERVICE);
+		dbus_g_proxy_call_no_reply(proxy, "Present", G_TYPE_INVALID, G_TYPE_INVALID);
+		g_object_unref(G_OBJECT(proxy));
+		*retval = 0;
+	
+		g_print("Another instance is already running.\n");
+		dbus_g_connection_unref(sc);
+		return NULL;
+	}
+
+	return sc;
+}
+
 int main(int argc, char *argv[])
 {
+	GOptionContext *ctx;
 	GtkWidget *notebook;
-	DBusGConnection *conn;
-	DBusGProxy *manager;
+	GtkWidget *window;
 	GError *error = NULL;
-
+	DBusGConnection *conn, *session_conn = NULL;
+	DBusGProxy *manager;
+	DBusObjectPathVTable vtable;
+	int retval = 0;
+	gboolean singleton = FALSE;
+
+	GOptionEntry entries[] = {
+        { "singleton", 0, 0, G_OPTION_ARG_NONE, &singleton,
+		  N_("Only allow one instance of this application"), NULL },
+        { NULL, 0, 0, 0, NULL, NULL, NULL }
+	};
+	
 	bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
 	textdomain(GETTEXT_PACKAGE);
 
 	gtk_init(&argc, &argv);
 
+	ctx = g_option_context_new("");
+	g_option_context_add_main_entries(ctx, entries, NULL);
+	if (!g_option_context_parse(ctx, &argc, &argv, &error)) {
+		g_printerr(_("parsing failed: %s\n"), error->message);
+		g_error_free(error);
+		g_option_context_free(ctx);
+		return retval;
+	}
+	
 	conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
 	if (error != NULL) {
 		g_printerr("Connecting to system bus failed: %s\n",
@@ -160,15 +251,24 @@ int main(int argc, char *argv[])
 		exit(EXIT_FAILURE);
 	}
 
+	session_conn = register_instance(&retval, singleton);
+	if (!session_conn)
+		exit(retval);
+
 	setup_general();
 
 	notebook = gtk_notebook_new();
-
+    
 	assign_adapter(notebook);
 
 	manager = setup_manager(conn);
 
-	create_window(notebook);
+	window = create_window(notebook);
+
+	vtable.message_function = MessageFunc;
+	vtable.unregister_function = NULL;
+	dbus_connection_register_object_path(dbus_g_connection_get_connection (session_conn),
+										 "/org/bluez/GnomeProperties", &vtable, window);
 
 	gtk_main();
 
@@ -181,6 +281,9 @@ int main(int argc, char *argv[])
 	g_object_unref(manager);
 
 	dbus_g_connection_unref(conn);
+	dbus_g_connection_unref(session_conn);
 
+	g_option_context_free(ctx);
+	
 	return 0;
 }
Index: wizard/main.c
===================================================================
RCS file: /cvsroot/bluez/gnome/wizard/main.c,v
retrieving revision 1.23
diff -u -p -r1.23 main.c
--- wizard/main.c	15 Aug 2007 07:04:03 -0000	1.23
+++ wizard/main.c	13 Nov 2007 17:04:16 -0000
@@ -26,8 +26,10 @@
 #endif
 
 #include <string.h>
+#include <stdlib.h>
 
 #include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
 #include <glib/gi18n.h>
 
@@ -39,6 +41,9 @@
 
 #include "bluetooth-device-selection.h"
 
+#define WIZARD_DBUS_PATH "/org/bluez/GnomeWizard"
+#define WIZARD_DBUS_SERVICE "org.bluez.GnomeWizard"
+
 static BluetoothClient *client;
 
 static gchar *address = NULL;
@@ -387,7 +392,7 @@ static void create_summary(GtkWidget *as
 	page_summary = vbox;
 }
 
-static void create_wizard(void)
+static GtkWidget *create_wizard(void)
 {
 	GtkWidget *assistant;
 
@@ -430,23 +435,126 @@ static void create_wizard(void)
 	gtk_widget_show_all(assistant);
 
 	gtk_assistant_update_buttons_state(GTK_ASSISTANT(assistant));
+	return assistant;
+}
+
+static DBusHandlerResult MessageFunc (DBusConnection *c, DBusMessage *m, void *user_data)
+{
+	if (dbus_message_get_type(m) == DBUS_MESSAGE_TYPE_METHOD_CALL &&
+		!strncmp(WIZARD_DBUS_PATH, dbus_message_get_path(m), strlen(WIZARD_DBUS_PATH)) &&
+		!strncmp(WIZARD_DBUS_SERVICE, dbus_message_get_interface(m), strlen(WIZARD_DBUS_SERVICE)) &&
+		!strncmp("Present", dbus_message_get_member(m), 7)) {
+		GtkWindow *window = user_data;
+		gtk_window_present(window);
+	}
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusGConnection *register_instance (int *retval, gboolean singleton)
+{
+	DBusGConnection *sc;
+	DBusGProxy *proxy;
+	GError *error = NULL;
+	guint request_result;
+	gboolean ret;
+
+	sc = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+	if (error != NULL) {
+		g_printerr("Connecting to session bus failed: %s\n",
+					error->message);
+		g_error_free(error);
+		*retval = 1;
+		return NULL;
+	}
+
+	proxy = dbus_g_proxy_new_for_name(sc,
+									  DBUS_SERVICE_DBUS,
+									  DBUS_PATH_DBUS,
+									  DBUS_INTERFACE_DBUS);
+
+	ret = dbus_g_proxy_call(proxy, "RequestName", NULL,
+							G_TYPE_STRING, WIZARD_DBUS_SERVICE,
+							G_TYPE_UINT, 0,
+							G_TYPE_INVALID,
+							G_TYPE_UINT, &request_result,
+							G_TYPE_INVALID);
+	g_object_unref(G_OBJECT(proxy));
+	if (!ret) {
+		g_printerr("Failed to request name on the session bus\n");
+		dbus_g_connection_unref(sc);
+		*retval = 1;
+		return NULL;
+	}
+
+	if (request_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER && singleton) {
+		proxy = dbus_g_proxy_new_for_name(sc,
+										  WIZARD_DBUS_SERVICE,
+										  WIZARD_DBUS_PATH,
+										  WIZARD_DBUS_SERVICE);
+		dbus_g_proxy_call_no_reply(proxy, "Present", G_TYPE_INVALID, G_TYPE_INVALID);
+		g_object_unref(G_OBJECT(proxy));
+		*retval = 0;
+		
+		g_print("Another instance is already running.\n");
+		dbus_g_connection_unref(sc);
+		return NULL;
+	}
+
+	return sc;
 }
 
 int main(int argc, char *argv[])
 {
+	GOptionContext *ctx;
+	GtkWidget *window;
+	DBusGConnection *session_conn = NULL;
+	GError *error = NULL;
+	DBusObjectPathVTable vtable;
+	int retval = 0;
+	gboolean singleton = FALSE;
+
+	GOptionEntry entries[] = {
+        { "singleton", 0, 0, G_OPTION_ARG_NONE, &singleton,
+		  N_("Only allow one instance of this application"), NULL },
+        { NULL, 0, 0, 0, NULL, NULL, NULL }
+	};
+	
 	bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
 	textdomain(GETTEXT_PACKAGE);
 
 	gtk_init(&argc, &argv);
 
+	ctx = g_option_context_new("");
+	g_option_context_add_main_entries(ctx, entries, NULL);
+	if (!g_option_context_parse(ctx, &argc, &argv, &error)) {
+		g_printerr(_("parsing failed: %s\n"), error->message);
+		g_error_free(error);
+		g_option_context_free(ctx);
+		return retval;
+	}
+	
+	session_conn = register_instance(&retval, singleton);
+	if (!session_conn)
+		exit(retval);
+
 	client = bluetooth_client_new();
 
-	create_wizard();
+	window = create_wizard();
+    
+	vtable.message_function = MessageFunc;
+	vtable.unregister_function = NULL;
+	dbus_connection_register_object_path(dbus_g_connection_get_connection (session_conn),
+										 WIZARD_DBUS_PATH, &vtable, window);
 
 	gtk_main();
 
 	g_object_unref(client);
 
+	dbus_g_connection_unref(session_conn);
+
+	g_option_context_free(ctx);
+	
 	return 0;
 }

[-- Attachment #3: Type: text/plain, Size: 314 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Bluez-devel] [PATCH] make bluez GNOME UIs singletons
  2007-11-13 17:06                 ` Chris Rivera
@ 2007-11-27 15:45                   ` Chris Rivera
  0 siblings, 0 replies; 13+ messages in thread
From: Chris Rivera @ 2007-11-27 15:45 UTC (permalink / raw)
  To: BlueZ development


[-- Attachment #1.1: Type: text/plain, Size: 311 bytes --]

Any word on this?

Chris

On Nov 13, 2007 12:06 PM, Chris Rivera <chrismrivera@gmail.com> wrote:

> On Nov 13, 2007 11:30 AM, Bastien Nocera <hadess@hadess.net> wrote:
> > Could you modify the .desktop file that starts the applet as well?
> >
>
> Updated patch to include desktop file modification.
>
> Chris
>

[-- Attachment #1.2: Type: text/html, Size: 668 bytes --]

[-- Attachment #2: Type: text/plain, Size: 228 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

[-- Attachment #3: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2007-11-27 15:45 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-16 18:38 [Bluez-devel] [PATCH] make bluez GNOME UIs singletons Chris Rivera
2007-10-17 14:24 ` Marcel Holtmann
2007-10-17 14:48   ` Chris Rivera
2007-10-17 15:11     ` Bastien Nocera
2007-10-18 10:15       ` Fabien Chevalier
2007-10-31 16:14         ` Marcel Holtmann
2007-10-31 16:24           ` Bastien Nocera
2007-10-31 16:36             ` Marcel Holtmann
2007-11-13 16:24             ` Chris Rivera
2007-11-13 16:30               ` Bastien Nocera
2007-11-13 17:06                 ` Chris Rivera
2007-11-27 15:45                   ` Chris Rivera
2007-10-24 19:54       ` Chris Rivera

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox