[gnome-bluetooth] Use BluetoothClient for tracking the default-adapter



commit c36c9bd7a7601a1fc1f117181f8517b3fa27f221
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Sun Nov 21 17:46:54 2010 +0100

    Use BluetoothClient for tracking the default-adapter
    
    BluetoothClient already does all the work of tracking what adapter
    is the default, and whether it is powered or not.
    There is no need to duplicate that, and also we avoid searching
    the default adapter more often than needed, with the side effect
    of unregistering the agent (possibly in the middle of a transaction,
    making it just fail).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=635023

 applet/bluetooth-applet.c |  181 ++++++++++++++++++++-----------------------
 lib/bluetooth-client.c    |  191 +++++++++++++++++++++++++++++++++------------
 lib/bluetooth-client.h    |    2 +
 3 files changed, 226 insertions(+), 148 deletions(-)
---
diff --git a/applet/bluetooth-applet.c b/applet/bluetooth-applet.c
index 71b5a7d..b9d32ad 100644
--- a/applet/bluetooth-applet.c
+++ b/applet/bluetooth-applet.c
@@ -70,8 +70,11 @@ struct _BluetoothApplet
 
 	BluetoothKillswitch* killswitch_manager;
 	BluetoothClient* client;
-	GtkTreeModel* client_model;
-	GtkTreeIter* default_adapter;
+	GtkTreeModel* device_model;
+	gulong signal_row_added;
+	gulong signal_row_changed;
+	gulong signal_row_deleted;
+	DBusGProxy* default_adapter;
 	BluetoothAgent* agent;
 	GHashTable* pending_requests;
 
@@ -548,95 +551,91 @@ cancel_request(DBusGMethodInvocation *context,
 	return TRUE;
 }
 
-
 static void
-find_default_adapter (BluetoothApplet* self)
+device_added_or_changed (GtkTreeModel *model,
+			 GtkTreePath  *path,
+			 GtkTreeIter  *iter,
+			 gpointer      data)
 {
-	GtkTreeIter iter;
-	gboolean cont;
+	BluetoothApplet *self = BLUETOOTH_APPLET (data);
 
-	if (self->default_adapter) {
-		gtk_tree_iter_free (self->default_adapter);
-		self->default_adapter = NULL;
-	}
-	if (self->agent) {
-		g_object_unref (self->agent);
-		self->agent = NULL;
-	}
-	self->num_adapters_present = self->num_adapters_powered = 0;
+	g_signal_emit (self, signals[SIGNAL_DEVICES_CHANGED], 0);
+}
 
