FreeRDP
Loading...
Searching...
No Matches
SdlWindow Class Reference

#include <sdl_window.hpp>

Public Member Functions

 SdlWindow (const std::string &title, Sint32 startupX, Sint32 startupY, Sint32 width, Sint32 height, Uint32 flags)
 
 SdlWindow (const SdlWindow &other)=delete
 
 SdlWindow (SdlWindow &&other) noexcept
 
SdlWindowoperator= (const SdlWindow &other)=delete
 
SdlWindowoperator= (SdlWindow &&other)=delete
 
Uint32 id () const
 
int displayIndex () const
 
SDL_Rect rect () const
 
SDL_Window * window () const
 
Sint32 offsetX () const
 
void setOffsetX (Sint32 x)
 
void setOffsetY (Sint32 y)
 
Sint32 offsetY () const
 
bool grabKeyboard (bool enable)
 
bool grabMouse (bool enable)
 
void setBordered (bool bordered)
 
void raise ()
 
void resizeable (bool use)
 
void fullscreen (bool enter)
 
void minimize ()
 
bool fill (Uint8 r=0x00, Uint8 g=0x00, Uint8 b=0x00, Uint8 a=0xff)
 
bool blit (SDL_Surface *surface, SDL_Rect src, SDL_Rect &dst)
 
void updateSurface ()
 
 SdlWindow (SdlWindow &&other) noexcept
 
 SdlWindow (const SdlWindow &other)=delete
 
SdlWindowoperator= (const SdlWindow &other)=delete
 
SdlWindowoperator= (SdlWindow &&other)=delete
 
SDL_WindowID id () const
 
SDL_DisplayID displayIndex () const
 
SDL_Rect rect () const
 
SDL_Rect bounds () const
 
SDL_Window * window () const
 
SDL_Renderer * renderer () const
 
Sint32 offsetX () const
 
void setOffsetX (Sint32 x)
 
void setOffsetY (Sint32 y)
 
Sint32 offsetY () const
 
rdpMonitor monitor (bool isPrimary) const
 
void setMonitor (rdpMonitor monitor)
 
float scale () const
 
SDL_DisplayOrientation orientation () const
 
bool grabKeyboard (bool enable)
 
bool grabMouse (bool enable)
 
void setBordered (bool bordered)
 
void raise ()
 
void resizeable (bool use)
 
void fullscreen (bool enter, bool forceOriginalDisplay)
 
void minimize ()
 
bool resizeToScale ()
 
bool resize (const SDL_Point &size)
 
bool drawRect (SDL_Surface *surface, SDL_Point offset, const SDL_Rect &srcRect)
 
bool drawRects (SDL_Surface *surface, SDL_Point offset, const std::vector< SDL_Rect > &rects={})
 
bool drawScaledRect (SDL_Surface *surface, const SDL_FPoint &scale, const SDL_Rect &srcRect)
 
bool drawScaledRects (SDL_Surface *surface, const SDL_FPoint &scale, const std::vector< SDL_Rect > &rects={})
 
bool fill (Uint8 r=0x00, Uint8 g=0x00, Uint8 b=0x00, Uint8 a=0xff)
 
bool blit (SDL_Surface *surface, const SDL_Rect &src, SDL_Rect &dst)
 
void updateSurface ()
 

Static Public Member Functions

static SdlWindow create (SDL_DisplayID id, const std::string &title, Uint32 flags, Uint32 width=0, Uint32 height=0)
 
static rdpMonitor query (SDL_DisplayID id, bool forceAsPrimary=false)
 

Protected Types

enum  HighDPIMode { MODE_INVALID , MODE_NONE , MODE_WINDOWS , MODE_MACOS }
 

Protected Member Functions

 SdlWindow (SDL_DisplayID id, const std::string &title, const SDL_Rect &rect, Uint32 flags)
 

Static Protected Member Functions

static bool fill (SDL_Window *window, Uint8 r=0x00, Uint8 g=0x00, Uint8 b=0x00, Uint8 a=0xff)
 
static rdpMonitor query (SDL_Window *window, SDL_DisplayID id, bool forceAsPrimary=false)
 
static SDL_Rect rect (SDL_Window *window, bool forceAsPrimary=false)
 
static SDL_Rect rect (SDL_DisplayID id, bool forceAsPrimary=false)
 
static bool tryFallback (bool isFullscreen)
 
static enum HighDPIMode isHighDPIWindowsMode (SDL_Window *window)
 

Detailed Description

FreeRDP: A Remote Desktop Protocol Implementation SDL Client

