gnome-bluetooth r416 - trunk/properties



Author: hadess
Date: Sun Mar  1 02:31:18 2009
New Revision: 416
URL: http://svn.gnome.org/viewvc/gnome-bluetooth?rev=416&view=rev

Log:
First pass at Killswitch support

Pretty broken if you actually have a kilswitch, bear
with me...



Modified:
   trunk/properties/adapter.c
   trunk/properties/killswitch.c
   trunk/properties/killswitch.h

Modified: trunk/properties/adapter.c
==============================================================================
--- trunk/properties/adapter.c	(original)
+++ trunk/properties/adapter.c	Sun Mar  1 02:31:18 2009
@@ -36,9 +36,11 @@
 
 #include "adapter.h"
 #include "general.h"
+#include "killswitch.h"
 
 static BluetoothClient *client;
 static GtkTreeModel *adapter_model;
+static GtkWidget *killswitch_page;
 
 typedef struct adapter_data adapter_data;
 struct adapter_data {
@@ -754,6 +756,36 @@
 	}
 }
 
+static void
+button_clicked_cb (GtkButton *button, gpointer user_data)
+{
+	BluetoothKillswitch *killswitch = user_data;
+
+	g_message ("button_clicked_cb");
+
+	bluetooth_killswitch_set_state (killswitch, KILLSWITCH_STATE_NOT_KILLED);
+}
+
+static GtkWidget *
+create_killswitch_page (void)
+{
+	GtkWidget *button;
+	BluetoothKillswitch *killswitch;
+
+	killswitch = bluetooth_killswitch_new ();
+	if (bluetooth_killswitch_has_killswitches (killswitch) == FALSE) {
+		/* No killswitches */
+		g_object_unref (killswitch);
+		return NULL;
+	}
+
+	button = gtk_button_new_with_label ("Turn Bluetooth on");
+	g_signal_connect (G_OBJECT (button), "clicked",
+			  G_CALLBACK (button_clicked_cb), killswitch);
+
+	return button;
+}
+
 void setup_adapter(GtkNotebook *notebook)
 {
 	client = bluetooth_client_new();
@@ -767,6 +799,14 @@
 					G_CALLBACK(adapter_removed), notebook);
 
 	gtk_tree_model_foreach(adapter_model, adapter_insert, notebook);
+
+	killswitch_page = create_killswitch_page ();
+	if (killswitch_page && gtk_tree_model_iter_n_children (adapter_model, NULL) == 0) {
+		GtkWidget *label;
+
+		label = gtk_label_new (_("Bluetooth Status"));
+		gtk_notebook_prepend_page(notebook, killswitch_page, label);
+	}
 }
 
 void cleanup_adapter(void)
@@ -774,4 +814,20 @@
 	g_object_unref(adapter_model);
 
 	g_object_unref(client);
+
+	if (killswitch_page) {
+		GtkWidget *notebook = gtk_widget_get_parent (killswitch_page);
+		guint i;
+
+		for (i = 0; i < gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)); i++) {
+			GtkWidget *widget;
+			
+			widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), i);
+			if (widget == killswitch_page) {
+				gtk_notebook_remove_page (GTK_NOTEBOOK (notebook), i);
+				gtk_widget_destroy (killswitch_page);
+			}
+		}
+	}
 }
+

Modified: trunk/properties/killswitch.c
==============================================================================
--- trunk/properties/killswitch.c	(original)
+++ trunk/properties/killswitch.c	Sun Mar  1 02:31:18 2009
@@ -3,7 +3,7 @@
  *  BlueZ - Bluetooth protocol stack for Linux
  *
  *  Copyright (C) 2005-2008  Marcel Holtmann <marcel holtmann org>
- *  Copyright (C) 2006-2007  Bastien Nocera <hadess hadess net>
+ *  Copyright (C) 2006-2009  Bastien Nocera <hadess hadess net>
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -27,215 +27,320 @@
 #endif
 
 #include <glib/gi18n.h>
-#include <gtk/gtk.h>
 
 #include <dbus/dbus-glib-lowlevel.h>
 
 #include <hal/libhal.h>
 
-#include "general.h"
 #include "killswitch.h"
 
-static LibHalContext *halctx = NULL;
+#define BLUETOOTH_KILLSWITCH_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+				BLUETOOTH_TYPE_KILLSWITCH, BluetoothKillswitchPrivate))
 
