mirror of
https://github.com/CTCaer/RetroArch.git
synced 2025-02-05 02:58:04 +00:00
Bring up touch support for wayland subsystem for sailfish os devices
Touch code cleanup Make variabled static as suggest bparker06 C89 compilation error fix (at least for loops) More C89 fixes Signed-off-by: Wiktor Strzębała <wiktorek140@tlen.pl>
This commit is contained in:
parent
ca769b0006
commit
45799ee034
@ -28,6 +28,16 @@
|
||||
#define UDEV_KEY_MAX 0x2ff
|
||||
#define UDEV_MAX_KEYS (UDEV_KEY_MAX + 7) / 8
|
||||
|
||||
#define MAX_TOUCHES 16
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool active;
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
} wayland_touch_data_t;
|
||||
|
||||
|
||||
typedef struct input_ctx_wayland_data
|
||||
{
|
||||
/* Wayland uses Linux keysyms. */
|
||||
@ -49,6 +59,9 @@ typedef struct input_ctx_wayland_data
|
||||
|
||||
const input_device_driver_t *joypad;
|
||||
bool blocked;
|
||||
|
||||
wayland_touch_data_t touches[MAX_TOUCHES];
|
||||
|
||||
} input_ctx_wayland_data_t;
|
||||
|
||||
#endif
|
||||
|
@ -51,6 +51,19 @@
|
||||
#include "../../input/input_driver.h"
|
||||
#include "../../input/input_keymaps.h"
|
||||
|
||||
|
||||
typedef struct touch_pos
|
||||
{
|
||||
bool active;
|
||||
int32_t id;
|
||||
unsigned x;
|
||||
unsigned y;
|
||||
} touch_pos_t;
|
||||
|
||||
static int num_active_touches;
|
||||
static touch_pos_t active_touch_positions[MAX_TOUCHES];
|
||||
|
||||
|
||||
typedef struct gfx_ctx_wayland_data
|
||||
{
|
||||
#ifdef HAVE_EGL
|
||||
@ -70,6 +83,7 @@ typedef struct gfx_ctx_wayland_data
|
||||
struct wl_shell *shell;
|
||||
struct wl_keyboard *wl_keyboard;
|
||||
struct wl_pointer *wl_pointer;
|
||||
struct wl_touch *wl_touch;
|
||||
struct wl_seat *seat;
|
||||
struct wl_shm *shm;
|
||||
unsigned swap_interval;
|
||||
@ -329,8 +343,136 @@ static const struct wl_pointer_listener pointer_listener = {
|
||||
pointer_handle_axis,
|
||||
};
|
||||
|
||||
static void touch_handle_down(void *data,
|
||||
struct wl_touch *wl_touch,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
struct wl_surface *surface,
|
||||
int32_t id,
|
||||
wl_fixed_t x,
|
||||
wl_fixed_t y)
|
||||
{
|
||||
int i;
|
||||
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||
if (num_active_touches < MAX_TOUCHES)
|
||||
{
|
||||
for (i=0; i<MAX_TOUCHES; i++)
|
||||
{
|
||||
/* Use next empty slot */
|
||||
if (!active_touch_positions[i].active)
|
||||
{
|
||||
active_touch_positions[num_active_touches].active = true;
|
||||
active_touch_positions[num_active_touches].id = id;
|
||||
active_touch_positions[num_active_touches].x = (unsigned) wl_fixed_to_int(x);
|
||||
active_touch_positions[num_active_touches].y = (unsigned) wl_fixed_to_int(y);
|
||||
num_active_touches++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static void reorder_touches()
|
||||
{
|
||||
int i, j;
|
||||
if (num_active_touches == 0)
|
||||
return;
|
||||
|
||||
for (i=0; i<MAX_TOUCHES; i++)
|
||||
{
|
||||
if (!active_touch_positions[i].active)
|
||||
{
|
||||
for (j=i+1; j<MAX_TOUCHES; j++)
|
||||
{
|
||||
if (active_touch_positions[j].active)
|
||||
{
|
||||
active_touch_positions[i].active = active_touch_positions[j].active;
|
||||
active_touch_positions[i].id = active_touch_positions[j].id;
|
||||
active_touch_positions[i].x = active_touch_positions[j].x;
|
||||
active_touch_positions[i].y = active_touch_positions[j].y;
|
||||
active_touch_positions[j].active = false;
|
||||
active_touch_positions[j].id = -1;
|
||||
active_touch_positions[j].x = (unsigned) 0;
|
||||
active_touch_positions[j].y = (unsigned) 0;
|
||||
break;
|
||||
}
|
||||
if (j == MAX_TOUCHES)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static void touch_handle_up(void *data,
|
||||
struct wl_touch *wl_touch,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
int32_t id)
|
||||
{
|
||||
int i;
|
||||
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||
|
||||
for (i=0; i<MAX_TOUCHES; i++)
|
||||
{
|
||||
if (active_touch_positions[i].active && active_touch_positions[i].id == id)
|
||||
{
|
||||
active_touch_positions[i].active = false;
|
||||
active_touch_positions[i].id = -1;
|
||||
active_touch_positions[i].x = (unsigned) 0;
|
||||
active_touch_positions[i].y = (unsigned) 0;
|
||||
num_active_touches--;
|
||||
}
|
||||
}
|
||||
reorder_touches(wl);
|
||||
}
|
||||
static void touch_handle_motion(void *data,
|
||||
struct wl_touch *wl_touch,
|
||||
uint32_t time,
|
||||
int32_t id,
|
||||
wl_fixed_t x,
|
||||
wl_fixed_t y)
|
||||
{
|
||||
int i;
|
||||
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||
for (i=0; i<MAX_TOUCHES; i++)
|
||||
{
|
||||
if (active_touch_positions[i].active && active_touch_positions[i].id == id)
|
||||
{
|
||||
active_touch_positions[i].x = (unsigned) wl_fixed_to_int(x);
|
||||
active_touch_positions[i].y = (unsigned) wl_fixed_to_int(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void touch_handle_frame(void *data,
|
||||
struct wl_touch *wl_touch)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
static void touch_handle_cancel(void *data,
|
||||
struct wl_touch *wl_touch)
|
||||
{
|
||||
/* If i understand the spec correctly we have to reset all touches here
|
||||
* since they were not ment for us anyway */
|
||||
int i;
|
||||
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||
for (i=0; i<MAX_TOUCHES; i++)
|
||||
{
|
||||
active_touch_positions[i].active = false;
|
||||
active_touch_positions[i].id = -1;
|
||||
active_touch_positions[i].x = (unsigned) 0;
|
||||
active_touch_positions[i].y = (unsigned) 0;
|
||||
}
|
||||
num_active_touches = 0;
|
||||
}
|
||||
static const struct wl_touch_listener touch_listener = {
|
||||
touch_handle_down,
|
||||
touch_handle_up,
|
||||
touch_handle_motion,
|
||||
touch_handle_frame,
|
||||
touch_handle_cancel,
|
||||
};
|
||||
|
||||
|
||||
static void seat_handle_capabilities(void *data,
|
||||
struct wl_seat *seat, unsigned caps)
|
||||
struct wl_seat *seat, unsigned caps)
|
||||
{
|
||||
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||
|
||||
@ -354,6 +496,17 @@ struct wl_seat *seat, unsigned caps)
|
||||
wl_pointer_destroy(wl->wl_pointer);
|
||||
wl->wl_pointer = NULL;
|
||||
}
|
||||
if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !wl->wl_touch)
|
||||
{
|
||||
wl->wl_touch = wl_seat_get_touch(seat);
|
||||
wl_touch_add_listener(wl->wl_touch, &touch_listener, wl);
|
||||
}
|
||||
else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && wl->wl_touch)
|
||||
{
|
||||
wl_touch_destroy(wl->wl_touch);
|
||||
wl->wl_touch = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void seat_handle_name(void *data, struct wl_seat *seat, const char *name)
|
||||
@ -368,6 +521,22 @@ static const struct wl_seat_listener seat_listener = {
|
||||
seat_handle_name,
|
||||
};
|
||||
|
||||
/* Touch handle functions */
|
||||
|
||||
bool wayland_context_gettouchpos(void *data, unsigned id,
|
||||
unsigned* touch_x, unsigned* touch_y)
|
||||
{
|
||||
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||
|
||||
if (id >= MAX_TOUCHES)
|
||||
return false;
|
||||
*touch_x = active_touch_positions[id].x;
|
||||
*touch_y = active_touch_positions[id].y;
|
||||
return active_touch_positions[id].active;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Shell surface callbacks. */
|
||||
static void shell_surface_handle_ping(void *data,
|
||||
struct wl_shell_surface *shell_surface,
|
||||
@ -503,7 +672,7 @@ static void registry_handle_global(void *data, struct wl_registry *reg,
|
||||
wl->shm = (struct wl_shm*)wl_registry_bind(reg, id, &wl_shm_interface, 1);
|
||||
else if (string_is_equal(interface, "wl_seat"))
|
||||
{
|
||||
wl->seat = (struct wl_seat*)wl_registry_bind(reg, id, &wl_seat_interface, 4);
|
||||
wl->seat = (struct wl_seat*)wl_registry_bind(reg, id, &wl_seat_interface, 2);
|
||||
wl_seat_add_listener(wl->seat, &seat_listener, wl);
|
||||
}
|
||||
}
|
||||
@ -568,6 +737,8 @@ static void gfx_ctx_wl_destroy_resources(gfx_ctx_wayland_data_t *wl)
|
||||
wl_keyboard_destroy(wl->wl_keyboard);
|
||||
if (wl->wl_pointer)
|
||||
wl_pointer_destroy(wl->wl_pointer);
|
||||
if (wl->wl_touch)
|
||||
wl_touch_destroy(wl->wl_touch);
|
||||
|
||||
if (wl->cursor.theme)
|
||||
wl_cursor_theme_destroy(wl->cursor.theme);
|
||||
@ -776,6 +947,7 @@ static bool gfx_ctx_wl_get_metrics(void *data,
|
||||
|
||||
static void *gfx_ctx_wl_init(video_frame_info_t *video_info, void *video_driver)
|
||||
{
|
||||
int i;
|
||||
#ifdef HAVE_OPENGL
|
||||
static const EGLint egl_attribs_gl[] = {
|
||||
WL_EGL_ATTRIBS_BASE,
|
||||
@ -924,12 +1096,23 @@ static void *gfx_ctx_wl_init(video_frame_info_t *video_info, void *video_driver)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
wl->input.keyboard_focus = true;
|
||||
wl->input.mouse.focus = true;
|
||||
|
||||
wl->cursor.surface = wl_compositor_create_surface(wl->compositor);
|
||||
wl->cursor.theme = wl_cursor_theme_load(NULL, 16, wl->shm);
|
||||
wl->cursor.default_cursor = wl_cursor_theme_get_cursor(wl->cursor.theme, "left_ptr");
|
||||
|
||||
num_active_touches = 0;
|
||||
for (i=0;i<MAX_TOUCHES;i++)
|
||||
{
|
||||
active_touch_positions[i].active = false;
|
||||
active_touch_positions[i].id = -1;
|
||||
active_touch_positions[i].x = (unsigned) 0;
|
||||
active_touch_positions[i].y = (unsigned) 0;
|
||||
}
|
||||
|
||||
flush_wayland_fd(&wl->input);
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
|
@ -50,6 +50,7 @@
|
||||
/* TODO/FIXME -
|
||||
* fix game focus toggle */
|
||||
|
||||
|
||||
/* Forward declaration */
|
||||
|
||||
void flush_wayland_fd(void *data);
|
||||
@ -98,6 +99,32 @@ static int16_t input_wl_lightgun_state(input_ctx_wayland_data_t *wl, unsigned id
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void input_wl_touch_pool(void *data)
|
||||
{
|
||||
int id;
|
||||
input_ctx_wayland_data_t *wl = (input_ctx_wayland_data_t*)data;
|
||||
|
||||
if (!wl)
|
||||
return;
|
||||
|
||||
unsigned touch_x = 0;
|
||||
unsigned touch_y = 0;
|
||||
|
||||
for (id=0; id<MAX_TOUCHES; id++)
|
||||
{
|
||||
if (wayland_context_gettouchpos(wl, id, &touch_x, &touch_y))
|
||||
{
|
||||
wl->touches[id].active = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
wl->touches[id].active = false;
|
||||
}
|
||||
wl->touches[id].x = touch_x;
|
||||
wl->touches[id].y = touch_y;
|
||||
}
|
||||
}
|
||||
|
||||
static void input_wl_poll(void *data)
|
||||
{
|
||||
input_ctx_wayland_data_t *wl = (input_ctx_wayland_data_t*)data;
|
||||
@ -119,6 +146,8 @@ static void input_wl_poll(void *data)
|
||||
|
||||
if (wl->joypad)
|
||||
wl->joypad->poll();
|
||||
|
||||
input_wl_touch_pool(wl);
|
||||
}
|
||||
|
||||
static int16_t input_wl_analog_pressed(input_ctx_wayland_data_t *wl,
|
||||
@ -175,8 +204,9 @@ static int16_t input_wl_pointer_state(input_ctx_wayland_data_t *wl,
|
||||
vp.full_height = 0;
|
||||
|
||||
if (!(video_driver_translate_coord_viewport_wrap(&vp,
|
||||
wl->mouse.x, wl->mouse.y,
|
||||
wl->mouse.x, wl->mouse.y,
|
||||
&res_x, &res_y, &res_screen_x, &res_screen_y)))
|
||||
|
||||
return 0;
|
||||
|
||||
if (screen)
|
||||
@ -203,6 +233,59 @@ static int16_t input_wl_pointer_state(input_ctx_wayland_data_t *wl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int16_t input_wl_touch_state(input_ctx_wayland_data_t *wl,
|
||||
unsigned idx, unsigned id, bool screen)
|
||||
{
|
||||
struct video_viewport vp;
|
||||
|
||||
bool inside = false;
|
||||
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;
|
||||
|
||||
if (idx > MAX_TOUCHES)
|
||||
return 0;
|
||||
|
||||
if (!(video_driver_translate_coord_viewport_wrap(&vp,
|
||||
wl->touches[idx].x, wl->touches[idx].y,
|
||||
&res_x, &res_y, &res_screen_x, &res_screen_y)))
|
||||
return 0;
|
||||
|
||||
if (screen)
|
||||
{
|
||||
res_x = res_screen_x;
|
||||
res_y = res_screen_y;
|
||||
}
|
||||
|
||||
inside = (res_x >= -0x7fff) && (res_y >= -0x7fff);
|
||||
|
||||
if (!inside)
|
||||
return 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int16_t input_wl_state(void *data,
|
||||
rarch_joypad_info_t joypad_info,
|
||||
const struct retro_keybind **binds,
|
||||
@ -233,11 +316,15 @@ static int16_t input_wl_state(void *data,
|
||||
return input_wl_mouse_state(wl, id, true);
|
||||
|
||||
case RETRO_DEVICE_POINTER:
|
||||
case RARCH_DEVICE_POINTER_SCREEN:
|
||||
if (idx == 0)
|
||||
return input_wl_pointer_state(wl, idx, id,
|
||||
device == RARCH_DEVICE_POINTER_SCREEN);
|
||||
break;
|
||||
case RARCH_DEVICE_POINTER_SCREEN:
|
||||
if (idx < MAX_TOUCHES)
|
||||
return input_wl_touch_state(wl, idx, id,
|
||||
device == RARCH_DEVICE_POINTER_SCREEN);
|
||||
break;
|
||||
case RETRO_DEVICE_LIGHTGUN:
|
||||
return input_wl_lightgun_state(wl, id);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user