src/video/winrt/SDL_winrtmouse.cpp
author David Ludwig <dludwig@pobox.com>
Sun, 01 Sep 2013 10:20:17 -0400
changeset 8514 8ba600edd93f
parent 8513 0bcf3970deba
child 8515 bc6cf9201dab
permissions -rw-r--r--
WinRT: added touch input event support for Windows 8/RT devices
dludwig@8500
     1
/*
dludwig@8500
     2
  Simple DirectMedia Layer
dludwig@8500
     3
  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
dludwig@8500
     4
dludwig@8500
     5
  This software is provided 'as-is', without any express or implied
dludwig@8500
     6
  warranty.  In no event will the authors be held liable for any damages
dludwig@8500
     7
  arising from the use of this software.
dludwig@8500
     8
dludwig@8500
     9
  Permission is granted to anyone to use this software for any purpose,
dludwig@8500
    10
  including commercial applications, and to alter it and redistribute it
dludwig@8500
    11
  freely, subject to the following restrictions:
dludwig@8500
    12
dludwig@8500
    13
  1. The origin of this software must not be misrepresented; you must not
dludwig@8500
    14
     claim that you wrote the original software. If you use this software
dludwig@8500
    15
     in a product, an acknowledgment in the product documentation would be
dludwig@8500
    16
     appreciated but is not required.
dludwig@8500
    17
  2. Altered source versions must be plainly marked as such, and must not be
dludwig@8500
    18
     misrepresented as being the original software.
dludwig@8500
    19
  3. This notice may not be removed or altered from any source distribution.
dludwig@8500
    20
*/
dludwig@8500
    21
dludwig@8500
    22
#include "SDL_config.h"
dludwig@8500
    23
dludwig@8500
    24
#if SDL_VIDEO_DRIVER_WINRT
dludwig@8500
    25
dludwig@8500
    26
/*
dludwig@8500
    27
 * Windows includes:
dludwig@8500
    28
 */
dludwig@8500
    29
#include <Windows.h>
dludwig@8500
    30
using namespace Windows::UI::Core;
dludwig@8500
    31
using Windows::UI::Core::CoreCursor;
dludwig@8500
    32
dludwig@8500
    33
/*
dludwig@8500
    34
 * SDL includes:
dludwig@8500
    35
 */
dludwig@8500
    36
extern "C" {
dludwig@8500
    37
#include "SDL_assert.h"
dludwig@8500
    38
#include "../../events/SDL_mouse_c.h"
dludwig@8513
    39
#include "../../events/SDL_touch_c.h"
dludwig@8500
    40
#include "../SDL_sysvideo.h"
dludwig@8500
    41
#include "SDL_events.h"
dludwig@8500
    42
#include "SDL_log.h"
dludwig@8500
    43
}
dludwig@8500
    44
dludwig@8500
    45
#include "../../core/winrt/SDL_winrtapp.h"
dludwig@8512
    46
#include "SDL_winrtvideo_cpp.h"
dludwig@8500
    47
#include "SDL_winrtmouse.h"
dludwig@8500
    48
dludwig@8500
    49
dludwig@8500
    50
static SDL_bool WINRT_UseRelativeMouseMode = SDL_FALSE;
dludwig@8513
    51
static SDL_TouchID WINRT_TouchID = 1;
dludwig@8513
    52
static unsigned int WINRT_LeftFingerDown = 0;
dludwig@8500
    53
dludwig@8500
    54
dludwig@8500
    55
static SDL_Cursor *
dludwig@8500
    56
