Re: [Bluez-devel] Wizard patch

Michael Terry
2008-06-27T19:18:42Z

[-- Attachment #1.1.1: Type: text/plain, Size: 72 bytes --]

Whoops, here's a fixed patch that actually installs the binary.

-mt

[-- Attachment #1.1.2: Type: text/x-patch, Size: 47144 bytes --]

diff -rupN bluez-gnome-0.27.orig/applet/main.c bluez-gnome-0.27/applet/main.c
--- bluez-gnome-0.27.orig/applet/main.c 2008-06-27 14:12:49.000000000 -0400
+++ bluez-gnome-0.27/applet/main.c 2008-06-27 14:13:05.000000000 -0400
@@ -625,7 +625,6 @@ static void sendto_callback(GObject *wid
g_printerr("Couldn't execute command: %s\n", command);
}

-#if 0
static void wizard_callback(GObject *widget, gpointer user_data)
{
const char *command = "bluetooth-wizard --singleton";
@@ -633,7 +632,6 @@ static void wizard_callback(GObject *wid
if (!g_spawn_command_line_async(command, NULL))
g_printerr("Couldn't execute command: %s\n", command);
}
-#endif

static void activate_callback(GObject *widget, gpointer user_data)
{
@@ -697,17 +695,15 @@ static GtkWidget *create_popupmenu(void)

menuitem_browse = item;

-#if 0
item = gtk_separator_menu_item_new();
gtk_widget_show(item);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);

- item = gtk_menu_item_new_with_label(_("Setup New Device"));
+ item = gtk_menu_item_new_with_label(_("Connect New Device..."));
g_signal_connect(item, "activate",
G_CALLBACK(wizard_callback), NULL);
gtk_widget_show(item);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-#endif

return menu;
}
diff -rupN bluez-gnome-0.27.orig/common/bluetooth-device-selection.c bluez-gnome-0.27/common/bluetooth-device-selection.c
--- bluez-gnome-0.27.orig/common/bluetooth-device-selection.c 2008-06-27 14:12:49.000000000 -0400
+++ bluez-gnome-0.27/common/bluetooth-device-selection.c 2008-06-27 14:13:05.000000000 -0400
@@ -90,6 +90,15 @@ bluetooth_device_category_to_string (int
}
}

+static int
+int_log2(int v)
+{
+ unsigned rv = 0;
+ while (v >>= 1)
+ rv++;
+ return rv;
+}
+
static void
name_to_text (GtkTreeViewColumn *column, GtkCellRenderer *cell,
GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
@@ -591,7 +600,7 @@ bluetooth_device_selection_init(Bluetoot
}
g_signal_connect (G_OBJECT (priv->device_type), "changed",
G_CALLBACK(filter_type_changed_cb), self);
- gtk_combo_box_set_active (GTK_COMBO_BOX(priv->device_type), priv->device_type_filter);
+ gtk_combo_box_set_active (GTK_COMBO_BOX(priv->device_type), int_log2(priv->device_type_filter));
if (priv->show_device_type) {
gtk_widget_show (priv->device_type_label);
gtk_widget_show (priv->device_type);
@@ -665,7 +674,7 @@ bluetooth_device_selection_set_property
break;
case PROP_DEVICE_TYPE_FILTER:
priv->device_type_filter = g_value_get_int (value);
- gtk_combo_box_set_active (GTK_COMBO_BOX(priv->device_type), priv->device_type_filter >> 1);
+ gtk_combo_box_set_active (GTK_COMBO_BOX(priv->device_type), int_log2(priv->device_type_filter));
break;
case PROP_DEVICE_CATEGORY_FILTER:
priv->device_category_filter = g_value_get_int (value);
@@ -751,7 +760,7 @@ bluetooth_device_selection_class_init (B
NULL, NULL, TRUE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS(klass),
PROP_DEVICE_TYPE_FILTER, g_param_spec_int ("device-type-filter", NULL, NULL,
- 0, BLUETOOTH_TYPE_NUM_TYPES, 0, G_PARAM_READWRITE));
+ 1, 1 << (BLUETOOTH_TYPE_NUM_TYPES-1), 1, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS(klass),
PROP_DEVICE_CATEGORY_FILTER, g_param_spec_int ("device-category-filter", NULL, NULL,
0, BLUETOOTH_CATEGORY_NUM_CATEGORIES, 0, G_PARAM_READWRITE));
diff -rupN bluez-gnome-0.27.orig/common/client.c bluez-gnome-0.27/common/client.c
--- bluez-gnome-0.27.orig/common/client.c 2008-06-27 14:12:49.000000000 -0400
+++ bluez-gnome-0.27/common/client.c 2008-06-27 14:13:05.000000000 -0400
@@ -48,6 +48,8 @@ struct _BluetoothClientPrivate {

DBusGConnection *conn;
DBusGProxy *manager_object;
+ DBusGProxy *input_service;
+ DBusGProxy *audio_service;
GtkTreeStore *store;
gchar *default_adapter;
};
@@ -935,6 +937,33 @@ static void setup_manager(BluetoothClien
g_error_free(error);
}

+static void setup_services(BluetoothClient *client)
+{
+ BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
+ gchar *busname = NULL;
+
+ priv->input_service = NULL;
+ priv->audio_service = NULL;
+
+ if (dbus_g_proxy_call(priv->manager_object, "ActivateService", NULL,
+ G_TYPE_STRING, "input", G_TYPE_INVALID,
+ G_TYPE_STRING, &busname, G_TYPE_INVALID)) {
+ priv->input_service = dbus_g_proxy_new_for_name(priv->conn, busname,
+ "/org/bluez/input",
+ "org.bluez.input.Manager");
+ g_free(busname);
+ }
+
+ if (dbus_g_proxy_call(priv->manager_object, "ActivateService", NULL,
+ G_TYPE_STRING, "audio", G_TYPE_INVALID,
+ G_TYPE_STRING, &busname, G_TYPE_INVALID)) {
+ priv->audio_service = dbus_g_proxy_new_for_name(priv->conn, busname,
+ "/org/bluez/audio",
+ "org.bluez.audio.Manager");
+ g_free(busname);
+ }
+}
+
static void name_owner_changed(DBusGProxy *object, const char *name,
const char *prev, const char *new, gpointer user_data)
{
@@ -984,6 +1013,8 @@ static void bluetooth_client_finalize(GO
g_free(priv->default_adapter);
g_object_unref(G_OBJECT(priv->store));
g_object_unref (priv->manager_object);
+ g_object_unref (priv->input_service);
+ g_object_unref (priv->audio_service);
}

static void bluetooth_client_init(BluetoothClient *client)
@@ -1000,6 +1031,8 @@ static void bluetooth_client_init(Blueto
setup_dbus(client);

setup_manager(client);
+
+ setup_services(client);
}

static void bluetooth_client_set_property(GObject *object, guint prop_id,
@@ -1085,6 +1118,50 @@ BluetoothClient *bluetooth_client_new(vo
}
}

+const gchar *bluetooth_client_get_name(BluetoothClient *self, const gchar *adapter)
+{
+ BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(self);
+ GtkTreeIter iter;
+ gboolean cont;
+
+ if (adapter == NULL)
+ adapter = priv->default_adapter;
+
+ if (adapter == NULL)
+ return FALSE;
+
+ cont = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(priv->store), &iter);
+
+ while (cont == TRUE) {
+ gchar *path;
+ gchar *name;
+
+ gtk_tree_model_get(GTK_TREE_MODEL(priv->store), &iter,
+ COLUMN_PATH, &path,
+ COLUMN_NAME, &name, -1);
+
+ if (g_ascii_strcasecmp(path, adapter) == 0)
+ return g_strdup(name);
+
+ cont = gtk_tree_model_iter_next(GTK_TREE_MODEL(priv->store), &iter);
+ }
+
+ return NULL;
+}
+
+int bluetooth_client_available_services(BluetoothClient *client)
+{
+ BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
+ int rv = 0;
+
+ if (priv->input_service)
+ rv |= BLUETOOTH_TYPE_MOUSE | BLUETOOTH_TYPE_KEYBOARD;
+ if (priv->audio_service)
+ rv |= BLUETOOTH_TYPE_HEADSET;
+
+ return rv;
+}
+
gboolean bluetooth_client_register_passkey_agent(BluetoothClient *client,
const char *path, const char *address, const void *info)
{
@@ -1112,13 +1189,7 @@ gboolean bluetooth_client_register_passk
return TRUE;
}

-static void create_bonding_reply(DBusGProxy *proxy,
- GError *error, gpointer userdata)
-{
- //g_printf("create bonding reply\n");
-}
-
-gboolean bluetooth_client_create_bonding(BluetoothClient *client,
+gboolean bluetooth_client_cancel_call(BluetoothClient *client,
gchar *adapter, const gchar *address)
{
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
@@ -1142,9 +1213,14 @@ gboolean bluetooth_client_create_bonding
COLUMN_OBJECT, &object, -1);

if (g_ascii_strcasecmp(path, adapter) == 0) {
- adapter_create_bonding_async(object, address,
- create_bonding_reply, NULL);
- return TRUE;
+ DBusGProxyCall *call;
+ call = (DBusGProxyCall *)g_object_get_data(G_OBJECT(object), "call");
+ if (call != NULL) {
+ dbus_g_proxy_cancel_call(object, call);
+ g_object_set_data(G_OBJECT(object), "call", NULL);
+ return TRUE;
+ }
+ return FALSE;
}

cont = gtk_tree_model_iter_next(GTK_TREE_MODEL(priv->store), &iter);
@@ -1153,14 +1229,48 @@ gboolean bluetooth_client_create_bonding
return FALSE;
}

-static void remove_bonding_reply(DBusGProxy *proxy,
- GError *error, gpointer userdata)
+static void call_reply(DBusGProxy *proxy,
+ GError *error, gpointer userdata)
+{
+ DBusGAsyncData *data = (DBusGAsyncData*) userdata;
+ g_object_set_data(G_OBJECT(proxy), "call", NULL);
+ if (data) {
+ (*(bluetooth_client_call_reply)data->cb) (error, data->userdata);
+ g_free(data);
+ }
+ if (error)
+ g_error_free(error);
+}
+
+static void call_reply_s(DBusGProxy *proxy, char *s,
+ GError *error, gpointer userdata)
{
- //g_printf("remove bonding reply\n");
+ call_reply(proxy, error, userdata);
}

-gboolean bluetooth_client_remove_bonding(BluetoothClient *client,
- gchar *adapter, const gchar *address)
+static gboolean connect_to_service(BluetoothClient *client, DBusGProxy *object,
+ const gchar *address, guint type,
+ gpointer userdata)
+{
+ BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
+ DBusGProxyCall *call = NULL;
+
+ /* Special case the few types we can handle */
+ if (type == BLUETOOTH_TYPE_MOUSE || type == BLUETOOTH_TYPE_KEYBOARD)
+ call = input_create_secure_device_async(priv->input_service, address,
+ call_reply_s, userdata);
+ else if (type == BLUETOOTH_TYPE_HEADSET)
+ call = audio_create_headset_async(priv->audio_service, address,
+ call_reply_s, userdata);
+
+ g_object_set_data(G_OBJECT(object), "call", call);
+ return call != NULL;
+}
+
+gboolean bluetooth_client_connect(BluetoothClient *client, guint type,
+ gchar *adapter, const gchar *address,
+ bluetooth_client_call_reply callback,
+ gpointer userdata)
{
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
GtkTreeIter iter;
@@ -1183,9 +1293,36 @@ gboolean bluetooth_client_remove_bonding
COLUMN_OBJECT, &object, -1);

if (g_ascii_strcasecmp(path, adapter) == 0) {
- adapter_remove_bonding_async(object, address,
- remove_bonding_reply, NULL);
- return TRUE;
+ DBusGAsyncData *stuff;
+ gboolean cont;
+ GtkTreeIter child;
+
+ stuff = g_new (DBusGAsyncData, 1);
+ stuff->cb = G_CALLBACK (callback);
+ stuff->userdata = userdata;
+
+ // If caller didn't specify a forced type, determine it from device info
+ if (type == 0 || type == BLUETOOTH_TYPE_ANY) {
+ cont = gtk_tree_model_iter_children(GTK_TREE_MODEL(priv->store),
+ &child, &iter);
+
+ while (cont == TRUE) {
+ gchar *value;
+
+ gtk_tree_model_get(GTK_TREE_MODEL(priv->store), &child,
+ COLUMN_ADDRESS, &value, -1);
+
+ if (g_ascii_strcasecmp(address, value) == 0) {
+ gtk_tree_model_get(GTK_TREE_MODEL(priv->store), &child,
+ COLUMN_TYPE, &type, -1);
+ break;
+ }
+
+ cont = gtk_tree_model_iter_next(GTK_TREE_MODEL(priv->store), &child);
+ }
+ }
+
+ return connect_to_service(client, object, address, type, stuff);
}

cont = gtk_tree_model_iter_next(GTK_TREE_MODEL(priv->store), &iter);
@@ -1194,14 +1331,53 @@ gboolean bluetooth_client_remove_bonding
return FALSE;
}

-static void set_trusted_reply(DBusGProxy *proxy,
- GError *error, gpointer userdata)
+gboolean bluetooth_client_create_bonding(BluetoothClient *client,
+ gchar *adapter, const gchar *address,
+ bluetooth_client_call_reply callback,
+ gpointer userdata)
{
- //g_printf("set trusted reply\n");
+ BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
+ GtkTreeIter iter;
+ gboolean cont;
+
+ if (adapter == NULL)
+ adapter = priv->default_adapter;
+
+ if (adapter == NULL)
+ return FALSE;
+
+ cont = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(priv->store), &iter);
+
+ while (cont == TRUE) {
+ DBusGProxy *object;
+ gchar *path;
+
+ gtk_tree_model_get(GTK_TREE_MODEL(priv->store), &iter,
+ COLUMN_PATH, &path,
+ COLUMN_OBJECT, &object, -1);
+
+ if (g_ascii_strcasecmp(path, adapter) == 0) {
+ DBusGProxyCall *call;
+ DBusGAsyncData *stuff;
+ stuff = g_new (DBusGAsyncData, 1);
+ stuff->cb = G_CALLBACK (callback);
+ stuff->userdata = userdata;
+ call = adapter_create_bonding_async(object, address,
+ call_reply, stuff);
+ g_object_set_data(G_OBJECT(object), "call", call);
+ return call != NULL;
+ }
+
+ cont = gtk_tree_model_iter_next(GTK_TREE_MODEL(priv->store), &iter);
+ }
+
+ return FALSE;
}

