network-manager-applet r801 - in trunk: . src/connection-editor



Author: dcbw
Date: Sun Jul 27 04:06:16 2008
New Revision: 801
URL: http://svn.gnome.org/viewvc/network-manager-applet?rev=801&view=rev

Log:
2008-07-27  Dan Williams  <dcbw redhat com>

	* src/connection-editor/Makefile.am
	  src/connection-editor/nm-connection-editor-service.xml
		- Add service definition for single-app-instance D-Bus API

	* src/connection-editor/nm-connection-list.c
	  src/connection-editor/nm-connection-list.h
		- (add_connection_tab): keep connection type list around for later
		- (add_connection_tabs): don't free connection type lists since they
			are now kept around by add_connection_tab()
		- (nm_connection_list_set_type): new function; given a connection type
			select that type's tab in the connection list and bring the
			connection list window to the front

	* src/connection-editor/main.c
		- Implement a single-app-instance object that exports a D-Bus API to
			accept the same args that the connection editor does on the command
			line
		- (main, try_existing_instance): if a connection editor is already open
			in the current session, just send the command-line arguments to that
			existing editor over D-Bus instead of spawning a second editor



Added:
   trunk/src/connection-editor/nm-connection-editor-service.xml
Modified:
   trunk/ChangeLog
   trunk/src/connection-editor/Makefile.am
   trunk/src/connection-editor/main.c
   trunk/src/connection-editor/nm-connection-list.c
   trunk/src/connection-editor/nm-connection-list.h

Modified: trunk/src/connection-editor/Makefile.am
==============================================================================
--- trunk/src/connection-editor/Makefile.am	(original)
+++ trunk/src/connection-editor/Makefile.am	Sun Jul 27 04:06:16 2008
@@ -55,6 +55,9 @@
 	polkit-06-helpers.h
 endif
 
+nm-connection-editor-service-glue.h: $(top_srcdir)/src/connection-editor/nm-connection-editor-service.xml
+	dbus-binding-tool --prefix=nm_connection_editor_service --mode=glib-server --output=$@ $<
+
 nm_connection_editor_LDADD = \
 	$(top_builddir)/src/gconf-helpers/libgconf-helpers.la \
 	${top_builddir}/src/wireless-security/libwireless-security.la \
@@ -75,8 +78,9 @@
 	ce-page-ppp.glade \
 	ce-vpn-wizard.glade
 
+BUILT_SOURCES = nm-connection-editor-service-glue.h
+
 CLEANFILES = *.bak *.gladep
 
-EXTRA_DIST = 		\
-	$(glade_DATA)	\
-	$(NULL)
+EXTRA_DIST = $(glade_DATA) nm-connection-editor-service.xml
+

Modified: trunk/src/connection-editor/main.c
==============================================================================
--- trunk/src/connection-editor/main.c	(original)
+++ trunk/src/connection-editor/main.c	Sun Jul 27 04:06:16 2008
@@ -28,15 +28,117 @@
 #include <stdlib.h>
 #include <signal.h>
 
+#include <dbus/dbus.h>
 #include <gtk/gtk.h>
 #include <glib/gi18n-lib.h>
+#include <glib/gtypes.h>
+#include <glib-object.h>
 #include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
 #include <nm-setting-wired.h>
 #include "nm-connection-list.h"
 
 static GMainLoop *loop = NULL;
 
