forked from Bananymous/banan-os
				
			
		
			
				
	
	
		
			1240 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			Diff
		
	
	
	
			
		
		
	
	
			1240 lines
		
	
	
		
			40 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	2025-08-06 02:07:18.347821313 +0300
 | |
| @@ -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	2025-08-06 02:19:44.864415796 +0300
 | |
| @@ -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,57 @@
 | |
|    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_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)
 | |
| +
 | |
| +    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	2025-08-06 02:01:21.085539504 +0300
 | |
| @@ -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@
 | |
| @@ -406,6 +407,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	2025-08-06 02:01:21.085701327 +0300
 | |
| @@ -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	2025-08-06 02:01:21.085876490 +0300
 | |
| @@ -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	2025-08-06 02:01:21.085937043 +0300
 | |
| @@ -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	2025-08-06 02:01:21.086082872 +0300
 | |
| @@ -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	2025-08-06 02:01:21.086309718 +0300
 | |
| @@ -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/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	2025-08-06 02:01:21.086457363 +0300
 | |
| @@ -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_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	2025-08-06 02:01:21.086557935 +0300
 | |
| @@ -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	2025-08-06 02:01:21.086603053 +0300
 | |
| @@ -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	2025-08-21 02:32:59.649175565 +0300
 | |
| @@ -0,0 +1,724 @@
 | |
| +/*
 | |
| +  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_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->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	2025-08-06 02:01:21.086873550 +0300
 | |
| @@ -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	2025-08-06 02:01:21.087224294 +0300
 | |
| @@ -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
 |