FreeRDP
Loading...
Searching...
No Matches
xf_reconnect.c
1
18#include <freerdp/config.h>
19#include <freerdp/client.h>
20#include "xf_reconnect.h"
21#include "xf_utils.h"
22
23static void xf_reconnect_draw(xfContext* xfc)
24{
25 WINPR_ASSERT(xfc);
26 LogDynAndXFlush(xfc->log, xfc->display);
27 const int screen = DefaultScreen(xfc->display);
28 GC gc = LogDynAndXCreateGC(xfc->log, xfc->display, xfc->reconnectWindow, 0, nullptr);
29 if (!gc)
30 return;
31 LogDynAndXSetForeground(xfc->log, xfc->display, gc, BlackPixel(xfc->display, screen));
32 XFontStruct* font = XLoadQueryFont(xfc->display, "10x20");
33 if (font)
34 XSetFont(xfc->display, gc, font->fid);
35 LogDynAndXClearWindow(xfc->log, xfc->display, xfc->reconnectWindow);
36 XDrawString(xfc->display, xfc->reconnectWindow, gc, 16, 30, xfc->reconnectMessage,
37 (int)strlen(xfc->reconnectMessage));
38 const char cancel[] = "Close this window to cancel.";
39 XDrawString(xfc->display, xfc->reconnectWindow, gc, 16, 60, cancel, sizeof(cancel) - 1);
40 if (font)
41 XFreeFont(xfc->display, font);
42 LogDynAndXFreeGC(xfc->log, xfc->display, gc);
43 LogDynAndXFlush(xfc->log, xfc->display);
44}
45
46SSIZE_T xf_retry_dialog(freerdp* instance, const char* what, size_t current, void* userarg)
47{
48 WINPR_ASSERT(instance);
49 const SSIZE_T delay = client_common_retry_dialog(instance, what, current, userarg);
50 xfContext* xfc = (xfContext*)instance->context;
51 WINPR_ASSERT(xfc);
52 if ((delay < 0) || !xfc->display || strcmp(what, "connection") != 0)
53 return delay;
54
55 xf_lock_x11(xfc);
56 if (!xfc->reconnectWindow)
57 {
58 const int screen = DefaultScreen(xfc->display);
59 xfc->reconnectWindow =
60 XCreateSimpleWindow(xfc->display, DefaultRootWindow(xfc->display), 0, 0, 420, 90, 1,
61 BlackPixel(xfc->display, screen), WhitePixel(xfc->display, screen));
62 XStoreName(xfc->display, xfc->reconnectWindow, "FreeRDP - Reconnecting");
63 LogDynAndXSelectInput(xfc->log, xfc->display, xfc->reconnectWindow, ExposureMask);
64 XSetWMProtocols(xfc->display, xfc->reconnectWindow, &xfc->WM_DELETE_WINDOW, 1);
65 XMapRaised(xfc->display, xfc->reconnectWindow);
66 }
67 const UINT32 max =
68 freerdp_settings_get_uint32(instance->context->settings, FreeRDP_AutoReconnectMaxRetries);
69 if (max)
70 (void)snprintf(xfc->reconnectMessage, sizeof(xfc->reconnectMessage),
71 "Reconnecting: attempt %zu of %" PRIu32, current + 1, max);
72 else
73 (void)snprintf(xfc->reconnectMessage, sizeof(xfc->reconnectMessage),
74 "Reconnecting: attempt %zu", current + 1);
75 xf_reconnect_draw(xfc);
76 xf_unlock_x11(xfc);
77 return delay;
78}
79
80BOOL xf_reconnect_event(xfContext* xfc, const XEvent* event)
81{
82 WINPR_ASSERT(xfc);
83 WINPR_ASSERT(event);
84
85 if (!xfc->reconnectWindow || (event->xany.window != xfc->reconnectWindow))
86 return TRUE;
87
88 if (event->type == Expose)
89 xf_reconnect_draw(xfc);
90 else if (event->type == ClientMessage && event->xclient.format == 32 &&
91 event->xclient.message_type == xfc->WM_PROTOCOLS &&
92 (Atom)event->xclient.data.l[0] == xfc->WM_DELETE_WINDOW)
93 {
94 return FALSE;
95 }
96 return TRUE;
97}
98
99void xf_reconnect_close(xfContext* xfc)
100{
101 WINPR_ASSERT(xfc);
102 if (xfc->display && xfc->reconnectWindow)
103 {
104 xf_lock_x11(xfc);
105 LogDynAndXDestroyWindow(xfc->log, xfc->display, xfc->reconnectWindow);
106 xfc->reconnectWindow = 0;
107 LogDynAndXFlush(xfc->log, xfc->display);
108 xf_unlock_x11(xfc);
109 }
110}
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.