Copyright 2023 Armin Novak armin.nosp@m..nov.nosp@m.ak@th.nosp@m.inca.nosp@m.st.co.nosp@m.m 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.

Definition at line 25 of file SDL2/sdl_window.hpp.

Member Enumeration Documentation

◆ HighDPIMode

enum SdlWindow::HighDPIMode
protected

Definition at line 98 of file SDL3/sdl_window.hpp.

99 {
100 MODE_INVALID,
101 MODE_NONE,
102 MODE_WINDOWS,
103 MODE_MACOS
104 };

Constructor & Destructor Documentation

◆ SdlWindow() [1/3]

SdlWindow::SdlWindow ( const std::string &  title,
Sint32  startupX,
Sint32  startupY,
Sint32  width,
Sint32  height,
Uint32  flags 
)

FreeRDP: A Remote Desktop Protocol Implementation SDL Client

Copyright 2023 Armin Novak armin.nosp@m..nov.nosp@m.ak@th.nosp@m.inca.nosp@m.st.co.nosp@m.m 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.

Definition at line 23 of file SDL2/sdl_window.cpp.

25 : _window(SDL_CreateWindow(title.c_str(), startupX, startupY, width, height, flags))
26{
27}

◆ SdlWindow() [2/3]

SdlWindow::SdlWindow ( SdlWindow &&  other)
noexcept

Definition at line 29 of file SDL2/sdl_window.cpp.

30 : _window(other._window), _offset_x(other._offset_x), _offset_y(other._offset_y)
31{
32 other._window = nullptr;
33}

◆ ~SdlWindow()

SdlWindow::~SdlWindow ( )

Definition at line 35 of file SDL2/sdl_window.cpp.

36{
37 SDL_DestroyWindow(_window);
38}

◆ SdlWindow() [3/3]

SdlWindow::SdlWindow ( SDL_DisplayID  id,
const std::string &  title,
const SDL_Rect &  rect,
Uint32  flags 
)
protected

FreeRDP: A Remote Desktop Protocol Implementation SDL Client

Copyright 2023 Armin Novak armin.nosp@m..nov.nosp@m.ak@th.nosp@m.inca.nosp@m.st.co.nosp@m.m 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.

Definition at line 29 of file SDL3/sdl_window.cpp.

31 : _initialW(rect.w), _initialH(rect.h), _displayID(id)
32{
33 float pd = SDL_GetDisplayContentScale(id);
34 if (pd <= 0.0f)
35 pd = 1.0f;
36 const int createW = static_cast<int>(std::ceil(static_cast<float>(rect.w) / pd));
37 const int createH = static_cast<int>(std::ceil(static_cast<float>(rect.h) / pd));
38
39 auto props = SDL_CreateProperties();
40 SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, title.c_str());
41 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, rect.x);
42 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, rect.y);
43 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, createW);
44 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, createH);
45 SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, true);
46
47 if (flags & SDL_WINDOW_HIGH_PIXEL_DENSITY)
48 SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, true);
49
50 if (flags & SDL_WINDOW_FULLSCREEN)
51 SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN, true);
52
53 if (flags & SDL_WINDOW_BORDERLESS)
54 SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_BORDERLESS_BOOLEAN, true);
55
56 _window = SDL_CreateWindowWithProperties(props);
57 SDL_DestroyProperties(props);
58 SDL_SetHint(SDL_HINT_APP_NAME, "");
59 std::ignore = SDL_SyncWindow(_window);
60
61 _renderer = SDL_CreateRenderer(_window, nullptr);
62
63 std::ignore = resizeToScale();
64
65 _monitor = query(_window, id, true);
66}

Member Function Documentation

◆ blit() [1/2]

bool SdlWindow::blit ( SDL_Surface *  surface,
const SDL_Rect &  src,
SDL_Rect &  dst 
)

Definition at line 504 of file SDL3/sdl_window.cpp.

