src/core/winrt/SDL_winrtapp_direct3d.cpp
author Sam Lantinga <slouken@libsdl.org>
Mon, 22 Jun 2015 23:36:06 -0700
changeset 9776 952ff8a5076f
parent 9619 b94b6d0bff0f
child 9924 355cccccc7dc
permissions -rw-r--r--
Fixed bug 3030 - SDL_RecreateWindow fails to restore title, icon, etc.

Adam M.

It loses the title and icon when window recreation fails. For instance, this may happen when trying to create an OpenGL ES window on a system that doesn't support it. But at that point, the title and icon have already been lost.
slouken@8616
     1
/*
slouken@8616
     2
  Simple DirectMedia Layer
slouken@9619
     3
  Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
slouken@8616
     4
slouken@8616
     5
  This software is provided 'as-is', without any express or implied
slouken@8616
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@8616
     7
  arising from the use of this software.
slouken@8616
     8
slouken@8616
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@8616
    10
  including commercial applications, and to alter it and redistribute it
slouken@8616
    11
  freely, subject to the following restrictions:
slouken@8616
    12
slouken@8616
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@8616
    14
     claim that you wrote the original software. If you use this software
slouken@8616
    15
     in a product, an acknowledgment in the product documentation would be
slouken@8616
    16
     appreciated but is not required.
slouken@8616
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@8616
    18
     misrepresented as being the original software.
slouken@8616
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@8616
    20
*/
slouken@8616
    21
#include "../../SDL_internal.h"
slouken@8616
    22
slouken@8582
    23
/* Standard C++11 includes */
slouken@8582
    24
#include <functional>
slouken@8582
    25
#include <string>
slouken@8582
    26
#include <sstream>
slouken@8582
    27
using namespace std;
slouken@8582
    28
slouken@8582
    29
slouken@8582
    30
/* Windows includes */
slouken@8582
    31
#include "ppltasks.h"
slouken@8582
    32
using namespace concurrency;
slouken@8582
    33
using namespace Windows::ApplicationModel;
slouken@8582
    34
using namespace Windows::ApplicationModel::Core;
slouken@8582
    35
using namespace Windows::ApplicationModel::Activation;
slouken@8582
    36
using namespace Windows::Devices::Input;
slouken@8582
    37
using namespace Windows::Graphics::Display;
slouken@8582
    38
using namespace Windows::Foundation;
slouken@8582
    39
using namespace Windows::System;
slouken@8582
    40
using namespace Windows::UI::Core;
slouken@8582
    41
using namespace Windows::UI::Input;
slouken@8582
    42
slouken@8582
    43
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
slouken@8582
    44
using namespace Windows::Phone::UI::Input;
slouken@8582
    45
#endif
slouken@8582
    46
slouken@8582
    47
slouken@8582
    48
/* SDL includes */
slouken@8582
    49
extern "C" {
dludwig@8600
    50
#include "../../SDL_internal.h"
slouken@8582
    51
#include "SDL_assert.h"
slouken@8582
    52
#include "SDL_events.h"
slouken@8582
    53
#include "SDL_hints.h"
slouken@8582
    54
#include "SDL_log.h"
slouken@8582
    55
#include "SDL_main.h"
slouken@8582
    56
#include "SDL_stdinc.h"
slouken@8582
    57
#include "SDL_render.h"
slouken@8582
    58
#include "../../video/SDL_sysvideo.h"
slouken@8582
    59
//#include "../../SDL_hints_c.h"
slouken@8582
    60
#include "../../events/SDL_events_c.h"
slouken@8582
    61
#include "../../events/SDL_keyboard_c.h"
slouken@8582
    62
#include "../../events/SDL_mouse_c.h"
slouken@8582
    63
#include "../../events/SDL_windowevents_c.h"
slouken@8582
    64
#include "../../render/SDL_sysrender.h"
slouken@8582
    65
#include "../windows/SDL_windows.h"
slouken@8582
    66
}
slouken@8582
    67
slouken@8582
    68
#include "../../video/winrt/SDL_winrtevents_c.h"
slouken@8582
    69
#include "../../video/winrt/SDL_winrtvideo_cpp.h"
slouken@8582
    70
#include "SDL_winrtapp_common.h"
slouken@8582
    71
#include "SDL_winrtapp_direct3d.h"
slouken@8582
    72
dludwig@8679
    73
#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED
dludwig@8679
    74
/* Calling IDXGIDevice3::Trim on the active Direct3D 11.x device is necessary
dludwig@8679
    75
 * when Windows 8.1 apps are about to get suspended.
dludwig@8679
    76
 */
dludwig@8679
    77
extern "C" void D3D11_Trim(SDL_Renderer *);
dludwig@8679
    78
#endif
dludwig@8679
    79
slouken@8582
    80
slouken@8582
    81
// Compile-time debugging options:
slouken@8582
    82
// To enable, uncomment; to disable, comment them out.
slouken@8582
    83
//#define LOG_POINTER_EVENTS 1
slouken@8582
    84
//#define LOG_WINDOW_EVENTS 1
slouken@8582
    85
//#define LOG_ORIENTATION_EVENTS 1
slouken@8582
    86
slouken@8582
    87
slouken@8582
    88
// HACK, DLudwig: record a reference to the global, WinRT 'app'/view.
slouken@8582
    89
// SDL/WinRT will use this throughout its code.
slouken@8582
    90
//
slouken@8582
    91
// TODO, WinRT: consider replacing SDL_WinRTGlobalApp with something
slouken@8582
    92
// non-global, such as something created inside
slouken@8582
    93