-gboolean bluetooth_client_set_trusted(BluetoothClient *client,
- gchar *adapter, const gchar *address)
+gboolean bluetooth_client_remove_bonding(BluetoothClient *client,
+ gchar *adapter, const gchar *address,
+ bluetooth_client_call_reply callback,
+ gpointer userdata)
{
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
GtkTreeIter iter;
@@ -1224,8 +1400,14 @@ gboolean bluetooth_client_set_trusted(Bl
COLUMN_OBJECT, &object, -1);

if (g_ascii_strcasecmp(path, adapter) == 0) {
- adapter_set_trusted_async(object, address,
- set_trusted_reply, NULL);
+ DBusGProxyCall *call;
+ DBusGAsyncData *stuff;
+ stuff = g_new (DBusGAsyncData, 1);
+ stuff->cb = G_CALLBACK (callback);
+ stuff->userdata = userdata;
+ call = adapter_remove_bonding_async(object, address,
+ call_reply, stuff);
+ g_object_set_data(G_OBJECT(object), "call", call);
return TRUE;
}

@@ -1235,14 +1417,53 @@ gboolean bluetooth_client_set_trusted(Bl
return FALSE;
}

-static void remove_trust_reply(DBusGProxy *proxy,
- GError *error, gpointer userdata)
+gboolean bluetooth_client_set_trusted(BluetoothClient *client,
+ gchar *adapter, const gchar *address,
+ bluetooth_client_call_reply callback,
+ gpointer userdata)
{
- //g_printf("remove trust reply\n");
+ BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
+ GtkTreeIter iter;
+ gboolean cont;
+
+ if (adapter == NULL)
+ adapter = priv->default_adapter;
+
+ if (adapter == NULL)
+ return FALSE;
+
+ cont = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(priv->store), &iter);
+
+ while (cont == TRUE) {
+ DBusGProxy *object;
+ gchar *path;
+
+ gtk_tree_model_get(GTK_TREE_MODEL(priv->store), &iter,
+ COLUMN_PATH, &path,
+ COLUMN_OBJECT, &object, -1);
+
+ if (g_ascii_strcasecmp(path, adapter) == 0) {
+ DBusGProxyCall *call;
+ DBusGAsyncData *stuff;
+ stuff = g_new (DBusGAsyncData, 1);
+ stuff->cb = G_CALLBACK (callback);
+ stuff->userdata = userdata;
+ call = adapter_set_trusted_async(object, address,
+ call_reply, stuff);
+ g_object_set_data(G_OBJECT(object), "call", call);
+ return TRUE;
+ }
+
+ cont = gtk_tree_model_iter_next(GTK_TREE_MODEL(priv->store), &iter);
+ }
+
+ return FALSE;
}