-	cont = gtk_tree_model_get_iter_first (self->client_model, &iter);
-	while (cont) {
-		gboolean is_default, powered;
+static void
+device_removed (GtkTreeModel *model,
+	        GtkTreePath *path,
+	        gpointer user_data)
+{
+	device_added_or_changed (model, path, NULL, user_data);
+}
 
-		self->num_adapters_present++;
+static void
+default_adapter_changed (GObject    *client,
+			 GParamSpec *spec,
+			 gpointer    data)
+{
+	BluetoothApplet* self = BLUETOOTH_APPLET (data);
 
-		gtk_tree_model_get (self->client_model, &iter,
-				    BLUETOOTH_COLUMN_DEFAULT, &is_default,
-				    BLUETOOTH_COLUMN_POWERED, &powered,
-				    -1);
-		if (powered)
-			self->num_adapters_powered++;
-		if (is_default && powered)
-			self->default_adapter = gtk_tree_iter_copy (&iter);
+	if (self->default_adapter)
+		g_object_unref (self->default_adapter);
+	self->default_adapter = bluetooth_client_get_default_adapter (self->client);
 
-		cont = gtk_tree_model_iter_next (self->client_model, &iter);
+	if (self->device_model) {
+		g_signal_handler_disconnect (self->device_model, self->signal_row_added);
+		g_signal_handler_disconnect (self->device_model, self->signal_row_changed);
+		g_signal_handler_disconnect (self->device_model, self->signal_row_deleted);
+		g_object_unref (self->device_model);
+	}
+	if (self->default_adapter)
+		self->device_model = bluetooth_client_get_device_model (self->client, self->default_adapter);
+
+	if (self->device_model) {
+		self->signal_row_added = g_signal_connect (self->device_model, "row-inserted",
+							   G_CALLBACK(device_added_or_changed), self);
+		self->signal_row_deleted = g_signal_connect (self->device_model, "row-deleted",
+							     G_CALLBACK(device_removed), self);
+		self->signal_row_changed = g_signal_connect (self->device_model, "row-changed",
+							     G_CALLBACK (device_added_or_changed), self);
 	}
 
-	if (self->default_adapter) {
-		DBusGProxy* adapter;
-
-		gtk_tree_model_get (self->client_model, self->default_adapter,
-				    BLUETOOTH_COLUMN_PROXY, &adapter, -1);
-
-		self->agent = bluetooth_agent_new();
+	if (self->agent)
+		g_object_unref (self->agent);
 
-		/* This makes sure that the agent is NULL when released */
-		g_object_add_weak_pointer (G_OBJECT (self->agent), (gpointer *) (&self->agent));
+	if (self->default_adapter) {
+		self->agent = bluetooth_agent_new ();
+		g_object_add_weak_pointer (G_OBJECT (self->agent), (void**) &(self->agent));
 
 		bluetooth_agent_set_pincode_func (self->agent, pincode_request, self);
 		bluetooth_agent_set_passkey_func (self->agent, passkey_request, self);
-		bluetooth_agent_set_confirm_func (self->agent, confirm_request, self);
 		bluetooth_agent_set_authorize_func (self->agent, authorize_request, self);
+		bluetooth_agent_set_confirm_func (self->agent, confirm_request, self);
 		bluetooth_agent_set_cancel_func (self->agent, cancel_request, self);
 
-		bluetooth_agent_register (self->agent, adapter);
-
-		g_object_unref (adapter);
+		bluetooth_agent_register (self->agent, self->default_adapter);
 	}
+
+	g_signal_emit (self, signals[SIGNAL_DEVICES_CHANGED], 0);
 }
 
 static void
-device_added_or_changed (GtkTreeModel *model,
-                         GtkTreePath  *path,
-                         GtkTreeIter  *iter,
-                         gpointer      data)
+default_adapter_powered_changed (GObject    *client,
+				 GParamSpec *spec,
+				 gpointer    data)
 {
-	BluetoothApplet* self = BLUETOOTH_APPLET (data);
-
-	gboolean prev_visibility = bluetooth_applet_get_discoverable (self);
-	gint prev_num_adapters_powered = self->num_adapters_powered;
-	gint prev_num_adapters_present = self->num_adapters_present;
-
-	find_default_adapter (self);
+        BluetoothApplet *self = BLUETOOTH_APPLET (data);
 
-	if (bluetooth_applet_get_discoverable (self) != prev_visibility)
-		g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DISCOVERABLE]);
-	if (prev_num_adapters_powered != self->num_adapters_powered ||
-	    prev_num_adapters_present != self->num_adapters_present) {
-		g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_KILLSWITCH_STATE]);
-		g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FULL_MENU]);
-	}
-
-	g_signal_emit (self, signals[SIGNAL_DEVICES_CHANGED], 0);
+	g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FULL_MENU]);
 }
 
 static void
-device_removed(GtkTreeModel *model,
-			   GtkTreePath *path,
-			   gpointer user_data)
+default_adapter_discoverable_changed (GObject    *client,
+				 GParamSpec *spec,
+				 gpointer    data)
 {
-	device_added_or_changed (model, path, NULL, user_data);
+        BluetoothApplet *self = BLUETOOTH_APPLET (data);
+
+	g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DISCOVERABLE]);
 }
 
 static gboolean
