/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"

#if SDL_VIDEO_DRIVER_WINRT

/* WinRT SDL video driver implementation

   Initial work on this was done by David Ludwig (dludwig@pobox.com), and
   was based off of SDL's "dummy" video driver.
 */

/* Windows includes */
#include <agile.h>
#include <windows.graphics.display.h>
#include <windows.system.display.h>
#include <dxgi.h>
#include <dxgi1_2.h>
using namespace Windows::ApplicationModel::Core;
using namespace Windows::Foundation;
using namespace Windows::Graphics::Display;
using namespace Windows::UI::Core;
using namespace Windows::UI::ViewManagement;


/* [re]declare Windows GUIDs locally, to limit the amount of external lib(s) SDL has to link to */
static const GUID IID_IDisplayRequest   = { 0xe5732044, 0xf49f, 0x4b60, { 0x8d, 0xd4, 0x5e, 0x7e, 0x3a, 0x63, 0x2a, 0xc0 } };
static const GUID IID_IDXGIFactory2     = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } };


/* SDL includes */
extern "C" {
#include "SDL_video.h"
#include "SDL_mouse.h"
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h"
#include "../../render/SDL_sysrender.h"
#include "SDL_syswm.h"
#include "SDL_winrtopengles.h"
#include "../../core/windows/SDL_windows.h"
}

#include "../../core/winrt/SDL_winrtapp_direct3d.h"
#include "../../core/winrt/SDL_winrtapp_xaml.h"
#include "SDL_winrtvideo_cpp.h"
#include "SDL_winrtevents_c.h"
#include "SDL_winrtgamebar_cpp.h"
#include "SDL_winrtmouse_c.h"
#include "SDL_main.h"
#include "SDL_system.h"


/* Initialization/Query functions */
static int WINRT_VideoInit(_THIS);
static int WINRT_InitModes(_THIS);
static int WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
static void WINRT_VideoQuit(_THIS);


/* Window functions */
static int WINRT_CreateWindow(_THIS, SDL_Window * window);
static void WINRT_SetWindowSize(_THIS, SDL_Window * window);
static void WINRT_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
static void WINRT_DestroyWindow(_THIS, SDL_Window * window);
static SDL_bool WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info);


/* Misc functions */
static ABI::Windows::System::Display::IDisplayRequest * WINRT_CreateDisplayRequest(_THIS);
extern void WINRT_SuspendScreenSaver(_THIS);


/* SDL-internal globals: */
SDL_Window * WINRT_GlobalSDLWindow = NULL;


/* WinRT driver bootstrap functions */

static void
WINRT_DeleteDevice(SDL_VideoDevice * device)
{
    if (device->driverdata) {
        SDL_VideoData * video_data = (SDL_VideoData *)device->driverdata;
        if (video_data->winrtEglWindow) {
            video_data->winrtEglWindow->Release();
        }
        SDL_free(video_data);
    }

    SDL_free(device);
}

