From 6c1e3fd84c35ba212b1eaae75ac13675b5e7f516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 29 Jan 2024 18:03:47 +0100 Subject: [PATCH] Win32: Use existing cursor creation path --- src/win32_init.c | 52 +++------------------------------------------- src/win32_window.c | 28 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 49 deletions(-) diff --git a/src/win32_init.c b/src/win32_init.c index 25fde325..4a75cce6 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -430,46 +430,6 @@ static GLFWbool createHelperWindow(void) return GLFW_TRUE; } -// Creates the blank cursor -// -static void createBlankCursor(void) -{ - // HACK: Create a transparent cursor as using the NULL cursor breaks - // using SetCursorPos when connected over RDP - int cursorWidth = GetSystemMetrics(SM_CXCURSOR); - int cursorHeight = GetSystemMetrics(SM_CYCURSOR); - unsigned char* andMask = _glfw_calloc(cursorWidth * cursorHeight / 8, sizeof(unsigned char)); - unsigned char* xorMask = _glfw_calloc(cursorWidth * cursorHeight / 8, sizeof(unsigned char)); - - if (andMask != NULL && xorMask != NULL) { - - memset(andMask, 0xFF, (size_t)(cursorWidth * cursorHeight / 8)); - - // Cursor creation might fail, but that's fine as we get NULL in that case, - // which serves as an acceptable fallback blank cursor (other than on RDP) - _glfw.win32.blankCursor = CreateCursor(NULL, 0, 0, cursorWidth, cursorHeight, andMask, xorMask); - - _glfw_free(andMask); - _glfw_free(xorMask); - } -} - -// Initialize for remote sessions -// -static void initRemoteSession(void) -{ - //Check if the current progress was started with Remote Desktop. - _glfw.win32.isRemoteSession = GetSystemMetrics(SM_REMOTESESSION) > 0; - - // With Remote desktop, we need to create a blank cursor because of the cursor is Set to NULL - // if cannot be moved to center in capture mode. If not Remote Desktop win32.blankCursor stays NULL - // and will perform has before (normal). - if (_glfw.win32.isRemoteSession) - { - createBlankCursor(); - } -} - ////////////////////////////////////////////////////////////////////////// ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// @@ -738,14 +698,8 @@ int _glfwInitWin32(void) if (!createHelperWindow()) return GLFW_FALSE; - //Some hacks are needed to support Remote Desktop... - initRemoteSession(); - if (_glfw.win32.isRemoteSession && _glfw.win32.blankCursor == NULL ) - { - _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "Win32: Failed to create blank cursor for remote session."); - return GLFW_FALSE; - } + // Check if the current process was started via Remote Desktop + _glfw.win32.isRemoteSession = GetSystemMetrics(SM_REMOTESESSION) > 0; _glfwPollMonitorsWin32(); return GLFW_TRUE; @@ -754,7 +708,7 @@ int _glfwInitWin32(void) void _glfwTerminateWin32(void) { if (_glfw.win32.blankCursor) - DestroyCursor(_glfw.win32.blankCursor); + DestroyIcon((HICON) _glfw.win32.blankCursor); if (_glfw.win32.deviceNotificationHandle) UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle); diff --git a/src/win32_window.c b/src/win32_window.c index 6191f9a4..1a856713 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1314,6 +1314,34 @@ static int createNativeWindow(_GLFWwindow* window, } } + if (_glfw.win32.isRemoteSession) + { + // NOTE: On Remote Desktop, setting the cursor to NULL does not hide it + // HACK: Create a transparent cursor and always set that instead of NULL + // When not on Remote Desktop, this handle is NULL and normal hiding is used + if (!_glfw.win32.blankCursor) + { + const int cursorWidth = GetSystemMetrics(SM_CXCURSOR); + const int cursorHeight = GetSystemMetrics(SM_CYCURSOR); + + unsigned char* cursorPixels = _glfw_calloc(cursorWidth * cursorHeight, 4); + if (!cursorPixels) + return GLFW_FALSE; + + // NOTE: Windows checks whether the image is fully transparent and if so + // just ignores the alpha channel and makes the whole cursor opaque + // HACK: Make one pixel slightly less transparent + cursorPixels[3] = 1; + + const GLFWimage cursorImage = { cursorWidth, cursorHeight, cursorPixels }; + _glfw.win32.blankCursor = createIcon(&cursorImage, 0, 0, FALSE); + _glfw_free(cursorPixels); + + if (!_glfw.win32.blankCursor) + return GLFW_FALSE; + } + } + if (window->monitor) { MONITORINFO mi = { sizeof(mi) };