mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
Merge pull request #10390 from akallabeth/sdl_reconnect
[client,SDL] fix autoreconnect
This commit is contained in:
@@ -214,8 +214,11 @@ SSIZE_T sdl_retry_dialog(freerdp* instance, const char* what, size_t current, vo
|
||||
WINPR_ASSERT(what);
|
||||
|
||||
auto sdl = get_context(instance->context);
|
||||
auto settings = instance->context->settings;
|
||||
const size_t delay = freerdp_settings_get_uint32(settings, FreeRDP_TcpConnectTimeout);
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
WINPR_ASSERT(sdl->connection_dialog);
|
||||
if (!sdl->connection_dialog)
|
||||
return delay;
|
||||
|
||||
sdl->connection_dialog->setTitle("Retry connection to %s",
|
||||
freerdp_settings_get_server_name(instance->context->settings));
|
||||
@@ -233,7 +236,6 @@ SSIZE_T sdl_retry_dialog(freerdp* instance, const char* what, size_t current, vo
|
||||
what);
|
||||
}
|
||||
|
||||
auto settings = instance->context->settings;
|
||||
const BOOL enabled = freerdp_settings_get_bool(settings, FreeRDP_AutoReconnectionEnabled);
|
||||
|
||||
if (!enabled)
|
||||
@@ -244,7 +246,7 @@ SSIZE_T sdl_retry_dialog(freerdp* instance, const char* what, size_t current, vo
|
||||
}
|
||||
|
||||
const size_t max = freerdp_settings_get_uint32(settings, FreeRDP_AutoReconnectMaxRetries);
|
||||
const size_t delay = freerdp_settings_get_uint32(settings, FreeRDP_TcpConnectTimeout);
|
||||
|
||||
if (current >= max)
|
||||
{
|
||||
sdl->connection_dialog->showError(
|
||||
|
||||
@@ -337,7 +337,10 @@ BOOL sdlDispContext::handle_display_event(const SDL_DisplayEvent* ev)
|
||||
BOOL sdlDispContext::handle_window_event(const SDL_WindowEvent* ev)
|
||||
{
|
||||
WINPR_ASSERT(ev);
|
||||
|
||||
#if defined(WITH_DEBUG_SDL_EVENTS)
|
||||
SDL_Log("got windowEvent %s [0x%08" PRIx32 "]", sdl_window_event_str(ev->event).c_str(),
|
||||
ev->event);
|
||||
#endif
|
||||
auto bordered = freerdp_settings_get_bool(_sdl->context()->settings, FreeRDP_Decorations)
|
||||
? SDL_TRUE
|
||||
: SDL_FALSE;
|
||||
@@ -351,7 +354,6 @@ BOOL sdlDispContext::handle_window_event(const SDL_WindowEvent* ev)
|
||||
case SDL_WINDOWEVENT_HIDDEN:
|
||||
case SDL_WINDOWEVENT_MINIMIZED:
|
||||
gdi_send_suppress_output(_sdl->context()->gdi, TRUE);
|
||||
|
||||
return TRUE;
|
||||
|
||||
case SDL_WINDOWEVENT_EXPOSED:
|
||||
|
||||
@@ -220,6 +220,14 @@ static const struct sdl_exit_code_map_t* sdl_map_entry_by_code(int exit_code)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void sdl_hide_connection_dialog(SdlContext* sdl)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
if (sdl->connection_dialog)
|
||||
sdl->connection_dialog->hide();
|
||||
}
|
||||
|
||||
static const struct sdl_exit_code_map_t* sdl_map_entry_by_error(DWORD error)
|
||||
{
|
||||
for (size_t x = 0; x < ARRAYSIZE(sdl_exit_code_map); x++)
|
||||
@@ -781,6 +789,8 @@ static bool shall_abort(SdlContext* sdl)
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
if (freerdp_shall_disconnect_context(sdl->context()))
|
||||
{
|
||||
if (sdl->rdp_thread_running)
|
||||
return false;
|
||||
if (!sdl->connection_dialog)
|
||||
return true;
|
||||
return !sdl->connection_dialog->running();
|
||||
@@ -914,14 +924,14 @@ static int sdl_run(SdlContext* sdl)
|
||||
case SDL_WINDOWEVENT:
|
||||
{
|
||||
const SDL_WindowEvent* ev = &windowEvent.window;
|
||||
sdl->disp.handle_window_event(ev);
|
||||
|
||||
auto window = sdl->windows.find(ev->windowID);
|
||||
if (window != sdl->windows.end())
|
||||
sdl->disp.handle_window_event(ev);
|
||||
switch (ev->event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
{
|
||||
auto window = sdl->windows.find(ev->windowID);
|
||||
if (window != sdl->windows.end())
|
||||
{
|
||||
window->second.fill();
|
||||
@@ -931,7 +941,6 @@ static int sdl_run(SdlContext* sdl)
|
||||
break;
|
||||
case SDL_WINDOWEVENT_MOVED:
|
||||
{
|
||||
auto window = sdl->windows.find(ev->windowID);
|
||||
if (window != sdl->windows.end())
|
||||
{
|
||||
auto r = window->second.rect();
|
||||
@@ -1071,11 +1080,7 @@ static BOOL sdl_post_connect(freerdp* instance)
|
||||
auto sdl = get_context(context);
|
||||
|
||||
// Retry was successful, discard dialog
|
||||
{
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
if (sdl->connection_dialog)
|
||||
sdl->connection_dialog->hide();
|
||||
}
|
||||
sdl_hide_connection_dialog(sdl);
|
||||
|
||||
if (freerdp_settings_get_bool(context->settings, FreeRDP_AuthenticationOnly))
|
||||
{
|
||||
@@ -1165,6 +1170,7 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
auto instance = sdl->context()->instance;
|
||||
WINPR_ASSERT(instance);
|
||||
|
||||
sdl->rdp_thread_running = true;
|
||||
BOOL rc = freerdp_connect(instance);
|
||||
|
||||
rdpContext* context = sdl->context();
|
||||
@@ -1200,11 +1206,15 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
freerdp_get_last_error_string(last));
|
||||
}
|
||||
|
||||
if (last == FREERDP_ERROR_AUTHENTICATION_FAILED)
|
||||
exit_code = SDL_EXIT_AUTH_FAILURE;
|
||||
else if (code == ERRINFO_SUCCESS)
|
||||
exit_code = SDL_EXIT_CONN_FAILED;
|
||||
if (exit_code == SDL_EXIT_SUCCESS)
|
||||
{
|
||||
if (last == FREERDP_ERROR_AUTHENTICATION_FAILED)
|
||||
exit_code = SDL_EXIT_AUTH_FAILURE;
|
||||
else if (code == ERRINFO_SUCCESS)
|
||||
exit_code = SDL_EXIT_CONN_FAILED;
|
||||
}
|
||||
|
||||
sdl_hide_connection_dialog(sdl);
|
||||
goto terminate;
|
||||
}
|
||||
|
||||
@@ -1233,12 +1243,19 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
break;
|
||||
}
|
||||
|
||||
status = WaitForMultipleObjects(nCount, handles, FALSE, 100);
|
||||
status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
|
||||
|
||||
if (status == WAIT_FAILED)
|
||||
break;
|
||||
|
||||
if (!freerdp_check_event_handles(context))
|
||||
{
|
||||
if (client_auto_reconnect(instance))
|
||||
{
|
||||
// Retry was successful, discard dialog
|
||||
sdl_hide_connection_dialog(sdl);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
@@ -1252,14 +1269,8 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
if (freerdp_get_last_error(context) == FREERDP_ERROR_SUCCESS)
|
||||
WLog_Print(sdl->log, WLOG_ERROR, "WaitForMultipleObjects failed with %" PRIu32 "",
|
||||
status);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!freerdp_check_event_handles(context))
|
||||
{
|
||||
if (freerdp_get_last_error(context) == FREERDP_ERROR_SUCCESS)
|
||||
WLog_Print(sdl->log, WLOG_ERROR, "Failed to check FreeRDP event handles");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1288,6 +1299,8 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
freerdp_disconnect(instance);
|
||||
|
||||
terminate:
|
||||
sdl->rdp_thread_running = false;
|
||||
bool showError = false;
|
||||
if (freerdp_settings_get_bool(settings, FreeRDP_AuthenticationOnly))
|
||||
WLog_Print(sdl->log, WLOG_INFO, "Authentication only, exit status %s [%" PRId32 "]",
|
||||
sdl_map_to_code_tag(exit_code), exit_code);
|
||||
@@ -1299,17 +1312,24 @@ terminate:
|
||||
case SDL_EXIT_DISCONNECT:
|
||||
case SDL_EXIT_LOGOFF:
|
||||
case SDL_EXIT_DISCONNECT_BY_USER:
|
||||
case SDL_EXIT_CONNECT_CANCELLED:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
if (sdl->connection_dialog && error_msg)
|
||||
{
|
||||
sdl->connection_dialog->showError(error_msg);
|
||||
showError = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(error_msg);
|
||||
if (!showError)
|
||||
sdl_hide_connection_dialog(sdl);
|
||||
|
||||
sdl->exit_code = exit_code;
|
||||
sdl_push_user_event(SDL_USEREVENT_QUIT);
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 16)
|
||||
@@ -1691,7 +1711,8 @@ BOOL SdlContext::update_resizeable(BOOL enable)
|
||||
|
||||
SdlContext::SdlContext(rdpContext* context)
|
||||
: _context(context), log(WLog_Get(SDL_TAG)), update_complete(true), disp(this), input(this),
|
||||
primary(nullptr, SDL_FreeSurface), primary_format(nullptr, SDL_FreeFormat)
|
||||
primary(nullptr, SDL_FreeSurface), primary_format(nullptr, SDL_FreeFormat),
|
||||
rdp_thread_running(false)
|
||||
{
|
||||
WINPR_ASSERT(context);
|
||||
grab_kbd_enabled = freerdp_settings_get_bool(context->settings, FreeRDP_GrabKeyboard);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <map>
|
||||
#include <atomic>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/client/rdpei.h>
|
||||
@@ -80,6 +81,8 @@ class SdlContext
|
||||
|
||||
std::unique_ptr<SDLConnectionDialog> connection_dialog;
|
||||
|
||||
std::atomic<bool> rdp_thread_running;
|
||||
|
||||
public:
|
||||
BOOL update_resizeable(BOOL enable);
|
||||
BOOL update_fullscreen(BOOL enter);
|
||||
|
||||
@@ -214,8 +214,12 @@ SSIZE_T sdl_retry_dialog(freerdp* instance, const char* what, size_t current, vo
|
||||
WINPR_ASSERT(what);
|
||||
|
||||
auto sdl = get_context(instance->context);
|
||||
auto settings = instance->context->settings;
|
||||
const BOOL enabled = freerdp_settings_get_bool(settings, FreeRDP_AutoReconnectionEnabled);
|
||||
const size_t delay = freerdp_settings_get_uint32(settings, FreeRDP_TcpConnectTimeout);
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
WINPR_ASSERT(sdl->connection_dialog);
|
||||
if (!sdl->connection_dialog)
|
||||
return delay;
|
||||
|
||||
sdl->connection_dialog->setTitle("Retry connection to %s",
|
||||
freerdp_settings_get_server_name(instance->context->settings));
|
||||
@@ -233,9 +237,6 @@ SSIZE_T sdl_retry_dialog(freerdp* instance, const char* what, size_t current, vo
|
||||
what);
|
||||
}
|
||||
|
||||
auto settings = instance->context->settings;
|
||||
const BOOL enabled = freerdp_settings_get_bool(settings, FreeRDP_AutoReconnectionEnabled);
|
||||
|
||||
if (!enabled)
|
||||
{
|
||||
sdl->connection_dialog->showError(
|
||||
@@ -244,7 +245,6 @@ SSIZE_T sdl_retry_dialog(freerdp* instance, const char* what, size_t current, vo
|
||||
}
|
||||
|
||||
const size_t max = freerdp_settings_get_uint32(settings, FreeRDP_AutoReconnectMaxRetries);
|
||||
const size_t delay = freerdp_settings_get_uint32(settings, FreeRDP_TcpConnectTimeout);
|
||||
if (current >= max)
|
||||
{
|
||||
sdl->connection_dialog->showError(
|
||||
|
||||
@@ -220,6 +220,14 @@ static const struct sdl_exit_code_map_t* sdl_map_entry_by_code(int exit_code)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void sdl_hide_connection_dialog(SdlContext* sdl)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
if (sdl->connection_dialog)
|
||||
sdl->connection_dialog->hide();
|
||||
}
|
||||
|
||||
static const struct sdl_exit_code_map_t* sdl_map_entry_by_error(DWORD error)
|
||||
{
|
||||
for (size_t x = 0; x < ARRAYSIZE(sdl_exit_code_map); x++)
|
||||
@@ -779,6 +787,8 @@ static bool shall_abort(SdlContext* sdl)
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
if (freerdp_shall_disconnect_context(sdl->context()))
|
||||
{
|
||||
if (sdl->rdp_thread_running)
|
||||
return false;
|
||||
if (!sdl->connection_dialog)
|
||||
return true;
|
||||
return !sdl->connection_dialog->running();
|
||||
@@ -1007,35 +1017,29 @@ static int sdl_run(SdlContext* sdl)
|
||||
(windowEvent.type <= SDL_EVENT_WINDOW_LAST))
|
||||
{
|
||||
const SDL_WindowEvent* ev = &windowEvent.window;
|
||||
sdl->disp.handle_window_event(ev);
|
||||
|
||||
switch (ev->type)
|
||||
auto window = sdl->windows.find(ev->windowID);
|
||||
if (window != sdl->windows.end())
|
||||
{
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
||||
sdl->disp.handle_window_event(ev);
|
||||
|
||||
switch (ev->type)
|
||||
{
|
||||
auto window = sdl->windows.find(ev->windowID);
|
||||
if (window != sdl->windows.end())
|
||||
{
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
||||
window->second.fill();
|
||||
window->second.updateSurface();
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_MOVED:
|
||||
{
|
||||
auto window = sdl->windows.find(ev->windowID);
|
||||
if (window != sdl->windows.end())
|
||||
{
|
||||
auto r = window->second.rect();
|
||||
auto id = window->second.id();
|
||||
WLog_DBG(SDL_TAG, "%lu: %dx%d-%dx%d", id, r.x, r.y, r.w, r.h);
|
||||
}
|
||||
auto r = window->second.rect();
|
||||
auto id = window->second.id();
|
||||
WLog_DBG(SDL_TAG, "%lu: %dx%d-%dx%d", id, r.x, r.y, r.w, r.h);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1066,11 +1070,7 @@ static BOOL sdl_post_connect(freerdp* instance)
|
||||
auto sdl = get_context(context);
|
||||
|
||||
// Retry was successful, discard dialog
|
||||
{
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
if (sdl->connection_dialog)
|
||||
sdl->connection_dialog->hide();
|
||||
}
|
||||
sdl_hide_connection_dialog(sdl);
|
||||
|
||||
if (freerdp_settings_get_bool(context->settings, FreeRDP_AuthenticationOnly))
|
||||
{
|
||||
@@ -1160,6 +1160,7 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
auto instance = sdl->context()->instance;
|
||||
WINPR_ASSERT(instance);
|
||||
|
||||
sdl->rdp_thread_running = true;
|
||||
BOOL rc = freerdp_connect(instance);
|
||||
|
||||
rdpContext* context = sdl->context();
|
||||
@@ -1195,11 +1196,15 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
freerdp_get_last_error_string(last));
|
||||
}
|
||||
|
||||
if (last == FREERDP_ERROR_AUTHENTICATION_FAILED)
|
||||
exit_code = SDL_EXIT_AUTH_FAILURE;
|
||||
else if (code == ERRINFO_SUCCESS)
|
||||
exit_code = SDL_EXIT_CONN_FAILED;
|
||||
if (exit_code == SDL_EXIT_SUCCESS)
|
||||
{
|
||||
if (last == FREERDP_ERROR_AUTHENTICATION_FAILED)
|
||||
exit_code = SDL_EXIT_AUTH_FAILURE;
|
||||
else if (code == ERRINFO_SUCCESS)
|
||||
exit_code = SDL_EXIT_CONN_FAILED;
|
||||
}
|
||||
|
||||
sdl_hide_connection_dialog(sdl);
|
||||
goto terminate;
|
||||
}
|
||||
|
||||
@@ -1228,12 +1233,19 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
break;
|
||||
}
|
||||
|
||||
status = WaitForMultipleObjects(nCount, handles, FALSE, 100);
|
||||
status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
|
||||
|
||||
if (status == WAIT_FAILED)
|
||||
break;
|
||||
|
||||
if (!freerdp_check_event_handles(context))
|
||||
{
|
||||
if (client_auto_reconnect(instance))
|
||||
{
|
||||
// Retry was successful, discard dialog
|
||||
sdl_hide_connection_dialog(sdl);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
@@ -1247,14 +1259,8 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
if (freerdp_get_last_error(context) == FREERDP_ERROR_SUCCESS)
|
||||
WLog_Print(sdl->log, WLOG_ERROR, "WaitForMultipleObjects failed with %" PRIu32 "",
|
||||
status);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!freerdp_check_event_handles(context))
|
||||
{
|
||||
if (freerdp_get_last_error(context) == FREERDP_ERROR_SUCCESS)
|
||||
WLog_Print(sdl->log, WLOG_ERROR, "Failed to check FreeRDP event handles");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1283,6 +1289,8 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
freerdp_disconnect(instance);
|
||||
|
||||
terminate:
|
||||
sdl->rdp_thread_running = false;
|
||||
bool showError = false;
|
||||
if (freerdp_settings_get_bool(settings, FreeRDP_AuthenticationOnly))
|
||||
WLog_Print(sdl->log, WLOG_INFO, "Authentication only, exit status %s [%" PRId32 "]",
|
||||
sdl_map_to_code_tag(exit_code), exit_code);
|
||||
@@ -1294,17 +1302,24 @@ terminate:
|
||||
case SDL_EXIT_DISCONNECT:
|
||||
case SDL_EXIT_LOGOFF:
|
||||
case SDL_EXIT_DISCONNECT_BY_USER:
|
||||
case SDL_EXIT_CONNECT_CANCELLED:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
if (sdl->connection_dialog && error_msg)
|
||||
{
|
||||
sdl->connection_dialog->showError(error_msg);
|
||||
showError = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(error_msg);
|
||||
if (!showError)
|
||||
sdl_hide_connection_dialog(sdl);
|
||||
|
||||
sdl->exit_code = exit_code;
|
||||
sdl_push_user_event(SDL_EVENT_USER_QUIT);
|
||||
SDL_CleanupTLS();
|
||||
@@ -1685,7 +1700,7 @@ BOOL SdlContext::update_resizeable(BOOL enable)
|
||||
SdlContext::SdlContext(rdpContext* context)
|
||||
: _context(context), log(WLog_Get(SDL_TAG)), update_complete(true), disp(this), clip(this),
|
||||
input(this), primary(nullptr, SDL_DestroySurface),
|
||||
primary_format(nullptr, SDL_DestroyPixelFormat)
|
||||
primary_format(nullptr, SDL_DestroyPixelFormat), rdp_thread_running(false)
|
||||
{
|
||||
WINPR_ASSERT(context);
|
||||
grab_kbd_enabled = freerdp_settings_get_bool(context->settings, FreeRDP_GrabKeyboard);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <map>
|
||||
#include <atomic>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/client/rdpei.h>
|
||||
@@ -82,6 +83,8 @@ class SdlContext
|
||||
|
||||
std::unique_ptr<SDLConnectionDialog> connection_dialog;
|
||||
|
||||
std::atomic<bool> rdp_thread_running;
|
||||
|
||||
public:
|
||||
BOOL update_resizeable(BOOL enable);
|
||||
BOOL update_fullscreen(BOOL enter);
|
||||
|
||||
Reference in New Issue
Block a user