FreeRDP
Loading...
Searching...
No Matches
SDL3/sdl_window.cpp
1
20#include "sdl_window.hpp"
21#include "sdl_utils.hpp"
22
23SdlWindow::SdlWindow(const std::string& title, Sint32 startupX, Sint32 startupY, Sint32 width,
24 Sint32 height, [[maybe_unused]] Uint32 flags)
25{
26 auto props = SDL_CreateProperties();
27 SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, title.c_str());
28 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, startupX);
29 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, startupY);
30 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width);
31 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height);
32
33 if (flags & SDL_WINDOW_HIGH_PIXEL_DENSITY)
34 SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, true);
35
36 if (flags & SDL_WINDOW_FULLSCREEN)
37 SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN, true);
38
39 if (flags & SDL_WINDOW_BORDERLESS)
40 SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_BORDERLESS_BOOLEAN, true);
41
42 _window = SDL_CreateWindowWithProperties(props);
43 SDL_DestroyProperties(props);
44
45 auto scale = SDL_GetWindowPixelDensity(_window);
46 const int iscale = static_cast<int>(scale * 100.0f);
47 auto w = 100 * width / iscale;
48 auto h = 100 * height / iscale;
49 (void)SDL_SetWindowSize(_window, w, h);
50 SDL_SetHint(SDL_HINT_APP_NAME, "");
51 (void)SDL_SyncWindow(_window);
52}
53
54SdlWindow::SdlWindow(SdlWindow&& other) noexcept
55 : _window(other._window), _offset_x(other._offset_x), _offset_y(other._offset_y)
56{
57 other._window = nullptr;
58}
59
60SdlWindow::~SdlWindow()
61{
62 SDL_DestroyWindow(_window);
63}
64
65Uint32 SdlWindow::id() const
66{
67 if (!_window)
68 return 0;
69 return SDL_GetWindowID(_window);
70}
71
72SDL_DisplayID SdlWindow::displayIndex() const
73{
74 if (!_window)
75 return 0;
76 return SDL_GetDisplayForWindow(_window);
77}
78
79SDL_Rect SdlWindow::rect() const
80{
81 SDL_Rect rect = {};
82 if (_window)
83 {
84 SDL_GetWindowPosition(_window, &rect.x, &rect.y);
85 SDL_GetWindowSizeInPixels(_window, &rect.w, &rect.h);
86 }
87 return rect;
88}
89
90SDL_Window* SdlWindow::window() const
91{
92 return _window;
93}
94
95Sint32 SdlWindow::offsetX() const
96{
97 return _offset_x;
98}
99
100void SdlWindow::setOffsetX(Sint32 x)
101{
102 _offset_x = x;
103}
104
105void SdlWindow::setOffsetY(Sint32 y)
106{
107 _offset_y = y;
108}
109
110Sint32 SdlWindow::offsetY() const
111{
112 return _offset_y;
113}
114
115rdpMonitor SdlWindow::monitor() const
116{
117 rdpMonitor mon{};
118
119 const auto factor = SDL_GetWindowDisplayScale(_window);
120 const auto dsf = static_cast<UINT32>(100 * factor);
121 mon.attributes.desktopScaleFactor = dsf;
122 mon.attributes.deviceScaleFactor = 100;
123
124 int pixelWidth = 0;
125 int pixelHeight = 0;
126 auto prc = SDL_GetWindowSizeInPixels(_window, &pixelWidth, &pixelHeight);
127
128 if (prc)
129 {
130 mon.width = pixelWidth;
131 mon.height = pixelHeight;
132
133 mon.attributes.physicalWidth = WINPR_ASSERTING_INT_CAST(uint32_t, pixelWidth);
134 mon.attributes.physicalHeight = WINPR_ASSERTING_INT_CAST(uint32_t, pixelHeight);
135 }
136
137 SDL_Rect rect = {};
138 auto did = SDL_GetDisplayForWindow(_window);
139 auto rc = SDL_GetDisplayBounds(did, &rect);
140
141 if (rc)
142 {
143 mon.x = rect.x;
144 mon.y = rect.y;
145 }
146
147 auto orientation = SDL_GetCurrentDisplayOrientation(did);
148 mon.attributes.orientation = sdl::utils::orientaion_to_rdp(orientation);
149
150 auto primary = SDL_GetPrimaryDisplay();
151 mon.is_primary = SDL_GetWindowID(_window) == primary;
152 mon.orig_screen = did;
153 return mon;
154}
155
156bool SdlWindow::grabKeyboard(bool enable)
157{
158 if (!_window)
159 return false;
160 SDL_SetWindowKeyboardGrab(_window, enable);
161 return true;
162}
163
164bool SdlWindow::grabMouse(bool enable)
165{
166 if (!_window)
167 return false;
168 SDL_SetWindowMouseGrab(_window, enable);
169 return true;
170}
171
172void SdlWindow::setBordered(bool bordered)
173{
174 if (_window)
175 SDL_SetWindowBordered(_window, bordered);
176 (void)SDL_SyncWindow(_window);
177}
178
179void SdlWindow::raise()
180{
181 SDL_RaiseWindow(_window);
182 (void)SDL_SyncWindow(_window);
183}
184
185void SdlWindow::resizeable(bool use)
186{
187 SDL_SetWindowResizable(_window, use);
188 (void)SDL_SyncWindow(_window);
189}
190
191void SdlWindow::fullscreen(bool enter)
192{
193 (void)SDL_SetWindowFullscreen(_window, enter);
194 (void)SDL_SyncWindow(_window);
195}
196
197void SdlWindow::minimize()
198{
199 SDL_MinimizeWindow(_window);
200 (void)SDL_SyncWindow(_window);
201}
202
203bool SdlWindow::fill(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
204{
205 auto surface = SDL_GetWindowSurface(_window);
206 if (!surface)
207 return false;
208 SDL_Rect rect = { 0, 0, surface->w, surface->h };
209 auto color = SDL_MapSurfaceRGBA(surface, r, g, b, a);
210
211 SDL_FillSurfaceRect(surface, &rect, color);
212 return true;
213}
214
215bool SdlWindow::blit(SDL_Surface* surface, const SDL_Rect& srcRect, SDL_Rect& dstRect)
216{
217 auto screen = SDL_GetWindowSurface(_window);
218 if (!screen || !surface)
219 return false;
220 if (!SDL_SetSurfaceClipRect(surface, &srcRect))
221 return true;
222 if (!SDL_SetSurfaceClipRect(screen, &dstRect))
223 return true;
224 if (!SDL_BlitSurfaceScaled(surface, &srcRect, screen, &dstRect, SDL_SCALEMODE_LINEAR))
225 {
226 SDL_LogError(SDL_LOG_CATEGORY_RENDER, "SDL_BlitScaled: %s", SDL_GetError());
227 return false;
228 }
229 return true;
230}
231
232void SdlWindow::updateSurface()
233{
234 SDL_UpdateWindowSurface(_window);
235}
SdlWindow(const std::string &title, Sint32 startupX, Sint32 startupY, Sint32 width, Sint32 height, Uint32 flags)