mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-14 00:14:11 +09:00
Merge pull request #12173 from akallabeth/sdl3-high-dpiv2
Sdl3 high dpiv2
This commit is contained in:
@@ -27,8 +27,8 @@ set(SRCS
|
||||
sdl_types.hpp
|
||||
sdl_utils.cpp
|
||||
sdl_utils.hpp
|
||||
sdl_kbd.cpp
|
||||
sdl_kbd.hpp
|
||||
sdl_input.cpp
|
||||
sdl_input.hpp
|
||||
sdl_touch.cpp
|
||||
sdl_touch.hpp
|
||||
sdl_pointer.cpp
|
||||
@@ -45,6 +45,8 @@ set(SRCS
|
||||
sdl_window.cpp
|
||||
sdl_clip.hpp
|
||||
sdl_clip.cpp
|
||||
sdl_context.hpp
|
||||
sdl_context.cpp
|
||||
)
|
||||
|
||||
list(
|
||||
|
||||
@@ -34,5 +34,5 @@ class SDL3ResourceManager : public SDLResourceManager
|
||||
SDL3ResourceManager& operator=(const SDL3ResourceManager& other) = delete;
|
||||
SDL3ResourceManager& operator=(SDL3ResourceManager&& other) = delete;
|
||||
|
||||
static SDL_IOStream* get(const std::string& type, const std::string& id);
|
||||
[[nodiscard]] static SDL_IOStream* get(const std::string& type, const std::string& id);
|
||||
};
|
||||
|
||||
@@ -37,7 +37,7 @@ class SdlBlendModeGuard
|
||||
SdlBlendModeGuard& operator=(const SdlBlendModeGuard& other) = delete;
|
||||
SdlBlendModeGuard& operator=(SdlBlendModeGuard&& other) = delete;
|
||||
|
||||
bool update(SDL_BlendMode mode);
|
||||
[[nodiscard]] bool update(SDL_BlendMode mode);
|
||||
|
||||
private:
|
||||
SDL_BlendMode _restore_mode = SDL_BLENDMODE_INVALID;
|
||||
|
||||
@@ -31,8 +31,8 @@ SdlButton::SdlButton(std::shared_ptr<SDL_Renderer>& renderer, const std::string&
|
||||
_highlightcolor = { 0xcd, 0xca, 0x35, 0x60 };
|
||||
_mouseovercolor = { 0x66, 0xff, 0x66, 0x60 };
|
||||
_fontcolor = { 0xd1, 0xcf, 0xcd, 0xff };
|
||||
update_text(label);
|
||||
update();
|
||||
std::ignore = update_text(label);
|
||||
std::ignore = update();
|
||||
}
|
||||
|
||||
SdlButton::SdlButton(SdlButton&& other) noexcept = default;
|
||||
|
||||
@@ -95,8 +95,10 @@ bool SdlButtonList::update()
|
||||
{
|
||||
for (auto& btn : _list)
|
||||
{
|
||||
btn->highlight(btn == _highlighted);
|
||||
btn->mouseover(btn == _mouseover);
|
||||
if (!btn->highlight(btn == _highlighted))
|
||||
return false;
|
||||
if (!btn->mouseover(btn == _mouseover))
|
||||
return false;
|
||||
|
||||
if (!btn->update())
|
||||
return false;
|
||||
|
||||
@@ -17,13 +17,13 @@ class SdlButtonList
|
||||
SdlButtonList& operator=(const SdlButtonList& other) = delete;
|
||||
SdlButtonList& operator=(SdlButtonList&& other) = delete;
|
||||
|
||||
bool populate(std::shared_ptr<SDL_Renderer>& renderer, const std::vector<std::string>& labels,
|
||||
const std::vector<int>& ids, Sint32 total_width, Sint32 offsetY, Sint32 width,
|
||||
Sint32 height);
|
||||
[[nodiscard]] bool populate(std::shared_ptr<SDL_Renderer>& renderer,
|
||||
const std::vector<std::string>& labels, const std::vector<int>& ids,
|
||||
Sint32 total_width, Sint32 offsetY, Sint32 width, Sint32 height);
|
||||
|
||||
bool update();
|
||||
std::shared_ptr<SdlButton> get_selected(const SDL_MouseButtonEvent& button);
|
||||
std::shared_ptr<SdlButton> get_selected(float x, float y);
|
||||
[[nodiscard]] bool update();
|
||||
[[nodiscard]] std::shared_ptr<SdlButton> get_selected(const SDL_MouseButtonEvent& button);
|
||||
[[nodiscard]] std::shared_ptr<SdlButton> get_selected(float x, float y);
|
||||
|
||||
bool set_highlight_next(bool reset = false);
|
||||
bool set_highlight(size_t index);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "sdl_connection_dialog.hpp"
|
||||
#include "../sdl_utils.hpp"
|
||||
#include "../sdl_freerdp.hpp"
|
||||
#include "../sdl_context.hpp"
|
||||
#include "res/sdl3_resource_manager.hpp"
|
||||
|
||||
static const SDL_Color textcolor = { 0xd1, 0xcf, 0xcd, 0xff };
|
||||
@@ -34,7 +34,7 @@ static const Uint32 hpadding = 5;
|
||||
|
||||
SDLConnectionDialog::SDLConnectionDialog(rdpContext* context) : _context(context)
|
||||
{
|
||||
hide();
|
||||
std::ignore = hide();
|
||||
}
|
||||
|
||||
SDLConnectionDialog::~SDLConnectionDialog()
|
||||
@@ -109,7 +109,8 @@ bool SDLConnectionDialog::updateMsg(SdlConnectionDialogWrapper::MsgType type)
|
||||
case SdlConnectionDialogWrapper::MSG_WARN:
|
||||
case SdlConnectionDialogWrapper::MSG_ERROR:
|
||||
_type_active = type;
|
||||
createWindow();
|
||||
if (!createWindow())
|
||||
return false;
|
||||
break;
|
||||
case SdlConnectionDialogWrapper::MSG_DISCARD:
|
||||
resetTimer();
|
||||
@@ -130,13 +131,16 @@ bool SDLConnectionDialog::setModal()
|
||||
if (_window)
|
||||
{
|
||||
auto sdl = get_context(_context);
|
||||
if (sdl->windows.empty())
|
||||
auto parent = sdl->getFirstWindow();
|
||||
if (!parent)
|
||||
return true;
|
||||
|
||||
auto parent = sdl->windows.begin()->second.window();
|
||||
SDL_SetWindowParent(_window.get(), parent);
|
||||
SDL_SetWindowModal(_window.get(), true);
|
||||
SDL_RaiseWindow(_window.get());
|
||||
if (!SDL_SetWindowParent(_window.get(), parent->window()))
|
||||
return false;
|
||||
if (!SDL_SetWindowModal(_window.get(), true))
|
||||
return false;
|
||||
if (!SDL_RaiseWindow(_window.get()))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -192,7 +196,8 @@ bool SDLConnectionDialog::handle(const SDL_Event& event)
|
||||
if (visible())
|
||||
{
|
||||
auto& ev = reinterpret_cast<const SDL_KeyboardEvent&>(event);
|
||||
update();
|
||||
if (!update())
|
||||
return false;
|
||||
switch (event.key.key)
|
||||
{
|
||||
case SDLK_RETURN:
|
||||
@@ -202,11 +207,12 @@ bool SDLConnectionDialog::handle(const SDL_Event& event)
|
||||
if (event.type == SDL_EVENT_KEY_UP)
|
||||
{
|
||||
freerdp_abort_event(_context);
|
||||
sdl_push_quit();
|
||||
std::ignore = sdl_push_quit();
|
||||
}
|
||||
break;
|
||||
case SDLK_TAB:
|
||||
_buttons.set_highlight_next();
|
||||
if (!_buttons.set_highlight_next())
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -221,7 +227,8 @@ bool SDLConnectionDialog::handle(const SDL_Event& event)
|
||||
auto& ev = reinterpret_cast<const SDL_MouseMotionEvent&>(event);
|
||||
|
||||
_buttons.set_mouseover(event.button.x, event.button.y);
|
||||
update();
|
||||
if (!update())
|
||||
return false;
|
||||
return windowID == ev.windowID;
|
||||
}
|
||||
return false;
|
||||
@@ -230,7 +237,8 @@ bool SDLConnectionDialog::handle(const SDL_Event& event)
|
||||
if (visible())
|
||||
{
|
||||
auto& ev = reinterpret_cast<const SDL_MouseButtonEvent&>(event);
|
||||
update();
|
||||
if (!update())
|
||||
return false;
|
||||
|
||||
auto button = _buttons.get_selected(event.button);
|
||||
if (button)
|
||||
@@ -238,7 +246,7 @@ bool SDLConnectionDialog::handle(const SDL_Event& event)
|
||||
if (event.type == SDL_EVENT_MOUSE_BUTTON_UP)
|
||||
{
|
||||
freerdp_abort_event(_context);
|
||||
sdl_push_quit();
|
||||
std::ignore = sdl_push_quit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,7 +257,8 @@ bool SDLConnectionDialog::handle(const SDL_Event& event)
|
||||
if (visible())
|
||||
{
|
||||
auto& ev = reinterpret_cast<const SDL_MouseWheelEvent&>(event);
|
||||
update();
|
||||
if (!update())
|
||||
return false;
|
||||
return windowID == ev.windowID;
|
||||
}
|
||||
return false;
|
||||
@@ -258,7 +267,8 @@ bool SDLConnectionDialog::handle(const SDL_Event& event)
|
||||
if (visible())
|
||||
{
|
||||
auto& ev = reinterpret_cast<const SDL_TouchFingerEvent&>(event);
|
||||
update();
|
||||
if (!update())
|
||||
return false;
|
||||
return windowID == ev.windowID;
|
||||
}
|
||||
return false;
|
||||
@@ -272,12 +282,14 @@ bool SDLConnectionDialog::handle(const SDL_Event& event)
|
||||
if (windowID == ev.windowID)
|
||||
{
|
||||
freerdp_abort_event(_context);
|
||||
sdl_push_quit();
|
||||
std::ignore = sdl_push_quit();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
update();
|
||||
setModal();
|
||||
if (!update())
|
||||
return false;
|
||||
if (!setModal())
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -304,7 +316,8 @@ bool SDLConnectionDialog::createWindow()
|
||||
if (!reset(_title, widget_width, total_height))
|
||||
return false;
|
||||
|
||||
setModal();
|
||||
if (!setModal())
|
||||
return false;
|
||||
|
||||
SDL_Color res_bgcolor;
|
||||
switch (_type_active)
|
||||
@@ -343,16 +356,15 @@ bool SDLConnectionDialog::createWindow()
|
||||
break;
|
||||
}
|
||||
|
||||
const auto height = (total_height - 3ul * vpadding) / 2ul;
|
||||
SDL_FRect iconRect{ hpadding, vpadding, widget_width / 4ul - 2ul * hpadding,
|
||||
static_cast<float>(height) };
|
||||
const auto height = (total_height - 3.0f * vpadding) / 2.0f;
|
||||
SDL_FRect iconRect{ hpadding, vpadding, widget_width / 4.0f - 2.0f * hpadding, height };
|
||||
widget_cfg_t icon{ textcolor,
|
||||
res_bgcolor,
|
||||
{ _renderer, iconRect,
|
||||
SDL3ResourceManager::get(SDLResourceManager::typeImages(), res_name) } };
|
||||
_list.emplace_back(std::move(icon));
|
||||
|
||||
iconRect.y += static_cast<float>(height);
|
||||
iconRect.y += height;
|
||||
|
||||
widget_cfg_t logo{ textcolor,
|
||||
_backgroundcolor,
|
||||
@@ -361,7 +373,7 @@ bool SDLConnectionDialog::createWindow()
|
||||
"FreeRDP_Icon.svg") } };
|
||||
_list.emplace_back(std::move(logo));
|
||||
|
||||
SDL_FRect rect = { widget_width / 4ul, vpadding, widget_width * 3ul / 4ul,
|
||||
SDL_FRect rect = { widget_width / 4.0f, vpadding, widget_width * 3.0f / 4.0f,
|
||||
total_height - 3ul * vpadding - widget_height };
|
||||
#else
|
||||
SDL_FRect rect = { hpadding, vpadding, widget_width - 2ul * hpadding,
|
||||
@@ -369,19 +381,25 @@ bool SDLConnectionDialog::createWindow()
|
||||
#endif
|
||||
|
||||
widget_cfg_t w{ textcolor, _backgroundcolor, { _renderer, rect } };
|
||||
w.widget.set_wrap(true, widget_width);
|
||||
if (!w.widget.set_wrap(true, widget_width))
|
||||
return false;
|
||||
_list.emplace_back(std::move(w));
|
||||
rect.y += widget_height + vpadding;
|
||||
|
||||
const std::vector<int> buttonids = { 1 };
|
||||
const std::vector<std::string> buttonlabels = { "cancel" };
|
||||
_buttons.populate(_renderer, buttonlabels, buttonids, widget_width,
|
||||
total_height - widget_height - vpadding,
|
||||
static_cast<Sint32>(widget_width / 2), static_cast<Sint32>(widget_height));
|
||||
_buttons.set_highlight(0);
|
||||
if (!_buttons.populate(_renderer, buttonlabels, buttonids, widget_width,
|
||||
total_height - widget_height - vpadding,
|
||||
static_cast<Sint32>(widget_width / 2),
|
||||
static_cast<Sint32>(widget_height)))
|
||||
return false;
|
||||
if (!_buttons.set_highlight(0))
|
||||
return false;
|
||||
|
||||
SDL_ShowWindow(_window.get());
|
||||
SDL_RaiseWindow(_window.get());
|
||||
if (!SDL_ShowWindow(_window.get()))
|
||||
return false;
|
||||
if (!SDL_RaiseWindow(_window.get()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -455,7 +473,7 @@ Uint32 SDLConnectionDialog::timeout(void* pvthis, [[maybe_unused]] SDL_TimerID t
|
||||
[[maybe_unused]] Uint32 intervalMS)
|
||||
{
|
||||
auto self = static_cast<SDLConnectionDialog*>(pvthis);
|
||||
self->hide();
|
||||
std::ignore = self->hide();
|
||||
self->_running = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -42,40 +42,40 @@ class SDLConnectionDialog : public SdlWidgetList
|
||||
SDLConnectionDialog& operator=(const SDLConnectionDialog& other) = delete;
|
||||
SDLConnectionDialog& operator=(SDLConnectionDialog&& other) = delete;
|
||||
|
||||
bool setTitle(const char* fmt, ...);
|
||||
bool showInfo(const char* fmt, ...);
|
||||
bool showWarn(const char* fmt, ...);
|
||||
bool showError(const char* fmt, ...);
|
||||
[[nodiscard]] bool setTitle(const char* fmt, ...);
|
||||
[[nodiscard]] bool showInfo(const char* fmt, ...);
|
||||
[[nodiscard]] bool showWarn(const char* fmt, ...);
|
||||
[[nodiscard]] bool showError(const char* fmt, ...);
|
||||
|
||||
bool show();
|
||||
bool hide();
|
||||
[[nodiscard]] bool show();
|
||||
[[nodiscard]] bool hide();
|
||||
|
||||
bool running() const;
|
||||
bool wait(bool ignoreRdpContextQuit = false);
|
||||
[[nodiscard]] bool running() const;
|
||||
[[nodiscard]] bool wait(bool ignoreRdpContextQuit = false);
|
||||
|
||||
bool handle(const SDL_Event& event);
|
||||
[[nodiscard]] bool handle(const SDL_Event& event);
|
||||
|
||||
bool visible() const override;
|
||||
[[nodiscard]] bool visible() const override;
|
||||
|
||||
protected:
|
||||
bool updateInternal() override;
|
||||
[[nodiscard]] bool updateInternal() override;
|
||||
|
||||
private:
|
||||
bool createWindow();
|
||||
[[nodiscard]] bool createWindow();
|
||||
void destroyWindow();
|
||||
|
||||
bool updateMsg(SdlConnectionDialogWrapper::MsgType type);
|
||||
[[nodiscard]] bool updateMsg(SdlConnectionDialogWrapper::MsgType type);
|
||||
|
||||
bool setModal();
|
||||
[[nodiscard]] bool setModal();
|
||||
|
||||
bool show(SdlConnectionDialogWrapper::MsgType type, const char* fmt, va_list ap);
|
||||
bool show(SdlConnectionDialogWrapper::MsgType type);
|
||||
[[nodiscard]] bool show(SdlConnectionDialogWrapper::MsgType type, const char* fmt, va_list ap);
|
||||
[[nodiscard]] bool show(SdlConnectionDialogWrapper::MsgType type);
|
||||
|
||||
static std::string print(const char* fmt, va_list ap);
|
||||
bool setTimer(Uint32 timeoutMS = 15000);
|
||||
[[nodiscard]] static std::string print(const char* fmt, va_list ap);
|
||||
[[nodiscard]] bool setTimer(Uint32 timeoutMS = 15000);
|
||||
void resetTimer();
|
||||
|
||||
static Uint32 timeout(void* pvthis, SDL_TimerID timerID, Uint32 intervalMS);
|
||||
[[nodiscard]] static Uint32 timeout(void* pvthis, SDL_TimerID timerID, Uint32 intervalMS);
|
||||
|
||||
struct widget_cfg_t
|
||||
{
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#include "sdl_connection_dialog_hider.hpp"
|
||||
#include "../sdl_freerdp.hpp"
|
||||
#include "../sdl_context.hpp"
|
||||
|
||||
SDLConnectionDialogHider::SDLConnectionDialogHider(SdlContext* sdl)
|
||||
: _sdl(sdl), _visible(_sdl->dialog.isVisible())
|
||||
: _sdl(sdl), _visible(_sdl->getDialog().isVisible())
|
||||
{
|
||||
_sdl->dialog.show(false);
|
||||
_sdl->getDialog().show(false);
|
||||
}
|
||||
|
||||
SDLConnectionDialogHider::~SDLConnectionDialogHider()
|
||||
{
|
||||
_sdl->dialog.show(_visible);
|
||||
_sdl->getDialog().show(_visible);
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ static std::string format(WINPR_FORMAT_ARG const char* fmt, va_list ap)
|
||||
|
||||
va_list ap2;
|
||||
va_copy(ap2, ap);
|
||||
(void)vsnprintf(msg.data(), msg.size(), fmt, ap2);
|
||||
std::ignore = vsnprintf(msg.data(), msg.size(), fmt, ap2);
|
||||
va_end(ap2);
|
||||
return msg;
|
||||
}
|
||||
@@ -166,7 +166,7 @@ void SdlConnectionDialogWrapper::handleShow()
|
||||
|
||||
if (arg.hasTitle() && _connection_dialog)
|
||||
{
|
||||
_connection_dialog->setTitle(arg.title().c_str());
|
||||
std::ignore = _connection_dialog->setTitle(arg.title().c_str());
|
||||
}
|
||||
|
||||
if (arg.hasType() && arg.hasMessage())
|
||||
@@ -175,19 +175,19 @@ void SdlConnectionDialogWrapper::handleShow()
|
||||
{
|
||||
case SdlConnectionDialogWrapper::MSG_INFO:
|
||||
if (_connection_dialog)
|
||||
_connection_dialog->showInfo(arg.message().c_str());
|
||||
std::ignore = _connection_dialog->showInfo(arg.message().c_str());
|
||||
else
|
||||
WLog_Print(_log, WLOG_INFO, "%s", arg.message().c_str());
|
||||
break;
|
||||
case SdlConnectionDialogWrapper::MSG_WARN:
|
||||
if (_connection_dialog)
|
||||
_connection_dialog->showWarn(arg.message().c_str());
|
||||
std::ignore = _connection_dialog->showWarn(arg.message().c_str());
|
||||
else
|
||||
WLog_Print(_log, WLOG_WARN, "%s", arg.message().c_str());
|
||||
break;
|
||||
case SdlConnectionDialogWrapper::MSG_ERROR:
|
||||
if (_connection_dialog)
|
||||
_connection_dialog->showError(arg.message().c_str());
|
||||
std::ignore = _connection_dialog->showError(arg.message().c_str());
|
||||
else
|
||||
WLog_Print(_log, WLOG_ERROR, "%s", arg.message().c_str());
|
||||
break;
|
||||
@@ -199,9 +199,9 @@ void SdlConnectionDialogWrapper::handleShow()
|
||||
if (arg.hasVisibility() && _connection_dialog)
|
||||
{
|
||||
if (arg.visible())
|
||||
_connection_dialog->show();
|
||||
std::ignore = _connection_dialog->show();
|
||||
else
|
||||
_connection_dialog->hide();
|
||||
std::ignore = _connection_dialog->hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,10 +57,10 @@ class SdlConnectionDialogWrapper
|
||||
void create(rdpContext* context);
|
||||
void destroy();
|
||||
|
||||
bool isRunning() const;
|
||||
bool isVisible() const;
|
||||
[[nodiscard]] bool isRunning() const;
|
||||
[[nodiscard]] bool isVisible() const;
|
||||
|
||||
bool handleEvent(const SDL_Event& event);
|
||||
[[nodiscard]] bool handleEvent(const SDL_Event& event);
|
||||
|
||||
WINPR_ATTR_FORMAT_ARG(2, 3)
|
||||
void setTitle(WINPR_FORMAT_ARG const char* fmt, ...);
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include "../sdl_freerdp.hpp"
|
||||
#include "../sdl_context.hpp"
|
||||
#include "sdl_dialogs.hpp"
|
||||
#include "sdl_input_widget_pair.hpp"
|
||||
#include "sdl_input_widget_pair_list.hpp"
|
||||
@@ -212,24 +212,24 @@ SSIZE_T sdl_retry_dialog(freerdp* instance, const char* what, size_t current,
|
||||
const BOOL enabled = freerdp_settings_get_bool(settings, FreeRDP_AutoReconnectionEnabled);
|
||||
const size_t delay = freerdp_settings_get_uint32(settings, FreeRDP_TcpConnectTimeout);
|
||||
|
||||
sdl->dialog.setTitle("Retry connection to %s",
|
||||
freerdp_settings_get_server_name(instance->context->settings));
|
||||
sdl->getDialog().setTitle("Retry connection to %s",
|
||||
freerdp_settings_get_server_name(instance->context->settings));
|
||||
|
||||
if ((strcmp(what, "arm-transport") != 0) && (strcmp(what, "connection") != 0))
|
||||
{
|
||||
sdl->dialog.showError("Unknown module %s, aborting", what);
|
||||
sdl->getDialog().showError("Unknown module %s, aborting", what);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (current == 0)
|
||||
{
|
||||
if (strcmp(what, "arm-transport") == 0)
|
||||
sdl->dialog.showWarn("[%s] Starting your VM. It may take up to 5 minutes", what);
|
||||
sdl->getDialog().showWarn("[%s] Starting your VM. It may take up to 5 minutes", what);
|
||||
}
|
||||
|
||||
if (!enabled)
|
||||
{
|
||||
sdl->dialog.showError(
|
||||
sdl->getDialog().showError(
|
||||
"Automatic reconnection disabled, terminating. Try to connect again later");
|
||||
return -1;
|
||||
}
|
||||
@@ -237,16 +237,16 @@ SSIZE_T sdl_retry_dialog(freerdp* instance, const char* what, size_t current,
|
||||
const size_t max = freerdp_settings_get_uint32(settings, FreeRDP_AutoReconnectMaxRetries);
|
||||
if (current >= max)
|
||||
{
|
||||
sdl->dialog.showError(
|
||||
sdl->getDialog().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->dialog.showInfo("[%s] retry %" PRIuz "/%" PRIuz ", delaying %" PRIuz
|
||||
"ms before next attempt",
|
||||
what, current + 1, max, delay);
|
||||
sdl->getDialog().showInfo("[%s] retry %" PRIuz "/%" PRIuz ", delaying %" PRIuz
|
||||
"ms before next attempt",
|
||||
what, current + 1, max, delay);
|
||||
return WINPR_ASSERTING_INT_CAST(ssize_t, delay);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,32 +25,35 @@
|
||||
#include "../sdl_types.hpp"
|
||||
#include "../sdl_utils.hpp"
|
||||
|
||||
BOOL sdl_authenticate_ex(freerdp* instance, char** username, char** password, char** domain,
|
||||
rdp_auth_reason reason);
|
||||
BOOL sdl_choose_smartcard(freerdp* instance, SmartcardCertInfo** cert_list, DWORD count,
|
||||
DWORD* choice, BOOL gateway);
|
||||
[[nodiscard]] BOOL sdl_authenticate_ex(freerdp* instance, char** username, char** password,
|
||||
char** domain, rdp_auth_reason reason);
|
||||
[[nodiscard]] 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);
|
||||
[[nodiscard]] 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);
|
||||
[[nodiscard]] 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);
|
||||
|
||||
DWORD sdl_verify_changed_certificate_ex(freerdp* instance, const char* host, UINT16 port,
|
||||
const char* common_name, const char* subject,
|
||||
const char* issuer, const char* new_fingerprint,
|
||||
const char* old_subject, const char* old_issuer,
|
||||
const char* old_fingerprint, DWORD flags);
|
||||
[[nodiscard]] DWORD
|
||||
sdl_verify_changed_certificate_ex(freerdp* instance, const char* host, UINT16 port,
|
||||
const char* common_name, const char* subject, const char* issuer,
|
||||
const char* new_fingerprint, const char* old_subject,
|
||||
const char* old_issuer, const char* old_fingerprint, DWORD flags);
|
||||
|
||||
int sdl_logon_error_info(freerdp* instance, UINT32 data, UINT32 type);
|
||||
[[nodiscard]] int sdl_logon_error_info(freerdp* instance, UINT32 data, UINT32 type);
|
||||
|
||||
BOOL sdl_present_gateway_message(freerdp* instance, UINT32 type, BOOL isDisplayMandatory,
|
||||
BOOL isConsentMandatory, size_t length, const WCHAR* message);
|
||||
[[nodiscard]] BOOL sdl_present_gateway_message(freerdp* instance, UINT32 type,
|
||||
BOOL isDisplayMandatory, BOOL isConsentMandatory,
|
||||
size_t length, const WCHAR* message);
|
||||
|
||||
BOOL sdl_message_dialog_show(const char* title, const char* message, Sint32 flags);
|
||||
BOOL sdl_cert_dialog_show(const char* title, const char* message);
|
||||
BOOL sdl_scard_dialog_show(const char* title, Sint32 count, const char** list);
|
||||
BOOL sdl_auth_dialog_show(const SDL_UserAuthArg* args);
|
||||
[[nodiscard]] BOOL sdl_message_dialog_show(const char* title, const char* message, Sint32 flags);
|
||||
[[nodiscard]] BOOL sdl_cert_dialog_show(const char* title, const char* message);
|
||||
[[nodiscard]] BOOL sdl_scard_dialog_show(const char* title, Sint32 count, const char** list);
|
||||
[[nodiscard]] BOOL sdl_auth_dialog_show(const SDL_UserAuthArg* args);
|
||||
|
||||
void sdl_dialogs_init();
|
||||
void sdl_dialogs_uninit();
|
||||
|
||||
@@ -36,7 +36,7 @@ class SdlInputWidget : public SdlSelectableWidget
|
||||
|
||||
~SdlInputWidget() override;
|
||||
|
||||
std::string text() const;
|
||||
[[nodiscard]] std::string text() const;
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
@@ -40,8 +40,8 @@ SdlInputWidgetPair::SdlInputWidgetPair(std::shared_ptr<SDL_Renderer>& renderer,
|
||||
static_cast<float>(offset * (height + _vpadding)),
|
||||
static_cast<float>(width), static_cast<float>(height) })
|
||||
{
|
||||
_label.update_text(label);
|
||||
update_input_text(initial);
|
||||
std::ignore = _label.update_text(label);
|
||||
std::ignore = update_input_text(initial);
|
||||
}
|
||||
|
||||
SdlInputWidgetPair::SdlInputWidgetPair(SdlInputWidgetPair&& other) noexcept = default;
|
||||
|
||||
@@ -48,19 +48,19 @@ class SdlInputWidgetPair
|
||||
bool set_mouseover(bool mouseOver);
|
||||
bool set_highlight(bool highlight);
|
||||
|
||||
bool set_str(const std::string& text);
|
||||
bool remove_str(size_t count);
|
||||
bool append_str(const std::string& text);
|
||||
[[nodiscard]] bool set_str(const std::string& text);
|
||||
[[nodiscard]] bool remove_str(size_t count);
|
||||
[[nodiscard]] bool append_str(const std::string& text);
|
||||
|
||||
[[nodiscard]] const SDL_FRect& input_rect() const;
|
||||
[[nodiscard]] std::string value() const;
|
||||
|
||||
[[nodiscard]] bool readonly() const;
|
||||
|
||||
bool update();
|
||||
[[nodiscard]] bool update();
|
||||
|
||||
protected:
|
||||
bool update_input_text(const std::string& txt);
|
||||
[[nodiscard]] bool update_input_text(const std::string& txt);
|
||||
|
||||
Uint32 _vpadding = 5;
|
||||
Uint32 _hpadding = 10;
|
||||
|
||||
@@ -55,9 +55,9 @@ SdlInputWidgetPairList::SdlInputWidgetPairList(const std::string& title,
|
||||
m_list.emplace_back(widget);
|
||||
}
|
||||
|
||||
_buttons.populate(_renderer, buttonlabels, buttonids, total_width,
|
||||
static_cast<Sint32>(input_height), static_cast<Sint32>(widget_width),
|
||||
static_cast<Sint32>(widget_heigth));
|
||||
std::ignore = _buttons.populate(
|
||||
_renderer, buttonlabels, buttonids, total_width, static_cast<Sint32>(input_height),
|
||||
static_cast<Sint32>(widget_width), static_cast<Sint32>(widget_heigth));
|
||||
_buttons.set_highlight(0);
|
||||
m_currentActiveTextInput = selected;
|
||||
}
|
||||
@@ -211,7 +211,8 @@ int SdlInputWidgetPairList::run(std::vector<std::string>& result)
|
||||
if (cur)
|
||||
{
|
||||
auto text = SDL_GetClipboardText();
|
||||
cur->set_str(text);
|
||||
if (!cur->set_str(text))
|
||||
throw;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -235,14 +236,12 @@ int SdlInputWidgetPairList::run(std::vector<std::string>& result)
|
||||
auto TextInputIndex = get_index(event.button);
|
||||
for (auto& cur : m_list)
|
||||
{
|
||||
if (!cur->set_mouseover(false))
|
||||
throw;
|
||||
cur->set_mouseover(false);
|
||||
}
|
||||
if (TextInputIndex >= 0)
|
||||
{
|
||||
auto& cur = m_list[static_cast<size_t>(TextInputIndex)];
|
||||
if (!cur->set_mouseover(true))
|
||||
throw;
|
||||
cur->set_mouseover(true);
|
||||
}
|
||||
|
||||
_buttons.set_mouseover(event.button.x, event.button.y);
|
||||
|
||||
@@ -41,11 +41,11 @@ class SdlInputWidgetPairList : public SdlWidgetList
|
||||
SdlInputWidgetPairList& operator=(const SdlInputWidgetPairList& other) = delete;
|
||||
SdlInputWidgetPairList& operator=(SdlInputWidgetPairList&& other) = delete;
|
||||
|
||||
int run(std::vector<std::string>& result);
|
||||
[[nodiscard]] int run(std::vector<std::string>& result);
|
||||
|
||||
protected:
|
||||
bool updateInternal() override;
|
||||
ssize_t get_index(const SDL_MouseButtonEvent& button);
|
||||
[[nodiscard]] bool updateInternal() override;
|
||||
[[nodiscard]] ssize_t get_index(const SDL_MouseButtonEvent& button);
|
||||
|
||||
private:
|
||||
enum
|
||||
@@ -54,9 +54,9 @@ class SdlInputWidgetPairList : public SdlWidgetList
|
||||
INPUT_BUTTON_CANCEL = -2
|
||||
};
|
||||
|
||||
ssize_t next(ssize_t current);
|
||||
[[nodiscard]] ssize_t next(ssize_t current);
|
||||
[[nodiscard]] bool valid(ssize_t current) const;
|
||||
std::shared_ptr<SdlInputWidgetPair> get(ssize_t index);
|
||||
[[nodiscard]] std::shared_ptr<SdlInputWidgetPair> get(ssize_t index);
|
||||
|
||||
std::vector<std::shared_ptr<SdlInputWidgetPair>> m_list;
|
||||
ssize_t m_currentActiveTextInput = -1;
|
||||
|
||||
@@ -37,7 +37,7 @@ SdlSelectWidget::SdlSelectWidget(std::shared_ptr<SDL_Renderer>& renderer, const
|
||||
{
|
||||
_backgroundcolor = { 0x69, 0x66, 0x63, 0xff };
|
||||
_fontcolor = { 0xd1, 0xcf, 0xcd, 0xff };
|
||||
update_text(label);
|
||||
std::ignore = update_text(label);
|
||||
}
|
||||
|
||||
SdlSelectWidget::~SdlSelectWidget() = default;
|
||||
|
||||
@@ -23,9 +23,9 @@ SdlSelectList::SdlSelectList(const std::string& title, const std::vector<std::st
|
||||
|
||||
const std::vector<int> buttonids = { INPUT_BUTTON_ACCEPT, INPUT_BUTTON_CANCEL };
|
||||
const std::vector<std::string> buttonlabels = { "accept", "cancel" };
|
||||
_buttons.populate(_renderer, buttonlabels, buttonids, widget_width,
|
||||
static_cast<Sint32>(total_height), static_cast<Sint32>(widget_width / 2),
|
||||
static_cast<Sint32>(widget_height));
|
||||
std::ignore = _buttons.populate(
|
||||
_renderer, buttonlabels, buttonids, widget_width, static_cast<Sint32>(total_height),
|
||||
static_cast<Sint32>(widget_width / 2), static_cast<Sint32>(widget_height));
|
||||
_buttons.set_highlight(0);
|
||||
}
|
||||
}
|
||||
@@ -147,7 +147,8 @@ int SdlSelectList::run()
|
||||
throw;
|
||||
}
|
||||
|
||||
update();
|
||||
if (!update())
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
|
||||
@@ -21,10 +21,10 @@ class SdlSelectList : public SdlWidgetList
|
||||
SdlSelectList& operator=(const SdlSelectList& other) = delete;
|
||||
SdlSelectList& operator=(SdlSelectList&& other) = delete;
|
||||
|
||||
int run();
|
||||
[[nodiscard]] int run();
|
||||
|
||||
protected:
|
||||
bool updateInternal() override;
|
||||
[[nodiscard]] bool updateInternal() override;
|
||||
|
||||
private:
|
||||
enum
|
||||
|
||||
@@ -40,7 +40,7 @@ class SdlSelectableWidget : public SdlWidget
|
||||
bool mouseover(bool enable);
|
||||
|
||||
protected:
|
||||
bool updateInternal() override;
|
||||
[[nodiscard]] bool updateInternal() override;
|
||||
SDL_Color _highlightcolor = { 0xcd, 0xca, 0x35, 0x60 };
|
||||
SDL_Color _mouseovercolor = { 0x66, 0xff, 0x66, 0x60 };
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ SdlWidget::SdlWidget(std::shared_ptr<SDL_Renderer>& renderer, const SDL_FRect& r
|
||||
{
|
||||
if (ops)
|
||||
{
|
||||
_image = std::shared_ptr<SDL_Texture>(IMG_LoadTexture_IO(renderer.get(), ops, 1),
|
||||
_image = std::shared_ptr<SDL_Texture>(IMG_LoadTexture_IO(renderer.get(), ops, true),
|
||||
SDL_DestroyTexture);
|
||||
if (!_image)
|
||||
widget_log_error(false, "IMG_LoadTexture_IO");
|
||||
@@ -313,7 +313,10 @@ bool SdlWidget::update_text(const std::string& text)
|
||||
auto w = SDL_GetNumberProperty(propId, SDL_PROP_TEXTURE_WIDTH_NUMBER, -1);
|
||||
auto h = SDL_GetNumberProperty(propId, SDL_PROP_TEXTURE_HEIGHT_NUMBER, -1);
|
||||
if (w < 0 || h < 0)
|
||||
widget_log_error(false, "SDL_GetTextureProperties");
|
||||
{
|
||||
if (!widget_log_error(false, "SDL_GetTextureProperties"))
|
||||
return false;
|
||||
}
|
||||
src.w = static_cast<float>(w);
|
||||
src.h = static_cast<float>(h);
|
||||
}
|
||||
|
||||
@@ -59,15 +59,15 @@ class SdlWidget
|
||||
SdlWidget& operator=(const SdlWidget& other) = delete;
|
||||
SdlWidget& operator=(SdlWidget&& other) = delete;
|
||||
|
||||
bool fill(SDL_Color color) const;
|
||||
bool fill(const std::vector<SDL_Color>& colors) const;
|
||||
bool update_text(const std::string& text);
|
||||
[[nodiscard]] bool fill(SDL_Color color) const;
|
||||
[[nodiscard]] bool fill(const std::vector<SDL_Color>& colors) const;
|
||||
[[nodiscard]] bool update_text(const std::string& text);
|
||||
|
||||
[[nodiscard]] bool wrap() const;
|
||||
bool set_wrap(bool wrap = true, size_t width = 0);
|
||||
[[nodiscard]] bool set_wrap(bool wrap = true, size_t width = 0);
|
||||
[[nodiscard]] const SDL_FRect& rect() const;
|
||||
|
||||
bool update();
|
||||
[[nodiscard]] bool update();
|
||||
|
||||
#define widget_log_error(res, what) SdlWidget::error_ex(res, what, __FILE__, __LINE__, __func__)
|
||||
static bool error_ex(bool success, const char* what, const char* file, size_t line,
|
||||
@@ -83,11 +83,13 @@ class SdlWidget
|
||||
virtual bool updateInternal();
|
||||
|
||||
private:
|
||||
bool draw_rect(const SDL_FRect& rect, SDL_Color color) const;
|
||||
std::shared_ptr<SDL_Texture> render_text(const std::string& text, SDL_Color fgcolor,
|
||||
SDL_FRect& src, SDL_FRect& dst) const;
|
||||
std::shared_ptr<SDL_Texture> render_text_wrapped(const std::string& text, SDL_Color fgcolor,
|
||||
SDL_FRect& src, SDL_FRect& dst) const;
|
||||
[[nodiscard]] bool draw_rect(const SDL_FRect& rect, SDL_Color color) const;
|
||||
[[nodiscard]] std::shared_ptr<SDL_Texture>
|
||||
render_text(const std::string& text, SDL_Color fgcolor, SDL_FRect& src, SDL_FRect& dst) const;
|
||||
[[nodiscard]] std::shared_ptr<SDL_Texture> render_text_wrapped(const std::string& text,
|
||||
SDL_Color fgcolor,
|
||||
SDL_FRect& src,
|
||||
SDL_FRect& dst) const;
|
||||
|
||||
std::shared_ptr<TTF_Font> _font = nullptr;
|
||||
std::shared_ptr<SDL_Texture> _image = nullptr;
|
||||
|
||||
@@ -47,8 +47,10 @@ bool SdlWidgetList::update()
|
||||
if (!visible())
|
||||
return true;
|
||||
|
||||
clearWindow();
|
||||
updateInternal();
|
||||
if (!clearWindow())
|
||||
return false;
|
||||
if (!updateInternal())
|
||||
return false;
|
||||
if (!_buttons.update())
|
||||
return false;
|
||||
auto rc = SDL_RenderPresent(_renderer.get());
|
||||
|
||||
@@ -18,14 +18,14 @@ class SdlWidgetList
|
||||
SdlWidgetList& operator=(SdlWidgetList&& other) = delete;
|
||||
virtual ~SdlWidgetList();
|
||||
|
||||
virtual bool reset(const std::string& title, size_t width, size_t height);
|
||||
[[nodiscard]] virtual bool reset(const std::string& title, size_t width, size_t height);
|
||||
|
||||
[[nodiscard]] virtual bool visible() const;
|
||||
|
||||
protected:
|
||||
bool update();
|
||||
virtual bool clearWindow();
|
||||
virtual bool updateInternal() = 0;
|
||||
[[nodiscard]] bool update();
|
||||
[[nodiscard]] virtual bool clearWindow();
|
||||
[[nodiscard]] virtual bool updateInternal() = 0;
|
||||
|
||||
std::shared_ptr<SDL_Window> _window;
|
||||
std::shared_ptr<SDL_Renderer> _renderer;
|
||||
|
||||
@@ -53,14 +53,7 @@ static int runTest(fkt_t fkt)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[])
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
rc = runTest(auth_dialogs);
|
||||
|
||||
return rc;
|
||||
return runTest(auth_dialogs);
|
||||
}
|
||||
|
||||
@@ -41,14 +41,7 @@ static int runTest(fkt_t fkt)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[])
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
rc = runTest(select_dialogs);
|
||||
|
||||
return rc;
|
||||
return runTest(select_dialogs);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <freerdp/client/disp.h>
|
||||
|
||||
#include "sdl_channels.hpp"
|
||||
#include "sdl_freerdp.hpp"
|
||||
#include "sdl_context.hpp"
|
||||
#include "sdl_disp.hpp"
|
||||
|
||||
void sdl_OnChannelConnectedEventHandler(void* context, const ChannelConnectedEventArgs* e)
|
||||
@@ -43,13 +43,17 @@ void sdl_OnChannelConnectedEventHandler(void* context, const ChannelConnectedEve
|
||||
{
|
||||
auto clip = reinterpret_cast<CliprdrClientContext*>(e->pInterface);
|
||||
WINPR_ASSERT(clip);
|
||||
sdl->clip.init(clip);
|
||||
|
||||
if (!sdl->getClipboardChannelContext().init(clip))
|
||||
WLog_Print(sdl->getWLog(), WLOG_WARN, "Failed to initialize clipboard channel");
|
||||
}
|
||||
else if (strcmp(e->name, DISP_DVC_CHANNEL_NAME) == 0)
|
||||
{
|
||||
auto disp = reinterpret_cast<DispClientContext*>(e->pInterface);
|
||||
WINPR_ASSERT(disp);
|
||||
(void)sdl->disp.init(disp);
|
||||
|
||||
if (!sdl->getDisplayChannelContext().init(disp))
|
||||
WLog_Print(sdl->getWLog(), WLOG_WARN, "Failed to initialize display channel");
|
||||
}
|
||||
else
|
||||
freerdp_client_OnChannelConnectedEventHandler(context, e);
|
||||
@@ -70,14 +74,19 @@ void sdl_OnChannelDisconnectedEventHandler(void* context, const ChannelDisconnec
|
||||
{
|
||||
auto clip = reinterpret_cast<CliprdrClientContext*>(e->pInterface);
|
||||
WINPR_ASSERT(clip);
|
||||
(void)sdl->clip.uninit(clip);
|
||||
|
||||
if (!sdl->getClipboardChannelContext().uninit(clip))
|
||||
WLog_Print(sdl->getWLog(), WLOG_WARN, "Failed to uninitialize clipboard channel");
|
||||
clip->custom = nullptr;
|
||||
}
|
||||
else if (strcmp(e->name, DISP_DVC_CHANNEL_NAME) == 0)
|
||||
{
|
||||
auto disp = reinterpret_cast<DispClientContext*>(e->pInterface);
|
||||
WINPR_ASSERT(disp);
|
||||
(void)sdl->disp.uninit(disp);
|
||||
|
||||
if (!sdl->getDisplayChannelContext().uninit(disp))
|
||||
WLog_Print(sdl->getWLog(), WLOG_WARN, "Failed to uninitialize display channel");
|
||||
disp->custom = nullptr;
|
||||
}
|
||||
else
|
||||
freerdp_client_OnChannelDisconnectedEventHandler(context, e);
|
||||
|
||||
@@ -22,8 +22,5 @@
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/client/channels.h>
|
||||
|
||||
int sdl_on_channel_connected(freerdp* instance, const char* name, void* pInterface);
|
||||
int sdl_on_channel_disconnected(freerdp* instance, const char* name, void* pInterface);
|
||||
|
||||
void sdl_OnChannelConnectedEventHandler(void* context, const ChannelConnectedEventArgs* e);
|
||||
void sdl_OnChannelDisconnectedEventHandler(void* context, const ChannelDisconnectedEventArgs* e);
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <winpr/image.h>
|
||||
|
||||
#include "sdl_clip.hpp"
|
||||
#include "sdl_freerdp.hpp"
|
||||
#include "sdl_context.hpp"
|
||||
|
||||
#define TAG CLIENT_TAG("sdl.cliprdr")
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
|
||||
const char mime_text_utf8[] = mime_text_plain ";charset=utf-8";
|
||||
|
||||
static const std::vector<const char*>& s_mime_text()
|
||||
[[nodiscard]] static const std::vector<const char*>& s_mime_text()
|
||||
{
|
||||
static std::vector<const char*> values;
|
||||
if (values.empty())
|
||||
@@ -58,7 +58,7 @@ static const char s_mime_html[] = "text/html";
|
||||
|
||||
#define BMP_MIME_LIST "image/bmp", "image/x-bmp", "image/x-MS-bmp", "image/x-win-bitmap"
|
||||
|
||||
static const std::vector<const char*>& s_mime_bitmap()
|
||||
[[nodiscard]] static const std::vector<const char*>& s_mime_bitmap()
|
||||
{
|
||||
static std::vector<const char*> values;
|
||||
if (values.empty())
|
||||
@@ -68,7 +68,7 @@ static const std::vector<const char*>& s_mime_bitmap()
|
||||
return values;
|
||||
}
|
||||
|
||||
static const std::vector<const char*>& s_mime_image()
|
||||
[[nodiscard]] static const std::vector<const char*>& s_mime_image()
|
||||
{
|
||||
static std::vector<const char*> values;
|
||||
if (values.empty())
|
||||
@@ -144,10 +144,10 @@ sdlClip::~sdlClip()
|
||||
{
|
||||
cliprdr_file_context_free(_file);
|
||||
ClipboardDestroy(_system);
|
||||
(void)CloseHandle(_event);
|
||||
std::ignore = CloseHandle(_event);
|
||||
}
|
||||
|
||||
BOOL sdlClip::init(CliprdrClientContext* clip)
|
||||
bool sdlClip::init(CliprdrClientContext* clip)
|
||||
{
|
||||
WINPR_ASSERT(clip);
|
||||
_ctx = clip;
|
||||
@@ -162,14 +162,14 @@ BOOL sdlClip::init(CliprdrClientContext* clip)
|
||||
return cliprdr_file_context_init(_file, _ctx);
|
||||
}
|
||||
|
||||
BOOL sdlClip::uninit(CliprdrClientContext* clip)
|
||||
bool sdlClip::uninit(CliprdrClientContext* clip)
|
||||
{
|
||||
WINPR_ASSERT(clip);
|
||||
if (!cliprdr_file_context_uninit(_file, _ctx))
|
||||
return FALSE;
|
||||
return false;
|
||||
_ctx = nullptr;
|
||||
clip->custom = nullptr;
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sdlClip::contains(const char** mime_types, Sint32 count)
|
||||
@@ -183,7 +183,7 @@ bool sdlClip::contains(const char** mime_types, Sint32 count)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sdlClip::handle_update(const SDL_ClipboardEvent& ev)
|
||||
bool sdlClip::handleEvent(const SDL_ClipboardEvent& ev)
|
||||
{
|
||||
if (!_ctx || !_sync || ev.owner)
|
||||
{
|
||||
@@ -876,7 +876,7 @@ const void* sdlClip::ClipDataCb(void* userdata, const char* mime_type, size_t* s
|
||||
clip->_request_queue.pop();
|
||||
|
||||
if (clip->_request_queue.empty())
|
||||
(void)ResetEvent(clip->_event);
|
||||
std::ignore = ResetEvent(clip->_event);
|
||||
|
||||
if (request.success())
|
||||
{
|
||||
@@ -988,3 +988,21 @@ void ClipRequest::setSuccess(bool status)
|
||||
{
|
||||
_success = status;
|
||||
}
|
||||
|
||||
CliprdrFormat::CliprdrFormat(uint32_t formatID, const char* formatName) : _formatID(formatID)
|
||||
{
|
||||
if (formatName)
|
||||
_formatName = formatName;
|
||||
}
|
||||
|
||||
uint32_t CliprdrFormat::formatId() const
|
||||
{
|
||||
return _formatID;
|
||||
}
|
||||
|
||||
const char* CliprdrFormat::formatName() const
|
||||
{
|
||||
if (_formatName.empty())
|
||||
return nullptr;
|
||||
return _formatName.c_str();
|
||||
}
|
||||
|
||||
@@ -61,23 +61,10 @@ class ClipRequest
|
||||
class CliprdrFormat
|
||||
{
|
||||
public:
|
||||
CliprdrFormat(uint32_t formatID, const char* formatName) : _formatID(formatID)
|
||||
{
|
||||
if (formatName)
|
||||
_formatName = formatName;
|
||||
}
|
||||
CliprdrFormat(uint32_t formatID, const char* formatName);
|
||||
|
||||
[[nodiscard]] uint32_t formatId() const
|
||||
{
|
||||
return _formatID;
|
||||
}
|
||||
|
||||
[[nodiscard]] const char* formatName() const
|
||||
{
|
||||
if (_formatName.empty())
|
||||
return nullptr;
|
||||
return _formatName.c_str();
|
||||
}
|
||||
[[nodiscard]] uint32_t formatId() const;
|
||||
[[nodiscard]] const char* formatName() const;
|
||||
|
||||
private:
|
||||
uint32_t _formatID;
|
||||
@@ -97,47 +84,51 @@ class sdlClip
|
||||
sdlClip& operator=(const sdlClip&) = delete;
|
||||
sdlClip& operator=(sdlClip&&) = delete;
|
||||
|
||||
BOOL init(CliprdrClientContext* clip);
|
||||
BOOL uninit(CliprdrClientContext* clip);
|
||||
[[nodiscard]] bool init(CliprdrClientContext* clip);
|
||||
[[nodiscard]] bool uninit(CliprdrClientContext* clip);
|
||||
|
||||
bool handle_update(const SDL_ClipboardEvent& ev);
|
||||
[[nodiscard]] bool handleEvent(const SDL_ClipboardEvent& ev);
|
||||
|
||||
private:
|
||||
UINT SendClientCapabilities();
|
||||
[[nodiscard]] UINT SendClientCapabilities();
|
||||
void clearServerFormats();
|
||||
UINT SendFormatListResponse(BOOL status);
|
||||
UINT SendDataResponse(const BYTE* data, size_t size);
|
||||
UINT SendDataRequest(uint32_t formatID, const std::string& mime);
|
||||
[[nodiscard]] UINT SendFormatListResponse(BOOL status);
|
||||
[[nodiscard]] UINT SendDataResponse(const BYTE* data, size_t size);
|
||||
[[nodiscard]] UINT SendDataRequest(uint32_t formatID, const std::string& mime);
|
||||
|
||||
std::string getServerFormat(uint32_t id);
|
||||
uint32_t serverIdForMime(const std::string& mime);
|
||||
[[nodiscard]] std::string getServerFormat(uint32_t id);
|
||||
[[nodiscard]] uint32_t serverIdForMime(const std::string& mime);
|
||||
|
||||
bool contains(const char** mime_types, Sint32 count);
|
||||
[[nodiscard]] bool contains(const char** mime_types, Sint32 count);
|
||||
|
||||
static UINT MonitorReady(CliprdrClientContext* context,
|
||||
const CLIPRDR_MONITOR_READY* monitorReady);
|
||||
[[nodiscard]] static UINT MonitorReady(CliprdrClientContext* context,
|
||||
const CLIPRDR_MONITOR_READY* monitorReady);
|
||||
|
||||
static UINT ReceiveServerCapabilities(CliprdrClientContext* context,
|
||||
const CLIPRDR_CAPABILITIES* capabilities);
|
||||
static UINT ReceiveServerFormatList(CliprdrClientContext* context,
|
||||
const CLIPRDR_FORMAT_LIST* formatList);
|
||||
static UINT ReceiveFormatListResponse(CliprdrClientContext* context,
|
||||
const CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse);
|
||||
static std::shared_ptr<BYTE> ReceiveFormatDataRequestHandle(
|
||||
[[nodiscard]] static UINT ReceiveServerCapabilities(CliprdrClientContext* context,
|
||||
const CLIPRDR_CAPABILITIES* capabilities);
|
||||
[[nodiscard]] static UINT ReceiveServerFormatList(CliprdrClientContext* context,
|
||||
const CLIPRDR_FORMAT_LIST* formatList);
|
||||
[[nodiscard]] static UINT
|
||||
ReceiveFormatListResponse(CliprdrClientContext* context,
|
||||
const CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse);
|
||||
[[nodiscard]] static std::shared_ptr<BYTE> ReceiveFormatDataRequestHandle(
|
||||
sdlClip* clipboard, const CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest, uint32_t& len);
|
||||
static UINT ReceiveFormatDataRequest(CliprdrClientContext* context,
|
||||
const CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest);
|
||||
static UINT ReceiveFormatDataResponse(CliprdrClientContext* context,
|
||||
const CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse);
|
||||
[[nodiscard]] static UINT
|
||||
ReceiveFormatDataRequest(CliprdrClientContext* context,
|
||||
const CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest);
|
||||
[[nodiscard]] static UINT
|
||||
ReceiveFormatDataResponse(CliprdrClientContext* context,
|
||||
const CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse);
|
||||
|
||||
static const void* SDLCALL ClipDataCb(void* userdata, const char* mime_type, size_t* size);
|
||||
[[nodiscard]] static const void* SDLCALL ClipDataCb(void* userdata, const char* mime_type,
|
||||
size_t* size);
|
||||
static void SDLCALL ClipCleanCb(void* userdata);
|
||||
|
||||
static bool mime_is_file(const std::string& mime);
|
||||
static bool mime_is_text(const std::string& mime);
|
||||
static bool mime_is_image(const std::string& mime);
|
||||
static bool mime_is_bmp(const std::string& mime);
|
||||
static bool mime_is_html(const std::string& mime);
|
||||
[[nodiscard]] static bool mime_is_file(const std::string& mime);
|
||||
[[nodiscard]] static bool mime_is_text(const std::string& mime);
|
||||
[[nodiscard]] static bool mime_is_image(const std::string& mime);
|
||||
[[nodiscard]] static bool mime_is_bmp(const std::string& mime);
|
||||
[[nodiscard]] static bool mime_is_html(const std::string& mime);
|
||||
|
||||
SdlContext* _sdl = nullptr;
|
||||
CliprdrFileContext* _file = nullptr;
|
||||
@@ -145,7 +136,7 @@ class sdlClip
|
||||
wLog* _log = nullptr;
|
||||
wClipboard* _system = nullptr;
|
||||
std::atomic<bool> _sync = false;
|
||||
HANDLE _event;
|
||||
HANDLE _event = nullptr;
|
||||
Uint64 _last_timestamp = 0;
|
||||
|
||||
std::vector<CliprdrFormat> _serverFormats;
|
||||
|
||||
1384
client/SDL/SDL3/sdl_context.cpp
Normal file
1384
client/SDL/SDL3/sdl_context.cpp
Normal file
File diff suppressed because it is too large
Load Diff
200
client/SDL/SDL3/sdl_context.hpp
Normal file
200
client/SDL/SDL3/sdl_context.hpp
Normal file
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* SDL Client
|
||||
*
|
||||
* Copyright 2022 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 <map>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <sdl_common_utils.hpp>
|
||||
|
||||
#include "sdl_window.hpp"
|
||||
#include "sdl_disp.hpp"
|
||||
#include "sdl_clip.hpp"
|
||||
#include "sdl_input.hpp"
|
||||
|
||||
#include "dialogs/sdl_connection_dialog_wrapper.hpp"
|
||||
|
||||
class SdlContext
|
||||
{
|
||||
public:
|
||||
explicit SdlContext(rdpContext* context);
|
||||
SdlContext(const SdlContext& other) = delete;
|
||||
SdlContext(SdlContext&& other) = delete;
|
||||
~SdlContext() = default;
|
||||
|
||||
SdlContext& operator=(const SdlContext& other) = delete;
|
||||
SdlContext& operator=(SdlContext&& other) = delete;
|
||||
|
||||
[[nodiscard]] bool redraw(bool suppress = false) const;
|
||||
|
||||
void setConnected(bool val);
|
||||
[[nodiscard]] bool isConnected() const;
|
||||
void cleanup();
|
||||
|
||||
[[nodiscard]] bool resizeable() const;
|
||||
[[nodiscard]] bool toggleResizeable();
|
||||
[[nodiscard]] bool setResizeable(bool enable);
|
||||
|
||||
[[nodiscard]] bool fullscreen() const;
|
||||
[[nodiscard]] bool toggleFullscreen();
|
||||
[[nodiscard]] bool setFullscreen(bool enter);
|
||||
|
||||
[[nodiscard]] bool setMinimized();
|
||||
|
||||
[[nodiscard]] bool grabMouse() const;
|
||||
[[nodiscard]] bool toggleGrabMouse();
|
||||
[[nodiscard]] bool setGrabMouse(bool enter);
|
||||
|
||||
[[nodiscard]] bool grabKeyboard() const;
|
||||
[[nodiscard]] bool toggleGrabKeyboard();
|
||||
[[nodiscard]] bool setGrabKeyboard(bool enter);
|
||||
|
||||
[[nodiscard]] rdpContext* context() const;
|
||||
[[nodiscard]] rdpClientContext* common() const;
|
||||
|
||||
void setCursor(rdpPointer* cursor);
|
||||
[[nodiscard]] rdpPointer* cursor() const;
|
||||
|
||||
void setMonitorIds(const std::vector<SDL_DisplayID>& ids);
|
||||
const std::vector<SDL_DisplayID>& monitorIds() const;
|
||||
int64_t monitorId(uint32_t index) const;
|
||||
|
||||
void push(std::vector<SDL_Rect>&& rects);
|
||||
std::vector<SDL_Rect> pop();
|
||||
|
||||
void setHasCursor(bool val);
|
||||
[[nodiscard]] bool hasCursor() const;
|
||||
|
||||
void setMetadata();
|
||||
|
||||
[[nodiscard]] int start();
|
||||
[[nodiscard]] int join();
|
||||
[[nodiscard]] bool shallAbort(bool ignoreDialogs = false);
|
||||
|
||||
[[nodiscard]] bool createWindows();
|
||||
[[nodiscard]] bool updateWindowList();
|
||||
|
||||
[[nodiscard]] bool drawToWindows(const std::vector<SDL_Rect>& rects = {});
|
||||
[[nodiscard]] bool drawToWindow(SdlWindow& window, const std::vector<SDL_Rect>& rects = {});
|
||||
[[nodiscard]] bool minimizeAllWindows();
|
||||
[[nodiscard]] int exitCode() const;
|
||||
[[nodiscard]] SDL_PixelFormat pixelFormat() const;
|
||||
|
||||
[[nodiscard]] SdlWindow* getWindowForId(SDL_WindowID id);
|
||||
[[nodiscard]] SdlWindow* getFirstWindow();
|
||||
|
||||
[[nodiscard]] bool addDisplayWindow(SDL_DisplayID id);
|
||||
[[nodiscard]] bool removeDisplay(SDL_DisplayID id);
|
||||
|
||||
[[nodiscard]] sdlDispContext& getDisplayChannelContext();
|
||||
[[nodiscard]] sdlInput& getInputChannelContext();
|
||||
[[nodiscard]] sdlClip& getClipboardChannelContext();
|
||||
|
||||
[[nodiscard]] SdlConnectionDialogWrapper& getDialog();
|
||||
|
||||
[[nodiscard]] wLog* getWLog();
|
||||
|
||||
[[nodiscard]] bool moveMouseTo(const SDL_FPoint& pos);
|
||||
|
||||
[[nodiscard]] SDL_FPoint screenToPixel(SDL_WindowID id, const SDL_FPoint& pos);
|
||||
|
||||
[[nodiscard]] SDL_FPoint pixelToScreen(SDL_WindowID id, const SDL_FPoint& pos);
|
||||
[[nodiscard]] SDL_FRect pixelToScreen(SDL_WindowID id, const SDL_FRect& pos);
|
||||
|
||||
[[nodiscard]] bool handleEvent(const SDL_Event& ev);
|
||||
|
||||
private:
|
||||
[[nodiscard]] static BOOL preConnect(freerdp* instance);
|
||||
[[nodiscard]] static BOOL postConnect(freerdp* instance);
|
||||
static void postDisconnect(freerdp* instance);
|
||||
static void postFinalDisconnect(freerdp* instance);
|
||||
[[nodiscard]] static BOOL desktopResize(rdpContext* context);
|
||||
[[nodiscard]] static BOOL playSound(rdpContext* context, const PLAY_SOUND_UPDATE* play_sound);
|
||||
[[nodiscard]] static BOOL beginPaint(rdpContext* context);
|
||||
[[nodiscard]] static BOOL endPaint(rdpContext* context);
|
||||
[[nodiscard]] static DWORD WINAPI rdpThreadRun(SdlContext* sdl);
|
||||
|
||||
[[nodiscard]] bool eventToPixelCoordinates(SDL_WindowID id, SDL_Event& ev);
|
||||
|
||||
[[nodiscard]] SDL_FPoint applyLocalScaling(const SDL_FPoint& val) const;
|
||||
void removeLocalScaling(float& x, float& y) const;
|
||||
|
||||
[[nodiscard]] bool handleEvent(const SDL_WindowEvent& ev);
|
||||
[[nodiscard]] bool handleEvent(const SDL_DisplayEvent& ev);
|
||||
[[nodiscard]] bool handleEvent(const SDL_MouseButtonEvent& ev);
|
||||
[[nodiscard]] bool handleEvent(const SDL_MouseMotionEvent& ev);
|
||||
[[nodiscard]] bool handleEvent(const SDL_MouseWheelEvent& ev);
|
||||
[[nodiscard]] bool handleEvent(const SDL_TouchFingerEvent& ev);
|
||||
|
||||
[[nodiscard]] bool createPrimary();
|
||||
[[nodiscard]] std::string windowTitle() const;
|
||||
[[nodiscard]] bool waitForWindowsCreated();
|
||||
|
||||
void sdl_client_cleanup(int exit_code, const std::string& error_msg);
|
||||
[[nodiscard]] int sdl_client_thread_connect(std::string& error_msg);
|
||||
[[nodiscard]] int sdl_client_thread_run(std::string& error_msg);
|
||||
|
||||
[[nodiscard]] int error_info_to_error(DWORD* pcode, char** msg, size_t* len) const;
|
||||
|
||||
rdpContext* _context = nullptr;
|
||||
wLog* _log = nullptr;
|
||||
|
||||
std::atomic<bool> _connected = false;
|
||||
bool _cursor_visible = true;
|
||||
rdpPointer* _cursor = nullptr;
|
||||
std::vector<SDL_DisplayID> _monitorIds;
|
||||
std::mutex _queue_mux;
|
||||
std::queue<std::vector<SDL_Rect>> _queue;
|
||||
/* SDL */
|
||||
bool _fullscreen = false;
|
||||
bool _resizeable = false;
|
||||
bool _grabMouse = false;
|
||||
bool _grabKeyboard = false;
|
||||
int _exitCode = -1;
|
||||
std::atomic<bool> _rdpThreadRunning = false;
|
||||
SDL_PixelFormat _sdlPixelFormat = SDL_PIXELFORMAT_UNKNOWN;
|
||||
|
||||
CriticalSection _critical;
|
||||
|
||||
using SDLSurfacePtr = std::unique_ptr<SDL_Surface, decltype(&SDL_DestroySurface)>;
|
||||
|
||||
SDLSurfacePtr _primary;
|
||||
SDL_FPoint _localScale{ 1.0f, 1.0f };
|
||||
|
||||
sdlDispContext _disp;
|
||||
sdlInput _input;
|
||||
sdlClip _clip;
|
||||
|
||||
SdlConnectionDialogWrapper _dialog;
|
||||
|
||||
std::map<Uint32, SdlWindow> _windows;
|
||||
|
||||
WinPREvent _windowsCreatedEvent;
|
||||
std::thread _thread;
|
||||
};
|
||||
@@ -26,9 +26,8 @@
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include "sdl_disp.hpp"
|
||||
#include "sdl_kbd.hpp"
|
||||
#include "sdl_utils.hpp"
|
||||
#include "sdl_freerdp.hpp"
|
||||
#include "sdl_input.hpp"
|
||||
#include "sdl_context.hpp"
|
||||
|
||||
#include <freerdp/log.h>
|
||||
#define TAG CLIENT_TAG("sdl.disp")
|
||||
@@ -85,12 +84,12 @@ bool sdlDispContext::sendResize()
|
||||
const UINT32 mcount = freerdp_settings_get_uint32(settings, FreeRDP_MonitorCount);
|
||||
auto monitors = static_cast<const rdpMonitor*>(
|
||||
freerdp_settings_get_pointer(settings, FreeRDP_MonitorDefArray));
|
||||
return sendLayout(monitors, mcount) != CHANNEL_RC_OK;
|
||||
return sendLayout(monitors, mcount);
|
||||
}
|
||||
|
||||
bool sdlDispContext::set_window_resizable()
|
||||
bool sdlDispContext::setWindowResizeable()
|
||||
{
|
||||
return _sdl->update_resizeable(true);
|
||||
return _sdl->setResizeable(true);
|
||||
}
|
||||
|
||||
static bool sdl_disp_check_context(void* context, SdlContext** ppsdl, sdlDispContext** ppsdlDisp,
|
||||
@@ -107,7 +106,7 @@ static bool sdl_disp_check_context(void* context, SdlContext** ppsdl, sdlDispCon
|
||||
return false;
|
||||
|
||||
*ppsdl = sdl;
|
||||
*ppsdlDisp = &sdl->disp;
|
||||
*ppsdlDisp = &sdl->getDisplayChannelContext();
|
||||
*ppSettings = sdl->context()->settings;
|
||||
return true;
|
||||
}
|
||||
@@ -125,12 +124,13 @@ void sdlDispContext::OnActivated(void* context, const ActivatedEventArgs* e)
|
||||
|
||||
if (sdlDisp->_activated && !freerdp_settings_get_bool(settings, FreeRDP_Fullscreen))
|
||||
{
|
||||
sdlDisp->set_window_resizable();
|
||||
if (!sdlDisp->setWindowResizeable())
|
||||
return;
|
||||
|
||||
if (e->firstActivation)
|
||||
return;
|
||||
|
||||
sdlDisp->addTimer();
|
||||
std::ignore = sdlDisp->addTimer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,8 +148,8 @@ void sdlDispContext::OnGraphicsReset(void* context, const GraphicsResetEventArgs
|
||||
|
||||
if (sdlDisp->_activated && !freerdp_settings_get_bool(settings, FreeRDP_Fullscreen))
|
||||
{
|
||||
sdlDisp->set_window_resizable();
|
||||
sdlDisp->addTimer();
|
||||
if (sdlDisp->setWindowResizeable())
|
||||
std::ignore = sdlDisp->addTimer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,28 +169,24 @@ Uint32 sdlDispContext::OnTimer(void* param, [[maybe_unused]] SDL_TimerID timerID
|
||||
if (!sdl_disp_check_context(sdl->context(), &sdl, &sdlDisp, &settings))
|
||||
return 0;
|
||||
|
||||
WLog_Print(sdl->log, WLOG_TRACE, "checking for display changes...");
|
||||
if (!sdlDisp->_activated || freerdp_settings_get_bool(settings, FreeRDP_Fullscreen))
|
||||
return 0;
|
||||
WLog_Print(sdl->getWLog(), WLOG_TRACE, "checking for display changes...");
|
||||
|
||||
auto rc = sdlDisp->sendResize();
|
||||
if (!rc)
|
||||
WLog_Print(sdl->log, WLOG_TRACE, "sent new display layout, result %d", rc);
|
||||
WLog_Print(sdl->getWLog(), WLOG_TRACE, "sent new display layout, result %d", rc);
|
||||
|
||||
if (sdlDisp->_timer_retries++ >= MAX_RETRIES)
|
||||
{
|
||||
WLog_Print(sdl->log, WLOG_TRACE, "deactivate timer, retries exceeded");
|
||||
WLog_Print(sdl->getWLog(), WLOG_TRACE, "deactivate timer, retries exceeded");
|
||||
return 0;
|
||||
}
|
||||
|
||||
WLog_Print(sdl->log, WLOG_TRACE, "fire timer one more time");
|
||||
WLog_Print(sdl->getWLog(), WLOG_TRACE, "fire timer one more time");
|
||||
return interval;
|
||||
}
|
||||
|
||||
UINT sdlDispContext::sendLayout(const rdpMonitor* monitors, size_t nmonitors)
|
||||
bool sdlDispContext::sendLayout(const rdpMonitor* monitors, size_t nmonitors)
|
||||
{
|
||||
UINT ret = CHANNEL_RC_OK;
|
||||
|
||||
WINPR_ASSERT(monitors);
|
||||
WINPR_ASSERT(nmonitors > 0);
|
||||
|
||||
@@ -262,12 +258,12 @@ UINT sdlDispContext::sendLayout(const rdpMonitor* monitors, size_t nmonitors)
|
||||
WINPR_ASSERT(_disp);
|
||||
const size_t len = layouts.size();
|
||||
WINPR_ASSERT(len <= UINT32_MAX);
|
||||
ret = IFCALLRESULT(CHANNEL_RC_OK, _disp->SendMonitorLayout, _disp, static_cast<UINT32>(len),
|
||||
layouts.data());
|
||||
const auto ret = IFCALLRESULT(CHANNEL_RC_OK, _disp->SendMonitorLayout, _disp,
|
||||
static_cast<UINT32>(len), layouts.data());
|
||||
if (ret != CHANNEL_RC_OK)
|
||||
return ret;
|
||||
return false;
|
||||
_last_sent_layout = layouts;
|
||||
return ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sdlDispContext::addTimer()
|
||||
@@ -276,47 +272,28 @@ bool sdlDispContext::addTimer()
|
||||
return false;
|
||||
|
||||
SDL_RemoveTimer(_timer);
|
||||
WLog_Print(_sdl->log, WLOG_TRACE, "adding new display check timer");
|
||||
WLog_Print(_sdl->getWLog(), WLOG_TRACE, "adding new display check timer");
|
||||
|
||||
_timer_retries = 0;
|
||||
sendResize();
|
||||
if (!sendResize())
|
||||
return false;
|
||||
_timer = SDL_AddTimer(1000, sdlDispContext::OnTimer, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sdlDispContext::updateMonitor(SDL_WindowID id)
|
||||
bool sdlDispContext::updateMonitor([[maybe_unused]] SDL_WindowID id)
|
||||
{
|
||||
auto settings = _sdl->context()->settings;
|
||||
if (freerdp_settings_get_bool(settings, FreeRDP_UseMultimon))
|
||||
return updateMonitors(SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED);
|
||||
|
||||
if (!freerdp_settings_get_bool(_sdl->context()->settings, FreeRDP_DynamicResolutionUpdate))
|
||||
return true;
|
||||
|
||||
const auto& window = _sdl->windows.at(id);
|
||||
auto monitor = window.monitor();
|
||||
|
||||
monitor.is_primary = TRUE;
|
||||
if (!freerdp_settings_set_monitor_def_array_sorted(settings, &monitor, 1))
|
||||
if (!_sdl->updateWindowList())
|
||||
return false;
|
||||
|
||||
return addTimer();
|
||||
}
|
||||
|
||||
bool sdlDispContext::updateMonitors(SDL_EventType type)
|
||||
bool sdlDispContext::updateMonitors(SDL_EventType type, SDL_DisplayID displayID)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case SDL_EVENT_DISPLAY_ADDED:
|
||||
case SDL_EVENT_DISPLAY_REMOVED:
|
||||
case SDL_EVENT_DISPLAY_MOVED:
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "TODO [%s] Not fully supported yet",
|
||||
sdl_event_type_str(type));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
auto settings = _sdl->context()->settings;
|
||||
if (!freerdp_settings_get_bool(settings, FreeRDP_UseMultimon))
|
||||
return true;
|
||||
@@ -324,69 +301,73 @@ bool sdlDispContext::updateMonitors(SDL_EventType type)
|
||||
if (!freerdp_settings_get_bool(settings, FreeRDP_DynamicResolutionUpdate))
|
||||
return true;
|
||||
|
||||
std::vector<rdpMonitor> monitors;
|
||||
monitors.reserve(_sdl->windows.size());
|
||||
for (auto& smon : _sdl->windows)
|
||||
switch (type)
|
||||
{
|
||||
monitors.emplace_back(smon.second.monitor());
|
||||
case SDL_EVENT_DISPLAY_ADDED:
|
||||
if (!_sdl->addDisplayWindow(displayID))
|
||||
return false;
|
||||
break;
|
||||
case SDL_EVENT_DISPLAY_REMOVED:
|
||||
if (!_sdl->removeDisplay(displayID))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!freerdp_settings_set_monitor_def_array_sorted(settings, monitors.data(), monitors.size()))
|
||||
if (!_sdl->updateWindowList())
|
||||
return false;
|
||||
return addTimer();
|
||||
}
|
||||
|
||||
bool sdlDispContext::handle_display_event(const SDL_DisplayEvent* ev)
|
||||
bool sdlDispContext::handleEvent(const SDL_DisplayEvent& ev)
|
||||
{
|
||||
WINPR_ASSERT(ev);
|
||||
|
||||
switch (ev->type)
|
||||
switch (ev.type)
|
||||
{
|
||||
case SDL_EVENT_DISPLAY_ADDED:
|
||||
SDL_Log("A new display with id %u was connected", ev->displayID);
|
||||
return updateMonitors(ev->type);
|
||||
SDL_Log("A new display with id %u was connected", ev.displayID);
|
||||
return updateMonitors(ev.type, ev.displayID);
|
||||
case SDL_EVENT_DISPLAY_REMOVED:
|
||||
SDL_Log("The display with id %u was disconnected", ev->displayID);
|
||||
return updateMonitors(ev->type);
|
||||
SDL_Log("The display with id %u was disconnected", ev.displayID);
|
||||
return updateMonitors(ev.type, ev.displayID);
|
||||
case SDL_EVENT_DISPLAY_ORIENTATION:
|
||||
SDL_Log("The orientation of display with id %u was changed", ev->displayID);
|
||||
return updateMonitors(ev->type);
|
||||
SDL_Log("The orientation of display with id %u was changed", ev.displayID);
|
||||
return updateMonitors(ev.type, ev.displayID);
|
||||
case SDL_EVENT_DISPLAY_MOVED:
|
||||
SDL_Log("The display with id %u was moved", ev->displayID);
|
||||
return updateMonitors(ev->type);
|
||||
SDL_Log("The display with id %u was moved", ev.displayID);
|
||||
return updateMonitors(ev.type, ev.displayID);
|
||||
case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED:
|
||||
SDL_Log("The display with id %u changed scale", ev->displayID);
|
||||
return updateMonitors(ev->type);
|
||||
SDL_Log("The display with id %u changed scale", ev.displayID);
|
||||
return updateMonitors(ev.type, ev.displayID);
|
||||
case SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED:
|
||||
SDL_Log("The display with id %u changed mode", ev->displayID);
|
||||
return updateMonitors(ev->type);
|
||||
SDL_Log("The display with id %u changed mode", ev.displayID);
|
||||
return updateMonitors(ev.type, ev.displayID);
|
||||
case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED:
|
||||
SDL_Log("The display with id %u changed desktop mode", ev->displayID);
|
||||
return updateMonitors(ev->type);
|
||||
SDL_Log("The display with id %u changed desktop mode", ev.displayID);
|
||||
return updateMonitors(ev.type, ev.displayID);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool sdlDispContext::handle_window_event(const SDL_WindowEvent* ev)
|
||||
bool sdlDispContext::handleEvent(const SDL_WindowEvent& ev)
|
||||
{
|
||||
WINPR_ASSERT(ev);
|
||||
auto window = _sdl->getWindowForId(ev.windowID);
|
||||
if (!window)
|
||||
return true;
|
||||
|
||||
auto bordered = freerdp_settings_get_bool(_sdl->context()->settings, FreeRDP_Decorations);
|
||||
window->setBordered(bordered);
|
||||
|
||||
auto it = _sdl->windows.find(ev->windowID);
|
||||
if (it != _sdl->windows.end())
|
||||
it->second.setBordered(bordered);
|
||||
|
||||
switch (ev->type)
|
||||
switch (ev.type)
|
||||
{
|
||||
case SDL_EVENT_WINDOW_HIDDEN:
|
||||
case SDL_EVENT_WINDOW_MINIMIZED:
|
||||
return _sdl->redraw(true);
|
||||
case SDL_EVENT_WINDOW_ENTER_FULLSCREEN:
|
||||
return updateMonitor(ev->windowID);
|
||||
return updateMonitor(ev.windowID);
|
||||
case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN:
|
||||
return updateMonitor(ev->windowID);
|
||||
return updateMonitor(ev.windowID);
|
||||
|
||||
case SDL_EVENT_WINDOW_EXPOSED:
|
||||
case SDL_EVENT_WINDOW_SHOWN:
|
||||
@@ -400,17 +381,17 @@ bool sdlDispContext::handle_window_event(const SDL_WindowEvent* ev)
|
||||
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED:
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
return updateMonitor(ev->windowID);
|
||||
return updateMonitor(ev.windowID);
|
||||
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
||||
WINPR_ASSERT(_sdl);
|
||||
_sdl->input.keyboard_grab(ev->windowID, false);
|
||||
return true;
|
||||
return _sdl->getInputChannelContext().keyboard_grab(ev.windowID, false);
|
||||
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
||||
WINPR_ASSERT(_sdl);
|
||||
_sdl->input.keyboard_grab(ev->windowID, true);
|
||||
return _sdl->input.keyboard_focus_in();
|
||||
if (!_sdl->getInputChannelContext().keyboard_grab(ev.windowID, true))
|
||||
return false;
|
||||
return _sdl->getInputChannelContext().keyboard_focus_in();
|
||||
case SDL_EVENT_WINDOW_FOCUS_GAINED:
|
||||
return _sdl->input.keyboard_focus_in();
|
||||
return _sdl->getInputChannelContext().keyboard_focus_in();
|
||||
|
||||
default:
|
||||
return true;
|
||||
@@ -444,7 +425,7 @@ UINT sdlDispContext::DisplayControlCaps(UINT32 maxNumMonitors, UINT32 maxMonitor
|
||||
return CHANNEL_RC_OK;
|
||||
|
||||
WLog_DBG(TAG, "DisplayControlCapsPdu: setting the window as resizable");
|
||||
return set_window_resizable() ? CHANNEL_RC_OK : CHANNEL_RC_NO_MEMORY;
|
||||
return setWindowResizeable() ? CHANNEL_RC_OK : CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
bool sdlDispContext::init(DispClientContext* disp)
|
||||
@@ -465,7 +446,7 @@ bool sdlDispContext::init(DispClientContext* disp)
|
||||
disp->DisplayControlCaps = sdlDispContext::DisplayControlCaps;
|
||||
}
|
||||
|
||||
return _sdl->update_resizeable(true);
|
||||
return _sdl->setResizeable(true);
|
||||
}
|
||||
|
||||
bool sdlDispContext::uninit(DispClientContext* disp)
|
||||
@@ -474,7 +455,7 @@ bool sdlDispContext::uninit(DispClientContext* disp)
|
||||
return false;
|
||||
|
||||
_disp = nullptr;
|
||||
return _sdl->update_resizeable(false);
|
||||
return _sdl->setResizeable(false);
|
||||
}
|
||||
|
||||
sdlDispContext::sdlDispContext(SdlContext* sdl) : _sdl(sdl)
|
||||
@@ -487,7 +468,7 @@ sdlDispContext::sdlDispContext(SdlContext* sdl) : _sdl(sdl)
|
||||
|
||||
PubSub_SubscribeActivated(pubSub, sdlDispContext::OnActivated);
|
||||
PubSub_SubscribeGraphicsReset(pubSub, sdlDispContext::OnGraphicsReset);
|
||||
addTimer();
|
||||
std::ignore = addTimer();
|
||||
}
|
||||
|
||||
sdlDispContext::~sdlDispContext()
|
||||
|
||||
@@ -35,7 +35,7 @@ class sdlDispContext
|
||||
explicit sdlDispContext(SdlContext* sdl);
|
||||
sdlDispContext(const sdlDispContext& other) = delete;
|
||||
sdlDispContext(sdlDispContext&& other) = delete;
|
||||
~sdlDispContext();
|
||||
virtual ~sdlDispContext();
|
||||
|
||||
sdlDispContext& operator=(const sdlDispContext& other) = delete;
|
||||
sdlDispContext& operator=(sdlDispContext&& other) = delete;
|
||||
@@ -43,28 +43,29 @@ class sdlDispContext
|
||||
[[nodiscard]] bool init(DispClientContext* disp);
|
||||
[[nodiscard]] bool uninit(DispClientContext* disp);
|
||||
|
||||
[[nodiscard]] bool handle_display_event(const SDL_DisplayEvent* ev);
|
||||
[[nodiscard]] bool handle_window_event(const SDL_WindowEvent* ev);
|
||||
[[nodiscard]] bool handleEvent(const SDL_DisplayEvent& ev);
|
||||
[[nodiscard]] bool handleEvent(const SDL_WindowEvent& ev);
|
||||
|
||||
private:
|
||||
UINT DisplayControlCaps(UINT32 maxNumMonitors, UINT32 maxMonitorAreaFactorA,
|
||||
UINT32 maxMonitorAreaFactorB);
|
||||
bool set_window_resizable();
|
||||
[[nodiscard]] UINT DisplayControlCaps(UINT32 maxNumMonitors, UINT32 maxMonitorAreaFactorA,
|
||||
UINT32 maxMonitorAreaFactorB);
|
||||
[[nodiscard]] bool setWindowResizeable();
|
||||
|
||||
bool sendResize();
|
||||
bool settings_changed(const std::vector<DISPLAY_CONTROL_MONITOR_LAYOUT>& layout);
|
||||
UINT sendLayout(const rdpMonitor* monitors, size_t nmonitors);
|
||||
[[nodiscard]] bool sendResize();
|
||||
[[nodiscard]] bool settings_changed(const std::vector<DISPLAY_CONTROL_MONITOR_LAYOUT>& layout);
|
||||
[[nodiscard]] bool sendLayout(const rdpMonitor* monitors, size_t nmonitors);
|
||||
|
||||
bool addTimer();
|
||||
[[nodiscard]] bool addTimer();
|
||||
|
||||
bool updateMonitor(SDL_WindowID id);
|
||||
bool updateMonitors(SDL_EventType type);
|
||||
[[nodiscard]] bool updateMonitor(SDL_WindowID id);
|
||||
[[nodiscard]] bool updateMonitors(SDL_EventType type, SDL_DisplayID displayID);
|
||||
|
||||
static UINT DisplayControlCaps(DispClientContext* disp, UINT32 maxNumMonitors,
|
||||
UINT32 maxMonitorAreaFactorA, UINT32 maxMonitorAreaFactorB);
|
||||
[[nodiscard]] static UINT DisplayControlCaps(DispClientContext* disp, UINT32 maxNumMonitors,
|
||||
UINT32 maxMonitorAreaFactorA,
|
||||
UINT32 maxMonitorAreaFactorB);
|
||||
static void OnActivated(void* context, const ActivatedEventArgs* e);
|
||||
static void OnGraphicsReset(void* context, const GraphicsResetEventArgs* e);
|
||||
static Uint32 SDLCALL OnTimer(void* param, SDL_TimerID timerID, Uint32 interval);
|
||||
[[nodiscard]] static Uint32 SDLCALL OnTimer(void* param, SDL_TimerID timerID, Uint32 interval);
|
||||
|
||||
SdlContext* _sdl = nullptr;
|
||||
DispClientContext* _disp = nullptr;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,105 +19,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <map>
|
||||
#include <atomic>
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/client/rdpei.h>
|
||||
#include <freerdp/client/rail.h>
|
||||
#include <freerdp/client/cliprdr.h>
|
||||
#include <freerdp/client/rdpgfx.h>
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_video.h>
|
||||
|
||||
#include "sdl_types.hpp"
|
||||
#include "sdl_disp.hpp"
|
||||
#include "sdl_kbd.hpp"
|
||||
#include "sdl_clip.hpp"
|
||||
#include "sdl_utils.hpp"
|
||||
#include "sdl_window.hpp"
|
||||
#include "dialogs/sdl_connection_dialog_wrapper.hpp"
|
||||
|
||||
using SDLSurfacePtr = std::unique_ptr<SDL_Surface, decltype(&SDL_DestroySurface)>;
|
||||
|
||||
class SdlContext
|
||||
{
|
||||
public:
|
||||
explicit SdlContext(rdpContext* context);
|
||||
SdlContext(const SdlContext& other) = delete;
|
||||
SdlContext(SdlContext&& other) = delete;
|
||||
~SdlContext() = default;
|
||||
|
||||
SdlContext& operator=(const SdlContext& other) = delete;
|
||||
SdlContext& operator=(SdlContext&& other) = delete;
|
||||
|
||||
[[nodiscard]] bool redraw(bool suppress = false) const;
|
||||
|
||||
void setConnected(bool val);
|
||||
[[nodiscard]] bool isConnected() const;
|
||||
|
||||
[[nodiscard]] bool update_resizeable(bool enable);
|
||||
[[nodiscard]] bool update_fullscreen(bool enter);
|
||||
[[nodiscard]] bool update_minimize();
|
||||
|
||||
[[nodiscard]] rdpContext* context() const;
|
||||
[[nodiscard]] rdpClientContext* common() const;
|
||||
|
||||
void setCursor(rdpPointer* cursor);
|
||||
[[nodiscard]] rdpPointer* cursor() const;
|
||||
|
||||
void setMonitorIds(const std::vector<SDL_DisplayID>& ids);
|
||||
const std::vector<SDL_DisplayID>& monitorIds() const;
|
||||
int64_t monitorId(uint32_t index) const;
|
||||
|
||||
void push(std::vector<SDL_Rect>&& rects);
|
||||
std::vector<SDL_Rect> pop();
|
||||
|
||||
void setHasCursor(bool val);
|
||||
[[nodiscard]] bool hasCursor() const;
|
||||
|
||||
void setMetadata();
|
||||
|
||||
private:
|
||||
rdpContext* _context;
|
||||
std::atomic<bool> _connected = false;
|
||||
bool _cursor_visible = true;
|
||||
rdpPointer* _cursor = nullptr;
|
||||
std::vector<SDL_DisplayID> _monitorIds;
|
||||
std::mutex _queue_mux;
|
||||
std::queue<std::vector<SDL_Rect>> _queue;
|
||||
|
||||
public:
|
||||
wLog* log;
|
||||
|
||||
/* SDL */
|
||||
bool fullscreen = false;
|
||||
bool resizeable = false;
|
||||
bool grab_mouse = false;
|
||||
bool grab_kbd = false;
|
||||
|
||||
std::map<Uint32, SdlWindow> windows;
|
||||
|
||||
CriticalSection critical;
|
||||
std::thread thread;
|
||||
WinPREvent initialize;
|
||||
WinPREvent initialized;
|
||||
WinPREvent windows_created;
|
||||
int exit_code = -1;
|
||||
|
||||
sdlDispContext disp;
|
||||
sdlInput input;
|
||||
sdlClip clip;
|
||||
|
||||
SDLSurfacePtr primary;
|
||||
|
||||
SDL_PixelFormat sdl_pixel_format = SDL_PIXELFORMAT_UNKNOWN;
|
||||
|
||||
std::atomic<bool> rdp_thread_running;
|
||||
SdlConnectionDialogWrapper dialog;
|
||||
};
|
||||
#include "sdl_context.hpp"
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "sdl_kbd.hpp"
|
||||
#include "sdl_input.hpp"
|
||||
#include "sdl_disp.hpp"
|
||||
#include "sdl_freerdp.hpp"
|
||||
#include "sdl_context.hpp"
|
||||
#include "sdl_utils.hpp"
|
||||
#include "sdl_prefs.hpp"
|
||||
#include "sdl_touch.hpp"
|
||||
@@ -44,10 +44,7 @@ typedef struct
|
||||
} scancode_entry_t;
|
||||
|
||||
#define STR(x) #x
|
||||
#define ENTRY(x, y) \
|
||||
{ \
|
||||
x, STR(x), y, #y \
|
||||
}
|
||||
#define ENTRY(x, y) { x, STR(x), y, #y }
|
||||
static const scancode_entry_t map[] = {
|
||||
ENTRY(SDL_SCANCODE_UNKNOWN, RDP_SCANCODE_UNKNOWN),
|
||||
ENTRY(SDL_SCANCODE_A, RDP_SCANCODE_KEY_A),
|
||||
@@ -283,7 +280,7 @@ static const scancode_entry_t map[] = {
|
||||
ENTRY(SDL_SCANCODE_MEDIA_FAST_FORWARD, RDP_SCANCODE_UNKNOWN)
|
||||
};
|
||||
|
||||
static UINT32 sdl_get_kbd_flags()
|
||||
[[nodiscard]] static UINT32 sdl_get_kbd_flags()
|
||||
{
|
||||
UINT32 flags = 0;
|
||||
|
||||
@@ -300,13 +297,13 @@ static UINT32 sdl_get_kbd_flags()
|
||||
return flags;
|
||||
}
|
||||
|
||||
BOOL sdlInput::keyboard_sync_state()
|
||||
bool sdlInput::keyboard_sync_state()
|
||||
{
|
||||
const UINT32 syncFlags = sdl_get_kbd_flags();
|
||||
return freerdp_input_send_synchronize_event(_sdl->context()->input, syncFlags);
|
||||
}
|
||||
|
||||
BOOL sdlInput::keyboard_focus_in()
|
||||
bool sdlInput::keyboard_focus_in()
|
||||
{
|
||||
auto input = _sdl->context()->input;
|
||||
WINPR_ASSERT(input);
|
||||
@@ -318,23 +315,16 @@ BOOL sdlInput::keyboard_focus_in()
|
||||
// TODO: fullscreen/remote app
|
||||
float fx = 0.0f;
|
||||
float fy = 0.0f;
|
||||
if (_sdl->fullscreen)
|
||||
{
|
||||
if (_sdl->fullscreen())
|
||||
SDL_GetGlobalMouseState(&fx, &fy);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_GetMouseState(&fx, &fy);
|
||||
}
|
||||
auto x = static_cast<int32_t>(fx);
|
||||
auto y = static_cast<int32_t>(fy);
|
||||
|
||||
auto w = SDL_GetMouseFocus();
|
||||
if (w)
|
||||
{
|
||||
auto id = SDL_GetWindowID(w);
|
||||
sdl_scale_coordinates(_sdl, id, &x, &y, TRUE, TRUE);
|
||||
}
|
||||
return freerdp_client_send_button_event(_sdl->common(), FALSE, PTR_FLAGS_MOVE, x, y);
|
||||
const auto& pos = _sdl->screenToPixel(SDL_GetWindowID(w), SDL_FPoint{ fx, fy });
|
||||
|
||||
return freerdp_client_send_button_event(_sdl->common(), FALSE, PTR_FLAGS_MOVE,
|
||||
static_cast<Sint32>(pos.x), static_cast<Sint32>(pos.y));
|
||||
}
|
||||
|
||||
/* This function is called to update the keyboard indicator LED */
|
||||
@@ -366,14 +356,14 @@ BOOL sdlInput::keyboard_set_ime_status(rdpContext* context, UINT16 imeId, UINT32
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
WLog_Print(sdl->log, WLOG_WARN,
|
||||
WLog_Print(sdl->getWLog(), WLOG_WARN,
|
||||
"KeyboardSetImeStatus(unitId=%04" PRIx16 ", imeState=%08" PRIx32
|
||||
", imeConvMode=%08" PRIx32 ") ignored",
|
||||
imeId, imeState, imeConvMode);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const std::map<std::string, uint32_t>& getSdlMap()
|
||||
[[nodiscard]] static const std::map<std::string, uint32_t>& getSdlMap()
|
||||
{
|
||||
static std::map<std::string, uint32_t> s_map = {
|
||||
{ "KMOD_LSHIFT", SDL_KMOD_LSHIFT }, { "KMOD_RSHIFT", SDL_KMOD_RSHIFT },
|
||||
@@ -398,7 +388,7 @@ static const std::map<std::string, uint32_t>& getSdlMap()
|
||||
return s_map;
|
||||
}
|
||||
|
||||
static std::string modbyvalue(uint32_t val)
|
||||
[[nodiscard]] static std::string modbyvalue(uint32_t val)
|
||||
{
|
||||
for (const auto& v : getSdlMap())
|
||||
{
|
||||
@@ -410,7 +400,7 @@ static std::string modbyvalue(uint32_t val)
|
||||
return "KMOD_UNKNONW";
|
||||
}
|
||||
|
||||
static std::string masktostr(uint32_t mask)
|
||||
[[nodiscard]] static std::string masktostr(uint32_t mask)
|
||||
{
|
||||
if (mask == 0)
|
||||
return "<NONE>";
|
||||
@@ -447,7 +437,7 @@ bool sdlInput::prefToEnabled()
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_Print(_sdl->log, WLOG_WARN,
|
||||
WLog_Print(_sdl->getWLog(), WLOG_WARN,
|
||||
"Invalid config::SDL_KeyModMask entry value '%s', disabling hotkeys",
|
||||
val.c_str());
|
||||
enabled = false;
|
||||
@@ -469,7 +459,7 @@ uint32_t sdlInput::prefToMask()
|
||||
return mod;
|
||||
}
|
||||
|
||||
static const char* sdl_scancode_name(Uint32 scancode)
|
||||
[[nodiscard]] static const char* sdl_scancode_name(Uint32 scancode)
|
||||
{
|
||||
for (const auto& cur : map)
|
||||
{
|
||||
@@ -480,7 +470,7 @@ static const char* sdl_scancode_name(Uint32 scancode)
|
||||
return "SDL_SCANCODE_UNKNOWN";
|
||||
}
|
||||
|
||||
static Uint32 sdl_scancode_val(const char* scancodeName)
|
||||
[[nodiscard]] static Uint32 sdl_scancode_val(const char* scancodeName)
|
||||
{
|
||||
for (const auto& cur : map)
|
||||
{
|
||||
@@ -492,7 +482,7 @@ static Uint32 sdl_scancode_val(const char* scancodeName)
|
||||
}
|
||||
|
||||
#if defined(WITH_DEBUG_SDL_KBD_EVENTS)
|
||||
static const char* sdl_rdp_scancode_name(UINT32 scancode)
|
||||
[[nodiscard]] static const char* sdl_rdp_scancode_name(UINT32 scancode)
|
||||
{
|
||||
for (const auto& cur : map)
|
||||
{
|
||||
@@ -503,7 +493,7 @@ static const char* sdl_rdp_scancode_name(UINT32 scancode)
|
||||
return "RDP_SCANCODE_UNKNOWN";
|
||||
}
|
||||
|
||||
static UINT32 sdl_rdp_scancode_val(const char* scancodeName)
|
||||
[[nodiscard]] static UINT32 sdl_rdp_scancode_val(const char* scancodeName)
|
||||
{
|
||||
for (const auto& cur : map)
|
||||
{
|
||||
@@ -530,7 +520,7 @@ UINT32 sdlInput::scancode_to_rdp(Uint32 scancode)
|
||||
|
||||
#if defined(WITH_DEBUG_SDL_KBD_EVENTS)
|
||||
auto code = static_cast<SDL_Scancode>(scancode);
|
||||
WLog_Print(_sdl->log, WLOG_DEBUG, "got %s [%s] -> [%s]", SDL_GetScancodeName(code),
|
||||
WLog_Print(_sdl->getWLog(), WLOG_DEBUG, "got %s [%s] -> [%s]", SDL_GetScancodeName(code),
|
||||
sdl_scancode_name(scancode), sdl_rdp_scancode_name(rdp));
|
||||
#endif
|
||||
return rdp;
|
||||
@@ -568,53 +558,56 @@ bool sdlInput::extract(const std::string& token, uint32_t& key, uint32_t& value)
|
||||
return freerdp_extract_key_value(token.c_str(), &key, &value);
|
||||
}
|
||||
|
||||
BOOL sdlInput::keyboard_handle_event(const SDL_KeyboardEvent* ev)
|
||||
bool sdlInput::handleEvent(const SDL_KeyboardEvent& ev)
|
||||
{
|
||||
WINPR_ASSERT(ev);
|
||||
const UINT32 rdp_scancode = scancode_to_rdp(ev->scancode);
|
||||
const UINT32 rdp_scancode = scancode_to_rdp(ev.scancode);
|
||||
const SDL_Keymod mods = SDL_GetModState();
|
||||
|
||||
if (_hotkeysEnabled && (mods & _hotkeyModmask) == _hotkeyModmask)
|
||||
{
|
||||
if (ev->type == SDL_EVENT_KEY_DOWN)
|
||||
if (ev.type == SDL_EVENT_KEY_DOWN)
|
||||
{
|
||||
if (ev->scancode == _hotkeyFullscreen)
|
||||
if (ev.scancode == _hotkeyFullscreen)
|
||||
{
|
||||
WLog_Print(_sdl->log, WLOG_INFO, "%s+<%s> pressed, toggling fullscreen state",
|
||||
WLog_Print(_sdl->getWLog(), WLOG_INFO, "%s+<%s> pressed, toggling fullscreen state",
|
||||
masktostr(_hotkeyModmask).c_str(), sdl_scancode_name(_hotkeyFullscreen));
|
||||
keyboard_sync_state();
|
||||
return _sdl->update_fullscreen(!_sdl->fullscreen);
|
||||
if (!keyboard_sync_state())
|
||||
return false;
|
||||
return _sdl->toggleFullscreen();
|
||||
}
|
||||
if (ev->scancode == _hotkeyResizable)
|
||||
if (ev.scancode == _hotkeyResizable)
|
||||
{
|
||||
WLog_Print(_sdl->log, WLOG_INFO, "%s+<%s> pressed, toggling resizeable state",
|
||||
WLog_Print(_sdl->getWLog(), WLOG_INFO, "%s+<%s> pressed, toggling resizeable state",
|
||||
masktostr(_hotkeyModmask).c_str(), sdl_scancode_name(_hotkeyResizable));
|
||||
keyboard_sync_state();
|
||||
return _sdl->update_resizeable(!_sdl->resizeable);
|
||||
if (!keyboard_sync_state())
|
||||
return false;
|
||||
return _sdl->toggleResizeable();
|
||||
}
|
||||
|
||||
if (ev->scancode == _hotkeyGrab)
|
||||
if (ev.scancode == _hotkeyGrab)
|
||||
{
|
||||
WLog_Print(_sdl->log, WLOG_INFO, "%s+<%s> pressed, toggling grab state",
|
||||
WLog_Print(_sdl->getWLog(), WLOG_INFO, "%s+<%s> pressed, toggling grab state",
|
||||
masktostr(_hotkeyModmask).c_str(), sdl_scancode_name(_hotkeyGrab));
|
||||
keyboard_sync_state();
|
||||
keyboard_grab(ev->windowID, !_sdl->grab_kbd);
|
||||
return TRUE;
|
||||
if (!keyboard_sync_state())
|
||||
return false;
|
||||
return keyboard_grab(ev.windowID, !_sdl->grabKeyboard());
|
||||
}
|
||||
if (ev->scancode == _hotkeyDisconnect)
|
||||
if (ev.scancode == _hotkeyDisconnect)
|
||||
{
|
||||
WLog_Print(_sdl->log, WLOG_INFO, "%s+<%s> pressed, disconnecting RDP session",
|
||||
WLog_Print(_sdl->getWLog(), WLOG_INFO, "%s+<%s> pressed, disconnecting RDP session",
|
||||
masktostr(_hotkeyModmask).c_str(), sdl_scancode_name(_hotkeyDisconnect));
|
||||
keyboard_sync_state();
|
||||
if (!keyboard_sync_state())
|
||||
return false;
|
||||
freerdp_abort_connect_context(_sdl->context());
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
if (ev->scancode == _hotkeyMinimize)
|
||||
if (ev.scancode == _hotkeyMinimize)
|
||||
{
|
||||
WLog_Print(_sdl->log, WLOG_INFO, "%s+<%s> pressed, minimizing client",
|
||||
WLog_Print(_sdl->getWLog(), WLOG_INFO, "%s+<%s> pressed, minimizing client",
|
||||
masktostr(_hotkeyModmask).c_str(), sdl_scancode_name(_hotkeyMinimize));
|
||||
keyboard_sync_state();
|
||||
return _sdl->update_minimize();
|
||||
if (!keyboard_sync_state())
|
||||
return false;
|
||||
return _sdl->setMinimized();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -623,9 +616,9 @@ BOOL sdlInput::keyboard_handle_event(const SDL_KeyboardEvent* ev)
|
||||
{
|
||||
const BOOL ex = RDP_SCANCODE_EXTENDED(rdp_scancode);
|
||||
const DWORD sc = RDP_SCANCODE_CODE(rdp_scancode);
|
||||
WLog_Print(_sdl->log, WLOG_DEBUG,
|
||||
WLog_Print(_sdl->getWLog(), WLOG_DEBUG,
|
||||
"SDL keycode: %02" PRIX32 " -> rdp code: [%04" PRIx16 "] %02" PRIX8 "%s",
|
||||
ev->scancode, rdp_scancode, sc, ex ? " extended" : "");
|
||||
ev.scancode, rdp_scancode, sc, ex ? " extended" : "");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -634,50 +627,52 @@ BOOL sdlInput::keyboard_handle_event(const SDL_KeyboardEvent* ev)
|
||||
{
|
||||
const BOOL ex = RDP_SCANCODE_EXTENDED(scancode);
|
||||
const DWORD sc = RDP_SCANCODE_CODE(scancode);
|
||||
WLog_Print(_sdl->log, WLOG_DEBUG,
|
||||
WLog_Print(_sdl->getWLog(), WLOG_DEBUG,
|
||||
"SDL keycode: %02" PRIX32 " -> remapped rdp code: [%04" PRIx16 "] %02" PRIX8
|
||||
"%s",
|
||||
ev->scancode, scancode, sc, ex ? " extended" : "");
|
||||
ev.scancode, scancode, sc, ex ? " extended" : "");
|
||||
}
|
||||
#endif
|
||||
return freerdp_input_send_keyboard_event_ex(
|
||||
_sdl->context()->input, ev->type == SDL_EVENT_KEY_DOWN, ev->repeat, scancode);
|
||||
return freerdp_input_send_keyboard_event_ex(_sdl->context()->input,
|
||||
ev.type == SDL_EVENT_KEY_DOWN, ev.repeat, scancode);
|
||||
}
|
||||
|
||||
BOOL sdlInput::keyboard_grab(Uint32 windowID, bool enable)
|
||||
bool sdlInput::keyboard_grab(Uint32 windowID, bool enable)
|
||||
{
|
||||
auto it = _sdl->windows.find(windowID);
|
||||
if (it == _sdl->windows.end())
|
||||
return FALSE;
|
||||
const auto window = _sdl->getWindowForId(windowID);
|
||||
if (!window)
|
||||
return false;
|
||||
|
||||
auto settings = _sdl->context()->settings;
|
||||
auto kbd_enabled = freerdp_settings_get_bool(settings, FreeRDP_GrabKeyboard);
|
||||
auto status = enable && kbd_enabled;
|
||||
_sdl->grab_kbd = status;
|
||||
return it->second.grabKeyboard(status);
|
||||
if (!_sdl->setGrabKeyboard(status))
|
||||
WLog_Print(_sdl->getWLog(), WLOG_WARN, "Failed to ungrab keyboard");
|
||||
return window->grabKeyboard(status);
|
||||
}
|
||||
|
||||
BOOL sdlInput::mouse_focus(Uint32 windowID)
|
||||
bool sdlInput::mouse_focus(Uint32 windowID)
|
||||
{
|
||||
if (_lastWindowID != windowID)
|
||||
{
|
||||
_lastWindowID = windowID;
|
||||
auto it = _sdl->windows.find(windowID);
|
||||
if (it == _sdl->windows.end())
|
||||
return FALSE;
|
||||
auto window = _sdl->getWindowForId(windowID);
|
||||
if (!window)
|
||||
return false;
|
||||
|
||||
it->second.raise();
|
||||
window->raise();
|
||||
}
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL sdlInput::mouse_grab(Uint32 windowID, bool enable)
|
||||
bool sdlInput::mouse_grab(Uint32 windowID, bool enable)
|
||||
{
|
||||
auto it = _sdl->windows.find(windowID);
|
||||
if (it == _sdl->windows.end())
|
||||
return FALSE;
|
||||
_sdl->grab_mouse = enable;
|
||||
return it->second.grabMouse(enable);
|
||||
auto window = _sdl->getWindowForId(windowID);
|
||||
if (!window)
|
||||
return false;
|
||||
if (!_sdl->setGrabMouse(enable))
|
||||
WLog_Print(_sdl->getWLog(), WLOG_WARN, "Failed to ungrab mouse");
|
||||
return window->grabMouse(enable);
|
||||
}
|
||||
|
||||
sdlInput::sdlInput(SdlContext* sdl)
|
||||
@@ -696,7 +691,7 @@ sdlInput::~sdlInput()
|
||||
freerdp_keyboard_remap_free(_remapTable);
|
||||
}
|
||||
|
||||
BOOL sdlInput::initialize()
|
||||
bool sdlInput::initialize()
|
||||
{
|
||||
auto settings = _sdl->context()->settings;
|
||||
WINPR_ASSERT(settings);
|
||||
@@ -706,7 +701,7 @@ BOOL sdlInput::initialize()
|
||||
auto list = freerdp_settings_get_string(settings, FreeRDP_KeyboardRemappingList);
|
||||
_remapTable = freerdp_keyboard_remap_string_to_list(list);
|
||||
if (!_remapTable)
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (freerdp_settings_get_uint32(settings, FreeRDP_KeyboardLayout) == 0)
|
||||
@@ -718,7 +713,7 @@ BOOL sdlInput::initialize()
|
||||
KeyboardLayout = ENGLISH_UNITED_STATES;
|
||||
|
||||
if (!freerdp_settings_set_uint32(settings, FreeRDP_KeyboardLayout, KeyboardLayout))
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
84
client/SDL/SDL3/sdl_input.hpp
Normal file
84
client/SDL/SDL3/sdl_input.hpp
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* SDL Client keyboard helper
|
||||
*
|
||||
* Copyright 2022 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 <string>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <atomic>
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/locale/keyboard.h>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include "sdl_types.hpp"
|
||||
|
||||
class sdlInput
|
||||
{
|
||||
public:
|
||||
explicit sdlInput(SdlContext* sdl);
|
||||
sdlInput(const sdlInput& other) = delete;
|
||||
sdlInput(sdlInput&& other) = delete;
|
||||
virtual ~sdlInput();
|
||||
|
||||
sdlInput& operator=(const sdlInput& other) = delete;
|
||||
sdlInput& operator=(sdlInput&& other) = delete;
|
||||
|
||||
[[nodiscard]] bool initialize();
|
||||
|
||||
[[nodiscard]] bool keyboard_sync_state();
|
||||
[[nodiscard]] bool keyboard_focus_in();
|
||||
|
||||
[[nodiscard]] bool handleEvent(const SDL_KeyboardEvent& ev);
|
||||
|
||||
[[nodiscard]] bool keyboard_grab(Uint32 windowID, bool enable);
|
||||
[[nodiscard]] bool mouse_focus(Uint32 windowID);
|
||||
[[nodiscard]] bool mouse_grab(Uint32 windowID, bool enable);
|
||||
|
||||
[[nodiscard]] static BOOL keyboard_set_indicators(rdpContext* context, UINT16 led_flags);
|
||||
[[nodiscard]] static BOOL keyboard_set_ime_status(rdpContext* context, UINT16 imeId,
|
||||
UINT32 imeState, UINT32 imeConvMode);
|
||||
|
||||
[[nodiscard]] bool prefToEnabled();
|
||||
[[nodiscard]] uint32_t prefToMask();
|
||||
[[nodiscard]] static uint32_t prefKeyValue(const std::string& key,
|
||||
uint32_t fallback = SDL_SCANCODE_UNKNOWN);
|
||||
|
||||
private:
|
||||
[[nodiscard]] static std::list<std::string> tokenize(const std::string& data,
|
||||
const std::string& delimiter = ",");
|
||||
[[nodiscard]] static bool extract(const std::string& token, uint32_t& key, uint32_t& value);
|
||||
|
||||
[[nodiscard]] UINT32 scancode_to_rdp(Uint32 scancode);
|
||||
|
||||
SdlContext* _sdl = nullptr;
|
||||
Uint32 _lastWindowID = 0;
|
||||
|
||||
// hotkey handling
|
||||
bool _hotkeysEnabled = false;
|
||||
uint32_t _hotkeyModmask = 0; // modifier keys mask
|
||||
uint32_t _hotkeyFullscreen = 0;
|
||||
uint32_t _hotkeyResizable = 0;
|
||||
uint32_t _hotkeyGrab = 0;
|
||||
uint32_t _hotkeyDisconnect = 0;
|
||||
uint32_t _hotkeyMinimize = 0;
|
||||
FREERDP_REMAP_TABLE* _remapTable = nullptr;
|
||||
};
|
||||
@@ -1,83 +0,0 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* SDL Client keyboard helper
|
||||
*
|
||||
* Copyright 2022 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 <string>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <atomic>
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/locale/keyboard.h>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include "sdl_types.hpp"
|
||||
|
||||
class sdlInput
|
||||
{
|
||||
public:
|
||||
explicit sdlInput(SdlContext* sdl);
|
||||
sdlInput(const sdlInput& other) = delete;
|
||||
sdlInput(sdlInput&& other) = delete;
|
||||
~sdlInput();
|
||||
|
||||
sdlInput& operator=(const sdlInput& other) = delete;
|
||||
sdlInput& operator=(sdlInput&& other) = delete;
|
||||
|
||||
BOOL initialize();
|
||||
|
||||
BOOL keyboard_sync_state();
|
||||
BOOL keyboard_focus_in();
|
||||
|
||||
BOOL keyboard_handle_event(const SDL_KeyboardEvent* ev);
|
||||
|
||||
BOOL keyboard_grab(Uint32 windowID, bool enable);
|
||||
BOOL mouse_focus(Uint32 windowID);
|
||||
BOOL mouse_grab(Uint32 windowID, bool enable);
|
||||
|
||||
static BOOL keyboard_set_indicators(rdpContext* context, UINT16 led_flags);
|
||||
static BOOL keyboard_set_ime_status(rdpContext* context, UINT16 imeId, UINT32 imeState,
|
||||
UINT32 imeConvMode);
|
||||
|
||||
bool prefToEnabled();
|
||||
uint32_t prefToMask();
|
||||
static uint32_t prefKeyValue(const std::string& key, uint32_t fallback = SDL_SCANCODE_UNKNOWN);
|
||||
|
||||
private:
|
||||
static std::list<std::string> tokenize(const std::string& data,
|
||||
const std::string& delimiter = ",");
|
||||
static bool extract(const std::string& token, uint32_t& key, uint32_t& value);
|
||||
|
||||
UINT32 scancode_to_rdp(Uint32 scancode);
|
||||
|
||||
SdlContext* _sdl;
|
||||
Uint32 _lastWindowID;
|
||||
|
||||
// hotkey handling
|
||||
bool _hotkeysEnabled;
|
||||
uint32_t _hotkeyModmask; // modifier keys mask
|
||||
uint32_t _hotkeyFullscreen;
|
||||
uint32_t _hotkeyResizable;
|
||||
uint32_t _hotkeyGrab;
|
||||
uint32_t _hotkeyDisconnect;
|
||||
uint32_t _hotkeyMinimize;
|
||||
FREERDP_REMAP_TABLE* _remapTable = nullptr;
|
||||
};
|
||||
@@ -36,7 +36,7 @@
|
||||
#define TAG CLIENT_TAG("sdl")
|
||||
|
||||
#include "sdl_monitor.hpp"
|
||||
#include "sdl_freerdp.hpp"
|
||||
#include "sdl_context.hpp"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -81,7 +81,8 @@ int sdl_list_monitors([[maybe_unused]] SdlContext* sdl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BOOL sdl_apply_mon_max_size(SdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
[[nodiscard]] static BOOL sdl_apply_mon_max_size(SdlContext* sdl, UINT32* pMaxWidth,
|
||||
UINT32* pMaxHeight)
|
||||
{
|
||||
int32_t left = 0;
|
||||
int32_t right = 0;
|
||||
@@ -113,7 +114,7 @@ static BOOL sdl_apply_mon_max_size(SdlContext* sdl, UINT32* pMaxWidth, UINT32* p
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL sdl_apply_max_size(SdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
[[nodiscard]] static BOOL sdl_apply_max_size(SdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
WINPR_ASSERT(pMaxWidth);
|
||||
@@ -170,14 +171,15 @@ static BOOL sdl_apply_max_size(SdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxH
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Uint32 scale(Uint32 val, float scale)
|
||||
[[nodiscard]] static Uint32 scale(Uint32 val, float scale)
|
||||
{
|
||||
const auto dval = static_cast<float>(val);
|
||||
const auto sval = dval / scale;
|
||||
return static_cast<Uint32>(sval);
|
||||
}
|
||||
|
||||
static BOOL sdl_apply_monitor_properties(rdpMonitor& monitor, SDL_DisplayID id, bool isPrimary)
|
||||
[[nodiscard]] static BOOL sdl_apply_monitor_properties(rdpMonitor& monitor, SDL_DisplayID id,
|
||||
bool isPrimary)
|
||||
{
|
||||
|
||||
float dpi = SDL_GetDisplayContentScale(id);
|
||||
@@ -248,7 +250,7 @@ static BOOL sdl_apply_monitor_properties(rdpMonitor& monitor, SDL_DisplayID id,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL sdl_apply_display_properties(SdlContext* sdl)
|
||||
[[nodiscard]] static BOOL sdl_apply_display_properties(SdlContext* sdl)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
|
||||
@@ -285,7 +287,8 @@ static BOOL sdl_apply_display_properties(SdlContext* sdl)
|
||||
monitors.size());
|
||||
}
|
||||
|
||||
static BOOL sdl_detect_single_window(SdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
[[nodiscard]] static BOOL sdl_detect_single_window(SdlContext* sdl, UINT32* pMaxWidth,
|
||||
UINT32* pMaxHeight)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
WINPR_ASSERT(pMaxWidth);
|
||||
|
||||
@@ -24,5 +24,5 @@
|
||||
|
||||
#include "sdl_types.hpp"
|
||||
|
||||
int sdl_list_monitors(SdlContext* sdl);
|
||||
BOOL sdl_detect_monitors(SdlContext* sdl, UINT32* pMaxWidth, UINT32* ppMaxHeight);
|
||||
[[nodiscard]] int sdl_list_monitors(SdlContext* sdl);
|
||||
[[nodiscard]] BOOL sdl_detect_monitors(SdlContext* sdl, UINT32* pMaxWidth, UINT32* ppMaxHeight);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#include "sdl_pointer.hpp"
|
||||
#include "sdl_freerdp.hpp"
|
||||
#include "sdl_context.hpp"
|
||||
#include "sdl_touch.hpp"
|
||||
#include "sdl_utils.hpp"
|
||||
|
||||
@@ -37,7 +37,7 @@ typedef struct
|
||||
void* data;
|
||||
} sdlPointer;
|
||||
|
||||
static BOOL sdl_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||
[[nodiscard]] static BOOL sdl_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||
{
|
||||
auto ptr = reinterpret_cast<sdlPointer*>(pointer);
|
||||
|
||||
@@ -90,14 +90,14 @@ static void sdl_Pointer_Free(rdpContext* context, rdpPointer* pointer)
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL sdl_Pointer_SetDefault(rdpContext* context)
|
||||
[[nodiscard]] static BOOL sdl_Pointer_SetDefault(rdpContext* context)
|
||||
{
|
||||
WINPR_UNUSED(context);
|
||||
|
||||
return sdl_push_user_event(SDL_EVENT_USER_POINTER_DEFAULT);
|
||||
}
|
||||
|
||||
static BOOL sdl_Pointer_Set(rdpContext* context, rdpPointer* pointer)
|
||||
[[nodiscard]] static BOOL sdl_Pointer_Set(rdpContext* context, rdpPointer* pointer)
|
||||
{
|
||||
WINPR_UNUSED(context);
|
||||
return sdl_push_user_event(SDL_EVENT_USER_POINTER_SET, pointer);
|
||||
@@ -105,9 +105,6 @@ static BOOL sdl_Pointer_Set(rdpContext* context, rdpPointer* pointer)
|
||||
|
||||
BOOL sdl_Pointer_Set_Process(SdlContext* sdl)
|
||||
{
|
||||
INT32 w = 0;
|
||||
INT32 h = 0;
|
||||
|
||||
WINPR_ASSERT(sdl);
|
||||
|
||||
auto context = sdl->context();
|
||||
@@ -119,10 +116,10 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl)
|
||||
rdpGdi* gdi = context->gdi;
|
||||
WINPR_ASSERT(gdi);
|
||||
|
||||
auto x = static_cast<INT32>(pointer->xPos);
|
||||
auto y = static_cast<INT32>(pointer->yPos);
|
||||
auto sw = w = static_cast<INT32>(pointer->width);
|
||||
auto sh = h = static_cast<INT32>(pointer->height);
|
||||
auto ix = static_cast<float>(pointer->xPos);
|
||||
auto iy = static_cast<float>(pointer->yPos);
|
||||
auto isw = static_cast<float>(pointer->width);
|
||||
auto ish = static_cast<float>(pointer->height);
|
||||
|
||||
SDL_Window* window = SDL_GetMouseFocus();
|
||||
if (!window)
|
||||
@@ -130,13 +127,12 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl)
|
||||
|
||||
const Uint32 id = SDL_GetWindowID(window);
|
||||
|
||||
if (!sdl_scale_coordinates(sdl, id, &x, &y, FALSE, FALSE) ||
|
||||
!sdl_scale_coordinates(sdl, id, &sw, &sh, FALSE, FALSE))
|
||||
return FALSE;
|
||||
auto pos = sdl->pixelToScreen(id, SDL_FRect{ ix, iy, isw, ish });
|
||||
|
||||
sdl_Pointer_Clear(ptr);
|
||||
|
||||
ptr->image = SDL_CreateSurface(sw, sh, sdl->sdl_pixel_format);
|
||||
ptr->image =
|
||||
SDL_CreateSurface(static_cast<int>(pos.w), static_cast<int>(pos.h), sdl->pixelFormat());
|
||||
if (!ptr->image)
|
||||
return FALSE;
|
||||
|
||||
@@ -146,27 +142,28 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl)
|
||||
const BOOL rc = freerdp_image_scale(
|
||||
pixels, gdi->dstFormat, static_cast<UINT32>(ptr->image->pitch), 0, 0,
|
||||
static_cast<UINT32>(ptr->image->w), static_cast<UINT32>(ptr->image->h), data,
|
||||
gdi->dstFormat, 0, 0, 0, static_cast<UINT32>(w), static_cast<UINT32>(h));
|
||||
gdi->dstFormat, 0, 0, 0, static_cast<UINT32>(isw), static_cast<UINT32>(ish));
|
||||
SDL_UnlockSurface(ptr->image);
|
||||
if (!rc)
|
||||
return FALSE;
|
||||
|
||||
// create a cursor image in 100% display scale to trick SDL into creating the cursor with the
|
||||
// correct size
|
||||
auto it = sdl->windows.begin();
|
||||
if (it == sdl->windows.end())
|
||||
auto fw = sdl->getFirstWindow();
|
||||
if (!fw)
|
||||
return FALSE;
|
||||
|
||||
const auto hidpi_scale = SDL_GetWindowDisplayScale(it->second.window());
|
||||
auto normal = SDL_CreateSurface(
|
||||
static_cast<int>(static_cast<float>(ptr->image->w) / hidpi_scale),
|
||||
static_cast<int>(static_cast<float>(ptr->image->h) / hidpi_scale), ptr->image->format);
|
||||
const auto hidpi_scale =
|
||||
sdl->pixelToScreen(fw->id(), SDL_FPoint{ static_cast<float>(ptr->image->w),
|
||||
static_cast<float>(ptr->image->h) });
|
||||
auto normal = SDL_CreateSurface(static_cast<int>(hidpi_scale.x),
|
||||
static_cast<int>(hidpi_scale.y), ptr->image->format);
|
||||
assert(normal);
|
||||
SDL_BlitSurfaceScaled(ptr->image, nullptr, normal, nullptr,
|
||||
SDL_ScaleMode::SDL_SCALEMODE_LINEAR);
|
||||
SDL_AddSurfaceAlternateImage(normal, ptr->image);
|
||||
|
||||
ptr->cursor = SDL_CreateColorCursor(normal, x, y);
|
||||
ptr->cursor = SDL_CreateColorCursor(normal, static_cast<int>(pos.x), static_cast<int>(pos.y));
|
||||
if (!ptr->cursor)
|
||||
return FALSE;
|
||||
|
||||
@@ -178,14 +175,14 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL sdl_Pointer_SetNull(rdpContext* context)
|
||||
[[nodiscard]] static BOOL sdl_Pointer_SetNull(rdpContext* context)
|
||||
{
|
||||
WINPR_UNUSED(context);
|
||||
|
||||
return sdl_push_user_event(SDL_EVENT_USER_POINTER_NULL);
|
||||
}
|
||||
|
||||
static BOOL sdl_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y)
|
||||
[[nodiscard]] static BOOL sdl_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y)
|
||||
{
|
||||
WINPR_UNUSED(context);
|
||||
WINPR_ASSERT(context);
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
|
||||
#include <freerdp/graphics.h>
|
||||
|
||||
BOOL sdl_register_pointer(rdpGraphics* graphics);
|
||||
[[nodiscard]] BOOL sdl_register_pointer(rdpGraphics* graphics);
|
||||
|
||||
BOOL sdl_Pointer_Set_Process(SdlContext* sdl);
|
||||
[[nodiscard]] BOOL sdl_Pointer_Set_Process(SdlContext* sdl);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <freerdp/config.h>
|
||||
|
||||
#include "sdl_touch.hpp"
|
||||
#include "sdl_freerdp.hpp"
|
||||
#include "sdl_context.hpp"
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/assert.h>
|
||||
@@ -30,95 +30,7 @@
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
BOOL sdl_scale_coordinates(SdlContext* sdl, Uint32 windowId, INT32* px, INT32* py,
|
||||
BOOL fromLocalToRDP, BOOL applyOffset)
|
||||
{
|
||||
rdpGdi* gdi = nullptr;
|
||||
double sx = 1.0;
|
||||
double sy = 1.0;
|
||||
|
||||
if (!sdl || !px || !py || !sdl->context()->gdi)
|
||||
return FALSE;
|
||||
|
||||
WINPR_ASSERT(sdl->context()->gdi);
|
||||
WINPR_ASSERT(sdl->context()->settings);
|
||||
|
||||
gdi = sdl->context()->gdi;
|
||||
|
||||
// TODO: Make this multimonitor ready!
|
||||
// TODO: Need to find the primary monitor, get the scale
|
||||
// TODO: Need to find the destination monitor, get the scale
|
||||
// TODO: All intermediate monitors, get the scale
|
||||
|
||||
int offset_x = 0;
|
||||
int offset_y = 0;
|
||||
for (const auto& it : sdl->windows)
|
||||
{
|
||||
auto& window = it.second;
|
||||
const auto id = window.id();
|
||||
if (id != windowId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto size = window.rect();
|
||||
|
||||
sx = size.w / static_cast<double>(gdi->width);
|
||||
sy = size.h / static_cast<double>(gdi->height);
|
||||
offset_x = window.offsetX();
|
||||
offset_y = window.offsetY();
|
||||
break;
|
||||
}
|
||||
|
||||
if (freerdp_settings_get_bool(sdl->context()->settings, FreeRDP_SmartSizing))
|
||||
{
|
||||
if (!fromLocalToRDP)
|
||||
{
|
||||
*px = static_cast<INT32>(*px * sx);
|
||||
*py = static_cast<INT32>(*py * sy);
|
||||
}
|
||||
else
|
||||
{
|
||||
*px = static_cast<INT32>(*px / sx);
|
||||
*py = static_cast<INT32>(*py / sy);
|
||||
}
|
||||
}
|
||||
else if (applyOffset)
|
||||
{
|
||||
*px -= offset_x;
|
||||
*py -= offset_y;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL sdl_get_touch_scaled(SdlContext* sdl, const SDL_TouchFingerEvent* ev, INT32* px,
|
||||
INT32* py, BOOL local)
|
||||
{
|
||||
Uint32 windowID = 0;
|
||||
|
||||
WINPR_ASSERT(sdl);
|
||||
WINPR_ASSERT(ev);
|
||||
WINPR_ASSERT(px);
|
||||
WINPR_ASSERT(py);
|
||||
|
||||
SDL_Window* window = SDL_GetWindowFromID(ev->windowID);
|
||||
|
||||
if (!window)
|
||||
return FALSE;
|
||||
|
||||
windowID = SDL_GetWindowID(window);
|
||||
SDL_Surface* surface = SDL_GetWindowSurface(window);
|
||||
if (!surface)
|
||||
return FALSE;
|
||||
|
||||
// TODO: Add the offset of the surface in the global coordinates
|
||||
*px = static_cast<INT32>(ev->x * static_cast<float>(surface->w));
|
||||
*py = static_cast<INT32>(ev->y * static_cast<float>(surface->h));
|
||||
return sdl_scale_coordinates(sdl, windowID, px, py, local, TRUE);
|
||||
}
|
||||
|
||||
static BOOL send_mouse_wheel(SdlContext* sdl, UINT16 flags, INT32 avalue)
|
||||
[[nodiscard]] static bool send_mouse_wheel(SdlContext* sdl, UINT16 flags, INT32 avalue)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
if (avalue < 0)
|
||||
@@ -142,7 +54,7 @@ static BOOL send_mouse_wheel(SdlContext* sdl, UINT16 flags, INT32 avalue)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static UINT32 sdl_scale_pressure(const float pressure)
|
||||
[[nodiscard]] static UINT32 sdl_scale_pressure(const float pressure)
|
||||
{
|
||||
const float val = pressure * 0x400; /* [MS-RDPEI] 2.2.3.3.1.1 RDPINPUT_TOUCH_CONTACT */
|
||||
if (val < 0.0f)
|
||||
@@ -152,101 +64,99 @@ static UINT32 sdl_scale_pressure(const float pressure)
|
||||
return static_cast<UINT32>(val);
|
||||
}
|
||||
|
||||
BOOL sdl_handle_touch_up(SdlContext* sdl, const SDL_TouchFingerEvent* ev)
|
||||
bool SdlTouch::touchUp(SdlContext* sdl, const SDL_TouchFingerEvent& ev)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
WINPR_ASSERT(ev);
|
||||
|
||||
INT32 x = 0;
|
||||
INT32 y = 0;
|
||||
if (!sdl_get_touch_scaled(sdl, ev, &x, &y, TRUE))
|
||||
return FALSE;
|
||||
return freerdp_client_handle_touch(sdl->common(), FREERDP_TOUCH_UP | FREERDP_TOUCH_HAS_PRESSURE,
|
||||
static_cast<INT32>(ev->fingerID),
|
||||
sdl_scale_pressure(ev->pressure), x, y);
|
||||
static_cast<INT32>(ev.fingerID),
|
||||
sdl_scale_pressure(ev.pressure), static_cast<Sint32>(ev.x),
|
||||
static_cast<Sint32>(ev.y));
|
||||
}
|
||||
|
||||
BOOL sdl_handle_touch_down(SdlContext* sdl, const SDL_TouchFingerEvent* ev)
|
||||
bool SdlTouch::touchCancel(SdlContext* sdl, const SDL_TouchFingerEvent& ev)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
|
||||
return freerdp_client_handle_touch(
|
||||
sdl->common(), FREERDP_TOUCH_CANCEL | FREERDP_TOUCH_HAS_PRESSURE,
|
||||
static_cast<INT32>(ev.fingerID), sdl_scale_pressure(ev.pressure), static_cast<Sint32>(ev.x),
|
||||
static_cast<Sint32>(ev.y));
|
||||
}
|
||||
|
||||
bool SdlTouch::touchDown(SdlContext* sdl, const SDL_TouchFingerEvent& ev)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
WINPR_ASSERT(ev);
|
||||
|
||||
INT32 x = 0;
|
||||
INT32 y = 0;
|
||||
if (!sdl_get_touch_scaled(sdl, ev, &x, &y, TRUE))
|
||||
return FALSE;
|
||||
return freerdp_client_handle_touch(
|
||||
sdl->common(), FREERDP_TOUCH_DOWN | FREERDP_TOUCH_HAS_PRESSURE,
|
||||
static_cast<INT32>(ev->fingerID), sdl_scale_pressure(ev->pressure), x, y);
|
||||
static_cast<INT32>(ev.fingerID), sdl_scale_pressure(ev.pressure), static_cast<Sint32>(ev.x),
|
||||
static_cast<Sint32>(ev.y));
|
||||
}
|
||||
|
||||
BOOL sdl_handle_touch_motion(SdlContext* sdl, const SDL_TouchFingerEvent* ev)
|
||||
bool SdlTouch::touchMotion(SdlContext* sdl, const SDL_TouchFingerEvent& ev)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
WINPR_ASSERT(ev);
|
||||
|
||||
INT32 x = 0;
|
||||
INT32 y = 0;
|
||||
if (!sdl_get_touch_scaled(sdl, ev, &x, &y, TRUE))
|
||||
return FALSE;
|
||||
return freerdp_client_handle_touch(
|
||||
sdl->common(), FREERDP_TOUCH_MOTION | FREERDP_TOUCH_HAS_PRESSURE,
|
||||
static_cast<INT32>(ev->fingerID), sdl_scale_pressure(ev->pressure), x, y);
|
||||
static_cast<INT32>(ev.fingerID), sdl_scale_pressure(ev.pressure), static_cast<Sint32>(ev.x),
|
||||
static_cast<Sint32>(ev.y));
|
||||
}
|
||||
|
||||
BOOL sdl_handle_mouse_motion(SdlContext* sdl, const SDL_MouseMotionEvent* ev)
|
||||
bool SdlTouch::handleEvent(SdlContext* sdl, const SDL_MouseMotionEvent& ev)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
WINPR_ASSERT(ev);
|
||||
|
||||
sdl->input.mouse_focus(ev->windowID);
|
||||
if (!sdl->getInputChannelContext().mouse_focus(ev.windowID))
|
||||
return FALSE;
|
||||
|
||||
const BOOL relative =
|
||||
freerdp_client_use_relative_mouse_events(sdl->common()) && !sdl->hasCursor();
|
||||
auto x = static_cast<INT32>(relative ? ev->xrel : ev->x);
|
||||
auto y = static_cast<INT32>(relative ? ev->yrel : ev->y);
|
||||
sdl_scale_coordinates(sdl, ev->windowID, &x, &y, TRUE, TRUE);
|
||||
auto x = static_cast<INT32>(relative ? ev.xrel : ev.x);
|
||||
auto y = static_cast<INT32>(relative ? ev.yrel : ev.y);
|
||||
return freerdp_client_send_button_event(sdl->common(), relative, PTR_FLAGS_MOVE, x, y);
|
||||
}
|
||||
|
||||
BOOL sdl_handle_mouse_wheel(SdlContext* sdl, const SDL_MouseWheelEvent* ev)
|
||||
bool SdlTouch::handleEvent(SdlContext* sdl, const SDL_MouseWheelEvent& ev)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
WINPR_ASSERT(ev);
|
||||
|
||||
const BOOL flipped = (ev->direction == SDL_MOUSEWHEEL_FLIPPED);
|
||||
const auto x = static_cast<INT32>(ev->x * (flipped ? -1.0f : 1.0f) * 120.0f);
|
||||
const auto y = static_cast<INT32>(ev->y * (flipped ? -1.0f : 1.0f) * 120.0f);
|
||||
const BOOL flipped = (ev.direction == SDL_MOUSEWHEEL_FLIPPED);
|
||||
const auto x = static_cast<INT32>(ev.x * (flipped ? -1.0f : 1.0f) * 120.0f);
|
||||
const auto y = static_cast<INT32>(ev.y * (flipped ? -1.0f : 1.0f) * 120.0f);
|
||||
UINT16 flags = 0;
|
||||
|
||||
if (y != 0)
|
||||
{
|
||||
flags |= PTR_FLAGS_WHEEL;
|
||||
send_mouse_wheel(sdl, flags, y);
|
||||
if (!send_mouse_wheel(sdl, flags, y))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (x != 0)
|
||||
{
|
||||
flags |= PTR_FLAGS_HWHEEL;
|
||||
send_mouse_wheel(sdl, flags, x);
|
||||
if (!send_mouse_wheel(sdl, flags, x))
|
||||
return false;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL sdl_handle_mouse_button(SdlContext* sdl, const SDL_MouseButtonEvent* ev)
|
||||
bool SdlTouch::handleEvent(SdlContext* sdl, const SDL_MouseButtonEvent& ev)
|
||||
{
|
||||
UINT16 flags = 0;
|
||||
UINT16 xflags = 0;
|
||||
|
||||
WINPR_ASSERT(sdl);
|
||||
WINPR_ASSERT(ev);
|
||||
|
||||
if (ev->type == SDL_EVENT_MOUSE_BUTTON_DOWN)
|
||||
if (ev.type == SDL_EVENT_MOUSE_BUTTON_DOWN)
|
||||
{
|
||||
flags |= PTR_FLAGS_DOWN;
|
||||
xflags |= PTR_XFLAGS_DOWN;
|
||||
}
|
||||
|
||||
switch (ev->button)
|
||||
switch (ev.button)
|
||||
{
|
||||
case 1:
|
||||
flags |= PTR_FLAGS_BUTTON1;
|
||||
@@ -269,9 +179,9 @@ BOOL sdl_handle_mouse_button(SdlContext* sdl, const SDL_MouseButtonEvent* ev)
|
||||
|
||||
const BOOL relative =
|
||||
freerdp_client_use_relative_mouse_events(sdl->common()) && !sdl->hasCursor();
|
||||
auto x = static_cast<INT32>(relative ? 0 : ev->x);
|
||||
auto y = static_cast<INT32>(relative ? 0 : ev->y);
|
||||
sdl_scale_coordinates(sdl, ev->windowID, &x, &y, TRUE, TRUE);
|
||||
auto x = static_cast<INT32>(relative ? 0 : ev.x);
|
||||
auto y = static_cast<INT32>(relative ? 0 : ev.y);
|
||||
|
||||
if ((flags & (~PTR_FLAGS_DOWN)) != 0)
|
||||
return freerdp_client_send_button_event(sdl->common(), relative, flags, x, y);
|
||||
else if ((xflags & (~PTR_XFLAGS_DOWN)) != 0)
|
||||
@@ -279,3 +189,20 @@ BOOL sdl_handle_mouse_button(SdlContext* sdl, const SDL_MouseButtonEvent* ev)
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool SdlTouch::handleEvent(SdlContext* sdl, const SDL_TouchFingerEvent& ev)
|
||||
{
|
||||
switch (ev.type)
|
||||
{
|
||||
case SDL_EVENT_FINGER_CANCELED:
|
||||
return SdlTouch::touchCancel(sdl, ev);
|
||||
case SDL_EVENT_FINGER_UP:
|
||||
return SdlTouch::touchUp(sdl, ev);
|
||||
case SDL_EVENT_FINGER_DOWN:
|
||||
return SdlTouch::touchDown(sdl, ev);
|
||||
case SDL_EVENT_FINGER_MOTION:
|
||||
return SdlTouch::touchMotion(sdl, ev);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,13 +24,18 @@
|
||||
#include <SDL3/SDL.h>
|
||||
#include "sdl_types.hpp"
|
||||
|
||||
BOOL sdl_scale_coordinates(SdlContext* sdl, Uint32 windowId, INT32* px, INT32* py,
|
||||
BOOL fromLocalToRDP, BOOL applyOffset);
|
||||
class SdlTouch
|
||||
{
|
||||
public:
|
||||
[[nodiscard]] static bool handleEvent(SdlContext* sdl, const SDL_MouseMotionEvent& ev);
|
||||
[[nodiscard]] static bool handleEvent(SdlContext* sdl, const SDL_MouseWheelEvent& ev);
|
||||
[[nodiscard]] static bool handleEvent(SdlContext* sdl, const SDL_MouseButtonEvent& ev);
|
||||
|
||||
BOOL sdl_handle_mouse_motion(SdlContext* sdl, const SDL_MouseMotionEvent* ev);
|
||||
BOOL sdl_handle_mouse_wheel(SdlContext* sdl, const SDL_MouseWheelEvent* ev);
|
||||
BOOL sdl_handle_mouse_button(SdlContext* sdl, const SDL_MouseButtonEvent* ev);
|
||||
[[nodiscard]] static bool handleEvent(SdlContext* sdl, const SDL_TouchFingerEvent& ev);
|
||||
|
||||
BOOL sdl_handle_touch_down(SdlContext* sdl, const SDL_TouchFingerEvent* ev);
|
||||
BOOL sdl_handle_touch_up(SdlContext* sdl, const SDL_TouchFingerEvent* ev);
|
||||
BOOL sdl_handle_touch_motion(SdlContext* sdl, const SDL_TouchFingerEvent* ev);
|
||||
private:
|
||||
[[nodiscard]] static bool touchDown(SdlContext* sdl, const SDL_TouchFingerEvent& ev);
|
||||
[[nodiscard]] static bool touchUp(SdlContext* sdl, const SDL_TouchFingerEvent& ev);
|
||||
[[nodiscard]] static bool touchCancel(SdlContext* sdl, const SDL_TouchFingerEvent& ev);
|
||||
[[nodiscard]] static bool touchMotion(SdlContext* sdl, const SDL_TouchFingerEvent& ev);
|
||||
};
|
||||
|
||||
@@ -29,7 +29,7 @@ typedef struct
|
||||
SdlContext* sdl;
|
||||
} sdl_rdp_context;
|
||||
|
||||
static inline SdlContext* get_context(void* ctx)
|
||||
[[nodiscard]] static inline SdlContext* get_context(void* ctx)
|
||||
{
|
||||
if (!ctx)
|
||||
return nullptr;
|
||||
@@ -37,7 +37,7 @@ static inline SdlContext* get_context(void* ctx)
|
||||
return sdl->sdl;
|
||||
}
|
||||
|
||||
static inline SdlContext* get_context(rdpContext* ctx)
|
||||
[[nodiscard]] static inline SdlContext* get_context(rdpContext* ctx)
|
||||
{
|
||||
if (!ctx)
|
||||
return nullptr;
|
||||
|
||||
@@ -29,152 +29,13 @@
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <freerdp/version.h>
|
||||
#include <freerdp/utils/string.h>
|
||||
|
||||
#define STR(x) #x
|
||||
#define EV_CASE_STR(x) \
|
||||
case x: \
|
||||
return STR(x)
|
||||
|
||||
const char* sdl_event_type_str(Uint32 type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
EV_CASE_STR(SDL_EVENT_FIRST);
|
||||
EV_CASE_STR(SDL_EVENT_QUIT);
|
||||
EV_CASE_STR(SDL_EVENT_TERMINATING);
|
||||
EV_CASE_STR(SDL_EVENT_LOW_MEMORY);
|
||||
EV_CASE_STR(SDL_EVENT_WILL_ENTER_BACKGROUND);
|
||||
EV_CASE_STR(SDL_EVENT_DID_ENTER_BACKGROUND);
|
||||
EV_CASE_STR(SDL_EVENT_WILL_ENTER_FOREGROUND);
|
||||
EV_CASE_STR(SDL_EVENT_DID_ENTER_FOREGROUND);
|
||||
EV_CASE_STR(SDL_EVENT_LOCALE_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_SYSTEM_THEME_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_DISPLAY_ORIENTATION);
|
||||
EV_CASE_STR(SDL_EVENT_DISPLAY_ADDED);
|
||||
EV_CASE_STR(SDL_EVENT_DISPLAY_REMOVED);
|
||||
EV_CASE_STR(SDL_EVENT_DISPLAY_MOVED);
|
||||
EV_CASE_STR(SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_SHOWN);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_HIDDEN);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_EXPOSED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_MOVED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_RESIZED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_MINIMIZED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_MAXIMIZED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_RESTORED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_MOUSE_ENTER);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_MOUSE_LEAVE);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_FOCUS_GAINED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_FOCUS_LOST);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_CLOSE_REQUESTED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_HIT_TEST);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_ICCPROF_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_DISPLAY_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_OCCLUDED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_ENTER_FULLSCREEN);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_LEAVE_FULLSCREEN);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_DESTROYED);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_KEY_DOWN);
|
||||
EV_CASE_STR(SDL_EVENT_KEY_UP);
|
||||
EV_CASE_STR(SDL_EVENT_TEXT_EDITING);
|
||||
EV_CASE_STR(SDL_EVENT_TEXT_INPUT);
|
||||
EV_CASE_STR(SDL_EVENT_KEYMAP_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_KEYBOARD_ADDED);
|
||||
EV_CASE_STR(SDL_EVENT_KEYBOARD_REMOVED);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_MOUSE_MOTION);
|
||||
EV_CASE_STR(SDL_EVENT_MOUSE_BUTTON_DOWN);
|
||||
EV_CASE_STR(SDL_EVENT_MOUSE_BUTTON_UP);
|
||||
EV_CASE_STR(SDL_EVENT_MOUSE_WHEEL);
|
||||
EV_CASE_STR(SDL_EVENT_MOUSE_ADDED);
|
||||
EV_CASE_STR(SDL_EVENT_MOUSE_REMOVED);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_AXIS_MOTION);
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_BALL_MOTION);
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_HAT_MOTION);
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_BUTTON_DOWN);
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_BUTTON_UP);
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_ADDED);
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_REMOVED);
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_BATTERY_UPDATED);
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_UPDATE_COMPLETE);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_AXIS_MOTION);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_BUTTON_DOWN);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_BUTTON_UP);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_ADDED);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_REMOVED);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_REMAPPED);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_TOUCHPAD_UP);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_SENSOR_UPDATE);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_UPDATE_COMPLETE);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_FINGER_DOWN);
|
||||
EV_CASE_STR(SDL_EVENT_FINGER_UP);
|
||||
EV_CASE_STR(SDL_EVENT_FINGER_MOTION);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_CLIPBOARD_UPDATE);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_DROP_FILE);
|
||||
EV_CASE_STR(SDL_EVENT_DROP_TEXT);
|
||||
EV_CASE_STR(SDL_EVENT_DROP_BEGIN);
|
||||
EV_CASE_STR(SDL_EVENT_DROP_COMPLETE);
|
||||
EV_CASE_STR(SDL_EVENT_DROP_POSITION);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_AUDIO_DEVICE_ADDED);
|
||||
EV_CASE_STR(SDL_EVENT_AUDIO_DEVICE_REMOVED);
|
||||
EV_CASE_STR(SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_SENSOR_UPDATE);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_PEN_DOWN);
|
||||
EV_CASE_STR(SDL_EVENT_PEN_UP);
|
||||
EV_CASE_STR(SDL_EVENT_PEN_MOTION);
|
||||
EV_CASE_STR(SDL_EVENT_PEN_BUTTON_DOWN);
|
||||
EV_CASE_STR(SDL_EVENT_PEN_BUTTON_UP);
|
||||
EV_CASE_STR(SDL_EVENT_CAMERA_DEVICE_ADDED);
|
||||
EV_CASE_STR(SDL_EVENT_CAMERA_DEVICE_REMOVED);
|
||||
EV_CASE_STR(SDL_EVENT_CAMERA_DEVICE_APPROVED);
|
||||
EV_CASE_STR(SDL_EVENT_CAMERA_DEVICE_DENIED);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_RENDER_TARGETS_RESET);
|
||||
EV_CASE_STR(SDL_EVENT_RENDER_DEVICE_RESET);
|
||||
EV_CASE_STR(SDL_EVENT_POLL_SENTINEL);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_USER);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_USER_CERT_DIALOG);
|
||||
EV_CASE_STR(SDL_EVENT_USER_CERT_RESULT);
|
||||
EV_CASE_STR(SDL_EVENT_USER_SHOW_DIALOG);
|
||||
EV_CASE_STR(SDL_EVENT_USER_SHOW_RESULT);
|
||||
EV_CASE_STR(SDL_EVENT_USER_AUTH_DIALOG);
|
||||
EV_CASE_STR(SDL_EVENT_USER_AUTH_RESULT);
|
||||
EV_CASE_STR(SDL_EVENT_USER_SCARD_DIALOG);
|
||||
EV_CASE_STR(SDL_EVENT_USER_RETRY_DIALOG);
|
||||
EV_CASE_STR(SDL_EVENT_USER_SCARD_RESULT);
|
||||
EV_CASE_STR(SDL_EVENT_USER_UPDATE);
|
||||
EV_CASE_STR(SDL_EVENT_USER_CREATE_WINDOWS);
|
||||
EV_CASE_STR(SDL_EVENT_USER_WINDOW_RESIZEABLE);
|
||||
EV_CASE_STR(SDL_EVENT_USER_WINDOW_FULLSCREEN);
|
||||
EV_CASE_STR(SDL_EVENT_USER_WINDOW_MINIMIZE);
|
||||
EV_CASE_STR(SDL_EVENT_USER_POINTER_NULL);
|
||||
EV_CASE_STR(SDL_EVENT_USER_POINTER_DEFAULT);
|
||||
EV_CASE_STR(SDL_EVENT_USER_POINTER_POSITION);
|
||||
EV_CASE_STR(SDL_EVENT_USER_POINTER_SET);
|
||||
EV_CASE_STR(SDL_EVENT_USER_QUIT);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_LAST);
|
||||
default:
|
||||
return "SDL_UNKNOWNEVENT";
|
||||
}
|
||||
}
|
||||
|
||||
const char* sdl_error_string(Sint32 res)
|
||||
{
|
||||
if (res == 0)
|
||||
@@ -294,99 +155,434 @@ bool sdl_push_quit()
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string sdl_window_event_str(Uint32 ev)
|
||||
namespace sdl::utils
|
||||
{
|
||||
if ((ev >= SDL_EVENT_WINDOW_FIRST) && (ev <= SDL_EVENT_WINDOW_LAST))
|
||||
return sdl_event_type_str(ev);
|
||||
|
||||
return "SDL_EVENT_WINDOW_UNKNOWN";
|
||||
}
|
||||
|
||||
UINT32 sdl::utils::orientaion_to_rdp(SDL_DisplayOrientation orientation)
|
||||
{
|
||||
switch (orientation)
|
||||
UINT32 orientaion_to_rdp(SDL_DisplayOrientation orientation)
|
||||
{
|
||||
case SDL_ORIENTATION_LANDSCAPE:
|
||||
return ORIENTATION_LANDSCAPE;
|
||||
case SDL_ORIENTATION_LANDSCAPE_FLIPPED:
|
||||
return ORIENTATION_LANDSCAPE_FLIPPED;
|
||||
case SDL_ORIENTATION_PORTRAIT_FLIPPED:
|
||||
return ORIENTATION_PORTRAIT_FLIPPED;
|
||||
case SDL_ORIENTATION_PORTRAIT:
|
||||
default:
|
||||
return ORIENTATION_PORTRAIT;
|
||||
}
|
||||
}
|
||||
|
||||
std::string sdl::utils::sdl_orientation_to_str(SDL_DisplayOrientation orientation)
|
||||
{
|
||||
switch (orientation)
|
||||
{
|
||||
case SDL_ORIENTATION_LANDSCAPE:
|
||||
return "SDL_ORIENTATION_LANDSCAPE";
|
||||
case SDL_ORIENTATION_LANDSCAPE_FLIPPED:
|
||||
return "SDL_ORIENTATION_LANDSCAPE_FLIPPED";
|
||||
case SDL_ORIENTATION_PORTRAIT_FLIPPED:
|
||||
return "SDL_ORIENTATION_PORTRAIT_FLIPPED";
|
||||
case SDL_ORIENTATION_PORTRAIT:
|
||||
return "SDL_ORIENTATION_PORTRAIT";
|
||||
default:
|
||||
return "SDL_ORIENTATION_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
std::string sdl::utils::rdp_orientation_to_str(uint32_t orientation)
|
||||
{
|
||||
switch (orientation)
|
||||
{
|
||||
case ORIENTATION_LANDSCAPE:
|
||||
return "ORIENTATION_LANDSCAPE";
|
||||
case ORIENTATION_LANDSCAPE_FLIPPED:
|
||||
return "ORIENTATION_LANDSCAPE_FLIPPED";
|
||||
case ORIENTATION_PORTRAIT_FLIPPED:
|
||||
return "ORIENTATION_PORTRAIT_FLIPPED";
|
||||
case ORIENTATION_PORTRAIT:
|
||||
return "ORIENTATION_PORTRAIT";
|
||||
default:
|
||||
switch (orientation)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "ORIENTATION_UNKNOWN_" << std::hex << std::setfill('0') << std::setw(8)
|
||||
<< orientation;
|
||||
return ss.str();
|
||||
case SDL_ORIENTATION_LANDSCAPE:
|
||||
return ORIENTATION_LANDSCAPE;
|
||||
case SDL_ORIENTATION_LANDSCAPE_FLIPPED:
|
||||
return ORIENTATION_LANDSCAPE_FLIPPED;
|
||||
case SDL_ORIENTATION_PORTRAIT_FLIPPED:
|
||||
return ORIENTATION_PORTRAIT_FLIPPED;
|
||||
case SDL_ORIENTATION_PORTRAIT:
|
||||
default:
|
||||
return ORIENTATION_PORTRAIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string sdl::utils::generate_uuid_v4()
|
||||
std::string touchFlagsToString(Uint32 flags)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "{";
|
||||
bool first = true;
|
||||
for (size_t x = 0; x < 32; x++)
|
||||
{
|
||||
const Uint32 mask = 1u << x;
|
||||
if (flags & mask)
|
||||
{
|
||||
if (!first)
|
||||
ss << "|";
|
||||
first = false;
|
||||
ss << freerdp_input_touch_state_string(mask);
|
||||
}
|
||||
}
|
||||
ss << "}";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string toString(SDL_DisplayOrientation orientation)
|
||||
{
|
||||
switch (orientation)
|
||||
{
|
||||
case SDL_ORIENTATION_LANDSCAPE:
|
||||
return "SDL_ORIENTATION_LANDSCAPE";
|
||||
case SDL_ORIENTATION_LANDSCAPE_FLIPPED:
|
||||
return "SDL_ORIENTATION_LANDSCAPE_FLIPPED";
|
||||
case SDL_ORIENTATION_PORTRAIT_FLIPPED:
|
||||
return "SDL_ORIENTATION_PORTRAIT_FLIPPED";
|
||||
case SDL_ORIENTATION_PORTRAIT:
|
||||
return "SDL_ORIENTATION_PORTRAIT";
|
||||
default:
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "SDL_ORIENTATION_UNKNOWN[0x" << std::hex << std::setw(8) << std::setfill('0')
|
||||
<< orientation << "]";
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string toString(FreeRDP_DesktopRotationFlags orientation)
|
||||
{
|
||||
return freerdp_desktop_rotation_flags_to_string(orientation);
|
||||
}
|
||||
|
||||
std::string toString(const SDL_DisplayMode* mode)
|
||||
{
|
||||
if (!mode)
|
||||
return "SDL_DisplayMode=null";
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "["
|
||||
<< "id=" << mode->displayID << ","
|
||||
<< "fmt=" << mode->format << ","
|
||||
<< "w=" << mode->w << ","
|
||||
<< "h=" << mode->h << ","
|
||||
<< "dpi=" << mode->pixel_density << ","
|
||||
<< "refresh=" << mode->refresh_rate << ","
|
||||
<< "num=" << mode->refresh_rate_numerator << ","
|
||||
<< "denom=" << mode->refresh_rate_denominator << "]";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string toString(Uint32 type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
EV_CASE_STR(SDL_EVENT_FIRST);
|
||||
EV_CASE_STR(SDL_EVENT_QUIT);
|
||||
EV_CASE_STR(SDL_EVENT_TERMINATING);
|
||||
EV_CASE_STR(SDL_EVENT_LOW_MEMORY);
|
||||
EV_CASE_STR(SDL_EVENT_WILL_ENTER_BACKGROUND);
|
||||
EV_CASE_STR(SDL_EVENT_DID_ENTER_BACKGROUND);
|
||||
EV_CASE_STR(SDL_EVENT_WILL_ENTER_FOREGROUND);
|
||||
EV_CASE_STR(SDL_EVENT_DID_ENTER_FOREGROUND);
|
||||
EV_CASE_STR(SDL_EVENT_LOCALE_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_SYSTEM_THEME_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_DISPLAY_ORIENTATION);
|
||||
EV_CASE_STR(SDL_EVENT_DISPLAY_ADDED);
|
||||
EV_CASE_STR(SDL_EVENT_DISPLAY_REMOVED);
|
||||
EV_CASE_STR(SDL_EVENT_DISPLAY_MOVED);
|
||||
EV_CASE_STR(SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_SHOWN);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_HIDDEN);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_EXPOSED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_MOVED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_RESIZED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_MINIMIZED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_MAXIMIZED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_RESTORED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_MOUSE_ENTER);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_MOUSE_LEAVE);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_FOCUS_GAINED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_FOCUS_LOST);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_CLOSE_REQUESTED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_HIT_TEST);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_ICCPROF_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_DISPLAY_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_SAFE_AREA_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_OCCLUDED);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_ENTER_FULLSCREEN);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_LEAVE_FULLSCREEN);
|
||||
EV_CASE_STR(SDL_EVENT_WINDOW_DESTROYED);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_KEY_DOWN);
|
||||
EV_CASE_STR(SDL_EVENT_KEY_UP);
|
||||
EV_CASE_STR(SDL_EVENT_TEXT_EDITING);
|
||||
EV_CASE_STR(SDL_EVENT_TEXT_INPUT);
|
||||
EV_CASE_STR(SDL_EVENT_KEYMAP_CHANGED);
|
||||
EV_CASE_STR(SDL_EVENT_KEYBOARD_ADDED);
|
||||
EV_CASE_STR(SDL_EVENT_KEYBOARD_REMOVED);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_MOUSE_MOTION);
|
||||
EV_CASE_STR(SDL_EVENT_MOUSE_BUTTON_DOWN);
|
||||
EV_CASE_STR(SDL_EVENT_MOUSE_BUTTON_UP);
|
||||
EV_CASE_STR(SDL_EVENT_MOUSE_WHEEL);
|
||||
EV_CASE_STR(SDL_EVENT_MOUSE_ADDED);
|
||||
EV_CASE_STR(SDL_EVENT_MOUSE_REMOVED);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_AXIS_MOTION);
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_BALL_MOTION);
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_HAT_MOTION);
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_BUTTON_DOWN);
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_BUTTON_UP);
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_ADDED);
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_REMOVED);
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_BATTERY_UPDATED);
|
||||
EV_CASE_STR(SDL_EVENT_JOYSTICK_UPDATE_COMPLETE);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_AXIS_MOTION);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_BUTTON_DOWN);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_BUTTON_UP);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_ADDED);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_REMOVED);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_REMAPPED);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_TOUCHPAD_UP);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_SENSOR_UPDATE);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_UPDATE_COMPLETE);
|
||||
EV_CASE_STR(SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_FINGER_DOWN);
|
||||
EV_CASE_STR(SDL_EVENT_FINGER_UP);
|
||||
EV_CASE_STR(SDL_EVENT_FINGER_MOTION);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_CLIPBOARD_UPDATE);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_DROP_FILE);
|
||||
EV_CASE_STR(SDL_EVENT_DROP_TEXT);
|
||||
EV_CASE_STR(SDL_EVENT_DROP_BEGIN);
|
||||
EV_CASE_STR(SDL_EVENT_DROP_COMPLETE);
|
||||
EV_CASE_STR(SDL_EVENT_DROP_POSITION);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_AUDIO_DEVICE_ADDED);
|
||||
EV_CASE_STR(SDL_EVENT_AUDIO_DEVICE_REMOVED);
|
||||
EV_CASE_STR(SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_SENSOR_UPDATE);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_PEN_DOWN);
|
||||
EV_CASE_STR(SDL_EVENT_PEN_UP);
|
||||
EV_CASE_STR(SDL_EVENT_PEN_MOTION);
|
||||
EV_CASE_STR(SDL_EVENT_PEN_BUTTON_DOWN);
|
||||
EV_CASE_STR(SDL_EVENT_PEN_BUTTON_UP);
|
||||
EV_CASE_STR(SDL_EVENT_CAMERA_DEVICE_ADDED);
|
||||
EV_CASE_STR(SDL_EVENT_CAMERA_DEVICE_REMOVED);
|
||||
EV_CASE_STR(SDL_EVENT_CAMERA_DEVICE_APPROVED);
|
||||
EV_CASE_STR(SDL_EVENT_CAMERA_DEVICE_DENIED);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_RENDER_TARGETS_RESET);
|
||||
EV_CASE_STR(SDL_EVENT_RENDER_DEVICE_RESET);
|
||||
EV_CASE_STR(SDL_EVENT_POLL_SENTINEL);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_USER);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_USER_CERT_DIALOG);
|
||||
EV_CASE_STR(SDL_EVENT_USER_CERT_RESULT);
|
||||
EV_CASE_STR(SDL_EVENT_USER_SHOW_DIALOG);
|
||||
EV_CASE_STR(SDL_EVENT_USER_SHOW_RESULT);
|
||||
EV_CASE_STR(SDL_EVENT_USER_AUTH_DIALOG);
|
||||
EV_CASE_STR(SDL_EVENT_USER_AUTH_RESULT);
|
||||
EV_CASE_STR(SDL_EVENT_USER_SCARD_DIALOG);
|
||||
EV_CASE_STR(SDL_EVENT_USER_RETRY_DIALOG);
|
||||
EV_CASE_STR(SDL_EVENT_USER_SCARD_RESULT);
|
||||
EV_CASE_STR(SDL_EVENT_USER_UPDATE);
|
||||
EV_CASE_STR(SDL_EVENT_USER_CREATE_WINDOWS);
|
||||
EV_CASE_STR(SDL_EVENT_USER_WINDOW_RESIZEABLE);
|
||||
EV_CASE_STR(SDL_EVENT_USER_WINDOW_FULLSCREEN);
|
||||
EV_CASE_STR(SDL_EVENT_USER_WINDOW_MINIMIZE);
|
||||
EV_CASE_STR(SDL_EVENT_USER_POINTER_NULL);
|
||||
EV_CASE_STR(SDL_EVENT_USER_POINTER_DEFAULT);
|
||||
EV_CASE_STR(SDL_EVENT_USER_POINTER_POSITION);
|
||||
EV_CASE_STR(SDL_EVENT_USER_POINTER_SET);
|
||||
EV_CASE_STR(SDL_EVENT_USER_QUIT);
|
||||
|
||||
EV_CASE_STR(SDL_EVENT_LAST);
|
||||
default:
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "SDL_UNKNOWNEVENT[0x" << std::hex << std::setw(8) << std::setfill('0') << type
|
||||
<< "]";
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string generate_uuid_v4()
|
||||
{
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
static std::uniform_int_distribution<> dis(0, 255);
|
||||
std::stringstream ss;
|
||||
ss << std::hex << std::setfill('0') << std::setw(2);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
ss << dis(gen);
|
||||
}
|
||||
ss << "-";
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
ss << dis(gen);
|
||||
}
|
||||
ss << "-";
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
ss << dis(gen);
|
||||
}
|
||||
ss << "-";
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
ss << dis(gen);
|
||||
}
|
||||
ss << "-";
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
ss << dis(gen);
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
HighDpiScaleMode platformScaleMode()
|
||||
{
|
||||
const auto platform = SDL_GetPlatform();
|
||||
if (!platform)
|
||||
return SCALE_MODE_INVALID;
|
||||
if (strcmp("Windows", platform) == 0)
|
||||
return SCALE_MODE_X11;
|
||||
if (strcmp("macOS", platform) == 0)
|
||||
return SCALE_MODE_WAYLAND;
|
||||
if (strcmp("Linux", platform) == 0)
|
||||
{
|
||||
const auto driver = SDL_GetCurrentVideoDriver();
|
||||
if (!driver)
|
||||
return SCALE_MODE_WAYLAND;
|
||||
if (strcmp("x11", driver) == 0)
|
||||
return SCALE_MODE_X11;
|
||||
if (strcmp("wayland", driver) == 0)
|
||||
return SCALE_MODE_WAYLAND;
|
||||
}
|
||||
return SCALE_MODE_INVALID;
|
||||
}
|
||||
|
||||
std::string windowTitle(const rdpSettings* settings)
|
||||
{
|
||||
const char* prefix = "FreeRDP:";
|
||||
|
||||
if (!settings)
|
||||
return {};
|
||||
|
||||
const auto windowTitle = freerdp_settings_get_string(settings, FreeRDP_WindowTitle);
|
||||
if (windowTitle)
|
||||
return {};
|
||||
|
||||
const auto name = freerdp_settings_get_server_name(settings);
|
||||
const auto port = freerdp_settings_get_uint32(settings, FreeRDP_ServerPort);
|
||||
|
||||
const auto addPort = (port != 3389);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << prefix << " ";
|
||||
if (!addPort)
|
||||
ss << name;
|
||||
else
|
||||
ss << name << ":" << port;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
} // namespace sdl::utils
|
||||
|
||||
namespace sdl::error
|
||||
{
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
static std::uniform_int_distribution<> dis(0, 255);
|
||||
std::stringstream ss;
|
||||
ss << std::hex << std::setfill('0') << std::setw(2);
|
||||
for (int i = 0; i < 4; i++)
|
||||
struct sdl_exitCode_map_t
|
||||
{
|
||||
ss << dis(gen);
|
||||
}
|
||||
ss << "-";
|
||||
for (int i = 0; i < 2; i++)
|
||||
DWORD error;
|
||||
int code;
|
||||
const char* code_tag;
|
||||
};
|
||||
|
||||
#define ENTRY(x, y) { x, y, #y }
|
||||
static const struct sdl_exitCode_map_t sdl_exitCode_map[] = {
|
||||
ENTRY(FREERDP_ERROR_SUCCESS, SUCCESS), ENTRY(FREERDP_ERROR_NONE, DISCONNECT),
|
||||
ENTRY(FREERDP_ERROR_NONE, LOGOFF), ENTRY(FREERDP_ERROR_NONE, IDLE_TIMEOUT),
|
||||
ENTRY(FREERDP_ERROR_NONE, LOGON_TIMEOUT), ENTRY(FREERDP_ERROR_NONE, CONN_REPLACED),
|
||||
ENTRY(FREERDP_ERROR_NONE, OUT_OF_MEMORY), ENTRY(FREERDP_ERROR_NONE, CONN_DENIED),
|
||||
ENTRY(FREERDP_ERROR_NONE, CONN_DENIED_FIPS), ENTRY(FREERDP_ERROR_NONE, USER_PRIVILEGES),
|
||||
ENTRY(FREERDP_ERROR_NONE, FRESH_CREDENTIALS_REQUIRED),
|
||||
ENTRY(ERRINFO_LOGOFF_BY_USER, DISCONNECT_BY_USER), ENTRY(FREERDP_ERROR_NONE, UNKNOWN),
|
||||
|
||||
/* section 16-31: license error set */
|
||||
ENTRY(FREERDP_ERROR_NONE, LICENSE_INTERNAL),
|
||||
ENTRY(FREERDP_ERROR_NONE, LICENSE_NO_LICENSE_SERVER),
|
||||
ENTRY(FREERDP_ERROR_NONE, LICENSE_NO_LICENSE),
|
||||
ENTRY(FREERDP_ERROR_NONE, LICENSE_BAD_CLIENT_MSG),
|
||||
ENTRY(FREERDP_ERROR_NONE, LICENSE_HWID_DOESNT_MATCH),
|
||||
ENTRY(FREERDP_ERROR_NONE, LICENSE_BAD_CLIENT),
|
||||
ENTRY(FREERDP_ERROR_NONE, LICENSE_CANT_FINISH_PROTOCOL),
|
||||
ENTRY(FREERDP_ERROR_NONE, LICENSE_CLIENT_ENDED_PROTOCOL),
|
||||
ENTRY(FREERDP_ERROR_NONE, LICENSE_BAD_CLIENT_ENCRYPTION),
|
||||
ENTRY(FREERDP_ERROR_NONE, LICENSE_CANT_UPGRADE),
|
||||
ENTRY(FREERDP_ERROR_NONE, LICENSE_NO_REMOTE_CONNECTIONS),
|
||||
ENTRY(FREERDP_ERROR_NONE, LICENSE_CANT_UPGRADE),
|
||||
|
||||
/* section 32-127: RDP protocol error set */
|
||||
ENTRY(FREERDP_ERROR_NONE, RDP),
|
||||
|
||||
/* section 128-254: xfreerdp specific exit codes */
|
||||
ENTRY(FREERDP_ERROR_NONE, PARSE_ARGUMENTS), ENTRY(FREERDP_ERROR_NONE, MEMORY),
|
||||
ENTRY(FREERDP_ERROR_NONE, PROTOCOL), ENTRY(FREERDP_ERROR_NONE, CONN_FAILED),
|
||||
|
||||
ENTRY(FREERDP_ERROR_AUTHENTICATION_FAILED, AUTH_FAILURE),
|
||||
ENTRY(FREERDP_ERROR_SECURITY_NEGO_CONNECT_FAILED, NEGO_FAILURE),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_LOGON_FAILURE, LOGON_FAILURE),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_TARGET_BOOTING, CONNECT_TARGET_BOOTING),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_ACCOUNT_LOCKED_OUT, ACCOUNT_LOCKED_OUT),
|
||||
ENTRY(FREERDP_ERROR_PRE_CONNECT_FAILED, PRE_CONNECT_FAILED),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_UNDEFINED, CONNECT_UNDEFINED),
|
||||
ENTRY(FREERDP_ERROR_POST_CONNECT_FAILED, POST_CONNECT_FAILED),
|
||||
ENTRY(FREERDP_ERROR_DNS_ERROR, DNS_ERROR),
|
||||
ENTRY(FREERDP_ERROR_DNS_NAME_NOT_FOUND, DNS_NAME_NOT_FOUND),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_FAILED, CONNECT_FAILED),
|
||||
ENTRY(FREERDP_ERROR_MCS_CONNECT_INITIAL_ERROR, MCS_CONNECT_INITIAL_ERROR),
|
||||
ENTRY(FREERDP_ERROR_TLS_CONNECT_FAILED, TLS_CONNECT_FAILED),
|
||||
ENTRY(FREERDP_ERROR_INSUFFICIENT_PRIVILEGES, INSUFFICIENT_PRIVILEGES),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_CANCELLED, CONNECT_CANCELLED),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_TRANSPORT_FAILED, CONNECT_TRANSPORT_FAILED),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_PASSWORD_EXPIRED, CONNECT_PASSWORD_EXPIRED),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_PASSWORD_MUST_CHANGE, CONNECT_PASSWORD_MUST_CHANGE),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_KDC_UNREACHABLE, CONNECT_KDC_UNREACHABLE),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_ACCOUNT_DISABLED, CONNECT_ACCOUNT_DISABLED),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_PASSWORD_CERTAINLY_EXPIRED, CONNECT_PASSWORD_CERTAINLY_EXPIRED),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_CLIENT_REVOKED, CONNECT_CLIENT_REVOKED),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_WRONG_PASSWORD, CONNECT_WRONG_PASSWORD),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_ACCESS_DENIED, CONNECT_ACCESS_DENIED),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_ACCOUNT_RESTRICTION, CONNECT_ACCOUNT_RESTRICTION),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_ACCOUNT_EXPIRED, CONNECT_ACCOUNT_EXPIRED),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_LOGON_TYPE_NOT_GRANTED, CONNECT_LOGON_TYPE_NOT_GRANTED),
|
||||
ENTRY(FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS, CONNECT_NO_OR_MISSING_CREDENTIALS)
|
||||
};
|
||||
|
||||
static const sdl_exitCode_map_t* mapEntryByCode(int exit_code)
|
||||
{
|
||||
ss << dis(gen);
|
||||
for (const auto& x : sdl_exitCode_map)
|
||||
{
|
||||
auto cur = &x;
|
||||
if (cur->code == exit_code)
|
||||
return cur;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
ss << "-";
|
||||
for (int i = 0; i < 2; i++)
|
||||
|
||||
static const sdl_exitCode_map_t* mapEntryByError(UINT32 error)
|
||||
{
|
||||
ss << dis(gen);
|
||||
for (const auto& x : sdl_exitCode_map)
|
||||
{
|
||||
auto cur = &x;
|
||||
if (cur->error == error)
|
||||
return cur;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
ss << "-";
|
||||
for (int i = 0; i < 2; i++)
|
||||
|
||||
int errorToExitCode(DWORD error)
|
||||
{
|
||||
ss << dis(gen);
|
||||
auto entry = mapEntryByError(error);
|
||||
if (entry)
|
||||
return entry->code;
|
||||
|
||||
return CONN_FAILED;
|
||||
}
|
||||
ss << "-";
|
||||
for (int i = 0; i < 6; i++)
|
||||
|
||||
const char* errorToExitCodeTag(UINT32 error)
|
||||
{
|
||||
ss << dis(gen);
|
||||
auto entry = mapEntryByError(error);
|
||||
if (entry)
|
||||
return entry->code_tag;
|
||||
return nullptr;
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
const char* exitCodeToTag(int code)
|
||||
{
|
||||
auto entry = mapEntryByCode(code);
|
||||
if (entry)
|
||||
return entry->code_tag;
|
||||
return nullptr;
|
||||
}
|
||||
} // namespace sdl::error
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/wlog.h>
|
||||
|
||||
#include <freerdp/settings.h>
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -67,23 +69,114 @@ typedef struct
|
||||
Sint32 result;
|
||||
} SDL_UserAuthArg;
|
||||
|
||||
bool sdl_push_user_event(Uint32 type, ...);
|
||||
[[nodiscard]] bool sdl_push_user_event(Uint32 type, ...);
|
||||
|
||||
bool sdl_push_quit();
|
||||
[[nodiscard]] bool sdl_push_quit();
|
||||
|
||||
std::string sdl_window_event_str(Uint32 ev);
|
||||
const char* sdl_event_type_str(Uint32 type);
|
||||
const char* sdl_error_string(Sint32 res);
|
||||
[[nodiscard]] const char* sdl_error_string(Sint32 res);
|
||||
|
||||
#define sdl_log_error(res, log, what) sdl_log_error_ex(res, log, what, __FILE__, __LINE__, __func__)
|
||||
BOOL sdl_log_error_ex(Sint32 res, wLog* log, const char* what, const char* file, size_t line,
|
||||
const char* fkt);
|
||||
[[nodiscard]] BOOL sdl_log_error_ex(Sint32 res, wLog* log, const char* what, const char* file,
|
||||
size_t line, const char* fkt);
|
||||
|
||||
namespace sdl::utils
|
||||
{
|
||||
std::string rdp_orientation_to_str(uint32_t orientation);
|
||||
std::string sdl_orientation_to_str(SDL_DisplayOrientation orientation);
|
||||
UINT32 orientaion_to_rdp(SDL_DisplayOrientation orientation);
|
||||
[[nodiscard]] std::string touchFlagsToString(Uint32 flags);
|
||||
[[nodiscard]] std::string toString(enum FreeRDP_DesktopRotationFlags orientation);
|
||||
[[nodiscard]] std::string toString(SDL_DisplayOrientation orientation);
|
||||
[[nodiscard]] std::string toString(const SDL_DisplayMode* mode);
|
||||
[[nodiscard]] std::string toString(Uint32 type);
|
||||
|
||||
[[nodiscard]] UINT32 orientaion_to_rdp(SDL_DisplayOrientation orientation);
|
||||
|
||||
[[nodiscard]] std::string generate_uuid_v4();
|
||||
|
||||
enum HighDpiScaleMode
|
||||
{
|
||||
SCALE_MODE_INVALID,
|
||||
SCALE_MODE_X11,
|
||||
SCALE_MODE_WAYLAND
|
||||
};
|
||||
|
||||
[[nodiscard]] HighDpiScaleMode platformScaleMode();
|
||||
|
||||
[[nodiscard]] std::string windowTitle(const rdpSettings* settings);
|
||||
|
||||
std::string generate_uuid_v4();
|
||||
} // namespace sdl::utils
|
||||
|
||||
namespace sdl::error
|
||||
{
|
||||
enum EXIT_CODE
|
||||
{
|
||||
/* section 0-15: protocol-independent codes */
|
||||
SUCCESS = 0,
|
||||
DISCONNECT = 1,
|
||||
LOGOFF = 2,
|
||||
IDLE_TIMEOUT = 3,
|
||||
LOGON_TIMEOUT = 4,
|
||||
CONN_REPLACED = 5,
|
||||
OUT_OF_MEMORY = 6,
|
||||
CONN_DENIED = 7,
|
||||
CONN_DENIED_FIPS = 8,
|
||||
USER_PRIVILEGES = 9,
|
||||
FRESH_CREDENTIALS_REQUIRED = 10,
|
||||
DISCONNECT_BY_USER = 11,
|
||||
|
||||
/* section 16-31: license error set */
|
||||
LICENSE_INTERNAL = 16,
|
||||
LICENSE_NO_LICENSE_SERVER = 17,
|
||||
LICENSE_NO_LICENSE = 18,
|
||||
LICENSE_BAD_CLIENT_MSG = 19,
|
||||
LICENSE_HWID_DOESNT_MATCH = 20,
|
||||
LICENSE_BAD_CLIENT = 21,
|
||||
LICENSE_CANT_FINISH_PROTOCOL = 22,
|
||||
LICENSE_CLIENT_ENDED_PROTOCOL = 23,
|
||||
LICENSE_BAD_CLIENT_ENCRYPTION = 24,
|
||||
LICENSE_CANT_UPGRADE = 25,
|
||||
LICENSE_NO_REMOTE_CONNECTIONS = 26,
|
||||
|
||||
/* section 32-127: RDP protocol error set */
|
||||
RDP = 32,
|
||||
|
||||
/* section 128-254: xfreerdp specific exit codes */
|
||||
PARSE_ARGUMENTS = 128,
|
||||
MEMORY = 129,
|
||||
PROTOCOL = 130,
|
||||
CONN_FAILED = 131,
|
||||
AUTH_FAILURE = 132,
|
||||
NEGO_FAILURE = 133,
|
||||
LOGON_FAILURE = 134,
|
||||
ACCOUNT_LOCKED_OUT = 135,
|
||||
PRE_CONNECT_FAILED = 136,
|
||||
CONNECT_UNDEFINED = 137,
|
||||
POST_CONNECT_FAILED = 138,
|
||||
DNS_ERROR = 139,
|
||||
DNS_NAME_NOT_FOUND = 140,
|
||||
CONNECT_FAILED = 141,
|
||||
MCS_CONNECT_INITIAL_ERROR = 142,
|
||||
TLS_CONNECT_FAILED = 143,
|
||||
INSUFFICIENT_PRIVILEGES = 144,
|
||||
CONNECT_CANCELLED = 145,
|
||||
|
||||
CONNECT_TRANSPORT_FAILED = 147,
|
||||
CONNECT_PASSWORD_EXPIRED = 148,
|
||||
CONNECT_PASSWORD_MUST_CHANGE = 149,
|
||||
CONNECT_KDC_UNREACHABLE = 150,
|
||||
CONNECT_ACCOUNT_DISABLED = 151,
|
||||
CONNECT_PASSWORD_CERTAINLY_EXPIRED = 152,
|
||||
CONNECT_CLIENT_REVOKED = 153,
|
||||
CONNECT_WRONG_PASSWORD = 154,
|
||||
CONNECT_ACCESS_DENIED = 155,
|
||||
CONNECT_ACCOUNT_RESTRICTION = 156,
|
||||
CONNECT_ACCOUNT_EXPIRED = 157,
|
||||
CONNECT_LOGON_TYPE_NOT_GRANTED = 158,
|
||||
CONNECT_NO_OR_MISSING_CREDENTIALS = 159,
|
||||
CONNECT_TARGET_BOOTING = 160,
|
||||
|
||||
UNKNOWN = 255,
|
||||
};
|
||||
|
||||
[[nodiscard]] int errorToExitCode(DWORD error);
|
||||
[[nodiscard]] const char* errorToExitCodeTag(UINT32 error);
|
||||
[[nodiscard]] const char* exitCodeToTag(int code);
|
||||
} // namespace sdl::error
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
|
||||
#include "sdl_window.hpp"
|
||||
#include "sdl_utils.hpp"
|
||||
|
||||
@@ -42,13 +45,13 @@ SdlWindow::SdlWindow(const std::string& title, Sint32 startupX, Sint32 startupY,
|
||||
_window = SDL_CreateWindowWithProperties(props);
|
||||
SDL_DestroyProperties(props);
|
||||
|
||||
auto scale = SDL_GetWindowPixelDensity(_window);
|
||||
const int iscale = static_cast<int>(scale * 100.0f);
|
||||
auto sc = scale();
|
||||
const int iscale = static_cast<int>(sc * 100.0f);
|
||||
auto w = 100 * width / iscale;
|
||||
auto h = 100 * height / iscale;
|
||||
(void)SDL_SetWindowSize(_window, w, h);
|
||||
std::ignore = resize({ w, h });
|
||||
SDL_SetHint(SDL_HINT_APP_NAME, "");
|
||||
(void)SDL_SyncWindow(_window);
|
||||
std::ignore = SDL_SyncWindow(_window);
|
||||
}
|
||||
|
||||
SdlWindow::SdlWindow(SdlWindow&& other) noexcept
|
||||
@@ -62,7 +65,7 @@ SdlWindow::~SdlWindow()
|
||||
SDL_DestroyWindow(_window);
|
||||
}
|
||||
|
||||
Uint32 SdlWindow::id() const
|
||||
SDL_WindowID SdlWindow::id() const
|
||||
{
|
||||
if (!_window)
|
||||
return 0;
|
||||
@@ -87,6 +90,17 @@ SDL_Rect SdlWindow::rect() const
|
||||
return rect;
|
||||
}
|
||||
|
||||
SDL_Rect SdlWindow::bounds() const
|
||||
{
|
||||
SDL_Rect rect = {};
|
||||
if (_window)
|
||||
{
|
||||
SDL_GetWindowPosition(_window, &rect.x, &rect.y);
|
||||
SDL_GetWindowSize(_window, &rect.w, &rect.h);
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
SDL_Window* SdlWindow::window() const
|
||||
{
|
||||
return _window;
|
||||
@@ -112,27 +126,21 @@ Sint32 SdlWindow::offsetY() const
|
||||
return _offset_y;
|
||||
}
|
||||
|
||||
rdpMonitor SdlWindow::monitor() const
|
||||
rdpMonitor SdlWindow::monitor(bool isPrimary) const
|
||||
{
|
||||
rdpMonitor mon{};
|
||||
|
||||
const auto factor = SDL_GetWindowDisplayScale(_window);
|
||||
const auto factor = scale();
|
||||
const auto dsf = static_cast<UINT32>(100 * factor);
|
||||
mon.attributes.desktopScaleFactor = dsf;
|
||||
mon.attributes.deviceScaleFactor = 100;
|
||||
|
||||
int pixelWidth = 0;
|
||||
int pixelHeight = 0;
|
||||
auto prc = SDL_GetWindowSizeInPixels(_window, &pixelWidth, &pixelHeight);
|
||||
const auto r = rect();
|
||||
mon.width = r.w;
|
||||
mon.height = r.h;
|
||||
|
||||
if (prc)
|
||||
{
|
||||
mon.width = pixelWidth;
|
||||
mon.height = pixelHeight;
|
||||
|
||||
mon.attributes.physicalWidth = WINPR_ASSERTING_INT_CAST(uint32_t, pixelWidth);
|
||||
mon.attributes.physicalHeight = WINPR_ASSERTING_INT_CAST(uint32_t, pixelHeight);
|
||||
}
|
||||
mon.attributes.physicalWidth = WINPR_ASSERTING_INT_CAST(uint32_t, r.w);
|
||||
mon.attributes.physicalHeight = WINPR_ASSERTING_INT_CAST(uint32_t, r.h);
|
||||
|
||||
SDL_Rect rect = {};
|
||||
auto did = SDL_GetDisplayForWindow(_window);
|
||||
@@ -144,15 +152,31 @@ rdpMonitor SdlWindow::monitor() const
|
||||
mon.y = rect.y;
|
||||
}
|
||||
|
||||
auto orientation = SDL_GetCurrentDisplayOrientation(did);
|
||||
mon.attributes.orientation = sdl::utils::orientaion_to_rdp(orientation);
|
||||
const auto orient = orientation();
|
||||
mon.attributes.orientation = sdl::utils::orientaion_to_rdp(orient);
|
||||
|
||||
auto primary = SDL_GetPrimaryDisplay();
|
||||
mon.is_primary = SDL_GetWindowID(_window) == primary;
|
||||
mon.is_primary = isPrimary || (SDL_GetWindowID(_window) == primary);
|
||||
mon.orig_screen = did;
|
||||
if (mon.is_primary)
|
||||
{
|
||||
mon.x = 0;
|
||||
mon.y = 0;
|
||||
}
|
||||
return mon;
|
||||
}
|
||||
|
||||
float SdlWindow::scale() const
|
||||
{
|
||||
return SDL_GetWindowDisplayScale(_window);
|
||||
}
|
||||
|
||||
SDL_DisplayOrientation SdlWindow::orientation() const
|
||||
{
|
||||
const auto did = displayIndex();
|
||||
return SDL_GetCurrentDisplayOrientation(did);
|
||||
}
|
||||
|
||||
bool SdlWindow::grabKeyboard(bool enable)
|
||||
{
|
||||
if (!_window)
|
||||
@@ -173,31 +197,84 @@ void SdlWindow::setBordered(bool bordered)
|
||||
{
|
||||
if (_window)
|
||||
SDL_SetWindowBordered(_window, bordered);
|
||||
(void)SDL_SyncWindow(_window);
|
||||
std::ignore = SDL_SyncWindow(_window);
|
||||
}
|
||||
|
||||
void SdlWindow::raise()
|
||||
{
|
||||
SDL_RaiseWindow(_window);
|
||||
(void)SDL_SyncWindow(_window);
|
||||
std::ignore = SDL_SyncWindow(_window);
|
||||
}
|
||||
|
||||
void SdlWindow::resizeable(bool use)
|
||||
{
|
||||
SDL_SetWindowResizable(_window, use);
|
||||
(void)SDL_SyncWindow(_window);
|
||||
std::ignore = SDL_SyncWindow(_window);
|
||||
}
|
||||
|
||||
void SdlWindow::fullscreen(bool enter)
|
||||
{
|
||||
(void)SDL_SetWindowFullscreen(_window, enter);
|
||||
(void)SDL_SyncWindow(_window);
|
||||
std::ignore = SDL_SetWindowFullscreen(_window, enter);
|
||||
std::ignore = SDL_SyncWindow(_window);
|
||||
}
|
||||
|
||||
void SdlWindow::minimize()
|
||||
{
|
||||
SDL_MinimizeWindow(_window);
|
||||
(void)SDL_SyncWindow(_window);
|
||||
std::ignore = SDL_SyncWindow(_window);
|
||||
}
|
||||
|
||||
bool SdlWindow::resize(const SDL_Point& size)
|
||||
{
|
||||
return SDL_SetWindowSize(_window, size.x, size.y);
|
||||
}
|
||||
|
||||
bool SdlWindow::drawRect(SDL_Surface* surface, SDL_Point offset, const SDL_Rect& srcRect)
|
||||
{
|
||||
WINPR_ASSERT(surface);
|
||||
SDL_Rect dstRect = { offset.x + srcRect.x, offset.y + srcRect.y, srcRect.w, srcRect.h };
|
||||
return blit(surface, srcRect, dstRect);
|
||||
}
|
||||
|
||||
bool SdlWindow::drawRects(SDL_Surface* surface, SDL_Point offset,
|
||||
const std::vector<SDL_Rect>& rects)
|
||||
{
|
||||
if (rects.empty())
|
||||
{
|
||||
return drawRect(surface, offset, { 0, 0, surface->w, surface->h });
|
||||
}
|
||||
for (auto& srcRect : rects)
|
||||
{
|
||||
if (!drawRect(surface, offset, srcRect))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SdlWindow::drawScaledRect(SDL_Surface* surface, const SDL_FPoint& scale,
|
||||
const SDL_Rect& srcRect)
|
||||
{
|
||||
SDL_Rect dstRect = srcRect;
|
||||
dstRect.x = static_cast<Sint32>(static_cast<float>(dstRect.x) * scale.x);
|
||||
dstRect.w = static_cast<Sint32>(static_cast<float>(dstRect.w) * scale.x);
|
||||
dstRect.y = static_cast<Sint32>(static_cast<float>(dstRect.y) * scale.y);
|
||||
dstRect.h = static_cast<Sint32>(static_cast<float>(dstRect.h) * scale.y);
|
||||
return blit(surface, srcRect, dstRect);
|
||||
}
|
||||
|
||||
bool SdlWindow::drawScaledRects(SDL_Surface* surface, const SDL_FPoint& scale,
|
||||
const std::vector<SDL_Rect>& rects)
|
||||
{
|
||||
if (rects.empty())
|
||||
{
|
||||
return drawScaledRect(surface, scale, { 0, 0, surface->w, surface->h });
|
||||
}
|
||||
for (const auto& srcRect : rects)
|
||||
{
|
||||
if (!drawScaledRect(surface, scale, srcRect))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SdlWindow::fill(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
||||
@@ -233,3 +310,37 @@ void SdlWindow::updateSurface()
|
||||
{
|
||||
SDL_UpdateWindowSurface(_window);
|
||||
}
|
||||
|
||||
SdlWindow SdlWindow::create(SDL_DisplayID id, const std::string& title, Uint32 flags, Uint32 width,
|
||||
Uint32 height)
|
||||
{
|
||||
flags |= SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||
auto startupX = static_cast<int>(SDL_WINDOWPOS_CENTERED_DISPLAY(id));
|
||||
auto startupY = static_cast<int>(SDL_WINDOWPOS_CENTERED_DISPLAY(id));
|
||||
|
||||
if ((flags & SDL_WINDOW_FULLSCREEN) != 0)
|
||||
{
|
||||
SDL_Rect rect = {};
|
||||
SDL_GetDisplayBounds(id, &rect);
|
||||
startupX = rect.x;
|
||||
startupY = rect.y;
|
||||
width = static_cast<Uint32>(rect.w);
|
||||
height = static_cast<Uint32>(rect.h);
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << title << ":" << id;
|
||||
SdlWindow window{
|
||||
ss.str(), startupX, startupY, static_cast<int>(width), static_cast<int>(height), flags
|
||||
};
|
||||
|
||||
if ((flags & (SDL_WINDOW_FULLSCREEN)) != 0)
|
||||
{
|
||||
SDL_Rect rect = {};
|
||||
SDL_GetDisplayBounds(id, &rect);
|
||||
window.setOffsetX(rect.x);
|
||||
window.setOffsetY(rect.y);
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <freerdp/settings_types.h>
|
||||
@@ -27,18 +29,20 @@
|
||||
class SdlWindow
|
||||
{
|
||||
public:
|
||||
SdlWindow(const std::string& title, Sint32 startupX, Sint32 startupY, Sint32 width,
|
||||
Sint32 height, Uint32 flags);
|
||||
[[nodiscard]] static SdlWindow create(SDL_DisplayID id, const std::string& title, Uint32 flags,
|
||||
Uint32 width = 0, Uint32 height = 0);
|
||||
|
||||
SdlWindow(SdlWindow&& other) noexcept;
|
||||
SdlWindow(const SdlWindow& other) = delete;
|
||||
~SdlWindow();
|
||||
virtual ~SdlWindow();
|
||||
|
||||
SdlWindow& operator=(const SdlWindow& other) = delete;
|
||||
SdlWindow& operator=(SdlWindow&& other) = delete;
|
||||
|
||||
[[nodiscard]] Uint32 id() const;
|
||||
[[nodiscard]] SDL_WindowID id() const;
|
||||
[[nodiscard]] SDL_DisplayID displayIndex() const;
|
||||
[[nodiscard]] SDL_Rect rect() const;
|
||||
[[nodiscard]] SDL_Rect bounds() const;
|
||||
[[nodiscard]] SDL_Window* window() const;
|
||||
|
||||
[[nodiscard]] Sint32 offsetX() const;
|
||||
@@ -47,23 +51,39 @@ class SdlWindow
|
||||
void setOffsetY(Sint32 y);
|
||||
[[nodiscard]] Sint32 offsetY() const;
|
||||
|
||||
[[nodiscard]] rdpMonitor monitor() const;
|
||||
[[nodiscard]] rdpMonitor monitor(bool isPrimary) const;
|
||||
|
||||
bool grabKeyboard(bool enable);
|
||||
bool grabMouse(bool enable);
|
||||
[[nodiscard]] float scale() const;
|
||||
[[nodiscard]] SDL_DisplayOrientation orientation() const;
|
||||
|
||||
[[nodiscard]] bool grabKeyboard(bool enable);
|
||||
[[nodiscard]] bool grabMouse(bool enable);
|
||||
void setBordered(bool bordered);
|
||||
void raise();
|
||||
void resizeable(bool use);
|
||||
void fullscreen(bool enter);
|
||||
void minimize();
|
||||
|
||||
bool fill(Uint8 r = 0x00, Uint8 g = 0x00, Uint8 b = 0x00, Uint8 a = 0xff);
|
||||
bool blit(SDL_Surface* surface, const SDL_Rect& src, SDL_Rect& dst);
|
||||
[[nodiscard]] bool resize(const SDL_Point& size);
|
||||
|
||||
[[nodiscard]] bool drawRect(SDL_Surface* surface, SDL_Point offset, const SDL_Rect& srcRect);
|
||||
[[nodiscard]] bool drawRects(SDL_Surface* surface, SDL_Point offset,
|
||||
const std::vector<SDL_Rect>& rects = {});
|
||||
[[nodiscard]] bool drawScaledRect(SDL_Surface* surface, const SDL_FPoint& scale,
|
||||
const SDL_Rect& srcRect);
|
||||
|
||||
[[nodiscard]] bool drawScaledRects(SDL_Surface* surface, const SDL_FPoint& scale,
|
||||
const std::vector<SDL_Rect>& rects = {});
|
||||
|
||||
[[nodiscard]] bool fill(Uint8 r = 0x00, Uint8 g = 0x00, Uint8 b = 0x00, Uint8 a = 0xff);
|
||||
[[nodiscard]] bool blit(SDL_Surface* surface, const SDL_Rect& src, SDL_Rect& dst);
|
||||
void updateSurface();
|
||||
|
||||
private:
|
||||
static UINT32 orientaion_to_rdp(SDL_DisplayOrientation orientation);
|
||||
protected:
|
||||
SdlWindow(const std::string& title, Sint32 startupX, Sint32 startupY, Sint32 width,
|
||||
Sint32 height, Uint32 flags);
|
||||
|
||||
private:
|
||||
SDL_Window* _window = nullptr;
|
||||
Sint32 _offset_x = 0;
|
||||
Sint32 _offset_y = 0;
|
||||
|
||||
@@ -26,8 +26,8 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
BOOL sdl_webview_get_access_token(freerdp* instance, AccessTokenType tokenType, char** token,
|
||||
size_t count, ...);
|
||||
[[nodiscard]] BOOL sdl_webview_get_access_token(freerdp* instance, AccessTokenType tokenType,
|
||||
char** token, size_t count, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -21,4 +21,5 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
bool webview_impl_run(const std::string& title, const std::string& url, std::string& code);
|
||||
[[nodiscard]] bool webview_impl_run(const std::string& title, const std::string& url,
|
||||
std::string& code);
|
||||
|
||||
@@ -33,20 +33,21 @@ class SDLResourceManager
|
||||
SDLResourceManager operator=(const SDLResourceManager& other) = delete;
|
||||
SDLResourceManager& operator=(SDLResourceManager&& other) = delete;
|
||||
|
||||
static std::string typeFonts();
|
||||
static std::string typeImages();
|
||||
[[nodiscard]] static std::string typeFonts();
|
||||
[[nodiscard]] static std::string typeImages();
|
||||
|
||||
protected:
|
||||
static void insert(const std::string& type, const std::string& id,
|
||||
const std::vector<unsigned char>& data);
|
||||
|
||||
static const std::vector<unsigned char>* data(const std::string& type, const std::string& id);
|
||||
static std::string filename(const std::string& type, const std::string& id);
|
||||
[[nodiscard]] static const std::vector<unsigned char>* data(const std::string& type,
|
||||
const std::string& id);
|
||||
[[nodiscard]] static std::string filename(const std::string& type, const std::string& id);
|
||||
|
||||
static bool useCompiledResources();
|
||||
[[nodiscard]] static bool useCompiledResources();
|
||||
|
||||
private:
|
||||
static std::map<std::string, std::vector<unsigned char>>& resources();
|
||||
[[nodiscard]] static std::map<std::string, std::vector<unsigned char>>& resources();
|
||||
#if defined(SDL_USE_COMPILED_RESOURCES)
|
||||
static void init(); // implemented in generated file
|
||||
#endif
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
class SdlPref
|
||||
{
|
||||
public:
|
||||
static std::shared_ptr<SdlPref>
|
||||
[[nodiscard]] static std::shared_ptr<SdlPref>
|
||||
instance(const std::string& name = SdlPref::get_default_file(false));
|
||||
|
||||
[[nodiscard]] std::string get_pref_file(bool systemConfigOnly = false) const;
|
||||
@@ -63,6 +63,7 @@ class SdlPref
|
||||
|
||||
[[nodiscard]] bool is_user_config_enabled() const;
|
||||
|
||||
static std::string get_default_file(bool systemConfigOnly);
|
||||
static std::string item_to_str(WINPR_JSON* item, const std::string& fallback = "");
|
||||
[[nodiscard]] static std::string get_default_file(bool systemConfigOnly);
|
||||
[[nodiscard]] static std::string item_to_str(WINPR_JSON* item,
|
||||
const std::string& fallback = "");
|
||||
};
|
||||
|
||||
@@ -533,9 +533,7 @@ WINPR_PRAGMA_DIAG_POP
|
||||
#define WINPR_DEPRECATED_VAR(text, obj) obj
|
||||
#endif
|
||||
|
||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 202202L)
|
||||
#define WINPR_NORETURN(obj) [[noreturn]] obj
|
||||
#elif defined(WIN32) && !defined(__CYGWIN__)
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
#define WINPR_NORETURN(obj) __declspec(noreturn) obj
|
||||
#elif defined(__GNUC__)
|
||||
#define WINPR_NORETURN(obj) __attribute__((__noreturn__)) obj
|
||||
|
||||
Reference in New Issue
Block a user