[network-manager-applet] bluetooth: show Bluetooth devices in the menu



commit ddf47d957a43c2d86531a3cd8d666cdbcadf58ee
Author: Dan Williams <dcbw redhat com>
Date:   Fri Jul 10 10:46:34 2009 -0400

    bluetooth: show Bluetooth devices in the menu

 src/Makefile.am        |    4 +-
 src/applet-device-bt.c |  255 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/applet-device-bt.h |   31 ++++++
 src/applet.c           |   16 +++
 src/applet.h           |    1 +
 src/utils/utils.c      |   64 ++++++++++++
 6 files changed, 370 insertions(+), 1 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 69e32d2..14ad753 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -44,7 +44,9 @@ nm_applet_SOURCES =			\
 	applet-device-gsm.h \
 	applet-device-gsm.c \
 	applet-device-cdma.h \
-	applet-device-cdma.c
+	applet-device-cdma.c \
+	applet-device-bt.h \
+	applet-device-bt.c
 
 nm_applet_LDADD = \
 	$(NMA_LIBS) \
diff --git a/src/applet-device-bt.c b/src/applet-device-bt.c
new file mode 100644
index 0000000..b614052
--- /dev/null
+++ b/src/applet-device-bt.c
@@ -0,0 +1,255 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
+ *
+ * Dan Williams <dcbw redhat com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Red Hat, Inc.
+ * (C) Copyright 2008 Novell, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include <nm-device.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-bluetooth.h>
+#include <nm-device-bt.h>
+#include <nm-utils.h>
+
+#include "applet.h"
+#include "applet-device-bt.h"
+#include "wired-dialog.h"
+#include "utils.h"
+#include "gconf-helpers.h"
+
+typedef struct {
+	NMApplet *applet;
+	NMDevice *device;
+	NMConnection *connection;
+} BtMenuItemInfo;
+
+static void
+bt_menu_item_info_destroy (gpointer data)
+{
+	BtMenuItemInfo *info = data;
+
+	g_object_unref (G_OBJECT (info->device));
+	if (info->connection)
+		g_object_unref (G_OBJECT (info->connection));
+
+	g_slice_free (BtMenuItemInfo, data);
+}
+
+static gboolean
+bt_new_auto_connection (NMDevice *device,
+                        gpointer dclass_data,
+                        AppletNewAutoConnectionCallback callback,
+                        gpointer callback_data)
+{
+
+	// FIXME: call gnome-bluetooth setup wizard
+	return FALSE;
+}
+
+static void
+bt_menu_item_activate (GtkMenuItem *item, gpointer user_data)
+{
+	BtMenuItemInfo *info = user_data;
+
+	applet_menu_item_activate_helper (info->device,
+	                                  info->connection,
+	                                  "/",
+	                                  info->applet,
+	                                  user_data);
+}
+
+static void
+add_connection_items (NMDevice *device,
+                      GSList *connections,
+                      gboolean carrier,
+                      NMConnection *active,
+                      GtkWidget *menu,
+                      NMApplet *applet)
+{
+	GSList *iter;
+	BtMenuItemInfo *info;
+
+	for (iter = connections; iter; iter = g_slist_next (iter)) {
+		NMConnection *connection = NM_CONNECTION (iter->data);
+		NMSettingConnection *s_con;
+		GtkWidget *item;
+
+		s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+		item = gtk_check_menu_item_new_with_label (nm_setting_connection_get_id (s_con));
+ 		gtk_widget_set_sensitive (GTK_WIDGET (item), carrier);
+		gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (item), TRUE);
+
+		if (connection == active)
+			gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
+
+		info = g_slice_new0 (BtMenuItemInfo);
+		info->applet = applet;
+		info->device = g_object_ref (G_OBJECT (device));
+		info->connection = g_object_ref (connection);
+
+		g_signal_connect_data (item, "activate",
+		                       G_CALLBACK (bt_menu_item_activate),
+		                       info,
+		                       (GClosureNotify) bt_menu_item_info_destroy, 0);
+
+		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+	}
+}
+
+static void
+bt_add_menu_item (NMDevice *device,
+                  guint32 n_devices,
+                  NMConnection *active,
+                  GtkWidget *menu,
+                  NMApplet *applet)
+{
+	const char *text;
+	GtkWidget *item;
+	GSList *connections, *all;
+	gboolean carrier = TRUE;
+	char *bold_text;
+
+	all = applet_get_all_connections (applet);
+	connections = utils_filter_connections_for_device (device, all);
+	g_slist_free (all);
+
+	text = nm_device_bt_get_name (NM_DEVICE_BT (device));
+	if (!text) {
+		text = utils_get_device_description (device);
+		if (!text)
+			text = nm_device_get_iface (device);
+		g_assert (text);
+	}
+
+	item = gtk_menu_item_new_with_label ("");
+	bold_text = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>", text);
+	gtk_label_set_markup (GTK_LABEL (gtk_bin_get_child (GTK_BIN (item))), bold_text);
+	g_free (bold_text);
+
+	gtk_widget_set_sensitive (item, FALSE);
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+	gtk_widget_show (item);
+
+	/* Notify user of unmanaged or unavailable device */
+	item = nma_menu_device_check_unusable (device, NULL);
+	if (item) {
+		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+		gtk_widget_show (item);
+	} else {
+		if (g_slist_length (connections))
+			add_connection_items (device, connections, carrier, active, menu, applet);
+	}
+
+	g_slist_free (connections);
+}
+
+static void
+bt_device_state_changed (NMDevice *device,
+                         NMDeviceState new_state,
+                         NMDeviceState old_state,
+                         NMDeviceStateReason reason,
+                         NMApplet *applet)
+{
+	if (new_state == NM_DEVICE_STATE_ACTIVATED) {
+		NMConnection *connection;
+		NMSettingConnection *s_con = NULL;
+		char *str = NULL;
+
+		connection = applet_find_active_connection_for_device (device, applet, NULL);
+		if (connection) {
+			const char *id;
+			s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+			id = s_con ? nm_setting_connection_get_id (s_con) : NULL;
+			if (id)
+				str = g_strdup_printf (_("You are now connected to '%s'."), id);
+		}
+
+		applet_do_notify_with_pref (applet,
+		                            _("Connection Established"),
+		                            str ? str : _("You are now connected to the mobile broadband network."),
+		                            "nm-device-wwan",
+		                            PREF_DISABLE_CONNECTED_NOTIFICATIONS);
+		g_free (str);
+	}
+}
+
+static GdkPixbuf *
+bt_get_icon (NMDevice *device,
+             NMDeviceState state,
+             NMConnection *connection,
+             char **tip,
+             NMApplet *applet)
+{
+	NMSettingConnection *s_con;
+	GdkPixbuf *pixbuf = NULL;
+	const char *id;
+
+	id = nm_device_get_iface (NM_DEVICE (device));
+	if (connection) {
+		s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+		id = nm_setting_connection_get_id (s_con);
+	}
+
+	switch (state) {
+	case NM_DEVICE_STATE_PREPARE:
+		*tip = g_strdup_printf (_("Preparing mobile broadband connection '%s'..."), id);
+		break;
+	case NM_DEVICE_STATE_CONFIG:
+		*tip = g_strdup_printf (_("Configuring mobile broadband connection '%s'..."), id);
+		break;
+	case NM_DEVICE_STATE_NEED_AUTH:
+		*tip = g_strdup_printf (_("User authentication required for mobile broadband connection '%s'..."), id);
+		break;
+	case NM_DEVICE_STATE_IP_CONFIG:
+		*tip = g_strdup_printf (_("Requesting a network address for '%s'..."), id);
+		break;
+	case NM_DEVICE_STATE_ACTIVATED:
+		pixbuf = applet->wwan_icon;
+		*tip = g_strdup_printf (_("Mobile broadband connection '%s' active"), id);
+		break;
+	default:
+		break;
+	}
+
+	return pixbuf;
+}
+
+NMADeviceClass *
+applet_device_bt_get_class (NMApplet *applet)
+{
+	NMADeviceClass *dclass;
+
+	dclass = g_slice_new0 (NMADeviceClass);
+	if (!dclass)
+		return NULL;
+
+	dclass->new_auto_connection = bt_new_auto_connection;
+	dclass->add_menu_item = bt_add_menu_item;
+	dclass->device_state_changed = bt_device_state_changed;
+	dclass->get_icon = bt_get_icon;
+
+	return dclass;
+}
diff --git a/src/applet-device-bt.h b/src/applet-device-bt.h
new file mode 100644
index 0000000..7760a5d
--- /dev/null
+++ b/src/applet-device-bt.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
+ *
+ * Dan Williams <dcbw redhat com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Red Hat, Inc.
+ * (C) Copyright 2008 Novell, Inc.
+ */
+
+#ifndef __APPLET_DEVICE_BT_H__
+#define __APPLET_DEVICE_BT_H__
+
+#include "applet.h"
+
+NMADeviceClass *applet_device_bt_get_class (NMApplet *applet);
+
+#endif /* __APPLET_DEVICE_BT_H__ */
diff --git a/src/applet.c b/src/applet.c
index 9fcb012..d35abcb 100644
--- a/src/applet.c
+++ b/src/applet.c
@@ -45,6 +45,7 @@
 #include <nm-device-wifi.h>
 #include <nm-gsm-device.h>
 #include <nm-cdma-device.h>
