Track unique button states between different mice

We were already halfway doing this, but now we make that information available to the Windows driver so it can cache the button state per-mouse
This commit is contained in:
Sam Lantinga 2024-03-22 16:30:20 -07:00
parent 35756593d6
commit 361b7190df
4 changed files with 32 additions and 18 deletions

View File

@ -402,14 +402,21 @@ SDL_Mouse *SDL_GetMouse(void)
return &SDL_mouse;
}
static Uint32 GetButtonState(SDL_Mouse *mouse, SDL_bool include_touch)
Uint32 SDL_GetMouseButtonState(SDL_Mouse *mouse, SDL_MouseID mouseID, SDL_bool include_touch)
{
int i;
Uint32 buttonstate = 0;
for (i = 0; i < mouse->num_sources; ++i) {
if (include_touch || mouse->sources[i].mouseID != SDL_TOUCH_MOUSEID) {
buttonstate |= mouse->sources[i].buttonstate;
if (mouseID == SDL_GLOBAL_MOUSE_ID || mouseID == SDL_TOUCH_MOUSEID) {
if (include_touch || mouse->sources[i].mouseID != SDL_TOUCH_MOUSEID) {
buttonstate |= mouse->sources[i].buttonstate;
}
} else {
if (mouseID == mouse->sources[i].mouseID) {
buttonstate |= mouse->sources[i].buttonstate;
break;
}
}
}
return buttonstate;
@ -433,7 +440,7 @@ SDL_Window *SDL_GetMouseFocus(void)
void SDL_ResetMouse(void)
{
SDL_Mouse *mouse = SDL_GetMouse();
Uint32 buttonState = GetButtonState(mouse, SDL_FALSE);
Uint32 buttonState = SDL_GetMouseButtonState(mouse, SDL_GLOBAL_MOUSE_ID, SDL_FALSE);
int i;
for (i = 1; i <= sizeof(buttonState)*8; ++i) {
@ -441,7 +448,7 @@ void SDL_ResetMouse(void)
SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, SDL_RELEASED, i);
}
}
SDL_assert(GetButtonState(mouse, SDL_FALSE) == 0);
SDL_assert(SDL_GetMouseButtonState(mouse, SDL_GLOBAL_MOUSE_ID, SDL_FALSE) == 0);
}
#endif /* 0 */
@ -530,7 +537,7 @@ int SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseI
{
if (window && !relative) {
SDL_Mouse *mouse = SDL_GetMouse();
if (!SDL_UpdateMouseFocus(window, x, y, GetButtonState(mouse, SDL_TRUE), (mouseID != SDL_TOUCH_MOUSEID))) {
if (!SDL_UpdateMouseFocus(window, x, y, SDL_GetMouseButtonState(mouse, mouseID, SDL_TRUE), (mouseID != SDL_TOUCH_MOUSEID))) {
return 0;
}
}
@ -760,7 +767,7 @@ static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_
}
/* Ignore relative motion positioning the first touch */
if (mouseID == SDL_TOUCH_MOUSEID && !GetButtonState(mouse, SDL_TRUE)) {
if (mouseID == SDL_TOUCH_MOUSEID && !SDL_GetMouseButtonState(mouse, mouseID, SDL_TRUE)) {
xrel = 0.0f;
yrel = 0.0f;
}
@ -800,7 +807,7 @@ static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_
event.motion.which = mouseID;
/* Set us pending (or clear during a normal mouse movement event) as having triggered */
mouse->was_touch_mouse_events = (mouseID == SDL_TOUCH_MOUSEID);
event.motion.state = GetButtonState(mouse, SDL_TRUE);
event.motion.state = SDL_GetMouseButtonState(mouse, mouseID, SDL_TRUE);
event.motion.x = mouse->x;
event.motion.y = mouse->y;
event.motion.xrel = xrel;
@ -1126,7 +1133,7 @@ Uint32 SDL_GetMouseState(float *x, float *y)
if (y) {
*y = mouse->y;
}
return GetButtonState(mouse, SDL_TRUE);
return SDL_GetMouseButtonState(mouse, SDL_GLOBAL_MOUSE_ID, SDL_TRUE);
}
Uint32 SDL_GetRelativeMouseState(float *x, float *y)
@ -1141,7 +1148,7 @@ Uint32 SDL_GetRelativeMouseState(float *x, float *y)
}
mouse->xdelta = 0.0f;
mouse->ydelta = 0.0f;
return GetButtonState(mouse, SDL_TRUE);
return SDL_GetMouseButtonState(mouse, SDL_GLOBAL_MOUSE_ID, SDL_TRUE);
}
Uint32 SDL_GetGlobalMouseState(float *x, float *y)
@ -1318,7 +1325,7 @@ int SDL_UpdateMouseCapture(SDL_bool force_release)
if (!force_release) {
if (SDL_GetMessageBoxCount() == 0 &&
(mouse->capture_desired || (mouse->auto_capture && GetButtonState(mouse, SDL_FALSE) != 0))) {
(mouse->capture_desired || (mouse->auto_capture && SDL_GetMouseButtonState(mouse, SDL_GLOBAL_MOUSE_ID, SDL_FALSE) != 0))) {
if (!mouse->relative_mode) {
capture_window = mouse->focus;
}

View File

@ -154,6 +154,9 @@ extern void SDL_SetMouseFocus(SDL_Window *window);
/* Update the mouse capture window */
extern int SDL_UpdateMouseCapture(SDL_bool force_release);
/* Get the current mouse button state for a mouse */
Uint32 SDL_GetMouseButtonState(SDL_Mouse *mouse, SDL_MouseID mouseID, SDL_bool include_touch);
/* You can set either a single scale, or a set of {speed, scale} values in sorted order */
extern int SDL_SetMouseSystemScale(int num_values, const float *values);

View File

@ -234,7 +234,9 @@ static void WIN_CheckWParamMouseButton(Uint64 timestamp, SDL_bool bwParamMousePr
*/
static void WIN_CheckWParamMouseButtons(Uint64 timestamp, WPARAM wParam, SDL_WindowData *data, SDL_MouseID mouseID)
{
if (wParam != data->mouse_button_flags) {
Uint64 unique_bits = wParam;
if (unique_bits != data->mouse_button_flags) {
Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL);
/* WM_LBUTTONDOWN and friends handle button swapping for us. No need to check SM_SWAPBUTTON here. */
@ -244,17 +246,19 @@ static void WIN_CheckWParamMouseButtons(Uint64 timestamp, WPARAM wParam, SDL_Win
WIN_CheckWParamMouseButton(timestamp, (wParam & MK_XBUTTON1), mouseFlags, SDL_FALSE, data, SDL_BUTTON_X1, mouseID);
WIN_CheckWParamMouseButton(timestamp, (wParam & MK_XBUTTON2), mouseFlags, SDL_FALSE, data, SDL_BUTTON_X2, mouseID);
data->mouse_button_flags = wParam;
data->mouse_button_flags = unique_bits;
}
}
static void WIN_CheckRawMouseButtons(Uint64 timestamp, HANDLE hDevice, ULONG rawButtons, SDL_WindowData *data, SDL_MouseID mouseID)
{
// Add a flag to distinguish raw mouse buttons from wParam above
rawButtons |= 0x8000000;
Uint64 unique_bits = 0x8000000 | (uintptr_t)hDevice;
unique_bits <<= 32;
unique_bits |= rawButtons;
if (rawButtons != data->mouse_button_flags) {
Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL);
if (unique_bits != data->mouse_button_flags) {
Uint32 mouseFlags = SDL_GetMouseButtonState(SDL_GetMouse(), mouseID, SDL_FALSE);
SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0;
if (swapButtons && hDevice == NULL) {
/* Touchpad, already has buttons swapped */
@ -290,7 +294,7 @@ static void WIN_CheckRawMouseButtons(Uint64 timestamp, HANDLE hDevice, ULONG raw
if (rawButtons & RI_MOUSE_BUTTON_5_UP) {
WIN_CheckWParamMouseButton(timestamp, !(rawButtons & RI_MOUSE_BUTTON_5_UP), mouseFlags, swapButtons, data, SDL_BUTTON_X2, mouseID);
}
data->mouse_button_flags = rawButtons;
data->mouse_button_flags = unique_bits;
}
}

View File

@ -52,7 +52,7 @@ struct SDL_WindowData
HBITMAP hbm;
WNDPROC wndproc;
HHOOK keyboard_hook;
WPARAM mouse_button_flags;
Uint64 mouse_button_flags;
LPARAM last_pointer_update;
WCHAR high_surrogate;
SDL_bool initializing;