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