[gnome-bluetooth] Port bluetooth-applet to the new applet library



commit c7b48a3e6e2c8195d02fd9e6757794e3e28e53da
Author: Giovanni Campagna <scampa giovanni gmail com>
Date:   Tue Oct 5 20:37:18 2010 +0200

    Port bluetooth-applet to the new applet library
    
    Refactor the existing standalone bluetooth-applet to use the applet
    library just introduced, to reduce duplicated code and make it easier
    to test and fix the library itself.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=626759

 applet/Makefile.am        |    6 +-
 applet/agent.c            |  453 ++++++++----------------------------------
 applet/agent.h            |    5 +-
 applet/main.c             |  478 +++++++++++++++------------------------------
 applet/notify.c           |   19 --
 applet/notify.h           |    4 -
 applet/test-agentdialog.c |   35 +---
 7 files changed, 254 insertions(+), 746 deletions(-)
---
diff --git a/applet/Makefile.am b/applet/Makefile.am
index dbe7aa9..f5841b2 100644
--- a/applet/Makefile.am
+++ b/applet/Makefile.am
@@ -4,15 +4,15 @@ bin_PROGRAMS = bluetooth-applet
 
 bluetooth_applet_SOURCES = main.c notify.h notify.c agent.h agent.c
 
-bluetooth_applet_LDADD = $(top_builddir)/lib/libcommon.la $(top_builddir)/lib/libgnome-bluetooth.la $(APPLET_LIBS)
+bluetooth_applet_LDADD = $(top_builddir)/lib/libgnome-bluetooth.la $(builddir)/lib/libgnome-bluetooth-applet.la $(APPLET_LIBS)
 
 noinst_PROGRAMS = test-agentdialog test-icon
 
 test_agentdialog_SOURCES = test-agentdialog.c notify.h notify.c
-test_agentdialog_LDADD = $(top_builddir)/lib/libcommon.la $(APPLET_LIBS)
+test_agentdialog_LDADD = $(builddir)/lib/libgnome-bluetooth-applet.la $(APPLET_LIBS)
 
 test_icon_SOURCES = test-icon.c notify.h notify.c
-test_icon_LDADD = $(top_builddir)/lib/libcommon.la $(APPLET_LIBS)
+test_icon_LDADD = $(APPLET_LIBS)
 
 AM_CFLAGS = $(APPLET_CFLAGS) $(WARN_CFLAGS) $(DISABLE_DEPRECATED) -DPKGDATADIR="\"$(pkgdatadir)\""
 
diff --git a/applet/agent.c b/applet/agent.c
index 094948b..f667f50 100644
--- a/applet/agent.c
+++ b/applet/agent.c
@@ -31,54 +31,36 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
-#include <dbus/dbus-glib.h>
-
-#include <bluetooth-client.h>
-#include <bluetooth-agent.h>
+#include <lib/bluetooth-applet.h>
 
 #include "notify.h"
 #include "agent.h"
 
-static BluetoothClient *client;
-static BluetoothAgent *agent = NULL;
-
 static GList *input_list = NULL;
 
 typedef struct input_data input_data;
 struct input_data {
+	BluetoothApplet *applet;
 	char *path;
 	char *uuid;
 	gboolean numeric;
-	DBusGProxy *device;
-	DBusGMethodInvocation *context;
 	GtkWidget *dialog;
 	GtkWidget *button;
 	GtkWidget *entry;
 };
 
-static gint input_compare(gconstpointer a, gconstpointer b)
-{
-	input_data *a_data = (input_data *) a;
-	input_data *b_data = (input_data *) b;
-
-	return g_ascii_strcasecmp(a_data->path, b_data->path);
-}
-
 static void input_free(input_data *input)
 {
 	gtk_widget_destroy(input->dialog);
 
-	input_list = g_list_remove(input_list, input);
-
-	if (input->device != NULL)
-		g_object_unref(input->device);
-
+	g_object_unref (G_OBJECT (input->applet));
 	g_free(input->uuid);
 	g_free(input->path);
+
+	input_list = g_list_remove(input_list, input);
+
 	g_free(input);
 
-	if (g_list_length(input_list) == 0)
-		disable_blinking();
 }
 
 static void pin_callback(GtkWidget *dialog,
@@ -93,15 +75,14 @@ static void pin_callback(GtkWidget *dialog,
 
 		if (input->numeric == TRUE) {
 			guint pin = atoi(text);
-			dbus_g_method_return(input->context, pin);
-		} else {
-			dbus_g_method_return(input->context, text);
-		}
+			bluetooth_applet_agent_reply_pincode (input->applet, input->path, pin);
+		} else
+			bluetooth_applet_agent_reply_passkey (input->applet, input->path, g_strdup (text));
 	} else {
-		GError *error;
-		error = g_error_new(AGENT_ERROR, AGENT_ERROR_REJECT,
-						"Pairing request rejected");
-		dbus_g_method_return_error(input->context, error);
+		if (input->numeric == TRUE)
+			bluetooth_applet_agent_reply_pincode (input->applet, input->path, -1);
+		else
+			bluetooth_applet_agent_reply_passkey (input->applet, input->path, NULL);
 	}
 
 	input_free(input);
@@ -114,56 +95,23 @@ confirm_callback (GtkWidget *dialog,
 {
 	input_data *input = user_data;
 
-	if (response != GTK_RESPONSE_ACCEPT) {
-		GError *error;
-		error = g_error_new(AGENT_ERROR, AGENT_ERROR_REJECT,
-					"Confirmation request rejected");
-		dbus_g_method_return_error(input->context, error);
-	} else
-		dbus_g_method_return(input->context);
+	bluetooth_applet_agent_reply_confirm (input->applet, input->path, response == GTK_RESPONSE_ACCEPT);
 
 	input_free(input);
 }
 
-static void set_trusted(input_data *input)
-{
-	GValue value = { 0 };
-	gboolean active;
-
-	if (input->device == NULL)
-		return;
-
-	active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (input->button));
-	if (active == FALSE)
-		return;
-
-	g_value_init (&value, G_TYPE_BOOLEAN);
-	g_value_set_boolean (&value, TRUE);
-
-	dbus_g_proxy_call (input->device, "SetProperty", NULL,
-			   G_TYPE_STRING, "Trusted",
-			   G_TYPE_VALUE, &value, G_TYPE_INVALID,
-			   G_TYPE_INVALID);
-
-	g_value_unset (&value);
-}
-
 static void
 auth_callback (GtkWidget *dialog,
-	       gint response,
-	       gpointer user_data)
+               gint response,
+               gpointer user_data)
 {
 	input_data *input = user_data;
 
 	if (response == GTK_RESPONSE_ACCEPT) {
-		set_trusted (input);
-		dbus_g_method_return(input->context);
-	} else {
-		GError *error;
-		error = g_error_new (AGENT_ERROR, AGENT_ERROR_REJECT,
-				     "Authorization request rejected");
-		dbus_g_method_return_error (input->context, error);
-	}
+		gboolean trusted = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (input->button));
+		bluetooth_applet_agent_reply_auth (input->applet, input->path, TRUE, trusted);
+	} else
+		bluetooth_applet_agent_reply_auth (input->applet, input->path, FALSE, FALSE);
 
 	input_free(input);
 }
@@ -208,12 +156,11 @@ static void toggled_callback(GtkWidget *button, gpointer user_data)
 }
 
 static void
