From f3f7d5445e6f64a7c946f6e0144452952f0809e8 Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Mon, 17 Aug 2015 20:54:45 +0200 Subject: Revamp advanced UI --- Makefile | 4 +- rcm-client-advanced.c | 157 ++++++++++++++++++++ rcm-client-advanced.h | 3 + rcm-client-hardware-list.c | 90 +----------- rcm-client-main.c | 30 +++- rcm-client-main.h | 6 +- rcm-client-receive.c | 30 +--- rcm-client.ui | 359 ++++++++++++++++++++++++++++++++------------- rcm-server-evdev.c | 2 +- 9 files changed, 461 insertions(+), 220 deletions(-) create mode 100644 rcm-client-advanced.c create mode 100644 rcm-client-advanced.h diff --git a/Makefile b/Makefile index cef1614..d4d8185 100644 --- a/Makefile +++ b/Makefile @@ -27,8 +27,8 @@ RCC_CFLAGS = ${GENERIC_CFLAGS} ${EXTRA_CFLAGS} $(shell pkg-config --cflags ${RCC RCC_LDFLAGS = ${GENERIC_LDFLAGS} ${EXTRA_LDFLAGS} $(shell pkg-config --libs ${RCC_PACKAGES}) RCC_COMPILE = $(CC) $(RCC_CFLAGS) RCC_LINK = $(CC) $(RCC_CFLAGS) $(RCC_LDFLAGS) -RCC_OBJECTS = rcm-client-main.o rcm-client-hardware-list.o rcm-client-receive.o generated.o shared.o -RCC_HEADERS = rcm-client-main.h rcm-client-hardware-list.h rcm-client-receive.h generated.h $(COMMON_HEADERS) +RCC_OBJECTS = rcm-client-main.o rcm-client-hardware-list.o rcm-client-receive.o rcm-client-advanced.o generated.o shared.o +RCC_HEADERS = rcm-client-main.h rcm-client-hardware-list.h rcm-client-receive.h rcm-client-advanced.h generated.h $(COMMON_HEADERS) INSTALL = install -c INSTALL_PROGRAM = ${INSTALL} 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 +#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); +} + diff --git a/rcm-client-advanced.h b/rcm-client-advanced.h new file mode 100644 index 0000000..81c1ebc --- /dev/null +++ b/rcm-client-advanced.h @@ -0,0 +1,3 @@ + +void advanced_init_ui(RCDevice *object); + diff --git a/rcm-client-hardware-list.c b/rcm-client-hardware-list.c index 2c47ee5..ea1a0d9 100644 --- a/rcm-client-hardware-list.c +++ b/rcm-client-hardware-list.c @@ -10,6 +10,7 @@ #include "rcm-client-main.h" #include "rcm-client-hardware-list.h" #include "rcm-client-receive.h" +#include "rcm-client-advanced.h" static GList *hw_list = NULL; @@ -85,99 +86,12 @@ hardware_properties_cb(GtkButton *button, gpointer user_data) gtk_widget_hide(dialog); } -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_main_transmit_protocol")); - scancodew = GTK_ENTRY(gtk_builder_get_object(global->builder, "advanced_main_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 advanced_cb(GtkButton *button, gpointer user_data) { RCDevice *object = user_data; - 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_button")); - g_signal_connect(transmit, "clicked", G_CALLBACK(advanced_transmit_cb), object); - g_signal_connect_swapped(dialog, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), dialog); - gtk_widget_show(dialog); + advanced_init_ui(object); } static void diff --git a/rcm-client-main.c b/rcm-client-main.c index 1467f16..420ab6c 100644 --- a/rcm-client-main.c +++ b/rcm-client-main.c @@ -138,6 +138,33 @@ manager_ready_cb(GObject *source, GAsyncResult *res, gpointer user_data) } +GtkWidget * +create_header_button(GtkHeaderBar *header, const gchar *tooltip, + const gchar *icon_name, gboolean end, GCallback callback, + gpointer user_data) +{ + GtkWidget *button; + + button = gtk_button_new_from_icon_name(icon_name, GTK_ICON_SIZE_BUTTON); + + if (tooltip) + gtk_widget_set_tooltip_text(button, tooltip); + + g_signal_connect(button, "clicked", callback, user_data); + gtk_widget_set_valign(button, GTK_ALIGN_CENTER); + gtk_widget_show_all(button); + + if (!header) + header = GTK_HEADER_BAR(gtk_builder_get_object(global->builder, "main_headerbar")); + + if (end) + gtk_header_bar_pack_end(header, button); + else + gtk_header_bar_pack_start(header, button); + + return button; +} + int main(int argc, char *argv[]) { GtkCssProvider *css; @@ -158,9 +185,6 @@ int main(int argc, char *argv[]) global->window = GTK_WINDOW(gtk_builder_get_object(global->builder, "main_window")); g_signal_connect(global->window, "destroy", G_CALLBACK(gtk_main_quit), NULL); - global->header = GTK_HEADER_BAR(gtk_builder_get_object(global->builder, "headerbar")); - gtk_header_bar_set_show_close_button(global->header, TRUE); - global->stack = GTK_STACK(gtk_builder_get_object(global->builder, "main_stack")); gtk_widget_show_all(GTK_WIDGET(global->window)); diff --git a/rcm-client-main.h b/rcm-client-main.h index 9107273..f48be19 100644 --- a/rcm-client-main.h +++ b/rcm-client-main.h @@ -2,9 +2,13 @@ void poke_objects(); struct global_variables { GtkWindow *window; - GtkHeaderBar *header; GtkStack *stack; GtkBuilder *builder; }; +GtkWidget * +create_header_button(GtkHeaderBar *header, const gchar *tooltip, + const gchar *icon_name, gboolean end, GCallback callback, + gpointer user_data); + extern struct global_variables *global; diff --git a/rcm-client-receive.c b/rcm-client-receive.c index 4adfb7c..828d07e 100644 --- a/rcm-client-receive.c +++ b/rcm-client-receive.c @@ -378,27 +378,13 @@ new_button_add(struct remote *remote, const gchar *protocol, guint64 scancode, return rcb; } -/* FIXME: These two functions should probably move to the core */ static void -create_header_button(const gchar *tooltip, const gchar *icon_name, gboolean end, - GCallback callback, gpointer user_data) +local_create_header_button(const gchar *tooltip, const gchar *icon_name, gboolean end, + GCallback callback, gpointer user_data) { GtkWidget *button; - button = gtk_button_new_from_icon_name(icon_name, GTK_ICON_SIZE_BUTTON); - - if (tooltip) - gtk_widget_set_tooltip_text(button, tooltip); - - g_signal_connect(button, "clicked", callback, user_data); - gtk_widget_set_valign(button, GTK_ALIGN_CENTER); - gtk_widget_show_all(button); - - if (end) - gtk_header_bar_pack_end(GTK_HEADER_BAR(global->header), button); - else - gtk_header_bar_pack_start(GTK_HEADER_BAR(global->header), button); - + button = create_header_button(NULL, tooltip, icon_name, end, callback, user_data); state.header_buttons = g_list_prepend(state.header_buttons, button); } @@ -642,7 +628,7 @@ static void show_hardware_list(GtkButton *button, gpointer user_data) { remove_header_buttons(); - gtk_header_bar_set_custom_title(GTK_HEADER_BAR(global->header), NULL); + gtk_header_bar_set_custom_title(GTK_HEADER_BAR(gtk_builder_get_object(global->builder, "main_headerbar")), NULL); gtk_stack_set_visible_child_name(global->stack, "hardware_page"); if (state.title) @@ -663,11 +649,11 @@ set_edit_keymap(bool editing) remove_header_buttons(); - create_header_button("Return to hardware list", "go-previous-symbolic", false, G_CALLBACK(show_hardware_list), NULL); + local_create_header_button("Return to hardware list", "go-previous-symbolic", false, G_CALLBACK(show_hardware_list), NULL); if (editing) - create_header_button("Save changes", "document-save-symbolic", true, G_CALLBACK(toggle_edit_keymap), NULL); + local_create_header_button("Save changes", "document-save-symbolic", true, G_CALLBACK(toggle_edit_keymap), NULL); else - create_header_button("Edit keymaps", "document-properties-symbolic", true, G_CALLBACK(toggle_edit_keymap), NULL); + local_create_header_button("Edit keymaps", "document-properties-symbolic", true, G_CALLBACK(toggle_edit_keymap), NULL); for (l = state.remotes; l; l = l->next) { struct remote *remote = l->data; @@ -971,6 +957,6 @@ void rcng_client_receive_init_ui(GDBusObject *new_hw) gtk_stack_set_visible_child(global->stack, state.stack); set_edit_keymap(state.editing); - gtk_header_bar_set_custom_title(GTK_HEADER_BAR(global->header), state.title); + gtk_header_bar_set_custom_title(GTK_HEADER_BAR(gtk_builder_get_object(global->builder, "main_headerbar")), state.title); } diff --git a/rcm-client.ui b/rcm-client.ui index 8384abd..0e3fae1 100644 --- a/rcm-client.ui +++ b/rcm-client.ui @@ -2,32 +2,21 @@ - - True - False - network-receive-symbolic - - - True - False - network-transmit-symbolic - False - Advanced Actions True False + 18 + 18 + 18 + 18 crossfade True False - 18 - 18 - 18 - 18 12 12 @@ -36,6 +25,7 @@ False 6 1 + 0 input-dialpad 6 @@ -45,40 +35,241 @@ - + + True + False + 6 + True + True + 0 + + + 1 + 0 + + + + True False True True - end - advanced_button_receive_image + True + none + + + True + False + False + 12 + + + True + False + 1 + 0 + network-receive-symbolic + 6 + + + False + True + 0 + + + + + True + False + <b><big>Receive Raw Events</big></b> +Receive raw events from the kernel +without using a keytable + True + 0 + 0 + + + False + True + 1 + + + + 0 1 + 2 - + True True True - end - start - advanced_button_transmit_image + True + none + + + True + False + 12 + + + True + False + 1 + 0 + network-transmit-symbolic + 6 + + + False + True + 0 + + + + + True + False + <b><big>Transmit Raw Events</big></b> +Transmit raw events without using +a keytable + True + 0 + 0 + + + False + True + 1 + + + + 0 2 + 2 - + + True + False + True + True + True + none + + + True + False + 12 + + + True + False + 1 + 0 + accessories-calculator + 6 + + + False + True + 0 + + + + + True + False + <b><big>Edit Kernel Keytable</big></b> +Edit the in-kernel protocol/scancode +to keycode table + True + + + False + True + 1 + + + + + + + 0 + 3 + 2 + + + + + advanced_main_page + advanced_main_page + + + + + True + False + 12 + 12 + + True False - 6 + 0 + 0 + network-transmit-symbolic + 6 + + + 0 + 0 + + + + + True + False + False + Protocol + 1 + + + 0 + 1 + + + + + True + False + False + Scancode + 1 + + + 0 + 2 + + + + + True + False + <b><big>Transmit Raw Command</big></b> +Transmit a raw command +Based on protocol and scancode True 0 + 0 1 @@ -86,11 +277,13 @@ - + True False - Receive raw commands - 0 + 0 + + NEC + 1 @@ -98,94 +291,53 @@ - + True - False - 6 - 12 - - - True - False - <b>Transmit raw command</b> - True - 0 - - - 0 - 0 - 2 - - - - - True - False - False - 6 - Protocol - 1 - - - 0 - 1 - - - - - True - False - False - 6 - Scancode - 1 - - - 0 - 2 - - - - - True - False - 0 - - NEC - - - - 1 - 1 - - - - - True - True - 10 - 0x01FE0FF0 - GTK_INPUT_HINT_UPPERCASE_CHARS | GTK_INPUT_HINT_NONE - - - 1 - 2 - - + True + 10 + 0x1FE0FF0 + GTK_INPUT_HINT_UPPERCASE_CHARS | GTK_INPUT_HINT_NONE 1 2 + + + Transmit + True + True + True + end + + + 0 + 3 + 2 + + - page0 - page0 + advanced_transmit_page + advanced_transmit_page + 1 + + + True + False + Remove Control - Advanced Actions + False + True + + + + + 1 @@ -317,11 +469,12 @@ Currently connected receivers/transmitters - + True False Remote Control Configuration False + True diff --git a/rcm-server-evdev.c b/rcm-server-evdev.c index ab5ac0e..34014e3 100644 --- a/rcm-server-evdev.c +++ b/rcm-server-evdev.c @@ -234,7 +234,7 @@ evdev_read(sd_event_source *s, int fd, uint32_t revents, void *userdata) device->path, "org.gnome.RemoteControlManager.Device", "KeyPressed", - "sts", protocol, scancode, + "sts", protocol ? protocol : "NEC", scancode, keycode ? keycode->name : "KEY_RESERVED"); else if (keycode && !pressed) -- cgit v1.2.3