3
* BlueZ - Bluetooth protocol stack for Linux
5
* Copyright (C) 2006-2010 Bastien Nocera <hadess@hadess.net>
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28
#include <glib/gi18n-lib.h>
29
#include <shell/cc-shell.h>
31
#include "cc-bluetooth-panel.h"
33
#include <bluetooth-client.h>
34
#include <bluetooth-utils.h>
35
#include <bluetooth-killswitch.h>
36
#include <bluetooth-chooser.h>
37
#include <bluetooth-plugin-manager.h>
39
CC_PANEL_REGISTER (CcBluetoothPanel, cc_bluetooth_panel)
41
#define BLUETOOTH_PANEL_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_BLUETOOTH_PANEL, CcBluetoothPanelPrivate))
43
#define WID(s) GTK_WIDGET (gtk_builder_get_object (self->priv->builder, s))
45
#define KEYBOARD_PREFS "keyboard"
46
#define MOUSE_PREFS "mouse"
47
#define SOUND_PREFS "sound"
48
#define WIZARD "bluetooth-wizard"
50
struct CcBluetoothPanelPrivate {
53
char *selected_bdaddr;
54
BluetoothClient *client;
55
BluetoothKillswitch *killswitch;
57
GHashTable *connecting_devices;
60
static void cc_bluetooth_panel_finalize (GObject *object);
63
launch_command (const char *command)
67
if (!g_spawn_command_line_async(command, &error)) {
68
g_warning ("Couldn't execute command '%s': %s\n", command, error->message);
74
cc_bluetooth_panel_get_help_uri (CcPanel *panel)
76
return "help:gnome-help/bluetooth";
80
cc_bluetooth_panel_class_init (CcBluetoothPanelClass *klass)
82
GObjectClass *object_class = G_OBJECT_CLASS (klass);
83
CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
85
object_class->finalize = cc_bluetooth_panel_finalize;
87
panel_class->get_help_uri = cc_bluetooth_panel_get_help_uri;
89
g_type_class_add_private (klass, sizeof (CcBluetoothPanelPrivate));
93
cc_bluetooth_panel_finalize (GObject *object)
95
CcBluetoothPanel *self;
97
bluetooth_plugin_manager_cleanup ();
99
self = CC_BLUETOOTH_PANEL (object);
100
g_clear_object (&self->priv->builder);
101
g_clear_object (&self->priv->killswitch);
102
g_clear_object (&self->priv->client);
104
g_clear_pointer (&self->priv->connecting_devices, g_hash_table_destroy);
105
g_clear_pointer (&self->priv->selected_bdaddr, g_free);
107
G_OBJECT_CLASS (cc_bluetooth_panel_parent_class)->finalize (object);
111
CONNECTING_NOTEBOOK_PAGE_SWITCH = 0,
112
CONNECTING_NOTEBOOK_PAGE_SPINNER = 1
116
set_connecting_page (CcBluetoothPanel *self,
119
if (page == CONNECTING_NOTEBOOK_PAGE_SPINNER)
120
gtk_spinner_start (GTK_SPINNER (WID ("connecting_spinner")));
121
gtk_notebook_set_current_page (GTK_NOTEBOOK (WID ("connecting_notebook")), page);
122
if (page == CONNECTING_NOTEBOOK_PAGE_SWITCH)
123
gtk_spinner_start (GTK_SPINNER (WID ("connecting_spinner")));
127
remove_connecting (CcBluetoothPanel *self,
130
g_hash_table_remove (self->priv->connecting_devices, bdaddr);
134
add_connecting (CcBluetoothPanel *self,
137
g_hash_table_insert (self->priv->connecting_devices,
139
GINT_TO_POINTER (1));
143
is_connecting (CcBluetoothPanel *self,
146
return GPOINTER_TO_INT (g_hash_table_lookup (self->priv->connecting_devices,
152
CcBluetoothPanel *self;
156
connect_done (GObject *source_object,
160
CcBluetoothPanel *self;
163
ConnectData *data = (ConnectData *) user_data;
165
success = bluetooth_client_connect_service_finish (BLUETOOTH_CLIENT (source_object),
170
/* Check whether the same device is now selected, and update the UI */
171
bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
172
if (g_strcmp0 (bdaddr, data->bdaddr) == 0) {
175
button = GTK_SWITCH (WID ("switch_connection"));
176
/* Reset the switch if it failed */
177
if (success == FALSE)
178
gtk_switch_set_active (button, !gtk_switch_get_active (button));
179
set_connecting_page (self, CONNECTING_NOTEBOOK_PAGE_SWITCH);
182
remove_connecting (self, data->bdaddr);
185
g_object_unref (data->self);
186
g_free (data->bdaddr);
191
switch_connected_active_changed (GtkSwitch *button,
193
CcBluetoothPanel *self)
196
GValue value = { 0, };
200
bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
201
if (is_connecting (self, bdaddr)) {
206
if (bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
207
"proxy", &value) == FALSE) {
208
g_warning ("Could not get D-Bus proxy for selected device");
211
proxy = g_strdup (g_dbus_proxy_get_object_path (g_value_get_object (&value)));
212
g_value_unset (&value);
217
data = g_new0 (ConnectData, 1);
218
data->bdaddr = bdaddr;
219
data->self = g_object_ref (self);
221
bluetooth_client_connect_service (self->priv->client,
223
gtk_switch_get_active (button),
228
add_connecting (self, data->bdaddr);
229
set_connecting_page (self, CONNECTING_NOTEBOOK_PAGE_SPINNER);
234
NOTEBOOK_PAGE_EMPTY = 0,
235
NOTEBOOK_PAGE_PROPS = 1
239
set_notebook_page (CcBluetoothPanel *self,
242
gtk_notebook_set_current_page (GTK_NOTEBOOK (WID ("props_notebook")), page);
246
add_extra_setup_widgets (CcBluetoothPanel *self,
249
GValue value = { 0 };
252
GtkWidget *container;
254
if (bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
255
"uuids", &value) == FALSE)
258
uuids = (char **) g_value_get_boxed (&value);
259
list = bluetooth_plugin_manager_get_widgets (bdaddr, (const char **) uuids);
261
g_value_unset (&value);
265
container = WID ("additional_setup_box");
266
for (l = list; l != NULL; l = l->next) {
267
GtkWidget *widget = l->data;
268
gtk_box_pack_start (GTK_BOX (container), widget,
270
gtk_widget_show_all (widget);
272
gtk_widget_show (container);
273
g_value_unset (&value);
277
remove_extra_setup_widgets (CcBluetoothPanel *self)
281
box = WID ("additional_setup_box");
282
gtk_container_forall (GTK_CONTAINER (box), (GtkCallback) gtk_widget_destroy, NULL);
283
gtk_widget_hide (WID ("additional_setup_box"));
287
cc_bluetooth_panel_update_properties (CcBluetoothPanel *self)
292
button = GTK_SWITCH (WID ("switch_connection"));
293
g_signal_handlers_block_by_func (button, switch_connected_active_changed, self);
295
/* Hide all the buttons now, and show them again if we need to */
296
gtk_widget_hide (WID ("keyboard_box"));
297
gtk_widget_hide (WID ("sound_box"));
298
gtk_widget_hide (WID ("mouse_box"));
299
gtk_widget_hide (WID ("browse_box"));
300
gtk_widget_hide (WID ("send_box"));
302
bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
304
/* Remove the extra setup widgets */
305
if (g_strcmp0 (self->priv->selected_bdaddr, bdaddr) != 0)
306
remove_extra_setup_widgets (self);
308
if (bdaddr == NULL) {
309
gtk_widget_set_sensitive (WID ("properties_vbox"), FALSE);
310
gtk_switch_set_active (button, FALSE);
311
gtk_widget_set_sensitive (WID ("button_delete"), FALSE);
312
set_notebook_page (self, NOTEBOOK_PAGE_EMPTY);
316
GValue value = { 0 };
317
GHashTable *services;
319
if (self->priv->debug)
320
bluetooth_chooser_dump_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
322
gtk_widget_set_sensitive (WID ("properties_vbox"), TRUE);
324
if (is_connecting (self, bdaddr)) {
325
gtk_switch_set_active (button, TRUE);
326
set_connecting_page (self, CONNECTING_NOTEBOOK_PAGE_SPINNER);
328
connected = bluetooth_chooser_get_selected_device_is_connected (BLUETOOTH_CHOOSER (self->priv->chooser));
329
gtk_switch_set_active (button, connected);
330
set_connecting_page (self, CONNECTING_NOTEBOOK_PAGE_SWITCH);
334
bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
336
gtk_label_set_text (GTK_LABEL (WID ("paired_label")),
337
g_value_get_boolean (&value) ? _("Yes") : _("No"));
338
g_value_unset (&value);
341
bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
343
services = g_value_get_boxed (&value);
344
gtk_widget_set_sensitive (GTK_WIDGET (button), (services != NULL));
345
g_value_unset (&value);
348
if (bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
353
uuids = (const char **) g_value_get_boxed (&value);
354
for (i = 0; uuids && uuids[i] != NULL; i++) {
355
if (g_str_equal (uuids[i], "OBEXObjectPush"))
356
gtk_widget_show (WID ("send_box"));
357
else if (g_str_equal (uuids[i], "OBEXFileTransfer"))
358
gtk_widget_show (WID ("browse_box"));
360
g_value_unset (&value);
364
type = bluetooth_chooser_get_selected_device_type (BLUETOOTH_CHOOSER (self->priv->chooser));
365
gtk_label_set_text (GTK_LABEL (WID ("type_label")), bluetooth_type_to_string (type));
367
case BLUETOOTH_TYPE_KEYBOARD:
368
gtk_widget_show (WID ("keyboard_box"));
370
case BLUETOOTH_TYPE_MOUSE:
371
case BLUETOOTH_TYPE_TABLET:
372
gtk_widget_show (WID ("mouse_box"));
374
case BLUETOOTH_TYPE_HEADSET:
375
case BLUETOOTH_TYPE_HEADPHONES:
376
case BLUETOOTH_TYPE_OTHER_AUDIO:
377
gtk_widget_show (WID ("sound_box"));
384
if (g_strcmp0 (self->priv->selected_bdaddr, bdaddr) != 0)
385
add_extra_setup_widgets (self, bdaddr);
387
gtk_label_set_text (GTK_LABEL (WID ("address_label")), bdaddr);
389
gtk_widget_set_sensitive (WID ("button_delete"), TRUE);
390
set_notebook_page (self, NOTEBOOK_PAGE_PROPS);
393
g_free (self->priv->selected_bdaddr);
394
self->priv->selected_bdaddr = bdaddr;
396
g_signal_handlers_unblock_by_func (button, switch_connected_active_changed, self);
400
power_callback (GObject *object,
402
CcBluetoothPanel *self)
406
state = gtk_switch_get_active (GTK_SWITCH (WID ("switch_bluetooth")));
407
g_debug ("Power switched to %s", state ? "off" : "on");
408
bluetooth_killswitch_set_state (self->priv->killswitch,
409
state ? BLUETOOTH_KILLSWITCH_STATE_UNBLOCKED : BLUETOOTH_KILLSWITCH_STATE_SOFT_BLOCKED);
413
cc_bluetooth_panel_update_treeview_message (CcBluetoothPanel *self,
416
if (message != NULL) {
417
gtk_widget_hide (self->priv->chooser);
418
gtk_widget_show (WID ("message_scrolledwindow"));
420
gtk_label_set_text (GTK_LABEL (WID ("message_label")),
423
gtk_widget_hide (WID ("message_scrolledwindow"));
424
gtk_widget_show (self->priv->chooser);
429
cc_bluetooth_panel_update_power (CcBluetoothPanel *self)
431
BluetoothKillswitchState state;
433
gboolean powered, sensitive;
435
g_object_get (G_OBJECT (self->priv->client),
436
"default-adapter", &path,
437
"default-adapter-powered", &powered,
439
state = bluetooth_killswitch_get_state (self->priv->killswitch);
441
g_debug ("Updating power, default adapter: %s (powered: %s), killswitch: %s",
442
path ? path : "(none)",
443
powered ? "on" : "off",
444
bluetooth_killswitch_state_to_string (state));
447
bluetooth_killswitch_has_killswitches (self->priv->killswitch) &&
448
state != BLUETOOTH_KILLSWITCH_STATE_HARD_BLOCKED) {
449
g_debug ("Default adapter is unpowered, but should be available");
451
cc_bluetooth_panel_update_treeview_message (self, _("Bluetooth is disabled"));
452
} else if (path == NULL &&
453
state == BLUETOOTH_KILLSWITCH_STATE_HARD_BLOCKED) {
454
g_debug ("Bluetooth is Hard blocked");
456
cc_bluetooth_panel_update_treeview_message (self, _("Bluetooth is disabled by hardware switch"));
457
} else if (path == NULL) {
459
g_debug ("No Bluetooth available");
460
cc_bluetooth_panel_update_treeview_message (self, _("No Bluetooth adapters found"));
463
g_debug ("Bluetooth is available and powered");
464
cc_bluetooth_panel_update_treeview_message (self, NULL);
468
gtk_widget_set_sensitive (WID ("box_power") , sensitive);
469
gtk_widget_set_sensitive (WID ("box_vis") , sensitive);
473
switch_panel (CcBluetoothPanel *self,
477
GError *error = NULL;
479
shell = cc_panel_get_shell (CC_PANEL (self));
480
if (cc_shell_set_active_panel_from_id (shell, panel, NULL, &error) == FALSE)
482
g_warning ("Failed to activate '%s' panel: %s", panel, error->message);
483
g_error_free (error);
488
keyboard_callback (GtkButton *button,
489
CcBluetoothPanel *self)
491
switch_panel (self, KEYBOARD_PREFS);
496
mouse_callback (GtkButton *button,
497
CcBluetoothPanel *self)
499
switch_panel (self, MOUSE_PREFS);
504
sound_callback (GtkButton *button,
505
CcBluetoothPanel *self)
507
switch_panel (self, SOUND_PREFS);
512
send_callback (GtkButton *button,
513
CcBluetoothPanel *self)
515
char *bdaddr, *alias;
517
bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
518
alias = bluetooth_chooser_get_selected_device_name (BLUETOOTH_CHOOSER (self->priv->chooser));
520
bluetooth_send_to_address (bdaddr, alias);
527
mount_finish_cb (GObject *source_object,
531
GError *error = NULL;
533
if (bluetooth_browse_address_finish (source_object, res, &error) == FALSE) {
534
g_printerr ("Failed to mount OBEX volume: %s", error->message);
535
g_error_free (error);
541
browse_callback (GtkButton *button,
542
CcBluetoothPanel *self)
546
bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
548
bluetooth_browse_address (G_OBJECT (self), bdaddr,
549
GDK_CURRENT_TIME, mount_finish_cb, NULL);
554
/* Visibility/Discoverable */
555
static void discoverable_changed (BluetoothClient *client,
557
CcBluetoothPanel *self);
560
switch_discoverable_active_changed (GtkSwitch *button,
562
CcBluetoothPanel *self)
564
g_signal_handlers_block_by_func (self->priv->client, discoverable_changed, self);
565
g_object_set (G_OBJECT (self->priv->client), "default-adapter-discoverable",
566
gtk_switch_get_active (button), NULL);
567
g_signal_handlers_unblock_by_func (self->priv->client, discoverable_changed, self);
571
cc_bluetooth_panel_update_visibility (CcBluetoothPanel *self)
573
gboolean discoverable;
577
button = GTK_SWITCH (WID ("switch_discoverable"));
578
g_object_get (G_OBJECT (self->priv->client), "default-adapter-discoverable", &discoverable, NULL);
579
g_signal_handlers_block_by_func (button, switch_discoverable_active_changed, self);
580
gtk_switch_set_active (button, discoverable);
581
g_signal_handlers_unblock_by_func (button, switch_discoverable_active_changed, self);
583
g_object_get (G_OBJECT (self->priv->client), "default-adapter-name", &name, NULL);
585
gtk_widget_set_sensitive (WID ("switch_discoverable"), FALSE);
586
gtk_widget_set_sensitive (WID ("visible_label"), FALSE);
587
gtk_label_set_text (GTK_LABEL (WID ("visible_label")), _("Visibility"));
591
label = g_strdup_printf (_("Visibility of “%s”"), name);
593
gtk_label_set_text (GTK_LABEL (WID ("visible_label")), label);
596
gtk_widget_set_sensitive (WID ("switch_discoverable"), TRUE);
597
gtk_widget_set_sensitive (WID ("visible_label"), TRUE);
602
discoverable_changed (BluetoothClient *client,
604
CcBluetoothPanel *self)
606
cc_bluetooth_panel_update_visibility (self);
610
name_changed (BluetoothClient *client,
612
CcBluetoothPanel *self)
614
cc_bluetooth_panel_update_visibility (self);
618
device_selected_changed (BluetoothChooser *chooser,
620
CcBluetoothPanel *self)
622
cc_bluetooth_panel_update_properties (self);
626
show_confirm_dialog (CcBluetoothPanel *self,
629
GtkWidget *dialog, *parent;
632
parent = gtk_widget_get_toplevel (GTK_WIDGET (self));
633
dialog = gtk_message_dialog_new (GTK_WINDOW (parent), GTK_DIALOG_MODAL,
634
GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
635
_("Remove '%s' from the list of devices?"), name);
636
g_object_set (G_OBJECT (dialog), "secondary-text",
637
_("If you remove the device, you will have to set it up again before next use."),
640
gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
641
gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_REMOVE, GTK_RESPONSE_ACCEPT);
643
response = gtk_dialog_run (GTK_DIALOG (dialog));
645
gtk_widget_destroy (dialog);
647
if (response == GTK_RESPONSE_ACCEPT)
654
remove_selected_device (CcBluetoothPanel *self)
656
GValue value = { 0, };
657
char *device, *adapter;
658
GDBusProxy *adapter_proxy;
659
GError *error = NULL;
662
if (bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
663
"proxy", &value) == FALSE) {
666
device = g_strdup (g_dbus_proxy_get_object_path (g_value_get_object (&value)));
667
g_value_unset (&value);
669
g_object_get (G_OBJECT (self->priv->client), "default-adapter", &adapter, NULL);
670
adapter_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
671
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
679
if (adapter_proxy == NULL) {
680
g_warning ("Failed to create a GDBusProxy for the default adapter: %s", error->message);
681
g_error_free (error);
686
ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (adapter_proxy),
688
g_variant_new ("(o)", device),
689
G_DBUS_CALL_FLAGS_NONE,
694
g_warning ("Failed to remove device '%s': %s", device, error->message);
695
g_error_free (error);
697
g_variant_unref (ret);
700
g_object_unref (adapter_proxy);
703
return (ret != NULL);
706
/* Treeview buttons */
708
delete_clicked (GtkToolButton *button,
709
CcBluetoothPanel *self)
711
char *address, *name;
713
address = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
716
name = bluetooth_chooser_get_selected_device_name (BLUETOOTH_CHOOSER (self->priv->chooser));
718
if (show_confirm_dialog (self, name) != FALSE) {
719
if (remove_selected_device (self))
720
bluetooth_plugin_manager_device_deleted (address);
728
setup_clicked (GtkToolButton *button,
729
CcBluetoothPanel *self)
731
launch_command (WIZARD);
734
/* Overall device state */
736
cc_bluetooth_panel_update_state (CcBluetoothPanel *self)
740
g_object_get (G_OBJECT (self->priv->client),
741
"default-adapter", &bdaddr,
743
gtk_widget_set_sensitive (WID ("toolbar"), (bdaddr != NULL));
748
cc_bluetooth_panel_update_powered_state (CcBluetoothPanel *self)
752
g_object_get (G_OBJECT (self->priv->client),
753
"default-adapter-powered", &powered,
755
gtk_switch_set_active (GTK_SWITCH (WID ("switch_bluetooth")), powered);
759
default_adapter_power_changed (BluetoothClient *client,
761
CcBluetoothPanel *self)
763
g_debug ("Default adapter power changed");
764
cc_bluetooth_panel_update_powered_state (self);
768
default_adapter_changed (BluetoothClient *client,
770
CcBluetoothPanel *self)
772
g_debug ("Default adapter changed");
773
cc_bluetooth_panel_update_state (self);
774
cc_bluetooth_panel_update_power (self);
775
cc_bluetooth_panel_update_powered_state (self);
779
killswitch_changed (BluetoothKillswitch *killswitch,
780
BluetoothKillswitchState state,
781
CcBluetoothPanel *self)
783
g_debug ("Killswitch changed to state '%s' (%d)", bluetooth_killswitch_state_to_string (state) , state);
784
cc_bluetooth_panel_update_state (self);
785
cc_bluetooth_panel_update_power (self);
789
cc_bluetooth_panel_init (CcBluetoothPanel *self)
792
GError *error = NULL;
793
GtkStyleContext *context;
795
self->priv = BLUETOOTH_PANEL_PRIVATE (self);
797
bluetooth_plugin_manager_init ();
798
self->priv->killswitch = bluetooth_killswitch_new ();
799
self->priv->client = bluetooth_client_new ();
800
self->priv->connecting_devices = g_hash_table_new_full (g_str_hash,
802
(GDestroyNotify) g_free,
804
self->priv->debug = g_getenv ("BLUETOOTH_DEBUG") != NULL;
806
self->priv->builder = gtk_builder_new ();
807
gtk_builder_set_translation_domain (self->priv->builder, GETTEXT_PACKAGE);
808
gtk_builder_add_from_file (self->priv->builder,
809
PKGDATADIR "/bluetooth.ui",
812
g_warning ("Failed to load '%s': %s", PKGDATADIR "/bluetooth.ui", error->message);
813
g_error_free (error);
817
widget = WID ("grid");
818
gtk_widget_reparent (widget, GTK_WIDGET (self));
820
/* Overall device state */
821
cc_bluetooth_panel_update_state (self);
822
g_signal_connect (G_OBJECT (self->priv->client), "notify::default-adapter",
823
G_CALLBACK (default_adapter_changed), self);
824
g_signal_connect (G_OBJECT (self->priv->client), "notify::default-adapter-powered",
825
G_CALLBACK (default_adapter_power_changed), self);
827
/* The discoverable button */
828
cc_bluetooth_panel_update_visibility (self);
829
g_signal_connect (G_OBJECT (self->priv->client), "notify::default-adapter-discoverable",
830
G_CALLBACK (discoverable_changed), self);
831
g_signal_connect (G_OBJECT (self->priv->client), "notify::default-adapter-name",
832
G_CALLBACK (name_changed), self);
833
g_signal_connect (G_OBJECT (WID ("switch_discoverable")), "notify::active",
834
G_CALLBACK (switch_discoverable_active_changed), self);
836
/* The known devices */
837
widget = WID ("devices_table");
839
context = gtk_widget_get_style_context (WID ("message_scrolledwindow"));
840
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
842
/* Note that this will only ever show the devices on the default
843
* adapter, this is on purpose */
844
self->priv->chooser = bluetooth_chooser_new ();
845
gtk_box_pack_start (GTK_BOX (WID ("box_devices")), self->priv->chooser, TRUE, TRUE, 0);
846
g_object_set (self->priv->chooser,
847
"show-searching", FALSE,
848
"show-device-type", FALSE,
849
"show-device-type-column", FALSE,
850
"show-device-category", FALSE,
851
"show-pairing", FALSE,
852
"show-connected", FALSE,
853
"device-category-filter", BLUETOOTH_CATEGORY_PAIRED_OR_TRUSTED,
857
/* Join treeview and buttons */
858
widget = bluetooth_chooser_get_scrolled_window (BLUETOOTH_CHOOSER (self->priv->chooser));
859
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (widget), 250);
860
gtk_scrolled_window_set_min_content_width (GTK_SCROLLED_WINDOW (widget), 200);
861
context = gtk_widget_get_style_context (widget);
862
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
863
widget = WID ("toolbar");
864
context = gtk_widget_get_style_context (widget);
865
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
867
g_signal_connect (G_OBJECT (self->priv->chooser), "notify::device-selected",
868
G_CALLBACK (device_selected_changed), self);
869
g_signal_connect (G_OBJECT (WID ("button_delete")), "clicked",
870
G_CALLBACK (delete_clicked), self);
871
g_signal_connect (G_OBJECT (WID ("button_setup")), "clicked",
872
G_CALLBACK (setup_clicked), self);
874
/* Set the initial state of the properties */
875
cc_bluetooth_panel_update_properties (self);
876
g_signal_connect (G_OBJECT (WID ("mouse_link")), "activate-link",
877
G_CALLBACK (mouse_callback), self);
878
g_signal_connect (G_OBJECT (WID ("keyboard_link")), "activate-link",
879
G_CALLBACK (keyboard_callback), self);
880
g_signal_connect (G_OBJECT (WID ("sound_link")), "activate-link",
881
G_CALLBACK (sound_callback), self);
882
g_signal_connect (G_OBJECT (WID ("browse_button")), "clicked",
883
G_CALLBACK (browse_callback), self);
884
g_signal_connect (G_OBJECT (WID ("send_button")), "clicked",
885
G_CALLBACK (send_callback), self);
886
g_signal_connect (G_OBJECT (WID ("switch_connection")), "notify::active",
887
G_CALLBACK (switch_connected_active_changed), self);
889
/* Set the initial state of power */
890
g_signal_connect (G_OBJECT (WID ("switch_bluetooth")), "notify::active",
891
G_CALLBACK (power_callback), self);
892
g_signal_connect (G_OBJECT (self->priv->killswitch), "state-changed",
893
G_CALLBACK (killswitch_changed), self);
894
cc_bluetooth_panel_update_power (self);
896
gtk_widget_show_all (GTK_WIDGET (self));
900
cc_bluetooth_panel_register (GIOModule *module)
902
cc_bluetooth_panel_register_type (G_TYPE_MODULE (module));
903
g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT,
904
CC_TYPE_BLUETOOTH_PANEL,
908
/* GIO extension stuff */
910
g_io_module_load (GIOModule *module)
912
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
913
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
915
/* register the panel */
916
cc_bluetooth_panel_register (module);
920
g_io_module_unload (GIOModule *module)