-static void setpower_reply(DBusPendingCall *call, void *user_data)
+typedef struct _BluetoothIndKillswitch BluetoothIndKillswitch;
+struct _BluetoothIndKillswitch {
+	char *udi;
+	DBusPendingCall *call;
+	gboolean killed;
+};
+
+typedef struct _BluetoothKillswitchPrivate BluetoothKillswitchPrivate;
+struct _BluetoothKillswitchPrivate {
+	LibHalContext *halctx;
+	DBusConnection *connection;
+	GList *killswitches; /* a GList of BluetoothIndKillswitch */
+};
+
+G_DEFINE_TYPE(BluetoothKillswitch, bluetooth_killswitch, G_TYPE_OBJECT)
+
+static void
+setpower_reply (DBusPendingCall *call, void *user_data)
 {
-	GtkWidget *button = user_data;
 	DBusMessage *reply;
 	gint32 power;
 
 	reply = dbus_pending_call_steal_reply(call);
 
 	if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INT32, &power,
-						DBUS_TYPE_INVALID) == FALSE) {
+				  DBUS_TYPE_INVALID) == FALSE) {
 		dbus_message_unref(reply);
 		return;
 	}
 
 	dbus_message_unref(reply);
 	dbus_pending_call_unref (call);
-
-	gtk_widget_set_sensitive(button, TRUE);
 }
 
-static void toggle_callback(GtkWidget *button, gpointer user_data)
+static void
+getpower_reply (DBusPendingCall *call, void *user_data)
 {
-	DBusConnection *conn;
-	DBusPendingCall *call;
-	DBusMessage *message;
-	const char *udi;
-	gboolean value;
+	BluetoothKillswitch *killswitch = BLUETOOTH_KILLSWITCH (user_data);
+	BluetoothKillswitchPrivate *priv = BLUETOOTH_KILLSWITCH_GET_PRIVATE (killswitch);
+	DBusMessage *reply;
+	GList *l;
+	gint32 power;
 
-	value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
+	reply = dbus_pending_call_steal_reply (call);
 
-	gtk_widget_set_sensitive(button, FALSE);
+	if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INT32, &power,
+				  DBUS_TYPE_INVALID) == FALSE) {
+		dbus_message_unref(reply);
+		return;
+	}
 
-	udi = g_object_get_data(G_OBJECT(button), "UDI");
+	/* Look for the killswitch */
+	for (l = priv->killswitches; l ; l = l->next) {
+		BluetoothIndKillswitch *ind = l->data;
+		g_message ("comparing %p", call);
+		g_message ("with %p", ind->call);
+		if (call != ind->call)
+			continue;
+		ind->killed = (power > 0);
+		ind->call = NULL;
+	}
 
-	message = dbus_message_new_method_call("org.freedesktop.Hal", udi,
-				"org.freedesktop.Hal.Device.KillSwitch",
-								"SetPower");
-	if (message == NULL)
-		return;
+	dbus_message_unref(reply);
+	dbus_pending_call_unref (call);
 
-	dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &value,
-							DBUS_TYPE_INVALID);
+	//g_object_notify (G_OBJECT (killswitch), "killed");
+}
 
-	conn = libhal_ctx_get_dbus_connection(halctx);
+void
+bluetooth_killswitch_update_state (BluetoothKillswitch *killswitch)
+{
+	BluetoothKillswitchPrivate *priv = BLUETOOTH_KILLSWITCH_GET_PRIVATE (killswitch);
+	GList *l;
 
-	if (dbus_connection_send_with_reply(conn, message,
-						&call, -1) == FALSE) {
-		dbus_message_unref(message);
-		return;
-	}
+	for (l = priv->killswitches ; l ; l = l->next) {
+		BluetoothIndKillswitch *ind = l->data;
+		DBusPendingCall *call;
+		DBusMessage *message;
+
+		/* Already checking status */
+		if (ind->call != NULL)
+			continue;
+
+		message = dbus_message_new_method_call ("org.freedesktop.Hal",
+							ind->udi,
+							"org.freedesktop.Hal.Device.KillSwitch",
+							"GetPower");
+
+		if (message == NULL)
+			continue;
+
+		if (dbus_connection_send_with_reply (priv->connection, message, &call, -1) == FALSE) {
+			dbus_message_unref(message);
+			continue;
+		}
 
-	dbus_pending_call_set_notify(call, setpower_reply, button, NULL);
+		dbus_pending_call_set_notify (call, getpower_reply, killswitch, NULL);
 
-	dbus_message_unref(message);
+		dbus_message_unref (message);
+	}
 }
 
