From 2e7639d903a69bb30f51f2cbfa1739332d5e77f0 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Sun, 25 Jan 2026 12:14:36 +0100 Subject: [PATCH] [client,sdl] add coordinat conversion functions * pixel to screen mapper * screen to pixel mapper * local scaling add/remove for smart-sizing --- client/SDL/SDL3/sdl_context.cpp | 49 +++++++++++++++++++++++++++++++++ client/SDL/SDL3/sdl_context.hpp | 7 +++++ 2 files changed, 56 insertions(+) diff --git a/client/SDL/SDL3/sdl_context.cpp b/client/SDL/SDL3/sdl_context.cpp index e3c0e6878..0942de432 100644 --- a/client/SDL/SDL3/sdl_context.cpp +++ b/client/SDL/SDL3/sdl_context.cpp @@ -927,6 +927,17 @@ bool SdlContext::handleEvent(const SDL_DisplayEvent* ev) return true; } +bool SdlContext::eventToPixelCoordinates(SDL_WindowID id, SDL_Event& ev) +{ + auto w = getWindowForId(id); + if (!w) + return false; + auto renderer = SDL_GetRenderer(w->window()); + if (!renderer) + return false; + return SDL_ConvertEventToRenderCoordinates(renderer, &ev); +} + SDL_FPoint SdlContext::applyLocalScaling(const SDL_FPoint& val) const { if (!freerdp_settings_get_bool(context()->settings, FreeRDP_SmartSizing)) @@ -946,6 +957,44 @@ void SdlContext::removeLocalScaling(float& x, float& y) y /= _localScale.y; } +SDL_FPoint SdlContext::screenToPixel(SDL_WindowID id, const SDL_FPoint& pos) +{ + auto w = getWindowForId(id); + if (!w) + return {}; + auto renderer = SDL_GetRenderer(w->window()); + if (!renderer) + return {}; + + SDL_FPoint rpos{}; + if (!SDL_RenderCoordinatesFromWindow(renderer, pos.x, pos.y, &rpos.x, &rpos.y)) + return {}; + removeLocalScaling(rpos.x, rpos.y); + return rpos; +} + +SDL_FPoint SdlContext::pixelToScreen(SDL_WindowID id, const SDL_FPoint& pos) +{ + auto w = getWindowForId(id); + if (!w) + return {}; + auto renderer = SDL_GetRenderer(w->window()); + if (!renderer) + return {}; + + SDL_FPoint rpos{}; + if (!SDL_RenderCoordinatesToWindow(renderer, pos.x, pos.y, &rpos.x, &rpos.y)) + return {}; + return applyLocalScaling(rpos); +} + +SDL_FRect SdlContext::pixelToScreen(SDL_WindowID id, const SDL_FRect& pos) +{ + const auto fpos = pixelToScreen(id, SDL_FPoint{ pos.x, pos.y }); + const auto size = pixelToScreen(id, SDL_FPoint{ pos.w, pos.h }); + return { fpos.x, fpos.y, size.x, size.y }; +} + bool SdlContext::drawToWindows(const std::vector& rects) { for (auto& window : _windows) diff --git a/client/SDL/SDL3/sdl_context.hpp b/client/SDL/SDL3/sdl_context.hpp index 9b945f107..4b98a8807 100644 --- a/client/SDL/SDL3/sdl_context.hpp +++ b/client/SDL/SDL3/sdl_context.hpp @@ -120,6 +120,11 @@ class SdlContext [[nodiscard]] wLog* getWLog(); + [[nodiscard]] SDL_FPoint screenToPixel(SDL_WindowID id, const SDL_FPoint& pos); + + [[nodiscard]] SDL_FPoint pixelToScreen(SDL_WindowID id, const SDL_FPoint& pos); + [[nodiscard]] SDL_FRect pixelToScreen(SDL_WindowID id, const SDL_FRect& pos); + [[nodiscard]] bool handleEvent(const SDL_WindowEvent* ev); [[nodiscard]] bool handleEvent(const SDL_DisplayEvent* ev); @@ -134,6 +139,8 @@ class SdlContext [[nodiscard]] static BOOL endPaint(rdpContext* context); [[nodiscard]] static DWORD WINAPI rdpThreadRun(SdlContext* sdl); + [[nodiscard]] bool eventToPixelCoordinates(SDL_WindowID id, SDL_Event& ev); + [[nodiscard]] SDL_FPoint applyLocalScaling(const SDL_FPoint& val) const; void removeLocalScaling(float& x, float& y);