/* * * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2005-2008 Marcel Holtmann * * * 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 #endif #include #include "bluetooth-client.h" #include "bluetooth-client-private.h" #include "gnome-bluetooth-enum-types.h" #include "bluetooth-utils.h" static BluetoothClient *client; static GtkTreeSelection *selection; static void delete_callback(GtkWidget *window, GdkEvent *event, gpointer user_data) { gtk_widget_destroy(window); gtk_main_quit(); } static void scan_callback(GtkWidget *button, gpointer user_data) { g_object_set (G_OBJECT (client), "default-adapter-discovering", TRUE, NULL); } static void select_callback(GtkTreeSelection *selection, gpointer user_data) { GtkTreeModel *model; GtkTreeIter iter; if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE) { g_print ("No devices selected"); return; } bluetooth_client_dump_device (model, &iter); } static void row_inserted(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data) { GtkTreeView *tree = user_data; gtk_tree_view_expand_all(tree); } static void proxy_to_text(GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) { GDBusProxy *proxy; gchar *path; gtk_tree_model_get(model, iter, BLUETOOTH_COLUMN_PROXY, &proxy, -1); if (proxy == NULL) { g_object_set(cell, "text", "", NULL); return; } path = g_path_get_basename(g_dbus_proxy_get_object_path(proxy)); g_object_set(cell, "text", path, NULL); g_free(path); g_object_unref(proxy); } static void type_to_text(GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) { guint type; gtk_tree_model_get(model, iter, BLUETOOTH_COLUMN_TYPE, &type, -1); g_object_set(cell, "text", bluetooth_type_to_string(type), NULL); } static void legacypairing_to_text(GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) { gint legacypairing; gtk_tree_model_get(model, iter, BLUETOOTH_COLUMN_LEGACYPAIRING, &legacypairing, -1); switch (legacypairing) { case -1: g_object_set(cell, "text", "UNSET", NULL); break; case 0: g_object_set(cell, "text", "FALSE", NULL); break; default: g_object_set(cell, "text", "TRUE", NULL); } } static void uuids_to_text(GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) { char **uuids; char *str; gtk_tree_model_get(model, iter, BLUETOOTH_COLUMN_UUIDS, &uuids, -1); if (uuids == NULL) str = NULL; else str = g_strjoinv (", ", uuids); g_strfreev (uuids); g_object_set(cell, "text", str, NULL); g_free (str); } static void create_window(void) { GtkWidget *window; GtkWidget *vbox; GtkWidget *toolbar; GtkToolItem *item; GtkWidget *scrolled; GtkWidget *tree; GtkTreeModel *model; GtkTreeModel *sorted; GtkWidget *statusbar; window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Test client"); gtk_window_set_icon_name(GTK_WINDOW(window), "bluetooth"); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 800, 600); g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(delete_callback), NULL); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_add(GTK_CONTAINER(window), vbox); toolbar = gtk_toolbar_new(); gtk_toolbar_set_show_arrow(GTK_TOOLBAR(toolbar), FALSE); gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, TRUE, 0); item = gtk_tool_button_new (gtk_image_new_from_icon_name ("view-refresh", GTK_ICON_SIZE_LARGE_TOOLBAR), NULL); gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); g_signal_connect(item, "clicked", G_CALLBACK(scan_callback), NULL); scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0); tree = gtk_tree_view_new(); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), TRUE); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(tree), TRUE); gtk_widget_grab_focus(GTK_WIDGET(tree)); gtk_container_add(GTK_CONTAINER(scrolled), tree); gtk_tree_view_insert_column_with_data_func(GTK_TREE_VIEW(tree), -1, "Proxy", gtk_cell_renderer_text_new(), proxy_to_text, NULL, NULL); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, "Address", gtk_cell_renderer_text_new(), "text", BLUETOOTH_COLUMN_ADDRESS, NULL); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, "Alias", gtk_cell_renderer_text_new(), "text", BLUETOOTH_COLUMN_ALIAS, NULL); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, "Name", gtk_cell_renderer_text_new(), "text", BLUETOOTH_COLUMN_NAME, NULL); gtk_tree_view_insert_column_with_data_func(GTK_TREE_VIEW(tree), -1, "Type", gtk_cell_renderer_text_new(), type_to_text, NULL, NULL); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, "Icon", gtk_cell_renderer_text_new(), "text", BLUETOOTH_COLUMN_ICON, NULL); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, "Default", gtk_cell_renderer_text_new(), "text", BLUETOOTH_COLUMN_DEFAULT, NULL); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, "Paired", gtk_cell_renderer_text_new(), "text", BLUETOOTH_COLUMN_PAIRED, NULL); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, "Trusted", gtk_cell_renderer_text_new(), "text", BLUETOOTH_COLUMN_TRUSTED, NULL); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, "Connected", gtk_cell_renderer_text_new(), "text", BLUETOOTH_COLUMN_CONNECTED, NULL); gtk_tree_view_insert_column_with_data_func(GTK_TREE_VIEW(tree), -1, "Legacy Pairing", gtk_cell_renderer_text_new(), legacypairing_to_text, NULL, NULL); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, "Discoverable", gtk_cell_renderer_text_new(), "text", BLUETOOTH_COLUMN_DISCOVERABLE, NULL); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, "Discovering", gtk_cell_renderer_text_new(), "text", BLUETOOTH_COLUMN_DISCOVERING, NULL); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, "Powered", gtk_cell_renderer_text_new(), "text", BLUETOOTH_COLUMN_POWERED, NULL); gtk_tree_view_insert_column_with_data_func(GTK_TREE_VIEW(tree), -1, "UUIDs", gtk_cell_renderer_text_new(), uuids_to_text, NULL, NULL); model = bluetooth_client_get_model(client); sorted = gtk_tree_model_sort_new_with_model(model); gtk_tree_view_set_model(GTK_TREE_VIEW(tree), sorted); g_signal_connect(G_OBJECT(model), "row-inserted", G_CALLBACK(row_inserted), tree); g_object_unref(sorted); g_object_unref(model); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(select_callback), NULL); gtk_tree_view_expand_all(GTK_TREE_VIEW(tree)); statusbar = gtk_statusbar_new(); gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, FALSE, 0); gtk_widget_show_all(window); } static void default_adapter_changed (GObject *gobject, GParamSpec *pspec, gpointer user_data) { char *adapter; g_object_get (G_OBJECT (gobject), "default-adapter", &adapter, NULL); g_message ("Default adapter changed: %s", adapter ? adapter : "(none)"); g_free (adapter); } static void default_adapter_powered_changed (GObject *gobject, GParamSpec *pspec, gpointer user_data) { gboolean powered; g_object_get (G_OBJECT (gobject), "default-adapter-powered", &powered, NULL); g_message ("Default adapter is %s", powered ? "powered" : "switched off"); } static void default_adapter_discovering_changed (GObject *gobject, GParamSpec *pspec, gpointer user_data) { gboolean discovering; g_object_get (G_OBJECT (gobject), "default-adapter-discovering", &discovering, NULL); g_message ("Default adapter is %s", discovering ? "discovering" : "not discovering"); } int main(int argc, char *argv[]) { GLogLevelFlags fatal_mask; gtk_init(&argc, &argv); fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; g_log_set_always_fatal (fatal_mask); client = bluetooth_client_new(); g_signal_connect (G_OBJECT (client), "notify::default-adapter", G_CALLBACK (default_adapter_changed), NULL); g_signal_connect (G_OBJECT (client), "notify::default-adapter-powered", G_CALLBACK (default_adapter_powered_changed), NULL); g_signal_connect (G_OBJECT (client), "notify::default-adapter-discovering", G_CALLBACK (default_adapter_discovering_changed), NULL); default_adapter_changed (G_OBJECT (client), NULL, NULL); default_adapter_powered_changed (G_OBJECT (client), NULL, NULL); create_window(); gtk_main(); g_object_unref(client); return 0; }