Rename raw input to raw mouse motion, cleanup

This renames 'raw input' to 'raw mouse motion' as there are other kinds
of raw input.  The update path is restructured to avoid reinitializing
all of disabled cursor mode.  Modification of shared state is moved out
into shared code.  Raw mouse motion is disabled by default for
compatibility.

Related to #1401.
This commit is contained in:
Camilla Löwy 2019-02-11 19:10:20 +01:00
parent 9e29f556fd
commit 1155c83013
13 changed files with 196 additions and 123 deletions

View File

@ -158,6 +158,8 @@ information on what to include when reporting a bug.
per-joystick user pointers per-joystick user pointers
- Added `glfwGetX11SelectionString` and `glfwSetX11SelectionString` - Added `glfwGetX11SelectionString` and `glfwSetX11SelectionString`
functions for accessing X11 primary selection (#894,#1056) functions for accessing X11 primary selection (#894,#1056)
- Added `glfwRawMouseMotionSupported` function for querying raw motion support
(#125,#1400,#1401)
- Added headless [OSMesa](http://mesa3d.org/osmesa.html) backend (#850) - Added headless [OSMesa](http://mesa3d.org/osmesa.html) backend (#850)
- Added definition of `GLAPIENTRY` to public header - Added definition of `GLAPIENTRY` to public header
- Added `GLFW_TRANSPARENT_FRAMEBUFFER` window hint and attribute for controlling - Added `GLFW_TRANSPARENT_FRAMEBUFFER` window hint and attribute for controlling
@ -171,6 +173,8 @@ information on what to include when reporting a bug.
(#676,#1115) (#676,#1115)
- Added `GLFW_JOYSTICK_HAT_BUTTONS` init hint (#889) - Added `GLFW_JOYSTICK_HAT_BUTTONS` init hint (#889)
- Added `GLFW_LOCK_KEY_MODS` input mode and `GLFW_MOD_*_LOCK` mod bits (#946) - Added `GLFW_LOCK_KEY_MODS` input mode and `GLFW_MOD_*_LOCK` mod bits (#946)
- Added `GLFW_RAW_MOUSE_MOTION` input mode for selecting raw motion input
(#125,#1400,#1401)
- Added macOS specific `GLFW_COCOA_RETINA_FRAMEBUFFER` window hint - Added macOS specific `GLFW_COCOA_RETINA_FRAMEBUFFER` window hint
- Added macOS specific `GLFW_COCOA_FRAME_NAME` window hint (#195) - Added macOS specific `GLFW_COCOA_FRAME_NAME` window hint (#195)
- Added macOS specific `GLFW_COCOA_GRAPHICS_SWITCHING` window hint (#377,#935) - Added macOS specific `GLFW_COCOA_GRAPHICS_SWITCHING` window hint (#377,#935)
@ -182,7 +186,6 @@ information on what to include when reporting a bug.
- Added `GLFW_OSMESA_CONTEXT_API` for creating OpenGL contexts with - Added `GLFW_OSMESA_CONTEXT_API` for creating OpenGL contexts with
[OSMesa](https://www.mesa3d.org/osmesa.html) (#281) [OSMesa](https://www.mesa3d.org/osmesa.html) (#281)
- Added `GenerateMappings.cmake` script for updating gamepad mappings - Added `GenerateMappings.cmake` script for updating gamepad mappings
- Added `GLFW_RAW_INPUT` input mode and `glfwRawInputSupported` function (#1401)
- Made `glfwCreateWindowSurface` emit an error when the window has a context - Made `glfwCreateWindowSurface` emit an error when the window has a context
(#1194,#1205) (#1194,#1205)
- Deprecated window parameter of clipboard string functions - Deprecated window parameter of clipboard string functions
@ -203,7 +206,6 @@ information on what to include when reporting a bug.
- Bugfix: The gamma ramp generated by `glfwSetGamma` did not use the monitor - Bugfix: The gamma ramp generated by `glfwSetGamma` did not use the monitor
ramp size (#1387,#1388) ramp size (#1387,#1388)
- [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] Removed XInput circular deadzone from joystick axis data (#1045) - [Win32] Removed XInput circular deadzone from joystick axis data (#1045)
- [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)
@ -233,7 +235,6 @@ information on what to include when reporting a bug.
- [Win32] Bugfix: A title bar would be drawn over undecorated windows in some - [Win32] Bugfix: A title bar would be drawn over undecorated windows in some
circumstances (#1383) circumstances (#1383)
- [Win32] Bugfix: Standard cursors were not per-monitor DPI aware (#1431) - [Win32] Bugfix: Standard cursors were not per-monitor DPI aware (#1431)
- [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125)
- [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading - [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading
- [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X - [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X
- [X11] Bugfix: Dynamic X11 library loading did not use full sonames (#941) - [X11] Bugfix: Dynamic X11 library loading did not use full sonames (#941)
@ -437,6 +438,7 @@ skills.
- Cyril Pichard - Cyril Pichard
- Keith Pitt - Keith Pitt
- Stanislav Podgorskiy - Stanislav Podgorskiy
- Nathan Poirier
- Alexandre Pretyman - Alexandre Pretyman
- przemekmirek - przemekmirek
- Philip Rideout - Philip Rideout
@ -490,7 +492,6 @@ skills.
- Santi Zupancic - Santi Zupancic
- Jonas Ådahl - Jonas Ådahl
- Lasse Öörni - Lasse Öörni
- Nathan Poirier
- All the unmentioned and anonymous contributors in the GLFW community, for bug - All the unmentioned and anonymous contributors in the GLFW community, for bug
reports, patches, feedback, testing and encouragement reports, patches, feedback, testing and encouragement

View File

@ -233,7 +233,7 @@ arguments can always be passed unmodified to this function.
@section input_mouse Mouse input @section input_mouse Mouse input
Mouse input comes in many forms, including cursor motion, button presses and Mouse input comes in many forms, including mouse motion, button presses and
scrolling offsets. The cursor appearance can also be changed, either to scrolling offsets. The cursor appearance can also be changed, either to
a custom image or a standard cursor shape from the system theme. a custom image or a standard cursor shape from the system theme.
@ -308,6 +308,31 @@ glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
@endcode @endcode
@anchor GLFW_RAW_MOUSE_MOTION
@subsection raw_mouse_motion Raw mouse motion
When the cursor is disabled, raw (unscaled and unaccelerated) mouse motion can
be enabled if available.
Raw mouse motion is closer to the actual motion of the mouse across a surface.
It is not affected by the scaling and acceleration applied to the motion of the
desktop cursor. That processing is suitable for a cursor while raw motion is
better for controlling for example a 3D camera. Because of this, raw mouse
motion is only provided when the cursor is disabled.
Call @ref glfwRawMouseMotionSupported to check if the current machine provides
raw motion and set the `GLFW_RAW_MOUSE_MOTION` input mode to enable it. It is
disabled by default.
@code
if (glfwRawMouseMotionSupported())
glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);
@endcode
If supported, raw mouse motion can be enabled or disabled per-window and at any
time but it will only be provided when the cursor is disabled.
@subsection cursor_object Cursor objects @subsection cursor_object Cursor objects
GLFW supports creating both custom and system theme cursor images, encapsulated GLFW supports creating both custom and system theme cursor images, encapsulated

View File

@ -135,8 +135,10 @@ attribute corresponds to the [cursor enter/leave](@ref cursor_enter) event.
@subsection news_33_rawmotion Support for raw mouse motion @subsection news_33_rawmotion Support for raw mouse motion
GLFW now uses raw (unscaled and unaccelerated) mouse motion in disabled cursor GLFW now supports raw (unscaled and unaccelerated) mouse motion in disabled
mode on platforms where this is available, specifically Windows and X11. cursor mode with the [GLFW_RAW_MOUSE_MOTION](@ref GLFW_RAW_MOUSE_MOTION) input
mode. Call @ref glfwRawMouseMotionSupported to check if the current machine
supports raw mouse motion.
@subsection news_33_moltenvk Support for Vulkan on macOS via MoltenVK @subsection news_33_moltenvk Support for Vulkan on macOS via MoltenVK

View File

@ -1002,7 +1002,7 @@ extern "C" {
#define GLFW_STICKY_KEYS 0x00033002 #define GLFW_STICKY_KEYS 0x00033002
#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003 #define GLFW_STICKY_MOUSE_BUTTONS 0x00033003
#define GLFW_LOCK_KEY_MODS 0x00033004 #define GLFW_LOCK_KEY_MODS 0x00033004
#define GLFW_RAW_INPUT 0x00033005 #define GLFW_RAW_MOUSE_MOTION 0x00033005
#define GLFW_CURSOR_NORMAL 0x00034001 #define GLFW_CURSOR_NORMAL 0x00034001
#define GLFW_CURSOR_HIDDEN 0x00034002 #define GLFW_CURSOR_HIDDEN 0x00034002
@ -3814,11 +3814,12 @@ GLFWAPI void glfwPostEmptyEvent(void);
* This function returns the value of an input option for the specified window. * This function returns the value of an input option for the specified window.
* The mode must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS, * The mode must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS,
* @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or
* @ref GLFW_RAW_INPUT. * @ref GLFW_RAW_MOUSE_MOTION.
* *
* @param[in] window The window to query. * @param[in] window The window to query.
* @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`, * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`,
* `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or `GLFW_RAW_INPUT`. * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or
* `GLFW_RAW_MOUSE_MOTION`.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_INVALID_ENUM. * GLFW_INVALID_ENUM.
@ -3838,7 +3839,7 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
* This function sets an input mode option for the specified window. The mode * This function sets an input mode option for the specified window. The mode
* must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS, * must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS,
* @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or
* @ref GLFW_RAW_INPUT. * @ref GLFW_RAW_MOUSE_MOTION.
* *
* If the mode is `GLFW_CURSOR`, the value must be one of the following cursor * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor
* modes: * modes:
@ -3870,14 +3871,16 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
* GLFW_MOD_CAPS_LOCK bit set when the event was generated with Caps Lock on, * GLFW_MOD_CAPS_LOCK bit set when the event was generated with Caps Lock on,
* and the @ref GLFW_MOD_NUM_LOCK bit when Num Lock was on. * and the @ref GLFW_MOD_NUM_LOCK bit when Num Lock was on.
* *
* If the mode is `GLFW_RAW_INPUT`, the value must be either `GLFW_TRUE` to * If the mode is `GLFW_RAW_MOUSE_MOTION`, the value must be either `GLFW_TRUE`
* enable the use of raw input, or `GLFW_FALSE` to disable it. If enabled and * to enable raw (unscaled and unaccelerated) mouse motion when the cursor is
* supported by the machine, the program will retrieve high-definition mouse * disabled, or `GLFW_FALSE` to disable it. If raw motion is not supported,
* movement when cursor is grabbed. * attempting to set this will emit @ref GLFW_PLATFORM_ERROR. Call @ref
* glfwRawMouseMotionSupported to check for support.
* *
* @param[in] window The window whose input mode to set. * @param[in] window The window whose input mode to set.
* @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`, * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`,
* `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or `GLFW_RAW_INPUT`. * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or
* `GLFW_RAW_MOUSE_MOTION`.
* @param[in] value The new value of the specified input mode. * @param[in] value The new value of the specified input mode.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
@ -3893,37 +3896,34 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
*/ */
GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);
/*! @brief Returns whether the raw input is supported. /*! @brief Returns whether raw mouse motion is supported.
* *
* This function returns whether the raw input is supported by the current * This function returns whether raw mouse motion is supported on the current
* machine. * system. This status does not change after GLFW has been initialized so you
* only need to check this once. If you attempt to enable raw motion on
* a system that does not support it, @ref GLFW_PLATFORM_ERROR will be emitted.
* *
* Raw input allow to retrieve high-definition movement from mouse. * Raw mouse motion is closer to the actual motion of the mouse across
* Input from a high-definition mouse is much more precise than that from a * a surface. It is not affected by the scaling and acceleration applied to
* standard mouse. But often, they cannot be obtained through standard * the motion of the desktop cursor. That processing is suitable for a cursor
* platforms API which transform mouse movement using their own improvements * while raw motion is better for controlling for example a 3D camera. Because
* (like pointer acceleration). Platform's improvements are ideal for pointer * of this, raw mouse motion is only provided when the cursor is disabled.
* control but it is not so good for moving a first-person camera. For this
* reason when the cursor of a window is grabbed by setting @ref GLFW_CURSOR
* to @ref GLFW_CURSOR_DISABLED, raw input is used.
* *
* The use of raw input can be disabled using @ref glfwSetInputMode with * @return `GLFW_TRUE` if raw mouse motion is supported on the current machine,
* @ref GLFW_RAW_INPUT mode. * or `GLFW_FALSE` otherwise.
*
* @return `GLFW_TRUE` if high-definition mouse movement is supported, or
* `GLFW_FALSE` otherwise.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
* *
* @thread_safety This function may be called from any thread. * @thread_safety This function must only be called from the main thread.
* *
* @sa @ref raw_mouse_motion
* @sa @ref glfwSetInputMode * @sa @ref glfwSetInputMode
* *
* @since Added in version 3.3. * @since Added in version 3.3.
* *
* @ingroup input * @ingroup input
*/ */
GLFWAPI int glfwRawInputSupported(void); GLFWAPI int glfwRawMouseMotionSupported(void);
/*! @brief Returns the layout-specific name of the specified printable key. /*! @brief Returns the layout-specific name of the specified printable key.
* *

View File

@ -1297,12 +1297,11 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
[window->ns.object setAlphaValue:opacity]; [window->ns.object setAlphaValue:opacity];
} }
void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled) void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
{ {
window->useRawInput = enabled;
} }
GLFWbool _glfwPlatformRawInputSupported(void) GLFWbool _glfwPlatformRawMouseMotionSupported(void)
{ {
return GLFW_FALSE; return GLFW_FALSE;
} }

View File

@ -463,6 +463,7 @@ void _glfwCenterCursorInContentArea(_GLFWwindow* window)
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW public API ////// ////// GLFW public API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -484,8 +485,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
return window->stickyMouseButtons; return window->stickyMouseButtons;
case GLFW_LOCK_KEY_MODS: case GLFW_LOCK_KEY_MODS:
return window->lockKeyMods; return window->lockKeyMods;
case GLFW_RAW_INPUT: case GLFW_RAW_MOUSE_MOTION:
return window->useRawInput; return window->rawMouseMotion;
} }
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
@ -562,17 +563,33 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
window->stickyMouseButtons = value; window->stickyMouseButtons = value;
} }
else if (mode == GLFW_LOCK_KEY_MODS) else if (mode == GLFW_LOCK_KEY_MODS)
{
window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE; window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE;
else if (mode == GLFW_RAW_INPUT) }
_glfwPlatformSetRawInput(window, value ? GLFW_TRUE : GLFW_FALSE); else if (mode == GLFW_RAW_MOUSE_MOTION)
{
if (!_glfwPlatformRawMouseMotionSupported())
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Raw mouse motion is not supported on this system");
return;
}
value = value ? GLFW_TRUE : GLFW_FALSE;
if (window->rawMouseMotion == value)
return;
window->rawMouseMotion = value;
_glfwPlatformSetRawMouseMotion(window, value);
}
else else
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
} }
GLFWAPI int glfwRawInputSupported(void) GLFWAPI int glfwRawMouseMotionSupported(void)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(0); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
return _glfwPlatformRawInputSupported(); return _glfwPlatformRawMouseMotionSupported();
} }
GLFWAPI const char* glfwGetKeyName(int key, int scancode) GLFWAPI const char* glfwGetKeyName(int key, int scancode)

View File

@ -390,7 +390,7 @@ struct _GLFWwindow
char keys[GLFW_KEY_LAST + 1]; char keys[GLFW_KEY_LAST + 1];
// Virtual cursor position when cursor is disabled // Virtual cursor position when cursor is disabled
double virtualCursorPosX, virtualCursorPosY; double virtualCursorPosX, virtualCursorPosY;
GLFWbool useRawInput; GLFWbool rawMouseMotion;
_GLFWcontext context; _GLFWcontext context;
@ -597,8 +597,8 @@ const char* _glfwPlatformGetVersionString(void);
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos); void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos); void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos);
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode); void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled); void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwPlatformRawInputSupported(void); GLFWbool _glfwPlatformRawMouseMotionSupported(void);
int _glfwPlatformCreateCursor(_GLFWcursor* cursor, int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image, int xhot, int yhot); const GLFWimage* image, int xhot, int yhot);
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape); int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape);

View File

@ -196,12 +196,11 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
{ {
} }
void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled) void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
{ {
window->useRawInput = enabled;
} }
GLFWbool _glfwPlatformRawInputSupported(void) GLFWbool _glfwPlatformRawMouseMotionSupported(void)
{ {
return GLFW_FALSE; return GLFW_FALSE;
} }

View File

@ -267,12 +267,36 @@ static void updateClipRect(_GLFWwindow* window)
ClipCursor(NULL); ClipCursor(NULL);
} }
// Enables WM_INPUT messages for the mouse for the specified window
//
static void enableRawMouseMotion(_GLFWwindow* window)
{
const RAWINPUTDEVICE rid = { 0x01, 0x02, 0, window->win32.handle };
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to register raw input device");
}
}
// Disables WM_INPUT messages for the mouse
//
static void disableRawMouseMotion(_GLFWwindow* window)
{
const RAWINPUTDEVICE rid = { 0x01, 0x02, RIDEV_REMOVE, NULL };
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to remove raw input device");
}
}
// Apply disabled cursor mode to a focused window // Apply disabled cursor mode to a focused window
// //
static void disableCursor(_GLFWwindow* window) static void disableCursor(_GLFWwindow* window)
{ {
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,
@ -281,18 +305,16 @@ static void disableCursor(_GLFWwindow* window)
_glfwCenterCursorInContentArea(window); _glfwCenterCursorInContentArea(window);
updateClipRect(window); updateClipRect(window);
if (window->useRawInput && !RegisterRawInputDevices(&rid, 1, sizeof(rid))) if (window->rawMouseMotion)
{ enableRawMouseMotion(window);
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to register raw input device");
}
} }
// Exit disabled cursor mode for the specified window // Exit disabled cursor mode for the specified window
// //
static void enableCursor(_GLFWwindow* window) static void enableCursor(_GLFWwindow* window)
{ {
const RAWINPUTDEVICE rid = { 0x01, 0x02, RIDEV_REMOVE, NULL }; if (window->rawMouseMotion)
disableRawMouseMotion(window);
_glfw.win32.disabledCursorWindow = NULL; _glfw.win32.disabledCursorWindow = NULL;
updateClipRect(NULL); updateClipRect(NULL);
@ -300,12 +322,6 @@ static void enableCursor(_GLFWwindow* window)
_glfw.win32.restoreCursorPosX, _glfw.win32.restoreCursorPosX,
_glfw.win32.restoreCursorPosY); _glfw.win32.restoreCursorPosY);
updateCursorImage(window); updateCursorImage(window);
if (window->useRawInput && !RegisterRawInputDevices(&rid, 1, sizeof(rid)))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to remove raw input device");
}
} }
// Returns whether the cursor is in the content area of the specified window // Returns whether the cursor is in the content area of the specified window
@ -817,11 +833,14 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
// Disabled cursor motion input is provided by WM_INPUT // Disabled cursor motion input is provided by WM_INPUT
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
{ {
if (_glfw.win32.disabledCursorWindow != window || window->useRawInput)
break;
const int dx = x - window->win32.lastCursorPosX; const int dx = x - window->win32.lastCursorPosX;
const int dy = y - window->win32.lastCursorPosY; const int dy = y - window->win32.lastCursorPosY;
if (_glfw.win32.disabledCursorWindow != window)
break;
if (window->rawMouseMotion)
break;
_glfwInputCursorPos(window, _glfwInputCursorPos(window,
window->virtualCursorPosX + dx, window->virtualCursorPosX + dx,
window->virtualCursorPosY + dy); window->virtualCursorPosY + dy);
@ -855,8 +874,9 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
RAWINPUT* data; RAWINPUT* data;
int dx, dy; 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;
if (!window->rawMouseMotion)
break; break;
GetRawInputData(ri, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); GetRawInputData(ri, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER));
@ -1854,20 +1874,18 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
} }
} }
void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled) void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
{ {
if (window->useRawInput != enabled) if (_glfw.win32.disabledCursorWindow != window)
{ return;
int update = (_glfw.win32.disabledCursorWindow == window);
if (update) if (enabled)
enableCursor(window); enableRawMouseMotion(window);
window->useRawInput = enabled; else
if (update) disableRawMouseMotion(window);
disableCursor(window);
}
} }
GLFWbool _glfwPlatformRawInputSupported(void) GLFWbool _glfwPlatformRawMouseMotionSupported(void)
{ {
return GLFW_TRUE; return GLFW_TRUE;
} }

View File

@ -202,7 +202,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
window->floating = wndconfig.floating; window->floating = wndconfig.floating;
window->focusOnShow = wndconfig.focusOnShow; window->focusOnShow = wndconfig.focusOnShow;
window->cursorMode = GLFW_CURSOR_NORMAL; window->cursorMode = GLFW_CURSOR_NORMAL;
window->useRawInput = GLFW_TRUE;
window->minwidth = GLFW_DONT_CARE; window->minwidth = GLFW_DONT_CARE;
window->minheight = GLFW_DONT_CARE; window->minheight = GLFW_DONT_CARE;

View File

@ -1318,12 +1318,11 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
{ {
} }
void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled) void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
{ {
window->useRawInput = enabled;
} }
GLFWbool _glfwPlatformRawInputSupported(void) GLFWbool _glfwPlatformRawMouseMotionSupported(void)
{ {
return GLFW_FALSE; return GLFW_FALSE;
} }

View File

@ -522,22 +522,41 @@ static void updateCursorImage(_GLFWwindow* window)
} }
} }
// Enable XI2 raw mouse motion events
//
static void enableRawMouseMotion(_GLFWwindow* window)
{
XIEventMask em;
unsigned char mask[XIMaskLen(XI_RawMotion)] = { 0 };
em.deviceid = XIAllMasterDevices;
em.mask_len = sizeof(mask);
em.mask = mask;
XISetMask(mask, XI_RawMotion);
XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
}
// Disable XI2 raw mouse motion events
//
static void disableRawMouseMotion(_GLFWwindow* window)
{
XIEventMask em;
unsigned char mask[] = { 0 };
em.deviceid = XIAllMasterDevices;
em.mask_len = sizeof(mask);
em.mask = mask;
XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
}
// Apply disabled cursor mode to a focused window // Apply disabled cursor mode to a focused window
// //
static void disableCursor(_GLFWwindow* window) static void disableCursor(_GLFWwindow* window)
{ {
if (_glfw.x11.xi.available && window->useRawInput) if (window->rawMouseMotion)
{ enableRawMouseMotion(window);
XIEventMask em;
unsigned char mask[XIMaskLen(XI_RawMotion)] = { 0 };
em.deviceid = XIAllMasterDevices;
em.mask_len = sizeof(mask);
em.mask = mask;
XISetMask(mask, XI_RawMotion);
XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
}
_glfw.x11.disabledCursorWindow = window; _glfw.x11.disabledCursorWindow = window;
_glfwPlatformGetCursorPos(window, _glfwPlatformGetCursorPos(window,
@ -557,17 +576,8 @@ static void disableCursor(_GLFWwindow* window)
// //
static void enableCursor(_GLFWwindow* window) static void enableCursor(_GLFWwindow* window)
{ {
if (_glfw.x11.xi.available && window->useRawInput) if (window->rawMouseMotion)
{ disableRawMouseMotion(window);
XIEventMask em;
unsigned char mask[] = { 0 };
em.deviceid = XIAllMasterDevices;
em.mask_len = sizeof(mask);
em.mask = mask;
XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
}
_glfw.x11.disabledCursorWindow = NULL; _glfw.x11.disabledCursorWindow = NULL;
XUngrabPointer(_glfw.x11.display, CurrentTime); XUngrabPointer(_glfw.x11.display, CurrentTime);
@ -1183,7 +1193,7 @@ static void processEvent(XEvent *event)
_GLFWwindow* window = _glfw.x11.disabledCursorWindow; _GLFWwindow* window = _glfw.x11.disabledCursorWindow;
if (window && if (window &&
window->useRawInput && window->rawMouseMotion &&
event->xcookie.extension == _glfw.x11.xi.majorOpcode && event->xcookie.extension == _glfw.x11.xi.majorOpcode &&
XGetEventData(_glfw.x11.display, &event->xcookie) && XGetEventData(_glfw.x11.display, &event->xcookie) &&
event->xcookie.evtype == XI_RawMotion) event->xcookie.evtype == XI_RawMotion)
@ -1484,7 +1494,7 @@ static void processEvent(XEvent *event)
{ {
if (_glfw.x11.disabledCursorWindow != window) if (_glfw.x11.disabledCursorWindow != window)
return; return;
if (_glfw.x11.xi.available && window->useRawInput) if (window->rawMouseMotion)
return; return;
const int dx = x - window->x11.lastCursorPosX; const int dx = x - window->x11.lastCursorPosX;
@ -2653,20 +2663,21 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
PropModeReplace, (unsigned char*) &value, 1); PropModeReplace, (unsigned char*) &value, 1);
} }
void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled) void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
{ {
if (window->useRawInput != enabled) if (!_glfw.x11.xi.available)
{ return;
int update = (_glfw.x11.disabledCursorWindow == window && _glfw.x11.xi.available);
if (update) if (_glfw.x11.disabledCursorWindow != window)
enableCursor(window); return;
window->useRawInput = enabled;
if (update) if (enabled)
disableCursor(window); enableRawMouseMotion(window);
} else
disableRawMouseMotion(window);
} }
GLFWbool _glfwPlatformRawInputSupported(void) GLFWbool _glfwPlatformRawMouseMotionSupported(void)
{ {
return _glfw.x11.xi.available; return _glfw.x11.xi.available;
} }

View File

@ -164,14 +164,17 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
break; break;
case GLFW_KEY_R: case GLFW_KEY_R:
if (glfwGetInputMode(window, GLFW_RAW_INPUT)) if (!glfwRawMouseMotionSupported())
break;
if (glfwGetInputMode(window, GLFW_RAW_MOUSE_MOTION))
{ {
glfwSetInputMode(window, GLFW_RAW_INPUT, GLFW_FALSE); glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_FALSE);
printf("(( raw input is disabled ))\n"); printf("(( raw input is disabled ))\n");
} }
else else
{ {
glfwSetInputMode(window, GLFW_RAW_INPUT, GLFW_TRUE); glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);
printf("(( raw input is enabled ))\n"); printf("(( raw input is enabled ))\n");
} }
break; break;