505{
506 if (!_renderer || !surface)
507 return false;
508
509 /* Lazily create or recreate the persistent GDI texture */
510 if (!_gdiTexture || _gdiTextureW != surface->w || _gdiTextureH != surface->h)
511 {
512 if (_gdiTexture)
513 SDL_DestroyTexture(_gdiTexture);
514 _gdiTexture = SDL_CreateTexture(_renderer, surface->format, SDL_TEXTUREACCESS_STREAMING,
515 surface->w, surface->h);
516 if (!_gdiTexture)
517 {
518 SDL_LogError(SDL_LOG_CATEGORY_RENDER, "SDL_CreateTexture: %s", SDL_GetError());
519 return false;
520 }
521 _gdiTextureW = surface->w;
522 _gdiTextureH = surface->h;
523 }
524
525 /* Upload only the dirty region */
526 const auto* details = SDL_GetPixelFormatDetails(surface->format);
527 const int bpp = details ? details->bytes_per_pixel : 4;
528 const auto* pixels = static_cast<const uint8_t*>(surface->pixels) +
529 (1ll * srcRect.y * surface->pitch) + (1ll * srcRect.x * bpp);
530 if (!SDL_UpdateTexture(_gdiTexture, &srcRect, pixels, surface->pitch))
531 {
532 SDL_LogError(SDL_LOG_CATEGORY_RENDER, "SDL_UpdateTexture: %s", SDL_GetError());
533 return false;
534 }
535
536 /* Render onto persistent render target to accumulate dirty rects */
537 if (!SDL_SetRenderTarget(_renderer, _renderTarget))
538 return false;
539
540 SDL_FRect fsrc = { static_cast<float>(srcRect.x), static_cast<float>(srcRect.y),
541 static_cast<float>(srcRect.w), static_cast<float>(srcRect.h) };
542 SDL_FRect fdst = { static_cast<float>(dstRect.x), static_cast<float>(dstRect.y),
543 static_cast<float>(dstRect.w), static_cast<float>(dstRect.h) };
544 if (!SDL_RenderTexture(_renderer, _gdiTexture, &fsrc, &fdst))
545 {
546 SDL_LogError(SDL_LOG_CATEGORY_RENDER, "SDL_RenderTexture: %s", SDL_GetError());
547 return false;
548 }
549 return true;
550}

◆ blit() [2/2]

bool SdlWindow::blit ( SDL_Surface *  surface,
SDL_Rect  src,
SDL_Rect &  dst 
)

Definition at line 187 of file SDL2/sdl_window.cpp.

188{
189 auto screen = SDL_GetWindowSurface(_window);
190 if (!screen || !surface)
191 return false;
192 if (!SDL_SetClipRect(surface, &srcRect))
193 return true;
194 if (!SDL_SetClipRect(screen, &dstRect))
195 return true;
196 auto rc = SDL_BlitScaled(surface, &srcRect, screen, &dstRect);
197 if (rc != 0)
198 {
199 SDL_LogError(SDL_LOG_CATEGORY_RENDER, "SDL_BlitScaled: %s [%d]", sdl_error_string(rc), rc);
200 }
201 return rc == 0;
202}

◆ bounds()

SDL_Rect SdlWindow::bounds ( ) const

Definition at line 112 of file SDL3/sdl_window.cpp.

113{
114 SDL_Rect rect = {};
115 if (_window)
116 {
117 if (!SDL_GetWindowPosition(_window, &rect.x, &rect.y))
118 return {};
119 if (!SDL_GetWindowSize(_window, &rect.w, &rect.h))
120 return {};
121 }
122 return rect;
123}

◆ create()

SdlWindow SdlWindow::create ( SDL_DisplayID  id,
const std::string &  title,
Uint32  flags,
Uint32  width = 0,
Uint32  height = 0 
)
static

Definition at line 568 of file SDL3/sdl_window.cpp.

570{
571 flags |= SDL_WINDOW_HIGH_PIXEL_DENSITY;
572
573 SDL_Rect rect = { static_cast<int>(SDL_WINDOWPOS_CENTERED_DISPLAY(id)),
574 static_cast<int>(SDL_WINDOWPOS_CENTERED_DISPLAY(id)), static_cast<int>(width),
575 static_cast<int>(height) };
576
577 if ((flags & SDL_WINDOW_FULLSCREEN) != 0)
578 {
579 std::ignore = SDL_GetDisplayBounds(id, &rect);
580 }
581
582 SdlWindow window{ id, title, rect, flags };
583
584 if ((flags & SDL_WINDOW_FULLSCREEN) != 0)
585 {
586 window.setOffsetX(rect.x);
587 window.setOffsetY(rect.y);
588 }
589
590 return window;
591}

◆ displayIndex()

SDL_DisplayID SdlWindow::displayIndex ( ) const

Definition at line 47 of file SDL2/sdl_window.cpp.

48{
49 if (!_window)
50 return 0;
51 return SDL_GetWindowDisplayIndex(_window);
52}

◆ drawRect()

bool SdlWindow::drawRect ( SDL_Surface *  surface,
SDL_Point  offset,
const SDL_Rect &  srcRect 
)