+#include <nm-device-bt.h>
 #include <nm-utils.h>
 #include <nm-connection.h>
 #include <nm-vpn-connection.h>
@@ -64,6 +65,7 @@
 #include "applet-device-wifi.h"
 #include "applet-device-gsm.h"
 #include "applet-device-cdma.h"
+#include "applet-device-bt.h"
 #include "applet-dialogs.h"
 #include "vpn-password-dialog.h"
 #include "applet-dbus-manager.h"
@@ -276,6 +278,8 @@ get_device_class (NMDevice *device, NMApplet *applet)
 		return applet->gsm_class;
 	else if (NM_IS_CDMA_DEVICE (device))
 		return applet->cdma_class;
+	else if (NM_IS_DEVICE_BT (device))
+		return applet->bt_class;
 	else
 		g_message ("%s: Unknown device type '%s'", __func__, G_OBJECT_TYPE_NAME (device));
 	return NULL;
@@ -977,14 +981,23 @@ sort_devices (gconstpointer a, gconstpointer b)
 		return -1;
 	if (aa_type == NM_TYPE_DEVICE_ETHERNET && bb_type == NM_TYPE_CDMA_DEVICE)
 		return -1;
+	if (aa_type == NM_TYPE_DEVICE_ETHERNET && bb_type == NM_TYPE_DEVICE_BT)
+		return -1;
 
 	if (aa_type == NM_TYPE_GSM_DEVICE && bb_type == NM_TYPE_CDMA_DEVICE)
 		return -1;
 	if (aa_type == NM_TYPE_GSM_DEVICE && bb_type == NM_TYPE_DEVICE_WIFI)
 		return -1;
