src/video/winrt/SDL_winrtpointerinput.cpp
author Alex Szpakowski <slime73@gmail.com>
Sat, 10 Nov 2018 16:15:48 -0400
changeset 12404 eb60e952b13f
parent 11811 5d94cb6b24d3
child 12503 806492103856
permissions -rw-r--r--
Add SDL_TouchDeviceType enum and SDL_GetTouchDeviceType(SDL_TouchID id).

Touch device types include SDL_TOUCH_DEVICE_DIRECT (a touch screen with window-relative coordinates for touches), SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE (a trackpad-style device with absolute device coordinates), and SDL_TOUCH_DEVICE_INDIRECT_RELATIVE (a trackpad-style device with screen cursor-relative coordinates).

Phone screens are an example of a direct device type. Mac trackpads are the indirect-absolute touch device type. The Apple TV remote is an indirect-relative touch device type.
dludwig@8515
     1
/*
dludwig@8515
     2
  Simple DirectMedia Layer
slouken@11811
     3
  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
dludwig@8515
     4
dludwig@8515
     5
  This software is provided 'as-is', without any express or implied
dludwig@8515
     6
  warranty.  In no event will the authors be held liable for any damages
dludwig@8515
     7
  arising from the use of this software.
dludwig@8515
     8
dludwig@8515
     9
  Permission is granted to anyone to use this software for any purpose,
dludwig@8515
    10
  including commercial applications, and to alter it and redistribute it
dludwig@8515
    11
  freely, subject to the following restrictions:
dludwig@8515
    12
dludwig@8515
    13
  1. The origin of this software must not be misrepresented; you must not
dludwig@8515
    14
     claim that you wrote the original software. If you use this software
dludwig@8515
    15
     in a product, an acknowledgment in the product documentation would be
dludwig@8515
    16
     appreciated but is not required.
dludwig@8515
    17
  2. Altered source versions must be plainly marked as such, and must not be
dludwig@8515
    18
     misrepresented as being the original software.
dludwig@8515
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@8582
    20
*/
slouken@8609
    21
#include "../../SDL_internal.h"
dludwig@8515
    22
dludwig@8515
    23
#if SDL_VIDEO_DRIVER_WINRT
dludwig@8515
    24
dludwig@8515
    25
/* SDL includes */
dludwig@8515
    26
#include "SDL_winrtevents_c.h"
dludwig@8516
    27
#include "SDL_winrtmouse_c.h"
dludwig@8515
    28
#include "SDL_winrtvideo_cpp.h"
dludwig@8515
    29
#include "SDL_assert.h"
dludwig@8515
    30
#include "SDL_system.h"
dludwig@8515
    31
dludwig@8515
    32
extern "C" {
dludwig@8515
    33
#include "../SDL_sysvideo.h"
dludwig@8515
    34
#include "../../events/SDL_events_c.h"
slouken@8582
    35
#include "../../events/SDL_mouse_c.h"
dludwig@8515
    36
#include "../../events/SDL_touch_c.h"
dludwig@8515
    37
}
slouken@8582
    38
slouken@8582
    39
/* File-specific globals: */
slouken@8582
    40
static SDL_TouchID WINRT_TouchID = 1;
slouken@8582
    41
static unsigned int WINRT_LeftFingerDown = 0;
slouken@8582
    42
slouken@8582
    43
slouken@8582
    44
void
slouken@8582
    45
WINRT_InitTouch(_THIS)
slouken@8582
    46
{
slime73@12404
    47
    SDL_AddTouch(WINRT_TouchID, SDL_TOUCH_DEVICE_DIRECT, "");
dludwig@8515
    48
}
dludwig@8521
    49
dludwig@8521
    50
slouken@8582
    51
//
slouken@8582
    52
// Applies necessary geometric transformations to raw cursor positions:
slouken@8582
    53
//
slouken@8582
    54
Windows::Foundation::Point
slouken@8582
    55
WINRT_TransformCursorPosition(SDL_Window * window,
slouken@8582
    56
                              Windows::Foundation::Point rawPosition,
slouken@8582
    57
                              WINRT_CursorNormalizationType normalization)