WINRT_CreateSystemCursor(SDL_SystemCursor id)
dludwig@8500
    57
{
dludwig@8500
    58
    SDL_Cursor *cursor;
dludwig@8500
    59
    CoreCursorType cursorType = CoreCursorType::Arrow;
dludwig@8500
    60
dludwig@8500
    61
    switch(id)
dludwig@8500
    62
    {
dludwig@8500
    63
    default:
dludwig@8500
    64
        SDL_assert(0);
dludwig@8500
    65
        return NULL;
dludwig@8500
    66
    case SDL_SYSTEM_CURSOR_ARROW:     cursorType = CoreCursorType::Arrow; break;
dludwig@8500
    67
    case SDL_SYSTEM_CURSOR_IBEAM:     cursorType = CoreCursorType::IBeam; break;
dludwig@8500
    68
    case SDL_SYSTEM_CURSOR_WAIT:      cursorType = CoreCursorType::Wait; break;
dludwig@8500
    69
    case SDL_SYSTEM_CURSOR_CROSSHAIR: cursorType = CoreCursorType::Cross; break;
dludwig@8500
    70
    case SDL_SYSTEM_CURSOR_WAITARROW: cursorType = CoreCursorType::Wait; break;
dludwig@8500
    71
    case SDL_SYSTEM_CURSOR_SIZENWSE:  cursorType = CoreCursorType::SizeNorthwestSoutheast; break;
dludwig@8500
    72
    case SDL_SYSTEM_CURSOR_SIZENESW:  cursorType = CoreCursorType::SizeNortheastSouthwest; break;
dludwig@8500
    73
    case SDL_SYSTEM_CURSOR_SIZEWE:    cursorType = CoreCursorType::SizeWestEast; break;
dludwig@8500
    74
    case SDL_SYSTEM_CURSOR_SIZENS:    cursorType = CoreCursorType::SizeNorthSouth; break;
dludwig@8500
    75
    case SDL_SYSTEM_CURSOR_SIZEALL:   cursorType = CoreCursorType::SizeAll; break;
dludwig@8500
    76
    case SDL_SYSTEM_CURSOR_NO:        cursorType = CoreCursorType::UniversalNo; break;
dludwig@8500
    77
    case SDL_SYSTEM_CURSOR_HAND:      cursorType = CoreCursorType::Hand; break;
dludwig@8500
    78
    }
dludwig@8500
    79
dludwig@8500
    80
    cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
dludwig@8500
    81
    if (cursor) {
dludwig@8500
    82
        /* Create a pointer to a COM reference to a cursor.  The extra
dludwig@8500
    83
           pointer is used (on top of the COM reference) to allow the cursor
dludwig@8500
    84
           to be referenced by the SDL_cursor's driverdata field, which is
dludwig@8500
    85
           a void pointer.
dludwig@8500
    86
        */
dludwig@8500
    87
        CoreCursor ^* theCursor = new CoreCursor^(nullptr);
dludwig@8500
    88
        *theCursor = ref new CoreCursor(cursorType, 0);
dludwig@8500
    89
        cursor->driverdata = (void *) theCursor;
dludwig@8500
    90
    } else {
dludwig@8500
    91
        SDL_OutOfMemory();
dludwig@8500
    92
    }
dludwig@8500
    93
dludwig@8500
    94
    return cursor;
dludwig@8500
    95
}
dludwig@8500
    96
dludwig@8500
    97
static SDL_Cursor *
dludwig@8500
    98
WINRT_CreateDefaultCursor()
dludwig@8500
    99
{
dludwig@8500
   100
    return WINRT_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
dludwig@8500
   101
}
dludwig@8500
   102
dludwig@8500
   103
static void
dludwig@8500
   104
WINRT_FreeCursor(SDL_Cursor * cursor)
dludwig@8500
   105
{
dludwig@8500
   106
    if (cursor->driverdata) {
dludwig@8500
   107
        CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata;
dludwig@8500
   108
        *theCursor = nullptr;       // Release the COM reference to the CoreCursor
dludwig@8500
   109
        delete theCursor;           // Delete the pointer to the COM reference
dludwig@8500
   110
    }
dludwig@8500
   111
    SDL_free(cursor);
dludwig@8500
   112
}
dludwig@8500
   113
dludwig@8500
   114
static int
dludwig@8500
   115
WINRT_ShowCursor(SDL_Cursor * cursor)
dludwig@8500
   116
{
dludwig@8505
   117
    // TODO, WinRT, XAML: make WINRT_ShowCursor work when XAML support is enabled.
dludwig@8505
   118
    if ( ! CoreWindow::GetForCurrentThread()) {
dludwig@8505
   119
        return 0;
dludwig@8505
   120
    }
dludwig@8505
   121
dludwig@8500
   122
    if (cursor) {
dludwig@8500
   123
        CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata;
dludwig@8500
   124
        CoreWindow::GetForCurrentThread()->PointerCursor = *theCursor;
dludwig@8500
   125
    } else {
dludwig@8500
   126
        CoreWindow::GetForCurrentThread()->PointerCursor = nullptr;
dludwig@8500
   127
    }
dludwig@8500
   128
    return 0;
dludwig@8500
   129
}
dludwig@8500
   130