static SDL_VideoDevice *
WINRT_CreateDevice(int devindex)
{
    SDL_VideoDevice *device;
    SDL_VideoData *data;

    /* Initialize all variables that we clean on shutdown */
    device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
    if (!device) {
        SDL_OutOfMemory();
        return (0);
    }

    data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
    if (!data) {
        SDL_OutOfMemory();
        SDL_free(device);
        return (0);
    }
    device->driverdata = data;

    /* Set the function pointers */
    device->VideoInit = WINRT_VideoInit;
    device->VideoQuit = WINRT_VideoQuit;
    device->CreateSDLWindow = WINRT_CreateWindow;
    device->SetWindowSize = WINRT_SetWindowSize;
    device->SetWindowFullscreen = WINRT_SetWindowFullscreen;
    device->DestroyWindow = WINRT_DestroyWindow;
    device->SetDisplayMode = WINRT_SetDisplayMode;
    device->PumpEvents = WINRT_PumpEvents;
    device->GetWindowWMInfo = WINRT_GetWindowWMInfo;
    device->SuspendScreenSaver = WINRT_SuspendScreenSaver;

#if NTDDI_VERSION >= NTDDI_WIN10
    device->HasScreenKeyboardSupport = WINRT_HasScreenKeyboardSupport;
    device->ShowScreenKeyboard = WINRT_ShowScreenKeyboard;
    device->HideScreenKeyboard = WINRT_HideScreenKeyboard;
    device->IsScreenKeyboardShown = WINRT_IsScreenKeyboardShown;
#endif

#ifdef SDL_VIDEO_OPENGL_EGL
    device->GL_LoadLibrary = WINRT_GLES_LoadLibrary;
    device->GL_GetProcAddress = WINRT_GLES_GetProcAddress;
    device->GL_UnloadLibrary = WINRT_GLES_UnloadLibrary;
    device->GL_CreateContext = WINRT_GLES_CreateContext;
    device->GL_MakeCurrent = WINRT_GLES_MakeCurrent;
    device->GL_SetSwapInterval = WINRT_GLES_SetSwapInterval;
    device->GL_GetSwapInterval = WINRT_GLES_GetSwapInterval;
    device->GL_SwapWindow = WINRT_GLES_SwapWindow;
    device->GL_DeleteContext = WINRT_GLES_DeleteContext;
#endif
    device->free = WINRT_DeleteDevice;

    return device;
}

#define WINRTVID_DRIVER_NAME "winrt"
VideoBootStrap WINRT_bootstrap = {
    WINRTVID_DRIVER_NAME, "SDL WinRT video driver",
    WINRT_CreateDevice
};

int
WINRT_VideoInit(_THIS)
{
    SDL_VideoData * driverdata = (SDL_VideoData *) _this->driverdata;
    if (WINRT_InitModes(_this) < 0) {
        return -1;
    }
    WINRT_InitMouse(_this);
    WINRT_InitTouch(_this);
    WINRT_InitGameBar(_this);
    if (driverdata) {
        /* Initialize screensaver-disabling support */
        driverdata->displayRequest = WINRT_CreateDisplayRequest(_this);
    }
    return 0;
}

extern "C"
Uint32 D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat);

static void
WINRT_DXGIModeToSDLDisplayMode(const DXGI_MODE_DESC * dxgiMode, SDL_DisplayMode * sdlMode)
{
    SDL_zerop(sdlMode);
    sdlMode->w = dxgiMode->Width;
    sdlMode->h = dxgiMode->Height;
    sdlMode->refresh_rate = dxgiMode->RefreshRate.Numerator / dxgiMode->RefreshRate.Denominator;
    sdlMode->format = D3D11_DXGIFormatToSDLPixelFormat(dxgiMode->Format);
}

