3
* BlueZ - Bluetooth protocol stack for Linux
5
* Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org>
6
* Copyright (C) 2006-2007 Bastien Nocera <hadess@hadess.net>
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31
#include <glib/gi18n.h>
34
#include "bluetooth-applet.h"
38
static GList *input_list = NULL;
40
typedef struct input_data input_data;
42
BluetoothApplet *applet;
51
static void input_free(input_data *input)
53
gtk_widget_destroy(input->dialog);
55
g_object_unref (G_OBJECT (input->applet));
59
input_list = g_list_remove(input_list, input);
65
static void pin_callback(GtkWidget *dialog,
66
gint response, gpointer user_data)
68
input_data *input = user_data;
70
if (response == GTK_RESPONSE_OK) {
73
text = gtk_entry_get_text(GTK_ENTRY(input->entry));
75
if (input->numeric == TRUE) {
76
guint pin = atoi(text);
77
bluetooth_applet_agent_reply_passkey (input->applet, input->path, pin);
79
bluetooth_applet_agent_reply_pincode (input->applet, input->path, text);
81
if (input->numeric == TRUE)
82
bluetooth_applet_agent_reply_passkey (input->applet, input->path, -1);
84
bluetooth_applet_agent_reply_pincode (input->applet, input->path, NULL);
91
confirm_callback (GtkWidget *dialog,
95
input_data *input = user_data;
97
bluetooth_applet_agent_reply_confirm (input->applet, input->path, response == GTK_RESPONSE_ACCEPT);
103
auth_callback (GtkWidget *dialog,
107
input_data *input = user_data;
109
if (response == GTK_RESPONSE_ACCEPT) {
110
gboolean trusted = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (input->button));
111
bluetooth_applet_agent_reply_auth (input->applet, input->path, TRUE, trusted);
113
bluetooth_applet_agent_reply_auth (input->applet, input->path, FALSE, FALSE);
118
static void insert_callback(GtkEditable *editable, const gchar *text,
119
gint length, gint *position, gpointer user_data)
121
input_data *input = user_data;
124
if (input->numeric == FALSE)
127
for (i = 0; i < length; i++) {
128
if (g_ascii_isdigit(text[i]) == FALSE) {
129
g_signal_stop_emission_by_name(editable,
135
static void changed_callback(GtkWidget *editable, gpointer user_data)
137
input_data *input = user_data;
140
text = gtk_entry_get_text(GTK_ENTRY(input->entry));
142
gtk_dialog_set_response_sensitive (GTK_DIALOG (input->dialog),
144
*text != '\0' ? TRUE : FALSE);
147
static void toggled_callback(GtkWidget *button, gpointer user_data)
149
input_data *input = user_data;
152
mode = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
154
gtk_entry_set_visibility (GTK_ENTRY (input->entry), mode);
158
pin_dialog (BluetoothApplet *applet,
161
const char *long_name,
171
xml = gtk_builder_new ();
172
if (gtk_builder_add_from_file (xml, "passkey-dialogue.ui", NULL) == 0)
173
gtk_builder_add_from_file (xml, PKGDATADIR "/passkey-dialogue.ui", NULL);
175
input = g_new0 (input_data, 1);
176
input->applet = g_object_ref (G_OBJECT (applet));
177
input->path = g_strdup (path);
178
input->numeric = numeric;
180
dialog = GTK_WIDGET (gtk_builder_get_object (xml, "dialog"));
182
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
183
if (notification_supports_actions () != FALSE)
184
gtk_window_set_keep_above (GTK_WINDOW (dialog), TRUE);
186
gtk_window_set_focus_on_map (GTK_WINDOW (dialog), FALSE);
187
gtk_window_set_urgency_hint (GTK_WINDOW (dialog), TRUE);
188
input->dialog = dialog;
190
gtk_dialog_set_default_response (GTK_DIALOG (dialog),
192
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
196
str = g_strdup_printf (_("Device '%s' wants to pair with this computer"),
198
g_object_set (G_OBJECT (dialog), "text", str, NULL);
201
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
202
_("Please enter the PIN mentioned on device %s."),
205
entry = GTK_WIDGET (gtk_builder_get_object (xml, "entry"));
206
if (numeric == TRUE) {
207
gtk_entry_set_max_length (GTK_ENTRY (entry), 6);
208
gtk_entry_set_width_chars (GTK_ENTRY (entry), 6);
209
g_signal_connect (G_OBJECT (entry), "insert-text",
210
G_CALLBACK (insert_callback), input);
212
gtk_entry_set_max_length (GTK_ENTRY (entry), 16);
213
gtk_entry_set_width_chars (GTK_ENTRY (entry), 16);
214
gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
216
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
217
input->entry = entry;
218
g_signal_connect (G_OBJECT (entry), "changed",
219
G_CALLBACK (changed_callback), input);
221
button = GTK_WIDGET (gtk_builder_get_object (xml, "showinput_button"));
222
if (numeric == FALSE) {
223
g_signal_connect (G_OBJECT (button), "toggled",
224
G_CALLBACK (toggled_callback), input);
226
gtk_widget_set_no_show_all (button, TRUE);
227
gtk_widget_hide (button);
230
input_list = g_list_append(input_list, input);
232
g_signal_connect (G_OBJECT (dialog), "response",
233
G_CALLBACK (pin_callback), input);
237
confirm_dialog (BluetoothApplet *applet,
240
const char *long_name,
248
input = g_new0 (input_data, 1);
249
input->applet = g_object_ref (G_OBJECT (applet));
250
input->path = g_strdup (path);
252
xml = gtk_builder_new ();
253
if (gtk_builder_add_from_file (xml, "confirm-dialogue.ui", NULL) == 0)
254
gtk_builder_add_from_file (xml, PKGDATADIR "/confirm-dialogue.ui", NULL);
256
dialog = GTK_WIDGET (gtk_builder_get_object (xml, "dialog"));
257
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
258
if (notification_supports_actions () != FALSE)
259
gtk_window_set_keep_above (GTK_WINDOW (dialog), TRUE);
261
gtk_window_set_focus_on_map (GTK_WINDOW (dialog), FALSE);
262
gtk_window_set_urgency_hint (GTK_WINDOW (dialog), TRUE);
263
input->dialog = dialog;
265
str = g_strdup_printf (_("Device '%s' wants to pair with this computer"),
267
g_object_set (G_OBJECT (dialog), "text", str, NULL);
270
str = g_strdup_printf ("<b>%s</b>", value);
271
gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog),
272
_("Please confirm whether the PIN '%s' matches the one on device %s."),
276
input_list = g_list_append (input_list, input);
278
g_signal_connect (G_OBJECT (dialog), "response",
279
G_CALLBACK (confirm_callback), input);
283
auth_dialog (BluetoothApplet *applet,
286
const char *long_name,
295
input = g_new0 (input_data, 1);
296
input->applet = g_object_ref (G_OBJECT (applet));
297
input->path = g_strdup (path);
298
input->uuid = g_strdup (uuid);
300
xml = gtk_builder_new ();
301
if (gtk_builder_add_from_file (xml, "authorisation-dialogue.ui", NULL) == 0)
302
gtk_builder_add_from_file (xml, PKGDATADIR "/authorisation-dialogue.ui", NULL);
304
dialog = GTK_WIDGET (gtk_builder_get_object (xml, "dialog"));
305
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
306
if (notification_supports_actions () != FALSE)
307
gtk_window_set_keep_above (GTK_WINDOW (dialog), TRUE);
309
gtk_window_set_focus_on_map (GTK_WINDOW (dialog), FALSE);
310
gtk_window_set_urgency_hint (GTK_WINDOW (dialog), TRUE);
311
input->dialog = dialog;
313
/* translators: Whether to grant access to a particular service */
314
str = g_strdup_printf (_("Grant access to '%s'"), uuid);
315
g_object_set (G_OBJECT (dialog), "text", str, NULL);
318
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
319
_("Device %s wants access to the service '%s'."),
322
button = GTK_WIDGET (gtk_builder_get_object (xml, "always_button"));
323
input->button = button;
325
input_list = g_list_append (input_list, input);
327
g_signal_connect (G_OBJECT (dialog), "response",
328
G_CALLBACK (auth_callback), input);
331
static void show_dialog(gpointer data, gpointer user_data)
333
input_data *input = data;
335
gtk_widget_show_all(input->dialog);
337
gtk_window_present(GTK_WINDOW(input->dialog));
340
static void present_notification_dialogs (void)
342
g_list_foreach(input_list, show_dialog, NULL);
345
static void notification_closed(GObject *object, gpointer user_data)
347
present_notification_dialogs ();
351
pin_request(BluetoothApplet *applet,
360
pin_dialog(applet, path, name, long_name, numeric);
362
if (notification_supports_actions () == FALSE) {
363
present_notification_dialogs ();
367
/* translators: this is a popup telling you a particular device
368
* has asked for pairing */
369
line = g_strdup_printf(_("Pairing request for '%s'"), name);
371
show_notification(_("Bluetooth device"),
372
line, _("Enter PIN"), 0,
373
G_CALLBACK(notification_closed));
381
confirm_request (BluetoothApplet *applet,
390
text = g_strdup_printf("%06d", pin);
391
confirm_dialog(applet, path, name, long_name, text);
394
/* translators: this is a popup telling you a particular device
395
* has asked for pairing */
396
line = g_strdup_printf(_("Pairing confirmation for '%s'"), name);
399
* This message is for Bluetooth 2.1 support, when the
400
* action is clicked in the notification popup, the user
401
* will get to check whether the PIN matches the one
402
* showing on the Bluetooth device */
403
if (notification_supports_actions () != FALSE)
404
show_notification(_("Bluetooth device"),
405
line, _("Verify PIN"), 0,
406
G_CALLBACK(notification_closed));
408
present_notification_dialogs ();
416
authorize_request (BluetoothApplet *applet,
425
auth_dialog (applet, path, name, long_name, uuid);
427
if (notification_supports_actions () == FALSE) {
428
present_notification_dialogs ();
432
line = g_strdup_printf (_("Authorization request from '%s'"), name);
434
show_notification (_("Bluetooth device"),
435
line, _("Check authorization"), 0,
436
G_CALLBACK (notification_closed));
443
static void input_free_list (gpointer data, gpointer user_data) {
444
input_data *input = data;
446
gtk_widget_destroy(input->dialog);
448
g_object_unref (G_OBJECT (input->applet));
454
static void cancel_request(BluetoothApplet *applet,
457
g_list_foreach (input_list, input_free_list, NULL);
458
g_list_free (input_list);
462
int setup_agents(BluetoothApplet *applet)
464
g_signal_connect (applet, "pincode-request",
465
G_CALLBACK (pin_request), NULL);
466
g_signal_connect (applet, "confirm-request",
467
G_CALLBACK (confirm_request), NULL);
468
g_signal_connect (applet, "auth-request",
469
G_CALLBACK (authorize_request), NULL);
470
g_signal_connect (applet, "cancel-request",
471
G_CALLBACK (cancel_request), NULL);
476
void show_agents(void)
478
close_notification();
480
g_list_foreach(input_list, show_dialog, NULL);