#include #include #include #include #include #include #include "generated.h" #include "shared.h" #include "rcm-client-main.h" #include "rcm-client-hardware-list.h" #include "rcm-client-receive.h" static GList *hw_list = NULL; struct hwentry { GDBusObject *hw; GtkWidget *widget; }; static gint find_hwentry_by_object(gconstpointer a, gconstpointer user_data) { const struct hwentry *hwe = a; return hwe->hw == user_data ? 0 : -1; } void rcng_client_hardware_list_remove(GDBusObject *hw) { GList *entry; struct hwentry *hwe; entry = g_list_find_custom(hw_list, hw, find_hwentry_by_object); if (!entry) return; hwe = entry->data; hw_list = g_list_remove_all(hw_list, hwe); g_print(" - Object removed %s\n", g_dbus_object_get_object_path(hwe->hw)); gtk_widget_destroy(hwe->widget); g_free(hwe); if (!hw_list) gtk_stack_set_visible_child_name(global->stack, "status_page"); } static void edit_keymaps_cb(GtkButton *button, gpointer user_data) { GDBusObject *hw = user_data; rcng_client_receive_init_ui(hw); } static void hardware_properties_cb(GtkButton *button, gpointer user_data) { RCDevice *object = user_data; GtkWidget *dialog; GtkLabel *dev; GtkLabel *desc; GtkLabel *driver; GtkLabel *kernelmap; dialog = GTK_WIDGET(gtk_builder_get_object(global->builder, "hardware_properties")); dev = GTK_LABEL(gtk_builder_get_object(global->builder, "hardware_properties_dev_value")); gtk_label_set_text(dev, rcdevice_get_sys_name(object)); desc = GTK_LABEL(gtk_builder_get_object(global->builder, "hardware_properties_desc_value")); gtk_label_set_text(desc, rcdevice_get_description(object)); driver = GTK_LABEL(gtk_builder_get_object(global->builder, "hardware_properties_driver_value")); gtk_label_set_text(driver, rcdevice_get_driver_name(object)); kernelmap = GTK_LABEL(gtk_builder_get_object(global->builder, "hardware_properties_kernelmap_value")); gtk_label_set_text(kernelmap, rcdevice_get_kernel_keymap_name(object)); gtk_widget_show_all(dialog); gtk_dialog_run(GTK_DIALOG(dialog)); 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); } static void hw_selected_cb(GtkListBox *box, GtkListBoxRow *row, gpointer user_data) { RCDevice *object = user_data; GtkWidget *advanced_button; gchar *error; advanced_button = GTK_WIDGET(gtk_builder_get_object(global->builder, "hardware_page_action_advanced")); error = row ? g_object_get_data(G_OBJECT(row), "error") : NULL; g_signal_connect(advanced_button, "clicked", G_CALLBACK(advanced_cb), object); gtk_widget_set_sensitive(advanced_button, row && !error ? true : false); } static gint rcdev_sort(GtkListBoxRow *a, GtkListBoxRow *b, gpointer user_data) { return strcmp(g_object_get_data(G_OBJECT(a), "rcdev"), g_object_get_data(G_OBJECT(b), "rcdev")); } void rcng_client_hardware_list_add(GDBusObject *hw) { GList *interfaces; GList *ll; GtkWidget *row; GtkWidget *box; GtkWidget *icon; GtkWidget *label; GtkWidget *button; struct hwentry *hwe; gchar *labeltxt; GtkWidget *hw_list_swin; GtkWidget *hw_list_box; GDBusInterface *interface; RCDevice *object; const gchar *error; g_print(" - Object at %s\n", g_dbus_object_get_object_path(hw)); interfaces = g_dbus_object_get_interfaces(hw); for (ll = interfaces; ll != NULL; ll = ll->next) { GDBusInterface *iface = G_DBUS_INTERFACE(ll->data); g_print (" - Interface %s\n", g_dbus_interface_get_info(iface)->name); } g_list_free_full(interfaces, g_object_unref); interface = g_dbus_object_get_interface(hw, "org.gnome.RemoteControlManager.Device"); if (!interface) return; object = RCDEVICE(interface); error = rcdevice_get_error(object); if (error && strlen(error) == 0) error = NULL; printf("Name: %s, Desc: %s, Driver: %s, Kernel keymap: %s, HW: %s, error %s\n", rcdevice_get_sys_name(object), rcdevice_get_description(object), rcdevice_get_driver_name(object), rcdevice_get_kernel_keymap_name(object), rcdevice_get_hardware_type(object), rcdevice_get_error(object)); row = gtk_list_box_row_new(); g_object_set_data_full(G_OBJECT(row), "rcdev", rcdevice_dup_sys_name(object), g_free); if (error) g_object_set_data_full(G_OBJECT(row), "error", rcdevice_dup_error(object), g_free); box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); gtk_widget_set_margin_top(box, 6); gtk_widget_set_margin_bottom(box, 6); gtk_widget_set_margin_start(box, 12); gtk_widget_set_margin_end(box, 12); icon = gtk_image_new_from_icon_name("input-dialpad-symbolic", GTK_ICON_SIZE_MENU); gtk_widget_set_valign(icon, GTK_ALIGN_CENTER); gtk_widget_set_halign(icon, GTK_ALIGN_START); gtk_box_pack_start(GTK_BOX(box), icon, FALSE, FALSE, 0); const char *dev_name = rcdevice_get_sys_name(object); const char *dev_desc = rcdevice_get_description(object); if (dev_desc && strlen(dev_desc) < 1) dev_desc = NULL; if (error) { labeltxt = g_markup_printf_escaped("%s%s%s", dev_name, dev_desc ? ": " : "", dev_desc ? dev_desc : ""); gtk_widget_set_tooltip_text(row, error); } else labeltxt = g_markup_printf_escaped("%s: %s", dev_name, dev_desc); label = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(label), labeltxt); g_free(labeltxt); gtk_widget_set_valign(label, GTK_ALIGN_CENTER); gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); button = gtk_button_new_from_icon_name("dialog-information-symbolic", GTK_ICON_SIZE_MENU); gtk_widget_set_valign(button, GTK_ALIGN_CENTER); gtk_widget_set_halign(button, GTK_ALIGN_END); g_signal_connect(button, "clicked", G_CALLBACK(hardware_properties_cb), object); gtk_widget_set_sensitive(button, error ? false : true); gtk_box_pack_end(GTK_BOX(box), button, FALSE, FALSE, 0); button = gtk_button_new_from_icon_name("accessories-calculator-symbolic", GTK_ICON_SIZE_MENU); gtk_widget_set_valign(button, GTK_ALIGN_CENTER); gtk_widget_set_halign(button, GTK_ALIGN_END); g_signal_connect(button, "clicked", G_CALLBACK(edit_keymaps_cb), hw); gtk_widget_set_sensitive(button, error ? false : true); gtk_box_pack_end(GTK_BOX(box), button, FALSE, FALSE, 0); gtk_container_add(GTK_CONTAINER(row), box); gtk_widget_show_all(row); hw_list_swin = GTK_WIDGET(gtk_builder_get_object(global->builder, "hardware_page_swin")); for (hw_list_box = gtk_bin_get_child(GTK_BIN(hw_list_swin)); hw_list_box && !GTK_IS_LIST_BOX(hw_list_box); hw_list_box = gtk_bin_get_child(GTK_BIN(hw_list_box))) /* Do nothing */; if (!hw_list_box) { hw_list_box = gtk_list_box_new(); g_signal_connect(hw_list_box, "row-selected", G_CALLBACK(hw_selected_cb), object); gtk_list_box_set_sort_func(GTK_LIST_BOX(hw_list_box), rcdev_sort, NULL, NULL); gtk_container_add(GTK_CONTAINER(hw_list_swin), hw_list_box); gtk_widget_show_all(hw_list_swin); } gtk_list_box_insert(GTK_LIST_BOX(hw_list_box), row, -1); if (!hw_list) gtk_stack_set_visible_child_name(global->stack, "hardware_page"); hwe = g_malloc(sizeof(*hwe)); hwe->hw = hw; hwe->widget = box; hw_list = g_list_append(hw_list, hwe); } void rcng_client_hardware_list_update_status(gchar *status) { GtkLabel *status_msg; status_msg = GTK_LABEL(gtk_stack_get_child_by_name(global->stack, "status_page")); gtk_label_set_text(status_msg, status); }