static int
WINRT_AddDisplaysForOutput (_THIS, IDXGIAdapter1 * dxgiAdapter1, int outputIndex)
{
    HRESULT hr;
    IDXGIOutput * dxgiOutput = NULL;
    DXGI_OUTPUT_DESC dxgiOutputDesc;
    SDL_VideoDisplay display;
    char * displayName = NULL;
    UINT numModes;
    DXGI_MODE_DESC * dxgiModes = NULL;
    int functionResult = -1;        /* -1 for failure, 0 for success */
    DXGI_MODE_DESC modeToMatch, closestMatch;

    SDL_zero(display);

    hr = dxgiAdapter1->EnumOutputs(outputIndex, &dxgiOutput);
    if (FAILED(hr)) {
        if (hr != DXGI_ERROR_NOT_FOUND) {
            WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIAdapter1::EnumOutputs failed", hr);
        }
        goto done;
    }

    hr = dxgiOutput->GetDesc(&dxgiOutputDesc);
    if (FAILED(hr)) {
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::GetDesc failed", hr);
        goto done;
    }

    SDL_zero(modeToMatch);
    modeToMatch.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    modeToMatch.Width = (dxgiOutputDesc.DesktopCoordinates.right - dxgiOutputDesc.DesktopCoordinates.left);
    modeToMatch.Height = (dxgiOutputDesc.DesktopCoordinates.bottom - dxgiOutputDesc.DesktopCoordinates.top);
    hr = dxgiOutput->FindClosestMatchingMode(&modeToMatch, &closestMatch, NULL);
    if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) {
        /* DXGI_ERROR_NOT_CURRENTLY_AVAILABLE gets returned by IDXGIOutput::FindClosestMatchingMode
           when running under the Windows Simulator, which uses Remote Desktop (formerly known as Terminal
           Services) under the hood.  According to the MSDN docs for the similar function,
           IDXGIOutput::GetDisplayModeList, DXGI_ERROR_NOT_CURRENTLY_AVAILABLE is returned if and
           when an app is run under a Terminal Services session, hence the assumption.

           In this case, just add an SDL display mode, with approximated values.
        */
        SDL_DisplayMode mode;
        SDL_zero(mode);
        display.name = "Windows Simulator / Terminal Services Display";
        mode.w = (dxgiOutputDesc.DesktopCoordinates.right - dxgiOutputDesc.DesktopCoordinates.left);
        mode.h = (dxgiOutputDesc.DesktopCoordinates.bottom - dxgiOutputDesc.DesktopCoordinates.top);
        mode.format = DXGI_FORMAT_B8G8R8A8_UNORM;
        mode.refresh_rate = 0;  /* Display mode is unknown, so just fill in zero, as specified by SDL's header files */
        display.desktop_mode = mode;
        display.current_mode = mode;
        if ( ! SDL_AddDisplayMode(&display, &mode)) {
            goto done;
        }
    } else if (FAILED(hr)) {
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::FindClosestMatchingMode failed", hr);
        goto done;
    } else {
        displayName = WIN_StringToUTF8(dxgiOutputDesc.DeviceName);
        display.name = displayName;
        WINRT_DXGIModeToSDLDisplayMode(&closestMatch, &display.desktop_mode);
        display.current_mode = display.desktop_mode;

        hr = dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, NULL);
        if (FAILED(hr)) {
            if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) {
                // TODO, WinRT: make sure display mode(s) are added when using Terminal Services / Windows Simulator
            }
            WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::GetDisplayModeList [get mode list size] failed", hr);
            goto done;
        }

        dxgiModes = (DXGI_MODE_DESC *)SDL_calloc(numModes, sizeof(DXGI_MODE_DESC));
        if ( ! dxgiModes) {
            SDL_OutOfMemory();
            goto done;
        }

        hr = dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, dxgiModes);
        if (FAILED(hr)) {
            WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::GetDisplayModeList [get mode contents] failed", hr);
            goto done;
        }

        for (UINT i = 0; i < numModes; ++i) {
            SDL_DisplayMode sdlMode;
            WINRT_DXGIModeToSDLDisplayMode(&dxgiModes[i], &sdlMode);
            SDL_AddDisplayMode(&display, &sdlMode);
        }
    }

    if (SDL_AddVideoDisplay(&display, SDL_FALSE) < 0) {
        goto done;
    }

    functionResult = 0;     /* 0 for Success! */
done:
    if (dxgiModes) {
        SDL_free(dxgiModes);
    }
    if (dxgiOutput) {
        dxgiOutput->Release();
    }
    if (displayName) {
        SDL_free(displayName);
    }
    return functionResult;
}

