23#include "sdl_window.hpp"
24#include "sdl_utils.hpp"
28 auto props = SDL_CreateProperties();
29 SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, title.c_str());
30 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, rect.x);
31 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, rect.y);
32 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, rect.w);
33 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, rect.h);
35 if (flags & SDL_WINDOW_HIGH_PIXEL_DENSITY)
36 SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN,
true);
38 if (flags & SDL_WINDOW_FULLSCREEN)
39 SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN,
true);
41 if (flags & SDL_WINDOW_BORDERLESS)
42 SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_BORDERLESS_BOOLEAN,
true);
44 _window = SDL_CreateWindowWithProperties(props);
45 SDL_DestroyProperties(props);
48 const int iscale =
static_cast<int>(sc * 100.0f);
49 auto w = 100 * rect.w / iscale;
50 auto h = 100 * rect.h / iscale;
51 std::ignore = resize({ w, h });
52 SDL_SetHint(SDL_HINT_APP_NAME,
"");
53 std::ignore = SDL_SyncWindow(_window);
57 : _window(other._window), _offset_x(other._offset_x), _offset_y(other._offset_y)
59 other._window =
nullptr;
62SdlWindow::~SdlWindow()
64 SDL_DestroyWindow(_window);
67SDL_WindowID SdlWindow::id()
const
71 return SDL_GetWindowID(_window);
74SDL_DisplayID SdlWindow::displayIndex()
const
78 return SDL_GetDisplayForWindow(_window);
81SDL_Rect SdlWindow::rect()
const
86 SDL_GetWindowPosition(_window, &rect.x, &rect.y);
87 SDL_GetWindowSizeInPixels(_window, &rect.w, &rect.h);
92SDL_Rect SdlWindow::bounds()
const
97 SDL_GetWindowPosition(_window, &rect.x, &rect.y);
98 SDL_GetWindowSize(_window, &rect.w, &rect.h);
103SDL_Window* SdlWindow::window()
const
108Sint32 SdlWindow::offsetX()
const
113void SdlWindow::setOffsetX(Sint32 x)
118void SdlWindow::setOffsetY(Sint32 y)
123Sint32 SdlWindow::offsetY()
const
128rdpMonitor SdlWindow::monitor(
bool isPrimary)
const
132 const auto factor = scale();
133 const auto dsf =
static_cast<UINT32
>(100 * factor);
134 mon.attributes.desktopScaleFactor = dsf;
135 mon.attributes.deviceScaleFactor = 100;
137 const auto r = rect();
141 mon.attributes.physicalWidth = WINPR_ASSERTING_INT_CAST(uint32_t, r.w);
142 mon.attributes.physicalHeight = WINPR_ASSERTING_INT_CAST(uint32_t, r.h);
145 auto did = SDL_GetDisplayForWindow(_window);
146 auto rc = SDL_GetDisplayBounds(did, &rect);
154 const auto orient = orientation();
155 mon.attributes.orientation = sdl::utils::orientaion_to_rdp(orient);
157 auto primary = SDL_GetPrimaryDisplay();
158 mon.is_primary = isPrimary || (SDL_GetWindowID(_window) == primary);
159 mon.orig_screen = did;
168float SdlWindow::scale()
const
170 return SDL_GetWindowDisplayScale(_window);
173SDL_DisplayOrientation SdlWindow::orientation()
const
175 const auto did = displayIndex();
176 return SDL_GetCurrentDisplayOrientation(did);
179bool SdlWindow::grabKeyboard(
bool enable)
183 SDL_SetWindowKeyboardGrab(_window, enable);
187bool SdlWindow::grabMouse(
bool enable)
191 SDL_SetWindowMouseGrab(_window, enable);
195void SdlWindow::setBordered(
bool bordered)
198 SDL_SetWindowBordered(_window, bordered);
199 std::ignore = SDL_SyncWindow(_window);
202void SdlWindow::raise()
204 SDL_RaiseWindow(_window);
205 std::ignore = SDL_SyncWindow(_window);
208void SdlWindow::resizeable(
bool use)
210 SDL_SetWindowResizable(_window, use);
211 std::ignore = SDL_SyncWindow(_window);
214void SdlWindow::fullscreen(
bool enter)
216 std::ignore = SDL_SetWindowFullscreen(_window, enter);
217 std::ignore = SDL_SyncWindow(_window);
220void SdlWindow::minimize()
222 SDL_MinimizeWindow(_window);
223 std::ignore = SDL_SyncWindow(_window);
226bool SdlWindow::resize(
const SDL_Point& size)
228 return SDL_SetWindowSize(_window, size.x, size.y);
231bool SdlWindow::drawRect(SDL_Surface* surface, SDL_Point offset,
const SDL_Rect& srcRect)
233 WINPR_ASSERT(surface);
234 SDL_Rect dstRect = { offset.x + srcRect.x, offset.y + srcRect.y, srcRect.w, srcRect.h };
235 return blit(surface, srcRect, dstRect);
238bool SdlWindow::drawRects(SDL_Surface* surface, SDL_Point offset,
239 const std::vector<SDL_Rect>& rects)
243 return drawRect(surface, offset, { 0, 0, surface->w, surface->h });
245 for (
auto& srcRect : rects)
247 if (!drawRect(surface, offset, srcRect))
253bool SdlWindow::drawScaledRect(SDL_Surface* surface,
const SDL_FPoint& scale,
254 const SDL_Rect& srcRect)
256 SDL_Rect dstRect = srcRect;
257 dstRect.x =
static_cast<Sint32
>(
static_cast<float>(dstRect.x) * scale.x);
258 dstRect.w =
static_cast<Sint32
>(
static_cast<float>(dstRect.w) * scale.x);
259 dstRect.y =
static_cast<Sint32
>(
static_cast<float>(dstRect.y) * scale.y);
260 dstRect.h =
static_cast<Sint32
>(
static_cast<float>(dstRect.h) * scale.y);
261 return blit(surface, srcRect, dstRect);
264bool SdlWindow::drawScaledRects(SDL_Surface* surface,
const SDL_FPoint& scale,
265 const std::vector<SDL_Rect>& rects)
269 return drawScaledRect(surface, scale, { 0, 0, surface->w, surface->h });
271 for (
const auto& srcRect : rects)
273 if (!drawScaledRect(surface, scale, srcRect))
279bool SdlWindow::fill(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
281 auto surface = SDL_GetWindowSurface(_window);
284 SDL_Rect rect = { 0, 0, surface->w, surface->h };
285 auto color = SDL_MapSurfaceRGBA(surface, r, g, b, a);
287 SDL_FillSurfaceRect(surface, &rect, color);
291bool SdlWindow::blit(SDL_Surface* surface,
const SDL_Rect& srcRect, SDL_Rect& dstRect)
293 auto screen = SDL_GetWindowSurface(_window);
294 if (!screen || !surface)
296 if (!SDL_SetSurfaceClipRect(surface, &srcRect))
298 if (!SDL_SetSurfaceClipRect(screen, &dstRect))
300 if (!SDL_BlitSurfaceScaled(surface, &srcRect, screen, &dstRect, SDL_SCALEMODE_LINEAR))
302 SDL_LogError(SDL_LOG_CATEGORY_RENDER,
"SDL_BlitScaled: %s", SDL_GetError());
308void SdlWindow::updateSurface()
310 SDL_UpdateWindowSurface(_window);
313SdlWindow SdlWindow::create(SDL_DisplayID
id,
const std::string& title, Uint32 flags, Uint32 width,
316 flags |= SDL_WINDOW_HIGH_PIXEL_DENSITY;
318 SDL_Rect rect = {
static_cast<int>(SDL_WINDOWPOS_CENTERED_DISPLAY(
id)),
319 static_cast<int>(SDL_WINDOWPOS_CENTERED_DISPLAY(
id)),
static_cast<int>(width),
320 static_cast<int>(height) };
322 if ((flags & SDL_WINDOW_FULLSCREEN) != 0)
324 std::ignore = SDL_GetDisplayBounds(
id, &rect);
329 if ((flags & (SDL_WINDOW_FULLSCREEN)) != 0)
331 window.setOffsetX(rect.x);
332 window.setOffsetY(rect.y);
SdlWindow(const std::string &title, Sint32 startupX, Sint32 startupY, Sint32 width, Sint32 height, Uint32 flags)