|
Packit |
8fb625 |
/*
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* BlueZ - Bluetooth protocol stack for Linux
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org>
|
|
Packit |
8fb625 |
* Copyright (C) 2010 Giovanni Campagna <scampa.giovanni@gmail.com>
|
|
Packit |
8fb625 |
* Copyright (C) 2013 Intel Corporation.
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
8fb625 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
8fb625 |
* License as published by the Free Software Foundation; either
|
|
Packit |
8fb625 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
8fb625 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
8fb625 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
8fb625 |
* Lesser General Public License for more details.
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
8fb625 |
* License along with this library; if not, write to the Free Software
|
|
Packit |
8fb625 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
*/
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
/**
|
|
Packit |
8fb625 |
* SECTION:bluetooth-client
|
|
Packit |
8fb625 |
* @short_description: Bluetooth client object
|
|
Packit |
8fb625 |
* @stability: Stable
|
|
Packit |
8fb625 |
* @include: bluetooth-client.h
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* The #BluetoothClient object is used to query the state of Bluetooth
|
|
Packit |
8fb625 |
* devices and adapters.
|
|
Packit |
8fb625 |
**/
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
8fb625 |
#include <config.h>
|
|
Packit |
8fb625 |
#endif
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
#include <string.h>
|
|
Packit |
8fb625 |
#include <glib/gi18n-lib.h>
|
|
Packit |
8fb625 |
#include <gtk/gtk.h>
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
#include "bluetooth-client.h"
|
|
Packit |
8fb625 |
#include "bluetooth-client-private.h"
|
|
Packit |
8fb625 |
#include "bluetooth-client-glue.h"
|
|
Packit |
8fb625 |
#include "bluetooth-utils.h"
|
|
Packit |
8fb625 |
#include "gnome-bluetooth-enum-types.h"
|
|
Packit |
8fb625 |
#include "pin.h"
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
#define BLUEZ_SERVICE "org.bluez"
|
|
Packit |
8fb625 |
#define BLUEZ_MANAGER_PATH "/"
|
|
Packit |
8fb625 |
#define BLUEZ_ADAPTER_INTERFACE "org.bluez.Adapter1"
|
|
Packit |
8fb625 |
#define BLUEZ_DEVICE_INTERFACE "org.bluez.Device1"
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
#define BLUETOOTH_CLIENT_GET_PRIVATE(obj) bluetooth_client_get_instance_private (obj)
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
typedef struct _BluetoothClientPrivate BluetoothClientPrivate;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
struct _BluetoothClientPrivate {
|
|
Packit |
8fb625 |
GDBusObjectManager *manager;
|
|
Packit |
8fb625 |
GCancellable *cancellable;
|
|
Packit |
8fb625 |
GtkTreeStore *store;
|
|
Packit |
8fb625 |
GtkTreeRowReference *default_adapter;
|
|
Packit |
8fb625 |
/* Discoverable during discovery? */
|
|
Packit |
8fb625 |
gboolean disco_during_disco;
|
|
Packit |
8fb625 |
gboolean discovery_started;
|
|
Packit |
8fb625 |
};
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
enum {
|
|
Packit |
8fb625 |
PROP_0,
|
|
Packit |
8fb625 |
PROP_DEFAULT_ADAPTER,
|
|
Packit |
8fb625 |
PROP_DEFAULT_ADAPTER_POWERED,
|
|
Packit |
8fb625 |
PROP_DEFAULT_ADAPTER_DISCOVERABLE,
|
|
Packit |
8fb625 |
PROP_DEFAULT_ADAPTER_NAME,
|
|
Packit |
8fb625 |
PROP_DEFAULT_ADAPTER_DISCOVERING
|
|
Packit |
8fb625 |
};
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
enum {
|
|
Packit |
8fb625 |
DEVICE_REMOVED,
|
|
Packit |
8fb625 |
LAST_SIGNAL
|
|
Packit |
8fb625 |
};
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static guint signals[LAST_SIGNAL] = { 0 };
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static const char *connectable_uuids[] = {
|
|
Packit |
8fb625 |
"HSP",
|
|
Packit |
8fb625 |
"AudioSource",
|
|
Packit |
8fb625 |
"AudioSink",
|
|
Packit |
8fb625 |
"A/V_RemoteControlTarget",
|
|
Packit |
8fb625 |
"A/V_RemoteControl",
|
|
Packit |
8fb625 |
"Headset_-_AG",
|
|
Packit |
8fb625 |
"Handsfree",
|
|
Packit |
8fb625 |
"HandsfreeAudioGateway",
|
|
Packit |
8fb625 |
"HumanInterfaceDeviceService",
|
|
Packit |
8fb625 |
};
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
G_DEFINE_TYPE_WITH_PRIVATE(BluetoothClient, bluetooth_client, G_TYPE_OBJECT)
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
typedef gboolean (*IterSearchFunc) (GtkTreeStore *store,
|
|
Packit |
8fb625 |
GtkTreeIter *iter, gpointer user_data);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static gboolean iter_search(GtkTreeStore *store,
|
|
Packit |
8fb625 |
GtkTreeIter *iter, GtkTreeIter *parent,
|
|
Packit |
8fb625 |
IterSearchFunc func, gpointer user_data)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
gboolean cont, found = FALSE;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (parent == NULL)
|
|
Packit |
8fb625 |
cont = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store),
|
|
Packit |
8fb625 |
iter);
|
|
Packit |
8fb625 |
else
|
|
Packit |
8fb625 |
cont = gtk_tree_model_iter_children(GTK_TREE_MODEL(store),
|
|
Packit |
8fb625 |
iter, parent);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
while (cont == TRUE) {
|
|
Packit |
8fb625 |
GtkTreeIter child;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
found = func(store, iter, user_data);
|
|
Packit |
8fb625 |
if (found == TRUE)
|
|
Packit |
8fb625 |
break;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
found = iter_search(store, &child, iter, func, user_data);
|
|
Packit |
8fb625 |
if (found == TRUE) {
|
|
Packit |
8fb625 |
*iter = child;
|
|
Packit |
8fb625 |
break;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
cont = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), iter);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return found;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static gboolean compare_path(GtkTreeStore *store,
|
|
Packit |
8fb625 |
GtkTreeIter *iter, gpointer user_data)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
const gchar *path = user_data;
|
|
Packit |
8fb625 |
GDBusProxy *object;
|
|
Packit |
8fb625 |
gboolean found = FALSE;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get(GTK_TREE_MODEL(store), iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PROXY, &object, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (object != NULL) {
|
|
Packit |
8fb625 |
found = g_str_equal(path, g_dbus_proxy_get_object_path(object));
|
|
Packit |
8fb625 |
g_object_unref(object);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return found;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static gboolean
|
|
Packit |
8fb625 |
compare_address (GtkTreeStore *store,
|
|
Packit |
8fb625 |
GtkTreeIter *iter,
|
|
Packit |
8fb625 |
gpointer user_data)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
const char *address = user_data;
|
|
Packit |
8fb625 |
char *tmp_address;
|
|
Packit |
8fb625 |
gboolean found = FALSE;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL(store), iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_ADDRESS, &tmp_address, -1);
|
|
Packit |
8fb625 |
found = g_str_equal (address, tmp_address);
|
|
Packit |
8fb625 |
g_free (tmp_address);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return found;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static gboolean
|
|
Packit |
8fb625 |
get_iter_from_path (GtkTreeStore *store,
|
|
Packit |
8fb625 |
GtkTreeIter *iter,
|
|
Packit |
8fb625 |
const char *path)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
return iter_search(store, iter, NULL, compare_path, (gpointer) path);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static gboolean
|
|
Packit |
8fb625 |
get_iter_from_proxy(GtkTreeStore *store,
|
|
Packit |
8fb625 |
GtkTreeIter *iter,
|
|
Packit |
8fb625 |
GDBusProxy *proxy)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
return iter_search(store, iter, NULL, compare_path,
|
|
Packit |
8fb625 |
(gpointer) g_dbus_proxy_get_object_path (proxy));
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static gboolean
|
|
Packit |
8fb625 |
get_iter_from_address (GtkTreeStore *store,
|
|
Packit |
8fb625 |
GtkTreeIter *iter,
|
|
Packit |
8fb625 |
const char *address,
|
|
Packit |
8fb625 |
GDBusProxy *adapter)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
GtkTreeIter parent_iter;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (get_iter_from_proxy (store, &parent_iter, adapter) == FALSE)
|
|
Packit |
8fb625 |
return FALSE;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return iter_search (store, iter, &parent_iter, compare_address, (gpointer) address);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static char **
|
|
Packit |
8fb625 |
device_list_uuids (const gchar * const *uuids)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
GPtrArray *ret;
|
|
Packit |
8fb625 |
guint i;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (uuids == NULL)
|
|
Packit |
8fb625 |
return NULL;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
ret = g_ptr_array_new ();
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
for (i = 0; uuids[i] != NULL; i++) {
|
|
Packit |
8fb625 |
const char *uuid;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
uuid = bluetooth_uuid_to_string (uuids[i]);
|
|
Packit |
8fb625 |
if (uuid == NULL)
|
|
Packit |
8fb625 |
continue;
|
|
Packit |
8fb625 |
g_ptr_array_add (ret, g_strdup (uuid));
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (ret->len == 0) {
|
|
Packit |
8fb625 |
g_ptr_array_free (ret, TRUE);
|
|
Packit |
8fb625 |
return NULL;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_ptr_array_add (ret, NULL);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return (char **) g_ptr_array_free (ret, FALSE);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gboolean
|
|
Packit |
8fb625 |
bluetooth_client_get_connectable(const char **uuids)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
int i, j;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
for (i = 0; uuids && uuids[i] != NULL; i++) {
|
|
Packit |
8fb625 |
for (j = 0; j < G_N_ELEMENTS (connectable_uuids); j++) {
|
|
Packit |
8fb625 |
if (g_str_equal (connectable_uuids[j], uuids[i]))
|
|
Packit |
8fb625 |
return TRUE;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return FALSE;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static const char *
|
|
Packit |
8fb625 |
phone_oui_to_icon_name (const char *bdaddr)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
char *vendor;
|
|
Packit |
8fb625 |
const char *ret = NULL;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
vendor = oui_to_vendor (bdaddr);
|
|
Packit |
8fb625 |
if (vendor == NULL)
|
|
Packit |
8fb625 |
return NULL;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (strstr (vendor, "Apple") != NULL)
|
|
Packit |
8fb625 |
ret = "phone-apple-iphone";
|
|
Packit |
8fb625 |
else if (strstr (vendor, "Samsung") != NULL)
|
|
Packit |
8fb625 |
ret = "phone-samsung-galaxy-s";
|
|
Packit |
8fb625 |
else if (strstr (vendor, "Google") != NULL)
|
|
Packit |
8fb625 |
ret = "phone-google-nexus-one";
|
|
Packit |
8fb625 |
g_free (vendor);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return ret;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static const char *
|
|
Packit |
8fb625 |
icon_override (const char *bdaddr,
|
|
Packit |
8fb625 |
BluetoothType type)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
/* audio-card, you're ugly */
|
|
Packit |
8fb625 |
switch (type) {
|
|
Packit |
8fb625 |
case BLUETOOTH_TYPE_HEADSET:
|
|
Packit |
8fb625 |
return "audio-headset";
|
|
Packit |
8fb625 |
case BLUETOOTH_TYPE_HEADPHONES:
|
|
Packit |
8fb625 |
return "audio-headphones";
|
|
Packit |
8fb625 |
case BLUETOOTH_TYPE_OTHER_AUDIO:
|
|
Packit |
8fb625 |
return "audio-speakers";
|
|
Packit |
8fb625 |
case BLUETOOTH_TYPE_PHONE:
|
|
Packit |
8fb625 |
return phone_oui_to_icon_name (bdaddr);
|
|
Packit |
8fb625 |
case BLUETOOTH_TYPE_DISPLAY:
|
|
Packit |
8fb625 |
return "video-display";
|
|
Packit |
8fb625 |
case BLUETOOTH_TYPE_SCANNER:
|
|
Packit |
8fb625 |
return "scanner";
|
|
Packit |
8fb625 |
case BLUETOOTH_TYPE_REMOTE_CONTROL:
|
|
Packit |
8fb625 |
case BLUETOOTH_TYPE_WEARABLE:
|
|
Packit |
8fb625 |
case BLUETOOTH_TYPE_TOY:
|
|
Packit |
8fb625 |
/* FIXME */
|
|
Packit |
8fb625 |
default:
|
|
Packit |
8fb625 |
return NULL;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
device_resolve_type_and_icon (Device1 *device, BluetoothType *type, const char **icon)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
g_return_if_fail (type);
|
|
Packit |
8fb625 |
g_return_if_fail (icon);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
*type = bluetooth_appearance_to_type (device1_get_appearance (device));
|
|
Packit |
8fb625 |
if (*type == 0 || *type == BLUETOOTH_TYPE_ANY)
|
|
Packit |
8fb625 |
*type = bluetooth_class_to_type (device1_get_class (device));
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
*icon = icon_override (device1_get_address (device), *type);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (!*icon)
|
|
Packit |
8fb625 |
*icon = device1_get_icon (device);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (!*icon)
|
|
Packit |
8fb625 |
*icon = "bluetooth";
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
device_notify_cb (Device1 *device,
|
|
Packit |
8fb625 |
GParamSpec *pspec,
|
|
Packit |
8fb625 |
BluetoothClient *client)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
const char *property = g_param_spec_get_name (pspec);
|
|
Packit |
8fb625 |
GtkTreeIter iter;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (get_iter_from_proxy (priv->store, &iter, G_DBUS_PROXY (device)) == FALSE)
|
|
Packit |
8fb625 |
return;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (g_strcmp0 (property, "name") == 0) {
|
|
Packit |
8fb625 |
const gchar *name = device1_get_name (device);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_store_set (priv->store, &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_NAME, name, -1);
|
|
Packit |
8fb625 |
} else if (g_strcmp0 (property, "alias") == 0) {
|
|
Packit |
8fb625 |
const gchar *alias = device1_get_alias (device);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_store_set (priv->store, &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_ALIAS, alias, -1);
|
|
Packit |
8fb625 |
} else if (g_strcmp0 (property, "paired") == 0) {
|
|
Packit |
8fb625 |
gboolean paired = device1_get_paired (device);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_store_set (priv->store, &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PAIRED, paired, -1);
|
|
Packit |
8fb625 |
} else if (g_strcmp0 (property, "trusted") == 0) {
|
|
Packit |
8fb625 |
gboolean trusted = device1_get_trusted (device);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_store_set (priv->store, &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_TRUSTED, trusted, -1);
|
|
Packit |
8fb625 |
} else if (g_strcmp0 (property, "connected") == 0) {
|
|
Packit |
8fb625 |
gboolean connected = device1_get_connected (device);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_store_set (priv->store, &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_CONNECTED, connected, -1);
|
|
Packit |
8fb625 |
} else if (g_strcmp0 (property, "uuids") == 0) {
|
|
Packit |
8fb625 |
char **uuids;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
uuids = device_list_uuids (device1_get_uuids (device));
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_store_set (priv->store, &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_UUIDS, uuids, -1);
|
|
Packit |
8fb625 |
g_strfreev (uuids);
|
|
Packit |
8fb625 |
} else if (g_strcmp0 (property, "legacy-pairing") == 0) {
|
|
Packit |
8fb625 |
gboolean legacypairing = device1_get_legacy_pairing (device);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_store_set (priv->store, &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_LEGACYPAIRING, legacypairing,
|
|
Packit |
8fb625 |
-1);
|
|
Packit |
8fb625 |
} else if (g_strcmp0 (property, "icon") == 0 ||
|
|
Packit |
8fb625 |
g_strcmp0 (property, "class") == 0 ||
|
|
Packit |
8fb625 |
g_strcmp0 (property, "appearance") == 0) {
|
|
Packit |
8fb625 |
BluetoothType type = BLUETOOTH_TYPE_ANY;
|
|
Packit |
8fb625 |
const char *icon = NULL;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
device_resolve_type_and_icon (device, &type, &icon);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_store_set (priv->store, &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_TYPE, type,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_ICON, icon,
|
|
Packit |
8fb625 |
-1);
|
|
Packit |
8fb625 |
} else {
|
|
Packit |
8fb625 |
g_debug ("Unhandled property: %s", property);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
device_added (GDBusObjectManager *manager,
|
|
Packit |
8fb625 |
Device1 *device,
|
|
Packit |
8fb625 |
BluetoothClient *client)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
GDBusProxy *adapter;
|
|
Packit |
8fb625 |
const char *adapter_path, *address, *alias, *name, *icon;
|
|
Packit |
8fb625 |
char **uuids;
|
|
Packit |
8fb625 |
gboolean paired, trusted, connected;
|
|
Packit |
8fb625 |
int legacypairing;
|
|
Packit |
8fb625 |
BluetoothType type;
|
|
Packit |
8fb625 |
GtkTreeIter iter, parent;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_signal_connect (G_OBJECT (device), "notify",
|
|
Packit |
8fb625 |
G_CALLBACK (device_notify_cb), client);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
adapter_path = device1_get_adapter (device);
|
|
Packit |
8fb625 |
address = device1_get_address (device);
|
|
Packit |
8fb625 |
alias = device1_get_alias (device);
|
|
Packit |
8fb625 |
name = device1_get_name (device);
|
|
Packit |
8fb625 |
paired = device1_get_paired (device);
|
|
Packit |
8fb625 |
trusted = device1_get_trusted (device);
|
|
Packit |
8fb625 |
connected = device1_get_connected (device);
|
|
Packit |
8fb625 |
uuids = device_list_uuids (device1_get_uuids (device));
|
|
Packit |
8fb625 |
legacypairing = device1_get_legacy_pairing (device);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
device_resolve_type_and_icon (device, &type, &icon);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (get_iter_from_path (priv->store, &parent, adapter_path) == FALSE)
|
|
Packit |
8fb625 |
return;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &parent,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PROXY, &adapter, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (get_iter_from_address (priv->store, &iter, address, adapter) == FALSE) {
|
|
Packit |
8fb625 |
gtk_tree_store_insert_with_values (priv->store, &iter, &parent, -1,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_ADDRESS, address,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_ALIAS, alias,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_NAME, name,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_TYPE, type,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_ICON, icon,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_LEGACYPAIRING, legacypairing,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_UUIDS, uuids,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PAIRED, paired,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_CONNECTED, connected,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_TRUSTED, trusted,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PROXY, device,
|
|
Packit |
8fb625 |
-1);
|
|
Packit |
8fb625 |
} else {
|
|
Packit |
8fb625 |
gtk_tree_store_set(priv->store, &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_ADDRESS, address,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_ALIAS, alias,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_NAME, name,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_TYPE, type,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_ICON, icon,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_LEGACYPAIRING, legacypairing,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_UUIDS, uuids,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PAIRED, paired,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_CONNECTED, connected,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_TRUSTED, trusted,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PROXY, device,
|
|
Packit |
8fb625 |
-1);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
g_strfreev (uuids);
|
|
Packit |
8fb625 |
g_object_unref (adapter);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
device_removed (const char *path,
|
|
Packit |
8fb625 |
BluetoothClient *client)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
GtkTreeIter iter;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (get_iter_from_path(priv->store, &iter, path) == TRUE) {
|
|
Packit |
8fb625 |
/* Note that removal can also happen from adapter_removed. */
|
|
Packit |
8fb625 |
g_signal_emit (G_OBJECT (client), signals[DEVICE_REMOVED], 0, path);
|
|
Packit |
8fb625 |
gtk_tree_store_remove(priv->store, &iter);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static gboolean
|
|
Packit |
8fb625 |
adapter_set_powered (BluetoothClient *client,
|
|
Packit |
8fb625 |
const char *path,
|
|
Packit |
8fb625 |
gboolean powered)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
GObject *adapter;
|
|
Packit |
8fb625 |
GtkTreeIter iter;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), FALSE);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (get_iter_from_path (priv->store, &iter, path) == FALSE)
|
|
Packit |
8fb625 |
return FALSE;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PROXY, &adapter, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (adapter == NULL)
|
|
Packit |
8fb625 |
return FALSE;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_object_set (adapter, "powered", powered, NULL);
|
|
Packit |
8fb625 |
g_object_unref (adapter);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return TRUE;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
default_adapter_changed (GDBusObjectManager *manager,
|
|
Packit |
8fb625 |
const char *path,
|
|
Packit |
8fb625 |
BluetoothClient *client)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
GtkTreeIter iter;
|
|
Packit |
8fb625 |
GtkTreePath *tree_path;
|
|
Packit |
8fb625 |
gboolean powered;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_assert (!priv->default_adapter);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (get_iter_from_path (priv->store, &iter, path) == FALSE)
|
|
Packit |
8fb625 |
return;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->store), &iter);
|
|
Packit |
8fb625 |
priv->default_adapter = gtk_tree_row_reference_new (GTK_TREE_MODEL (priv->store), tree_path);
|
|
Packit |
8fb625 |
gtk_tree_path_free (tree_path);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_store_set (priv->store, &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_DEFAULT, TRUE, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_POWERED, &powered, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (powered) {
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter");
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter-powered");
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter-discoverable");
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter-discovering");
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter-name");
|
|
Packit |
8fb625 |
return;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
/*
|
|
Packit |
8fb625 |
* If the adapter is turn off (Powered = False in bluetooth) object
|
|
Packit |
8fb625 |
* notifications will be sent only when a Powered = True signal arrives
|
|
Packit |
8fb625 |
* from bluetoothd
|
|
Packit |
8fb625 |
*/
|
|
Packit |
8fb625 |
adapter_set_powered (client, path, TRUE);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
adapter_notify_cb (Adapter1 *adapter,
|
|
Packit |
8fb625 |
GParamSpec *pspec,
|
|
Packit |
8fb625 |
BluetoothClient *client)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
const char *property = g_param_spec_get_name (pspec);
|
|
Packit |
8fb625 |
GtkTreeIter iter;
|
|
Packit |
8fb625 |
gboolean notify = TRUE;
|
|
Packit |
8fb625 |
gboolean is_default;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (get_iter_from_proxy (priv->store, &iter, G_DBUS_PROXY (adapter)) == FALSE)
|
|
Packit |
8fb625 |
return;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_DEFAULT, &is_default, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (g_strcmp0 (property, "name") == 0) {
|
|
Packit |
8fb625 |
const gchar *name = adapter1_get_name (adapter);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_store_set (priv->store, &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_NAME, name, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (is_default) {
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter-powered");
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter-name");
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
} else if (g_strcmp0 (property, "discovering") == 0) {
|
|
Packit |
8fb625 |
gboolean discovering = adapter1_get_discovering (adapter);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_store_set (priv->store, &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_DISCOVERING, discovering, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (is_default)
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter-discovering");
|
|
Packit |
8fb625 |
} else if (g_strcmp0 (property, "powered") == 0) {
|
|
Packit |
8fb625 |
gboolean powered = adapter1_get_powered (adapter);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_store_set (priv->store, &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_POWERED, powered, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (is_default && powered) {
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter");
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter-discoverable");
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter-discovering");
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter-name");
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter-powered");
|
|
Packit |
8fb625 |
} else if (g_strcmp0 (property, "discoverable") == 0) {
|
|
Packit |
8fb625 |
gboolean discoverable = adapter1_get_discoverable (adapter);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_store_set (priv->store, &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_DISCOVERABLE, discoverable, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (is_default)
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter-discoverable");
|
|
Packit |
8fb625 |
} else {
|
|
Packit |
8fb625 |
notify = FALSE;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (notify != FALSE) {
|
|
Packit |
8fb625 |
GtkTreePath *path;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
/* Tell the world */
|
|
Packit |
8fb625 |
path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->store), &iter);
|
|
Packit |
8fb625 |
gtk_tree_model_row_changed (GTK_TREE_MODEL (priv->store), path, &iter);
|
|
Packit |
8fb625 |
gtk_tree_path_free (path);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
adapter_added (GDBusObjectManager *manager,
|
|
Packit |
8fb625 |
Adapter1 *adapter,
|
|
Packit |
8fb625 |
BluetoothClient *client)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
GtkTreeIter iter;
|
|
Packit |
8fb625 |
const gchar *address, *name;
|
|
Packit |
8fb625 |
gboolean discovering, discoverable, powered;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_signal_connect (G_OBJECT (adapter), "notify",
|
|
Packit |
8fb625 |
G_CALLBACK (adapter_notify_cb), client);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
address = adapter1_get_address (adapter);
|
|
Packit |
8fb625 |
name = adapter1_get_name (adapter);
|
|
Packit |
8fb625 |
discovering = adapter1_get_discovering (adapter);
|
|
Packit |
8fb625 |
powered = adapter1_get_powered (adapter);
|
|
Packit |
8fb625 |
discoverable = adapter1_get_discoverable (adapter);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_store_insert_with_values(priv->store, &iter, NULL, -1,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PROXY, adapter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_ADDRESS, address,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_NAME, name,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_DISCOVERING, discovering,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_DISCOVERABLE, discoverable,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_POWERED, powered,
|
|
Packit |
8fb625 |
-1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (!priv->default_adapter) {
|
|
Packit |
8fb625 |
default_adapter_changed (manager,
|
|
Packit |
8fb625 |
g_dbus_object_get_object_path (g_dbus_interface_get_object (G_DBUS_INTERFACE (adapter))),
|
|
Packit |
8fb625 |
client);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
adapter_removed (GDBusObjectManager *manager,
|
|
Packit |
8fb625 |
const char *path,
|
|
Packit |
8fb625 |
BluetoothClient *client)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
GtkTreeIter iter, childiter;
|
|
Packit |
8fb625 |
gboolean was_default;
|
|
Packit |
8fb625 |
gboolean have_child;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (get_iter_from_path (priv->store, &iter, path) == FALSE)
|
|
Packit |
8fb625 |
return;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_DEFAULT, &was_default, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (!was_default)
|
|
Packit |
8fb625 |
return;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
/* Ensure that all devices are removed. This can happen if bluetoothd
|
|
Packit |
8fb625 |
* crashes as the "object-removed" signal is emitted in an undefined
|
|
Packit |
8fb625 |
* order. */
|
|
Packit |
8fb625 |
have_child = gtk_tree_model_iter_children (GTK_TREE_MODEL (priv->store), &childiter, &iter);
|
|
Packit |
8fb625 |
while (have_child) {
|
|
Packit |
8fb625 |
GDBusProxy *object;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &childiter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PROXY, &object, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_signal_emit (G_OBJECT (client), signals[DEVICE_REMOVED], 0, g_dbus_proxy_get_object_path (object));
|
|
Packit |
8fb625 |
g_object_unref (object);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
have_child = gtk_tree_store_remove (priv->store, &childiter);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_clear_pointer (&priv->default_adapter, gtk_tree_row_reference_free);
|
|
Packit |
8fb625 |
gtk_tree_store_remove (priv->store, &iter);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL(priv->store),
|
|
Packit |
8fb625 |
&iter)) {
|
|
Packit |
8fb625 |
GDBusProxy *adapter;
|
|
Packit |
8fb625 |
const char *adapter_path;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PROXY, &adapter, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
adapter_path = g_dbus_proxy_get_object_path (adapter);
|
|
Packit |
8fb625 |
default_adapter_changed (manager, adapter_path, client);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_object_unref(adapter);
|
|
Packit |
8fb625 |
} else {
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter");
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter-powered");
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter-discoverable");
|
|
Packit |
8fb625 |
g_object_notify (G_OBJECT (client), "default-adapter-discovering");
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static GType
|
|
Packit |
8fb625 |
object_manager_get_proxy_type_func (GDBusObjectManagerClient *manager,
|
|
Packit |
8fb625 |
const gchar *object_path,
|
|
Packit |
8fb625 |
const gchar *interface_name,
|
|
Packit |
8fb625 |
gpointer user_data)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
if (interface_name == NULL)
|
|
Packit |
8fb625 |
return G_TYPE_DBUS_OBJECT_PROXY;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (g_str_equal (interface_name, BLUEZ_DEVICE_INTERFACE))
|
|
Packit |
8fb625 |
return TYPE_DEVICE1_PROXY;
|
|
Packit |
8fb625 |
if (g_str_equal (interface_name, BLUEZ_ADAPTER_INTERFACE))
|
|
Packit |
8fb625 |
return TYPE_ADAPTER1_PROXY;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return G_TYPE_DBUS_PROXY;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
interface_added (GDBusObjectManager *manager,
|
|
Packit |
8fb625 |
GDBusObject *object,
|
|
Packit |
8fb625 |
GDBusInterface *interface,
|
|
Packit |
8fb625 |
gpointer user_data)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClient *client = user_data;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (IS_ADAPTER1 (interface)) {
|
|
Packit |
8fb625 |
adapter_added (manager,
|
|
Packit |
8fb625 |
ADAPTER1 (interface),
|
|
Packit |
8fb625 |
client);
|
|
Packit |
8fb625 |
} else if (IS_DEVICE1 (interface)) {
|
|
Packit |
8fb625 |
device_added (manager,
|
|
Packit |
8fb625 |
DEVICE1 (interface),
|
|
Packit |
8fb625 |
client);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
interface_removed (GDBusObjectManager *manager,
|
|
Packit |
8fb625 |
GDBusObject *object,
|
|
Packit |
8fb625 |
GDBusInterface *interface,
|
|
Packit |
8fb625 |
gpointer user_data)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClient *client = user_data;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (IS_ADAPTER1 (interface)) {
|
|
Packit |
8fb625 |
adapter_removed (manager,
|
|
Packit |
8fb625 |
g_dbus_object_get_object_path (object),
|
|
Packit |
8fb625 |
client);
|
|
Packit |
8fb625 |
} else if (IS_DEVICE1 (interface)) {
|
|
Packit |
8fb625 |
device_removed (g_dbus_object_get_object_path (object),
|
|
Packit |
8fb625 |
client);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
object_added (GDBusObjectManager *manager,
|
|
Packit |
8fb625 |
GDBusObject *object,
|
|
Packit |
8fb625 |
BluetoothClient *client)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
GList *interfaces, *l;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
interfaces = g_dbus_object_get_interfaces (object);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
for (l = interfaces; l != NULL; l = l->next)
|
|
Packit |
8fb625 |
interface_added (manager, object, G_DBUS_INTERFACE (l->data), client);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_list_free_full (interfaces, g_object_unref);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
object_removed (GDBusObjectManager *manager,
|
|
Packit |
8fb625 |
GDBusObject *object,
|
|
Packit |
8fb625 |
BluetoothClient *client)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
GList *interfaces, *l;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
interfaces = g_dbus_object_get_interfaces (object);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
for (l = interfaces; l != NULL; l = l->next)
|
|
Packit |
8fb625 |
interface_removed (manager, object, G_DBUS_INTERFACE (l->data), client);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_list_free_full (interfaces, g_object_unref);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
object_manager_new_callback(GObject *source_object,
|
|
Packit |
8fb625 |
GAsyncResult *res,
|
|
Packit |
8fb625 |
void *user_data)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClient *client;
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv;
|
|
Packit |
8fb625 |
GDBusObjectManager *manager;
|
|
Packit |
8fb625 |
GList *object_list, *l;
|
|
Packit |
8fb625 |
GError *error = NULL;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
manager = g_dbus_object_manager_client_new_for_bus_finish (res, &error);
|
|
Packit |
8fb625 |
if (!manager) {
|
|
Packit |
8fb625 |
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
Packit |
8fb625 |
g_warning ("Could not create bluez object manager: %s", error->message);
|
|
Packit |
8fb625 |
g_error_free (error);
|
|
Packit |
8fb625 |
return;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
client = BLUETOOTH_CLIENT (user_data);
|
|
Packit |
8fb625 |
priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
priv->manager = manager;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_signal_connect (G_OBJECT (priv->manager), "interface-added", (GCallback) interface_added, client);
|
|
Packit |
8fb625 |
g_signal_connect (G_OBJECT (priv->manager), "interface-removed", (GCallback) interface_removed, client);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_signal_connect (G_OBJECT (priv->manager), "object-added", (GCallback) object_added, client);
|
|
Packit |
8fb625 |
g_signal_connect (G_OBJECT (priv->manager), "object-removed", (GCallback) object_removed, client);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
object_list = g_dbus_object_manager_get_objects (priv->manager);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
/* We need to add the adapters first, otherwise the devices will
|
|
Packit |
8fb625 |
* be dropped to the floor, as they wouldn't have a parent in
|
|
Packit |
8fb625 |
* the treestore */
|
|
Packit |
8fb625 |
for (l = object_list; l != NULL; l = l->next) {
|
|
Packit |
8fb625 |
GDBusObject *object = l->data;
|
|
Packit |
8fb625 |
GDBusInterface *iface;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
iface = g_dbus_object_get_interface (object, BLUEZ_ADAPTER_INTERFACE);
|
|
Packit |
8fb625 |
if (!iface)
|
|
Packit |
8fb625 |
continue;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
adapter_added (priv->manager,
|
|
Packit |
8fb625 |
ADAPTER1 (iface),
|
|
Packit |
8fb625 |
client);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
for (l = object_list; l != NULL; l = l->next) {
|
|
Packit |
8fb625 |
GDBusObject *object = l->data;
|
|
Packit |
8fb625 |
GDBusInterface *iface;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
iface = g_dbus_object_get_interface (object, BLUEZ_DEVICE_INTERFACE);
|
|
Packit |
8fb625 |
if (!iface)
|
|
Packit |
8fb625 |
continue;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
device_added (priv->manager,
|
|
Packit |
8fb625 |
DEVICE1 (iface),
|
|
Packit |
8fb625 |
client);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
g_list_free_full (object_list, g_object_unref);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void bluetooth_client_init(BluetoothClient *client)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
priv->cancellable = g_cancellable_new ();
|
|
Packit |
8fb625 |
priv->store = gtk_tree_store_new(_BLUETOOTH_NUM_COLUMNS,
|
|
Packit |
8fb625 |
G_TYPE_OBJECT, /* BLUETOOTH_COLUMN_PROXY */
|
|
Packit |
8fb625 |
G_TYPE_OBJECT, /* BLUETOOTH_COLUMN_PROPERTIES */
|
|
Packit |
8fb625 |
G_TYPE_STRING, /* BLUETOOTH_COLUMN_ADDRESS */
|
|
Packit |
8fb625 |
G_TYPE_STRING, /* BLUETOOTH_COLUMN_ALIAS */
|
|
Packit |
8fb625 |
G_TYPE_STRING, /* BLUETOOTH_COLUMN_NAME */
|
|
Packit |
8fb625 |
G_TYPE_UINT, /* BLUETOOTH_COLUMN_TYPE */
|
|
Packit |
8fb625 |
G_TYPE_STRING, /* BLUETOOTH_COLUMN_ICON */
|
|
Packit |
8fb625 |
G_TYPE_BOOLEAN, /* BLUETOOTH_COLUMN_DEFAULT */
|
|
Packit |
8fb625 |
G_TYPE_BOOLEAN, /* BLUETOOTH_COLUMN_PAIRED */
|
|
Packit |
8fb625 |
G_TYPE_BOOLEAN, /* BLUETOOTH_COLUMN_TRUSTED */
|
|
Packit |
8fb625 |
G_TYPE_BOOLEAN, /* BLUETOOTH_COLUMN_CONNECTED */
|
|
Packit |
8fb625 |
G_TYPE_BOOLEAN, /* BLUETOOTH_COLUMN_DISCOVERABLE */
|
|
Packit |
8fb625 |
G_TYPE_BOOLEAN, /* BLUETOOTH_COLUMN_DISCOVERING */
|
|
Packit |
8fb625 |
G_TYPE_INT, /* BLUETOOTH_COLUMN_LEGACYPAIRING */
|
|
Packit |
8fb625 |
G_TYPE_BOOLEAN, /* BLUETOOTH_COLUMN_POWERED */
|
|
Packit |
8fb625 |
G_TYPE_HASH_TABLE, /* BLUETOOTH_COLUMN_SERVICES */
|
|
Packit |
8fb625 |
G_TYPE_STRV); /* BLUETOOTH_COLUMN_UUIDS */
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_dbus_object_manager_client_new_for_bus (G_BUS_TYPE_SYSTEM,
|
|
Packit |
8fb625 |
G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START,
|
|
Packit |
8fb625 |
BLUEZ_SERVICE,
|
|
Packit |
8fb625 |
BLUEZ_MANAGER_PATH,
|
|
Packit |
8fb625 |
object_manager_get_proxy_type_func,
|
|
Packit |
8fb625 |
NULL, NULL,
|
|
Packit |
8fb625 |
priv->cancellable,
|
|
Packit |
8fb625 |
object_manager_new_callback, client);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
GDBusProxy *
|
|
Packit |
8fb625 |
_bluetooth_client_get_default_adapter(BluetoothClient *client)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
GtkTreePath *path;
|
|
Packit |
8fb625 |
GtkTreeIter iter;
|
|
Packit |
8fb625 |
GDBusProxy *adapter;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), NULL);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (priv->default_adapter == NULL)
|
|
Packit |
8fb625 |
return NULL;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
path = gtk_tree_row_reference_get_path (priv->default_adapter);
|
|
Packit |
8fb625 |
gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->store), &iter, path);
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PROXY, &adapter, -1);
|
|
Packit |
8fb625 |
gtk_tree_path_free (path);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return adapter;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static const char*
|
|
Packit |
8fb625 |
_bluetooth_client_get_default_adapter_path (BluetoothClient *self)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
GDBusProxy *adapter = _bluetooth_client_get_default_adapter (self);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (adapter != NULL) {
|
|
Packit |
8fb625 |
const char *ret = g_dbus_proxy_get_object_path (adapter);
|
|
Packit |
8fb625 |
g_object_unref (adapter);
|
|
Packit |
8fb625 |
return ret;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
return NULL;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static gboolean
|
|
Packit |
8fb625 |
_bluetooth_client_get_default_adapter_powered (BluetoothClient *self)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE (self);
|
|
Packit |
8fb625 |
GtkTreePath *path;
|
|
Packit |
8fb625 |
GtkTreeIter iter;
|
|
Packit |
8fb625 |
gboolean ret;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (priv->default_adapter == NULL)
|
|
Packit |
8fb625 |
return FALSE;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
path = gtk_tree_row_reference_get_path (priv->default_adapter);
|
|
Packit |
8fb625 |
gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->store), &iter, path);
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter, BLUETOOTH_COLUMN_POWERED, &ret, -1);
|
|
Packit |
8fb625 |
gtk_tree_path_free (path);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return ret;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static char *
|
|
Packit |
8fb625 |
_bluetooth_client_get_default_adapter_name (BluetoothClient *self)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE (self);
|
|
Packit |
8fb625 |
GtkTreePath *path;
|
|
Packit |
8fb625 |
GtkTreeIter iter;
|
|
Packit |
8fb625 |
char *ret;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (priv->default_adapter == NULL)
|
|
Packit |
8fb625 |
return NULL;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
path = gtk_tree_row_reference_get_path (priv->default_adapter);
|
|
Packit |
8fb625 |
gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->store), &iter, path);
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter, BLUETOOTH_COLUMN_NAME, &ret, -1);
|
|
Packit |
8fb625 |
gtk_tree_path_free (path);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return ret;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
/**
|
|
Packit |
8fb625 |
* _bluetooth_client_set_discoverable:
|
|
Packit |
8fb625 |
* @client: a #BluetoothClient object
|
|
Packit |
8fb625 |
* @discoverable: whether the device should be discoverable
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* Sets the default adapter's discoverable status.
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* Return value: Whether setting the state on the default adapter was successful.
|
|
Packit |
8fb625 |
**/
|
|
Packit |
8fb625 |
static gboolean
|
|
Packit |
8fb625 |
_bluetooth_client_set_discoverable (BluetoothClient *client,
|
|
Packit |
8fb625 |
gboolean discoverable)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE (client);
|
|
Packit |
8fb625 |
GtkTreePath *path;
|
|
Packit |
8fb625 |
GObject *adapter;
|
|
Packit |
8fb625 |
GtkTreeIter iter;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), FALSE);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (priv->default_adapter == NULL)
|
|
Packit |
8fb625 |
return FALSE;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
path = gtk_tree_row_reference_get_path (priv->default_adapter);
|
|
Packit |
8fb625 |
gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->store), &iter, path);
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PROXY, &adapter, -1);
|
|
Packit |
8fb625 |
gtk_tree_path_free (path);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (adapter == NULL)
|
|
Packit |
8fb625 |
return FALSE;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (discoverable) {
|
|
Packit |
8fb625 |
g_object_set (adapter,
|
|
Packit |
8fb625 |
"discoverable", discoverable,
|
|
Packit |
8fb625 |
"discoverable-timeout", 0,
|
|
Packit |
8fb625 |
NULL);
|
|
Packit |
8fb625 |
} else {
|
|
Packit |
8fb625 |
/* Work-around race in bluetoothd which would reset the discoverable
|
|
Packit |
8fb625 |
* flag if a timeout change was requested before discoverable finished
|
|
Packit |
8fb625 |
* being set to off:
|
|
Packit |
8fb625 |
* https://bugzilla.redhat.com/show_bug.cgi?id=1602985 */
|
|
Packit |
8fb625 |
g_object_set (adapter,
|
|
Packit |
8fb625 |
"discoverable", FALSE,
|
|
Packit |
8fb625 |
NULL);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
g_object_unref (adapter);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return TRUE;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
_bluetooth_client_set_default_adapter_discovering (BluetoothClient *client,
|
|
Packit |
8fb625 |
gboolean discovering,
|
|
Packit |
8fb625 |
gboolean discoverable)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE (client);
|
|
Packit |
8fb625 |
GDBusProxy *adapter;
|
|
Packit |
8fb625 |
GVariantBuilder builder;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
adapter = _bluetooth_client_get_default_adapter (client);
|
|
Packit |
8fb625 |
if (adapter == NULL)
|
|
Packit |
8fb625 |
return;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
|
|
Packit |
8fb625 |
g_variant_builder_add (&builder, "{sv}",
|
|
Packit |
8fb625 |
"Discoverable", g_variant_new_boolean (discoverable));
|
|
Packit |
8fb625 |
if (!adapter1_call_set_discovery_filter_sync (ADAPTER1 (adapter),
|
|
Packit |
8fb625 |
g_variant_builder_end (&builder), NULL, NULL)) {
|
|
Packit |
8fb625 |
/* BlueZ too old? */
|
|
Packit |
8fb625 |
_bluetooth_client_set_discoverable (client, discoverable);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
priv->discovery_started = discovering;
|
|
Packit |
8fb625 |
if (discovering)
|
|
Packit |
8fb625 |
adapter1_call_start_discovery_sync (ADAPTER1 (adapter), NULL, NULL);
|
|
Packit |
8fb625 |
else
|
|
Packit |
8fb625 |
adapter1_call_stop_discovery_sync (ADAPTER1 (adapter), NULL, NULL);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_object_unref(adapter);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static gboolean
|
|
Packit |
8fb625 |
_bluetooth_client_get_default_adapter_discovering (BluetoothClient *self)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE (self);
|
|
Packit |
8fb625 |
GtkTreePath *path;
|
|
Packit |
8fb625 |
GtkTreeIter iter;
|
|
Packit |
8fb625 |
gboolean ret;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (priv->default_adapter == NULL)
|
|
Packit |
8fb625 |
return FALSE;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
path = gtk_tree_row_reference_get_path (priv->default_adapter);
|
|
Packit |
8fb625 |
gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->store), &iter, path);
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter, BLUETOOTH_COLUMN_DISCOVERING, &ret, -1);
|
|
Packit |
8fb625 |
gtk_tree_path_free (path);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return ret;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
bluetooth_client_get_property (GObject *object,
|
|
Packit |
8fb625 |
guint property_id,
|
|
Packit |
8fb625 |
GValue *value,
|
|
Packit |
8fb625 |
GParamSpec *pspec)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClient *self = BLUETOOTH_CLIENT (object);
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE (self);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
switch (property_id) {
|
|
Packit |
8fb625 |
case PROP_DEFAULT_ADAPTER:
|
|
Packit |
8fb625 |
g_value_set_string (value, _bluetooth_client_get_default_adapter_path (self));
|
|
Packit |
8fb625 |
break;
|
|
Packit |
8fb625 |
case PROP_DEFAULT_ADAPTER_POWERED:
|
|
Packit |
8fb625 |
g_value_set_boolean (value, _bluetooth_client_get_default_adapter_powered (self));
|
|
Packit |
8fb625 |
break;
|
|
Packit |
8fb625 |
case PROP_DEFAULT_ADAPTER_NAME:
|
|
Packit |
8fb625 |
g_value_take_string (value, _bluetooth_client_get_default_adapter_name (self));
|
|
Packit |
8fb625 |
break;
|
|
Packit |
8fb625 |
case PROP_DEFAULT_ADAPTER_DISCOVERABLE:
|
|
Packit |
8fb625 |
g_value_set_boolean (value, priv->disco_during_disco);
|
|
Packit |
8fb625 |
break;
|
|
Packit |
8fb625 |
case PROP_DEFAULT_ADAPTER_DISCOVERING:
|
|
Packit |
8fb625 |
g_value_set_boolean (value, _bluetooth_client_get_default_adapter_discovering (self));
|
|
Packit |
8fb625 |
break;
|
|
Packit |
8fb625 |
default:
|
|
Packit |
8fb625 |
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
|
Packit |
8fb625 |
break;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
bluetooth_client_set_property (GObject *object,
|
|
Packit |
8fb625 |
guint property_id,
|
|
Packit |
8fb625 |
const GValue *value,
|
|
Packit |
8fb625 |
GParamSpec *pspec)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClient *self = BLUETOOTH_CLIENT (object);
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE (self);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
switch (property_id) {
|
|
Packit |
8fb625 |
case PROP_DEFAULT_ADAPTER_DISCOVERABLE:
|
|
Packit |
8fb625 |
priv->disco_during_disco = g_value_get_boolean (value);
|
|
Packit |
8fb625 |
_bluetooth_client_set_default_adapter_discovering (self, priv->discovery_started, priv->disco_during_disco);
|
|
Packit |
8fb625 |
break;
|
|
Packit |
8fb625 |
case PROP_DEFAULT_ADAPTER_DISCOVERING:
|
|
Packit |
8fb625 |
_bluetooth_client_set_default_adapter_discovering (self, g_value_get_boolean (value), priv->disco_during_disco);
|
|
Packit |
8fb625 |
break;
|
|
Packit |
8fb625 |
default:
|
|
Packit |
8fb625 |
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
|
Packit |
8fb625 |
break;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void bluetooth_client_finalize(GObject *object)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClient *client = BLUETOOTH_CLIENT (object);
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE (client);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (priv->cancellable != NULL) {
|
|
Packit |
8fb625 |
g_cancellable_cancel (priv->cancellable);
|
|
Packit |
8fb625 |
g_clear_object (&priv->cancellable);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
g_clear_object (&priv->manager);
|
|
Packit |
8fb625 |
g_object_unref (priv->store);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_clear_pointer (&priv->default_adapter, gtk_tree_row_reference_free);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
G_OBJECT_CLASS(bluetooth_client_parent_class)->finalize (object);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void bluetooth_client_class_init(BluetoothClientClass *klass)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
object_class->finalize = bluetooth_client_finalize;
|
|
Packit |
8fb625 |
object_class->get_property = bluetooth_client_get_property;
|
|
Packit |
8fb625 |
object_class->set_property = bluetooth_client_set_property;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
/**
|
|
Packit |
8fb625 |
* BluetoothClient::device-removed:
|
|
Packit |
8fb625 |
* @client: a #BluetoothClient object which received the signal
|
|
Packit |
8fb625 |
* @device: the D-Bus object path for the now-removed device
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* The #BluetoothClient::device-removed signal is launched when a
|
|
Packit |
8fb625 |
* device gets removed from the model.
|
|
Packit |
8fb625 |
**/
|
|
Packit |
8fb625 |
signals[DEVICE_REMOVED] =
|
|
Packit |
8fb625 |
g_signal_new ("device-removed",
|
|
Packit |
8fb625 |
G_TYPE_FROM_CLASS (klass),
|
|
Packit |
8fb625 |
G_SIGNAL_RUN_LAST,
|
|
Packit |
8fb625 |
0,
|
|
Packit |
8fb625 |
NULL, NULL,
|
|
Packit |
8fb625 |
g_cclosure_marshal_VOID__STRING,
|
|
Packit |
8fb625 |
G_TYPE_NONE, 1, G_TYPE_STRING);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
/**
|
|
Packit |
8fb625 |
* BluetoothClient:default-adapter:
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* The D-Bus path of the default Bluetooth adapter or %NULL.
|
|
Packit |
8fb625 |
*/
|
|
Packit |
8fb625 |
g_object_class_install_property (object_class, PROP_DEFAULT_ADAPTER,
|
|
Packit |
8fb625 |
g_param_spec_string ("default-adapter", NULL,
|
|
Packit |
8fb625 |
"The D-Bus path of the default adapter",
|
|
Packit |
8fb625 |
NULL, G_PARAM_READABLE));
|
|
Packit |
8fb625 |
/**
|
|
Packit |
8fb625 |
* BluetoothClient:default-adapter-powered:
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* %TRUE if the default Bluetooth adapter is powered.
|
|
Packit |
8fb625 |
*/
|
|
Packit |
8fb625 |
g_object_class_install_property (object_class, PROP_DEFAULT_ADAPTER_POWERED,
|
|
Packit |
8fb625 |
g_param_spec_boolean ("default-adapter-powered", NULL,
|
|
Packit |
8fb625 |
"Whether the default adapter is powered",
|
|
Packit |
8fb625 |
FALSE, G_PARAM_READABLE));
|
|
Packit |
8fb625 |
/**
|
|
Packit |
8fb625 |
* BluetoothClient:default-adapter-discoverable:
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* %TRUE if the default Bluetooth adapter is discoverable during discovery.
|
|
Packit |
8fb625 |
*/
|
|
Packit |
8fb625 |
g_object_class_install_property (object_class, PROP_DEFAULT_ADAPTER_DISCOVERABLE,
|
|
Packit |
8fb625 |
g_param_spec_boolean ("default-adapter-discoverable", NULL,
|
|
Packit |
8fb625 |
"Whether the default adapter is visible by other devices during discovery",
|
|
Packit |
8fb625 |
FALSE, G_PARAM_READWRITE));
|
|
Packit |
8fb625 |
/**
|
|
Packit |
8fb625 |
* BluetoothClient:default-adapter-name:
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* The name of the default Bluetooth adapter or %NULL.
|
|
Packit |
8fb625 |
*/
|
|
Packit |
8fb625 |
g_object_class_install_property (object_class, PROP_DEFAULT_ADAPTER_NAME,
|
|
Packit |
8fb625 |
g_param_spec_string ("default-adapter-name", NULL,
|
|
Packit |
8fb625 |
"The human readable name of the default adapter",
|
|
Packit |
8fb625 |
NULL, G_PARAM_READABLE));
|
|
Packit |
8fb625 |
/**
|
|
Packit |
8fb625 |
* BluetoothClient:default-adapter-discovering:
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* %TRUE if the default Bluetooth adapter is discovering.
|
|
Packit |
8fb625 |
*/
|
|
Packit |
8fb625 |
g_object_class_install_property (object_class, PROP_DEFAULT_ADAPTER_DISCOVERING,
|
|
Packit |
8fb625 |
g_param_spec_boolean ("default-adapter-discovering", NULL,
|
|
Packit |
8fb625 |
"Whether the default adapter is searching for devices",
|
|
Packit |
8fb625 |
FALSE, G_PARAM_READWRITE));
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
/**
|
|
Packit |
8fb625 |
* bluetooth_client_new:
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* Returns a reference to the #BluetoothClient singleton. Use g_object_unref() when done with the object.
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* Return value: (transfer full): a #BluetoothClient object.
|
|
Packit |
8fb625 |
**/
|
|
Packit |
8fb625 |
BluetoothClient *bluetooth_client_new(void)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
static BluetoothClient *bluetooth_client = NULL;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (bluetooth_client != NULL)
|
|
Packit |
8fb625 |
return g_object_ref(bluetooth_client);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
bluetooth_client = BLUETOOTH_CLIENT (g_object_new (BLUETOOTH_TYPE_CLIENT, NULL));
|
|
Packit |
8fb625 |
g_object_add_weak_pointer (G_OBJECT (bluetooth_client),
|
|
Packit |
8fb625 |
(gpointer) &bluetooth_client);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return bluetooth_client;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
/**
|
|
Packit |
8fb625 |
* bluetooth_client_get_model:
|
|
Packit |
8fb625 |
* @client: a #BluetoothClient object
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* Returns an unfiltered #GtkTreeModel representing the adapter and devices available on the system.
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* Return value: (transfer full): a #GtkTreeModel object.
|
|
Packit |
8fb625 |
**/
|
|
Packit |
8fb625 |
GtkTreeModel *bluetooth_client_get_model (BluetoothClient *client)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv;
|
|
Packit |
8fb625 |
GtkTreeModel *model;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), NULL);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
model = GTK_TREE_MODEL (g_object_ref(priv->store));
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return model;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
/**
|
|
Packit |
8fb625 |
* bluetooth_client_get_filter_model:
|
|
Packit |
8fb625 |
* @client: a #BluetoothClient object
|
|
Packit |
8fb625 |
* @func: a #GtkTreeModelFilterVisibleFunc
|
|
Packit |
8fb625 |
* @data: user data to pass to gtk_tree_model_filter_set_visible_func()
|
|
Packit |
8fb625 |
* @destroy: a destroy function for gtk_tree_model_filter_set_visible_func()
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* Returns a #GtkTreeModelFilter of devices filtered using the @func, @data and @destroy arguments to pass to gtk_tree_model_filter_set_visible_func().
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* Return value: (transfer full): a #GtkTreeModel object.
|
|
Packit |
8fb625 |
**/
|
|
Packit |
8fb625 |
GtkTreeModel *bluetooth_client_get_filter_model (BluetoothClient *client,
|
|
Packit |
8fb625 |
GtkTreeModelFilterVisibleFunc func,
|
|
Packit |
8fb625 |
gpointer data, GDestroyNotify destroy)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv;
|
|
Packit |
8fb625 |
GtkTreeModel *model;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), NULL);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
model = gtk_tree_model_filter_new(GTK_TREE_MODEL(priv->store), NULL);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(model),
|
|
Packit |
8fb625 |
func, data, destroy);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return model;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static gboolean adapter_filter(GtkTreeModel *model,
|
|
Packit |
8fb625 |
GtkTreeIter *iter, gpointer user_data)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
GDBusProxy *proxy;
|
|
Packit |
8fb625 |
gboolean active;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get(model, iter, BLUETOOTH_COLUMN_PROXY, &proxy, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (proxy == NULL)
|
|
Packit |
8fb625 |
return FALSE;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
active = g_str_equal(BLUEZ_ADAPTER_INTERFACE,
|
|
Packit |
8fb625 |
g_dbus_proxy_get_interface_name(proxy));
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_object_unref(proxy);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return active;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
/**
|
|
Packit |
8fb625 |
* bluetooth_client_get_adapter_model:
|
|
Packit |
8fb625 |
* @client: a #BluetoothClient object
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* Returns a #GtkTreeModelFilter with only adapters present.
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* Return value: (transfer full): a #GtkTreeModel object.
|
|
Packit |
8fb625 |
**/
|
|
Packit |
8fb625 |
GtkTreeModel *bluetooth_client_get_adapter_model (BluetoothClient *client)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
return bluetooth_client_get_filter_model (client, adapter_filter,
|
|
Packit |
8fb625 |
NULL, NULL);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
/**
|
|
Packit |
8fb625 |
* bluetooth_client_get_device_model:
|
|
Packit |
8fb625 |
* @client: a #BluetoothClient object
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* Returns a #GtkTreeModelFilter with only devices belonging to the default adapter listed.
|
|
Packit |
8fb625 |
* Note that the model will follow a specific adapter, and will not follow the default adapter.
|
|
Packit |
8fb625 |
* Also note that due to the way #GtkTreeModelFilter works, you will probably want to
|
|
Packit |
8fb625 |
* monitor signals on the "child-model" #GtkTreeModel to monitor for changes.
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* Return value: (transfer full): a #GtkTreeModel object.
|
|
Packit |
8fb625 |
**/
|
|
Packit |
8fb625 |
GtkTreeModel *bluetooth_client_get_device_model (BluetoothClient *client)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv;
|
|
Packit |
8fb625 |
GtkTreeModel *model;
|
|
Packit |
8fb625 |
GtkTreePath *path;
|
|
Packit |
8fb625 |
GtkTreeIter iter;
|
|
Packit |
8fb625 |
gboolean cont, found = FALSE;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), NULL);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
cont = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(priv->store), &iter);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
while (cont == TRUE) {
|
|
Packit |
8fb625 |
gboolean is_default;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_DEFAULT, &is_default, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (is_default == TRUE) {
|
|
Packit |
8fb625 |
found = TRUE;
|
|
Packit |
8fb625 |
break;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
cont = gtk_tree_model_iter_next (GTK_TREE_MODEL(priv->store), &iter);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (found == TRUE) {
|
|
Packit |
8fb625 |
path = gtk_tree_model_get_path (GTK_TREE_MODEL(priv->store), &iter);
|
|
Packit |
8fb625 |
model = gtk_tree_model_filter_new (GTK_TREE_MODEL(priv->store), path);
|
|
Packit |
8fb625 |
gtk_tree_path_free (path);
|
|
Packit |
8fb625 |
} else
|
|
Packit |
8fb625 |
model = NULL;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return model;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
typedef struct {
|
|
Packit |
8fb625 |
BluetoothClientSetupFunc func;
|
|
Packit |
8fb625 |
BluetoothClient *client;
|
|
Packit |
8fb625 |
} CreateDeviceData;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
device_pair_callback (GDBusProxy *proxy,
|
|
Packit |
8fb625 |
GAsyncResult *res,
|
|
Packit |
8fb625 |
GSimpleAsyncResult *simple)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
GError *error = NULL;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (device1_call_pair_finish (DEVICE1(proxy), res, &error) == FALSE) {
|
|
Packit |
8fb625 |
g_debug ("Pair() failed for %s: %s",
|
|
Packit |
8fb625 |
g_dbus_proxy_get_object_path (proxy),
|
|
Packit |
8fb625 |
error->message);
|
|
Packit |
8fb625 |
g_simple_async_result_take_error (simple, error);
|
|
Packit |
8fb625 |
} else {
|
|
Packit |
8fb625 |
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_simple_async_result_complete_in_idle (simple);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_object_unref (simple);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gboolean
|
|
Packit |
8fb625 |
bluetooth_client_setup_device_finish (BluetoothClient *client,
|
|
Packit |
8fb625 |
GAsyncResult *res,
|
|
Packit |
8fb625 |
char **path,
|
|
Packit |
8fb625 |
GError **error)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
GSimpleAsyncResult *simple;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
simple = (GSimpleAsyncResult *) res;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == bluetooth_client_setup_device);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (path != NULL)
|
|
Packit |
8fb625 |
*path = g_object_get_data (G_OBJECT (res), "device-object-path");
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (g_simple_async_result_get_op_res_gboolean (simple))
|
|
Packit |
8fb625 |
return TRUE;
|
|
Packit |
8fb625 |
g_simple_async_result_propagate_error (simple, error);
|
|
Packit |
8fb625 |
return FALSE;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
void
|
|
Packit |
8fb625 |
bluetooth_client_setup_device (BluetoothClient *client,
|
|
Packit |
8fb625 |
const char *path,
|
|
Packit |
8fb625 |
gboolean pair,
|
|
Packit |
8fb625 |
GCancellable *cancellable,
|
|
Packit |
8fb625 |
GAsyncReadyCallback callback,
|
|
Packit |
8fb625 |
gpointer user_data)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
GSimpleAsyncResult *simple;
|
|
Packit |
8fb625 |
GDBusProxy *device;
|
|
Packit |
8fb625 |
GtkTreeIter iter, adapter_iter;
|
|
Packit |
8fb625 |
gboolean paired;
|
|
Packit |
8fb625 |
GError *err = NULL;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_return_if_fail (BLUETOOTH_IS_CLIENT (client));
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
simple = g_simple_async_result_new (G_OBJECT (client),
|
|
Packit |
8fb625 |
callback,
|
|
Packit |
8fb625 |
user_data,
|
|
Packit |
8fb625 |
bluetooth_client_setup_device);
|
|
Packit |
8fb625 |
g_simple_async_result_set_check_cancellable (simple, cancellable);
|
|
Packit |
8fb625 |
g_object_set_data (G_OBJECT (simple), "device-object-path", g_strdup (path));
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (get_iter_from_path (priv->store, &iter, path) == FALSE) {
|
|
Packit |
8fb625 |
g_simple_async_result_set_error (simple, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
|
|
Packit |
8fb625 |
"Device with object path %s does not exist",
|
|
Packit |
8fb625 |
path);
|
|
Packit |
8fb625 |
g_simple_async_result_complete_in_idle (simple);
|
|
Packit |
8fb625 |
g_object_unref (simple);
|
|
Packit |
8fb625 |
return;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PROXY, &device,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PAIRED, &paired, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (paired != FALSE &&
|
|
Packit |
8fb625 |
gtk_tree_model_iter_parent (GTK_TREE_MODEL(priv->store), &adapter_iter, &iter)) {
|
|
Packit |
8fb625 |
GDBusProxy *adapter;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &adapter_iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PROXY, &adapter,
|
|
Packit |
8fb625 |
-1);
|
|
Packit |
8fb625 |
adapter1_call_remove_device_sync (ADAPTER1 (adapter),
|
|
Packit |
8fb625 |
path,
|
|
Packit |
8fb625 |
NULL, &err;;
|
|
Packit |
8fb625 |
if (err != NULL) {
|
|
Packit |
8fb625 |
g_warning ("Failed to remove device: %s", err->message);
|
|
Packit |
8fb625 |
g_error_free (err);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
g_object_unref (adapter);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (pair == TRUE) {
|
|
Packit |
8fb625 |
device1_call_pair (DEVICE1(device),
|
|
Packit |
8fb625 |
cancellable,
|
|
Packit |
8fb625 |
(GAsyncReadyCallback) device_pair_callback,
|
|
Packit |
8fb625 |
simple);
|
|
Packit |
8fb625 |
} else {
|
|
Packit |
8fb625 |
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
|
|
Packit |
8fb625 |
g_simple_async_result_complete_in_idle (simple);
|
|
Packit |
8fb625 |
g_object_unref (simple);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_object_unref (device);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gboolean
|
|
Packit |
8fb625 |
bluetooth_client_set_trusted (BluetoothClient *client,
|
|
Packit |
8fb625 |
const char *device_path,
|
|
Packit |
8fb625 |
gboolean trusted)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
GObject *device;
|
|
Packit |
8fb625 |
GtkTreeIter iter;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), FALSE);
|
|
Packit |
8fb625 |
g_return_val_if_fail (device != NULL, FALSE);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (get_iter_from_path (priv->store, &iter, device_path) == FALSE) {
|
|
Packit |
8fb625 |
g_debug ("Couldn't find device '%s' in tree to mark it as trusted", device_path);
|
|
Packit |
8fb625 |
return FALSE;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PROXY, &device, -1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (device == NULL)
|
|
Packit |
8fb625 |
return FALSE;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_object_set (device, "trusted", trusted, NULL);
|
|
Packit |
8fb625 |
g_object_unref (device);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
return TRUE;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
GDBusProxy *
|
|
Packit |
8fb625 |
bluetooth_client_get_device (BluetoothClient *client,
|
|
Packit |
8fb625 |
const char *path)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
GtkTreeIter iter;
|
|
Packit |
8fb625 |
GDBusProxy *proxy;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (get_iter_from_path (priv->store, &iter, path) == FALSE) {
|
|
Packit |
8fb625 |
return NULL;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PROXY, &proxy,
|
|
Packit |
8fb625 |
-1);
|
|
Packit |
8fb625 |
return proxy;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
connect_callback (GDBusProxy *proxy,
|
|
Packit |
8fb625 |
GAsyncResult *res,
|
|
Packit |
8fb625 |
GSimpleAsyncResult *simple)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
gboolean retval;
|
|
Packit |
8fb625 |
GError *error = NULL;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
retval = device1_call_connect_finish (DEVICE1(proxy), res, &error);
|
|
Packit |
8fb625 |
if (retval == FALSE) {
|
|
Packit |
8fb625 |
g_debug ("Connect failed for %s: %s",
|
|
Packit |
8fb625 |
g_dbus_proxy_get_object_path (proxy), error->message);
|
|
Packit |
8fb625 |
g_simple_async_result_take_error (simple, error);
|
|
Packit |
8fb625 |
} else {
|
|
Packit |
8fb625 |
g_debug ("Connect succeeded for %s",
|
|
Packit |
8fb625 |
g_dbus_proxy_get_object_path (proxy));
|
|
Packit |
8fb625 |
g_simple_async_result_set_op_res_gboolean (simple, retval);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_simple_async_result_complete_in_idle (simple);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_object_unref (simple);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
static void
|
|
Packit |
8fb625 |
disconnect_callback (GDBusProxy *proxy,
|
|
Packit |
8fb625 |
GAsyncResult *res,
|
|
Packit |
8fb625 |
GSimpleAsyncResult *simple)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
gboolean retval;
|
|
Packit |
8fb625 |
GError *error = NULL;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
retval = device1_call_disconnect_finish (DEVICE1(proxy), res, &error);
|
|
Packit |
8fb625 |
if (retval == FALSE) {
|
|
Packit |
8fb625 |
g_debug ("Disconnect failed for %s: %s",
|
|
Packit |
8fb625 |
g_dbus_proxy_get_object_path (proxy),
|
|
Packit |
8fb625 |
error->message);
|
|
Packit |
8fb625 |
g_simple_async_result_take_error (simple, error);
|
|
Packit |
8fb625 |
} else {
|
|
Packit |
8fb625 |
g_debug ("Disconnect succeeded for %s",
|
|
Packit |
8fb625 |
g_dbus_proxy_get_object_path (proxy));
|
|
Packit |
8fb625 |
g_simple_async_result_set_op_res_gboolean (simple, retval);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_simple_async_result_complete_in_idle (simple);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_object_unref (simple);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
/**
|
|
Packit |
8fb625 |
* bluetooth_client_connect_service:
|
|
Packit |
8fb625 |
* @client: a #BluetoothClient
|
|
Packit |
8fb625 |
* @path: the object path on which to operate
|
|
Packit |
8fb625 |
* @connect: Whether try to connect or disconnect from services on a device
|
|
Packit |
8fb625 |
* @cancellable: optional #GCancellable object, %NULL to ignore
|
|
Packit |
8fb625 |
* @callback: (scope async): a #GAsyncReadyCallback to call when the connection is complete
|
|
Packit |
8fb625 |
* @user_data: the data to pass to callback function
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* When the connection operation is finished, @callback will be called. You can
|
|
Packit |
8fb625 |
* then call bluetooth_client_connect_service_finish() to get the result of the
|
|
Packit |
8fb625 |
* operation.
|
|
Packit |
8fb625 |
**/
|
|
Packit |
8fb625 |
void
|
|
Packit |
8fb625 |
bluetooth_client_connect_service (BluetoothClient *client,
|
|
Packit |
8fb625 |
const char *path,
|
|
Packit |
8fb625 |
gboolean connect,
|
|
Packit |
8fb625 |
GCancellable *cancellable,
|
|
Packit |
8fb625 |
GAsyncReadyCallback callback,
|
|
Packit |
8fb625 |
gpointer user_data)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
|
|
Packit |
8fb625 |
GtkTreeIter iter;
|
|
Packit |
8fb625 |
GSimpleAsyncResult *simple;
|
|
Packit |
8fb625 |
GDBusProxy *device;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_return_if_fail (BLUETOOTH_IS_CLIENT (client));
|
|
Packit |
8fb625 |
g_return_if_fail (path != NULL);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (get_iter_from_path (priv->store, &iter, path) == FALSE)
|
|
Packit |
8fb625 |
return;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PROXY, &device,
|
|
Packit |
8fb625 |
-1);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
simple = g_simple_async_result_new (G_OBJECT (client),
|
|
Packit |
8fb625 |
callback,
|
|
Packit |
8fb625 |
user_data,
|
|
Packit |
8fb625 |
bluetooth_client_connect_service);
|
|
Packit |
8fb625 |
g_simple_async_result_set_check_cancellable (simple, cancellable);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (connect) {
|
|
Packit |
8fb625 |
device1_call_connect (DEVICE1(device),
|
|
Packit |
8fb625 |
cancellable,
|
|
Packit |
8fb625 |
(GAsyncReadyCallback) connect_callback,
|
|
Packit |
8fb625 |
simple);
|
|
Packit |
8fb625 |
} else {
|
|
Packit |
8fb625 |
device1_call_disconnect (DEVICE1(device),
|
|
Packit |
8fb625 |
cancellable,
|
|
Packit |
8fb625 |
(GAsyncReadyCallback) disconnect_callback,
|
|
Packit |
8fb625 |
simple);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_object_unref (device);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
/**
|
|
Packit |
8fb625 |
* bluetooth_client_connect_service_finish:
|
|
Packit |
8fb625 |
* @client: a #BluetoothClient
|
|
Packit |
8fb625 |
* @res: a #GAsyncResult
|
|
Packit |
8fb625 |
* @error: a #GError
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* Finishes the connection operation. See bluetooth_client_connect_service().
|
|
Packit |
8fb625 |
*
|
|
Packit |
8fb625 |
* Returns: %TRUE if the connection operation succeeded, %FALSE otherwise.
|
|
Packit |
8fb625 |
**/
|
|
Packit |
8fb625 |
gboolean
|
|
Packit |
8fb625 |
bluetooth_client_connect_service_finish (BluetoothClient *client,
|
|
Packit |
8fb625 |
GAsyncResult *res,
|
|
Packit |
8fb625 |
GError **error)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
GSimpleAsyncResult *simple;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
simple = (GSimpleAsyncResult *) res;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == bluetooth_client_connect_service);
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (g_simple_async_result_get_op_res_gboolean (simple))
|
|
Packit |
8fb625 |
return TRUE;
|
|
Packit |
8fb625 |
g_simple_async_result_propagate_error (simple, error);
|
|
Packit |
8fb625 |
return FALSE;
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
#define BOOL_STR(x) (x ? "True" : "False")
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
void
|
|
Packit |
8fb625 |
bluetooth_client_dump_device (GtkTreeModel *model,
|
|
Packit |
8fb625 |
GtkTreeIter *iter)
|
|
Packit |
8fb625 |
{
|
|
Packit |
8fb625 |
GDBusProxy *proxy;
|
|
Packit |
8fb625 |
char *address, *alias, *name, *icon, **uuids;
|
|
Packit |
8fb625 |
gboolean is_default, paired, trusted, connected, discoverable, discovering, powered, is_adapter;
|
|
Packit |
8fb625 |
GtkTreeIter parent;
|
|
Packit |
8fb625 |
BluetoothType type;
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
gtk_tree_model_get (model, iter,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_ADDRESS, &address,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_ALIAS, &alias,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_NAME, &name,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_TYPE, &type,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_ICON, &icon,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_DEFAULT, &is_default,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PAIRED, &paired,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_TRUSTED, &trusted,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_CONNECTED, &connected,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_DISCOVERABLE, &discoverable,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_DISCOVERING, &discovering,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_POWERED, &powered,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_UUIDS, &uuids,
|
|
Packit |
8fb625 |
BLUETOOTH_COLUMN_PROXY, &proxy,
|
|
Packit |
8fb625 |
-1);
|
|
Packit |
8fb625 |
if (proxy) {
|
|
Packit |
8fb625 |
char *basename;
|
|
Packit |
8fb625 |
basename = g_path_get_basename(g_dbus_proxy_get_object_path(proxy));
|
|
Packit |
8fb625 |
is_adapter = !g_str_has_prefix (basename, "dev_");
|
|
Packit |
8fb625 |
g_free (basename);
|
|
Packit |
8fb625 |
} else {
|
|
Packit |
8fb625 |
is_adapter = !gtk_tree_model_iter_parent (model, &parent, iter);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
if (is_adapter != FALSE) {
|
|
Packit |
8fb625 |
/* Adapter */
|
|
Packit |
8fb625 |
g_print ("Adapter: %s (%s)\n", name, address);
|
|
Packit |
8fb625 |
if (is_default)
|
|
Packit |
8fb625 |
g_print ("\tDefault adapter\n");
|
|
Packit |
8fb625 |
g_print ("\tD-Bus Path: %s\n", proxy ? g_dbus_proxy_get_object_path (proxy) : "(none)");
|
|
Packit |
8fb625 |
g_print ("\tDiscoverable: %s\n", BOOL_STR (discoverable));
|
|
Packit |
8fb625 |
if (discovering)
|
|
Packit |
8fb625 |
g_print ("\tDiscovery in progress\n");
|
|
Packit |
8fb625 |
g_print ("\t%s\n", powered ? "Is powered" : "Is not powered");
|
|
Packit |
8fb625 |
} else {
|
|
Packit |
8fb625 |
/* Device */
|
|
Packit |
8fb625 |
g_print ("Device: %s (%s)\n", alias, address);
|
|
Packit |
8fb625 |
g_print ("\tD-Bus Path: %s\n", proxy ? g_dbus_proxy_get_object_path (proxy) : "(none)");
|
|
Packit |
8fb625 |
g_print ("\tType: %s Icon: %s\n", bluetooth_type_to_string (type), icon);
|
|
Packit |
8fb625 |
g_print ("\tPaired: %s Trusted: %s Connected: %s\n", BOOL_STR(paired), BOOL_STR(trusted), BOOL_STR(connected));
|
|
Packit |
8fb625 |
if (uuids != NULL) {
|
|
Packit |
8fb625 |
guint i;
|
|
Packit |
8fb625 |
g_print ("\tUUIDs: ");
|
|
Packit |
8fb625 |
for (i = 0; uuids[i] != NULL; i++)
|
|
Packit |
8fb625 |
g_print ("%s ", uuids[i]);
|
|
Packit |
8fb625 |
g_print ("\n");
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
g_print ("\n");
|
|
Packit |
8fb625 |
|
|
Packit |
8fb625 |
g_free (alias);
|
|
Packit |
8fb625 |
g_free (address);
|
|
Packit |
8fb625 |
g_free (icon);
|
|
Packit |
8fb625 |
g_clear_object (&proxy);
|
|
Packit |
8fb625 |
g_strfreev (uuids);
|
|
Packit |
8fb625 |
}
|
|
Packit |
8fb625 |
|