gboolean bluetooth_client_remove_trust(BluetoothClient *client,
- gchar *adapter, const gchar *address)
+ gchar *adapter, const gchar *address,
+ bluetooth_client_call_reply callback,
+ gpointer userdata)
{
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
GtkTreeIter iter;
@@ -1265,8 +1486,14 @@ gboolean bluetooth_client_remove_trust(B
COLUMN_OBJECT, &object, -1);

if (g_ascii_strcasecmp(path, adapter) == 0) {
- adapter_remove_trust_async(object, address,
- remove_trust_reply, NULL);
+ DBusGProxyCall *call;
+ DBusGAsyncData *stuff;
+ stuff = g_new (DBusGAsyncData, 1);
+ stuff->cb = G_CALLBACK (callback);
+ stuff->userdata = userdata;
+ call = adapter_remove_trust_async(object, address,
+ call_reply, stuff);
+ g_object_set_data(G_OBJECT(object), "call", call);
return TRUE;
}

diff -rupN bluez-gnome-0.27.orig/common/client.h bluez-gnome-0.27/common/client.h
--- bluez-gnome-0.27.orig/common/client.h 2008-06-27 14:12:49.000000000 -0400
+++ bluez-gnome-0.27/common/client.h 2008-06-27 14:13:05.000000000 -0400
@@ -99,14 +99,34 @@ const gchar *bluetooth_type_to_string(gu
gboolean bluetooth_client_register_passkey_agent(BluetoothClient *self,
const char *path, const char *address, const void *info);

-gboolean bluetooth_client_create_bonding(BluetoothClient *self,
+typedef void (*bluetooth_client_call_reply) (GError *error, gpointer data);
+
+int bluetooth_client_available_services(BluetoothClient *self);
+
+gboolean bluetooth_client_cancel_call(BluetoothClient *self,
gchar *adapter, const gchar *address);
+gboolean bluetooth_client_connect(BluetoothClient *self, guint type, // set to non-ANY to force a certain type connection -- useful for dumb devices
+ gchar *adapter, const gchar *address,
+ bluetooth_client_call_reply callback,
+ gpointer data);
+gboolean bluetooth_client_create_bonding(BluetoothClient *self,
+ gchar *adapter, const gchar *address,
+ bluetooth_client_call_reply callback,
+ gpointer data);
gboolean bluetooth_client_remove_bonding(BluetoothClient *self,
- gchar *adapter, const gchar *address);
+ gchar *adapter, const gchar *address,
+ bluetooth_client_call_reply callback,
+ gpointer data);
gboolean bluetooth_client_set_trusted(BluetoothClient *self,
- gchar *adapter, const gchar *address);
+ gchar *adapter, const gchar *address,
+ bluetooth_client_call_reply callback,
+ gpointer data);
gboolean bluetooth_client_remove_trust(BluetoothClient *self,
- gchar *adapter, const gchar *address);
+ gchar *adapter, const gchar *address,
+ bluetooth_client_call_reply callback,
+ gpointer data);
+
+const gchar *bluetooth_client_get_name(BluetoothClient *self, const gchar *adapter);

