diff options
Diffstat (limited to 'rcm-client-advanced.c')
-rw-r--r-- | rcm-client-advanced.c | 201 |
1 files changed, 185 insertions, 16 deletions
diff --git a/rcm-client-advanced.c b/rcm-client-advanced.c index 3374ba3..31ac86b 100644 --- a/rcm-client-advanced.c +++ b/rcm-client-advanced.c @@ -1,6 +1,8 @@ #include <stdint.h> #include <string.h> #include <gtk/gtk.h> +#include <inttypes.h> +#include <stdint.h> #include "generated.h" #include "shared.h" @@ -58,8 +60,8 @@ advanced_transmit_cb(GtkButton *button, gpointer user_data) GError *error = NULL; gboolean r; - protocolw = GTK_COMBO_BOX_TEXT(gtk_builder_get_object(global->builder, "advanced_transmit_protocol")); - scancodew = GTK_ENTRY(gtk_builder_get_object(global->builder, "advanced_transmit_scancode")); + protocolw = GTK_COMBO_BOX_TEXT(get_object("advanced_transmit_protocol")); + scancodew = GTK_ENTRY(get_object("advanced_transmit_scancode")); protocol = gtk_combo_box_text_get_active_text(protocolw); scancode = gtk_entry_get_text(scancodew); @@ -89,7 +91,7 @@ local_create_header_button(const gchar *tooltip, const gchar *icon_name, gboolean end, GCallback callback, gpointer user_data) { - GtkHeaderBar *header = GTK_HEADER_BAR(gtk_builder_get_object(global->builder, "advanced_headerbar")); + GtkHeaderBar *header = GTK_HEADER_BAR(get_object("advanced_headerbar")); GtkWidget *button; button = create_header_button(header, tooltip, icon_name, end, callback, user_data); @@ -114,7 +116,7 @@ advanced_show_main_cb(GtkButton *button, gpointer user_data) GtkStack *stack; remove_header_buttons(); - stack = GTK_STACK(gtk_builder_get_object(global->builder, "advanced_stack")); + stack = GTK_STACK(get_object("advanced_stack")); gtk_stack_set_visible_child_name(stack, "advanced_main_page"); } @@ -123,35 +125,202 @@ advanced_show_transmit_cb(GtkButton *button, gpointer user_data) { RCDevice *object = user_data; GtkStack *stack; - GtkWidget *transmit_button; - stack = GTK_STACK(gtk_builder_get_object(global->builder, "advanced_stack")); + stack = GTK_STACK(get_object("advanced_stack")); gtk_stack_set_visible_child_name(stack, "advanced_transmit_page"); - transmit_button = GTK_WIDGET(gtk_builder_get_object(global->builder, "advanced_transmit_button")); - g_signal_connect(transmit_button, "clicked", G_CALLBACK(advanced_transmit_cb), object); + g_signal_replace_id("advanced_transmit_button", "clicked", G_CALLBACK(advanced_transmit_cb), object); + local_create_header_button("Return to advanced menu", "go-previous-symbolic", false, G_CALLBACK(advanced_show_main_cb), NULL); +} + +static void advanced_show_keymap_cb(GtkButton *button, gpointer user_data); + +static void +advanced_keymap_remove_cb(GtkButton *button, gpointer user_data) +{ + RCDevice *object = user_data; + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + gchar *protocol; + guint64 scancode; + gchar *keycode; + GVariantBuilder builder; + + selection = GTK_TREE_SELECTION(get_object("advanced_keymap_treeselection")); + if (!gtk_tree_selection_get_selected(selection, &model, &iter)) + return; + + gtk_tree_model_get(model, &iter, 0, &protocol, 1, &scancode, 2, &keycode, -1); + printf("Row to be deleted: %s:%lux:%s\n", protocol, scancode, keycode); + + g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); + g_variant_builder_open(&builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add(&builder, "{sv}", "protocol", + g_variant_new_string(protocol)); + g_variant_builder_add(&builder, "{sv}", "scancode", + g_variant_new_uint64(scancode)); + g_variant_builder_add(&builder, "{sv}", "keycode", + g_variant_new_string("KEY_RESERVED")); + g_variant_builder_close(&builder); + + if (!rcdevice_call_set_kernel_mappings_sync(object, + g_variant_builder_end(&builder), + NULL, NULL)) + return; + + advanced_show_keymap_cb(NULL, object); +} + +static void +advanced_keymap_row_selected_cb(GtkTreeSelection *selection, gpointer user_data) +{ + GtkTreeModel *model; + GtkTreeIter iter; + GtkWidget *remove; + + remove = GTK_WIDGET(get_object("advanced_keymap_remove")); + if (gtk_tree_selection_get_selected(selection, &model, &iter)) { + g_signal_replace(remove, "clicked", G_CALLBACK(advanced_keymap_remove_cb), user_data); + gtk_widget_set_sensitive(remove, true); + } else + gtk_widget_set_sensitive(remove, false); +} + +static void +advanced_keymap_add_cb(GtkButton *button, gpointer user_data) +{ + RCDevice *object = user_data; + GtkWidget *dialog; + gchar *protocol; + const char *scanstr; + guint64 scancode; + gchar *keycode; + GVariantBuilder builder; + int r; + + dialog = GTK_WIDGET(get_object("advanced_add")); + gtk_widget_show_all(dialog); + r = gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_hide(dialog); + + if (r != 1) + return; + + scanstr = gtk_entry_get_text(GTK_ENTRY(get_object("advanced_add_scancode"))); + r = strtoull_strict(scanstr, &scancode); + if (r < 0) + return; + + protocol = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(get_object("advanced_add_protocol"))); + keycode = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(get_object("advanced_add_keycode"))); + + g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); + g_variant_builder_open(&builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add(&builder, "{sv}", "protocol", + g_variant_new_string(protocol)); + g_variant_builder_add(&builder, "{sv}", "scancode", + g_variant_new_uint64(scancode)); + g_variant_builder_add(&builder, "{sv}", "keycode", + g_variant_new_string(keycode)); + g_variant_builder_close(&builder); + + g_free(protocol); + g_free(keycode); + + if (!rcdevice_call_set_kernel_mappings_sync(object, + g_variant_builder_end(&builder), + NULL, NULL)) + return; + + advanced_show_keymap_cb(NULL, object); +} + +static void +advanced_show_keymap_cb(GtkButton *button, gpointer user_data) +{ + RCDevice *object = user_data; + GtkListStore *store; + GVariant *keymap_entries = NULL; + GtkStack *stack; + + g_signal_replace_id("advanced_keymap_treeselection", "changed", G_CALLBACK(advanced_keymap_row_selected_cb), object); + g_signal_replace_id("advanced_keymap_add", "clicked", G_CALLBACK(advanced_keymap_add_cb), object); + g_signal_replace_id("advanced_keymap_refresh", "clicked", G_CALLBACK(advanced_show_keymap_cb), object); + store = GTK_LIST_STORE(get_object("advanced_keymap_liststore")); + gtk_list_store_clear(store); + + rcdevice_call_get_kernel_mappings_sync(object, &keymap_entries, NULL, NULL); + + g_assert(g_variant_is_of_type(keymap_entries, G_VARIANT_TYPE("aa{sv}"))); + + GVariantIter iter; + gsize n_items; + GVariant *item; + + n_items = g_variant_iter_init(&iter, keymap_entries); + g_print("Keymap items: %zu\n", n_items); + while (g_variant_iter_loop (&iter, "@a{sv}", &item)) { + gchar *protocol; + guint64 scancode; + gchar *keycode; + GtkTreeIter iter; + + g_variant_lookup(item, "protocol", "s", &protocol); + g_variant_lookup(item, "scancode", "t", &scancode); + g_variant_lookup(item, "keycode", "s", &keycode); + + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, protocol, 1, scancode, 2, keycode, -1); + } + g_variant_unref(keymap_entries); + + stack = GTK_STACK(get_object("advanced_stack")); + gtk_stack_set_visible_child_name(stack, "advanced_keymap_page"); + remove_header_buttons(); local_create_header_button("Return to advanced menu", "go-previous-symbolic", false, G_CALLBACK(advanced_show_main_cb), NULL); } +static void +render_cell_as_hexadecimal(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, + GtkTreeModel *tree_model, GtkTreeIter *iter, + gpointer user_data) +{ + guint64 val; + gchar *text; + + gtk_tree_model_get(tree_model, iter, 1, &val, -1); + if (val > UINT32_MAX) + text = g_strdup_printf("0x%016" PRIX64, val); + else + text = g_strdup_printf("0x%08" PRIX64, val); + g_object_set(cell, "text", text, NULL); + g_free (text); +} + void advanced_init_ui(RCDevice *object) { - GtkWidget *dialog; GtkWidget *title; - GtkWidget *transmit; gchar *titlestr; + GtkWidget *dialog; - dialog = GTK_WIDGET(gtk_builder_get_object(global->builder, "advanced")); - - title = GTK_WIDGET(gtk_builder_get_object(global->builder, "advanced_main_title_label")); + title = GTK_WIDGET(get_object("advanced_main_title_label")); titlestr = g_markup_printf_escaped("<b><big>Advanced Actions</big></b>\nFor device %s", rcdevice_get_sys_name(object)); gtk_label_set_markup(GTK_LABEL(title), titlestr); g_free(titlestr); - transmit = GTK_WIDGET(gtk_builder_get_object(global->builder, "advanced_main_transmit")); - g_signal_connect(transmit, "clicked", G_CALLBACK(advanced_show_transmit_cb), object); + g_signal_replace_id("advanced_main_transmit", "clicked", G_CALLBACK(advanced_show_transmit_cb), object); + g_signal_replace_id("advanced_main_keymap", "clicked", G_CALLBACK(advanced_show_keymap_cb), object); + + gtk_tree_view_column_set_cell_data_func(GTK_TREE_VIEW_COLUMN(get_object("advanced_keymap_treecol_scancode")), + GTK_CELL_RENDERER(get_object("advanced_keymap_treecell_scancode")), + render_cell_as_hexadecimal, + NULL, NULL); - g_signal_connect_swapped(dialog, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), dialog); + dialog = GTK_WIDGET(get_object("advanced")); + g_signal_replace_swapped(dialog, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), dialog); + advanced_show_main_cb(NULL, NULL); gtk_widget_show(dialog); } |