diff --git a/Makefile.common b/Makefile.common index 5783c2ca3f..bcd8b8804c 100644 --- a/Makefile.common +++ b/Makefile.common @@ -676,7 +676,6 @@ ifeq ($(HAVE_X11), 1) input/drivers/x11_input.o \ gfx/common/dbus_common.o \ gfx/common/x11_common.o \ - input/drivers_keyboard/keyboard_event_x11.o \ gfx/common/xinerama_common.o LIBS += $(X11_LIBS) $(XEXT_LIBS) $(XF86VM_LIBS) $(XINERAMA_LIBS) @@ -710,7 +709,6 @@ ifeq ($(HAVE_UDEV), 1) LIBS += $(UDEV_LIBS) OBJ += input/drivers/udev_input.o \ input/common/udev_common.o \ - input/drivers_keyboard/keyboard_event_udev.o \ input/drivers_joypad/udev_joypad.o endif diff --git a/gfx/common/x11_common.c b/gfx/common/x11_common.c index 76eadf3f5d..25fa1895d7 100644 --- a/gfx/common/x11_common.c +++ b/gfx/common/x11_common.c @@ -27,10 +27,16 @@ #include "../../config.h" #endif +#ifdef HAVE_XINERAMA +#include +#endif + #include "x11_common.h" #include +#include + #include "dbus_common.h" #include "../../frontend/frontend_driver.h" @@ -344,6 +350,75 @@ bool x11_get_metrics(void *data, return true; } +static void x11_handle_key_event(XEvent *event, XIC ic, bool filter) +{ + int i; + unsigned key; + uint32_t chars[32]; + uint16_t mod = 0; + unsigned state = event->xkey.state; + bool down = event->type == KeyPress; + int num = 0; + KeySym keysym = 0; + + chars[0] = '\0'; + + if (!filter) + { + if (down) + { + char keybuf[32]; + + keybuf[0] = '\0'; +#ifdef X_HAVE_UTF8_STRING + Status status = 0; + + /* XwcLookupString doesn't seem to work. */ + num = Xutf8LookupString(ic, &event->xkey, keybuf, ARRAY_SIZE(keybuf), &keysym, &status); + + /* libc functions need UTF-8 locale to work properly, + * which makes mbrtowc a bit impractical. + * + * Use custom UTF8 -> UTF-32 conversion. */ + num = utf8_conv_utf32(chars, ARRAY_SIZE(chars), keybuf, num); +#else + (void)ic; + num = XLookupString(&event->xkey, keybuf, sizeof(keybuf), &keysym, NULL); /* ASCII only. */ + for (i = 0; i < num; i++) + chars[i] = keybuf[i] & 0x7f; +#endif + } + else + keysym = XLookupKeysym(&event->xkey, (state & ShiftMask) || (state & LockMask)); + } + + /* We can't feed uppercase letters to the keycode translator. Seems like a bad idea + * to feed it keysyms anyway, so here is a little hack... */ + if (keysym >= XK_A && keysym <= XK_Z) + keysym += XK_z - XK_Z; + + key = input_keymaps_translate_keysym_to_rk(keysym); + + if (state & ShiftMask) + mod |= RETROKMOD_SHIFT; + if (state & LockMask) + mod |= RETROKMOD_CAPSLOCK; + if (state & ControlMask) + mod |= RETROKMOD_CTRL; + if (state & Mod1Mask) + mod |= RETROKMOD_ALT; + if (state & Mod4Mask) + mod |= RETROKMOD_META; + if (IsKeypadKey(keysym)) + mod |= RETROKMOD_NUMLOCK; + + input_keyboard_event(down, key, chars[0], mod, RETRO_DEVICE_KEYBOARD); + + for (i = 1; i < num; i++) + input_keyboard_event(down, RETROK_UNKNOWN, + chars[i], mod, RETRO_DEVICE_KEYBOARD); +} + bool x11_alive(void *data) { while (XPending(g_x11_dpy)) diff --git a/gfx/common/x11_common.h b/gfx/common/x11_common.h index f8e0820a82..d70f2d28c6 100644 --- a/gfx/common/x11_common.h +++ b/gfx/common/x11_common.h @@ -44,7 +44,6 @@ void x11_set_window_attr(Display *dpy, Window win); bool x11_create_input_context(Display *dpy, Window win, XIM *xim, XIC *xic); void x11_destroy_input_context(XIM *xim, XIC *xic); -void x11_handle_key_event(XEvent *event, XIC ic, bool filter); bool x11_get_metrics(void *data, enum display_metric_types type, float *value); diff --git a/griffin/griffin.c b/griffin/griffin.c index e03701ecd4..2fb08a2506 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -489,7 +489,6 @@ INPUT #ifdef HAVE_UDEV #include "../input/common/udev_common.c" #include "../input/drivers/udev_input.c" -#include "../input/drivers_keyboard/keyboard_event_udev.c" #include "../input/drivers_joypad/udev_joypad.c" #endif diff --git a/input/drivers/udev_input.c b/input/drivers/udev_input.c index ffb70d7aca..11bb42b9aa 100644 --- a/input/drivers/udev_input.c +++ b/input/drivers/udev_input.c @@ -39,13 +39,14 @@ #include #include #include +#include #include "../input_config.h" #include "../input_driver.h" #include "../input_joypad_driver.h" #include "../input_keymaps.h" +#include "../input_keyboard.h" -#include "../drivers_keyboard/keyboard_event_udev.h" #include "../../gfx/video_driver.h" #include "../common/linux_common.h" #include "../common/udev_common.h" @@ -53,16 +54,18 @@ #include "../../verbosity.h" +#define UDEV_MAX_KEYS (KEY_MAX + 7) / 8 + typedef struct udev_input udev_input_t; -typedef void (*device_handle_cb)(void *data, - const struct input_event *event, udev_input_device_t *dev); +typedef struct udev_input_device udev_input_device_t; struct udev_input_device { int fd; dev_t dev; - device_handle_cb handle_cb; + void (*handle_cb)(void *data, + const struct input_event *event, udev_input_device_t *dev); char devnode[PATH_MAX_LENGTH]; union @@ -82,6 +85,9 @@ struct udev_input_device } state; }; +typedef void (*device_handle_cb)(void *data, + const struct input_event *event, udev_input_device_t *dev); + struct udev_input { bool blocked; @@ -102,8 +108,70 @@ struct udev_input #ifdef HAVE_XKBCOMMON int init_xkb(int fd, size_t size); +void free_xkb(void); +int handle_xkb(int code, int value); #endif +static uint8_t udev_key_state[UDEV_MAX_KEYS]; + +static void udev_handle_keyboard(void *data, + const struct input_event *event, udev_input_device_t *dev) +{ + bool key_handled = false; + + switch (event->type) + { + case EV_KEY: + if (event->value) + BIT_SET(udev_key_state, event->code); + else + BIT_CLEAR(udev_key_state, event->code); + +#ifdef HAVE_XKBCOMMON + if (handle_xkb(event->code, event->value) == 0) + return; +#endif + + input_keyboard_event(event->value, + input_keymaps_translate_keysym_to_rk(event->code), + 0, 0, RETRO_DEVICE_KEYBOARD); + break; + + default: + break; + } +} + +static bool udev_input_is_pressed(const struct retro_keybind *binds, unsigned id) +{ + if (id < RARCH_BIND_LIST_END) + { + const struct retro_keybind *bind = &binds[id]; + unsigned bit = input_keymaps_translate_rk_to_keysym(binds[id].key); + return BIT_GET(udev_key_state, bit); + } + return false; +} + +static bool udev_input_state_kb(void *data, const struct retro_keybind **binds, + unsigned port, unsigned device, unsigned idx, unsigned id) +{ + unsigned bit = input_keymaps_translate_rk_to_keysym((enum retro_key)id); + return id < RETROK_LAST && BIT_GET(udev_key_state, bit); +} + +static void udev_input_kb_free(void) +{ + unsigned i; + +#ifdef HAVE_XKBCOMMON + free_xkb(); +#endif + + for (i = 0; i < UDEV_MAX_KEYS; i++) + udev_key_state[i] = 0; +} + static void udev_handle_touchpad(void *data, const struct input_event *event, udev_input_device_t *dev) { diff --git a/input/drivers_keyboard/keyboard_event_udev.c b/input/drivers_keyboard/keyboard_event_udev.c deleted file mode 100644 index 99a885fa9c..0000000000 --- a/input/drivers_keyboard/keyboard_event_udev.c +++ /dev/null @@ -1,94 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2011-2017 - Daniel De Matteis - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . - */ - -#include - -#ifdef HAVE_CONFIG_H -#include "../../config.h" -#endif - -#include "../input_keymaps.h" -#include "../input_keyboard.h" -#include "../../driver.h" - -#include "keyboard_event_udev.h" - -#define UDEV_MAX_KEYS (KEY_MAX + 7) / 8 - -static uint8_t udev_key_state[UDEV_MAX_KEYS]; - -#ifdef HAVE_XKBCOMMON -void free_xkb(void); - -int handle_xkb(int code, int value); -#endif - -void udev_handle_keyboard(void *data, - const struct input_event *event, udev_input_device_t *dev) -{ - bool key_handled = false; - - switch (event->type) - { - case EV_KEY: - if (event->value) - BIT_SET(udev_key_state, event->code); - else - BIT_CLEAR(udev_key_state, event->code); - -#ifdef HAVE_XKBCOMMON - if (handle_xkb(event->code, event->value) == 0) - return; -#endif - - input_keyboard_event(event->value, - input_keymaps_translate_keysym_to_rk(event->code), - 0, 0, RETRO_DEVICE_KEYBOARD); - break; - - default: - break; - } -} - -bool udev_input_is_pressed(const struct retro_keybind *binds, unsigned id) -{ - if (id < RARCH_BIND_LIST_END) - { - const struct retro_keybind *bind = &binds[id]; - unsigned bit = input_keymaps_translate_rk_to_keysym(binds[id].key); - return BIT_GET(udev_key_state, bit); - } - return false; -} - -bool udev_input_state_kb(void *data, const struct retro_keybind **binds, - unsigned port, unsigned device, unsigned idx, unsigned id) -{ - unsigned bit = input_keymaps_translate_rk_to_keysym((enum retro_key)id); - return id < RETROK_LAST && BIT_GET(udev_key_state, bit); -} - -void udev_input_kb_free(void) -{ - unsigned i; - -#ifdef HAVE_XKBCOMMON - free_xkb(); -#endif - - for (i = 0; i < UDEV_MAX_KEYS; i++) - udev_key_state[i] = 0; -} diff --git a/input/drivers_keyboard/keyboard_event_udev.h b/input/drivers_keyboard/keyboard_event_udev.h deleted file mode 100644 index 7dff10eaf9..0000000000 --- a/input/drivers_keyboard/keyboard_event_udev.h +++ /dev/null @@ -1,38 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2011-2017 - Daniel De Matteis - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . - */ - -#ifndef _KEYBOARD_DRIVER_UDEV_H -#define _KEYBOARD_DRIVER_UDEV_H - -#include -#include - -#include - -#include "../input_driver.h" - -typedef struct udev_input_device udev_input_device_t; - -void udev_handle_keyboard(void *data, - const struct input_event *event, udev_input_device_t *dev); - -bool udev_input_is_pressed(const struct retro_keybind *binds, unsigned id); - -bool udev_input_state_kb(void *data, const struct retro_keybind **binds, - unsigned port, unsigned device, unsigned idx, unsigned id); - -void udev_input_kb_free(void); - -#endif diff --git a/input/drivers_keyboard/keyboard_event_x11.c b/input/drivers_keyboard/keyboard_event_x11.c deleted file mode 100644 index 00b4f6056c..0000000000 --- a/input/drivers_keyboard/keyboard_event_x11.c +++ /dev/null @@ -1,106 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * Copyright (C) 2011-2017 - Daniel De Matteis - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef HAVE_CONFIG_H -#include "../../config.h" -#endif - -#ifdef HAVE_XINERAMA -#include -#endif - -#include "../input_keyboard.h" -#include "../input_keymaps.h" - -void x11_handle_key_event(XEvent *event, XIC ic, bool filter) -{ - int i; - unsigned key; - unsigned state = event->xkey.state; - uint16_t mod = 0; - uint32_t chars[32]; - - bool down = event->type == KeyPress; - int num = 0; - KeySym keysym = 0; - - chars[0] = '\0'; - - if (!filter) - { - if (down) - { - char keybuf[32]; - - keybuf[0] = '\0'; -#ifdef X_HAVE_UTF8_STRING - Status status = 0; - - /* XwcLookupString doesn't seem to work. */ - num = Xutf8LookupString(ic, &event->xkey, keybuf, ARRAY_SIZE(keybuf), &keysym, &status); - - /* libc functions need UTF-8 locale to work properly, - * which makes mbrtowc a bit impractical. - * - * Use custom UTF8 -> UTF-32 conversion. */ - num = utf8_conv_utf32(chars, ARRAY_SIZE(chars), keybuf, num); -#else - (void)ic; - num = XLookupString(&event->xkey, keybuf, sizeof(keybuf), &keysym, NULL); /* ASCII only. */ - for (i = 0; i < num; i++) - chars[i] = keybuf[i] & 0x7f; -#endif - } - else - keysym = XLookupKeysym(&event->xkey, (state & ShiftMask) || (state & LockMask)); - } - - /* We can't feed uppercase letters to the keycode translator. Seems like a bad idea - * to feed it keysyms anyway, so here is a little hack... */ - if (keysym >= XK_A && keysym <= XK_Z) - keysym += XK_z - XK_Z; - - key = input_keymaps_translate_keysym_to_rk(keysym); - - if (state & ShiftMask) - mod |= RETROKMOD_SHIFT; - if (state & LockMask) - mod |= RETROKMOD_CAPSLOCK; - if (state & ControlMask) - mod |= RETROKMOD_CTRL; - if (state & Mod1Mask) - mod |= RETROKMOD_ALT; - if (state & Mod4Mask) - mod |= RETROKMOD_META; - if (IsKeypadKey(keysym)) - mod |= RETROKMOD_NUMLOCK; - - input_keyboard_event(down, key, chars[0], mod, RETRO_DEVICE_KEYBOARD); - - for (i = 1; i < num; i++) - input_keyboard_event(down, RETROK_UNKNOWN, - chars[i], mod, RETRO_DEVICE_KEYBOARD); -}