-static void getpower_reply(DBusPendingCall *call, void *user_data)
+void
+bluetooth_killswitch_set_state (BluetoothKillswitch *killswitch, KillswitchState state)
 {
-	GtkWidget *button = user_data;
-	DBusMessage *reply;
-	gint32 power;
+	BluetoothKillswitchPrivate *priv = BLUETOOTH_KILLSWITCH_GET_PRIVATE (killswitch);
+	gboolean value;
+	GList *l;
 
-	reply = dbus_pending_call_steal_reply(call);
+	g_return_if_fail (state == KILLSWITCH_STATE_KILLED || state == KILLSWITCH_STATE_NOT_KILLED);
 
-	if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INT32, &power,
-						DBUS_TYPE_INVALID) == FALSE) {
-		dbus_message_unref(reply);
-		return;
+	value = (state == KILLSWITCH_STATE_NOT_KILLED);
+
+	for (l = priv->killswitches ; l ; l = l->next) {
+		BluetoothIndKillswitch *ind = l->data;
+		DBusPendingCall *call;
+		DBusMessage *message;
+
+		message = dbus_message_new_method_call("org.freedesktop.Hal",
+						       ind->udi,
+						       "org.freedesktop.Hal.Device.KillSwitch",
+						       "SetPower");
+		if (message == NULL)
+			return;
+
+		dbus_message_append_args(message,
+					 DBUS_TYPE_BOOLEAN, &value,
+					 DBUS_TYPE_INVALID);
+
+		if (dbus_connection_send_with_reply(priv->connection, message,
+						    &call, -1) == FALSE) {
+			dbus_message_unref(message);
+			return;
+		}
+
+		ind->call = call;
+		g_message ("set state, call %p", call);
+
+		dbus_pending_call_set_notify(call, setpower_reply, killswitch, NULL);
+
+		dbus_message_unref(message);
 	}
+}
 
-	if (power > 0)
-		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
+KillswitchState
+bluetooth_killswitch_get_state (BluetoothKillswitch *killswitch)
+{
+	BluetoothKillswitchPrivate *priv = BLUETOOTH_KILLSWITCH_GET_PRIVATE (killswitch);
+	int state = KILLSWITCH_STATE_UNKNOWN;
+	GList *l;
+
+	for (l = priv->killswitches ; l ; l = l->next) {
+		BluetoothIndKillswitch *ind = l->data;
+
+		if (ind->killed) {
+			if (state == KILLSWITCH_STATE_UNKNOWN)
+				state = KILLSWITCH_STATE_KILLED;
+			if (state != KILLSWITCH_STATE_KILLED)
+				state = KILLSWITCH_STATE_MIXED;
+		} else {
+			if (state == KILLSWITCH_STATE_UNKNOWN)
+				state = KILLSWITCH_STATE_NOT_KILLED;
+			if (state != KILLSWITCH_STATE_NOT_KILLED)
+				state = KILLSWITCH_STATE_MIXED;
+		}
+	}
 
-	dbus_message_unref(reply);
+	if (state == KILLSWITCH_STATE_UNKNOWN)
+		return KILLSWITCH_STATE_UNKNOWN;
+
+	return state;
+}
 
-	gtk_widget_set_sensitive(button, TRUE);
+gboolean
+bluetooth_killswitch_has_killswitches (BluetoothKillswitch *killswitch)
+{
+	BluetoothKillswitchPrivate *priv = BLUETOOTH_KILLSWITCH_GET_PRIVATE (killswitch);
+
+	return (priv->killswitches != NULL);
 }
 
-static gboolean add_killswitch(GtkWidget *vbox, const char *udi)
+static void
+add_killswitch (BluetoothKillswitch *killswitch, const char *udi)
 {
-	DBusConnection *conn;
+	BluetoothKillswitchPrivate *priv = BLUETOOTH_KILLSWITCH_GET_PRIVATE (killswitch);
 	DBusPendingCall *call;
 	DBusMessage *message;
-	GtkWidget *button;
-	char *type, *name;
+	BluetoothIndKillswitch *ind;
+	char *type;
 
-	type = libhal_device_get_property_string(halctx, udi,
-						"killswitch.type", NULL);
+	type = libhal_device_get_property_string (priv->halctx,
+						  udi,
+						  "killswitch.type",
+						  NULL);
 	if (type == NULL || g_str_equal(type, "bluetooth") == FALSE) {
 		g_free (type);
-		return FALSE;
+		return;
 	}
 	g_free (type);
 
-	name = libhal_device_get_property_string(halctx, udi,
-							"info.product", NULL);
+	message = dbus_message_new_method_call ("org.freedesktop.Hal",
+						udi,
+						"org.freedesktop.Hal.Device.KillSwitch",
+						"GetPower");
 
-	button = gtk_check_button_new_with_label(name ? name : _("Bluetooth Switch"));
-	g_free (name);
-	g_object_set_data_full(G_OBJECT(button), "UDI", g_strdup(udi), (GDestroyNotify) g_free);
-	gtk_widget_set_sensitive(button, FALSE);
-	gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, FALSE, 0);
-	g_signal_connect(G_OBJECT(button), "toggled",
-					G_CALLBACK(toggle_callback), NULL);
-
-	message = dbus_message_new_method_call("org.freedesktop.Hal", udi,
-				"org.freedesktop.Hal.Device.KillSwitch",
-								"GetPower");
 	if (message == NULL)