+	if (aa_type == NM_TYPE_GSM_DEVICE && bb_type == NM_TYPE_DEVICE_BT)
+		return -1;
 
 	if (aa_type == NM_TYPE_CDMA_DEVICE && bb_type == NM_TYPE_DEVICE_WIFI)
 		return -1;
+	if (aa_type == NM_TYPE_CDMA_DEVICE && bb_type == NM_TYPE_DEVICE_BT)
+		return -1;
+
+	if (aa_type == NM_TYPE_DEVICE_BT && bb_type == NM_TYPE_DEVICE_WIFI)
+		return -1;
 
 	return 1;
 }
@@ -2626,6 +2639,9 @@ constructor (GType type,
 	applet->cdma_class = applet_device_cdma_get_class (applet);
 	g_assert (applet->cdma_class);
 
+	applet->bt_class = applet_device_bt_get_class (applet);
+	g_assert (applet->bt_class);
+
 	foo_client_setup (applet);
 
 	/* timeout to update connection timestamps every 5 minutes */
diff --git a/src/applet.h b/src/applet.h
index acacc2e..db0102c 100644
--- a/src/applet.h
+++ b/src/applet.h
@@ -96,6 +96,7 @@ typedef struct
 	NMADeviceClass *wifi_class;
 	NMADeviceClass *gsm_class;
 	NMADeviceClass *cdma_class;
+	NMADeviceClass *bt_class;
 
 	/* Data model elements */
 	guint			update_icon_id;
diff --git a/src/utils/utils.c b/src/utils/utils.c
index 4faa161..0e2234b 100644
--- a/src/utils/utils.c
+++ b/src/utils/utils.c
@@ -26,6 +26,7 @@
 
 #include <nm-device-ethernet.h>
 #include <nm-device-wifi.h>
+#include <nm-device-bt.h>
 #include <nm-gsm-device.h>
 #include <nm-cdma-device.h>
 #include <nm-access-point.h>
@@ -39,6 +40,7 @@
 #include <nm-setting-gsm.h>
 #include <nm-setting-cdma.h>
 #include <nm-setting-pppoe.h>
+#include <nm-setting-bluetooth.h>
 #include <nm-utils.h>
 
 #include "utils.h"
@@ -743,6 +745,66 @@ connection_valid_for_cdma (NMConnection *connection,
 	return TRUE;
 }
 
+static guint32
+get_connection_bt_type (NMConnection *connection)
+{
+	NMSettingBluetooth *s_bt;
+	const char *bt_type;
+
+	s_bt = (NMSettingBluetooth *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH);
+	if (!s_bt)
+		return NM_BT_CAPABILITY_NONE;
+
+	bt_type = nm_setting_bluetooth_get_connection_type (s_bt);
+	g_assert (bt_type);
+
+	if (!strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN))
+		return NM_BT_CAPABILITY_DUN;
+	else if (!strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU))
+		return NM_BT_CAPABILITY_NAP;
+
+	return NM_BT_CAPABILITY_NONE;
+}
+
+static gboolean
+connection_valid_for_bt (NMConnection *connection,
+                         NMSettingConnection *s_con,
+                         NMDevice *device,
+                         gpointer specific_object)
+{
+	NMSettingBluetooth *s_bt;
+	const GByteArray *array;
+	char *str;
+	const char *hw_addr;
+	int addr_match = FALSE;
+	guint32 bt_type;
+
+	if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_BLUETOOTH_SETTING_NAME))
+		return FALSE;
+
+	s_bt = NM_SETTING_BLUETOOTH (nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH));
+	if (!s_bt)
+		return FALSE;
+
+	array = nm_setting_bluetooth_get_bdaddr (s_bt);
+	if (!array || (array->len != ETH_ALEN))
+		return FALSE;
+
+	bt_type = get_connection_bt_type (connection);
+	if (!(bt_type & nm_device_bt_get_capabilities (NM_DEVICE_BT (device))))
+		return FALSE;
+
+	str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+	                       array->data[0], array->data[1], array->data[2],
+	                       array->data[3], array->data[4], array->data[5]);
+	hw_addr = nm_device_bt_get_hw_address (NM_DEVICE_BT (device));
+	if (hw_addr)
+		addr_match = !g_ascii_strcasecmp (hw_addr, str);
+	g_free (str);
+
+	return addr_match;
+}
+
 gboolean
 utils_connection_valid_for_device (NMConnection *connection,
                                    NMDevice *device,
@@ -765,6 +827,8 @@ utils_connection_valid_for_device (NMConnection *connection,
 		return connection_valid_for_gsm (connection, s_con, device, specific_object);
 	else if (NM_IS_CDMA_DEVICE (device))
 		return connection_valid_for_cdma (connection, s_con, device, specific_object);
+	else if (NM_IS_DEVICE_BT (device))
+		return connection_valid_for_bt (connection, s_con, device, specific_object);
 	else
 		g_warning ("Unknown device type '%s'", g_type_name (G_OBJECT_TYPE(device)));
 



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