static int
WINRT_AddDisplaysForAdapter (_THIS, IDXGIFactory2 * dxgiFactory2, int adapterIndex)
{
    HRESULT hr;
    IDXGIAdapter1 * dxgiAdapter1;

    hr = dxgiFactory2->EnumAdapters1(adapterIndex, &dxgiAdapter1);
    if (FAILED(hr)) {
        if (hr != DXGI_ERROR_NOT_FOUND) {
            WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory1::EnumAdapters1() failed", hr);
        }
        return -1;
    }

    for (int outputIndex = 0; ; ++outputIndex) {
        if (WINRT_AddDisplaysForOutput(_this, dxgiAdapter1, outputIndex) < 0) {
            /* HACK: The Windows App Certification Kit 10.0 can fail, when
               running the Store Apps' test, "Direct3D Feature Test".  The
               certification kit's error is:

               "Application App was not running at the end of the test. It likely crashed or was terminated for having become unresponsive."

               This was caused by SDL/WinRT's DXGI failing to report any
               outputs.  Attempts to get the 1st display-output from the
               1st display-adapter can fail, with IDXGIAdapter::EnumOutputs
               returning DXGI_ERROR_NOT_FOUND.  This could be a bug in Windows,
               the Windows App Certification Kit, or possibly in SDL/WinRT's
               display detection code.  Either way, try to detect when this
               happens, and use a hackish means to create a reasonable-as-possible
               'display mode'.  -- DavidL
            */
            if (adapterIndex == 0 && outputIndex == 0) {
                SDL_VideoDisplay display;
                SDL_DisplayMode mode;
#if SDL_WINRT_USE_APPLICATIONVIEW
                ApplicationView ^ appView = ApplicationView::GetForCurrentView();
#endif
                CoreWindow ^ coreWin = CoreWindow::GetForCurrentThread();
                SDL_zero(display);
                SDL_zero(mode);
                display.name = "DXGI Display-detection Workaround";

                /* HACK: ApplicationView's VisibleBounds property, appeared, via testing, to
                   give a better approximation of display-size, than did CoreWindow's
                   Bounds property, insofar that ApplicationView::VisibleBounds seems like
                   it will, at least some of the time, give the full display size (during the
                   failing test), whereas CoreWindow might not.  -- DavidL
                */

#if (NTDDI_VERSION >= NTDDI_WIN10) || (SDL_WINRT_USE_APPLICATIONVIEW && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
                mode.w = WINRT_DIPS_TO_PHYSICAL_PIXELS(appView->VisibleBounds.Width);
                mode.h = WINRT_DIPS_TO_PHYSICAL_PIXELS(appView->VisibleBounds.Height);
#else
                /* On platform(s) that do not support VisibleBounds, such as Windows 8.1,
                   fall back to CoreWindow's Bounds property.
                */
                mode.w = WINRT_DIPS_TO_PHYSICAL_PIXELS(coreWin->Bounds.Width);
                mode.h = WINRT_DIPS_TO_PHYSICAL_PIXELS(coreWin->Bounds.Height);
#endif

                mode.format = DXGI_FORMAT_B8G8R8A8_UNORM;
                mode.refresh_rate = 0;  /* Display mode is unknown, so just fill in zero, as specified by SDL's header files */
                display.desktop_mode = mode;
                display.current_mode = mode;
                if ((SDL_AddDisplayMode(&display, &mode) < 0) ||
                    (SDL_AddVideoDisplay(&display, SDL_FALSE) < 0))
                {
                    return SDL_SetError("Failed to apply DXGI Display-detection workaround");
                }
            }

            break;
        }
    }

    dxgiAdapter1->Release();
    return 0;
}

int
WINRT_InitModes(_THIS)
{
    /* HACK: Initialize a single display, for whatever screen the app's
         CoreApplicationView is on.
       TODO, WinRT: Try initializing multiple displays, one for each monitor.
         Appropriate WinRT APIs for this seem elusive, though.  -- DavidL
    */

    HRESULT hr;
    IDXGIFactory2 * dxgiFactory2 = NULL;

    hr = CreateDXGIFactory1(IID_IDXGIFactory2, (void **)&dxgiFactory2);
    if (FAILED(hr)) {
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", CreateDXGIFactory1() failed", hr);
        return -1;
    }

    for (int adapterIndex = 0; ; ++adapterIndex) {
        if (WINRT_AddDisplaysForAdapter(_this, dxgiFactory2, adapterIndex) < 0) {
            break;
        }
    }

    return 0;
}

