From be5356af932fb9e4db9c97add00e036aeeb6eebf Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Fri, 14 May 2021 14:44:13 -0400 Subject: [PATCH] winrt: Fix support for multiple simultaneous mouse button presses --- src/core/winrt/SDL_winrtapp_direct3d.cpp | 7 ++-- src/video/winrt/SDL_winrtevents_c.h | 2 +- src/video/winrt/SDL_winrtpointerinput.cpp | 44 ++++++++++++++++------- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp index 0018604d1..9c115c6d6 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -729,15 +729,18 @@ void SDL_WinRTApp::OnExiting(Platform::Object^ sender, Platform::Object^ args) static void WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint) { + Uint8 button, pressed; Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint; - SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d\n", + WINRT_GetSDLButtonForPointerPoint(pt, &button, &pressed); + SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d pressed=%d\n", header, pt->Position.X, pt->Position.Y, transformedPoint.X, transformedPoint.Y, pt->Properties->MouseWheelDelta, pt->FrameId, pt->PointerId, - WINRT_GetSDLButtonForPointerPoint(pt)); + button, + pressed); } void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) diff --git a/src/video/winrt/SDL_winrtevents_c.h b/src/video/winrt/SDL_winrtevents_c.h index 910dc6a64..a95e9656a 100644 --- a/src/video/winrt/SDL_winrtevents_c.h +++ b/src/video/winrt/SDL_winrtevents_c.h @@ -53,7 +53,7 @@ typedef enum { extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition, WINRT_CursorNormalizationType normalization); -extern Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt); +extern SDL_bool WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt, Uint8 *button, Uint8 *pressed); extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); diff --git a/src/video/winrt/SDL_winrtpointerinput.cpp b/src/video/winrt/SDL_winrtpointerinput.cpp index 6959be71d..1639083f0 100644 --- a/src/video/winrt/SDL_winrtpointerinput.cpp +++ b/src/video/winrt/SDL_winrtpointerinput.cpp @@ -116,8 +116,8 @@ WINRT_TransformCursorPosition(SDL_Window * window, return outputPosition; } -Uint8 -WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt) +SDL_bool +WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt, Uint8 *button, Uint8 *pressed) { using namespace Windows::UI::Input; @@ -128,30 +128,42 @@ WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt) { case PointerUpdateKind::LeftButtonPressed: case PointerUpdateKind::LeftButtonReleased: - return SDL_BUTTON_LEFT; + *button = SDL_BUTTON_LEFT; + *pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::LeftButtonPressed); + return SDL_TRUE; case PointerUpdateKind::RightButtonPressed: case PointerUpdateKind::RightButtonReleased: - return SDL_BUTTON_RIGHT; + *button = SDL_BUTTON_RIGHT; + *pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::RightButtonPressed); + return SDL_TRUE; case PointerUpdateKind::MiddleButtonPressed: case PointerUpdateKind::MiddleButtonReleased: - return SDL_BUTTON_MIDDLE; + *button = SDL_BUTTON_MIDDLE; + *pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::MiddleButtonPressed); + return SDL_TRUE; case PointerUpdateKind::XButton1Pressed: case PointerUpdateKind::XButton1Released: - return SDL_BUTTON_X1; + *button = SDL_BUTTON_X1; + *pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::XButton1Pressed); + return SDL_TRUE; case PointerUpdateKind::XButton2Pressed: case PointerUpdateKind::XButton2Released: - return SDL_BUTTON_X2; + *button = SDL_BUTTON_X2; + *pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::XButton2Pressed); + return SDL_TRUE; default: break; } #endif - return 0; + *button = 0; + *pressed = 0; + return SDL_FALSE; } //const char * @@ -211,9 +223,10 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::Po return; } - Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - if ( ! WINRT_IsTouchEvent(pointerPoint)) { + Uint8 button, pressed; + WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed); + SDL_assert(pressed == 1); SDL_SendMouseButton(window, 0, SDL_PRESSED, button); } else { Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); @@ -241,6 +254,12 @@ WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPo Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize); if ( ! WINRT_IsTouchEvent(pointerPoint)) { + /* For some odd reason Moved events are used for multiple mouse buttons */ + Uint8 button, pressed; + if (WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed)) { + SDL_SendMouseButton(window, 0, pressed, button); + } + SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y); } else { SDL_SendTouchMotion( @@ -259,9 +278,10 @@ void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::P return; } - Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - if (!WINRT_IsTouchEvent(pointerPoint)) { + Uint8 button, pressed; + WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed); + SDL_assert(pressed == 0); SDL_SendMouseButton(window, 0, SDL_RELEASED, button); } else { Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);