// SDL_InitSubSystem(SDL_INIT_VIDEO), or something inside
slouken@8582
    94
// SDL_CreateWindow().
slouken@8582
    95
SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr;
slouken@8582
    96
slouken@8582
    97
ref class SDLApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
slouken@8582
    98
{
slouken@8582
    99
public:
slouken@8582
   100
    virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView();
slouken@8582
   101
};
slouken@8582
   102
slouken@8582
   103
IFrameworkView^ SDLApplicationSource::CreateView()
slouken@8582
   104
{
slouken@8582
   105
    // TODO, WinRT: see if this function (CreateView) can ever get called
slouken@8582
   106
    // more than once.  For now, just prevent it from ever assigning
slouken@8582
   107
    // SDL_WinRTGlobalApp more than once.
slouken@8582
   108
    SDL_assert(!SDL_WinRTGlobalApp);
slouken@8582
   109
    SDL_WinRTApp ^ app = ref new SDL_WinRTApp();
slouken@8582
   110
    if (!SDL_WinRTGlobalApp)
slouken@8582
   111
    {
slouken@8582
   112
        SDL_WinRTGlobalApp = app;
slouken@8582
   113
    }
slouken@8582
   114
    return app;
slouken@8582
   115
}
slouken@8582
   116
slouken@8582
   117
int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **))
slouken@8582
   118
{
slouken@8582
   119
    WINRT_SDLAppEntryPoint = mainFunction;
slouken@8582
   120
    auto direct3DApplicationSource = ref new SDLApplicationSource();
slouken@8582
   121
    CoreApplication::Run(direct3DApplicationSource);
slouken@8582
   122
    return 0;
slouken@8582
   123
}
slouken@8582
   124
slouken@8582
   125
static void WINRT_SetDisplayOrientationsPreference(void *userdata, const char *name, const char *oldValue, const char *newValue)
slouken@8582
   126
{
slouken@8582
   127
    SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0);
slouken@8582
   128
dludwig@9256
   129
    /* HACK: prevent SDL from altering an app's .appxmanifest-set orientation
dludwig@9256
   130
     * from being changed on startup, by detecting when SDL_HINT_ORIENTATIONS
dludwig@9256
   131
     * is getting registered.
dludwig@9256
   132
     *
dludwig@9256
   133
     * TODO, WinRT: consider reading in an app's .appxmanifest file, and apply its orientation when 'newValue == NULL'.
dludwig@9256
   134
     */
dludwig@9256
   135
    if ((oldValue == NULL) && (newValue == NULL)) {
dludwig@9256
   136
        return;
dludwig@9256
   137
    }
dludwig@9256
   138
slouken@8582
   139
    // Start with no orientation flags, then add each in as they're parsed
slouken@8582
   140
    // from newValue.
slouken@8582
   141
    unsigned int orientationFlags = 0;
slouken@8582
   142
    if (newValue) {
slouken@8582
   143
        std::istringstream tokenizer(newValue);
slouken@8582
   144
        while (!tokenizer.eof()) {
slouken@8582
   145
            std::string orientationName;
slouken@8582
   146
            std::getline(tokenizer, orientationName, ' ');
slouken@8582
   147
            if (orientationName == "LandscapeLeft") {
slouken@8582
   148
                orientationFlags |= (unsigned int) DisplayOrientations::LandscapeFlipped;
slouken@8582
   149
            } else if (orientationName == "LandscapeRight") {
slouken@8582
   150
                orientationFlags |= (unsigned int) DisplayOrientations::Landscape;
slouken@8582
   151
            } else if (orientationName == "Portrait") {
slouken@8582
   152
                orientationFlags |= (unsigned int) DisplayOrientations::Portrait;
slouken@8582
   153
            } else if (orientationName == "PortraitUpsideDown") {
slouken@8582
   154
                orientationFlags |= (unsigned int) DisplayOrientations::PortraitFlipped;
slouken@8582
   155
            }
slouken@8582
   156
        }
slouken@8582
   157
    }
slouken@8582
   158
slouken@8582
   159
    // If no valid orientation flags were specified, use a reasonable set of defaults:
slouken@8582
   160
    if (!orientationFlags) {
slouken@8582
   161
        // TODO, WinRT: consider seeing if an app's default orientation flags can be found out via some API call(s).
slouken@8582
   162
        orientationFlags = (unsigned int) ( \
slouken@8582
   163
            DisplayOrientations::Landscape |
slouken@8582
   164
            DisplayOrientations::LandscapeFlipped |
slouken@8582
   165
            DisplayOrientations::Portrait |
slouken@8582
   166
            DisplayOrientations::PortraitFlipped);
slouken@8582
   167
    }
slouken@8582
   168
slouken@8582
   169
    // Set the orientation/rotation preferences.  Please note that this does
slouken@8582
   170
    // not constitute a 100%-certain lock of a given set of possible
slouken@8582
   171
    // orientations.  According to Microsoft's documentation on WinRT [1]
slouken@8582
   172
    // when a device is not capable of being rotated, Windows may ignore
slouken@8582
   173
    // the orientation preferences, and stick to what the device is capable of
slouken@8582
   174
    // displaying.
slouken@8582
   175
    //
slouken@8582
   176
    // [1] Documentation on the 'InitialRotationPreference' setting for a
slouken@8582
   177
    // Windows app's manifest file describes how some orientation/rotation
slouken@8582
   178
    // preferences may be ignored.  See
slouken@8582
   179
    // http://msdn.microsoft.com/en-us/library/windows/apps/hh700343.aspx