static int
WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
{
    return 0;
}

void
WINRT_VideoQuit(_THIS)
{
    SDL_VideoData * driverdata = (SDL_VideoData *) _this->driverdata;
    if (driverdata && driverdata->displayRequest) {
        driverdata->displayRequest->Release();
        driverdata->displayRequest = NULL;
    }
    WINRT_QuitGameBar(_this);
    WINRT_QuitMouse(_this);
}

static const Uint32 WINRT_DetectableFlags =
    SDL_WINDOW_MAXIMIZED |
    SDL_WINDOW_FULLSCREEN_DESKTOP |
    SDL_WINDOW_SHOWN |
    SDL_WINDOW_HIDDEN |
    SDL_WINDOW_MOUSE_FOCUS;

extern "C" Uint32
WINRT_DetectWindowFlags(SDL_Window * window)
{
    Uint32 latestFlags = 0;
    SDL_WindowData * data = (SDL_WindowData *) window->driverdata;
    bool is_fullscreen = false;

#if SDL_WINRT_USE_APPLICATIONVIEW
    if (data->appView) {
        is_fullscreen = data->appView->IsFullScreen;
    }
#elif (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION == NTDDI_WIN8)
    is_fullscreen = true;
#endif

    if (data->coreWindow.Get()) {
        if (is_fullscreen) {
            SDL_VideoDisplay * display = SDL_GetDisplayForWindow(window);
            int w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width);
            int h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height);

#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION > NTDDI_WIN8)
            // On all WinRT platforms, except for WinPhone 8.0, rotate the
            // window size.  This is needed to properly calculate
            // fullscreen vs. maximized.
            const DisplayOrientations currentOrientation = WINRT_DISPLAY_PROPERTY(CurrentOrientation);
            switch (currentOrientation) {
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
                case DisplayOrientations::Landscape:
                case DisplayOrientations::LandscapeFlipped:
#else
                case DisplayOrientations::Portrait:
                case DisplayOrientations::PortraitFlipped:
#endif
                {
                    int tmp = w;
                    w = h;
                    h = tmp;
                } break;
            }
#endif

            if (display->desktop_mode.w != w || display->desktop_mode.h != h) {
                latestFlags |= SDL_WINDOW_MAXIMIZED;
            } else {
                latestFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
            }
        }

        if (data->coreWindow->Visible) {
            latestFlags |= SDL_WINDOW_SHOWN;
        } else {
            latestFlags |= SDL_WINDOW_HIDDEN;
        }

#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (NTDDI_VERSION < NTDDI_WINBLUE)
        // data->coreWindow->PointerPosition is not supported on WinPhone 8.0
        latestFlags |= SDL_WINDOW_MOUSE_FOCUS;
#else
        if (data->coreWindow->Visible && data->coreWindow->Bounds.Contains(data->coreWindow->PointerPosition)) {
            latestFlags |= SDL_WINDOW_MOUSE_FOCUS;
        }
#endif
    }

    return latestFlags;
}

// TODO, WinRT: consider removing WINRT_UpdateWindowFlags, and just calling WINRT_DetectWindowFlags as-appropriate (with appropriate calls to SDL_SendWindowEvent)
void
WINRT_UpdateWindowFlags(SDL_Window * window, Uint32 mask)
{
    mask &= WINRT_DetectableFlags;
    if (window) {
        Uint32 apply = WINRT_DetectWindowFlags(window);
        if ((apply & mask) & SDL_WINDOW_FULLSCREEN) {
            window->last_fullscreen_flags = window->flags;  // seems necessary to programmatically un-fullscreen, via SDL APIs
        }
        window->flags = (window->flags & ~mask) | (apply & mask);
    }
}

