summaryrefslogtreecommitdiff
path: root/rcm-client-advanced.c
diff options
context:
space:
mode:
Diffstat (limited to 'rcm-client-advanced.c')
-rw-r--r--rcm-client-advanced.c157
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);
+}
+