mirror of
https://github.com/libretro/RetroArch
synced 2025-02-19 12:41:00 +00:00
Merge keyboard files for udev/x11
This commit is contained in:
parent
188d213c8d
commit
5a9dbf7e4f
@ -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
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
@ -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
|
@ -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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user