mirror of https://github.com/FreeRDP/FreeRDP
[client,sdl] add connection dialog
This commit is contained in:
parent
49936fc529
commit
e1de32f9ab
|
@ -15,6 +15,8 @@ set(SRCS
|
|||
sdl_select.cpp
|
||||
sdl_selectlist.hpp
|
||||
sdl_selectlist.cpp
|
||||
sdl_connection_dialog.cpp
|
||||
sdl_connection_dialog.hpp
|
||||
)
|
||||
|
||||
set(LIBS
|
||||
|
|
|
@ -0,0 +1,363 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* SDL Client helper dialogs
|
||||
*
|
||||
* Copyright 2023 Armin Novak <armin.novak@thincast.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <thread>
|
||||
|
||||
#include "sdl_connection_dialog.hpp"
|
||||
#include "../sdl_utils.hpp"
|
||||
#include "../sdl_freerdp.hpp"
|
||||
|
||||
static const SDL_Color backgroundcolor = { 0x38, 0x36, 0x35, 0xff };
|
||||
static const SDL_Color textcolor = { 0xd1, 0xcf, 0xcd, 0xff };
|
||||
|
||||
static const Uint32 hpadding = 10;
|
||||
static const Uint32 vpadding = 5;
|
||||
|
||||
SDLConnectionDialog::SDLConnectionDialog(rdpContext* context)
|
||||
: _context(context), _window(nullptr), _renderer(nullptr)
|
||||
{
|
||||
hide();
|
||||
}
|
||||
|
||||
SDLConnectionDialog::~SDLConnectionDialog()
|
||||
{
|
||||
resetTimer();
|
||||
destroyWindow();
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::visible() const
|
||||
{
|
||||
return _window && _renderer;
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::setTitle(const char* fmt, ...)
|
||||
{
|
||||
std::lock_guard lock(_mux);
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
_title = print(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return show(MSG_NONE);
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::showInfo(const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
auto rc = show(MSG_INFO, fmt, ap);
|
||||
va_end(ap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::showWarn(const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
auto rc = show(MSG_WARN, fmt, ap);
|
||||
va_end(ap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::showError(const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
auto rc = show(MSG_ERROR, fmt, ap);
|
||||
va_end(ap);
|
||||
return setTimer();
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::hide()
|
||||
{
|
||||
std::lock_guard lock(_mux);
|
||||
return show(MSG_DISCARD);
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::running() const
|
||||
{
|
||||
std::lock_guard lock(_mux);
|
||||
return _running;
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::update()
|
||||
{
|
||||
std::lock_guard lock(_mux);
|
||||
switch (_type)
|
||||
{
|
||||
case MSG_INFO:
|
||||
case MSG_WARN:
|
||||
case MSG_ERROR:
|
||||
createWindow();
|
||||
break;
|
||||
case MSG_DISCARD:
|
||||
resetTimer();
|
||||
destroyWindow();
|
||||
break;
|
||||
default:
|
||||
if (_window)
|
||||
{
|
||||
SDL_SetWindowTitle(_window, _title.c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
_type = MSG_NONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::setModal()
|
||||
{
|
||||
if (_window)
|
||||
{
|
||||
auto sdl = get_context(_context);
|
||||
if (sdl->windows.empty())
|
||||
return true;
|
||||
|
||||
auto parent = sdl->windows.front().window;
|
||||
SDL_SetWindowModalFor(_window, parent);
|
||||
SDL_RaiseWindow(_window);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::clearWindow(SDL_Renderer* renderer)
|
||||
{
|
||||
assert(renderer);
|
||||
|
||||
const int drc = SDL_SetRenderDrawColor(renderer, backgroundcolor.r, backgroundcolor.g,
|
||||
backgroundcolor.b, backgroundcolor.a);
|
||||
if (widget_log_error(drc, "SDL_SetRenderDrawColor"))
|
||||
return false;
|
||||
|
||||
const int rcls = SDL_RenderClear(renderer);
|
||||
return !widget_log_error(rcls, "SDL_RenderClear");
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::update(SDL_Renderer* renderer)
|
||||
{
|
||||
if (!renderer)
|
||||
return false;
|
||||
|
||||
if (!clearWindow(renderer))
|
||||
return false;
|
||||
|
||||
for (auto& btn : _list)
|
||||
{
|
||||
if (!btn.update_text(renderer, _msg, textcolor))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_buttons.update(renderer))
|
||||
return false;
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::wait(bool ignoreRdpContext)
|
||||
{
|
||||
while (running())
|
||||
{
|
||||
if (!ignoreRdpContext)
|
||||
{
|
||||
if (freerdp_shall_disconnect_context(_context))
|
||||
return false;
|
||||
}
|
||||
std::this_thread::yield();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::handle(const SDL_Event& event)
|
||||
{
|
||||
Uint32 windowID = 0;
|
||||
if (_window)
|
||||
{
|
||||
windowID = SDL_GetWindowID(_window);
|
||||
}
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_USEREVENT_RETRY_DIALOG:
|
||||
return update();
|
||||
case SDL_QUIT:
|
||||
resetTimer();
|
||||
destroyWindow();
|
||||
return false;
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
auto ev = reinterpret_cast<const SDL_KeyboardEvent&>(event);
|
||||
update(_renderer);
|
||||
return windowID == ev.windowID;
|
||||
}
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
{
|
||||
auto ev = reinterpret_cast<const SDL_MouseButtonEvent&>(event);
|
||||
update(_renderer);
|
||||
return windowID == ev.windowID;
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
{
|
||||
auto ev = reinterpret_cast<const SDL_MouseWheelEvent&>(event);
|
||||
update(_renderer);
|
||||
return windowID == ev.windowID;
|
||||
}
|
||||
break;
|
||||
case SDL_FINGERUP:
|
||||
case SDL_FINGERDOWN:
|
||||
{
|
||||
auto ev = reinterpret_cast<const SDL_TouchFingerEvent&>(event);
|
||||
update(_renderer);
|
||||
return windowID == ev.windowID;
|
||||
}
|
||||
case SDL_WINDOWEVENT:
|
||||
{
|
||||
auto ev = reinterpret_cast<const SDL_WindowEvent&>(event);
|
||||
switch (ev.event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_CLOSE:
|
||||
if (windowID == ev.windowID)
|
||||
{
|
||||
resetTimer();
|
||||
destroyWindow();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
update(_renderer);
|
||||
setModal();
|
||||
break;
|
||||
}
|
||||
|
||||
return windowID == ev.windowID;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::createWindow()
|
||||
{
|
||||
destroyWindow();
|
||||
|
||||
const size_t widget_height = 50;
|
||||
const size_t widget_width = 600;
|
||||
const size_t total_height = 400;
|
||||
|
||||
_window = SDL_CreateWindow(_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
widget_width, total_height, 0);
|
||||
if (_window == nullptr)
|
||||
{
|
||||
widget_log_error(-1, "SDL_CreateWindow");
|
||||
return false;
|
||||
}
|
||||
setModal();
|
||||
|
||||
_renderer = SDL_CreateRenderer(_window, -1, SDL_RENDERER_ACCELERATED);
|
||||
if (_renderer == nullptr)
|
||||
{
|
||||
widget_log_error(-1, "SDL_CreateRenderer");
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_Rect rect = { 0, 0, widget_width, widget_height };
|
||||
_list.push_back(SdlWidget(_renderer, rect, false));
|
||||
rect.y += widget_height + vpadding;
|
||||
|
||||
const std::vector<int> buttonids = { 1 };
|
||||
const std::vector<std::string> buttonlabels = { "cancel" };
|
||||
_buttons.populate(_renderer, buttonlabels, buttonids, static_cast<Sint32>(total_height),
|
||||
static_cast<Sint32>(widget_width / 2), static_cast<Sint32>(widget_height));
|
||||
|
||||
SDL_ShowWindow(_window);
|
||||
SDL_RaiseWindow(_window);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SDLConnectionDialog::destroyWindow()
|
||||
{
|
||||
_buttons.clear();
|
||||
_list.clear();
|
||||
SDL_DestroyRenderer(_renderer);
|
||||
SDL_DestroyWindow(_window);
|
||||
_renderer = nullptr;
|
||||
_window = nullptr;
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::show(MsgType type, const char* fmt, va_list ap)
|
||||
{
|
||||
std::lock_guard lock(_mux);
|
||||
_msg = print(fmt, ap);
|
||||
return show(type);
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::show(MsgType type)
|
||||
{
|
||||
_type = type;
|
||||
return sdl_push_user_event(SDL_USEREVENT_RETRY_DIALOG);
|
||||
}
|
||||
|
||||
std::string SDLConnectionDialog::print(const char* fmt, va_list ap)
|
||||
{
|
||||
int size = -1;
|
||||
std::string res;
|
||||
|
||||
do
|
||||
{
|
||||
res.resize(128);
|
||||
if (size > 0)
|
||||
res.resize(size);
|
||||
|
||||
va_list copy;
|
||||
va_copy(copy, ap);
|
||||
size = vsnprintf(res.data(), res.size(), fmt, copy);
|
||||
va_end(copy);
|
||||
|
||||
} while ((size > 0) && (size > res.size()));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool SDLConnectionDialog::setTimer(Uint32 timeoutMS)
|
||||
{
|
||||
std::lock_guard lock(_mux);
|
||||
resetTimer();
|
||||
|
||||
_timer = SDL_AddTimer(timeoutMS, &SDLConnectionDialog::timeout, this);
|
||||
_running = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SDLConnectionDialog::resetTimer()
|
||||
{
|
||||
if (_running)
|
||||
SDL_RemoveTimer(_timer);
|
||||
_running = false;
|
||||
}
|
||||
|
||||
Uint32 SDLConnectionDialog::timeout(Uint32 intervalMS, void* pvthis)
|
||||
{
|
||||
auto ths = static_cast<SDLConnectionDialog*>(pvthis);
|
||||
ths->hide();
|
||||
ths->_running = false;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* SDL Client helper dialogs
|
||||
*
|
||||
* Copyright 2023 Armin Novak <armin.novak@thincast.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
|
||||
#include "sdl_widget.hpp"
|
||||
#include "sdl_buttons.hpp"
|
||||
|
||||
class SDLConnectionDialog
|
||||
{
|
||||
public:
|
||||
SDLConnectionDialog(rdpContext* context);
|
||||
virtual ~SDLConnectionDialog();
|
||||
|
||||
bool visible() const;
|
||||
|
||||
bool setTitle(const char* fmt, ...);
|
||||
bool showInfo(const char* fmt, ...);
|
||||
bool showWarn(const char* fmt, ...);
|
||||
bool showError(const char* fmt, ...);
|
||||
bool hide();
|
||||
|
||||
bool running() const;
|
||||
bool wait(bool ignoreRdpContextQuit = false);
|
||||
|
||||
bool handle(const SDL_Event& event);
|
||||
|
||||
private:
|
||||
enum MsgType
|
||||
{
|
||||
MSG_NONE,
|
||||
MSG_INFO,
|
||||
MSG_WARN,
|
||||
MSG_ERROR,
|
||||
MSG_DISCARD
|
||||
};
|
||||
|
||||
private:
|
||||
bool createWindow();
|
||||
void destroyWindow();
|
||||
|
||||
bool update();
|
||||
|
||||
bool setModal();
|
||||
|
||||
bool clearWindow(SDL_Renderer* renderer);
|
||||
|
||||
bool update(SDL_Renderer* renderer);
|
||||
|
||||
bool show(MsgType type, const char* fmt, va_list ap);
|
||||
bool show(MsgType type);
|
||||
|
||||
std::string print(const char* fmt, va_list ap);
|
||||
bool setTimer(Uint32 timeoutMS = 15000);
|
||||
void resetTimer();
|
||||
|
||||
private:
|
||||
static Uint32 timeout(Uint32 intervalMS, void* _this);
|
||||
|
||||
private:
|
||||
rdpContext* _context;
|
||||
SDL_Window* _window;
|
||||
SDL_Renderer* _renderer;
|
||||
mutable std::mutex _mux;
|
||||
std::string _title;
|
||||
std::string _msg;
|
||||
MsgType _type = MSG_NONE;
|
||||
SDL_TimerID _timer = -1;
|
||||
bool _running = false;
|
||||
std::vector<SdlWidget> _list;
|
||||
SdlButtonList _buttons;
|
||||
};
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "../sdl_freerdp.hpp"
|
||||
#include "sdl_dialogs.hpp"
|
||||
#include "sdl_input.hpp"
|
||||
#include "sdl_input_widgets.hpp"
|
||||
|
@ -199,6 +200,63 @@ fail:
|
|||
return res;
|
||||
}
|
||||
|
||||
SSIZE_T sdl_retry_dialog(freerdp* instance, const char* what, size_t current, void* userarg)
|
||||
{
|
||||
WINPR_ASSERT(instance);
|
||||
WINPR_ASSERT(instance->context);
|
||||
WINPR_ASSERT(what);
|
||||
|
||||
auto sdl = get_context(instance->context);
|
||||
WINPR_ASSERT(sdl->connection_dialog);
|
||||
|
||||
sdl->connection_dialog->setTitle("Retry connection to %s",
|
||||
freerdp_settings_get_server_name(instance->context->settings));
|
||||
|
||||
if ((strcmp(what, "arm-transport") != 0) && (strcmp(what, "connection") != 0))
|
||||
{
|
||||
sdl->connection_dialog->showError("Unknown module %s, aborting", what);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (current == 0)
|
||||
{
|
||||
if (strcmp(what, "arm-transport") == 0)
|
||||
sdl->connection_dialog->showWarn("[%s] Starting your VM. It may take up to 5 minutes",
|
||||
what);
|
||||
}
|
||||
|
||||
auto settings = instance->context->settings;
|
||||
const BOOL enabled = freerdp_settings_get_bool(settings, FreeRDP_AutoReconnectionEnabled);
|
||||
|
||||
SDL_Window* window = nullptr;
|
||||
if (!sdl->windows.empty())
|
||||
{
|
||||
window = sdl->windows.begin()->window;
|
||||
}
|
||||
if (!enabled)
|
||||
{
|
||||
sdl->connection_dialog->showError(
|
||||
"Automatic reconnection disabled, terminating. Try to connect again later");
|
||||
return -1;
|
||||
}
|
||||
|
||||
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(
|
||||
"[%s] retries exceeded. Your VM failed to start. Try again later or contact your "
|
||||
"tech support for help if this keeps happening.",
|
||||
what);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sdl->connection_dialog->showInfo("[%s] retry %" PRIuz "/%" PRIuz ", delaying %" PRIuz
|
||||
"ms before next attempt",
|
||||
what, current, max, delay);
|
||||
return delay;
|
||||
}
|
||||
|
||||
BOOL sdl_present_gateway_message(freerdp* instance, UINT32 type, BOOL isDisplayMandatory,
|
||||
BOOL isConsentMandatory, size_t length, const WCHAR* wmessage)
|
||||
{
|
||||
|
|
|
@ -30,6 +30,8 @@ BOOL sdl_authenticate_ex(freerdp* instance, char** username, char** password, ch
|
|||
BOOL sdl_choose_smartcard(freerdp* instance, SmartcardCertInfo** cert_list, DWORD count,
|
||||
DWORD* choice, BOOL gateway);
|
||||
|
||||
SSIZE_T sdl_retry_dialog(freerdp* instance, const char* what, size_t current, void* userarg);
|
||||
|
||||
DWORD sdl_verify_certificate_ex(freerdp* instance, const char* host, UINT16 port,
|
||||
const char* common_name, const char* subject, const char* issuer,
|
||||
const char* fingerprint, DWORD flags);
|
||||
|
|
|
@ -16,8 +16,6 @@ SdlInputWidgetList::SdlInputWidgetList(const std::string& title,
|
|||
const std::vector<int> buttonids = { INPUT_BUTTON_ACCEPT, INPUT_BUTTON_CANCEL };
|
||||
const std::vector<std::string> buttonlabels = { "accept", "cancel" };
|
||||
|
||||
TTF_Init();
|
||||
|
||||
const size_t widget_width = 300;
|
||||
const size_t widget_heigth = 50;
|
||||
|
||||
|
@ -102,8 +100,6 @@ SdlInputWidgetList::~SdlInputWidgetList()
|
|||
_buttons.clear();
|
||||
SDL_DestroyRenderer(_renderer);
|
||||
SDL_DestroyWindow(_window);
|
||||
|
||||
TTF_Quit();
|
||||
}
|
||||
|
||||
bool SdlInputWidgetList::update(SDL_Renderer* renderer)
|
||||
|
|
|
@ -5,8 +5,6 @@ static const Uint32 vpadding = 5;
|
|||
SdlSelectList::SdlSelectList(const std::string& title, const std::vector<std::string>& labels)
|
||||
: _window(nullptr), _renderer(nullptr)
|
||||
{
|
||||
TTF_Init();
|
||||
|
||||
const size_t widget_height = 50;
|
||||
const size_t widget_width = 600;
|
||||
|
||||
|
@ -48,8 +46,6 @@ SdlSelectList::~SdlSelectList()
|
|||
_buttons.clear();
|
||||
SDL_DestroyRenderer(_renderer);
|
||||
SDL_DestroyWindow(_window);
|
||||
|
||||
TTF_Quit();
|
||||
}
|
||||
|
||||
int SdlSelectList::run()
|
||||
|
|
|
@ -598,6 +598,12 @@ static BOOL sdl_pre_connect(freerdp* instance)
|
|||
if (!sdl_wait_for_init(sdl))
|
||||
return FALSE;
|
||||
|
||||
sdl->connection_dialog.reset(new SDLConnectionDialog(instance->context));
|
||||
|
||||
sdl->connection_dialog->setTitle("Connecting to '%s'",
|
||||
freerdp_settings_get_server_name(settings));
|
||||
sdl->connection_dialog->showInfo("Please wait while the connection is being established");
|
||||
|
||||
if (!sdl_detect_monitors(sdl, &maxWidth, &maxHeight))
|
||||
return FALSE;
|
||||
|
||||
|
@ -678,6 +684,7 @@ static void sdl_cleanup_sdl(SdlContext* sdl)
|
|||
sdl_destroy_primary(sdl);
|
||||
|
||||
freerdp_del_signal_cleanup_handler(sdl->context(), sdl_term_handler);
|
||||
TTF_Quit();
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
|
@ -777,6 +784,18 @@ static BOOL sdl_wait_create_windows(SdlContext* sdl)
|
|||
}
|
||||
}
|
||||
|
||||
static bool shall_abort(SdlContext* sdl)
|
||||
{
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
if (freerdp_shall_disconnect_context(sdl->context()))
|
||||
{
|
||||
if (!sdl->connection_dialog)
|
||||
return true;
|
||||
return !sdl->connection_dialog->running();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int sdl_run(SdlContext* sdl)
|
||||
{
|
||||
int rc = -1;
|
||||
|
@ -792,7 +811,8 @@ static int sdl_run(SdlContext* sdl)
|
|||
return -1;
|
||||
}
|
||||
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
SDL_Init(SDL_INIT_EVERYTHING);
|
||||
TTF_Init();
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 16)
|
||||
SDL_SetHint(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, "0");
|
||||
#endif
|
||||
|
@ -804,17 +824,16 @@ static int sdl_run(SdlContext* sdl)
|
|||
|
||||
sdl->initialized.set();
|
||||
|
||||
while (!freerdp_shall_disconnect_context(sdl->context()))
|
||||
while (!shall_abort(sdl))
|
||||
{
|
||||
SDL_Event windowEvent = { 0 };
|
||||
while (!freerdp_shall_disconnect_context(sdl->context()) &&
|
||||
SDL_WaitEventTimeout(nullptr, 1000))
|
||||
while (!shall_abort(sdl) && SDL_WaitEventTimeout(nullptr, 1000))
|
||||
{
|
||||
/* Only poll standard SDL events and SDL_USEREVENTS meant to create dialogs.
|
||||
* do not process the dialog return value events here.
|
||||
*/
|
||||
const int prc = SDL_PeepEvents(&windowEvent, 1, SDL_GETEVENT, SDL_FIRSTEVENT,
|
||||
SDL_USEREVENT_SCARD_DIALOG);
|
||||
SDL_USEREVENT_RETRY_DIALOG);
|
||||
if (prc < 0)
|
||||
{
|
||||
if (sdl_log_error(prc, sdl->log, "SDL_PeepEvents"))
|
||||
|
@ -826,6 +845,14 @@ static int sdl_run(SdlContext* sdl)
|
|||
windowEvent.type);
|
||||
#endif
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
if (sdl->connection_dialog)
|
||||
{
|
||||
if (sdl->connection_dialog->handle(windowEvent))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
switch (windowEvent.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
|
@ -1078,6 +1105,10 @@ static BOOL sdl_post_connect(freerdp* instance)
|
|||
|
||||
auto sdl = get_context(context);
|
||||
|
||||
// Retry was successful, discard dialog
|
||||
if (sdl->connection_dialog)
|
||||
sdl->connection_dialog->hide();
|
||||
|
||||
if (freerdp_settings_get_bool(context->settings, FreeRDP_AuthenticationOnly))
|
||||
{
|
||||
/* Check +auth-only has a username and password. */
|
||||
|
@ -1130,14 +1161,11 @@ static void sdl_post_disconnect(freerdp* instance)
|
|||
if (!instance->context)
|
||||
return;
|
||||
|
||||
auto context = get_context(instance->context);
|
||||
PubSub_UnsubscribeChannelConnected(instance->context->pubSub,
|
||||
sdl_OnChannelConnectedEventHandler);
|
||||
PubSub_UnsubscribeChannelDisconnected(instance->context->pubSub,
|
||||
sdl_OnChannelDisconnectedEventHandler);
|
||||
gdi_free(instance);
|
||||
/* TODO : Clean up custom stuff */
|
||||
WINPR_UNUSED(context);
|
||||
}
|
||||
|
||||
static void sdl_post_final_disconnect(freerdp* instance)
|
||||
|
@ -1147,6 +1175,12 @@ static void sdl_post_final_disconnect(freerdp* instance)
|
|||
|
||||
if (!instance->context)
|
||||
return;
|
||||
|
||||
auto context = get_context(instance->context);
|
||||
|
||||
if (context->connection_dialog)
|
||||
context->connection_dialog->wait(true);
|
||||
context->connection_dialog.reset();
|
||||
}
|
||||
|
||||
/* RDP main loop.
|
||||
|
@ -1338,6 +1372,7 @@ static BOOL sdl_client_new(freerdp* instance, rdpContext* context)
|
|||
instance->LogonErrorInfo = sdl_logon_error_info;
|
||||
instance->PresentGatewayMessage = sdl_present_gateway_message;
|
||||
instance->ChooseSmartcard = sdl_choose_smartcard;
|
||||
instance->RetryDialog = sdl_retry_dialog;
|
||||
|
||||
#ifdef WITH_WEBVIEW
|
||||
instance->GetAccessToken = sdl_webview_get_access_token;
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "sdl_kbd.hpp"
|
||||
#include "sdl_utils.hpp"
|
||||
#include "sdl_window.hpp"
|
||||
#include "dialogs/sdl_connection_dialog.hpp"
|
||||
|
||||
using SDLSurfacePtr = std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)>;
|
||||
using SDLPixelFormatPtr = std::unique_ptr<SDL_PixelFormat, decltype(&SDL_FreeFormat)>;
|
||||
|
@ -76,6 +77,8 @@ class SdlContext
|
|||
|
||||
Uint32 sdl_pixel_format = 0;
|
||||
|
||||
std::unique_ptr<SDLConnectionDialog> connection_dialog;
|
||||
|
||||
public:
|
||||
BOOL update_resizeable(BOOL enable);
|
||||
BOOL update_fullscreen(BOOL enter);
|
||||
|
|
|
@ -102,6 +102,7 @@ const char* sdl_event_type_str(Uint32 type)
|
|||
EV_CASE_STR(SDL_USEREVENT_AUTH_DIALOG);
|
||||
EV_CASE_STR(SDL_USEREVENT_AUTH_RESULT);
|
||||
EV_CASE_STR(SDL_USEREVENT_SCARD_DIALOG);
|
||||
EV_CASE_STR(SDL_USEREVENT_RETRY_DIALOG);
|
||||
EV_CASE_STR(SDL_USEREVENT_SCARD_RESULT);
|
||||
EV_CASE_STR(SDL_USEREVENT_UPDATE);
|
||||
EV_CASE_STR(SDL_USEREVENT_CREATE_WINDOWS);
|
||||
|
@ -180,6 +181,8 @@ BOOL sdl_push_user_event(Uint32 type, ...)
|
|||
event->code = va_arg(ap, Sint32);
|
||||
}
|
||||
break;
|
||||
case SDL_USEREVENT_RETRY_DIALOG:
|
||||
break;
|
||||
case SDL_USEREVENT_SCARD_RESULT:
|
||||
case SDL_USEREVENT_SHOW_RESULT:
|
||||
case SDL_USEREVENT_CERT_RESULT:
|
||||
|
|
|
@ -69,6 +69,7 @@ enum
|
|||
SDL_USEREVENT_SHOW_DIALOG,
|
||||
SDL_USEREVENT_AUTH_DIALOG,
|
||||
SDL_USEREVENT_SCARD_DIALOG,
|
||||
SDL_USEREVENT_RETRY_DIALOG,
|
||||
|
||||
SDL_USEREVENT_CERT_RESULT,
|
||||
SDL_USEREVENT_SHOW_RESULT,
|
||||
|
|
Loading…
Reference in New Issue