Definition at line 299 of file SDL3/sdl_window.cpp.

300{
301 WINPR_ASSERT(surface);
302 SDL_Rect dstRect = { offset.x + srcRect.x, offset.y + srcRect.y, srcRect.w, srcRect.h };
303 return blit(surface, srcRect, dstRect);
304}

◆ drawRects()

bool SdlWindow::drawRects ( SDL_Surface *  surface,
SDL_Point  offset,
const std::vector< SDL_Rect > &  rects = {} 
)

Definition at line 306 of file SDL3/sdl_window.cpp.

308{
309 if (rects.empty())
310 {
311 return drawRect(surface, offset, { 0, 0, surface->w, surface->h });
312 }
313 for (auto& srcRect : rects)
314 {
315 if (!drawRect(surface, offset, srcRect))
316 return false;
317 }
318 return true;
319}

◆ drawScaledRect()

bool SdlWindow::drawScaledRect ( SDL_Surface *  surface,
const SDL_FPoint &  scale,
const SDL_Rect &  srcRect 
)

Definition at line 321 of file SDL3/sdl_window.cpp.

323{
324 SDL_Rect dstRect = {};
325 float ix = 0.0f;
326 float iy = 0.0f;
327 const auto modx = std::modf(static_cast<float>(srcRect.x) * scale.x, &ix);
328 const auto mody = std::modf(static_cast<float>(srcRect.y) * scale.y, &iy);
329 auto sw = std::ceil(static_cast<float>(srcRect.w) * scale.x) + std::ceil(modx);
330 auto sh = std::ceil(static_cast<float>(srcRect.h) * scale.y) + std::ceil(mody);
331 dstRect.x = static_cast<Sint32>(ix);
332 dstRect.w = static_cast<Sint32>(sw);
333 dstRect.y = static_cast<Sint32>(iy);
334 dstRect.h = static_cast<Sint32>(sh);
335 return blit(surface, srcRect, dstRect);
336}

◆ drawScaledRects()

bool SdlWindow::drawScaledRects ( SDL_Surface *  surface,
const SDL_FPoint &  scale,
const std::vector< SDL_Rect > &  rects = {} 
)

Definition at line 338 of file SDL3/sdl_window.cpp.

340{
341 if (rects.empty())
342 {
343 return drawScaledRect(surface, scale, { 0, 0, surface->w, surface->h });
344 }
345 for (const auto& srcRect : rects)
346 {
347 if (!drawScaledRect(surface, scale, srcRect))
348 return false;
349 }
350 return true;
351}

◆ fill() [1/2]

bool SdlWindow::fill ( SDL_Window *  window,
Uint8  r = 0x00,
Uint8  g = 0x00,
Uint8  b = 0x00,
Uint8  a = 0xff 
)
staticprotected

Definition at line 367 of file SDL3/sdl_window.cpp.

368{
369 auto surface = SDL_GetWindowSurface(window);
370 if (!surface)
371 return false;
372 SDL_Rect rect = { 0, 0, surface->w, surface->h };
373 auto color = SDL_MapSurfaceRGBA(surface, r, g, b, a);
374
375 return SDL_FillSurfaceRect(surface, &rect, color);
376}

◆ fill() [2/2]

bool SdlWindow::fill ( Uint8  r = 0x00,
Uint8  g = 0x00,
Uint8  b = 0x00,
Uint8  a = 0xff 
)

Definition at line 175 of file SDL2/sdl_window.cpp.

176{
177 auto surface = SDL_GetWindowSurface(_window);
178 if (!surface)
179 return false;
180 SDL_Rect rect = { 0, 0, surface->w, surface->h };
181 auto color = SDL_MapRGBA(surface->format, r, g, b, a);
182
183 SDL_FillRect(surface, &rect, color);
184 return true;
185}

◆ fullscreen() [1/2]

void SdlWindow::fullscreen ( bool  enter)

Definition at line 131 of file SDL2/sdl_window.cpp.