gboolean bluetooth_client_disconnect(BluetoothClient *self,
gchar *adapter, const gchar *address);
diff -rupN bluez-gnome-0.27.orig/common/dbus.xml bluez-gnome-0.27/common/dbus.xml
--- bluez-gnome-0.27.orig/common/dbus.xml 2008-06-27 14:12:49.000000000 -0400
+++ bluez-gnome-0.27/common/dbus.xml 2008-06-27 14:13:05.000000000 -0400
@@ -98,4 +98,20 @@
<arg type="s" name="address"/>
</method>
</interface>
+
+ <interface name="input">
+ <method name="CreateSecureDevice">
+
+ <arg type="s" name="address"/>
+ <arg type="s" direction="out"/>
+ </method>
+ </interface>
+
+ <interface name="audio">
+ <method name="CreateHeadset">
+
+ <arg type="s" name="address"/>
+ <arg type="s" direction="out"/>
+ </method>
+ </interface>
</node>
diff -rupN bluez-gnome-0.27.orig/properties/adapter.c bluez-gnome-0.27/properties/adapter.c
--- bluez-gnome-0.27.orig/properties/adapter.c 2008-06-27 14:12:49.000000000 -0400
+++ bluez-gnome-0.27/properties/adapter.c 2008-06-27 14:13:05.000000000 -0400
@@ -317,7 +317,7 @@ static void delete_callback(GtkWidget *b
gtk_tree_model_get(model, &iter, COLUMN_ADDRESS, &address, -1);

if (show_confirm_dialog() == TRUE)
- bluetooth_client_remove_bonding(client, adapter->path, address);
+ bluetooth_client_remove_bonding(client, adapter->path, address, NULL, NULL);

g_free(address);
}
@@ -338,9 +338,9 @@ static void trusted_callback(GtkWidget *
COLUMN_TRUSTED, &trusted, -1);

if (trusted == FALSE)
- bluetooth_client_set_trusted(client, adapter->path, address);
+ bluetooth_client_set_trusted(client, adapter->path, address, NULL, NULL);
else
- bluetooth_client_remove_trust(client, adapter->path, address);
+ bluetooth_client_remove_trust(client, adapter->path, address, NULL, NULL);

