mirror of
https://github.com/libretro/RetroArch
synced 2025-03-30 07:20:36 +00:00
Basic mouse grabbing for X11.
This commit is contained in:
parent
e42c698d22
commit
292bc36b43
@ -204,6 +204,7 @@ static const struct cmd_map map[] = {
|
||||
{ "OVERLAY_NEXT", RARCH_OVERLAY_NEXT },
|
||||
{ "DISK_EJECT_TOGGLE", RARCH_DISK_EJECT_TOGGLE },
|
||||
{ "DISK_NEXT", RARCH_DISK_NEXT },
|
||||
{ "GRAB_MOUSE_TOGGLE", RARCH_GRAB_MOUSE_TOGGLE },
|
||||
{ "MENU_TOGGLE", RARCH_MENU_TOGGLE },
|
||||
};
|
||||
|
||||
|
@ -556,8 +556,8 @@ static const bool input_autodetect_enable = true;
|
||||
#define RETRO_LBL_OVERLAY_NEXT "Next Overlay"
|
||||
#define RETRO_LBL_DISK_EJECT_TOGGLE "Disk Eject Toggle"
|
||||
#define RETRO_LBL_DISK_NEXT "Disk Swap Next"
|
||||
#define RETRO_LBL_GRAB_MOUSE_TOGGLE "Grab mouse toggle"
|
||||
#define RETRO_LBL_MENU_TOGGLE "Menu toggle"
|
||||
#define RETRO_LBL_MENU_QUICKMENU_TOGGLE "Menu quickmenu toggle"
|
||||
|
||||
// Player 1
|
||||
static const struct retro_keybind retro_keybinds_1[] = {
|
||||
@ -628,6 +628,7 @@ static const struct retro_keybind retro_keybinds_1[] = {
|
||||
{ true, RARCH_OVERLAY_NEXT, RETRO_LBL_OVERLAY_NEXT, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE },
|
||||
{ true, RARCH_DISK_EJECT_TOGGLE, RETRO_LBL_DISK_EJECT_TOGGLE, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE },
|
||||
{ true, RARCH_DISK_NEXT, RETRO_LBL_DISK_NEXT, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE },
|
||||
{ true, RARCH_GRAB_MOUSE_TOGGLE, RETRO_LBL_GRAB_MOUSE_TOGGLE, RETROK_F11, NO_BTN, 0, AXIS_NONE },
|
||||
#ifdef HAVE_RGUI
|
||||
{ true, RARCH_MENU_TOGGLE, RETRO_LBL_MENU_TOGGLE, RETROK_F1, NO_BTN, 0, AXIS_NONE },
|
||||
#endif
|
||||
|
6
driver.h
6
driver.h
@ -107,6 +107,7 @@ enum // RetroArch specific bind IDs.
|
||||
RARCH_OVERLAY_NEXT,
|
||||
RARCH_DISK_EJECT_TOGGLE,
|
||||
RARCH_DISK_NEXT,
|
||||
RARCH_GRAB_MOUSE_TOGGLE,
|
||||
|
||||
RARCH_MENU_TOGGLE,
|
||||
RARCH_MENU_QUICKMENU_TOGGLE,
|
||||
@ -298,6 +299,8 @@ typedef struct input_driver
|
||||
void (*free)(void *data);
|
||||
void (*set_keybinds)(void *data, unsigned device, unsigned port, unsigned id, unsigned keybind_action);
|
||||
const char *ident;
|
||||
|
||||
void (*grab_mouse)(void *data, bool state);
|
||||
} input_driver_t;
|
||||
|
||||
struct rarch_viewport;
|
||||
@ -332,6 +335,9 @@ typedef struct video_poke_interface
|
||||
void (*set_rgui_texture)(void *data, const void *frame);
|
||||
#endif
|
||||
void (*set_osd_msg)(void *data, const char *msg, void *userdata);
|
||||
|
||||
void (*show_mouse)(void *data, bool state);
|
||||
void (*grab_mouse_toggle)(void *data);
|
||||
} video_poke_interface_t;
|
||||
|
||||
typedef struct video_driver
|
||||
|
9
gfx/gl.c
9
gfx/gl.c
@ -2369,6 +2369,13 @@ static void gl_set_osd_msg(void *data, const char *msg, void *userdata)
|
||||
gl->font_ctx->render_msg(gl, msg, params);
|
||||
}
|
||||
|
||||
static void gl_show_mouse(void *data, bool state)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
if (gl->ctx_driver->show_mouse)
|
||||
gl->ctx_driver->show_mouse(state);
|
||||
}
|
||||
|
||||
static const video_poke_interface_t gl_poke_interface = {
|
||||
gl_set_blend,
|
||||
gl_set_filtering,
|
||||
@ -2382,6 +2389,8 @@ static const video_poke_interface_t gl_poke_interface = {
|
||||
gl_set_rgui_texture,
|
||||
#endif
|
||||
gl_set_osd_msg,
|
||||
|
||||
gl_show_mouse,
|
||||
};
|
||||
|
||||
static void gl_get_poke_interface(void *data, const video_poke_interface_t **iface)
|
||||
|
@ -551,6 +551,7 @@ static const struct str_to_bind_map str_to_bind[] = {
|
||||
{ "overlay_next", RARCH_OVERLAY_NEXT },
|
||||
{ "disk_eject_toggle", RARCH_DISK_EJECT_TOGGLE },
|
||||
{ "disk_next", RARCH_DISK_NEXT },
|
||||
{ "grab_mouse_toggle", RARCH_GRAB_MOUSE_TOGGLE },
|
||||
{ "menu_toggle", RARCH_MENU_TOGGLE },
|
||||
};
|
||||
|
||||
|
@ -37,6 +37,8 @@ typedef struct x11_input
|
||||
bool mouse_l, mouse_r, mouse_m;
|
||||
int mouse_x, mouse_y;
|
||||
int mouse_last_x, mouse_last_y;
|
||||
|
||||
bool grab_mouse;
|
||||
} x11_input_t;
|
||||
|
||||
static void *x_input_init(void)
|
||||
@ -229,6 +231,20 @@ static void x_input_poll_mouse(x11_input_t *x11)
|
||||
x11->mouse_l = mask & Button1Mask;
|
||||
x11->mouse_m = mask & Button2Mask;
|
||||
x11->mouse_r = mask & Button3Mask;
|
||||
|
||||
// Somewhat hacky, but seem to do the job.
|
||||
if (x11->grab_mouse)
|
||||
{
|
||||
struct rarch_viewport vp = {0};
|
||||
video_viewport_info_func(&vp);
|
||||
unsigned mid_w = vp.full_width >> 1;
|
||||
unsigned mid_h = vp.full_height >> 1;
|
||||
XWarpPointer(x11->display, None,
|
||||
x11->win, 0, 0, 0, 0,
|
||||
mid_w, mid_h);
|
||||
x11->mouse_last_x = mid_w;
|
||||
x11->mouse_last_y = mid_h;
|
||||
}
|
||||
}
|
||||
|
||||
static void x_input_poll(void *data)
|
||||
@ -244,6 +260,12 @@ static void x_input_poll(void *data)
|
||||
input_joypad_poll(x11->joypad);
|
||||
}
|
||||
|
||||
static void x_grab_mouse(void *data, bool state)
|
||||
{
|
||||
x11_input_t *x11 = (x11_input_t*)data;
|
||||
x11->grab_mouse = state;
|
||||
}
|
||||
|
||||
const input_driver_t input_x = {
|
||||
x_input_init,
|
||||
x_input_poll,
|
||||
@ -251,6 +273,7 @@ const input_driver_t input_x = {
|
||||
x_bind_button_pressed,
|
||||
x_input_free,
|
||||
NULL,
|
||||
"x"
|
||||
"x",
|
||||
x_grab_mouse,
|
||||
};
|
||||
|
||||
|
@ -94,6 +94,8 @@ void retro_set_video_refresh(retro_video_refresh_t cb)
|
||||
static unsigned x_coord;
|
||||
static unsigned y_coord;
|
||||
static unsigned phase;
|
||||
static int mouse_rel_x;
|
||||
static int mouse_rel_y;
|
||||
|
||||
void retro_reset(void)
|
||||
{
|
||||
@ -135,6 +137,17 @@ static void update_input(void)
|
||||
if (mouse_r)
|
||||
fprintf(stderr, "Mouse R pressed.\n");
|
||||
|
||||
mouse_rel_x += mouse_x;
|
||||
mouse_rel_y += mouse_y;
|
||||
if (mouse_rel_x >= 310)
|
||||
mouse_rel_x = 309;
|
||||
else if (mouse_rel_x < 10)
|
||||
mouse_rel_x = 10;
|
||||
if (mouse_rel_y >= 230)
|
||||
mouse_rel_y = 229;
|
||||
else if (mouse_rel_y < 10)
|
||||
mouse_rel_y = 10;
|
||||
|
||||
bool pointer_pressed = input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED);
|
||||
int16_t pointer_x = input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X);
|
||||
int16_t pointer_y = input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y);
|
||||
@ -166,6 +179,10 @@ static void render_checkered(void)
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned y = mouse_rel_y - 5; y <= mouse_rel_y + 5; y++)
|
||||
for (unsigned x = mouse_rel_x - 5; x <= mouse_rel_x + 5; x++)
|
||||
frame_buf[y * 320 + x] = 0x1f;
|
||||
|
||||
video_cb(frame_buf, 320, 240, 320 << 1);
|
||||
}
|
||||
|
||||
|
27
retroarch.c
27
retroarch.c
@ -2577,6 +2577,29 @@ static void check_overlay(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef RARCH_CONSOLE
|
||||
static void check_grab_mouse_toggle(void)
|
||||
{
|
||||
static bool old_pressed;
|
||||
bool pressed = input_key_pressed_func(RARCH_GRAB_MOUSE_TOGGLE) &&
|
||||
driver.input->grab_mouse;
|
||||
|
||||
static bool grab_mouse_state;
|
||||
|
||||
if (pressed && !old_pressed)
|
||||
{
|
||||
grab_mouse_state = !grab_mouse_state;
|
||||
RARCH_LOG("Grab mouse state: %s.\n", grab_mouse_state ? "yes" : "no");
|
||||
driver.input->grab_mouse(driver.input_data, grab_mouse_state);
|
||||
|
||||
if (driver.video_poke && driver.video_poke->show_mouse)
|
||||
driver.video_poke->show_mouse(driver.video_data, !grab_mouse_state);
|
||||
}
|
||||
|
||||
old_pressed = pressed;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void do_state_checks(void)
|
||||
{
|
||||
check_block_hotkey();
|
||||
@ -2591,6 +2614,10 @@ static void do_state_checks(void)
|
||||
|
||||
check_turbo();
|
||||
|
||||
#ifndef RARCH_CONSOLE
|
||||
check_grab_mouse_toggle();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
check_overlay();
|
||||
#endif
|
||||
|
@ -398,6 +398,11 @@
|
||||
# Toggles RGUI menu.
|
||||
# input_menu_toggle = f1
|
||||
|
||||
# Toggles mouse grab. When mouse is grabbed, RetroArch hides the mouse,
|
||||
# and keeps the mouse pointer inside the window to allow relative mouse games
|
||||
# to work better.
|
||||
# input_grab_mouse_toggle = f11
|
||||
|
||||
#### Misc
|
||||
|
||||
# Enable rewinding. This will take a performance hit when playing, so it is disabled by default.
|
||||
|
@ -840,6 +840,7 @@ static const struct bind_map bind_maps[MAX_PLAYERS][RARCH_BIND_LIST_END_NULL] =
|
||||
DECLARE_BIND(overlay_next, RARCH_OVERLAY_NEXT),
|
||||
DECLARE_BIND(disk_eject_toggle, RARCH_DISK_EJECT_TOGGLE),
|
||||
DECLARE_BIND(disk_next, RARCH_DISK_NEXT),
|
||||
DECLARE_BIND(grab_mouse_toggle, RARCH_GRAB_MOUSE_TOGGLE),
|
||||
#ifdef HAVE_RGUI
|
||||
DECLARE_BIND(menu_toggle, RARCH_MENU_TOGGLE),
|
||||
#endif
|
||||
|
@ -125,6 +125,7 @@ static struct bind binds[] = {
|
||||
MISC_BIND("Next overlay", overlay_next),
|
||||
MISC_BIND("Disk eject toggle", disk_eject_toggle),
|
||||
MISC_BIND("Disk next cycle", disk_next),
|
||||
MISC_BIND("Grab mouse toggle", grab_mouse_toggle),
|
||||
MISC_BIND("Menu toggle", menu_toggle),
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user