1698 lines
54 KiB
Diff
1698 lines
54 KiB
Diff
diff -ruN SDL2-2.32.8/cmake/sdlplatform.cmake SDL2-2.32.8-banan_os/cmake/sdlplatform.cmake
|
|
--- SDL2-2.32.8/cmake/sdlplatform.cmake 2024-08-14 13:35:43.000000000 +0300
|
|
+++ SDL2-2.32.8-banan_os/cmake/sdlplatform.cmake 2026-01-03 19:50:45.777185459 +0200
|
|
@@ -28,6 +28,8 @@
|
|
set(SDL_CMAKE_PLATFORM AIX)
|
|
elseif(CMAKE_SYSTEM_NAME MATCHES "Minix.*")
|
|
set(SDL_CMAKE_PLATFORM MINIX)
|
|
+ elseif(CMAKE_SYSTEM_NAME MATCHES "banan-os")
|
|
+ set(SDL_CMAKE_PLATFORM BANAN_OS)
|
|
elseif(CMAKE_SYSTEM_NAME MATCHES "QNX")
|
|
set(SDL_CMAKE_PLATFORM QNX)
|
|
endif()
|
|
diff -ruN SDL2-2.32.8/CMakeLists.txt SDL2-2.32.8-banan_os/CMakeLists.txt
|
|
--- SDL2-2.32.8/CMakeLists.txt 2025-06-03 02:00:39.000000000 +0300
|
|
+++ SDL2-2.32.8-banan_os/CMakeLists.txt 2026-01-03 19:51:02.494165302 +0200
|
|
@@ -14,7 +14,7 @@
|
|
set(SDL2_SUBPROJECT ON)
|
|
endif()
|
|
|
|
-if (HAIKU)
|
|
+if (HAIKU OR BANAN_OS)
|
|
enable_language(CXX)
|
|
set(LINKER_LANGUAGE CXX)
|
|
endif()
|
|
@@ -1462,7 +1462,7 @@
|
|
CheckPTHREAD()
|
|
CheckLibUnwind()
|
|
|
|
-elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
|
|
+elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU AND NOT BANAN_OS)
|
|
if(SDL_AUDIO)
|
|
if(SYSV5 OR SOLARIS OR HPUX)
|
|
set(SDL_AUDIO_DRIVER_SUNAUDIO 1)
|
|
@@ -2459,6 +2459,64 @@
|
|
CheckPTHREAD()
|
|
list(APPEND EXTRA_LIBS root be media game device textencoding)
|
|
|
|
+elseif(BANAN_OS)
|
|
+ if(SDL_MISC)
|
|
+ file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/banan_os/*.cpp)
|
|
+ list(APPEND SOURCE_FILES ${MISC_SOURCES})
|
|
+ set(HAVE_SDL_MISC TRUE)
|
|
+ endif()
|
|
+
|
|
+ if(SDL_AUDIO)
|
|
+ set(SDL_AUDIO_DRIVER_BANANOS 1)
|
|
+ file(GLOB AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/banan_os/*.cpp)
|
|
+ list(APPEND SOURCE_FILES ${AUDIO_SOURCES})
|
|
+ set(HAVE_SDL_AUDIO TRUE)
|
|
+ list(APPEND EXTRA_LIBS audio)
|
|
+ endif()
|
|
+
|
|
+ if(SDL_JOYSTICK)
|
|
+ set(SDL_JOYSTICK_BANANOS 1)
|
|
+ file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/banan_os/*.cpp)
|
|
+ list(APPEND SOURCE_FILES ${JOYSTICK_SOURCES})
|
|
+ set(HAVE_SDL_JOYSTICK TRUE)
|
|
+ endif()
|
|
+
|
|
+ if(SDL_VIDEO)
|
|
+ set(SDL_VIDEO_DRIVER_BANANOS 1)
|
|
+ file(GLOB VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/banan_os/*.cpp)
|
|
+ list(APPEND SOURCE_FILES ${VIDEO_SOURCES})
|
|
+ set(HAVE_SDL_VIDEO TRUE)
|
|
+ list(APPEND EXTRA_LIBS gui input clipboard)
|
|
+
|
|
+ if(SDL_OPENGL)
|
|
+ set(SDL_VIDEO_OPENGL 1)
|
|
+ set(SDL_VIDEO_OPENGL_BANANOS 1)
|
|
+ set(SDL_VIDEO_RENDER_OGL 1)
|
|
+ list(APPEND EXTRA_LIBS OSMesa)
|
|
+ set(HAVE_OPENGL TRUE)
|
|
+ endif()
|
|
+ endif()
|
|
+
|
|
+ if(SDL_FILESYSTEM)
|
|
+ set(SDL_FILESYSTEM_UNIX 1)
|
|
+ file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/unix/*.c)
|
|
+ list(APPEND SOURCE_FILES ${FILESYSTEM_SOURCES})
|
|
+ set(HAVE_SDL_FILESYSTEM TRUE)
|
|
+ endif()
|
|
+
|
|
+ if(SDL_TIMERS)
|
|
+ set(SDL_TIMER_UNIX 1)
|
|
+ file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c)
|
|
+ list(APPEND SOURCE_FILES ${TIMER_SOURCES})
|
|
+ set(HAVE_SDL_TIMERS TRUE)
|
|
+
|
|
+ if(SDL_CLOCK_GETTIME)
|
|
+ set(HAVE_CLOCK_GETTIME 1)
|
|
+ endif()
|
|
+ endif()
|
|
+
|
|
+ CheckPTHREAD()
|
|
+
|
|
elseif(RISCOS)
|
|
if(SDL_MISC)
|
|
file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/riscos/*.c)
|
|
diff -ruN SDL2-2.32.8/include/SDL_config.h.cmake SDL2-2.32.8-banan_os/include/SDL_config.h.cmake
|
|
--- SDL2-2.32.8/include/SDL_config.h.cmake 2025-01-01 17:47:53.000000000 +0200
|
|
+++ SDL2-2.32.8-banan_os/include/SDL_config.h.cmake 2026-01-03 19:55:22.679890924 +0200
|
|
@@ -307,6 +307,7 @@
|
|
#cmakedefine SDL_AUDIO_DRIVER_FUSIONSOUND @SDL_AUDIO_DRIVER_FUSIONSOUND@
|
|
#cmakedefine SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC @SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC@
|
|
#cmakedefine SDL_AUDIO_DRIVER_HAIKU @SDL_AUDIO_DRIVER_HAIKU@
|
|
+#cmakedefine SDL_AUDIO_DRIVER_BANANOS @SDL_AUDIO_DRIVER_BANANOS@
|
|
#cmakedefine SDL_AUDIO_DRIVER_JACK @SDL_AUDIO_DRIVER_JACK@
|
|
#cmakedefine SDL_AUDIO_DRIVER_JACK_DYNAMIC @SDL_AUDIO_DRIVER_JACK_DYNAMIC@
|
|
#cmakedefine SDL_AUDIO_DRIVER_NAS @SDL_AUDIO_DRIVER_NAS@
|
|
@@ -337,6 +338,7 @@
|
|
#cmakedefine SDL_INPUT_WSCONS @SDL_INPUT_WSCONS@
|
|
#cmakedefine SDL_JOYSTICK_ANDROID @SDL_JOYSTICK_ANDROID@
|
|
#cmakedefine SDL_JOYSTICK_HAIKU @SDL_JOYSTICK_HAIKU@
|
|
+#cmakedefine SDL_JOYSTICK_BANANOS @SDL_JOYSTICK_BANANOS@
|
|
#cmakedefine SDL_JOYSTICK_WGI @SDL_JOYSTICK_WGI@
|
|
#cmakedefine SDL_JOYSTICK_DINPUT @SDL_JOYSTICK_DINPUT@
|
|
#cmakedefine SDL_JOYSTICK_XINPUT @SDL_JOYSTICK_XINPUT@
|
|
@@ -406,6 +408,7 @@
|
|
#cmakedefine SDL_VIDEO_DRIVER_ANDROID @SDL_VIDEO_DRIVER_ANDROID@
|
|
#cmakedefine SDL_VIDEO_DRIVER_EMSCRIPTEN @SDL_VIDEO_DRIVER_EMSCRIPTEN@
|
|
#cmakedefine SDL_VIDEO_DRIVER_HAIKU @SDL_VIDEO_DRIVER_HAIKU@
|
|
+#cmakedefine SDL_VIDEO_DRIVER_BANANOS @SDL_VIDEO_DRIVER_BANANOS@
|
|
#cmakedefine SDL_VIDEO_DRIVER_COCOA @SDL_VIDEO_DRIVER_COCOA@
|
|
#cmakedefine SDL_VIDEO_DRIVER_UIKIT @SDL_VIDEO_DRIVER_UIKIT@
|
|
#cmakedefine SDL_VIDEO_DRIVER_DIRECTFB @SDL_VIDEO_DRIVER_DIRECTFB@
|
|
diff -ruN SDL2-2.32.8/include/SDL_platform.h SDL2-2.32.8-banan_os/include/SDL_platform.h
|
|
--- SDL2-2.32.8/include/SDL_platform.h 2025-01-01 17:47:53.000000000 +0200
|
|
+++ SDL2-2.32.8-banan_os/include/SDL_platform.h 2026-01-03 19:50:45.778818009 +0200
|
|
@@ -36,6 +36,10 @@
|
|
#undef __HAIKU__
|
|
#define __HAIKU__ 1
|
|
#endif
|
|
+#if defined(__banan_os__)
|
|
+#undef __banan_os__
|
|
+#define __banan_os__ 1
|
|
+#endif
|
|
#if defined(bsdi) || defined(__bsdi) || defined(__bsdi__)
|
|
#undef __BSDI__
|
|
#define __BSDI__ 1
|
|
diff -ruN SDL2-2.32.8/src/audio/banan_os/SDL_banan_os_audio.cpp SDL2-2.32.8-banan_os/src/audio/banan_os/SDL_banan_os_audio.cpp
|
|
--- SDL2-2.32.8/src/audio/banan_os/SDL_banan_os_audio.cpp 1970-01-01 02:00:00.000000000 +0200
|
|
+++ SDL2-2.32.8-banan_os/src/audio/banan_os/SDL_banan_os_audio.cpp 2026-01-03 19:50:45.779146754 +0200
|
|
@@ -0,0 +1,150 @@
|
|
+/*
|
|
+ Simple DirectMedia Layer
|
|
+ Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
|
|
+
|
|
+ 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_BANANOS
|
|
+
|
|
+extern "C" {
|
|
+#include "SDL_audio.h"
|
|
+#include "../SDL_audio_c.h"
|
|
+#include "../SDL_sysaudio.h"
|
|
+}
|
|
+
|
|
+#include "SDL_banan_os_audio.h"
|
|
+
|
|
+#include <unistd.h>
|
|
+
|
|
+#define DUMP_FUNCTIONS 0
|
|
+
|
|
+#if DUMP_FUNCTIONS
|
|
+# define DUMP_FUNCTION() dprintln(__FUNCTION__)
|
|
+#else
|
|
+# define DUMP_FUNCTION()
|
|
+#endif
|
|
+
|
|
+static void BANANOS_CloseDevice(_THIS)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ if (!_this->hidden)
|
|
+ return;
|
|
+
|
|
+ if (_this->hidden->mixbuf)
|
|
+ SDL_free(_this->hidden->mixbuf);
|
|
+
|
|
+ delete _this->hidden;
|
|
+}
|
|
+
|
|
+static int BANANOS_OpenDevice(_THIS, char const*)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ // TODO: try to accept already existing spec
|
|
+ _this->spec.freq = 44100;
|
|
+ _this->spec.format = AUDIO_S16LSB;
|
|
+ _this->spec.channels = 2;
|
|
+ _this->spec.samples = 2048;
|
|
+ SDL_CalculateAudioSpec(&_this->spec);
|
|
+
|
|
+ auto audio_or_error = LibAudio::Audio::create(_this->spec.channels, _this->spec.freq, 0x1000);
|
|
+ if (audio_or_error.is_error())
|
|
+ return SDL_SetError("failed to create audio device: %s", audio_or_error.error().get_message());
|
|
+
|
|
+ void* mixbuf = SDL_malloc(_this->spec.size);
|
|
+ if (mixbuf == nullptr)
|
|
+ return SDL_OutOfMemory();
|
|
+
|
|
+ _this->hidden = new SDL_PrivateAudioData(audio_or_error.release_value(), mixbuf);
|
|
+ if (!_this->hidden)
|
|
+ return SDL_OutOfMemory();
|
|
+ MUST(_this->hidden->audio.start());
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void BANANOS_PlayDevice(_THIS)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ const bool should_play = SDL_AtomicGet(&_this->enabled) && !SDL_AtomicGet(&_this->paused);
|
|
+ _this->hidden->audio.set_paused(!should_play);
|
|
+ if (!should_play)
|
|
+ {
|
|
+ usleep(100);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ static_assert(BAN::is_same_v<LibAudio::AudioBuffer::sample_t, double>);
|
|
+
|
|
+ const auto convert_sample = [](int16_t input) {
|
|
+ return (static_cast<double>(input) - BAN::numeric_limits<int16_t>::min()) / BAN::numeric_limits<int16_t>::max() * 2.0 - 1.0;
|
|
+ };
|
|
+
|
|
+ const size_t input_samples = _this->spec.size / sizeof(int16_t);
|
|
+ size_t samples_queued = 0;
|
|
+
|
|
+ const int16_t* mixbuf = static_cast<const int16_t*>(_this->hidden->mixbuf);
|
|
+ while (samples_queued < input_samples)
|
|
+ {
|
|
+ const size_t to_convert = BAN::Math::min(_this->hidden->conversion.size(), input_samples - samples_queued);
|
|
+ for (size_t i = 0; i < to_convert; i++)
|
|
+ _this->hidden->conversion[i] = convert_sample(mixbuf[samples_queued + i]);
|
|
+
|
|
+ auto sample_span = _this->hidden->conversion.span();
|
|
+ while (!sample_span.empty())
|
|
+ {
|
|
+ const size_t queued = _this->hidden->audio.queue_samples(sample_span);
|
|
+ if (queued == 0)
|
|
+ usleep(100);
|
|
+ sample_span = sample_span.slice(queued);
|
|
+ }
|
|
+
|
|
+ samples_queued += to_convert;
|
|
+ }
|
|
+}
|
|
+
|
|
+static Uint8* BANANOS_GetDeviceBuf(_THIS)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ return static_cast<Uint8*>(_this->hidden->mixbuf);
|
|
+}
|
|
+
|
|
+static SDL_bool BANANOS_Init(SDL_AudioDriverImpl* impl)
|
|
+{
|
|
+ impl->OpenDevice = BANANOS_OpenDevice;
|
|
+ impl->CloseDevice = BANANOS_CloseDevice;
|
|
+ impl->PlayDevice = BANANOS_PlayDevice;
|
|
+ impl->GetDeviceBuf = BANANOS_GetDeviceBuf;
|
|
+
|
|
+ impl->ProvidesOwnCallbackThread = SDL_FALSE;
|
|
+ impl->HasCaptureSupport = SDL_FALSE;
|
|
+ impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
|
+ impl->SupportsNonPow2Samples = SDL_TRUE;
|
|
+
|
|
+ return SDL_TRUE;
|
|
+}
|
|
+
|
|
+AudioBootStrap BANANOSAUDIO_bootstrap = {
|
|
+ "banan-os", "banan-os AudioServer", BANANOS_Init, SDL_FALSE
|
|
+};
|
|
+
|
|
+#endif
|
|
diff -ruN SDL2-2.32.8/src/audio/banan_os/SDL_banan_os_audio.h SDL2-2.32.8-banan_os/src/audio/banan_os/SDL_banan_os_audio.h
|
|
--- SDL2-2.32.8/src/audio/banan_os/SDL_banan_os_audio.h 1970-01-01 02:00:00.000000000 +0200
|
|
+++ SDL2-2.32.8-banan_os/src/audio/banan_os/SDL_banan_os_audio.h 2026-01-03 19:50:45.779253053 +0200
|
|
@@ -0,0 +1,34 @@
|
|
+/*
|
|
+ Simple DirectMedia Layer
|
|
+ Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
|
|
+
|
|
+ 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 <LibAudio/Audio.h>
|
|
+#include <BAN/Array.h>
|
|
+
|
|
+#define _THIS SDL_AudioDevice* _this
|
|
+
|
|
+struct SDL_PrivateAudioData {
|
|
+ LibAudio::Audio audio;
|
|
+ void* mixbuf { nullptr };
|
|
+ BAN::Array<LibAudio::AudioBuffer::sample_t, 4096> conversion;
|
|
+};
|
|
diff -ruN SDL2-2.32.8/src/audio/SDL_audio.c SDL2-2.32.8-banan_os/src/audio/SDL_audio.c
|
|
--- SDL2-2.32.8/src/audio/SDL_audio.c 2025-01-01 17:47:53.000000000 +0200
|
|
+++ SDL2-2.32.8-banan_os/src/audio/SDL_audio.c 2026-01-03 19:50:45.779381073 +0200
|
|
@@ -87,6 +87,9 @@
|
|
#ifdef SDL_AUDIO_DRIVER_HAIKU
|
|
&HAIKUAUDIO_bootstrap,
|
|
#endif
|
|
+#ifdef SDL_AUDIO_DRIVER_BANANOS
|
|
+ &BANANOSAUDIO_bootstrap,
|
|
+#endif
|
|
#ifdef SDL_AUDIO_DRIVER_COREAUDIO
|
|
&COREAUDIO_bootstrap,
|
|
#endif
|
|
diff -ruN SDL2-2.32.8/src/audio/SDL_sysaudio.h SDL2-2.32.8-banan_os/src/audio/SDL_sysaudio.h
|
|
--- SDL2-2.32.8/src/audio/SDL_sysaudio.h 2025-01-01 17:47:53.000000000 +0200
|
|
+++ SDL2-2.32.8-banan_os/src/audio/SDL_sysaudio.h 2026-01-03 19:50:45.779975705 +0200
|
|
@@ -196,6 +196,7 @@
|
|
extern AudioBootStrap WINMM_bootstrap;
|
|
extern AudioBootStrap PAUDIO_bootstrap;
|
|
extern AudioBootStrap HAIKUAUDIO_bootstrap;
|
|
+extern AudioBootStrap BANANOSAUDIO_bootstrap;
|
|
extern AudioBootStrap COREAUDIO_bootstrap;
|
|
extern AudioBootStrap DISKAUDIO_bootstrap;
|
|
extern AudioBootStrap DUMMYAUDIO_bootstrap;
|
|
diff -ruN SDL2-2.32.8/src/joystick/banan_os/SDL_banan_os_joystick.cpp SDL2-2.32.8-banan_os/src/joystick/banan_os/SDL_banan_os_joystick.cpp
|
|
--- SDL2-2.32.8/src/joystick/banan_os/SDL_banan_os_joystick.cpp 1970-01-01 02:00:00.000000000 +0200
|
|
+++ SDL2-2.32.8-banan_os/src/joystick/banan_os/SDL_banan_os_joystick.cpp 2026-01-03 19:51:21.437329388 +0200
|
|
@@ -0,0 +1,308 @@
|
|
+/*
|
|
+Simple DirectMedia Layer
|
|
+Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
|
+
|
|
+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"
|
|
+
|
|
+#ifdef SDL_JOYSTICK_BANANOS
|
|
+
|
|
+#include <BAN/Math.h>
|
|
+
|
|
+#include <LibInput/Joystick.h>
|
|
+
|
|
+extern "C"
|
|
+{
|
|
+
|
|
+#include "SDL_joystick.h"
|
|
+#include "../SDL_sysjoystick.h"
|
|
+#include "../SDL_joystick_c.h"
|
|
+
|
|
+#include <fcntl.h>
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include <string.h>
|
|
+#include <sys/stat.h>
|
|
+
|
|
+#define MAX_JOYSTICKS 16
|
|
+
|
|
+struct joystick_hwdata
|
|
+{
|
|
+ int fd;
|
|
+};
|
|
+
|
|
+static int s_joystick_count = 0;
|
|
+static char* s_joystick_path[MAX_JOYSTICKS];
|
|
+
|
|
+static void BANANOS_JoystickDetect(void);
|
|
+
|
|
+static int BANANOS_JoystickInit(void)
|
|
+{
|
|
+ s_joystick_count = 0;
|
|
+
|
|
+ for (int i = 0; i < MAX_JOYSTICKS; i++)
|
|
+ {
|
|
+ char path[PATH_MAX];
|
|
+ sprintf(path, "/dev/joystick%d", i);
|
|
+
|
|
+ struct stat st;
|
|
+ if (stat(path, &st) == -1)
|
|
+ continue;
|
|
+
|
|
+ s_joystick_path[i] = SDL_strdup(path);
|
|
+ if (s_joystick_path[i] == NULL)
|
|
+ continue;
|
|
+ s_joystick_count++;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int BANANOS_JoystickGetCount(void)
|
|
+{
|
|
+ return s_joystick_count;
|
|
+}
|
|
+
|
|
+static void BANANOS_JoystickDetect(void)
|
|
+{
|
|
+}
|
|
+
|
|
+static const char* BANANOS_JoystickGetDeviceName(int device_index)
|
|
+{
|
|
+ return s_joystick_path[device_index] + strlen("/dev/");
|
|
+}
|
|
+
|
|
+static const char* BANANOS_JoystickGetDevicePath(int device_index)
|
|
+{
|
|
+ return s_joystick_path[device_index];
|
|
+}
|
|
+
|
|
+static int BANANOS_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index)
|
|
+{
|
|
+ (void)device_index;
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+static int BANANOS_JoystickGetDevicePlayerIndex(int device_index)
|
|
+{
|
|
+ (void)device_index;
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+static void BANANOS_JoystickSetDevicePlayerIndex(int device_index, int player_index)
|
|
+{
|
|
+ (void)device_index;
|
|
+ (void)player_index;
|
|
+}
|
|
+
|
|
+static SDL_JoystickID BANANOS_JoystickGetDeviceInstanceID(int device_index)
|
|
+{
|
|
+ return device_index;
|
|
+}
|
|
+
|
|
+static void BANANOS_JoystickClose(SDL_Joystick* joystick)
|
|
+{
|
|
+ if (joystick->hwdata == NULL)
|
|
+ return;
|
|
+
|
|
+ if (joystick->hwdata->fd != -1)
|
|
+ close(joystick->hwdata->fd);
|
|
+ SDL_free(joystick->hwdata);
|
|
+}
|
|
+
|
|
+static int BANANOS_JoystickOpen(SDL_Joystick* joystick, int device_index)
|
|
+{
|
|
+ joystick->instance_id = device_index;
|
|
+ joystick->hwdata = static_cast<joystick_hwdata*>(SDL_calloc(1, sizeof(joystick_hwdata)));
|
|
+ if (joystick->hwdata == NULL)
|
|
+ return SDL_OutOfMemory();
|
|
+
|
|
+ joystick->hwdata->fd = open(s_joystick_path[device_index], O_RDONLY);
|
|
+ if (joystick->hwdata->fd == -1)
|
|
+ {
|
|
+ BANANOS_JoystickClose(joystick);
|
|
+ return SDL_SetError("Unable to open joystick");
|
|
+ }
|
|
+
|
|
+ joystick->nbuttons = sizeof(LibInput::JoystickState::buttons) / sizeof(*LibInput::JoystickState::buttons);
|
|
+ joystick->naxes = sizeof(LibInput::JoystickState::axis) / sizeof(*LibInput::JoystickState::axis);
|
|
+ joystick->nhats = 0;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void BANANOS_JoystickUpdate(SDL_Joystick *joystick)
|
|
+{
|
|
+ LibInput::JoystickState state;
|
|
+ if (read(joystick->hwdata->fd, &state, sizeof(state)) < static_cast<ssize_t>(sizeof(state)))
|
|
+ return;
|
|
+
|
|
+ const auto map_joystick_value =
|
|
+ [](const LibInput::JoystickState::Axis& axis) -> Sint16
|
|
+ {
|
|
+ if (axis.min == axis.max)
|
|
+ return 0;
|
|
+ const float mapped = (axis.value - axis.min) * 65534.0f / (axis.max - axis.min) - 32767.0f;
|
|
+ return BAN::Math::clamp<Sint32>(mapped, -32767, 32767);
|
|
+ };
|
|
+
|
|
+ for (int i = 0; i < joystick->naxes; i++)
|
|
+ SDL_PrivateJoystickAxis(joystick, i, map_joystick_value(state.axis[i]));
|
|
+
|
|
+ for (int i = 0; i < joystick->nbuttons; i++)
|
|
+ SDL_PrivateJoystickButton(joystick, i, state.buttons[i]);
|
|
+}
|
|
+
|
|
+static void BANANOS_JoystickQuit(void)
|
|
+{
|
|
+ for (int i = 0; i < s_joystick_count; i++)
|
|
+ SDL_free(s_joystick_path[i]);
|
|
+}
|
|
+
|
|
+static SDL_JoystickGUID BANANOS_JoystickGetDeviceGUID(int device_index)
|
|
+{
|
|
+ return SDL_CreateJoystickGUIDForName(BANANOS_JoystickGetDeviceName(device_index));
|
|
+}
|
|
+
|
|
+static int BANANOS_JoystickRumble(SDL_Joystick* joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
|
|
+{
|
|
+ (void)joystick;
|
|
+ (void)low_frequency_rumble;
|
|
+ (void)high_frequency_rumble;
|
|
+ return SDL_Unsupported();
|
|
+}
|
|
+
|
|
+static int BANANOS_JoystickRumbleTriggers(SDL_Joystick* joystick, Uint16 left_rumble, Uint16 right_rumble)
|
|
+{
|
|
+ (void)joystick;
|
|
+ (void)left_rumble;
|
|
+ (void)right_rumble;
|
|
+ return SDL_Unsupported();
|
|
+}
|
|
+
|
|
+static SDL_bool BANANOS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping* out)
|
|
+{
|
|
+ (void)device_index;
|
|
+
|
|
+ // FIXME: this is hardcoded to a PS3 controller layout :D
|
|
+
|
|
+ memset(out, 0, sizeof(SDL_GamepadMapping));
|
|
+
|
|
+#define BANANOS_MAP_BUTTON(name, button) \
|
|
+ out->name.kind = EMappingKind_Button; \
|
|
+ out->name.target = button
|
|
+
|
|
+#define BANANOS_MAP_AXIS(name, axis) \
|
|
+ out->name.kind = EMappingKind_Axis; \
|
|
+ out->name.target = axis
|
|
+
|
|
+ BANANOS_MAP_BUTTON(a, 14);
|
|
+ BANANOS_MAP_BUTTON(b, 13);
|
|
+ BANANOS_MAP_BUTTON(x, 15);
|
|
+ BANANOS_MAP_BUTTON(y, 12);
|
|
+
|
|
+ BANANOS_MAP_BUTTON(back, 0);
|
|
+ BANANOS_MAP_BUTTON(guide, 16);
|
|
+ BANANOS_MAP_BUTTON(start, 3);
|
|
+
|
|
+ BANANOS_MAP_BUTTON(leftstick, 1);
|
|
+ BANANOS_MAP_BUTTON(rightstick, 2);
|
|
+
|
|
+ BANANOS_MAP_BUTTON(leftshoulder, 10);
|
|
+ BANANOS_MAP_BUTTON(rightshoulder, 11);
|
|
+
|
|
+ BANANOS_MAP_BUTTON(dpup, 4);
|
|
+ BANANOS_MAP_BUTTON(dpdown, 6);
|
|
+ BANANOS_MAP_BUTTON(dpleft, 7);
|
|
+ BANANOS_MAP_BUTTON(dpright, 5);
|
|
+
|
|
+ BANANOS_MAP_AXIS(leftx, 0);
|
|
+ BANANOS_MAP_AXIS(lefty, 1);
|
|
+ BANANOS_MAP_AXIS(rightx, 2);
|
|
+ BANANOS_MAP_AXIS(righty, 3);
|
|
+
|
|
+ // TODO: these should probably be axis
|
|
+ BANANOS_MAP_BUTTON(lefttrigger, 8);
|
|
+ BANANOS_MAP_BUTTON(righttrigger, 9);
|
|
+
|
|
+#undef BANANOS_MAP_BUTTON
|
|
+#undef BANANOS_MAP_AXIS
|
|
+
|
|
+ return SDL_TRUE;
|
|
+}
|
|
+
|
|
+static Uint32 BANANOS_JoystickGetCapabilities(SDL_Joystick* joystick)
|
|
+{
|
|
+ (void)joystick;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int BANANOS_JoystickSetLED(SDL_Joystick* joystick, Uint8 red, Uint8 green, Uint8 blue)
|
|
+{
|
|
+ (void)joystick;
|
|
+ (void)red;
|
|
+ (void)green;
|
|
+ (void)blue;
|
|
+ return SDL_Unsupported();
|
|
+}
|
|
+
|
|
+static int BANANOS_JoystickSendEffect(SDL_Joystick* joystick, const void* data, int size)
|
|
+{
|
|
+ (void)joystick;
|
|
+ (void)data;
|
|
+ (void)size;
|
|
+ return SDL_Unsupported();
|
|
+}
|
|
+
|
|
+static int BANANOS_JoystickSetSensorsEnabled(SDL_Joystick* joystick, SDL_bool enabled)
|
|
+{
|
|
+ (void)joystick;
|
|
+ (void)enabled;
|
|
+ return SDL_Unsupported();
|
|
+}
|
|
+
|
|
+SDL_JoystickDriver SDL_BANANOS_JoystickDriver =
|
|
+{
|
|
+ BANANOS_JoystickInit,
|
|
+ BANANOS_JoystickGetCount,
|
|
+ BANANOS_JoystickDetect,
|
|
+ BANANOS_JoystickGetDeviceName,
|
|
+ BANANOS_JoystickGetDevicePath,
|
|
+ BANANOS_JoystickGetDeviceSteamVirtualGamepadSlot,
|
|
+ BANANOS_JoystickGetDevicePlayerIndex,
|
|
+ BANANOS_JoystickSetDevicePlayerIndex,
|
|
+ BANANOS_JoystickGetDeviceGUID,
|
|
+ BANANOS_JoystickGetDeviceInstanceID,
|
|
+ BANANOS_JoystickOpen,
|
|
+ BANANOS_JoystickRumble,
|
|
+ BANANOS_JoystickRumbleTriggers,
|
|
+ BANANOS_JoystickGetCapabilities,
|
|
+ BANANOS_JoystickSetLED,
|
|
+ BANANOS_JoystickSendEffect,
|
|
+ BANANOS_JoystickSetSensorsEnabled,
|
|
+ BANANOS_JoystickUpdate,
|
|
+ BANANOS_JoystickClose,
|
|
+ BANANOS_JoystickQuit,
|
|
+ BANANOS_JoystickGetGamepadMapping
|
|
+};
|
|
+
|
|
+} // extern "C"
|
|
+
|
|
+#endif /* SDL_JOYSTICK_BANANOS */
|
|
+
|
|
+/* vi: set ts=4 sw=4 expandtab: */
|
|
diff -ruN SDL2-2.32.8/src/joystick/SDL_joystick.c SDL2-2.32.8-banan_os/src/joystick/SDL_joystick.c
|
|
--- SDL2-2.32.8/src/joystick/SDL_joystick.c 2025-01-01 17:47:53.000000000 +0200
|
|
+++ SDL2-2.32.8-banan_os/src/joystick/SDL_joystick.c 2026-01-03 19:52:38.740921854 +0200
|
|
@@ -85,6 +85,9 @@
|
|
#ifdef SDL_JOYSTICK_HAIKU
|
|
&SDL_HAIKU_JoystickDriver,
|
|
#endif
|
|
+#ifdef SDL_JOYSTICK_BANANOS
|
|
+ &SDL_BANANOS_JoystickDriver,
|
|
+#endif
|
|
#ifdef SDL_JOYSTICK_USBHID /* !!! FIXME: "USBHID" is a generic name, and doubly-confusing with HIDAPI next to it. This is the *BSD interface, rename this. */
|
|
&SDL_BSD_JoystickDriver,
|
|
#endif
|
|
diff -ruN SDL2-2.32.8/src/joystick/SDL_sysjoystick.h SDL2-2.32.8-banan_os/src/joystick/SDL_sysjoystick.h
|
|
--- SDL2-2.32.8/src/joystick/SDL_sysjoystick.h 2025-01-01 17:47:53.000000000 +0200
|
|
+++ SDL2-2.32.8-banan_os/src/joystick/SDL_sysjoystick.h 2026-01-03 19:52:50.906765671 +0200
|
|
@@ -235,6 +235,7 @@
|
|
|
|
/* The available joystick drivers */
|
|
extern SDL_JoystickDriver SDL_ANDROID_JoystickDriver;
|
|
+extern SDL_JoystickDriver SDL_BANANOS_JoystickDriver;
|
|
extern SDL_JoystickDriver SDL_BSD_JoystickDriver;
|
|
extern SDL_JoystickDriver SDL_DARWIN_JoystickDriver;
|
|
extern SDL_JoystickDriver SDL_DUMMY_JoystickDriver;
|
|
diff -ruN SDL2-2.32.8/src/misc/banan_os/SDL_sysurl.cpp SDL2-2.32.8-banan_os/src/misc/banan_os/SDL_sysurl.cpp
|
|
--- SDL2-2.32.8/src/misc/banan_os/SDL_sysurl.cpp 1970-01-01 02:00:00.000000000 +0200
|
|
+++ SDL2-2.32.8-banan_os/src/misc/banan_os/SDL_sysurl.cpp 2026-01-03 19:50:45.780251300 +0200
|
|
@@ -0,0 +1,30 @@
|
|
+/*
|
|
+ Simple DirectMedia Layer
|
|
+ Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
|
+
|
|
+ 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_sysurl.h"
|
|
+
|
|
+int SDL_SYS_OpenURL(const char *url)
|
|
+{
|
|
+ return SDL_SetError("SDL_SYS_OpenURL not supported");
|
|
+}
|
|
+
|
|
+/* vi: set ts=4 sw=4 expandtab: */
|
|
+
|
|
diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_clipboard.cpp SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_clipboard.cpp
|
|
--- SDL2-2.32.8/src/video/banan_os/SDL_banan_os_clipboard.cpp 1970-01-01 02:00:00.000000000 +0200
|
|
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_clipboard.cpp 2026-01-03 19:50:45.780447206 +0200
|
|
@@ -0,0 +1,51 @@
|
|
+/*
|
|
+ Simple DirectMedia Layer
|
|
+ Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
|
+
|
|
+ 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"
|
|
+
|
|
+#ifdef SDL_VIDEO_DRIVER_BANANOS
|
|
+
|
|
+#include "SDL_banan_os_clipboard.h"
|
|
+
|
|
+#include <LibClipboard/Clipboard.h>
|
|
+
|
|
+int BANANOS_SetClipboardText(_THIS, const char *text) {
|
|
+ if (LibClipboard::Clipboard::set_clipboard_text(text).is_error())
|
|
+ return -1;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+char *BANANOS_GetClipboardText(_THIS) {
|
|
+ auto text_or_error = LibClipboard::Clipboard::get_clipboard_text();
|
|
+ if (text_or_error.is_error())
|
|
+ return NULL;
|
|
+ return SDL_strdup(text_or_error.value().data());
|
|
+}
|
|
+
|
|
+SDL_bool BANANOS_HasClipboardText(_THIS) {
|
|
+ auto text_or_error = LibClipboard::Clipboard::get_clipboard_text();
|
|
+ if (text_or_error.is_error())
|
|
+ return SDL_FALSE;
|
|
+ return text_or_error.value().empty() ? SDL_FALSE : SDL_TRUE;
|
|
+}
|
|
+
|
|
+#endif /* SDL_VIDEO_DRIVER_BANANOS */
|
|
+
|
|
+/* vi: set ts=4 sw=4 expandtab: */
|
|
diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_clipboard.h SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_clipboard.h
|
|
--- SDL2-2.32.8/src/video/banan_os/SDL_banan_os_clipboard.h 1970-01-01 02:00:00.000000000 +0200
|
|
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_clipboard.h 2026-01-03 19:50:45.780567334 +0200
|
|
@@ -0,0 +1,43 @@
|
|
+/*
|
|
+ Simple DirectMedia Layer
|
|
+ Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
|
+
|
|
+ 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_BANANOS_CLIPBOARD_H
|
|
+#define SDL_BANANOS_CLIPBOARD_H
|
|
+
|
|
+#include "../../SDL_internal.h"
|
|
+
|
|
+#include "../SDL_sysvideo.h"
|
|
+
|
|
+#ifdef __cplusplus
|
|
+extern "C" {
|
|
+#endif
|
|
+
|
|
+extern int BANANOS_SetClipboardText(_THIS, const char *text);
|
|
+extern char *BANANOS_GetClipboardText(_THIS);
|
|
+extern SDL_bool BANANOS_HasClipboardText(_THIS);
|
|
+
|
|
+#ifdef __cplusplus
|
|
+}
|
|
+#endif
|
|
+
|
|
+#endif
|
|
+
|
|
+/* vi: set ts=4 sw=4 expandtab: */
|
|
diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_message_box.cpp SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_message_box.cpp
|
|
--- SDL2-2.32.8/src/video/banan_os/SDL_banan_os_message_box.cpp 1970-01-01 02:00:00.000000000 +0200
|
|
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_message_box.cpp 2026-01-03 19:50:45.780690325 +0200
|
|
@@ -0,0 +1,60 @@
|
|
+/*
|
|
+ Simple DirectMedia Layer
|
|
+ Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
|
+ Copyright (C) 2018-2019 EXL <exlmotodev@gmail.com>
|
|
+
|
|
+ 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"
|
|
+
|
|
+#ifdef SDL_VIDEO_DRIVER_BANANOS
|
|
+
|
|
+#include "SDL_messagebox.h"
|
|
+
|
|
+#include "SDL_banan_os_message_box.h"
|
|
+
|
|
+#include <BAN/Debug.h>
|
|
+#include <LibGUI/MessageBox.h>
|
|
+
|
|
+int BANANOS_ShowMessageBox(const SDL_MessageBoxData* messageboxdata, int* buttonid)
|
|
+{
|
|
+ BAN::Vector<BAN::StringView> buttons;
|
|
+ for (int i = 0; i < messageboxdata->numbuttons; i++) {
|
|
+ if (buttons.push_back(messageboxdata->buttons[i].text).is_error()) {
|
|
+ SDL_OutOfMemory();
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT)
|
|
+ buttons.reverse();
|
|
+
|
|
+ auto result = LibGUI::MessageBox::create(messageboxdata->message, messageboxdata->title, buttons.span());
|
|
+ if (result.is_error()) {
|
|
+ dwarnln("LibGUI::MessageBox::create: {}", result.error());
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ *buttonid = messageboxdata->buttons[result.value()].buttonid;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#endif /* SDL_VIDEO_DRIVER_BANANOS */
|
|
+
|
|
+/* vi: set ts=4 sw=4 expandtab: */
|
|
diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_message_box.h SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_message_box.h
|
|
--- SDL2-2.32.8/src/video/banan_os/SDL_banan_os_message_box.h 1970-01-01 02:00:00.000000000 +0200
|
|
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_message_box.h 2026-01-03 19:50:45.780815551 +0200
|
|
@@ -0,0 +1,45 @@
|
|
+/*
|
|
+ Simple DirectMedia Layer
|
|
+ Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
|
+ Copyright (C) 2018-2019 EXL <exlmotodev@gmail.com>
|
|
+
|
|
+ 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_BANANOS_MESSAGEBOX_H
|
|
+#define SDL_BANANOS_MESSAGEBOX_H
|
|
+
|
|
+#include "../../SDL_internal.h"
|
|
+
|
|
+#ifdef SDL_VIDEO_DRIVER_BANANOS
|
|
+
|
|
+#ifdef __cplusplus
|
|
+extern "C" {
|
|
+#endif
|
|
+
|
|
+extern int
|
|
+BANANOS_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
|
|
+
|
|
+#ifdef __cplusplus
|
|
+}
|
|
+#endif
|
|
+
|
|
+#endif /* SDL_BANANOS_MESSAGEBOX_H */
|
|
+
|
|
+#endif
|
|
+
|
|
+/* vi: set ts=4 sw=4 expandtab: */
|
|
diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_video.cpp
|
|
--- SDL2-2.32.8/src/video/banan_os/SDL_banan_os_video.cpp 1970-01-01 02:00:00.000000000 +0200
|
|
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_video.cpp 2026-01-03 19:50:45.780934771 +0200
|
|
@@ -0,0 +1,729 @@
|
|
+/*
|
|
+ Simple DirectMedia Layer
|
|
+ Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
|
+
|
|
+ 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"
|
|
+
|
|
+#ifdef SDL_VIDEO_DRIVER_BANANOS
|
|
+
|
|
+extern "C" {
|
|
+#include "../SDL_sysvideo.h"
|
|
+#include "../../events/SDL_events_c.h"
|
|
+}
|
|
+
|
|
+#include "SDL_banan_os_clipboard.h"
|
|
+#include "SDL_banan_os_message_box.h"
|
|
+
|
|
+#include <BAN/Debug.h>
|
|
+#include <BAN/LinkedList.h>
|
|
+#include <LibGUI/Window.h>
|
|
+#include <LibInput/KeyboardLayout.h>
|
|
+
|
|
+#include <fcntl.h>
|
|
+#include <sys/framebuffer.h>
|
|
+#include <sys/select.h>
|
|
+
|
|
+#include <GL/gl.h>
|
|
+#include <GL/osmesa.h>
|
|
+
|
|
+#define DUMP_FUNCTIONS 0
|
|
+
|
|
+#if DUMP_FUNCTIONS
|
|
+# define DUMP_FUNCTION() dprintln(__FUNCTION__)
|
|
+#else
|
|
+# define DUMP_FUNCTION()
|
|
+#endif
|
|
+
|
|
+struct banan_os_window
|
|
+{
|
|
+ BAN::UniqPtr<LibGUI::Window> window;
|
|
+ OSMesaContext gl_context { nullptr };
|
|
+ SDL_bool relative { SDL_FALSE };
|
|
+};
|
|
+
|
|
+struct banan_os_video_device_data
|
|
+{
|
|
+ BAN::LinkedList<banan_os_window*> windows;
|
|
+};
|
|
+
|
|
+struct Keymap
|
|
+{
|
|
+ consteval Keymap()
|
|
+ {
|
|
+ for (auto& scancode : map)
|
|
+ scancode = SDL_SCANCODE_UNKNOWN;
|
|
+
|
|
+ using LibInput::keycode_normal;
|
|
+ using LibInput::keycode_function;
|
|
+ using LibInput::keycode_numpad;
|
|
+
|
|
+ map[keycode_normal(0, 0)] = SDL_SCANCODE_GRAVE;
|
|
+ map[keycode_normal(0, 1)] = SDL_SCANCODE_1;
|
|
+ map[keycode_normal(0, 2)] = SDL_SCANCODE_2;
|
|
+ map[keycode_normal(0, 3)] = SDL_SCANCODE_3;
|
|
+ map[keycode_normal(0, 4)] = SDL_SCANCODE_4;
|
|
+ map[keycode_normal(0, 5)] = SDL_SCANCODE_5;
|
|
+ map[keycode_normal(0, 6)] = SDL_SCANCODE_6;
|
|
+ map[keycode_normal(0, 7)] = SDL_SCANCODE_7;
|
|
+ map[keycode_normal(0, 8)] = SDL_SCANCODE_8;
|
|
+ map[keycode_normal(0, 9)] = SDL_SCANCODE_9;
|
|
+ map[keycode_normal(0, 10)] = SDL_SCANCODE_0;
|
|
+ map[keycode_normal(0, 11)] = SDL_SCANCODE_MINUS;
|
|
+ map[keycode_normal(0, 12)] = SDL_SCANCODE_EQUALS;
|
|
+ map[keycode_normal(0, 13)] = SDL_SCANCODE_BACKSPACE;
|
|
+ map[keycode_normal(1, 0)] = SDL_SCANCODE_TAB;
|
|
+ map[keycode_normal(1, 1)] = SDL_SCANCODE_Q;
|
|
+ map[keycode_normal(1, 2)] = SDL_SCANCODE_W;
|
|
+ map[keycode_normal(1, 3)] = SDL_SCANCODE_E;
|
|
+ map[keycode_normal(1, 4)] = SDL_SCANCODE_R;
|
|
+ map[keycode_normal(1, 5)] = SDL_SCANCODE_T;
|
|
+ map[keycode_normal(1, 6)] = SDL_SCANCODE_Y;
|
|
+ map[keycode_normal(1, 7)] = SDL_SCANCODE_U;
|
|
+ map[keycode_normal(1, 8)] = SDL_SCANCODE_I;
|
|
+ map[keycode_normal(1, 9)] = SDL_SCANCODE_O;
|
|
+ map[keycode_normal(1, 10)] = SDL_SCANCODE_P;
|
|
+ map[keycode_normal(1, 11)] = SDL_SCANCODE_LEFTBRACKET;
|
|
+ map[keycode_normal(1, 12)] = SDL_SCANCODE_RIGHTBRACKET;
|
|
+ map[keycode_normal(2, 0)] = SDL_SCANCODE_CAPSLOCK;
|
|
+ map[keycode_normal(2, 1)] = SDL_SCANCODE_A;
|
|
+ map[keycode_normal(2, 2)] = SDL_SCANCODE_S;
|
|
+ map[keycode_normal(2, 3)] = SDL_SCANCODE_D;
|
|
+ map[keycode_normal(2, 4)] = SDL_SCANCODE_F;
|
|
+ map[keycode_normal(2, 5)] = SDL_SCANCODE_G;
|
|
+ map[keycode_normal(2, 6)] = SDL_SCANCODE_H;
|
|
+ map[keycode_normal(2, 7)] = SDL_SCANCODE_J;
|
|
+ map[keycode_normal(2, 8)] = SDL_SCANCODE_K;
|
|
+ map[keycode_normal(2, 9)] = SDL_SCANCODE_L;
|
|
+ map[keycode_normal(2, 10)] = SDL_SCANCODE_SEMICOLON;
|
|
+ map[keycode_normal(2, 11)] = SDL_SCANCODE_APOSTROPHE;
|
|
+ map[keycode_normal(2, 12)] = SDL_SCANCODE_BACKSLASH;
|
|
+ map[keycode_normal(2, 13)] = SDL_SCANCODE_RETURN;
|
|
+ map[keycode_normal(3, 0)] = SDL_SCANCODE_LSHIFT;
|
|
+ map[keycode_normal(3, 1)] = SDL_SCANCODE_NONUSBACKSLASH;
|
|
+ map[keycode_normal(3, 2)] = SDL_SCANCODE_Z;
|
|
+ map[keycode_normal(3, 3)] = SDL_SCANCODE_X;
|
|
+ map[keycode_normal(3, 4)] = SDL_SCANCODE_C;
|
|
+ map[keycode_normal(3, 5)] = SDL_SCANCODE_V;
|
|
+ map[keycode_normal(3, 6)] = SDL_SCANCODE_B;
|
|
+ map[keycode_normal(3, 7)] = SDL_SCANCODE_N;
|
|
+ map[keycode_normal(3, 8)] = SDL_SCANCODE_M;
|
|
+ map[keycode_normal(3, 9)] = SDL_SCANCODE_COMMA;
|
|
+ map[keycode_normal(3, 10)] = SDL_SCANCODE_PERIOD;
|
|
+ map[keycode_normal(3, 11)] = SDL_SCANCODE_SLASH;
|
|
+ map[keycode_normal(3, 12)] = SDL_SCANCODE_RSHIFT;
|
|
+ map[keycode_normal(4, 0)] = SDL_SCANCODE_LCTRL;
|
|
+ map[keycode_normal(4, 1)] = SDL_SCANCODE_LGUI;
|
|
+ map[keycode_normal(4, 2)] = SDL_SCANCODE_LALT;
|
|
+ map[keycode_normal(4, 3)] = SDL_SCANCODE_SPACE;
|
|
+ map[keycode_normal(4, 5)] = SDL_SCANCODE_RALT;
|
|
+ map[keycode_normal(4, 6)] = SDL_SCANCODE_RCTRL;
|
|
+
|
|
+ map[keycode_normal(5, 0)] = SDL_SCANCODE_UP;
|
|
+ map[keycode_normal(5, 1)] = SDL_SCANCODE_LEFT;
|
|
+ map[keycode_normal(5, 2)] = SDL_SCANCODE_DOWN;
|
|
+ map[keycode_normal(5, 3)] = SDL_SCANCODE_RIGHT;
|
|
+
|
|
+ map[keycode_function(0)] = SDL_SCANCODE_ESCAPE;
|
|
+ map[keycode_function(1)] = SDL_SCANCODE_F1;
|
|
+ map[keycode_function(2)] = SDL_SCANCODE_F2;
|
|
+ map[keycode_function(3)] = SDL_SCANCODE_F3;
|
|
+ map[keycode_function(4)] = SDL_SCANCODE_F4;
|
|
+ map[keycode_function(5)] = SDL_SCANCODE_F5;
|
|
+ map[keycode_function(6)] = SDL_SCANCODE_F6;
|
|
+ map[keycode_function(7)] = SDL_SCANCODE_F7;
|
|
+ map[keycode_function(8)] = SDL_SCANCODE_F8;
|
|
+ map[keycode_function(9)] = SDL_SCANCODE_F9;
|
|
+ map[keycode_function(10)] = SDL_SCANCODE_F10;
|
|
+ map[keycode_function(11)] = SDL_SCANCODE_F11;
|
|
+ map[keycode_function(12)] = SDL_SCANCODE_F12;
|
|
+ map[keycode_function(13)] = SDL_SCANCODE_INSERT;
|
|
+ map[keycode_function(14)] = SDL_SCANCODE_PRINTSCREEN;
|
|
+ map[keycode_function(15)] = SDL_SCANCODE_DELETE;
|
|
+ map[keycode_function(16)] = SDL_SCANCODE_HOME;
|
|
+ map[keycode_function(17)] = SDL_SCANCODE_END;
|
|
+ map[keycode_function(18)] = SDL_SCANCODE_PAGEUP;
|
|
+ map[keycode_function(19)] = SDL_SCANCODE_PAGEDOWN;
|
|
+ map[keycode_function(20)] = SDL_SCANCODE_SCROLLLOCK;
|
|
+
|
|
+ map[keycode_numpad(0, 0)] = SDL_SCANCODE_NUMLOCKCLEAR;
|
|
+ map[keycode_numpad(0, 1)] = SDL_SCANCODE_KP_DIVIDE;
|
|
+ map[keycode_numpad(0, 2)] = SDL_SCANCODE_KP_MULTIPLY;
|
|
+ map[keycode_numpad(0, 3)] = SDL_SCANCODE_KP_MINUS;
|
|
+ map[keycode_numpad(1, 0)] = SDL_SCANCODE_KP_7;
|
|
+ map[keycode_numpad(1, 1)] = SDL_SCANCODE_KP_8;
|
|
+ map[keycode_numpad(1, 2)] = SDL_SCANCODE_KP_9;
|
|
+ map[keycode_numpad(1, 3)] = SDL_SCANCODE_KP_PLUS;
|
|
+ map[keycode_numpad(2, 0)] = SDL_SCANCODE_KP_4;
|
|
+ map[keycode_numpad(2, 1)] = SDL_SCANCODE_KP_5;
|
|
+ map[keycode_numpad(2, 2)] = SDL_SCANCODE_KP_6;
|
|
+ map[keycode_numpad(3, 0)] = SDL_SCANCODE_KP_1;
|
|
+ map[keycode_numpad(3, 1)] = SDL_SCANCODE_KP_2;
|
|
+ map[keycode_numpad(3, 2)] = SDL_SCANCODE_KP_3;
|
|
+ map[keycode_numpad(3, 3)] = SDL_SCANCODE_KP_ENTER;
|
|
+ map[keycode_numpad(4, 0)] = SDL_SCANCODE_KP_0;
|
|
+ map[keycode_numpad(4, 1)] = SDL_SCANCODE_KP_COMMA;
|
|
+ };
|
|
+
|
|
+ SDL_Scancode map[0x100];
|
|
+};
|
|
+static Keymap s_keymap;
|
|
+
|
|
+static int BANANOS_mouse_button_to_sdl(LibInput::MouseButton button)
|
|
+{
|
|
+ switch (button) {
|
|
+#define BUTTON_CASE(my, sdl) case LibInput::MouseButton::my: return SDL_BUTTON_##sdl
|
|
+ BUTTON_CASE(Left, LEFT);
|
|
+ BUTTON_CASE(Right, RIGHT);
|
|
+ BUTTON_CASE(Middle, MIDDLE);
|
|
+ BUTTON_CASE(Extra1, X1);
|
|
+ BUTTON_CASE(Extra2, X2);
|
|
+#undef BUTTON_CASE
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static SDL_VideoDevice* s_video_device = nullptr;
|
|
+
|
|
+static SDL_Cursor* BANANOS_CreateSystemCursor(SDL_SystemCursor id)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ // FIXME: support system cursors :)
|
|
+
|
|
+ auto* cursor = static_cast<SDL_Cursor*>(SDL_calloc(1, sizeof(SDL_Cursor)));
|
|
+ if (cursor == nullptr) {
|
|
+ SDL_OutOfMemory();
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ return cursor;
|
|
+}
|
|
+
|
|
+static void BANANOS_FreeCursor(SDL_Cursor* cursor)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ if (cursor != nullptr)
|
|
+ SDL_free(cursor);
|
|
+}
|
|
+
|
|
+static int BANANOS_ShowCursor(SDL_Cursor* cursor)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ if (s_video_device == nullptr)
|
|
+ return 0;
|
|
+
|
|
+ auto& ban_video_device_data = *static_cast<banan_os_video_device_data*>(s_video_device->driverdata);
|
|
+ for (auto it = ban_video_device_data.windows.begin(); it != ban_video_device_data.windows.end(); it++)
|
|
+ (*it)->window->set_cursor_visible(!!cursor);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int BANANOS_SetRelativeMouseMode(SDL_bool enabled)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto* window = SDL_GetMouseFocus();
|
|
+ if (window == nullptr)
|
|
+ return 0;
|
|
+
|
|
+ auto& ban_window = *static_cast<banan_os_window*>(window->driverdata);
|
|
+ ban_window.window->set_mouse_relative(enabled);
|
|
+ ban_window.relative = enabled;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void BANANOS_InitMouse(_THIS)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto* mouse = SDL_GetMouse();
|
|
+ mouse->ShowCursor = BANANOS_ShowCursor;
|
|
+ mouse->SetRelativeMouseMode = BANANOS_SetRelativeMouseMode;
|
|
+ mouse->CreateSystemCursor = BANANOS_CreateSystemCursor;
|
|
+ mouse->FreeCursor = BANANOS_FreeCursor;
|
|
+
|
|
+ SDL_SetDefaultCursor(BANANOS_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW));
|
|
+}
|
|
+
|
|
+static int BANANOS_VideoInit(_THIS)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ BANANOS_InitMouse(_this);
|
|
+
|
|
+ int fb_fd = open("/dev/fb0", O_RDONLY);
|
|
+ if (fb_fd == -1) {
|
|
+ dwarnln("Failed to open framebuffer: {}", strerror(errno));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ framebuffer_info_t fb_info;
|
|
+ const ssize_t nread = pread(fb_fd, &fb_info, sizeof(fb_info), -1);
|
|
+ close(fb_fd);
|
|
+
|
|
+ if (nread != sizeof(fb_info)) {
|
|
+ dwarnln("Failed to get framebuffer info");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ SDL_DisplayMode mode {
|
|
+ .format = SDL_PIXELFORMAT_RGB888,
|
|
+ .w = static_cast<int>(fb_info.width),
|
|
+ .h = static_cast<int>(fb_info.height),
|
|
+ .refresh_rate = 60,
|
|
+ .driverdata = nullptr,
|
|
+ };
|
|
+
|
|
+ if (SDL_AddBasicVideoDisplay(&mode) < 0)
|
|
+ return -1;
|
|
+
|
|
+ SDL_AddDisplayMode(&_this->displays[0], &mode);
|
|
+
|
|
+ if (s_video_device == nullptr)
|
|
+ s_video_device = _this;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void BANANOS_VideoQuit(_THIS)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ if (s_video_device == _this)
|
|
+ s_video_device = nullptr;
|
|
+}
|
|
+
|
|
+static void BANANOS_free(_THIS)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+ delete static_cast<banan_os_video_device_data*>(_this->driverdata);
|
|
+ SDL_free(_this);
|
|
+}
|
|
+
|
|
+static int BANANOS_CreateSDLWindow(_THIS, SDL_Window* window)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto attributes = LibGUI::Window::default_attributes;
|
|
+ attributes.shown = false;
|
|
+ attributes.resizable = false;
|
|
+
|
|
+ auto window_or_error = LibGUI::Window::create(window->w, window->h, ""_sv, attributes);
|
|
+ if (window_or_error.is_error()) {
|
|
+ dwarnln("LibGUI::Window::create: {}", window_or_error.error());
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ auto& ban_video_device_data = *static_cast<banan_os_video_device_data*>(_this->driverdata);
|
|
+
|
|
+ auto* ban_window = new banan_os_window(window_or_error.release_value());
|
|
+
|
|
+ window->driverdata = ban_window;
|
|
+ if (window->driverdata == nullptr)
|
|
+ return -1;
|
|
+
|
|
+ if (ban_video_device_data.windows.push_back(ban_window).is_error()) {
|
|
+ delete ban_window;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ ban_window->window->set_key_event_callback(
|
|
+ [](LibGUI::EventPacket::KeyEvent::event_t event) {
|
|
+ SDL_SendKeyboardKey(event.pressed() ? SDL_PRESSED : SDL_RELEASED, s_keymap.map[event.scancode]);
|
|
+
|
|
+ if (event.pressed()) {
|
|
+ if (const char* utf8 = LibInput::key_to_utf8(event.key, event.modifier))
|
|
+ SDL_SendKeyboardText(utf8);
|
|
+ }
|
|
+ }
|
|
+ );
|
|
+
|
|
+ ban_window->window->set_mouse_button_event_callback(
|
|
+ [window, ban_window](LibGUI::EventPacket::MouseButtonEvent::event_t event) {
|
|
+ const int state = event.pressed ? SDL_PRESSED : SDL_RELEASED;
|
|
+ SDL_SendMouseMotion(window, 0, ban_window->relative, event.x, event.y);
|
|
+ SDL_SendMouseButton(window, 0, state, BANANOS_mouse_button_to_sdl(event.button));
|
|
+ }
|
|
+ );
|
|
+
|
|
+ ban_window->window->set_mouse_move_event_callback(
|
|
+ [window, ban_window](LibGUI::EventPacket::MouseMoveEvent::event_t event) {
|
|
+ SDL_SendMouseMotion(window, 0, ban_window->relative, event.x, event.y);
|
|
+ }
|
|
+ );
|
|
+
|
|
+ ban_window->window->set_mouse_scroll_event_callback(
|
|
+ [window](LibGUI::EventPacket::MouseScrollEvent::event_t event) {
|
|
+ SDL_SendMouseWheel(window, 0, 0.0f, event.scroll, SDL_MOUSEWHEEL_NORMAL);
|
|
+ }
|
|
+ );
|
|
+
|
|
+ ban_window->window->set_resize_window_event_callback(
|
|
+ [window, ban_window]() {
|
|
+ const size_t width = ban_window->window->width();
|
|
+ const size_t height = ban_window->window->height();
|
|
+
|
|
+ if (ban_window->gl_context) {
|
|
+ OSMesaMakeCurrent(
|
|
+ ban_window->gl_context,
|
|
+ ban_window->window->texture().pixels().data(),
|
|
+ GL_UNSIGNED_BYTE,
|
|
+ width, height
|
|
+ );
|
|
+ OSMesaPixelStore(OSMESA_Y_UP, 0);
|
|
+ }
|
|
+
|
|
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, width, height);
|
|
+ }
|
|
+ );
|
|
+
|
|
+ ban_window->window->set_window_shown_event_callback(
|
|
+ [window](LibGUI::EventPacket::WindowShownEvent::event_t event) {
|
|
+ const int state = event.shown ? SDL_WINDOWEVENT_SHOWN : SDL_WINDOWEVENT_HIDDEN;
|
|
+ SDL_SendWindowEvent(window, state, 0, 0);
|
|
+ }
|
|
+ );
|
|
+
|
|
+ ban_window->window->set_window_focus_event_callback(
|
|
+ [window](LibGUI::EventPacket::WindowFocusEvent::event_t event) {
|
|
+ SDL_SetKeyboardFocus(event.focused ? window : nullptr);
|
|
+ }
|
|
+ );
|
|
+
|
|
+ ban_window->window->set_close_window_event_callback(
|
|
+ [window]() {
|
|
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_CLOSE, 0, 0);
|
|
+ }
|
|
+ );
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void BANANOS_DestroyWindow(_THIS, SDL_Window* window)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto& ban_video_device_data = *static_cast<banan_os_video_device_data*>(_this->driverdata);
|
|
+ for (auto it = ban_video_device_data.windows.begin(); it != ban_video_device_data.windows.end(); it++) {
|
|
+ if (*it != static_cast<banan_os_window*>(window->driverdata))
|
|
+ continue;
|
|
+ ban_video_device_data.windows.remove(it);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ delete static_cast<banan_os_window*>(window->driverdata);
|
|
+ window->driverdata = nullptr;
|
|
+}
|
|
+
|
|
+static void BANANOS_ShowWindow(_THIS, SDL_Window* window)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto& ban_window = *static_cast<banan_os_window*>(window->driverdata);
|
|
+
|
|
+ auto attributes = ban_window.window->get_attributes();
|
|
+ if (attributes.shown)
|
|
+ return;
|
|
+ attributes.shown = true;
|
|
+
|
|
+ ban_window.window->set_attributes(attributes);
|
|
+}
|
|
+
|
|
+static void BANANOS_HideWindow(_THIS, SDL_Window* window)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto& ban_window = *static_cast<banan_os_window*>(window->driverdata);
|
|
+
|
|
+ auto attributes = ban_window.window->get_attributes();
|
|
+ if (!attributes.shown)
|
|
+ return;
|
|
+ attributes.shown = false;
|
|
+
|
|
+ ban_window.window->set_attributes(attributes);
|
|
+}
|
|
+
|
|
+static void BANANOS_SetWindowTitle(_THIS, SDL_Window* window)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto& ban_window = *static_cast<banan_os_window*>(window->driverdata);
|
|
+ ban_window.window->set_title(window->title);
|
|
+}
|
|
+
|
|
+static void BANANOS_SetWindowPosition(_THIS, SDL_Window* window)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto& ban_window = *static_cast<banan_os_window*>(window->driverdata);
|
|
+ ban_window.window->set_position(window->x, window->y);
|
|
+}
|
|
+
|
|
+static void BANANOS_SetWindowSize(_THIS, SDL_Window* window)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto& ban_window = *static_cast<banan_os_window*>(window->driverdata);
|
|
+ ban_window.window->request_resize(window->w, window->h);
|
|
+}
|
|
+
|
|
+static void BANANOS_SetWindowMinimumSize(_THIS, SDL_Window* window)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto& ban_window = *static_cast<banan_os_window*>(window->driverdata);
|
|
+ ban_window.window->set_min_size(window->min_w, window->min_h);
|
|
+}
|
|
+
|
|
+static void BANANOS_SetWindowMaximumSize(_THIS, SDL_Window* window)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto& ban_window = *static_cast<banan_os_window*>(window->driverdata);
|
|
+ ban_window.window->set_max_size(window->min_w, window->min_h);
|
|
+}
|
|
+
|
|
+static void BANANOS_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+}
|
|
+
|
|
+static void BANANOS_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto& ban_window = *static_cast<banan_os_window*>(window->driverdata);
|
|
+ if (auto attributes = ban_window.window->get_attributes(); attributes.resizable != resizable) {
|
|
+ attributes.resizable = resizable;
|
|
+ ban_window.window->set_attributes(attributes);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void BANANOS_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto& ban_window = *static_cast<banan_os_window*>(window->driverdata);
|
|
+ ban_window.window->set_fullscreen(fullscreen);
|
|
+}
|
|
+
|
|
+static int BANANOS_CreateWindowFramebuffer(_THIS, SDL_Window* window, Uint32* format, void** pixels, int* pitch)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto& ban_window = *static_cast<banan_os_window*>(window->driverdata);
|
|
+
|
|
+ if (ban_window.gl_context) {
|
|
+ dwarnln("CreateWindowFramebuffer with OpenGL context");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ auto framebuffer_or_error = LibGUI::Texture::create(ban_window.window->width(), ban_window.window->width(), 0x000000);
|
|
+ if (framebuffer_or_error.is_error()) {
|
|
+ dwarnln("LibGUI::Texture::create: {}", framebuffer_or_error.error());
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ *format = SDL_PIXELFORMAT_BGR888;
|
|
+ *pixels = ban_window.window->texture().pixels().data();
|
|
+ *pitch = ban_window.window->texture().width() * sizeof(uint32_t);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int BANANOS_UpdateWindowFramebuffer(_THIS, SDL_Window* window, const SDL_Rect* rects, int numrects)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto& ban_window = *static_cast<banan_os_window*>(window->driverdata);
|
|
+
|
|
+ for (int i = 0; i < numrects; i++)
|
|
+ ban_window.window->invalidate(rects[i].x, rects[i].y, rects[i].w, rects[i].h);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void BANANOS_DestroyWindowFramebuffer(_THIS, SDL_Window* window)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+}
|
|
+
|
|
+static void BANANOS_PumpEvents(_THIS)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto& ban_video_device_data = *static_cast<banan_os_video_device_data*>(_this->driverdata);
|
|
+ for (auto* window : ban_video_device_data.windows)
|
|
+ window->window->poll_events();
|
|
+}
|
|
+
|
|
+static int BANANOS_GL_LoadLibrary(_THIS, const char* path)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ if (_this->gl_config.driver_loaded) {
|
|
+ SDL_SetError("OpenGL library is already loaded");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ _this->gl_config.driver_loaded = SDL_TRUE;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void* BANANOS_GL_GetProcAddress(_THIS, const char* proc)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ return reinterpret_cast<void*>(OSMesaGetProcAddress(proc));
|
|
+}
|
|
+
|
|
+static SDL_GLContext BANANOS_GL_CreateContext(_THIS, SDL_Window* window)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto& ban_window = *static_cast<banan_os_window*>(window->driverdata);
|
|
+
|
|
+ auto gl_context = OSMesaCreateContext(OSMESA_BGRA, NULL);
|
|
+ if (gl_context == nullptr) {
|
|
+ dwarnln("OSMesaCreateContext");
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ auto& fb = ban_window.window->texture();
|
|
+ if (!OSMesaMakeCurrent(gl_context, fb.pixels().data(), GL_UNSIGNED_BYTE, fb.width(), fb.height())) {
|
|
+ OSMesaDestroyContext(gl_context);
|
|
+ return nullptr;
|
|
+ }
|
|
+ OSMesaPixelStore(OSMESA_Y_UP, 0);
|
|
+
|
|
+ ban_window.gl_context = gl_context;
|
|
+
|
|
+ return gl_context;
|
|
+}
|
|
+
|
|
+static void BANANOS_GL_DeleteContext(_THIS, SDL_GLContext context)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto gl_context = static_cast<OSMesaContext>(context);
|
|
+ OSMesaDestroyContext(gl_context);
|
|
+}
|
|
+
|
|
+static int BANANOS_GL_MakeCurrent(_THIS, SDL_Window* window, SDL_GLContext context)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ if (window == nullptr || context == nullptr)
|
|
+ return 0;
|
|
+
|
|
+ auto& ban_window = *static_cast<banan_os_window*>(window->driverdata);
|
|
+
|
|
+ auto gl_context = static_cast<OSMesaContext>(context);
|
|
+
|
|
+ auto& fb = ban_window.window->texture();
|
|
+ if (!OSMesaMakeCurrent(gl_context, fb.pixels().data(), GL_UNSIGNED_BYTE, fb.width(), fb.height()))
|
|
+ return -1;
|
|
+ OSMesaPixelStore(OSMESA_Y_UP, 0);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int BANANOS_GL_SwapWindow(_THIS, SDL_Window* window)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ static void (*glFinish)() = nullptr;
|
|
+ if (glFinish == nullptr)
|
|
+ glFinish = OSMesaGetProcAddress("glFinish");
|
|
+ glFinish();
|
|
+
|
|
+ auto& ban_window = *static_cast<banan_os_window*>(window->driverdata);
|
|
+ ban_window.window->invalidate();
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static SDL_VideoDevice* BANANOS_CreateDevice(void)
|
|
+{
|
|
+ DUMP_FUNCTION();
|
|
+
|
|
+ auto* device = static_cast<SDL_VideoDevice*>(SDL_calloc(1, sizeof(SDL_VideoDevice)));
|
|
+ if (device == nullptr) {
|
|
+ SDL_OutOfMemory();
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ device->driverdata = new banan_os_video_device_data();
|
|
+ if (device->driverdata == nullptr) {
|
|
+ SDL_OutOfMemory();
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ device->VideoInit = BANANOS_VideoInit;
|
|
+ device->VideoQuit = BANANOS_VideoQuit;
|
|
+
|
|
+ device->CreateSDLWindow = BANANOS_CreateSDLWindow;
|
|
+ device->DestroyWindow = BANANOS_DestroyWindow;
|
|
+ device->ShowWindow = BANANOS_ShowWindow;
|
|
+ device->HideWindow = BANANOS_HideWindow;
|
|
+
|
|
+ device->SetWindowTitle = BANANOS_SetWindowTitle;
|
|
+ device->SetWindowPosition = BANANOS_SetWindowPosition;
|
|
+ device->SetWindowSize = BANANOS_SetWindowSize;
|
|
+ device->SetWindowMinimumSize = BANANOS_SetWindowMinimumSize;
|
|
+ device->SetWindowMaximumSize = BANANOS_SetWindowMaximumSize;
|
|
+ device->SetWindowBordered = BANANOS_SetWindowBordered;
|
|
+ device->SetWindowResizable = BANANOS_SetWindowResizable;
|
|
+ device->SetWindowFullscreen = BANANOS_SetWindowFullscreen;
|
|
+
|
|
+ device->CreateWindowFramebuffer = BANANOS_CreateWindowFramebuffer;
|
|
+ device->UpdateWindowFramebuffer = BANANOS_UpdateWindowFramebuffer;
|
|
+ device->DestroyWindowFramebuffer = BANANOS_DestroyWindowFramebuffer;
|
|
+
|
|
+ device->PumpEvents = BANANOS_PumpEvents;
|
|
+
|
|
+ device->GL_LoadLibrary = BANANOS_GL_LoadLibrary;
|
|
+ device->GL_GetProcAddress = BANANOS_GL_GetProcAddress;
|
|
+ device->GL_CreateContext = BANANOS_GL_CreateContext;
|
|
+ device->GL_DeleteContext = BANANOS_GL_DeleteContext;
|
|
+ device->GL_MakeCurrent = BANANOS_GL_MakeCurrent;
|
|
+ device->GL_SwapWindow = BANANOS_GL_SwapWindow;
|
|
+
|
|
+ device->SetClipboardText = BANANOS_SetClipboardText;
|
|
+ device->GetClipboardText = BANANOS_GetClipboardText;
|
|
+ device->HasClipboardText = BANANOS_HasClipboardText;
|
|
+
|
|
+ device->free = BANANOS_free;
|
|
+
|
|
+ return device;
|
|
+}
|
|
+
|
|
+VideoBootStrap BANANOS_bootstrap = {
|
|
+ "banan-os", "banan-os graphics",
|
|
+ BANANOS_CreateDevice,
|
|
+ BANANOS_ShowMessageBox
|
|
+};
|
|
+
|
|
+#endif /* SDL_VIDEO_DRIVER_BANANOS */
|
|
+
|
|
+/* vi: set ts=4 sw=4 expandtab: */
|
|
diff -ruN SDL2-2.32.8/src/video/SDL_sysvideo.h SDL2-2.32.8-banan_os/src/video/SDL_sysvideo.h
|
|
--- SDL2-2.32.8/src/video/SDL_sysvideo.h 2025-05-20 00:24:41.000000000 +0300
|
|
+++ SDL2-2.32.8-banan_os/src/video/SDL_sysvideo.h 2026-01-03 19:50:45.781358361 +0200
|
|
@@ -462,6 +462,7 @@
|
|
extern VideoBootStrap WINDOWS_bootstrap;
|
|
extern VideoBootStrap WINRT_bootstrap;
|
|
extern VideoBootStrap HAIKU_bootstrap;
|
|
+extern VideoBootStrap BANANOS_bootstrap;
|
|
extern VideoBootStrap PND_bootstrap;
|
|
extern VideoBootStrap UIKIT_bootstrap;
|
|
extern VideoBootStrap Android_bootstrap;
|
|
diff -ruN SDL2-2.32.8/src/video/SDL_video.c SDL2-2.32.8-banan_os/src/video/SDL_video.c
|
|
--- SDL2-2.32.8/src/video/SDL_video.c 2025-05-20 00:24:41.000000000 +0300
|
|
+++ SDL2-2.32.8-banan_os/src/video/SDL_video.c 2026-01-03 19:50:45.782037083 +0200
|
|
@@ -96,6 +96,9 @@
|
|
#ifdef SDL_VIDEO_DRIVER_HAIKU
|
|
&HAIKU_bootstrap,
|
|
#endif
|
|
+#ifdef SDL_VIDEO_DRIVER_BANANOS
|
|
+ &BANANOS_bootstrap,
|
|
+#endif
|
|
#ifdef SDL_VIDEO_DRIVER_PANDORA
|
|
&PND_bootstrap,
|
|
#endif
|