g_free(address);
}
diff -rupN bluez-gnome-0.27.orig/wizard/agent.c bluez-gnome-0.27/wizard/agent.c
--- bluez-gnome-0.27.orig/wizard/agent.c 1969-12-31 19:00:00.000000000 -0500
+++ bluez-gnome-0.27/wizard/agent.c 2008-06-27 14:13:05.000000000 -0400
@@ -0,0 +1,504 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2006-2007 Bastien Nocera <hadess@hadess.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dbus/dbus-glib.h>
+
+#include <glib/gi18n.h>
+
+#include <gtk/gtk.h>
+
+#include "agent.h"
+
+#define PASSKEY_AGENT_PATH "/org/bluez/passkey"
+
+static GtkWidget *main_dialog;
+
+typedef enum {
+ AGENT_ERROR_REJECT
+} AgentError;
+
+#define AGENT_ERROR (agent_error_quark())
+
+#define AGENT_ERROR_TYPE (agent_error_get_type())
+
+static GQuark agent_error_quark(void)
+{
+ static GQuark quark = 0;
+ if (!quark)
+ quark = g_quark_from_static_string("agent");
+
+ return quark;
+}
+
+#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+
+static GList *input_list = NULL;
+
+struct input_data {
+ char *path;
+ char *address;
+ char *service;
+ char *uuid;
+ DBusGMethodInvocation *context;
+ GtkWidget *dialog;
+ GtkWidget *button;
+ GtkWidget *entry;
+};
+
+static gint input_compare(gconstpointer a, gconstpointer b)
+{
+ struct input_data *a_data = (struct input_data *) a;
+ struct input_data *b_data = (struct input_data *) b;
+
+ return g_ascii_strcasecmp(a_data->address, b_data->address);
+}
+
+static void input_free(struct input_data *input)
+{
+ gtk_widget_destroy(input->dialog);
+
+ g_free(input->uuid);
+ g_free(input->service);
+ g_free(input->address);
+ g_free(input->path);
+ g_free(input);
+}
+
+static void passkey_callback(GtkWidget *dialog,
+ gint response, gpointer user_data)
+{
+ struct input_data *input = user_data;
+
+ if (response == GTK_RESPONSE_ACCEPT) {
+ const char *passkey;
+ passkey = gtk_entry_get_text(GTK_ENTRY(input->entry));
+ dbus_g_method_return(input->context, passkey);
+ } else {
+ GError *error;
+ error = g_error_new(AGENT_ERROR, AGENT_ERROR_REJECT,
+ "Pairing request rejected");
+ dbus_g_method_return_error(input->context, error);
+ }
+
+ input_free(input);
+}
+
+static void changed_callback(GtkWidget *editable, gpointer user_data)
+{
+ struct input_data *input = user_data;
+ const gchar *text;
+
+ text = gtk_entry_get_text(GTK_ENTRY(input->entry));
+
+ gtk_widget_set_sensitive(input->button, *text != '\0' ? TRUE : FALSE);
+}
+
+static void toggled_callback(GtkWidget *button, gpointer user_data)
+{
+ struct input_data *input = user_data;
+ gboolean mode;
+
+ mode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
+
+ gtk_entry_set_visibility(GTK_ENTRY(input->entry), mode);
+}
+
+static void passkey_dialog(const char *path, const char *address,
+ const gchar *device, DBusGMethodInvocation *context)
+{
+ GtkWidget *dialog;
+ GtkWidget *button;
+ GtkWidget *image;
+ GtkWidget *label;
+ GtkWidget *entry;
+ GtkWidget *table;
+ GtkWidget *vbox;
+ struct input_data *input;
+ gchar *markup;
+
+ input = g_try_malloc0(sizeof(*input));
+ if (!input)
+ return;
+
+ input->path = g_strdup(path);
+ input->address = g_strdup(address);
+
+ input->context = context;
+
+ dialog = gtk_dialog_new();
+
+ gtk_window_set_title(GTK_WINDOW(dialog), _("Authentication request"));
+
+ gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
+
+ gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
+
+ gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
+
+ gtk_window_set_urgency_hint(GTK_WINDOW(dialog), TRUE);
+
+ gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(main_dialog));
+
+ input->dialog = dialog;
+
+ button = gtk_dialog_add_button(GTK_DIALOG(dialog),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
+
+ button = gtk_dialog_add_button(GTK_DIALOG(dialog),
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
+
+ gtk_widget_grab_default(button);
+
+ gtk_widget_set_sensitive(button, FALSE);
+
+ input->button = button;
+
+ table = gtk_table_new(5, 2, FALSE);
+
+ gtk_table_set_row_spacings(GTK_TABLE(table), 4);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 20);
+
+ gtk_container_set_border_width(GTK_CONTAINER(table), 12);
+
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table);
+
+ image = gtk_image_new_from_icon_name(GTK_STOCK_DIALOG_AUTHENTICATION,
+ GTK_ICON_SIZE_DIALOG);
+
+ gtk_misc_set_alignment(GTK_MISC(image), 0.0, 0.0);
+
+ gtk_table_attach(GTK_TABLE(table), image, 0, 1, 0, 5,
+ GTK_SHRINK, GTK_FILL, 0, 0);
+
+ vbox = gtk_vbox_new(FALSE, 6);
+
+ label = gtk_label_new(_("Pairing request for device:"));
+
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
+
+ gtk_container_add(GTK_CONTAINER(vbox), label);
+
+ gtk_table_attach(GTK_TABLE(table), vbox, 1, 2, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
+
+ label = gtk_label_new(NULL);
+
+ markup = g_strdup_printf("%s", device);
+ gtk_label_set_markup(GTK_LABEL(label), markup);
+ g_free(markup);
+
+ gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+
+ gtk_label_set_selectable(GTK_LABEL(label), TRUE);
+
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
+
+ gtk_widget_set_size_request(GTK_WIDGET(label), 280, -1);
+
+ gtk_container_add(GTK_CONTAINER(vbox), label);
+
+ vbox = gtk_vbox_new(FALSE, 6);
+
+ label = gtk_label_new(_("Enter passkey for authentication:"));
+
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
+
+ gtk_container_add(GTK_CONTAINER(vbox), label);
+
+ gtk_table_attach(GTK_TABLE(table), vbox, 1, 2, 2, 3,
+ GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
+
+ entry = gtk_entry_new();
+
+ gtk_entry_set_max_length(GTK_ENTRY(entry), 16);
+
+ gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
+
+ gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
+
+ input->entry = entry;
+
+ g_signal_connect(G_OBJECT(entry), "changed",
+ G_CALLBACK(changed_callback), input);
+
+ gtk_container_add(GTK_CONTAINER(vbox), entry);
+
+ button = gtk_check_button_new_with_label(_("Show input"));
+
+ g_signal_connect(G_OBJECT(button), "toggled",
+ G_CALLBACK(toggled_callback), input);
+
+ gtk_container_add(GTK_CONTAINER(vbox), button);
+
+ input_list = g_list_append(input_list, input);
+ gtk_widget_show_all(dialog);
+ gtk_window_present(GTK_WINDOW(dialog));
+
+ g_signal_connect(G_OBJECT(dialog), "response",
+ G_CALLBACK(passkey_callback), input);
+}
+
+static void confirm_callback(GtkWidget *dialog,
+ gint response, gpointer user_data)
+{
+ struct input_data *input = user_data;
+
+ if (response != GTK_RESPONSE_YES) {
+ 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);
+
+ input_free(input);
+}
+
+static void confirm_dialog(const char *path, const char *address,
+ const char *value, const gchar *device,
+ DBusGMethodInvocation *context)
+{
+ GtkWidget *dialog;
+ GtkWidget *button;
+ GtkWidget *image;
+ GtkWidget *label;
+ GtkWidget *table;
+ GtkWidget *vbox;
+ gchar *markup;
+ struct input_data *input;
+
+ input = g_try_malloc0(sizeof(*input));
+ if (!input)
+ return;
+
+ input->path = g_strdup(path);
+ input->address = g_strdup(address);
+
+ input->context = context;
+
+ dialog = gtk_dialog_new();
+
+ gtk_window_set_title(GTK_WINDOW(dialog), _("Confirmation request"));
+
+ gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
+
+ gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
+
+ gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
+
+ gtk_window_set_urgency_hint(GTK_WINDOW(dialog), TRUE);
+
+ gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(main_dialog));
+
+ input->dialog = dialog;
+
+ button = gtk_dialog_add_button(GTK_DIALOG(dialog),
+ GTK_STOCK_NO, GTK_RESPONSE_NO);
+
+ button = gtk_dialog_add_button(GTK_DIALOG(dialog),
+ GTK_STOCK_YES, GTK_RESPONSE_YES);
+
+ table = gtk_table_new(5, 2, FALSE);
+
+ gtk_table_set_row_spacings(GTK_TABLE(table), 4);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 20);
+
+ gtk_container_set_border_width(GTK_CONTAINER(table), 12);
+
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table);
+
+ image = gtk_image_new_from_icon_name(GTK_STOCK_DIALOG_AUTHENTICATION,
+ GTK_ICON_SIZE_DIALOG);
+
+ gtk_misc_set_alignment(GTK_MISC(image), 0.0, 0.0);
+
+ gtk_table_attach(GTK_TABLE(table), image, 0, 1, 0, 5,
+ GTK_SHRINK, GTK_FILL, 0, 0);
+
+ vbox = gtk_vbox_new(FALSE, 6);
+ label = gtk_label_new(_("Pairing request for device:"));
+
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
+
+ gtk_container_add(GTK_CONTAINER(vbox), label);
+
+ gtk_table_attach(GTK_TABLE(table), vbox, 1, 2, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
+
+ label = gtk_label_new(NULL);
+
+ markup = g_strdup_printf("%s", device);
+ gtk_label_set_markup(GTK_LABEL(label), markup);
+ g_free(markup);
+
+ gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+
+ gtk_label_set_selectable(GTK_LABEL(label), TRUE);
+
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
+
+ gtk_widget_set_size_request(GTK_WIDGET(label), 280, -1);
+
+ gtk_container_add(GTK_CONTAINER(vbox), label);
+
+ vbox = gtk_vbox_new(FALSE, 6);
+
+ label = gtk_label_new(_("Confirm value for authentication:"));
+
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
+
+ gtk_container_add(GTK_CONTAINER(vbox), label);
+
+ gtk_table_attach(GTK_TABLE(table), vbox, 1, 2, 2, 3,
+ GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
+
+ label = gtk_label_new(NULL);
+
+ markup = g_strdup_printf("%s\n", value);
+
+ gtk_label_set_markup(GTK_LABEL(label), markup);
+
+ g_free(markup);
+
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
+
+ gtk_container_add(GTK_CONTAINER(vbox), label);
+
+ input_list = g_list_append(input_list, input);
+ gtk_widget_show_all(dialog);
+ gtk_window_present(GTK_WINDOW(dialog));
+
+ g_signal_connect(G_OBJECT(dialog), "response",
+ G_CALLBACK(confirm_callback), input);
+}
+
+static gboolean passkey_agent_request(GObject *agent,
+ const char *path, const char *address,
+ DBusGMethodInvocation *context)
+{
+ BluetoothClient *client = BLUETOOTH_CLIENT(agent);
+ const char *name = NULL;
+ gchar *device;
+
+ name = bluetooth_client_get_name(client, path);
+
+ if (name) {
+ if (g_strrstr(name, address))
+ device = g_strdup(name);
+ else
+ device = g_strdup_printf("%s (%s)", name, address);
+ } else
+ device = g_strdup(address);
+
+ passkey_dialog(path, address, device, context);
+
+ g_free(device);
+ return TRUE;
+}
+
+static gboolean passkey_agent_confirm(GObject *agent,
+ const char *path, const char *address,
+ const char *value, DBusGMethodInvocation *context)
+{
+ BluetoothClient *client = BLUETOOTH_CLIENT(agent);
+ const char *name = NULL;
+ gchar *device;
+
+ name = bluetooth_client_get_name(client, path);
+
+ if (name) {
+ if (g_strrstr(name, address))
+ device = g_strdup(name);
+ else
+ device = g_strdup_printf("%s (%s)", name, address);
+ } else
+ device = g_strdup(address);
+
+ confirm_dialog(path, address, value, device, context);
+
+ g_free(device);
+ return TRUE;
+}
+
+static gboolean passkey_agent_cancel(GObject *agent,
+ const char *path, const char *address, GError **error)
+{
+ GList *list;
+ GError *result;
+ struct input_data *input;
+
+ input = g_try_malloc0(sizeof(*input));
+ if (!input)
+ return FALSE;
+
+ input->path = g_strdup(path);
+ input->address = g_strdup(address);
+
+ list = g_list_find_custom(input_list, input, input_compare);
+
+ g_free(input->address);
+ g_free(input->path);
+ g_free(input);
+
+ if (!list || !list->data)
+ return FALSE;
+
+ input = list->data;
+
+ result = g_error_new(AGENT_ERROR, AGENT_ERROR_REJECT,
+ "Agent callback canceled");
+
+ dbus_g_method_return_error(input->context, result);
+
+ input_free(input);
+
+ return TRUE;
+}
+
+static gboolean passkey_agent_release(GObject *agent, GError **error)
+{
+ return TRUE;
+}
+
+#include "passkey-agent-glue.h"
+
+void set_agent_parent_window(GtkWidget *window)
+{
+ main_dialog = window;
+}
+
+gboolean register_agent(BluetoothClient *client,
+ const char *path, const char *address)
+{
+ return bluetooth_client_register_passkey_agent(client, path, address, &dbus_glib_passkey_agent_object_info);
+}
+
diff -rupN bluez-gnome-0.27.orig/wizard/agent.h bluez-gnome-0.27/wizard/agent.h
--- bluez-gnome-0.27.orig/wizard/agent.h 1969-12-31 19:00:00.000000000 -0500
+++ bluez-gnome-0.27/wizard/agent.h 2008-06-27 14:13:05.000000000 -0400
@@ -0,0 +1,30 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2006-2007 Bastien Nocera <hadess@hadess.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <gtk/gtk.h>
+#include "client.h"
+
+void set_agent_parent_window(GtkWidget *window);
+int register_agent(BluetoothClient *client, const char *path, const char *address);
+
diff -rupN bluez-gnome-0.27.orig/wizard/main.c bluez-gnome-0.27/wizard/main.c
--- bluez-gnome-0.27.orig/wizard/main.c 2008-06-27 14:12:49.000000000 -0400
+++ bluez-gnome-0.27/wizard/main.c 2008-06-27 14:21:41.000000000 -0400
@@ -32,6 +32,7 @@
#include <gtk/gtk.h>

#include "client.h"
+#include "agent.h"

#include "dbus-glue.h"

@@ -41,93 +42,141 @@
static gboolean singleton = FALSE;

static BluetoothClient *client;
+static DBusGProxyCall *call = NULL;

static gchar *address = NULL;
-static gchar *passkey = "123456";

+static GtkWidget *page_prev = NULL;
static GtkWidget *page_search = NULL;
-static GtkWidget *page_info = NULL;
static GtkWidget *page_pairing = NULL;
+static GtkWidget *page_info = NULL;
static GtkWidget *page_summary = NULL;
+static int page_summary_num = 0;

-static GtkWidget *label_pairing = NULL;
-static GtkWidget *label_passkey = NULL;
+static GtkWidget *pairing_progress = NULL;
+static guint pairing_progress_timeout = 0;
+static GtkWidget *pairing_message = NULL;

+static GSList *type_group = NULL;
static GtkWidget *selector = NULL;

-static gboolean passkey_agent_request(GObject *agent,
- const char *path, const char *address,
- DBusGMethodInvocation *context)
-{
- const char *value = passkey;
-
- /* Apple Wireless and Mighty Mouse */
- if (g_str_has_prefix(address, "00:0A:95:") == TRUE ||
- g_str_has_prefix(address, "00:14:51:") == TRUE)
- value = "0000";
-
- dbus_g_method_return(context, value);
+static void close_callback(GtkWidget *assistant, gpointer data)
+{
+ gtk_widget_destroy(assistant);

- return TRUE;
+ gtk_main_quit();
}

-static gboolean passkey_agent_cancel(GObject *agent,
- const char *path, const char *address, GError **error)
+static void cancel_callback(GtkWidget *assistant, gpointer data)
{
- return TRUE;
+ gtk_widget_destroy(assistant);
+
+ gtk_main_quit();
}

-static gboolean passkey_agent_release(GObject *agent, GError **error)
+static gint selected_type(void)
{
- return TRUE;
+ GSList *iter;
+ for (iter = type_group; iter; iter = iter->next) {
+ GtkToggleButton *button = GTK_TOGGLE_BUTTON(iter->data);
+ if (gtk_toggle_button_get_active(button)) {
+ gpointer data = g_object_get_data(G_OBJECT(button), "bluez-type");
+ return GPOINTER_TO_INT(data);
+ }
+ }
+ return BLUETOOTH_TYPE_ANY;
}
+
+static void show_pairing_error(GError *error)
+{
+ gchar *msg;
+ const gchar *errmsg;
+
+ gtk_widget_hide(pairing_progress);
+ if (pairing_progress_timeout > 0) {
+ g_source_remove(pairing_progress_timeout);
+ pairing_progress_timeout = 0;
+ }

-#include "passkey-agent-glue.h"
+ if (!error)
+ errmsg = _("Could not contact bluetooth service");
+ else
+ errmsg = error->message;

-#if 0
-static gint page_forward(gint current_page, gpointer data)
-{
- return current_page + 1;
+ msg = g_strdup_printf("%s\n\n%s", _("Cannot connect to device:"), errmsg);
+ gtk_label_set_markup(GTK_LABEL(pairing_message), msg);
+ gtk_widget_show(pairing_message);
+ g_free(msg);
}
-#endif

-static void close_callback(GtkWidget *assistant, gpointer data)
+static void trusted_callback(GError *error, gpointer data)
{
- gtk_widget_destroy(assistant);
+ GtkAssistant *assistant = GTK_ASSISTANT(data);

- gtk_main_quit();
+ gtk_widget_hide(pairing_progress);
+ if (pairing_progress_timeout > 0) {
+ g_source_remove(pairing_progress_timeout);
+ pairing_progress_timeout = 0;
+ }
+
+ if (error) {
+ show_pairing_error(error);
+ }
+ else {
+ gtk_assistant_set_page_complete(assistant, page_pairing, TRUE);
+ gtk_assistant_set_current_page(assistant, page_summary_num); // jump to summary
+ }
}

-static void cancel_callback(GtkWidget *assistant, gpointer data)
+static void connect_callback(GError *error, gpointer data)
{
- gtk_widget_destroy(assistant);
+ if (error ||
+ !bluetooth_client_set_trusted(client, NULL, address, trusted_callback, data))
+ show_pairing_error(error);
+}

- gtk_main_quit();
+static gboolean pulse_progress(gpointer data)
+{
+ gtk_progress_bar_pulse(GTK_PROGRESS_BAR(pairing_progress));
+ return TRUE;
}

static void prepare_callback(GtkWidget *assistant,
GtkWidget *page, gpointer data)
{
+ gboolean complete = TRUE;
+
if (page == page_search) {
+ gint type = selected_type();
+ g_object_set(G_OBJECT(selector), "device-type-filter", type, NULL);
bluetooth_device_selection_start_discovery(BLUETOOTH_DEVICE_SELECTION(selector));
- return;
+ if (address)
+ bluetooth_client_cancel_call(client, NULL, address);
+ complete = address != NULL;
}
-
- if (page == page_pairing) {
+ else if (page == page_pairing) {
bluetooth_client_cancel_discovery(client, NULL);

- bluetooth_client_register_passkey_agent(client,
- "/org/bluez/applet", address,
- &dbus_glib_passkey_agent_object_info);
-
- bluetooth_client_create_bonding(client, NULL, address);
-
- gtk_label_set_markup(GTK_LABEL(label_pairing), address);
- gtk_label_set_markup(GTK_LABEL(label_passkey), passkey);
- return;
+ register_agent(client, "/org/bluez/applet", address);
+
+ if (page_prev == page_search) {
+ pairing_progress_timeout = g_timeout_add(100, pulse_progress, pairing_progress);
+ gtk_widget_show(pairing_progress);
+ gtk_widget_hide(pairing_message);
+ complete = FALSE;
+ if (!bluetooth_client_connect(client, selected_type(), NULL, address,
+ connect_callback, assistant))
+ show_pairing_error(NULL);
+ }
+ }
+
+ if (page != page_pairing && pairing_progress_timeout > 0) {
+ g_source_remove(pairing_progress_timeout);
+ pairing_progress_timeout = 0;
}

- gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant), page, TRUE);
+ gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant), page, complete);
+ page_prev = page;
}