dludwig@8500
   131
static int
dludwig@8500
   132
WINRT_SetRelativeMouseMode(SDL_bool enabled)
dludwig@8500
   133
{
dludwig@8500
   134
    WINRT_UseRelativeMouseMode = enabled;
dludwig@8500
   135
    return 0;
dludwig@8500
   136
}
dludwig@8500
   137
dludwig@8500
   138
void
dludwig@8500
   139
WINRT_InitMouse(_THIS)
dludwig@8500
   140
{
dludwig@8500
   141
    SDL_Mouse *mouse = SDL_GetMouse();
dludwig@8500
   142
dludwig@8500
   143
    /* DLudwig, Dec 3, 2012: WinRT does not currently provide APIs for
dludwig@8500
   144
       the following features, AFAIK:
dludwig@8500
   145
        - custom cursors  (multiple system cursors are, however, available)
dludwig@8500
   146
        - programmatically moveable cursors
dludwig@8500
   147
    */
dludwig@8500
   148
dludwig@8500
   149
#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
dludwig@8500
   150
    //mouse->CreateCursor = WINRT_CreateCursor;
dludwig@8500
   151
    mouse->CreateSystemCursor = WINRT_CreateSystemCursor;
dludwig@8500
   152
    mouse->ShowCursor = WINRT_ShowCursor;
dludwig@8500
   153
    mouse->FreeCursor = WINRT_FreeCursor;
dludwig@8500
   154
    //mouse->WarpMouse = WINRT_WarpMouse;
dludwig@8500
   155
    mouse->SetRelativeMouseMode = WINRT_SetRelativeMouseMode;
dludwig@8500
   156
dludwig@8500
   157
    SDL_SetDefaultCursor(WINRT_CreateDefaultCursor());
dludwig@8500
   158
#endif
dludwig@8513
   159
dludwig@8513
   160
    /* Init touch: */
dludwig@8513
   161
    SDL_AddTouch(WINRT_TouchID, "");
dludwig@8500
   162
}
dludwig@8500
   163
dludwig@8500
   164
void
dludwig@8500
   165
WINRT_QuitMouse(_THIS)
dludwig@8500
   166
{
dludwig@8500
   167
}
dludwig@8500
   168
dludwig@8489
   169
// Applies necessary geometric transformations to raw cursor positions:
dludwig@8511
   170
Windows::Foundation::Point
dludwig@8511
   171
WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition)
dludwig@8489
   172
{
dludwig@8512
   173
    using namespace Windows::Graphics::Display;
dludwig@8512
   174
dludwig@8489
   175
    if (!window) {
dludwig@8489
   176
        return rawPosition;
dludwig@8489
   177
    }
dludwig@8512
   178
dludwig@8512
   179
    SDL_WindowData * windowData = (SDL_WindowData *) window->driverdata;
dludwig@8512
   180
    if (windowData->coreWindow == nullptr) {
dludwig@8512
   181
        // For some reason, the window isn't associated with a CoreWindow.
dludwig@8512
   182
        // This might end up being the case as XAML support is extended.
dludwig@8512
   183
        // For now, if there's no CoreWindow attached to the SDL_Window,
dludwig@8512
   184
        // don't do any transforms.
dludwig@8512
   185
        return rawPosition;
dludwig@8512
   186
    }
dludwig@8512
   187
dludwig@8512
   188
    // The CoreWindow can only be accessed on certain thread(s).
dludwig@8512
   189
    SDL_assert(CoreWindow::GetForCurrentThread() != nullptr);
dludwig@8512
   190
dludwig@8512
   191
    CoreWindow ^ nativeWindow = windowData->coreWindow.Get();
dludwig@8489
   192
    Windows::Foundation::Point outputPosition;
dludwig@8512
   193
dludwig@8512
   194
#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
dludwig@8489
   195
    outputPosition.X = rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width);
dludwig@8489
   196
    outputPosition.Y = rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height);
dludwig@8512
   197
#else
dludwig@8512
   198
    switch (DisplayProperties::CurrentOrientation)
dludwig@8512
   199
    {
dludwig@8512
   200
        case DisplayOrientations::Portrait:
dludwig@8512
   201
            outputPosition.X = rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width);
dludwig@8512
   202
            outputPosition.Y = rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height);
dludwig@8512
   203
            break;