slouken@8582
   180
    // for details.  Microsoft's "Display orientation sample" also gives an
slouken@8582
   181
    // outline of how Windows treats device rotation
slouken@8582
   182
    // (http://code.msdn.microsoft.com/Display-Orientation-Sample-19a58e93).
dludwig@8757
   183
    WINRT_DISPLAY_PROPERTY(AutoRotationPreferences) = (DisplayOrientations) orientationFlags;
slouken@8582
   184
}
slouken@8582
   185
slouken@8582
   186
static void
slouken@8582
   187
WINRT_ProcessWindowSizeChange()
slouken@8582
   188
{
dludwig@8664
   189
    SDL_VideoDevice *_this = SDL_GetVideoDevice();
dludwig@8664
   190
slouken@8582
   191
    // Make the new window size be the one true fullscreen mode.
slouken@8582
   192
    // This change was initially done, in part, to allow the Direct3D 11.1
slouken@8582
   193
    // renderer to receive window-resize events as a device rotates.
slouken@8582
   194
    // Before, rotating a device from landscape, to portrait, and then
slouken@8582
   195
    // back to landscape would cause the Direct3D 11.1 swap buffer to
slouken@8582
   196
    // not get resized appropriately.  SDL would, on the rotation from
slouken@8582
   197
    // landscape to portrait, re-resize the SDL window to it's initial
slouken@8582
   198
    // size (landscape).  On the subsequent rotation, SDL would drop the
slouken@8582
   199
    // window-resize event as it appeared the SDL window didn't change
slouken@8582
   200
    // size, and the Direct3D 11.1 renderer wouldn't resize its swap
slouken@8582
   201
    // chain.
slouken@8582
   202
    SDL_DisplayMode newDisplayMode;
slouken@8582
   203
    if (WINRT_CalcDisplayModeUsingNativeWindow(&newDisplayMode) != 0) {
slouken@8582
   204
        return;
slouken@8582
   205
    }
slouken@8582
   206
slouken@8582
   207
    // Make note of the old display mode, and it's old driverdata.
slouken@8582
   208
    SDL_DisplayMode oldDisplayMode;
slouken@8582
   209
    SDL_zero(oldDisplayMode);
dludwig@8664
   210
    if (_this) {
dludwig@8664
   211
        oldDisplayMode = _this->displays[0].desktop_mode;
slouken@8582
   212
    }
slouken@8582
   213
slouken@8582
   214
    // Setup the new display mode in the appropriate spots.
dludwig@8664
   215
    if (_this) {
slouken@8582
   216
        // Make a full copy of the display mode for display_modes[0],
slouken@8582
   217
        // one with with a separately malloced 'driverdata' field.
slouken@8582
   218
        // SDL_VideoQuit(), if called, will attempt to free the driverdata
slouken@8582
   219
        // fields in 'desktop_mode' and each entry in the 'display_modes'
slouken@8582
   220
        // array.
dludwig@8664
   221
        if (_this->displays[0].display_modes[0].driverdata) {
slouken@8582
   222
            // Free the previous mode's memory
dludwig@8664
   223
            SDL_free(_this->displays[0].display_modes[0].driverdata);
dludwig@8664
   224
            _this->displays[0].display_modes[0].driverdata = NULL;
slouken@8582
   225
        }
dludwig@8664
   226
        if (WINRT_DuplicateDisplayMode(&(_this->displays[0].display_modes[0]), &newDisplayMode) != 0) {
slouken@8582
   227
            // Uh oh, something went wrong.  A malloc call probably failed.
slouken@8582
   228
            SDL_free(newDisplayMode.driverdata);
slouken@8582
   229
            return;
slouken@8582
   230
        }
slouken@8582
   231
slouken@8582
   232
        // Install 'newDisplayMode' into 'current_mode' and 'desktop_mode'.
dludwig@8664
   233
        _this->displays[0].current_mode = newDisplayMode;
dludwig@8664
   234
        _this->displays[0].desktop_mode = newDisplayMode;
slouken@8582
   235
    }
slouken@8582
   236
slouken@8582
   237
    if (WINRT_GlobalSDLWindow) {
dludwig@8755
   238
        // If the window size changed, send a resize event to SDL and its host app:
dludwig@8755
   239
        int window_w = 0;
dludwig@8755
   240
        int window_h = 0;
dludwig@8755
   241
        SDL_GetWindowSize(WINRT_GlobalSDLWindow, &window_w, &window_h);
dludwig@8755
   242
        if ((window_w != newDisplayMode.w) || (window_h != newDisplayMode.h)) {
dludwig@8755
   243
            SDL_SendWindowEvent(
dludwig@8755
   244
                WINRT_GlobalSDLWindow,
dludwig@8755
   245
                SDL_WINDOWEVENT_RESIZED,
dludwig@8755
   246
                newDisplayMode.w,
dludwig@8755
   247
                newDisplayMode.h);
dludwig@8755
   248
        } else {
slouken@8582
   249
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
dludwig@8755
   250
            // HACK: Make sure that orientation changes
dludwig@8755
   251
            // lead to the Direct3D renderer's viewport getting updated:
slouken@8582
   252
            //
dludwig@8755
   253
            // For some reason, this doesn't seem to need to be done on Windows 8.x,
dludwig@8755
   254
            // even when going from Landscape to LandscapeFlipped.  It only seems to
dludwig@8755
   255
            // be needed on Windows Phone, at least when I tested on my devices.
dludwig@8755
   256
            // I'm not currently sure why this is, but it seems to work fine. -- David L.
dludwig@8755
   257
            //
dludwig@8755
   258
            // TODO, WinRT: do more extensive research into why orientation changes on Win 8.x don't need D3D changes, or if they might, in some cases
dludwig@8755
   259
            const DisplayOrientations oldOrientation = ((SDL_DisplayModeData *)oldDisplayMode.driverdata)->currentOrientation;
dludwig@8755
   260
            const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)newDisplayMode.driverdata)->currentOrientation;
dludwig@8755
   261
            if (oldOrientation != newOrientation)
slouken@8582
   262
            {
slouken@8582
   263
                SDL_SendWindowEvent(
slouken@8582
   264
                    WINRT_GlobalSDLWindow,
slouken@8582
   265
                    SDL_WINDOWEVENT_SIZE_CHANGED,
slouken@8582
   266
                    newDisplayMode.w,
slouken@8582
   267
                    newDisplayMode.h);
slouken@8582
   268
            }
dludwig@8755
   269
#endif
slouken@8582
   270
        }
