All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bastien Nocera <hadess@hadess.net>
To: BlueZ Hackers <bluez-devel@lists.sourceforge.net>
Subject: [Bluez-devel] [PATCH] bluez-gnome: "search" button for the device selection
Date: Thu, 26 Jul 2007 19:49:16 +0100	[thread overview]
Message-ID: <1185475756.3641.329.camel@cookie.hadess.net> (raw)

[-- Attachment #1: Type: text/plain, Size: 342 bytes --]

For comments (but pretty much finished), to give you an idea of the way
it'd work. The search button starts a discovery on the default adapter,
and becomes unsensitive.

The search button becomes sensitive again when all discoveries
(including those possibly launched on other adapters) are finished.

-- 
Bastien Nocera <hadess@hadess.net> 

[-- Attachment #2: bluez-gnome-implement-search-button.patch --]
[-- Type: text/x-patch, Size: 13565 bytes --]

Index: bluetooth-device-selection.c
===================================================================
RCS file: /cvsroot/bluez/gnome/common/bluetooth-device-selection.c,v
retrieving revision 1.3
diff -u -p -r1.3 bluetooth-device-selection.c
--- bluetooth-device-selection.c	25 Jul 2007 18:01:44 -0000	1.3
+++ bluetooth-device-selection.c	26 Jul 2007 18:16:41 -0000
@@ -52,6 +52,13 @@ struct _BluetoothDeviceSelectionPrivate 
 	GtkTreeSelection *selection;
 	GtkTreeModel *model;
 	GtkWidget *label;
+
+	/* Widgets/UI bits that can be shown or hidden */
+	GtkCellRenderer *bonded_cell;
+	GtkWidget *search_button;
+
+	guint show_bonded : 1;
+	guint show_search : 1;
 };
 
 G_DEFINE_TYPE(BluetoothDeviceSelection, bluetooth_device_selection, GTK_TYPE_VBOX)
@@ -70,7 +77,7 @@ name_to_text (GtkTreeViewColumn *column,
 	 * Bluetooth address, with the ":" replaced by "-" */
 	if (name == NULL) {
 		name = g_strdup (address);
-		g_strdelimit (address, ":", '-');
+		g_strdelimit (name, ":", '-');
 	}
 
 	g_object_set (cell, "text", name ? name : address, NULL);
@@ -122,6 +129,20 @@ type_to_icon (GtkTreeViewColumn *column,
 }
 
 static void
+bonded_to_icon (GtkTreeViewColumn *column, GtkCellRenderer *cell,
+	      GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
+{
+	gboolean bonded;
+
+	gtk_tree_model_get (model, iter, COLUMN_BONDED, &bonded, -1);
+
+	if (bonded == FALSE)
+		g_object_set (cell, "stock-id", NULL, NULL);
+	else
+		g_object_set (cell, "stock-id", GTK_STOCK_DIALOG_AUTHENTICATION, NULL);
+}
+
+static void
 type_to_text (GtkTreeViewColumn *column, GtkCellRenderer *cell,
 	      GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
 {
@@ -132,6 +153,15 @@ type_to_text (GtkTreeViewColumn *column,
 	g_object_set (cell, "text", bluetooth_type_to_string (type), NULL);
 }
 
+void
+bluetooth_device_start_discovery (BluetoothDeviceSelection *self)
+{
+	BluetoothDeviceSelectionPrivate *priv = BLUETOOTH_DEVICE_SELECTION_GET_PRIVATE(self);
+
+	gtk_widget_set_sensitive (GTK_WIDGET(priv->search_button), FALSE);
+	bluetooth_client_discover_devices (priv->client, NULL);
+}
+
 gchar *
 bluetooth_device_selection_get_selected_device (BluetoothDeviceSelection *self)
 {
@@ -149,6 +179,23 @@ bluetooth_device_selection_get_selected_
 }
 
 static void
+search_button_clicked (GtkButton *button, gpointer user_data)
+{
+	BluetoothDeviceSelection *self = BLUETOOTH_DEVICE_SELECTION(user_data);
+
+	bluetooth_device_start_discovery (self);
+}
+
+static void
+discoveries_completed (BluetoothClient *client, gpointer user_data)
+{
+	BluetoothDeviceSelection *self = BLUETOOTH_DEVICE_SELECTION(user_data);
+	BluetoothDeviceSelectionPrivate *priv = BLUETOOTH_DEVICE_SELECTION_GET_PRIVATE(self);
+
+	gtk_widget_set_sensitive (GTK_WIDGET(priv->search_button), TRUE);
+}
+
+static void
 select_browse_device_callback (GtkTreeSelection *selection, gpointer user_data)
 {
 	BluetoothDeviceSelection *self = user_data;
@@ -166,10 +213,12 @@ static void
 bluetooth_device_selection_init(BluetoothDeviceSelection *self)
 {
 	BluetoothDeviceSelectionPrivate *priv = BLUETOOTH_DEVICE_SELECTION_GET_PRIVATE(self);
-	GtkWidget *tree, *scrolled, *frame, *box;
+	GtkWidget *tree, *scrolled, *frame, *box, *hbox;
 	GtkCellRenderer *renderer;
 	GtkTreeViewColumn *column;
 
+	priv->show_bonded = TRUE;
+
 	gtk_box_set_spacing (GTK_BOX(self), 6);
 	gtk_box_set_homogeneous (GTK_BOX(self), FALSE);
 	gtk_container_set_border_width (GTK_CONTAINER(self), 8);
@@ -184,7 +233,9 @@ bluetooth_device_selection_init(Bluetoot
 
 	priv->client = bluetooth_client_new ();
 
-	//FIXME add a frame around it
+	g_signal_connect (G_OBJECT(priv->client), "discoveries-completed",
+			  G_CALLBACK(discoveries_completed), self);
+
 	/* Create the scrolled window */
 	scrolled = gtk_scrolled_window_new (NULL, NULL);
 
@@ -207,6 +258,7 @@ bluetooth_device_selection_init(Bluetoot
 
 	gtk_tree_view_column_set_title (column, _("Device"));
 
+	/* The type icon */
 	renderer = gtk_cell_renderer_pixbuf_new ();
 	gtk_tree_view_column_set_spacing (column, 4);
 	gtk_tree_view_column_pack_start (column, renderer, FALSE);
@@ -214,12 +266,20 @@ bluetooth_device_selection_init(Bluetoot
 	gtk_tree_view_column_set_cell_data_func (column, renderer,
 						 type_to_icon, NULL, NULL);
 
+	/* The device name */
 	renderer = gtk_cell_renderer_text_new ();
 	gtk_tree_view_column_pack_start (column, renderer, TRUE);
 
 	gtk_tree_view_column_set_cell_data_func (column, renderer,
 						 name_to_text, NULL, NULL);
 
+	/* The bonded icon */
+	priv->bonded_cell = gtk_cell_renderer_pixbuf_new ();
+	gtk_tree_view_column_pack_end (column, priv->bonded_cell, FALSE);
+
+	gtk_tree_view_column_set_cell_data_func (column, priv->bonded_cell,
+						 bonded_to_icon, NULL, NULL);
+
 	gtk_tree_view_append_column (GTK_TREE_VIEW(tree), column);
 
 	gtk_tree_view_column_set_min_width (GTK_TREE_VIEW_COLUMN(column), 280);
@@ -241,10 +301,17 @@ bluetooth_device_selection_init(Bluetoot
 		g_object_unref (priv->model);
 	}
 
-	bluetooth_client_discover_devices (priv->client, NULL);
-
 	gtk_container_add (GTK_CONTAINER(scrolled), tree);
-	gtk_container_add (GTK_CONTAINER(box), scrolled);
+	gtk_box_pack_start (GTK_BOX(box), scrolled, TRUE, TRUE, 6);
+
+	hbox = gtk_hbox_new (FALSE, 0);
+	priv->search_button = gtk_button_new_with_label (_("Search"));
+	g_signal_connect (G_OBJECT(priv->search_button), "clicked",
+			  G_CALLBACK(search_button_clicked), self);
+	gtk_box_pack_start (GTK_BOX(box), hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX(hbox), priv->search_button,
+			    FALSE, FALSE, 0);
+
 	gtk_widget_show_all (scrolled);
 }
 
@@ -259,7 +326,9 @@ bluetooth_device_selection_finalize (GOb
 enum {
 	PROP_0,
 	PROP_TITLE,
-	PROP_DEVICE_SELECTED
+	PROP_DEVICE_SELECTED,
+	PROP_SHOW_BONDING,
+	PROP_SHOW_SEARCH
 };
 
 static void
@@ -281,6 +350,16 @@ bluetooth_device_selection_set_property 
 			g_free (str);
 		}
 		break;
+	case PROP_SHOW_BONDING:
+		priv->show_bonded = g_value_get_boolean (value);
+		if (priv->bonded_cell != NULL)
+			g_object_set (G_OBJECT (priv->bonded_cell), "visible", priv->show_bonded, NULL);
+		break;
+	case PROP_SHOW_SEARCH:
+		priv->show_search = g_value_get_boolean (value);
+		if (priv->search_button != NULL)
+			g_object_set (G_OBJECT (priv->search_button), "visible", priv->show_search, NULL);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
 		break;
@@ -292,11 +371,18 @@ bluetooth_device_selection_get_property 
 					 GValue *value, GParamSpec *pspec)
 {
 	BluetoothDeviceSelection *self = BLUETOOTH_DEVICE_SELECTION(object);
+	BluetoothDeviceSelectionPrivate *priv = BLUETOOTH_DEVICE_SELECTION_GET_PRIVATE(object);
 
 	switch (prop_id) {
 	case PROP_DEVICE_SELECTED:
 		g_value_set_string (value, bluetooth_device_selection_get_selected_device (self));
 		break;
+	case PROP_SHOW_BONDING:
+		g_value_set_boolean (value, priv->show_bonded);
+		break;
+	case PROP_SHOW_SEARCH:
+		g_value_set_boolean (value, priv->show_search);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
 		break;
@@ -328,6 +414,12 @@ bluetooth_device_selection_class_init (B
 	g_object_class_install_property (G_OBJECT_CLASS(klass),
 					 PROP_DEVICE_SELECTED, g_param_spec_string ("device-selected",
 										    NULL, NULL, NULL, G_PARAM_READABLE));
+	g_object_class_install_property (G_OBJECT_CLASS(klass),
+					 PROP_SHOW_BONDING, g_param_spec_boolean ("show-bonding",
+										  NULL, NULL, TRUE, G_PARAM_READWRITE));
+	g_object_class_install_property (G_OBJECT_CLASS(klass),
+					 PROP_SHOW_SEARCH, g_param_spec_boolean ("show-search",
+										 NULL, NULL, TRUE, G_PARAM_READWRITE));
 }
 
 GtkWidget *
Index: bluetooth-device-selection.h
===================================================================
RCS file: /cvsroot/bluez/gnome/common/bluetooth-device-selection.h,v
retrieving revision 1.2
diff -u -p -r1.2 bluetooth-device-selection.h
--- bluetooth-device-selection.h	25 Jul 2007 18:01:44 -0000	1.2
+++ bluetooth-device-selection.h	26 Jul 2007 18:16:42 -0000
@@ -58,6 +58,7 @@ GType bluetooth_device_selection_get_typ
 
 GtkWidget *bluetooth_device_selection_new (const gchar *title);
 gchar *bluetooth_device_selection_get_selected_device (BluetoothDeviceSelection *sel);
+void bluetooth_device_start_discovery (BluetoothDeviceSelection *sel);
 
 G_END_DECLS
 
Index: client.c
===================================================================
RCS file: /cvsroot/bluez/gnome/common/client.c,v
retrieving revision 1.18
diff -u -p -r1.18 client.c
--- client.c	25 Jul 2007 07:43:59 -0000	1.18
+++ client.c	26 Jul 2007 18:16:42 -0000
@@ -48,8 +48,18 @@ typedef struct _BluetoothClientPrivate B
 
 struct _BluetoothClientPrivate {
 	gboolean registered;
+
+	/* The number of discoveries in progress */
+	guint discoveries;
+};
+
+enum {
+	DISCOVERIES_COMPLETED,
+	LAST_SIGNAL
 };
 
+static int client_table_signals[LAST_SIGNAL] = { 0 };
+
 G_DEFINE_TYPE(BluetoothClient, bluetooth_client, G_TYPE_OBJECT)
 
 static void bluetooth_client_init(BluetoothClient *self)
@@ -190,7 +200,7 @@ static void insert_device(DBusGProxy *ob
 	const char *name = NULL;
 	guint type;
 	guint32 class = 0;
-	gboolean trusted = FALSE, connected = FALSE;
+	gboolean bonded = FALSE, connected = FALSE;
 	gboolean cont;
 
 	dbus_g_proxy_call(object, "GetRemoteName", NULL,
@@ -203,7 +213,7 @@ static void insert_device(DBusGProxy *ob
 
 	dbus_g_proxy_call(object, "HasBonding", NULL,
 				G_TYPE_STRING, address, G_TYPE_INVALID,
-				G_TYPE_BOOLEAN, &trusted, G_TYPE_INVALID);
+				G_TYPE_BOOLEAN, &bonded, G_TYPE_INVALID);
 
 	dbus_g_proxy_call(object, "IsConnected", NULL,
 				G_TYPE_STRING, address, G_TYPE_INVALID,
@@ -227,7 +237,7 @@ static void insert_device(DBusGProxy *ob
 						COLUMN_RSSI, rssi,
 						COLUMN_NAME, name,
 						COLUMN_TYPE, type,
-						COLUMN_TRUSTED, trusted,
+						COLUMN_BONDED, bonded,
 						COLUMN_CONNECTED, connected, -1);
 			return;
 		}
@@ -242,7 +252,7 @@ static void insert_device(DBusGProxy *ob
 					COLUMN_RSSI, rssi,
 					COLUMN_NAME, name,
 					COLUMN_TYPE, type,
-					COLUMN_TRUSTED, trusted,
+					COLUMN_BONDED, bonded,
 					COLUMN_CONNECTED, connected, -1);
 }
 
@@ -448,6 +458,9 @@ static void add_adapter(const char *path
 	dbus_g_proxy_connect_signal(object, "RemoteNameUpdated",
 				G_CALLBACK(name_updated), tree_path, NULL);
 
+	dbus_g_proxy_add_signal(object, "DiscoveryCompleted",
+				G_TYPE_INVALID);
+
 	update_adapter(object, &iter);
 }
 
@@ -498,6 +511,17 @@ static void default_adapter_changed(DBus
 	g_free(temp);
 }
 
+static void discovery_completed(DBusGProxy *object,
+				gpointer user_data)
+{
+	BluetoothClient *self = BLUETOOTH_CLIENT(user_data);
+	BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(self);
+
+	priv->discoveries--;
+	if (priv->discoveries == 0)
+		g_signal_emit(G_OBJECT(self), client_table_signals[DISCOVERIES_COMPLETED], 0);
+}
+
 static void setup_manager(void)
 {
 	DBusGProxy *object;
@@ -592,6 +616,15 @@ static void bluetooth_client_class_init(
 			G_TYPE_INT, G_TYPE_STRING, G_TYPE_UINT,
 			G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
 
+	client_table_signals[DISCOVERIES_COMPLETED] =
+		g_signal_new ("discoveries-completed",
+			      G_TYPE_FROM_CLASS (klass),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (BluetoothClientClass, discoveries_completed),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE, 0, G_TYPE_NONE);
+
 	setup_dbus();
 
 	setup_manager();
@@ -684,8 +717,22 @@ gboolean bluetooth_client_discover_devic
 						COLUMN_OBJECT, &object, -1);
 
 		if (g_ascii_strcasecmp(path, adapter) == 0) {
-			dbus_g_proxy_call(object, "DiscoverDevices",
-							NULL, G_TYPE_INVALID);
+			BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(self);
+
+			priv->discoveries++;
+			/* Disconnect any lingering signals, to avoid the callback
+			 * being called twice */
+			dbus_g_proxy_disconnect_signal(object, "DiscoveryCompleted",
+						       G_CALLBACK(discovery_completed),
+						       self);
+			dbus_g_proxy_connect_signal(object, "DiscoveryCompleted",
+						    G_CALLBACK(discovery_completed),
+						    self, NULL);
+
+			if (dbus_g_proxy_call(object, "DiscoverDevices",
+							NULL, G_TYPE_INVALID))
+				priv->discoveries--;
+
 			return TRUE;
 		}
 
Index: client.h
===================================================================
RCS file: /cvsroot/bluez/gnome/common/client.h,v
retrieving revision 1.12
diff -u -p -r1.12 client.h
--- client.h	24 Jul 2007 21:23:59 -0000	1.12
+++ client.h	26 Jul 2007 18:16:42 -0000
@@ -51,6 +51,8 @@ struct _BluetoothClient {
 
 struct _BluetoothClientClass {
 	GObjectClass parent_class;
+
+	void (*discoveries_completed) (BluetoothClient *self);
 };
 
 GType bluetooth_client_get_type(void);
@@ -66,7 +68,7 @@ enum {
 	COLUMN_RSSI,
 	COLUMN_NAME,
 	COLUMN_TYPE,
-	COLUMN_TRUSTED,
+	COLUMN_BONDED,
 	COLUMN_CONNECTED,
 };
 
Index: test-client.c
===================================================================
RCS file: /cvsroot/bluez/gnome/common/test-client.c,v
retrieving revision 1.8
diff -u -p -r1.8 test-client.c
--- test-client.c	24 Jul 2007 21:21:29 -0000	1.8
+++ test-client.c	26 Jul 2007 18:16:42 -0000
@@ -112,7 +112,7 @@ static void create_window(void)
 
 	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1,
 					"Trusted", gtk_cell_renderer_text_new(),
-						"text", COLUMN_TRUSTED, NULL);
+						"text", COLUMN_BONDED, NULL);
 
 	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1,
 					"Connected", gtk_cell_renderer_text_new(),

[-- Attachment #3: Type: text/plain, Size: 315 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

             reply	other threads:[~2007-07-26 18:49 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-26 18:49 Bastien Nocera [this message]
2007-07-26 20:17 ` [Bluez-devel] [PATCH] bluez-gnome: "search" button for the device selection Bastien Nocera
2007-07-27  9:18   ` Bastien Nocera
2007-07-27 15:30     ` Bastien Nocera
2007-07-27 17:09       ` Marcel Holtmann
2007-07-27 18:39         ` Bastien Nocera
2007-07-27 19:02           ` Marcel Holtmann
2007-07-27 19:41             ` Bastien Nocera
2007-07-27 20:16               ` Marcel Holtmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1185475756.3641.329.camel@cookie.hadess.net \
    --to=hadess@hadess.net \
    --cc=bluez-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.