#include #include #include #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("Advanced Actions\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); }