[client,sdl] wrap sdl windows in c++ class

use RAII for SDL window creation/destruction by wrapping it in
SdlWindow constructor/destructor
This commit is contained in:
Armin Novak 2023-12-20 10:02:40 +01:00 committed by akallabeth
parent 2b3d6dbe7b
commit 7ba84737ba
7 changed files with 146 additions and 42 deletions

View File

@ -86,7 +86,10 @@ set(SRCS
sdl_freerdp.hpp
sdl_freerdp.cpp
sdl_channels.hpp
sdl_channels.cpp)
sdl_channels.cpp
sdl_window.hpp
sdl_window.cpp
)
add_subdirectory(aad)
set(LIBS

View File

@ -380,7 +380,7 @@ static BOOL sdl_draw_to_window_scaled_rect(SdlContext* sdl, Sint32 windowId, SDL
return TRUE;
}
static BOOL sdl_draw_to_window(SdlContext* sdl, sdl_window_t window,
static BOOL sdl_draw_to_window(SdlContext* sdl, SdlWindow& window,
const std::vector<SDL_Rect>& rects = {})
{
WINPR_ASSERT(sdl);
@ -388,42 +388,42 @@ static BOOL sdl_draw_to_window(SdlContext* sdl, sdl_window_t window,
auto context = sdl->context();
auto gdi = context->gdi;
SDL_Surface* screen = SDL_GetWindowSurface(window.window);
SDL_Surface* screen = SDL_GetWindowSurface(window.window());
int w, h;
SDL_GetWindowSize(window.window, &w, &h);
SDL_GetWindowSize(window.window(), &w, &h);
if (!freerdp_settings_get_bool(context->settings, FreeRDP_SmartSizing))
{
if (gdi->width < w)
{
window.offset_x = (w - gdi->width) / 2;
window.setOffsetX((w - gdi->width) / 2);
}
if (gdi->height < h)
{
window.offset_y = (h - gdi->height) / 2;
window.setOffsetY((h - gdi->height) / 2);
}
auto surface = sdl->primary.get();
if (!sdl_draw_to_window_rect(sdl, screen, surface, { window.offset_x, window.offset_y },
if (!sdl_draw_to_window_rect(sdl, screen, surface, { window.offsetX(), window.offsetY() },
rects))
return FALSE;
}
else
{
auto id = SDL_GetWindowID(window.window);
auto id = SDL_GetWindowID(window.window());
if (!sdl_draw_to_window_scaled_rect(sdl, id, screen, sdl->primary.get(), rects))
return FALSE;
}
SDL_UpdateWindowSurface(window.window);
SDL_UpdateWindowSurface(window.window());
return TRUE;
}
static BOOL sdl_draw_to_window(SdlContext* sdl, const std::vector<sdl_window_t>& window,
static BOOL sdl_draw_to_window(SdlContext* sdl, std::vector<SdlWindow>& windows,
const std::vector<SDL_Rect>& rects = {})
{
for (auto& window : sdl->windows)
for (auto& window : windows)
{
if (!sdl_draw_to_window(sdl, window, rects))
return FALSE;
@ -666,12 +666,10 @@ static void sdl_cleanup_sdl(SdlContext* sdl)
if (!sdl)
return;
for (auto& window : sdl->windows)
SDL_DestroyWindow(window.window);
sdl->windows.clear();
sdl_destroy_primary(sdl);
sdl->windows.clear();
SDL_Quit();
}
@ -699,7 +697,6 @@ static BOOL sdl_create_windows(SdlContext* sdl)
h = freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight);
}
sdl_window_t window = {};
Uint32 flags = SDL_WINDOW_SHOWN;
Uint32 startupX = SDL_WINDOWPOS_CENTERED_DISPLAY(x);
Uint32 startupY = SDL_WINDOWPOS_CENTERED_DISPLAY(x);
@ -721,30 +718,29 @@ static BOOL sdl_create_windows(SdlContext* sdl)
{
flags |= SDL_WINDOW_BORDERLESS;
}
else
{
window.offset_x = 0;
window.offset_y = 0;
}
if (!freerdp_settings_get_bool(settings, FreeRDP_Decorations))
flags |= SDL_WINDOW_BORDERLESS;
window.window = SDL_CreateWindow(title, startupX, startupY, static_cast<int>(w),
static_cast<int>(h), flags);
if (!window.window)
SdlWindow window{ title,
static_cast<int>(startupX),
static_cast<int>(startupY),
static_cast<int>(w),
static_cast<int>(h),
flags };
if (!window.window())
goto fail;
if (freerdp_settings_get_bool(settings, FreeRDP_UseMultimon))
{
int win_x;
int win_y;
SDL_GetWindowPosition(window.window, &win_x, &win_y);
window.offset_x = 0 - win_x;
window.offset_y = 0 - win_y;
SDL_GetWindowPosition(window.window(), &win_x, &win_y);
window.setOffsetX(0 - win_x);
window.setOffsetY(0 - win_y);
}
sdl->windows.push_back(window);
sdl->windows.emplace_back(std::move(window));
}
rc = TRUE;
@ -1572,7 +1568,7 @@ BOOL SdlContext::update_fullscreen(BOOL enter)
std::lock_guard<CriticalSection> lock(critical);
for (const auto& window : windows)
{
if (!sdl_push_user_event(SDL_USEREVENT_WINDOW_FULLSCREEN, window.window, enter))
if (!sdl_push_user_event(SDL_USEREVENT_WINDOW_FULLSCREEN, window.window(), enter))
return FALSE;
}
fullscreen = enter;
@ -1590,7 +1586,7 @@ BOOL SdlContext::update_resizeable(BOOL enable)
for (const auto& window : windows)
{
if (!sdl_push_user_event(SDL_USEREVENT_WINDOW_RESIZEABLE, window.window, use))
if (!sdl_push_user_event(SDL_USEREVENT_WINDOW_RESIZEABLE, window.window(), use))
return FALSE;
}
resizeable = use;

View File

@ -36,13 +36,7 @@
#include "sdl_disp.hpp"
#include "sdl_kbd.hpp"
#include "sdl_utils.hpp"
typedef struct
{
SDL_Window* window;
int offset_x;
int offset_y;
} sdl_window_t;
#include "sdl_window.hpp"
using SDLSurfacePtr = std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)>;
using SDLPixelFormatPtr = std::unique_ptr<SDL_PixelFormat, decltype(&SDL_FreeFormat)>;
@ -64,7 +58,7 @@ class SdlContext
bool grab_mouse = false;
bool grab_kbd = false;
std::vector<sdl_window_t> windows;
std::vector<SdlWindow> windows;
CriticalSection critical;
std::thread thread;

View File

@ -283,7 +283,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_GetWindowDisplayIndex(sdl->windows[0].window()) : 0;
if (!freerdp_settings_set_pointer_len(settings, FreeRDP_MonitorIds, &id, 1))
return FALSE;
}

View File

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

63
client/SDL/sdl_window.cpp Normal file
View File

@ -0,0 +1,63 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* SDL Client
*
* Copyright 2023 Armin Novak <armin.novak@thincast.com>
* Copyright 2023 Thincast Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "sdl_window.hpp"
SdlWindow::SdlWindow(const std::string& title, Sint32 startupX, Sint32 startupY, Sint32 width,
Sint32 height, Uint32 flags)
: _window(SDL_CreateWindow(title.c_str(), startupX, startupY, width, height, flags)),
_offset_x(0), _offset_y(0)
{
}
SdlWindow::SdlWindow(SdlWindow&& other)
: _window(other._window), _offset_x(other._offset_x), _offset_y(other._offset_y)
{
other._window = nullptr;
}
SdlWindow::~SdlWindow()
{
SDL_DestroyWindow(_window);
}
SDL_Window* SdlWindow::window() const
{
return _window;
}
Sint32 SdlWindow::offsetX() const
{
return _offset_x;
}
void SdlWindow::setOffsetX(Sint32 x)
{
_offset_x = x;
}
void SdlWindow::setOffsetY(Sint32 y)
{
_offset_y = y;
}
Sint32 SdlWindow::offsetY() const
{
return _offset_y;
}

48
client/SDL/sdl_window.hpp Normal file
View File

@ -0,0 +1,48 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* SDL Client
*
* Copyright 2023 Armin Novak <armin.novak@thincast.com>
* Copyright 2023 Thincast Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <string>
#include <SDL.h>
class SdlWindow
{
public:
SdlWindow(const std::string& title, Sint32 startupX, Sint32 startupY, Sint32 width,
Sint32 height, Uint32 flags);
SdlWindow(SdlWindow&& other);
~SdlWindow();
SDL_Window* window() const;
Sint32 offsetX() const;
void setOffsetX(Sint32 x);
void setOffsetY(Sint32 y);
Sint32 offsetY() const;
private:
SDL_Window* _window;
Sint32 _offset_x;
Sint32 _offset_y;
private:
SdlWindow(const SdlWindow& other) = delete;
};