+#define ARG_TYPE "type"
+
+#define DBUS_TYPE_G_MAP_OF_VARIANT          (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
+
+#define NM_CE_DBUS_SERVICE_NAME "org.freedesktop.NetworkManager.Gnome.ConnectionEditor"
+
+#define NM_TYPE_CE_SERVICE            (nm_ce_service_get_type ())
+#define NM_CE_SERVICE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CE_SERVICE, NMCEService))
+#define NM_CE_SERVICE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CE_SERVICE, NMCEServiceClass))
+#define NM_IS_CE_SERVICE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CE_SERVICE))
+#define NM_IS_CE_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_CE_SERVICE))
+#define NM_CE_SERVICE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CE_SERVICE, NMCEServiceClass))
+
+typedef struct {
+	GObject parent;
+	NMConnectionList *list;
+} NMCEService;
+
+typedef struct {
+	GObjectClass parent;
+} NMCEServiceClass;
+
+GType nm_ce_service_get_type (void);
+
+G_DEFINE_TYPE (NMCEService, nm_ce_service, G_TYPE_OBJECT)
+
+static gboolean impl_start (NMCEService *self, GHashTable *args, GError **error);
+
+#include "nm-connection-editor-service-glue.h"
+
+static NMCEService *
+nm_ce_service_new (DBusGConnection *bus, DBusGProxy *proxy, NMConnectionList *list)
+{
+	GObject *object;
+	DBusConnection *connection;
+	GError *err = NULL;
+	guint32 result;
+
+	g_return_val_if_fail (bus != NULL, NULL);
+	g_return_val_if_fail (proxy != NULL, NULL);
+
+	object = g_object_new (NM_TYPE_CE_SERVICE, NULL);
+	if (!object)
+		return NULL;
+
+	NM_CE_SERVICE (object)->list = list;
+
+	dbus_connection_set_change_sigpipe (TRUE);
+	connection = dbus_g_connection_get_connection (bus);
+	dbus_connection_set_exit_on_disconnect (connection, FALSE);
+
+	/* Register our single-instance service.  Don't care if it fails. */
+	if (!dbus_g_proxy_call (proxy, "RequestName", &err,
+					    G_TYPE_STRING, NM_CE_DBUS_SERVICE_NAME,
+					    G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
+					    G_TYPE_INVALID,
+					    G_TYPE_UINT, &result,
+					    G_TYPE_INVALID)) {
+		g_warning ("Could not acquire the connection editor service.\n"
+		            "  Message: '%s'", err->message);
+		g_error_free (err);
+	} else {
+		if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
+			g_warning ("Could not acquire the connection editor service as it is already taken.");
+		else {
+			/* success */
+			dbus_g_connection_register_g_object (bus, "/", object);
+		}
+	}
+
+	return (NMCEService *) object;
+}
+
+static void
+nm_ce_service_init (NMCEService *self)
+{
+}
+
+static void
+nm_ce_service_class_init (NMCEServiceClass *config_class)
+{
+	dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (config_class),
+									 &dbus_glib_nm_connection_editor_service_object_info);
+}
+
+static gboolean
+impl_start (NMCEService *self, GHashTable *table, GError **error)
+{
+	GValue *value;
+
+	value = g_hash_table_lookup (table, ARG_TYPE);
+	if (value && G_VALUE_HOLDS_STRING (value))
+		nm_connection_list_set_type (self->list, g_value_get_string (value));
+
+	return TRUE;
+}
+
+
 static void
 signal_handler (int signo)
 {
@@ -60,10 +162,46 @@
 	sigaction (SIGINT,  &action, NULL);
 }
 
-static void
-list_done_cb (NMConnectionList *list, gint response, gpointer user_data)
+static gboolean
+try_existing_instance (DBusGConnection *bus, DBusGProxy *proxy, const char *type)
 {
-	g_main_loop_quit (loop);
+	gboolean has_owner = FALSE;
+	DBusGProxy *instance;
+	GHashTable *args;
+	GValue type_value = { 0, };
+	gboolean success = FALSE;
+
+	if (!dbus_g_proxy_call (proxy, "NameHasOwner", NULL,
+	                        G_TYPE_STRING, NM_CE_DBUS_SERVICE_NAME, G_TYPE_INVALID,
+	                        G_TYPE_BOOLEAN, &has_owner, G_TYPE_INVALID))
+		return FALSE;
+
+	if (!has_owner)
+		return FALSE;
+
+	/* Send arguments to existing process */
+	instance = dbus_g_proxy_new_for_name (bus,
+	                                      NM_CE_DBUS_SERVICE_NAME,
+	                                      "/",
+	                                      NM_CE_DBUS_SERVICE_NAME);
+	if (!instance)
+		return FALSE;
+
+	args = g_hash_table_new (g_str_hash, g_str_equal);
+	if (type) {
+		g_value_init (&type_value, G_TYPE_STRING);
+		g_value_set_static_string (&type_value, type);
+		g_hash_table_insert (args, "type", &type_value);
+	}
+
+	if (dbus_g_proxy_call (instance, "Start", NULL,
+	                       DBUS_TYPE_G_MAP_OF_VARIANT, args, G_TYPE_INVALID,
+	                       G_TYPE_INVALID))
+		success = TRUE;
+
+	g_hash_table_destroy (args);
+	g_object_unref (instance);
+	return success;
 }
 
 int
@@ -72,11 +210,13 @@
 	GOptionContext *opt_ctx;
 	GError *error = NULL;
 	NMConnectionList *list;
-	DBusGConnection *ignore;
+	DBusGConnection *bus;
 	char *type = NULL;
+	NMCEService *service = NULL;
+	DBusGProxy *proxy = NULL;
 
 	GOptionEntry entries[] = {
-		{ "type", 0, 0, G_OPTION_ARG_STRING, &type, "Type of connection to show at launch", NM_SETTING_WIRED_SETTING_NAME },
+		{ ARG_TYPE, 0, 0, G_OPTION_ARG_STRING, &type, "Type of connection to show at launch", NM_SETTING_WIRED_SETTING_NAME },
 		{ NULL }
 	};
 
@@ -100,9 +240,18 @@
 
 	g_option_context_free (opt_ctx);
 
-	/* Hack to init the dbus-glib type system */
-	ignore = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
-	dbus_g_connection_unref (ignore);
+	/* Inits the dbus-glib type system too */
+	bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+	proxy = dbus_g_proxy_new_for_name (bus,
+									 "org.freedesktop.DBus",
+									 "/org/freedesktop/DBus",
+									 "org.freedesktop.DBus");
+
+	/* Check for an existing instance on the bus */
+	if (proxy) {
+		if (try_existing_instance (bus, proxy, type))
+			goto exit;
+	}
 
 	loop = g_main_loop_new (NULL, FALSE);
 
@@ -112,13 +261,24 @@
 		return 1;
 	}
 