slouken@8582
    58
{
slouken@8582
    59
    using namespace Windows::UI::Core;
slouken@8582
    60
    using namespace Windows::Graphics::Display;
slouken@8582
    61
slouken@8582
    62
    if (!window) {
slouken@8582
    63
        return rawPosition;
slouken@8582
    64
    }
slouken@8582
    65
slouken@8582
    66
    SDL_WindowData * windowData = (SDL_WindowData *) window->driverdata;
slouken@8582
    67
    if (windowData->coreWindow == nullptr) {
slouken@8582
    68
        // For some reason, the window isn't associated with a CoreWindow.
slouken@8582
    69
        // This might end up being the case as XAML support is extended.
slouken@8582
    70
        // For now, if there's no CoreWindow attached to the SDL_Window,
slouken@8582
    71
        // don't do any transforms.
slouken@8582
    72
slouken@8582
    73
        // TODO, WinRT: make sure touch input coordinate ranges are correct when using XAML support
slouken@8582
    74
        return rawPosition;
slouken@8582
    75
    }
slouken@8582
    76
slouken@8582
    77
    // The CoreWindow can only be accessed on certain thread(s).
slouken@8582
    78
    SDL_assert(CoreWindow::GetForCurrentThread() != nullptr);
slouken@8582
    79
slouken@8582
    80
    CoreWindow ^ nativeWindow = windowData->coreWindow.Get();
slouken@8582
    81
    Windows::Foundation::Point outputPosition;
slouken@8582
    82
slouken@8582
    83
    // Compute coordinates normalized from 0..1.
slouken@8582
    84
    // If the coordinates need to be sized to the SDL window,
slouken@8582
    85
    // we'll do that after.
dludwig@8756
    86
#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION > NTDDI_WIN8)
slouken@8582
    87
    outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width;
slouken@8582
    88
    outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height;
slouken@8582
    89
#else
dludwig@8757
    90
    switch (WINRT_DISPLAY_PROPERTY(CurrentOrientation))
slouken@8582
    91
    {
slouken@8582
    92
        case DisplayOrientations::Portrait:
slouken@8582
    93
            outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width;
slouken@8582
    94
            outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height;
slouken@8582
    95
            break;
slouken@8582
    96
        case DisplayOrientations::PortraitFlipped:
slouken@8582
    97
            outputPosition.X = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width);
slouken@8582
    98
            outputPosition.Y = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height);
slouken@8582
    99
            break;
slouken@8582
   100
        case DisplayOrientations::Landscape:
slouken@8582
   101
            outputPosition.X = rawPosition.Y / nativeWindow->Bounds.Height;
slouken@8582
   102
            outputPosition.Y = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width);
slouken@8582
   103
            break;
slouken@8582
   104
        case DisplayOrientations::LandscapeFlipped:
slouken@8582
   105
            outputPosition.X = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height);
slouken@8582
   106
            outputPosition.Y = rawPosition.X / nativeWindow->Bounds.Width;
slouken@8582
   107
            break;
slouken@8582
   108
        default:
slouken@8582
   109
            break;
slouken@8582
   110
    }
slouken@8582
   111
#endif
slouken@8582
   112
slouken@8582
   113
    if (normalization == TransformToSDLWindowSize) {
slouken@8582
   114
        outputPosition.X *= ((float32) window->w);
slouken@8582
   115
        outputPosition.Y *= ((float32) window->h);
slouken@8582
   116
    }
slouken@8582
   117
slouken@8582
   118
    return outputPosition;
slouken@8582
   119
}
slouken@8582
   120
slouken@8582
   121
static inline int
slouken@8582
   122
_lround(float arg)
slouken@8582
   123
{
slouken@8582
   124
    if (arg >= 0.0f) {
slouken@8582
   125
        return (int)floor(arg + 0.5f);
slouken@8582
   126
    } else {
slouken@8582
   127
        return (int)ceil(arg - 0.5f);
slouken@8582
   128
    }
slouken@8582
   129
}
slouken@8582
   130
slouken@8582
   131