dludwig@8512
   204
        case DisplayOrientations::PortraitFlipped:
dludwig@8512
   205
            outputPosition.X = (float32)window->w - rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width);
dludwig@8512
   206
            outputPosition.Y = (float32)window->h - rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height);
dludwig@8512
   207
            break;
dludwig@8512
   208
        case DisplayOrientations::Landscape:
dludwig@8512
   209
            outputPosition.X = rawPosition.Y * (((float32)window->w) / nativeWindow->Bounds.Height);
dludwig@8512
   210
            outputPosition.Y = (float32)window->h - rawPosition.X * (((float32)window->h) / nativeWindow->Bounds.Width);
dludwig@8512
   211
            break;
dludwig@8512
   212
        case DisplayOrientations::LandscapeFlipped:
dludwig@8512
   213
            outputPosition.X = (float32)window->w - rawPosition.Y * (((float32)window->w) / nativeWindow->Bounds.Height);
dludwig@8512
   214
            outputPosition.Y = rawPosition.X * (((float32)window->h) / nativeWindow->Bounds.Width);
dludwig@8512
   215
            break;
dludwig@8512
   216
        default:
dludwig@8512
   217
            break;
dludwig@8512
   218
    }
dludwig@8512
   219
#endif
dludwig@8512
   220
dludwig@8489
   221
    return outputPosition;
dludwig@8500
   222
}
dludwig@8500
   223
dludwig@8489
   224
static inline int
dludwig@8489
   225
_lround(float arg)
dludwig@8489
   226
{
dludwig@8489
   227
    if (arg >= 0.0f) {
dludwig@8489
   228
        return (int)floor(arg + 0.5f);
dludwig@8489
   229
    } else {
dludwig@8489
   230
        return (int)ceil(arg - 0.5f);
dludwig@8489
   231
    }
dludwig@8500
   232
}
dludwig@8500
   233
dludwig@8500
   234
void
dludwig@8500
   235
WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args)
dludwig@8500
   236
{
dludwig@8500
   237
    if (!window || !WINRT_UseRelativeMouseMode) {
dludwig@8500
   238
        return;
dludwig@8500
   239
    }
dludwig@8500
   240
dludwig@8489
   241
    // DLudwig, 2012-12-28: On some systems, namely Visual Studio's Windows
dludwig@8489
   242
    // Simulator, as well as Windows 8 in a Parallels 8 VM, MouseEventArgs'
dludwig@8489
   243
    // MouseDelta field often reports very large values.  More information
dludwig@8489
   244
    // on this can be found at the following pages on MSDN:
dludwig@8489
   245
    //  - http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/a3c789fa-f1c5-49c4-9c0a-7db88d0f90f8
dludwig@8489
   246
    //  - https://connect.microsoft.com/VisualStudio/Feedback/details/756515
dludwig@8489
   247
    //
dludwig@8489
   248
    // The values do not appear to be as large when running on some systems,
dludwig@8489
   249
    // most notably a Surface RT.  Furthermore, the values returned by
dludwig@8489
   250
    // CoreWindow's PointerMoved event, and sent to this class' OnPointerMoved
dludwig@8489
   251
    // method, do not ever appear to be large, even when MouseEventArgs'
dludwig@8489
   252
    // MouseDelta is reporting to the contrary.
dludwig@8489
   253
    //
dludwig@8489
   254
    // On systems with the large-values behavior, it appears that the values
dludwig@8489
   255
    // get reported as if the screen's size is 65536 units in both the X and Y
dludwig@8489
   256
    // dimensions.  This can be viewed by using Windows' now-private, "Raw Input"
dludwig@8489
   257
    // APIs.  (GetRawInputData, RegisterRawInputDevices, WM_INPUT, etc.)
dludwig@8489
   258
    //
dludwig@8489
   259
    // MSDN's documentation on MouseEventArgs' MouseDelta field (at
dludwig@8489
   260
    // http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.input.mouseeventargs.mousedelta ),
dludwig@8489
   261
    // does not seem to indicate (to me) that its values should be so large.  It
dludwig@8489
   262
    // says that its values should be a "change in screen location".  I could
dludwig@8489
   263
    // be misinterpreting this, however a post on MSDN from a Microsoft engineer (see: 
dludwig@8489
   264
    // http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/09a9868e-95bb-4858-ba1a-cb4d2c298d62 ),
dludwig@8489
   265
    // indicates that these values are in DIPs, which is the same unit used
dludwig@8489
   266
    // by CoreWindow's PointerMoved events (via the Position field in its CurrentPoint
dludwig@8489
   267
    // property.  See http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.input.pointerpoint.position.aspx
dludwig@8489
   268
    // for details.)
dludwig@8489
   269
    //
dludwig@8489
   270
    // To note, PointerMoved events are sent a 'RawPosition' value (via the
dludwig@8489
   271
    // CurrentPoint property in MouseEventArgs), however these do not seem
dludwig@8489
   272
    // to exhibit the same large-value behavior.
dludwig@8489
   273
    //
dludwig@8489
   274
    // The values passed via PointerMoved events can't always be used for relative
dludwig@8489
   275
    // mouse motion, unfortunately.  Its values are bound to the cursor's position,
dludwig@8489
   276
    // which stops when it hits one of the screen's edges.  This can be a problem in
dludwig@8489
   277
    // first person shooters, whereby it is normal for mouse motion to travel far
dludwig@8489
   278
    // along any one axis for a period of time.  MouseMoved events do not have the
dludwig@8489
   279
    // screen-bounding limitation, and can be used regardless of where the system's
dludwig@8489
   280
    // cursor is.
dludwig@8489
   281
    //
dludwig@8489
   282
    // One possible workaround would be to programmatically set the cursor's
dludwig@8489
   283
    // position to the screen's center (when SDL's relative mouse mode is enabled),
dludwig@8500
   284
    // however WinRT does not yet seem to have the ability to set the cursor's
dludwig@8489
   285
    // position via a public API.  Win32 did this via an API call, SetCursorPos,
dludwig@8489
   286
    // however WinRT makes this function be private.  Apps that use it won't get
dludwig@8489
   287
    // approved for distribution in the Windows Store.  I've yet to be able to find
dludwig@8489
   288
    // a suitable, store-friendly counterpart for WinRT.
dludwig@8489
   289
    //
dludwig@8489
   290
    // There may be some room for a workaround whereby OnPointerMoved's values
dludwig@8489
   291
    // are compared to the values from OnMouseMoved in order to detect
dludwig@8489
   292
    // when this bug is active.  A suitable transformation could then be made to
dludwig@8489
   293
    // OnMouseMoved's values.  For now, however, the system-reported values are sent
dludwig@8489
   294
    // to SDL with minimal transformation: from native screen coordinates (in DIPs)
dludwig@8489
   295
    // to SDL window coordinates.
dludwig@8489
   296
    //
dludwig@8489
   297
    const Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y);
dludwig@8511
   298
    const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs);
dludwig@8489
   299
    SDL_SendMouseMotion(
dludwig@8489
   300
        window,
dludwig@8489
   301
        0,
dludwig@8489
   302
        1,
dludwig@8489
   303
        _lround(mouseDeltaInSDLWindowCoords.X),
dludwig@8489
   304
        _lround(mouseDeltaInSDLWindowCoords.Y));
dludwig@8500
   305
}
dludwig@8500
   306
dludwig@8511
   307
Uint8
dludwig@8489
   308
WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt)
dludwig@8489
   309
{
dludwig@8489
   310
    using namespace Windows::UI::Input;
dludwig@8489
   311
dludwig@8511
   312
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
dludwig@8511
   313
    return SDL_BUTTON_LEFT;
dludwig@8511
   314
#else
dludwig@8489
   315
    switch (pt->Properties->PointerUpdateKind)
dludwig@8489
   316
    {
dludwig@8489
   317
        case PointerUpdateKind::LeftButtonPressed:
dludwig@8489
   318
        case PointerUpdateKind::LeftButtonReleased:
dludwig@8489
   319
            return SDL_BUTTON_LEFT;
dludwig@8489
   320
dludwig@8489
   321
        case PointerUpdateKind::RightButtonPressed:
dludwig@8489
   322
        case PointerUpdateKind::RightButtonReleased:
dludwig@8489
   323
            return SDL_BUTTON_RIGHT;
dludwig@8489
   324
dludwig@8489
   325
        case PointerUpdateKind::MiddleButtonPressed:
dludwig@8489
   326
        case PointerUpdateKind::MiddleButtonReleased:
dludwig@8489
   327
            return SDL_BUTTON_MIDDLE;
dludwig@8489
   328
dludwig@8489
   329
        case PointerUpdateKind::XButton1Pressed:
dludwig@8489
   330
        case PointerUpdateKind::XButton1Released:
dludwig@8489
   331
            return SDL_BUTTON_X1;
dludwig@8489
   332
dludwig@8489
   333
        case PointerUpdateKind::XButton2Pressed:
dludwig@8489
   334
        case PointerUpdateKind::XButton2Released:
dludwig@8489
   335
            return SDL_BUTTON_X2;
dludwig@8489
   336
dludwig@8489
   337
        default:
dludwig@8489
   338
            break;
dludwig@8489
   339
    }
dludwig@8511
   340
#endif
dludwig@8489
   341
dludwig@8489
   342
    return 0;
dludwig@8489
   343
}
dludwig@8489
   344