slouken@8582
   271
    }
slouken@8582
   272
    
slouken@8582
   273
    // Finally, free the 'driverdata' field of the old 'desktop_mode'.
slouken@8582
   274
    if (oldDisplayMode.driverdata) {
slouken@8582
   275
        SDL_free(oldDisplayMode.driverdata);
slouken@8582
   276
        oldDisplayMode.driverdata = NULL;
slouken@8582
   277
    }
slouken@8582
   278
}
slouken@8582
   279
slouken@8582
   280
SDL_WinRTApp::SDL_WinRTApp() :
slouken@8582
   281
    m_windowClosed(false),
slouken@8582
   282
    m_windowVisible(true)
slouken@8582
   283
{
slouken@8582
   284
}
slouken@8582
   285
slouken@8582
   286
void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView)
slouken@8582
   287
{
slouken@8582
   288
    applicationView->Activated +=
slouken@8582
   289
        ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &SDL_WinRTApp::OnActivated);
slouken@8582
   290
slouken@8582
   291
    CoreApplication::Suspending +=
slouken@8582
   292
        ref new EventHandler<SuspendingEventArgs^>(this, &SDL_WinRTApp::OnSuspending);
slouken@8582
   293
slouken@8582
   294
    CoreApplication::Resuming +=
slouken@8582
   295
        ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnResuming);
slouken@8582
   296
slouken@8582
   297
    CoreApplication::Exiting +=
slouken@8582
   298
        ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnExiting);
slouken@8582
   299
}
slouken@8582
   300
dludwig@8621
   301
#if NTDDI_VERSION > NTDDI_WIN8
dludwig@8621
   302
void SDL_WinRTApp::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
dludwig@8621
   303
#else
slouken@8582
   304
void SDL_WinRTApp::OnOrientationChanged(Object^ sender)
dludwig@8621
   305
#endif
slouken@8582
   306
{
slouken@8582
   307
#if LOG_ORIENTATION_EVENTS==1
slouken@8582
   308
    CoreWindow^ window = CoreWindow::GetForCurrentThread();
slouken@8582
   309
    if (window) {
slouken@8582
   310
        SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, CoreWindow Size={%f,%f}\n",
slouken@8582
   311
            __FUNCTION__,
dludwig@8755
   312
            WINRT_DISPLAY_PROPERTY(CurrentOrientation),
dludwig@8755
   313
            WINRT_DISPLAY_PROPERTY(NativeOrientation),
dludwig@8755
   314
            WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
slouken@8582
   315
            window->Bounds.Width,
slouken@8582
   316
            window->Bounds.Height);
slouken@8582
   317
    } else {
slouken@8582
   318
        SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d\n",
slouken@8582
   319
            __FUNCTION__,
dludwig@8755
   320
            WINRT_DISPLAY_PROPERTY(CurrentOrientation),
dludwig@8755
   321
            WINRT_DISPLAY_PROPERTY(NativeOrientation),
dludwig@8755
   322
            WINRT_DISPLAY_PROPERTY(AutoRotationPreferences));
slouken@8582
   323
    }
slouken@8582
   324
#endif
slouken@8582
   325
slouken@8582
   326
    WINRT_ProcessWindowSizeChange();
slouken@8582
   327
}
slouken@8582
   328
slouken@8582
   329
void SDL_WinRTApp::SetWindow(CoreWindow^ window)
slouken@8582
   330
{
slouken@8582
   331
#if LOG_WINDOW_EVENTS==1
slouken@8582
   332
    SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, window Size={%f,%f}\n",
slouken@8582
   333
        __FUNCTION__,
dludwig@8755
   334
        WINRT_DISPLAY_PROPERTY(CurrentOrientation),
dludwig@8755
   335
        WINRT_DISPLAY_PROPERTY(NativeOrientation),
dludwig@8755
   336
        WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
slouken@8582
   337
        window->Bounds.Width,
slouken@8582
   338
        window->Bounds.Height);
slouken@8582
   339
#endif
slouken@8582
   340
slouken@8582
   341
    window->SizeChanged += 
slouken@8582
   342
        ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &SDL_WinRTApp::OnWindowSizeChanged);
slouken@8582
   343
slouken@8582
   344
    window->VisibilityChanged +=
slouken@8582
   345
        ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &SDL_WinRTApp::OnVisibilityChanged);
slouken@8582
   346
slouken@8582
   347
    window->Closed += 
slouken@8582
   348
        ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &SDL_WinRTApp::OnWindowClosed);
slouken@8582
   349
slouken@8582
   350
#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
slouken@8582
   351
    window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
slouken@8582
   352
