From de8d9dbb93c1f0dae77b032bac33ad7a0f5e9a67 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 6 Sep 2013 21:00:52 -0400 Subject: [PATCH] WinRT: minor code cleanup regarding events Some event handling functions got sorted in a somewhat consistent manner, and in some cases, were also segregated a bit from app-lifecycle code. --- src/core/winrt/SDL_winrtapp.cpp | 136 +++++------ src/core/winrt/SDL_winrtxaml.cpp | 12 +- src/video/winrt/SDL_winrtevents_c.h | 18 +- src/video/winrt/SDL_winrtpointerinput.cpp | 271 +++++++++++----------- 4 files changed, 218 insertions(+), 219 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index 6b4de54b1..f421ea45e 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -299,15 +299,15 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window) window->PointerPressed += ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerPressed); + window->PointerMoved += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerMoved); + window->PointerReleased += ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerReleased); window->PointerWheelChanged += ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerWheelChanged); - window->PointerMoved += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerMoved); - #if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP // Retrieves relative-only mouse movements: Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved += @@ -409,71 +409,6 @@ void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) m_windowClosed = true; } -static void -WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint) -{ - 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", - header, - pt->Position.X, pt->Position.Y, - transformedPoint.X, transformedPoint.Y, - pt->Properties->MouseWheelDelta, - pt->FrameId, - pt->PointerId, - WINRT_GetSDLButtonForPointerPoint(pt)); -} - -void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) -{ -#if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); -#endif - - WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); -} - -void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) -{ -#if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); -#endif - - WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); -} - -void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args) -{ -#if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); -#endif - - WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); -} - -void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) -{ -#if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); -#endif - - WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); -} - -void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args) -{ - WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args); -} - -void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) -{ - WINRT_ProcessKeyDownEvent(args); -} - -void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) -{ - WINRT_ProcessKeyUpEvent(args); -} - void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) { CoreWindow::GetForCurrentThread()->Activate(); @@ -547,3 +482,68 @@ void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args) SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0); } } + +static void +WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint) +{ + 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", + header, + pt->Position.X, pt->Position.Y, + transformedPoint.X, transformedPoint.Y, + pt->Properties->MouseWheelDelta, + pt->FrameId, + pt->PointerId, + WINRT_GetSDLButtonForPointerPoint(pt)); +} + +void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); +#endif + + WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); +#endif + + WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); +#endif + + WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); +#endif + + WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args) +{ + WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args); +} + +void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) +{ + WINRT_ProcessKeyDownEvent(args); +} + +void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) +{ + WINRT_ProcessKeyUpEvent(args); +} diff --git a/src/core/winrt/SDL_winrtxaml.cpp b/src/core/winrt/SDL_winrtxaml.cpp index 8b78a1f18..42500c3b5 100644 --- a/src/core/winrt/SDL_winrtxaml.cpp +++ b/src/core/winrt/SDL_winrtxaml.cpp @@ -57,6 +57,12 @@ WINRT_OnPointerPressedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); } +static void +WINRT_OnPointerMovedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +{ + WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); +} + static void WINRT_OnPointerReleasedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) { @@ -69,12 +75,6 @@ WINRT_OnPointerWheelChangedViaXAML(Platform::Object^ sender, Windows::UI::Xaml:: WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); } -static void -WINRT_OnPointerMovedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) -{ - WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); -} - #endif // WINAPI_FAMILY == WINAPI_FAMILY_APP diff --git a/src/video/winrt/SDL_winrtevents_c.h b/src/video/winrt/SDL_winrtevents_c.h index 4d9ae6d4d..ea09347ae 100644 --- a/src/video/winrt/SDL_winrtevents_c.h +++ b/src/video/winrt/SDL_winrtevents_c.h @@ -45,19 +45,19 @@ extern void WINRT_PumpEvents(_THIS); */ #ifdef __cplusplus_winrt +/* Pointers (Mice, Touch, etc.) */ +extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition); +extern Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt); +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); +extern void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); +extern void WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args); + /* Keyboard */ extern void WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args); extern void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args); -/* Pointers (Mice, Touch, etc.) */ -extern void WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args); -extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); -extern void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); -extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); -extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); -extern Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt); -extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition); - /* XAML Thread Management */ extern void WINRT_CycleXAMLThread(); diff --git a/src/video/winrt/SDL_winrtpointerinput.cpp b/src/video/winrt/SDL_winrtpointerinput.cpp index ec95b2b64..962ec3cbd 100644 --- a/src/video/winrt/SDL_winrtpointerinput.cpp +++ b/src/video/winrt/SDL_winrtpointerinput.cpp @@ -47,7 +47,6 @@ WINRT_InitTouch(_THIS) SDL_AddTouch(WINRT_TouchID, ""); } - // Applies necessary geometric transformations to raw cursor positions: Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition) @@ -114,79 +113,6 @@ _lround(float arg) } } -void -WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args) -{ - if (!window || !WINRT_UsingRelativeMouseMode) { - return; - } - - // DLudwig, 2012-12-28: On some systems, namely Visual Studio's Windows - // Simulator, as well as Windows 8 in a Parallels 8 VM, MouseEventArgs' - // MouseDelta field often reports very large values. More information - // on this can be found at the following pages on MSDN: - // - http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/a3c789fa-f1c5-49c4-9c0a-7db88d0f90f8 - // - https://connect.microsoft.com/VisualStudio/Feedback/details/756515 - // - // The values do not appear to be as large when running on some systems, - // most notably a Surface RT. Furthermore, the values returned by - // CoreWindow's PointerMoved event, and sent to this class' OnPointerMoved - // method, do not ever appear to be large, even when MouseEventArgs' - // MouseDelta is reporting to the contrary. - // - // On systems with the large-values behavior, it appears that the values - // get reported as if the screen's size is 65536 units in both the X and Y - // dimensions. This can be viewed by using Windows' now-private, "Raw Input" - // APIs. (GetRawInputData, RegisterRawInputDevices, WM_INPUT, etc.) - // - // MSDN's documentation on MouseEventArgs' MouseDelta field (at - // http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.input.mouseeventargs.mousedelta ), - // does not seem to indicate (to me) that its values should be so large. It - // says that its values should be a "change in screen location". I could - // be misinterpreting this, however a post on MSDN from a Microsoft engineer (see: - // http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/09a9868e-95bb-4858-ba1a-cb4d2c298d62 ), - // indicates that these values are in DIPs, which is the same unit used - // by CoreWindow's PointerMoved events (via the Position field in its CurrentPoint - // property. See http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.input.pointerpoint.position.aspx - // for details.) - // - // To note, PointerMoved events are sent a 'RawPosition' value (via the - // CurrentPoint property in MouseEventArgs), however these do not seem - // to exhibit the same large-value behavior. - // - // The values passed via PointerMoved events can't always be used for relative - // mouse motion, unfortunately. Its values are bound to the cursor's position, - // which stops when it hits one of the screen's edges. This can be a problem in - // first person shooters, whereby it is normal for mouse motion to travel far - // along any one axis for a period of time. MouseMoved events do not have the - // screen-bounding limitation, and can be used regardless of where the system's - // cursor is. - // - // One possible workaround would be to programmatically set the cursor's - // position to the screen's center (when SDL's relative mouse mode is enabled), - // however WinRT does not yet seem to have the ability to set the cursor's - // position via a public API. Win32 did this via an API call, SetCursorPos, - // however WinRT makes this function be private. Apps that use it won't get - // approved for distribution in the Windows Store. I've yet to be able to find - // a suitable, store-friendly counterpart for WinRT. - // - // There may be some room for a workaround whereby OnPointerMoved's values - // are compared to the values from OnMouseMoved in order to detect - // when this bug is active. A suitable transformation could then be made to - // OnMouseMoved's values. For now, however, the system-reported values are sent - // to SDL with minimal transformation: from native screen coordinates (in DIPs) - // to SDL window coordinates. - // - const Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y); - const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs); - SDL_SendMouseMotion( - window, - 0, - 1, - _lround(mouseDeltaInSDLWindowCoords.X), - _lround(mouseDeltaInSDLWindowCoords.Y)); -} - Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt) { @@ -276,68 +202,6 @@ WINRT_IsTouchEvent(Windows::UI::Input::PointerPoint ^pointerPoint) #endif } -void -WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) -{ - if (!window || WINRT_UsingRelativeMouseMode) { - return; - } - - Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); - - if (pointerPoint->PointerId == WINRT_LeftFingerDown) { - SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); - } - - if (WINRT_IsTouchEvent(pointerPoint)) { - SDL_SendTouchMotion( - WINRT_TouchID, - (SDL_FingerID) pointerPoint->PointerId, - transformedPoint.X, - transformedPoint.Y, - pointerPoint->Properties->Pressure); - } -} - -void -WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) -{ - if (!window) { - return; - } - - // FIXME: This may need to accumulate deltas up to WHEEL_DELTA - short motion = pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA; - SDL_SendMouseWheel(window, 0, 0, motion); -} - -void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) -{ - if (!window) { - return; - } - - Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); - - if (WINRT_LeftFingerDown == pointerPoint->PointerId) { - Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - if (button) { - SDL_SendMouseButton(window, 0, SDL_RELEASED, button); - } - WINRT_LeftFingerDown = 0; - } - - if (WINRT_IsTouchEvent(pointerPoint)) { - SDL_SendTouch( - WINRT_TouchID, - (SDL_FingerID) pointerPoint->PointerId, - SDL_FALSE, - transformedPoint.X, - transformedPoint.Y, - pointerPoint->Properties->Pressure); - } -} - void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) { if (!window) { @@ -368,5 +232,140 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::Po pointerPoint->Properties->Pressure); } } + +void +WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ + if (!window || WINRT_UsingRelativeMouseMode) { + return; + } + + Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); + + if (pointerPoint->PointerId == WINRT_LeftFingerDown) { + SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); + } + + if (WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendTouchMotion( + WINRT_TouchID, + (SDL_FingerID) pointerPoint->PointerId, + transformedPoint.X, + transformedPoint.Y, + pointerPoint->Properties->Pressure); + } +} + +void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ + if (!window) { + return; + } + + Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); + + if (WINRT_LeftFingerDown == pointerPoint->PointerId) { + Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); + if (button) { + SDL_SendMouseButton(window, 0, SDL_RELEASED, button); + } + WINRT_LeftFingerDown = 0; + } + + if (WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendTouch( + WINRT_TouchID, + (SDL_FingerID) pointerPoint->PointerId, + SDL_FALSE, + transformedPoint.X, + transformedPoint.Y, + pointerPoint->Properties->Pressure); + } +} + +void +WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ + if (!window) { + return; + } + + // FIXME: This may need to accumulate deltas up to WHEEL_DELTA + short motion = pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA; + SDL_SendMouseWheel(window, 0, 0, motion); +} + +void +WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args) +{ + if (!window || !WINRT_UsingRelativeMouseMode) { + return; + } + + // DLudwig, 2012-12-28: On some systems, namely Visual Studio's Windows + // Simulator, as well as Windows 8 in a Parallels 8 VM, MouseEventArgs' + // MouseDelta field often reports very large values. More information + // on this can be found at the following pages on MSDN: + // - http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/a3c789fa-f1c5-49c4-9c0a-7db88d0f90f8 + // - https://connect.microsoft.com/VisualStudio/Feedback/details/756515 + // + // The values do not appear to be as large when running on some systems, + // most notably a Surface RT. Furthermore, the values returned by + // CoreWindow's PointerMoved event, and sent to this class' OnPointerMoved + // method, do not ever appear to be large, even when MouseEventArgs' + // MouseDelta is reporting to the contrary. + // + // On systems with the large-values behavior, it appears that the values + // get reported as if the screen's size is 65536 units in both the X and Y + // dimensions. This can be viewed by using Windows' now-private, "Raw Input" + // APIs. (GetRawInputData, RegisterRawInputDevices, WM_INPUT, etc.) + // + // MSDN's documentation on MouseEventArgs' MouseDelta field (at + // http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.input.mouseeventargs.mousedelta ), + // does not seem to indicate (to me) that its values should be so large. It + // says that its values should be a "change in screen location". I could + // be misinterpreting this, however a post on MSDN from a Microsoft engineer (see: + // http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/09a9868e-95bb-4858-ba1a-cb4d2c298d62 ), + // indicates that these values are in DIPs, which is the same unit used + // by CoreWindow's PointerMoved events (via the Position field in its CurrentPoint + // property. See http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.input.pointerpoint.position.aspx + // for details.) + // + // To note, PointerMoved events are sent a 'RawPosition' value (via the + // CurrentPoint property in MouseEventArgs), however these do not seem + // to exhibit the same large-value behavior. + // + // The values passed via PointerMoved events can't always be used for relative + // mouse motion, unfortunately. Its values are bound to the cursor's position, + // which stops when it hits one of the screen's edges. This can be a problem in + // first person shooters, whereby it is normal for mouse motion to travel far + // along any one axis for a period of time. MouseMoved events do not have the + // screen-bounding limitation, and can be used regardless of where the system's + // cursor is. + // + // One possible workaround would be to programmatically set the cursor's + // position to the screen's center (when SDL's relative mouse mode is enabled), + // however WinRT does not yet seem to have the ability to set the cursor's + // position via a public API. Win32 did this via an API call, SetCursorPos, + // however WinRT makes this function be private. Apps that use it won't get + // approved for distribution in the Windows Store. I've yet to be able to find + // a suitable, store-friendly counterpart for WinRT. + // + // There may be some room for a workaround whereby OnPointerMoved's values + // are compared to the values from OnMouseMoved in order to detect + // when this bug is active. A suitable transformation could then be made to + // OnMouseMoved's values. For now, however, the system-reported values are sent + // to SDL with minimal transformation: from native screen coordinates (in DIPs) + // to SDL window coordinates. + // + const Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y); + const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs); + SDL_SendMouseMotion( + window, + 0, + 1, + _lround(mouseDeltaInSDLWindowCoords.X), + _lround(mouseDeltaInSDLWindowCoords.Y)); +} #endif // SDL_VIDEO_DRIVER_WINRT