From dc425fc6d1c75656fc30f0afd7825274200a97fa Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Fri, 17 Jul 2015 21:29:17 +0200 Subject: Separate keymap and layout --- RemoteControlManager.xml | 1 + rcm-client-receive.c | 109 ++++++++++++++++++++++++++++++++++++----------- rcm-server-main.c | 25 +++++++++-- 3 files changed, 105 insertions(+), 30 deletions(-) diff --git a/RemoteControlManager.xml b/RemoteControlManager.xml index 1d5751d..df8f2b2 100644 --- a/RemoteControlManager.xml +++ b/RemoteControlManager.xml @@ -10,6 +10,7 @@ + diff --git a/rcm-client-receive.c b/rcm-client-receive.c index f645fd7..8f43c7a 100644 --- a/rcm-client-receive.c +++ b/rcm-client-receive.c @@ -16,6 +16,12 @@ #define WINDOW_WIDTH 300 #define WINDOW_HEIGHT 300 +struct keymap_entry { + char *protocol; + guint64 scancode; + char *keycode; +}; + struct remote { char *name; guint16 width; @@ -24,6 +30,7 @@ struct remote { GtkWidget *widget; GtkWidget *grid; GtkWidget *edit_button; + GList *keymap; }; enum rcbutton_type { @@ -217,9 +224,8 @@ edit_button_dialog(GtkButton *button, struct rcbutton *rcb) GtkWidget *comment_label; GtkWidget *comment_entry; gint r; + GList *ke; unsigned i; - /* FIXME: Get keymap and use keycodes from there */ - const char *keycodes[] = { "KEY_VIDEO", "KEY_TV", "KEY_OK", NULL }; dialog = gtk_dialog_new_with_buttons("Edit Button", parent, GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, @@ -241,10 +247,12 @@ edit_button_dialog(GtkButton *button, struct rcbutton *rcb) gtk_widget_set_halign(keycode_label, GTK_ALIGN_START); keycode_cbox = gtk_combo_box_text_new(); - for (i = 0; keycodes[i]; i++) { + for (ke = rcb->remote->keymap, i = 0; ke; ke = ke->next, i++) { + struct keymap_entry *entry = ke->data; + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(keycode_cbox), - NULL, keycodes[i]); - if (rcb->name && !strcmp(rcb->name, keycodes[i])) + NULL, entry->keycode); + if (rcb->name && !strcmp(rcb->name, entry->keycode)) gtk_combo_box_set_active(GTK_COMBO_BOX(keycode_cbox), i); } gtk_grid_attach(GTK_GRID(grid), keycode_label, 1, 1, 1, 1); @@ -686,23 +694,18 @@ static struct remote * get_keymap(RCDevice *object, const gchar *keymap_name) { struct remote *remote; - GVariant *km_entries = NULL; + GVariant *keymap_entries = NULL; + GVariant *layout_entries = NULL; remote = g_malloc0(sizeof(*remote)); remote->name = strdup(keymap_name); rcdevice_call_get_keymap_sync(object, keymap_name, &remote->width, - &remote->height, &km_entries, NULL, NULL); + &remote->height, &keymap_entries, + &layout_entries, NULL, NULL); - g_print("type of keymaps is %s\n", g_variant_get_type_string(km_entries)); - GVariantIter iter; - gsize n_items; - GVariant *item; - - n_items = g_variant_iter_init(&iter, km_entries); - g_print("Key items: %zu\n", n_items); - guint row = 0; - guint col = 0; + g_assert(g_variant_is_of_type(keymap_entries, G_VARIANT_TYPE("aa{sv}"))); + g_assert(g_variant_is_of_type(layout_entries, G_VARIANT_TYPE("aa{sv}"))); GtkWidget *fixed; fixed = gtk_fixed_new(); @@ -725,30 +728,85 @@ get_keymap(RCDevice *object, const gchar *keymap_name) gtk_container_set_border_width(GTK_CONTAINER(grid), 12); remote->grid = grid; + GVariantIter iter; + gsize n_items; + GVariant *item; + + n_items = g_variant_iter_init(&iter, keymap_entries); + g_print("Keymap items: %zu\n", n_items); while (g_variant_iter_loop (&iter, "@a{sv}", &item)) { - gchar *type; gchar *protocol; guint64 scancode; gchar *keycode; + struct keymap_entry *entry; - g_variant_lookup(item, "type", "s", &type); g_variant_lookup(item, "protocol", "s", &protocol); g_variant_lookup(item, "scancode", "t", &scancode); g_variant_lookup(item, "keycode", "s", &keycode); + entry = g_malloc0(sizeof(*entry)); + entry->protocol = protocol; + entry->scancode = scancode; + entry->keycode = keycode; + remote->keymap = g_list_prepend(remote->keymap, entry); + } + + n_items = g_variant_iter_init(&iter, layout_entries); + g_print("Layout items: %zu\n", n_items); + guint row = 0; + guint col = 0; + while (g_variant_iter_loop (&iter, "@a{sv}", &item)) { + gchar *type; + struct keymap_entry *keymap_entry; + + g_variant_lookup(item, "type", "s", &type); + if (!strcmp(type, "button")) { + GList *k; + gchar *keycode; + + g_variant_lookup(item, "keycode", "s", &keycode); + + for (k = remote->keymap; k; k = k->next) { + struct keymap_entry *tmp = k->data; + + if (!strcmp(keycode, tmp->keycode)) + break; + } + + if (k) + keymap_entry = k->data; + else + keymap_entry = NULL; + + } else if (!strcmp(type, "blank")) { + printf("Got a blank\n"); + keymap_entry = NULL; + + } else { + printf("Error: unknown type: %s (treating as blank)\n", type); + keymap_entry = NULL; + } + + if (keymap_entry) { struct rcbutton *rcb; - rcb = new_button_add(remote, protocol, scancode, - keycode, col, row); + + rcb = new_button_add(remote, + keymap_entry->protocol, + keymap_entry->scancode, + keymap_entry->keycode, + col, row); remote->buttons = g_list_append(remote->buttons, rcb); - printf("Got a button: %s:0x%08" PRIx64 ":%s\n", protocol, scancode, keycode); - } else if (!strcmp(type, "blank")) { + printf("Got a button: %s:0x%08" PRIx64 ":%s\n", + keymap_entry->protocol, keymap_entry->scancode, + keymap_entry->keycode); + + } else { struct rcbutton *rcb; + rcb = new_blank_add(remote, col, row); remote->buttons = g_list_append(remote->buttons, rcb); - printf("Got a blank\n"); - } else - printf("Error: unknown type: %s (treating as blank)\n", type); + } col++; if (col >= remote->width) { @@ -777,7 +835,6 @@ void rcng_client_receive_init_ui(GDBusObject *new_hw) rcng_client_receive_destroy_ui(); - /* FIXME: if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a(uuuuaa{sv}))"))) */ scrollda = gtk_scrolled_window_new(NULL, NULL); gtk_container_set_border_width(GTK_CONTAINER(scrollda), 12); own_page_num = gtk_notebook_append_page(global->notebook, scrollda, gtk_label_new("Receive")); diff --git a/rcm-server-main.c b/rcm-server-main.c index 8ec3140..572d5c9 100644 --- a/rcm-server-main.c +++ b/rcm-server-main.c @@ -135,6 +135,25 @@ method_getkeymap(sd_bus_message *m, void *userdata, sd_bus_error *error) if (r < 0) goto out; + /* Keymap */ + r = sd_bus_message_open_container(reply, 'a', "a{sv}"); + if (r < 0) + goto out; + + for (i = 0; i < keymap->keycode_count; i++) { + r = sd_bus_message_append(reply, "a{sv}", 3, + "protocol", "s", keymap->keycodes[i].protocol, + "scancode", "t", keymap->keycodes[i].scancode, + "keycode", "s", keymap->keycodes[i].keycode); + if (r < 0) + goto out; + } + + r = sd_bus_message_close_container(reply); + if (r < 0) + goto out; + + /* Layout */ r = sd_bus_message_open_container(reply, 'a', "a{sv}"); if (r < 0) goto out; @@ -144,10 +163,8 @@ method_getkeymap(sd_bus_message *m, void *userdata, sd_bus_error *error) r = sd_bus_message_append(reply, "a{sv}", 1, "type", "s", "blank"); else - r = sd_bus_message_append(reply, "a{sv}", 4, + r = sd_bus_message_append(reply, "a{sv}", 2, "type", "s", "button", - "protocol", "s", keymap->layout[i]->protocol, - "scancode", "t", keymap->layout[i]->scancode, "keycode", "s", keymap->layout[i]->keycode); if (r < 0) goto out; @@ -173,7 +190,7 @@ static const sd_bus_vtable device_vtable[] = { SD_BUS_PROPERTY("KernelKeymapName", "s", property_get, 0, 0), SD_BUS_PROPERTY("HardwareType", "s", property_get, 0, 0), SD_BUS_METHOD("ListKeymaps", NULL, "as", method_listkeymaps, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("GetKeymap", "s", "qqaa{sv}", method_getkeymap, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("GetKeymap", "s", "qqaa{sv}aa{sv}", method_getkeymap, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_SIGNAL("KeyPressed", "s", 0), SD_BUS_SIGNAL("KeyReleased", "s", 0), SD_BUS_VTABLE_END -- cgit v1.2.3