1
0
Fork 0
mirror of https://github.com/gwm17/glfw.git synced 2024-11-26 20:28:49 -05:00

Refactor cursor mode paths

This is the refactoring part of adding GLFW_CURSOR_CAPTURED, separated
out to help keep the 3.3-stable branch layout compatible with master.

Related to #58.
This commit is contained in:
Camilla Löwy 2019-07-08 14:45:31 +02:00
parent 7dbdd2e6a5
commit 3e5331dc86
3 changed files with 114 additions and 41 deletions

View File

@ -338,6 +338,8 @@ typedef struct _GLFWlibraryWin32
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
// The window the cursor is captured in
_GLFWwindow* capturedCursorWindow;
RAWINPUT* rawInput;
int rawInputSize;
UINT mouseTrailSize;

View File

@ -253,20 +253,24 @@ static void updateCursorImage(_GLFWwindow* window)
SetCursor(NULL);
}
// Updates the cursor clip rect
// Sets the cursor clip rect to the window content area
//
static void updateClipRect(_GLFWwindow* window)
static void captureCursor(_GLFWwindow* window)
{
if (window)
{
RECT clipRect;
GetClientRect(window->win32.handle, &clipRect);
ClientToScreen(window->win32.handle, (POINT*) &clipRect.left);
ClientToScreen(window->win32.handle, (POINT*) &clipRect.right);
ClipCursor(&clipRect);
}
else
_glfw.win32.capturedCursorWindow = window;
}
// Disabled clip cursor
//
static void releaseCursor(void)
{
ClipCursor(NULL);
_glfw.win32.capturedCursorWindow = NULL;
}
// Enables WM_INPUT messages for the mouse for the specified window
@ -305,7 +309,7 @@ static void disableCursor(_GLFWwindow* window)
&_glfw.win32.restoreCursorPosY);
updateCursorImage(window);
_glfwCenterCursorInContentArea(window);
updateClipRect(window);
captureCursor(window);
if (window->rawMouseMotion)
enableRawMouseMotion(window);
@ -319,7 +323,7 @@ static void enableCursor(_GLFWwindow* window)
disableRawMouseMotion(window);
_glfw.win32.disabledCursorWindow = NULL;
updateClipRect(NULL);
releaseCursor();
_glfwPlatformSetCursorPos(window,
_glfw.win32.restoreCursorPosX,
_glfw.win32.restoreCursorPosY);
@ -980,8 +984,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
(window->win32.maximized &&
wParam != SIZE_RESTORED);
if (_glfw.win32.disabledCursorWindow == window)
updateClipRect(window);
if (_glfw.win32.capturedCursorWindow == window)
captureCursor(window);
if (window->win32.iconified != iconified)
_glfwInputWindowIconify(window, iconified);
@ -1010,8 +1014,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_MOVE:
{
if (_glfw.win32.disabledCursorWindow == window)
updateClipRect(window);
if (_glfw.win32.capturedCursorWindow == window)
captureCursor(window);
// NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as
// those macros do not handle negative window positions correctly
@ -1437,7 +1441,10 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
window->context.destroy(window);
if (_glfw.win32.disabledCursorWindow == window)
_glfw.win32.disabledCursorWindow = NULL;
enableCursor(window);
if (_glfw.win32.capturedCursorWindow == window)
releaseCursor();
if (window->win32.handle)
{
@ -2026,14 +2033,40 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{
if (_glfwPlatformWindowFocused(window))
{
if (mode == GLFW_CURSOR_DISABLED)
{
if (_glfwPlatformWindowFocused(window))
disableCursor(window);
_glfwPlatformGetCursorPos(window,
&_glfw.win32.restoreCursorPosX,
&_glfw.win32.restoreCursorPosY);
_glfwCenterCursorInContentArea(window);
if (window->rawMouseMotion)
enableRawMouseMotion(window);
}
else if (_glfw.win32.disabledCursorWindow == window)
enableCursor(window);
else if (cursorInContentArea(window))
{
if (window->rawMouseMotion)
disableRawMouseMotion(window);
}
if (mode == GLFW_CURSOR_DISABLED)
captureCursor(window);
else
releaseCursor();
if (mode == GLFW_CURSOR_DISABLED)
_glfw.win32.disabledCursorWindow = window;
else if (_glfw.win32.disabledCursorWindow == window)
{
_glfw.win32.disabledCursorWindow = NULL;
_glfwPlatformSetCursorPos(window,
_glfw.win32.restoreCursorPosX,
_glfw.win32.restoreCursorPosY);
}
}
if (cursorInContentArea(window))
updateCursorImage(window);
}

View File

@ -525,6 +525,25 @@ static void updateCursorImage(_GLFWwindow* window)
}
}
// Grabs the cursor and confines it to the window
//
static void captureCursor(_GLFWwindow* window)
{
XGrabPointer(_glfw.x11.display, window->x11.handle, True,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
GrabModeAsync, GrabModeAsync,
window->x11.handle,
None,
CurrentTime);
}
// Ungrabs the cursor
//
static void releaseCursor(void)
{
XUngrabPointer(_glfw.x11.display, CurrentTime);
}
// Enable XI2 raw mouse motion events
//
static void enableRawMouseMotion(_GLFWwindow* window)
@ -567,12 +586,7 @@ static void disableCursor(_GLFWwindow* window)
&_glfw.x11.restoreCursorPosY);
updateCursorImage(window);
_glfwCenterCursorInContentArea(window);
XGrabPointer(_glfw.x11.display, window->x11.handle, True,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
GrabModeAsync, GrabModeAsync,
window->x11.handle,
_glfw.x11.hiddenCursorHandle,
CurrentTime);
captureCursor(window);
}
// Exit disabled cursor mode for the specified window
@ -583,7 +597,7 @@ static void enableCursor(_GLFWwindow* window)
disableRawMouseMotion(window);
_glfw.x11.disabledCursorWindow = NULL;
XUngrabPointer(_glfw.x11.display, CurrentTime);
releaseCursor();
_glfwPlatformSetCursorPos(window,
_glfw.x11.restoreCursorPosX,
_glfw.x11.restoreCursorPosY);
@ -2022,7 +2036,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
{
if (_glfw.x11.disabledCursorWindow == window)
_glfw.x11.disabledCursorWindow = NULL;
enableCursor(window);
if (window->monitor)
releaseMonitor(window);
@ -2769,16 +2783,40 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{
if (_glfwPlatformWindowFocused(window))
{
if (mode == GLFW_CURSOR_DISABLED)
{
if (_glfwPlatformWindowFocused(window))
disableCursor(window);
_glfwPlatformGetCursorPos(window,
&_glfw.x11.restoreCursorPosX,
&_glfw.x11.restoreCursorPosY);
_glfwCenterCursorInContentArea(window);
if (window->rawMouseMotion)
enableRawMouseMotion(window);
}
else if (_glfw.x11.disabledCursorWindow == window)
enableCursor(window);
else
updateCursorImage(window);
{
if (window->rawMouseMotion)
disableRawMouseMotion(window);
}
if (mode == GLFW_CURSOR_DISABLED)
captureCursor(window);
else
releaseCursor();
if (mode == GLFW_CURSOR_DISABLED)
_glfw.x11.disabledCursorWindow = window;
else if (_glfw.x11.disabledCursorWindow == window)
{
_glfw.x11.disabledCursorWindow = NULL;
_glfwPlatformSetCursorPos(window,
_glfw.x11.restoreCursorPosX,
_glfw.x11.restoreCursorPosY);
}
}
updateCursorImage(window);
XFlush(_glfw.x11.display);
}