From 9e24385ebae1f6abbc5a04fe9111df8c0704b37a Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 23 Sep 2024 02:47:07 +0300 Subject: [PATCH] SAILFISH: New port for SailfishOS Still has some issues documented in README.md but is already playable --- backends/platform/sdl/module.mk | 7 + backends/platform/sdl/posix/posix-main.cpp | 2 +- backends/platform/sdl/sailfish/README.md | 48 +++ .../sdl/sailfish/rpm/org.scummvm.scummvm.spec | 276 +++++++++++++++++ .../sdl/sailfish/sailfish-download.sh | 10 + .../platform/sdl/sailfish/sailfish-main.cpp | 45 +++ .../platform/sdl/sailfish/sailfish-window.cpp | 38 +++ .../platform/sdl/sailfish/sailfish-window.h | 32 ++ backends/platform/sdl/sailfish/sailfish.cpp | 144 +++++++++ backends/platform/sdl/sailfish/sailfish.h | 41 +++ ...-wayland-Bring-back-wl_shell-support.patch | 288 ++++++++++++++++++ .../sailfish/sdl-patches/0002-wlcancel.patch | 49 +++ backends/platform/sdl/sdl-window.h | 2 +- configure | 68 ++++- dists/sailfish/108x108.png | Bin 0 -> 6270 bytes dists/sailfish/128x128.png | Bin 0 -> 7555 bytes dists/sailfish/172x172.png | Bin 0 -> 10229 bytes dists/sailfish/86x86.png | Bin 0 -> 4908 bytes dists/sailfish/org.scummvm.scummvm.desktop | 24 ++ 19 files changed, 1057 insertions(+), 17 deletions(-) create mode 100644 backends/platform/sdl/sailfish/README.md create mode 100644 backends/platform/sdl/sailfish/rpm/org.scummvm.scummvm.spec create mode 100644 backends/platform/sdl/sailfish/sailfish-download.sh create mode 100644 backends/platform/sdl/sailfish/sailfish-main.cpp create mode 100644 backends/platform/sdl/sailfish/sailfish-window.cpp create mode 100644 backends/platform/sdl/sailfish/sailfish-window.h create mode 100644 backends/platform/sdl/sailfish/sailfish.cpp create mode 100644 backends/platform/sdl/sailfish/sailfish.h create mode 100644 backends/platform/sdl/sailfish/sdl-patches/0001-wayland-Bring-back-wl_shell-support.patch create mode 100644 backends/platform/sdl/sailfish/sdl-patches/0002-wlcancel.patch create mode 100644 dists/sailfish/108x108.png create mode 100644 dists/sailfish/128x128.png create mode 100644 dists/sailfish/172x172.png create mode 100644 dists/sailfish/86x86.png create mode 100644 dists/sailfish/org.scummvm.scummvm.desktop diff --git a/backends/platform/sdl/module.mk b/backends/platform/sdl/module.mk index 230ea04b35157..4169cfc9a537f 100644 --- a/backends/platform/sdl/module.mk +++ b/backends/platform/sdl/module.mk @@ -79,6 +79,13 @@ MODULE_OBJS += \ psp2/psp2.o endif +ifdef SAILFISH +MODULE_OBJS += \ + sailfish/sailfish-main.o \ + sailfish/sailfish-window.o \ + sailfish/sailfish.o +endif + ifdef SWITCH MODULE_OBJS += \ switch/switch-main.o \ diff --git a/backends/platform/sdl/posix/posix-main.cpp b/backends/platform/sdl/posix/posix-main.cpp index a24bd0c3776f0..ed1c2e7e89b9c 100644 --- a/backends/platform/sdl/posix/posix-main.cpp +++ b/backends/platform/sdl/posix/posix-main.cpp @@ -21,7 +21,7 @@ #include "common/scummsys.h" -#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3) && !defined(PSP2) && !defined(NINTENDO_SWITCH) && !defined(__EMSCRIPTEN__) && !defined(MIYOO) && !defined(MIYOOMINI) +#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3) && !defined(PSP2) && !defined(NINTENDO_SWITCH) && !defined(__EMSCRIPTEN__) && !defined(MIYOO) && !defined(MIYOOMINI) && !defined(SAILFISH) #include "backends/platform/sdl/posix/posix.h" #include "backends/plugins/sdl/sdl-provider.h" diff --git a/backends/platform/sdl/sailfish/README.md b/backends/platform/sdl/sailfish/README.md new file mode 100644 index 0000000000000..b85c10fed6ffa --- /dev/null +++ b/backends/platform/sdl/sailfish/README.md @@ -0,0 +1,48 @@ +Welcome to Sailfish port of ScummVM. + +# Building + +First you need to download dependencies as we link statically with them: + +``` shell +./sailfish-download.sh +``` + +You have to do this only once + +Suppose that your SDK is in `$SDK_ROOT` + +First you need to figure out your target config + +``` shell +$SDK_ROOT/bin/sfdk engine exec sb2-config -l +``` + +``` text + +SailfishOS-armv7hl +SailfishOS-i486-x86 +``` + +Then run: + +``` shell +$SDK_ROOT/bin/sfdk config --push target $TARGET +$SDK_ROOT/bin/sfdk build +``` + +And finally you need to sign them with your developper key: + +``` shell +$SDK_ROOT/bin/sfdk engine exec -tt sb2 -t $TARGET rpmsign-external sign -k $KEY_PATH/regular_key.pem -c $KEY_PATH/regular_cert.pem RPMS/*.rpm +``` + + +# Known issues + +* Screen dimming and sleep aren't inhibited in game +* If you close ScummVM window on the panel ScummVM isn't closed and you +can't open it again +* When switching From Surface SDL to OpenGL renderer touchscreen coordinates +are garbled until restart +* make install doesn't install Sailfish-specific file. It's done in RPM spec diff --git a/backends/platform/sdl/sailfish/rpm/org.scummvm.scummvm.spec b/backends/platform/sdl/sailfish/rpm/org.scummvm.scummvm.spec new file mode 100644 index 0000000000000..41355945f2cbc --- /dev/null +++ b/backends/platform/sdl/sailfish/rpm/org.scummvm.scummvm.spec @@ -0,0 +1,276 @@ +%if %{undefined outdir} +%define outdir out-sailfish.%{_arch} +%endif + +%if %{undefined real_src_path} +%define real_src_path OFF +%endif + +%define freetype_version 2.13.3 +%define flac_version 1.4.3 +%define theora_version 1.1.1 +%define jpeg_turbo_version 3.0.4 +%define libmad_version 0.15.1b +%define libmpeg2_version 0.5.1 +%define libfaad_version 2.8.8 +%define giflib_version 5.2.2 +%define fribidi_version 1.0.16 +%define sdl2_version 2.30.7 + +%define minimal_build 1 + +%if %{minimal_build} +%define engine_config --disable-all-engines --enable-engines=scumm +%else +%define engine_config %{nil} +%endif + +%define _rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm + +Name: org.scummvm.scummvm +Summary: ScummVM: Multi-game engine +Version: 0 +Release: 1 +Group: Qt/Qt +License: GPLv3 +URL: https://scummvm.org +Source0: %{name}-%{version}.tar.bz2 +BuildRequires: pkgconfig(sdl2) +BuildRequires: SDL2_net-devel +BuildRequires: pkgconfig(ogg) +BuildRequires: pkgconfig(vorbis) +BuildRequires: pkgconfig(libpng) +BuildRequires: pkgconfig(vpx) +BuildRequires: pkgconfig(egl) +BuildRequires: pkgconfig(glesv2) +BuildRequires: cmake + +%description +ScummVM: Multi-game engine + +%build +mkdir -p %{outdir} +mkdir -p %{outdir}/scummvm +mkdir -p %{outdir}/pkgconfig +if ! [ -d %{outdir}/freetype-install ]; then + cd %{outdir} + tar xvf ../rpmdeps/freetype-%{freetype_version}.tar.xz + cd freetype-%{freetype_version} + ./configure --prefix=$PWD/../freetype-install --disable-shared --enable-static + make %{?_smp_mflags} + make install + cd ../.. +fi +if ! [ -d %{outdir}/flac-install ]; then + cd %{outdir} + tar xvf ../rpmdeps/flac-%{flac_version}.tar.xz + cd flac-%{flac_version} + ./configure --disable-shared --enable-static --disable-examples --disable-programs + make %{?_smp_mflags} + make DESTDIR=$PWD/../flac-install INSTALL_ROOT=$PWD/../flac-install install + cd ../.. +fi +if ! [ -d %{outdir}/theora-install ]; then + cd %{outdir} + tar xvf ../rpmdeps/libtheora-%{theora_version}.tar.xz + cd libtheora-%{theora_version} + ./configure --disable-shared --enable-static --disable-examples --disable-programs + make %{?_smp_mflags} + make DESTDIR=$PWD/../theora-install INSTALL_ROOT=$PWD/../theora-install install + cd ../.. +fi +if ! [ -d %{outdir}/jpeg-install ]; then + cd %{outdir} + tar xvf ../rpmdeps/libjpeg-turbo-%{jpeg_turbo_version}.tar.gz + cd libjpeg-turbo-%{jpeg_turbo_version} + %cmake -DENABLE_SHARED=FALSE + make %{?_smp_mflags} + make DESTDIR=$PWD/../jpeg-install INSTALL_ROOT=$PWD/../jpeg-install install + cd ../.. +fi +if ! [ -d %{outdir}/libmad-install ]; then + cd %{outdir} + tar xvf ../rpmdeps/libmad-%{libmad_version}.tar.gz + cd libmad-%{libmad_version} + ASFLAGS=-marm CFLAGS="-O2 -marm" ./configure --disable-shared --enable-static --disable-examples --disable-programs CFLAGS="-O2 -marm" ASFLAGS=-marm + make CFLAGS="-O2 -marm" ASFLAGS=-marm %{?_smp_mflags} + make DESTDIR=$PWD/../libmad-install INSTALL_ROOT=$PWD/../libmad-install install + cd ../.. +fi +if ! [ -d %{outdir}/mpeg2-install ]; then + cd %{outdir} + tar xvf ../rpmdeps/libmpeg2-%{libmpeg2_version}.tar.gz + cd libmpeg2-%{libmpeg2_version} + ./configure --disable-shared --enable-static --disable-examples --disable-programs + make %{?_smp_mflags} + make DESTDIR=$PWD/../mpeg2-install INSTALL_ROOT=$PWD/../mpeg2-install install + cd ../.. +fi +if ! [ -d %{outdir}/faad-install ]; then + cd %{outdir} + tar xvf ../rpmdeps/faad2-%{libfaad_version}.tar.gz + cd faad2-%{libfaad_version} + ./configure --disable-shared --enable-static --disable-examples --disable-programs + make %{?_smp_mflags} + make DESTDIR=$PWD/../faad-install INSTALL_ROOT=$PWD/../faad-install install + cd ../.. +fi +if ! [ -d %{outdir}/giflib-install ]; then + cd %{outdir} + tar xvf ../rpmdeps/giflib-%{giflib_version}.tar.gz + cd giflib-%{giflib_version} + make %{?_smp_mflags} libgif.a + make DESTDIR=$PWD/../giflib-install INSTALL_ROOT=$PWD/../giflib-install install-include + install -d "$PWD/../giflib-install/usr/local/lib" + install -m 644 libgif.a "$PWD/../giflib-install/usr/local/lib/libgif.a" + cd ../.. +fi +if ! [ -d %{outdir}/fribidi-install ]; then + cd %{outdir} + tar xvf ../rpmdeps/fribidi-%{fribidi_version}.tar.xz + cd fribidi-%{fribidi_version} + ./configure --disable-shared --enable-static --prefix=$PWD/../fribidi-install + make %{?_smp_mflags} + make install + cd ../.. +fi +if ! [ -d %{outdir}/sdl-install ]; then + cd %{outdir} + tar xvf ../rpmdeps/SDL2-%{sdl2_version}.tar.gz + cd SDL2-%{sdl2_version} + for x in ../../sdl-patches/*.patch; do + echo "Applying patch $x" + patch -p1 -i "$x" + done + cd .. + cmake \ + -Bsdl-build \ + -DSDL_PULSEAUDIO=ON \ + -DSDL_RPATH=OFF \ + -DSDL_STATIC=ON \ + -DSDL_SHARED=OFF \ + -DSDL_WAYLAND=ON \ + -DSDL_X11=OFF \ + -DSDL_DBUS=ON \ + -DSDL_WAYLAND_LIBDECOR=OFF \ + -DSDL_WAYLAND_QT_TOUCH=OFF \ + SDL2-%{sdl2_version} + make -C sdl-build %{?_smp_mflags} + make -C sdl-build install DESTDIR=$PWD/sdl-install INSTALL_ROOT=$PWD/sdl-install + cd .. +fi +sed "s@Libs: .*@Libs: $PWD/%{outdir}/freetype-install/lib/libfreetype.a@g" < %{outdir}/freetype-install/lib/pkgconfig/freetype2.pc > %{outdir}/pkgconfig/freetype2.pc +sed "s@Libs: .*@Libs: $PWD/%{outdir}/fribidi-install/lib/libfribidi.a@g" < %{outdir}/fribidi-install/lib/pkgconfig/fribidi.pc > %{outdir}/pkgconfig/fribidi.pc +export PKG_CONFIG_PATH=$PWD/%{outdir}/pkgconfig:$PKG_CONFIG_PATH +cd %{outdir}/scummvm; +../../../../../../configure --host=sailfish \ + --with-jpeg-prefix=../jpeg-install/usr \ + --with-mad-prefix=../libmad-install/usr/local \ + --with-flac-prefix=../flac-install/usr/local \ + --with-theoradec-prefix=../theora-install/usr/local \ + --with-mpeg2-prefix=../mpeg2-install/usr/local \ + --with-faad-prefix=../faad-install/usr/local \ + --with-gif-prefix=../giflib-install/usr/local \ + --enable-fribidi --with-fribidi-prefix=../fribidi-install/usr/local/org.scummvm.scummvm \ + --with-sdl-prefix=../sdl-install/usr/local --enable-static \ + %{engine_config} --disable-tinygl +cd ../.. +%{__make} -C %{outdir}/scummvm %{_make_output_sync} %{?_smp_mflags} + +%install +rm -rf %{buildroot}/* +%{__make} -C %{outdir}/scummvm DESTDIR=%{buildroot} INSTALL_ROOT=%{buildroot} install +# TODO: Move this stuff into make +mkdir -p %{buildroot}/usr/share/applications +mkdir -p %{buildroot}/usr/share/icons/hicolor/86x86/apps +mkdir -p %{buildroot}/usr/share/icons/hicolor/108x108/apps +mkdir -p %{buildroot}/usr/share/icons/hicolor/128x128/apps +mkdir -p %{buildroot}/usr/share/icons/hicolor/172x172/apps +cp ../../../../dists/sailfish/org.scummvm.scummvm.desktop %{buildroot}/usr/share/applications/org.scummvm.scummvm.desktop +cp ../../../../dists/sailfish/86x86.png %{buildroot}/usr/share/icons/hicolor/86x86/apps/org.scummvm.scummvm.png +cp ../../../../dists/sailfish/108x108.png %{buildroot}/usr/share/icons/hicolor/108x108/apps/org.scummvm.scummvm.png +cp ../../../../dists/sailfish/128x128.png %{buildroot}/usr/share/icons/hicolor/128x128/apps/org.scummvm.scummvm.png +cp ../../../../dists/sailfish/172x172.png %{buildroot}/usr/share/icons/hicolor/172x172/apps/org.scummvm.scummvm.png + +%files +%defattr(755,root,root,-) +%{_bindir}/org.scummvm.scummvm + +%defattr(644,root,root,-) + +%{_datadir}/org.scummvm.scummvm/applications/%{name}.desktop +%{_datadir}/org.scummvm.scummvm/doc/scummvm/AUTHORS +%{_datadir}/org.scummvm.scummvm/doc/scummvm/CONTRIBUTING.md +%{_datadir}/org.scummvm.scummvm/doc/scummvm/COPYING +%{_datadir}/org.scummvm.scummvm/doc/scummvm/COPYING.Apache +%{_datadir}/org.scummvm.scummvm/doc/scummvm/COPYING.BSD +%{_datadir}/org.scummvm.scummvm/doc/scummvm/COPYING.BSL +%{_datadir}/org.scummvm.scummvm/doc/scummvm/COPYING.FREEFONT +%{_datadir}/org.scummvm.scummvm/doc/scummvm/COPYING.GLAD +%{_datadir}/org.scummvm.scummvm/doc/scummvm/COPYING.ISC +%{_datadir}/org.scummvm.scummvm/doc/scummvm/COPYING.LGPL +%{_datadir}/org.scummvm.scummvm/doc/scummvm/COPYING.LUA +%{_datadir}/org.scummvm.scummvm/doc/scummvm/COPYING.MIT +%{_datadir}/org.scummvm.scummvm/doc/scummvm/COPYING.MKV +%{_datadir}/org.scummvm.scummvm/doc/scummvm/COPYING.MPL +%{_datadir}/org.scummvm.scummvm/doc/scummvm/COPYING.OFL +%{_datadir}/org.scummvm.scummvm/doc/scummvm/COPYING.TINYGL +%{_datadir}/org.scummvm.scummvm/doc/scummvm/COPYRIGHT +%{_datadir}/org.scummvm.scummvm/doc/scummvm/CatharonLicense.txt +%{_datadir}/org.scummvm.scummvm/doc/scummvm/NEWS.md +%{_datadir}/org.scummvm.scummvm/doc/scummvm/README.md +%{_datadir}/org.scummvm.scummvm/icons/hicolor/scalable/apps/org.scummvm.scummvm.svg +%{_datadir}/org.scummvm.scummvm/man/man6/scummvm.6 +%{_datadir}/org.scummvm.scummvm/metainfo/org.scummvm.scummvm.metainfo.xml +%{_datadir}/org.scummvm.scummvm/pixmaps/org.scummvm.scummvm.xpm +%{_datadir}/org.scummvm.scummvm/scummvm/achievements.dat +%{_datadir}/org.scummvm.scummvm/scummvm/classicmacfonts.dat +%{_datadir}/org.scummvm.scummvm/scummvm/encoding.dat +%{_datadir}/org.scummvm.scummvm/scummvm/fonts-cjk.dat +%{_datadir}/org.scummvm.scummvm/scummvm/fonts.dat +%{_datadir}/org.scummvm.scummvm/scummvm/vkeybd_default.zip +%{_datadir}/org.scummvm.scummvm/scummvm/vkeybd_small.zip +%{_datadir}/org.scummvm.scummvm/scummvm/gui-icons.dat +%{_datadir}/org.scummvm.scummvm/scummvm/helpdialog.zip +%{_datadir}/org.scummvm.scummvm/scummvm/macgui.dat +%{_datadir}/org.scummvm.scummvm/scummvm/residualvm.zip +%{_datadir}/org.scummvm.scummvm/scummvm/scummclassic.zip +%{_datadir}/org.scummvm.scummvm/scummvm/scummmodern.zip +%{_datadir}/org.scummvm.scummvm/scummvm/scummremastered.zip +%{_datadir}/org.scummvm.scummvm/scummvm/shaders.dat +%{_datadir}/org.scummvm.scummvm/scummvm/translations.dat +%{_datadir}/org.scummvm.scummvm/scummvm/wwwroot.zip +%if !%{minimal_build} +%{_datadir}/org.scummvm.scummvm/scummvm/access.dat +%{_datadir}/org.scummvm.scummvm/scummvm/bagel.dat +%{_datadir}/org.scummvm.scummvm/scummvm/cryomni3d.dat +%{_datadir}/org.scummvm.scummvm/scummvm/drascula.dat +%{_datadir}/org.scummvm.scummvm/scummvm/freescape.dat +%{_datadir}/org.scummvm.scummvm/scummvm/grim-patch.lab +%{_datadir}/org.scummvm.scummvm/scummvm/hadesch_translations.dat +%{_datadir}/org.scummvm.scummvm/scummvm/hugo.dat +%{_datadir}/org.scummvm.scummvm/scummvm/kyra.dat +%{_datadir}/org.scummvm.scummvm/scummvm/lure.dat +%{_datadir}/org.scummvm.scummvm/scummvm/mm.dat +%{_datadir}/org.scummvm.scummvm/scummvm/mort.dat +%{_datadir}/org.scummvm.scummvm/scummvm/myst3.dat +%{_datadir}/org.scummvm.scummvm/scummvm/nancy.dat +%{_datadir}/org.scummvm.scummvm/scummvm/neverhood.dat +%{_datadir}/org.scummvm.scummvm/scummvm/pred.dic +%{_datadir}/org.scummvm.scummvm/scummvm/prince_translation.dat +%{_datadir}/org.scummvm.scummvm/scummvm/queen.tbl +%{_datadir}/org.scummvm.scummvm/scummvm/sky.cpt +%{_datadir}/org.scummvm.scummvm/scummvm/supernova.dat +%{_datadir}/org.scummvm.scummvm/scummvm/teenagent.dat +%{_datadir}/org.scummvm.scummvm/scummvm/titanic.dat +%{_datadir}/org.scummvm.scummvm/scummvm/tony.dat +%{_datadir}/org.scummvm.scummvm/scummvm/toon.dat +%{_datadir}/org.scummvm.scummvm/scummvm/ultima.dat +%{_datadir}/org.scummvm.scummvm/scummvm/ultima8.dat +%{_datadir}/org.scummvm.scummvm/scummvm/wintermute.zip +%endif +%{_datadir}/applications/org.scummvm.scummvm.desktop +%{_datadir}/icons/hicolor/108x108/apps/org.scummvm.scummvm.png +%{_datadir}/icons/hicolor/128x128/apps/org.scummvm.scummvm.png +%{_datadir}/icons/hicolor/172x172/apps/org.scummvm.scummvm.png +%{_datadir}/icons/hicolor/86x86/apps/org.scummvm.scummvm.png diff --git a/backends/platform/sdl/sailfish/sailfish-download.sh b/backends/platform/sdl/sailfish/sailfish-download.sh new file mode 100644 index 0000000000000..bd2ae974442c2 --- /dev/null +++ b/backends/platform/sdl/sailfish/sailfish-download.sh @@ -0,0 +1,10 @@ +wget -O rpmdeps/freetype-2.13.3.tar.xz https://download.savannah.gnu.org/releases/freetype/freetype-2.13.3.tar.xz +wget -O rpmdeps/flac-1.4.3.tar.xz https://ftp.osuosl.org/pub/xiph/releases/flac/flac-1.4.3.tar.xz +wget -O rpmdeps/libjpeg-turbo-3.0.4.tar.gz https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/3.0.4/libjpeg-turbo-3.0.4.tar.gz +wget -O rpmdeps/libmad-0.15.1b.tar.gz https://downloads.sourceforge.net/mad/libmad-0.15.1b.tar.gz +wget -O rpmdeps/libmpeg2-0.5.1.tar.gz https://libmpeg2.sourceforge.net/files/libmpeg2-0.5.1.tar.gz +wget -O rpmdeps/faad2-2.8.8.tar.gz https://sourceforge.net/projects/faac/files/faad2-src/faad2-2.8.0/faad2-2.8.8.tar.gz +wget -O rpmdeps/giflib-5.2.2.tar.gz https://sourceforge.net/projects/giflib/files/giflib-5.2.2.tar.gz +wget -O rpmdeps/fribidi-1.0.16.tar.xz https://github.com/fribidi/fribidi/releases/download/v1.0.16/fribidi-1.0.16.tar.xz +wget -O rpmdeps/libtheora-1.1.1.tar.xz https://ftp.osuosl.org/pub/xiph/releases/theora/libtheora-1.1.1.tar.xz +wget -O rpmdeps/SDL2-2.30.7.tar.gz https://github.com/libsdl-org/SDL/releases/download/release-2.30.7/SDL2-2.30.7.tar.gz diff --git a/backends/platform/sdl/sailfish/sailfish-main.cpp b/backends/platform/sdl/sailfish/sailfish-main.cpp new file mode 100644 index 0000000000000..8e348cc374542 --- /dev/null +++ b/backends/platform/sdl/sailfish/sailfish-main.cpp @@ -0,0 +1,45 @@ + +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "backends/platform/sdl/sailfish/sailfish.h" +#include "backends/plugins/sdl/sdl-provider.h" +#include "base/main.h" + +int main(int argc, char* argv[]) { + + g_system = new OSystem_SDL_Sailfish(); + assert(g_system); + + g_system->init(); + +#ifdef DYNAMIC_MODULES + PluginManager::instance().addPluginProvider(new SDLPluginProvider()); +#endif + + // Invoke the actual ScummVM main entry point: + int res = scummvm_main(argc, argv); + + // Free OSystem + g_system->destroy(); + + return res; +} diff --git a/backends/platform/sdl/sailfish/sailfish-window.cpp b/backends/platform/sdl/sailfish/sailfish-window.cpp new file mode 100644 index 0000000000000..e0ec87dac82a4 --- /dev/null +++ b/backends/platform/sdl/sailfish/sailfish-window.cpp @@ -0,0 +1,38 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "backends/graphics/sdl/sdl-graphics.h" +#include "backends/platform/sdl/sailfish/sailfish-window.h" + +bool SdlWindow_Sailfish::createOrUpdateWindow(int, int, uint32 flags) { + SDL_DisplayMode dm; + SDL_GetCurrentDisplayMode(0,&dm); + int width, height; + + if (dm.w < dm.h) { + width = dm.w; + height = dm.h; + } else { + width = dm.h; + height = dm.w; + } + return SdlWindow::createOrUpdateWindow(width, height, flags); +} diff --git a/backends/platform/sdl/sailfish/sailfish-window.h b/backends/platform/sdl/sailfish/sailfish-window.h new file mode 100644 index 0000000000000..b30a7c3385783 --- /dev/null +++ b/backends/platform/sdl/sailfish/sailfish-window.h @@ -0,0 +1,32 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef BACKENDS_PLATFORM_SDL_MACOSX_MACOSX_WINDOW_H +#define BACKENDS_PLATFORM_SDL_MACOSX_MACOSX_WINDOW_H + +#include "backends/platform/sdl/sdl-window.h" + +class SdlWindow_Sailfish final : public SdlWindow { +public: + bool createOrUpdateWindow(int, int, uint32 flags) override; +}; + +#endif diff --git a/backends/platform/sdl/sailfish/sailfish.cpp b/backends/platform/sdl/sailfish/sailfish.cpp new file mode 100644 index 0000000000000..f8c8466b6d406 --- /dev/null +++ b/backends/platform/sdl/sailfish/sailfish.cpp @@ -0,0 +1,144 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "common/scummsys.h" +#include "common/config-manager.h" +#include "common/translation.h" + +#include "backends/platform/sdl/sailfish/sailfish.h" +#include "backends/platform/sdl/sailfish/sailfish-window.h" + +#include "backends/fs/posix/posix-fs-factory.h" +#include "backends/fs/posix/posix-fs.h" +#include "backends/saves/default/default-saves.h" + +#include "backends/keymapper/action.h" +#include "backends/keymapper/keymapper-defaults.h" +#include "backends/keymapper/hardware-input.h" +#include "backends/keymapper/keymap.h" +#include "backends/keymapper/keymapper.h" + +#define ORG_NAME "org.scummvm" +#define APP_NAME "scummvm" + +void OSystem_SDL_Sailfish::init() { + // Initialze File System Factory + _fsFactory = new POSIXFilesystemFactory(); + + _window = new SdlWindow_Sailfish(); + + // Invoke parent implementation of this method + OSystem_SDL::init(); +} + +void OSystem_SDL_Sailfish::initBackend() { + if (!ConfMan.hasKey("rotation_mode")) { + ConfMan.setPath("rotation_mode", "90"); + } + + if (!ConfMan.hasKey("savepath")) { + ConfMan.setPath("savepath", getDefaultSavePath()); + } + + // Create the savefile manager + if (_savefileManager == nullptr) { + _savefileManager = new DefaultSaveFileManager(getDefaultSavePath()); + } + + OSystem_SDL::initBackend(); +} + +Common::Path OSystem_SDL_Sailfish::getDefaultSavePath() { + Common::String saveRelPath; + + const char *prefix = getenv("HOME"); + if (prefix == nullptr) { + return Common::Path(); + } + + saveRelPath = ".local/share/" ORG_NAME "/" APP_NAME "/saves"; + + if (!Posix::assureDirectoryExists(saveRelPath, prefix)) { + return Common::Path(); + } + + Common::Path savePath(prefix); + savePath.joinInPlace(saveRelPath); + + return savePath; +} + +Common::Path OSystem_SDL_Sailfish::getDefaultConfigFileName() { + Common::String configPath; + + const char *prefix = getenv("HOME"); + if (prefix == nullptr) { + return Common::Path(); + } + + configPath = ".local/share/" ORG_NAME "/" APP_NAME ; + + if (!Posix::assureDirectoryExists(configPath, prefix)) { + return Common::Path(); + } + + Common::Path configFile(prefix); + configFile.joinInPlace(configPath); + configFile.joinInPlace("scummvm.ini"); + + return configFile; +} + +Common::Path OSystem_SDL_Sailfish::getDefaultLogFileName() { + Common::String logFile; + + const char *prefix = getenv("HOME"); + if (prefix == nullptr) { + return Common::Path(); + } + + logFile = ".cache/" ORG_NAME "/" APP_NAME "/logs"; + + if (!Posix::assureDirectoryExists(logFile, prefix)) { + return Common::Path(); + } + + Common::Path logPath(prefix); + logPath.joinInPlace(logFile); + logPath.joinInPlace("scummvm.log"); + + return logPath; +} + + +bool OSystem_SDL_Sailfish::hasFeature(Feature f) { + switch (f) { + case kFeatureFullscreenMode: + case kFeatureAspectRatioCorrection: + return false; + case kFeatureTouchpadMode: + return true; + default: + return OSystem_SDL::hasFeature(f); + } +} diff --git a/backends/platform/sdl/sailfish/sailfish.h b/backends/platform/sdl/sailfish/sailfish.h new file mode 100644 index 0000000000000..4f47101fecb82 --- /dev/null +++ b/backends/platform/sdl/sailfish/sailfish.h @@ -0,0 +1,41 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef PLATFORM_SDL_SAILFISH_H +#define PLATFORM_SDL_SAILFISH_H + +#include "backends/platform/sdl/sdl.h" + +class OSystem_SDL_Sailfish : public OSystem_SDL { +public: + void init() override; + void initBackend() override; + bool hasFeature(Feature f) override; + +protected: + Common::Path getDefaultConfigFileName() override; + Common::Path getDefaultLogFileName() override; + +private: + Common::Path getDefaultSavePath(); +}; + +#endif diff --git a/backends/platform/sdl/sailfish/sdl-patches/0001-wayland-Bring-back-wl_shell-support.patch b/backends/platform/sdl/sailfish/sdl-patches/0001-wayland-Bring-back-wl_shell-support.patch new file mode 100644 index 0000000000000..1819fec76b5d2 --- /dev/null +++ b/backends/platform/sdl/sailfish/sdl-patches/0001-wayland-Bring-back-wl_shell-support.patch @@ -0,0 +1,288 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Matti=20Lehtim=C3=A4ki?= +Date: Wed, 20 Apr 2022 18:03:42 +0300 +Subject: [PATCH] wayland: Bring back wl_shell support + +--- + include/SDL_syswm.h | 2 +- + src/video/wayland/SDL_waylanddyn.h | 2 + + src/video/wayland/SDL_waylandevents.c | 8 +++ + src/video/wayland/SDL_waylandsym.h | 2 + + src/video/wayland/SDL_waylandvideo.c | 7 ++ + src/video/wayland/SDL_waylandvideo.h | 1 + + src/video/wayland/SDL_waylandwindow.c | 95 +++++++++++++++++++++++++++ + src/video/wayland/SDL_waylandwindow.h | 1 + + 8 files changed, 117 insertions(+), 1 deletion(-) + +diff --git a/include/SDL_syswm.h b/include/SDL_syswm.h +index 7b8bd6ef996571bbba2e5f1e139a0c9292c88146..671a26ee945bdac99de9f07b57aef9cc893f4cec 100644 +--- a/include/SDL_syswm.h ++++ b/include/SDL_syswm.h +@@ -294,7 +294,7 @@ struct SDL_SysWMinfo + { + struct wl_display *display; /**< Wayland display */ + struct wl_surface *surface; /**< Wayland surface */ +- void *shell_surface; /**< DEPRECATED Wayland shell_surface (window manager handle) */ ++ struct wl_shell_surface *shell_surface; /**< DEPRECATED Wayland shell_surface (window manager handle) */ + struct wl_egl_window *egl_window; /**< Wayland EGL window (native window) */ + struct xdg_surface *xdg_surface; /**< Wayland xdg surface (window manager handle) */ + struct xdg_toplevel *xdg_toplevel; /**< Wayland xdg toplevel role */ +diff --git a/src/video/wayland/SDL_waylanddyn.h b/src/video/wayland/SDL_waylanddyn.h +index 6feb343912b15a6a9360a11b66a08c0c4e36f882..2c93149cd2dcbff5a69c20606c028aa13905dced 100644 +--- a/src/video/wayland/SDL_waylanddyn.h ++++ b/src/video/wayland/SDL_waylanddyn.h +@@ -111,11 +111,13 @@ void SDL_WAYLAND_UnloadSymbols(void); + #define wl_shm_pool_interface (*WAYLAND_wl_shm_pool_interface) + #define wl_buffer_interface (*WAYLAND_wl_buffer_interface) + #define wl_registry_interface (*WAYLAND_wl_registry_interface) ++#define wl_shell_surface_interface (*WAYLAND_wl_shell_surface_interface) + #define wl_region_interface (*WAYLAND_wl_region_interface) + #define wl_pointer_interface (*WAYLAND_wl_pointer_interface) + #define wl_keyboard_interface (*WAYLAND_wl_keyboard_interface) + #define wl_compositor_interface (*WAYLAND_wl_compositor_interface) + #define wl_output_interface (*WAYLAND_wl_output_interface) ++#define wl_shell_interface (*WAYLAND_wl_shell_interface) + #define wl_shm_interface (*WAYLAND_wl_shm_interface) + #define wl_data_device_interface (*WAYLAND_wl_data_device_interface) + #define wl_data_offer_interface (*WAYLAND_wl_data_offer_interface) +diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c +index a8382812ab149c4377441d46a693f736f5430cad..45d679abdafb94708e478745d4f1db57922c37b7 100644 +--- a/src/video/wayland/SDL_waylandevents.c ++++ b/src/video/wayland/SDL_waylandevents.c +@@ -518,6 +518,10 @@ static SDL_bool ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial) + input->seat, + serial); + } ++ } else { ++ if (window_data->shell_surface.wl) { ++ wl_shell_surface_move(window_data->shell_surface.wl, input->seat, serial); ++ } + } + return SDL_TRUE; + +@@ -543,6 +547,10 @@ static SDL_bool ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial) + serial, + directions[rc - SDL_HITTEST_RESIZE_TOPLEFT]); + } ++ } else { ++ if (window_data->shell_surface.wl) { ++ wl_shell_surface_resize(window_data->shell_surface.wl, input->seat, serial, directions[rc - SDL_HITTEST_RESIZE_TOPLEFT]); ++ } + } + return SDL_TRUE; + +diff --git a/src/video/wayland/SDL_waylandsym.h b/src/video/wayland/SDL_waylandsym.h +index 1b02b01c6691bd2df30508ab88bbd990586594d0..27ff34a31a77c970300790697204594d24e11a1f 100644 +--- a/src/video/wayland/SDL_waylandsym.h ++++ b/src/video/wayland/SDL_waylandsym.h +@@ -101,11 +101,13 @@ SDL_WAYLAND_INTERFACE(wl_surface_interface) + SDL_WAYLAND_INTERFACE(wl_shm_pool_interface) + SDL_WAYLAND_INTERFACE(wl_buffer_interface) + SDL_WAYLAND_INTERFACE(wl_registry_interface) ++SDL_WAYLAND_INTERFACE(wl_shell_surface_interface) + SDL_WAYLAND_INTERFACE(wl_region_interface) + SDL_WAYLAND_INTERFACE(wl_pointer_interface) + SDL_WAYLAND_INTERFACE(wl_keyboard_interface) + SDL_WAYLAND_INTERFACE(wl_compositor_interface) + SDL_WAYLAND_INTERFACE(wl_output_interface) ++SDL_WAYLAND_INTERFACE(wl_shell_interface) + SDL_WAYLAND_INTERFACE(wl_shm_interface) + SDL_WAYLAND_INTERFACE(wl_data_device_interface) + SDL_WAYLAND_INTERFACE(wl_data_source_interface) +diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c +index 2cae471792cd692129f193fac2100d7d98ab6705..70e9d7306a8fcc60a4b8b1a9289c18f88a8de990 100644 +--- a/src/video/wayland/SDL_waylandvideo.c ++++ b/src/video/wayland/SDL_waylandvideo.c +@@ -846,6 +846,8 @@ static void display_handle_global(void *data, struct wl_registry *registry, uint + } else if (SDL_strcmp(interface, "xdg_wm_base") == 0) { + d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, SDL_min(version, 3)); + xdg_wm_base_add_listener(d->shell.xdg, &shell_listener_xdg, NULL); ++ } else if (SDL_strcmp(interface, "wl_shell") == 0) { ++ d->shell.wl = wl_registry_bind(d->registry, id, &wl_shell_interface, 1); + } else if (SDL_strcmp(interface, "wl_shm") == 0) { + d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); + } else if (SDL_strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) { +@@ -1097,6 +1099,11 @@ static void Wayland_VideoCleanup(_THIS) + data->shm = NULL; + } + ++ if (data->shell.wl) { ++ wl_shell_destroy(data->shell.wl); ++ data->shell.wl = NULL; ++ } ++ + if (data->shell.xdg) { + xdg_wm_base_destroy(data->shell.xdg); + data->shell.xdg = NULL; +diff --git a/src/video/wayland/SDL_waylandvideo.h b/src/video/wayland/SDL_waylandvideo.h +index b7b3348c6d4d9285971d5a2416f7d123f303c7f8..e57ab2bd21a3064c257d704b4912c22d5c49074e 100644 +--- a/src/video/wayland/SDL_waylandvideo.h ++++ b/src/video/wayland/SDL_waylandvideo.h +@@ -64,6 +64,7 @@ typedef struct + struct + { + struct xdg_wm_base *xdg; ++ struct wl_shell *wl; + #ifdef HAVE_LIBDECOR_H + struct libdecor *libdecor; + #endif +diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c +index 08df3638c2e795ecdf4cd5f4972bd5d4f866653d..4cb20afbda9aef1edad59b3cf2bd73a7f6e3d289 100644 +--- a/src/video/wayland/SDL_waylandwindow.c ++++ b/src/video/wayland/SDL_waylandwindow.c +@@ -446,6 +446,20 @@ static void SetFullscreen(SDL_Window *window, struct wl_output *output) + } else { + xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel); + } ++ } else { ++ if (wind->shell_surface.wl == NULL) { ++ return; /* Can't do anything yet, wait for ShowWindow */ ++ } ++ ++ wl_surface_commit(wind->surface); ++ ++ if (output) { ++ wl_shell_surface_set_fullscreen(wind->shell_surface.wl, ++ WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, ++ 0, output); ++ } else { ++ wl_shell_surface_set_toplevel(wind->shell_surface.wl); ++ } + } + } + +@@ -541,6 +555,62 @@ static const struct wl_callback_listener gles_swap_frame_listener = { + + static void Wayland_HandleResize(SDL_Window *window, int width, int height, float scale); + ++/* On modern desktops, we probably will use the xdg-shell protocol instead ++ of wl_shell, but wl_shell might be useful on older Wayland installs that ++ don't have the newer protocol, or embedded things that don't have a full ++ window manager. */ ++ ++static void ++handle_ping_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface, ++ uint32_t serial) ++{ ++ wl_shell_surface_pong(shell_surface, serial); ++} ++ ++static void ++handle_configure_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface, ++ uint32_t edges, int32_t width, int32_t height) ++{ ++ SDL_WindowData *wind = (SDL_WindowData *)data; ++ SDL_Window *window = wind->sdlwindow; ++ ++ /* wl_shell_surface spec states that this is a suggestion. ++ Ignore if less than or greater than max/min size. */ ++ ++ if (width == 0 || height == 0) { ++ return; ++ } ++ ++ if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { ++ if ((window->flags & SDL_WINDOW_RESIZABLE)) { ++ if (window->max_w > 0) { ++ width = SDL_min(width, window->max_w); ++ } ++ width = SDL_max(width, window->min_w); ++ ++ if (window->max_h > 0) { ++ height = SDL_min(height, window->max_h); ++ } ++ height = SDL_max(height, window->min_h); ++ } else { ++ return; ++ } ++ } ++ ++ Wayland_HandleResize(window, width, height, wind->scale_factor); ++} ++ ++static void ++handle_popup_done_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface) ++{ ++} ++ ++static const struct wl_shell_surface_listener shell_surface_listener_wl = { ++ handle_ping_wl_shell_surface, ++ handle_configure_wl_shell_surface, ++ handle_popup_done_wl_shell_surface ++}; ++ + static void handle_configure_xdg_shell_surface(void *data, struct xdg_surface *xdg, uint32_t serial) + { + SDL_WindowData *wind = (SDL_WindowData *)data; +@@ -1374,6 +1444,11 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window) + xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname); + xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data); + } ++ } else { ++ data->shell_surface.wl = wl_shell_get_shell_surface(c->shell.wl, data->surface); ++ wl_shell_surface_set_class(data->shell_surface.wl, c->classname); ++ wl_shell_surface_set_user_data(data->shell_surface.wl, data); ++ wl_shell_surface_add_listener(data->shell_surface.wl, &shell_surface_listener_wl, data); + } + + /* Restore state that was set prior to this call */ +@@ -1549,6 +1624,11 @@ void Wayland_HideWindow(_THIS, SDL_Window *window) + xdg_surface_destroy(wind->shell_surface.xdg.surface); + wind->shell_surface.xdg.surface = NULL; + } ++ } else { ++ if (wind->shell_surface.wl) { ++ wl_shell_surface_destroy(wind->shell_surface.wl); ++ wind->shell_surface.wl = NULL; ++ } + } + + /* +@@ -1829,6 +1909,11 @@ void Wayland_RestoreWindow(_THIS, SDL_Window *window) + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_unset_maximized(wind->shell_surface.xdg.roleobj.toplevel); ++ } else { ++ if (wind->shell_surface.wl == NULL) { ++ return; /* Can't do anything yet, wait for ShowWindow */ ++ } ++ wl_shell_surface_set_toplevel(wind->shell_surface.wl); + } + + WAYLAND_wl_display_roundtrip(viddata->display); +@@ -1908,6 +1993,11 @@ void Wayland_MaximizeWindow(_THIS, SDL_Window *window) + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_set_maximized(wind->shell_surface.xdg.roleobj.toplevel); ++ } else { ++ if (wind->shell_surface.wl == NULL) { ++ return; /* Can't do anything yet, wait for ShowWindow */ ++ } ++ wl_shell_surface_set_maximized(wind->shell_surface.wl, NULL); + } + + WAYLAND_wl_display_roundtrip(viddata->display); +@@ -2209,6 +2299,11 @@ void Wayland_SetWindowTitle(_THIS, SDL_Window *window) + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_set_title(wind->shell_surface.xdg.roleobj.toplevel, title); ++ } else { ++ if (wind->shell_surface.wl == NULL) { ++ return; /* Can'd do anything yet, wait for ShowWindow */ ++ } ++ wl_shell_surface_set_title(wind->shell_surface.wl, title); + } + + WAYLAND_wl_display_flush(viddata->display); +diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h +index 36600a4d2783e5205d0e1d2faf8422b54e1f7848..0951126949879d863cde175684a3605367428824 100644 +--- a/src/video/wayland/SDL_waylandwindow.h ++++ b/src/video/wayland/SDL_waylandwindow.h +@@ -67,6 +67,7 @@ typedef struct + } roleobj; + SDL_bool initial_configure_seen; + } xdg; ++ struct wl_shell_surface *wl; + } shell_surface; + enum + { diff --git a/backends/platform/sdl/sailfish/sdl-patches/0002-wlcancel.patch b/backends/platform/sdl/sailfish/sdl-patches/0002-wlcancel.patch new file mode 100644 index 0000000000000..9b5cea65170c6 --- /dev/null +++ b/backends/platform/sdl/sailfish/sdl-patches/0002-wlcancel.patch @@ -0,0 +1,49 @@ +commit 7dd1cdd4656e0bdbf0f851392f644b2a05c32d64 +Author: Vladimir Serbinenko +Date: Thu Sep 26 17:19:14 2024 +0300 + + Handle wayland touch cancel message + + Suppose host has some three-finger gesture. Then we get the following sequence + of events: + DOWN-DOWN-DOWN-MOTION-CANCEL + + Note that there is no UP in this sequence. So if we don't handle CANCEL then + we end up thinking that fingers are still touching the screen. Ideally we + should inform the application that cancel has happened as not to trigger + spurious taps but still this is way better than being stuck with phantom + finger touch. + +diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c +index 65838f480..236dc3232 100644 +--- a/src/video/wayland/SDL_waylandevents.c ++++ b/src/video/wayland/SDL_waylandevents.c +@@ -932,6 +932,28 @@ static void touch_handler_frame(void *data, struct wl_touch *touch) + + static void touch_handler_cancel(void *data, struct wl_touch *touch) + { ++ struct SDL_WaylandTouchPoint *tp; ++ while ((tp = touch_points.head)) { ++ wl_fixed_t fx = 0, fy = 0; ++ struct wl_surface *surface = NULL; ++ int id = tp->id; ++ ++ touch_del(id, &fx, &fy, &surface); ++ ++ if (surface) { ++ SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(surface); ++ ++ if (window_data) { ++ const double dblx = wl_fixed_to_double(fx) * window_data->pointer_scale_x; ++ const double dbly = wl_fixed_to_double(fy) * window_data->pointer_scale_y; ++ const float x = dblx / window_data->sdlwindow->w; ++ const float y = dbly / window_data->sdlwindow->h; ++ ++ SDL_SendTouch((SDL_TouchID)(intptr_t)touch, (SDL_FingerID)id, ++ window_data->sdlwindow, SDL_FALSE, x, y, 1.0f); ++ } ++ } ++ } + } + + static const struct wl_touch_listener touch_listener = { diff --git a/backends/platform/sdl/sdl-window.h b/backends/platform/sdl/sdl-window.h index 4a48d62df5630..b3e4933874c0d 100644 --- a/backends/platform/sdl/sdl-window.h +++ b/backends/platform/sdl/sdl-window.h @@ -153,7 +153,7 @@ class SdlWindow { * @param flags SDL flags passed to SDL_CreateWindow * @return true on success, false otherwise */ - bool createOrUpdateWindow(int width, int height, uint32 flags); + virtual bool createOrUpdateWindow(int width, int height, uint32 flags); /** * Destroys the current SDL window. diff --git a/configure b/configure index ab53209f3b7f8..4227ab4832042 100755 --- a/configure +++ b/configure @@ -906,6 +906,7 @@ Special configuration feature: ps3 for PlayStation 3 psp2 for PlayStation Vita psp for PlayStation Portable + sailfish for SailfishOS samsungtv for Samsung TV switch for Nintendo Switch tvos for Apple TV (tvOS 9.0+) @@ -1158,6 +1159,9 @@ Saved environment variables: AR="$SAVED_AR" AS="$SAVED_AS" ASFLAGS="$SAVED_ASFLAGS" CPPFLAGS="$SAVED_CPPFLAGS" CXX="$SAVED_CXX" CXXFLAGS="$SAVED_CXXFLAGS" DWP="$SAVED_DWP" LD="$SAVED_LD" LDFLAGS="$SAVED_LDFLAGS" PKG_CONFIG_LIBDIR="$SAVED_PKG_CONFIG_LIBDIR" RANLIB="$SAVED_RANLIB" SDL_CONFIG="$SAVED_SDL_CONFIG" STRIP="$SAVED_STRIP" WINDRES="$SAVED_WINDRES" WINDRESFLAGS="$SAVED_WINDRESFLAGS" EOF +JPEG_LIBS=-ljpeg +FLAC_LIBS=-lFLAC +THEORADEC_LIBS=-ltheoradec for ac_option in $@; do case "$ac_option" in @@ -1393,7 +1397,8 @@ for ac_option in $@; do --with-flac-prefix=*) arg=`echo $ac_option | cut -d '=' -f 2` FLAC_CFLAGS="-I$arg/include" - FLAC_LIBS="-L$arg/lib" + FLAC_LIBS="-L$arg/lib -lFLAC" + FLAC_PREFIX="$arg" ;; --with-mad-prefix=*) arg=`echo $ac_option | cut -d '=' -f 2` @@ -1408,7 +1413,8 @@ for ac_option in $@; do --with-jpeg-prefix=*) arg=`echo $ac_option | cut -d '=' -f 2` JPEG_CFLAGS="-I$arg/include" - JPEG_LIBS="-L$arg/lib" + JPEG_LIBS="-L$arg/lib -ljpeg" + JPEG_PREFIX="$arg" ;; --with-png-prefix=*) arg=`echo $ac_option | cut -d '=' -f 2` @@ -1423,7 +1429,8 @@ for ac_option in $@; do --with-theoradec-prefix=*) arg=`echo $ac_option | cut -d '=' -f 2` THEORADEC_CFLAGS="-I$arg/include" - THEORADEC_LIBS="-L$arg/lib" + THEORADEC_LIBS="-L$arg/lib -ltheoradec" + THEORADEC_PREFIX="$arg" ;; --with-vpx-prefix=*) arg=`echo $ac_option | cut -d '=' -f 2` @@ -1836,6 +1843,23 @@ samsungtv) _host_os=linux _host_cpu=arm _host_alias=arm-linux-gnueabi + ;; +sailfish) + _host_os=linux + test "x$prefix" = xNONE && prefix=/usr + datarootdir='/usr/share/org.scummvm.scummvm' + datadir='${datarootdir}/scummvm' + docdir='/usr/share/org.scummvm.scummvm/doc/scummvm' + if [ -n "$JPEG_PREFIX" ]; then + JPEG_LIBS="$JPEG_PREFIX/lib/libjpeg.a" + fi + if [ -n "$FLAC_PREFIX" ]; then + FLAC_LIBS="$FLAC_PREFIX/lib/libFLAC.a" + fi + if [ -n "$THEORADEC_PREFIX" ]; then + THEORADEC_LIBS="$THEORADEC_PREFIX/lib/libtheoradec.a" + fi + ;; switch) _host_os=switch @@ -2169,7 +2193,7 @@ if test -n "$CXX" && test_compiler "$CXX"; then # Use the compiler specified in CXX echo $CXX else - if test -n "$_host"; then + if test -n "$_host" && test "$_host" != sailfish ; then compilers="$_host_alias-g++ $_host_alias-c++ $_host_alias-clang++ $_host-g++ $_host-c++ $_host-clang++" else compilers="g++ c++ clang++" @@ -3907,6 +3931,14 @@ if test -n "$_host"; then _seq_midi=no _timidity=no ;; + sailfish) + append_var DEFINES "-DSAILFISH" + append_var LDFLAGS "-Wl,-rpath,/usr/share/org.scummvm.scummvm/lib" + _vkeybd=yes + HOSTEXEPRE=org.scummvm. + _backend="sailfish" + add_line_to_config_mk 'SAILFISH = 1' + ;; samsungtv) append_var DEFINES "-DSAMSUNGTV" append_var DEFINES "-DDISABLE_COMMAND_LINE" @@ -4050,7 +4082,7 @@ case $_backend in append_var DEFINES "-DUSE_NULL_DRIVER" _text_console=yes ;; - opendingux | miyoo | miyoomini) + opendingux | miyoo | miyoomini | sailfish) _sdlconfig=sdl-config _sdl=auto append_var MODULES "backends/platform/sdl" @@ -4089,7 +4121,7 @@ case $_backend in append_var LDFLAGS "-fpic" _sdl=auto ;; - sdl) + sdl | sailfish) _sdl=auto ;; switch) @@ -4461,7 +4493,7 @@ fi # Enable 16bit support only for backends which support it # case $_backend in - 3ds | android | dingux | dc | ds | ios7 | kolibrios | maemo | null | opendingux | miyoomini | miyoo | openpandora | psp | psp2 | samsungtv | sdl | switch | wii) + 3ds | android | dingux | dc | ds | ios7 | kolibrios | maemo | null | opendingux | miyoomini | miyoo | openpandora | psp | psp2 | sailfish | samsungtv | sdl | switch | wii) if test "$_16bit" = auto ; then _16bit=yes else @@ -5208,14 +5240,14 @@ int main(void) { EOF if test "$_ogg" = yes ; then cc_check $FLAC_CFLAGS $FLAC_LIBS $OGG_CFLAGS $OGG_LIBS \ - -lFLAC -logg && _flac=yes + -logg && _flac=yes else cc_check $FLAC_CFLAGS $FLAC_LIBS \ - -lFLAC && _flac=yes + && _flac=yes fi fi if test "$_flac" = yes ; then - append_var LIBS "$FLAC_LIBS -lFLAC" + append_var LIBS "$FLAC_LIBS" append_var INCLUDES "$FLAC_CFLAGS" fi define_in_config_if_yes "$_flac" 'USE_FLAC' @@ -5282,10 +5314,10 @@ int main(void) { return 0; } EOF - cc_check $JPEG_CFLAGS $JPEG_LIBS -ljpeg && _jpeg=yes + cc_check $JPEG_CFLAGS $JPEG_LIBS && _jpeg=yes fi if test "$_jpeg" = yes ; then - append_var LIBS "$JPEG_LIBS -ljpeg" + append_var LIBS "$JPEG_LIBS" append_var INCLUDES "$JPEG_CFLAGS" fi define_in_config_if_yes "$_jpeg" 'USE_JPEG' @@ -5367,10 +5399,10 @@ if test "$_theoradec" = auto ; then #include int main(void) { th_ycbcr_buffer yuv; th_decode_ycbcr_out(NULL, yuv); } EOF - cc_check $THEORADEC_CFLAGS $THEORADEC_LIBS -ltheoradec && _theoradec=yes + cc_check $THEORADEC_CFLAGS $THEORADEC_LIBS && _theoradec=yes fi if test "$_theoradec" = yes ; then - append_var LIBS "$THEORADEC_LIBS -ltheoradec" + append_var LIBS "$THEORADEC_LIBS" append_var INCLUDES "$THEORADEC_CFLAGS" fi define_in_config_if_yes "$_theoradec" 'USE_THEORADEC' @@ -6337,6 +6369,12 @@ if test "$_opengl_mode" != none ; then ;; esac ;; + sailfish) + _opengl_mode=gles2 + _opengl_glad=yes + OPENGL_CFLAGS=`$_pkgconfig --cflags glesv2 egl` + OPENGL_LIBS=`$_pkgconfig --libs glesv2 egl` + ;; switch) _opengl_mode=gles2 _opengl_glad=yes @@ -6728,7 +6766,7 @@ echocheck "ImGui" if test "$_imgui" != no ; then if test "$_freetype2" = yes ; then case $_backend in - sdl) + sdl | sailfish) if test "$_sdlMajorVersionNumber" -ge 2 ; then cat > $TMPC << EOF #include "SDL.h" diff --git a/dists/sailfish/108x108.png b/dists/sailfish/108x108.png new file mode 100644 index 0000000000000000000000000000000000000000..8627119b8df9193ad2ab2a401e3d27ed2f6a8e0a GIT binary patch literal 6270 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 literal 0 HcmV?d00001 diff --git a/dists/sailfish/128x128.png b/dists/sailfish/128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..7ccd61efd1a234f117c4b9ccfd1afb9705793ba0 GIT binary patch literal 7555 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 B-17hc literal 0 HcmV?d00001 diff --git a/dists/sailfish/86x86.png b/dists/sailfish/86x86.png new file mode 100644 index 0000000000000000000000000000000000000000..b7dd7e039031587eef20b992af8bc848e01a7a3f GIT binary patch literal 4908 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 literal 0 HcmV?d00001 diff --git a/dists/sailfish/org.scummvm.scummvm.desktop b/dists/sailfish/org.scummvm.scummvm.desktop new file mode 100644 index 0000000000000..9d4f4f03c5259 --- /dev/null +++ b/dists/sailfish/org.scummvm.scummvm.desktop @@ -0,0 +1,24 @@ +[Desktop Entry] +Name=ScummVM +Comment=Interpreter for numerous adventure games and RPGs +Comment[pl]=Interpreter graficznych gier przygodowych +Comment[sv]=Tolk för flertalet äventyrsspel +Comment[he]=פרשן למספר משחקי הרפתקאות +Comment[de]=Interpreter für zahlreiche Abenteuerspiele und RPGs +Comment[es]=Intérprete para varias aventuras gráficas +Comment[ca]=Intèrpret per diverses aventures gràfiques +Exec=/usr/bin/org.scummvm.scummvm +Icon=org.scummvm.scummvm +Type=Application +Categories=Game;AdventureGame; +X-Nemo-Application-Type=no-invoker +X-Desktop-File-Install-Version=0.26 + +[X-Application] +Permissions=UserDirs;RemovableMedia;Internet;Audio +OrganizationName=org.scummvm +ApplicationName=scummvm + +[X-Aurora-Application] +Orientation=Landscape;Portrait +IconMode=Crop