FreeRDP
SDL3/sdl_utils.cpp
1 
20 #include <cassert>
21 #include "sdl_utils.hpp"
22 
23 #include "sdl_freerdp.hpp"
24 
25 #include <SDL3/SDL.h>
26 
27 #include <freerdp/version.h>
28 
29 #define STR(x) #x
30 #define EV_CASE_STR(x) \
31  case x: \
32  return STR(x)
33 
34 const char* sdl_event_type_str(Uint32 type)
35 {
36  switch (type)
37  {
38  EV_CASE_STR(SDL_EVENT_FIRST);
39  EV_CASE_STR(SDL_EVENT_QUIT);
40  EV_CASE_STR(SDL_EVENT_TERMINATING);
41  EV_CASE_STR(SDL_EVENT_LOW_MEMORY);
42  EV_CASE_STR(SDL_EVENT_WILL_ENTER_BACKGROUND);
43  EV_CASE_STR(SDL_EVENT_DID_ENTER_BACKGROUND);
44  EV_CASE_STR(SDL_EVENT_WILL_ENTER_FOREGROUND);
45  EV_CASE_STR(SDL_EVENT_DID_ENTER_FOREGROUND);
46  EV_CASE_STR(SDL_EVENT_LOCALE_CHANGED);
47  EV_CASE_STR(SDL_EVENT_SYSTEM_THEME_CHANGED);
48  EV_CASE_STR(SDL_EVENT_DISPLAY_ORIENTATION);
49  EV_CASE_STR(SDL_EVENT_DISPLAY_ADDED);
50  EV_CASE_STR(SDL_EVENT_DISPLAY_REMOVED);
51  EV_CASE_STR(SDL_EVENT_DISPLAY_MOVED);
52  EV_CASE_STR(SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED);
53  EV_CASE_STR(SDL_EVENT_WINDOW_SHOWN);
54  EV_CASE_STR(SDL_EVENT_WINDOW_HIDDEN);
55  EV_CASE_STR(SDL_EVENT_WINDOW_EXPOSED);
56  EV_CASE_STR(SDL_EVENT_WINDOW_MOVED);
57  EV_CASE_STR(SDL_EVENT_WINDOW_RESIZED);
58  EV_CASE_STR(SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED);
59  EV_CASE_STR(SDL_EVENT_WINDOW_MINIMIZED);
60  EV_CASE_STR(SDL_EVENT_WINDOW_MAXIMIZED);
61  EV_CASE_STR(SDL_EVENT_WINDOW_RESTORED);
62  EV_CASE_STR(SDL_EVENT_WINDOW_MOUSE_ENTER);
63  EV_CASE_STR(SDL_EVENT_WINDOW_MOUSE_LEAVE);
64  EV_CASE_STR(SDL_EVENT_WINDOW_FOCUS_GAINED);
65  EV_CASE_STR(SDL_EVENT_WINDOW_FOCUS_LOST);
66  EV_CASE_STR(SDL_EVENT_WINDOW_CLOSE_REQUESTED);
67  EV_CASE_STR(SDL_EVENT_WINDOW_HIT_TEST);
68  EV_CASE_STR(SDL_EVENT_WINDOW_ICCPROF_CHANGED);
69  EV_CASE_STR(SDL_EVENT_WINDOW_DISPLAY_CHANGED);
70  EV_CASE_STR(SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED);
71  EV_CASE_STR(SDL_EVENT_WINDOW_OCCLUDED);
72  EV_CASE_STR(SDL_EVENT_WINDOW_ENTER_FULLSCREEN);
73  EV_CASE_STR(SDL_EVENT_WINDOW_LEAVE_FULLSCREEN);
74  EV_CASE_STR(SDL_EVENT_WINDOW_DESTROYED);
75 
76  EV_CASE_STR(SDL_EVENT_KEY_DOWN);
77  EV_CASE_STR(SDL_EVENT_KEY_UP);
78  EV_CASE_STR(SDL_EVENT_TEXT_EDITING);
79  EV_CASE_STR(SDL_EVENT_TEXT_INPUT);
80  EV_CASE_STR(SDL_EVENT_KEYMAP_CHANGED);
81  EV_CASE_STR(SDL_EVENT_KEYBOARD_ADDED);
82  EV_CASE_STR(SDL_EVENT_KEYBOARD_REMOVED);
83 
84  EV_CASE_STR(SDL_EVENT_MOUSE_MOTION);
85  EV_CASE_STR(SDL_EVENT_MOUSE_BUTTON_DOWN);
86  EV_CASE_STR(SDL_EVENT_MOUSE_BUTTON_UP);
87  EV_CASE_STR(SDL_EVENT_MOUSE_WHEEL);
88  EV_CASE_STR(SDL_EVENT_MOUSE_ADDED);
89  EV_CASE_STR(SDL_EVENT_MOUSE_REMOVED);
90 
91  EV_CASE_STR(SDL_EVENT_JOYSTICK_AXIS_MOTION);
92  EV_CASE_STR(SDL_EVENT_JOYSTICK_BALL_MOTION);
93  EV_CASE_STR(SDL_EVENT_JOYSTICK_HAT_MOTION);
94  EV_CASE_STR(SDL_EVENT_JOYSTICK_BUTTON_DOWN);
95  EV_CASE_STR(SDL_EVENT_JOYSTICK_BUTTON_UP);
96  EV_CASE_STR(SDL_EVENT_JOYSTICK_ADDED);
97  EV_CASE_STR(SDL_EVENT_JOYSTICK_REMOVED);
98  EV_CASE_STR(SDL_EVENT_JOYSTICK_BATTERY_UPDATED);
99  EV_CASE_STR(SDL_EVENT_JOYSTICK_UPDATE_COMPLETE);
100 
101  EV_CASE_STR(SDL_EVENT_GAMEPAD_AXIS_MOTION);
102  EV_CASE_STR(SDL_EVENT_GAMEPAD_BUTTON_DOWN);
103  EV_CASE_STR(SDL_EVENT_GAMEPAD_BUTTON_UP);
104  EV_CASE_STR(SDL_EVENT_GAMEPAD_ADDED);
105  EV_CASE_STR(SDL_EVENT_GAMEPAD_REMOVED);
106  EV_CASE_STR(SDL_EVENT_GAMEPAD_REMAPPED);
107  EV_CASE_STR(SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN);
108  EV_CASE_STR(SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION);
109  EV_CASE_STR(SDL_EVENT_GAMEPAD_TOUCHPAD_UP);
110  EV_CASE_STR(SDL_EVENT_GAMEPAD_SENSOR_UPDATE);
111  EV_CASE_STR(SDL_EVENT_GAMEPAD_UPDATE_COMPLETE);
112  EV_CASE_STR(SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED);
113 
114  EV_CASE_STR(SDL_EVENT_FINGER_DOWN);
115  EV_CASE_STR(SDL_EVENT_FINGER_UP);
116  EV_CASE_STR(SDL_EVENT_FINGER_MOTION);
117 
118  EV_CASE_STR(SDL_EVENT_CLIPBOARD_UPDATE);
119 
120  EV_CASE_STR(SDL_EVENT_DROP_FILE);
121  EV_CASE_STR(SDL_EVENT_DROP_TEXT);
122  EV_CASE_STR(SDL_EVENT_DROP_BEGIN);
123  EV_CASE_STR(SDL_EVENT_DROP_COMPLETE);
124  EV_CASE_STR(SDL_EVENT_DROP_POSITION);
125 
126  EV_CASE_STR(SDL_EVENT_AUDIO_DEVICE_ADDED);
127  EV_CASE_STR(SDL_EVENT_AUDIO_DEVICE_REMOVED);
128  EV_CASE_STR(SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED);
129 
130  EV_CASE_STR(SDL_EVENT_SENSOR_UPDATE);
131 
132  EV_CASE_STR(SDL_EVENT_PEN_DOWN);
133  EV_CASE_STR(SDL_EVENT_PEN_UP);
134  EV_CASE_STR(SDL_EVENT_PEN_MOTION);
135  EV_CASE_STR(SDL_EVENT_PEN_BUTTON_DOWN);
136  EV_CASE_STR(SDL_EVENT_PEN_BUTTON_UP);
137  EV_CASE_STR(SDL_EVENT_CAMERA_DEVICE_ADDED);
138  EV_CASE_STR(SDL_EVENT_CAMERA_DEVICE_REMOVED);
139  EV_CASE_STR(SDL_EVENT_CAMERA_DEVICE_APPROVED);
140  EV_CASE_STR(SDL_EVENT_CAMERA_DEVICE_DENIED);
141 
142  EV_CASE_STR(SDL_EVENT_RENDER_TARGETS_RESET);
143  EV_CASE_STR(SDL_EVENT_RENDER_DEVICE_RESET);
144  EV_CASE_STR(SDL_EVENT_POLL_SENTINEL);
145 
146  EV_CASE_STR(SDL_EVENT_USER);
147 
148  EV_CASE_STR(SDL_EVENT_USER_CERT_DIALOG);
149  EV_CASE_STR(SDL_EVENT_USER_CERT_RESULT);
150  EV_CASE_STR(SDL_EVENT_USER_SHOW_DIALOG);
151  EV_CASE_STR(SDL_EVENT_USER_SHOW_RESULT);
152  EV_CASE_STR(SDL_EVENT_USER_AUTH_DIALOG);
153  EV_CASE_STR(SDL_EVENT_USER_AUTH_RESULT);
154  EV_CASE_STR(SDL_EVENT_USER_SCARD_DIALOG);
155  EV_CASE_STR(SDL_EVENT_USER_RETRY_DIALOG);
156  EV_CASE_STR(SDL_EVENT_USER_SCARD_RESULT);
157  EV_CASE_STR(SDL_EVENT_USER_UPDATE);
158  EV_CASE_STR(SDL_EVENT_USER_CREATE_WINDOWS);
159  EV_CASE_STR(SDL_EVENT_USER_WINDOW_RESIZEABLE);
160  EV_CASE_STR(SDL_EVENT_USER_WINDOW_FULLSCREEN);
161  EV_CASE_STR(SDL_EVENT_USER_WINDOW_MINIMIZE);
162  EV_CASE_STR(SDL_EVENT_USER_POINTER_NULL);
163  EV_CASE_STR(SDL_EVENT_USER_POINTER_DEFAULT);
164  EV_CASE_STR(SDL_EVENT_USER_POINTER_POSITION);
165  EV_CASE_STR(SDL_EVENT_USER_POINTER_SET);
166  EV_CASE_STR(SDL_EVENT_USER_QUIT);
167 
168  EV_CASE_STR(SDL_EVENT_LAST);
169  default:
170  return "SDL_UNKNOWNEVENT";
171  }
172 }
173 
174 const char* sdl_error_string(Uint32 res)
175 {
176  if (res == 0)
177  return nullptr;
178 
179  return SDL_GetError();
180 }
181 
182 BOOL sdl_log_error_ex(Uint32 res, wLog* log, const char* what, const char* file, size_t line,
183  const char* fkt)
184 {
185  const char* msg = sdl_error_string(res);
186 
187  WINPR_UNUSED(file);
188 
189  if (!msg)
190  return FALSE;
191 
192  WLog_Print(log, WLOG_ERROR, "[%s:%" PRIuz "][%s]: %s", fkt, line, what, msg);
193  return TRUE;
194 }
195 
196 BOOL sdl_push_user_event(Uint32 type, ...)
197 {
198  SDL_Event ev = {};
199  SDL_UserEvent* event = &ev.user;
200 
201  va_list ap = {};
202  va_start(ap, type);
203  event->type = type;
204  switch (type)
205  {
206  case SDL_EVENT_USER_AUTH_RESULT:
207  {
208  auto arg = reinterpret_cast<SDL_UserAuthArg*>(ev.padding);
209  arg->user = va_arg(ap, char*);
210  arg->domain = va_arg(ap, char*);
211  arg->password = va_arg(ap, char*);
212  arg->result = va_arg(ap, Sint32);
213  }
214  break;
215  case SDL_EVENT_USER_AUTH_DIALOG:
216  {
217  auto arg = reinterpret_cast<SDL_UserAuthArg*>(ev.padding);
218 
219  arg->title = va_arg(ap, char*);
220  arg->user = va_arg(ap, char*);
221  arg->domain = va_arg(ap, char*);
222  arg->password = va_arg(ap, char*);
223  arg->result = va_arg(ap, Sint32);
224  }
225  break;
226  case SDL_EVENT_USER_SCARD_DIALOG:
227  {
228  event->data1 = va_arg(ap, char*);
229  event->data2 = va_arg(ap, char**);
230  event->code = va_arg(ap, Sint32);
231  }
232  break;
233  case SDL_EVENT_USER_RETRY_DIALOG:
234  break;
235  case SDL_EVENT_USER_SCARD_RESULT:
236  case SDL_EVENT_USER_SHOW_RESULT:
237  case SDL_EVENT_USER_CERT_RESULT:
238  event->code = va_arg(ap, Sint32);
239  break;
240 
241  case SDL_EVENT_USER_SHOW_DIALOG:
242  event->data1 = va_arg(ap, char*);
243  event->data2 = va_arg(ap, char*);
244  event->code = va_arg(ap, Sint32);
245  break;
246  case SDL_EVENT_USER_CERT_DIALOG:
247  event->data1 = va_arg(ap, char*);
248  event->data2 = va_arg(ap, char*);
249  break;
250  case SDL_EVENT_USER_UPDATE:
251  event->data1 = va_arg(ap, void*);
252  break;
253  case SDL_EVENT_USER_POINTER_POSITION:
254  event->data1 = reinterpret_cast<void*>(static_cast<uintptr_t>(va_arg(ap, UINT32)));
255  event->data2 = reinterpret_cast<void*>(static_cast<uintptr_t>(va_arg(ap, UINT32)));
256  break;
257  case SDL_EVENT_USER_POINTER_SET:
258  event->data1 = va_arg(ap, void*);
259  event->data2 = va_arg(ap, void*);
260  break;
261  case SDL_EVENT_USER_CREATE_WINDOWS:
262  event->data1 = va_arg(ap, void*);
263  break;
264  case SDL_EVENT_USER_WINDOW_FULLSCREEN:
265  case SDL_EVENT_USER_WINDOW_RESIZEABLE:
266  event->data1 = va_arg(ap, void*);
267  event->code = va_arg(ap, int);
268  break;
269  case SDL_EVENT_USER_WINDOW_MINIMIZE:
270  case SDL_EVENT_USER_QUIT:
271  case SDL_EVENT_USER_POINTER_NULL:
272  case SDL_EVENT_USER_POINTER_DEFAULT:
273  break;
274  default:
275  va_end(ap);
276  return FALSE;
277  }
278  va_end(ap);
279  return SDL_PushEvent(&ev) == 1;
280 }
281 
282 CriticalSection::CriticalSection()
283 {
284  InitializeCriticalSection(&_section);
285 }
286 
287 CriticalSection::~CriticalSection()
288 {
289  DeleteCriticalSection(&_section);
290 }
291 
292 void CriticalSection::lock()
293 {
294  EnterCriticalSection(&_section);
295 }
296 
297 void CriticalSection::unlock()
298 {
299  LeaveCriticalSection(&_section);
300 }
301 
302 WinPREvent::WinPREvent(bool initial)
303  : _handle(CreateEventA(nullptr, TRUE, initial ? TRUE : FALSE, nullptr))
304 {
305 }
306 
307 WinPREvent::~WinPREvent()
308 {
309  (void)CloseHandle(_handle);
310 }
311 
312 void WinPREvent::set()
313 {
314  (void)SetEvent(_handle);
315 }
316 
317 void WinPREvent::clear()
318 {
319  (void)ResetEvent(_handle);
320 }
321 
322 bool WinPREvent::isSet() const
323 {
324  return WaitForSingleObject(_handle, 0) == WAIT_OBJECT_0;
325 }
326 
327 HANDLE WinPREvent::handle() const
328 {
329  return _handle;
330 }
331 
332 bool sdl_push_quit()
333 {
334  SDL_Event ev = {};
335  ev.type = SDL_EVENT_QUIT;
336  SDL_PushEvent(&ev);
337  return true;
338 }
339 
340 std::string sdl_window_event_str(Uint32 ev)
341 {
342  if ((ev >= SDL_EVENT_WINDOW_FIRST) && (ev <= SDL_EVENT_WINDOW_LAST))
343  return sdl_event_type_str(ev);
344 
345  return "SDL_EVENT_WINDOW_UNKNOWN";
346 }