[client,sdl] unify window related operations

Access window related operations only in SdlWindow class
This commit is contained in:
akallabeth 2024-02-13 11:02:33 +01:00 committed by akallabeth
parent 867e663872
commit 5d3ffea061
9 changed files with 188 additions and 40 deletions

View File

@ -36,6 +36,7 @@ static const Uint32 hpadding = 5;
SDLConnectionDialog::SDLConnectionDialog(rdpContext* context)
: _context(context), _window(nullptr), _renderer(nullptr)
{
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
hide();
}
@ -43,6 +44,7 @@ SDLConnectionDialog::~SDLConnectionDialog()
{
resetTimer();
destroyWindow();
SDL_Quit();
}
bool SDLConnectionDialog::visible() const
@ -140,7 +142,7 @@ bool SDLConnectionDialog::setModal()
if (sdl->windows.empty())
return true;
auto parent = sdl->windows.front().window();
auto parent = sdl->windows.begin()->second.window();
SDL_SetWindowModalFor(_window, parent);
SDL_RaiseWindow(_window);
}

View File

@ -336,9 +336,10 @@ BOOL sdlDispContext::handle_window_event(const SDL_WindowEvent* ev)
auto bordered = freerdp_settings_get_bool(_sdl->context()->settings, FreeRDP_Decorations)
? SDL_TRUE
: SDL_FALSE;
auto window = SDL_GetWindowFromID(ev->windowID);
if (window)
SDL_SetWindowBordered(window, bordered);
auto it = _sdl->windows.find(ev->windowID);
if (it != _sdl->windows.end())
it->second.setBordered(bordered);
switch (ev->event)
{
@ -442,6 +443,8 @@ BOOL sdlDispContext::uninit(DispClientContext* disp)
sdlDispContext::sdlDispContext(SdlContext* sdl) : _sdl(sdl), _timer(0)
{
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
WINPR_ASSERT(_sdl);
WINPR_ASSERT(_sdl->context()->settings);
WINPR_ASSERT(_sdl->context()->pubSub);
@ -464,4 +467,5 @@ sdlDispContext::~sdlDispContext()
PubSub_UnsubscribeActivated(pubSub, sdlDispContext::OnActivated);
PubSub_UnsubscribeGraphicsReset(pubSub, sdlDispContext::OnGraphicsReset);
SDL_RemoveTimer(_timer);
SDL_Quit();
}

View File

@ -933,7 +933,8 @@ static int sdl_run(SdlContext* sdl)
if (window != sdl->windows.end())
{
auto r = window->second.rect();
auto id = window->second.id();
auto id = window->second.id();
WLog_DBG(SDL_TAG, "%lu: %dx%d-%dx%d", id, r.x, r.y, r.w, r.h);
}
}
break;

View File

@ -21,7 +21,7 @@
#include <memory>
#include <thread>
#include <vector>
#include <map>
#include <freerdp/freerdp.h>
#include <freerdp/client/rdpei.h>
@ -59,7 +59,7 @@ class SdlContext
bool grab_mouse = false;
bool grab_kbd = false;
std::vector<SdlWindow> windows;
std::map<Uint32, SdlWindow> windows;
CriticalSection critical;
std::thread thread;

View File

@ -532,17 +532,11 @@ BOOL sdlInput::keyboard_handle_event(const SDL_KeyboardEvent* ev)
BOOL sdlInput::keyboard_grab(Uint32 windowID, SDL_bool enable)
{
SDL_Window* window = SDL_GetWindowFromID(windowID);
if (!window)
auto it = _sdl->windows.find(windowID);
if (it == _sdl->windows.end())
return FALSE;
#if SDL_VERSION_ATLEAST(2, 0, 16)
_sdl->grab_kbd = enable;
SDL_SetWindowKeyboardGrab(window, enable);
return TRUE;
#else
WLog_WARN(TAG, "Keyboard grabbing not supported by SDL2 < 2.0.16");
return FALSE;
#endif
return it->second.grabKeyboard(enable);
}
BOOL sdlInput::mouse_focus(Uint32 windowID)
@ -550,29 +544,22 @@ BOOL sdlInput::mouse_focus(Uint32 windowID)
if (_lastWindowID != windowID)
{
_lastWindowID = windowID;
SDL_Window* window = SDL_GetWindowFromID(windowID);
if (!window)
auto it = _sdl->windows.find(windowID);
if (it == _sdl->windows.end())
return FALSE;
SDL_RaiseWindow(window);
it->second.raise();
}
return TRUE;
}
BOOL sdlInput::mouse_grab(Uint32 windowID, SDL_bool enable)
{
SDL_Window* window = SDL_GetWindowFromID(windowID);
if (!window)
auto it = _sdl->windows.find(windowID);
if (it == _sdl->windows.end())
return FALSE;
#if SDL_VERSION_ATLEAST(2, 0, 16)
_sdl->grab_mouse = enable;
SDL_SetWindowMouseGrab(window, enable);
return TRUE;
#else
_sdl->grab_mouse = enable;
SDL_SetWindowGrab(window, enable);
return TRUE;
#endif
return it->second.grabMouse(enable);
}
sdlInput::sdlInput(SdlContext* sdl) : _sdl(sdl), _lastWindowID(UINT32_MAX)