-	g_signal_connect (G_OBJECT (list), "done", G_CALLBACK (list_done_cb), NULL);
+	/* Create our single-instance-app service if we can */
+	if (proxy)
+		service = nm_ce_service_new (bus, proxy, list);
+
+	g_signal_connect_swapped (G_OBJECT (list), "done", G_CALLBACK (g_main_loop_quit), loop);
 	nm_connection_list_run (list);
 
 	setup_signals ();
 	g_main_loop_run (loop);
 
 	g_object_unref (list);
+	if (service)
+		g_object_unref (service);
 
+exit:
+	if (proxy)
+		g_object_unref (proxy);
+	dbus_g_connection_unref (bus);
 	return 0;
 }
+

Added: trunk/src/connection-editor/nm-connection-editor-service.xml
==============================================================================
--- (empty file)
+++ trunk/src/connection-editor/nm-connection-editor-service.xml	Sun Jul 27 04:06:16 2008
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+  <interface name="org.freedesktop.NetworkManager.Gnome.ConnectionEditor">
+    <method name="Start">
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_start"/>
+      <arg name="args" type="a{sv}" direction="in"/>
+    </method>
+  </interface>
+</node>

Modified: trunk/src/connection-editor/nm-connection-list.c
==============================================================================
--- trunk/src/connection-editor/nm-connection-list.c	(original)
+++ trunk/src/connection-editor/nm-connection-list.c	Sun Jul 27 04:06:16 2008
@@ -1413,6 +1413,9 @@
 	treeview = add_connection_treeview (self, prefix);
 	add_connection_buttons (self, prefix, treeview, is_vpn);
 
+	g_object_set_data_full (G_OBJECT (child), "types",
+	                        connection_types, (GDestroyNotify) g_slist_free);
+
 	for (iter = connection_types; iter; iter = iter->next) {
 		g_hash_table_insert (self->treeviews, g_strdup ((const char *) iter->data), treeview);
 		if (def_type && !strcmp ((const char *) iter->data, def_type)) {
@@ -1431,24 +1434,19 @@
 
 	types = g_slist_append (NULL, NM_SETTING_WIRED_SETTING_NAME);
 	add_connection_tab (self, def_type, types, self->wired_icon, "wired", _("Wired"), FALSE);
-	g_slist_free (types);
 
 	types = g_slist_append (NULL, NM_SETTING_WIRELESS_SETTING_NAME);
 	add_connection_tab (self, def_type, types, self->wireless_icon, "wireless", _("Wireless"), FALSE);
-	g_slist_free (types);
 
 	types = g_slist_append (NULL, NM_SETTING_GSM_SETTING_NAME);
 	types = g_slist_append (types, NM_SETTING_CDMA_SETTING_NAME);
 	add_connection_tab (self, def_type, types, self->wwan_icon, "wwan", _("Mobile Broadband"), FALSE);
-	g_slist_free (types);
 
 	types = g_slist_append (NULL, NM_SETTING_VPN_SETTING_NAME);
 	add_connection_tab (self, def_type, types, self->vpn_icon, "vpn", _("VPN"), TRUE);
-	g_slist_free (types);
 
 	types = g_slist_append (NULL, NM_SETTING_PPPOE_SETTING_NAME);
 	add_connection_tab (self, def_type, types, self->wired_icon, "dsl", _("DSL"), FALSE);
-	g_slist_free (types);
 }
 
 static void
@@ -1596,6 +1594,39 @@
 	gtk_window_present (GTK_WINDOW (list->dialog));
 }
 
+void
+nm_connection_list_set_type (NMConnectionList *self, const char *type)
+{
+	GtkWidget *notebook;
+	int i, num;
+	gboolean found = FALSE;
+
+	g_return_if_fail (NM_IS_CONNECTION_LIST (self));
+
+	/* If a notebook page is found that owns the requested type, set it
+	 * as the current page.
+	 */
+	notebook = glade_xml_get_widget (self->gui, "list_notebook");
+	num = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook));
+	for (i = 0; i < num && !found; i++) {
+		GtkWidget *child;
+		GSList *types, *iter;
+
+		child = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), i);
+		types = g_object_get_data (G_OBJECT (child), "types");
+		for (iter = types; iter; iter = g_slist_next (iter)) {
+			if (!strcmp (type, (const char *) iter->data)) {
+				gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), i);
+				found = TRUE;
+				break;
+			}
+		}
+	}
+
+	/* Bring the connection list to the front */
+	nm_connection_list_present (self);
+}
+
 static void
 list_response_cb (GtkDialog *dialog, gint response, gpointer user_data)
 {
@@ -1620,3 +1651,4 @@
 
 	nm_connection_list_present (list);
 }
+

Modified: trunk/src/connection-editor/nm-connection-list.h
==============================================================================
--- trunk/src/connection-editor/nm-connection-list.h	(original)
+++ trunk/src/connection-editor/nm-connection-list.h	Sun Jul 27 04:06:16 2008
@@ -70,4 +70,6 @@
 
 void              nm_connection_list_run (NMConnectionList *list);
 
+void              nm_connection_list_set_type (NMConnectionList *list, const char *type);
+
 #endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]