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