Whoops, here's a fixed patch that actually installs the binary. -mt
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"> + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> + <arg type="s" name="address"/> + <arg type="s" direction="out"/> + </method> + </interface> + + <interface name="audio"> + <method name="CreateHeadset"> + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> + <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@xxxxxxxxxxxx> + * Copyright (C) 2006-2007 Bastien Nocera <hadess@xxxxxxxxxx> + * + * + * 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("<b>%s</b>", 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("<b>%s</b>", 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("<b>%s</b>\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@xxxxxxxxxxxx> + * Copyright (C) 2006-2007 Bastien Nocera <hadess@xxxxxxxxxx> + * + * + * 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("<b>%s</b>\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:
signature.asc
Description: This is a digitally signed message part
------------------------------------------------------------------------- Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://sourceforge.net/services/buy/index.php
_______________________________________________ Bluez-devel mailing list Bluez-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.sourceforge.net/lists/listinfo/bluez-devel