Win32: Move to WM_INPUT for disabled cursor motion

Related to #125.
This commit is contained in:
Camilla Löwy 2017-01-10 18:16:15 +01:00
parent dd96d0ac93
commit 918b4e81d2
5 changed files with 79 additions and 12 deletions

View File

@ -144,6 +144,7 @@ information on what to include when reporting a bug.
- Bugfix: Invalid library paths were used in test and example CMake files (#930) - Bugfix: Invalid library paths were used in test and example CMake files (#930)
- Bugfix: The scancode for synthetic key release events was always zero - Bugfix: The scancode for synthetic key release events was always zero
- [Win32] Added system error strings to relevant GLFW error descriptions (#733) - [Win32] Added system error strings to relevant GLFW error descriptions (#733)
- [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125)
- [Win32] Bugfix: Undecorated windows could not be iconified by the user (#861) - [Win32] Bugfix: Undecorated windows could not be iconified by the user (#861)
- [Win32] Bugfix: Deadzone logic could underflow with some controllers (#910) - [Win32] Bugfix: Deadzone logic could underflow with some controllers (#910)
- [Win32] Bugfix: Bitness test in `FindVulkan.cmake` was VS specific (#928) - [Win32] Bugfix: Bitness test in `FindVulkan.cmake` was VS specific (#928)

View File

@ -32,6 +32,12 @@ full screen windows with the [GLFW_CENTER_CURSOR](@ref GLFW_CENTER_CURSOR_hint)
window hint. window hint.
@subsection news_33_rawmotion Support for raw mouse motion
GLFW now supports raw mouse motion in disabled cursor mode on platforms where
this is available.
@subsection news_33_moltenvk Support for Vulkan on macOS via MoltenVK @subsection news_33_moltenvk Support for Vulkan on macOS via MoltenVK
GLFW now supports the `VK_MVK_macos_surface` window surface creation extension GLFW now supports the `VK_MVK_macos_surface` window surface creation extension

View File

@ -483,6 +483,7 @@ void _glfwPlatformTerminate(void)
SPIF_SENDCHANGE); SPIF_SENDCHANGE);
free(_glfw.win32.clipboardString); free(_glfw.win32.clipboardString);
free(_glfw.win32.rawInput);
_glfwTerminateWGL(); _glfwTerminateWGL();
_glfwTerminateEGL(); _glfwTerminateEGL();

View File

@ -257,6 +257,8 @@ typedef struct _GLFWlibraryWin32
double restoreCursorPosX, restoreCursorPosY; double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active // The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow; _GLFWwindow* disabledCursorWindow;
RAWINPUT* rawInput;
int rawInputSize;
struct { struct {
HINSTANCE instance; HINSTANCE instance;

View File

@ -666,19 +666,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
const int x = GET_X_LPARAM(lParam); const int x = GET_X_LPARAM(lParam);
const int y = GET_Y_LPARAM(lParam); const int y = GET_Y_LPARAM(lParam);
// Disabled cursor motion input is provided by WM_INPUT
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
{
const int dx = x - window->win32.lastCursorPosX;
const int dy = y - window->win32.lastCursorPosY;
if (_glfw.win32.disabledCursorWindow != window)
break; break;
_glfwInputCursorPos(window,
window->virtualCursorPosX + dx,
window->virtualCursorPosY + dy);
}
else
_glfwInputCursorPos(window, x, y); _glfwInputCursorPos(window, x, y);
window->win32.lastCursorPosX = x; window->win32.lastCursorPosX = x;
@ -700,6 +691,56 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
return 0; return 0;
} }
case WM_INPUT:
{
UINT size;
HRAWINPUT ri = (HRAWINPUT) lParam;
RAWINPUT* data;
int dx, dy;
// Only process input when disabled cursor mode is applied
if (_glfw.win32.disabledCursorWindow != window)
break;
GetRawInputData(ri, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER));
if (size > _glfw.win32.rawInputSize)
{
free(_glfw.win32.rawInput);
_glfw.win32.rawInput = calloc(size, 1);
_glfw.win32.rawInputSize = size;
}
size = _glfw.win32.rawInputSize;
if (GetRawInputData(ri, RID_INPUT,
_glfw.win32.rawInput, &size,
sizeof(RAWINPUTHEADER)) == (UINT) -1)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to retrieve raw input data");
break;
}
data = _glfw.win32.rawInput;
if (data->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE)
{
dx = data->data.mouse.lLastX - window->win32.lastCursorPosX;
dy = data->data.mouse.lLastY - window->win32.lastCursorPosY;
}
else
{
dx = data->data.mouse.lLastX;
dy = data->data.mouse.lLastY;
}
_glfwInputCursorPos(window,
window->virtualCursorPosX + dx,
window->virtualCursorPosY + dy);
window->win32.lastCursorPosX += dx;
window->win32.lastCursorPosY += dy;
break;
}
case WM_MOUSELEAVE: case WM_MOUSELEAVE:
{ {
window->win32.cursorTracked = GLFW_FALSE; window->win32.cursorTracked = GLFW_FALSE;
@ -1527,20 +1568,36 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{ {
if (mode == GLFW_CURSOR_DISABLED) if (mode == GLFW_CURSOR_DISABLED)
{ {
const RAWINPUTDEVICE rid = { 0x01, 0x02, 0, window->win32.handle };
_glfw.win32.disabledCursorWindow = window; _glfw.win32.disabledCursorWindow = window;
_glfwPlatformGetCursorPos(window, _glfwPlatformGetCursorPos(window,
&_glfw.win32.restoreCursorPosX, &_glfw.win32.restoreCursorPosX,
&_glfw.win32.restoreCursorPosY); &_glfw.win32.restoreCursorPosY);
centerCursor(window); centerCursor(window);
updateClipRect(window); updateClipRect(window);
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to register raw input device");
}
} }
else if (_glfw.win32.disabledCursorWindow == window) else if (_glfw.win32.disabledCursorWindow == window)
{ {
const RAWINPUTDEVICE rid = { 0x01, 0x02, RIDEV_REMOVE, NULL };
_glfw.win32.disabledCursorWindow = NULL; _glfw.win32.disabledCursorWindow = NULL;
updateClipRect(NULL); updateClipRect(NULL);
_glfwPlatformSetCursorPos(window, _glfwPlatformSetCursorPos(window,
_glfw.win32.restoreCursorPosX, _glfw.win32.restoreCursorPosX,
_glfw.win32.restoreCursorPosY); _glfw.win32.restoreCursorPosY);
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to remove raw input device");
}
} }
if (cursorInClientArea(window)) if (cursorInClientArea(window))