From d1dc2e9670c7bb735a91da63eadc6b559739abcf Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 19 Jun 2017 12:34:01 +0200 Subject: [PATCH] add support for remote control devices and other ID_INPUT_KEY devices * the remote control presents itself as ID_INPUT_KEY, not ID_INPUT_KEYBOARD. However, ID_INPUT_KEYBOARD is a subset of ID_INPUT_KEY. * the remote control lacks the backspace and enter keys, which are hard coded in RetroArch. It has "back" and "ok" instead, so map those to RETROK_BACKSPACE and RETROK_ENTER as well. Remote controls also have no ESC key, but that one is customizable and I used the Power key of the remote (which already has a mapping to RETROK_POWER). The functionality provided is really the bare minimum, but it is enough to teach a kid "press the power button here to watch TV"; compared to pressing L1+R1+START+SELECT and navigating to the RetroArch's "quit" menu item, that hopefully has more chances of success. --- input/drivers/udev_input.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/input/drivers/udev_input.c b/input/drivers/udev_input.c index d797fd6a01..b6c1dea98f 100644 --- a/input/drivers/udev_input.c +++ b/input/drivers/udev_input.c @@ -140,28 +140,46 @@ int handle_xkb(int code, int value); static uint8_t udev_key_state[UDEV_MAX_KEYS]; +static unsigned input_unify_ev_key_code(unsigned code) +{ + /* input_keymaps_translate_keysym_to_rk does not support the case + where multiple keysyms translate to the same RETROK_* code, + so unify remote control keysyms to keyboard keysyms here. */ + switch (code) + { + case KEY_OK: + return KEY_ENTER; + case KEY_BACK: + return KEY_BACKSPACE; + default: + return code; + } +} + static void udev_handle_keyboard(void *data, const struct input_event *event, udev_input_device_t *dev) { #ifdef UDEV_XKB_HANDLING udev_input_t *udev = (udev_input_t*)data; #endif + unsigned keysym; switch (event->type) { case EV_KEY: + keysym = input_unify_ev_key_code(event->code); if (event->value) - BIT_SET(udev_key_state, event->code); + BIT_SET(udev_key_state, keysym); else - BIT_CLEAR(udev_key_state, event->code); + BIT_CLEAR(udev_key_state, keysym); #ifdef UDEV_XKB_HANDLING - if (udev->xkb_handling && handle_xkb(event->code, event->value) == 0) + if (udev->xkb_handling && handle_xkb(keysym, event->value) == 0) return; #endif input_keyboard_event(event->value, - input_keymaps_translate_keysym_to_rk(event->code), + input_keymaps_translate_keysym_to_rk(keysym), 0, 0, RETRO_DEVICE_KEYBOARD); break; @@ -392,7 +410,7 @@ static void udev_input_handle_hotplug(udev_input_t *udev) { device_handle_cb cb; enum udev_input_dev_type dev_type = UDEV_INPUT_KEYBOARD; - const char *val_keyboard = NULL; + const char *val_key = NULL; const char *val_mouse = NULL; const char *val_touchpad = NULL; const char *action = NULL; @@ -403,14 +421,15 @@ static void udev_input_handle_hotplug(udev_input_t *udev) if (!dev) return; - val_keyboard = udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD"); + val_key = udev_device_get_property_value(dev, "ID_INPUT_KEY"); val_mouse = udev_device_get_property_value(dev, "ID_INPUT_MOUSE"); val_touchpad = udev_device_get_property_value(dev, "ID_INPUT_TOUCHPAD"); action = udev_device_get_action(dev); devnode = udev_device_get_devnode(dev); - if (val_keyboard && string_is_equal_fast(val_keyboard, "1", 1) && devnode) + if (val_key && string_is_equal_fast(val_key, "1", 1) && devnode) { + /* EV_KEY device, can be a keyboard or a remote control device. */ dev_type = UDEV_INPUT_KEYBOARD; cb = udev_handle_keyboard; }