mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
@@ -411,9 +411,6 @@ bool SdlContext::createWindows()
|
||||
if (!freerdp_settings_get_bool(settings, FreeRDP_Decorations))
|
||||
flags |= SDL_WINDOW_BORDERLESS;
|
||||
|
||||
std::stringstream ss;
|
||||
ss << title << ":" << x;
|
||||
|
||||
auto did = WINPR_ASSERTING_INT_CAST(SDL_DisplayID, id);
|
||||
auto window = SdlWindow::create(did, title, flags, w, h);
|
||||
|
||||
@@ -667,7 +664,10 @@ int SdlContext::sdl_client_thread_run(std::string& error_msg)
|
||||
const DWORD status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
|
||||
|
||||
if (status == WAIT_FAILED)
|
||||
{
|
||||
WLog_Print(getWLog(), WLOG_ERROR, "WaitForMultipleObjects WAIT_FAILED");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!freerdp_check_event_handles(context()))
|
||||
{
|
||||
@@ -763,6 +763,16 @@ int SdlContext::error_info_to_error(DWORD* pcode, char** msg, size_t* len) const
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
void SdlContext::applyMonitorOffset(SDL_WindowID window, float& x, float& y) const
|
||||
{
|
||||
if (!freerdp_settings_get_bool(context()->settings, FreeRDP_UseMultimon))
|
||||
return;
|
||||
|
||||
auto w = getWindowForId(window);
|
||||
x -= static_cast<float>(w->offsetX());
|
||||
y -= static_cast<float>(w->offsetY());
|
||||
}
|
||||
|
||||
bool SdlContext::drawToWindow(SdlWindow& window, const std::vector<SDL_Rect>& rects)
|
||||
{
|
||||
if (!isConnected())
|
||||
@@ -840,6 +850,14 @@ bool SdlContext::removeDisplay(SDL_DisplayID id)
|
||||
return true;
|
||||
}
|
||||
|
||||
const SdlWindow* SdlContext::getWindowForId(SDL_WindowID id) const
|
||||
{
|
||||
auto it = _windows.find(id);
|
||||
if (it == _windows.end())
|
||||
return nullptr;
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
SdlWindow* SdlContext::getWindowForId(SDL_WindowID id)
|
||||
{
|
||||
auto it = _windows.find(id);
|
||||
@@ -900,6 +918,7 @@ bool SdlContext::handleEvent(const SDL_MouseMotionEvent& ev)
|
||||
return false;
|
||||
removeLocalScaling(copy.motion.x, copy.motion.y);
|
||||
removeLocalScaling(copy.motion.xrel, copy.motion.yrel);
|
||||
applyMonitorOffset(copy.motion.windowID, copy.motion.x, copy.motion.y);
|
||||
|
||||
return SdlTouch::handleEvent(this, copy.motion);
|
||||
}
|
||||
@@ -937,6 +956,8 @@ bool SdlContext::handleEvent(const SDL_WindowEvent& ev)
|
||||
|
||||
switch (ev.type)
|
||||
{
|
||||
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
||||
return restoreCursor();
|
||||
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED:
|
||||
if (isConnected())
|
||||
{
|
||||
@@ -944,7 +965,7 @@ bool SdlContext::handleEvent(const SDL_WindowEvent& ev)
|
||||
return false;
|
||||
if (!drawToWindow(*window))
|
||||
return false;
|
||||
if (!sdl_Pointer_Set_Process(this))
|
||||
if (!restoreCursor())
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@@ -953,7 +974,7 @@ bool SdlContext::handleEvent(const SDL_WindowEvent& ev)
|
||||
return false;
|
||||
if (!drawToWindow(*window))
|
||||
return false;
|
||||
if (!sdl_Pointer_Set_Process(this))
|
||||
if (!restoreCursor())
|
||||
return false;
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_MOVED:
|
||||
@@ -1016,6 +1037,7 @@ bool SdlContext::handleEvent(const SDL_MouseButtonEvent& ev)
|
||||
if (!eventToPixelCoordinates(ev.windowID, copy))
|
||||
return false;
|
||||
removeLocalScaling(copy.button.x, copy.button.y);
|
||||
applyMonitorOffset(copy.button.windowID, copy.button.x, copy.button.y);
|
||||
return SdlTouch::handleEvent(this, copy.button);
|
||||
}
|
||||
|
||||
@@ -1027,6 +1049,7 @@ bool SdlContext::handleEvent(const SDL_TouchFingerEvent& ev)
|
||||
return false;
|
||||
removeLocalScaling(copy.tfinger.dx, copy.tfinger.dy);
|
||||
removeLocalScaling(copy.tfinger.x, copy.tfinger.y);
|
||||
applyMonitorOffset(copy.tfinger.windowID, copy.tfinger.x, copy.tfinger.y);
|
||||
return SdlTouch::handleEvent(this, copy.tfinger);
|
||||
}
|
||||
|
||||
@@ -1035,9 +1058,11 @@ bool SdlContext::eventToPixelCoordinates(SDL_WindowID id, SDL_Event& ev)
|
||||
auto w = getWindowForId(id);
|
||||
if (!w)
|
||||
return false;
|
||||
|
||||
/* Ignore errors here, sometimes SDL has no renderer */
|
||||
auto renderer = SDL_GetRenderer(w->window());
|
||||
if (!renderer)
|
||||
return false;
|
||||
return true;
|
||||
return SDL_ConvertEventToRenderCoordinates(renderer, &ev);
|
||||
}
|
||||
|
||||
@@ -1065,9 +1090,11 @@ SDL_FPoint SdlContext::screenToPixel(SDL_WindowID id, const SDL_FPoint& pos)
|
||||
auto w = getWindowForId(id);
|
||||
if (!w)
|
||||
return {};
|
||||
|
||||
/* Ignore errors here, sometimes SDL has no renderer */
|
||||
auto renderer = SDL_GetRenderer(w->window());
|
||||
if (!renderer)
|
||||
return {};
|
||||
return pos;
|
||||
|
||||
SDL_FPoint rpos{};
|
||||
if (!SDL_RenderCoordinatesFromWindow(renderer, pos.x, pos.y, &rpos.x, &rpos.y))
|
||||
@@ -1081,9 +1108,11 @@ SDL_FPoint SdlContext::pixelToScreen(SDL_WindowID id, const SDL_FPoint& pos)
|
||||
auto w = getWindowForId(id);
|
||||
if (!w)
|
||||
return {};
|
||||
|
||||
/* Ignore errors here, sometimes SDL has no renderer */
|
||||
auto renderer = SDL_GetRenderer(w->window());
|
||||
if (!renderer)
|
||||
return {};
|
||||
return pos;
|
||||
|
||||
SDL_FPoint rpos{};
|
||||
if (!SDL_RenderCoordinatesToWindow(renderer, pos.x, pos.y, &rpos.x, &rpos.y))
|
||||
@@ -1247,9 +1276,16 @@ rdpClientContext* SdlContext::common() const
|
||||
return reinterpret_cast<rdpClientContext*>(context());
|
||||
}
|
||||
|
||||
void SdlContext::setCursor(rdpPointer* cursor)
|
||||
bool SdlContext::setCursor(CursorType type)
|
||||
{
|
||||
_cursorType = type;
|
||||
return restoreCursor();
|
||||
}
|
||||
|
||||
bool SdlContext::setCursor(rdpPointer* cursor)
|
||||
{
|
||||
_cursor = cursor;
|
||||
return setCursor(CURSOR_IMAGE);
|
||||
}
|
||||
|
||||
rdpPointer* SdlContext::cursor() const
|
||||
@@ -1257,6 +1293,36 @@ rdpPointer* SdlContext::cursor() const
|
||||
return _cursor;
|
||||
}
|
||||
|
||||
bool SdlContext::restoreCursor()
|
||||
{
|
||||
WLog_Print(getWLog(), WLOG_DEBUG, "restore cursor: %d", _cursorType);
|
||||
switch (_cursorType)
|
||||
{
|
||||
case CURSOR_NULL:
|
||||
if (!SDL_HideCursor())
|
||||
return false;
|
||||
|
||||
setHasCursor(false);
|
||||
return true;
|
||||
|
||||
case CURSOR_DEFAULT:
|
||||
{
|
||||
auto def = SDL_GetDefaultCursor();
|
||||
if (!SDL_SetCursor(def))
|
||||
return false;
|
||||
if (!SDL_ShowCursor())
|
||||
return false;
|
||||
setHasCursor(true);
|
||||
return true;
|
||||
}
|
||||
case CURSOR_IMAGE:
|
||||
setHasCursor(true);
|
||||
return sdl_Pointer_Set_Process(this);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void SdlContext::setMonitorIds(const std::vector<SDL_DisplayID>& ids)
|
||||
{
|
||||
_monitorIds.clear();
|
||||
|
||||
@@ -43,6 +43,13 @@
|
||||
class SdlContext
|
||||
{
|
||||
public:
|
||||
enum CursorType
|
||||
{
|
||||
CURSOR_NULL,
|
||||
CURSOR_DEFAULT,
|
||||
CURSOR_IMAGE
|
||||
};
|
||||
|
||||
explicit SdlContext(rdpContext* context);
|
||||
SdlContext(const SdlContext& other) = delete;
|
||||
SdlContext(SdlContext&& other) = delete;
|
||||
@@ -78,15 +85,17 @@ class SdlContext
|
||||
[[nodiscard]] rdpContext* context() const;
|
||||
[[nodiscard]] rdpClientContext* common() const;
|
||||
|
||||
void setCursor(rdpPointer* cursor);
|
||||
[[nodiscard]] bool setCursor(CursorType type);
|
||||
[[nodiscard]] bool setCursor(rdpPointer* cursor);
|
||||
[[nodiscard]] rdpPointer* cursor() const;
|
||||
[[nodiscard]] bool restoreCursor();
|
||||
|
||||
void setMonitorIds(const std::vector<SDL_DisplayID>& ids);
|
||||
const std::vector<SDL_DisplayID>& monitorIds() const;
|
||||
int64_t monitorId(uint32_t index) const;
|
||||
[[nodiscard]] const std::vector<SDL_DisplayID>& monitorIds() const;
|
||||
[[nodiscard]] int64_t monitorId(uint32_t index) const;
|
||||
|
||||
void push(std::vector<SDL_Rect>&& rects);
|
||||
std::vector<SDL_Rect> pop();
|
||||
[[nodiscard]] std::vector<SDL_Rect> pop();
|
||||
|
||||
void setHasCursor(bool val);
|
||||
[[nodiscard]] bool hasCursor() const;
|
||||
@@ -106,6 +115,7 @@ class SdlContext
|
||||
[[nodiscard]] int exitCode() const;
|
||||
[[nodiscard]] SDL_PixelFormat pixelFormat() const;
|
||||
|
||||
[[nodiscard]] const SdlWindow* getWindowForId(SDL_WindowID id) const;
|
||||
[[nodiscard]] SdlWindow* getWindowForId(SDL_WindowID id);
|
||||
[[nodiscard]] SdlWindow* getFirstWindow();
|
||||
|
||||
@@ -162,12 +172,15 @@ class SdlContext
|
||||
|
||||
[[nodiscard]] int error_info_to_error(DWORD* pcode, char** msg, size_t* len) const;
|
||||
|
||||
void applyMonitorOffset(SDL_WindowID window, float& x, float& y) const;
|
||||
|
||||
rdpContext* _context = nullptr;
|
||||
wLog* _log = nullptr;
|
||||
|
||||
std::atomic<bool> _connected = false;
|
||||
bool _cursor_visible = true;
|
||||
rdpPointer* _cursor = nullptr;
|
||||
CursorType _cursorType = CURSOR_NULL;
|
||||
std::vector<SDL_DisplayID> _monitorIds;
|
||||
std::mutex _queue_mux;
|
||||
std::queue<std::vector<SDL_Rect>> _queue;
|
||||
|
||||
@@ -70,6 +70,37 @@
|
||||
#define SDL_TAG CLIENT_TAG("SDL")
|
||||
#endif
|
||||
|
||||
class ErrorMsg : public std::exception
|
||||
{
|
||||
public:
|
||||
ErrorMsg(int rc, Uint32 type, const std::string& msg);
|
||||
|
||||
[[nodiscard]] int rc() const;
|
||||
[[nodiscard]] const char* what() const noexcept override;
|
||||
|
||||
private:
|
||||
int _rc;
|
||||
Uint32 _type;
|
||||
std::string _msg;
|
||||
std::string _buffer;
|
||||
};
|
||||
const char* ErrorMsg::what() const noexcept
|
||||
{
|
||||
return _buffer.c_str();
|
||||
}
|
||||
|
||||
int ErrorMsg::rc() const
|
||||
{
|
||||
return _rc;
|
||||
}
|
||||
|
||||
ErrorMsg::ErrorMsg(int rc, Uint32 type, const std::string& msg) : _rc(rc), _type(type), _msg(msg)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << _msg << " {" << sdl::utils::toString(_type) << "}";
|
||||
_buffer = ss.str();
|
||||
}
|
||||
|
||||
static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const char* signame,
|
||||
[[maybe_unused]] void* context)
|
||||
{
|
||||
@@ -81,21 +112,23 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const
|
||||
int rc = -1;
|
||||
WINPR_ASSERT(sdl);
|
||||
|
||||
while (!sdl->shallAbort())
|
||||
try
|
||||
{
|
||||
SDL_Event windowEvent = {};
|
||||
while (!sdl->shallAbort() && SDL_WaitEventTimeout(nullptr, 1000))
|
||||
while (!sdl->shallAbort())
|
||||
{
|
||||
/* Only poll standard SDL events and SDL_EVENT_USERS meant to create
|
||||
* dialogs. do not process the dialog return value events here.
|
||||
*/
|
||||
const int prc = SDL_PeepEvents(&windowEvent, 1, SDL_GETEVENT, SDL_EVENT_FIRST,
|
||||
SDL_EVENT_USER_RETRY_DIALOG);
|
||||
if (prc < 0)
|
||||
SDL_Event windowEvent = {};
|
||||
while (!sdl->shallAbort() && SDL_WaitEventTimeout(nullptr, 1000))
|
||||
{
|
||||
if (sdl_log_error(prc, sdl->getWLog(), "SDL_PeepEvents"))
|
||||
continue;
|
||||
}
|
||||
/* Only poll standard SDL events and SDL_EVENT_USERS meant to create
|
||||
* dialogs. do not process the dialog return value events here.
|
||||
*/
|
||||
const int prc = SDL_PeepEvents(&windowEvent, 1, SDL_GETEVENT, SDL_EVENT_FIRST,
|
||||
SDL_EVENT_USER_RETRY_DIALOG);
|
||||
if (prc < 0)
|
||||
{
|
||||
if (sdl_log_error(prc, sdl->getWLog(), "SDL_PeepEvents"))
|
||||
continue;
|
||||
}
|
||||
|
||||
#if defined(WITH_DEBUG_SDL_EVENTS)
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "got event %s [0x%08" PRIx32 "]",
|
||||
@@ -108,12 +141,12 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const
|
||||
continue;
|
||||
|
||||
if (!sdl->handleEvent(windowEvent))
|
||||
return -1;
|
||||
throw ErrorMsg{ -1, windowEvent.type, "sdl->handleEvent" };
|
||||
|
||||
switch (windowEvent.type)
|
||||
{
|
||||
case SDL_EVENT_QUIT:
|
||||
freerdp_abort_connect_context(sdl->context());
|
||||
std::ignore = freerdp_abort_connect_context(sdl->context());
|
||||
break;
|
||||
case SDL_EVENT_USER_CERT_DIALOG:
|
||||
{
|
||||
@@ -121,7 +154,7 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const
|
||||
auto title = static_cast<const char*>(windowEvent.user.data1);
|
||||
auto msg = static_cast<const char*>(windowEvent.user.data2);
|
||||
if (!sdl_cert_dialog_show(title, msg))
|
||||
return -1;
|
||||
throw ErrorMsg{ -1, windowEvent.type, "sdl_cert_dialog_show" };
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_USER_SHOW_DIALOG:
|
||||
@@ -130,7 +163,7 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const
|
||||
auto title = static_cast<const char*>(windowEvent.user.data1);
|
||||
auto msg = static_cast<const char*>(windowEvent.user.data2);
|
||||
if (!sdl_message_dialog_show(title, msg, windowEvent.user.code))
|
||||
return -1;
|
||||
throw ErrorMsg{ -1, windowEvent.type, "sdl_message_dialog_show" };
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_USER_SCARD_DIALOG:
|
||||
@@ -139,7 +172,7 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const
|
||||
auto title = static_cast<const char*>(windowEvent.user.data1);
|
||||
auto msg = static_cast<const char**>(windowEvent.user.data2);
|
||||
if (!sdl_scard_dialog_show(title, windowEvent.user.code, msg))
|
||||
return -1;
|
||||
throw ErrorMsg{ -1, windowEvent.type, "sdl_scard_dialog_show" };
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_USER_AUTH_DIALOG:
|
||||
@@ -147,7 +180,7 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const
|
||||
SDLConnectionDialogHider hider(sdl);
|
||||
if (!sdl_auth_dialog_show(
|
||||
reinterpret_cast<const SDL_UserAuthArg*>(windowEvent.padding)))
|
||||
return -1;
|
||||
throw ErrorMsg{ -1, windowEvent.type, "sdl_auth_dialog_show" };
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_USER_UPDATE:
|
||||
@@ -157,7 +190,7 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const
|
||||
{
|
||||
rectangles = sdl->pop();
|
||||
if (!sdl->drawToWindows(rectangles))
|
||||
return -1;
|
||||
throw ErrorMsg{ -1, windowEvent.type, "sdl->drawToWindows" };
|
||||
} while (!rectangles.empty());
|
||||
}
|
||||
break;
|
||||
@@ -165,7 +198,7 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const
|
||||
{
|
||||
auto ctx = static_cast<SdlContext*>(windowEvent.user.data1);
|
||||
if (!ctx->createWindows())
|
||||
return -1;
|
||||
throw ErrorMsg{ -1, windowEvent.type, "sdl->createWindows" };
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_USER_WINDOW_RESIZEABLE:
|
||||
@@ -186,22 +219,16 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const
|
||||
break;
|
||||
case SDL_EVENT_USER_WINDOW_MINIMIZE:
|
||||
if (!sdl->minimizeAllWindows())
|
||||
return -1;
|
||||
throw ErrorMsg{ -1, windowEvent.type, "sdl->minimizeAllWindows" };
|
||||
break;
|
||||
case SDL_EVENT_USER_POINTER_NULL:
|
||||
SDL_HideCursor();
|
||||
sdl->setCursor(nullptr);
|
||||
sdl->setHasCursor(false);
|
||||
if (!sdl->setCursor(SdlContext::CURSOR_NULL))
|
||||
throw ErrorMsg{ -1, windowEvent.type, "sdl->setCursor" };
|
||||
break;
|
||||
case SDL_EVENT_USER_POINTER_DEFAULT:
|
||||
{
|
||||
SDL_Cursor* def = SDL_GetDefaultCursor();
|
||||
SDL_SetCursor(def);
|
||||
SDL_ShowCursor();
|
||||
sdl->setCursor(nullptr);
|
||||
sdl->setHasCursor(true);
|
||||
}
|
||||
break;
|
||||
if (!sdl->setCursor(SdlContext::CURSOR_DEFAULT))
|
||||
throw ErrorMsg{ -1, windowEvent.type, "sdl->setCursor" };
|
||||
break;
|
||||
case SDL_EVENT_USER_POINTER_POSITION:
|
||||
{
|
||||
const auto x =
|
||||
@@ -210,22 +237,26 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const
|
||||
static_cast<INT32>(reinterpret_cast<uintptr_t>(windowEvent.user.data2));
|
||||
if (!sdl->moveMouseTo(
|
||||
{ static_cast<float>(x) * 1.0f, static_cast<float>(y) * 1.0f }))
|
||||
return -1;
|
||||
throw ErrorMsg{ -1, windowEvent.type, "sdl->moveMouseTo" };
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_USER_POINTER_SET:
|
||||
sdl->setCursor(static_cast<rdpPointer*>(windowEvent.user.data1));
|
||||
if (!sdl_Pointer_Set_Process(sdl))
|
||||
return -1;
|
||||
if (!sdl->setCursor(static_cast<rdpPointer*>(windowEvent.user.data1)))
|
||||
throw ErrorMsg{ -1, windowEvent.type, "sdl->setCursor" };
|
||||
break;
|
||||
case SDL_EVENT_USER_QUIT:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rc = 1;
|
||||
}
|
||||
catch (ErrorMsg& msg)
|
||||
{
|
||||
WLog_Print(sdl->getWLog(), WLOG_ERROR, "[exception] %s", msg.what());
|
||||
rc = msg.rc();
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -309,16 +309,14 @@ bool sdlInput::keyboard_focus_in()
|
||||
WINPR_ASSERT(input);
|
||||
|
||||
auto syncFlags = sdl_get_kbd_flags();
|
||||
freerdp_input_send_focus_in_event(input, WINPR_ASSERTING_INT_CAST(uint16_t, syncFlags));
|
||||
if (!freerdp_input_send_focus_in_event(input, WINPR_ASSERTING_INT_CAST(uint16_t, syncFlags)))
|
||||
return false;
|
||||
|
||||
/* finish with a mouse pointer position like mstsc.exe if required */
|
||||
// TODO: fullscreen/remote app
|
||||
float fx = 0.0f;
|
||||
float fy = 0.0f;
|
||||
if (_sdl->fullscreen())
|
||||
SDL_GetGlobalMouseState(&fx, &fy);
|
||||
else
|
||||
SDL_GetMouseState(&fx, &fy);
|
||||
SDL_GetMouseState(&fx, &fy);
|
||||
|
||||
auto w = SDL_GetMouseFocus();
|
||||
const auto& pos = _sdl->screenToPixel(SDL_GetWindowID(w), SDL_FPoint{ fx, fy });
|
||||
|
||||
@@ -103,7 +103,7 @@ static void sdl_Pointer_Free(rdpContext* context, rdpPointer* pointer)
|
||||
return sdl_push_user_event(SDL_EVENT_USER_POINTER_SET, pointer);
|
||||
}
|
||||
|
||||
BOOL sdl_Pointer_Set_Process(SdlContext* sdl)
|
||||
bool sdl_Pointer_Set_Process(SdlContext* sdl)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
|
||||
@@ -111,7 +111,7 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl)
|
||||
auto pointer = sdl->cursor();
|
||||
auto ptr = reinterpret_cast<sdlPointer*>(pointer);
|
||||
if (!ptr)
|
||||
return TRUE;
|
||||
return true;
|
||||
|
||||
rdpGdi* gdi = context->gdi;
|
||||
WINPR_ASSERT(gdi);
|
||||
@@ -121,7 +121,7 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl)
|
||||
auto isw = static_cast<float>(pointer->width);
|
||||
auto ish = static_cast<float>(pointer->height);
|
||||
|
||||
SDL_Window* window = SDL_GetMouseFocus();
|
||||
auto window = SDL_GetMouseFocus();
|
||||
if (!window)
|
||||
return sdl_Pointer_SetDefault(context);
|
||||
|
||||
@@ -134,9 +134,11 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl)
|
||||
ptr->image =
|
||||
SDL_CreateSurface(static_cast<int>(pos.w), static_cast<int>(pos.h), sdl->pixelFormat());
|
||||
if (!ptr->image)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
if (!SDL_LockSurface(ptr->image))
|
||||
return false;
|
||||
|
||||
SDL_LockSurface(ptr->image);
|
||||
auto pixels = static_cast<BYTE*>(ptr->image->pixels);
|
||||
auto data = static_cast<const BYTE*>(ptr->data);
|
||||
const BOOL rc = freerdp_image_scale(
|
||||
@@ -145,13 +147,13 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl)
|
||||
gdi->dstFormat, 0, 0, 0, static_cast<UINT32>(isw), static_cast<UINT32>(ish));
|
||||
SDL_UnlockSurface(ptr->image);
|
||||
if (!rc)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
// create a cursor image in 100% display scale to trick SDL into creating the cursor with the
|
||||
// correct size
|
||||
auto fw = sdl->getFirstWindow();
|
||||
if (!fw)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
const auto hidpi_scale =
|
||||
sdl->pixelToScreen(fw->id(), SDL_FPoint{ static_cast<float>(ptr->image->w),
|
||||
@@ -159,20 +161,24 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl)
|
||||
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);
|
||||
if (!SDL_BlitSurfaceScaled(ptr->image, nullptr, normal, nullptr,
|
||||
SDL_ScaleMode::SDL_SCALEMODE_LINEAR))
|
||||
return false;
|
||||
if (!SDL_AddSurfaceAlternateImage(normal, ptr->image))
|
||||
return false;
|
||||
|
||||
ptr->cursor = SDL_CreateColorCursor(normal, static_cast<int>(pos.x), static_cast<int>(pos.y));
|
||||
if (!ptr->cursor)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
SDL_DestroySurface(normal);
|
||||
|
||||
SDL_SetCursor(ptr->cursor);
|
||||
SDL_ShowCursor();
|
||||
if (!SDL_SetCursor(ptr->cursor))
|
||||
return false;
|
||||
if (!SDL_ShowCursor())
|
||||
return false;
|
||||
sdl->setHasCursor(true);
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] static BOOL sdl_Pointer_SetNull(rdpContext* context)
|
||||
@@ -190,7 +196,7 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl)
|
||||
return sdl_push_user_event(SDL_EVENT_USER_POINTER_POSITION, x, y);
|
||||
}
|
||||
|
||||
BOOL sdl_register_pointer(rdpGraphics* graphics)
|
||||
bool sdl_register_pointer(rdpGraphics* graphics)
|
||||
{
|
||||
const rdpPointer pointer = { sizeof(sdlPointer),
|
||||
sdl_Pointer_New,
|
||||
@@ -211,5 +217,5 @@ BOOL sdl_register_pointer(rdpGraphics* graphics)
|
||||
nullptr,
|
||||
{} };
|
||||
graphics_register_pointer(graphics, &pointer);
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
|
||||
#include <freerdp/graphics.h>
|
||||
|
||||
[[nodiscard]] BOOL sdl_register_pointer(rdpGraphics* graphics);
|
||||
[[nodiscard]] bool sdl_register_pointer(rdpGraphics* graphics);
|
||||
|
||||
[[nodiscard]] BOOL sdl_Pointer_Set_Process(SdlContext* sdl);
|
||||
[[nodiscard]] bool sdl_Pointer_Set_Process(SdlContext* sdl);
|
||||
|
||||
@@ -23,15 +23,14 @@
|
||||
#include "sdl_window.hpp"
|
||||
#include "sdl_utils.hpp"
|
||||
|
||||
SdlWindow::SdlWindow(const std::string& title, Sint32 startupX, Sint32 startupY, Sint32 width,
|
||||
Sint32 height, [[maybe_unused]] Uint32 flags)
|
||||
SdlWindow::SdlWindow(const std::string& title, const SDL_Rect& rect, [[maybe_unused]] Uint32 flags)
|
||||
{
|
||||
auto props = SDL_CreateProperties();
|
||||
SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, title.c_str());
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, startupX);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, startupY);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, rect.x);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, rect.y);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, rect.w);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, rect.h);
|
||||
|
||||
if (flags & SDL_WINDOW_HIGH_PIXEL_DENSITY)
|
||||
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, true);
|
||||
@@ -47,8 +46,8 @@ SdlWindow::SdlWindow(const std::string& title, Sint32 startupX, Sint32 startupY,
|
||||
|
||||
auto sc = scale();
|
||||
const int iscale = static_cast<int>(sc * 100.0f);
|
||||
auto w = 100 * width / iscale;
|
||||
auto h = 100 * height / iscale;
|
||||
auto w = 100 * rect.w / iscale;
|
||||
auto h = 100 * rect.h / iscale;
|
||||
std::ignore = resize({ w, h });
|
||||
SDL_SetHint(SDL_HINT_APP_NAME, "");
|
||||
std::ignore = SDL_SyncWindow(_window);
|
||||
@@ -315,29 +314,20 @@ SdlWindow SdlWindow::create(SDL_DisplayID id, const std::string& title, Uint32 f
|
||||
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));
|
||||
|
||||
SDL_Rect rect = { static_cast<int>(SDL_WINDOWPOS_CENTERED_DISPLAY(id)),
|
||||
static_cast<int>(SDL_WINDOWPOS_CENTERED_DISPLAY(id)), static_cast<int>(width),
|
||||
static_cast<int>(height) };
|
||||
|
||||
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::ignore = SDL_GetDisplayBounds(id, &rect);
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << title << ":" << id;
|
||||
SdlWindow window{
|
||||
ss.str(), startupX, startupY, static_cast<int>(width), static_cast<int>(height), flags
|
||||
};
|
||||
SdlWindow window{ title, rect, flags };
|
||||
|
||||
if ((flags & (SDL_WINDOW_FULLSCREEN)) != 0)
|
||||
{
|
||||
SDL_Rect rect = {};
|
||||
SDL_GetDisplayBounds(id, &rect);
|
||||
window.setOffsetX(rect.x);
|
||||
window.setOffsetY(rect.y);
|
||||
}
|
||||
|
||||
@@ -80,8 +80,7 @@ class SdlWindow
|
||||
void updateSurface();
|
||||
|
||||
protected:
|
||||
SdlWindow(const std::string& title, Sint32 startupX, Sint32 startupY, Sint32 width,
|
||||
Sint32 height, Uint32 flags);
|
||||
SdlWindow(const std::string& title, const SDL_Rect& rect, Uint32 flags);
|
||||
|
||||
private:
|
||||
SDL_Window* _window = nullptr;
|
||||
|
||||
@@ -1771,8 +1771,8 @@ BOOL freerdp_client_send_button_event(rdpClientContext* cctx, BOOL relative, UIN
|
||||
cctx->lastX = x;
|
||||
cctx->lastY = y;
|
||||
}
|
||||
freerdp_input_send_mouse_event(cctx->context.input, mflags, (UINT16)cctx->lastX,
|
||||
(UINT16)cctx->lastY);
|
||||
return freerdp_input_send_mouse_event(cctx->context.input, mflags, (UINT16)cctx->lastX,
|
||||
(UINT16)cctx->lastY);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user