mirror of
https://github.com/libretro/RetroArch
synced 2025-02-05 06:40:07 +00:00
Input sanitization, wayland enhancement and overlay (#17308)
Adapt the sanitized pointer handling, discussed at #17196 : Overlay "driver" specific changes: - make sure pointer position is always within [-0x7fff,0x7fff] by using the confined wrapper - enable pointer offscreen query - report -0x8000 for lightgun if pointer is at the edge - align lightgun offscreen reporting and button ID conversion with other drivers Android driver specific changes: - make sure pointer position is always within [-0x7fff,0x7fff] by using the confined wrapper - remove extra "inside" checks, general simplification - enable pointer offscreen reporting - report same value for all ports when querying mouse and lightgun - fill missing lightgun support, with fixed button map Udev and X11 driver specific changes: - simulate max. 3 touches instead of 1 using different mouse buttons Wayland driver specific changes: - integrate touch input better to the overall handling (enabling overlay usage with mouse) - simulate max. 3 touches instead of 1 using different mouse buttons
This commit is contained in:
parent
9ffb458626
commit
fe1575bc54
@ -115,6 +115,7 @@ typedef struct
|
||||
struct input_pointer
|
||||
{
|
||||
int16_t x, y;
|
||||
int16_t confined_x, confined_y;
|
||||
int16_t full_x, full_y;
|
||||
};
|
||||
|
||||
@ -818,16 +819,20 @@ static INLINE void android_input_poll_event_type_motion(
|
||||
|
||||
for (motion_ptr = 0; motion_ptr < pointer_max; motion_ptr++)
|
||||
{
|
||||
struct video_viewport vp;
|
||||
struct video_viewport vp = {0};
|
||||
float x = AMotionEvent_getX(event, motion_ptr);
|
||||
float y = AMotionEvent_getY(event, motion_ptr);
|
||||
|
||||
vp.x = 0;
|
||||
vp.y = 0;
|
||||
vp.width = 0;
|
||||
vp.height = 0;
|
||||
vp.full_width = 0;
|
||||
vp.full_height = 0;
|
||||
/* On other platforms, pointer query uses the confined wrap function, *
|
||||
* but some extra functionality is added to Android which needs the *
|
||||
* true offscreen value -0x8000, so both variants are called. */
|
||||
video_driver_translate_coord_viewport_confined_wrap(
|
||||
&vp,
|
||||
x, y,
|
||||
&android->pointer[motion_ptr].confined_x,
|
||||
&android->pointer[motion_ptr].confined_y,
|
||||
&android->pointer[motion_ptr].full_x,
|
||||
&android->pointer[motion_ptr].full_y);
|
||||
|
||||
video_driver_translate_coord_viewport_wrap(
|
||||
&vp,
|
||||
@ -1733,10 +1738,8 @@ static int16_t android_input_state(
|
||||
case RETRO_DEVICE_MOUSE:
|
||||
case RARCH_DEVICE_MOUSE_SCREEN:
|
||||
{
|
||||
/* Same mouse state is reported for all ports. */
|
||||
int val = 0;
|
||||
if (port > 0)
|
||||
break; /* TODO: implement mouse for additional ports/players */
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case RETRO_DEVICE_ID_MOUSE_LEFT:
|
||||
@ -1774,11 +1777,15 @@ static int16_t android_input_state(
|
||||
break;
|
||||
case RETRO_DEVICE_LIGHTGUN:
|
||||
{
|
||||
/* Same lightgun state is reported for all ports. */
|
||||
int val = 0;
|
||||
if (port > 0)
|
||||
break; /* TODO: implement lightgun for additional ports/players */
|
||||
switch (id)
|
||||
{
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X:
|
||||
return android->pointer[idx].x;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y:
|
||||
return android->pointer[idx].y;
|
||||
/* Deprecated relative lightgun. */
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_X:
|
||||
val = android->mouse_x_delta;
|
||||
android->mouse_x_delta = 0;
|
||||
@ -1789,32 +1796,36 @@ static int16_t android_input_state(
|
||||
android->mouse_y_delta = 0;
|
||||
/* flush delta after it has been read */
|
||||
return val;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER:
|
||||
return android->mouse_l || android_check_quick_tap(android);
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_CURSOR:
|
||||
return android->mouse_m;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_TURBO:
|
||||
return android->mouse_r;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_RELOAD:
|
||||
return android->mouse_m || android->pointer_count == 3;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_SELECT:
|
||||
return android->mouse_r && android->mouse_l;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_START:
|
||||
return android->mouse_m && android->mouse_r;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_PAUSE:
|
||||
return android->mouse_m && android->mouse_l;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_TURBO:
|
||||
return android->mouse_r || android->pointer_count == 2;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER:
|
||||
return android->mouse_l || android_check_quick_tap(android) || android->pointer_count == 1;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN:
|
||||
return input_driver_pointer_is_offscreen(android->pointer[idx].x, android->pointer[idx].y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RETRO_DEVICE_POINTER:
|
||||
case RARCH_DEVICE_POINTER_SCREEN:
|
||||
/* Same pointer state is reported for all ports. */
|
||||
switch (id)
|
||||
{
|
||||
case RETRO_DEVICE_ID_POINTER_X:
|
||||
if (device == RARCH_DEVICE_POINTER_SCREEN)
|
||||
return android->pointer[idx].full_x;
|
||||
return android->pointer[idx].x;
|
||||
return android->pointer[idx].confined_x;
|
||||
case RETRO_DEVICE_ID_POINTER_Y:
|
||||
if (device == RARCH_DEVICE_POINTER_SCREEN)
|
||||
return android->pointer[idx].full_y;
|
||||
return android->pointer[idx].y;
|
||||
return android->pointer[idx].confined_y;
|
||||
case RETRO_DEVICE_ID_POINTER_PRESSED:
|
||||
/* On mobile platforms, touches outside screen / core viewport are not reported. */
|
||||
if (device == RARCH_DEVICE_POINTER_SCREEN)
|
||||
return (idx < android->pointer_count) &&
|
||||
(android->pointer[idx].full_x != -0x8000) &&
|
||||
@ -1822,6 +1833,8 @@ static int16_t android_input_state(
|
||||
return (idx < android->pointer_count) &&
|
||||
(android->pointer[idx].x != -0x8000) &&
|
||||
(android->pointer[idx].y != -0x8000);
|
||||
case RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN:
|
||||
return input_driver_pointer_is_offscreen(android->pointer[idx].x, android->pointer[idx].y);
|
||||
case RETRO_DEVICE_ID_POINTER_COUNT:
|
||||
return android->pointer_count;
|
||||
case RARCH_DEVICE_ID_POINTER_BACK:
|
||||
|
@ -3685,7 +3685,7 @@ static bool udev_mouse_button_pressed(
|
||||
}
|
||||
|
||||
static int16_t udev_pointer_state(udev_input_t *udev,
|
||||
unsigned port, unsigned id, bool screen)
|
||||
unsigned port, unsigned idx, unsigned id, bool screen)
|
||||
{
|
||||
udev_input_mouse_t *mouse = udev_get_mouse(udev, port);
|
||||
int16_t res_x;
|
||||
@ -3701,8 +3701,19 @@ static int16_t udev_pointer_state(udev_input_t *udev,
|
||||
return res_y;
|
||||
case RETRO_DEVICE_ID_POINTER_PRESSED:
|
||||
if (mouse->abs == 1)
|
||||
return mouse->pp;
|
||||
return mouse->l;
|
||||
{
|
||||
if (idx == 0)
|
||||
return mouse->pp;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
/* Simulate max. 3 touches with mouse buttons*/
|
||||
else if (idx == 0)
|
||||
return (mouse->l | mouse->r | mouse->m);
|
||||
else if (idx == 1)
|
||||
return (mouse->r | mouse->m);
|
||||
else if (idx == 2)
|
||||
return mouse->m;
|
||||
case RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN:
|
||||
return input_driver_pointer_is_offscreen(res_x, res_y);
|
||||
}
|
||||
@ -3828,8 +3839,8 @@ static int16_t udev_input_state(
|
||||
return udev_input_touch_state(udev, pointer_dev, binds,
|
||||
keyboard_mapping_blocked, port, device, idx, id);
|
||||
#endif
|
||||
if (idx == 0) /* multi-touch unsupported (for now) */
|
||||
return udev_pointer_state(udev, port, id,
|
||||
if (idx < 3)
|
||||
return udev_pointer_state(udev, port, idx, id,
|
||||
device == RARCH_DEVICE_POINTER_SCREEN);
|
||||
break;
|
||||
|
||||
|
@ -109,18 +109,16 @@ static int16_t input_wl_touch_state(input_ctx_wayland_data_t *wl,
|
||||
{
|
||||
if (idx <= MAX_TOUCHES)
|
||||
{
|
||||
struct video_viewport vp;
|
||||
struct video_viewport vp = {0};
|
||||
int16_t res_x = 0;
|
||||
int16_t res_y = 0;
|
||||
int16_t res_screen_x = 0;
|
||||
int16_t res_screen_y = 0;
|
||||
|
||||
vp.x = 0;
|
||||
vp.y = 0;
|
||||
vp.width = 0;
|
||||
vp.height = 0;
|
||||
vp.full_width = 0;
|
||||
vp.full_height = 0;
|
||||
/* Shortcut: mouse button events will be reported on desktop with 0/0 coordinates. *
|
||||
* Skip these, mouse handling will catch it elsewhere. */
|
||||
if (wl->touches[idx].x == 0 && wl->touches[idx].y == 0)
|
||||
return 0;
|
||||
|
||||
if (video_driver_translate_coord_viewport_confined_wrap(&vp,
|
||||
wl->touches[idx].x, wl->touches[idx].y,
|
||||
@ -132,17 +130,14 @@ static int16_t input_wl_touch_state(input_ctx_wayland_data_t *wl,
|
||||
res_y = res_screen_y;
|
||||
}
|
||||
|
||||
if ((res_x >= -0x7fff) && (res_y >= -0x7fff)) /* Inside? */
|
||||
switch (id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case RETRO_DEVICE_ID_POINTER_X:
|
||||
return res_x;
|
||||
case RETRO_DEVICE_ID_POINTER_Y:
|
||||
return res_y;
|
||||
case RETRO_DEVICE_ID_POINTER_PRESSED:
|
||||
return wl->touches[idx].active;
|
||||
}
|
||||
case RETRO_DEVICE_ID_POINTER_X:
|
||||
return res_x;
|
||||
case RETRO_DEVICE_ID_POINTER_Y:
|
||||
return res_y;
|
||||
case RETRO_DEVICE_ID_POINTER_PRESSED:
|
||||
return wl->touches[idx].active;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -301,8 +296,18 @@ static int16_t input_wl_state(
|
||||
}
|
||||
break;
|
||||
case RETRO_DEVICE_POINTER:
|
||||
case RARCH_DEVICE_POINTER_SCREEN:
|
||||
/* All ports report the same pointer state. See notes at mouse case. */
|
||||
if (idx == 0)
|
||||
if (idx < MAX_TOUCHES)
|
||||
{
|
||||
int16_t touch_state = input_wl_touch_state(wl, idx, id,
|
||||
device == RARCH_DEVICE_POINTER_SCREEN);
|
||||
/* Touch state is only reported if it is meaningful. */
|
||||
if (touch_state)
|
||||
return touch_state;
|
||||
}
|
||||
/* Fall through to system pointer emulating max. 3 touches. */
|
||||
if (idx < 3)
|
||||
{
|
||||
struct video_viewport vp = {0};
|
||||
bool screen =
|
||||
@ -329,7 +334,12 @@ static int16_t input_wl_state(
|
||||
case RETRO_DEVICE_ID_POINTER_Y:
|
||||
return res_y;
|
||||
case RETRO_DEVICE_ID_POINTER_PRESSED:
|
||||
return wl->mouse.left;
|
||||
if (idx == 0)
|
||||
return (wl->mouse.left | wl->mouse.right | wl->mouse.middle);
|
||||
else if (idx == 1)
|
||||
return (wl->mouse.right | wl->mouse.middle);
|
||||
else if (idx == 2)
|
||||
return wl->mouse.middle;
|
||||
case RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN:
|
||||
return input_driver_pointer_is_offscreen(res_x, res_y);
|
||||
default:
|
||||
@ -338,14 +348,6 @@ static int16_t input_wl_state(
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RARCH_DEVICE_POINTER_SCREEN:
|
||||
if (port == 0) /* TODO/FIXME: support pointers on additional ports */
|
||||
{
|
||||
if (idx < MAX_TOUCHES)
|
||||
return input_wl_touch_state(wl, idx, id,
|
||||
device == RARCH_DEVICE_POINTER_SCREEN);
|
||||
}
|
||||
break;
|
||||
case RETRO_DEVICE_LIGHTGUN:
|
||||
/* All ports report the same lightgun state. See notes at mouse case. */
|
||||
{
|
||||
|
@ -241,7 +241,8 @@ static int16_t x_input_state(
|
||||
break;
|
||||
case RETRO_DEVICE_POINTER:
|
||||
case RARCH_DEVICE_POINTER_SCREEN:
|
||||
if (idx == 0)
|
||||
/* Map up to 3 touches to mouse buttons. */
|
||||
if (idx < 3)
|
||||
{
|
||||
struct video_viewport vp = {0};
|
||||
bool screen =
|
||||
@ -268,7 +269,12 @@ static int16_t x_input_state(
|
||||
case RETRO_DEVICE_ID_POINTER_Y:
|
||||
return res_y;
|
||||
case RETRO_DEVICE_ID_POINTER_PRESSED:
|
||||
return x11->mouse_l;
|
||||
if (idx == 0)
|
||||
return (x11->mouse_l | x11->mouse_r | x11->mouse_m);
|
||||
else if (idx == 1)
|
||||
return (x11->mouse_r | x11->mouse_m);
|
||||
else if (idx == 2)
|
||||
return x11->mouse_m;
|
||||
case RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN:
|
||||
return input_driver_pointer_is_offscreen(res_x, res_y);
|
||||
}
|
||||
|
@ -1207,64 +1207,36 @@ static int16_t input_overlay_lightgun_state(settings_t *settings,
|
||||
|
||||
switch(id)
|
||||
{
|
||||
/* Pointer positions have been clamped earlier in input drivers, *
|
||||
* so if we want to pass true offscreen value, it must be detected */
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X:
|
||||
ptr_st->device_mask |= (1 << RETRO_DEVICE_LIGHTGUN);
|
||||
|
||||
if ( ptr_st->ptr[0].x != -0x8000
|
||||
|| settings->bools.input_overlay_lightgun_allow_offscreen)
|
||||
if ( ( ptr_st->ptr[0].x > -0x7fff && ptr_st->ptr[0].x != 0x7fff)
|
||||
|| !settings->bools.input_overlay_lightgun_allow_offscreen)
|
||||
return ptr_st->ptr[0].x;
|
||||
else if (video_driver_get_viewport_info(&vp))
|
||||
{
|
||||
edge = ((2 * vp.x * 0x7fff) / (int)vp.full_width) - 0x7fff;
|
||||
return ((ptr_st->screen_x > edge) ? 0x7fff : -0x7fff);
|
||||
}
|
||||
return -0x8000;
|
||||
else
|
||||
return -0x8000;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y:
|
||||
if ( ptr_st->ptr[0].y != -0x8000
|
||||
|| settings->bools.input_overlay_lightgun_allow_offscreen)
|
||||
if ( ( ptr_st->ptr[0].y > -0x7fff && ptr_st->ptr[0].y != 0x7fff)
|
||||
|| !settings->bools.input_overlay_lightgun_allow_offscreen)
|
||||
return ptr_st->ptr[0].y;
|
||||
else if (video_driver_get_viewport_info(&vp))
|
||||
{
|
||||
edge = ((2 * vp.y * 0x7fff) / (int)vp.full_height) - 0x7fff;
|
||||
return ((ptr_st->screen_y > edge) ? 0x7fff : -0x7fff);
|
||||
}
|
||||
return -0x8000;
|
||||
else
|
||||
return -0x8000;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN:
|
||||
return ( settings->bools.input_overlay_lightgun_allow_offscreen
|
||||
&& (ptr_st->ptr[0].x == -0x8000 || ptr_st->ptr[0].y == -0x8000));
|
||||
return input_driver_pointer_is_offscreen(ptr_st->ptr[0].x, ptr_st->ptr[0].y);
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_AUX_A:
|
||||
rarch_id = RARCH_LIGHTGUN_AUX_A;
|
||||
break;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_AUX_B:
|
||||
rarch_id = RARCH_LIGHTGUN_AUX_B;
|
||||
break;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_AUX_C:
|
||||
rarch_id = RARCH_LIGHTGUN_AUX_C;
|
||||
break;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER:
|
||||
rarch_id = RARCH_LIGHTGUN_TRIGGER;
|
||||
break;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_START:
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_PAUSE:
|
||||
rarch_id = RARCH_LIGHTGUN_START;
|
||||
break;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_SELECT:
|
||||
rarch_id = RARCH_LIGHTGUN_SELECT;
|
||||
break;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_RELOAD:
|
||||
rarch_id = RARCH_LIGHTGUN_RELOAD;
|
||||
break;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_UP:
|
||||
rarch_id = RARCH_LIGHTGUN_DPAD_UP;
|
||||
break;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_DOWN:
|
||||
rarch_id = RARCH_LIGHTGUN_DPAD_DOWN;
|
||||
break;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_LEFT:
|
||||
rarch_id = RARCH_LIGHTGUN_DPAD_LEFT;
|
||||
break;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_RIGHT:
|
||||
rarch_id = RARCH_LIGHTGUN_DPAD_RIGHT;
|
||||
rarch_id = input_driver_lightgun_id_convert(id);
|
||||
break;
|
||||
default:
|
||||
rarch_id = RARCH_BIND_LIST_END;
|
||||
@ -1294,6 +1266,8 @@ static int16_t input_overlay_pointer_state(input_overlay_t *ol,
|
||||
&& ptr_st->ptr[idx].y != -0x8000;
|
||||
case RETRO_DEVICE_ID_POINTER_COUNT:
|
||||
return ptr_st->count;
|
||||
case RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN:
|
||||
return input_driver_pointer_is_offscreen(ptr_st->ptr[idx].x, ptr_st->ptr[idx].y);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user