132{
133 auto curFlags = SDL_GetWindowFlags(_window);
134
135 if (enter)
136 {
137 if (!(curFlags & SDL_WINDOW_BORDERLESS))
138 {
139 auto idx = SDL_GetWindowDisplayIndex(_window);
140 SDL_DisplayMode mode = {};
141 SDL_GetCurrentDisplayMode(idx, &mode);
142
143 SDL_RestoreWindow(_window); // Maximize so we can see the caption and
144 // bits
145 SDL_SetWindowBordered(_window, SDL_FALSE);
146 SDL_SetWindowPosition(_window, 0, 0);
147#if SDL_VERSION_ATLEAST(2, 0, 16)
148 SDL_SetWindowAlwaysOnTop(_window, SDL_TRUE);
149#endif
150 SDL_RaiseWindow(_window);
151 SDL_SetWindowSize(_window, mode.w, mode.h);
152 }
153 }
154 else
155 {
156 if (curFlags & SDL_WINDOW_BORDERLESS)
157 {
158
159 SDL_SetWindowBordered(_window, SDL_TRUE);
160#if SDL_VERSION_ATLEAST(2, 0, 16)
161 SDL_SetWindowAlwaysOnTop(_window, SDL_FALSE);
162#endif
163 SDL_RaiseWindow(_window);
164 SDL_MinimizeWindow(_window); // Maximize so we can see the caption and bits
165 SDL_MaximizeWindow(_window); // Maximize so we can see the caption and bits
166 }
167 }
168}

◆ fullscreen() [2/2]

void SdlWindow::fullscreen ( bool  enter,
bool  forceOriginalDisplay 
)

Definition at line 217 of file SDL3/sdl_window.cpp.

218{
219 if (enter && forceOriginalDisplay && _displayID != 0)
220 {
221 /* Move the window to the desired display. We should not wait
222 * for the window to be moved, because some backends can refuse
223 * the move. The intent of moving the window is enough for SDL
224 * to decide which display will be used for fullscreen. */
225 SDL_Rect rect = {};
226 std::ignore = SDL_GetDisplayBounds(_displayID, &rect);
227 std::ignore = SDL_SetWindowPosition(_window, rect.x, rect.y);
228 }
229 std::ignore = SDL_SetWindowFullscreen(_window, enter);
230 std::ignore = SDL_SyncWindow(_window);
231}

◆ grabKeyboard()

bool SdlWindow::grabKeyboard ( bool  enable)

Definition at line 90 of file SDL2/sdl_window.cpp.

91{
92 if (!_window)
93 return false;
94#if SDL_VERSION_ATLEAST(2, 0, 16)
95 SDL_SetWindowKeyboardGrab(_window, enable ? SDL_TRUE : SDL_FALSE);
96 return true;
97#else
98 SDL_LogError(SDL_LOG_CATEGORY_INPUT, "Keyboard grabbing not supported by SDL2 < 2.0.16");
99 return false;
100#endif
101}

◆ grabMouse()

bool SdlWindow::grabMouse ( bool  enable)

Definition at line 103 of file SDL2/sdl_window.cpp.

104{
105 if (!_window)
106 return false;
107#if SDL_VERSION_ATLEAST(2, 0, 16)
108 SDL_SetWindowMouseGrab(_window, enable ? SDL_TRUE : SDL_FALSE);
109#else
110 SDL_SetWindowGrab(_window, enable ? SDL_TRUE : SDL_FALSE);
111#endif
112 return true;
113}

◆ id()

SDL_WindowID SdlWindow::id ( ) const

Definition at line 40 of file SDL2/sdl_window.cpp.

41{
42 if (!_window)
43 return 0;
44 return SDL_GetWindowID(_window);
45}

◆ isHighDPIWindowsMode()

SdlWindow::HighDPIMode SdlWindow::isHighDPIWindowsMode ( SDL_Window *  window)
staticprotected

Definition at line 479 of file SDL3/sdl_window.cpp.

480{
481 if (!window)
482 return MODE_INVALID;
483
484 const auto id = SDL_GetDisplayForWindow(window);
485 if (id == 0)
486 return MODE_INVALID;
487
488 const auto cs = SDL_GetDisplayContentScale(id);
489 const auto ds = SDL_GetWindowDisplayScale(window);
490 const auto pd = SDL_GetWindowPixelDensity(window);
491
492 /* mac os x style, but no HighDPI display */
493 if ((cs == 1.0f) && (ds == 1.0f) && (pd == 1.0f))
494 return MODE_NONE;
495
496 /* mac os x style HighDPI */
497 if ((cs == 1.0f) && (ds > 1.0f) && (pd > 1.0f))
498 return MODE_MACOS;
499
500 /* rest is windows style */
501 return MODE_WINDOWS;
502}

◆ minimize()

void SdlWindow::minimize ( )

Definition at line 170 of file SDL2/sdl_window.cpp.

171{
172 SDL_MinimizeWindow(_window);
173}

◆ monitor()

rdpMonitor SdlWindow::monitor ( bool  isPrimary) const