#endif
slouken@8582
   353
slouken@8582
   354
    window->PointerPressed +=
slouken@8582
   355
        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerPressed);
slouken@8582
   356
slouken@8582
   357
    window->PointerMoved +=
slouken@8582
   358
        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerMoved);
slouken@8582
   359
slouken@8582
   360
    window->PointerReleased +=
slouken@8582
   361
        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerReleased);
slouken@8582
   362
slouken@8582
   363
    window->PointerWheelChanged +=
slouken@8582
   364
        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerWheelChanged);
slouken@8582
   365
slouken@8582
   366
#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
slouken@8582
   367
    // Retrieves relative-only mouse movements:
slouken@8582
   368
    Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved +=
slouken@8582
   369
        ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(this, &SDL_WinRTApp::OnMouseMoved);
slouken@8582
   370
#endif
slouken@8582
   371
slouken@8582
   372
    window->KeyDown +=
slouken@8582
   373
        ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyDown);
slouken@8582
   374
slouken@8582
   375
    window->KeyUp +=
slouken@8582
   376
        ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyUp);
slouken@8582
   377
dludwig@9240
   378
    window->CharacterReceived +=
dludwig@9240
   379
        ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(this, &SDL_WinRTApp::OnCharacterReceived);
dludwig@9240
   380
slouken@8582
   381
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
slouken@8582
   382
    HardwareButtons::BackPressed +=
slouken@8582
   383
        ref new EventHandler<BackPressedEventArgs^>(this, &SDL_WinRTApp::OnBackButtonPressed);
slouken@8582
   384
#endif
slouken@8582
   385
dludwig@8621
   386
#if NTDDI_VERSION > NTDDI_WIN8
dludwig@8621
   387
    DisplayInformation::GetForCurrentView()->OrientationChanged +=
dludwig@8621
   388
        ref new TypedEventHandler<Windows::Graphics::Display::DisplayInformation^, Object^>(this, &SDL_WinRTApp::OnOrientationChanged);
dludwig@8621
   389
#else
dludwig@8621
   390
    DisplayProperties::OrientationChanged +=
dludwig@8621
   391
        ref new DisplayPropertiesEventHandler(this, &SDL_WinRTApp::OnOrientationChanged);
dludwig@8621
   392
#endif
dludwig@8621
   393
dludwig@8621
   394
    // Register the hint, SDL_HINT_ORIENTATIONS, with SDL.
dludwig@8621
   395
    // TODO, WinRT: see if an app's default orientation can be found out via WinRT API(s), then set the initial value of SDL_HINT_ORIENTATIONS accordingly.
dludwig@8621
   396
    SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference, NULL);
dludwig@8621
   397
slouken@8582
   398
#if WINAPI_FAMILY == WINAPI_FAMILY_APP  // for Windows 8/8.1/RT apps... (and not Phone apps)
slouken@8582
   399
    // Make sure we know when a user has opened the app's settings pane.
slouken@8582
   400
    // This is needed in order to display a privacy policy, which needs
slouken@8582
   401
    // to be done for network-enabled apps, as per Windows Store requirements.
slouken@8582
   402
    using namespace Windows::UI::ApplicationSettings;
slouken@8582
   403
    SettingsPane::GetForCurrentView()->CommandsRequested +=
slouken@8582
   404
        ref new TypedEventHandler<SettingsPane^, SettingsPaneCommandsRequestedEventArgs^>
slouken@8582
   405
            (this, &SDL_WinRTApp::OnSettingsPaneCommandsRequested);
slouken@8582
   406
#endif
slouken@8582
   407
}
slouken@8582
   408
slouken@8582
   409
void SDL_WinRTApp::Load(Platform::String^ entryPoint)
slouken@8582
   410
{
slouken@8582
   411
}
slouken@8582
   412
slouken@8582
   413
void SDL_WinRTApp::Run()
slouken@8582
   414
{
slouken@8582
   415
    SDL_SetMainReady();
slouken@8582
   416
    if (WINRT_SDLAppEntryPoint)
slouken@8582
   417
    {
slouken@8582
   418
        // TODO, WinRT: pass the C-style main() a reasonably realistic
slouken@8582
   419
        // representation of command line arguments.
slouken@8582
   420
        int argc = 0;
slouken@8582
   421
        char **argv = NULL;
slouken@8582
   422
        WINRT_SDLAppEntryPoint(argc, argv);
slouken@8582
   423
    }
slouken@8582
   424
}
slouken@8582
   425
dludwig@8666
   426
static bool IsSDLWindowEventPending(SDL_WindowEventID windowEventID)
dludwig@8666
   427
{
dludwig@8666
   428
    SDL_Event events[128];
dludwig@8666
   429
    const int count = SDL_PeepEvents(events, sizeof(events)/sizeof(SDL_Event), SDL_PEEKEVENT, SDL_WINDOWEVENT, SDL_WINDOWEVENT);
dludwig@8666
   430
    for (int i = 0; i < count; ++i) {
dludwig@8666
   431
        if (events[i].window.event == windowEventID) {
dludwig@8666
   432
            return true;
dludwig@8666
   433
        }
dludwig@8666
   434
    }
dludwig@8666
   435
    return false;
dludwig@8666
   436
}
dludwig@8666
   437
dludwig@8666
   438
