Add GLFW_RAW_INPUT and glfwRawInputSupported

This adds runtime per-window control of whether accelerated or raw mouse
motion is provided when the cursor is disabled.

Fixes #1400.
Closes #1401.
This commit is contained in:
Nathan Poirier
2018-12-14 03:08:25 +01:00
committed by Camilla Löwy
parent 5f9cbd0ebc
commit 9e29f556fd
11 changed files with 157 additions and 14 deletions
+10
View File
@@ -1297,6 +1297,16 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
[window->ns.object setAlphaValue:opacity];
}
void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled)
{
window->useRawInput = enabled;
}
GLFWbool _glfwPlatformRawInputSupported(void)
{
return GLFW_FALSE;
}
void _glfwPlatformPollEvents(void)
{
for (;;)
+10 -1
View File
@@ -484,6 +484,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
return window->stickyMouseButtons;
case GLFW_LOCK_KEY_MODS:
return window->lockKeyMods;
case GLFW_RAW_INPUT:
return window->useRawInput;
}
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
@@ -561,10 +563,18 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
}
else if (mode == GLFW_LOCK_KEY_MODS)
window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE;
else if (mode == GLFW_RAW_INPUT)
_glfwPlatformSetRawInput(window, value ? GLFW_TRUE : GLFW_FALSE);
else
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
}
GLFWAPI int glfwRawInputSupported(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(0);
return _glfwPlatformRawInputSupported();
}
GLFWAPI const char* glfwGetKeyName(int key, int scancode)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
@@ -1313,4 +1323,3 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void)
_GLFW_REQUIRE_INIT_OR_RETURN(0);
return _glfwPlatformGetTimerFrequency();
}
+3
View File
@@ -390,6 +390,7 @@ struct _GLFWwindow
char keys[GLFW_KEY_LAST + 1];
// Virtual cursor position when cursor is disabled
double virtualCursorPosX, virtualCursorPosY;
GLFWbool useRawInput;
_GLFWcontext context;
@@ -596,6 +597,8 @@ const char* _glfwPlatformGetVersionString(void);
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos);
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwPlatformRawInputSupported(void);
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image, int xhot, int yhot);
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape);
+10
View File
@@ -196,6 +196,16 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
{
}
void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled)
{
window->useRawInput = enabled;
}
GLFWbool _glfwPlatformRawInputSupported(void)
{
return GLFW_FALSE;
}
void _glfwPlatformShowWindow(_GLFWwindow* window)
{
}
+32 -5
View File
@@ -281,7 +281,7 @@ static void disableCursor(_GLFWwindow* window)
_glfwCenterCursorInContentArea(window);
updateClipRect(window);
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
if (window->useRawInput && !RegisterRawInputDevices(&rid, 1, sizeof(rid)))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to register raw input device");
@@ -301,7 +301,7 @@ static void enableCursor(_GLFWwindow* window)
_glfw.win32.restoreCursorPosY);
updateCursorImage(window);
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
if (window->useRawInput && !RegisterRawInputDevices(&rid, 1, sizeof(rid)))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to remove raw input device");
@@ -816,9 +816,18 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
// Disabled cursor motion input is provided by WM_INPUT
if (window->cursorMode == GLFW_CURSOR_DISABLED)
break;
{
if (_glfw.win32.disabledCursorWindow != window || window->useRawInput)
break;
_glfwInputCursorPos(window, x, y);
const int dx = x - window->win32.lastCursorPosX;
const int dy = y - window->win32.lastCursorPosY;
_glfwInputCursorPos(window,
window->virtualCursorPosX + dx,
window->virtualCursorPosY + dy);
}
else
_glfwInputCursorPos(window, x, y);
window->win32.lastCursorPosX = x;
window->win32.lastCursorPosY = y;
@@ -847,7 +856,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
int dx, dy;
// Only process input when disabled cursor mode is applied
if (_glfw.win32.disabledCursorWindow != window)
if (_glfw.win32.disabledCursorWindow != window || !window->useRawInput)
break;
GetRawInputData(ri, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER));
@@ -1845,6 +1854,24 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
}
}
void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled)
{
if (window->useRawInput != enabled)
{
int update = (_glfw.win32.disabledCursorWindow == window);
if (update)
enableCursor(window);
window->useRawInput = enabled;
if (update)
disableCursor(window);
}
}
GLFWbool _glfwPlatformRawInputSupported(void)
{
return GLFW_TRUE;
}
void _glfwPlatformPollEvents(void)
{
MSG msg;
+1 -1
View File
@@ -202,6 +202,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
window->floating = wndconfig.floating;
window->focusOnShow = wndconfig.focusOnShow;
window->cursorMode = GLFW_CURSOR_NORMAL;
window->useRawInput = GLFW_TRUE;
window->minwidth = GLFW_DONT_CARE;
window->minheight = GLFW_DONT_CARE;
@@ -1097,4 +1098,3 @@ GLFWAPI void glfwPostEmptyEvent(void)
_GLFW_REQUIRE_INIT();
_glfwPlatformPostEmptyEvent();
}
+10
View File
@@ -1318,6 +1318,16 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
{
}
void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled)
{
window->useRawInput = enabled;
}
GLFWbool _glfwPlatformRawInputSupported(void)
{
return GLFW_FALSE;
}
void _glfwPlatformPollEvents(void)
{
handleEvents(0);
+22 -3
View File
@@ -526,7 +526,7 @@ static void updateCursorImage(_GLFWwindow* window)
//
static void disableCursor(_GLFWwindow* window)
{
if (_glfw.x11.xi.available)
if (_glfw.x11.xi.available && window->useRawInput)
{
XIEventMask em;
unsigned char mask[XIMaskLen(XI_RawMotion)] = { 0 };
@@ -557,7 +557,7 @@ static void disableCursor(_GLFWwindow* window)
//
static void enableCursor(_GLFWwindow* window)
{
if (_glfw.x11.xi.available)
if (_glfw.x11.xi.available && window->useRawInput)
{
XIEventMask em;
unsigned char mask[] = { 0 };
@@ -1183,6 +1183,7 @@ static void processEvent(XEvent *event)
_GLFWwindow* window = _glfw.x11.disabledCursorWindow;
if (window &&
window->useRawInput &&
event->xcookie.extension == _glfw.x11.xi.majorOpcode &&
XGetEventData(_glfw.x11.display, &event->xcookie) &&
event->xcookie.evtype == XI_RawMotion)
@@ -1483,7 +1484,7 @@ static void processEvent(XEvent *event)
{
if (_glfw.x11.disabledCursorWindow != window)
return;
if (_glfw.x11.xi.available)
if (_glfw.x11.xi.available && window->useRawInput)
return;
const int dx = x - window->x11.lastCursorPosX;
@@ -2652,6 +2653,24 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
PropModeReplace, (unsigned char*) &value, 1);
}
void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled)
{
if (window->useRawInput != enabled)
{
int update = (_glfw.x11.disabledCursorWindow == window && _glfw.x11.xi.available);
if (update)
enableCursor(window);
window->useRawInput = enabled;
if (update)
disableCursor(window);
}
}
GLFWbool _glfwPlatformRawInputSupported(void)
{
return _glfw.x11.xi.available;
}
void _glfwPlatformPollEvents(void)
{
_GLFWwindow* window;