@@ -783,18 +782,9 @@ bluetooth_applet_disconnect_device (BluetoothApplet* applet,
 gboolean
 bluetooth_applet_get_discoverable (BluetoothApplet* self)
 {
-	gboolean res = FALSE;
-
 	g_return_val_if_fail (BLUETOOTH_IS_APPLET (self), FALSE);
 
-	if (self->default_adapter == NULL)
-		return FALSE;
-
-	gtk_tree_model_get (self->client_model, self->default_adapter,
-			BLUETOOTH_COLUMN_DISCOVERABLE, &res,
-			-1);
-
-	return res;
+       	return bluetooth_client_get_discoverable (self->client);
 }
 
 /**
@@ -862,14 +852,17 @@ bluetooth_applet_set_killswitch_state (BluetoothApplet* self, BluetoothKillswitc
 gboolean
 bluetooth_applet_get_show_full_menu (BluetoothApplet* self)
 {
-
+	gboolean has_adapter, has_powered_adapter;
 	g_return_val_if_fail (BLUETOOTH_IS_APPLET (self), FALSE);
 
-	if (self->num_adapters_present == 0)
+	has_adapter = self->default_adapter != NULL;
+	g_object_get (G_OBJECT (self->client), "default-adapter-powered", &has_powered_adapter, NULL);
+
+	if (!has_adapter)
 		return FALSE;
 
-	return (self->num_adapters_present <= self->num_adapters_powered) &&
-		(bluetooth_applet_get_killswitch_state(self) == BLUETOOTH_KILLSWITCH_STATE_UNBLOCKED);
+	return has_powered_adapter &&
+		bluetooth_applet_get_killswitch_state(self) == BLUETOOTH_KILLSWITCH_STATE_UNBLOCKED;
 }
 
 static BluetoothSimpleDevice *
@@ -960,16 +953,16 @@ bluetooth_applet_get_devices (BluetoothApplet* self)
 	if (self->default_adapter == NULL)
 		return NULL;
 
-	cont = gtk_tree_model_iter_children (self->client_model, &iter, self->default_adapter);
+	cont = gtk_tree_model_get_iter_first (self->device_model, &iter);
 	while (cont) {
 		BluetoothSimpleDevice *dev;
 
-		dev = bluetooth_applet_create_device_from_iter (self->client_model, &iter, TRUE);
+		dev = bluetooth_applet_create_device_from_iter (self->device_model, &iter, TRUE);
 
 		if (dev != NULL)
 			result = g_list_prepend (result, dev);
 
-		cont = gtk_tree_model_iter_next(self->client_model, &iter);
+		cont = gtk_tree_model_iter_next (self->device_model, &iter);
 	}
 
 	result = g_list_reverse (result);
@@ -1021,10 +1014,8 @@ bluetooth_applet_set_property (GObject      *gobj,
 static void
 bluetooth_applet_init (BluetoothApplet *self)
 {
-	GObject* gobject_client_model = NULL;
-
 	self->client = bluetooth_client_new ();
-	self->client_model = bluetooth_client_get_model (self->client);
+	self->device_model = NULL;
 
 	self->default_adapter = NULL;
 	self->agent = NULL;
@@ -1039,15 +1030,11 @@ bluetooth_applet_init (BluetoothApplet *self)
 	 * so as to avoid seeing unpowered, but unblocked
 	 * devices */
 	set_adapter_powered (self);
-	find_default_adapter (self);
-
-	gobject_client_model = G_OBJECT (self->client_model);
-	g_signal_connect(gobject_client_model, "row-inserted",
-			 G_CALLBACK(device_added_or_changed), self);
-	g_signal_connect(gobject_client_model, "row-deleted",
-			 G_CALLBACK(device_removed), self);
-	g_signal_connect (gobject_client_model, "row-changed",
-			  G_CALLBACK (device_added_or_changed), self);
+	default_adapter_changed (NULL, NULL, self);
+
+	g_signal_connect (self->client, "notify::default-adapter", G_CALLBACK (default_adapter_changed), self);
+	g_signal_connect (self->client, "notify::default-adapter-powered", G_CALLBACK (default_adapter_powered_changed), self);
+	g_signal_connect (self->client, "notify::default-adapter-discoverable", G_CALLBACK (default_adapter_discoverable_changed), self);
 }
 
 static void
