mirror of
https://github.com/seekrs/MacroLibX.git
synced 2026-01-10 22:23:34 +00:00
293 lines
8.9 KiB
C++
293 lines
8.9 KiB
C++
#include <PreCompiled.h>
|
|
#include <Core/SDLManager.h>
|
|
#include <Core/Memory.h>
|
|
#include <Embedded/IconMlx.h>
|
|
#include <Utils/Bits.h>
|
|
|
|
namespace mlx
|
|
{
|
|
namespace Internal
|
|
{
|
|
struct WindowInfos
|
|
{
|
|
SDL_Window* window;
|
|
SDL_Surface* icon;
|
|
};
|
|
}
|
|
|
|
SDLManager* SDLManager::s_instance = nullptr;
|
|
|
|
SDLManager::SDLManager()
|
|
{
|
|
MLX_PROFILE_FUNCTION();
|
|
s_instance = this;
|
|
|
|
m_drop_sdl_responsability = SDL_WasInit(SDL_INIT_VIDEO) || std::getenv("MLX_HEADLESS_MODE") != nullptr;
|
|
if(m_drop_sdl_responsability) // is case the mlx is running in a sandbox like MacroUnitTester where SDL is already init
|
|
return;
|
|
//SDL_SetMemoryFunctions(MemManager::Get().Malloc, MemManager::Get().Calloc, MemManager::Get().Realloc, MemManager::Get().Free);
|
|
|
|
#ifdef FORCE_WAYLAND
|
|
SDL_SetHint(SDL_HINT_VIDEODRIVER, "wayland,x11");
|
|
#endif
|
|
|
|
//SDL_SetHintWithPriority(SDL_HINT_SHUTDOWN_DBUS_ON_QUIT, "1", SDL_HINT_OVERRIDE);
|
|
|
|
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_TIMER) != 0)
|
|
FatalError("SDL: unable to init all subsystems; %", SDL_GetError());
|
|
DebugLog("SDL Manager initialized");
|
|
}
|
|
|
|
Handle SDLManager::CreateWindow(const mlx_window_create_info* info, std::int32_t& id, bool hidden)
|
|
{
|
|
Internal::WindowInfos* infos = new Internal::WindowInfos;
|
|
Verify(infos != nullptr, "SDL: window allocation failed");
|
|
|
|
std::uint32_t flags = SDL_WINDOW_VULKAN;
|
|
if(hidden)
|
|
flags |= SDL_WINDOW_HIDDEN;
|
|
else
|
|
flags |= SDL_WINDOW_SHOWN;
|
|
if(info->is_resizable)
|
|
flags |= SDL_WINDOW_RESIZABLE;
|
|
if(info->is_fullscreen)
|
|
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
|
|
|
infos->window = SDL_CreateWindow(info->title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, info->width, info->height, flags);
|
|
if(!infos->window)
|
|
FatalError("SDL: unable to open a new window; %", SDL_GetError());
|
|
infos->icon = SDL_CreateRGBSurfaceFrom(static_cast<void*>(logo_mlx), logo_mlx_width, logo_mlx_height, 32, 4 * logo_mlx_width, Rmask(), Gmask(), Bmask(), Amask());
|
|
SDL_SetWindowIcon(infos->window, infos->icon);
|
|
|
|
m_windows_registry.insert(infos);
|
|
|
|
id = SDL_GetWindowID(infos->window);
|
|
|
|
return infos;
|
|
}
|
|
|
|
void SDLManager::DestroyWindow(Handle window) noexcept
|
|
{
|
|
Verify(m_windows_registry.find(window) != m_windows_registry.end(), "SDL: cannot destroy window; unknown window pointer");
|
|
|
|
Internal::WindowInfos* infos = static_cast<Internal::WindowInfos*>(window);
|
|
if(infos->window != nullptr)
|
|
SDL_DestroyWindow(infos->window);
|
|
if(infos->icon != nullptr)
|
|
SDL_FreeSurface(infos->icon);
|
|
|
|
m_windows_registry.erase(infos);
|
|
delete infos;
|
|
}
|
|
|
|
SDL_Window* SDLManager::GetRawWindow(Handle window) noexcept
|
|
{
|
|
Internal::WindowInfos* infos = static_cast<Internal::WindowInfos*>(window);
|
|
return infos->window;
|
|
}
|
|
|
|
VkSurfaceKHR SDLManager::CreateVulkanSurface(Handle window, VkInstance instance) const noexcept
|
|
{
|
|
VkSurfaceKHR surface;
|
|
if(!SDL_Vulkan_CreateSurface(static_cast<Internal::WindowInfos*>(window)->window, instance, &surface))
|
|
FatalError("SDL: could not create a Vulkan surface; %", SDL_GetError());
|
|
return surface;
|
|
}
|
|
|
|
std::vector<const char*> SDLManager::GetRequiredVulkanInstanceExtentions(Handle window) const noexcept
|
|
{
|
|
std::uint32_t count;
|
|
if(!SDL_Vulkan_GetInstanceExtensions(static_cast<Internal::WindowInfos*>(window)->window, &count, nullptr))
|
|
FatalError("SDL Manager: could not retrieve Vulkan instance extensions");
|
|
std::vector<const char*> extensions(count);
|
|
if(!SDL_Vulkan_GetInstanceExtensions(static_cast<Internal::WindowInfos*>(window)->window, &count, extensions.data()))
|
|
FatalError("SDL Manager: could not retrieve Vulkan instance extensions");
|
|
extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
|
|
return extensions;
|
|
}
|
|
|
|
Vec2ui SDLManager::GetVulkanDrawableSize(Handle window) const noexcept
|
|
{
|
|
Vec2i extent;
|
|
SDL_Vulkan_GetDrawableSize(static_cast<Internal::WindowInfos*>(window)->window, &extent.x, &extent.y);
|
|
return Vec2ui{ extent };
|
|
}
|
|
|
|
void SDLManager::MoveMouseOnWindow(Handle window, int x, int y) const noexcept
|
|
{
|
|
SDL_WarpMouseInWindow(static_cast<Internal::WindowInfos*>(window)->window, x, y);
|
|
SDL_PumpEvents();
|
|
}
|
|
|
|
void SDLManager::GetScreenSizeWindowIsOn(Handle window, int* x, int* y) const noexcept
|
|
{
|
|
SDL_DisplayMode DM;
|
|
SDL_GetDesktopDisplayMode(SDL_GetWindowDisplayIndex(static_cast<Internal::WindowInfos*>(window)->window), &DM);
|
|
*x = DM.w;
|
|
*y = DM.h;
|
|
}
|
|
|
|
void SDLManager::SetWindowPosition(Handle window, int x, int y) const noexcept
|
|
{
|
|
SDL_SetWindowPosition(static_cast<Internal::WindowInfos*>(window)->window, x, y);
|
|
}
|
|
|
|
void SDLManager::SetWindowSize(Handle window, int x, int y) const noexcept
|
|
{
|
|
SDL_SetWindowSize(static_cast<Internal::WindowInfos*>(window)->window, x, y);
|
|
}
|
|
|
|
void SDLManager::SetWindowTitle(Handle window, std::string_view title) const noexcept
|
|
{
|
|
SDL_SetWindowTitle(static_cast<Internal::WindowInfos*>(window)->window, title.data());
|
|
}
|
|
|
|
void SDLManager::SetWindowFullscreen(Handle window, bool enable) const noexcept
|
|
{
|
|
SDL_SetWindowFullscreen(static_cast<Internal::WindowInfos*>(window)->window, (enable ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0));
|
|
}
|
|
|
|
void SDLManager::SetWindowMaxSize(Handle window, int x, int y) const noexcept
|
|
{
|
|
SDL_SetWindowMaximumSize(static_cast<Internal::WindowInfos*>(window)->window, x, y);
|
|
}
|
|
|
|
void SDLManager::SetWindowMinSize(Handle window, int x, int y) const noexcept
|
|
{
|
|
SDL_SetWindowMinimumSize(static_cast<Internal::WindowInfos*>(window)->window, x, y);
|
|
}
|
|
|
|
void SDLManager::MaximizeWindow(Handle window) const noexcept
|
|
{
|
|
SDL_MaximizeWindow(static_cast<Internal::WindowInfos*>(window)->window);
|
|
}
|
|
|
|
void SDLManager::MinimizeWindow(Handle window) const noexcept
|
|
{
|
|
SDL_MinimizeWindow(static_cast<Internal::WindowInfos*>(window)->window);
|
|
}
|
|
|
|
void SDLManager::RestoreWindow(Handle window) const noexcept
|
|
{
|
|
SDL_RestoreWindow(static_cast<Internal::WindowInfos*>(window)->window);
|
|
}
|
|
|
|
void SDLManager::GetWindowPosition(Handle window, int* x, int* y) const noexcept
|
|
{
|
|
SDL_GetWindowPosition(static_cast<Internal::WindowInfos*>(window)->window, x, y);
|
|
}
|
|
|
|
void SDLManager::GetWindowSize(Handle window, int* x, int* y) const noexcept
|
|
{
|
|
SDL_GetWindowSize(static_cast<Internal::WindowInfos*>(window)->window, x, y);
|
|
}
|
|
|
|
void SDLManager::HideCursor() noexcept
|
|
{
|
|
SDL_ShowCursor(SDL_DISABLE);
|
|
}
|
|
|
|
void SDLManager::ShowCursor() noexcept
|
|
{
|
|
SDL_ShowCursor(SDL_ENABLE);
|
|
}
|
|
|
|
std::int32_t SDLManager::GetX() const noexcept
|
|
{
|
|
int dummy;
|
|
int x;
|
|
SDL_GetMouseState(&x, &dummy);
|
|
return x;
|
|
}
|
|
|
|
std::int32_t SDLManager::GetY() const noexcept
|
|
{
|
|
int dummy;
|
|
int y;
|
|
SDL_GetMouseState(&dummy, &y);
|
|
return y;
|
|
}
|
|
|
|
std::int32_t SDLManager::GetXRel() const noexcept
|
|
{
|
|
int dummy;
|
|
int x;
|
|
SDL_GetRelativeMouseState(&x, &dummy);
|
|
return x;
|
|
}
|
|
|
|
std::int32_t SDLManager::GetYRel() const noexcept
|
|
{
|
|
int dummy;
|
|
int y;
|
|
SDL_GetRelativeMouseState(&dummy, &y);
|
|
return y;
|
|
}
|
|
|
|
void SDLManager::SetInputBinding(std::function<void(SDL_Event*)> functor)
|
|
{
|
|
m_binding_hook = std::move(functor);
|
|
}
|
|
|
|
void SDLManager::InputsFetcher(std::function<void(mlx_event_type, int, int)> functor)
|
|
{
|
|
SDL_Event event;
|
|
while(SDL_PollEvent(&event))
|
|
{
|
|
std::uint32_t id = event.window.windowID;
|
|
switch(event.type)
|
|
{
|
|
case SDL_KEYUP: functor(MLX_KEYUP, id, event.key.keysym.scancode); break;
|
|
case SDL_KEYDOWN: functor(MLX_KEYDOWN, id, event.key.keysym.scancode); break;
|
|
case SDL_MOUSEBUTTONUP: functor(MLX_MOUSEUP, id, event.button.button); break;
|
|
case SDL_MOUSEBUTTONDOWN: functor(MLX_MOUSEDOWN, id, event.button.button); break;
|
|
case SDL_MOUSEWHEEL:
|
|
{
|
|
if(event.wheel.y > 0) // scroll up
|
|
functor(MLX_MOUSEWHEEL, id, 1);
|
|
else if(event.wheel.y < 0) // scroll down
|
|
functor(MLX_MOUSEWHEEL, id, 2);
|
|
if(event.wheel.x > 0) // scroll right
|
|
functor(MLX_MOUSEWHEEL, id, 3);
|
|
else if(event.wheel.x < 0) // scroll left
|
|
functor(MLX_MOUSEWHEEL, id, 4);
|
|
break;
|
|
}
|
|
case SDL_WINDOWEVENT:
|
|
{
|
|
switch(event.window.event)
|
|
{
|
|
case SDL_WINDOWEVENT_CLOSE: functor(MLX_WINDOW_EVENT, id, 0); break;
|
|
case SDL_WINDOWEVENT_MOVED: functor(MLX_WINDOW_EVENT, id, 1); break;
|
|
case SDL_WINDOWEVENT_MINIMIZED: functor(MLX_WINDOW_EVENT, id, 2); break;
|
|
case SDL_WINDOWEVENT_MAXIMIZED: functor(MLX_WINDOW_EVENT, id, 3); break;
|
|
case SDL_WINDOWEVENT_ENTER: functor(MLX_WINDOW_EVENT, id, 4); break;
|
|
case SDL_WINDOWEVENT_FOCUS_GAINED: functor(MLX_WINDOW_EVENT, id, 5); break;
|
|
case SDL_WINDOWEVENT_LEAVE: functor(MLX_WINDOW_EVENT, id, 6); break;
|
|
case SDL_WINDOWEVENT_FOCUS_LOST: functor(MLX_WINDOW_EVENT, id, 7); break;
|
|
case SDL_WINDOWEVENT_SIZE_CHANGED: functor(MLX_WINDOW_EVENT, id, 8); break;
|
|
|
|
default : break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
default: break;
|
|
}
|
|
|
|
if(m_binding_hook)
|
|
m_binding_hook(&event);
|
|
}
|
|
}
|
|
|
|
SDLManager::~SDLManager()
|
|
{
|
|
if(m_drop_sdl_responsability)
|
|
return;
|
|
SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS);
|
|
SDL_Quit();
|
|
s_instance = nullptr;
|
|
DebugLog("SDL Manager uninitialized");
|
|
}
|
|
}
|