FreeRDP
SDL2/sdl_utils.cpp
1 
20 #include <cassert>
21 #include "sdl_utils.hpp"
22 
23 #include "sdl_freerdp.hpp"
24 
25 #include <SDL.h>
26 
27 #include <freerdp/version.h>
28 
29 const char* sdl_event_type_str(Uint32 type)
30 {
31 #define STR(x) #x
32 #define EV_CASE_STR(x) \
33  case x: \
34  return STR(x)
35 
36  switch (type)
37  {
38  EV_CASE_STR(SDL_FIRSTEVENT);
39  EV_CASE_STR(SDL_QUIT);
40  EV_CASE_STR(SDL_APP_TERMINATING);
41  EV_CASE_STR(SDL_APP_LOWMEMORY);
42  EV_CASE_STR(SDL_APP_WILLENTERBACKGROUND);
43  EV_CASE_STR(SDL_APP_DIDENTERBACKGROUND);
44  EV_CASE_STR(SDL_APP_WILLENTERFOREGROUND);
45  EV_CASE_STR(SDL_APP_DIDENTERFOREGROUND);
46 #if SDL_VERSION_ATLEAST(2, 0, 10)
47  EV_CASE_STR(SDL_DISPLAYEVENT);
48 #endif
49  EV_CASE_STR(SDL_WINDOWEVENT);
50  EV_CASE_STR(SDL_SYSWMEVENT);
51  EV_CASE_STR(SDL_KEYDOWN);
52  EV_CASE_STR(SDL_KEYUP);
53  EV_CASE_STR(SDL_TEXTEDITING);
54  EV_CASE_STR(SDL_TEXTINPUT);
55  EV_CASE_STR(SDL_KEYMAPCHANGED);
56  EV_CASE_STR(SDL_MOUSEMOTION);
57  EV_CASE_STR(SDL_MOUSEBUTTONDOWN);
58  EV_CASE_STR(SDL_MOUSEBUTTONUP);
59  EV_CASE_STR(SDL_MOUSEWHEEL);
60  EV_CASE_STR(SDL_JOYAXISMOTION);
61  EV_CASE_STR(SDL_JOYBALLMOTION);
62  EV_CASE_STR(SDL_JOYHATMOTION);
63  EV_CASE_STR(SDL_JOYBUTTONDOWN);
64  EV_CASE_STR(SDL_JOYBUTTONUP);
65  EV_CASE_STR(SDL_JOYDEVICEADDED);
66  EV_CASE_STR(SDL_JOYDEVICEREMOVED);
67  EV_CASE_STR(SDL_CONTROLLERAXISMOTION);
68  EV_CASE_STR(SDL_CONTROLLERBUTTONDOWN);
69  EV_CASE_STR(SDL_CONTROLLERBUTTONUP);
70  EV_CASE_STR(SDL_CONTROLLERDEVICEADDED);
71  EV_CASE_STR(SDL_CONTROLLERDEVICEREMOVED);
72  EV_CASE_STR(SDL_CONTROLLERDEVICEREMAPPED);
73 #if SDL_VERSION_ATLEAST(2, 0, 14)
74  EV_CASE_STR(SDL_LOCALECHANGED);
75  EV_CASE_STR(SDL_CONTROLLERTOUCHPADDOWN);
76  EV_CASE_STR(SDL_CONTROLLERTOUCHPADMOTION);
77  EV_CASE_STR(SDL_CONTROLLERTOUCHPADUP);
78  EV_CASE_STR(SDL_CONTROLLERSENSORUPDATE);
79 #endif
80  EV_CASE_STR(SDL_FINGERDOWN);
81  EV_CASE_STR(SDL_FINGERUP);
82  EV_CASE_STR(SDL_FINGERMOTION);
83  EV_CASE_STR(SDL_DOLLARGESTURE);
84  EV_CASE_STR(SDL_DOLLARRECORD);
85  EV_CASE_STR(SDL_MULTIGESTURE);
86  EV_CASE_STR(SDL_CLIPBOARDUPDATE);
87  EV_CASE_STR(SDL_DROPFILE);
88  EV_CASE_STR(SDL_DROPTEXT);
89  EV_CASE_STR(SDL_DROPBEGIN);
90  EV_CASE_STR(SDL_DROPCOMPLETE);
91  EV_CASE_STR(SDL_AUDIODEVICEADDED);
92  EV_CASE_STR(SDL_AUDIODEVICEREMOVED);
93 #if SDL_VERSION_ATLEAST(2, 0, 9)
94  EV_CASE_STR(SDL_SENSORUPDATE);
95 #endif
96  EV_CASE_STR(SDL_RENDER_TARGETS_RESET);
97  EV_CASE_STR(SDL_RENDER_DEVICE_RESET);
98  EV_CASE_STR(SDL_USEREVENT);
99 
100  EV_CASE_STR(SDL_USEREVENT_CERT_DIALOG);
101  EV_CASE_STR(SDL_USEREVENT_CERT_RESULT);
102  EV_CASE_STR(SDL_USEREVENT_SHOW_DIALOG);
103  EV_CASE_STR(SDL_USEREVENT_SHOW_RESULT);
104  EV_CASE_STR(SDL_USEREVENT_AUTH_DIALOG);
105  EV_CASE_STR(SDL_USEREVENT_AUTH_RESULT);
106  EV_CASE_STR(SDL_USEREVENT_SCARD_DIALOG);
107  EV_CASE_STR(SDL_USEREVENT_RETRY_DIALOG);
108  EV_CASE_STR(SDL_USEREVENT_SCARD_RESULT);
109  EV_CASE_STR(SDL_USEREVENT_UPDATE);
110  EV_CASE_STR(SDL_USEREVENT_CREATE_WINDOWS);
111  EV_CASE_STR(SDL_USEREVENT_WINDOW_RESIZEABLE);
112  EV_CASE_STR(SDL_USEREVENT_WINDOW_FULLSCREEN);
113  EV_CASE_STR(SDL_USEREVENT_WINDOW_MINIMIZE);
114  EV_CASE_STR(SDL_USEREVENT_POINTER_NULL);
115  EV_CASE_STR(SDL_USEREVENT_POINTER_DEFAULT);
116  EV_CASE_STR(SDL_USEREVENT_POINTER_POSITION);
117  EV_CASE_STR(SDL_USEREVENT_POINTER_SET);
118  EV_CASE_STR(SDL_USEREVENT_QUIT);
119 
120  EV_CASE_STR(SDL_LASTEVENT);
121  default:
122  return "SDL_UNKNOWNEVENT";
123  }
124 #undef EV_CASE_STR
125 #undef STR
126 }
127 
128 const char* sdl_error_string(Uint32 res)
129 {
130  if (res == 0)
131  return nullptr;
132 
133  return SDL_GetError();
134 }
135 
136 BOOL sdl_log_error_ex(Uint32 res, wLog* log, const char* what, const char* file, size_t line,
137  const char* fkt)
138 {
139  const char* msg = sdl_error_string(res);
140 
141  WINPR_UNUSED(file);
142 
143  if (!msg)
144  return FALSE;
145 
146  WLog_Print(log, WLOG_ERROR, "[%s:%" PRIuz "][%s]: %s", fkt, line, what, msg);
147  return TRUE;
148 }
149 
150 BOOL sdl_push_user_event(Uint32 type, ...)
151 {
152  SDL_Event ev = {};
153  SDL_UserEvent* event = &ev.user;
154 
155  va_list ap = {};
156  va_start(ap, type);
157  event->type = type;
158  switch (type)
159  {
160  case SDL_USEREVENT_AUTH_RESULT:
161  {
162  auto arg = reinterpret_cast<SDL_UserAuthArg*>(ev.padding);
163  arg->user = va_arg(ap, char*);
164  arg->domain = va_arg(ap, char*);
165  arg->password = va_arg(ap, char*);
166  arg->result = va_arg(ap, Sint32);
167  }
168  break;
169  case SDL_USEREVENT_AUTH_DIALOG:
170  {
171  auto arg = reinterpret_cast<SDL_UserAuthArg*>(ev.padding);
172 
173  arg->title = va_arg(ap, char*);
174  arg->user = va_arg(ap, char*);
175  arg->domain = va_arg(ap, char*);
176  arg->password = va_arg(ap, char*);
177  arg->result = va_arg(ap, Sint32);
178  }
179  break;
180  case SDL_USEREVENT_SCARD_DIALOG:
181  {
182  event->data1 = va_arg(ap, char*);
183  event->data2 = va_arg(ap, char**);
184  event->code = va_arg(ap, Sint32);
185  }
186  break;
187  case SDL_USEREVENT_RETRY_DIALOG:
188  break;
189  case SDL_USEREVENT_SCARD_RESULT:
190  case SDL_USEREVENT_SHOW_RESULT:
191  case SDL_USEREVENT_CERT_RESULT:
192  event->code = va_arg(ap, Sint32);
193  break;
194 
195  case SDL_USEREVENT_SHOW_DIALOG:
196  event->data1 = va_arg(ap, char*);
197  event->data2 = va_arg(ap, char*);
198  event->code = va_arg(ap, Sint32);
199  break;
200  case SDL_USEREVENT_CERT_DIALOG:
201  event->data1 = va_arg(ap, char*);
202  event->data2 = va_arg(ap, char*);
203  break;
204  case SDL_USEREVENT_UPDATE:
205  event->data1 = va_arg(ap, void*);
206  break;
207  case SDL_USEREVENT_POINTER_POSITION:
208  event->data1 = reinterpret_cast<void*>(static_cast<uintptr_t>(va_arg(ap, UINT32)));
209  event->data2 = reinterpret_cast<void*>(static_cast<uintptr_t>(va_arg(ap, UINT32)));
210  break;
211  case SDL_USEREVENT_POINTER_SET:
212  event->data1 = va_arg(ap, void*);
213  event->data2 = va_arg(ap, void*);
214  break;
215  case SDL_USEREVENT_CREATE_WINDOWS:
216  event->data1 = va_arg(ap, void*);
217  break;
218  case SDL_USEREVENT_WINDOW_FULLSCREEN:
219  case SDL_USEREVENT_WINDOW_RESIZEABLE:
220  event->data1 = va_arg(ap, void*);
221  event->code = va_arg(ap, int);
222  break;
223  case SDL_USEREVENT_WINDOW_MINIMIZE:
224  case SDL_USEREVENT_QUIT:
225  case SDL_USEREVENT_POINTER_NULL:
226  case SDL_USEREVENT_POINTER_DEFAULT:
227  break;
228  default:
229  va_end(ap);
230  return FALSE;
231  }
232  va_end(ap);
233  return SDL_PushEvent(&ev) == 1;
234 }
235 
236 CriticalSection::CriticalSection()
237 {
238  InitializeCriticalSection(&_section);
239 }
240 
241 CriticalSection::~CriticalSection()
242 {
243  DeleteCriticalSection(&_section);
244 }
245 
246 void CriticalSection::lock()
247 {
248  EnterCriticalSection(&_section);
249 }
250 
251 void CriticalSection::unlock()
252 {
253  LeaveCriticalSection(&_section);
254 }
255 
256 WinPREvent::WinPREvent(bool initial)
257  : _handle(CreateEventA(nullptr, TRUE, initial ? TRUE : FALSE, nullptr))
258 {
259 }
260 
261 WinPREvent::~WinPREvent()
262 {
263  (void)CloseHandle(_handle);
264 }
265 
266 void WinPREvent::set()
267 {
268  (void)SetEvent(_handle);
269 }
270 
271 void WinPREvent::clear()
272 {
273  (void)ResetEvent(_handle);
274 }
275 
276 bool WinPREvent::isSet() const
277 {
278  return WaitForSingleObject(_handle, 0) == WAIT_OBJECT_0;
279 }
280 
281 HANDLE WinPREvent::handle() const
282 {
283  return _handle;
284 }
285 
286 bool sdl_push_quit()
287 {
288  SDL_Event ev = {};
289  ev.type = SDL_QUIT;
290  SDL_PushEvent(&ev);
291  return true;
292 }
293 
294 std::string sdl_window_event_str(Uint8 ev)
295 {
296  switch (ev)
297  {
298  case SDL_WINDOWEVENT_NONE:
299  return "SDL_WINDOWEVENT_NONE";
300  case SDL_WINDOWEVENT_SHOWN:
301  return "SDL_WINDOWEVENT_SHOWN";
302  case SDL_WINDOWEVENT_HIDDEN:
303  return "SDL_WINDOWEVENT_HIDDEN";
304  case SDL_WINDOWEVENT_EXPOSED:
305  return "SDL_WINDOWEVENT_EXPOSED";
306  case SDL_WINDOWEVENT_MOVED:
307  return "SDL_WINDOWEVENT_MOVED";
308  case SDL_WINDOWEVENT_RESIZED:
309  return "SDL_WINDOWEVENT_RESIZED";
310  case SDL_WINDOWEVENT_SIZE_CHANGED:
311  return "SDL_WINDOWEVENT_SIZE_CHANGED";
312  case SDL_WINDOWEVENT_MINIMIZED:
313  return "SDL_WINDOWEVENT_MINIMIZED";
314  case SDL_WINDOWEVENT_MAXIMIZED:
315  return "SDL_WINDOWEVENT_MAXIMIZED";
316  case SDL_WINDOWEVENT_RESTORED:
317  return "SDL_WINDOWEVENT_RESTORED";
318  case SDL_WINDOWEVENT_ENTER:
319  return "SDL_WINDOWEVENT_ENTER";
320  case SDL_WINDOWEVENT_LEAVE:
321  return "SDL_WINDOWEVENT_LEAVE";
322  case SDL_WINDOWEVENT_FOCUS_GAINED:
323  return "SDL_WINDOWEVENT_FOCUS_GAINED";
324  case SDL_WINDOWEVENT_FOCUS_LOST:
325  return "SDL_WINDOWEVENT_FOCUS_LOST";
326  case SDL_WINDOWEVENT_CLOSE:
327  return "SDL_WINDOWEVENT_CLOSE";
328 #if SDL_VERSION_ATLEAST(2, 0, 5)
329  case SDL_WINDOWEVENT_TAKE_FOCUS:
330  return "SDL_WINDOWEVENT_TAKE_FOCUS";
331  case SDL_WINDOWEVENT_HIT_TEST:
332  return "SDL_WINDOWEVENT_HIT_TEST";
333 #endif
334 #if SDL_VERSION_ATLEAST(2, 0, 18)
335  case SDL_WINDOWEVENT_ICCPROF_CHANGED:
336  return "SDL_WINDOWEVENT_ICCPROF_CHANGED";
337  case SDL_WINDOWEVENT_DISPLAY_CHANGED:
338  return "SDL_WINDOWEVENT_DISPLAY_CHANGED";
339 #endif
340  default:
341  return "SDL_WINDOWEVENT_UNKNOWN";
342  }
343 }