static GtkWidget *create_vbox(GtkWidget *assistant, GtkAssistantPageType type,
@@ -238,55 +287,39 @@ static void create_type(GtkWidget *assis

vbox = create_vbox(assistant, GTK_ASSISTANT_PAGE_CONTENT,
_("Device type"),
- _("Select the type of device you want to setup"));
-
- button = gtk_radio_button_new_with_label(group, _("Mouse"));
-
- group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
-
- //gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
+ _("Select the type of device you want to connect"));

+ button = gtk_radio_button_new_with_label(NULL, _("Mouse"));
+ g_object_set_data(G_OBJECT(button),
+ "bluez-type", GINT_TO_POINTER(BLUETOOTH_TYPE_MOUSE));
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);

- button = gtk_radio_button_new_with_label(group, _("Keyboard"));
-
- group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
-
- //gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
-
+ button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(button), _("Keyboard"));
+ g_object_set_data(G_OBJECT(button),
+ "bluez-type", GINT_TO_POINTER(BLUETOOTH_TYPE_KEYBOARD));
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);

- button = gtk_radio_button_new_with_label(group, _("Mobile phone"));
-
- group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
-
- gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
-
+#if 0
+ button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(button), _("Mobile phone"));
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);

- button = gtk_radio_button_new_with_label(group, _("Printer"));
-
- group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
-
- gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
-
+ button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(button), _("Printer"));
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+#endif

