diff --git a/xbanan/Base.cpp b/xbanan/Base.cpp index d52df06..8885e8e 100644 --- a/xbanan/Base.cpp +++ b/xbanan/Base.cpp @@ -450,7 +450,7 @@ void send_exposure_recursive(WINDOW wid) struct PlatformWindowInfo { - PlatformWindow* transient_for; + PlatformWindow* parent; 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]; PlatformWindowInfo info { - .transient_for = nullptr, + .parent = nullptr, .type = WindowType::Normal, }; @@ -478,7 +478,7 @@ static PlatformWindowInfo get_plaform_window_info(const Object::Window& window) const CARD32 type = *reinterpret_cast(it->value.data.data()); if (type == _NET_WM_WINDOW_TYPE_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; else info.type = WindowType::Popup; @@ -500,7 +500,7 @@ wm_window_type_done: // FIXME: support child windows auto& window = it2->value->object.get(); - info.transient_for = window.platform_window.ptr(); + info.parent = window.platform_window.ptr(); } transitient_for_done: @@ -529,7 +529,7 @@ static BAN::ErrorOr map_window(Client& client_info, WINDOW wid) auto info = get_plaform_window_info(window); window.platform_window = TRY(g_platform_ops.create_window( - info.transient_for, + info.parent, info.type, wid, window.x, diff --git a/xbanan/CMakeLists.txt b/xbanan/CMakeLists.txt index ecdda6e..a5efc52 100644 --- a/xbanan/CMakeLists.txt +++ b/xbanan/CMakeLists.txt @@ -24,15 +24,15 @@ endif() 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) message(FATAL_ERROR "platform \"${PLATFORM}\" not known, valid platforms are ${VALID_PLATFORMS}") endif() if(PLATFORM STREQUAL "banan-os") list(APPEND XBANAN_SOURCES banan-os/banan-os.cpp) -elseif(PLATFORM STREQUAL "SDL2") - list(APPEND XBANAN_SOURCES SDL2/sdl2.cpp) +elseif(PLATFORM STREQUAL "SDL3") + list(APPEND XBANAN_SOURCES SDL3/sdl3.cpp) endif() add_executable(xbanan ${XBANAN_SOURCES}) @@ -42,9 +42,9 @@ banan_link_library(xbanan libinput) if(PLATFORM STREQUAL "banan-os") banan_link_library(xbanan libgui) -elseif(PLATFORM STREQUAL "SDL2") - find_package(SDL2 REQUIRED) - banan_link_library(xbanan SDL2::SDL2) +elseif(PLATFORM STREQUAL "SDL3") + find_package(SDL3 REQUIRED) + banan_link_library(xbanan SDL3::SDL3) endif() target_compile_options(xbanan PRIVATE -Wall -Wextra) diff --git a/xbanan/Platform.h b/xbanan/Platform.h index 5042db4..2297bfd 100644 --- a/xbanan/Platform.h +++ b/xbanan/Platform.h @@ -16,9 +16,9 @@ struct PlatformCursor enum class WindowType { - Popup, Normal, Utility, + Popup, }; enum class SystemCursorType diff --git a/xbanan/SDL2/sdl2.cpp b/xbanan/SDL3/sdl3.cpp similarity index 67% rename from xbanan/SDL2/sdl2.cpp rename to xbanan/SDL3/sdl3.cpp index 28f5fbe..5db5605 100644 --- a/xbanan/SDL2/sdl2.cpp +++ b/xbanan/SDL3/sdl3.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include @@ -44,7 +44,7 @@ struct SDLCursor final : public PlatformCursor ~SDLCursor() { if (cursor != nullptr) - SDL_FreeCursor(cursor); + SDL_DestroyCursor(cursor); } SDL_Cursor* cursor { nullptr }; @@ -55,13 +55,13 @@ static int s_eventfd { -1 }; struct Keymap { consteval Keymap(); - uint8_t map[SDL_NUM_SCANCODES]; + uint8_t map[SDL_SCANCODE_COUNT]; }; static Keymap s_sdl_keymap; static SDL_Cursor* s_default_cursor { nullptr }; -static void* sdl2_thread(void*) +static void* sdl3_thread(void*) { for (;;) { @@ -73,22 +73,24 @@ static void* sdl2_thread(void*) 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()); return false; } - SDL_DisplayMode DM; - if (SDL_GetCurrentDisplayMode(0, &DM) == -1) + *display_w = *display_h = 0; + + const SDL_DisplayID* display_ids = SDL_GetDisplays(nullptr); + for (int i = 0; display_ids[i]; i++) { - dwarnln("Could not get display mode: {}", SDL_GetError()); - return false; + SDL_Rect rect; + SDL_GetDisplayBounds(display_ids[i], &rect); + *display_w = BAN::Math::max(*display_w, rect.x + rect.w); + *display_h = BAN::Math::max(*display_h, rect.y + rect.h); } - *display_w = DM.w; - *display_h = DM.h; 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); pthread_t thread; - pthread_create(&thread, nullptr, sdl2_thread, nullptr); + pthread_create(&thread, nullptr, sdl3_thread, nullptr); return true; } -static BAN::ErrorOr> sdl2_create_window(PlatformWindow* parent, WindowType type, WINDOW wid, int32_t x, int32_t y, uint32_t width, uint32_t height) +static BAN::ErrorOr> 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::create()); @@ -115,39 +117,37 @@ static BAN::ErrorOr> sdl2_create_window(PlatformWin window->width = width; window->height = height; - if (parent == nullptr) - x = y = SDL_WINDOWPOS_UNDEFINED; - else - { - auto& sdl_parent = *static_cast(parent); - int parent_x, parent_y; - SDL_GetWindowPosition(sdl_parent.window, &parent_x, &parent_y); - x += parent_x; - y += parent_y; - } - int flags; 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::Utility: flags = SDL_WINDOW_RESIZABLE; 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(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) { dwarnln("Could not create SDL window: {}", SDL_GetError()); 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) { dwarnln("Could not create SDL renderer: {}", SDL_GetError()); @@ -166,13 +166,13 @@ static BAN::ErrorOr> sdl2_create_window(PlatformWin return BAN::UniqPtr(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(window); SDL_SetWindowSize(sdl_window.window, width, height); } -static void sdl2_poll_events(void*) +static void sdl3_poll_events(void*) { uint64_t dummy; read(s_eventfd, &dummy, sizeof(dummy)); @@ -182,54 +182,44 @@ static void sdl2_poll_events(void*) { switch (event.type) { - case SDL_WINDOWEVENT: - { - auto it = s_window_map.find(event.window.windowID); - if (it == s_window_map.end()) - break; - auto& window = *it->value; - switch (event.window.event) + case SDL_EVENT_WINDOW_CLOSE_REQUESTED: + if (auto it = s_window_map.find(event.window.windowID); it != s_window_map.end()) + on_window_close_event(it->value->wid); + break; + case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: + if (auto it = s_window_map.find(event.window.windowID); it != s_window_map.end()) { - case SDL_WINDOWEVENT_CLOSE: - on_window_close_event(window.wid); - break; - case SDL_WINDOWEVENT_SIZE_CHANGED: - window.width = event.window.data1; - window.height = event.window.data2; + auto& window = *it->value; + window.width = event.window.data1; + window.height = event.window.data2; - SDL_DestroyTexture(window.texture); - window.texture = SDL_CreateTexture(window.renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, window.width, window.height); - ASSERT(window.texture); + SDL_DestroyTexture(window.texture); + window.texture = SDL_CreateTexture(window.renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, window.width, window.height); + ASSERT(window.texture); - on_window_resize_event(window.wid, event.window.data1, event.window.data2); - 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; + on_window_resize_event(window.wid, window.width, window.height); } break; - } - case SDL_MOUSEMOTION: - { - auto it = s_window_map.find(event.window.windowID); - if (it != s_window_map.end()) + case SDL_EVENT_WINDOW_FOCUS_GAINED: + case SDL_EVENT_WINDOW_FOCUS_LOST: + if (auto it = s_window_map.find(event.motion.windowID); it != s_window_map.end()) + on_window_focus_event(it->value->wid, (event.type == SDL_EVENT_WINDOW_FOCUS_GAINED)); + 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); break; - } - case SDL_MOUSEBUTTONUP: - case SDL_MOUSEBUTTONDOWN: + case SDL_EVENT_MOUSE_BUTTON_UP: + case SDL_EVENT_MOUSE_BUTTON_DOWN: { uint8_t xbutton { 0 }; switch (event.button.button) @@ -243,10 +233,10 @@ static void sdl2_poll_events(void*) auto it = s_window_map.find(event.window.windowID); 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; } - case SDL_MOUSEWHEEL: + case SDL_EVENT_MOUSE_WHEEL: { uint8_t xbutton { 0 }; if (event.wheel.y > 0) @@ -263,31 +253,31 @@ static void sdl2_poll_events(void*) break; } - case SDL_KEYUP: - case SDL_KEYDOWN: + case SDL_EVENT_KEY_UP: + 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 }; - if (event.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) + if (event.key.mod & SDL_KMOD_SHIFT) xmod |= (1 << 0); - if (event.key.keysym.mod & (KMOD_CAPS)) + if (event.key.mod & SDL_KMOD_CAPS) xmod |= (1 << 1); - if (event.key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) + if (event.key.mod & SDL_KMOD_CTRL) xmod |= (1 << 2); - if (event.key.keysym.mod & (KMOD_LALT | KMOD_RALT)) + if (event.key.mod & SDL_KMOD_ALT) xmod |= (1 << 3); auto it = s_window_map.find(event.window.windowID); 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; } } } } -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(window); @@ -303,7 +293,7 @@ static void sdl2_invalidate(PlatformWindow* window, const uint32_t* src_pixels, void* dst_pixels; 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()); return; @@ -321,63 +311,41 @@ static void sdl2_invalidate(PlatformWindow* window, const uint32_t* src_pixels, SDL_UnlockTexture(sdl_window.texture); 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); } -static void sdl2_request_fullscreen(PlatformWindow* window, bool fullscreen) +static void sdl3_request_fullscreen(PlatformWindow* window, bool fullscreen) { auto& sdl_window = *static_cast(window); - SDL_SetWindowFullscreen(sdl_window.window, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); + SDL_SetWindowFullscreen(sdl_window.window, fullscreen); } -static BAN::ErrorOr> sdl2_create_system_cursor(SystemCursorType type) +static BAN::ErrorOr> sdl3_create_system_cursor(SystemCursorType type) { - SDL_SystemCursor sdl_type; - switch (type) - { - case SystemCursorType::Help: - case SystemCursorType::Pointer: - sdl_type = SDL_SYSTEM_CURSOR_ARROW; - break; - case SystemCursorType::Text: - sdl_type = SDL_SYSTEM_CURSOR_IBEAM; - break; - case SystemCursorType::Wait: - sdl_type = SDL_SYSTEM_CURSOR_WAIT; - break; - case SystemCursorType::Hand: - sdl_type = SDL_SYSTEM_CURSOR_HAND; - break; - case SystemCursorType::Move: - sdl_type = SDL_SYSTEM_CURSOR_SIZEALL; - 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; - } + static constexpr SDL_SystemCursor cursor_type_map[] { + [static_cast(SystemCursorType::Pointer)] = SDL_SYSTEM_CURSOR_DEFAULT, + [static_cast(SystemCursorType::Text)] = SDL_SYSTEM_CURSOR_TEXT, + [static_cast(SystemCursorType::Wait)] = SDL_SYSTEM_CURSOR_WAIT, + [static_cast(SystemCursorType::Hand)] = SDL_SYSTEM_CURSOR_POINTER, + [static_cast(SystemCursorType::Help)] = SDL_SYSTEM_CURSOR_DEFAULT, // :( + [static_cast(SystemCursorType::Move)] = SDL_SYSTEM_CURSOR_MOVE, + [static_cast(SystemCursorType::Forbidden)] = SDL_SYSTEM_CURSOR_NOT_ALLOWED, + [static_cast(SystemCursorType::ResizeN)] = SDL_SYSTEM_CURSOR_N_RESIZE, + [static_cast(SystemCursorType::ResizeE)] = SDL_SYSTEM_CURSOR_E_RESIZE, + [static_cast(SystemCursorType::ResizeS)] = SDL_SYSTEM_CURSOR_S_RESIZE, + [static_cast(SystemCursorType::ResizeW)] = SDL_SYSTEM_CURSOR_W_RESIZE, + [static_cast(SystemCursorType::ResizeNW)] = SDL_SYSTEM_CURSOR_NW_RESIZE, + [static_cast(SystemCursorType::ResizeNE)] = SDL_SYSTEM_CURSOR_NE_RESIZE, + [static_cast(SystemCursorType::ResizeSW)] = SDL_SYSTEM_CURSOR_SW_RESIZE, + [static_cast(SystemCursorType::ResizeSE)] = SDL_SYSTEM_CURSOR_SE_RESIZE, + [static_cast(SystemCursorType::ResizeVertical)] = SDL_SYSTEM_CURSOR_NS_RESIZE, + [static_cast(SystemCursorType::ResizeHorizontal)] = SDL_SYSTEM_CURSOR_EW_RESIZE, + }; auto cursor = TRY(BAN::UniqPtr::create()); - cursor->cursor = SDL_CreateSystemCursor(sdl_type); + cursor->cursor = SDL_CreateSystemCursor(cursor_type_map[static_cast(type)]); if (cursor->cursor == nullptr) { dwarnln("Could not create SDL system cursor: {}", SDL_GetError()); @@ -387,11 +355,11 @@ static BAN::ErrorOr> sdl2_create_system_cursor(Syst return BAN::UniqPtr(BAN::move(cursor)); } -static BAN::ErrorOr> 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> 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::create()); - SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormatFrom(const_cast(pixels), width, height, 32, width * 4, SDL_PIXELFORMAT_ARGB8888); + SDL_Surface* surface = SDL_CreateSurfaceFrom(width, height, SDL_PIXELFORMAT_ARGB8888, const_cast(pixels), width * 4); if (surface == nullptr) { dwarnln("Could not create SDL surface for cursor: {}", SDL_GetError()); @@ -402,7 +370,7 @@ static BAN::ErrorOr> sdl2_create_bitmap_cursor(cons origin_y = BAN::Math::clamp(origin_y, 0, height - 1); cursor->cursor = SDL_CreateColorCursor(surface, origin_x, origin_y); - SDL_FreeSurface(surface); + SDL_DestroySurface(surface); if (cursor->cursor == nullptr) { @@ -413,7 +381,7 @@ static BAN::ErrorOr> sdl2_create_bitmap_cursor(cons return BAN::UniqPtr(BAN::move(cursor)); } -static void sdl2_set_cursor(PlatformWindow*, PlatformCursor* cursor) +static void sdl3_set_cursor(PlatformWindow*, PlatformCursor* cursor) { if (cursor == nullptr) SDL_SetCursor(s_default_cursor); @@ -425,15 +393,15 @@ static void sdl2_set_cursor(PlatformWindow*, PlatformCursor* cursor) } PlatformOps g_platform_ops = { - .initialize = sdl2_initialize, - .poll_events = sdl2_poll_events, - .create_window = sdl2_create_window, - .invalidate = sdl2_invalidate, - .request_resize = sdl2_request_resize, - .request_fullscreen = sdl2_request_fullscreen, - .create_system_cursor = sdl2_create_system_cursor, - .create_bitmap_cursor = sdl2_create_bitmap_cursor, - .set_cursor = sdl2_set_cursor, + .initialize = sdl3_initialize, + .poll_events = sdl3_poll_events, + .create_window = sdl3_create_window, + .invalidate = sdl3_invalidate, + .request_resize = sdl3_request_resize, + .request_fullscreen = sdl3_request_fullscreen, + .create_system_cursor = sdl3_create_system_cursor, + .create_bitmap_cursor = sdl3_create_bitmap_cursor, + .set_cursor = sdl3_set_cursor, }; #include @@ -556,4 +524,4 @@ consteval Keymap::Keymap() map[SDL_SCANCODE_KP_ENTER] = keycode_numpad(3, 3); map[SDL_SCANCODE_KP_0] = keycode_numpad(4, 0); map[SDL_SCANCODE_KP_COMMA] = keycode_numpad(4, 1); -}; \ No newline at end of file +};