-		return TRUE;
-
-	conn = libhal_ctx_get_dbus_connection(halctx);
+		return;
 
-	if (dbus_connection_send_with_reply(conn, message,
-						&call, -1) == FALSE) {
+	if (dbus_connection_send_with_reply (priv->connection, message, &call, -1) == FALSE) {
 		dbus_message_unref(message);
-		return TRUE;
+		return;
 	}
 
-	dbus_pending_call_set_notify(call, getpower_reply, button, NULL);
+	ind = g_new0 (BluetoothIndKillswitch, 1);
+	ind->udi = g_strdup (udi);
+	ind->call = call;
+	priv->killswitches = g_list_append (priv->killswitches, ind);
+
+	g_message ("add killswitch %p", call);
 
-	dbus_message_unref(message);
+	dbus_pending_call_set_notify (call, getpower_reply, killswitch, NULL);
 
-	return TRUE;
+	dbus_message_unref (message);
 }
 
-static gboolean detect_killswitch(GtkWidget *vbox)
+static void
+bluetooth_killswitch_init (BluetoothKillswitch *killswitch)
 {
-	gboolean result = FALSE;
+	BluetoothKillswitchPrivate *priv = BLUETOOTH_KILLSWITCH_GET_PRIVATE (killswitch);
 	char **list;
 	int num;
 
-	list = libhal_find_device_by_capability(halctx, "killswitch",
-								&num, NULL);
+	priv->connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+	if (priv->connection == NULL)
+		return;
+
+	priv->halctx = libhal_ctx_new();
+	if (priv->halctx == NULL) {
+		//FIXME clean up connection
+		return;
+	}
+
+	if (libhal_ctx_set_dbus_connection(priv->halctx, priv->connection) == FALSE) {
+		libhal_ctx_free(priv->halctx);
+		//FIXME clean up connection
+		priv->halctx = NULL;
+		return;
+	}
+
+	if (libhal_ctx_init(priv->halctx, NULL) == FALSE) {
+		//FIXME clean up connection
+		g_printerr("Couldn't init HAL context\n");
+		libhal_ctx_free(priv->halctx);
+		priv->halctx = NULL;
+		return;
+	}
+
+	list = libhal_find_device_by_capability(priv->halctx, "killswitch", &num, NULL);
 	if (list) {
 		char **tmp = list;
 
 		while (*tmp) {
-			if (add_killswitch(vbox, *tmp) == TRUE)
-				result = TRUE;
+			add_killswitch (killswitch, *tmp);
 			tmp++;
 		}
 
-		libhal_free_string_array(list);
+		libhal_free_string_array (list);
 	}
-
-	return result;
 }
 
-GtkWidget *create_killswitch(void)
+static void
+bluetooth_killswitch_finalize (GObject *object)
 {
-	GtkWidget *vbox;
-	GtkWidget *label;
+	BluetoothKillswitchPrivate *priv = BLUETOOTH_KILLSWITCH_GET_PRIVATE (object);
 
-	vbox = gtk_vbox_new(FALSE, 6);
+	if (priv->halctx != NULL) {
+		libhal_ctx_shutdown(priv->halctx, NULL);
+		libhal_ctx_free(priv->halctx);
+		priv->halctx = NULL;
+	}
 
-	if (detect_killswitch(vbox) == TRUE) {
-		label = create_label(_("Power switches"));
-		gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
+	if (priv->connection != NULL) {
+		dbus_connection_unref(priv->connection);
+		priv->connection = NULL;
 	}
 
-	return vbox;
-}
+	//FIXME
+	//kill everything in killswitches
 
-static DBusConnection *connection;
+	G_OBJECT_CLASS(bluetooth_killswitch_parent_class)->finalize(object);
+}
 