Uint8
slouken@8582
   132
WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt)
slouken@8582
   133
{
slouken@8582
   134
    using namespace Windows::UI::Input;
slouken@8582
   135
slouken@8582
   136
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
slouken@8582
   137
    return SDL_BUTTON_LEFT;
slouken@8582
   138
#else
slouken@8582
   139
    switch (pt->Properties->PointerUpdateKind)
slouken@8582
   140
    {
slouken@8582
   141
        case PointerUpdateKind::LeftButtonPressed:
slouken@8582
   142
        case PointerUpdateKind::LeftButtonReleased:
slouken@8582
   143
            return SDL_BUTTON_LEFT;
slouken@8582
   144
slouken@8582
   145
        case PointerUpdateKind::RightButtonPressed:
slouken@8582
   146
        case PointerUpdateKind::RightButtonReleased:
slouken@8582
   147
            return SDL_BUTTON_RIGHT;
slouken@8582
   148
slouken@8582
   149
        case PointerUpdateKind::MiddleButtonPressed:
slouken@8582
   150
        case PointerUpdateKind::MiddleButtonReleased:
slouken@8582
   151
            return SDL_BUTTON_MIDDLE;
slouken@8582
   152
slouken@8582
   153
        case PointerUpdateKind::XButton1Pressed:
slouken@8582
   154
        case PointerUpdateKind::XButton1Released:
slouken@8582
   155
            return SDL_BUTTON_X1;
slouken@8582
   156
slouken@8582
   157
        case PointerUpdateKind::XButton2Pressed:
slouken@8582
   158
        case PointerUpdateKind::XButton2Released:
slouken@8582
   159
            return SDL_BUTTON_X2;
slouken@8582
   160
slouken@8582
   161
        default:
slouken@8582
   162
            break;
slouken@8582
   163
    }
slouken@8582
   164
#endif
slouken@8582
   165
slouken@8582
   166
    return 0;
slouken@8582
   167
}
slouken@8582
   168
slouken@8582
   169
//const char *
slouken@8582
   170
//WINRT_ConvertPointerUpdateKindToString(Windows::UI::Input::PointerUpdateKind kind)
slouken@8582
   171
//{
slouken@8582
   172
//    using namespace Windows::UI::Input;
slouken@8582
   173
//
slouken@8582
   174
//    switch (kind)
slouken@8582
   175
//    {
slouken@8582
   176
//        case PointerUpdateKind::Other:
slouken@8582
   177
//            return "Other";
slouken@8582
   178
//        case PointerUpdateKind::LeftButtonPressed:
slouken@8582
   179
//            return "LeftButtonPressed";
slouken@8582
   180
//        case PointerUpdateKind::LeftButtonReleased:
slouken@8582
   181
//            return "LeftButtonReleased";
slouken@8582
   182
//        case PointerUpdateKind::RightButtonPressed:
slouken@8582
   183
//            return "RightButtonPressed";
slouken@8582
   184
//        case PointerUpdateKind::RightButtonReleased:
slouken@8582
   185
//            return "RightButtonReleased";
slouken@8582
   186
//        case PointerUpdateKind::MiddleButtonPressed:
slouken@8582
   187
//            return "MiddleButtonPressed";
slouken@8582
   188
//        case PointerUpdateKind::MiddleButtonReleased:
slouken@8582
   189
//            return "MiddleButtonReleased";
slouken@8582
   190
//        case PointerUpdateKind::XButton1Pressed:
slouken@8582
   191
//            return "XButton1Pressed";
slouken@8582
   192
//        case PointerUpdateKind::XButton1Released:
slouken@8582
   193
//            return "XButton1Released";
slouken@8582
   194
//        case PointerUpdateKind::XButton2Pressed:
slouken@8582
   195
//            return "XButton2Pressed";
slouken@8582
   196
//        case PointerUpdateKind::XButton2Released:
slouken@8582
   197
//            return "XButton2Released";
slouken@8582
   198
//    }
slouken@8582
   199
//
slouken@8582
   200
//    return "";
slouken@8582
   201
//}
slouken@8582
   202