bool SDL_WinRTApp::ShouldWaitForAppResumeEvents()
dludwig@8666
   439
{
dludwig@8666
   440
    /* Don't wait if the app is visible: */
dludwig@8666
   441
    if (m_windowVisible) {
dludwig@8666
   442
        return false;
dludwig@8666
   443
    }
dludwig@8666
   444
    
dludwig@8666
   445
    /* Don't wait until the window-hide events finish processing.
dludwig@8666
   446
     * Do note that if an app-suspend event is sent (as indicated
dludwig@8666
   447
     * by SDL_APP_WILLENTERBACKGROUND and SDL_APP_DIDENTERBACKGROUND
dludwig@8666
   448
     * events), then this code may be a moot point, as WinRT's
dludwig@8666
   449
     * own event pump (aka ProcessEvents()) will pause regardless
dludwig@8666
   450
     * of what we do here.  This happens on Windows Phone 8, to note.
dludwig@8666
   451
     * Windows 8.x apps, on the other hand, may get a chance to run
dludwig@8666
   452
     * these.
dludwig@8666
   453
     */
dludwig@8666
   454
    if (IsSDLWindowEventPending(SDL_WINDOWEVENT_HIDDEN)) {
dludwig@8666
   455
        return false;
dludwig@8666
   456
    } else if (IsSDLWindowEventPending(SDL_WINDOWEVENT_FOCUS_LOST)) {
dludwig@8666
   457
        return false;
dludwig@8666
   458
    } else if (IsSDLWindowEventPending(SDL_WINDOWEVENT_MINIMIZED)) {
dludwig@8666
   459
        return false;
dludwig@8666
   460
    }
dludwig@8666
   461
dludwig@8666
   462
    return true;
dludwig@8666
   463
}
dludwig@8666
   464
slouken@8582
   465
void SDL_WinRTApp::PumpEvents()
slouken@8582
   466
{
dludwig@8666
   467
    if (!m_windowClosed) {
dludwig@8666
   468
        if (!ShouldWaitForAppResumeEvents()) {
dludwig@8666
   469
            /* This is the normal way in which events should be pumped.
dludwig@8666
   470
             * 'ProcessAllIfPresent' will make ProcessEvents() process anywhere
dludwig@8666
   471
             * from zero to N events, and will then return.
dludwig@8666
   472
             */
slouken@8582
   473
            CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
dludwig@8666
   474
        } else {
dludwig@8666
   475
            /* This style of event-pumping, with 'ProcessOneAndAllPending',
dludwig@8666
   476
             * will cause anywhere from one to N events to be processed.  If
dludwig@8666
   477
             * at least one event is processed, the call will return.  If
dludwig@8666
   478
             * no events are pending, then the call will wait until one is
dludwig@8666
   479
             * available, and will not return (to the caller) until this
dludwig@8666
   480
             * happens!  This should only occur when the app is hidden.
dludwig@8666
   481
             */
slouken@8582
   482
            CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
slouken@8582
   483
        }
slouken@8582
   484
    }
slouken@8582
   485
}
slouken@8582
   486
slouken@8582
   487
void SDL_WinRTApp::Uninitialize()
slouken@8582
   488
{
slouken@8582
   489
}
slouken@8582
   490
slouken@8582
   491
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
slouken@8582
   492
void SDL_WinRTApp::OnSettingsPaneCommandsRequested(
slouken@8582
   493
    Windows::UI::ApplicationSettings::SettingsPane ^p,
slouken@8582
   494
    Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args)
slouken@8582
   495
{
slouken@8582
   496
    using namespace Platform;
slouken@8582
   497
    using namespace Windows::UI::ApplicationSettings;
slouken@8582
   498
    using namespace Windows::UI::Popups;
slouken@8582
   499
slouken@8582
   500
    String ^privacyPolicyURL = nullptr;     // a URL to an app's Privacy Policy
slouken@8582
   501
    String ^privacyPolicyLabel = nullptr;   // label/link text
slouken@8582
   502
    const char *tmpHintValue = NULL;        // SDL_GetHint-retrieved value, used immediately
slouken@8582
   503
    wchar_t *tmpStr = NULL;                 // used for UTF8 to UCS2 conversion
slouken@8582
   504
slouken@8582
   505
    // Setup a 'Privacy Policy' link, if one is available (via SDL_GetHint):
slouken@8582
   506
    tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_URL);
slouken@8582
   507
    if (tmpHintValue && tmpHintValue[0] != '\0') {
slouken@8582
   508
        // Convert the privacy policy's URL to UCS2:
slouken@8582
   509
        tmpStr = WIN_UTF8ToString(tmpHintValue);
slouken@8582
   510
        privacyPolicyURL = ref new String(tmpStr);
slouken@8582
   511
        SDL_free(tmpStr);
slouken@8582
   512
slouken@8582
   513
        // Optionally retrieve custom label-text for the link.  If this isn't
slouken@8582
   514
        // available, a default value will be used instead.
slouken@8582
   515
        tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_LABEL);
slouken@8582
   516
        if (tmpHintValue && tmpHintValue[0] != '\0') {
slouken@8582
   517
            tmpStr = WIN_UTF8ToString(tmpHintValue);
slouken@8582
   518
            privacyPolicyLabel = ref new String(tmpStr);
slouken@8582
   519
            SDL_free(tmpStr);
slouken@8582
   520
        } else {
slouken@8582
   521
            privacyPolicyLabel = ref new String(L"Privacy Policy");
slouken@8582
   522
        }
slouken@8582
   523
slouken@8582
   524
        // Register the link, along with a handler to be called if and when it is
slouken@8582
   525
        // clicked:
slouken@8582
   526
        auto cmd = ref new SettingsCommand(L"privacyPolicy", privacyPolicyLabel,
slouken@8582
   527
            ref new UICommandInvokedHandler([=](IUICommand ^) {
slouken@8582
   528
                Windows::System::Launcher::LaunchUriAsync(ref new Uri(privacyPolicyURL));
slouken@8582
   529
        }));
