gnome-control-center/panels/bluetooth/cc-bluetooth-panel.c

845 lines
24 KiB
C
Raw Normal View History

/*
*
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2006-2010 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 <glib/gi18n-lib.h>
#include <libgnome-control-center/cc-shell.h>
#include "cc-bluetooth-panel.h"
#include <bluetooth-client.h>
#include <bluetooth-utils.h>
#include <bluetooth-killswitch.h>
#include <bluetooth-chooser.h>
#include <bluetooth-plugin-manager.h>
G_DEFINE_DYNAMIC_TYPE (CcBluetoothPanel, cc_bluetooth_panel, CC_TYPE_PANEL)
#define BLUETOOTH_PANEL_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_BLUETOOTH_PANEL, CcBluetoothPanelPrivate))
#define WID(s) GTK_WIDGET (gtk_builder_get_object (self->priv->builder, s))
#define KEYBOARD_PREFS "keyboard"
#define MOUSE_PREFS "mouse"
#define SOUND_PREFS "sound"
#define WIZARD "bluetooth-wizard"
struct CcBluetoothPanelPrivate {
GtkBuilder *builder;
GtkWidget *chooser;
BluetoothClient *client;
BluetoothKillswitch *killswitch;
gboolean debug;
};
static void cc_bluetooth_panel_finalize (GObject *object);
static void
launch_command (const char *command)
{
GError *error = NULL;
if (!g_spawn_command_line_async(command, &error)) {
g_warning ("Couldn't execute command '%s': %s\n", command, error->message);
g_error_free (error);
}
}
static void
cc_bluetooth_panel_class_init (CcBluetoothPanelClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = cc_bluetooth_panel_finalize;
g_type_class_add_private (klass, sizeof (CcBluetoothPanelPrivate));
}
static void
cc_bluetooth_panel_class_finalize (CcBluetoothPanelClass *klass)
{
}
static void
cc_bluetooth_panel_finalize (GObject *object)
{
CcBluetoothPanel *self;
bluetooth_plugin_manager_cleanup ();
self = CC_BLUETOOTH_PANEL (object);
if (self->priv->builder) {
g_object_unref (self->priv->builder);
self->priv->builder = NULL;
}
if (self->priv->killswitch) {
g_object_unref (self->priv->killswitch);
self->priv->killswitch = NULL;
}
if (self->priv->client) {
g_object_unref (self->priv->client);
self->priv->client = NULL;
}
G_OBJECT_CLASS (cc_bluetooth_panel_parent_class)->finalize (object);
}
typedef struct {
char *bdaddr;
CcBluetoothPanel *self;
} ConnectData;
static void
connect_done (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
CcBluetoothPanel *self;
char *bdaddr;
gboolean success;
ConnectData *data = (ConnectData *) user_data;
success = bluetooth_client_connect_service_finish (BLUETOOTH_CLIENT (source_object),
res, NULL);
self = data->self;
/* Check whether the same device is now selected */
bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
if (g_strcmp0 (bdaddr, data->bdaddr) == 0) {
GtkSwitch *button;
button = GTK_SWITCH (WID ("switch_connection"));
/* Reset the switch if it failed */
if (success == FALSE)
gtk_switch_set_active (button, !gtk_switch_get_active (button));
gtk_widget_set_sensitive (GTK_WIDGET (button), TRUE);
}
g_free (bdaddr);
g_object_unref (data->self);
g_free (data->bdaddr);
g_free (data);
}
static void
switch_connected_active_changed (GtkSwitch *button,
GParamSpec *spec,
CcBluetoothPanel *self)
{
char *proxy;
GValue value = { 0, };
ConnectData *data;
if (bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
"proxy", &value) == FALSE) {
g_warning ("Could not get D-Bus proxy for selected device");
return;
}
proxy = g_strdup (g_dbus_proxy_get_object_path (g_value_get_object (&value)));
g_value_unset (&value);
if (proxy == NULL)
return;
data = g_new0 (ConnectData, 1);
data->bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
data->self = g_object_ref (self);
bluetooth_client_connect_service (self->priv->client,
proxy,
gtk_switch_get_active (button),
NULL,
connect_done,
data);
/* FIXME: make a note somewhere that the button for that
* device should be disabled */
gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
g_free (proxy);
}
enum {
NOTEBOOK_PAGE_EMPTY = 0,
NOTEBOOK_PAGE_PROPS = 1
};
static void
set_notebook_page (CcBluetoothPanel *self,
int page)
{
gtk_notebook_set_current_page (GTK_NOTEBOOK (WID ("props_notebook")), page);
}
static void
add_extra_setup_widgets (CcBluetoothPanel *self,
const char *bdaddr)
{
GValue value = { 0 };
char **uuids;
GList *list, *l;
GtkWidget *container;
if (bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
"uuids", &value) == FALSE)
return;
uuids = (char **) g_value_get_boxed (&value);
list = bluetooth_plugin_manager_get_widgets (bdaddr, (const char **) uuids);
if (list == NULL) {
g_value_unset (&value);
return;
}
container = WID ("additional_setup_box");
for (l = list; l != NULL; l = l->next) {
GtkWidget *widget = l->data;
gtk_box_pack_start (GTK_BOX (container), widget,
FALSE, FALSE, 0);
gtk_widget_show_all (widget);
}
gtk_widget_show (container);
g_value_unset (&value);
}
static void
remove_extra_setup_widgets (CcBluetoothPanel *self)
{
GtkWidget *box;
box = WID ("additional_setup_box");
gtk_container_forall (GTK_CONTAINER (box), (GtkCallback) gtk_widget_destroy, NULL);
gtk_widget_hide (WID ("additional_setup_box"));
}
static void
cc_bluetooth_panel_update_properties (CcBluetoothPanel *self)
{
char *bdaddr;
GtkSwitch *button;
button = GTK_SWITCH (WID ("switch_connection"));
g_signal_handlers_block_by_func (button, switch_connected_active_changed, self);
/* Hide all the buttons now, and show them again if we need to */
gtk_widget_hide (WID ("keyboard_box"));
gtk_widget_hide (WID ("sound_box"));
gtk_widget_hide (WID ("mouse_box"));
gtk_widget_hide (WID ("browse_box"));
gtk_widget_hide (WID ("send_box"));
/* Remove the extra setup widgets */
remove_extra_setup_widgets (self);
bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
if (bdaddr == NULL) {
gtk_widget_set_sensitive (WID ("properties_vbox"), FALSE);
gtk_switch_set_active (button, FALSE);
gtk_widget_set_sensitive (WID ("button_delete"), FALSE);
set_notebook_page (self, NOTEBOOK_PAGE_EMPTY);
} else {
BluetoothType type;
gboolean connected;
GValue value = { 0 };
GHashTable *services;
if (self->priv->debug)
bluetooth_chooser_dump_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
gtk_widget_set_sensitive (WID ("properties_vbox"), TRUE);
connected = bluetooth_chooser_get_selected_device_is_connected (BLUETOOTH_CHOOSER (self->priv->chooser));
gtk_switch_set_active (button, connected);
/* Paired */
bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
"paired", &value);
gtk_label_set_text (GTK_LABEL (WID ("paired_label")),
g_value_get_boolean (&value) ? _("Yes") : _("No"));
g_value_unset (&value);
/* Connection */
bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
"services", &value);
services = g_value_get_boxed (&value);
gtk_widget_set_sensitive (GTK_WIDGET (button), (services != NULL));
g_value_unset (&value);
/* UUIDs */
if (bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
"uuids", &value)) {
const char **uuids;
guint i;
uuids = (const char **) g_value_get_boxed (&value);
for (i = 0; uuids && uuids[i] != NULL; i++) {
if (g_str_equal (uuids[i], "OBEXObjectPush"))
gtk_widget_show (WID ("send_box"));
else if (g_str_equal (uuids[i], "OBEXFileTransfer"))
gtk_widget_show (WID ("browse_box"));
}
g_value_unset (&value);
}
/* Type */
type = bluetooth_chooser_get_selected_device_type (BLUETOOTH_CHOOSER (self->priv->chooser));
gtk_label_set_text (GTK_LABEL (WID ("type_label")), bluetooth_type_to_string (type));
switch (type) {
case BLUETOOTH_TYPE_KEYBOARD:
gtk_widget_show (WID ("keyboard_box"));
break;
case BLUETOOTH_TYPE_MOUSE:
case BLUETOOTH_TYPE_TABLET:
gtk_widget_show (WID ("mouse_box"));
break;
case BLUETOOTH_TYPE_HEADSET:
case BLUETOOTH_TYPE_HEADPHONES:
case BLUETOOTH_TYPE_OTHER_AUDIO:
gtk_widget_show (WID ("sound_box"));
default:
/* others? */
;
}
/* Extra widgets */
add_extra_setup_widgets (self, bdaddr);
gtk_label_set_text (GTK_LABEL (WID ("address_label")), bdaddr);
g_free (bdaddr);
gtk_widget_set_sensitive (WID ("button_delete"), TRUE);
set_notebook_page (self, NOTEBOOK_PAGE_PROPS);
}
g_signal_handlers_unblock_by_func (button, switch_connected_active_changed, self);
}
static void
power_callback (GObject *object,
GParamSpec *spec,
CcBluetoothPanel *self)
{
gboolean state;
state = gtk_switch_get_active (GTK_SWITCH (WID ("switch_bluetooth")));
g_debug ("Power switched to %s", state ? "off" : "on");
bluetooth_killswitch_set_state (self->priv->killswitch,
state ? KILLSWITCH_STATE_UNBLOCKED : KILLSWITCH_STATE_SOFT_BLOCKED);
}
static void
cc_bluetooth_panel_update_treeview_message (CcBluetoothPanel *self,
const char *message)
{
if (message != NULL) {
gtk_widget_hide (self->priv->chooser);
gtk_widget_show (WID ("message_scrolledwindow"));
gtk_label_set_text (GTK_LABEL (WID ("message_label")),
message);
} else {
gtk_widget_hide (WID ("message_scrolledwindow"));
gtk_widget_show (self->priv->chooser);
}
}
static void
cc_bluetooth_panel_update_power (CcBluetoothPanel *self)
{
KillswitchState state;
char *path;
gboolean powered, sensitive;
GtkSwitch *button;
g_object_get (G_OBJECT (self->priv->client),
"default-adapter", &path,
"default-adapter-powered", &powered,
NULL);
state = bluetooth_killswitch_get_state (self->priv->killswitch);
g_debug ("Updating power, default adapter: %s (powered: %s), killswitch: %s",
path ? path : "(none)",
powered ? "on" : "off",
bluetooth_killswitch_state_to_string (state));
if (path == NULL &&
bluetooth_killswitch_has_killswitches (self->priv->killswitch) &&
state != KILLSWITCH_STATE_HARD_BLOCKED) {
g_debug ("Default adapter is unpowered, but should be available");
sensitive = TRUE;
cc_bluetooth_panel_update_treeview_message (self, _("Bluetooth is disabled"));
} else if (path == NULL &&
state == KILLSWITCH_STATE_HARD_BLOCKED) {
g_debug ("Bluetooth is Hard blocked");
sensitive = FALSE;
cc_bluetooth_panel_update_treeview_message (self, _("Bluetooth is disabled by hardware switch"));
} else if (path == NULL) {
sensitive = FALSE;
g_debug ("No Bluetooth available");
cc_bluetooth_panel_update_treeview_message (self, _("No Bluetooth adapters found"));
} else {
sensitive = TRUE;
g_debug ("Bluetooth is available and powered");
cc_bluetooth_panel_update_treeview_message (self, NULL);
}
g_free (path);
gtk_widget_set_sensitive (WID ("box_power") , sensitive);
gtk_widget_set_sensitive (WID ("box_vis") , sensitive);
button = GTK_SWITCH (WID ("switch_bluetooth"));
g_signal_handlers_block_by_func (button, power_callback, self);
gtk_switch_set_active (button, powered);
g_signal_handlers_unblock_by_func (button, power_callback, self);
}
static void
switch_panel (CcBluetoothPanel *self,
const char *panel)
{
CcShell *shell;
GError *error = NULL;
shell = cc_panel_get_shell (CC_PANEL (self));
if (cc_shell_set_active_panel_from_id (shell, panel, NULL, &error) == FALSE)
{
g_warning ("Failed to activate Region panel: %s", error->message);
g_error_free (error);
}
}
static gboolean
keyboard_callback (GtkButton *button,
CcBluetoothPanel *self)
{
switch_panel (self, KEYBOARD_PREFS);
return TRUE;
}
static gboolean
mouse_callback (GtkButton *button,
CcBluetoothPanel *self)
{
switch_panel (self, MOUSE_PREFS);
return TRUE;
}
static gboolean
sound_callback (GtkButton *button,
CcBluetoothPanel *self)
{
switch_panel (self, SOUND_PREFS);
return TRUE;
}
static void
send_callback (GtkButton *button,
CcBluetoothPanel *self)
{
char *bdaddr, *alias;
bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
alias = bluetooth_chooser_get_selected_device_name (BLUETOOTH_CHOOSER (self->priv->chooser));
bluetooth_send_to_address (bdaddr, alias);
g_free (bdaddr);
g_free (alias);
}
static void
mount_finish_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
GError *error = NULL;
if (bluetooth_browse_address_finish (source_object, res, &error) == FALSE) {
g_printerr ("Failed to mount OBEX volume: %s", error->message);
g_error_free (error);
return;
}
}
static void
browse_callback (GtkButton *button,
CcBluetoothPanel *self)
{
char *bdaddr;
bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
bluetooth_browse_address (G_OBJECT (self), bdaddr,
GDK_CURRENT_TIME, mount_finish_cb, NULL);
g_free (bdaddr);
}
/* Visibility/Discoverable */
static void discoverable_changed (BluetoothClient *client,
GParamSpec *spec,
CcBluetoothPanel *self);
static void
switch_discoverable_active_changed (GtkSwitch *button,
GParamSpec *spec,
CcBluetoothPanel *self)
{
g_signal_handlers_block_by_func (self->priv->client, discoverable_changed, self);
g_object_set (G_OBJECT (self->priv->client), "default-adapter-discoverable",
gtk_switch_get_active (button), NULL);
g_signal_handlers_unblock_by_func (self->priv->client, discoverable_changed, self);
}
static void
cc_bluetooth_panel_update_visibility (CcBluetoothPanel *self)
{
gboolean discoverable;
GtkSwitch *button;
char *name;
button = GTK_SWITCH (WID ("switch_discoverable"));
g_object_get (G_OBJECT (self->priv->client), "default-adapter-discoverable", &discoverable, NULL);
g_signal_handlers_block_by_func (button, switch_discoverable_active_changed, self);
gtk_switch_set_active (button, discoverable);
g_signal_handlers_unblock_by_func (button, switch_discoverable_active_changed, self);
g_object_get (G_OBJECT (self->priv->client), "default-adapter-name", &name, NULL);
if (name == NULL) {
gtk_widget_set_sensitive (WID ("switch_discoverable"), FALSE);
gtk_widget_set_sensitive (WID ("visible_label"), FALSE);
gtk_label_set_text (GTK_LABEL (WID ("visible_label")), _("Visibility"));
} else {
char *label;
label = g_strdup_printf (_("Visibility of “%s”"), name);
g_free (name);
gtk_label_set_text (GTK_LABEL (WID ("visible_label")), label);
g_free (label);
gtk_widget_set_sensitive (WID ("switch_discoverable"), TRUE);
gtk_widget_set_sensitive (WID ("visible_label"), TRUE);
}
}
static void
discoverable_changed (BluetoothClient *client,
GParamSpec *spec,
CcBluetoothPanel *self)
{
cc_bluetooth_panel_update_visibility (self);
}
static void
name_changed (BluetoothClient *client,
GParamSpec *spec,
CcBluetoothPanel *self)
{
cc_bluetooth_panel_update_visibility (self);
}
static void
device_selected_changed (BluetoothChooser *chooser,
GParamSpec *spec,
CcBluetoothPanel *self)
{
cc_bluetooth_panel_update_properties (self);
}
static gboolean
show_confirm_dialog (CcBluetoothPanel *self,
const char *name)
{
GtkWidget *dialog, *parent;
gint response;
parent = gtk_widget_get_toplevel (GTK_WIDGET (self));
dialog = gtk_message_dialog_new (GTK_WINDOW (parent), GTK_DIALOG_MODAL,
GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
_("Remove '%s' from the list of devices?"), name);
g_object_set (G_OBJECT (dialog), "secondary-text",
_("If you remove the device, you will have to set it up again before next use."),
NULL);
gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_REMOVE, GTK_RESPONSE_ACCEPT);
response = gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
if (response == GTK_RESPONSE_ACCEPT)
return TRUE;
return FALSE;
}
static gboolean
remove_selected_device (CcBluetoothPanel *self)
{
GValue value = { 0, };
char *device, *adapter;
GDBusProxy *adapter_proxy;
GError *error = NULL;
GVariant *ret;
if (bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
"proxy", &value) == FALSE) {
return FALSE;
}
device = g_strdup (g_dbus_proxy_get_object_path (g_value_get_object (&value)));
g_value_unset (&value);
g_object_get (G_OBJECT (self->priv->client), "default-adapter", &adapter, NULL);
adapter_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
NULL,
"org.bluez",
adapter,
"org.bluez.Adapter",
NULL,
&error);
g_free (adapter);
if (adapter_proxy == NULL) {
g_warning ("Failed to create a GDBusProxy for the default adapter: %s", error->message);
g_error_free (error);
g_free (device);
return FALSE;
}
ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (adapter_proxy),
"RemoveDevice",
g_variant_new ("(o)", device),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
&error);
if (ret == NULL) {
g_warning ("Failed to remove device '%s': %s", device, error->message);
g_error_free (error);
} else {
g_variant_unref (ret);
}
g_object_unref (adapter_proxy);
g_free (device);
return (ret != NULL);
}
/* Treeview buttons */
static void
delete_clicked (GtkToolButton *button,
CcBluetoothPanel *self)
{
char *address, *name;
address = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
g_assert (address);
name = bluetooth_chooser_get_selected_device_name (BLUETOOTH_CHOOSER (self->priv->chooser));
if (show_confirm_dialog (self, name) != FALSE) {
if (remove_selected_device (self))
bluetooth_plugin_manager_device_deleted (address);
}
g_free (address);
g_free (name);
}
static void
setup_clicked (GtkToolButton *button,
CcBluetoothPanel *self)
{
launch_command (WIZARD);
}
/* Overall device state */
static void
cc_bluetooth_panel_update_state (CcBluetoothPanel *self)
{
char *bdaddr;
gboolean powered;
g_object_get (G_OBJECT (self->priv->client),
"default-adapter", &bdaddr,
"default-adapter-powered", &powered,
NULL);
gtk_widget_set_sensitive (WID ("toolbar"), (bdaddr != NULL));
g_free (bdaddr);
}
static void
default_adapter_changed (BluetoothClient *client,
GParamSpec *spec,
CcBluetoothPanel *self)
{
cc_bluetooth_panel_update_state (self);
cc_bluetooth_panel_update_power (self);
}
static void
killswitch_changed (BluetoothKillswitch *killswitch,
KillswitchState state,
CcBluetoothPanel *self)
{
cc_bluetooth_panel_update_state (self);
cc_bluetooth_panel_update_power (self);
}
static void
cc_bluetooth_panel_init (CcBluetoothPanel *self)
{
GtkWidget *widget;
GError *error = NULL;
GtkStyleContext *context;
self->priv = BLUETOOTH_PANEL_PRIVATE (self);
bluetooth_plugin_manager_init ();
self->priv->killswitch = bluetooth_killswitch_new ();
self->priv->client = bluetooth_client_new ();
self->priv->debug = g_getenv ("BLUETOOTH_DEBUG") != NULL;
self->priv->builder = gtk_builder_new ();
gtk_builder_set_translation_domain (self->priv->builder, GETTEXT_PACKAGE);
gtk_builder_add_from_file (self->priv->builder,
PKGDATADIR "/bluetooth.ui",
&error);
if (error != NULL) {
g_warning ("Failed to load '%s': %s", PKGDATADIR "/bluetooth.ui", error->message);
g_error_free (error);
return;
}
widget = WID ("grid");
gtk_widget_reparent (widget, GTK_WIDGET (self));
/* Overall device state */
cc_bluetooth_panel_update_state (self);
g_signal_connect (G_OBJECT (self->priv->client), "notify::default-adapter",
G_CALLBACK (default_adapter_changed), self);
/* The discoverable button */
cc_bluetooth_panel_update_visibility (self);
g_signal_connect (G_OBJECT (self->priv->client), "notify::default-adapter-discoverable",
G_CALLBACK (discoverable_changed), self);
g_signal_connect (G_OBJECT (self->priv->client), "notify::default-adapter-name",
G_CALLBACK (name_changed), self);
g_signal_connect (G_OBJECT (WID ("switch_discoverable")), "notify::active",
G_CALLBACK (switch_discoverable_active_changed), self);
/* The known devices */
widget = WID ("devices_table");
context = gtk_widget_get_style_context (WID ("message_scrolledwindow"));
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
/* Note that this will only ever show the devices on the default
* adapter, this is on purpose */
self->priv->chooser = bluetooth_chooser_new (NULL);
gtk_box_pack_start (GTK_BOX (WID ("box_devices")), self->priv->chooser, TRUE, TRUE, 0);
g_object_set (self->priv->chooser,
"show-searching", FALSE,
"show-device-type", FALSE,
"show-device-type-column", FALSE,
"show-device-category", FALSE,
"show-pairing", FALSE,
"show-connected", FALSE,
"device-category-filter", BLUETOOTH_CATEGORY_PAIRED_OR_TRUSTED,
"no-show-all", TRUE,
NULL);
/* Join treeview and buttons */
widget = bluetooth_chooser_get_scrolled_window (BLUETOOTH_CHOOSER (self->priv->chooser));
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (widget), 250);
gtk_scrolled_window_set_min_content_width (GTK_SCROLLED_WINDOW (widget), 200);
context = gtk_widget_get_style_context (widget);
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
widget = WID ("toolbar");
context = gtk_widget_get_style_context (widget);
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
g_signal_connect (G_OBJECT (self->priv->chooser), "notify::device-selected",
G_CALLBACK (device_selected_changed), self);
g_signal_connect (G_OBJECT (WID ("button_delete")), "clicked",
G_CALLBACK (delete_clicked), self);
g_signal_connect (G_OBJECT (WID ("button_setup")), "clicked",
G_CALLBACK (setup_clicked), self);
/* Set the initial state of the properties */
cc_bluetooth_panel_update_properties (self);
g_signal_connect (G_OBJECT (WID ("mouse_link")), "activate-link",
G_CALLBACK (mouse_callback), self);
g_signal_connect (G_OBJECT (WID ("keyboard_link")), "activate-link",
G_CALLBACK (keyboard_callback), self);
g_signal_connect (G_OBJECT (WID ("sound_link")), "activate-link",
G_CALLBACK (sound_callback), self);
g_signal_connect (G_OBJECT (WID ("browse_button")), "clicked",
G_CALLBACK (browse_callback), self);
g_signal_connect (G_OBJECT (WID ("send_button")), "clicked",
G_CALLBACK (send_callback), self);
g_signal_connect (G_OBJECT (WID ("switch_connection")), "notify::active",
G_CALLBACK (switch_connected_active_changed), self);
/* Set the initial state of power */
g_signal_connect (G_OBJECT (WID ("switch_bluetooth")), "notify::active",
G_CALLBACK (power_callback), self);
g_signal_connect (G_OBJECT (self->priv->killswitch), "state-changed",
G_CALLBACK (killswitch_changed), self);
cc_bluetooth_panel_update_power (self);
gtk_widget_show_all (GTK_WIDGET (self));
}
void
cc_bluetooth_panel_register (GIOModule *module)
{
cc_bluetooth_panel_register_type (G_TYPE_MODULE (module));
g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT,
CC_TYPE_BLUETOOTH_PANEL,
"bluetooth", 0);
}
/* GIO extension stuff */
void
g_io_module_load (GIOModule *module)
{
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
/* register the panel */
cc_bluetooth_panel_register (module);
}
void
g_io_module_unload (GIOModule *module)
{
}