gnome-bluetooth r491 - trunk/common



Author: hadess
Date: Wed Mar 18 20:07:47 2009
New Revision: 491
URL: http://svn.gnome.org/viewvc/gnome-bluetooth?rev=491&view=rev

Log:
Add a new column for services

The column contains the list of connectable services
for the device (eg. which interfaces have a Connect() function).

This would allow us to list input and headset devices in the
applet. Still requires listening to value changes.



Modified:
   trunk/common/bluetooth-client.c
   trunk/common/bluetooth-client.h
   trunk/common/test-client.c

Modified: trunk/common/bluetooth-client.c
==============================================================================
--- trunk/common/bluetooth-client.c	(original)
+++ trunk/common/bluetooth-client.c	Wed Mar 18 20:07:47 2009
@@ -57,7 +57,15 @@
 #define BLUEZ_MANAGER_INTERFACE	"org.bluez.Manager"
 #define BLUEZ_ADAPTER_INTERFACE	"org.bluez.Adapter"
 #define BLUEZ_DEVICE_INTERFACE	"org.bluez.Device"
-#define BLUEZ_INPUT_INTERFACE	"org.bluez.Input"
+
+static char * connectable_interfaces[] = {
+	"org.bluez.Input",
+	"org.bluez.Headset",
+	"org.bluez.AudioSink"
+};
+
+/* Keep in sync with above */
+#define BLUEZ_INPUT_INTERFACE	(connectable_interfaces[0])
 
 static DBusGConnection *connection = NULL;
 static BluetoothClient *bluetooth_client = NULL;
@@ -294,6 +302,48 @@
 	return iter_search(store, iter, NULL, compare_path, (gpointer) path);
 }
 
+static GHashTable *
+device_list_nodes (DBusGProxy *device, BluetoothClientPrivate *priv)
+{
+	GHashTable *table;
+	guint i;
+
+	if (device == NULL)
+		return NULL;
+
+	table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
+
+	for (i = 0; i < G_N_ELEMENTS (connectable_interfaces); i++) {
+		DBusGProxy *iface;
+		GHashTable *props;
+
+		iface = dbus_g_proxy_new_from_proxy (device, connectable_interfaces[i],
+						     NULL);
+		if (dbus_g_proxy_call (iface, "GetProperties", NULL,
+				       G_TYPE_INVALID, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &props,
+				       G_TYPE_INVALID) != FALSE) {
+			GValue *value;
+			gboolean is_connected;
+
+			value = g_hash_table_lookup(props, "Connected");
+			is_connected = value ? g_value_get_boolean(value) : FALSE;
+
+			g_hash_table_insert (table,
+					     connectable_interfaces[i],
+					     GINT_TO_POINTER (is_connected));
+
+			//FIXME connect to the changed properties for that iface?
+		}
+	}
+
+	if (g_hash_table_size (table) == 0) {
+		g_hash_table_destroy (table);
+		return NULL;
+	}
+
+	return table;
+}
+
 static void device_changed(DBusGProxy *device, const char *property,
 					GValue *value, gpointer user_data)
 {
@@ -347,6 +397,7 @@
 	DBusGProxy *device;
 	GValue *value;
 	const gchar *address, *alias, *name, *icon;
+	GHashTable *services;
 	gboolean paired, trusted, connected;
 	guint type;
 	gint rssi;
@@ -417,14 +468,19 @@
 					BLUETOOTH_COLUMN_NAME, name,
 					BLUETOOTH_COLUMN_TYPE, type,
 					BLUETOOTH_COLUMN_ICON, icon,
-					BLUETOOTH_COLUMN_RSSI, rssi, -1);
+					BLUETOOTH_COLUMN_RSSI, rssi,
+					-1);
 
 			if (device != NULL) {
+				services = device_list_nodes (device, priv);
+
 				gtk_tree_store_set(priv->store, &iter,
 					BLUETOOTH_COLUMN_PROXY, device,
 					BLUETOOTH_COLUMN_CONNECTED, connected,
 					BLUETOOTH_COLUMN_TRUSTED, trusted,
-					BLUETOOTH_COLUMN_PAIRED, paired, -1);
+					BLUETOOTH_COLUMN_PAIRED, paired,
+					BLUETOOTH_COLUMN_SERVICES, services,
+					-1);
 			}
 
 			goto done;
