FreeRDP
Loading...
Searching...
No Matches
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#include <freerdp/utils/string.h>
33
34#define STR(x) #x
35#define EV_CASE_STR(x) \
36 case x: \
37 return STR(x)
38
39const char* sdl_error_string(Sint32 res)
40{
41 if (res == 0)
42 return nullptr;
43
44 return SDL_GetError();
45}
46
47BOOL sdl_log_error_ex(Sint32 res, wLog* log, const char* what, const char* file, size_t line,
48 const char* fkt)
49{
50 const char* msg = sdl_error_string(res);
51
52 WINPR_UNUSED(file);
53
54 if (!msg)
55 return FALSE;
56
57 WLog_Print(log, WLOG_ERROR, "[%s:%" PRIuz "][%s]: %s", fkt, line, what, msg);
58 return TRUE;
59}
60
61[[nodiscard]] static Uint32 SDLCALL sdl_push_update_cb(WINPR_ATTR_UNUSED void* userdata,
62 WINPR_ATTR_UNUSED SDL_TimerID timerID,
63 WINPR_ATTR_UNUSED Uint32 interval)
64{
65 if (!sdl_push_user_event(SDL_EVENT_USER_UPDATE))
66 WLog_WARN(CLIENT_TAG("sdl.utils"), "sdl_push_user_event failed");
67 return 0;
68}
69
70bool sdl_push_update_after(Uint32 ms)
71{
72 return SDL_AddTimer(ms, sdl_push_update_cb, nullptr) != 0;
73}
74
75bool sdl_push_user_event(Uint32 type, ...)
76{
77 SDL_Event ev = {};
78 SDL_UserEvent* event = &ev.user;
79
80 va_list ap = {};
81 va_start(ap, type);
82 event->type = type;
83 switch (type)
84 {
85 case SDL_EVENT_USER_AUTH_RESULT:
86 {
87 auto arg = reinterpret_cast<SDL_UserAuthArg*>(ev.padding);
88 arg->user = va_arg(ap, char*);
89 arg->domain = va_arg(ap, char*);
90 arg->password = va_arg(ap, char*);
91 arg->result = va_arg(ap, Sint32);
92 }
93 break;
94 case SDL_EVENT_USER_AUTH_DIALOG:
95 {
96 auto arg = reinterpret_cast<SDL_UserAuthArg*>(ev.padding);
97
98 arg->title = va_arg(ap, char*);
99 arg->user = va_arg(ap, char*);
100 arg->domain = va_arg(ap, char*);
101 arg->password = va_arg(ap, char*);
102 arg->result = va_arg(ap, Sint32);
103 }
104 break;
105 case SDL_EVENT_USER_SCARD_DIALOG:
106 {
107 event->data1 = va_arg(ap, char*);
108 event->data2 = va_arg(ap, char**);
109 event->code = va_arg(ap, Sint32);
110 }
111 break;
112 case SDL_EVENT_USER_RETRY_DIALOG:
113 event->code = va_arg(ap, Sint32);
114 break;
115 case SDL_EVENT_USER_SCARD_RESULT:
116 case SDL_EVENT_USER_SHOW_RESULT:
117 case SDL_EVENT_USER_CERT_RESULT:
118 event->code = va_arg(ap, Sint32);
119 break;
120
121 case SDL_EVENT_USER_SHOW_DIALOG:
122 event->data1 = va_arg(ap, char*);
123 event->data2 = va_arg(ap, char*);
124 event->code = va_arg(ap, Sint32);
125 break;
126 case SDL_EVENT_USER_CERT_DIALOG:
127 event->data1 = va_arg(ap, char*);
128 event->data2 = va_arg(ap, char*);
129 break;
130 case SDL_EVENT_USER_UPDATE:
131 event->data1 = va_arg(ap, void*);
132 break;
133 case SDL_EVENT_USER_POINTER_POSITION:
134 event->data1 = reinterpret_cast<void*>(static_cast<uintptr_t>(va_arg(ap, UINT32)));
135 event->data2 = reinterpret_cast<void*>(static_cast<uintptr_t>(va_arg(ap, UINT32)));
136 break;
137 case SDL_EVENT_USER_POINTER_SET:
138 event->data1 = va_arg(ap, void*);
139 event->data2 = va_arg(ap, void*);
140 break;
141 case SDL_EVENT_USER_CREATE_WINDOWS:
142 event->data1 = va_arg(ap, void*);
143 break;
144 case SDL_EVENT_USER_WINDOW_FULLSCREEN:
145 event->data1 = va_arg(ap, void*);
146 event->code = va_arg(ap, int);
147 event->data2 = reinterpret_cast<void*>(static_cast<uintptr_t>(va_arg(ap, int)));
148 break;
149 case SDL_EVENT_USER_WINDOW_RESIZEABLE:
150 event->data1 = va_arg(ap, void*);
151 event->code = va_arg(ap, int);
152 break;
153 case SDL_EVENT_USER_RAIL_MOVE:
154 event->data1 = reinterpret_cast<void*>(static_cast<uintptr_t>(va_arg(ap, UINT32)));
155 event->code = va_arg(ap, int); /* RAIL_WMSZ_* move/resize type */
156 break;
157 case SDL_EVENT_USER_WINDOW_MINIMIZE:
158 case SDL_EVENT_USER_QUIT:
159 case SDL_EVENT_USER_POINTER_NULL:
160 case SDL_EVENT_USER_POINTER_DEFAULT:
161 case SDL_EVENT_CLIPBOARD_UPDATE:
162 break;
163 default:
164 va_end(ap);
165 SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "[%s] unsupported type %u", __func__, type);
166 return false;
167 }
168 va_end(ap);
169 const auto rc = SDL_PushEvent(&ev);
170 if (rc != 1)
171 SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "[%s] SDL_PushEvent returned %d", __func__, rc);
172 return rc == 1;
173}
174
175bool sdl_push_quit()
176{
177 SDL_Event ev = {};
178 ev.type = SDL_EVENT_QUIT;
179 SDL_PushEvent(&ev);
180 return true;
181}
182
183namespace sdl::utils
184{
185 UINT32 orientaion_to_rdp(SDL_DisplayOrientation orientation)
186 {
187 switch (orientation)
188 {
189 case SDL_ORIENTATION_LANDSCAPE:
190 return ORIENTATION_LANDSCAPE;
191 case SDL_ORIENTATION_LANDSCAPE_FLIPPED:
192 return ORIENTATION_LANDSCAPE_FLIPPED;
193 case SDL_ORIENTATION_PORTRAIT_FLIPPED:
194 return ORIENTATION_PORTRAIT_FLIPPED;
195 case SDL_ORIENTATION_PORTRAIT:
196 default:
197 return ORIENTATION_PORTRAIT;
198 }
199 }
200
201 std::string touchFlagsToString(Uint32 flags)
202 {
203 std::stringstream ss;
204 ss << "{";
205 bool first = true;
206 for (size_t x = 0; x < 32; x++)
207 {
208 const Uint32 mask = 1u << x;
209 if (flags & mask)
210 {
211 if (!first)
212 ss << "|";
213 first = false;
214 ss << freerdp_input_touch_state_string(mask);
215 }
216 }
217 ss << "}";
218 return ss.str();
219 }
220
221 std::string toString(SDL_DisplayOrientation orientation)
222 {
223 switch (orientation)
224 {
225 case SDL_ORIENTATION_LANDSCAPE:
226 return "SDL_ORIENTATION_LANDSCAPE";
227 case SDL_ORIENTATION_LANDSCAPE_FLIPPED:
228 return "SDL_ORIENTATION_LANDSCAPE_FLIPPED";
229 case SDL_ORIENTATION_PORTRAIT_FLIPPED:
230 return "SDL_ORIENTATION_PORTRAIT_FLIPPED";
231 case SDL_ORIENTATION_PORTRAIT:
232 return "SDL_ORIENTATION_PORTRAIT";
233 default:
234 {
235 std::stringstream ss;
236 ss << "SDL_ORIENTATION_UNKNOWN[0x" << std::hex << std::setw(8) << std::setfill('0')
237 << orientation << "]";
238 return ss.str();
239 }
240 }
241 }
242
243 std::string toString(FreeRDP_DesktopRotationFlags orientation)
244 {
245 return freerdp_desktop_rotation_flags_to_string(orientation);
246 }
247
248 std::string toString(const SDL_DisplayMode* mode)
249 {
250 if (!mode)
251 return "SDL_DisplayMode=null";
252
253 std::stringstream ss;
254
255 ss << "["
256 << "id=" << mode->displayID << ","
257 << "fmt=" << mode->format << ","
258 << "w=" << mode->w << ","
259 << "h=" << mode->h << ","
260 << "dpi=" << mode->pixel_density << ","
261 << "refresh=" << mode->refresh_rate << ","
262 << "num=" << mode->refresh_rate_numerator << ","
263 << "denom=" << mode->refresh_rate_denominator << "]";
264
265 return ss.str();
266 }
267
268 std::string toString(Uint32 type)
269 {
270 switch (type)
271 {
272 EV_CASE_STR(SDL_EVENT_FIRST);
273 EV_CASE_STR(SDL_EVENT_QUIT);
274 EV_CASE_STR(SDL_EVENT_TERMINATING);
275 EV_CASE_STR(SDL_EVENT_LOW_MEMORY);
276 EV_CASE_STR(SDL_EVENT_WILL_ENTER_BACKGROUND);
277 EV_CASE_STR(SDL_EVENT_DID_ENTER_BACKGROUND);
278 EV_CASE_STR(SDL_EVENT_WILL_ENTER_FOREGROUND);
279 EV_CASE_STR(SDL_EVENT_DID_ENTER_FOREGROUND);
280 EV_CASE_STR(SDL_EVENT_LOCALE_CHANGED);
281 EV_CASE_STR(SDL_EVENT_SYSTEM_THEME_CHANGED);
282 EV_CASE_STR(SDL_EVENT_DISPLAY_ORIENTATION);
283 EV_CASE_STR(SDL_EVENT_DISPLAY_ADDED);
284 EV_CASE_STR(SDL_EVENT_DISPLAY_REMOVED);
285 EV_CASE_STR(SDL_EVENT_DISPLAY_MOVED);
286 EV_CASE_STR(SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED);
287#if SDL_VERSION_ATLEAST(3, 4, 0)
288 EV_CASE_STR(SDL_EVENT_DISPLAY_USABLE_BOUNDS_CHANGED);
289 EV_CASE_STR(SDL_EVENT_SCREEN_KEYBOARD_SHOWN);
290 EV_CASE_STR(SDL_EVENT_SCREEN_KEYBOARD_HIDDEN);
291 EV_CASE_STR(SDL_EVENT_PINCH_BEGIN);
292 EV_CASE_STR(SDL_EVENT_PINCH_UPDATE);
293 EV_CASE_STR(SDL_EVENT_PINCH_END);
294#endif
295#if SDL_VERSION_ATLEAST(3, 4, 20)
296 EV_CASE_STR(SDL_EVENT_WINDOW_SETTINGS_CHANGED);
297 EV_CASE_STR(SDL_EVENT_GAMEPAD_CAPSENSE_TOUCH);
298 EV_CASE_STR(SDL_EVENT_GAMEPAD_CAPSENSE_RELEASE);
299 EV_CASE_STR(SDL_EVENT_NOTIFICATION_ACTION_INVOKED);
300#endif
301 EV_CASE_STR(SDL_EVENT_WINDOW_SHOWN);
302 EV_CASE_STR(SDL_EVENT_WINDOW_HIDDEN);
303 EV_CASE_STR(SDL_EVENT_WINDOW_EXPOSED);
304 EV_CASE_STR(SDL_EVENT_WINDOW_MOVED);
305 EV_CASE_STR(SDL_EVENT_WINDOW_RESIZED);
306 EV_CASE_STR(SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED);
307 EV_CASE_STR(SDL_EVENT_WINDOW_MINIMIZED);
308 EV_CASE_STR(SDL_EVENT_WINDOW_MAXIMIZED);
309 EV_CASE_STR(SDL_EVENT_WINDOW_RESTORED);
310 EV_CASE_STR(SDL_EVENT_WINDOW_MOUSE_ENTER);
311 EV_CASE_STR(SDL_EVENT_WINDOW_MOUSE_LEAVE);
312 EV_CASE_STR(SDL_EVENT_WINDOW_FOCUS_GAINED);
313 EV_CASE_STR(SDL_EVENT_WINDOW_FOCUS_LOST);
314 EV_CASE_STR(SDL_EVENT_WINDOW_CLOSE_REQUESTED);
315 EV_CASE_STR(SDL_EVENT_WINDOW_HIT_TEST);
316 EV_CASE_STR(SDL_EVENT_WINDOW_ICCPROF_CHANGED);
317 EV_CASE_STR(SDL_EVENT_WINDOW_DISPLAY_CHANGED);
318 EV_CASE_STR(SDL_EVENT_WINDOW_SAFE_AREA_CHANGED);
319 EV_CASE_STR(SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED);
320 EV_CASE_STR(SDL_EVENT_WINDOW_OCCLUDED);
321 EV_CASE_STR(SDL_EVENT_WINDOW_ENTER_FULLSCREEN);
322 EV_CASE_STR(SDL_EVENT_WINDOW_LEAVE_FULLSCREEN);
323 EV_CASE_STR(SDL_EVENT_WINDOW_DESTROYED);
324
325 EV_CASE_STR(SDL_EVENT_KEY_DOWN);
326 EV_CASE_STR(SDL_EVENT_KEY_UP);
327 EV_CASE_STR(SDL_EVENT_TEXT_EDITING);
328 EV_CASE_STR(SDL_EVENT_TEXT_INPUT);
329 EV_CASE_STR(SDL_EVENT_KEYMAP_CHANGED);
330 EV_CASE_STR(SDL_EVENT_KEYBOARD_ADDED);
331 EV_CASE_STR(SDL_EVENT_KEYBOARD_REMOVED);
332
333 EV_CASE_STR(SDL_EVENT_MOUSE_MOTION);
334 EV_CASE_STR(SDL_EVENT_MOUSE_BUTTON_DOWN);
335 EV_CASE_STR(SDL_EVENT_MOUSE_BUTTON_UP);
336 EV_CASE_STR(SDL_EVENT_MOUSE_WHEEL);
337 EV_CASE_STR(SDL_EVENT_MOUSE_ADDED);
338 EV_CASE_STR(SDL_EVENT_MOUSE_REMOVED);
339
340 EV_CASE_STR(SDL_EVENT_JOYSTICK_AXIS_MOTION);
341 EV_CASE_STR(SDL_EVENT_JOYSTICK_BALL_MOTION);
342 EV_CASE_STR(SDL_EVENT_JOYSTICK_HAT_MOTION);
343 EV_CASE_STR(SDL_EVENT_JOYSTICK_BUTTON_DOWN);
344 EV_CASE_STR(SDL_EVENT_JOYSTICK_BUTTON_UP);
345 EV_CASE_STR(SDL_EVENT_JOYSTICK_ADDED);
346 EV_CASE_STR(SDL_EVENT_JOYSTICK_REMOVED);
347 EV_CASE_STR(SDL_EVENT_JOYSTICK_BATTERY_UPDATED);
348 EV_CASE_STR(SDL_EVENT_JOYSTICK_UPDATE_COMPLETE);
349
350 EV_CASE_STR(SDL_EVENT_GAMEPAD_AXIS_MOTION);
351 EV_CASE_STR(SDL_EVENT_GAMEPAD_BUTTON_DOWN);
352 EV_CASE_STR(SDL_EVENT_GAMEPAD_BUTTON_UP);
353 EV_CASE_STR(SDL_EVENT_GAMEPAD_ADDED);
354 EV_CASE_STR(SDL_EVENT_GAMEPAD_REMOVED);
355 EV_CASE_STR(SDL_EVENT_GAMEPAD_REMAPPED);
356 EV_CASE_STR(SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN);
357 EV_CASE_STR(SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION);
358 EV_CASE_STR(SDL_EVENT_GAMEPAD_TOUCHPAD_UP);
359 EV_CASE_STR(SDL_EVENT_GAMEPAD_SENSOR_UPDATE);
360 EV_CASE_STR(SDL_EVENT_GAMEPAD_UPDATE_COMPLETE);
361 EV_CASE_STR(SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED);
362
363 EV_CASE_STR(SDL_EVENT_FINGER_DOWN);
364 EV_CASE_STR(SDL_EVENT_FINGER_UP);
365 EV_CASE_STR(SDL_EVENT_FINGER_MOTION);
366
367 EV_CASE_STR(SDL_EVENT_CLIPBOARD_UPDATE);
368
369 EV_CASE_STR(SDL_EVENT_DROP_FILE);
370 EV_CASE_STR(SDL_EVENT_DROP_TEXT);
371 EV_CASE_STR(SDL_EVENT_DROP_BEGIN);
372 EV_CASE_STR(SDL_EVENT_DROP_COMPLETE);
373 EV_CASE_STR(SDL_EVENT_DROP_POSITION);
374
375 EV_CASE_STR(SDL_EVENT_AUDIO_DEVICE_ADDED);
376 EV_CASE_STR(SDL_EVENT_AUDIO_DEVICE_REMOVED);
377 EV_CASE_STR(SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED);
378
379 EV_CASE_STR(SDL_EVENT_SENSOR_UPDATE);
380
381 EV_CASE_STR(SDL_EVENT_PEN_DOWN);
382 EV_CASE_STR(SDL_EVENT_PEN_UP);
383 EV_CASE_STR(SDL_EVENT_PEN_MOTION);
384 EV_CASE_STR(SDL_EVENT_PEN_BUTTON_DOWN);
385 EV_CASE_STR(SDL_EVENT_PEN_BUTTON_UP);
386 EV_CASE_STR(SDL_EVENT_CAMERA_DEVICE_ADDED);
387 EV_CASE_STR(SDL_EVENT_CAMERA_DEVICE_REMOVED);
388 EV_CASE_STR(SDL_EVENT_CAMERA_DEVICE_APPROVED);
389 EV_CASE_STR(SDL_EVENT_CAMERA_DEVICE_DENIED);
390
391 EV_CASE_STR(SDL_EVENT_RENDER_TARGETS_RESET);
392 EV_CASE_STR(SDL_EVENT_RENDER_DEVICE_RESET);
393 EV_CASE_STR(SDL_EVENT_POLL_SENTINEL);
394
395 EV_CASE_STR(SDL_EVENT_USER);
396
397 EV_CASE_STR(SDL_EVENT_USER_CERT_DIALOG);
398 EV_CASE_STR(SDL_EVENT_USER_CERT_RESULT);
399 EV_CASE_STR(SDL_EVENT_USER_SHOW_DIALOG);
400 EV_CASE_STR(SDL_EVENT_USER_SHOW_RESULT);
401 EV_CASE_STR(SDL_EVENT_USER_AUTH_DIALOG);
402 EV_CASE_STR(SDL_EVENT_USER_AUTH_RESULT);
403 EV_CASE_STR(SDL_EVENT_USER_SCARD_DIALOG);
404 EV_CASE_STR(SDL_EVENT_USER_RETRY_DIALOG);
405 EV_CASE_STR(SDL_EVENT_USER_SCARD_RESULT);
406 EV_CASE_STR(SDL_EVENT_USER_UPDATE);
407 EV_CASE_STR(SDL_EVENT_USER_CREATE_WINDOWS);
408 EV_CASE_STR(SDL_EVENT_USER_WINDOW_RESIZEABLE);
409 EV_CASE_STR(SDL_EVENT_USER_WINDOW_FULLSCREEN);
410 EV_CASE_STR(SDL_EVENT_USER_WINDOW_MINIMIZE);
411 EV_CASE_STR(SDL_EVENT_USER_POINTER_NULL);
412 EV_CASE_STR(SDL_EVENT_USER_POINTER_DEFAULT);
413 EV_CASE_STR(SDL_EVENT_USER_POINTER_POSITION);
414 EV_CASE_STR(SDL_EVENT_USER_POINTER_SET);
415 EV_CASE_STR(SDL_EVENT_USER_RAIL_MOVE);
416 EV_CASE_STR(SDL_EVENT_USER_QUIT);
417
418 EV_CASE_STR(SDL_EVENT_LAST);
419 default:
420 {
421 std::stringstream ss;
422 ss << "SDL_UNKNOWNEVENT[0x" << std::hex << std::setw(8) << std::setfill('0') << type
423 << "]";
424 return ss.str();
425 }
426 }
427 }
428
429 std::string generate_uuid_v4()
430 {
431 static std::random_device rd;
432 static std::mt19937 gen(rd());
433 static std::uniform_int_distribution<> dis(0, 255);
434 std::stringstream ss;
435 ss << std::hex << std::setfill('0') << std::setw(2);
436 for (int i = 0; i < 4; i++)
437 {
438 ss << dis(gen);
439 }
440 ss << "-";
441 for (int i = 0; i < 2; i++)
442 {
443 ss << dis(gen);
444 }
445 ss << "-";
446 for (int i = 0; i < 2; i++)
447 {
448 ss << dis(gen);
449 }
450 ss << "-";
451 for (int i = 0; i < 2; i++)
452 {
453 ss << dis(gen);
454 }
455 ss << "-";
456 for (int i = 0; i < 6; i++)
457 {
458 ss << dis(gen);
459 }
460 return ss.str();
461 }
462
463 HighDpiScaleMode platformScaleMode()
464 {
465 const auto platform = SDL_GetPlatform();
466 if (!platform)
467 return SCALE_MODE_INVALID;
468 if (strcmp("Windows", platform) == 0)
469 return SCALE_MODE_X11;
470 if (strcmp("macOS", platform) == 0)
471 return SCALE_MODE_WAYLAND;
472 if (strcmp("Linux", platform) == 0)
473 {
474 const auto driver = SDL_GetCurrentVideoDriver();
475 if (!driver)
476 return SCALE_MODE_WAYLAND;
477 if (strcmp("x11", driver) == 0)
478 return SCALE_MODE_X11;
479 if (strcmp("wayland", driver) == 0)
480 return SCALE_MODE_WAYLAND;
481 }
482 return SCALE_MODE_INVALID;
483 }
484
485 static bool isVideoDriver(const char* name)
486 {
487 const auto driver = SDL_GetCurrentVideoDriver();
488 return driver && name && (strcmp(driver, name) == 0);
489 }
490
491 bool isWaylandDriver()
492 {
493 return isVideoDriver("wayland");
494 }
495
496 bool isX11Driver()
497 {
498 return isVideoDriver("x11");
499 }
500
501 bool isWindowsDriver()
502 {
503 return isVideoDriver("windows");
504 }
505
506 std::string windowTitle(const rdpSettings* settings)
507 {
508 const char* prefix = "FreeRDP:";
509
510 if (!settings)
511 return {};
512
513 const auto windowTitle = freerdp_settings_get_string(settings, FreeRDP_WindowTitle);
514 if (windowTitle)
515 return {};
516
517 const auto name = freerdp_settings_get_server_name(settings);
518 const auto port = freerdp_settings_get_uint32(settings, FreeRDP_ServerPort);
519
520 const auto addPort = (port != 3389);
521
522 std::stringstream ss;
523 ss << prefix << " ";
524 if (!addPort)
525 ss << name;
526 else
527 ss << name << ":" << port;
528
529 return ss.str();
530 }
531
532 std::string toString(SDL_Rect rect)
533 {
534 std::stringstream ss;
535 ss << "SDL_Rect{" << rect.x << "x" << rect.y << "-" << rect.w << "x" << rect.h << "}";
536 return ss.str();
537 }
538
539 std::string toString(SDL_FRect rect)
540 {
541 std::stringstream ss;
542 ss << "SDL_Rect{" << rect.x << "x" << rect.y << "-" << rect.w << "x" << rect.h << "}";
543 return ss.str();
544 }
545
546} // namespace sdl::utils
547
548namespace sdl::error
549{
550 struct sdl_exitCode_map_t
551 {
552 DWORD error;
553 int code;
554 const char* code_tag;
555 };
556
557#define ENTRY(x, y) { x, y, #y }
558 static const struct sdl_exitCode_map_t sdl_exitCode_map[] = {
559 ENTRY(FREERDP_ERROR_SUCCESS, SUCCESS), ENTRY(FREERDP_ERROR_NONE, DISCONNECT),
560 ENTRY(FREERDP_ERROR_NONE, LOGOFF), ENTRY(FREERDP_ERROR_NONE, IDLE_TIMEOUT),
561 ENTRY(FREERDP_ERROR_NONE, LOGON_TIMEOUT), ENTRY(FREERDP_ERROR_NONE, CONN_REPLACED),
562 ENTRY(FREERDP_ERROR_NONE, OUT_OF_MEMORY), ENTRY(FREERDP_ERROR_NONE, CONN_DENIED),
563 ENTRY(FREERDP_ERROR_NONE, CONN_DENIED_FIPS), ENTRY(FREERDP_ERROR_NONE, USER_PRIVILEGES),
564 ENTRY(FREERDP_ERROR_NONE, FRESH_CREDENTIALS_REQUIRED),
565 ENTRY(ERRINFO_LOGOFF_BY_USER, DISCONNECT_BY_USER), ENTRY(FREERDP_ERROR_NONE, UNKNOWN),
566
567 /* section 16-31: license error set */
568 ENTRY(FREERDP_ERROR_NONE, LICENSE_INTERNAL),
569 ENTRY(FREERDP_ERROR_NONE, LICENSE_NO_LICENSE_SERVER),
570 ENTRY(FREERDP_ERROR_NONE, LICENSE_NO_LICENSE),
571 ENTRY(FREERDP_ERROR_NONE, LICENSE_BAD_CLIENT_MSG),
572 ENTRY(FREERDP_ERROR_NONE, LICENSE_HWID_DOESNT_MATCH),
573 ENTRY(FREERDP_ERROR_NONE, LICENSE_BAD_CLIENT),
574 ENTRY(FREERDP_ERROR_NONE, LICENSE_CANT_FINISH_PROTOCOL),
575 ENTRY(FREERDP_ERROR_NONE, LICENSE_CLIENT_ENDED_PROTOCOL),
576 ENTRY(FREERDP_ERROR_NONE, LICENSE_BAD_CLIENT_ENCRYPTION),
577 ENTRY(FREERDP_ERROR_NONE, LICENSE_CANT_UPGRADE),
578 ENTRY(FREERDP_ERROR_NONE, LICENSE_NO_REMOTE_CONNECTIONS),
579 ENTRY(FREERDP_ERROR_NONE, LICENSE_CANT_UPGRADE),
580
581 /* section 32-127: RDP protocol error set */
582 ENTRY(FREERDP_ERROR_NONE, RDP),
583
584 /* section 128-254: xfreerdp specific exit codes */
585 ENTRY(FREERDP_ERROR_NONE, PARSE_ARGUMENTS), ENTRY(FREERDP_ERROR_NONE, MEMORY),
586 ENTRY(FREERDP_ERROR_NONE, PROTOCOL), ENTRY(FREERDP_ERROR_NONE, CONN_FAILED),
587
588 ENTRY(FREERDP_ERROR_AUTHENTICATION_FAILED, AUTH_FAILURE),
589 ENTRY(FREERDP_ERROR_SECURITY_NEGO_CONNECT_FAILED, NEGO_FAILURE),
590 ENTRY(FREERDP_ERROR_CONNECT_LOGON_FAILURE, LOGON_FAILURE),
591 ENTRY(FREERDP_ERROR_CONNECT_TARGET_BOOTING, CONNECT_TARGET_BOOTING),
592 ENTRY(FREERDP_ERROR_CONNECT_HYBRID_REQUIRED_BY_SERVER, CONNECT_HYBRID_REQUIRED_BY_SERVER),
593 ENTRY(FREERDP_ERROR_CONNECT_ACCOUNT_LOCKED_OUT, ACCOUNT_LOCKED_OUT),
594 ENTRY(FREERDP_ERROR_PRE_CONNECT_FAILED, PRE_CONNECT_FAILED),
595 ENTRY(FREERDP_ERROR_CONNECT_UNDEFINED, CONNECT_UNDEFINED),
596 ENTRY(FREERDP_ERROR_POST_CONNECT_FAILED, POST_CONNECT_FAILED),
597 ENTRY(FREERDP_ERROR_DNS_ERROR, DNS_ERROR),
598 ENTRY(FREERDP_ERROR_DNS_NAME_NOT_FOUND, DNS_NAME_NOT_FOUND),
599 ENTRY(FREERDP_ERROR_CONNECT_FAILED, CONNECT_FAILED),
600 ENTRY(FREERDP_ERROR_MCS_CONNECT_INITIAL_ERROR, MCS_CONNECT_INITIAL_ERROR),
601 ENTRY(FREERDP_ERROR_TLS_CONNECT_FAILED, TLS_CONNECT_FAILED),
602 ENTRY(FREERDP_ERROR_INSUFFICIENT_PRIVILEGES, INSUFFICIENT_PRIVILEGES),
603 ENTRY(FREERDP_ERROR_CONNECT_CANCELLED, CONNECT_CANCELLED),
604 ENTRY(FREERDP_ERROR_CONNECT_TRANSPORT_FAILED, CONNECT_TRANSPORT_FAILED),
605 ENTRY(FREERDP_ERROR_CONNECT_PASSWORD_EXPIRED, CONNECT_PASSWORD_EXPIRED),
606 ENTRY(FREERDP_ERROR_CONNECT_PASSWORD_MUST_CHANGE, CONNECT_PASSWORD_MUST_CHANGE),
607 ENTRY(FREERDP_ERROR_CONNECT_KDC_UNREACHABLE, CONNECT_KDC_UNREACHABLE),
608 ENTRY(FREERDP_ERROR_CONNECT_ACCOUNT_DISABLED, CONNECT_ACCOUNT_DISABLED),
609 ENTRY(FREERDP_ERROR_CONNECT_PASSWORD_CERTAINLY_EXPIRED, CONNECT_PASSWORD_CERTAINLY_EXPIRED),
610 ENTRY(FREERDP_ERROR_CONNECT_CLIENT_REVOKED, CONNECT_CLIENT_REVOKED),
611 ENTRY(FREERDP_ERROR_CONNECT_WRONG_PASSWORD, CONNECT_WRONG_PASSWORD),
612 ENTRY(FREERDP_ERROR_CONNECT_ACCESS_DENIED, CONNECT_ACCESS_DENIED),
613 ENTRY(FREERDP_ERROR_CONNECT_ACCOUNT_RESTRICTION, CONNECT_ACCOUNT_RESTRICTION),
614 ENTRY(FREERDP_ERROR_CONNECT_ACCOUNT_EXPIRED, CONNECT_ACCOUNT_EXPIRED),
615 ENTRY(FREERDP_ERROR_CONNECT_LOGON_TYPE_NOT_GRANTED, CONNECT_LOGON_TYPE_NOT_GRANTED),
616 ENTRY(FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS, CONNECT_NO_OR_MISSING_CREDENTIALS)
617 };
618
619 static const sdl_exitCode_map_t* mapEntryByCode(int exit_code)
620 {
621 for (const auto& x : sdl_exitCode_map)
622 {
623 auto cur = &x;
624 if (cur->code == exit_code)
625 return cur;
626 }
627 return nullptr;
628 }
629
630 static const sdl_exitCode_map_t* mapEntryByError(UINT32 error)
631 {
632 for (const auto& x : sdl_exitCode_map)
633 {
634 auto cur = &x;
635 if (cur->error == error)
636 return cur;
637 }
638 return nullptr;
639 }
640
641 int errorToExitCode(DWORD error)
642 {
643 auto entry = mapEntryByError(error);
644 if (entry)
645 return entry->code;
646
647 return CONN_FAILED;
648 }
649
650 const char* errorToExitCodeTag(UINT32 error)
651 {
652 auto entry = mapEntryByError(error);
653 if (entry)
654 return entry->code_tag;
655 return nullptr;
656 }
657
658 const char* exitCodeToTag(int code)
659 {
660 auto entry = mapEntryByCode(code);
661 if (entry)
662 return entry->code_tag;
663 return nullptr;
664 }
665} // namespace sdl::error
WINPR_ATTR_NODISCARD FREERDP_API const char * freerdp_settings_get_server_name(const rdpSettings *settings)
A helper function to return the correct server name.
WINPR_ATTR_NODISCARD FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.