WinRT: fixed bug: touch input coordinates weren't normalized [0..1]
authorDavid Ludwig <dludwig@pobox.com>
Thu, 28 Nov 2013 21:15:05 -0500
changeset 854297dcef41e4a7
parent 8541 0041edb891f3
child 8543 b9dd3cf38585
WinRT: fixed bug: touch input coordinates weren't normalized [0..1]

Thanks to Pierre-Yves for pointing this out and providing a fix!
src/core/winrt/SDL_winrtapp_direct3d.cpp
src/video/winrt/SDL_winrtevents_c.h
src/video/winrt/SDL_winrtpointerinput.cpp
     1.1 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp	Mon Nov 04 19:54:29 2013 -0500
     1.2 +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp	Thu Nov 28 21:15:05 2013 -0500
     1.3 @@ -495,7 +495,7 @@
     1.4  void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
     1.5  {
     1.6  #if LOG_POINTER_EVENTS
     1.7 -    WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position));
     1.8 +    WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
     1.9  #endif
    1.10  
    1.11      WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
    1.12 @@ -504,7 +504,7 @@
    1.13  void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args)
    1.14  {
    1.15  #if LOG_POINTER_EVENTS
    1.16 -    WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position));
    1.17 +    WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
    1.18  #endif
    1.19  
    1.20      WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
    1.21 @@ -513,7 +513,7 @@
    1.22  void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
    1.23  {
    1.24  #if LOG_POINTER_EVENTS
    1.25 -    WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position));
    1.26 +    WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
    1.27  #endif
    1.28  
    1.29      WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
    1.30 @@ -522,7 +522,7 @@
    1.31  void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args)
    1.32  {
    1.33  #if LOG_POINTER_EVENTS
    1.34 -    WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position));
    1.35 +    WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
    1.36  #endif
    1.37  
    1.38      WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
     2.1 --- a/src/video/winrt/SDL_winrtevents_c.h	Mon Nov 04 19:54:29 2013 -0500
     2.2 +++ b/src/video/winrt/SDL_winrtevents_c.h	Thu Nov 28 21:15:05 2013 -0500
     2.3 @@ -46,7 +46,13 @@
     2.4  #ifdef __cplusplus_winrt
     2.5  
     2.6  /* Pointers (Mice, Touch, etc.) */
     2.7 -extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition);
     2.8 +typedef enum {
     2.9 +    NormalizeZeroToOne,
    2.10 +    TransformToSDLWindowSize
    2.11 +} WINRT_CursorNormalizationType;
    2.12 +extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window,
    2.13 +                                                                Windows::Foundation::Point rawPosition,
    2.14 +                                                                WINRT_CursorNormalizationType normalization);
    2.15  extern Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt);
    2.16  extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
    2.17  extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
     3.1 --- a/src/video/winrt/SDL_winrtpointerinput.cpp	Mon Nov 04 19:54:29 2013 -0500
     3.2 +++ b/src/video/winrt/SDL_winrtpointerinput.cpp	Thu Nov 28 21:15:05 2013 -0500
     3.3 @@ -47,9 +47,14 @@
     3.4      SDL_AddTouch(WINRT_TouchID, "");
     3.5  }
     3.6  
     3.7 +
     3.8 +//
     3.9  // Applies necessary geometric transformations to raw cursor positions:
    3.10 +//
    3.11  Windows::Foundation::Point
    3.12 -WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition)
    3.13 +WINRT_TransformCursorPosition(SDL_Window * window,
    3.14 +                              Windows::Foundation::Point rawPosition,
    3.15 +                              WINRT_CursorNormalizationType normalization)
    3.16  {
    3.17      using namespace Windows::UI::Core;
    3.18      using namespace Windows::Graphics::Display;
    3.19 @@ -64,6 +69,8 @@
    3.20          // This might end up being the case as XAML support is extended.
    3.21          // For now, if there's no CoreWindow attached to the SDL_Window,
    3.22          // don't do any transforms.
    3.23 +
    3.24 +        // TODO, WinRT: make sure touch input coordinate ranges are correct when using XAML support
    3.25          return rawPosition;
    3.26      }
    3.27  
    3.28 @@ -73,33 +80,41 @@
    3.29      CoreWindow ^ nativeWindow = windowData->coreWindow.Get();
    3.30      Windows::Foundation::Point outputPosition;
    3.31  
    3.32 +    // Compute coordinates normalized from 0..1.
    3.33 +    // If the coordinates need to be sized to the SDL window,
    3.34 +    // we'll do that after.
    3.35  #if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
    3.36 -    outputPosition.X = rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width);
    3.37 -    outputPosition.Y = rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height);
    3.38 +    outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width;
    3.39 +    outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height;
    3.40  #else
    3.41      switch (DisplayProperties::CurrentOrientation)
    3.42      {
    3.43          case DisplayOrientations::Portrait:
    3.44 -            outputPosition.X = rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width);
    3.45 -            outputPosition.Y = rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height);
    3.46 +            outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width;
    3.47 +            outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height;
    3.48              break;
    3.49          case DisplayOrientations::PortraitFlipped:
    3.50 -            outputPosition.X = (float32)window->w - rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width);
    3.51 -            outputPosition.Y = (float32)window->h - rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height);
    3.52 +            outputPosition.X = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width);
    3.53 +            outputPosition.Y = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height);
    3.54              break;
    3.55          case DisplayOrientations::Landscape:
    3.56 -            outputPosition.X = rawPosition.Y * (((float32)window->w) / nativeWindow->Bounds.Height);
    3.57 -            outputPosition.Y = (float32)window->h - rawPosition.X * (((float32)window->h) / nativeWindow->Bounds.Width);
    3.58 +            outputPosition.X = rawPosition.Y / nativeWindow->Bounds.Height;
    3.59 +            outputPosition.Y = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width);
    3.60              break;
    3.61          case DisplayOrientations::LandscapeFlipped:
    3.62 -            outputPosition.X = (float32)window->w - rawPosition.Y * (((float32)window->w) / nativeWindow->Bounds.Height);
    3.63 -            outputPosition.Y = rawPosition.X * (((float32)window->h) / nativeWindow->Bounds.Width);
    3.64 +            outputPosition.X = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height);
    3.65 +            outputPosition.Y = rawPosition.X / nativeWindow->Bounds.Width;
    3.66              break;
    3.67          default:
    3.68              break;
    3.69      }
    3.70  #endif
    3.71  
    3.72 +    if (normalization == TransformToSDLWindowSize) {
    3.73 +        outputPosition.X *= ((float32) window->w);
    3.74 +        outputPosition.Y *= ((float32) window->h);
    3.75 +    }
    3.76 +
    3.77      return outputPosition;
    3.78  }
    3.79  
    3.80 @@ -208,15 +223,17 @@
    3.81          return;
    3.82      }
    3.83  
    3.84 -    Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position);
    3.85      Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint);
    3.86  
    3.87 -    if (!WINRT_IsTouchEvent(pointerPoint)) {
    3.88 +    if ( ! WINRT_IsTouchEvent(pointerPoint)) {
    3.89          SDL_SendMouseButton(window, 0, SDL_PRESSED, button);
    3.90      } else {
    3.91 +        Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
    3.92 +        Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize);
    3.93 +
    3.94          if (!WINRT_LeftFingerDown) {
    3.95              if (button) {
    3.96 -                SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y);
    3.97 +                SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y);
    3.98                  SDL_SendMouseButton(window, 0, SDL_PRESSED, button);
    3.99              }
   3.100  
   3.101 @@ -227,8 +244,8 @@
   3.102              WINRT_TouchID,
   3.103              (SDL_FingerID) pointerPoint->PointerId,
   3.104              SDL_TRUE,
   3.105 -            transformedPoint.X,
   3.106 -            transformedPoint.Y,
   3.107 +            normalizedPoint.X,
   3.108 +            normalizedPoint.Y,
   3.109              pointerPoint->Properties->Pressure);
   3.110      }
   3.111  }
   3.112 @@ -240,20 +257,21 @@
   3.113          return;
   3.114      }
   3.115  
   3.116 -    Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position);
   3.117 +    Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
   3.118 +    Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize);
   3.119  
   3.120 -    if (!WINRT_IsTouchEvent(pointerPoint)) {
   3.121 -        SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y);
   3.122 +    if ( ! WINRT_IsTouchEvent(pointerPoint)) {
   3.123 +        SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y);
   3.124      } else if (pointerPoint->PointerId == WINRT_LeftFingerDown) {
   3.125          if (pointerPoint->PointerId == WINRT_LeftFingerDown) {
   3.126 -            SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y);
   3.127 +            SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y);
   3.128          }
   3.129  
   3.130          SDL_SendTouchMotion(
   3.131              WINRT_TouchID,
   3.132              (SDL_FingerID) pointerPoint->PointerId,
   3.133 -            transformedPoint.X,
   3.134 -            transformedPoint.Y,
   3.135 +            normalizedPoint.X,
   3.136 +            normalizedPoint.Y,
   3.137              pointerPoint->Properties->Pressure);
   3.138      }
   3.139  }
   3.140 @@ -264,12 +282,13 @@
   3.141          return;
   3.142      }
   3.143  
   3.144 -    Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position);
   3.145      Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint);
   3.146  
   3.147      if (!WINRT_IsTouchEvent(pointerPoint)) {
   3.148          SDL_SendMouseButton(window, 0, SDL_RELEASED, button);
   3.149      } else {
   3.150 +        Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
   3.151 +
   3.152          if (WINRT_LeftFingerDown == pointerPoint->PointerId) {
   3.153              if (button) {
   3.154                  SDL_SendMouseButton(window, 0, SDL_RELEASED, button);
   3.155 @@ -281,8 +300,8 @@
   3.156              WINRT_TouchID,
   3.157              (SDL_FingerID) pointerPoint->PointerId,
   3.158              SDL_FALSE,
   3.159 -            transformedPoint.X,
   3.160 -            transformedPoint.Y,
   3.161 +            normalizedPoint.X,
   3.162 +            normalizedPoint.Y,
   3.163              pointerPoint->Properties->Pressure);
   3.164      }
   3.165  }
   3.166 @@ -363,7 +382,7 @@
   3.167      // to SDL window coordinates.
   3.168      //
   3.169      const Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y);
   3.170 -    const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs);
   3.171 +    const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs, TransformToSDLWindowSize);
   3.172      SDL_SendMouseMotion(
   3.173          window,
   3.174          0,