mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
[client,sdl] simplify mouse cursor update and restore
This commit is contained in:
@@ -956,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())
|
||||
{
|
||||
@@ -963,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;
|
||||
@@ -972,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:
|
||||
@@ -1177,8 +1179,6 @@ bool SdlContext::handleEvent(const SDL_Event& ev)
|
||||
case SDL_EVENT_RENDER_DEVICE_RESET:
|
||||
case SDL_EVENT_WILL_ENTER_FOREGROUND:
|
||||
return redraw();
|
||||
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
||||
return sdl_Pointer_Set_Process(this);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
@@ -1276,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
|
||||
@@ -1286,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;
|
||||
@@ -171,6 +180,7 @@ class SdlContext
|
||||
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;
|
||||
|
||||
@@ -198,19 +198,13 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const
|
||||
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 =
|
||||
@@ -223,9 +217,8 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_USER_POINTER_SET:
|
||||
sdl->setCursor(static_cast<rdpPointer*>(windowEvent.user.data1));
|
||||
if (!sdl_Pointer_Set_Process(sdl))
|
||||
throw ErrorMsg{ -1, windowEvent.type, "sdl_Pointer_Set_Process" };
|
||||
if (!sdl->setCursor(static_cast<rdpPointer*>(windowEvent.user.data1)))
|
||||
throw ErrorMsg{ -1, windowEvent.type, "sdl->setCursor" };
|
||||
break;
|
||||
case SDL_EVENT_USER_QUIT:
|
||||
default:
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user