static bool
WINRT_IsCoreWindowActive(CoreWindow ^ coreWindow)
{
    /* WinRT does not appear to offer API(s) to determine window-activation state,
       at least not that I am aware of in Win8 - Win10.  As such, SDL tracks this
       itself, via window-activation events.
       
       If there *is* an API to track this, it should probably get used instead
       of the following hack (that uses "SDLHelperWindowActivationState").
         -- DavidL.
    */
    if (coreWindow->CustomProperties->HasKey("SDLHelperWindowActivationState")) {
        CoreWindowActivationState activationState = \
            safe_cast<CoreWindowActivationState>(coreWindow->CustomProperties->Lookup("SDLHelperWindowActivationState"));
        return (activationState != CoreWindowActivationState::Deactivated);
    }

    /* Assume that non-SDL tracked windows are active, although this should
       probably be avoided, if possible.
       
       This might not even be possible, in normal SDL use, at least as of
       this writing (Dec 22, 2015; via latest hg.libsdl.org/SDL clone)  -- DavidL
    */
    return true;
}

int
WINRT_CreateWindow(_THIS, SDL_Window * window)
{
    // Make sure that only one window gets created, at least until multimonitor
    // support is added.
    if (WINRT_GlobalSDLWindow != NULL) {
        SDL_SetError("WinRT only supports one window");
        return -1;
    }

    SDL_WindowData *data = new SDL_WindowData;  /* use 'new' here as SDL_WindowData may use WinRT/C++ types */
    if (!data) {
        SDL_OutOfMemory();
        return -1;
    }
    window->driverdata = data;
    data->sdlWindow = window;

    /* To note, when XAML support is enabled, access to the CoreWindow will not
       be possible, at least not via the SDL/XAML thread.  Attempts to access it
       from there will throw exceptions.  As such, the SDL_WindowData's
       'coreWindow' field will only be set (to a non-null value) if XAML isn't
       enabled.
    */
    if (!WINRT_XAMLWasEnabled) {
        data->coreWindow = CoreWindow::GetForCurrentThread();
#if SDL_WINRT_USE_APPLICATIONVIEW
        data->appView = ApplicationView::GetForCurrentView();
#endif
    }

    /* Make note of the requested window flags, before they start getting changed. */
    const Uint32 requestedFlags = window->flags;

#if SDL_VIDEO_OPENGL_EGL
    /* Setup the EGL surface, but only if OpenGL ES 2 was requested. */
    if (!(window->flags & SDL_WINDOW_OPENGL)) {
        /* OpenGL ES 2 wasn't requested.  Don't set up an EGL surface. */
        data->egl_surface = EGL_NO_SURFACE;
    } else {
        /* OpenGL ES 2 was reuqested.  Set up an EGL surface. */
        SDL_VideoData * video_data = (SDL_VideoData *)_this->driverdata;

        /* Call SDL_EGL_ChooseConfig and eglCreateWindowSurface directly,
         * rather than via SDL_EGL_CreateSurface, as older versions of
         * ANGLE/WinRT may require that a C++ object, ComPtr<IUnknown>,
         * be passed into eglCreateWindowSurface.
         */
        if (SDL_EGL_ChooseConfig(_this) != 0) {
            char buf[512];
            SDL_snprintf(buf, sizeof(buf), "SDL_EGL_ChooseConfig failed: %s", SDL_GetError());
            return SDL_SetError("%s", buf);
        }

        if (video_data->winrtEglWindow) {   /* ... is the 'old' version of ANGLE/WinRT being used? */
            /* Attempt to create a window surface using older versions of
             * ANGLE/WinRT:
             */
            Microsoft::WRL::ComPtr<IUnknown> cpp_winrtEglWindow = video_data->winrtEglWindow;
            data->egl_surface = ((eglCreateWindowSurface_Old_Function)_this->egl_data->eglCreateWindowSurface)(
                _this->egl_data->egl_display,
                _this->egl_data->egl_config,
                cpp_winrtEglWindow, NULL);
            if (data->egl_surface == NULL) {
                return SDL_EGL_SetError("unable to create EGL native-window surface", "eglCreateWindowSurface");
            }
        } else if (data->coreWindow.Get() != nullptr) {
            /* Attempt to create a window surface using newer versions of
             * ANGLE/WinRT:
             */
            IInspectable * coreWindowAsIInspectable = reinterpret_cast<IInspectable *>(data->coreWindow.Get());
            data->egl_surface = _this->egl_data->eglCreateWindowSurface(
                _this->egl_data->egl_display,
                _this->egl_data->egl_config,
                coreWindowAsIInspectable,
                NULL);
            if (data->egl_surface == NULL) {
                return SDL_EGL_SetError("unable to create EGL native-window surface", "eglCreateWindowSurface");
            }
        } else {
            return SDL_SetError("No supported means to create an EGL window surface are available");
        }
    }
#endif

    /* Determine as many flags dynamically, as possible. */
    window->flags =
        SDL_WINDOW_BORDERLESS |
        SDL_WINDOW_RESIZABLE;

#if SDL_VIDEO_OPENGL_EGL
    if (data->egl_surface) {
        window->flags |= SDL_WINDOW_OPENGL;
    }
#endif

    if (WINRT_XAMLWasEnabled) {
        /* TODO, WinRT: set SDL_Window size, maybe position too, from XAML control */
        window->x = 0;
        window->y = 0;
        window->flags |= SDL_WINDOW_SHOWN;
        SDL_SetMouseFocus(NULL);        // TODO: detect this
        SDL_SetKeyboardFocus(NULL);     // TODO: detect this
    } else {
        /* WinRT 8.x apps seem to live in an environment where the OS controls the
           app's window size, with some apps being fullscreen, depending on
           user choice of various things.  For now, just adapt the SDL_Window to
           whatever Windows set-up as the native-window's geometry.
        */
        window->x = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Left);
        window->y = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Top);