@@ -434,6 +490,8 @@
 		cont = gtk_tree_model_iter_next(GTK_TREE_MODEL(priv->store), &iter);
 	}
 
+	services = device_list_nodes (device, priv);
+
 	gtk_tree_store_insert_with_values(priv->store, &iter, parent, -1,
 				BLUETOOTH_COLUMN_PROXY, device,
 				BLUETOOTH_COLUMN_ADDRESS, address,
@@ -444,7 +502,9 @@
 				BLUETOOTH_COLUMN_RSSI, rssi,
 				BLUETOOTH_COLUMN_PAIRED, paired,
 				BLUETOOTH_COLUMN_TRUSTED, trusted,
-				BLUETOOTH_COLUMN_CONNECTED, connected, -1);
+				BLUETOOTH_COLUMN_CONNECTED, connected,
+				BLUETOOTH_COLUMN_SERVICES, services,
+				-1);
 
 done:
 	if (device != NULL) {
@@ -452,7 +512,6 @@
 				G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
 		dbus_g_proxy_connect_signal(device, "PropertyChanged",
 				G_CALLBACK(device_changed), client, NULL);
-
 		g_object_unref(device);
 	}
 }
@@ -794,7 +853,8 @@
 					 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
 					 G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INT,
 					 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
-					 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
+					 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
+					 G_TYPE_HASH_TABLE);
 
 	priv->dbus = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS,
 				DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);

Modified: trunk/common/bluetooth-client.h
==============================================================================
--- trunk/common/bluetooth-client.h	(original)
+++ trunk/common/bluetooth-client.h	Wed Mar 18 20:07:47 2009
@@ -45,6 +45,7 @@
 	BLUETOOTH_COLUMN_CONNECTED,
 	BLUETOOTH_COLUMN_DISCOVERING,
 	BLUETOOTH_COLUMN_POWERED,
+	BLUETOOTH_COLUMN_SERVICES,
 	_BLUETOOTH_NUM_COLUMNS
 };
 

Modified: trunk/common/test-client.c
==============================================================================
--- trunk/common/test-client.c	(original)
+++ trunk/common/test-client.c	Wed Mar 18 20:07:47 2009
@@ -96,6 +96,31 @@
 	g_object_set(cell, "text", bluetooth_type_to_string(type), NULL);
 }
 
+static void
+services_foreach (const char *service, gpointer _value, GString *str)
+{
+	gboolean value = GPOINTER_TO_INT (_value);
+	g_string_append_printf (str, "%s (%s) ", service, value ? "connected" : "not connected");
+}
+
+static void services_to_text(GtkTreeViewColumn *column, GtkCellRenderer *cell,
+		GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
+{
+	GString *str;
+	GHashTable *services;
+
+	gtk_tree_model_get(model, iter, BLUETOOTH_COLUMN_SERVICES, &services, -1);
+	if (services == NULL) {
+		g_object_set(cell, "text", NULL, NULL);
+		return;
+	}
+
+	str = g_string_new (NULL);
+	g_hash_table_foreach (services, (GHFunc) services_foreach, str);
+	g_object_set(cell, "text", str->str, NULL);
+	g_string_free (str, TRUE);
+}
+
 static void create_window(void)
 {
 	GtkWidget *window;
@@ -190,6 +215,10 @@
 					"Powered", gtk_cell_renderer_text_new(),
 					"text", BLUETOOTH_COLUMN_POWERED, NULL);
 
+	gtk_tree_view_insert_column_with_data_func(GTK_TREE_VIEW(tree), -1,
+					"Services", gtk_cell_renderer_text_new(),
+						services_to_text, NULL, NULL);
+
 	model = bluetooth_client_get_model(client);
 	sorted = gtk_tree_model_sort_new_with_model(model);
 	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(sorted),
@@ -222,6 +251,7 @@
 
 	g_object_get (G_OBJECT (gobject), "default-adapter", &adapter, NULL);
 	g_message ("Default adapter changed: %s", adapter ? adapter : "(none)");
+	g_free (adapter);
 }
 
 static void



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