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.
This commit is contained in:
David Ludwig
2013-09-06 21:00:52 -04:00
parent 9de76eb526
commit de8d9dbb93
4 changed files with 218 additions and 219 deletions

View File

@@ -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