slouken@8582
   530
        args->Request->ApplicationCommands->Append(cmd);
slouken@8582
   531
    }
slouken@8582
   532
}
slouken@8582
   533
#endif // if WINAPI_FAMILY == WINAPI_FAMILY_APP
slouken@8582
   534
slouken@8582
   535
void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
slouken@8582
   536
{
slouken@8582
   537
#if LOG_WINDOW_EVENTS==1
slouken@8582
   538
    SDL_Log("%s, size={%f,%f}, current orientation=%d, native orientation=%d, auto rot. pref=%d, WINRT_GlobalSDLWindow?=%s\n",
slouken@8582
   539
        __FUNCTION__,
slouken@8582
   540
        args->Size.Width, args->Size.Height,
dludwig@8755
   541
        WINRT_DISPLAY_PROPERTY(CurrentOrientation),
dludwig@8755
   542
        WINRT_DISPLAY_PROPERTY(NativeOrientation),
dludwig@8755
   543
        WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
slouken@8582
   544
        (WINRT_GlobalSDLWindow ? "yes" : "no"));
slouken@8582
   545
#endif
slouken@8582
   546
slouken@8582
   547
    WINRT_ProcessWindowSizeChange();
slouken@8582
   548
}
slouken@8582
   549
slouken@8582
   550
void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
slouken@8582
   551
{
slouken@8582
   552
#if LOG_WINDOW_EVENTS==1
slouken@8582
   553
    SDL_Log("%s, visible?=%s, WINRT_GlobalSDLWindow?=%s\n",
slouken@8582
   554
        __FUNCTION__,
slouken@8582
   555
        (args->Visible ? "yes" : "no"),
slouken@8582
   556
        (WINRT_GlobalSDLWindow ? "yes" : "no"));
slouken@8582
   557
#endif
slouken@8582
   558
slouken@8582
   559
    m_windowVisible = args->Visible;
slouken@8582
   560
    if (WINRT_GlobalSDLWindow) {
slouken@8582
   561
        SDL_bool wasSDLWindowSurfaceValid = WINRT_GlobalSDLWindow->surface_valid;
slouken@8582
   562
slouken@8582
   563
        if (args->Visible) {
slouken@8582
   564
            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_SHOWN, 0, 0);
dludwig@8678
   565
            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
dludwig@8678
   566
            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_RESTORED, 0, 0);
slouken@8582
   567
        } else {
slouken@8582
   568
            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_HIDDEN, 0, 0);
dludwig@8678
   569
            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
dludwig@8678
   570
            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
slouken@8582
   571
        }
slouken@8582
   572
slouken@8582
   573
        // HACK: Prevent SDL's window-hide handling code, which currently
slouken@8582
   574
        // triggers a fake window resize (possibly erronously), from
slouken@8582
   575
        // marking the SDL window's surface as invalid.
slouken@8582
   576
        //
slouken@8582
   577
        // A better solution to this probably involves figuring out if the
slouken@8582
   578
        // fake window resize can be prevented.
slouken@8582
   579
        WINRT_GlobalSDLWindow->surface_valid = wasSDLWindowSurfaceValid;
slouken@8582
   580
    }
slouken@8582
   581
}
slouken@8582
   582
slouken@8582
   583
void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
slouken@8582
   584
{
slouken@8582
   585
#if LOG_WINDOW_EVENTS==1
slouken@8582
   586
    SDL_Log("%s\n", __FUNCTION__);
slouken@8582
   587
#endif
slouken@8582
   588
    m_windowClosed = true;
slouken@8582
   589
}
slouken@8582
   590
slouken@8582
   591
void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
slouken@8582
   592
{
slouken@8582
   593
    CoreWindow::GetForCurrentThread()->Activate();
slouken@8582
   594
}
slouken@8582
   595
slouken@8582
   596
void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
slouken@8582
   597
{
slouken@8582
   598
    // Save app state asynchronously after requesting a deferral. Holding a deferral
slouken@8582
   599
    // indicates that the application is busy performing suspending operations. Be
slouken@8582
   600
    // aware that a deferral may not be held indefinitely. After about five seconds,
slouken@8582
   601
    // the app will be forced to exit.
dludwig@8665
   602
dludwig@8665
   603
    // ... but first, let the app know it's about to go to the background.
dludwig@8665
   604
    // The separation of events may be important, given that the deferral
dludwig@8665
   605
    // runs in a separate thread.  This'll make SDL_APP_WILLENTERBACKGROUND
dludwig@8665
   606
    // the only event among the two that runs in the main thread.  Given
dludwig@8665
   607
    // that a few WinRT operations can only be done from the main thread
dludwig@8665
   608
    // (things that access the WinRT CoreWindow are one example of this),
dludwig@8665
   609
    // this could be important.
dludwig@8665
   610
    SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND);
dludwig@8665
   611
slouken@8582
   612
    SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
