31
31
#include <glib/gi18n.h>
32
32
#include <gtk/gtk.h>
34
#include <dbus/dbus-glib.h>
36
#include <bluetooth-client.h>
37
#include <bluetooth-agent.h>
34
#include "bluetooth-applet.h"
39
35
#include "notify.h"
42
static BluetoothClient *client;
43
static BluetoothAgent *agent = NULL;
45
38
static GList *input_list = NULL;
47
40
typedef struct input_data input_data;
48
41
struct input_data {
42
BluetoothApplet *applet;
53
DBusGMethodInvocation *context;
59
static gint input_compare(gconstpointer a, gconstpointer b)
61
input_data *a_data = (input_data *) a;
62
input_data *b_data = (input_data *) b;
64
return g_ascii_strcasecmp(a_data->path, b_data->path);
67
51
static void input_free(input_data *input)
69
53
gtk_widget_destroy(input->dialog);
55
g_object_unref (G_OBJECT (input->applet));
71
59
input_list = g_list_remove(input_list, input);
73
if (input->device != NULL)
74
g_object_unref(input->device);
80
if (g_list_length(input_list) == 0)
84
65
static void pin_callback(GtkWidget *dialog,
115
95
input_data *input = user_data;
117
if (response != GTK_RESPONSE_ACCEPT) {
119
error = g_error_new(AGENT_ERROR, AGENT_ERROR_REJECT,
120
"Confirmation request rejected");
121
dbus_g_method_return_error(input->context, error);
123
dbus_g_method_return(input->context);
97
bluetooth_applet_agent_reply_confirm (input->applet, input->path, response == GTK_RESPONSE_ACCEPT);
125
99
input_free(input);
128
static void set_trusted(input_data *input)
130
GValue value = { 0 };
133
if (input->device == NULL)
136
active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (input->button));
140
g_value_init (&value, G_TYPE_BOOLEAN);
141
g_value_set_boolean (&value, TRUE);
143
dbus_g_proxy_call (input->device, "SetProperty", NULL,
144
G_TYPE_STRING, "Trusted",
145
G_TYPE_VALUE, &value, G_TYPE_INVALID,
148
g_value_unset (&value);
152
103
auth_callback (GtkWidget *dialog,
156
107
input_data *input = user_data;
158
109
if (response == GTK_RESPONSE_ACCEPT) {
160
dbus_g_method_return(input->context);
163
error = g_error_new (AGENT_ERROR, AGENT_ERROR_REJECT,
164
"Authorization request rejected");
165
dbus_g_method_return_error (input->context, error);
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);
168
115
input_free(input);
422
347
present_notification_dialogs ();
425
#ifndef DBUS_TYPE_G_DICTIONARY
426
#define DBUS_TYPE_G_DICTIONARY \
427
(dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
431
device_get_name(DBusGProxy *proxy, char **long_name)
435
char *alias, *address;
437
if (long_name != NULL)
440
if (dbus_g_proxy_call (proxy, "GetProperties", NULL,
442
DBUS_TYPE_G_DICTIONARY, &hash,
443
G_TYPE_INVALID) == FALSE) {
447
value = g_hash_table_lookup(hash, "Address");
449
g_hash_table_destroy (hash);
452
address = g_value_dup_string(value);
454
value = g_hash_table_lookup(hash, "Alias");
455
alias = value ? g_value_dup_string(value) : NULL;
457
g_hash_table_destroy (hash);
459
if (g_strcmp0 (alias, address) == 0) {
461
if (long_name != NULL)
462
*long_name = g_strdup_printf ("'%s'", address);
466
if (long_name != NULL)
467
*long_name = g_strdup_printf ("'%s' (%s)", alias, address);
474
static gboolean pincode_request(DBusGMethodInvocation *context,
475
DBusGProxy *device, gpointer user_data)
477
DBusGProxy *adapter = user_data;
478
char *name, *long_name, *line;
480
name = device_get_name (device, &long_name);
484
pin_dialog(adapter, device, name, long_name, FALSE, context);
488
if (notification_supports_actions () == FALSE) {
490
present_notification_dialogs ();
494
/* translators: this is a popup telling you a particular device
495
* has asked for pairing */
496
line = g_strdup_printf(_("Pairing request for '%s'"), name);
500
show_notification(_("Bluetooth device"),
501
line, _("Enter PIN"), 0,
502
G_CALLBACK(notification_closed));
509
static gboolean pin_request(DBusGMethodInvocation *context,
510
DBusGProxy *device, gpointer user_data)
512
DBusGProxy *adapter = user_data;
513
char *name, *long_name, *line;
515
name = device_get_name (device, &long_name);
519
pin_dialog(adapter, device, name, long_name, TRUE, context);
523
if (notification_supports_actions () == FALSE) {
525
present_notification_dialogs ();
529
/* translators: this is a popup telling you a particular device
530
* has asked for pairing */
531
line = g_strdup_printf(_("Pairing request for '%s'"), name);
535
show_notification(_("Bluetooth device"),
536
line, _("Enter PIN"), 0,
537
G_CALLBACK(notification_closed));
545
display_request (DBusGMethodInvocation *context,
551
g_warning ("Not implemented, please file a bug at how this happened");
554
DBusGProxy *adapter = user_data;
557
name = get_name_for_display (device);
561
text = g_strdup_printf("%d", pin);
562
display_dialog(adapter, device, address, name, text, entered, context);
565
if (notification_supports_actions () == FALSE) {
567
present_notification_dialogs ();
571
/* translators: this is a popup telling you a particular device
572
* has asked for pairing */
573
line = g_strdup_printf(_("Pairing request for '%s'"), name);
577
show_notification(_("Bluetooth device"),
578
line, _("Enter PIN"), 0,
579
G_CALLBACK(notification_closed));
588
confirm_request (DBusGMethodInvocation *context,
593
DBusGProxy *adapter = user_data;
594
char *name, *long_name, *line, *text;
596
name = device_get_name (device, &long_name);
600
text = g_strdup_printf("%d", pin);
601
confirm_dialog(adapter, device, name, long_name, text, context);
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("%d", pin);
391
confirm_dialog(applet, path, name, long_name, text);
606
394
/* translators: this is a popup telling you a particular device
607
395
* has asked for pairing */
608
396
line = g_strdup_printf(_("Pairing confirmation for '%s'"), name);
613
399
* This message is for Bluetooth 2.1 support, when the
614
400
* action is clicked in the notification popup, the user
630
authorize_request (DBusGMethodInvocation *context,
416
authorize_request (BluetoothApplet *applet,
635
DBusGProxy *adapter = user_data;
636
char *name, *long_name, *line;
638
name = device_get_name (device, &long_name);
642
auth_dialog (adapter, device, name, long_name, uuid, context);
425
auth_dialog (applet, path, name, long_name, uuid);
646
427
if (notification_supports_actions () == FALSE) {
648
428
present_notification_dialogs ();
652
432
line = g_strdup_printf (_("Authorization request from '%s'"), name);
656
434
show_notification (_("Bluetooth device"),
657
435
line, _("Check authorization"), 0,
658
436
G_CALLBACK (notification_closed));
665
static gboolean cancel_request(DBusGMethodInvocation *context,
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,
666
455
gpointer user_data)
668
DBusGProxy *adapter = user_data;
673
input = g_new0(input_data, 1);
674
input->path = g_strdup(dbus_g_proxy_get_path(adapter));
676
list = g_list_find_custom(input_list, input, input_compare);
681
if (!list || !list->data)
686
close_notification();
688
result = g_error_new(AGENT_ERROR, AGENT_ERROR_REJECT,
689
"Agent callback cancelled");
691
dbus_g_method_return_error(input->context, result);
699
default_adapter_changed (GObject *gobject,
705
g_object_get (G_OBJECT (gobject), "default-adapter", &adapter_str, NULL);
707
bluetooth_agent_unregister (agent);
708
g_object_unref (agent);
711
if (adapter_str != NULL) {
712
DBusGConnection *connection;
715
connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
716
adapter = dbus_g_proxy_new_for_name (connection,
719
"org.bluez.Adapter");
720
dbus_g_connection_unref (connection);
722
agent = bluetooth_agent_new();
724
bluetooth_agent_set_pincode_func(agent, pincode_request, adapter);
725
bluetooth_agent_set_passkey_func(agent, pin_request, adapter);
726
bluetooth_agent_set_display_func(agent, display_request, adapter);
727
bluetooth_agent_set_confirm_func(agent, confirm_request, adapter);
728
bluetooth_agent_set_authorize_func(agent, authorize_request, adapter);
729
bluetooth_agent_set_cancel_func(agent, cancel_request, adapter);
731
bluetooth_agent_register(agent, adapter);
733
g_object_unref (adapter);
735
g_free (adapter_str);
738
int setup_agents(void)
740
dbus_g_error_domain_register(AGENT_ERROR, "org.bluez.Error",
743
client = bluetooth_client_new();
744
g_signal_connect (G_OBJECT (client), "notify::default-adapter",
745
G_CALLBACK (default_adapter_changed), NULL);
746
default_adapter_changed (G_OBJECT (client), NULL, NULL);
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);
751
void cleanup_agents(void)
754
bluetooth_agent_unregister (agent);
755
g_object_unref (agent);
757
g_object_unref (client);
760
476
void show_agents(void)
762
478
close_notification();
764
480
g_list_foreach(input_list, show_dialog, NULL);