Definition at line 155 of file SDL3/sdl_window.cpp.

156{
157 auto m = _monitor;
158 if (isPrimary)
159 {
160 m.x = 0;
161 m.y = 0;
162 }
163 return m;
164}

◆ offsetX()

Sint32 SdlWindow::offsetX ( ) const

Definition at line 70 of file SDL2/sdl_window.cpp.

71{
72 return _offset_x;
73}

◆ offsetY()

Sint32 SdlWindow::offsetY ( ) const

Definition at line 85 of file SDL2/sdl_window.cpp.

86{
87 return _offset_y;
88}

◆ orientation()

SDL_DisplayOrientation SdlWindow::orientation ( ) const

Definition at line 176 of file SDL3/sdl_window.cpp.

177{
178 const auto did = displayIndex();
179 return SDL_GetCurrentDisplayOrientation(did);
180}

◆ query() [1/2]

rdpMonitor SdlWindow::query ( SDL_DisplayID  id,
bool  forceAsPrimary = false 
)
static

Definition at line 630 of file SDL3/sdl_window.cpp.

631{
632 std::unique_ptr<SDL_Window, void (*)(SDL_Window*)> window(createDummy(id), SDL_DestroyWindow);
633 if (!window)
634 return {};
635
636 std::unique_ptr<SDL_Renderer, void (*)(SDL_Renderer*)> renderer(
637 SDL_CreateRenderer(window.get(), nullptr), SDL_DestroyRenderer);
638
639 if (!SDL_SyncWindow(window.get()))
640 return {};
641
642 SDL_Event event{};
643 while (SDL_PollEvent(&event))
644 ;
645
646 return query(window.get(), id, forceAsPrimary);
647}

◆ query() [2/2]

rdpMonitor SdlWindow::query ( SDL_Window *  window,
SDL_DisplayID  id,
bool  forceAsPrimary = false 
)
staticprotected

Definition at line 378 of file SDL3/sdl_window.cpp.

379{
380 if (!window)
381 return {};
382
383 const auto& r = rect(window, forceAsPrimary);
384 const float factor = SDL_GetWindowDisplayScale(window);
385 const float dpi = std::roundf(factor * 100.0f);
386
387 WINPR_ASSERT(r.w > 0);
388 WINPR_ASSERT(r.h > 0);
389
390 const auto primary = SDL_GetPrimaryDisplay();
391 const auto orientation = SDL_GetCurrentDisplayOrientation(id);
392 const auto rdp_orientation = sdl::utils::orientaion_to_rdp(orientation);
393
394 rdpMonitor monitor{};
395 monitor.orig_screen = id;
396 monitor.x = r.x;
397 monitor.y = r.y;
398 monitor.width = r.w;
399 monitor.height = r.h;
400 monitor.is_primary = forceAsPrimary || (id == primary);
401 monitor.attributes.desktopScaleFactor = static_cast<UINT32>(dpi);
402 monitor.attributes.deviceScaleFactor = 100;
403 monitor.attributes.orientation = rdp_orientation;
404 monitor.attributes.physicalWidth = WINPR_ASSERTING_INT_CAST(uint32_t, r.w);
405 monitor.attributes.physicalHeight = WINPR_ASSERTING_INT_CAST(uint32_t, r.h);
406
407 const auto cat = SDL_LOG_CATEGORY_APPLICATION;
408 SDL_LogDebug(cat, "monitor.orig_screen %" PRIu32, monitor.orig_screen);
409 SDL_LogDebug(cat, "monitor.x %" PRId32, monitor.x);
410 SDL_LogDebug(cat, "monitor.y %" PRId32, monitor.y);
411 SDL_LogDebug(cat, "monitor.width %" PRId32, monitor.width);
412 SDL_LogDebug(cat, "monitor.height %" PRId32, monitor.height);
413 SDL_LogDebug(cat, "monitor.is_primary %" PRIu32, monitor.is_primary);
414 SDL_LogDebug(cat, "monitor.attributes.desktopScaleFactor %" PRIu32,
415 monitor.attributes.desktopScaleFactor);
416 SDL_LogDebug(cat, "monitor.attributes.deviceScaleFactor %" PRIu32,
417 monitor.attributes.deviceScaleFactor);
418 SDL_LogDebug(cat, "monitor.attributes.orientation %s",
419 freerdp_desktop_rotation_flags_to_string(monitor.attributes.orientation));
420 SDL_LogDebug(cat, "monitor.attributes.physicalWidth %" PRIu32,
421 monitor.attributes.physicalWidth);
422 SDL_LogDebug(cat, "monitor.attributes.physicalHeight %" PRIu32,
423 monitor.attributes.physicalHeight);
424 return monitor;
425}