View File

@ -282,7 +282,7 @@ static BOOL sdl_detect_single_window(SdlContext* sdl, UINT32* pMaxWidth, UINT32*
if (freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds) == 0)
{
const size_t id =
(sdl->windows.size() > 0) ? SDL_GetWindowDisplayIndex(sdl->windows[0].window()) : 0;
(sdl->windows.size() > 0) ? sdl->windows.begin()->second.displayIndex() : 0;
if (!freerdp_settings_set_pointer_len(settings, FreeRDP_MonitorIds, &id, 1))
return FALSE;
}

View File

@ -54,19 +54,19 @@ BOOL sdl_scale_coordinates(SdlContext* sdl, Uint32 windowId, INT32* px, INT32* p
int offset_x = 0;
int offset_y = 0;
for (const auto& window : sdl->windows)
for (const auto& it : sdl->windows)
{
int w = 0;
int h = 0;
const Uint32 id = SDL_GetWindowID(window.window());
auto& window = it.second;
const auto id = window.id();
if (id != windowId)
{
continue;
}
SDL_GetWindowSize(window.window(), &w, &h);
sx = w / static_cast<double>(gdi->width);
sy = h / static_cast<double>(gdi->height);
auto size = window.rect();
sx = size.w / static_cast<double>(gdi->width);
sy = size.h / static_cast<double>(gdi->height);
offset_x = window.offsetX();
offset_y = window.offsetY();
break;

View File

@ -18,6 +18,7 @@
* limitations under the License.
*/
#include "sdl_window.hpp"
#include "sdl_utils.hpp"
SdlWindow::SdlWindow(const std::string& title, Sint32 startupX, Sint32 startupY, Sint32 width,
Sint32 height, Uint32 flags)
@ -37,6 +38,31 @@ SdlWindow::~SdlWindow()
SDL_DestroyWindow(_window);
}
Uint32 SdlWindow::id() const
{
if (!_window)
return 0;
return SDL_GetWindowID(_window);
}
int SdlWindow::displayIndex() const
{
if (!_window)
return 0;
return SDL_GetWindowDisplayIndex(_window);
}
SDL_Rect SdlWindow::rect() const
{
SDL_Rect rect = {};
if (_window)
{
SDL_GetWindowPosition(_window, &rect.x, &rect.y);
SDL_GetWindowSize(_window, &rect.w, &rect.h);
}
return rect;
}
SDL_Window* SdlWindow::window() const
{
return _window;
@ -61,3 +87,117 @@ Sint32 SdlWindow::offsetY() const
{
return _offset_y;
}
bool SdlWindow::grabKeyboard(bool enable)
{
if (!_window)
return false;
#if SDL_VERSION_ATLEAST(2, 0, 16)
SDL_SetWindowKeyboardGrab(_window, enable ? SDL_TRUE : SDL_FALSE);
return true;
#else
SDL_LogError(SDL_LOG_CATEGORY_INPUT, "Keyboard grabbing not supported by SDL2 < 2.0.16");
return false;
#endif
}
bool SdlWindow::grabMouse(bool enable)
{
if (!_window)
return false;
#if SDL_VERSION_ATLEAST(2, 0, 16)
SDL_SetWindowMouseGrab(_window, enable ? SDL_TRUE : SDL_FALSE);
#else
SDL_SetWindowGrab(_window, enable ? SDL_TRUE : SDL_FALSE);
#endif
return true;
}
void SdlWindow::setBordered(bool bordered)
{
if (_window)
SDL_SetWindowBordered(_window, bordered ? SDL_TRUE : SDL_FALSE);
}
void SdlWindow::raise()
{
SDL_RaiseWindow(_window);
}
void SdlWindow::resizeable(bool use)
{
SDL_SetWindowResizable(_window, use ? SDL_TRUE : SDL_FALSE);
}
void SdlWindow::fullscreen(bool enter)
{
auto curFlags = SDL_GetWindowFlags(_window);
if (enter)
{
if (!(curFlags & SDL_WINDOW_BORDERLESS))
{
auto idx = SDL_GetWindowDisplayIndex(_window);
SDL_DisplayMode mode = {};
SDL_GetCurrentDisplayMode(idx, &mode);
SDL_RestoreWindow(_window); // Maximize so we can see the caption and
// bits
SDL_SetWindowBordered(_window, SDL_FALSE);
SDL_SetWindowPosition(_window, 0, 0);
#if SDL_VERSION_ATLEAST(2, 0, 16)
SDL_SetWindowAlwaysOnTop(_window, SDL_TRUE);
#endif
SDL_RaiseWindow(_window);
SDL_SetWindowSize(_window, mode.w, mode.h);
}
}
else
{
if (curFlags & SDL_WINDOW_BORDERLESS)
{
SDL_SetWindowBordered(_window, SDL_TRUE);
#if SDL_VERSION_ATLEAST(2, 0, 16)
SDL_SetWindowAlwaysOnTop(_window, SDL_FALSE);
#endif
SDL_RaiseWindow(_window);
SDL_MinimizeWindow(_window); // Maximize so we can see the caption and bits
SDL_MaximizeWindow(_window); // Maximize so we can see the caption and bits
}
}
}
bool SdlWindow::fill(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
auto surface = SDL_GetWindowSurface(_window);
if (!surface)
return false;
SDL_Rect rect = { 0, 0, surface->w, surface->h };
auto color = SDL_MapRGBA(surface->format, r, g, b, a);
SDL_FillRect(surface, &rect, color);
return true;
}
bool SdlWindow::blit(SDL_Surface* surface, const SDL_Rect& srcRect, SDL_Rect& dstRect)
{
auto screen = SDL_GetWindowSurface(_window);
if (!screen || !surface)
return false;
if (!SDL_SetClipRect(surface, &srcRect))
return false;
if (!SDL_SetClipRect(screen, &dstRect))
return false;
auto rc = SDL_BlitScaled(surface, &srcRect, screen, &dstRect);
if (rc != 0)
{
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "SDL_BlitScaled: %s [%d]", sdl_error_string(rc), rc);
}
return rc == 0;
}
void SdlWindow::updateSurface()
{
SDL_UpdateWindowSurface(_window);
}

View File

@ -30,6 +30,9 @@ class SdlWindow
SdlWindow(SdlWindow&& other);
~SdlWindow();
[[nodiscard]] Uint32 id() const;
[[nodiscard]] int displayIndex() const;
[[nodiscard]] SDL_Rect rect() const;
[[nodiscard]] SDL_Window* window() const;
[[nodiscard]] Sint32 offsetX() const;
@ -38,10 +41,21 @@ class SdlWindow
void setOffsetY(Sint32 y);
[[nodiscard]] Sint32 offsetY() const;
bool grabKeyboard(bool enable);
bool grabMouse(bool enable);
void setBordered(bool bordered);
void raise();
void resizeable(bool use);
void fullscreen(bool use);
bool fill(Uint8 r = 0x00, Uint8 g = 0x00, Uint8 b = 0x00, Uint8 a = 0xff);
bool blit(SDL_Surface* surface, const SDL_Rect& src, SDL_Rect& dst);
void updateSurface();
private:
SDL_Window* _window;
Sint32 _offset_x;
Sint32 _offset_y;
SDL_Window* _window = nullptr;
Sint32 _offset_x = 0;
Sint32 _offset_y = 0;
private:
SdlWindow(const SdlWindow& other) = delete;