From cb6a40619093b5d3a9990b6ffd00d84f00dbe989 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 21 May 2022 20:42:08 +0200 Subject: [PATCH] Ports: Return SDL2 to upstream --- Ports/AvailablePorts.md | 2 +- Ports/SDL2/package.sh | 7 +- ...0001-Add-SerenityOS-platform-support.patch | 1699 +++++++++++++++++ ...f-FULL-paths-with-their-relative-cou.patch | 31 + Ports/SDL2/patches/ReadMe.md | 17 + 5 files changed, 1752 insertions(+), 4 deletions(-) create mode 100644 Ports/SDL2/patches/0001-Add-SerenityOS-platform-support.patch create mode 100644 Ports/SDL2/patches/0002-Replace-usages-of-FULL-paths-with-their-relative-cou.patch create mode 100644 Ports/SDL2/patches/ReadMe.md diff --git a/Ports/AvailablePorts.md b/Ports/AvailablePorts.md index 202faf615f..440ec73ba5 100644 --- a/Ports/AvailablePorts.md +++ b/Ports/AvailablePorts.md @@ -195,7 +195,7 @@ Please make sure to keep this list up to date when adding and updating ports. :^ | [`sam`](sam/) | Software Automatic Mouth (SAM) | c86ea39 | https://github.com/vidarh/SAM | | [`scummvm`](scummvm/) | ScummVM | 2.5.1 | https://www.scummvm.org/ | | [`SDL_sound`](SDL_sound/) | SDL_sound (Abstract soundfile decoder) | | https://github.com/icculus/SDL_sound | -| [`SDL2`](SDL2/) | Simple DirectMedia Layer (SDL2) | | https://github.com/SerenityOS/SDL | +| [`SDL2`](SDL2/) | Simple DirectMedia Layer (SDL2) | 9f1e1a0 | https://github.com/libsdl-org/SDL | | [`SDL2-GNUBoy`](SDL2-GNUBoy/) | SDL2 GNUBoy | 1.2.1 | https://github.com/AlexOberhofer/SDL2-GNUBoy | | [`SDL2_gfx`](SDL2_gfx/) | SDL2\_gfx (Graphics primitives add-on for SDL2) | 1.0.4 | https://sourceforge.net/projects/sdl2gfx/ | | [`SDL2_image`](SDL2_image/) | SDL2\_image (Image loading add-on for SDL2) | 2.0.5 | https://www.libsdl.org/projects/SDL_image/ | diff --git a/Ports/SDL2/package.sh b/Ports/SDL2/package.sh index 6c8c5f25dd..5fa8eb06fb 100755 --- a/Ports/SDL2/package.sh +++ b/Ports/SDL2/package.sh @@ -1,9 +1,10 @@ #!/usr/bin/env -S bash ../.port_include.sh port=SDL2 -version=git -workdir=SDL-main-serenity +version=c63a62ae49cd20e46786a4437edac09ff5c24c16 +workdir=SDL-${version} useconfigure=true -files="https://github.com/SerenityPorts/SDL/archive/main-serenity.tar.gz SDL2-git.tar.gz" +auth_type=sha256 +files="https://github.com/libsdl-org/SDL/archive/${version}.tar.gz SDL2-${version}.tar.gz 9f1e1a00cf2f840839f0a3158e3acc046526e4418378625929cb583eae3acc10" configopts=("-DCMAKE_TOOLCHAIN_FILE=${SERENITY_BUILD_DIR}/CMakeToolchain.txt" "-DPULSEAUDIO=OFF" "-DJACK=OFF" "-DEXTRA_LDFLAGS=-laudio;-liconv;-ldl") depends=("libiconv") diff --git a/Ports/SDL2/patches/0001-Add-SerenityOS-platform-support.patch b/Ports/SDL2/patches/0001-Add-SerenityOS-platform-support.patch new file mode 100644 index 0000000000..04c8864569 --- /dev/null +++ b/Ports/SDL2/patches/0001-Add-SerenityOS-platform-support.patch @@ -0,0 +1,1699 @@ +From ab6529f3d53a3d596dcf8697aec2f1ca27cf6956 Mon Sep 17 00:00:00 2001 +From: Andreas Kling +Date: Sat, 27 Mar 2021 22:05:09 +0100 +Subject: [PATCH 1/2] Add SerenityOS platform support + +Co-Authored-By: Robin Burchell +Co-Authored-By: tgsm +Co-Authored-By: TheMorc +Co-Authored-By: thatdutchguy +Co-Authored-By: Oleg Sikorskiy +Co-Authored-By: Gunnar Beutner +Co-Authored-By: AnicJov +Co-Authored-By: Jelle Raaijmakers +Co-Authored-By: Kenneth Myhra +Co-Authored-By: Stephan Unverwerth +Co-Authored-By: Tim Schumacher +Co-Authored-By: circl +--- + CMakeLists.txt | 24 +- + build-scripts/config.sub | 3 + + cmake/sdlchecks.cmake | 20 + + include/SDL_config.h.cmake | 2 + + src/SDL_error.c | 9 +- + src/audio/SDL_audio.c | 3 + + src/audio/SDL_sysaudio.h | 1 + + src/audio/serenity/SDL_serenityaudio.cpp | 159 ++++ + src/audio/serenity/SDL_serenityaudio.h | 38 + + src/stdlib/SDL_stdlib.c | 2 +- + src/video/SDL_sysvideo.h | 1 + + src/video/SDL_video.c | 13 + + src/video/serenity/SDL_serenityevents.cpp | 52 ++ + src/video/serenity/SDL_serenityevents_c.h | 33 + + src/video/serenity/SDL_serenitymessagebox.cpp | 40 + + src/video/serenity/SDL_serenitymessagebox.h | 38 + + src/video/serenity/SDL_serenitymouse.cpp | 142 ++++ + src/video/serenity/SDL_serenitymouse.h | 39 + + src/video/serenity/SDL_serenityvideo.cpp | 717 ++++++++++++++++++ + src/video/serenity/SDL_serenityvideo.h | 98 +++ + 20 files changed, 1410 insertions(+), 24 deletions(-) + create mode 100644 src/audio/serenity/SDL_serenityaudio.cpp + create mode 100644 src/audio/serenity/SDL_serenityaudio.h + create mode 100644 src/video/serenity/SDL_serenityevents.cpp + create mode 100644 src/video/serenity/SDL_serenityevents_c.h + create mode 100644 src/video/serenity/SDL_serenitymessagebox.cpp + create mode 100644 src/video/serenity/SDL_serenitymessagebox.h + create mode 100644 src/video/serenity/SDL_serenitymouse.cpp + create mode 100644 src/video/serenity/SDL_serenitymouse.h + create mode 100644 src/video/serenity/SDL_serenityvideo.cpp + create mode 100644 src/video/serenity/SDL_serenityvideo.h + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 358f32f..e744d17 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,10 +1,9 @@ +-if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) +- message(FATAL_ERROR "Prevented in-tree built. Please create a build directory outside of the SDL source code and call cmake from there") +-endif() +- + cmake_minimum_required(VERSION 3.0.0) + project(SDL2 C CXX) + ++set(UNIX 1) ++set(VIDEO_WAYLAND off) ++ + if(WINDOWS_STORE) + cmake_minimum_required(VERSION 3.11) + add_definitions(-DSDL_BUILDING_WINRT=1 -ZW) +@@ -360,7 +359,7 @@ set_option(VIDEO_DUMMY "Use dummy video driver" ON) + set_option(VIDEO_OPENGL "Include OpenGL support" ON) + set_option(VIDEO_OPENGLES "Include OpenGL ES support" ON) + set_option(PTHREADS "Use POSIX threads for multi-threading" ${SDL_PTHREADS_ENABLED_BY_DEFAULT}) +-dep_option(PTHREADS_SEM "Use pthread semaphores" ON "PTHREADS" OFF) ++dep_option(PTHREADS_SEM "Use pthread semaphores" OFF "PTHREADS" OFF) + set_option(SDL_DLOPEN "Use dlopen for shared object loading" ${SDL_DLOPEN_ENABLED_BY_DEFAULT}) + dep_option(OSS "Support the OSS audio API" ON "UNIX_SYS OR RISCOS" OFF) + set_option(ALSA "Support the ALSA audio API" ${UNIX_SYS}) +@@ -1197,20 +1196,7 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS) + CheckLibSampleRate() + endif() + +- if(SDL_VIDEO) +- # Need to check for Raspberry PI first and add platform specific compiler flags, otherwise the test for GLES fails! +- CheckRPI() +- CheckX11() +- CheckDirectFB() +- CheckOpenGLX11() +- CheckOpenGLESX11() +- CheckWayland() +- CheckVivante() +- # Need to check EGL before checking KMSDRM because KMSDRM depends on it. +- CheckEGLKMSDRM() +- CheckKMSDRM() +- CheckOpenGLKMSDRM() +- endif() ++ CheckSerenity() + + if(UNIX) + file(GLOB CORE_UNIX_SOURCES ${SDL2_SOURCE_DIR}/src/core/unix/*.c) +diff --git a/build-scripts/config.sub b/build-scripts/config.sub +index a525aab..717488d 100755 +--- a/build-scripts/config.sub ++++ b/build-scripts/config.sub +@@ -1403,6 +1403,9 @@ case $os in + os400*) + os=os400 + ;; ++ serenity*) ++ os=serenity ++ ;; + sunos5*) + os=`echo "$os" | sed -e 's|sunos5|solaris2|'` + ;; +diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake +index f21a900..e3b8643 100644 +--- a/cmake/sdlchecks.cmake ++++ b/cmake/sdlchecks.cmake +@@ -777,6 +777,26 @@ macro(CheckVivante) + endif(VIDEO_VIVANTE) + endmacro(CheckVivante) + ++# Requires: ++# - n/a ++macro(CheckSerenity) ++ message_warn("Configuring SerenityOS!") ++ set(HAVE_VIDEO_SERENITY TRUE) ++ set(HAVE_AUDIO_SERENITY TRUE) ++ set(HAVE_SDL_VIDEO TRUE) ++ set(HAVE_SDL_AUDIO TRUE) ++ ++ set(CMAKE_CXX_FLAGS "-std=c++2a ${CMAKE_CXX_FLAGS}") ++ file(GLOB SERENITY_SOURCES ${SDL2_SOURCE_DIR}/src/video/serenity/*.cpp ${SDL2_SOURCE_DIR}/src/audio/serenity/*.cpp) ++ set(SOURCE_FILES ${SOURCE_FILES} ${SERENITY_SOURCES}) ++ set(SDL_VIDEO_DRIVER_SERENITY 1) ++ set(SDL_AUDIO_DRIVER_SERENITY 1) ++ set(SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1) ++ set(HAVE_VIDEO_OPENGL TRUE) ++ set(SDL_VIDEO_OPENGL 1) ++ list(APPEND EXTRA_LIBS ipc gui gfx gl core) ++endmacro(CheckSerenity) ++ + # Requires: + # - libglvnd + macro(CheckOpenGLKMSDRM) +diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake +index 0446547..d7002b1 100644 +--- a/include/SDL_config.h.cmake ++++ b/include/SDL_config.h.cmake +@@ -291,6 +291,7 @@ + #cmakedefine SDL_AUDIO_DRIVER_PULSEAUDIO @SDL_AUDIO_DRIVER_PULSEAUDIO@ + #cmakedefine SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC @SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC@ + #cmakedefine SDL_AUDIO_DRIVER_QSA @SDL_AUDIO_DRIVER_QSA@ ++#cmakedefine SDL_AUDIO_DRIVER_SERENITY @SDL_AUDIO_DRIVER_SERENITY@ + #cmakedefine SDL_AUDIO_DRIVER_SNDIO @SDL_AUDIO_DRIVER_SNDIO@ + #cmakedefine SDL_AUDIO_DRIVER_SNDIO_DYNAMIC @SDL_AUDIO_DRIVER_SNDIO_DYNAMIC@ + #cmakedefine SDL_AUDIO_DRIVER_SUNAUDIO @SDL_AUDIO_DRIVER_SUNAUDIO@ +@@ -367,6 +368,7 @@ + #cmakedefine SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC @SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC@ + #cmakedefine SDL_VIDEO_DRIVER_DUMMY @SDL_VIDEO_DRIVER_DUMMY@ + #cmakedefine SDL_VIDEO_DRIVER_OFFSCREEN @SDL_VIDEO_DRIVER_OFFSCREEN@ ++#cmakedefine SDL_VIDEO_DRIVER_SERENITY @SDL_VIDEO_DRIVER_SERENITY@ + #cmakedefine SDL_VIDEO_DRIVER_WINDOWS @SDL_VIDEO_DRIVER_WINDOWS@ + #cmakedefine SDL_VIDEO_DRIVER_WINRT @SDL_VIDEO_DRIVER_WINRT@ + #cmakedefine SDL_VIDEO_DRIVER_WAYLAND @SDL_VIDEO_DRIVER_WAYLAND@ +diff --git a/src/SDL_error.c b/src/SDL_error.c +index 3a5667b..d00654b 100644 +--- a/src/SDL_error.c ++++ b/src/SDL_error.c +@@ -33,6 +33,7 @@ SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) + /* Ignore call if invalid format pointer was passed */ + if (fmt != NULL) { + va_list ap; ++ char errmsg[SDL_ERRBUFIZE]; + SDL_error *error = SDL_GetErrBuf(); + + error->error = 1; /* mark error as valid */ +@@ -41,10 +42,10 @@ SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) + SDL_vsnprintf(error->str, ERR_MAX_STRLEN, fmt, ap); + va_end(ap); + +- if (SDL_LogGetPriority(SDL_LOG_CATEGORY_ERROR) <= SDL_LOG_PRIORITY_DEBUG) { +- /* If we are in debug mode, print out the error message */ +- SDL_LogDebug(SDL_LOG_CATEGORY_ERROR, "%s", error->str); +- } ++ // # HACK(SerenityOS): show everything that's going on ++ SDL_GetErrorMsg(errmsg, sizeof(errmsg)); ++ dbgputstr(errmsg, strlen(errmsg)); ++ dbgputstr("\n", 1); + } + + return -1; +diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c +index 5ce94d1..b98645b 100644 +--- a/src/audio/SDL_audio.c ++++ b/src/audio/SDL_audio.c +@@ -121,6 +121,9 @@ static const AudioBootStrap *const bootstrap[] = { + #endif + #if SDL_AUDIO_DRIVER_DUMMY + &DUMMYAUDIO_bootstrap, ++#endif ++#if SDL_AUDIO_DRIVER_SERENITY ++ &SERENITYAUDIO_bootstrap, + #endif + NULL + }; +diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h +index 17b9e70..fde6b68 100644 +--- a/src/audio/SDL_sysaudio.h ++++ b/src/audio/SDL_sysaudio.h +@@ -212,6 +212,7 @@ extern AudioBootStrap PSPAUDIO_bootstrap; + extern AudioBootStrap VITAAUD_bootstrap; + extern AudioBootStrap EMSCRIPTENAUDIO_bootstrap; + extern AudioBootStrap OS2AUDIO_bootstrap; ++extern AudioBootStrap SERENITYAUDIO_bootstrap; + + #endif /* SDL_sysaudio_h_ */ + +diff --git a/src/audio/serenity/SDL_serenityaudio.cpp b/src/audio/serenity/SDL_serenityaudio.cpp +new file mode 100644 +index 0000000..01633cd +--- /dev/null ++++ b/src/audio/serenity/SDL_serenityaudio.cpp +@@ -0,0 +1,159 @@ ++/* ++ Simple DirectMedia Layer ++ Copyright (C) 1997-2019 Sam Lantinga ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++*/ ++#include "../../SDL_internal.h" ++ ++#if SDL_AUDIO_DRIVER_SERENITY ++# define AK_DONT_REPLACE_STD ++ ++extern "C" { ++ ++# include "SDL_audio.h" ++ ++# include "../SDL_audio_c.h" ++# include "../SDL_audiodev_c.h" ++} ++ ++# include ++# include ++# include ++# include ++# include "SDL_serenityaudio.h" ++ ++static Array output_buffer {}; ++static size_t output_buffer_samples_remaining { 0 }; ++ ++static void SERENITYAUDIO_CloseDevice(_THIS) ++{ ++ SDL_free(that->hidden->mixbuf); ++ SDL_free(that->hidden); ++} ++ ++static int SERENITYAUDIO_OpenDevice(_THIS, void*, char const*, int iscapture) ++{ ++ /* Initialize all variables that we clean on shutdown */ ++ that->hidden = static_cast(SDL_malloc(sizeof *that->hidden)); ++ if (!that->hidden) ++ return SDL_OutOfMemory(); ++ SDL_zerop(that->hidden); ++ ++ that->spec.freq = 44100; ++ that->spec.format = AUDIO_S16LSB; ++ that->spec.channels = 2; ++ that->spec.samples = 1024; ++ ++ /* Calculate the final parameters for this audio specification */ ++ SDL_CalculateAudioSpec(&that->spec); ++ ++ /* Allocate mixing buffer */ ++ if (!iscapture) { ++ that->hidden->mixlen = that->spec.size; ++ that->hidden->mixbuf = (Uint8*)SDL_malloc(that->hidden->mixlen); ++ if (!that->hidden->mixbuf) ++ return SDL_OutOfMemory(); ++ SDL_memset(that->hidden->mixbuf, that->spec.silence, that->spec.size); ++ } ++ ++ /* We're ready to rock and roll. :-) */ ++ return 0; ++} ++ ++static void SERENITYAUDIO_PlayDevice(_THIS) ++{ ++ struct SDL_PrivateAudioData* h = that->hidden; ++ ++ // We need to create our audio connection and event loop here, in order to register them with SDL's audio thread ++ if (!h->event_loop) ++ h->event_loop = make(Core::EventLoop::MakeInspectable::No); ++ if (!h->client) ++ h->client = MUST(Audio::ConnectionFromClient::try_create()); ++ ++ h->client->async_start_playback(); ++ ++ auto convert_i16_to_double = [](i16 input) -> auto { ++ return (static_cast(input) - NumericLimits::min()) / NumericLimits::max() * 2. - 1.; ++ }; ++ ++ auto const sleep_spec = Time::from_nanoseconds(100).to_timespec(); ++ auto input_buffer = reinterpret_cast(h->mixbuf); ++ auto input_samples = h->mixlen / that->spec.channels / sizeof(i16); ++ size_t input_position = 0; ++ ++ while (input_samples > 0) { ++ // Fill up the output buffer ++ auto const input_samples_to_process = min(input_samples, Audio::AUDIO_BUFFER_SIZE - output_buffer_samples_remaining); ++ for (size_t i = 0; i < input_samples_to_process; ++i) { ++ auto left = convert_i16_to_double(input_buffer[input_position]); ++ auto right = convert_i16_to_double(input_buffer[input_position + 1]); ++ output_buffer[output_buffer_samples_remaining + i] = Audio::Sample(left, right); ++ input_position += 2; ++ } ++ output_buffer_samples_remaining += input_samples_to_process; ++ input_samples -= input_samples_to_process; ++ ++ // Stop if we don't have enough samples to fill a buffer ++ if (output_buffer_samples_remaining < Audio::AUDIO_BUFFER_SIZE) ++ break; ++ ++ // Try to enqueue our output buffer ++ for (;;) { ++ auto enqueue_result = h->client->realtime_enqueue(output_buffer); ++ if (!enqueue_result.is_error()) ++ break; ++ if (enqueue_result.error() != Audio::AudioQueue::QueueStatus::Full) ++ return; ++ ++ nanosleep(&sleep_spec, nullptr); ++ } ++ output_buffer_samples_remaining = 0; ++ } ++ ++ // Pump our event loop - should just be the IPC call to start playback ++ for (;;) { ++ auto number_of_events_pumped = h->event_loop->pump(Core::EventLoop::WaitMode::PollForEvents); ++ if (number_of_events_pumped == 0) ++ break; ++ } ++} ++ ++static Uint8* SERENITYAUDIO_GetDeviceBuf(_THIS) ++{ ++ return that->hidden->mixbuf; ++} ++ ++static int SERENITYAUDIO_Init(SDL_AudioDriverImpl* impl) ++{ ++ /* Set the function pointers */ ++ impl->OpenDevice = SERENITYAUDIO_OpenDevice; ++ impl->PlayDevice = SERENITYAUDIO_PlayDevice; ++ impl->GetDeviceBuf = SERENITYAUDIO_GetDeviceBuf; ++ impl->CloseDevice = SERENITYAUDIO_CloseDevice; ++ ++ impl->AllowsArbitraryDeviceNames = 1; ++ impl->HasCaptureSupport = SDL_FALSE; ++ ++ return 1; // this audio target is available. ++} ++ ++AudioBootStrap SERENITYAUDIO_bootstrap = { ++ "serenity", "Serenity using AudioServer", SERENITYAUDIO_Init, 0 ++}; ++ ++#endif +diff --git a/src/audio/serenity/SDL_serenityaudio.h b/src/audio/serenity/SDL_serenityaudio.h +new file mode 100644 +index 0000000..e1b98b3 +--- /dev/null ++++ b/src/audio/serenity/SDL_serenityaudio.h +@@ -0,0 +1,38 @@ ++/* ++ Simple DirectMedia Layer ++ Copyright (C) 1997-2019 Sam Lantinga ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++*/ ++#include "../../SDL_internal.h" ++ ++#pragma once ++ ++#include "../SDL_sysaudio.h" ++#include ++#include ++#include ++#include ++ ++#define _THIS SDL_AudioDevice* that ++ ++struct SDL_PrivateAudioData { ++ RefPtr client; ++ OwnPtr event_loop; ++ Uint8* mixbuf { nullptr }; ++ size_t mixlen { 0 }; ++}; +diff --git a/src/stdlib/SDL_stdlib.c b/src/stdlib/SDL_stdlib.c +index b6dc32a..5eda105 100644 +--- a/src/stdlib/SDL_stdlib.c ++++ b/src/stdlib/SDL_stdlib.c +@@ -533,7 +533,7 @@ int SDL_toupper(int x) { return ((x) >= 'a') && ((x) <= 'z') ? ('A'+((x)-'a')) : + int SDL_tolower(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a'+((x)-'A')) : (x); } + #endif + +-#if defined(HAVE_CTYPE_H) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L ++#if defined(HAVE_CTYPE_H) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && !defined(__serenity__) + int SDL_isblank(int x) { return isblank(x); } + #else + int SDL_isblank(int x) { return ((x) == ' ') || ((x) == '\t'); } +diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h +index 682e525..c1047f7 100644 +--- a/src/video/SDL_sysvideo.h ++++ b/src/video/SDL_sysvideo.h +@@ -442,6 +442,7 @@ extern VideoBootStrap QNX_bootstrap; + extern VideoBootStrap OFFSCREEN_bootstrap; + extern VideoBootStrap OS2DIVE_bootstrap; + extern VideoBootStrap OS2VMAN_bootstrap; ++extern VideoBootStrap SERENITYVIDEO_bootstrap; + + extern SDL_VideoDevice *SDL_GetVideoDevice(void); + extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode); +diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c +index a5cbe69..a83fb1a 100644 +--- a/src/video/SDL_video.c ++++ b/src/video/SDL_video.c +@@ -119,6 +119,9 @@ static VideoBootStrap *bootstrap[] = { + &OS2DIVE_bootstrap, + &OS2VMAN_bootstrap, + #endif ++#if SDL_VIDEO_DRIVER_SERENITY ++ &SERENITYVIDEO_bootstrap, ++#endif + #if SDL_VIDEO_DRIVER_DUMMY + &DUMMY_bootstrap, + #endif +@@ -4073,6 +4076,10 @@ SDL_IsScreenKeyboardShown(SDL_Window *window) + #if SDL_VIDEO_DRIVER_VITA + #include "vita/SDL_vitamessagebox.h" + #endif ++#if SDL_VIDEO_DRIVER_SERENITY ++#include "serenity/SDL_serenitymessagebox.h" ++#endif ++ + + #if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_HAIKU || SDL_VIDEO_DRIVER_OS2 + static SDL_bool SDL_MessageboxValidForDriver(const SDL_MessageBoxData *messageboxdata, SDL_SYSWM_TYPE drivertype) +@@ -4199,6 +4206,12 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) + VITA_ShowMessageBox(messageboxdata, buttonid) == 0) { + retval = 0; + } ++#endif ++#if SDL_VIDEO_DRIVER_SERENITY ++ if (retval == -1 && ++ SERENITY_ShowMessageBox(messageboxdata, buttonid) == 0) { ++ retval = 0; ++ } + #endif + if (retval == -1) { + SDL_SetError("No message system available"); +diff --git a/src/video/serenity/SDL_serenityevents.cpp b/src/video/serenity/SDL_serenityevents.cpp +new file mode 100644 +index 0000000..04cbf21 +--- /dev/null ++++ b/src/video/serenity/SDL_serenityevents.cpp +@@ -0,0 +1,52 @@ ++/* ++ Simple DirectMedia Layer ++ Copyright (C) 1997-2021 Sam Lantinga ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++*/ ++#include "../../SDL_internal.h" ++ ++#if SDL_VIDEO_DRIVER_SERENITY ++#define AK_DONT_REPLACE_STD ++ ++#include "../../events/SDL_events_c.h" ++ ++#include "SDL_serenityvideo.h" ++#include "SDL_serenityevents_c.h" ++#include "SDL_timer.h" ++ ++#include ++ ++void ++SERENITY_PumpEvents(_THIS) ++{ ++ auto& loop = Core::EventLoop::current(); ++ if (loop.was_exit_requested()) ++ exit(0); ++ ++ auto const event_loop_timeout_ms = SDL_GetTicks() + 100; ++ while (loop.pump(Core::EventLoop::WaitMode::PollForEvents) > 0) { ++ if (SDL_TICKS_PASSED(SDL_GetTicks(), event_loop_timeout_ms)) ++ break; ++ } ++ ++} ++ ++ ++#endif /* SDL_VIDEO_DRIVER_SERENITY */ ++ ++/* vi: set ts=4 sw=4 expandtab: */ +diff --git a/src/video/serenity/SDL_serenityevents_c.h b/src/video/serenity/SDL_serenityevents_c.h +new file mode 100644 +index 0000000..89e9e91 +--- /dev/null ++++ b/src/video/serenity/SDL_serenityevents_c.h +@@ -0,0 +1,33 @@ ++/* ++ Simple DirectMedia Layer ++ Copyright (C) 1997-2019 Sam Lantinga ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++*/ ++ ++#ifndef SDL_serenityevents_c_h_ ++#define SDL_serenityevents_c_h_ ++ ++#include "../../SDL_internal.h" ++ ++#include "SDL_serenityvideo.h" ++ ++extern void SERENITY_PumpEvents(_THIS); ++ ++#endif /* SDL_serenityevents_c_h_ */ ++ ++/* vi: set ts=4 sw=4 expandtab: */ +diff --git a/src/video/serenity/SDL_serenitymessagebox.cpp b/src/video/serenity/SDL_serenitymessagebox.cpp +new file mode 100644 +index 0000000..ac5e358 +--- /dev/null ++++ b/src/video/serenity/SDL_serenitymessagebox.cpp +@@ -0,0 +1,40 @@ ++/* ++ Simple DirectMedia Layer ++ Copyright (C) 1997-2019 Sam Lantinga ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++ */ ++ ++#include "../../SDL_internal.h" ++ ++#if SDL_VIDEO_DRIVER_SERENITY ++# define AK_DONT_REPLACE_STD ++ ++# include "SDL_messagebox.h" ++# include "SDL_serenitymessagebox.h" ++ ++# include ++ ++extern "C" int SERENITY_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) ++{ ++ GUI::MessageBox::show(nullptr, messageboxdata->message, messageboxdata->title); ++ return 0; ++} ++ ++#endif /* SDL_VIDEO_DRIVER_SERENITY */ ++ ++/* vi: set ts=4 sw=4 expandtab: */ +diff --git a/src/video/serenity/SDL_serenitymessagebox.h b/src/video/serenity/SDL_serenitymessagebox.h +new file mode 100644 +index 0000000..34e6077 +--- /dev/null ++++ b/src/video/serenity/SDL_serenitymessagebox.h +@@ -0,0 +1,38 @@ ++/* ++ Simple DirectMedia Layer ++ Copyright (C) 1997-2019 Sam Lantinga ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++*/ ++#include "../../SDL_internal.h" ++ ++#ifndef SDL_serenitymessagebox_h_ ++#define SDL_serenitymessagebox_h_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++int SERENITY_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* SDL_serenitymessagebox_h_ */ ++ ++/* vi: set ts=4 sw=4 expandtab: */ +diff --git a/src/video/serenity/SDL_serenitymouse.cpp b/src/video/serenity/SDL_serenitymouse.cpp +new file mode 100644 +index 0000000..5d0cb52 +--- /dev/null ++++ b/src/video/serenity/SDL_serenitymouse.cpp +@@ -0,0 +1,142 @@ ++/* ++ Simple DirectMedia Layer ++ Copyright (C) 1997-2021 Sam Lantinga ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++*/ ++#include "../../SDL_internal.h" ++ ++#if SDL_VIDEO_DRIVER_SERENITY ++#define AK_DONT_REPLACE_STD ++ ++/* ++ * SDL includes: ++ */ ++extern "C" { ++#include "../../events/SDL_mouse_c.h" ++#include "../../events/SDL_touch_c.h" ++#include "../SDL_sysvideo.h" ++#include "SDL_events.h" ++} ++ ++#include "SDL_serenitymouse.h" ++#include "SDL_serenityvideo.h" ++ ++#include ++ ++struct SerenityCursorData final { ++ Gfx::StandardCursor cursor_type; ++}; ++ ++static SDL_Cursor* ++SERENITY_CreateSystemCursor(SDL_SystemCursor id) ++{ ++ auto cursor = static_cast(SDL_calloc(1, sizeof(SDL_Cursor))); ++ if (!cursor) ++ SDL_OutOfMemory(); ++ ++ auto cursor_data = static_cast(SDL_calloc(1, sizeof(SerenityCursorData))); ++ if (!cursor_data) ++ SDL_OutOfMemory(); ++ cursor->driverdata = static_cast(cursor_data); ++ ++ switch(id) ++ { ++ case SDL_SYSTEM_CURSOR_ARROW: cursor_data->cursor_type = Gfx::StandardCursor::Arrow; break; ++ case SDL_SYSTEM_CURSOR_IBEAM: cursor_data->cursor_type = Gfx::StandardCursor::IBeam; break; ++ case SDL_SYSTEM_CURSOR_WAIT: cursor_data->cursor_type = Gfx::StandardCursor::Wait; break; ++ case SDL_SYSTEM_CURSOR_CROSSHAIR: cursor_data->cursor_type = Gfx::StandardCursor::Crosshair; break; ++ case SDL_SYSTEM_CURSOR_WAITARROW: cursor_data->cursor_type = Gfx::StandardCursor::Wait; break; ++ case SDL_SYSTEM_CURSOR_SIZENWSE: cursor_data->cursor_type = Gfx::StandardCursor::ResizeDiagonalTLBR; break; ++ case SDL_SYSTEM_CURSOR_SIZENESW: cursor_data->cursor_type = Gfx::StandardCursor::ResizeDiagonalBLTR; break; ++ case SDL_SYSTEM_CURSOR_SIZEWE: cursor_data->cursor_type = Gfx::StandardCursor::ResizeHorizontal; break; ++ case SDL_SYSTEM_CURSOR_SIZENS: cursor_data->cursor_type = Gfx::StandardCursor::ResizeVertical; break; ++ case SDL_SYSTEM_CURSOR_SIZEALL: cursor_data->cursor_type = Gfx::StandardCursor::Move; break; ++ case SDL_SYSTEM_CURSOR_NO: cursor_data->cursor_type = Gfx::StandardCursor::Disallowed; break; ++ case SDL_SYSTEM_CURSOR_HAND: cursor_data->cursor_type = Gfx::StandardCursor::Hand; break; ++ default: ++ SDL_assert(0); ++ return nullptr; ++ } ++ return cursor; ++} ++ ++static SDL_Cursor* ++SERENITY_CreateDefaultCursor() ++{ ++ return SERENITY_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); ++} ++ ++static void ++SERENITY_FreeCursor(SDL_Cursor* cursor) ++{ ++ if (cursor->driverdata) ++ SDL_free(cursor->driverdata); ++ SDL_free(cursor); ++} ++ ++static int ++SERENITY_ShowCursor(SDL_Cursor* cursor) ++{ ++ auto focused_window = SDL_GetMouseFocus(); ++ if (!focused_window) ++ return -1; ++ ++ auto platform_window = SerenityPlatformWindow::from_sdl_window(focused_window); ++ ++ // Hide the cursor ++ if (cursor == nullptr) { ++ platform_window->window()->set_cursor(Gfx::StandardCursor::Hidden); ++ return 0; ++ } ++ ++ auto cursor_data = static_cast(cursor->driverdata); ++ if (!cursor_data) ++ return -1; ++ ++ platform_window->window()->set_cursor(cursor_data->cursor_type); ++ return 0; ++} ++ ++void ++SERENITY_InitMouse(_THIS) ++{ ++ dbgln("SERENITY_InitMouse"); ++ ++ auto mouse = SDL_GetMouse(); ++ ++ mouse->CreateSystemCursor = SERENITY_CreateSystemCursor; ++ mouse->ShowCursor = SERENITY_ShowCursor; ++ mouse->FreeCursor = SERENITY_FreeCursor; ++ ++ // FIXME: implement below methods ++ //mouse->CreateCursor = ...; ++ //mouse->WarpMouse = ...; ++ //mouse->SetRelativeMouseMode = ...; ++ ++ SDL_SetDefaultCursor(SERENITY_CreateDefaultCursor()); ++} ++ ++void ++SERENITY_QuitMouse(_THIS) ++{ ++ dbgln("SERENITY_QuitMouse"); ++} ++ ++#endif /* SDL_VIDEO_DRIVER_SERENITY */ ++ ++/* vi: set ts=4 sw=4 expandtab: */ +diff --git a/src/video/serenity/SDL_serenitymouse.h b/src/video/serenity/SDL_serenitymouse.h +new file mode 100644 +index 0000000..039f036 +--- /dev/null ++++ b/src/video/serenity/SDL_serenitymouse.h +@@ -0,0 +1,39 @@ ++/* ++ Simple DirectMedia Layer ++ Copyright (C) 1997-2021 Sam Lantinga ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++*/ ++#include "SDL_config.h" ++ ++#ifndef SDL_serenitymouse_h_ ++#define SDL_serenitymouse_h_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++extern void SERENITY_InitMouse(_THIS); ++extern void SERENITY_QuitMouse(_THIS); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* SDL_serenitymouse_h_ */ ++ ++/* vi: set ts=4 sw=4 expandtab: */ +diff --git a/src/video/serenity/SDL_serenityvideo.cpp b/src/video/serenity/SDL_serenityvideo.cpp +new file mode 100644 +index 0000000..30fcadb +--- /dev/null ++++ b/src/video/serenity/SDL_serenityvideo.cpp +@@ -0,0 +1,717 @@ ++/* ++ Simple DirectMedia Layer ++ Copyright (C) 1997-2019 Sam Lantinga ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++ */ ++extern "C" { ++ ++#include "../../SDL_internal.h" ++ ++#if SDL_VIDEO_DRIVER_SERENITY ++# define AK_DONT_REPLACE_STD ++ ++# include "../../events/SDL_events_c.h" ++# include "../SDL_pixels_c.h" ++# include "../SDL_sysvideo.h" ++# include "SDL_mouse.h" ++# include "SDL_video.h" ++# include "../../../include/SDL_scancode.h" ++} ++ ++# include "SDL_serenityevents_c.h" ++# include "SDL_serenitymouse.h" ++# include "SDL_serenityvideo.h" ++ ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++ ++static int conversion_map[] = { ++ SDLK_UNKNOWN, ++ SDLK_ESCAPE, ++ SDLK_TAB, ++ SDLK_BACKSPACE, ++ SDLK_RETURN, ++ SDLK_INSERT, ++ SDLK_DELETE, ++ SDLK_PRINTSCREEN, ++ SDLK_SYSREQ, ++ SDLK_HOME, ++ SDLK_END, ++ SDLK_LEFT, ++ SDLK_UP, ++ SDLK_RIGHT, ++ SDLK_DOWN, ++ SDLK_PAGEUP, ++ SDLK_PAGEDOWN, ++ SDLK_LSHIFT, ++ SDLK_RSHIFT, ++ SDLK_LCTRL, ++ SDLK_LALT, ++ SDLK_CAPSLOCK, ++ SDLK_NUMLOCKCLEAR, ++ SDLK_SCROLLLOCK, ++ SDLK_F1, ++ SDLK_F2, ++ SDLK_F3, ++ SDLK_F4, ++ SDLK_F5, ++ SDLK_F6, ++ SDLK_F7, ++ SDLK_F8, ++ SDLK_F9, ++ SDLK_F10, ++ SDLK_F11, ++ SDLK_F12, ++ SDLK_SPACE, ++ SDLK_EXCLAIM, ++ SDLK_QUOTE, ++ SDLK_3, ++ SDLK_4, ++ SDLK_5, ++ SDLK_7, ++ SDLK_QUOTE, ++ SDLK_9, ++ SDLK_0, ++ SDLK_8, ++ SDLK_PLUS, ++ SDLK_COMMA, ++ SDLK_MINUS, ++ SDLK_PERIOD, ++ SDLK_SLASH, ++ SDLK_0, ++ SDLK_1, ++ SDLK_2, ++ SDLK_3, ++ SDLK_4, ++ SDLK_5, ++ SDLK_6, ++ SDLK_7, ++ SDLK_8, ++ SDLK_9, ++ SDLK_SEMICOLON, ++ SDLK_SEMICOLON, ++ SDLK_COMMA, ++ SDLK_EQUALS, ++ SDLK_PERIOD, ++ SDLK_SLASH, ++ SDLK_2, ++ SDLK_a, ++ SDLK_b, ++ SDLK_c, ++ SDLK_d, ++ SDLK_e, ++ SDLK_f, ++ SDLK_g, ++ SDLK_h, ++ SDLK_i, ++ SDLK_j, ++ SDLK_k, ++ SDLK_l, ++ SDLK_m, ++ SDLK_n, ++ SDLK_o, ++ SDLK_p, ++ SDLK_q, ++ SDLK_r, ++ SDLK_s, ++ SDLK_t, ++ SDLK_u, ++ SDLK_v, ++ SDLK_w, ++ SDLK_x, ++ SDLK_y, ++ SDLK_z, ++ SDLK_LEFTBRACKET, ++ SDLK_RIGHTBRACKET, ++ SDLK_BACKSLASH, ++ SDLK_6, ++ SDLK_MINUS, ++ SDLK_LEFTBRACKET, ++ SDLK_RIGHTBRACKET, ++ SDLK_BACKSLASH, ++ SDLK_BACKQUOTE, ++ SDLK_BACKQUOTE, ++ SDLK_UNKNOWN, ++}; ++ ++static SDL_Scancode scancode_map[] = { ++ SDL_SCANCODE_UNKNOWN, ++ SDL_SCANCODE_ESCAPE, ++ SDL_SCANCODE_TAB, ++ SDL_SCANCODE_BACKSPACE, ++ SDL_SCANCODE_RETURN, ++ SDL_SCANCODE_INSERT, ++ SDL_SCANCODE_DELETE, ++ SDL_SCANCODE_PRINTSCREEN, ++ SDL_SCANCODE_SYSREQ, ++ SDL_SCANCODE_HOME, ++ SDL_SCANCODE_END, ++ SDL_SCANCODE_LEFT, ++ SDL_SCANCODE_UP, ++ SDL_SCANCODE_RIGHT, ++ SDL_SCANCODE_DOWN, ++ SDL_SCANCODE_PAGEUP, ++ SDL_SCANCODE_PAGEDOWN, ++ SDL_SCANCODE_LSHIFT, ++ SDL_SCANCODE_RSHIFT, ++ SDL_SCANCODE_LCTRL, ++ SDL_SCANCODE_LALT, ++ SDL_SCANCODE_CAPSLOCK, ++ SDL_SCANCODE_NUMLOCKCLEAR, ++ SDL_SCANCODE_SCROLLLOCK, ++ SDL_SCANCODE_F1, ++ SDL_SCANCODE_F2, ++ SDL_SCANCODE_F3, ++ SDL_SCANCODE_F4, ++ SDL_SCANCODE_F5, ++ SDL_SCANCODE_F6, ++ SDL_SCANCODE_F7, ++ SDL_SCANCODE_F8, ++ SDL_SCANCODE_F9, ++ SDL_SCANCODE_F10, ++ SDL_SCANCODE_F11, ++ SDL_SCANCODE_F12, ++ SDL_SCANCODE_SPACE, ++ SDL_SCANCODE_1, ++ SDL_SCANCODE_APOSTROPHE, ++ SDL_SCANCODE_3, ++ SDL_SCANCODE_4, ++ SDL_SCANCODE_5, ++ SDL_SCANCODE_7, ++ SDL_SCANCODE_APOSTROPHE, ++ SDL_SCANCODE_9, ++ SDL_SCANCODE_0, ++ SDL_SCANCODE_8, ++ SDL_SCANCODE_EQUALS, ++ SDL_SCANCODE_COMMA, ++ SDL_SCANCODE_MINUS, ++ SDL_SCANCODE_PERIOD, ++ SDL_SCANCODE_SLASH, ++ SDL_SCANCODE_0, ++ SDL_SCANCODE_1, ++ SDL_SCANCODE_2, ++ SDL_SCANCODE_3, ++ SDL_SCANCODE_4, ++ SDL_SCANCODE_5, ++ SDL_SCANCODE_6, ++ SDL_SCANCODE_7, ++ SDL_SCANCODE_8, ++ SDL_SCANCODE_9, ++ SDL_SCANCODE_SEMICOLON, ++ SDL_SCANCODE_SEMICOLON, ++ SDL_SCANCODE_COMMA, ++ SDL_SCANCODE_EQUALS, ++ SDL_SCANCODE_PERIOD, ++ SDL_SCANCODE_SLASH, ++ SDL_SCANCODE_2, ++ SDL_SCANCODE_A, ++ SDL_SCANCODE_B, ++ SDL_SCANCODE_C, ++ SDL_SCANCODE_D, ++ SDL_SCANCODE_E, ++ SDL_SCANCODE_F, ++ SDL_SCANCODE_G, ++ SDL_SCANCODE_H, ++ SDL_SCANCODE_I, ++ SDL_SCANCODE_J, ++ SDL_SCANCODE_K, ++ SDL_SCANCODE_L, ++ SDL_SCANCODE_M, ++ SDL_SCANCODE_N, ++ SDL_SCANCODE_O, ++ SDL_SCANCODE_P, ++ SDL_SCANCODE_Q, ++ SDL_SCANCODE_R, ++ SDL_SCANCODE_S, ++ SDL_SCANCODE_T, ++ SDL_SCANCODE_U, ++ SDL_SCANCODE_V, ++ SDL_SCANCODE_W, ++ SDL_SCANCODE_X, ++ SDL_SCANCODE_Y, ++ SDL_SCANCODE_Z, ++ SDL_SCANCODE_LEFTBRACKET, ++ SDL_SCANCODE_RIGHTBRACKET, ++ SDL_SCANCODE_BACKSLASH, ++ SDL_SCANCODE_6, ++ SDL_SCANCODE_MINUS, ++ SDL_SCANCODE_LEFTBRACKET, ++ SDL_SCANCODE_RIGHTBRACKET, ++ SDL_SCANCODE_BACKSLASH, ++ SDL_SCANCODE_GRAVE, ++ SDL_SCANCODE_GRAVE, ++ SDL_SCANCODE_UNKNOWN, ++}; ++ ++/* Initialization/Query functions */ ++static int SERENITY_VideoInit(_THIS); ++static int SERENITY_SetDisplayMode(_THIS, SDL_VideoDisplay* display, ++ SDL_DisplayMode* mode); ++static void SERENITY_VideoQuit(_THIS); ++ ++/* SERENITY driver bootstrap functions */ ++ ++static int SERENITY_Available(void) { return (1); } ++ ++static void SERENITY_DeleteDevice(SDL_VideoDevice* device) ++{ ++ dbgln("SERENITY_DeleteDevice"); ++ SDL_free(device); ++} ++ ++extern int Serenity_CreateWindow(_THIS, SDL_Window* window); ++extern void Serenity_ShowWindow(_THIS, SDL_Window* window); ++extern void Serenity_HideWindow(_THIS, SDL_Window* window); ++extern void Serenity_SetWindowTitle(_THIS, SDL_Window* window); ++extern void Serenity_SetWindowSize(_THIS, SDL_Window* window); ++extern void Serenity_SetWindowFullscreen(_THIS, SDL_Window* window, ++ SDL_VideoDisplay* display, ++ SDL_bool fullscreen); ++extern void Serenity_SetWindowIcon(_THIS, SDL_Window* window, SDL_Surface* icon); ++extern void Serenity_DestroyWindow(_THIS, SDL_Window* window); ++extern int Serenity_CreateWindowFramebuffer(_THIS, SDL_Window* window, ++ Uint32* format, void** pixels, ++ int* pitch); ++extern int Serenity_UpdateWindowFramebuffer(_THIS, SDL_Window* window, ++ const SDL_Rect* rects, ++ int numrects); ++extern void Serenity_DestroyWindowFramebuffer(_THIS, SDL_Window* window); ++extern SDL_GLContext Serenity_GL_CreateContext(_THIS, SDL_Window* window); ++extern void Serenity_GL_DeleteContext(_THIS, SDL_GLContext context); ++extern void* Serenity_GL_GetProcAddress(_THIS, const char* proc); ++extern int Serenity_GL_LoadLibrary(_THIS, const char* path); ++extern int Serenity_GL_MakeCurrent(_THIS, SDL_Window* window, SDL_GLContext context); ++extern int Serenity_GL_SwapWindow(_THIS, SDL_Window* window); ++ ++static SDL_VideoDevice* SERENITY_CreateDevice(int devindex) ++{ ++ SDL_VideoDevice* device; ++ ++ dbgln("SERENITY_CreateDevice {}", devindex); ++ /* Initialize all variables that we clean on shutdown */ ++ device = (SDL_VideoDevice*)SDL_calloc(1, sizeof(SDL_VideoDevice)); ++ if (!device) { ++ SDL_OutOfMemory(); ++ return (0); ++ } ++ device->is_dummy = SDL_FALSE; ++ ++ /* Set the function pointers */ ++ device->VideoInit = SERENITY_VideoInit; ++ device->VideoQuit = SERENITY_VideoQuit; ++ device->SetDisplayMode = SERENITY_SetDisplayMode; ++ device->PumpEvents = SERENITY_PumpEvents; ++ ++ device->CreateWindowFramebuffer = Serenity_CreateWindowFramebuffer; ++ device->UpdateWindowFramebuffer = Serenity_UpdateWindowFramebuffer; ++ device->DestroyWindowFramebuffer = Serenity_DestroyWindowFramebuffer; ++ device->CreateSDLWindow = Serenity_CreateWindow; ++ device->ShowWindow = Serenity_ShowWindow; ++ device->HideWindow = Serenity_HideWindow; ++ device->SetWindowTitle = Serenity_SetWindowTitle; ++ device->SetWindowSize = Serenity_SetWindowSize; ++ device->SetWindowFullscreen = Serenity_SetWindowFullscreen; ++ device->SetWindowIcon = Serenity_SetWindowIcon; ++ device->DestroyWindow = Serenity_DestroyWindow; ++ ++ device->GL_CreateContext = Serenity_GL_CreateContext; ++ device->GL_DeleteContext = Serenity_GL_DeleteContext; ++ device->GL_GetProcAddress = Serenity_GL_GetProcAddress; ++ device->GL_LoadLibrary = Serenity_GL_LoadLibrary; ++ device->GL_MakeCurrent = Serenity_GL_MakeCurrent; ++ device->GL_SwapWindow = Serenity_GL_SwapWindow; ++ ++ device->free = SERENITY_DeleteDevice; ++ ++ Serenity_GL_LoadLibrary(device, nullptr); ++ ++ return device; ++} ++ ++VideoBootStrap SERENITYVIDEO_bootstrap = { "serenity", "SDL serenity video driver", SERENITY_CreateDevice }; ++ ++static RefPtr g_app; ++ ++int SERENITY_VideoInit(_THIS) ++{ ++ VERIFY(!g_app); ++ g_app = GUI::Application::construct(0, nullptr); ++ g_app->set_quit_when_last_window_deleted(false); ++ ++ dbgln("SDL2: Initialising SDL application"); ++ ++ SERENITY_InitMouse(_this); ++ ++ // We only add the active desktop resolution until we properly support multiple ++ // fullscreen resolutions ++ auto desktop_rect = GUI::Desktop::the().rect(); ++ ++ SDL_DisplayMode mode; ++ mode.format = SDL_PIXELFORMAT_RGB888; ++ mode.w = desktop_rect.width(); ++ mode.h = desktop_rect.height(); ++ mode.refresh_rate = 60; ++ mode.driverdata = nullptr; ++ ++ if (SDL_AddBasicVideoDisplay(&mode) < 0) { ++ return -1; ++ } ++ ++ SDL_AddDisplayMode(&_this->displays[0], &mode); ++ ++ /* We're done! */ ++ return 0; ++} ++ ++static int SERENITY_SetDisplayMode(_THIS, SDL_VideoDisplay* display, ++ SDL_DisplayMode* mode) ++{ ++ dbgln("SERENITY_SetDisplayMode"); ++ return 0; ++} ++ ++void SERENITY_VideoQuit(_THIS) ++{ ++ dbgln("SERENITY_VideoQuit"); ++ SERENITY_QuitMouse(_this); ++ g_app->quit(); ++} ++ ++SerenitySDLWidget::SerenitySDLWidget(SDL_Window* window) ++ : m_sdl_window(window) ++{ ++ SDL_Keycode keymap[SDL_NUM_SCANCODES]; ++ SDL_GetDefaultKeymap(keymap); ++ ++ for (int i = 0; i < (sizeof(scancode_map) / sizeof(SDL_Keycode)); ++i) { ++ if (scancode_map[i] != SDL_SCANCODE_UNKNOWN) ++ keymap[scancode_map[i]] = conversion_map[i]; ++ } ++ SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES); ++ ++ update(); ++} ++ ++void SerenitySDLWidget::paint_event(GUI::PaintEvent& event) ++{ ++ GUI::Painter painter(*this); ++ painter.add_clip_rect(event.rect()); ++ painter.blit(event.rect().location(), *m_buffer, event.rect()); ++} ++ ++void SerenitySDLWidget::resize_event(GUI::ResizeEvent&) ++{ ++ SDL_SendWindowEvent(m_sdl_window, SDL_WINDOWEVENT_RESIZED, width(), height()); ++} ++void SerenitySDLWidget::show_event(GUI::ShowEvent&) ++{ ++ SDL_SendWindowEvent(m_sdl_window, SDL_WINDOWEVENT_SHOWN, 0, 0); ++} ++void SerenitySDLWidget::hide_event(GUI::HideEvent&) ++{ ++ SDL_SendWindowEvent(m_sdl_window, SDL_WINDOWEVENT_HIDDEN, 0, 0); ++} ++ ++static int map_button(GUI::MouseButton button) ++{ ++ switch (button) { ++ case GUI::MouseButton::Primary: ++ return SDL_BUTTON_LEFT; ++ case GUI::MouseButton::Middle: ++ return SDL_BUTTON_MIDDLE; ++ case GUI::MouseButton::Secondary: ++ return SDL_BUTTON_RIGHT; ++ case GUI::MouseButton::Forward: ++ return SDL_BUTTON_X1; ++ case GUI::MouseButton::Backward: ++ return SDL_BUTTON_X2; ++ } ++ ++ VERIFY_NOT_REACHED(); ++ return 0; ++} ++ ++void SerenitySDLWidget::mousedown_event(GUI::MouseEvent& event) ++{ ++ SDL_SendMouseMotion(m_sdl_window, 0, 0, event.x(), event.y()); ++ SDL_SendMouseButton(m_sdl_window, 0, SDL_PRESSED, map_button(event.button())); ++} ++ ++void SerenitySDLWidget::mousemove_event(GUI::MouseEvent& event) ++{ ++ SDL_SendMouseMotion(m_sdl_window, 0, 0, event.x(), event.y()); ++} ++ ++void SerenitySDLWidget::mouseup_event(GUI::MouseEvent& event) ++{ ++ SDL_SendMouseMotion(m_sdl_window, 0, 0, event.x(), event.y()); ++ SDL_SendMouseButton(m_sdl_window, 0, SDL_RELEASED, map_button(event.button())); ++} ++ ++void SerenitySDLWidget::mousewheel_event(GUI::MouseEvent& event) ++{ ++ SDL_SendMouseMotion(m_sdl_window, 0, 0, event.x(), event.y()); ++ SDL_SendMouseWheel(m_sdl_window, 0, (float)event.wheel_raw_delta_x(), -(float)event.wheel_raw_delta_y(), SDL_MOUSEWHEEL_NORMAL); ++} ++ ++void SerenitySDLWidget::keydown_event(GUI::KeyEvent& event) ++{ ++ SDL_SendKeyboardKey(SDL_PRESSED, scancode_map[event.key()]); ++ auto text = event.text(); ++ if (!text.is_empty()) ++ SDL_SendKeyboardText(text.characters()); ++} ++ ++void SerenitySDLWidget::keyup_event(GUI::KeyEvent& event) ++{ ++ SDL_SendKeyboardKey(SDL_RELEASED, scancode_map[event.key()]); ++} ++ ++void SerenitySDLWidget::enter_event(Core::Event&) ++{ ++ SDL_SetMouseFocus(m_sdl_window); ++} ++ ++void SerenitySDLWidget::leave_event(Core::Event&) ++{ ++ SDL_SetMouseFocus(nullptr); ++} ++ ++int Serenity_CreateWindow(_THIS, SDL_Window* window) ++{ ++ dbgln("SDL2: Creating new window of size {}x{}", window->w, window->h); ++ auto w = new SerenityPlatformWindow(window); ++ window->driverdata = w; ++ w->window()->set_double_buffering_enabled(false); ++ w->widget()->set_fill_with_background_color(false); ++ w->window()->set_main_widget(w->widget()); ++ w->window()->on_close_request = [] { ++ if (SDL_SendQuit()) ++ return GUI::Window::CloseRequestDecision::Close; ++ return GUI::Window::CloseRequestDecision::StayOpen; ++ }; ++ SERENITY_PumpEvents(_this); ++ ++ return 0; ++} ++ ++void Serenity_ShowWindow(_THIS, SDL_Window* window) ++{ ++ SerenityPlatformWindow::from_sdl_window(window)->window()->show(); ++} ++ ++void Serenity_HideWindow(_THIS, SDL_Window* window) ++{ ++ SerenityPlatformWindow::from_sdl_window(window)->window()->hide(); ++} ++ ++void Serenity_SetWindowTitle(_THIS, SDL_Window* window) ++{ ++ SerenityPlatformWindow::from_sdl_window(window)->window()->set_title(window->title); ++} ++ ++void Serenity_SetWindowSize(_THIS, SDL_Window* window) ++{ ++ SerenityPlatformWindow::from_sdl_window(window)->window()->resize(window->w, window->h); ++} ++ ++void Serenity_SetWindowFullscreen(_THIS, SDL_Window* window, ++ SDL_VideoDisplay* display, ++ SDL_bool fullscreen) ++{ ++ dbgln("Attempting to set SDL Window fullscreen to {}", (bool)fullscreen); ++ SerenityPlatformWindow::from_sdl_window(window)->window()->set_fullscreen(fullscreen); ++} ++ ++static Gfx::Color get_color_from_sdl_pixel(SDL_PixelFormat const& format, u32 pixel) ++{ ++ u8 r = ((pixel & format.Rmask) >> format.Rshift) << format.Rloss; ++ u8 g = ((pixel & format.Gmask) >> format.Gshift) << format.Gloss; ++ u8 b = ((pixel & format.Bmask) >> format.Bshift) << format.Bloss; ++ u8 a = ((pixel & format.Amask) >> format.Ashift) << format.Aloss; ++ return {r, g, b, a}; ++} ++ ++static RefPtr create_bitmap_from_surface(SDL_Surface& icon) ++{ ++ auto bitmap_or_error = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, {icon.w, icon.h}); ++ if (bitmap_or_error.is_error()) ++ return {}; ++ auto bitmap = bitmap_or_error.release_value(); ++ ++ SDL_LockSurface(&icon); ++ ++ auto const& pixel_format = *icon.format; ++ auto pixels = static_cast(icon.pixels); ++ size_t offset = 0; ++ switch (pixel_format.format) { ++ case SDL_PIXELFORMAT_ARGB8888: ++ for (size_t y = 0; y < icon.h; ++y) { ++ for (size_t x = 0; x < icon.w; ++x) { ++ bitmap->set_pixel({x, y}, get_color_from_sdl_pixel(pixel_format, pixels[offset])); ++ ++offset; ++ } ++ } ++ break; ++ default: ++ warnln("Unable to convert SDL_Surface with format {} to bitmap", SDL_GetPixelFormatName(pixel_format.format)); ++ } ++ ++ SDL_UnlockSurface(&icon); ++ ++ return bitmap; ++} ++ ++void Serenity_SetWindowIcon(_THIS, SDL_Window* window, SDL_Surface* icon) ++{ ++ auto serenity_window = SerenityPlatformWindow::from_sdl_window(window)->window(); ++ if (!icon) { ++ serenity_window->set_icon(nullptr); ++ return; ++ } ++ ++ auto icon_bitmap = create_bitmap_from_surface(*icon); ++ if (icon_bitmap) ++ serenity_window->set_icon(icon_bitmap); ++} ++ ++void Serenity_DestroyWindow(_THIS, SDL_Window* window) ++{ ++ auto platform_window = SerenityPlatformWindow::from_sdl_window(window); ++ delete platform_window; ++ window->driverdata = nullptr; ++} ++ ++int Serenity_CreateWindowFramebuffer(_THIS, SDL_Window* window, Uint32* format, ++ void** pixels, int* pitch) ++{ ++ dbgln("SDL2: Creating a new framebuffer of size {}x{}", window->w, window->h); ++ auto win = SerenityPlatformWindow::from_sdl_window(window); ++ *format = SDL_PIXELFORMAT_RGB888; ++ auto bitmap_or_error = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRx8888, {window->w, window->h}); ++ if (bitmap_or_error.is_error()) ++ return SDL_OutOfMemory(); ++ win->widget()->m_buffer = bitmap_or_error.release_value(); ++ *pitch = win->widget()->m_buffer->pitch(); ++ *pixels = win->widget()->m_buffer->scanline(0); ++ dbgln("Created framebuffer {}x{}", win->widget()->width(), win->widget()->height()); ++ return 0; ++} ++ ++int Serenity_UpdateWindowFramebuffer(_THIS, SDL_Window* window, ++ const SDL_Rect* rects, int numrects) ++{ ++ auto win = SerenityPlatformWindow::from_sdl_window(window); ++ for (int i = 0; i < numrects; i++) { ++ win->widget()->update(Gfx::IntRect(rects[i].x, rects[i].y, rects[i].w, rects[i].h)); ++ } ++ SERENITY_PumpEvents(_this); ++ ++ return 0; ++} ++ ++void Serenity_DestroyWindowFramebuffer(_THIS, SDL_Window* window) ++{ ++ auto widget = SerenityPlatformWindow::from_sdl_window(window)->widget(); ++ dbgln("SDL2: Destroy framebuffer {}", widget->m_buffer->size()); ++ widget->m_buffer = nullptr; ++} ++ ++SDL_GLContext Serenity_GL_CreateContext(_THIS, SDL_Window* window) ++{ ++ auto win = SerenityPlatformWindow::from_sdl_window(window); ++ ++ Uint32 format; ++ void* pixels; ++ int pitch; ++ Serenity_CreateWindowFramebuffer(_this, window, &format, &pixels, &pitch); ++ ++ win->widget()->m_gl_context = GL::create_context(*win->widget()->m_buffer); ++ GL::make_context_current(win->widget()->m_gl_context); ++ ++ return new SerenityGLContext(*window); ++} ++ ++void Serenity_GL_DeleteContext(_THIS, SDL_GLContext context) ++{ ++ auto platform_context = static_cast(context); ++ auto sdl_window = platform_context->sdl_window(); ++ auto platform_window = SerenityPlatformWindow::from_sdl_window(&sdl_window); ++ ++ platform_window->widget()->m_gl_context = nullptr; ++ delete platform_context; ++} ++ ++int Serenity_GL_LoadLibrary(_THIS, const char* path) ++{ ++ if (_this->gl_config.driver_loaded) { ++ SDL_SetError("OpenGL library is already loaded"); ++ return -1; ++ } ++ ++ _this->gl_config.dll_handle = dlopen("libgl.so.serenity", RTLD_LAZY | RTLD_LOCAL); ++ if (!_this->gl_config.dll_handle) { ++ dbgln("Could not load OpenGL library: {}", dlerror()); ++ _this->gl_config.driver_loaded = SDL_FALSE; ++ return -1; ++ } ++ ++ _this->gl_config.driver_loaded = SDL_TRUE; ++ return 0; ++} ++ ++void* Serenity_GL_GetProcAddress(_THIS, const char* proc) ++{ ++ if (!_this->gl_config.dll_handle) { ++ SDL_SetError("OpenGL library not available"); ++ return nullptr; ++ } ++ auto* res = dlsym(_this->gl_config.dll_handle, proc); ++ dbgln("GetProcAddress: {} -> {}", proc, res); ++ return res; ++} ++ ++int Serenity_GL_MakeCurrent(_THIS, SDL_Window* window, SDL_GLContext context) ++{ ++ if (!window || !context) ++ return 0; ++ ++ auto platform_window = SerenityPlatformWindow::from_sdl_window(window); ++ GL::make_context_current(platform_window->widget()->m_gl_context); ++ return 0; ++} ++ ++int Serenity_GL_SwapWindow(_THIS, SDL_Window* window) ++{ ++ auto win = SerenityPlatformWindow::from_sdl_window(window); ++ if (win->widget()->m_gl_context) ++ GL::present_context(win->widget()->m_gl_context); ++ ++ win->widget()->repaint(); ++ return 0; ++} ++ ++#endif /* SDL_VIDEO_DRIVER_SERENITY */ ++ ++/* vi: set ts=4 sw=4 expandtab: */ +diff --git a/src/video/serenity/SDL_serenityvideo.h b/src/video/serenity/SDL_serenityvideo.h +new file mode 100644 +index 0000000..b5c6759 +--- /dev/null ++++ b/src/video/serenity/SDL_serenityvideo.h +@@ -0,0 +1,98 @@ ++/* ++ Simple DirectMedia Layer ++ Copyright (C) 1997-2019 Sam Lantinga ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++*/ ++#include "../../SDL_internal.h" ++ ++#ifndef SDL_serenityvideo_h_ ++#define SDL_serenityvideo_h_ ++ ++#include "../SDL_sysvideo.h" ++ ++#include ++#include ++#include ++ ++class SerenitySDLWidget final : public GUI::Widget { ++ C_OBJECT(SerenitySDLWidget) ++public: ++ explicit SerenitySDLWidget(SDL_Window*); ++ RefPtr m_buffer; ++ OwnPtr m_gl_context; ++ ++protected: ++ void paint_event(GUI::PaintEvent&) override; ++ void resize_event(GUI::ResizeEvent&) override; ++ void show_event(GUI::ShowEvent&) override; ++ void hide_event(GUI::HideEvent&) override; ++ ++ void mousedown_event(GUI::MouseEvent&) override; ++ void mousemove_event(GUI::MouseEvent&) override; ++ void mouseup_event(GUI::MouseEvent&) override; ++ void mousewheel_event(GUI::MouseEvent&) override; ++ ++ void keydown_event(GUI::KeyEvent& event) override; ++ void keyup_event(GUI::KeyEvent& event) override; ++ ++ void enter_event(Core::Event&) override; ++ void leave_event(Core::Event&) override; ++ ++private: ++ SDL_Window* m_sdl_window = nullptr; ++}; ++ ++class SerenityPlatformWindow final { ++public: ++ SerenityPlatformWindow(SDL_Window* sdl_window) ++ : m_window(GUI::Window::construct()) ++ , m_widget(SerenitySDLWidget::construct(sdl_window)) ++ { ++ m_window->resize(sdl_window->w, sdl_window->h); ++ m_window->set_resizable(false); ++ } ++ ++ static SerenityPlatformWindow* from_sdl_window(SDL_Window* window) ++ { ++ return static_cast(window->driverdata); ++ } ++ ++ NonnullRefPtr window() { return m_window; } ++ NonnullRefPtr widget() { return m_widget; } ++ ++private: ++ NonnullRefPtr m_window; ++ NonnullRefPtr m_widget; ++}; ++ ++class SerenityGLContext final { ++public: ++ explicit SerenityGLContext(SDL_Window& sdl_window) ++ : m_sdl_window(sdl_window) ++ { ++ } ++ ++ SDL_Window& sdl_window() const { return m_sdl_window; } ++ ++private: ++ SDL_Window& m_sdl_window; ++}; ++ ++#endif /* SDL_serenityvideo_h_ */ ++ ++/* vi: set ts=4 sw=4 expandtab: */ +-- +2.36.1 + diff --git a/Ports/SDL2/patches/0002-Replace-usages-of-FULL-paths-with-their-relative-cou.patch b/Ports/SDL2/patches/0002-Replace-usages-of-FULL-paths-with-their-relative-cou.patch new file mode 100644 index 0000000000..bc0d9dd29a --- /dev/null +++ b/Ports/SDL2/patches/0002-Replace-usages-of-FULL-paths-with-their-relative-cou.patch @@ -0,0 +1,31 @@ +From 602fc626d157e66d0436f99f8d8df30f2022182b Mon Sep 17 00:00:00 2001 +From: Tim Schumacher +Date: Fri, 29 Oct 2021 20:17:42 +0200 +Subject: [PATCH 2/2] Replace usages of FULL paths with their relative + counterparts + +GNUInstallDirs currently doesn't support the seperate STAGING directory, +and will always prepend the final installation prefix to its paths. + +Work around that by just using the path that is relative to the +installation directory and let CMake figure out the rest. +--- + CMakeLists.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index e744d17..b574e6f 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -2630,7 +2630,7 @@ if(NOT (WINDOWS OR CYGWIN)) + endif() + install(PROGRAMS ${SDL2_BINARY_DIR}/sdl2-config DESTINATION bin) + # TODO: what about the .spec file? Is it only needed for RPM creation? +- install(FILES "${SDL2_SOURCE_DIR}/sdl2.m4" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/aclocal") ++ install(FILES "${SDL2_SOURCE_DIR}/sdl2.m4" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/aclocal") + endif() + + ##### Uninstall target ##### +-- +2.36.1 + diff --git a/Ports/SDL2/patches/ReadMe.md b/Ports/SDL2/patches/ReadMe.md new file mode 100644 index 0000000000..c506837a56 --- /dev/null +++ b/Ports/SDL2/patches/ReadMe.md @@ -0,0 +1,17 @@ +# Patches for SDL2 on SerenityOS + +## `0001-Add-SerenityOS-platform-support.patch` + +Add SerenityOS platform support + + +## `0002-Replace-usages-of-FULL-paths-with-their-relative-cou.patch` + +Replace usages of FULL paths with their relative counterparts + +GNUInstallDirs currently doesn't support the seperate STAGING directory, +and will always prepend the final installation prefix to its paths. + +Work around that by just using the path that is relative to the +installation directory and let CMake figure out the rest. +