◆ raise()

void SdlWindow::raise ( )

Definition at line 121 of file SDL2/sdl_window.cpp.

122{
123 SDL_RaiseWindow(_window);
124}

◆ rect() [1/3]

SDL_Rect SdlWindow::rect ( ) const

Definition at line 54 of file SDL2/sdl_window.cpp.

55{
56 SDL_Rect rect = {};
57 if (_window)
58 {
59 SDL_GetWindowPosition(_window, &rect.x, &rect.y);
60 SDL_GetWindowSize(_window, &rect.w, &rect.h);
61 }
62 return rect;
63}

◆ rect() [2/3]

SDL_Rect SdlWindow::rect ( SDL_DisplayID  id,
bool  forceAsPrimary = false 
)
staticprotected

Definition at line 649 of file SDL3/sdl_window.cpp.

650{
651 std::unique_ptr<SDL_Window, void (*)(SDL_Window*)> window(createDummy(id), SDL_DestroyWindow);
652 if (!window)
653 return {};
654
655 std::unique_ptr<SDL_Renderer, void (*)(SDL_Renderer*)> renderer(
656 SDL_CreateRenderer(window.get(), nullptr), SDL_DestroyRenderer);
657
658 if (!SDL_SyncWindow(window.get()))
659 return {};
660
661 SDL_Event event{};
662 while (SDL_PollEvent(&event))
663 ;
664
665 return rect(window.get(), forceAsPrimary);
666}

◆ rect() [3/3]

SDL_Rect SdlWindow::rect ( SDL_Window *  window,
bool  forceAsPrimary = false 
)
staticprotected

Definition at line 427 of file SDL3/sdl_window.cpp.

428{
429 SDL_Rect rect = {};
430 if (!window)
431 return {};
432
433 if (!forceAsPrimary)
434 {
435 if (!SDL_GetWindowPosition(window, &rect.x, &rect.y))
436 return {};
437 }
438
439 if (!SDL_GetWindowSizeInPixels(window, &rect.w, &rect.h))
440 return {};
441
442 const auto flags = SDL_GetWindowFlags(window);
443 const auto mask = SDL_WINDOW_FULLSCREEN;
444 const auto fs = (flags & mask) == mask;
445 if (tryFallback(fs))
446 {
447 /* On wlroots compositors (Sway, river, etc.), windows that are hidden/unmapped
448 * don't get their actual display dimensions. The dummy window returns its creation size
449 * (64x64) instead of the display size. This causes validation errors since we require >=
450 * 200px. Workaround: If we got dimensions that are too small, query the display directly.
451 */
452
453 const auto displayID = SDL_GetDisplayForWindow(window);
454 SDL_Rect displayBounds = {};
455 if (SDL_GetDisplayBounds(displayID, &displayBounds))
456 {
457 if (forceAsPrimary)
458 {
459 rect.x = 0;
460 rect.y = 0;
461 }
462 rect.w = displayBounds.w;
463 rect.h = displayBounds.h;
464
465 const float contentScale = SDL_GetDisplayContentScale(displayID);
466 if (contentScale > 1.0f)
467 {
468 const auto fw = static_cast<float>(rect.w);
469 const auto fh = static_cast<float>(rect.h);
470 rect.w = static_cast<int>(std::roundf(fw * contentScale));
471 rect.h = static_cast<int>(std::roundf(fh * contentScale));
472 }
473 }
474 }
475
476 return rect;
477}

◆ renderer()

SDL_Renderer * SdlWindow::renderer ( ) const

Definition at line 130 of file SDL3/sdl_window.cpp.

131{
132 return _renderer;
133}

◆ resize()

bool SdlWindow::resize ( const SDL_Point &  size)

Definition at line 264 of file SDL3/sdl_window.cpp.

265{
266 return SDL_SetWindowSize(_window, size.x, size.y);
267}

◆ resizeable()

void SdlWindow::resizeable ( bool  use)

Definition at line 126 of file SDL2/sdl_window.cpp.

127{
128 SDL_SetWindowResizable(_window, use ? SDL_TRUE : SDL_FALSE);
129}

◆ resizeToScale()

bool SdlWindow::resizeToScale ( )

Definition at line 239 of file SDL3/sdl_window.cpp.