#if NTDDI_VERSION < NTDDI_WIN10
        /* On WinRT 8.x / pre-Win10, just use the size we were given. */
        window->w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width);
        window->h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height);
#else
        /* On Windows 10, we occasionally get control over window size.  For windowed
           mode apps, try this.
        */
        bool didSetSize = false;
        if (!(requestedFlags & SDL_WINDOW_FULLSCREEN)) {
            const Windows::Foundation::Size size(WINRT_PHYSICAL_PIXELS_TO_DIPS(window->w),
                                                 WINRT_PHYSICAL_PIXELS_TO_DIPS(window->h));
            didSetSize = data->appView->TryResizeView(size);
        }
        if (!didSetSize) {
            /* We either weren't able to set the window size, or a request for
               fullscreen was made.  Get window-size info from the OS.
            */
            window->w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width);
            window->h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height);
        }
#endif

        WINRT_UpdateWindowFlags(
            window,
            0xffffffff      /* Update any window flag(s) that WINRT_UpdateWindow can handle */
        );

        /* Try detecting if the window is active */
        bool isWindowActive = WINRT_IsCoreWindowActive(data->coreWindow.Get());
        if (isWindowActive) {
            SDL_SetKeyboardFocus(window);
        }
    }
 
    /* Make sure the WinRT app's IFramworkView can post events on
       behalf of SDL:
    */
    WINRT_GlobalSDLWindow = window;

    /* All done! */
    return 0;
}

