Port to SDL3 instead of SDL2

Main reason is that SDL3 allows getting keyboard mappings with modifiers
This commit is contained in:
2026-06-01 17:11:12 +03:00
parent 11ebced96a
commit b41d979dcb
4 changed files with 128 additions and 160 deletions

View File

@@ -450,7 +450,7 @@ void send_exposure_recursive(WINDOW wid)
struct PlatformWindowInfo struct PlatformWindowInfo
{ {
PlatformWindow* transient_for; PlatformWindow* parent;
WindowType type; WindowType type;
}; };
@@ -466,7 +466,7 @@ static PlatformWindowInfo get_plaform_window_info(const Object::Window& window)
static const CARD32 _NET_WM_WINDOW_TYPE_UTILITY = g_atoms_name_to_id["_NET_WM_WINDOW_TYPE_UTILITY"_sv]; static const CARD32 _NET_WM_WINDOW_TYPE_UTILITY = g_atoms_name_to_id["_NET_WM_WINDOW_TYPE_UTILITY"_sv];
PlatformWindowInfo info { PlatformWindowInfo info {
.transient_for = nullptr, .parent = nullptr,
.type = WindowType::Normal, .type = WindowType::Normal,
}; };
@@ -478,7 +478,7 @@ static PlatformWindowInfo get_plaform_window_info(const Object::Window& window)
const CARD32 type = *reinterpret_cast<const CARD32*>(it->value.data.data()); const CARD32 type = *reinterpret_cast<const CARD32*>(it->value.data.data());
if (type == _NET_WM_WINDOW_TYPE_NORMAL) if (type == _NET_WM_WINDOW_TYPE_NORMAL)
info.type = WindowType::Normal; info.type = WindowType::Normal;
else if (type == _NET_WM_WINDOW_TYPE_SPLASH || type == _NET_WM_WINDOW_TYPE_UTILITY || type == _NET_WM_WINDOW_TYPE_DIALOG) else if (type == _NET_WM_WINDOW_TYPE_SPLASH || type == _NET_WM_WINDOW_TYPE_DIALOG)
info.type = WindowType::Utility; info.type = WindowType::Utility;
else else
info.type = WindowType::Popup; info.type = WindowType::Popup;
@@ -500,7 +500,7 @@ wm_window_type_done:
// FIXME: support child windows // FIXME: support child windows
auto& window = it2->value->object.get<Object::Window>(); auto& window = it2->value->object.get<Object::Window>();
info.transient_for = window.platform_window.ptr(); info.parent = window.platform_window.ptr();
} }
transitient_for_done: transitient_for_done:
@@ -529,7 +529,7 @@ static BAN::ErrorOr<void> map_window(Client& client_info, WINDOW wid)
auto info = get_plaform_window_info(window); auto info = get_plaform_window_info(window);
window.platform_window = TRY(g_platform_ops.create_window( window.platform_window = TRY(g_platform_ops.create_window(
info.transient_for, info.parent,
info.type, info.type,
wid, wid,
window.x, window.x,

View File

@@ -24,15 +24,15 @@ endif()
set(PLATFORM "banan-os" CACHE STRING "target platform") set(PLATFORM "banan-os" CACHE STRING "target platform")
set(VALID_PLATFORMS "banan-os" "SDL2") set(VALID_PLATFORMS "banan-os" "SDL3")
if(NOT PLATFORM IN_LIST VALID_PLATFORMS) if(NOT PLATFORM IN_LIST VALID_PLATFORMS)
message(FATAL_ERROR "platform \"${PLATFORM}\" not known, valid platforms are ${VALID_PLATFORMS}") message(FATAL_ERROR "platform \"${PLATFORM}\" not known, valid platforms are ${VALID_PLATFORMS}")
endif() endif()
if(PLATFORM STREQUAL "banan-os") if(PLATFORM STREQUAL "banan-os")
list(APPEND XBANAN_SOURCES banan-os/banan-os.cpp) list(APPEND XBANAN_SOURCES banan-os/banan-os.cpp)
elseif(PLATFORM STREQUAL "SDL2") elseif(PLATFORM STREQUAL "SDL3")
list(APPEND XBANAN_SOURCES SDL2/sdl2.cpp) list(APPEND XBANAN_SOURCES SDL3/sdl3.cpp)
endif() endif()
add_executable(xbanan ${XBANAN_SOURCES}) add_executable(xbanan ${XBANAN_SOURCES})
@@ -42,9 +42,9 @@ banan_link_library(xbanan libinput)
if(PLATFORM STREQUAL "banan-os") if(PLATFORM STREQUAL "banan-os")
banan_link_library(xbanan libgui) banan_link_library(xbanan libgui)
elseif(PLATFORM STREQUAL "SDL2") elseif(PLATFORM STREQUAL "SDL3")
find_package(SDL2 REQUIRED) find_package(SDL3 REQUIRED)
banan_link_library(xbanan SDL2::SDL2) banan_link_library(xbanan SDL3::SDL3)
endif() endif()
target_compile_options(xbanan PRIVATE -Wall -Wextra) target_compile_options(xbanan PRIVATE -Wall -Wextra)

View File

@@ -16,9 +16,9 @@ struct PlatformCursor
enum class WindowType enum class WindowType
{ {
Popup,
Normal, Normal,
Utility, Utility,
Popup,
}; };
enum class SystemCursorType enum class SystemCursorType

View File

@@ -4,7 +4,7 @@
#include <BAN/Atomic.h> #include <BAN/Atomic.h>
#include <BAN/HashMap.h> #include <BAN/HashMap.h>
#include <SDL2/SDL.h> #include <SDL3/SDL.h>
#include <pthread.h> #include <pthread.h>
#include <sys/eventfd.h> #include <sys/eventfd.h>
@@ -44,7 +44,7 @@ struct SDLCursor final : public PlatformCursor
~SDLCursor() ~SDLCursor()
{ {
if (cursor != nullptr) if (cursor != nullptr)
SDL_FreeCursor(cursor); SDL_DestroyCursor(cursor);
} }
SDL_Cursor* cursor { nullptr }; SDL_Cursor* cursor { nullptr };
@@ -55,13 +55,13 @@ static int s_eventfd { -1 };
struct Keymap struct Keymap
{ {
consteval Keymap(); consteval Keymap();
uint8_t map[SDL_NUM_SCANCODES]; uint8_t map[SDL_SCANCODE_COUNT];
}; };
static Keymap s_sdl_keymap; static Keymap s_sdl_keymap;
static SDL_Cursor* s_default_cursor { nullptr }; static SDL_Cursor* s_default_cursor { nullptr };
static void* sdl2_thread(void*) static void* sdl3_thread(void*)
{ {
for (;;) for (;;)
{ {
@@ -73,22 +73,24 @@ static void* sdl2_thread(void*)
return nullptr; return nullptr;
} }
static bool sdl2_initialize(uint32_t* display_w, uint32_t* display_h) static bool sdl3_initialize(uint32_t* display_w, uint32_t* display_h)
{ {
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) == -1) if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS))
{ {
dwarnln("Could not initialize SDL: {}", SDL_GetError()); dwarnln("Could not initialize SDL: {}", SDL_GetError());
return false; return false;
} }
SDL_DisplayMode DM; *display_w = *display_h = 0;
if (SDL_GetCurrentDisplayMode(0, &DM) == -1)
const SDL_DisplayID* display_ids = SDL_GetDisplays(nullptr);
for (int i = 0; display_ids[i]; i++)
{ {
dwarnln("Could not get display mode: {}", SDL_GetError()); SDL_Rect rect;
return false; SDL_GetDisplayBounds(display_ids[i], &rect);
*display_w = BAN::Math::max<uint32_t>(*display_w, rect.x + rect.w);
*display_h = BAN::Math::max<uint32_t>(*display_h, rect.y + rect.h);
} }
*display_w = DM.w;
*display_h = DM.h;
s_default_cursor = SDL_GetCursor(); s_default_cursor = SDL_GetCursor();
@@ -102,12 +104,12 @@ static bool sdl2_initialize(uint32_t* display_w, uint32_t* display_h)
register_event_fd(s_eventfd, nullptr); register_event_fd(s_eventfd, nullptr);
pthread_t thread; pthread_t thread;
pthread_create(&thread, nullptr, sdl2_thread, nullptr); pthread_create(&thread, nullptr, sdl3_thread, nullptr);
return true; return true;
} }
static BAN::ErrorOr<BAN::UniqPtr<PlatformWindow>> sdl2_create_window(PlatformWindow* parent, WindowType type, WINDOW wid, int32_t x, int32_t y, uint32_t width, uint32_t height) static BAN::ErrorOr<BAN::UniqPtr<PlatformWindow>> sdl3_create_window(PlatformWindow* parent, WindowType type, WINDOW wid, int32_t x, int32_t y, uint32_t width, uint32_t height)
{ {
auto window = TRY(BAN::UniqPtr<SDLWindow>::create()); auto window = TRY(BAN::UniqPtr<SDLWindow>::create());
@@ -115,39 +117,37 @@ static BAN::ErrorOr<BAN::UniqPtr<PlatformWindow>> sdl2_create_window(PlatformWin
window->width = width; window->width = width;
window->height = height; window->height = height;
if (parent == nullptr)
x = y = SDL_WINDOWPOS_UNDEFINED;
else
{
auto& sdl_parent = *static_cast<SDLWindow*>(parent);
int parent_x, parent_y;
SDL_GetWindowPosition(sdl_parent.window, &parent_x, &parent_y);
x += parent_x;
y += parent_y;
}
int flags; int flags;
switch (type) switch (type)
{ {
case WindowType::Popup:
flags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_UTILITY;
break;
case WindowType::Utility:
flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_UTILITY;
break;
case WindowType::Normal: case WindowType::Normal:
case WindowType::Utility:
flags = SDL_WINDOW_RESIZABLE; flags = SDL_WINDOW_RESIZABLE;
break; break;
case WindowType::Popup:
flags = SDL_WINDOW_BORDERLESS;
break;
}
if (parent == nullptr || type != WindowType::Popup)
{
if (type != WindowType::Normal)
flags |= SDL_WINDOW_UTILITY;
window->window = SDL_CreateWindow("", width, height, flags);
}
else
{
auto& sdl_parent = *static_cast<SDLWindow*>(parent);
window->window = SDL_CreatePopupWindow(sdl_parent.window, x, y, width, height, flags | SDL_WINDOW_POPUP_MENU);
} }
window->window = SDL_CreateWindow("", x, y, width, height, flags);
if (window->window == nullptr) if (window->window == nullptr)
{ {
dwarnln("Could not create SDL window: {}", SDL_GetError()); dwarnln("Could not create SDL window: {}", SDL_GetError());
return BAN::Error::from_errno(EFAULT); return BAN::Error::from_errno(EFAULT);
} }
window->renderer = SDL_CreateRenderer(window->window, -1, SDL_RENDERER_ACCELERATED); window->renderer = SDL_CreateRenderer(window->window, nullptr);
if (window->renderer == nullptr) if (window->renderer == nullptr)
{ {
dwarnln("Could not create SDL renderer: {}", SDL_GetError()); dwarnln("Could not create SDL renderer: {}", SDL_GetError());
@@ -166,13 +166,13 @@ static BAN::ErrorOr<BAN::UniqPtr<PlatformWindow>> sdl2_create_window(PlatformWin
return BAN::UniqPtr<PlatformWindow>(BAN::move(window)); return BAN::UniqPtr<PlatformWindow>(BAN::move(window));
} }
static void sdl2_request_resize(PlatformWindow* window, uint32_t width, uint32_t height) static void sdl3_request_resize(PlatformWindow* window, uint32_t width, uint32_t height)
{ {
auto& sdl_window = *static_cast<SDLWindow*>(window); auto& sdl_window = *static_cast<SDLWindow*>(window);
SDL_SetWindowSize(sdl_window.window, width, height); SDL_SetWindowSize(sdl_window.window, width, height);
} }
static void sdl2_poll_events(void*) static void sdl3_poll_events(void*)
{ {
uint64_t dummy; uint64_t dummy;
read(s_eventfd, &dummy, sizeof(dummy)); read(s_eventfd, &dummy, sizeof(dummy));
@@ -182,54 +182,44 @@ static void sdl2_poll_events(void*)
{ {
switch (event.type) switch (event.type)
{ {
case SDL_WINDOWEVENT: case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
{ if (auto it = s_window_map.find(event.window.windowID); it != s_window_map.end())
auto it = s_window_map.find(event.window.windowID); on_window_close_event(it->value->wid);
if (it == s_window_map.end()) break;
break; case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
auto& window = *it->value; if (auto it = s_window_map.find(event.window.windowID); it != s_window_map.end())
switch (event.window.event)
{ {
case SDL_WINDOWEVENT_CLOSE: auto& window = *it->value;
on_window_close_event(window.wid); window.width = event.window.data1;
break; window.height = event.window.data2;
case SDL_WINDOWEVENT_SIZE_CHANGED:
window.width = event.window.data1;
window.height = event.window.data2;
SDL_DestroyTexture(window.texture); SDL_DestroyTexture(window.texture);
window.texture = SDL_CreateTexture(window.renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, window.width, window.height); window.texture = SDL_CreateTexture(window.renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, window.width, window.height);
ASSERT(window.texture); ASSERT(window.texture);
on_window_resize_event(window.wid, event.window.data1, event.window.data2); on_window_resize_event(window.wid, window.width, window.height);
break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
on_window_focus_event(window.wid, true);
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
on_window_focus_event(window.wid, false);
break;
case SDL_WINDOWEVENT_MAXIMIZED:
on_window_fullscreen_event(window.wid, true);
break;
case SDL_WINDOWEVENT_RESTORED:
on_window_fullscreen_event(window.wid, false);
break;
case SDL_WINDOWEVENT_LEAVE:
on_window_leave_event(window.wid);
break;
} }
break; break;
} case SDL_EVENT_WINDOW_FOCUS_GAINED:
case SDL_MOUSEMOTION: case SDL_EVENT_WINDOW_FOCUS_LOST:
{ if (auto it = s_window_map.find(event.motion.windowID); it != s_window_map.end())
auto it = s_window_map.find(event.window.windowID); on_window_focus_event(it->value->wid, (event.type == SDL_EVENT_WINDOW_FOCUS_GAINED));
if (it != s_window_map.end()) break;
case SDL_EVENT_WINDOW_ENTER_FULLSCREEN:
case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN:
if (auto it = s_window_map.find(event.motion.windowID); it != s_window_map.end())
on_window_fullscreen_event(it->value->wid, (event.type == SDL_EVENT_WINDOW_ENTER_FULLSCREEN));
break;
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
if (auto it = s_window_map.find(event.motion.windowID); it != s_window_map.end())
on_window_leave_event(it->value->wid);
break;
case SDL_EVENT_MOUSE_MOTION:
if (auto it = s_window_map.find(event.motion.windowID); it != s_window_map.end())
on_mouse_move_event(it->value->wid, event.motion.x, event.motion.y); on_mouse_move_event(it->value->wid, event.motion.x, event.motion.y);
break; break;
} case SDL_EVENT_MOUSE_BUTTON_UP:
case SDL_MOUSEBUTTONUP: case SDL_EVENT_MOUSE_BUTTON_DOWN:
case SDL_MOUSEBUTTONDOWN:
{ {
uint8_t xbutton { 0 }; uint8_t xbutton { 0 };
switch (event.button.button) switch (event.button.button)
@@ -243,10 +233,10 @@ static void sdl2_poll_events(void*)
auto it = s_window_map.find(event.window.windowID); auto it = s_window_map.find(event.window.windowID);
if (xbutton && it != s_window_map.end()) if (xbutton && it != s_window_map.end())
on_mouse_button_event(it->value->wid, xbutton, (event.type == SDL_MOUSEBUTTONDOWN)); on_mouse_button_event(it->value->wid, xbutton, (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN));
break; break;
} }
case SDL_MOUSEWHEEL: case SDL_EVENT_MOUSE_WHEEL:
{ {
uint8_t xbutton { 0 }; uint8_t xbutton { 0 };
if (event.wheel.y > 0) if (event.wheel.y > 0)
@@ -263,31 +253,31 @@ static void sdl2_poll_events(void*)
break; break;
} }
case SDL_KEYUP: case SDL_EVENT_KEY_UP:
case SDL_KEYDOWN: case SDL_EVENT_KEY_DOWN:
{ {
uint8_t scancode = s_sdl_keymap.map[event.key.keysym.scancode]; uint8_t scancode = s_sdl_keymap.map[event.key.scancode];
uint8_t xmod { 0 }; uint8_t xmod { 0 };
if (event.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) if (event.key.mod & SDL_KMOD_SHIFT)
xmod |= (1 << 0); xmod |= (1 << 0);
if (event.key.keysym.mod & (KMOD_CAPS)) if (event.key.mod & SDL_KMOD_CAPS)
xmod |= (1 << 1); xmod |= (1 << 1);
if (event.key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) if (event.key.mod & SDL_KMOD_CTRL)
xmod |= (1 << 2); xmod |= (1 << 2);
if (event.key.keysym.mod & (KMOD_LALT | KMOD_RALT)) if (event.key.mod & SDL_KMOD_ALT)
xmod |= (1 << 3); xmod |= (1 << 3);
auto it = s_window_map.find(event.window.windowID); auto it = s_window_map.find(event.window.windowID);
if (it != s_window_map.end()) if (it != s_window_map.end())
on_key_event(it->value->wid, scancode, xmod, (event.type == SDL_KEYDOWN)); on_key_event(it->value->wid, scancode, xmod, (event.type == SDL_EVENT_KEY_DOWN));
break; break;
} }
} }
} }
} }
static void sdl2_invalidate(PlatformWindow* window, const uint32_t* src_pixels, uint32_t x, uint32_t y, uint32_t width, uint32_t height) static void sdl3_invalidate(PlatformWindow* window, const uint32_t* src_pixels, uint32_t x, uint32_t y, uint32_t width, uint32_t height)
{ {
auto& sdl_window = *static_cast<SDLWindow*>(window); auto& sdl_window = *static_cast<SDLWindow*>(window);
@@ -303,7 +293,7 @@ static void sdl2_invalidate(PlatformWindow* window, const uint32_t* src_pixels,
void* dst_pixels; void* dst_pixels;
int dst_pitch; int dst_pitch;
if (SDL_LockTexture(sdl_window.texture, &rect, &dst_pixels, &dst_pitch) == -1) if (!SDL_LockTexture(sdl_window.texture, &rect, &dst_pixels, &dst_pitch))
{ {
dwarnln("Could not lock texture: {}", SDL_GetError()); dwarnln("Could not lock texture: {}", SDL_GetError());
return; return;
@@ -321,63 +311,41 @@ static void sdl2_invalidate(PlatformWindow* window, const uint32_t* src_pixels,
SDL_UnlockTexture(sdl_window.texture); SDL_UnlockTexture(sdl_window.texture);
SDL_RenderClear(sdl_window.renderer); SDL_RenderClear(sdl_window.renderer);
SDL_RenderCopy(sdl_window.renderer, sdl_window.texture, NULL, NULL); SDL_RenderTexture(sdl_window.renderer, sdl_window.texture, NULL, NULL);
SDL_RenderPresent(sdl_window.renderer); SDL_RenderPresent(sdl_window.renderer);
} }
static void sdl2_request_fullscreen(PlatformWindow* window, bool fullscreen) static void sdl3_request_fullscreen(PlatformWindow* window, bool fullscreen)
{ {
auto& sdl_window = *static_cast<SDLWindow*>(window); auto& sdl_window = *static_cast<SDLWindow*>(window);
SDL_SetWindowFullscreen(sdl_window.window, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); SDL_SetWindowFullscreen(sdl_window.window, fullscreen);
} }
static BAN::ErrorOr<BAN::UniqPtr<PlatformCursor>> sdl2_create_system_cursor(SystemCursorType type) static BAN::ErrorOr<BAN::UniqPtr<PlatformCursor>> sdl3_create_system_cursor(SystemCursorType type)
{ {
SDL_SystemCursor sdl_type; static constexpr SDL_SystemCursor cursor_type_map[] {
switch (type) [static_cast<size_t>(SystemCursorType::Pointer)] = SDL_SYSTEM_CURSOR_DEFAULT,
{ [static_cast<size_t>(SystemCursorType::Text)] = SDL_SYSTEM_CURSOR_TEXT,
case SystemCursorType::Help: [static_cast<size_t>(SystemCursorType::Wait)] = SDL_SYSTEM_CURSOR_WAIT,
case SystemCursorType::Pointer: [static_cast<size_t>(SystemCursorType::Hand)] = SDL_SYSTEM_CURSOR_POINTER,
sdl_type = SDL_SYSTEM_CURSOR_ARROW; [static_cast<size_t>(SystemCursorType::Help)] = SDL_SYSTEM_CURSOR_DEFAULT, // :(
break; [static_cast<size_t>(SystemCursorType::Move)] = SDL_SYSTEM_CURSOR_MOVE,
case SystemCursorType::Text: [static_cast<size_t>(SystemCursorType::Forbidden)] = SDL_SYSTEM_CURSOR_NOT_ALLOWED,
sdl_type = SDL_SYSTEM_CURSOR_IBEAM; [static_cast<size_t>(SystemCursorType::ResizeN)] = SDL_SYSTEM_CURSOR_N_RESIZE,
break; [static_cast<size_t>(SystemCursorType::ResizeE)] = SDL_SYSTEM_CURSOR_E_RESIZE,
case SystemCursorType::Wait: [static_cast<size_t>(SystemCursorType::ResizeS)] = SDL_SYSTEM_CURSOR_S_RESIZE,
sdl_type = SDL_SYSTEM_CURSOR_WAIT; [static_cast<size_t>(SystemCursorType::ResizeW)] = SDL_SYSTEM_CURSOR_W_RESIZE,
break; [static_cast<size_t>(SystemCursorType::ResizeNW)] = SDL_SYSTEM_CURSOR_NW_RESIZE,
case SystemCursorType::Hand: [static_cast<size_t>(SystemCursorType::ResizeNE)] = SDL_SYSTEM_CURSOR_NE_RESIZE,
sdl_type = SDL_SYSTEM_CURSOR_HAND; [static_cast<size_t>(SystemCursorType::ResizeSW)] = SDL_SYSTEM_CURSOR_SW_RESIZE,
break; [static_cast<size_t>(SystemCursorType::ResizeSE)] = SDL_SYSTEM_CURSOR_SE_RESIZE,
case SystemCursorType::Move: [static_cast<size_t>(SystemCursorType::ResizeVertical)] = SDL_SYSTEM_CURSOR_NS_RESIZE,
sdl_type = SDL_SYSTEM_CURSOR_SIZEALL; [static_cast<size_t>(SystemCursorType::ResizeHorizontal)] = SDL_SYSTEM_CURSOR_EW_RESIZE,
break; };
case SystemCursorType::Forbidden:
sdl_type = SDL_SYSTEM_CURSOR_NO;
break;
case SystemCursorType::ResizeN:
case SystemCursorType::ResizeS:
case SystemCursorType::ResizeVertical:
sdl_type = SDL_SYSTEM_CURSOR_SIZENS;
break;
case SystemCursorType::ResizeE:
case SystemCursorType::ResizeW:
case SystemCursorType::ResizeHorizontal:
sdl_type = SDL_SYSTEM_CURSOR_SIZEWE;
break;
case SystemCursorType::ResizeNW:
case SystemCursorType::ResizeSE:
sdl_type = SDL_SYSTEM_CURSOR_SIZENWSE;
break;
case SystemCursorType::ResizeNE:
case SystemCursorType::ResizeSW:
sdl_type = SDL_SYSTEM_CURSOR_SIZENESW;
break;
}
auto cursor = TRY(BAN::UniqPtr<SDLCursor>::create()); auto cursor = TRY(BAN::UniqPtr<SDLCursor>::create());
cursor->cursor = SDL_CreateSystemCursor(sdl_type); cursor->cursor = SDL_CreateSystemCursor(cursor_type_map[static_cast<size_t>(type)]);
if (cursor->cursor == nullptr) if (cursor->cursor == nullptr)
{ {
dwarnln("Could not create SDL system cursor: {}", SDL_GetError()); dwarnln("Could not create SDL system cursor: {}", SDL_GetError());
@@ -387,11 +355,11 @@ static BAN::ErrorOr<BAN::UniqPtr<PlatformCursor>> sdl2_create_system_cursor(Syst
return BAN::UniqPtr<PlatformCursor>(BAN::move(cursor)); return BAN::UniqPtr<PlatformCursor>(BAN::move(cursor));
} }
static BAN::ErrorOr<BAN::UniqPtr<PlatformCursor>> sdl2_create_bitmap_cursor(const uint32_t* pixels, uint32_t width, uint32_t height, int32_t origin_x, int32_t origin_y) static BAN::ErrorOr<BAN::UniqPtr<PlatformCursor>> sdl3_create_bitmap_cursor(const uint32_t* pixels, uint32_t width, uint32_t height, int32_t origin_x, int32_t origin_y)
{ {
auto cursor = TRY(BAN::UniqPtr<SDLCursor>::create()); auto cursor = TRY(BAN::UniqPtr<SDLCursor>::create());
SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormatFrom(const_cast<uint32_t*>(pixels), width, height, 32, width * 4, SDL_PIXELFORMAT_ARGB8888); SDL_Surface* surface = SDL_CreateSurfaceFrom(width, height, SDL_PIXELFORMAT_ARGB8888, const_cast<uint32_t*>(pixels), width * 4);
if (surface == nullptr) if (surface == nullptr)
{ {
dwarnln("Could not create SDL surface for cursor: {}", SDL_GetError()); dwarnln("Could not create SDL surface for cursor: {}", SDL_GetError());
@@ -402,7 +370,7 @@ static BAN::ErrorOr<BAN::UniqPtr<PlatformCursor>> sdl2_create_bitmap_cursor(cons
origin_y = BAN::Math::clamp<int32_t>(origin_y, 0, height - 1); origin_y = BAN::Math::clamp<int32_t>(origin_y, 0, height - 1);
cursor->cursor = SDL_CreateColorCursor(surface, origin_x, origin_y); cursor->cursor = SDL_CreateColorCursor(surface, origin_x, origin_y);
SDL_FreeSurface(surface); SDL_DestroySurface(surface);
if (cursor->cursor == nullptr) if (cursor->cursor == nullptr)
{ {
@@ -413,7 +381,7 @@ static BAN::ErrorOr<BAN::UniqPtr<PlatformCursor>> sdl2_create_bitmap_cursor(cons
return BAN::UniqPtr<PlatformCursor>(BAN::move(cursor)); return BAN::UniqPtr<PlatformCursor>(BAN::move(cursor));
} }
static void sdl2_set_cursor(PlatformWindow*, PlatformCursor* cursor) static void sdl3_set_cursor(PlatformWindow*, PlatformCursor* cursor)
{ {
if (cursor == nullptr) if (cursor == nullptr)
SDL_SetCursor(s_default_cursor); SDL_SetCursor(s_default_cursor);
@@ -425,15 +393,15 @@ static void sdl2_set_cursor(PlatformWindow*, PlatformCursor* cursor)
} }
PlatformOps g_platform_ops = { PlatformOps g_platform_ops = {
.initialize = sdl2_initialize, .initialize = sdl3_initialize,
.poll_events = sdl2_poll_events, .poll_events = sdl3_poll_events,
.create_window = sdl2_create_window, .create_window = sdl3_create_window,
.invalidate = sdl2_invalidate, .invalidate = sdl3_invalidate,
.request_resize = sdl2_request_resize, .request_resize = sdl3_request_resize,
.request_fullscreen = sdl2_request_fullscreen, .request_fullscreen = sdl3_request_fullscreen,
.create_system_cursor = sdl2_create_system_cursor, .create_system_cursor = sdl3_create_system_cursor,
.create_bitmap_cursor = sdl2_create_bitmap_cursor, .create_bitmap_cursor = sdl3_create_bitmap_cursor,
.set_cursor = sdl2_set_cursor, .set_cursor = sdl3_set_cursor,
}; };
#include <LibInput/KeyEvent.h> #include <LibInput/KeyEvent.h>
@@ -556,4 +524,4 @@ consteval Keymap::Keymap()
map[SDL_SCANCODE_KP_ENTER] = keycode_numpad(3, 3); map[SDL_SCANCODE_KP_ENTER] = keycode_numpad(3, 3);
map[SDL_SCANCODE_KP_0] = keycode_numpad(4, 0); map[SDL_SCANCODE_KP_0] = keycode_numpad(4, 0);
map[SDL_SCANCODE_KP_COMMA] = keycode_numpad(4, 1); map[SDL_SCANCODE_KP_COMMA] = keycode_numpad(4, 1);
}; };