diff -urN gnome/applet/bluetooth-applet.1 gnome-new/applet/bluetooth-applet.1 --- gnome/applet/bluetooth-applet.1 2007-07-22 11:33:13.000000000 -0400 +++ gnome-new/applet/bluetooth-applet.1 2007-12-06 11:28:00.000000000 -0500 @@ -10,8 +10,9 @@ .I bluetooth-applet is part of bluez-gnome, see also http://www.bluez.org .SH OPTIONS -.I bluetooth-applet -takes no options +.TP +.BI \-\-singleton +Ensure that only one instance is running. .SH AUTHOR Marcel Holtmann .SH LICENSE diff -urN gnome/applet/bluetooth-applet.desktop.in gnome-new/applet/bluetooth-applet.desktop.in --- gnome/applet/bluetooth-applet.desktop.in 2007-04-03 04:09:01.000000000 -0400 +++ gnome-new/applet/bluetooth-applet.desktop.in 2007-12-06 11:16:03.000000000 -0500 @@ -3,7 +3,7 @@ _Name=Bluetooth Manager _Comment=Bluetooth Manager applet Icon=stock_bluetooth -Exec=bluetooth-applet +Exec=bluetooth-applet --singleton Terminal=false Type=Application Categories= diff -urN gnome/applet/main.c gnome-new/applet/main.c --- gnome/applet/main.c 2007-12-04 10:30:51.000000000 -0500 +++ gnome-new/applet/main.c 2007-12-06 11:16:03.000000000 -0500 @@ -49,6 +49,7 @@ #endif #include "bluetooth-device-selection.h" +#include "bluetooth-application-instance.h" #define PASSKEY_AGENT_PATH "/org/bluez/passkey" #define AUTH_AGENT_PATH "/org/bluez/auth" @@ -1550,7 +1551,7 @@ 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); @@ -1639,7 +1640,7 @@ #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); @@ -1782,9 +1783,19 @@ int main(int argc, char *argv[]) { + GOptionContext *ctx; GtkWidget *menu; GError *error = NULL; + BluetoothApplicationInstance *app; 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"); @@ -1792,6 +1803,15 @@ 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 @@ -1804,6 +1824,11 @@ exit(EXIT_FAILURE); } + app = bluetooth_application_instance_new(); + if(!bluetooth_application_instance_register(app, &retval, singleton, + "/org/bluez/Applet", "org.bluez.Applet")) + exit(retval); + gconf = gconf_client_get_default(); #ifdef HAVE_HAL @@ -1860,6 +1885,10 @@ g_list_foreach(adapter_list, adapter_free, NULL); dbus_g_connection_unref(conn); + + g_object_unref(app); + g_option_context_free(ctx); + return 0; } diff -urN gnome/common/bluetooth-application-instance.c gnome-new/common/bluetooth-application-instance.c --- gnome/common/bluetooth-application-instance.c 1969-12-31 19:00:00.000000000 -0500 +++ gnome-new/common/bluetooth-application-instance.c 2007-12-06 11:16:19.000000000 -0500 @@ -0,0 +1,132 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005-2007 Marcel Holtmann + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +#include "bluetooth-application-instance.h" +#include "app-instance-glue.h" + +G_DEFINE_TYPE(BluetoothApplicationInstance, bluetooth_application_instance, G_TYPE_OBJECT) + +#define BLUETOOTH_APPLICATION_INSTANCE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + BLUETOOTH_TYPE_APPLICATION_INSTANCE, BluetoothApplicationInstancePrivate)) + +typedef struct _BluetoothApplicationInstancePrivate BluetoothApplicationInstancePrivate; + +struct _BluetoothApplicationInstancePrivate { + GtkWindow *window; + DBusGConnection *connection; +}; + +gboolean +bluetooth_application_instance_register(BluetoothApplicationInstance *self, + int *retval, gboolean singleton, gchar *path, gchar *service) +{ + BluetoothApplicationInstancePrivate *priv = BLUETOOTH_APPLICATION_INSTANCE_GET_PRIVATE(self); + 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 FALSE; + } + + 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, 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 FALSE; + } + + if (request_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER && singleton) { + proxy = dbus_g_proxy_new_for_name(sc, service, path, "org.bluez.ApplicationInstance"); + dbus_g_proxy_call_no_reply(proxy, "Present", G_TYPE_INVALID, G_TYPE_INVALID); + g_object_unref(G_OBJECT(proxy)); + g_print("Another instance is already running.\n"); + dbus_g_connection_unref(sc); + *retval = 0; + return FALSE; + } + + dbus_g_connection_register_g_object(sc, path, G_OBJECT (self)); + priv->connection = sc; + return TRUE; +} + +void +bluetooth_application_instance_set_window (BluetoothApplicationInstance *self, GtkWindow *window) +{ + BluetoothApplicationInstancePrivate *priv = BLUETOOTH_APPLICATION_INSTANCE_GET_PRIVATE(self); + priv->window = window; +} + +gboolean +bluetooth_application_instance_present(BluetoothApplicationInstance *self, GError **error) +{ + BluetoothApplicationInstancePrivate *priv = BLUETOOTH_APPLICATION_INSTANCE_GET_PRIVATE(self); + if (priv->window) + gtk_window_present(priv->window); + return TRUE; +} + +static void +bluetooth_application_instance_init(BluetoothApplicationInstance *self) +{ +} + +static void +bluetooth_application_instance_finalize(GObject *self) +{ + BluetoothApplicationInstancePrivate *priv = BLUETOOTH_APPLICATION_INSTANCE_GET_PRIVATE(self); + if (priv->connection) + dbus_g_connection_unref(priv->connection); +} + +static void +bluetooth_application_instance_class_init(BluetoothApplicationInstanceClass *klass) +{ + g_type_class_add_private(klass, sizeof(BluetoothApplicationInstancePrivate)); + G_OBJECT_CLASS(klass)->finalize = bluetooth_application_instance_finalize; + dbus_g_object_type_install_info(BLUETOOTH_TYPE_APPLICATION_INSTANCE, + &dbus_glib_bluetooth_application_instance_object_info); +} + +BluetoothApplicationInstance * +bluetooth_application_instance_new(void) +{ + return g_object_new(BLUETOOTH_TYPE_APPLICATION_INSTANCE, NULL); +} diff -urN gnome/common/bluetooth-application-instance.h gnome-new/common/bluetooth-application-instance.h --- gnome/common/bluetooth-application-instance.h 1969-12-31 19:00:00.000000000 -0500 +++ gnome-new/common/bluetooth-application-instance.h 2007-12-06 11:16:19.000000000 -0500 @@ -0,0 +1,63 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005-2007 Marcel Holtmann + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __BLUETOOTH_APPLICATION_INSTANCE_H +#define __BLUETOOTH_APPLICATION_INSTANCE_H + +#include + +G_BEGIN_DECLS + +#define BLUETOOTH_TYPE_APPLICATION_INSTANCE (bluetooth_application_instance_get_type()) +#define BLUETOOTH_APPLICATION_INSTANCE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + BLUETOOTH_TYPE_APPLICATION_INSTANCE, BluetoothApplicationInstance)) +#define BLUETOOTH_APPLICATION_INSTANCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \ + BLUETOOTH_TYPE_APPLICATION_INSTANCE, BluetoothApplicationInstanceClass)) +#define BLUETOOTH_IS_APPLICATION_INSTANCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \ + BLUETOOTH_TYPE_APPLICATION_INSTANCE)) +#define BLUETOOTH_IS_APPLICATION_INSTANCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \ + BLUETOOTH_TYPE_APPLICATION_INSTANCE)) +#define BLUETOOTH_GET_APPLICATION_INSTANCE_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \ + BLUETOOTH_TYPE_APPLICATION_INSTANCE, BluetoothApplicationInstanceClass)) + +typedef struct _BluetoothApplicationInstance BluetoothApplicationInstance; +typedef struct _BluetoothApplicationInstanceClass BluetoothApplicationInstanceClass; + +struct _BluetoothApplicationInstance { + GObject parent; +}; + +struct _BluetoothApplicationInstanceClass { + GObjectClass parent_class; +}; + +GType bluetooth_application_instance_get_type(void); +BluetoothApplicationInstance *bluetooth_application_instance_new(void); +void bluetooth_application_instance_set_window(BluetoothApplicationInstance *self, GtkWindow *window); +gboolean bluetooth_application_instance_present(BluetoothApplicationInstance *self, GError **error); +gboolean bluetooth_application_instance_register(BluetoothApplicationInstance *self, + int *retval, gboolean singleton, gchar *path, gchar *service); + +G_END_DECLS + +#endif /* __BLUETOOTH_APPLICATION_INSTANCE_H */ diff -urN gnome/common/bluetooth-application-instance.xml gnome-new/common/bluetooth-application-instance.xml --- gnome/common/bluetooth-application-instance.xml 1969-12-31 19:00:00.000000000 -0500 +++ gnome-new/common/bluetooth-application-instance.xml 2007-12-06 11:16:19.000000000 -0500 @@ -0,0 +1,8 @@ + + + + + + + + diff -urN gnome/common/Makefile.am gnome-new/common/Makefile.am --- gnome/common/Makefile.am 2007-07-25 06:28:56.000000000 -0400 +++ gnome-new/common/Makefile.am 2007-12-06 11:16:03.000000000 -0500 @@ -3,12 +3,13 @@ libcommon_a_SOURCES = \ client.h client.c device-store.h device-store.c \ + bluetooth-application-instance.c bluetooth-application-instance.h \ bluetooth-device-selection.c bluetooth-device-selection.h AM_CFLAGS = @DBUS_CFLAGS@ @GTK_CFLAGS@ BUILT_SOURCES = marshal.h marshal.c dbus-glue.h \ - passkey-agent-glue.h auth-agent-glue.h + passkey-agent-glue.h auth-agent-glue.h app-instance-glue.h nodist_libcommon_a_SOURCES = $(BUILT_SOURCES) @@ -22,7 +23,8 @@ test_deviceselection_LDADD = libcommon.a @GTK_LIBS@ @DBUS_LIBS@ -EXTRA_DIST = marshal.list dbus.xml passkey-agent.xml auth-agent.xml +EXTRA_DIST = marshal.list dbus.xml passkey-agent.xml auth-agent.xml \ + bluetooth-application-instance.xml MAINTAINERCLEANFILES = Makefile.in @@ -40,3 +42,6 @@ auth-agent-glue.h: auth-agent.xml $(DBUS_BINDING_TOOL) --prefix=auth_agent --mode=glib-server --output=$@ $< + +app-instance-glue.h: bluetooth-application-instance.xml + $(DBUS_BINDING_TOOL) --prefix=bluetooth_application_instance --mode=glib-server --output=$@ $< diff -urN gnome/properties/bluetooth-properties.1 gnome-new/properties/bluetooth-properties.1 --- gnome/properties/bluetooth-properties.1 2007-07-22 11:33:13.000000000 -0400 +++ gnome-new/properties/bluetooth-properties.1 2007-12-06 11:31:18.000000000 -0500 @@ -9,8 +9,9 @@ .I bluetooth-properties is part of bluez-gnome, see also http://www.bluez.org .SH OPTIONS -.I bluetooth-properties -takes no options +.TP +.BI \-\-singleton +Ensure that only one instance is running. .SH AUTHOR Marcel Holtmann .SH LICENSE diff -urN gnome/properties/main.c gnome-new/properties/main.c --- gnome/properties/main.c 2007-07-31 17:37:29.000000000 -0400 +++ gnome-new/properties/main.c 2007-12-06 11:16:03.000000000 -0500 @@ -40,6 +40,7 @@ #include "general.h" #include "service.h" #include "adapter.h" +#include "bluetooth-application-instance.h" static void delete_callback(GtkWidget *window, GdkEvent *event, gpointer user_data) @@ -58,7 +59,7 @@ gtk_main_quit(); } -static void create_window(GtkWidget *notebook) +static GtkWidget *create_window(GtkWidget *notebook) { GtkWidget *window; GtkWidget *widget; @@ -108,6 +109,7 @@ widget, _("General")); gtk_widget_show_all(window); + return window; } static void name_owner_changed(DBusGProxy *object, const char *name, @@ -141,17 +143,37 @@ int main(int argc, char *argv[]) { + GOptionContext *ctx; GtkWidget *notebook; + GtkWidget *window; + GError *error = NULL; DBusGConnection *conn; + BluetoothApplicationInstance *app; DBusGProxy *manager; - GError *error = NULL; + 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", @@ -163,12 +185,18 @@ setup_general(); notebook = gtk_notebook_new(); - + assign_adapter(notebook); - manager = setup_manager(conn); + window = create_window(notebook); - create_window(notebook); + app = bluetooth_application_instance_new(); + bluetooth_application_instance_set_window(app, GTK_WINDOW(window)); + if(!bluetooth_application_instance_register(app, &retval, singleton, + "/org/bluez/Properties", "org.bluez.Properties")) + exit(retval); + + manager = setup_manager(conn); gtk_main(); @@ -181,6 +209,10 @@ g_object_unref(manager); dbus_g_connection_unref(conn); + + g_object_unref(app); + g_option_context_free(ctx); + return 0; } diff -urN gnome/wizard/bluetooth-wizard.1 gnome-new/wizard/bluetooth-wizard.1 --- gnome/wizard/bluetooth-wizard.1 2007-07-22 11:33:12.000000000 -0400 +++ gnome-new/wizard/bluetooth-wizard.1 2007-12-06 11:31:41.000000000 -0500 @@ -9,8 +9,9 @@ .I bluetooth-wizard is part of bluez-gnome, see also http://www.bluez.org .SH OPTIONS -.I bluetooth-wizard -takes no options +.TP +.BI \-\-singleton +Ensure that only one instance is running. .SH AUTHOR Marcel Holtmann .SH LICENSE diff -urN gnome/wizard/main.c gnome-new/wizard/main.c --- gnome/wizard/main.c 2007-08-15 03:04:03.000000000 -0400 +++ gnome-new/wizard/main.c 2007-12-06 11:16:03.000000000 -0500 @@ -26,6 +26,7 @@ #endif #include +#include #include @@ -38,6 +39,7 @@ #include "dbus-glue.h" #include "bluetooth-device-selection.h" +#include "bluetooth-application-instance.h" static BluetoothClient *client; @@ -387,7 +389,7 @@ page_summary = vbox; } -static void create_wizard(void) +static GtkWidget *create_wizard(void) { GtkWidget *assistant; @@ -430,23 +432,56 @@ gtk_widget_show_all(assistant); gtk_assistant_update_buttons_state(GTK_ASSISTANT(assistant)); + return assistant; } int main(int argc, char *argv[]) { + GOptionContext *ctx; + GtkWidget *window; + BluetoothApplicationInstance *app; + GError *error = NULL; + 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; + } + client = bluetooth_client_new(); - create_wizard(); + window = create_wizard(); + + app = bluetooth_application_instance_new(); + bluetooth_application_instance_set_window(app, GTK_WINDOW(window)); + if(!bluetooth_application_instance_register(app, &retval, singleton, + "/org/bluez/Wizard", "org.bluez.Wizard")) + exit(retval); gtk_main(); g_object_unref(client); + g_object_unref(app); + + g_option_context_free(ctx); + return 0; }