dludwig@8511
   345
//const char *
dludwig@8511
   346
//WINRT_ConvertPointerUpdateKindToString(Windows::UI::Input::PointerUpdateKind kind)
dludwig@8511
   347
//{
dludwig@8511
   348
//    using namespace Windows::UI::Input;
dludwig@8511
   349
//
dludwig@8511
   350
//    switch (kind)
dludwig@8511
   351
//    {
dludwig@8511
   352
//        case PointerUpdateKind::Other:
dludwig@8511
   353
//            return "Other";
dludwig@8511
   354
//        case PointerUpdateKind::LeftButtonPressed:
dludwig@8511
   355
//            return "LeftButtonPressed";
dludwig@8511
   356
//        case PointerUpdateKind::LeftButtonReleased:
dludwig@8511
   357
//            return "LeftButtonReleased";
dludwig@8511
   358
//        case PointerUpdateKind::RightButtonPressed:
dludwig@8511
   359
//            return "RightButtonPressed";
dludwig@8511
   360
//        case PointerUpdateKind::RightButtonReleased:
dludwig@8511
   361
//            return "RightButtonReleased";
dludwig@8511
   362
//        case PointerUpdateKind::MiddleButtonPressed:
dludwig@8511
   363
//            return "MiddleButtonPressed";
dludwig@8511
   364
//        case PointerUpdateKind::MiddleButtonReleased:
dludwig@8511
   365
//            return "MiddleButtonReleased";
dludwig@8511
   366
//        case PointerUpdateKind::XButton1Pressed:
dludwig@8511
   367
//            return "XButton1Pressed";
dludwig@8511
   368
//        case PointerUpdateKind::XButton1Released:
dludwig@8511
   369
//            return "XButton1Released";
dludwig@8511
   370
//        case PointerUpdateKind::XButton2Pressed:
dludwig@8511
   371
//            return "XButton2Pressed";
dludwig@8511
   372
//        case PointerUpdateKind::XButton2Released:
dludwig@8511
   373
//            return "XButton2Released";
dludwig@8511
   374
//    }
dludwig@8511
   375
//
dludwig@8511
   376
//    return "";
dludwig@8511
   377
//}
dludwig@8500
   378
dludwig@8514
   379
static bool
dludwig@8514
   380
WINRT_IsTouchEvent(Windows::UI::Input::PointerPoint ^pointerPoint)
dludwig@8514
   381
{
dludwig@8514
   382
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
dludwig@8514
   383
    return true;
dludwig@8514
   384
#else
dludwig@8514
   385
    using namespace Windows::Devices::Input;
dludwig@8514
   386
    switch (pointerPoint->PointerDevice->PointerDeviceType) {
dludwig@8514
   387
        case PointerDeviceType::Touch:
dludwig@8514
   388
        case PointerDeviceType::Pen:
dludwig@8514
   389
            return true;
dludwig@8514
   390
        default:
dludwig@8514
   391
            return false;
dludwig@8514
   392
    }
dludwig@8514
   393
#endif
dludwig@8514
   394
}
dludwig@8514
   395
dludwig@8500
   396
void
dludwig@8505
   397
WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
dludwig@8489
   398
{
dludwig@8489
   399
    if (!window || WINRT_UseRelativeMouseMode) {
dludwig@8489
   400
        return;
dludwig@8489
   401
    }
dludwig@8489
   402
dludwig@8511
   403
    Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position);
dludwig@8513
   404
dludwig@8513
   405
    if (pointerPoint->PointerId == WINRT_LeftFingerDown) {
dludwig@8513
   406
        SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y);
