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 #include +#include #ifdef HAVE_HAL -#include #include #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 #include +#include #include @@ -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 +#include #include +#include #include @@ -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; }