@@ -1066,9 +1053,9 @@ bluetooth_applet_dispose (GObject* self)
 		applet->killswitch_manager = NULL;
 	}
 
-	if (applet->client_model) {
-		g_object_unref (applet->client_model);
-		applet->client_model = NULL;
+	if (applet->device_model) {
+		g_object_unref (applet->device_model);
+		applet->device_model = NULL;
 	}
 
 	if (applet->agent) {
diff --git a/lib/bluetooth-client.c b/lib/bluetooth-client.c
index 156ce2f..301b868 100644
--- a/lib/bluetooth-client.c
+++ b/lib/bluetooth-client.c
@@ -3,6 +3,7 @@
  *  BlueZ - Bluetooth protocol stack for Linux
  *
  *  Copyright (C) 2005-2008  Marcel Holtmann <marcel holtmann org>
+ *  Copyright (C) 2010       Giovanni Campagna <scampa giovanni gmail com>
  *
  *
  *  This library is free software; you can redistribute it and/or
@@ -100,14 +101,14 @@ struct _BluetoothClientPrivate {
 	DBusGProxy *dbus;
 	DBusGProxy *manager;
 	GtkTreeStore *store;
-	char *default_adapter;
-	gboolean default_adapter_powered;
+	GtkTreeRowReference *default_adapter;
 };
 
 enum {
 	PROP_0,
 	PROP_DEFAULT_ADAPTER,
 	PROP_DEFAULT_ADAPTER_POWERED,
+	PROP_DEFAULT_ADAPTER_DISCOVERABLE,
 };
 
 G_DEFINE_TYPE(BluetoothClient, bluetooth_client, G_TYPE_OBJECT)
@@ -905,15 +906,19 @@ static void adapter_changed(DBusGProxy *adapter, const char *property,
 				   BLUETOOTH_COLUMN_POWERED, powered, -1);
 		gtk_tree_model_get(GTK_TREE_MODEL(priv->store), &iter,
 				   BLUETOOTH_COLUMN_DEFAULT, &is_default, -1);
-		if (is_default != FALSE && powered != priv->default_adapter_powered) {
-			priv->default_adapter_powered = powered;
+		if (is_default != FALSE)
 			g_object_notify (G_OBJECT (client), "default-adapter-powered");
-		}
+		notify = TRUE;
 	} else if (g_str_equal(property, "Discoverable") == TRUE) {
 		gboolean discoverable = g_value_get_boolean(value);
+		gboolean is_default;
 
 		gtk_tree_store_set(priv->store, &iter,
-				BLUETOOTH_COLUMN_DISCOVERABLE, discoverable, -1);
+				   BLUETOOTH_COLUMN_DISCOVERABLE, discoverable, -1);
+		gtk_tree_model_get(GTK_TREE_MODEL(priv->store), &iter,
+				   BLUETOOTH_COLUMN_DEFAULT, &is_default, -1);
+		if (is_default != FALSE)
+			g_object_notify (G_OBJECT (client), "default-adapter-discoverable");
 		notify = TRUE;
 	}
 
