src/core/winrt/SDL_winrtapp_direct3d.cpp
changeset 8582 c3e9a2b93517
parent 8581 c001dc3e258b
child 8600 092802455aed
     1.1 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp	Tue Mar 04 19:49:11 2014 -0500
     1.2 +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp	Sun Mar 09 11:06:11 2014 -0700
     1.3 @@ -1,668 +1,668 @@
     1.4 -
     1.5 -/* Standard C++11 includes */
     1.6 -#include <functional>
     1.7 -#include <string>
     1.8 -#include <sstream>
     1.9 -using namespace std;
    1.10 -
    1.11 -
    1.12 -/* Windows includes */
    1.13 -#include "ppltasks.h"
    1.14 -using namespace concurrency;
    1.15 -using namespace Windows::ApplicationModel;
    1.16 -using namespace Windows::ApplicationModel::Core;
    1.17 -using namespace Windows::ApplicationModel::Activation;
    1.18 -using namespace Windows::Devices::Input;
    1.19 -using namespace Windows::Graphics::Display;
    1.20 -using namespace Windows::Foundation;
    1.21 -using namespace Windows::System;
    1.22 -using namespace Windows::UI::Core;
    1.23 -using namespace Windows::UI::Input;
    1.24 -
    1.25 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
    1.26 -using namespace Windows::Phone::UI::Input;
    1.27 -#endif
    1.28 -
    1.29 -
    1.30 -/* SDL includes */
    1.31 -extern "C" {
    1.32 -#include "SDL_assert.h"
    1.33 -#include "SDL_events.h"
    1.34 -#include "SDL_hints.h"
    1.35 -#include "SDL_log.h"
    1.36 -#include "SDL_main.h"
    1.37 -#include "SDL_stdinc.h"
    1.38 -#include "SDL_render.h"
    1.39 -#include "../../video/SDL_sysvideo.h"
    1.40 -//#include "../../SDL_hints_c.h"
    1.41 -#include "../../events/SDL_events_c.h"
    1.42 -#include "../../events/SDL_keyboard_c.h"
    1.43 -#include "../../events/SDL_mouse_c.h"
    1.44 -#include "../../events/SDL_windowevents_c.h"
    1.45 -#include "../../render/SDL_sysrender.h"
    1.46 -#include "../windows/SDL_windows.h"
    1.47 -}
    1.48 -
    1.49 -#include "../../video/winrt/SDL_winrtevents_c.h"
    1.50 -#include "../../video/winrt/SDL_winrtvideo_cpp.h"
    1.51 -#include "SDL_winrtapp_common.h"
    1.52 -#include "SDL_winrtapp_direct3d.h"
    1.53 -
    1.54 -
    1.55 -// Compile-time debugging options:
    1.56 -// To enable, uncomment; to disable, comment them out.
    1.57 -//#define LOG_POINTER_EVENTS 1
    1.58 -//#define LOG_WINDOW_EVENTS 1
    1.59 -//#define LOG_ORIENTATION_EVENTS 1
    1.60 -
    1.61 -
    1.62 -// HACK, DLudwig: record a reference to the global, WinRT 'app'/view.
    1.63 -// SDL/WinRT will use this throughout its code.
    1.64 -//
    1.65 -// TODO, WinRT: consider replacing SDL_WinRTGlobalApp with something
    1.66 -// non-global, such as something created inside
    1.67 -// SDL_InitSubSystem(SDL_INIT_VIDEO), or something inside
    1.68 -// SDL_CreateWindow().
    1.69 -SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr;
    1.70 -
    1.71 -ref class SDLApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
    1.72 -{
    1.73 -public:
    1.74 -    virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView();
    1.75 -};
    1.76 -
    1.77 -IFrameworkView^ SDLApplicationSource::CreateView()
    1.78 -{
    1.79 -    // TODO, WinRT: see if this function (CreateView) can ever get called
    1.80 -    // more than once.  For now, just prevent it from ever assigning
    1.81 -    // SDL_WinRTGlobalApp more than once.
    1.82 -    SDL_assert(!SDL_WinRTGlobalApp);
    1.83 -    SDL_WinRTApp ^ app = ref new SDL_WinRTApp();
    1.84 -    if (!SDL_WinRTGlobalApp)
    1.85 -    {
    1.86 -        SDL_WinRTGlobalApp = app;
    1.87 -    }
    1.88 -    return app;
    1.89 -}
    1.90 -
    1.91 -int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **))
    1.92 -{
    1.93 -    WINRT_SDLAppEntryPoint = mainFunction;
    1.94 -    auto direct3DApplicationSource = ref new SDLApplicationSource();
    1.95 -    CoreApplication::Run(direct3DApplicationSource);
    1.96 -    return 0;
    1.97 -}
    1.98 -
    1.99 -static void WINRT_SetDisplayOrientationsPreference(void *userdata, const char *name, const char *oldValue, const char *newValue)
   1.100 -{
   1.101 -    SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0);
   1.102 -
   1.103 -    // Start with no orientation flags, then add each in as they're parsed
   1.104 -    // from newValue.
   1.105 -    unsigned int orientationFlags = 0;
   1.106 -    if (newValue) {
   1.107 -        std::istringstream tokenizer(newValue);
   1.108 -        while (!tokenizer.eof()) {
   1.109 -            std::string orientationName;
   1.110 -            std::getline(tokenizer, orientationName, ' ');
   1.111 -            if (orientationName == "LandscapeLeft") {
   1.112 -                orientationFlags |= (unsigned int) DisplayOrientations::LandscapeFlipped;
   1.113 -            } else if (orientationName == "LandscapeRight") {
   1.114 -                orientationFlags |= (unsigned int) DisplayOrientations::Landscape;
   1.115 -            } else if (orientationName == "Portrait") {
   1.116 -                orientationFlags |= (unsigned int) DisplayOrientations::Portrait;
   1.117 -            } else if (orientationName == "PortraitUpsideDown") {
   1.118 -                orientationFlags |= (unsigned int) DisplayOrientations::PortraitFlipped;
   1.119 -            }
   1.120 -        }
   1.121 -    }
   1.122 -
   1.123 -    // If no valid orientation flags were specified, use a reasonable set of defaults:
   1.124 -    if (!orientationFlags) {
   1.125 -        // TODO, WinRT: consider seeing if an app's default orientation flags can be found out via some API call(s).
   1.126 -        orientationFlags = (unsigned int) ( \
   1.127 -            DisplayOrientations::Landscape |
   1.128 -            DisplayOrientations::LandscapeFlipped |
   1.129 -            DisplayOrientations::Portrait |
   1.130 -            DisplayOrientations::PortraitFlipped);
   1.131 -    }
   1.132 -
   1.133 -    // Set the orientation/rotation preferences.  Please note that this does
   1.134 -    // not constitute a 100%-certain lock of a given set of possible
   1.135 -    // orientations.  According to Microsoft's documentation on WinRT [1]
   1.136 -    // when a device is not capable of being rotated, Windows may ignore
   1.137 -    // the orientation preferences, and stick to what the device is capable of
   1.138 -    // displaying.
   1.139 -    //
   1.140 -    // [1] Documentation on the 'InitialRotationPreference' setting for a
   1.141 -    // Windows app's manifest file describes how some orientation/rotation
   1.142 -    // preferences may be ignored.  See
   1.143 -    // http://msdn.microsoft.com/en-us/library/windows/apps/hh700343.aspx
   1.144 -    // for details.  Microsoft's "Display orientation sample" also gives an
   1.145 -    // outline of how Windows treats device rotation
   1.146 -    // (http://code.msdn.microsoft.com/Display-Orientation-Sample-19a58e93).
   1.147 -    DisplayProperties::AutoRotationPreferences = (DisplayOrientations) orientationFlags;
   1.148 -}
   1.149 -
   1.150 -static void
   1.151 -WINRT_ProcessWindowSizeChange()
   1.152 -{
   1.153 -    // Make the new window size be the one true fullscreen mode.
   1.154 -    // This change was initially done, in part, to allow the Direct3D 11.1
   1.155 -    // renderer to receive window-resize events as a device rotates.
   1.156 -    // Before, rotating a device from landscape, to portrait, and then
   1.157 -    // back to landscape would cause the Direct3D 11.1 swap buffer to
   1.158 -    // not get resized appropriately.  SDL would, on the rotation from
   1.159 -    // landscape to portrait, re-resize the SDL window to it's initial
   1.160 -    // size (landscape).  On the subsequent rotation, SDL would drop the
   1.161 -    // window-resize event as it appeared the SDL window didn't change
   1.162 -    // size, and the Direct3D 11.1 renderer wouldn't resize its swap
   1.163 -    // chain.
   1.164 -    SDL_DisplayMode newDisplayMode;
   1.165 -    if (WINRT_CalcDisplayModeUsingNativeWindow(&newDisplayMode) != 0) {
   1.166 -        return;
   1.167 -    }
   1.168 -
   1.169 -    // Make note of the old display mode, and it's old driverdata.
   1.170 -    SDL_DisplayMode oldDisplayMode;
   1.171 -    SDL_zero(oldDisplayMode);
   1.172 -    if (WINRT_GlobalSDLVideoDevice) {
   1.173 -        oldDisplayMode = WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode;
   1.174 -    }
   1.175 -
   1.176 -    // Setup the new display mode in the appropriate spots.
   1.177 -    if (WINRT_GlobalSDLVideoDevice) {
   1.178 -        // Make a full copy of the display mode for display_modes[0],
   1.179 -        // one with with a separately malloced 'driverdata' field.
   1.180 -        // SDL_VideoQuit(), if called, will attempt to free the driverdata
   1.181 -        // fields in 'desktop_mode' and each entry in the 'display_modes'
   1.182 -        // array.
   1.183 -        if (WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata) {
   1.184 -            // Free the previous mode's memory
   1.185 -            SDL_free(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata);
   1.186 -            WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata = NULL;
   1.187 -        }
   1.188 -        if (WINRT_DuplicateDisplayMode(&(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0]), &newDisplayMode) != 0) {
   1.189 -            // Uh oh, something went wrong.  A malloc call probably failed.
   1.190 -            SDL_free(newDisplayMode.driverdata);
   1.191 -            return;
   1.192 -        }
   1.193 -
   1.194 -        // Install 'newDisplayMode' into 'current_mode' and 'desktop_mode'.
   1.195 -        WINRT_GlobalSDLVideoDevice->displays[0].current_mode = newDisplayMode;
   1.196 -        WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode = newDisplayMode;
   1.197 -    }
   1.198 -
   1.199 -    if (WINRT_GlobalSDLWindow) {
   1.200 -        // Send a window-resize event to the rest of SDL, and to apps:
   1.201 -        SDL_SendWindowEvent(
   1.202 -            WINRT_GlobalSDLWindow,
   1.203 -            SDL_WINDOWEVENT_RESIZED,
   1.204 -            newDisplayMode.w,
   1.205 -            newDisplayMode.h);
   1.206 -
   1.207 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
   1.208 -        // HACK: On Windows Phone, make sure that orientation changes from
   1.209 -        // Landscape to LandscapeFlipped, Portrait to PortraitFlipped,
   1.210 -        // or vice-versa on either of those two, lead to the Direct3D renderer
   1.211 -        // getting updated.
   1.212 -        const DisplayOrientations oldOrientation = ((SDL_DisplayModeData *)oldDisplayMode.driverdata)->currentOrientation;
   1.213 -        const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)newDisplayMode.driverdata)->currentOrientation;
   1.214 -
   1.215 -        if ((oldOrientation == DisplayOrientations::Landscape && newOrientation == DisplayOrientations::LandscapeFlipped) ||
   1.216 -            (oldOrientation == DisplayOrientations::LandscapeFlipped && newOrientation == DisplayOrientations::Landscape) ||
   1.217 -            (oldOrientation == DisplayOrientations::Portrait && newOrientation == DisplayOrientations::PortraitFlipped) ||
   1.218 -            (oldOrientation == DisplayOrientations::PortraitFlipped && newOrientation == DisplayOrientations::Portrait))
   1.219 -        {
   1.220 -            // One of the reasons this event is getting sent out is because SDL
   1.221 -            // will ignore requests to send out SDL_WINDOWEVENT_RESIZED events
   1.222 -            // if and when the event size doesn't change (and the Direct3D 11.1
   1.223 -            // renderer doesn't get the memo).
   1.224 -            //
   1.225 -            // Make sure that the display/window size really didn't change.  If
   1.226 -            // it did, then a SDL_WINDOWEVENT_SIZE_CHANGED event got sent, and
   1.227 -            // the Direct3D 11.1 renderer picked it up, presumably.
   1.228 -            if (oldDisplayMode.w == newDisplayMode.w &&
   1.229 -                oldDisplayMode.h == newDisplayMode.h)
   1.230 -            {
   1.231 -                SDL_SendWindowEvent(
   1.232 -                    WINRT_GlobalSDLWindow,
   1.233 -                    SDL_WINDOWEVENT_SIZE_CHANGED,
   1.234 -                    newDisplayMode.w,
   1.235 -                    newDisplayMode.h);
   1.236 -            }
   1.237 -        }
   1.238 -#endif
   1.239 -    }
   1.240 -    
   1.241 -    // Finally, free the 'driverdata' field of the old 'desktop_mode'.
   1.242 -    if (oldDisplayMode.driverdata) {
   1.243 -        SDL_free(oldDisplayMode.driverdata);
   1.244 -        oldDisplayMode.driverdata = NULL;
   1.245 -    }
   1.246 -}
   1.247 -
   1.248 -SDL_WinRTApp::SDL_WinRTApp() :
   1.249 -    m_windowClosed(false),
   1.250 -    m_windowVisible(true)
   1.251 -{
   1.252 -}
   1.253 -
   1.254 -void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView)
   1.255 -{
   1.256 -    applicationView->Activated +=
   1.257 -        ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &SDL_WinRTApp::OnActivated);
   1.258 -
   1.259 -    CoreApplication::Suspending +=
   1.260 -        ref new EventHandler<SuspendingEventArgs^>(this, &SDL_WinRTApp::OnSuspending);
   1.261 -
   1.262 -    CoreApplication::Resuming +=
   1.263 -        ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnResuming);
   1.264 -
   1.265 -    CoreApplication::Exiting +=
   1.266 -        ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnExiting);
   1.267 -
   1.268 -    DisplayProperties::OrientationChanged +=
   1.269 -        ref new DisplayPropertiesEventHandler(this, &SDL_WinRTApp::OnOrientationChanged);
   1.270 -
   1.271 -    // Register the hint, SDL_HINT_ORIENTATIONS, with SDL.  This needs to be
   1.272 -    // done before the hint's callback is registered (as of Feb 22, 2013),
   1.273 -    // otherwise the hint callback won't get registered.
   1.274 -    //
   1.275 -    // 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.
   1.276 -    //SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight Portrait PortraitUpsideDown");   // DavidL: this is no longer needed (for SDL_AddHintCallback)
   1.277 -    SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference, NULL);
   1.278 -}
   1.279 -
   1.280 -void SDL_WinRTApp::OnOrientationChanged(Object^ sender)
   1.281 -{
   1.282 -#if LOG_ORIENTATION_EVENTS==1
   1.283 -    CoreWindow^ window = CoreWindow::GetForCurrentThread();
   1.284 -    if (window) {
   1.285 -        SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, CoreWindow Size={%f,%f}\n",
   1.286 -            __FUNCTION__,
   1.287 -            (int)DisplayProperties::CurrentOrientation,
   1.288 -            (int)DisplayProperties::NativeOrientation,
   1.289 -            (int)DisplayProperties::AutoRotationPreferences,
   1.290 -            window->Bounds.Width,
   1.291 -            window->Bounds.Height);
   1.292 -    } else {
   1.293 -        SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d\n",
   1.294 -            __FUNCTION__,
   1.295 -            (int)DisplayProperties::CurrentOrientation,
   1.296 -            (int)DisplayProperties::NativeOrientation,
   1.297 -            (int)DisplayProperties::AutoRotationPreferences);
   1.298 -    }
   1.299 -#endif
   1.300 -
   1.301 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
   1.302 -    // On Windows Phone, treat an orientation change as a change in window size.
   1.303 -    // The native window's size doesn't seem to change, however SDL will simulate
   1.304 -    // a window size change.
   1.305 -    WINRT_ProcessWindowSizeChange();
   1.306 -#endif
   1.307 -}
   1.308 -
   1.309 -void SDL_WinRTApp::SetWindow(CoreWindow^ window)
   1.310 -{
   1.311 -#if LOG_WINDOW_EVENTS==1
   1.312 -    SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, window Size={%f,%f}\n",
   1.313 -        __FUNCTION__,
   1.314 -        (int)DisplayProperties::CurrentOrientation,
   1.315 -        (int)DisplayProperties::NativeOrientation,
   1.316 -        (int)DisplayProperties::AutoRotationPreferences,
   1.317 -        window->Bounds.Width,
   1.318 -        window->Bounds.Height);
   1.319 -#endif
   1.320 -
   1.321 -    window->SizeChanged += 
   1.322 -        ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &SDL_WinRTApp::OnWindowSizeChanged);
   1.323 -
   1.324 -    window->VisibilityChanged +=
   1.325 -        ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &SDL_WinRTApp::OnVisibilityChanged);
   1.326 -
   1.327 -    window->Closed += 
   1.328 -        ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &SDL_WinRTApp::OnWindowClosed);
   1.329 -
   1.330 -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
   1.331 -    window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
   1.332 -#endif
   1.333 -
   1.334 -    window->PointerPressed +=
   1.335 -        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerPressed);
   1.336 -
   1.337 -    window->PointerMoved +=
   1.338 -        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerMoved);
   1.339 -
   1.340 -    window->PointerReleased +=
   1.341 -        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerReleased);
   1.342 -
   1.343 -    window->PointerWheelChanged +=
   1.344 -        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerWheelChanged);
   1.345 -
   1.346 -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
   1.347 -    // Retrieves relative-only mouse movements:
   1.348 -    Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved +=
   1.349 -        ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(this, &SDL_WinRTApp::OnMouseMoved);
   1.350 -#endif
   1.351 -
   1.352 -    window->KeyDown +=
   1.353 -        ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyDown);
   1.354 -
   1.355 -    window->KeyUp +=
   1.356 -        ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyUp);
   1.357 -
   1.358 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
   1.359 -    HardwareButtons::BackPressed +=
   1.360 -        ref new EventHandler<BackPressedEventArgs^>(this, &SDL_WinRTApp::OnBackButtonPressed);
   1.361 -#endif
   1.362 -
   1.363 -#if WINAPI_FAMILY == WINAPI_FAMILY_APP  // for Windows 8/8.1/RT apps... (and not Phone apps)
   1.364 -    // Make sure we know when a user has opened the app's settings pane.
   1.365 -    // This is needed in order to display a privacy policy, which needs
   1.366 -    // to be done for network-enabled apps, as per Windows Store requirements.
   1.367 -    using namespace Windows::UI::ApplicationSettings;
   1.368 -    SettingsPane::GetForCurrentView()->CommandsRequested +=
   1.369 -        ref new TypedEventHandler<SettingsPane^, SettingsPaneCommandsRequestedEventArgs^>
   1.370 -            (this, &SDL_WinRTApp::OnSettingsPaneCommandsRequested);
   1.371 -#endif
   1.372 -}
   1.373 -
   1.374 -void SDL_WinRTApp::Load(Platform::String^ entryPoint)
   1.375 -{
   1.376 -}
   1.377 -
   1.378 -void SDL_WinRTApp::Run()
   1.379 -{
   1.380 -    SDL_SetMainReady();
   1.381 -    if (WINRT_SDLAppEntryPoint)
   1.382 -    {
   1.383 -        // TODO, WinRT: pass the C-style main() a reasonably realistic
   1.384 -        // representation of command line arguments.
   1.385 -        int argc = 0;
   1.386 -        char **argv = NULL;
   1.387 -        WINRT_SDLAppEntryPoint(argc, argv);
   1.388 -    }
   1.389 -}
   1.390 -
   1.391 -void SDL_WinRTApp::PumpEvents()
   1.392 -{
   1.393 -    if (!m_windowClosed)
   1.394 -    {
   1.395 -        if (m_windowVisible)
   1.396 -        {
   1.397 -            CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
   1.398 -        }
   1.399 -        else
   1.400 -        {
   1.401 -            CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
   1.402 -        }
   1.403 -    }
   1.404 -}
   1.405 -
   1.406 -void SDL_WinRTApp::Uninitialize()
   1.407 -{
   1.408 -}
   1.409 -
   1.410 -#if WINAPI_FAMILY == WINAPI_FAMILY_APP
   1.411 -void SDL_WinRTApp::OnSettingsPaneCommandsRequested(
   1.412 -    Windows::UI::ApplicationSettings::SettingsPane ^p,
   1.413 -    Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args)
   1.414 -{
   1.415 -    using namespace Platform;
   1.416 -    using namespace Windows::UI::ApplicationSettings;
   1.417 -    using namespace Windows::UI::Popups;
   1.418 -
   1.419 -    String ^privacyPolicyURL = nullptr;     // a URL to an app's Privacy Policy
   1.420 -    String ^privacyPolicyLabel = nullptr;   // label/link text
   1.421 -    const char *tmpHintValue = NULL;        // SDL_GetHint-retrieved value, used immediately
   1.422 -    wchar_t *tmpStr = NULL;                 // used for UTF8 to UCS2 conversion
   1.423 -
   1.424 -    // Setup a 'Privacy Policy' link, if one is available (via SDL_GetHint):
   1.425 -    tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_URL);
   1.426 -    if (tmpHintValue && tmpHintValue[0] != '\0') {
   1.427 -        // Convert the privacy policy's URL to UCS2:
   1.428 -        tmpStr = WIN_UTF8ToString(tmpHintValue);
   1.429 -        privacyPolicyURL = ref new String(tmpStr);
   1.430 -        SDL_free(tmpStr);
   1.431 -
   1.432 -        // Optionally retrieve custom label-text for the link.  If this isn't
   1.433 -        // available, a default value will be used instead.
   1.434 -        tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_LABEL);
   1.435 -        if (tmpHintValue && tmpHintValue[0] != '\0') {
   1.436 -            tmpStr = WIN_UTF8ToString(tmpHintValue);
   1.437 -            privacyPolicyLabel = ref new String(tmpStr);
   1.438 -            SDL_free(tmpStr);
   1.439 -        } else {
   1.440 -            privacyPolicyLabel = ref new String(L"Privacy Policy");
   1.441 -        }
   1.442 -
   1.443 -        // Register the link, along with a handler to be called if and when it is
   1.444 -        // clicked:
   1.445 -        auto cmd = ref new SettingsCommand(L"privacyPolicy", privacyPolicyLabel,
   1.446 -            ref new UICommandInvokedHandler([=](IUICommand ^) {
   1.447 -                Windows::System::Launcher::LaunchUriAsync(ref new Uri(privacyPolicyURL));
   1.448 -        }));
   1.449 -        args->Request->ApplicationCommands->Append(cmd);
   1.450 -    }
   1.451 -}
   1.452 -#endif // if WINAPI_FAMILY == WINAPI_FAMILY_APP
   1.453 -
   1.454 -void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
   1.455 -{
   1.456 -#if LOG_WINDOW_EVENTS==1
   1.457 -    SDL_Log("%s, size={%f,%f}, current orientation=%d, native orientation=%d, auto rot. pref=%d, WINRT_GlobalSDLWindow?=%s\n",
   1.458 -        __FUNCTION__,
   1.459 -        args->Size.Width, args->Size.Height,
   1.460 -        (int)DisplayProperties::CurrentOrientation,
   1.461 -        (int)DisplayProperties::NativeOrientation,
   1.462 -        (int)DisplayProperties::AutoRotationPreferences,
   1.463 -        (WINRT_GlobalSDLWindow ? "yes" : "no"));
   1.464 -#endif
   1.465 -
   1.466 -    WINRT_ProcessWindowSizeChange();
   1.467 -}
   1.468 -
   1.469 -void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
   1.470 -{
   1.471 -#if LOG_WINDOW_EVENTS==1
   1.472 -    SDL_Log("%s, visible?=%s, WINRT_GlobalSDLWindow?=%s\n",
   1.473 -        __FUNCTION__,
   1.474 -        (args->Visible ? "yes" : "no"),
   1.475 -        (WINRT_GlobalSDLWindow ? "yes" : "no"));
   1.476 -#endif
   1.477 -
   1.478 -    m_windowVisible = args->Visible;
   1.479 -    if (WINRT_GlobalSDLWindow) {
   1.480 -        SDL_bool wasSDLWindowSurfaceValid = WINRT_GlobalSDLWindow->surface_valid;
   1.481 -
   1.482 -        if (args->Visible) {
   1.483 -            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_SHOWN, 0, 0);
   1.484 -        } else {
   1.485 -            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_HIDDEN, 0, 0);
   1.486 -        }
   1.487 -
   1.488 -        // HACK: Prevent SDL's window-hide handling code, which currently
   1.489 -        // triggers a fake window resize (possibly erronously), from
   1.490 -        // marking the SDL window's surface as invalid.
   1.491 -        //
   1.492 -        // A better solution to this probably involves figuring out if the
   1.493 -        // fake window resize can be prevented.
   1.494 -        WINRT_GlobalSDLWindow->surface_valid = wasSDLWindowSurfaceValid;
   1.495 -    }
   1.496 -}
   1.497 -
   1.498 -void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
   1.499 -{
   1.500 -#if LOG_WINDOW_EVENTS==1
   1.501 -    SDL_Log("%s\n", __FUNCTION__);
   1.502 -#endif
   1.503 -    m_windowClosed = true;
   1.504 -}
   1.505 -
   1.506 -void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
   1.507 -{
   1.508 -    CoreWindow::GetForCurrentThread()->Activate();
   1.509 -}
   1.510 -
   1.511 -static int SDLCALL RemoveAppSuspendAndResumeEvents(void * userdata, SDL_Event * event)
   1.512 -{
   1.513 -    if (event->type == SDL_WINDOWEVENT)
   1.514 -    {
   1.515 -        switch (event->window.event)
   1.516 -        {
   1.517 -            case SDL_WINDOWEVENT_MINIMIZED:
   1.518 -            case SDL_WINDOWEVENT_RESTORED:
   1.519 -                // Return 0 to indicate that the event should be removed from the
   1.520 -                // event queue:
   1.521 -                return 0;
   1.522 -            default:
   1.523 -                break;
   1.524 -        }
   1.525 -    }
   1.526 -
   1.527 -    // Return 1 to indicate that the event should stay in the event queue:
   1.528 -    return 1;
   1.529 -}
   1.530 -
   1.531 -void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
   1.532 -{
   1.533 -    // Save app state asynchronously after requesting a deferral. Holding a deferral
   1.534 -    // indicates that the application is busy performing suspending operations. Be
   1.535 -    // aware that a deferral may not be held indefinitely. After about five seconds,
   1.536 -    // the app will be forced to exit.
   1.537 -    SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
   1.538 -    create_task([this, deferral]()
   1.539 -    {
   1.540 -        // Send a window-minimized event immediately to observers.
   1.541 -        // CoreDispatcher::ProcessEvents, which is the backbone on which
   1.542 -        // SDL_WinRTApp::PumpEvents is built, will not return to its caller
   1.543 -        // once it sends out a suspend event.  Any events posted to SDL's
   1.544 -        // event queue won't get received until the WinRT app is resumed.
   1.545 -        // SDL_AddEventWatch() may be used to receive app-suspend events on
   1.546 -        // WinRT.
   1.547 -        //
   1.548 -        // In order to prevent app-suspend events from being received twice:
   1.549 -        // first via a callback passed to SDL_AddEventWatch, and second via
   1.550 -        // SDL's event queue, the event will be sent to SDL, then immediately
   1.551 -        // removed from the queue.
   1.552 -        if (WINRT_GlobalSDLWindow)
   1.553 -        {
   1.554 -            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0);   // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently)
   1.555 -            SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0);
   1.556 -        }
   1.557 -
   1.558 -        SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND);
   1.559 -        SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND);
   1.560 -
   1.561 -        deferral->Complete();
   1.562 -    });
   1.563 -}
   1.564 -
   1.565 -void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args)
   1.566 -{
   1.567 -    SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND);
   1.568 -    SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND);
   1.569 -
   1.570 -    // Restore any data or state that was unloaded on suspend. By default, data
   1.571 -    // and state are persisted when resuming from suspend. Note that this event
   1.572 -    // does not occur if the app was previously terminated.
   1.573 -    if (WINRT_GlobalSDLWindow)
   1.574 -    {
   1.575 -        SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_RESTORED, 0, 0);    // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently)
   1.576 -
   1.577 -        // Remove the app-resume event from the queue, as is done with the
   1.578 -        // app-suspend event.
   1.579 -        //
   1.580 -        // TODO, WinRT: consider posting this event to the queue even though
   1.581 -        // its counterpart, the app-suspend event, effectively has to be
   1.582 -        // processed immediately.
   1.583 -        SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0);
   1.584 -    }
   1.585 -}
   1.586 -
   1.587 -void SDL_WinRTApp::OnExiting(Platform::Object^ sender, Platform::Object^ args)
   1.588 -{
   1.589 -    SDL_SendAppEvent(SDL_APP_TERMINATING);
   1.590 -}
   1.591 -
   1.592 -static void
   1.593 -WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint)
   1.594 -{
   1.595 -    Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint;
   1.596 -    SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d\n",
   1.597 -        header,
   1.598 -        pt->Position.X, pt->Position.Y,
   1.599 -        transformedPoint.X, transformedPoint.Y,
   1.600 -        pt->Properties->MouseWheelDelta,
   1.601 -        pt->FrameId,
   1.602 -        pt->PointerId,
   1.603 -        WINRT_GetSDLButtonForPointerPoint(pt));
   1.604 -}
   1.605 -
   1.606 -void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
   1.607 -{
   1.608 -#if LOG_POINTER_EVENTS
   1.609 -    WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
   1.610 -#endif
   1.611 -
   1.612 -    WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
   1.613 -}
   1.614 -
   1.615 -void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args)
   1.616 -{
   1.617 -#if LOG_POINTER_EVENTS
   1.618 -    WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
   1.619 -#endif
   1.620 -
   1.621 -    WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
   1.622 -}
   1.623 -
   1.624 -void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
   1.625 -{
   1.626 -#if LOG_POINTER_EVENTS
   1.627 -    WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
   1.628 -#endif
   1.629 -
   1.630 -    WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
   1.631 -}
   1.632 -
   1.633 -void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args)
   1.634 -{
   1.635 -#if LOG_POINTER_EVENTS
   1.636 -    WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
   1.637 -#endif
   1.638 -
   1.639 -    WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
   1.640 -}
   1.641 -
   1.642 -void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args)
   1.643 -{
   1.644 -    WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args);
   1.645 -}
   1.646 -
   1.647 -void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
   1.648 -{
   1.649 -    WINRT_ProcessKeyDownEvent(args);
   1.650 -}
   1.651 -
   1.652 -void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
   1.653 -{
   1.654 -    WINRT_ProcessKeyUpEvent(args);
   1.655 -}
   1.656 -
   1.657 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
   1.658 -void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args)
   1.659 -{
   1.660 -    SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_AC_BACK);
   1.661 -    SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_AC_BACK);
   1.662 -
   1.663 +
   1.664 +/* Standard C++11 includes */
   1.665 +#include <functional>
   1.666 +#include <string>
   1.667 +#include <sstream>
   1.668 +using namespace std;
   1.669 +
   1.670 +
   1.671 +/* Windows includes */
   1.672 +#include "ppltasks.h"
   1.673 +using namespace concurrency;
   1.674 +using namespace Windows::ApplicationModel;
   1.675 +using namespace Windows::ApplicationModel::Core;
   1.676 +using namespace Windows::ApplicationModel::Activation;
   1.677 +using namespace Windows::Devices::Input;
   1.678 +using namespace Windows::Graphics::Display;
   1.679 +using namespace Windows::Foundation;
   1.680 +using namespace Windows::System;
   1.681 +using namespace Windows::UI::Core;
   1.682 +using namespace Windows::UI::Input;
   1.683 +
   1.684 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
   1.685 +using namespace Windows::Phone::UI::Input;
   1.686 +#endif
   1.687 +
   1.688 +
   1.689 +/* SDL includes */
   1.690 +extern "C" {
   1.691 +#include "SDL_assert.h"
   1.692 +#include "SDL_events.h"
   1.693 +#include "SDL_hints.h"
   1.694 +#include "SDL_log.h"
   1.695 +#include "SDL_main.h"
   1.696 +#include "SDL_stdinc.h"
   1.697 +#include "SDL_render.h"
   1.698 +#include "../../video/SDL_sysvideo.h"
   1.699 +//#include "../../SDL_hints_c.h"
   1.700 +#include "../../events/SDL_events_c.h"
   1.701 +#include "../../events/SDL_keyboard_c.h"
   1.702 +#include "../../events/SDL_mouse_c.h"
   1.703 +#include "../../events/SDL_windowevents_c.h"
   1.704 +#include "../../render/SDL_sysrender.h"
   1.705 +#include "../windows/SDL_windows.h"
   1.706 +}
   1.707 +
   1.708 +#include "../../video/winrt/SDL_winrtevents_c.h"
   1.709 +#include "../../video/winrt/SDL_winrtvideo_cpp.h"
   1.710 +#include "SDL_winrtapp_common.h"
   1.711 +#include "SDL_winrtapp_direct3d.h"
   1.712 +
   1.713 +
   1.714 +// Compile-time debugging options:
   1.715 +// To enable, uncomment; to disable, comment them out.
   1.716 +//#define LOG_POINTER_EVENTS 1
   1.717 +//#define LOG_WINDOW_EVENTS 1
   1.718 +//#define LOG_ORIENTATION_EVENTS 1
   1.719 +
   1.720 +
   1.721 +// HACK, DLudwig: record a reference to the global, WinRT 'app'/view.
   1.722 +// SDL/WinRT will use this throughout its code.
   1.723 +//
   1.724 +// TODO, WinRT: consider replacing SDL_WinRTGlobalApp with something
   1.725 +// non-global, such as something created inside
   1.726 +// SDL_InitSubSystem(SDL_INIT_VIDEO), or something inside
   1.727 +// SDL_CreateWindow().
   1.728 +SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr;
   1.729 +
   1.730 +ref class SDLApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
   1.731 +{
   1.732 +public:
   1.733 +    virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView();
   1.734 +};
   1.735 +
   1.736 +IFrameworkView^ SDLApplicationSource::CreateView()
   1.737 +{
   1.738 +    // TODO, WinRT: see if this function (CreateView) can ever get called
   1.739 +    // more than once.  For now, just prevent it from ever assigning
   1.740 +    // SDL_WinRTGlobalApp more than once.
   1.741 +    SDL_assert(!SDL_WinRTGlobalApp);
   1.742 +    SDL_WinRTApp ^ app = ref new SDL_WinRTApp();
   1.743 +    if (!SDL_WinRTGlobalApp)
   1.744 +    {
   1.745 +        SDL_WinRTGlobalApp = app;
   1.746 +    }
   1.747 +    return app;
   1.748 +}
   1.749 +
   1.750 +int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **))
   1.751 +{
   1.752 +    WINRT_SDLAppEntryPoint = mainFunction;
   1.753 +    auto direct3DApplicationSource = ref new SDLApplicationSource();
   1.754 +    CoreApplication::Run(direct3DApplicationSource);
   1.755 +    return 0;
   1.756 +}
   1.757 +
   1.758 +static void WINRT_SetDisplayOrientationsPreference(void *userdata, const char *name, const char *oldValue, const char *newValue)
   1.759 +{
   1.760 +    SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0);
   1.761 +
   1.762 +    // Start with no orientation flags, then add each in as they're parsed
   1.763 +    // from newValue.
   1.764 +    unsigned int orientationFlags = 0;
   1.765 +    if (newValue) {
   1.766 +        std::istringstream tokenizer(newValue);
   1.767 +        while (!tokenizer.eof()) {
   1.768 +            std::string orientationName;
   1.769 +            std::getline(tokenizer, orientationName, ' ');
   1.770 +            if (orientationName == "LandscapeLeft") {
   1.771 +                orientationFlags |= (unsigned int) DisplayOrientations::LandscapeFlipped;
   1.772 +            } else if (orientationName == "LandscapeRight") {
   1.773 +                orientationFlags |= (unsigned int) DisplayOrientations::Landscape;
   1.774 +            } else if (orientationName == "Portrait") {
   1.775 +                orientationFlags |= (unsigned int) DisplayOrientations::Portrait;
   1.776 +            } else if (orientationName == "PortraitUpsideDown") {
   1.777 +                orientationFlags |= (unsigned int) DisplayOrientations::PortraitFlipped;
   1.778 +            }
   1.779 +        }
   1.780 +    }
   1.781 +
   1.782 +    // If no valid orientation flags were specified, use a reasonable set of defaults:
   1.783 +    if (!orientationFlags) {
   1.784 +        // TODO, WinRT: consider seeing if an app's default orientation flags can be found out via some API call(s).
   1.785 +        orientationFlags = (unsigned int) ( \
   1.786 +            DisplayOrientations::Landscape |
   1.787 +            DisplayOrientations::LandscapeFlipped |
   1.788 +            DisplayOrientations::Portrait |
   1.789 +            DisplayOrientations::PortraitFlipped);
   1.790 +    }
   1.791 +
   1.792 +    // Set the orientation/rotation preferences.  Please note that this does
   1.793 +    // not constitute a 100%-certain lock of a given set of possible
   1.794 +    // orientations.  According to Microsoft's documentation on WinRT [1]
   1.795 +    // when a device is not capable of being rotated, Windows may ignore
   1.796 +    // the orientation preferences, and stick to what the device is capable of
   1.797 +    // displaying.
   1.798 +    //
   1.799 +    // [1] Documentation on the 'InitialRotationPreference' setting for a
   1.800 +    // Windows app's manifest file describes how some orientation/rotation
   1.801 +    // preferences may be ignored.  See
   1.802 +    // http://msdn.microsoft.com/en-us/library/windows/apps/hh700343.aspx
   1.803 +    // for details.  Microsoft's "Display orientation sample" also gives an
   1.804 +    // outline of how Windows treats device rotation
   1.805 +    // (http://code.msdn.microsoft.com/Display-Orientation-Sample-19a58e93).
   1.806 +    DisplayProperties::AutoRotationPreferences = (DisplayOrientations) orientationFlags;
   1.807 +}
   1.808 +
   1.809 +static void
   1.810 +WINRT_ProcessWindowSizeChange()
   1.811 +{
   1.812 +    // Make the new window size be the one true fullscreen mode.
   1.813 +    // This change was initially done, in part, to allow the Direct3D 11.1
   1.814 +    // renderer to receive window-resize events as a device rotates.
   1.815 +    // Before, rotating a device from landscape, to portrait, and then
   1.816 +    // back to landscape would cause the Direct3D 11.1 swap buffer to
   1.817 +    // not get resized appropriately.  SDL would, on the rotation from
   1.818 +    // landscape to portrait, re-resize the SDL window to it's initial
   1.819 +    // size (landscape).  On the subsequent rotation, SDL would drop the
   1.820 +    // window-resize event as it appeared the SDL window didn't change
   1.821 +    // size, and the Direct3D 11.1 renderer wouldn't resize its swap
   1.822 +    // chain.
   1.823 +    SDL_DisplayMode newDisplayMode;
   1.824 +    if (WINRT_CalcDisplayModeUsingNativeWindow(&newDisplayMode) != 0) {
   1.825 +        return;
   1.826 +    }
   1.827 +
   1.828 +    // Make note of the old display mode, and it's old driverdata.
   1.829 +    SDL_DisplayMode oldDisplayMode;
   1.830 +    SDL_zero(oldDisplayMode);
   1.831 +    if (WINRT_GlobalSDLVideoDevice) {
   1.832 +        oldDisplayMode = WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode;
   1.833 +    }
   1.834 +
   1.835 +    // Setup the new display mode in the appropriate spots.
   1.836 +    if (WINRT_GlobalSDLVideoDevice) {
   1.837 +        // Make a full copy of the display mode for display_modes[0],
   1.838 +        // one with with a separately malloced 'driverdata' field.
   1.839 +        // SDL_VideoQuit(), if called, will attempt to free the driverdata
   1.840 +        // fields in 'desktop_mode' and each entry in the 'display_modes'
   1.841 +        // array.
   1.842 +        if (WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata) {
   1.843 +            // Free the previous mode's memory
   1.844 +            SDL_free(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata);
   1.845 +            WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata = NULL;
   1.846 +        }
   1.847 +        if (WINRT_DuplicateDisplayMode(&(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0]), &newDisplayMode) != 0) {
   1.848 +            // Uh oh, something went wrong.  A malloc call probably failed.
   1.849 +            SDL_free(newDisplayMode.driverdata);
   1.850 +            return;
   1.851 +        }
   1.852 +
   1.853 +        // Install 'newDisplayMode' into 'current_mode' and 'desktop_mode'.
   1.854 +        WINRT_GlobalSDLVideoDevice->displays[0].current_mode = newDisplayMode;
   1.855 +        WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode = newDisplayMode;
   1.856 +    }
   1.857 +
   1.858 +    if (WINRT_GlobalSDLWindow) {
   1.859 +        // Send a window-resize event to the rest of SDL, and to apps:
   1.860 +        SDL_SendWindowEvent(
   1.861 +            WINRT_GlobalSDLWindow,
   1.862 +            SDL_WINDOWEVENT_RESIZED,
   1.863 +            newDisplayMode.w,
   1.864 +            newDisplayMode.h);
   1.865 +
   1.866 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
   1.867 +        // HACK: On Windows Phone, make sure that orientation changes from
   1.868 +        // Landscape to LandscapeFlipped, Portrait to PortraitFlipped,
   1.869 +        // or vice-versa on either of those two, lead to the Direct3D renderer
   1.870 +        // getting updated.
   1.871 +        const DisplayOrientations oldOrientation = ((SDL_DisplayModeData *)oldDisplayMode.driverdata)->currentOrientation;
   1.872 +        const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)newDisplayMode.driverdata)->currentOrientation;
   1.873 +
   1.874 +        if ((oldOrientation == DisplayOrientations::Landscape && newOrientation == DisplayOrientations::LandscapeFlipped) ||
   1.875 +            (oldOrientation == DisplayOrientations::LandscapeFlipped && newOrientation == DisplayOrientations::Landscape) ||
   1.876 +            (oldOrientation == DisplayOrientations::Portrait && newOrientation == DisplayOrientations::PortraitFlipped) ||
   1.877 +            (oldOrientation == DisplayOrientations::PortraitFlipped && newOrientation == DisplayOrientations::Portrait))
   1.878 +        {
   1.879 +            // One of the reasons this event is getting sent out is because SDL
   1.880 +            // will ignore requests to send out SDL_WINDOWEVENT_RESIZED events
   1.881 +            // if and when the event size doesn't change (and the Direct3D 11.1
   1.882 +            // renderer doesn't get the memo).
   1.883 +            //
   1.884 +            // Make sure that the display/window size really didn't change.  If
   1.885 +            // it did, then a SDL_WINDOWEVENT_SIZE_CHANGED event got sent, and
   1.886 +            // the Direct3D 11.1 renderer picked it up, presumably.
   1.887 +            if (oldDisplayMode.w == newDisplayMode.w &&
   1.888 +                oldDisplayMode.h == newDisplayMode.h)
   1.889 +            {
   1.890 +                SDL_SendWindowEvent(
   1.891 +                    WINRT_GlobalSDLWindow,
   1.892 +                    SDL_WINDOWEVENT_SIZE_CHANGED,
   1.893 +                    newDisplayMode.w,
   1.894 +                    newDisplayMode.h);
   1.895 +            }
   1.896 +        }
   1.897 +#endif
   1.898 +    }
   1.899 +    
   1.900 +    // Finally, free the 'driverdata' field of the old 'desktop_mode'.
   1.901 +    if (oldDisplayMode.driverdata) {
   1.902 +        SDL_free(oldDisplayMode.driverdata);
   1.903 +        oldDisplayMode.driverdata = NULL;
   1.904 +    }
   1.905 +}
   1.906 +
   1.907 +SDL_WinRTApp::SDL_WinRTApp() :
   1.908 +    m_windowClosed(false),
   1.909 +    m_windowVisible(true)
   1.910 +{
   1.911 +}
   1.912 +
   1.913 +void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView)
   1.914 +{
   1.915 +    applicationView->Activated +=
   1.916 +        ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &SDL_WinRTApp::OnActivated);
   1.917 +
   1.918 +    CoreApplication::Suspending +=
   1.919 +        ref new EventHandler<SuspendingEventArgs^>(this, &SDL_WinRTApp::OnSuspending);
   1.920 +
   1.921 +    CoreApplication::Resuming +=
   1.922 +        ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnResuming);
   1.923 +
   1.924 +    CoreApplication::Exiting +=
   1.925 +        ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnExiting);
   1.926 +
   1.927 +    DisplayProperties::OrientationChanged +=
   1.928 +        ref new DisplayPropertiesEventHandler(this, &SDL_WinRTApp::OnOrientationChanged);
   1.929 +
   1.930 +    // Register the hint, SDL_HINT_ORIENTATIONS, with SDL.  This needs to be
   1.931 +    // done before the hint's callback is registered (as of Feb 22, 2013),
   1.932 +    // otherwise the hint callback won't get registered.
   1.933 +    //
   1.934 +    // 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.
   1.935 +    //SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight Portrait PortraitUpsideDown");   // DavidL: this is no longer needed (for SDL_AddHintCallback)
   1.936 +    SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference, NULL);
   1.937 +}
   1.938 +
   1.939 +void SDL_WinRTApp::OnOrientationChanged(Object^ sender)
   1.940 +{
   1.941 +#if LOG_ORIENTATION_EVENTS==1
   1.942 +    CoreWindow^ window = CoreWindow::GetForCurrentThread();
   1.943 +    if (window) {
   1.944 +        SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, CoreWindow Size={%f,%f}\n",
   1.945 +            __FUNCTION__,
   1.946 +            (int)DisplayProperties::CurrentOrientation,
   1.947 +            (int)DisplayProperties::NativeOrientation,
   1.948 +            (int)DisplayProperties::AutoRotationPreferences,
   1.949 +            window->Bounds.Width,
   1.950 +            window->Bounds.Height);
   1.951 +    } else {
   1.952 +        SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d\n",
   1.953 +            __FUNCTION__,
   1.954 +            (int)DisplayProperties::CurrentOrientation,
   1.955 +            (int)DisplayProperties::NativeOrientation,
   1.956 +            (int)DisplayProperties::AutoRotationPreferences);
   1.957 +    }
   1.958 +#endif
   1.959 +
   1.960 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
   1.961 +    // On Windows Phone, treat an orientation change as a change in window size.
   1.962 +    // The native window's size doesn't seem to change, however SDL will simulate
   1.963 +    // a window size change.
   1.964 +    WINRT_ProcessWindowSizeChange();
   1.965 +#endif
   1.966 +}
   1.967 +
   1.968 +void SDL_WinRTApp::SetWindow(CoreWindow^ window)
   1.969 +{
   1.970 +#if LOG_WINDOW_EVENTS==1
   1.971 +    SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, window Size={%f,%f}\n",
   1.972 +        __FUNCTION__,
   1.973 +        (int)DisplayProperties::CurrentOrientation,
   1.974 +        (int)DisplayProperties::NativeOrientation,
   1.975 +        (int)DisplayProperties::AutoRotationPreferences,
   1.976 +        window->Bounds.Width,
   1.977 +        window->Bounds.Height);
   1.978 +#endif
   1.979 +
   1.980 +    window->SizeChanged += 
   1.981 +        ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &SDL_WinRTApp::OnWindowSizeChanged);
   1.982 +
   1.983 +    window->VisibilityChanged +=
   1.984 +        ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &SDL_WinRTApp::OnVisibilityChanged);
   1.985 +
   1.986 +    window->Closed += 
   1.987 +        ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &SDL_WinRTApp::OnWindowClosed);
   1.988 +
   1.989 +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
   1.990 +    window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
   1.991 +#endif
   1.992 +
   1.993 +    window->PointerPressed +=
   1.994 +        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerPressed);
   1.995 +
   1.996 +    window->PointerMoved +=
   1.997 +        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerMoved);
   1.998 +
   1.999 +    window->PointerReleased +=
  1.1000 +        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerReleased);
  1.1001 +
  1.1002 +    window->PointerWheelChanged +=
  1.1003 +        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerWheelChanged);
  1.1004 +
  1.1005 +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
  1.1006 +    // Retrieves relative-only mouse movements:
  1.1007 +    Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved +=
  1.1008 +        ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(this, &SDL_WinRTApp::OnMouseMoved);
  1.1009 +#endif
  1.1010 +
  1.1011 +    window->KeyDown +=
  1.1012 +        ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyDown);
  1.1013 +
  1.1014 +    window->KeyUp +=
  1.1015 +        ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyUp);
  1.1016 +
  1.1017 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
  1.1018 +    HardwareButtons::BackPressed +=
  1.1019 +        ref new EventHandler<BackPressedEventArgs^>(this, &SDL_WinRTApp::OnBackButtonPressed);
  1.1020 +#endif
  1.1021 +
  1.1022 +#if WINAPI_FAMILY == WINAPI_FAMILY_APP  // for Windows 8/8.1/RT apps... (and not Phone apps)
  1.1023 +    // Make sure we know when a user has opened the app's settings pane.
  1.1024 +    // This is needed in order to display a privacy policy, which needs
  1.1025 +    // to be done for network-enabled apps, as per Windows Store requirements.
  1.1026 +    using namespace Windows::UI::ApplicationSettings;
  1.1027 +    SettingsPane::GetForCurrentView()->CommandsRequested +=
  1.1028 +        ref new TypedEventHandler<SettingsPane^, SettingsPaneCommandsRequestedEventArgs^>
  1.1029 +            (this, &SDL_WinRTApp::OnSettingsPaneCommandsRequested);
  1.1030 +#endif
  1.1031 +}
  1.1032 +
  1.1033 +void SDL_WinRTApp::Load(Platform::String^ entryPoint)
  1.1034 +{
  1.1035 +}
  1.1036 +
  1.1037 +void SDL_WinRTApp::Run()
  1.1038 +{
  1.1039 +    SDL_SetMainReady();
  1.1040 +    if (WINRT_SDLAppEntryPoint)
  1.1041 +    {
  1.1042 +        // TODO, WinRT: pass the C-style main() a reasonably realistic
  1.1043 +        // representation of command line arguments.
  1.1044 +        int argc = 0;
  1.1045 +        char **argv = NULL;
  1.1046 +        WINRT_SDLAppEntryPoint(argc, argv);
  1.1047 +    }
  1.1048 +}
  1.1049 +
  1.1050 +void SDL_WinRTApp::PumpEvents()
  1.1051 +{
  1.1052 +    if (!m_windowClosed)
  1.1053 +    {
  1.1054 +        if (m_windowVisible)
  1.1055 +        {
  1.1056 +            CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
  1.1057 +        }
  1.1058 +        else
  1.1059 +        {
  1.1060 +            CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
  1.1061 +        }
  1.1062 +    }
  1.1063 +}
  1.1064 +
  1.1065 +void SDL_WinRTApp::Uninitialize()
  1.1066 +{
  1.1067 +}
  1.1068 +
  1.1069 +#if WINAPI_FAMILY == WINAPI_FAMILY_APP
  1.1070 +void SDL_WinRTApp::OnSettingsPaneCommandsRequested(
  1.1071 +    Windows::UI::ApplicationSettings::SettingsPane ^p,
  1.1072 +    Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args)
  1.1073 +{
  1.1074 +    using namespace Platform;
  1.1075 +    using namespace Windows::UI::ApplicationSettings;
  1.1076 +    using namespace Windows::UI::Popups;
  1.1077 +
  1.1078 +    String ^privacyPolicyURL = nullptr;     // a URL to an app's Privacy Policy
  1.1079 +    String ^privacyPolicyLabel = nullptr;   // label/link text
  1.1080 +    const char *tmpHintValue = NULL;        // SDL_GetHint-retrieved value, used immediately
  1.1081 +    wchar_t *tmpStr = NULL;                 // used for UTF8 to UCS2 conversion
  1.1082 +
  1.1083 +    // Setup a 'Privacy Policy' link, if one is available (via SDL_GetHint):
  1.1084 +    tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_URL);
  1.1085 +    if (tmpHintValue && tmpHintValue[0] != '\0') {
  1.1086 +        // Convert the privacy policy's URL to UCS2:
  1.1087 +        tmpStr = WIN_UTF8ToString(tmpHintValue);
  1.1088 +        privacyPolicyURL = ref new String(tmpStr);
  1.1089 +        SDL_free(tmpStr);
  1.1090 +
  1.1091 +        // Optionally retrieve custom label-text for the link.  If this isn't
  1.1092 +        // available, a default value will be used instead.
  1.1093 +        tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_LABEL);
  1.1094 +        if (tmpHintValue && tmpHintValue[0] != '\0') {
  1.1095 +            tmpStr = WIN_UTF8ToString(tmpHintValue);
  1.1096 +            privacyPolicyLabel = ref new String(tmpStr);
  1.1097 +            SDL_free(tmpStr);
  1.1098 +        } else {
  1.1099 +            privacyPolicyLabel = ref new String(L"Privacy Policy");
  1.1100 +        }
  1.1101 +
  1.1102 +        // Register the link, along with a handler to be called if and when it is
  1.1103 +        // clicked:
  1.1104 +        auto cmd = ref new SettingsCommand(L"privacyPolicy", privacyPolicyLabel,
  1.1105 +            ref new UICommandInvokedHandler([=](IUICommand ^) {
  1.1106 +                Windows::System::Launcher::LaunchUriAsync(ref new Uri(privacyPolicyURL));
  1.1107 +        }));
  1.1108 +        args->Request->ApplicationCommands->Append(cmd);
  1.1109 +    }
  1.1110 +}
  1.1111 +#endif // if WINAPI_FAMILY == WINAPI_FAMILY_APP
  1.1112 +
  1.1113 +void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
  1.1114 +{
  1.1115 +#if LOG_WINDOW_EVENTS==1
  1.1116 +    SDL_Log("%s, size={%f,%f}, current orientation=%d, native orientation=%d, auto rot. pref=%d, WINRT_GlobalSDLWindow?=%s\n",
  1.1117 +        __FUNCTION__,
  1.1118 +        args->Size.Width, args->Size.Height,
  1.1119 +        (int)DisplayProperties::CurrentOrientation,
  1.1120 +        (int)DisplayProperties::NativeOrientation,
  1.1121 +        (int)DisplayProperties::AutoRotationPreferences,
  1.1122 +        (WINRT_GlobalSDLWindow ? "yes" : "no"));
  1.1123 +#endif
  1.1124 +
  1.1125 +    WINRT_ProcessWindowSizeChange();
  1.1126 +}
  1.1127 +
  1.1128 +void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
  1.1129 +{
  1.1130 +#if LOG_WINDOW_EVENTS==1
  1.1131 +    SDL_Log("%s, visible?=%s, WINRT_GlobalSDLWindow?=%s\n",
  1.1132 +        __FUNCTION__,
  1.1133 +        (args->Visible ? "yes" : "no"),
  1.1134 +        (WINRT_GlobalSDLWindow ? "yes" : "no"));
  1.1135 +#endif
  1.1136 +
  1.1137 +    m_windowVisible = args->Visible;
  1.1138 +    if (WINRT_GlobalSDLWindow) {
  1.1139 +        SDL_bool wasSDLWindowSurfaceValid = WINRT_GlobalSDLWindow->surface_valid;
  1.1140 +
  1.1141 +        if (args->Visible) {
  1.1142 +            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_SHOWN, 0, 0);
  1.1143 +        } else {
  1.1144 +            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_HIDDEN, 0, 0);
  1.1145 +        }
  1.1146 +
  1.1147 +        // HACK: Prevent SDL's window-hide handling code, which currently
  1.1148 +        // triggers a fake window resize (possibly erronously), from
  1.1149 +        // marking the SDL window's surface as invalid.
  1.1150 +        //
  1.1151 +        // A better solution to this probably involves figuring out if the
  1.1152 +        // fake window resize can be prevented.
  1.1153 +        WINRT_GlobalSDLWindow->surface_valid = wasSDLWindowSurfaceValid;
  1.1154 +    }
  1.1155 +}
  1.1156 +
  1.1157 +void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
  1.1158 +{
  1.1159 +#if LOG_WINDOW_EVENTS==1
  1.1160 +    SDL_Log("%s\n", __FUNCTION__);
  1.1161 +#endif
  1.1162 +    m_windowClosed = true;
  1.1163 +}
  1.1164 +
  1.1165 +void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
  1.1166 +{
  1.1167 +    CoreWindow::GetForCurrentThread()->Activate();
  1.1168 +}
  1.1169 +
  1.1170 +static int SDLCALL RemoveAppSuspendAndResumeEvents(void * userdata, SDL_Event * event)
  1.1171 +{
  1.1172 +    if (event->type == SDL_WINDOWEVENT)
  1.1173 +    {
  1.1174 +        switch (event->window.event)
  1.1175 +        {
  1.1176 +            case SDL_WINDOWEVENT_MINIMIZED:
  1.1177 +            case SDL_WINDOWEVENT_RESTORED:
  1.1178 +                // Return 0 to indicate that the event should be removed from the
  1.1179 +                // event queue:
  1.1180 +                return 0;
  1.1181 +            default:
  1.1182 +                break;
  1.1183 +        }
  1.1184 +    }
  1.1185 +
  1.1186 +    // Return 1 to indicate that the event should stay in the event queue:
  1.1187 +    return 1;
  1.1188 +}
  1.1189 +
  1.1190 +void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
  1.1191 +{
  1.1192 +    // Save app state asynchronously after requesting a deferral. Holding a deferral
  1.1193 +    // indicates that the application is busy performing suspending operations. Be
  1.1194 +    // aware that a deferral may not be held indefinitely. After about five seconds,
  1.1195 +    // the app will be forced to exit.
  1.1196 +    SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
  1.1197 +    create_task([this, deferral]()
  1.1198 +    {
  1.1199 +        // Send a window-minimized event immediately to observers.
  1.1200 +        // CoreDispatcher::ProcessEvents, which is the backbone on which
  1.1201 +        // SDL_WinRTApp::PumpEvents is built, will not return to its caller
  1.1202 +        // once it sends out a suspend event.  Any events posted to SDL's
  1.1203 +        // event queue won't get received until the WinRT app is resumed.
  1.1204 +        // SDL_AddEventWatch() may be used to receive app-suspend events on
  1.1205 +        // WinRT.
  1.1206 +        //
  1.1207 +        // In order to prevent app-suspend events from being received twice:
  1.1208 +        // first via a callback passed to SDL_AddEventWatch, and second via
  1.1209 +        // SDL's event queue, the event will be sent to SDL, then immediately
  1.1210 +        // removed from the queue.
  1.1211 +        if (WINRT_GlobalSDLWindow)
  1.1212 +        {
  1.1213 +            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0);   // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently)
  1.1214 +            SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0);
  1.1215 +        }
  1.1216 +
  1.1217 +        SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND);
  1.1218 +        SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND);
  1.1219 +
  1.1220 +        deferral->Complete();
  1.1221 +    });
  1.1222 +}
  1.1223 +
  1.1224 +void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args)
  1.1225 +{
  1.1226 +    SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND);
  1.1227 +    SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND);
  1.1228 +
  1.1229 +    // Restore any data or state that was unloaded on suspend. By default, data
  1.1230 +    // and state are persisted when resuming from suspend. Note that this event
  1.1231 +    // does not occur if the app was previously terminated.
  1.1232 +    if (WINRT_GlobalSDLWindow)
  1.1233 +    {
  1.1234 +        SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_RESTORED, 0, 0);    // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently)
  1.1235 +
  1.1236 +        // Remove the app-resume event from the queue, as is done with the
  1.1237 +        // app-suspend event.
  1.1238 +        //
  1.1239 +        // TODO, WinRT: consider posting this event to the queue even though
  1.1240 +        // its counterpart, the app-suspend event, effectively has to be
  1.1241 +        // processed immediately.
  1.1242 +        SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0);
  1.1243 +    }
  1.1244 +}
  1.1245 +
  1.1246 +void SDL_WinRTApp::OnExiting(Platform::Object^ sender, Platform::Object^ args)
  1.1247 +{
  1.1248 +    SDL_SendAppEvent(SDL_APP_TERMINATING);
  1.1249 +}
  1.1250 +
  1.1251 +static void
  1.1252 +WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint)
  1.1253 +{
  1.1254 +    Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint;
  1.1255 +    SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d\n",
  1.1256 +        header,
  1.1257 +        pt->Position.X, pt->Position.Y,
  1.1258 +        transformedPoint.X, transformedPoint.Y,
  1.1259 +        pt->Properties->MouseWheelDelta,
  1.1260 +        pt->FrameId,
  1.1261 +        pt->PointerId,
  1.1262 +        WINRT_GetSDLButtonForPointerPoint(pt));
  1.1263 +}
  1.1264 +
  1.1265 +void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
  1.1266 +{
  1.1267 +#if LOG_POINTER_EVENTS
  1.1268 +    WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
  1.1269 +#endif
  1.1270 +
  1.1271 +    WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
  1.1272 +}
  1.1273 +
  1.1274 +void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args)
  1.1275 +{
  1.1276 +#if LOG_POINTER_EVENTS
  1.1277 +    WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
  1.1278 +#endif
  1.1279 +
  1.1280 +    WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
  1.1281 +}
  1.1282 +
  1.1283 +void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
  1.1284 +{
  1.1285 +#if LOG_POINTER_EVENTS
  1.1286 +    WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
  1.1287 +#endif
  1.1288 +
  1.1289 +    WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
  1.1290 +}
  1.1291 +
  1.1292 +void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args)
  1.1293 +{
  1.1294 +#if LOG_POINTER_EVENTS
  1.1295 +    WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
  1.1296 +#endif
  1.1297 +
  1.1298 +    WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
  1.1299 +}
  1.1300 +
  1.1301 +void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args)
  1.1302 +{
  1.1303 +    WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args);
  1.1304 +}
  1.1305 +
  1.1306 +void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
  1.1307 +{
  1.1308 +    WINRT_ProcessKeyDownEvent(args);
  1.1309 +}
  1.1310 +
  1.1311 +void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
  1.1312 +{
  1.1313 +    WINRT_ProcessKeyUpEvent(args);
  1.1314 +}
  1.1315 +
  1.1316 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
  1.1317 +void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args)
  1.1318 +{
  1.1319 +    SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_AC_BACK);
  1.1320 +    SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_AC_BACK);
  1.1321 +
  1.1322      const char *hint = SDL_GetHint(SDL_HINT_WINRT_HANDLE_BACK_BUTTON);
  1.1323      if (hint) {
  1.1324          if (*hint == '1') {
  1.1325              args->Handled = true;
  1.1326          }
  1.1327 -    }
  1.1328 -}
  1.1329 -#endif
  1.1330 -
  1.1331 +    }
  1.1332 +}
  1.1333 +#endif
  1.1334 +