slouken@8582
   613
    create_task([this, deferral]()
slouken@8582
   614
    {
dludwig@8666
   615
        // Send an app did-enter-background event immediately to observers.
slouken@8582
   616
        // CoreDispatcher::ProcessEvents, which is the backbone on which
slouken@8582
   617
        // SDL_WinRTApp::PumpEvents is built, will not return to its caller
slouken@8582
   618
        // once it sends out a suspend event.  Any events posted to SDL's
slouken@8582
   619
        // event queue won't get received until the WinRT app is resumed.
slouken@8582
   620
        // SDL_AddEventWatch() may be used to receive app-suspend events on
slouken@8582
   621
        // WinRT.
slouken@8582
   622
        SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND);
slouken@8582
   623
dludwig@8679
   624
        // Let the Direct3D 11 renderer prepare for the app to be backgrounded.
dludwig@8679
   625
        // This is necessary for Windows 8.1, possibly elsewhere in the future.
dludwig@8679
   626
        // More details at: http://msdn.microsoft.com/en-us/library/windows/apps/Hh994929.aspx
dludwig@8679
   627
#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED
dludwig@8679
   628
        if (WINRT_GlobalSDLWindow) {
dludwig@8679
   629
            SDL_Renderer * renderer = SDL_GetRenderer(WINRT_GlobalSDLWindow);
dludwig@8679
   630
            if (renderer && (SDL_strcmp(renderer->info.name, "direct3d11") == 0)) {
dludwig@8679
   631
                D3D11_Trim(renderer);
dludwig@8679
   632
            }
dludwig@8679
   633
        }
dludwig@8679
   634
#endif
dludwig@8679
   635
slouken@8582
   636
        deferral->Complete();
slouken@8582
   637
    });
slouken@8582
   638
}
slouken@8582
   639
slouken@8582
   640
void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args)
slouken@8582
   641
{
dludwig@8666
   642
    // Restore any data or state that was unloaded on suspend. By default, data
dludwig@8666
   643
    // and state are persisted when resuming from suspend. Note that these events
dludwig@8666
   644
    // do not occur if the app was previously terminated.
slouken@8582
   645
    SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND);
slouken@8582
   646
    SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND);
slouken@8582
   647
}
slouken@8582
   648
slouken@8582
   649
void SDL_WinRTApp::OnExiting(Platform::Object^ sender, Platform::Object^ args)
slouken@8582
   650
{
slouken@8582
   651
    SDL_SendAppEvent(SDL_APP_TERMINATING);
slouken@8582
   652
}
slouken@8582
   653
slouken@8582
   654
static void
slouken@8582
   655
WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint)
slouken@8582
   656
{
slouken@8582
   657
    Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint;
slouken@8582
   658
    SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d\n",
slouken@8582
   659
        header,
slouken@8582
   660
        pt->Position.X, pt->Position.Y,
slouken@8582
   661
        transformedPoint.X, transformedPoint.Y,
slouken@8582
   662
        pt->Properties->MouseWheelDelta,
slouken@8582
   663
        pt->FrameId,
slouken@8582
   664
        pt->PointerId,
slouken@8582
   665
        WINRT_GetSDLButtonForPointerPoint(pt));
slouken@8582
   666
}
slouken@8582
   667
slouken@8582
   668
void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
slouken@8582
   669
{
slouken@8582
   670
#if LOG_POINTER_EVENTS
slouken@8582
   671
    WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
slouken@8582
   672
#endif
slouken@8582
   673
slouken@8582
   674
    WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
slouken@8582
   675
}
slouken@8582
   676
slouken@8582
   677
void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args)
slouken@8582
   678
{
slouken@8582
   679
#if LOG_POINTER_EVENTS
slouken@8582
   680
    WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
slouken@8582
   681
#endif
slouken@8582
   682
slouken@8582
   683
    WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
slouken@8582
   684
}
slouken@8582
   685
slouken@8582
   686
void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
slouken@8582
   687
{
slouken@8582
   688
#if LOG_POINTER_EVENTS
slouken@8582
   689
    WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
slouken@8582
   690
#endif
slouken@8582
   691
slouken@8582
   692
    WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
slouken@8582
   693
}
slouken@8582
   694
slouken@8582
   695
void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args)
slouken@8582
   696
{
slouken@8582
   697
#if LOG_POINTER_EVENTS
slouken@8582
   698
    WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
slouken@8582
   699
#endif
slouken@8582
   700
slouken@8582
   701
    WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
slouken@8582
   702
}
slouken@8582
   703
slouken@8582
   704
void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args)
slouken@8582
   705
{
slouken@8582
   706
    WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args);
slouken@8582
   707
}
slouken@8582
   708
slouken@8582
   709
void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
slouken@8582
   710
{
slouken@8582
   711
    WINRT_ProcessKeyDownEvent(args);
slouken@8582
   712
}
slouken@8582
   713
slouken@8582
   714
void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
slouken@8582
   715
{
slouken@8582
   716
    WINRT_ProcessKeyUpEvent(args);
slouken@8582
   717
}
slouken@8582
   718
dludwig@9240
   719
void SDL_WinRTApp::OnCharacterReceived(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CharacterReceivedEventArgs^ args)
dludwig@9240
   720
{
dludwig@9240
   721
    WINRT_ProcessCharacterReceivedEvent(args);
dludwig@9240
   722
}
dludwig@9240
   723
slouken@8582
   724
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
slouken@8582
   725
void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args)
slouken@8582
   726
{
slouken@8582
   727
    SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_AC_BACK);
slouken@8582
   728
    SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_AC_BACK);
slouken@8582
   729
dludwig@8577
   730
    const char *hint = SDL_GetHint(SDL_HINT_WINRT_HANDLE_BACK_BUTTON);
dludwig@8577
   731
    if (hint) {
dludwig@8577
   732
        if (*hint == '1') {
dludwig@8577
   733
            args->Handled = true;
dludwig@8577
   734
        }
slouken@8582
   735
    }
slouken@8582
   736
}
slouken@8582
   737
#endif
slouken@8582
   738