@@ -1031,10 +1036,11 @@ static void adapter_removed(DBusGProxy *manager,
 	while (cont == TRUE) {
 		DBusGProxy *adapter;
 		const char *adapter_path;
-		gboolean found;
+		gboolean found, was_default;
 
 		gtk_tree_model_get(GTK_TREE_MODEL(priv->store), &iter,
-					BLUETOOTH_COLUMN_PROXY, &adapter, -1);
+				   BLUETOOTH_COLUMN_PROXY, &adapter,
+				   BLUETOOTH_COLUMN_DEFAULT, &was_default, -1);
 
 		adapter_path = dbus_g_proxy_get_path(adapter);
 
@@ -1053,22 +1059,20 @@ static void adapter_removed(DBusGProxy *manager,
 		g_object_unref(adapter);
 
 		if (found == TRUE) {
-			cont = gtk_tree_store_remove(priv->store, &iter);
-			continue;
+			if (was_default) {
+				gtk_tree_row_reference_free (priv->default_adapter);
+				priv->default_adapter = NULL;
+				g_object_notify (G_OBJECT (client), "default-adapter");
+				g_object_notify (G_OBJECT (client), "default-adapter-powered");
+				g_object_notify (G_OBJECT (client), "default-adapter-discoverable");
+			}
+			gtk_tree_store_remove(priv->store, &iter);
+			break;
 		}
 
 		cont = gtk_tree_model_iter_next(GTK_TREE_MODEL(priv->store),
 									&iter);
 	}
-
-	/* No adapters left in the tree? */
-	if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL(priv->store), NULL) == 0) {
-		g_free(priv->default_adapter);
-		priv->default_adapter = NULL;
-		priv->default_adapter_powered = FALSE;
-		g_object_notify (G_OBJECT (client), "default-adapter");
-		g_object_notify (G_OBJECT (client), "default-adapter-powered");
-	}
 }
 
 static void default_adapter_changed(DBusGProxy *manager,
@@ -1083,6 +1087,10 @@ static void default_adapter_changed(DBusGProxy *manager,
 
 	cont = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(priv->store),
 									&iter);
+	if (priv->default_adapter) {
+		gtk_tree_row_reference_free (priv->default_adapter);
+		priv->default_adapter = NULL;
+	}
 
 	while (cont == TRUE) {
 		DBusGProxy *adapter;
@@ -1099,8 +1107,11 @@ static void default_adapter_changed(DBusGProxy *manager,
 
 		g_object_unref(adapter);
 
-		if (found != FALSE)
-			priv->default_adapter_powered = powered;
+		if (found != FALSE) {
+			GtkTreePath *tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->store), &iter);
+			priv->default_adapter = gtk_tree_row_reference_new (GTK_TREE_MODEL (priv->store), tree_path);
+			gtk_tree_path_free (tree_path);
+		}
 
 		gtk_tree_store_set(priv->store, &iter,
 					BLUETOOTH_COLUMN_DEFAULT, found, -1);
@@ -1110,10 +1121,9 @@ static void default_adapter_changed(DBusGProxy *manager,
 	}
 
 	/* Record the new default adapter */
-	g_free(priv->default_adapter);
-	priv->default_adapter = g_strdup(path);
 	g_object_notify (G_OBJECT (client), "default-adapter");
 	g_object_notify (G_OBJECT (client), "default-adapter-powered");
+	g_object_notify (G_OBJECT (client), "default-adapter-discoverable");
 }
 
 static void name_owner_changed(DBusGProxy *dbus, const char *name,
@@ -1129,6 +1139,11 @@ static void name_owner_changed(DBusGProxy *dbus, const char *name,
 
 	DBG("client %p name %s", client, name);
 
+	if (priv->default_adapter) {
+		gtk_tree_row_reference_free (priv->default_adapter);
+		priv->default_adapter = NULL;
+	}
+
 	cont = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(priv->store),
 									&iter);
 
@@ -1196,20 +1211,72 @@ static void bluetooth_client_init(BluetoothClient *client)
 	}
 }
 
