[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:
parent
2b3d6dbe7b
commit
7ba84737ba
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
63
client/SDL/sdl_window.cpp
Normal 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
48
client/SDL/sdl_window.hpp
Normal 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;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user