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 auto props = SDL_CreateProperties();
34 SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, title.c_str());
35 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, rect.x);
36 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, rect.y);
37 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, rect.w);
38 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, rect.h);
39 SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, true);
40
41 if (flags & SDL_WINDOW_HIGH_PIXEL_DENSITY)
42 SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, true);
43
44 if (flags & SDL_WINDOW_FULLSCREEN)
45 SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN, true);
46
47 if (flags & SDL_WINDOW_BORDERLESS)
48 SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_BORDERLESS_BOOLEAN, true);
49
50 _window = SDL_CreateWindowWithProperties(props);
51 SDL_DestroyProperties(props);
52 SDL_SetHint(SDL_HINT_APP_NAME, "");
53 std::ignore = SDL_SyncWindow(_window);
54
55 _renderer = SDL_CreateRenderer(_window, nullptr);
56
57 std::ignore = resizeToScale();
58
59 _monitor = query(_window, id, true);
60}

Member Function Documentation

◆ blit() [1/2]

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

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

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

◆ 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 106 of file SDL3/sdl_window.cpp.

107{
108 SDL_Rect rect = {};
109 if (_window)
110 {
111 if (!SDL_GetWindowPosition(_window, &rect.x, &rect.y))
112 return {};
113 if (!SDL_GetWindowSize(_window, &rect.w, &rect.h))
114 return {};
115 }
116 return rect;
117}

◆ create()

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

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

558{
559 flags |= SDL_WINDOW_HIGH_PIXEL_DENSITY;
560
561 SDL_Rect rect = { static_cast<int>(SDL_WINDOWPOS_CENTERED_DISPLAY(id)),
562 static_cast<int>(SDL_WINDOWPOS_CENTERED_DISPLAY(id)), static_cast<int>(width),
563 static_cast<int>(height) };
564
565 if ((flags & SDL_WINDOW_FULLSCREEN) != 0)
566 {
567 std::ignore = SDL_GetDisplayBounds(id, &rect);
568 }
569
570 SdlWindow window{ id, title, rect, flags };
571
572 if ((flags & SDL_WINDOW_FULLSCREEN) != 0)
573 {
574 window.setOffsetX(rect.x);
575 window.setOffsetY(rect.y);
576 }
577
578 return window;
579}

◆ 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 293 of file SDL3/sdl_window.cpp.

294{
295 WINPR_ASSERT(surface);
296 SDL_Rect dstRect = { offset.x + srcRect.x, offset.y + srcRect.y, srcRect.w, srcRect.h };
297 return blit(surface, srcRect, dstRect);
298}

◆ drawRects()

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

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

302{
303 if (rects.empty())
304 {
305 return drawRect(surface, offset, { 0, 0, surface->w, surface->h });
306 }
307 for (auto& srcRect : rects)
308 {
309 if (!drawRect(surface, offset, srcRect))
310 return false;
311 }
312 return true;
313}

◆ drawScaledRect()

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

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

317{
318 SDL_Rect dstRect = srcRect;
319 dstRect.x = static_cast<Sint32>(static_cast<float>(dstRect.x) * scale.x);
320 dstRect.w = static_cast<Sint32>(static_cast<float>(dstRect.w) * scale.x);
321 dstRect.y = static_cast<Sint32>(static_cast<float>(dstRect.y) * scale.y);
322 dstRect.h = static_cast<Sint32>(static_cast<float>(dstRect.h) * scale.y);
323 return blit(surface, srcRect, dstRect);
324}

◆ drawScaledRects()

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

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

328{
329 if (rects.empty())
330 {
331 return drawScaledRect(surface, scale, { 0, 0, surface->w, surface->h });
332 }
333 for (const auto& srcRect : rects)
334 {
335 if (!drawScaledRect(surface, scale, srcRect))
336 return false;
337 }
338 return true;
339}

◆ 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 355 of file SDL3/sdl_window.cpp.

356{
357 auto surface = SDL_GetWindowSurface(window);
358 if (!surface)
359 return false;
360 SDL_Rect rect = { 0, 0, surface->w, surface->h };
361 auto color = SDL_MapSurfaceRGBA(surface, r, g, b, a);
362
363 return SDL_FillSurfaceRect(surface, &rect, color);
364}

◆ 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 211 of file SDL3/sdl_window.cpp.

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

◆ 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 467 of file SDL3/sdl_window.cpp.

468{
469 if (!window)
470 return MODE_INVALID;
471
472 const auto id = SDL_GetDisplayForWindow(window);
473 if (id == 0)
474 return MODE_INVALID;
475
476 const auto cs = SDL_GetDisplayContentScale(id);
477 const auto ds = SDL_GetWindowDisplayScale(window);
478 const auto pd = SDL_GetWindowPixelDensity(window);
479
480 /* mac os x style, but no HighDPI display */
481 if ((cs == 1.0f) && (ds == 1.0f) && (pd == 1.0f))
482 return MODE_NONE;
483
484 /* mac os x style HighDPI */
485 if ((cs == 1.0f) && (ds > 1.0f) && (pd > 1.0f))
486 return MODE_MACOS;
487
488 /* rest is windows style */
489 return MODE_WINDOWS;
490}

◆ 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 149 of file SDL3/sdl_window.cpp.

150{
151 auto m = _monitor;
152 if (isPrimary)
153 {
154 m.x = 0;
155 m.y = 0;
156 }
157 return m;
158}

◆ 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 170 of file SDL3/sdl_window.cpp.

171{
172 const auto did = displayIndex();
173 return SDL_GetCurrentDisplayOrientation(did);
174}

◆ query() [1/2]

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

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

619{
620 std::unique_ptr<SDL_Window, void (*)(SDL_Window*)> window(createDummy(id), SDL_DestroyWindow);
621 if (!window)
622 return {};
623
624 std::unique_ptr<SDL_Renderer, void (*)(SDL_Renderer*)> renderer(
625 SDL_CreateRenderer(window.get(), nullptr), SDL_DestroyRenderer);
626
627 if (!SDL_SyncWindow(window.get()))
628 return {};
629
630 SDL_Event event{};
631 while (SDL_PollEvent(&event))
632 ;
633
634 return query(window.get(), id, forceAsPrimary);
635}

◆ query() [2/2]

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

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

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

◆ 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 637 of file SDL3/sdl_window.cpp.

638{
639 std::unique_ptr<SDL_Window, void (*)(SDL_Window*)> window(createDummy(id), SDL_DestroyWindow);
640 if (!window)
641 return {};
642
643 std::unique_ptr<SDL_Renderer, void (*)(SDL_Renderer*)> renderer(
644 SDL_CreateRenderer(window.get(), nullptr), SDL_DestroyRenderer);
645
646 if (!SDL_SyncWindow(window.get()))
647 return {};
648
649 SDL_Event event{};
650 while (SDL_PollEvent(&event))
651 ;
652
653 return rect(window.get(), forceAsPrimary);
654}

◆ rect() [3/3]

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

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

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

◆ renderer()

SDL_Renderer * SdlWindow::renderer ( ) const

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

125{
126 return _renderer;
127}

◆ resize()

bool SdlWindow::resize ( const SDL_Point &  size)

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

259{
260 return SDL_SetWindowSize(_window, size.x, size.y);
261}

◆ 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 233 of file SDL3/sdl_window.cpp.

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

◆ scale()

float SdlWindow::scale ( ) const

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

166{
167 return SDL_GetWindowDisplayScale(_window);
168}

◆ 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 160 of file SDL3/sdl_window.cpp.

161{
162 _monitor = monitor;
163}

◆ 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 656 of file SDL3/sdl_window.cpp.

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

◆ 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: