mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-24 08:30:16 +00:00
Merge pull request #7061 from wiktorek140/sailfishos-touch
Sailfish OS device build configuration connected with touch screen support required for device with this OS
This commit is contained in:
commit
4d96fddf5e
@ -960,6 +960,9 @@ endif
|
||||
ifeq ($(HAVE_WAYLAND), 1)
|
||||
OBJ += gfx/drivers_context/wayland_ctx.o \
|
||||
input/drivers/wayland_input.o
|
||||
ifeq ($(HAVE_EGL), 1)
|
||||
LIBS += $(EGL_LIBS)
|
||||
endif
|
||||
DEFINES += $(WAYLAND_CFLAGS) $(WAYLAND_CURSOR_CFLAGS)
|
||||
LIBS += $(WAYLAND_LIBS) $(WAYLAND_CURSOR_LIBS)
|
||||
endif
|
||||
|
@ -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);
|
||||
}
|
||||
|
87
pkg/sailfishos/retroarch-sailfishos.spec
Normal file
87
pkg/sailfishos/retroarch-sailfishos.spec
Normal file
@ -0,0 +1,87 @@
|
||||
Name: retroarch
|
||||
Version: 1.7.3
|
||||
Release: v1.2
|
||||
Summary: Official reference frontend for libretro
|
||||
|
||||
Group: Applications/Emulators
|
||||
License: GPLv3+
|
||||
URL: http://www.libretro.com/
|
||||
|
||||
BuildRequires: libxml2-devel
|
||||
BuildRequires: mesa-llvmpipe-libwayland-egl-devel
|
||||
BuildRequires: pulseaudio-devel
|
||||
BuildRequires: OpenAL-devel
|
||||
BuildRequires: libxkbcommon-devel
|
||||
BuildRequires: zlib-devel
|
||||
BuildRequires: freetype-devel
|
||||
#BuildRequires: ffmpeg-devel
|
||||
BuildRequires: SDL2-devel
|
||||
BuildRequires: SDL2_image-devel
|
||||
#Requires libusb 1.0.16
|
||||
#BuildRequires: libusb-devel
|
||||
|
||||
%description
|
||||
RetroArch is the official reference frontend for the libretro API.
|
||||
Libretro is a simple but powerful development interface that allows for the
|
||||
easy creation of emulators, games and multimedia applications that can plug
|
||||
straight into any libretro-compatible frontend. This development interface
|
||||
is open to others so that they can run these pluggable emulator and game
|
||||
cores also in their own programs or devices.
|
||||
|
||||
%build
|
||||
# No autotools, custom configure script
|
||||
%ifarch armv7hl
|
||||
./configure --prefix=%{_prefix} --enable-opengles --enable-neon --enable-egl --enable-wayland
|
||||
%else
|
||||
./configure --prefix=%{_prefix} --enable-gles
|
||||
%endif
|
||||
make %{?_smp_mflags}
|
||||
|
||||
|
||||
%install
|
||||
make install DESTDIR=%{buildroot}
|
||||
# Configuration changes
|
||||
sed -i \
|
||||
's|^# libretro_directory =.*|libretro_directory = "~/.config/retroarch/cores/"|;
|
||||
s|^# libretro_info_path =.*|libretro_info_path = "~/.config/retroarch/cores/"|;
|
||||
s|^# joypad_autoconfig_dir =.*|joypad_autoconfig_dir = "/etc/retroarch/joypad"|;
|
||||
s|^# video_fullscreen =.*|video_fullscreen = "true"|;
|
||||
s|^# menu_driver =.*|menu_driver = "glui"|;
|
||||
s|^# menu_pointer_enable =.*|menu_pointer_enable = "true"|;
|
||||
s|^# input_driver =.*|input_driver = "wayland"|' \
|
||||
%{buildroot}/etc/retroarch.cfg
|
||||
|
||||
%ifarch armv7hl
|
||||
sed -i \
|
||||
's|^# core_updater_buildbot_url =.*|core_updater_buildbot_url = "http://buildbot.libretro.com/nightly/linux/armhf/latest/"|;' \
|
||||
%{buildroot}/etc/retroarch.cfg
|
||||
%endif
|
||||
|
||||
#Disabling audio till it's fixed
|
||||
sed -i \
|
||||
's|^# audio_enable.*|audio_enable = "false"|' \
|
||||
%{buildroot}/etc/retroarch.cfg
|
||||
|
||||
sed -i \
|
||||
's|^Exec=retroarch|Exec=retroarch --menu|' \
|
||||
%{buildroot}/usr/share/applications/retroarch.desktop
|
||||
|
||||
# Install icon file in the correct place
|
||||
mkdir -p %{buildroot}/usr/share/icons/hicolor/86x86/apps
|
||||
install -m 644 "./media/retroarch-96x96.png" "%{buildroot}/usr/share/icons/hicolor/86x86/apps/retroarch.png"
|
||||
rm "%{buildroot}/usr/share/pixmaps/retroarch.svg"
|
||||
rmdir "%{buildroot}/usr/share/pixmaps"
|
||||
|
||||
%files
|
||||
%doc README.md
|
||||
%config /etc/retroarch.cfg
|
||||
%{_prefix}/bin/retroarch
|
||||
%{_prefix}/bin/retroarch-cg2glsl
|
||||
%{_prefix}/share/applications/retroarch.desktop
|
||||
%{_prefix}/share/man/man6/*.6*
|
||||
%{_prefix}/share/icons/hicolor/86x86/apps/retroarch.*
|
||||
%{_prefix}/share/doc/retroarch/*
|
||||
%changelog
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user