- button = gtk_radio_button_new_with_label(group, _("Headset"));
-
- group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
-
- gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
-
+ button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(button), _("Headset"));
+ g_object_set_data(G_OBJECT(button),
+ "bluez-type", GINT_TO_POINTER(BLUETOOTH_TYPE_HEADSET));
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);

- button = gtk_radio_button_new_with_label(group, _("Any device"));
-
- group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
-
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
-
+#if 0
+ button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(button), _("Any device"));
+ g_object_set_data(G_OBJECT(button),
+ "bluez-type", GINT_TO_POINTER(BLUETOOTH_TYPE_ANY));
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+#endif
+
+ type_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
}

static void select_callback(BluetoothDeviceSelection *sel,
@@ -310,7 +343,7 @@ static void create_search(GtkWidget *ass

vbox = create_vbox(assistant, GTK_ASSISTANT_PAGE_CONTENT,
_("Device search"),
- _("Select the device you want to setup"));
+ _("Select the device you want to connect"));

selector = bluetooth_device_selection_new(NULL);

@@ -349,26 +382,27 @@ static void create_pairing(GtkWidget *as
{
GtkWidget *vbox;
GtkWidget *label;
+ GtkWidget *progress;

vbox = create_vbox(assistant, GTK_ASSISTANT_PAGE_CONTENT,
- _("Device pairing"),
- _("Pairing with new device"));
-
- label = gtk_label_new(NULL);
+ _("Device connection"),
+ _("Connecting with new device"));

- gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+ progress = gtk_progress_bar_new();

- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), progress, FALSE, TRUE, 0);

