FreeRDP
SDL2/sdl_window.cpp
1 
20 #include "sdl_window.hpp"
21 #include "sdl_utils.hpp"
22 
23 SdlWindow::SdlWindow(const std::string& title, Sint32 startupX, Sint32 startupY, Sint32 width,
24  Sint32 height, Uint32 flags)
25  : _window(SDL_CreateWindow(title.c_str(), startupX, startupY, width, height, flags))
26 {
27 }
28 
29 SdlWindow::SdlWindow(SdlWindow&& other) noexcept
30  : _window(other._window), _offset_x(other._offset_x), _offset_y(other._offset_y)
31 {
32  other._window = nullptr;
33 }
34 
35 SdlWindow::~SdlWindow()
36 {
37  SDL_DestroyWindow(_window);
38 }
39 
40 Uint32 SdlWindow::id() const
41 {
42  if (!_window)
43  return 0;
44  return SDL_GetWindowID(_window);
45 }
46 
47 int SdlWindow::displayIndex() const
48 {
49  if (!_window)
50  return 0;
51  return SDL_GetWindowDisplayIndex(_window);
52 }
53 
54 SDL_Rect SdlWindow::rect() const
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 }
64 
65 SDL_Window* SdlWindow::window() const
66 {
67  return _window;
68 }
69 
70 Sint32 SdlWindow::offsetX() const
71 {
72  return _offset_x;
73 }
74 
75 void SdlWindow::setOffsetX(Sint32 x)
76 {
77  _offset_x = x;
78 }
79 
80 void SdlWindow::setOffsetY(Sint32 y)
81 {
82  _offset_y = y;
83 }
84 
85 Sint32 SdlWindow::offsetY() const
86 {
87  return _offset_y;
88 }
89 
90 bool SdlWindow::grabKeyboard(bool enable)
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 }
102 
103 bool SdlWindow::grabMouse(bool enable)
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 }
114 
115 void SdlWindow::setBordered(bool bordered)
116 {
117  if (_window)
118  SDL_SetWindowBordered(_window, bordered ? SDL_TRUE : SDL_FALSE);
119 }
120 
121 void SdlWindow::raise()
122 {
123  SDL_RaiseWindow(_window);
124 }
125 
126 void SdlWindow::resizeable(bool use)
127 {
128  SDL_SetWindowResizable(_window, use ? SDL_TRUE : SDL_FALSE);
129 }
130 
131 void SdlWindow::fullscreen(bool enter)
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 }
169 
170 void SdlWindow::minimize()
171 {
172  SDL_MinimizeWindow(_window);
173 }
174 
175 bool SdlWindow::fill(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
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 }
186 
187 bool SdlWindow::blit(SDL_Surface* surface, SDL_Rect srcRect, SDL_Rect& dstRect)
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 }
203 
204 void SdlWindow::updateSurface()
205 {
206  SDL_UpdateWindowSurface(_window);
207 }
SdlWindow(const std::string &title, Sint32 startupX, Sint32 startupY, Sint32 width, Sint32 height, Uint32 flags)