mirror of
https://github.com/libretro/RetroArch
synced 2025-02-20 15:40:44 +00:00
Merge pull request #72 from meancoot/master
Allow libretro core to receive keyboard input using events rather than polling.
This commit is contained in:
commit
3c5aec41a1
@ -482,6 +482,15 @@ static bool environment_cb(unsigned cmd, void *data)
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK:
|
||||
{
|
||||
const struct retro_keyboard_callback *info = (const struct retro_keyboard_callback*)data;
|
||||
|
||||
g_extern.system.key_event = info->callback;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
RARCH_LOG("Environ UNSUPPORTED (#%u).\n", cmd);
|
||||
|
@ -324,6 +324,8 @@ struct global
|
||||
bool force_nonblock;
|
||||
|
||||
const char *input_desc_btn[MAX_PLAYERS][RARCH_FIRST_CUSTOM_BIND];
|
||||
|
||||
retro_keyboard_event_t key_event;
|
||||
} system;
|
||||
|
||||
struct
|
||||
|
@ -49,6 +49,108 @@ static bool g_is_double;
|
||||
|
||||
static int (*g_pglSwapInterval)(int);
|
||||
|
||||
struct key_bind
|
||||
{
|
||||
unsigned x;
|
||||
enum retro_key sk;
|
||||
};
|
||||
|
||||
static unsigned keysym_lut[RETROK_LAST];
|
||||
|
||||
static const struct key_bind lut_binds[] = {
|
||||
{ XK_Left, RETROK_LEFT },
|
||||
{ XK_Right, RETROK_RIGHT },
|
||||
{ XK_Up, RETROK_UP },
|
||||
{ XK_Down, RETROK_DOWN },
|
||||
{ XK_Return, RETROK_RETURN },
|
||||
{ XK_Tab, RETROK_TAB },
|
||||
{ XK_Insert, RETROK_INSERT },
|
||||
{ XK_Home, RETROK_HOME },
|
||||
{ XK_End, RETROK_END },
|
||||
{ XK_Page_Up, RETROK_PAGEUP },
|
||||
{ XK_Page_Down, RETROK_PAGEDOWN },
|
||||
{ XK_Delete, RETROK_DELETE },
|
||||
{ XK_Shift_R, RETROK_RSHIFT },
|
||||
{ XK_Shift_L, RETROK_LSHIFT },
|
||||
{ XK_Control_L, RETROK_LCTRL },
|
||||
{ XK_Alt_L, RETROK_LALT },
|
||||
{ XK_space, RETROK_SPACE },
|
||||
{ XK_Escape, RETROK_ESCAPE },
|
||||
{ XK_BackSpace, RETROK_BACKSPACE },
|
||||
{ XK_KP_Enter, RETROK_KP_ENTER },
|
||||
{ XK_KP_Add, RETROK_KP_PLUS },
|
||||
{ XK_KP_Subtract, RETROK_KP_MINUS },
|
||||
{ XK_KP_Multiply, RETROK_KP_MULTIPLY },
|
||||
{ XK_KP_Divide, RETROK_KP_DIVIDE },
|
||||
{ XK_grave, RETROK_BACKQUOTE },
|
||||
{ XK_Pause, RETROK_PAUSE },
|
||||
{ XK_KP_0, RETROK_KP0 },
|
||||
{ XK_KP_1, RETROK_KP1 },
|
||||
{ XK_KP_2, RETROK_KP2 },
|
||||
{ XK_KP_3, RETROK_KP3 },
|
||||
{ XK_KP_4, RETROK_KP4 },
|
||||
{ XK_KP_5, RETROK_KP5 },
|
||||
{ XK_KP_6, RETROK_KP6 },
|
||||
{ XK_KP_7, RETROK_KP7 },
|
||||
{ XK_KP_8, RETROK_KP8 },
|
||||
{ XK_KP_9, RETROK_KP9 },
|
||||
{ XK_0, RETROK_0 },
|
||||
{ XK_1, RETROK_1 },
|
||||
{ XK_2, RETROK_2 },
|
||||
{ XK_3, RETROK_3 },
|
||||
{ XK_4, RETROK_4 },
|
||||
{ XK_5, RETROK_5 },
|
||||
{ XK_6, RETROK_6 },
|
||||
{ XK_7, RETROK_7 },
|
||||
{ XK_8, RETROK_8 },
|
||||
{ XK_9, RETROK_9 },
|
||||
{ XK_F1, RETROK_F1 },
|
||||
{ XK_F2, RETROK_F2 },
|
||||
{ XK_F3, RETROK_F3 },
|
||||
{ XK_F4, RETROK_F4 },
|
||||
{ XK_F5, RETROK_F5 },
|
||||
{ XK_F6, RETROK_F6 },
|
||||
{ XK_F7, RETROK_F7 },
|
||||
{ XK_F8, RETROK_F8 },
|
||||
{ XK_F9, RETROK_F9 },
|
||||
{ XK_F10, RETROK_F10 },
|
||||
{ XK_F11, RETROK_F11 },
|
||||
{ XK_F12, RETROK_F12 },
|
||||
{ XK_a, RETROK_a },
|
||||
{ XK_b, RETROK_b },
|
||||
{ XK_c, RETROK_c },
|
||||
{ XK_d, RETROK_d },
|
||||
{ XK_e, RETROK_e },
|
||||
{ XK_f, RETROK_f },
|
||||
{ XK_g, RETROK_g },
|
||||
{ XK_h, RETROK_h },
|
||||
{ XK_i, RETROK_i },
|
||||
{ XK_j, RETROK_j },
|
||||
{ XK_k, RETROK_k },
|
||||
{ XK_l, RETROK_l },
|
||||
{ XK_m, RETROK_m },
|
||||
{ XK_n, RETROK_n },
|
||||
{ XK_o, RETROK_o },
|
||||
{ XK_p, RETROK_p },
|
||||
{ XK_q, RETROK_q },
|
||||
{ XK_r, RETROK_r },
|
||||
{ XK_s, RETROK_s },
|
||||
{ XK_t, RETROK_t },
|
||||
{ XK_u, RETROK_u },
|
||||
{ XK_v, RETROK_v },
|
||||
{ XK_w, RETROK_w },
|
||||
{ XK_x, RETROK_x },
|
||||
{ XK_y, RETROK_y },
|
||||
{ XK_z, RETROK_z },
|
||||
};
|
||||
|
||||
static void init_lut(void)
|
||||
{
|
||||
memset(keysym_lut, 0, sizeof(keysym_lut));
|
||||
for (unsigned i = 0; i < sizeof(lut_binds) / sizeof(lut_binds[0]); i++)
|
||||
keysym_lut[lut_binds[i].sk] = lut_binds[i].x;
|
||||
}
|
||||
|
||||
static void sighandler(int sig)
|
||||
{
|
||||
(void)sig;
|
||||
@ -113,6 +215,36 @@ static void gfx_ctx_check_window(bool *quit,
|
||||
case UnmapNotify:
|
||||
g_has_focus = false;
|
||||
break;
|
||||
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
if (g_extern.system.key_event)
|
||||
{
|
||||
static XComposeStatus state;
|
||||
char keybuf[32];
|
||||
const unsigned x_keycode = XKeycodeToKeysym(g_dpy, event.xkey.keycode, 0);
|
||||
|
||||
bool down = event.type == KeyPress;
|
||||
uint32_t character = 0;
|
||||
unsigned key = RETROK_UNKNOWN;
|
||||
|
||||
for (int i = 0; i != RETROK_LAST; i ++)
|
||||
{
|
||||
if (keysym_lut[i] == x_keycode)
|
||||
{
|
||||
key = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (down && XLookupString(&event.xkey, keybuf, sizeof(keybuf), 0, &state))
|
||||
{
|
||||
character = keybuf[0];
|
||||
}
|
||||
|
||||
g_extern.system.key_event(down, key, character, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -192,6 +324,8 @@ static bool gfx_ctx_init(void)
|
||||
|
||||
g_quit = 0;
|
||||
|
||||
init_lut();
|
||||
|
||||
g_dpy = XOpenDisplay(NULL);
|
||||
if (!g_dpy)
|
||||
goto error;
|
||||
@ -249,7 +383,7 @@ static bool gfx_ctx_set_video_mode(
|
||||
|
||||
swa.colormap = g_cmap = XCreateColormap(g_dpy, RootWindow(g_dpy, vi->screen),
|
||||
vi->visual, AllocNone);
|
||||
swa.event_mask = StructureNotifyMask;
|
||||
swa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask;
|
||||
swa.override_redirect = fullscreen ? True : False;
|
||||
|
||||
if (fullscreen && !windowed_full)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
@ -70,11 +70,11 @@ static void gfx_ctx_swap_interval(unsigned interval)
|
||||
GL_SYM_WRAP(glx_swap_interval, "glXSwapInterval");
|
||||
if (!glx_swap_interval)
|
||||
GL_SYM_WRAP(glx_swap_interval, "glXSwapIntervalMESA");
|
||||
if (!glx_swap_interval)
|
||||
if (!glx_swap_interval)
|
||||
GL_SYM_WRAP(glx_swap_interval, "glXSwapIntervalSGI");
|
||||
if (glx_swap_interval)
|
||||
success = glx_swap_interval(g_interval) == 0;
|
||||
else
|
||||
else
|
||||
RARCH_WARN("Could not find GLX VSync call.\n");
|
||||
#endif
|
||||
}
|
||||
@ -118,7 +118,7 @@ static bool gfx_ctx_init(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void gfx_ctx_destroy(void)
|
||||
static void gfx_ctx_destroy(void)
|
||||
{
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||
g_inited = false;
|
||||
@ -254,6 +254,34 @@ static void gfx_ctx_check_window(bool *quit,
|
||||
*width = event.resize.w;
|
||||
*height = event.resize.h;
|
||||
break;
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
if (g_extern.system.key_event)
|
||||
{
|
||||
SDL_EnableUNICODE(true);
|
||||
|
||||
uint16_t mods = 0;
|
||||
|
||||
if (event.key.keysym.mod)
|
||||
{
|
||||
mods |= (event.key.keysym.mod & KMOD_CTRL) ? RETROKMOD_CTRL : 0;
|
||||
mods |= (event.key.keysym.mod & KMOD_ALT) ? RETROKMOD_ALT : 0;
|
||||
mods |= (event.key.keysym.mod & KMOD_SHIFT) ? RETROKMOD_SHIFT : 0;
|
||||
mods |= (event.key.keysym.mod & KMOD_META) ? RETROKMOD_META : 0;
|
||||
mods |= (event.key.keysym.mod & KMOD_NUM) ? RETROKMOD_NUMLOCK : 0;
|
||||
mods |= (event.key.keysym.mod & KMOD_CAPS) ? RETROKMOD_CAPSLOCK : 0;
|
||||
|
||||
// TODO: What is KMOD_MODE in SDL?
|
||||
mods |= (event.key.keysym.mod & KMOD_MODE) ? RETROKMOD_SCROLLOCK : 0;
|
||||
}
|
||||
|
||||
// For now it seems that all RETROK_* constant values match the SDLK_* values.
|
||||
// Ultimately the table in sdl_input.c should be used in case this changes.
|
||||
// TODO: event.key.keysym.unicode is UTF-16
|
||||
g_extern.system.key_event(event.type == SDL_KEYDOWN, event.key.keysym.sym, event.key.keysym.unicode, mods);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
32
libretro.h
32
libretro.h
@ -310,6 +310,21 @@ enum retro_key
|
||||
RETROK_LAST
|
||||
};
|
||||
|
||||
enum retro_mod
|
||||
{
|
||||
RETROKMOD_NONE = 0x0000,
|
||||
|
||||
RETROKMOD_SHIFT = 0x01,
|
||||
RETROKMOD_CTRL = 0x02,
|
||||
RETROKMOD_ALT = 0x04,
|
||||
RETROKMOD_META = 0x08,
|
||||
|
||||
RETROKMOD_NUMLOCK = 0x10,
|
||||
RETROKMOD_CAPSLOCK = 0x20,
|
||||
RETROKMOD_SCROLLOCK = 0x40
|
||||
};
|
||||
|
||||
|
||||
// Environment commands.
|
||||
#define RETRO_ENVIRONMENT_SET_ROTATION 1 // const unsigned * --
|
||||
// Sets screen rotation of graphics.
|
||||
@ -353,7 +368,7 @@ enum retro_key
|
||||
//
|
||||
// It can be used by the frontend to potentially warn
|
||||
// about too demanding implementations.
|
||||
//
|
||||
//
|
||||
// The levels are "floating", but roughly defined as:
|
||||
// 0: Low-powered embedded devices such as Raspberry Pi
|
||||
// 1: 6th generation consoles, such as Wii/Xbox 1, and phones, tablets, etc.
|
||||
@ -388,8 +403,23 @@ enum retro_key
|
||||
// It is up to the frontend to present this in a usable way.
|
||||
// The array is terminated by retro_input_descriptor::description being set to NULL.
|
||||
// This function can be called at any time, but it is recommended to call it as early as possible.
|
||||
#define RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK 12
|
||||
// const struct retro_keyboard_callback * --
|
||||
// Sets a callback function used to notify core about keyboard events.
|
||||
|
||||
|
||||
// Callback type passed in RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK. Called by the frontend in response to keyboard events.
|
||||
// down is set if the key is being pressed, or false if it is being released.
|
||||
// keycode is the RETROK value of the char.
|
||||
// character is the text character of the pressed key. (UTF-32).
|
||||
// key_modifiers is a set of RETROKMOD values or'ed together.
|
||||
typedef void (*retro_keyboard_event_t)(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers);
|
||||
|
||||
struct retro_keyboard_callback
|
||||
{
|
||||
retro_keyboard_event_t callback;
|
||||
};
|
||||
|
||||
enum retro_pixel_format
|
||||
{
|
||||
// 0RGB1555, native endian. 0 bit must be set to 0.
|
||||
|
Loading…
x
Reference in New Issue
Block a user