- label_pairing = label;
+ pairing_progress = progress;

label = gtk_label_new(NULL);
+ gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+ gtk_label_set_selectable(GTK_LABEL(label), TRUE);

gtk_misc_set_alignment(GTK_MISC(label), 0, 0);

gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);

- label_passkey = label;
+ pairing_message = label;

page_pairing = vbox;
}
@@ -381,6 +415,8 @@ static void create_summary(GtkWidget *as
_("Summary"),
_("Succesfully configured new device"));

+ page_summary_num = gtk_assistant_get_n_pages(GTK_ASSISTANT(assistant)) - 1;
+
page_summary = vbox;
}

@@ -401,13 +437,13 @@ static GtkWidget *create_wizard(void)
page_forward, NULL, NULL);
#endif

- create_intro(assistant);
+ /*create_intro(assistant);*/

create_type(assistant);

create_search(assistant);

- create_info(assistant);
+ /*create_info(assistant);*/

create_pairing(assistant);

@@ -465,6 +501,7 @@ int main(int argc, char *argv[])
client = bluetooth_client_new();

window = create_wizard();
+ set_agent_parent_window(window);

bluetooth_instance_set_window(instance, GTK_WINDOW(window));

diff -rupN bluez-gnome-0.27.orig/wizard/Makefile.am bluez-gnome-0.27/wizard/Makefile.am
--- bluez-gnome-0.27.orig/wizard/Makefile.am 2008-06-27 14:12:49.000000000 -0400
+++ bluez-gnome-0.27/wizard/Makefile.am 2008-06-27 14:13:05.000000000 -0400
@@ -1,7 +1,7 @@

-noinst_PROGRAMS = bluetooth-wizard
+bin_PROGRAMS = bluetooth-wizard

-bluetooth_wizard_SOURCES = main.c
+bluetooth_wizard_SOURCES = main.c agent.c agent.h

bluetooth_wizard_LDADD = @GTK_LIBS@ @DBUS_LIBS@ \
$(top_builddir)/common/libcommon.a
@@ -13,7 +13,7 @@ AM_CFLAGS = @DBUS_CFLAGS@ @GTK_CFLAGS@

INCLUDES = -I$(top_srcdir)/common -I$(top_builddir)/common

-noinst_MANS = bluetooth-wizard.1
+man_MANS = bluetooth-wizard.1

EXTRA_DIST = $(noinst_MANS)

[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

[-- Attachment #2: Type: text/plain, Size: 247 bytes --]