240{
241 if (!_window || _initialW <= 0 || _initialH <= 0)
242 return false;
243 if ((SDL_GetWindowFlags(_window) & SDL_WINDOW_FULLSCREEN) != 0)
244 return true;
245
246 float pd = SDL_GetWindowPixelDensity(_window);
247 if (pd <= 0.0f)
248 pd = 1.0f;
249
250 const int targetW = static_cast<int>(std::ceil(static_cast<float>(_initialW) / pd));
251 const int targetH = static_cast<int>(std::ceil(static_cast<float>(_initialH) / pd));
252
253 int curW = 0;
254 int curH = 0;
255 if (!SDL_GetWindowSize(_window, &curW, &curH))
256 return false;
257
258 if (curW == targetW && curH == targetH)
259 return true;
260
261 return resize({ targetW, targetH });
262}

◆ scale()

float SdlWindow::scale ( ) const

Definition at line 171 of file SDL3/sdl_window.cpp.

172{
173 return SDL_GetWindowDisplayScale(_window);
174}

◆ setBordered()

void SdlWindow::setBordered ( bool  bordered)

Definition at line 115 of file SDL2/sdl_window.cpp.

116{
117 if (_window)
118 SDL_SetWindowBordered(_window, bordered ? SDL_TRUE : SDL_FALSE);
119}

◆ setMonitor()

void SdlWindow::setMonitor ( rdpMonitor  monitor)

Definition at line 166 of file SDL3/sdl_window.cpp.

167{
168 _monitor = monitor;
169}

◆ setOffsetX()

void SdlWindow::setOffsetX ( Sint32  x)

Definition at line 75 of file SDL2/sdl_window.cpp.

76{
77 _offset_x = x;
78}

◆ setOffsetY()

void SdlWindow::setOffsetY ( Sint32  y)

Definition at line 80 of file SDL2/sdl_window.cpp.

81{
82 _offset_y = y;
83}

◆ tryFallback()

bool SdlWindow::tryFallback ( bool  isFullscreen)
staticprotected

Definition at line 668 of file SDL3/sdl_window.cpp.

669{
670 /* If we define a custom env variable to use the wlroots hack
671 * then enable/disable according to this setting only.
672 */
673 const auto wlroots_hack = SDL_getenv("FREERDP_WLROOTS_HACK");
674 if (wlroots_hack != nullptr)
675 {
676 const auto enabled = strcmp(wlroots_hack, "0") != 0;
677 if (strcmp(wlroots_hack, "force") == 0)
678 isFullscreen = true;
679 return enabled && isFullscreen;
680 }
681
682 const auto platform = SDL_GetPlatform();
683 if ((platform == nullptr) || (strcmp(platform, "Linux") != 0))
684 return false;
685
686 const auto driver = SDL_GetCurrentVideoDriver();
687 if ((driver == nullptr) || (strcmp(driver, "wayland") != 0))
688 return false;
689
690 /* Check XDG_SESSION_DESKTOP and XDG_CURRENT_DESKTOP for wlroots-based
691 * compositors. The original check only matched Sway, but other wlroots
692 * compositors (Hyprland, river, etc.) have the same dummy-window sizing
693 * behavior where hidden/unmapped windows return 64x64 instead of the
694 * display size. Use strstr for substring matching since XDG_CURRENT_DESKTOP
695 * can be a colon-separated list (e.g. "sway:wlroots", "Hyprland").
696 */
697 auto isWlrootsCompositor = [](const char* value) -> bool
698 {
699 if (!value)
700 return false;
701 if (strstr(value, "sway") || strstr(value, "Sway") || strstr(value, "Hyprland") ||
702 strstr(value, "hyprland") || strstr(value, "river") || strstr(value, "wlroots"))
703 return true;
704 return false;
705 };
706
707 const auto xdg_session = SDL_getenv("XDG_SESSION_DESKTOP");
708 if (isWlrootsCompositor(xdg_session))
709 return isFullscreen;
710
711 const auto xdg_desktop = SDL_getenv("XDG_CURRENT_DESKTOP");
712 if (isWlrootsCompositor(xdg_desktop))
713 return isFullscreen;
714
715 return false;
716}

◆ updateSurface()

void SdlWindow::updateSurface ( )

Definition at line 204 of file SDL2/sdl_window.cpp.

205{
206 SDL_UpdateWindowSurface(_window);
207}

◆ window()

SDL_Window * SdlWindow::window ( ) const

Definition at line 65 of file SDL2/sdl_window.cpp.

66{
67 return _window;
68}

The documentation for this class was generated from the following files: