1
0
mirror of https://github.com/libretro/RetroArch synced 2024-07-08 12:15:49 +00:00

Merge keyboard files for udev/x11

This commit is contained in:
twinaphex 2017-05-20 19:44:04 +02:00
parent 188d213c8d
commit 5a9dbf7e4f
8 changed files with 147 additions and 246 deletions

View File

@ -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

View File

@ -27,10 +27,16 @@
#include "../../config.h"
#endif
#ifdef HAVE_XINERAMA
#include <X11/extensions/Xinerama.h>
#endif
#include "x11_common.h"
#include <X11/extensions/xf86vmode.h>
#include <encodings/utf.h>
#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))

View File

@ -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);

View File

@ -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

View File

@ -39,13 +39,14 @@
#include <file/file_path.h>
#include <compat/strl.h>
#include <string/stdstring.h>
#include <retro_miscellaneous.h>
#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)
{

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <retro_miscellaneous.h>
#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;
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef _KEYBOARD_DRIVER_UDEV_H
#define _KEYBOARD_DRIVER_UDEV_H
#include <linux/input.h>
#include <libudev.h>
#include <boolean.h>
#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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysymdef.h>
#include <X11/extensions/xf86vmode.h>
#include <boolean.h>
#include <retro_inline.h>
#include <encodings/utf.h>
#include <retro_miscellaneous.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#endif
#ifdef HAVE_XINERAMA
#include <X11/extensions/Xinerama.h>
#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);
}