Basic mouse grabbing for X11.

This commit is contained in:
Themaister 2013-03-29 18:53:07 +01:00
parent e42c698d22
commit 292bc36b43
11 changed files with 94 additions and 2 deletions

View File

@ -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 },
};

View File

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

View File

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

View File

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

View File

@ -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 },
};

View File

@ -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,
};

View File

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

View File

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

View File

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

View File

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

View File

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