-pin_dialog (DBusGProxy *adapter,
-		DBusGProxy *device,
-		const char *name,
-		const char *long_name,
-		gboolean numeric,
-		DBusGMethodInvocation *context)
+pin_dialog (BluetoothApplet *applet,
+            const char *path,
+            const char *name,
+            const char *long_name,
+            gboolean numeric)
 {
 	GtkWidget *dialog;
 	GtkWidget *button;
@@ -227,10 +174,9 @@ pin_dialog (DBusGProxy *adapter,
 		gtk_builder_add_from_file (xml, PKGDATADIR "/passkey-dialogue.ui", NULL);
 
 	input = g_new0 (input_data, 1);
-	input->path = g_strdup (dbus_g_proxy_get_path(adapter));
+	input->applet = g_object_ref (G_OBJECT (applet));
+	input->path = g_strdup (path);
 	input->numeric = numeric;
-	input->context = context;
-	input->device = g_object_ref (device);
 
 	dialog = GTK_WIDGET (gtk_builder_get_object (xml, "dialog"));
 
@@ -286,25 +232,14 @@ pin_dialog (DBusGProxy *adapter,
 
 	g_signal_connect (G_OBJECT (dialog), "response",
 			  G_CALLBACK (pin_callback), input);
-
-	enable_blinking();
 }
 
-#if 0
-static void display_dialog(DBusGProxy *adapter, DBusGProxy *device,
-		const char *address, const char *name, const char *value,
-				guint entered, DBusGMethodInvocation *context)
-{
-}
-#endif
-
 static void
-confirm_dialog (DBusGProxy *adapter,
-		DBusGProxy *device,
-		const char *name,
-		const char *long_name,
-		const char *value,
-		DBusGMethodInvocation *context)
+confirm_dialog (BluetoothApplet *applet,
+                const char *path,
+                const char *name,
+                const char *long_name,
+                const char *value)
 {
 	GtkWidget *dialog;
 	GtkBuilder *xml;
@@ -312,9 +247,8 @@ confirm_dialog (DBusGProxy *adapter,
 	input_data *input;
 
 	input = g_new0 (input_data, 1);
-	input->path = g_strdup (dbus_g_proxy_get_path(adapter));
-	input->device = g_object_ref (device);
-	input->context = context;
+	input->applet = g_object_ref (G_OBJECT (applet));
+	input->path = g_strdup (path);
 
 	xml = gtk_builder_new ();
 	if (gtk_builder_add_from_file (xml, "confirm-dialogue.ui", NULL) == 0)
@@ -344,17 +278,14 @@ confirm_dialog (DBusGProxy *adapter,
 
 	g_signal_connect (G_OBJECT (dialog), "response",
 			  G_CALLBACK (confirm_callback), input);
-
-	enable_blinking ();
 }
 
 static void
-auth_dialog (DBusGProxy *adapter,
-	     DBusGProxy *device,
-	     const char *name,
-	     const char *long_name,
-	     const char *uuid,
-	     DBusGMethodInvocation *context)
+auth_dialog (BluetoothApplet *applet,
+             const char *path,
+             const char *name,
+             const char *long_name,
+             const char *uuid)
 {
 	GtkBuilder *xml;
 	GtkWidget *dialog;
@@ -363,10 +294,9 @@ auth_dialog (DBusGProxy *adapter,
 	input_data *input;
 
 	input = g_new0 (input_data, 1);
-	input->path = g_strdup (dbus_g_proxy_get_path (adapter));
+	input->applet = g_object_ref (G_OBJECT (applet));
+	input->path = g_strdup (path);
 	input->uuid = g_strdup (uuid);
-	input->device = g_object_ref (device);
-	input->context = context;
 
 	xml = gtk_builder_new ();
 	if (gtk_builder_add_from_file (xml, "authorisation-dialogue.ui", NULL) == 0)
@@ -397,8 +327,6 @@ auth_dialog (DBusGProxy *adapter,
 
 	g_signal_connect (G_OBJECT (dialog), "response",
 			  G_CALLBACK (auth_callback), input);
-
-	enable_blinking ();
 }
 
 static void show_dialog(gpointer data, gpointer user_data)
@@ -413,8 +341,6 @@ static void show_dialog(gpointer data, gpointer user_data)
 static void present_notification_dialogs (void)
 {
 	g_list_foreach(input_list, show_dialog, NULL);
-
-	disable_blinking();
 }
 
 static void notification_closed(GObject *object, gpointer user_data)
@@ -422,148 +348,19 @@ static void notification_closed(GObject *object, gpointer user_data)
 	present_notification_dialogs ();
 }
 
-#ifndef DBUS_TYPE_G_DICTIONARY
-#define DBUS_TYPE_G_DICTIONARY \
-	(dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
-#endif
-
-static char *
-device_get_name(DBusGProxy *proxy, char **long_name)
-{
-	GHashTable *hash;
-	GValue *value;
-	char *alias, *address;
-
-	if (long_name != NULL)
-		*long_name = NULL;
-
-	if (dbus_g_proxy_call (proxy, "GetProperties",  NULL,
-			       G_TYPE_INVALID,
-			       DBUS_TYPE_G_DICTIONARY, &hash,
-			       G_TYPE_INVALID) == FALSE) {
-		return NULL;
-	}
-
-	value = g_hash_table_lookup(hash, "Address");
-	if (value == NULL) {
-		g_hash_table_destroy (hash);
-		return NULL;
-	}
-	address = g_value_dup_string(value);
-
-	value = g_hash_table_lookup(hash, "Alias");
-	alias = value ? g_value_dup_string(value) : NULL;
-
-	g_hash_table_destroy (hash);
-
-	if (g_strcmp0 (alias, address) == 0) {
-		g_free (alias);
-		if (long_name != NULL)
-			*long_name = g_strdup_printf ("'%s'", address);
-		return address;
-	}
-
-	if (long_name != NULL)
-		*long_name = g_strdup_printf ("'%s' (%s)", alias, address);
-
-	g_free (address);
-
-	return alias;
-}
-
-static gboolean pincode_request(DBusGMethodInvocation *context,
-					DBusGProxy *device, gpointer user_data)
-{
-	DBusGProxy *adapter = user_data;
-	char *name, *long_name, *line;
-
-	name = device_get_name (device, &long_name);
-	if (name == NULL)
-		return FALSE;
-
-	pin_dialog(adapter, device, name, long_name, FALSE, context);
-
-	g_free (long_name);
-
-	if (notification_supports_actions () == FALSE) {
-		g_free (name);
-		present_notification_dialogs ();
-		return TRUE;
-	}
-
-	/* translators: this is a popup telling you a particular device
-	 * has asked for pairing */
-	line = g_strdup_printf(_("Pairing request for '%s'"), name);
-
-	g_free(name);
-
-	show_notification(_("Bluetooth device"),
-			  line, _("Enter PIN"), 0,
-			  G_CALLBACK(notification_closed));
-
-	g_free(line);
-
-	return TRUE;
-}
-
-static gboolean pin_request(DBusGMethodInvocation *context,
-					DBusGProxy *device, gpointer user_data)
-{
-	DBusGProxy *adapter = user_data;
-	char *name, *long_name, *line;
-
-	name = device_get_name (device, &long_name);
-	if (name == NULL)
-		return FALSE;
-
-	pin_dialog(adapter, device, name, long_name, TRUE, context);
-
-	g_free (long_name);
-
-	if (notification_supports_actions () == FALSE) {
-		g_free (name);
-		present_notification_dialogs ();
-		return TRUE;
-	}
-
-	/* translators: this is a popup telling you a particular device
-	 * has asked for pairing */
-	line = g_strdup_printf(_("Pairing request for '%s'"), name);
-
-	g_free(name);
-
-	show_notification(_("Bluetooth device"),
-			  line, _("Enter PIN"), 0,
-			  G_CALLBACK(notification_closed));
-
-	g_free(line);
-
-	return TRUE;
-}
-
 static gboolean
-display_request (DBusGMethodInvocation *context,
-		 DBusGProxy *device,
-		 guint pin,
-		 guint entered,
-		 gpointer user_data)
+pin_request(BluetoothApplet *applet,
+            char *path,
+            char *name,
+            char *long_name,
+            gboolean numeric,
+            gpointer user_data)
 {
-	g_warning ("Not implemented, please file a bug at how this happened");
-	return FALSE;
-#if 0
-	DBusGProxy *adapter = user_data;
-	char *name, *text;
+	char *line;
 
-	name = get_name_for_display (device);
-	if (name == NULL)
-		return FALSE;
-
-	text = g_strdup_printf("%d", pin);
-	display_dialog(adapter, device, address, name, text, entered, context);
-	g_free(text);
+	pin_dialog(applet, path, name, long_name, numeric);
 
 	if (notification_supports_actions () == FALSE) {
-		g_free (name);
 		present_notification_dialogs ();
 		return TRUE;
 	}
@@ -572,8 +369,6 @@ display_request (DBusGMethodInvocation *context,
 	 * has asked for pairing */
 	line = g_strdup_printf(_("Pairing request for '%s'"), name);
 
-	g_free(name);
-
 	show_notification(_("Bluetooth device"),
 			  line, _("Enter PIN"), 0,
 			  G_CALLBACK(notification_closed));
@@ -581,34 +376,26 @@ display_request (DBusGMethodInvocation *context,
 	g_free(line);
 
 	return TRUE;
-#endif
 }
 
 static gboolean
-confirm_request (DBusGMethodInvocation *context,
-		 DBusGProxy *device,
-		 guint pin,
-		 gpointer user_data)
+confirm_request (BluetoothApplet *applet,
+                 char *path,
+                 char *name,
+                 char *long_name,
+                 guint pin,
+                 gpointer user_data)
 {
-	DBusGProxy *adapter = user_data;
-	char *name, *long_name, *line, *text;
-
-	name = device_get_name (device, &long_name);
-	if (name == NULL)
-		return FALSE;
+	char *text, *line;
 
 	text = g_strdup_printf("%d", pin);
-	confirm_dialog(adapter, device, name, long_name, text, context);
+	confirm_dialog(applet, path, name, long_name, text);
 	g_free(text);
 
-	g_free (long_name);
-
 	/* translators: this is a popup telling you a particular device
 	 * has asked for pairing */
 	line = g_strdup_printf(_("Pairing confirmation for '%s'"), name);
 
-	g_free(name);
-
 	/* translators:
 	 * This message is for Bluetooth 2.1 support, when the
 	 * action is clicked in the notification popup, the user
@@ -627,32 +414,24 @@ confirm_request (DBusGMethodInvocation *context,
 }
 
 static gboolean
-authorize_request (DBusGMethodInvocation *context,
-		   DBusGProxy *device,
-		   const char *uuid,
-		   gpointer user_data)
+authorize_request (BluetoothApplet *applet,
+                   char *path,
+                   char *name,
+                   char *long_name,
+                   char *uuid,
+                   gpointer user_data)
 {
-	DBusGProxy *adapter = user_data;
-	char *name, *long_name, *line;
-
-	name = device_get_name (device, &long_name);
-	if (name == NULL)
-		return FALSE;
+	char *line;
 
-	auth_dialog (adapter, device, name, long_name, uuid, context);
-
-	g_free (long_name);
+	auth_dialog (applet, path, name, long_name, uuid);
 
 	if (notification_supports_actions () == FALSE) {
-		g_free (name);
 		present_notification_dialogs ();
 		return TRUE;
 	}
 
 	line = g_strdup_printf (_("Authorization request from '%s'"), name);
 
-	g_free (name);
-
 	show_notification (_("Bluetooth device"),
 			   line, _("Check authorization"), 0,
 			   G_CALLBACK (notification_closed));
@@ -662,106 +441,42 @@ authorize_request (DBusGMethodInvocation *context,
 	return TRUE;
 }
 
-static gboolean cancel_request(DBusGMethodInvocation *context,
-							gpointer user_data)
-{
-	DBusGProxy *adapter = user_data;
-	GList *list;
-	GError *result;
-	input_data *input;
-
-	input = g_new0(input_data, 1);
-	input->path = g_strdup(dbus_g_proxy_get_path(adapter));
+static void input_free_list (gpointer data, gpointer user_data) {
+	input_data *input = data;
 
-	list = g_list_find_custom(input_list, input, input_compare);
+	gtk_widget_destroy(input->dialog);
 
+	g_object_unref (G_OBJECT (input->applet));
+	g_free(input->uuid);
 	g_free(input->path);
 	g_free(input);
-
-	if (!list || !list->data)
-		return FALSE;
-
-	input = list->data;
-
-	close_notification();
-
-	result = g_error_new(AGENT_ERROR, AGENT_ERROR_REJECT,
-						"Agent callback cancelled");
-
-	dbus_g_method_return_error(input->context, result);
-
-	input_free(input);
-
-	return TRUE;
 }
 
-static void
-default_adapter_changed (GObject    *gobject,
-			 GParamSpec *pspec,
-			 gpointer    user_data)
+static void cancel_request(BluetoothApplet *applet,
+							gpointer user_data)
 {
-	char *adapter_str;
-
-	g_object_get (G_OBJECT (gobject), "default-adapter", &adapter_str, NULL);
-	if (agent != NULL) {
-		bluetooth_agent_unregister (agent);
-		g_object_unref (agent);
-		agent = NULL;
-	}
-	if (adapter_str != NULL) {
-		DBusGConnection *connection;
-		DBusGProxy *adapter;
-
-		connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
-		adapter = dbus_g_proxy_new_for_name (connection,
-						     "org.bluez",
-						     adapter_str,
-						     "org.bluez.Adapter");
-		dbus_g_connection_unref (connection);
-
-		agent = bluetooth_agent_new();
-
-		bluetooth_agent_set_pincode_func(agent, pincode_request, adapter);
-		bluetooth_agent_set_passkey_func(agent, pin_request, adapter);
-		bluetooth_agent_set_display_func(agent, display_request, adapter);
-		bluetooth_agent_set_confirm_func(agent, confirm_request, adapter);
-		bluetooth_agent_set_authorize_func(agent, authorize_request, adapter);
-		bluetooth_agent_set_cancel_func(agent, cancel_request, adapter);
-
-		bluetooth_agent_register(agent, adapter);
-
-		g_object_unref (adapter);
-	}
-	g_free (adapter_str);
+	g_list_foreach (input_list, input_free_list, NULL);
+	g_list_free (input_list);
+	input_list = NULL;
 }
 
-int setup_agents(void)
+int setup_agents(BluetoothApplet *applet)
 {
-	dbus_g_error_domain_register(AGENT_ERROR, "org.bluez.Error",
-							AGENT_ERROR_TYPE);
-
-	client = bluetooth_client_new();
-	g_signal_connect (G_OBJECT (client), "notify::default-adapter",
-			  G_CALLBACK (default_adapter_changed), NULL);
-	default_adapter_changed (G_OBJECT (client), NULL, NULL);
+	g_signal_connect (applet, "pincode-request",
+			G_CALLBACK (pin_request), NULL);
+	g_signal_connect (applet, "confirm-request",
+			G_CALLBACK (confirm_request), NULL);
+	g_signal_connect (applet, "auth-request",
+			G_CALLBACK (authorize_request), NULL);
+	g_signal_connect (applet, "cancel-request",
+			G_CALLBACK (cancel_request), NULL);
 
 	return 0;
 }
 
-void cleanup_agents(void)
-{
-	if (agent != NULL) {
-		bluetooth_agent_unregister (agent);
-		g_object_unref (agent);
-	}
-	g_object_unref (client);
-}
-
 void show_agents(void)
 {
 	close_notification();
 
 	g_list_foreach(input_list, show_dialog, NULL);
-
-	disable_blinking();
 }
diff --git a/applet/agent.h b/applet/agent.h
index 3368a37..aa99f91 100644
--- a/applet/agent.h
+++ b/applet/agent.h
@@ -22,7 +22,8 @@
  *
  */
 
-int setup_agents(void);
-void cleanup_agents(void);
+#include <lib/bluetooth-applet.h>
+
+int setup_agents(BluetoothApplet* applet);
 
 void show_agents(void);
diff --git a/applet/main.c b/applet/main.c
index 25bda9a..c131a7e 100644
--- a/applet/main.c
+++ b/applet/main.c
@@ -29,20 +29,15 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
-#include <bluetooth-client.h>
-#include <bluetooth-client-private.h>
+#include <lib/bluetooth-applet.h>
 #include <bluetooth-chooser.h>
-#include <bluetooth-killswitch.h>
 
 #include "notify.h"
 #include "agent.h"
 
 static gboolean option_debug = FALSE;
-static gboolean option_dump = FALSE;
-static BluetoothClient *client;
-static GtkTreeModel *devices_model;
-static guint num_adapters_present = 0;
-static guint num_adapters_powered = 0;
+static BluetoothApplet *applet = NULL;
+static GSettings *settings = NULL;
 static gboolean show_icon_pref = TRUE;
 static gboolean discover_lock = FALSE;
 
@@ -61,9 +56,6 @@ enum {
 	DISCONNECTING
 };
 
-static GSettings *settings;
-static BluetoothKillswitch *killswitch = NULL;
-
 static GtkBuilder *xml = NULL;
 static GtkActionGroup *devices_action_group = NULL;
 
@@ -261,45 +253,6 @@ void wizard_callback(GObject *widget, gpointer user_data)
 		g_printerr("Couldn't execute command: %s\n", command);
 }
 
-static gboolean
-set_powered_foreach (GtkTreeModel *model,
-		     GtkTreePath  *path,
-		     GtkTreeIter  *iter,
-		     gpointer      data)
-{
-	DBusGProxy *proxy = NULL;
-	GValue value = { 0, };
-
-	gtk_tree_model_get (model, iter,
-			    BLUETOOTH_COLUMN_PROXY, &proxy, -1);
-	if (proxy == NULL)
-		return FALSE;
-
-	g_value_init (&value, G_TYPE_BOOLEAN);
-	g_value_set_boolean (&value, TRUE);
-
-	dbus_g_proxy_call_no_reply (proxy, "SetProperty",
-				    G_TYPE_STRING, "Powered",
-				    G_TYPE_VALUE, &value,
-				    G_TYPE_INVALID,
-				    G_TYPE_INVALID);
-
-	g_value_unset (&value);
-	g_object_unref (proxy);
-
-	return FALSE;
-}
-
-static void
-bluetooth_set_adapter_powered (void)
-{
-	GtkTreeModel *adapters;
-
-	adapters = bluetooth_client_get_adapter_model (client);
-	gtk_tree_model_foreach (adapters, set_powered_foreach, NULL);
-	g_object_unref (adapters);
-}
-
 void bluetooth_status_callback (GObject *widget, gpointer user_data)
 {
 	GObject *object;
@@ -308,10 +261,9 @@ void bluetooth_status_callback (GObject *widget, gpointer user_data)
 	object = gtk_builder_get_object (xml, "killswitch");
 	active = GPOINTER_TO_INT (g_object_get_data (object, "bt-active"));
 	active = !active;
-	bluetooth_killswitch_set_state (killswitch,
-					active ? KILLSWITCH_STATE_UNBLOCKED : KILLSWITCH_STATE_SOFT_BLOCKED);
+	bluetooth_applet_set_killswitch_state (applet,
+					active ? BLUETOOTH_KILLSWITCH_STATE_UNBLOCKED : BLUETOOTH_KILLSWITCH_STATE_SOFT_BLOCKED);
 	g_object_set_data (object, "bt-active", GINT_TO_POINTER (active));
-	bluetooth_set_adapter_powered ();
 }
 
 void
@@ -321,7 +273,7 @@ bluetooth_discoverable_callback (GtkToggleAction *toggleaction, gpointer user_da
 
 	discoverable = gtk_toggle_action_get_active (toggleaction);
 	discover_lock = TRUE;
-	bluetooth_client_set_discoverable (client, discoverable, 0);
+	bluetooth_applet_set_discoverable (applet, discoverable);
 	discover_lock = FALSE;
 }
 
@@ -352,38 +304,41 @@ static void activate_callback(GObject *widget, gpointer user_data)
 {
 	guint32 activate_time = gtk_get_current_event_time();
 
-	if (query_blinking() == TRUE) {
-		show_agents();
-		return;
-	}
-
+	/* Always show the menu, whatever button is pressed.
+	 * Agent dialog can be shown from the notification (or should
+	 * be shown automatically in the background).
+	 */
 	popup_callback(widget, 0, activate_time, user_data);
 }
 
 static void
-killswitch_state_changed (BluetoothKillswitch *killswitch, KillswitchState state)
+killswitch_state_changed (GObject    *gobject,
+                          GParamSpec *pspec,
+                          gpointer    user_data)
 {
 	GObject *object;
+	BluetoothApplet *applet = BLUETOOTH_APPLET (gobject);
+	BluetoothKillswitchState state = bluetooth_applet_get_killswitch_state (applet);
 	gboolean sensitive = TRUE;
 	gboolean bstate = FALSE;
 	const char *label, *status_label;
 
-	if (state == KILLSWITCH_STATE_NO_ADAPTER) {
+	if (state == BLUETOOTH_KILLSWITCH_STATE_NO_ADAPTER) {
 		object = gtk_builder_get_object (xml, "bluetooth-applet-popup");
 		gtk_menu_popdown (GTK_MENU (object));
 		update_icon_visibility ();
 		return;
 	}
 
-	if (state == KILLSWITCH_STATE_SOFT_BLOCKED) {
+	if (state == BLUETOOTH_KILLSWITCH_STATE_SOFT_BLOCKED) {
 		label = N_("Turn On Bluetooth");
 		status_label = N_("Bluetooth: Off");
 		bstate = FALSE;
-	} else if (state == KILLSWITCH_STATE_UNBLOCKED) {
+	} else if (state == BLUETOOTH_KILLSWITCH_STATE_UNBLOCKED) {
 		label = N_("Turn Off Bluetooth");
 		status_label = N_("Bluetooth: On");
 		bstate = TRUE;
-	} else if (state == KILLSWITCH_STATE_HARD_BLOCKED) {
+	} else if (state == BLUETOOTH_KILLSWITCH_STATE_HARD_BLOCKED) {
 		sensitive = FALSE;
 		label = NULL;
 		status_label = N_("Bluetooth: Disabled");
@@ -433,7 +388,7 @@ static GtkWidget *create_popupmenu(void)
 
 	gtk_builder_connect_signals (xml, NULL);
 
-	if (bluetooth_killswitch_has_killswitches (killswitch) != FALSE) {
+	if (bluetooth_applet_get_killswitch_state (applet) != BLUETOOTH_KILLSWITCH_STATE_NO_ADAPTER) {
 		GObject *object;
 
 		object = gtk_builder_get_object (xml, "killswitch-label");
@@ -460,15 +415,15 @@ static GtkWidget *create_popupmenu(void)
 }
 
 static void
-update_menu_items (void)
+update_menu_items (GObject    *gobject,
+                   GParamSpec *pspec,
+                   gpointer    user_data)
 {
+	BluetoothApplet *applet = BLUETOOTH_APPLET (gobject);
 	gboolean enabled;
 	GObject *object;
 
-	if (num_adapters_present == 0)
-		enabled = FALSE;
-	else
-		enabled = (num_adapters_present - num_adapters_powered) <= 0;
+	enabled = bluetooth_applet_get_show_full_menu (applet);
 
 	object = gtk_builder_get_object (xml, "adapter-action-group");
 	gtk_action_group_set_visible (GTK_ACTION_GROUP (object), enabled);
@@ -481,16 +436,16 @@ update_menu_items (void)
 }
 
 static void
-update_icon_visibility (void)
+update_icon_visibility ()
 {
-	if (num_adapters_powered == 0)
+	gboolean state = bluetooth_applet_get_killswitch_state (applet);
+	if (state != BLUETOOTH_KILLSWITCH_STATE_UNBLOCKED)
 		set_icon (FALSE);
 	else
 		set_icon (TRUE);
 
 	if (show_icon_pref != FALSE) {
-		if (num_adapters_present > 0 ||
-		    bluetooth_killswitch_has_killswitches (killswitch) != FALSE) {
+		if (state != BLUETOOTH_KILLSWITCH_STATE_NO_ADAPTER) {
 			show_icon ();
 			return;
 		}
@@ -499,8 +454,11 @@ update_icon_visibility (void)
 }
 
 static void
-update_discoverability (GtkTreeIter *iter)
+update_discoverability (GObject    *gobject,
+                        GParamSpec *pspec,
+                        gpointer    user_data)
 {
+	BluetoothApplet *applet = BLUETOOTH_APPLET (gobject);
 	gboolean discoverable;
 	GObject *object;
 
@@ -512,15 +470,7 @@ update_discoverability (GtkTreeIter *iter)
 
 	object = gtk_builder_get_object (xml, "discoverable");
 
-	if (iter == NULL) {
-		discover_lock = FALSE;
-		gtk_action_set_visible (GTK_ACTION (object), FALSE);
-		return;
-	}
-
-	gtk_tree_model_get (devices_model, iter,
-			    BLUETOOTH_COLUMN_DISCOVERABLE, &discoverable,
-			    -1);
+	discoverable = bluetooth_applet_get_discoverable (applet);
 
 	gtk_action_set_visible (GTK_ACTION (object), TRUE);
 	gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (object), discoverable);
@@ -570,7 +520,7 @@ set_device_status_label (const char *address, int connected)
 }
 
 static void
-connection_action_callback (BluetoothClient *_client,
+connection_action_callback (BluetoothApplet *_client,
 			    gboolean success,
 			    gpointer user_data)
 {
@@ -579,7 +529,10 @@ connection_action_callback (BluetoothClient *_client,
 	int connected;
 
 	/* Revert to the previous state and wait for the
-	 * BluetoothClient to catch up */
+	 * BluetoothApplet to catch up */
+	/* XXX: wouldn't it make more sense just to set the new state if
+	 * the operation succeded?
+	 */
 	connected = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (action), "connected"));
 	if (connected == DISCONNECTING)
 		connected = CONNECTED;
@@ -609,10 +562,10 @@ on_connect_activate (GtkAction *action, gpointer data)
 	path = g_object_get_data (G_OBJECT (action), "device-path");
 
 	if (connected == DISCONNECTED) {
-		if (bluetooth_client_connect_service (client, path, connection_action_callback, action) != FALSE)
+		if (bluetooth_applet_connect_device (applet, path, connection_action_callback, action) != FALSE)
 			connected = DISCONNECTING;
 	} else if (connected == CONNECTED) {
-		if (bluetooth_client_disconnect_service (client, path, connection_action_callback, action) != FALSE)
+		if (bluetooth_applet_disconnect_device (applet, path, connection_action_callback, action) != FALSE)
 			connected = CONNECTING;
 	} else {
 		g_assert_not_reached ();
@@ -682,32 +635,18 @@ escape_label_for_action (const char *alias)
 }
 
 static gboolean
-device_has_uuid (const char **uuids, const char *uuid)
+device_has_submenu (BluetoothSimpleDevice *dev)
 {
-	guint i;
-
-	if (uuids == NULL)
-		return FALSE;
-
-	for (i = 0; uuids[i] != NULL; i++) {
-		if (g_str_equal (uuid, uuids[i]) != FALSE)
-			return TRUE;
-	}
-	return FALSE;
-}
-
-static gboolean
-device_has_submenu (const char **uuids, GHashTable *services, BluetoothType type)
-{
-	if (services != NULL)
+	if (dev->can_connect)
 		return TRUE;
-	if (device_has_uuid (uuids, "OBEXObjectPush") != FALSE)
+	if (dev->capabilities != BLUETOOTH_CAPABILITIES_NONE)
 		return TRUE;
-	if (device_has_uuid (uuids, "OBEXFileTransfer") != FALSE)
+	if (dev->type == BLUETOOTH_TYPE_KEYBOARD ||
+		dev->type == BLUETOOTH_TYPE_MOUSE ||
+		dev->type == BLUETOOTH_TYPE_HEADSET ||
+		dev->type == BLUETOOTH_TYPE_HEADPHONES ||
+		dev->type == BLUETOOTH_TYPE_OTHER_AUDIO)
 		return TRUE;
-	if (type == BLUETOOTH_TYPE_KEYBOARD ||
-	    type == BLUETOOTH_TYPE_MOUSE)
-	    	return TRUE;
 	return FALSE;
 }
 
@@ -770,24 +709,57 @@ add_separator_item (const char *address,
 	g_free (action_name);
 }
 
+static gboolean
+verify_address (const char *bdaddr)
+{
+	gboolean retval = TRUE;
+	char **elems;
+	guint i;
+
+	g_return_val_if_fail (bdaddr != NULL, FALSE);
+
+	if (strlen (bdaddr) != 17)
+		return FALSE;
+
+	elems = g_strsplit (bdaddr, ":", -1);
+	if (elems == NULL)
+		return FALSE;
+	if (g_strv_length (elems) != 6) {
+		g_strfreev (elems);
+		return FALSE;
+	}
+	for (i = 0; i < 6; i++) {
+		if (strlen (elems[i]) != 2 ||
+		    g_ascii_isxdigit (elems[i][0]) == FALSE ||
+		    g_ascii_isxdigit (elems[i][1]) == FALSE) {
+			retval = FALSE;
+			break;
+		}
+	}
+
+	g_strfreev (elems);
+	return retval;
+}
+
+
 static void
-update_device_list (GtkTreeIter *parent)
+update_device_list (BluetoothApplet *applet,
+					gpointer user_data)
 {
 	GtkUIManager *uimanager;
-	GtkTreeIter iter;
-	gboolean cont;
-	guint num_devices;
-	GList *actions, *l;
-
-	num_devices = 0;
+	GList *actions, *devices, *l;
+	gboolean has_devices = TRUE;
 
 	uimanager = GTK_UI_MANAGER (gtk_builder_get_object (xml, "bluetooth-applet-ui-manager"));
 
-	if (parent == NULL) {
-		/* No default adapter? Remove everything */
+	devices = bluetooth_applet_get_devices (applet);
+
+	if (devices == NULL) {
+		/* No devices? Remove everything */
 		actions = gtk_action_group_list_actions (devices_action_group);
 		g_list_foreach (actions, (GFunc) remove_action_item, uimanager);
 		g_list_free (actions);
+		has_devices = FALSE;
 		goto done;
 	}
 
@@ -795,44 +767,22 @@ update_device_list (GtkTreeIter *parent)
 	 * device in the list. We remove the submenu items first */
 	actions = gtk_action_group_list_actions (devices_action_group);
 	for (l = actions; l != NULL; l = l->next) {
-		if (bluetooth_verify_address (gtk_action_get_name (l->data)) == FALSE)
+		if (verify_address (gtk_action_get_name (l->data)) == FALSE)
 			l->data = NULL;
 	}
 	actions = g_list_remove_all (actions, NULL);
 
-	cont = gtk_tree_model_iter_children (devices_model, &iter, parent);
-	while (cont) {
-		GHashTable *services;
-		DBusGProxy *proxy;
-		char *alias, *address, **uuids, *name;
-		gboolean is_connected;
-		BluetoothType type;
+	for (l = devices; l != NULL; l = g_list_next (l)) {
+		BluetoothSimpleDevice *device = l->data;
 		GtkAction *action, *status, *oper;
+		char *name;
 
-		gtk_tree_model_get (devices_model, &iter,
-				    BLUETOOTH_COLUMN_PROXY, &proxy,
-				    BLUETOOTH_COLUMN_ADDRESS, &address,
-				    BLUETOOTH_COLUMN_SERVICES, &services,
-				    BLUETOOTH_COLUMN_ALIAS, &alias,
-				    BLUETOOTH_COLUMN_UUIDS, &uuids,
-				    BLUETOOTH_COLUMN_TYPE, &type,
-				    -1);
-
-		if (device_has_submenu ((const char **) uuids, services, type) == FALSE ||
-		    address == NULL || proxy == NULL || alias == NULL) {
-			if (proxy != NULL)
-				g_object_unref (proxy);
-
-			if (services != NULL)
-				g_hash_table_unref (services);
-			g_strfreev (uuids);
-			g_free (alias);
-			g_free (address);
-			cont = gtk_tree_model_iter_next (devices_model, &iter);
+		if (device_has_submenu (device) == FALSE) {
+			g_boxed_free (BLUETOOTH_TYPE_SIMPLE_DEVICE, device);
 			continue;
 		}
 
-		action = gtk_action_group_get_action (devices_action_group, address);
+		action = gtk_action_group_get_action (devices_action_group, device->bdaddr);
 		oper = NULL;
 		status = NULL;
 		if (action) {
@@ -840,62 +790,45 @@ update_device_list (GtkTreeIter *parent)
 
 			actions = g_list_remove (actions, action);
 
-			action_name = g_strdup_printf ("%s-status", address);
+			action_name = g_strdup_printf ("%s-status", device->bdaddr);
 			status = gtk_action_group_get_action (devices_action_group, action_name);
 			g_free (action_name);
 
-			action_name = g_strdup_printf ("%s-action", address);
+			action_name = g_strdup_printf ("%s-action", device->bdaddr);
 			oper = gtk_action_group_get_action (devices_action_group, action_name);
 			g_free (action_name);
 		}
 
-		/* If one service is connected, then we're connected */
-		is_connected = FALSE;
-		if (services != NULL) {
-			GList *list, *l;
-
-			list = g_hash_table_get_values (services);
-			for (l = list; l != NULL; l = l->next) {
-				BluetoothStatus val = GPOINTER_TO_INT (l->data);
-				if (val == BLUETOOTH_STATUS_CONNECTED ||
-				    val == BLUETOOTH_STATUS_PLAYING) {
-					is_connected = TRUE;
-					break;
-				}
-			}
-			g_list_free (list);
-		}
-
-		name = escape_label_for_action (alias);
+		name = escape_label_for_action (device->alias);
 
 		if (action == NULL) {
 			guint menu_merge_id;
 			char *action_path;
 
 			/* The menu item with descendants */
-			action = gtk_action_new (address, name, NULL, NULL);
+			action = gtk_action_new (device->bdaddr, name, NULL, NULL);
 
 			gtk_action_group_add_action (devices_action_group, action);
 			g_object_unref (action);
 			menu_merge_id = gtk_ui_manager_new_merge_id (uimanager);
 			gtk_ui_manager_add_ui (uimanager, menu_merge_id,
-					       "/bluetooth-applet-popup/devices-placeholder", address, address,
+					       "/bluetooth-applet-popup/devices-placeholder", device->bdaddr, device->bdaddr,
 					       GTK_UI_MANAGER_MENU, FALSE);
 			g_object_set_data_full (G_OBJECT (action),
 						"merge-id", GUINT_TO_POINTER (menu_merge_id), NULL);
 
 			/* The status menu item */
-			status = add_menu_item (address,
+			status = add_menu_item (device->bdaddr,
 						"status",
-						is_connected ? _("Connected") : _("Disconnected"),
+						device->connected ? _("Connected") : _("Disconnected"),
 						uimanager,
 						menu_merge_id,
 						NULL);
 			gtk_action_set_sensitive (status, FALSE);
 
-			if (services != NULL) {
+			if (device->can_connect) {
 				action_path = g_strdup_printf ("/bluetooth-applet-popup/devices-placeholder/%s/%s-status",
-							       address, address);
+							       device->bdaddr, device->bdaddr);
 				action_set_bold (uimanager, status, action_path);
 				g_free (action_path);
 			} else {
@@ -903,30 +836,30 @@ update_device_list (GtkTreeIter *parent)
 			}
 
 			/* The connect button */
-			oper = add_menu_item (address,
+			oper = add_menu_item (device->bdaddr,
 					      "action",
-					      is_connected ? _("Disconnect") : _("Connect"),
+					      device->connected ? _("Disconnect") : _("Connect"),
 					      uimanager,
 					      menu_merge_id,
 					      G_CALLBACK (on_connect_activate));
-			if (services == NULL)
+			if (!device->can_connect)
 				gtk_action_set_visible (oper, FALSE);
 
-			add_separator_item (address, "connect-sep", uimanager, menu_merge_id);
+			add_separator_item (device->bdaddr, "connect-sep", uimanager, menu_merge_id);
 
 			/* The Send to... button */
-			if (device_has_uuid ((const char **) uuids, "OBEXObjectPush") != FALSE) {
-				add_menu_item (address,
+			if (device->capabilities & BLUETOOTH_CAPABILITIES_OBEX_PUSH) {
+				add_menu_item (device->bdaddr,
 					       "sendto",
 					       _("Send files..."),
 					       uimanager,
 					       menu_merge_id,
 					       G_CALLBACK (sendto_callback));
 				g_object_set_data_full (G_OBJECT (action),
-							"alias", g_strdup (alias), g_free);
+							"alias", g_strdup (device->alias), g_free);
 			}
-			if (device_has_uuid ((const char **) uuids, "OBEXFileTransfer") != FALSE) {
-				add_menu_item (address,
+			if (device->capabilities & BLUETOOTH_CAPABILITIES_OBEX_FILE_TRANSFER) {
+				add_menu_item (device->bdaddr,
 					       "browse",
 					       _("Browse files..."),
 					       uimanager,
@@ -934,28 +867,28 @@ update_device_list (GtkTreeIter *parent)
 					       G_CALLBACK (browse_callback));
 			}
 
-			add_separator_item (address, "files-sep", uimanager, menu_merge_id);
+			add_separator_item (device->bdaddr, "files-sep", uimanager, menu_merge_id);
 
-			if (type == BLUETOOTH_TYPE_KEYBOARD && program_available (GNOMECC)) {
-				add_menu_item (address,
+			if (device->type == BLUETOOTH_TYPE_KEYBOARD && program_available (GNOMECC)) {
+				add_menu_item (device->bdaddr,
 					       "keyboard",
 					       _("Open Keyboard Preferences..."),
 					       uimanager,
 					       menu_merge_id,
 					       G_CALLBACK (keyboard_callback));
 			}
-			if (type == BLUETOOTH_TYPE_MOUSE && program_available (GNOMECC)) {
-				add_menu_item (address,
+			if (device->type == BLUETOOTH_TYPE_MOUSE && program_available (GNOMECC)) {
+				add_menu_item (device->bdaddr,
 					       "mouse",
 					       _("Open Mouse Preferences..."),
 					       uimanager,
 					       menu_merge_id,
 					       G_CALLBACK (mouse_callback));
 			}
-			if ((type == BLUETOOTH_TYPE_HEADSET ||
-			     type == BLUETOOTH_TYPE_HEADPHONES ||
-			     type == BLUETOOTH_TYPE_OTHER_AUDIO) && program_available (GNOMECC)) {
-				add_menu_item (address,
+			if ((device->type == BLUETOOTH_TYPE_HEADSET ||
+				 device->type == BLUETOOTH_TYPE_HEADPHONES ||
+				 device->type == BLUETOOTH_TYPE_OTHER_AUDIO) && program_available (GNOMECC)) {
+				add_menu_item (device->bdaddr,
 					       "sound",
 					       _("Open Sound Preferences..."),
 					       uimanager,
@@ -965,106 +898,48 @@ update_device_list (GtkTreeIter *parent)
 		} else {
 			gtk_action_set_label (action, name);
 
-			gtk_action_set_visible (status, services != NULL);
-			gtk_action_set_visible (oper, services != NULL);
-			if (services != NULL) {
-				set_device_status_label (address, is_connected ? CONNECTED : DISCONNECTED);
-				gtk_action_set_label (oper, is_connected ? _("Disconnect") : _("Connect"));
+			if (device->can_connect) {
+				gtk_action_set_visible (status, TRUE);
+				gtk_action_set_visible (oper, TRUE);
+				set_device_status_label (device->bdaddr, device->connected ? CONNECTED : DISCONNECTED);
+				gtk_action_set_label (oper, device->connected ? _("Disconnect") : _("Connect"));
+			} else {
+				gtk_action_set_visible (status, FALSE);
+				gtk_action_set_visible (oper, FALSE);
 			}
 		}
 		g_free (name);
 
 		if (oper != NULL) {
 			g_object_set_data_full (G_OBJECT (oper),
-						"connected", GINT_TO_POINTER (is_connected ? CONNECTED : DISCONNECTED), NULL);
+						"connected", GINT_TO_POINTER (device->connected ? CONNECTED : DISCONNECTED), NULL);
 			g_object_set_data_full (G_OBJECT (oper),
-						"device-path", g_strdup (dbus_g_proxy_get_path (proxy)), g_free);
+						"device-path", g_strdup (device->device_path), g_free);
 		}
 
 		/* And now for the trick of the day */
-		if (is_connected != FALSE) {
+		if (device->connected != FALSE) {
 			char *path;
 
-			path = g_strdup_printf ("/bluetooth-applet-popup/devices-placeholder/%s", address);
+			path = g_strdup_printf ("/bluetooth-applet-popup/devices-placeholder/%s", device->bdaddr);
 			action_set_bold (uimanager, action, path);
 			g_free (path);
 		}
 
-		num_devices++;
-
-		if (proxy != NULL)
-			g_object_unref (proxy);
-
-		if (services != NULL)
-			g_hash_table_unref (services);
-		g_strfreev (uuids);
-		g_free (alias);
-		g_free (address);
-		cont = gtk_tree_model_iter_next (devices_model, &iter);
+		g_boxed_free (BLUETOOTH_TYPE_SIMPLE_DEVICE, device);
 	}
 
 	/* Remove the left-over devices */
 	g_list_foreach (actions, (GFunc) remove_action_item, uimanager);
 	g_list_free (actions);
 
+	/* Cleanup */
+	g_list_free (devices);
 done:
 	gtk_ui_manager_ensure_update (uimanager);
 
 	gtk_action_set_visible (GTK_ACTION (gtk_builder_get_object (xml, "devices-label")),
-				num_devices > 0);
-}
-
-static void device_changed (GtkTreeModel *model,
-			     GtkTreePath  *path,
-			     GtkTreeIter  *_iter,
-			     gpointer      data)
-{
-	GtkTreeIter iter, *default_iter;
-	gboolean powered, cont;
-
-	default_iter = NULL;
-	num_adapters_present = num_adapters_powered = 0;
-
-	cont = gtk_tree_model_get_iter_first (model, &iter);
-	while (cont) {
-		gboolean is_default;
-
-		num_adapters_present++;
-
-		gtk_tree_model_get (model, &iter,
-				    BLUETOOTH_COLUMN_DEFAULT, &is_default,
-				    BLUETOOTH_COLUMN_POWERED, &powered,
-				    -1);
-		if (powered)
-			num_adapters_powered++;
-		if (is_default && powered)
-			default_iter = gtk_tree_iter_copy (&iter);
-
-		cont = gtk_tree_model_iter_next (model, &iter);
-	}
-
-	update_discoverability (default_iter);
-	update_icon_visibility ();
-	update_menu_items ();
-	update_device_list (default_iter);
-
-	if (default_iter != NULL)
-		gtk_tree_iter_free (default_iter);
-}
-
-static void device_added(GtkTreeModel *model,
-			  GtkTreePath *path,
-			  GtkTreeIter *iter,
-			  gpointer user_data)
-{
-	device_changed (model, path, iter, user_data);
-}
-
-static void device_removed(GtkTreeModel *model,
-			    GtkTreePath *path,
-			    gpointer user_data)
-{
-	device_changed (model, path, NULL, user_data);
+				has_devices);
 }
 
 static void
@@ -1076,29 +951,8 @@ show_icon_changed (GSettings *settings,
 	update_icon_visibility();
 }
 
-static void
-dump_devices (void)
-{
-	BluetoothClient *client;
-	GtkTreeModel *model;
-	GtkTreeIter iter;
-
-	client = bluetooth_client_new ();
-	model = bluetooth_client_get_model (client);
-
-	if (gtk_tree_model_get_iter_first (model, &iter) == FALSE) {
-		g_print ("No known devices\n");
-		g_print ("Is bluetoothd running, and a Bluetooth adapter enabled?\n");
-		return;
-	}
-	bluetooth_client_dump_device (model, &iter, TRUE);
-	while (gtk_tree_model_iter_next (model, &iter))
-		bluetooth_client_dump_device (model, &iter, TRUE);
-}
-
 static GOptionEntry options[] = {
 	{ "debug", 'd', 0, G_OPTION_ARG_NONE, &option_debug, N_("Debug"), NULL },
-	{ "dump-devices", 'u', 0, G_OPTION_ARG_NONE, &option_dump, N_("Output a list of currently known devices"), NULL },
 	{ NULL },
 };
 
@@ -1128,11 +982,6 @@ int main(int argc, char *argv[])
 		return 1;
 	}
 
-	if (option_dump != FALSE) {
-		dump_devices ();
-		return 0;
-	}
-
 	if (option_debug == FALSE) {
 		app = gtk_application_new ("org.gnome.Bluetooth.applet",
 					   &argc, &argv);
@@ -1149,34 +998,23 @@ int main(int argc, char *argv[])
 
 	gtk_window_set_default_icon_name("bluetooth");
 
-	killswitch = bluetooth_killswitch_new ();
-	g_signal_connect (G_OBJECT (killswitch), "state-changed",
-			  G_CALLBACK (killswitch_state_changed), NULL);
+	applet = g_object_new (BLUETOOTH_TYPE_APPLET, NULL);
+	g_signal_connect (G_OBJECT (applet), "notify::killswitch-state",
+			G_CALLBACK (killswitch_state_changed), NULL);
 
 	menu = create_popupmenu();
 
-	client = bluetooth_client_new();
+	g_signal_connect (G_OBJECT (applet), "devices-changed",
+			G_CALLBACK (update_device_list), NULL);
+	g_signal_connect (G_OBJECT (applet), "notify::discoverable",
+			G_CALLBACK (update_discoverability), NULL);
+	g_signal_connect (G_OBJECT (applet), "notify::show-full-menu",
+			G_CALLBACK (update_menu_items), NULL);
 
-	devices_model = bluetooth_client_get_model(client);
-
-	g_signal_connect(G_OBJECT(devices_model), "row-inserted",
-			 G_CALLBACK(device_added), NULL);
-	g_signal_connect(G_OBJECT(devices_model), "row-deleted",
-			 G_CALLBACK(device_removed), NULL);
-	g_signal_connect (G_OBJECT (devices_model), "row-changed",
-			  G_CALLBACK (device_changed), NULL);
-
-	/* Set the default adapter */
-	device_changed (devices_model, NULL, NULL, NULL);
-	if (bluetooth_killswitch_has_killswitches (killswitch) != FALSE) {
-		killswitch_state_changed (killswitch,
-					  bluetooth_killswitch_get_state (killswitch));
-	}
-
-	/* Make sure all the unblocked adapters are powered,
-	 * so as to avoid seeing unpowered, but unblocked
-	 * devices */
-	bluetooth_set_adapter_powered ();
+	killswitch_state_changed ((GObject*) applet, NULL, NULL);
+	update_menu_items ((GObject*) applet, NULL, NULL);
+	update_discoverability ((GObject*) applet, NULL, NULL);
+	update_device_list (applet, NULL);
 
 	settings = g_settings_new (SCHEMA_NAME);
 	show_icon_pref = g_settings_get_boolean (settings, PREF_SHOW_ICON);
@@ -1193,7 +1031,7 @@ int main(int argc, char *argv[])
 	g_signal_connect(statusicon, "popup-menu",
 				G_CALLBACK(popup_callback), menu);
 
-	setup_agents();
+	setup_agents(applet);
 
 	gtk_main();
 
@@ -1201,13 +1039,9 @@ int main(int argc, char *argv[])
 
 	g_object_unref(settings);
 
-	cleanup_agents();
-
 	cleanup_notification();
 
-	g_object_unref(devices_model);
-
-	g_object_unref(client);
+	g_object_unref(applet);
 
 	if (app != NULL)
 		g_object_unref (app);
diff --git a/applet/notify.c b/applet/notify.c
index 70ad3a2..adccbb3 100644
--- a/applet/notify.c
+++ b/applet/notify.c
@@ -168,22 +168,3 @@ void set_icon(gboolean enabled)
 		gtk_status_icon_set_tooltip_markup(statusicon, _tooltip);
 	}
 }
-
-void enable_blinking(void)
-{
-	/* FIXME
-	gtk_status_icon_set_blinking(statusicon, TRUE); */
-}
-
-void disable_blinking(void)
-{
-	/* FIXME
-	gtk_status_icon_set_blinking(statusicon, FALSE); */
-}
-
-gboolean query_blinking(void)
-{
-	/* FIXME
-	 * return gtk_status_icon_get_blinking(statusicon); */
-	return FALSE;
-}
diff --git a/applet/notify.h b/applet/notify.h
index 9ee5cb8..ac75823 100644
--- a/applet/notify.h
+++ b/applet/notify.h
@@ -33,7 +33,3 @@ void close_notification(void);
 void show_icon(void);
 void hide_icon(void);
 void set_icon(gboolean enabled);
-
-void enable_blinking(void);
-void disable_blinking(void);
-gboolean query_blinking(void);
diff --git a/applet/test-agentdialog.c b/applet/test-agentdialog.c
index d2506d5..7d2acdf 100644
--- a/applet/test-agentdialog.c
+++ b/applet/test-agentdialog.c
@@ -21,6 +21,7 @@
  *
  */
 
+#include <lib/bluetooth-applet.h>
 #include "agent.c"
 #include "notify.h"
 
@@ -32,9 +33,7 @@ static void activate_callback(GObject *widget, gpointer user_data)
 int main(int argc, char *argv[])
 {
 	GtkStatusIcon *statusicon;
-	DBusGConnection *conn;
-	DBusGProxy *adapter, *device;
-	GError *error = NULL;
+	BluetoothApplet *applet;
 
 	bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
@@ -44,13 +43,7 @@ int main(int argc, char *argv[])
 
 	gtk_window_set_default_icon_name("bluetooth");
 
-	conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
-	if (error != NULL) {
-		g_printerr("Connecting to system bus failed: %s\n",
-							error->message);
-		g_error_free(error);
-		return 1;
-	}
+	applet = g_object_new (BLUETOOTH_TYPE_APPLET, NULL);
 
 	set_icon (TRUE);
 	statusicon = init_notification();
@@ -58,29 +51,17 @@ int main(int argc, char *argv[])
 	g_signal_connect(statusicon, "activate",
 				G_CALLBACK(activate_callback), NULL);
 
-	setup_agents();
+	setup_agents(applet);
 
-	adapter = dbus_g_proxy_new_for_name(conn, "org.bluez",
-						"/hci0", "org.bluez.Adapter");
-
-	device = dbus_g_proxy_new_from_proxy(adapter,
-			"/hci0/dev_11_22_33_44_55_66", "org.bluez.Device");
-
-	//display_dialog(adapter, device, "Test (00:11:22:33:44:55)", "123456", 0, NULL);
-	pin_dialog(adapter, device, "Test", "'Test' (00:11:22:33:44:55)", FALSE, NULL);
-	confirm_dialog(adapter, device, "Test", "'Test' (00:11:22:33:44:55)", "123456", NULL);
-	auth_dialog(adapter, device, "Test", "'Test' (00:11:22:33:44:55)", "UUID", NULL);
+	pin_dialog(applet, "/hci0/dev_11_22_33_44_55_66", "Test", "'Test' (00:11:22:33:44:55)", FALSE);
+	confirm_dialog(applet, "/hci0/dev_11_22_33_44_55_66", "Test", "'Test' (00:11:22:33:44:55)", "123456");
+	auth_dialog(applet, "/hci0/dev_11_22_33_44_55_66", "Test", "'Test' (00:11:22:33:44:55)", "UUID");
 
 	gtk_main();
 
-	g_object_unref(device);
-	g_object_unref(adapter);
+	g_object_unref(applet);
 
 	cleanup_notification();
 
-	cleanup_agents();
-
-	dbus_g_connection_unref(conn);
-
 	return 0;
 }



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