-void setup_killswitch(void)
+static void
+bluetooth_killswitch_class_init(BluetoothKillswitchClass *klass)
 {
-	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
-	if (connection == NULL)
-		return;
-
-	halctx = libhal_ctx_new();
-	if (halctx == NULL)
-		return;
+	GObjectClass *object_class = (GObjectClass *) klass;
 
-	if (libhal_ctx_set_dbus_connection(halctx, connection) == FALSE) {
-		libhal_ctx_free(halctx);
-		halctx = NULL;
-		return;
-	}
-
-	if (libhal_ctx_init(halctx, NULL) == FALSE) {
-		g_printerr("Couldn't init HAL context\n");
-		libhal_ctx_free(halctx);
-		halctx = NULL;
-		return;
-	}
+	g_type_class_add_private(klass, sizeof(BluetoothKillswitchPrivate));
+	object_class->finalize = bluetooth_killswitch_finalize;
 }
 
-void cleanup_killswitch(void)
+BluetoothKillswitch *
+bluetooth_killswitch_new (void)
 {
-	if (halctx != NULL) {
-		libhal_ctx_shutdown(halctx, NULL);
-		libhal_ctx_free(halctx);
-		halctx = NULL;
-	}
-
-	if (connection != NULL)
-		dbus_connection_unref(connection);
+	return BLUETOOTH_KILLSWITCH(g_object_new (BLUETOOTH_TYPE_KILLSWITCH, NULL));
 }
+

Modified: trunk/properties/killswitch.h
==============================================================================
--- trunk/properties/killswitch.h	(original)
+++ trunk/properties/killswitch.h	Sun Mar  1 02:31:18 2009
@@ -3,7 +3,7 @@
  *  BlueZ - Bluetooth protocol stack for Linux
  *
  *  Copyright (C) 2005-2008  Marcel Holtmann <marcel holtmann org>
- *  Copyright (C) 2006-2007  Bastien Nocera <hadess hadess net>
+ *  Copyright (C) 2006-2009  Bastien Nocera <hadess hadess net>
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -22,6 +22,53 @@
  *
  */
 
-GtkWidget *create_killswitch(void);
-void setup_killswitch(void);
-void cleanup_killswitch(void);
+#ifndef __BLUETOOTH_KILLSWITCH_H
+#define __BLUETOOTH_KILLSWITCH_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+	KILLSWITCH_STATE_UNKNOWN = -1,
+	KILLSWITCH_STATE_KILLED = 0,
+	KILLSWITCH_STATE_NOT_KILLED,
+	KILLSWITCH_STATE_MIXED,
+} KillswitchState;
+
+#define BLUETOOTH_TYPE_KILLSWITCH (bluetooth_killswitch_get_type())
+#define BLUETOOTH_KILLSWITCH(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+					BLUETOOTH_TYPE_KILLSWITCH, BluetoothKillswitch))
+#define BLUETOOTH_KILLSWITCH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
+					BLUETOOTH_TYPE_KILLSWITCH, BluetoothKillswitchClass))
+#define BLUETOOTH_IS_KILLSWITCH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
+							BLUETOOTH_TYPE_KILLSWITCH))
+#define BLUETOOTH_IS_KILLSWITCH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \
+							BLUETOOTH_TYPE_KILLSWITCH))
+#define BLUETOOTH_GET_KILLSWITCH_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
+					BLUETOOTH_TYPE_KILLSWITCH, BluetoothKillswitchClass))
+
+typedef struct _BluetoothKillswitch BluetoothKillswitch;
+typedef struct _BluetoothKillswitchClass BluetoothKillswitchClass;
+
+struct _BluetoothKillswitch {
+	GObject parent;
+};
+
+struct _BluetoothKillswitchClass {
+	GObjectClass parent_class;
+};
+
+GType bluetooth_killswitch_get_type(void);
+
+BluetoothKillswitch * bluetooth_killswitch_new (void);
+
+gboolean bluetooth_killswitch_has_killswitches (BluetoothKillswitch *killswitch);
+
+void bluetooth_killswitch_update_state (BluetoothKillswitch *killswitch);
+void bluetooth_killswitch_set_state (BluetoothKillswitch *killswitch, KillswitchState state);
+KillswitchState bluetooth_killswitch_get_state (BluetoothKillswitch *killswitch);
+
+G_END_DECLS
+
+#endif /* __BLUETOOTH_KILLSWITCH_H */



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