diff options
Diffstat (limited to 'rcm-client-advanced.c')
-rw-r--r-- | rcm-client-advanced.c | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/rcm-client-advanced.c b/rcm-client-advanced.c new file mode 100644 index 0000000..3374ba3 --- /dev/null +++ b/rcm-client-advanced.c @@ -0,0 +1,157 @@ +#include <stdint.h> +#include <string.h> +#include <gtk/gtk.h> + +#include "generated.h" +#include "shared.h" +#include "rcm-client-main.h" +#include "rcm-client-advanced.h" + +struct state { + GList *header_buttons; +}; + +static struct state state; + +static GVariant * +encode_nec(uint32_t scancode_raw) +{ + GVariantBuilder *builder; + GVariant *r; + unsigned i; + uint32_t scancode; + + scancode = ((((scancode_raw >> 24) & 0xff) << 0) | + (((scancode_raw >> 16) & 0xff) << 8) | + (((scancode_raw >> 8) & 0xff) << 16) | + (((scancode_raw >> 0) & 0xff) << 24)); + + builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY); + g_variant_builder_add(builder, "u", 9000); + g_variant_builder_add(builder, "u", 4500); + + for (i = 0; i < 32; i++) { + g_variant_builder_add(builder, "u", 560); + if (scancode & 0x1) + g_variant_builder_add(builder, "u", 3 * 560); + else + g_variant_builder_add(builder, "u", 1 * 560); + scancode >>= 1; + } + + g_variant_builder_add(builder, "u", 560); + + r = g_variant_builder_end(builder); + g_variant_builder_unref(builder); + return r; +} + +static void +advanced_transmit_cb(GtkButton *button, gpointer user_data) +{ + RCDevice *object = user_data; + GtkComboBoxText *protocolw; + GtkEntry *scancodew; + gchar *protocol; + const gchar *scancode; + uint64_t sc; + 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")); + + protocol = gtk_combo_box_text_get_active_text(protocolw); + scancode = gtk_entry_get_text(scancodew); + printf("Asked to transmit: protocol %s scancode %s\n", protocol, scancode); + g_free(protocol); + + if (!strcmp(protocol, "NEC")) { + printf("Invalid protocol: %s\n", protocol); + return; + } + + r = strtoull_strict(scancode, &sc); + if (r < 0 || sc > UINT32_MAX) { + printf("Invalid scancode: %s\n", scancode); + return; + } + + if (!rcdevice_call_transmit_sync(object, encode_nec(sc), NULL, &error)) { + printf("rcdevice_call_transmit_sync failed: %s\n", + error ? error->message : "no error reported"); + g_error_free(error); + } +} + +static void +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")); + GtkWidget *button; + + button = create_header_button(header, tooltip, icon_name, end, callback, user_data); + state.header_buttons = g_list_prepend(state.header_buttons, button); +} + +static void +remove_header_buttons(void) +{ + GList *l; + + for (l = state.header_buttons; l; l = l->next) + gtk_widget_destroy(l->data); + + g_list_free(state.header_buttons); + state.header_buttons = NULL; +} + +static void +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")); + gtk_stack_set_visible_child_name(stack, "advanced_main_page"); +} + +static void +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")); + 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); + local_create_header_button("Return to advanced menu", "go-previous-symbolic", false, G_CALLBACK(advanced_show_main_cb), NULL); +} + +void +advanced_init_ui(RCDevice *object) +{ + GtkWidget *dialog; + GtkWidget *title; + GtkWidget *transmit; + gchar *titlestr; + + dialog = GTK_WIDGET(gtk_builder_get_object(global->builder, "advanced")); + + title = GTK_WIDGET(gtk_builder_get_object(global->builder, "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_connect_swapped(dialog, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), dialog); + gtk_widget_show(dialog); +} + |