dludwig@8513
   407
    }
dludwig@8513
   408
dludwig@8514
   409
    if (WINRT_IsTouchEvent(pointerPoint)) {
dludwig@8514
   410
        SDL_SendTouchMotion(
dludwig@8514
   411
            WINRT_TouchID,
dludwig@8514
   412
            (SDL_FingerID) pointerPoint->PointerId,
dludwig@8514
   413
            transformedPoint.X,
dludwig@8514
   414
            transformedPoint.Y,
dludwig@8514
   415
            pointerPoint->Properties->Pressure);
dludwig@8514
   416
    }
dludwig@8500
   417
}
dludwig@8500
   418
dludwig@8500
   419
void
dludwig@8505
   420
WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
dludwig@8489
   421
{
dludwig@8489
   422
    if (!window) {
dludwig@8489
   423
        return;
dludwig@8489
   424
    }
dludwig@8489
   425
dludwig@8489
   426
    // FIXME: This may need to accumulate deltas up to WHEEL_DELTA
dludwig@8505
   427
    short motion = pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA;
dludwig@8489
   428
    SDL_SendMouseWheel(window, 0, 0, motion);
dludwig@8500
   429
}
dludwig@8500
   430
dludwig@8505
   431
void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
dludwig@8489
   432
{
dludwig@8489
   433
    if (!window) {
dludwig@8489
   434
        return;
dludwig@8489
   435
    }
dludwig@8489
   436
dludwig@8513
   437
    Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position);
dludwig@8513
   438
dludwig@8513
   439
    if (WINRT_LeftFingerDown == pointerPoint->PointerId) {
dludwig@8513
   440
        Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint);
dludwig@8513
   441
        if (button) {
dludwig@8513
   442
            SDL_SendMouseButton(window, 0, SDL_RELEASED, button);
dludwig@8513
   443
        }
dludwig@8513
   444
        WINRT_LeftFingerDown = 0;
dludwig@8489
   445
    }
dludwig@8513
   446
dludwig@8514
   447
    if (WINRT_IsTouchEvent(pointerPoint)) {
dludwig@8514
   448
        SDL_SendTouch(
dludwig@8514
   449
            WINRT_TouchID,
dludwig@8514
   450
            (SDL_FingerID) pointerPoint->PointerId,
dludwig@8514
   451
            SDL_FALSE,
dludwig@8514
   452
            transformedPoint.X,
dludwig@8514
   453
            transformedPoint.Y,
dludwig@8514
   454
            pointerPoint->Properties->Pressure);
dludwig@8514
   455
    }
dludwig@8500
   456
}
dludwig@8500
   457
dludwig@8505
   458
void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
dludwig@8489
   459
{
dludwig@8489
   460
    if (!window) {
dludwig@8489
   461
        return;
dludwig@8489
   462
    }
dludwig@8489
   463
dludwig@8513
   464
    Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position);
dludwig@8513
   465
dludwig@8513
   466
    if (!WINRT_LeftFingerDown) {
dludwig@8513
   467
        Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint);
dludwig@8513
   468
        if (button) {
dludwig@8511
   469
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
dludwig@8513
   470
            SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y);
dludwig@8511
   471
#endif
dludwig@8513
   472
            SDL_SendMouseButton(window, 0, SDL_PRESSED, button);
dludwig@8513
   473
        }
dludwig@8513
   474
dludwig@8513
   475
        WINRT_LeftFingerDown = pointerPoint->PointerId;
dludwig@8489
   476
    }
dludwig@8513
   477
dludwig@8514
   478
    if (WINRT_IsTouchEvent(pointerPoint)) {
dludwig@8514
   479
        SDL_SendTouch(
dludwig@8514
   480
            WINRT_TouchID,
dludwig@8514
   481
            (SDL_FingerID) pointerPoint->PointerId,
dludwig@8514
   482
            SDL_TRUE,
dludwig@8514
   483
            transformedPoint.X,
dludwig@8514
   484
            transformedPoint.Y,
dludwig@8514
   485
            pointerPoint->Properties->Pressure);
dludwig@8514
   486
    }
dludwig@8500
   487
}
dludwig@8500
   488
dludwig@8500
   489
#endif /* SDL_VIDEO_DRIVER_WINRT */
dludwig@8500
   490
dludwig@8500
   491
/* vi: set ts=4 sw=4 expandtab: */