mirror of
https://github.com/glfw/glfw.git
synced 2024-11-25 03:25:10 +00:00
Unlimited mouse button input mode
This adds the GLFW_UNLIMITED_MOUSE_BUTTONS input mode which permits mouse buttons over GLFW_MOUSE_BUTTON_LAST to be reported to the mouse button callback. Closes #2423
This commit is contained in:
parent
dc557ecf38
commit
bf945f1213
@ -121,6 +121,9 @@ information on what to include when reporting a bug.
|
|||||||
|
|
||||||
## Changelog since 3.4
|
## Changelog since 3.4
|
||||||
|
|
||||||
|
- Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond
|
||||||
|
the limit of the mouse button tokens to be reported (#2423)
|
||||||
|
|
||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
|
|
||||||
|
@ -492,6 +492,20 @@ a mouse button callback.
|
|||||||
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@anchor GLFW_UNLIMITED_MOUSE_BUTTONS
|
||||||
|
To handle all mouse buttons in the callback, instead of only ones with associated
|
||||||
|
[button tokens](@ref buttons), set the @ref GLFW_UNLIMITED_MOUSE_BUTTONS
|
||||||
|
input mode.
|
||||||
|
|
||||||
|
```c
|
||||||
|
glfwSetInputMode(window, GLFW_UNLIMITED_MOUSE_BUTTONS, GLFW_TRUE);
|
||||||
|
```
|
||||||
|
|
||||||
|
When this input mode is enabled, GLFW doesn't limit the reported mouse buttons
|
||||||
|
to only those that have an associated button token, for compatibility with
|
||||||
|
earlier versions of GLFW, which never reported any buttons over
|
||||||
|
@ref GLFW_MOUSE_BUTTON_LAST, on which users could have relied on.
|
||||||
|
|
||||||
The callback function receives the [mouse button](@ref buttons), button action
|
The callback function receives the [mouse button](@ref buttons), button action
|
||||||
and [modifier bits](@ref mods).
|
and [modifier bits](@ref mods).
|
||||||
|
|
||||||
@ -503,11 +517,16 @@ void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The mouse button is an integer that can be one of the
|
||||||
|
[mouse button tokens](@ref buttons) or, if the
|
||||||
|
@ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode is set, any other positive value.
|
||||||
|
|
||||||
The action is one of `GLFW_PRESS` or `GLFW_RELEASE`.
|
The action is one of `GLFW_PRESS` or `GLFW_RELEASE`.
|
||||||
|
|
||||||
The last reported state for every [supported mouse button](@ref buttons) is also
|
The last reported state for every [mouse button token](@ref buttons) is also
|
||||||
saved in per-window state arrays that can be polled with @ref
|
saved in per-window state arrays that can be polled with @ref
|
||||||
glfwGetMouseButton.
|
glfwGetMouseButton. This is not effected by the @ref GLFW_UNLIMITED_MOUSE_BUTTONS
|
||||||
|
input mode.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
|
int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
|
||||||
@ -540,7 +559,7 @@ had been processed in the meantime, the state will reset to `GLFW_RELEASE`,
|
|||||||
otherwise it will remain `GLFW_PRESS`.
|
otherwise it will remain `GLFW_PRESS`.
|
||||||
|
|
||||||
The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any
|
The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any
|
||||||
[supported mouse button](@ref buttons).
|
[mouse button token](@ref buttons).
|
||||||
|
|
||||||
|
|
||||||
### Scroll input {#scrolling}
|
### Scroll input {#scrolling}
|
||||||
|
11
docs/news.md
11
docs/news.md
@ -5,6 +5,15 @@
|
|||||||
|
|
||||||
## New features {#features}
|
## New features {#features}
|
||||||
|
|
||||||
|
### Unlimited mouse buttons {#unlimited_mouse_buttons}
|
||||||
|
|
||||||
|
GLFW now has an input mode which allows an unlimited number of mouse buttons to
|
||||||
|
be reported by the mouse buttton callback, rather than just the associated
|
||||||
|
[mouse button tokens](@ref buttons). This allows using mouse buttons with
|
||||||
|
values over 8. For compatibility with older versions, the
|
||||||
|
@ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode needs to be set to make use of
|
||||||
|
this.
|
||||||
|
|
||||||
## Caveats {#caveats}
|
## Caveats {#caveats}
|
||||||
|
|
||||||
## Deprecations {#deprecations}
|
## Deprecations {#deprecations}
|
||||||
@ -19,6 +28,8 @@
|
|||||||
|
|
||||||
### New constants {#new_constants}
|
### New constants {#new_constants}
|
||||||
|
|
||||||
|
- @ref GLFW_UNLIMITED_MOUSE_BUTTONS
|
||||||
|
|
||||||
## Release notes for earlier versions {#news_archive}
|
## Release notes for earlier versions {#news_archive}
|
||||||
|
|
||||||
- [Release notes for 3.4](https://www.glfw.org/docs/3.4/news.html)
|
- [Release notes for 3.4](https://www.glfw.org/docs/3.4/news.html)
|
||||||
|
@ -1154,6 +1154,7 @@ extern "C" {
|
|||||||
#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_MOUSE_MOTION 0x00033005
|
#define GLFW_RAW_MOUSE_MOTION 0x00033005
|
||||||
|
#define GLFW_UNLIMITED_MOUSE_BUTTONS 0x00033006
|
||||||
|
|
||||||
#define GLFW_CURSOR_NORMAL 0x00034001
|
#define GLFW_CURSOR_NORMAL 0x00034001
|
||||||
#define GLFW_CURSOR_HIDDEN 0x00034002
|
#define GLFW_CURSOR_HIDDEN 0x00034002
|
||||||
@ -4676,8 +4677,8 @@ 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
|
||||||
* @ref GLFW_RAW_MOUSE_MOTION.
|
* @ref GLFW_RAW_MOUSE_MOTION, or @ref GLFW_UNLIMITED_MOUSE_BUTTONS.
|
||||||
*
|
*
|
||||||
* 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:
|
||||||
@ -4717,6 +4718,11 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
|
|||||||
* attempting to set this will emit @ref GLFW_FEATURE_UNAVAILABLE. Call @ref
|
* attempting to set this will emit @ref GLFW_FEATURE_UNAVAILABLE. Call @ref
|
||||||
* glfwRawMouseMotionSupported to check for support.
|
* glfwRawMouseMotionSupported to check for support.
|
||||||
*
|
*
|
||||||
|
* If the mode is `GLFW_UNLIMITED_MOUSE_BUTTONS`, the value must be either
|
||||||
|
* `GLFW_TRUE` to disable the mouse button limit when calling the mouse button
|
||||||
|
* callback, or `GLFW_FALSE` to limit the mouse buttons sent to the callback
|
||||||
|
* to the mouse button token values up to `GLFW_MOUSE_BUTTON_LAST`.
|
||||||
|
*
|
||||||
* @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_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or
|
||||||
@ -4911,8 +4917,11 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
|
|||||||
* returns `GLFW_PRESS` the first time you call it for a mouse button that was
|
* returns `GLFW_PRESS` the first time you call it for a mouse button that was
|
||||||
* pressed, even if that mouse button has already been released.
|
* pressed, even if that mouse button has already been released.
|
||||||
*
|
*
|
||||||
|
* The @ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode does not effect the
|
||||||
|
* limit on buttons which can be polled with this function.
|
||||||
|
*
|
||||||
* @param[in] window The desired window.
|
* @param[in] window The desired window.
|
||||||
* @param[in] button The desired [mouse button](@ref buttons).
|
* @param[in] button The desired [mouse button token](@ref buttons).
|
||||||
* @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
|
* @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||||
@ -5288,10 +5297,15 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods
|
|||||||
* is called when a mouse button is pressed or released.
|
* is called when a mouse button is pressed or released.
|
||||||
*
|
*
|
||||||
* When a window loses input focus, it will generate synthetic mouse button
|
* When a window loses input focus, it will generate synthetic mouse button
|
||||||
* release events for all pressed mouse buttons. You can tell these events
|
* release events for all pressed mouse buttons with associated button tokens.
|
||||||
* from user-generated events by the fact that the synthetic ones are generated
|
* You can tell these events from user-generated events by the fact that the
|
||||||
* after the focus loss event has been processed, i.e. after the
|
* synthetic ones are generated after the focus loss event has been processed,
|
||||||
* [window focus callback](@ref glfwSetWindowFocusCallback) has been called.
|
* i.e. after the [window focus callback](@ref glfwSetWindowFocusCallback) has
|
||||||
|
* been called.
|
||||||
|
*
|
||||||
|
* The reported `button` value can be higher than `GLFW_MOUSE_BUTTON_LAST` if
|
||||||
|
* the button does not have an associated [button token](@ref buttons) and the
|
||||||
|
* @ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode is set.
|
||||||
*
|
*
|
||||||
* @param[in] window The window whose callback to set.
|
* @param[in] window The window whose callback to set.
|
||||||
* @param[in] callback The new callback, or `NULL` to remove the currently set
|
* @param[in] callback The new callback, or `NULL` to remove the currently set
|
||||||
|
14
src/input.c
14
src/input.c
@ -348,20 +348,22 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
|
|||||||
{
|
{
|
||||||
assert(window != NULL);
|
assert(window != NULL);
|
||||||
assert(button >= 0);
|
assert(button >= 0);
|
||||||
assert(button <= GLFW_MOUSE_BUTTON_LAST);
|
|
||||||
assert(action == GLFW_PRESS || action == GLFW_RELEASE);
|
assert(action == GLFW_PRESS || action == GLFW_RELEASE);
|
||||||
assert(mods == (mods & GLFW_MOD_MASK));
|
assert(mods == (mods & GLFW_MOD_MASK));
|
||||||
|
|
||||||
if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
|
if (button < 0 || (!window->disableMouseButtonLimit && button > GLFW_MOUSE_BUTTON_LAST))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!window->lockKeyMods)
|
if (!window->lockKeyMods)
|
||||||
mods &= ~(GLFW_MOD_CAPS_LOCK | GLFW_MOD_NUM_LOCK);
|
mods &= ~(GLFW_MOD_CAPS_LOCK | GLFW_MOD_NUM_LOCK);
|
||||||
|
|
||||||
|
if (button <= GLFW_MOUSE_BUTTON_LAST)
|
||||||
|
{
|
||||||
if (action == GLFW_RELEASE && window->stickyMouseButtons)
|
if (action == GLFW_RELEASE && window->stickyMouseButtons)
|
||||||
window->mouseButtons[button] = _GLFW_STICK;
|
window->mouseButtons[button] = _GLFW_STICK;
|
||||||
else
|
else
|
||||||
window->mouseButtons[button] = (char) action;
|
window->mouseButtons[button] = (char) action;
|
||||||
|
}
|
||||||
|
|
||||||
if (window->callbacks.mouseButton)
|
if (window->callbacks.mouseButton)
|
||||||
window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods);
|
window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods);
|
||||||
@ -576,6 +578,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
|
|||||||
return window->lockKeyMods;
|
return window->lockKeyMods;
|
||||||
case GLFW_RAW_MOUSE_MOTION:
|
case GLFW_RAW_MOUSE_MOTION:
|
||||||
return window->rawMouseMotion;
|
return window->rawMouseMotion;
|
||||||
|
case GLFW_UNLIMITED_MOUSE_BUTTONS:
|
||||||
|
return window->disableMouseButtonLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
||||||
@ -683,6 +687,12 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
|||||||
_glfw.platform.setRawMouseMotion(window, value);
|
_glfw.platform.setRawMouseMotion(window, value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case GLFW_UNLIMITED_MOUSE_BUTTONS:
|
||||||
|
{
|
||||||
|
window->disableMouseButtonLimit = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
||||||
|
@ -544,6 +544,7 @@ struct _GLFWwindow
|
|||||||
GLFWbool stickyKeys;
|
GLFWbool stickyKeys;
|
||||||
GLFWbool stickyMouseButtons;
|
GLFWbool stickyMouseButtons;
|
||||||
GLFWbool lockKeyMods;
|
GLFWbool lockKeyMods;
|
||||||
|
GLFWbool disableMouseButtonLimit;
|
||||||
int cursorMode;
|
int cursorMode;
|
||||||
char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];
|
char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];
|
||||||
char keys[GLFW_KEY_LAST + 1];
|
char keys[GLFW_KEY_LAST + 1];
|
||||||
|
@ -630,6 +630,7 @@ int main(int argc, char** argv)
|
|||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
glfwSetInputMode(slots[i].window, GLFW_UNLIMITED_MOUSE_BUTTONS, GLFW_TRUE);
|
||||||
|
|
||||||
glfwSetWindowUserPointer(slots[i].window, slots + i);
|
glfwSetWindowUserPointer(slots[i].window, slots + i);
|
||||||
|
|
||||||
|
@ -78,6 +78,7 @@ int main(int argc, char** argv)
|
|||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
glfwSetInputMode(window, GLFW_UNLIMITED_MOUSE_BUTTONS, GLFW_TRUE);
|
||||||
|
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
gladLoadGL(glfwGetProcAddress);
|
gladLoadGL(glfwGetProcAddress);
|
||||||
|
Loading…
Reference in New Issue
Block a user