slouken@8582
   203
static bool
slouken@8582
   204
WINRT_IsTouchEvent(Windows::UI::Input::PointerPoint ^pointerPoint)
slouken@8582
   205
{
slouken@8582
   206
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
slouken@8582
   207
    return true;
slouken@8582
   208
#else
slouken@8582
   209
    using namespace Windows::Devices::Input;
slouken@8582
   210
    switch (pointerPoint->PointerDevice->PointerDeviceType) {
slouken@8582
   211
        case PointerDeviceType::Touch:
slouken@8582
   212
        case PointerDeviceType::Pen:
slouken@8582
   213
            return true;
slouken@8582
   214
        default:
slouken@8582
   215
            return false;
slouken@8582
   216
    }
slouken@8582
   217
#endif
slouken@8582
   218
}
slouken@8582
   219
slouken@8582
   220
void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
slouken@8582
   221
{
slouken@8582
   222
    if (!window) {
slouken@8582
   223
        return;
slouken@8582
   224
    }
slouken@8582
   225
slouken@8582
   226
    Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint);
slouken@8582
   227
slouken@8582
   228
    if ( ! WINRT_IsTouchEvent(pointerPoint)) {
slouken@8582
   229
        SDL_SendMouseButton(window, 0, SDL_PRESSED, button);
slouken@8582
   230
    } else {
slouken@8582
   231
        Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
slouken@8582
   232
        Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize);
slouken@8582
   233
slouken@8582
   234
        if (!WINRT_LeftFingerDown) {
slouken@8582
   235
            if (button) {
dludwig@9226
   236
                SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, (int)windowPoint.X, (int)windowPoint.Y);
dludwig@9226
   237
                SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_PRESSED, button);
slouken@8582
   238
            }
slouken@8582
   239
slouken@8582
   240
            WINRT_LeftFingerDown = pointerPoint->PointerId;
slouken@8582
   241
        }
slouken@8582
   242
slouken@8582
   243
        SDL_SendTouch(
slouken@8582
   244
            WINRT_TouchID,
slouken@8582
   245
            (SDL_FingerID) pointerPoint->PointerId,
slouken@8582
   246
            SDL_TRUE,
slouken@8582
   247
            normalizedPoint.X,
slouken@8582
   248
            normalizedPoint.Y,
slouken@8582
   249
            pointerPoint->Properties->Pressure);
slouken@8582
   250
    }
slouken@8582
   251
}
slouken@8582
   252
slouken@8582
   253
void
slouken@8582
   254
WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
slouken@8582
   255
{
slouken@8582
   256
    if (!window || WINRT_UsingRelativeMouseMode) {
slouken@8582
   257
        return;
slouken@8582
   258
    }
slouken@8582
   259
slouken@8582
   260
    Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
slouken@8582
   261
    Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize);
slouken@8582
   262
slouken@8582
   263
    if ( ! WINRT_IsTouchEvent(pointerPoint)) {
slouken@8582
   264
        SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y);
dludwig@9220
   265
    } else {
slouken@8582
   266
        if (pointerPoint->PointerId == WINRT_LeftFingerDown) {
dludwig@9226
   267
            SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, (int)windowPoint.X, (int)windowPoint.Y);
slouken@8582
   268
        }
slouken@8582
   269
slouken@8582
   270
        SDL_SendTouchMotion(
slouken@8582
   271
            WINRT_TouchID,
slouken@8582
   272
            (SDL_FingerID) pointerPoint->PointerId,
slouken@8582
   273
            normalizedPoint.X,
slouken@8582
   274
            normalizedPoint.Y,
slouken@8582
   275
            pointerPoint->Properties->Pressure);
slouken@8582
   276
    }
slouken@8582
   277
}
slouken@8582
   278
slouken@8582
   279
void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
slouken@8582
   280
{
slouken@8582
   281
    if (!window) {
slouken@8582
   282
        return;
slouken@8582
   283
    }
slouken@8582
   284
slouken@8582
   285
    Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint);
slouken@8582
   286