+static const char*
+_bluetooth_client_get_default_adapter_path (BluetoothClient *self)
+{
+	DBusGProxy *adapter = bluetooth_client_get_default_adapter (self);
+
+	if (adapter != NULL) {
+		const char *ret = dbus_g_proxy_get_path (adapter);
+		g_object_unref (adapter);
+		return ret;
+	}
+	return NULL;
+}
+
+static gboolean
+_bluetooth_client_get_default_adapter_powered (BluetoothClient *self)
+{
+	BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE (self);
+	GtkTreePath *path;
+	GtkTreeIter iter;
+	gboolean ret;
+
+	if (priv->default_adapter == NULL)
+		return FALSE;
+
+	path = gtk_tree_row_reference_get_path (priv->default_adapter);
+	gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->store), &iter, path);
+	gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter, BLUETOOTH_COLUMN_POWERED, &ret, -1);
+	
+	return ret;
+}
+
 static void
 bluetooth_client_get_property (GObject        *object,
 			       guint           property_id,
 			       GValue         *value,
 			       GParamSpec     *pspec)
 {
-	BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(object);
+	BluetoothClient *self = BLUETOOTH_CLIENT (object);
 
 	switch (property_id) {
 	case PROP_DEFAULT_ADAPTER:
-		g_value_set_string (value, priv->default_adapter);
+		g_value_set_string (value, _bluetooth_client_get_default_adapter_path (self));
 		break;
 	case PROP_DEFAULT_ADAPTER_POWERED:
-		g_value_set_boolean (value, priv->default_adapter_powered);
+		g_value_set_boolean (value, _bluetooth_client_get_default_adapter_powered (self));
+		break;
+	case PROP_DEFAULT_ADAPTER_DISCOVERABLE:
+		g_value_set_boolean (value, bluetooth_client_get_discoverable (self));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+		break;
+	}
+}
+
+static void
+bluetooth_client_set_property (GObject        *object,
+			       guint           property_id,
+			       const GValue   *value,
+			       GParamSpec     *pspec)
+{
+	BluetoothClient *self = BLUETOOTH_CLIENT (object);
+
+	switch (property_id) {
+	case PROP_DEFAULT_ADAPTER_DISCOVERABLE:
+	        bluetooth_client_set_discoverable (self, g_value_get_boolean (value), 0);
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
@@ -1237,8 +1304,8 @@ static void bluetooth_client_finalize(GObject *client)
 
 	g_object_unref(priv->store);
 
-	g_free (priv->default_adapter);
-	priv->default_adapter = NULL;
+	if (priv->default_adapter)
+		gtk_tree_row_reference_free (priv->default_adapter);
 
 	G_OBJECT_CLASS(bluetooth_client_parent_class)->finalize(client);
 }
@@ -1254,7 +1321,7 @@ static void bluetooth_client_class_init(BluetoothClientClass *klass)
 
 	object_class->finalize = bluetooth_client_finalize;
 	object_class->get_property = bluetooth_client_get_property;
-
+	object_class->set_property = bluetooth_client_set_property;
 
 	g_object_class_install_property (object_class, PROP_DEFAULT_ADAPTER,
 					 g_param_spec_string ("default-adapter", NULL, NULL,
@@ -1262,6 +1329,9 @@ static void bluetooth_client_class_init(BluetoothClientClass *klass)
 	g_object_class_install_property (object_class, PROP_DEFAULT_ADAPTER_POWERED,
 					 g_param_spec_boolean ("default-adapter-powered", NULL, NULL,
 					 		       FALSE, G_PARAM_READABLE));
+	g_object_class_install_property (object_class, PROP_DEFAULT_ADAPTER_DISCOVERABLE,
+					 g_param_spec_boolean ("default-adapter-discoverable", NULL, NULL,
+							       FALSE, G_PARAM_READWRITE));
 
 	dbus_g_object_register_marshaller(marshal_VOID__STRING_BOXED,
 						G_TYPE_NONE, G_TYPE_STRING,
@@ -1281,7 +1351,7 @@ static void bluetooth_client_class_init(BluetoothClientClass *klass)
  *
  * Returns a reference to the #BluetoothClient singleton. Use #g_object_unref() the object when done.
  *
- * Return value: a #BluetoothClient object.
+ * Return value: (transfer full): a #BluetoothClient object.
  **/
 BluetoothClient *bluetooth_client_new(void)
 {
@@ -1486,39 +1556,28 @@ GtkTreeModel *bluetooth_client_get_device_filter_model(BluetoothClient *client,
  *
  * Returns a #DBusGProxy object representing the default adapter, or %NULL if no adapters are present.
  *
- * Return value: a #DBusGProxy object.
+ * Return value: (transfer full): a #DBusGProxy object.
  **/
 DBusGProxy *bluetooth_client_get_default_adapter(BluetoothClient *client)
 {
 	BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
+	GtkTreePath *path;
 	GtkTreeIter iter;
-	gboolean cont;
+	DBusGProxy *adapter;
 
 	g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), NULL);
 
 	DBG("client %p", client);
 
-	cont = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(priv->store),
-									&iter);
-
-	while (cont == TRUE) {
-		DBusGProxy *adapter;
-		gboolean is_default;
-
-		gtk_tree_model_get(GTK_TREE_MODEL(priv->store), &iter,
-				BLUETOOTH_COLUMN_PROXY, &adapter,
-				BLUETOOTH_COLUMN_DEFAULT, &is_default, -1);
-
-		if (is_default == TRUE)
-			return adapter;
+	if (priv->default_adapter == NULL)
+		return NULL;
 
-		g_object_unref(adapter);
+	path = gtk_tree_row_reference_get_path (priv->default_adapter);
+	gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->store), &iter, path);
+	gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter,
+			    BLUETOOTH_COLUMN_PROXY, &adapter, -1);
 
-		cont = gtk_tree_model_iter_next(GTK_TREE_MODEL(priv->store),
-									&iter);
-	}
-
-	return NULL;
+	return adapter;
 }
 
 /**
@@ -1576,6 +1635,36 @@ gboolean bluetooth_client_stop_discovery(BluetoothClient *client)
 }
 
 /**
+ * bluetooth_client_get_discoverable:
+ * @client: a #BluetoothClient
+ *
+ * Gets the default adapter's discoverable status, cached in the adapter model.
+ *
+ * Returns: the discoverable status, or FALSE if no default adapter exists
+ */
+gboolean
+bluetooth_client_get_discoverable (BluetoothClient *client)
+{
+	BluetoothClientPrivate *priv;
+	GtkTreePath *path;
+	GtkTreeIter iter;
+	gboolean ret;
+
+	g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), FALSE);
+
+	priv = BLUETOOTH_CLIENT_GET_PRIVATE (client);
+	if (priv->default_adapter == NULL)
+		return FALSE;
+
+	path = gtk_tree_row_reference_get_path (priv->default_adapter);
+	gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->store), &iter, path);
+	gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter,
+                            BLUETOOTH_COLUMN_DISCOVERABLE, &ret, -1);
+
+	return ret;
+}
+
+/**
  * bluetooth_client_set_discoverable:
  * @client: a #BluetoothClient object
  * @discoverable: whether the device should be discoverable
diff --git a/lib/bluetooth-client.h b/lib/bluetooth-client.h
index d375d27..e3e1f75 100644
--- a/lib/bluetooth-client.h
+++ b/lib/bluetooth-client.h
@@ -70,6 +70,8 @@ GtkTreeModel *bluetooth_client_get_device_filter_model(BluetoothClient *client,
 		DBusGProxy *adapter, GtkTreeModelFilterVisibleFunc func,
 				gpointer data, GDestroyNotify destroy);
 
+gboolean bluetooth_client_get_discoverable (BluetoothClient *client);
+
 const gchar *bluetooth_type_to_string(guint type);
 gboolean bluetooth_verify_address (const char *bdaddr);
 const char *bluetooth_uuid_to_string (const char *uuid);



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