void
WINRT_SetWindowSize(_THIS, SDL_Window * window)
{
#if NTDDI_VERSION >= NTDDI_WIN10
    SDL_WindowData * data = (SDL_WindowData *)window->driverdata;
    const Windows::Foundation::Size size(WINRT_PHYSICAL_PIXELS_TO_DIPS(window->w),
                                         WINRT_PHYSICAL_PIXELS_TO_DIPS(window->h));
    data->appView->TryResizeView(size); // TODO, WinRT: return failure (to caller?) from TryResizeView()
#endif
}

void
WINRT_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
{
#if NTDDI_VERSION >= NTDDI_WIN10
    SDL_WindowData * data = (SDL_WindowData *)window->driverdata;
    bool isWindowActive = WINRT_IsCoreWindowActive(data->coreWindow.Get());
    if (isWindowActive) {
        if (fullscreen) {
            if (!data->appView->IsFullScreenMode) {
                data->appView->TryEnterFullScreenMode();    // TODO, WinRT: return failure (to caller?) from TryEnterFullScreenMode()
            }
        } else {
            if (data->appView->IsFullScreenMode) {
                data->appView->ExitFullScreenMode();
            }
        }
    }
#endif
}


void
WINRT_DestroyWindow(_THIS, SDL_Window * window)
{
    SDL_WindowData * data = (SDL_WindowData *) window->driverdata;

    if (WINRT_GlobalSDLWindow == window) {
        WINRT_GlobalSDLWindow = NULL;
    }

    if (data) {
        // Delete the internal window data:
        delete data;
        data = NULL;
        window->driverdata = NULL;
    }
}

SDL_bool
WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
{
    SDL_WindowData * data = (SDL_WindowData *) window->driverdata;

    if (info->version.major <= SDL_MAJOR_VERSION) {
        info->subsystem = SDL_SYSWM_WINRT;
        info->info.winrt.window = reinterpret_cast<IInspectable *>(data->coreWindow.Get());
        return SDL_TRUE;
    } else {
        SDL_SetError("Application not compiled with SDL %d.%d",
                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
        return SDL_FALSE;
    }
    return SDL_FALSE;
}

static ABI::Windows::System::Display::IDisplayRequest *
WINRT_CreateDisplayRequest(_THIS)
{
    /* Setup a WinRT DisplayRequest object, usable for enabling/disabling screensaver requests */
    wchar_t *wClassName = L"Windows.System.Display.DisplayRequest";
    HSTRING hClassName;
    IActivationFactory *pActivationFactory = NULL;
    IInspectable * pDisplayRequestRaw = nullptr;
    ABI::Windows::System::Display::IDisplayRequest * pDisplayRequest = nullptr;
    HRESULT hr;

    hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName);
    if (FAILED(hr)) {
        goto done;
    }

    hr = Windows::Foundation::GetActivationFactory(hClassName, &pActivationFactory);
    if (FAILED(hr)) {
        goto done;
    }

    hr = pActivationFactory->ActivateInstance(&pDisplayRequestRaw);
    if (FAILED(hr)) {
        goto done;
    }

    hr = pDisplayRequestRaw->QueryInterface(IID_IDisplayRequest, (void **) &pDisplayRequest);
    if (FAILED(hr)) {
        goto done;
    }

done:
    if (pDisplayRequestRaw) {
        pDisplayRequestRaw->Release();
    }
    if (pActivationFactory) {
        pActivationFactory->Release();
    }
    if (hClassName) {
        ::WindowsDeleteString(hClassName);
    }

    return pDisplayRequest;
}

void
WINRT_SuspendScreenSaver(_THIS)
{
    SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata;
    if (driverdata && driverdata->displayRequest) {
        ABI::Windows::System::Display::IDisplayRequest * displayRequest = (ABI::Windows::System::Display::IDisplayRequest *) driverdata->displayRequest;
        if (_this->suspend_screensaver) {
            displayRequest->RequestActive();
        } else {
            displayRequest->RequestRelease();
        }
    }
}

#endif /* SDL_VIDEO_DRIVER_WINRT */

/* vi: set ts=4 sw=4 expandtab: */