slouken@8582
   287
    if (!WINRT_IsTouchEvent(pointerPoint)) {
slouken@8582
   288
        SDL_SendMouseButton(window, 0, SDL_RELEASED, button);
slouken@8582
   289
    } else {
slouken@8582
   290
        Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
slouken@8582
   291
slouken@8582
   292
        if (WINRT_LeftFingerDown == pointerPoint->PointerId) {
slouken@8582
   293
            if (button) {
dludwig@9226
   294
                SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_RELEASED, button);
slouken@8582
   295
            }
slouken@8582
   296
            WINRT_LeftFingerDown = 0;
slouken@8582
   297
        }
slouken@11300
   298
slouken@8582
   299
        SDL_SendTouch(
slouken@8582
   300
            WINRT_TouchID,
slouken@8582
   301
            (SDL_FingerID) pointerPoint->PointerId,
slouken@8582
   302
            SDL_FALSE,
slouken@8582
   303
            normalizedPoint.X,
slouken@8582
   304
            normalizedPoint.Y,
slouken@8582
   305
            pointerPoint->Properties->Pressure);
slouken@8582
   306
    }
slouken@8582
   307
}
slouken@8582
   308
dludwig@9924
   309
void WINRT_ProcessPointerEnteredEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
dludwig@9924
   310
{
dludwig@9924
   311
    if (!window) {
dludwig@9924
   312
        return;
dludwig@9924
   313
    }
dludwig@9924
   314
dludwig@9924
   315
    if (!WINRT_IsTouchEvent(pointerPoint)) {
dludwig@9924
   316
        SDL_SetMouseFocus(window);
dludwig@9924
   317
    }
dludwig@9924
   318
}
dludwig@9924
   319
dludwig@9924
   320
void WINRT_ProcessPointerExitedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
dludwig@9924
   321
{
dludwig@9924
   322
    if (!window) {
dludwig@9924
   323
        return;
dludwig@9924
   324
    }
dludwig@9924
   325
dludwig@9924
   326
    if (!WINRT_IsTouchEvent(pointerPoint)) {
dludwig@9924
   327
        SDL_SetMouseFocus(NULL);
dludwig@9924
   328
    }
dludwig@9924
   329
}
dludwig@9924
   330
slouken@8582
   331
void
slouken@8582
   332
WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
slouken@8582
   333
{
slouken@8582
   334
    if (!window) {
slouken@8582
   335
        return;
slouken@8582
   336
    }
slouken@8582
   337
slouken@11300
   338
    float motion = (float) pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA;
slouken@11300
   339
    SDL_SendMouseWheel(window, 0, 0, (float) motion, SDL_MOUSEWHEEL_NORMAL);
slouken@8582
   340
}
slouken@8582
   341
slouken@8582
   342
void
slouken@8582
   343
WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args)
slouken@8582
   344
{
slouken@8582
   345
    if (!window || !WINRT_UsingRelativeMouseMode) {
slouken@8582
   346
        return;
slouken@8582
   347
    }
slouken@8582
   348
slouken@8582
   349
    // DLudwig, 2012-12-28: On some systems, namely Visual Studio's Windows
slouken@8582
   350
    // Simulator, as well as Windows 8 in a Parallels 8 VM, MouseEventArgs'
slouken@8582
   351
    // MouseDelta field often reports very large values.  More information
slouken@8582
   352
    // on this can be found at the following pages on MSDN:
slouken@8582
   353
    //  - http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/a3c789fa-f1c5-49c4-9c0a-7db88d0f90f8
slouken@8582
   354
    //  - https://connect.microsoft.com/VisualStudio/Feedback/details/756515
slouken@8582
   355
    //
slouken@8582
   356
    // The values do not appear to be as large when running on some systems,
slouken@8582
   357
    // most notably a Surface RT.  Furthermore, the values returned by
slouken@8582
   358
    // CoreWindow's PointerMoved event, and sent to this class' OnPointerMoved
slouken@8582
   359
    // method, do not ever appear to be large, even when MouseEventArgs'
slouken@8582
   360
    // MouseDelta is reporting to the contrary.
slouken@8582
   361
    //
slouken@8582
   362
    // On systems with the large-values behavior, it appears that the values
slouken@8582
   363
    // get reported as if the screen's size is 65536 units in both the X and Y
slouken@8582
   364
    // dimensions.  This can be viewed by using Windows' now-private, "Raw Input"
slouken@8582
   365
    // APIs.  (GetRawInputData, RegisterRawInputDevices, WM_INPUT, etc.)
slouken@8582
   366
    //
slouken@8582
   367
    // MSDN's documentation on MouseEventArgs' MouseDelta field (at
slouken@8582
   368
    // http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.input.mouseeventargs.mousedelta ),
slouken@8582
   369
    // does not seem to indicate (to me) that its values should be so large.  It
slouken@8582
   370
    // says that its values should be a "change in screen location".  I could
slouken@11300
   371
    // be misinterpreting this, however a post on MSDN from a Microsoft engineer (see:
slouken@8582
   372
    // http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/09a9868e-95bb-4858-ba1a-cb4d2c298d62 ),
slouken@8582
   373
    // indicates that these values are in DIPs, which is the same unit used
slouken@8582
   374
    // by CoreWindow's PointerMoved events (via the Position field in its CurrentPoint
slouken@8582
   375
    // property.  See http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.input.pointerpoint.position.aspx
slouken@8582
   376
    // for details.)
slouken@8582
   377
    //
slouken@8582
   378
    // To note, PointerMoved events are sent a 'RawPosition' value (via the
slouken@8582
   379
    // CurrentPoint property in MouseEventArgs), however these do not seem
slouken@8582
   380
    // to exhibit the same large-value behavior.
slouken@8582
   381
    //
slouken@8582
   382
    // The values passed via PointerMoved events can't always be used for relative
slouken@8582
   383
    // mouse motion, unfortunately.  Its values are bound to the cursor's position,
slouken@8582
   384
    // which stops when it hits one of the screen's edges.  This can be a problem in
slouken@8582
   385
    // first person shooters, whereby it is normal for mouse motion to travel far
slouken@8582
   386
    // along any one axis for a period of time.  MouseMoved events do not have the
slouken@8582
   387
    // screen-bounding limitation, and can be used regardless of where the system's
slouken@8582
   388
    // cursor is.
slouken@8582
   389
    //
slouken@8582
   390
    // One possible workaround would be to programmatically set the cursor's
slouken@8582
   391
    // position to the screen's center (when SDL's relative mouse mode is enabled),
slouken@8582
   392
    // however WinRT does not yet seem to have the ability to set the cursor's
slouken@8582
   393
    // position via a public API.  Win32 did this via an API call, SetCursorPos,
slouken@8582
   394
    // however WinRT makes this function be private.  Apps that use it won't get
slouken@8582
   395
    // approved for distribution in the Windows Store.  I've yet to be able to find
slouken@8582
   396
    // a suitable, store-friendly counterpart for WinRT.
slouken@8582
   397
    //
slouken@8582
   398
    // There may be some room for a workaround whereby OnPointerMoved's values
slouken@8582
   399
    // are compared to the values from OnMouseMoved in order to detect
slouken@8582
   400
    // when this bug is active.  A suitable transformation could then be made to
slouken@8582
   401
    // OnMouseMoved's values.  For now, however, the system-reported values are sent
slouken@8582
   402
    // to SDL with minimal transformation: from native screen coordinates (in DIPs)
slouken@8582
   403
    // to SDL window coordinates.
slouken@8582
   404
    //
slouken@8582
   405
    const Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y);
slouken@8582
   406
    const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs, TransformToSDLWindowSize);
slouken@8582
   407
    SDL_SendMouseMotion(
slouken@8582
   408
        window,
slouken@8582
   409
        0,
slouken@8582
   410
        1,
slouken@8582
   411
        _lround(mouseDeltaInSDLWindowCoords.X),
slouken@8582
   412
        _lround(mouseDeltaInSDLWindowCoords.Y));
dludwig@8521
   413
}
dludwig@8515
   414
dludwig@8515
   415
#endif // SDL_VIDEO_DRIVER_WINRT