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