public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [Bluez-devel] [PATCH] [RESEND] make bluez GNOME UIs singletons
@ 2007-12-03 15:33 Chris Rivera
  2007-12-03 16:25 ` Marcel Holtmann
  0 siblings, 1 reply; 19+ messages in thread
From: Chris Rivera @ 2007-12-03 15:33 UTC (permalink / raw)
  To: BlueZ development


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

I'm resending this patch since I haven't gotten a response in the original
thread in weeks.  Let me know if this looks OK.

Chris

[-- Attachment #1.2: Type: text/html, Size: 153 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: 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: 309 bytes --]

-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper
from Novell.  From the desktop to the data center, Linux is going
mainstream.  Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4

[-- 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] 19+ messages in thread

end of thread, other threads:[~2007-12-18 21:00 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-03 15:33 [Bluez-devel] [PATCH] [RESEND] make bluez GNOME UIs singletons Chris Rivera
2007-12-03 16:25 ` Marcel Holtmann
2007-12-03 16:50   ` Chris Rivera
2007-12-03 16:59     ` Marcel Holtmann
2007-12-06 17:59       ` Chris Rivera
2007-12-17  3:08         ` Chris Rivera
2007-12-17  5:47         ` Marcel Holtmann
2007-12-17 15:54           ` Chris Rivera
2007-12-17 18:53             ` Marcel Holtmann
2007-12-17 19:29               ` Chris Rivera
2007-12-17 20:17                 ` Marcel Holtmann
2007-12-17 20:47                   ` Chris Rivera
2007-12-17 21:01                     ` Marcel Holtmann
2007-12-18 18:37                       ` Chris Rivera
2007-12-18 19:10                         ` Marcel Holtmann
2007-12-18 19:51                           ` Chris Rivera
2007-12-18 19:58                             ` Marcel Holtmann
2007-12-18 20:52                               ` Bastien Nocera
2007-12-18 21:00                                 ` Marcel Holtmann

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