diff options
| author | chai <chaifix@163.com> | 2019-05-11 22:54:56 +0800 | 
|---|---|---|
| committer | chai <chaifix@163.com> | 2019-05-11 22:54:56 +0800 | 
| commit | 9645be0af1b1d5cb0ad5892d5464e1b23c51b550 (patch) | |
| tree | 129c716bed8e93312421c3adb2f8e7c4f811602d /source/3rd-party/SDL2/src/video/winrt | |
Diffstat (limited to 'source/3rd-party/SDL2/src/video/winrt')
14 files changed, 2938 insertions, 0 deletions
diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtevents.cpp b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtevents.cpp new file mode 100644 index 0000000..370e8c5 --- /dev/null +++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtevents.cpp @@ -0,0 +1,154 @@ +/* +  Simple DirectMedia Layer +  Copyright (C) 1997-2018 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 + +/* + * Windows includes: + */ +#include <Windows.h> +using namespace Windows::UI::Core; +using Windows::UI::Core::CoreCursor; + +/* + * SDL includes: + */ +#include "SDL_winrtevents_c.h" +#include "../../core/winrt/SDL_winrtapp_common.h" +#include "../../core/winrt/SDL_winrtapp_direct3d.h" +#include "../../core/winrt/SDL_winrtapp_xaml.h" +#include "SDL_assert.h" +#include "SDL_system.h" + +extern "C" { +#include "../../thread/SDL_systhread.h" +#include "../SDL_sysvideo.h" +#include "../../events/SDL_events_c.h" +} + + +/* Forward declarations */ +static void WINRT_YieldXAMLThread(); + + +/* Global event management */ + +void +WINRT_PumpEvents(_THIS) +{ +    if (SDL_WinRTGlobalApp) { +        SDL_WinRTGlobalApp->PumpEvents(); +    } else if (WINRT_XAMLWasEnabled) { +        WINRT_YieldXAMLThread(); +    } +} + + +/* XAML Thread management */ + +enum SDL_XAMLAppThreadState +{ +    ThreadState_NotLaunched = 0, +    ThreadState_Running, +    ThreadState_Yielding +}; + +static SDL_XAMLAppThreadState _threadState = ThreadState_NotLaunched; +static SDL_Thread * _XAMLThread = nullptr; +static SDL_mutex * _mutex = nullptr; +static SDL_cond * _cond = nullptr; + +static void +WINRT_YieldXAMLThread() +{ +    SDL_LockMutex(_mutex); +    SDL_assert(_threadState == ThreadState_Running); +    _threadState = ThreadState_Yielding; +    SDL_UnlockMutex(_mutex); + +    SDL_CondSignal(_cond); + +    SDL_LockMutex(_mutex); +    while (_threadState != ThreadState_Running) { +        SDL_CondWait(_cond, _mutex); +    } +    SDL_UnlockMutex(_mutex); +} + +static int +WINRT_XAMLThreadMain(void * userdata) +{ +    // TODO, WinRT: pass the C-style main() a reasonably realistic +    // representation of command line arguments. +    int argc = 0; +    char **argv = NULL; +    return WINRT_SDLAppEntryPoint(argc, argv); +} + +void +WINRT_CycleXAMLThread(void) +{ +    switch (_threadState) { +        case ThreadState_NotLaunched: +        { +            _cond = SDL_CreateCond(); + +            _mutex = SDL_CreateMutex(); +            _threadState = ThreadState_Running; +            _XAMLThread = SDL_CreateThreadInternal(WINRT_XAMLThreadMain, "SDL/XAML App Thread", 0, nullptr); + +            SDL_LockMutex(_mutex); +            while (_threadState != ThreadState_Yielding) { +                SDL_CondWait(_cond, _mutex); +            } +            SDL_UnlockMutex(_mutex); + +            break; +        } + +        case ThreadState_Running: +        { +            SDL_assert(false); +            break; +        } + +        case ThreadState_Yielding: +        { +            SDL_LockMutex(_mutex); +            SDL_assert(_threadState == ThreadState_Yielding); +            _threadState = ThreadState_Running; +            SDL_UnlockMutex(_mutex); + +            SDL_CondSignal(_cond); + +            SDL_LockMutex(_mutex); +            while (_threadState != ThreadState_Yielding) { +                SDL_CondWait(_cond, _mutex); +            } +            SDL_UnlockMutex(_mutex); +        } +    } +} + +#endif /* SDL_VIDEO_DRIVER_WINRT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtevents_c.h b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtevents_c.h new file mode 100644 index 0000000..8b346ec --- /dev/null +++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtevents_c.h @@ -0,0 +1,82 @@ +/* +  Simple DirectMedia Layer +  Copyright (C) 1997-2018 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_config.h" + +extern "C" { +#include "../SDL_sysvideo.h" +} + +/* + * Internal-use, C-style functions: + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern void WINRT_InitTouch(_THIS); +extern void WINRT_PumpEvents(_THIS); + +#ifdef __cplusplus +} +#endif + + +/* + * Internal-use, C++/CX functions: + */ +#ifdef __cplusplus_winrt + +/* Pointers (Mice, Touch, etc.) */ +typedef enum { +    NormalizeZeroToOne, +    TransformToSDLWindowSize +} WINRT_CursorNormalizationType; +extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window, +                                                                Windows::Foundation::Point rawPosition, +                                                                WINRT_CursorNormalizationType normalization); +extern Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt); +extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); +extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); +extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); +extern void WINRT_ProcessPointerEnteredEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); +extern void WINRT_ProcessPointerExitedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); +extern void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); +extern void WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args); + +/* Keyboard */ +extern void WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args); +extern void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args); +extern void WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^args); + +#if NTDDI_VERSION >= NTDDI_WIN10 +extern SDL_bool WINRT_HasScreenKeyboardSupport(_THIS); +extern void WINRT_ShowScreenKeyboard(_THIS, SDL_Window *window); +extern void WINRT_HideScreenKeyboard(_THIS, SDL_Window *window); +extern SDL_bool WINRT_IsScreenKeyboardShown(_THIS, SDL_Window *window); +#endif  // NTDDI_VERSION >= ... + +/* XAML Thread Management */ +extern void WINRT_CycleXAMLThread(void); + +#endif // ifdef __cplusplus_winrt + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar.cpp b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar.cpp new file mode 100644 index 0000000..9617111 --- /dev/null +++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar.cpp @@ -0,0 +1,196 @@ +/* +  Simple DirectMedia Layer +  Copyright (C) 1997-2018 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 + +/* Windows includes */ +#include <roapi.h> +#include <windows.foundation.h> +#include <EventToken.h> + + +/* SDL includes */ +extern "C" { +#include "SDL_mouse.h" +#include "../SDL_sysvideo.h" +} +#include "SDL_winrtvideo_cpp.h" + + +/* Game Bar events can come in off the main thread.  Use the following +   WinRT CoreDispatcher to deal with them on SDL's thread. +*/ +static Platform::WeakReference WINRT_MainThreadDispatcher; + + +/* Win10's initial SDK (the 10.0.10240.0 release) does not include references +   to Game Bar APIs, as the Game Bar was released via Win10 10.0.10586.0. + +   Declare its WinRT/COM interface here, to allow compilation with earlier +   Windows SDKs. +*/ +MIDL_INTERFACE("1DB9A292-CC78-4173-BE45-B61E67283EA7") +IGameBarStatics_ : public IInspectable +{ +public: +    virtual HRESULT STDMETHODCALLTYPE add_VisibilityChanged(  +        __FIEventHandler_1_IInspectable *handler, +        Windows::Foundation::EventRegistrationToken *token) = 0; +     +    virtual HRESULT STDMETHODCALLTYPE remove_VisibilityChanged(  +        Windows::Foundation::EventRegistrationToken token) = 0; +     +    virtual HRESULT STDMETHODCALLTYPE add_IsInputRedirectedChanged(  +        __FIEventHandler_1_IInspectable *handler, +        Windows::Foundation::EventRegistrationToken *token) = 0; +     +    virtual HRESULT STDMETHODCALLTYPE remove_IsInputRedirectedChanged(  +        Windows::Foundation::EventRegistrationToken token) = 0; +     +    virtual HRESULT STDMETHODCALLTYPE get_Visible(  +        boolean *value) = 0; +     +    virtual HRESULT STDMETHODCALLTYPE get_IsInputRedirected(  +        boolean *value) = 0; +}; + +/* Declare the game bar's COM GUID */ +static GUID IID_IGameBarStatics_ = { MAKELONG(0xA292, 0x1DB9), 0xCC78, 0x4173, { 0xBE, 0x45, 0xB6, 0x1E, 0x67, 0x28, 0x3E, 0xA7 } }; + +/* Retrieves a pointer to the game bar, or NULL if it is not available. +   If a pointer is returned, it's ->Release() method must be called +   after the caller has finished using it. +*/ +static IGameBarStatics_ * +WINRT_GetGameBar() +{ +    wchar_t *wClassName = L"Windows.Gaming.UI.GameBar"; +    HSTRING hClassName; +    IActivationFactory *pActivationFactory = NULL; +    IGameBarStatics_ *pGameBar = NULL; +    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; +    } + +    pActivationFactory->QueryInterface(IID_IGameBarStatics_, (void **) &pGameBar); + +done: +    if (pActivationFactory) { +        pActivationFactory->Release(); +    } +    if (hClassName) { +        ::WindowsDeleteString(hClassName); +    } +    return pGameBar; +} + +static void +WINRT_HandleGameBarIsInputRedirected_MainThread() +{ +    IGameBarStatics_ *gameBar; +    boolean isInputRedirected = 0; +    if (!WINRT_MainThreadDispatcher) { +        /* The game bar event handler has been deregistered! */ +        return; +    } +    gameBar = WINRT_GetGameBar(); +    if (!gameBar) { +        /* Shouldn't happen, but just in case... */ +        return; +    } +    if (SUCCEEDED(gameBar->get_IsInputRedirected(&isInputRedirected))) { +        if ( ! isInputRedirected) { +            /* Input-control is now back to the SDL app. Restore the cursor, +               in case Windows does not (it does not in either Win10 +               10.0.10240.0 or 10.0.10586.0, maybe later version(s) too. +            */ +            SDL_Cursor *cursor = SDL_GetCursor(); +            SDL_SetCursor(cursor); +        } +    } +    gameBar->Release(); +} + +static void +WINRT_HandleGameBarIsInputRedirected_NonMainThread(Platform::Object ^ o1, Platform::Object ^o2) +{ +    Windows::UI::Core::CoreDispatcher ^dispatcher = WINRT_MainThreadDispatcher.Resolve<Windows::UI::Core::CoreDispatcher>(); +    if (dispatcher) { +        dispatcher->RunAsync( +            Windows::UI::Core::CoreDispatcherPriority::Normal, +            ref new Windows::UI::Core::DispatchedHandler(&WINRT_HandleGameBarIsInputRedirected_MainThread)); +    } +} + +void +WINRT_InitGameBar(_THIS) +{ +    SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; +    IGameBarStatics_ *gameBar = WINRT_GetGameBar(); +    if (gameBar) { +        /* GameBar.IsInputRedirected events can come in via something other than +           the main/SDL thread. + +           Get a WinRT 'CoreDispatcher' that can be used to call back into the +           SDL thread. +        */ +        WINRT_MainThreadDispatcher = Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher; +        Windows::Foundation::EventHandler<Platform::Object ^> ^handler = \ +            ref new Windows::Foundation::EventHandler<Platform::Object ^>(&WINRT_HandleGameBarIsInputRedirected_NonMainThread); +        __FIEventHandler_1_IInspectable * pHandler = reinterpret_cast<__FIEventHandler_1_IInspectable *>(handler); +        gameBar->add_IsInputRedirectedChanged(pHandler, &driverdata->gameBarIsInputRedirectedToken); +        gameBar->Release(); +    } +} + +void +WINRT_QuitGameBar(_THIS) +{ +    SDL_VideoData *driverdata; +    IGameBarStatics_ *gameBar; +    if (!_this || !_this->driverdata) { +        return; +    } +    gameBar = WINRT_GetGameBar(); +    if (!gameBar) { +        return; +    } +    driverdata = (SDL_VideoData *)_this->driverdata; +    if (driverdata->gameBarIsInputRedirectedToken.Value) { +        gameBar->remove_IsInputRedirectedChanged(driverdata->gameBarIsInputRedirectedToken); +        driverdata->gameBarIsInputRedirectedToken.Value = 0; +    } +    WINRT_MainThreadDispatcher = nullptr; +    gameBar->Release(); +} + +#endif /* SDL_VIDEO_DRIVER_WINRT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar_cpp.h b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar_cpp.h new file mode 100644 index 0000000..a3e4777 --- /dev/null +++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar_cpp.h @@ -0,0 +1,35 @@ +/* +  Simple DirectMedia Layer +  Copyright (C) 1997-2018 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_config.h" + +#ifndef SDL_winrtgamebar_h_ +#define SDL_winrtgamebar_h_ + +#ifdef __cplusplus +/* These are exported as C++ functions, rather than C, to fix a compilation +   bug with MSVC 2013, for Windows 8.x builds. */ +extern void WINRT_InitGameBar(_THIS); +extern void WINRT_QuitGameBar(_THIS); +#endif + +#endif /* SDL_winrtgamebar_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtkeyboard.cpp b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtkeyboard.cpp new file mode 100644 index 0000000..34f2421 --- /dev/null +++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtkeyboard.cpp @@ -0,0 +1,430 @@ +/* +  Simple DirectMedia Layer +  Copyright (C) 1997-2018 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 + +/* Windows-specific includes */ +#include <Windows.h> +#include <agile.h> + + +/* SDL-specific includes */ +#include "SDL.h" +#include "SDL_winrtevents_c.h" + +extern "C" { +#include "../../events/scancodes_windows.h" +#include "../../events/SDL_keyboard_c.h" +} + + +static SDL_Scancode WinRT_Official_Keycodes[] = { +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.None -- 0 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.LeftButton -- 1 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.RightButton -- 2 */ +    SDL_SCANCODE_CANCEL,        /* VirtualKey.Cancel -- 3 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.MiddleButton -- 4 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.XButton1 -- 5 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.XButton2 -- 6 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 7 */ +    SDL_SCANCODE_BACKSPACE,     /* VirtualKey.Back -- 8 */ +    SDL_SCANCODE_TAB,           /* VirtualKey.Tab -- 9 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 10 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 11 */ +    SDL_SCANCODE_CLEAR,         /* VirtualKey.Clear -- 12 */ +    SDL_SCANCODE_RETURN,        /* VirtualKey.Enter -- 13 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 14 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 15 */ +    SDL_SCANCODE_LSHIFT,        /* VirtualKey.Shift -- 16 */ +    SDL_SCANCODE_LCTRL,         /* VirtualKey.Control -- 17 */ +    SDL_SCANCODE_MENU,          /* VirtualKey.Menu -- 18 */ +    SDL_SCANCODE_PAUSE,         /* VirtualKey.Pause -- 19 */ +    SDL_SCANCODE_CAPSLOCK,      /* VirtualKey.CapitalLock -- 20 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Kana or VirtualKey.Hangul -- 21 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 22 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Junja -- 23 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Final -- 24 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Hanja or VirtualKey.Kanji -- 25 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 26 */ +    SDL_SCANCODE_ESCAPE,        /* VirtualKey.Escape -- 27 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Convert -- 28 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.NonConvert -- 29 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Accept -- 30 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.ModeChange -- 31  (maybe SDL_SCANCODE_MODE ?) */ +    SDL_SCANCODE_SPACE,         /* VirtualKey.Space -- 32 */ +    SDL_SCANCODE_PAGEUP,        /* VirtualKey.PageUp -- 33 */ +    SDL_SCANCODE_PAGEDOWN,      /* VirtualKey.PageDown -- 34 */ +    SDL_SCANCODE_END,           /* VirtualKey.End -- 35 */ +    SDL_SCANCODE_HOME,          /* VirtualKey.Home -- 36 */ +    SDL_SCANCODE_LEFT,          /* VirtualKey.Left -- 37 */ +    SDL_SCANCODE_UP,            /* VirtualKey.Up -- 38 */ +    SDL_SCANCODE_RIGHT,         /* VirtualKey.Right -- 39 */ +    SDL_SCANCODE_DOWN,          /* VirtualKey.Down -- 40 */ +    SDL_SCANCODE_SELECT,        /* VirtualKey.Select -- 41 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Print -- 42  (maybe SDL_SCANCODE_PRINTSCREEN ?) */ +    SDL_SCANCODE_EXECUTE,       /* VirtualKey.Execute -- 43 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Snapshot -- 44 */ +    SDL_SCANCODE_INSERT,        /* VirtualKey.Insert -- 45 */ +    SDL_SCANCODE_DELETE,        /* VirtualKey.Delete -- 46 */ +    SDL_SCANCODE_HELP,          /* VirtualKey.Help -- 47 */ +    SDL_SCANCODE_0,             /* VirtualKey.Number0 -- 48 */ +    SDL_SCANCODE_1,             /* VirtualKey.Number1 -- 49 */ +    SDL_SCANCODE_2,             /* VirtualKey.Number2 -- 50 */ +    SDL_SCANCODE_3,             /* VirtualKey.Number3 -- 51 */ +    SDL_SCANCODE_4,             /* VirtualKey.Number4 -- 52 */ +    SDL_SCANCODE_5,             /* VirtualKey.Number5 -- 53 */ +    SDL_SCANCODE_6,             /* VirtualKey.Number6 -- 54 */ +    SDL_SCANCODE_7,             /* VirtualKey.Number7 -- 55 */ +    SDL_SCANCODE_8,             /* VirtualKey.Number8 -- 56 */ +    SDL_SCANCODE_9,             /* VirtualKey.Number9 -- 57 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 58 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 59 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 60 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 61 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 62 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 63 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 64 */ +    SDL_SCANCODE_A,             /* VirtualKey.A -- 65 */ +    SDL_SCANCODE_B,             /* VirtualKey.B -- 66 */ +    SDL_SCANCODE_C,             /* VirtualKey.C -- 67 */ +    SDL_SCANCODE_D,             /* VirtualKey.D -- 68 */ +    SDL_SCANCODE_E,             /* VirtualKey.E -- 69 */ +    SDL_SCANCODE_F,             /* VirtualKey.F -- 70 */ +    SDL_SCANCODE_G,             /* VirtualKey.G -- 71 */ +    SDL_SCANCODE_H,             /* VirtualKey.H -- 72 */ +    SDL_SCANCODE_I,             /* VirtualKey.I -- 73 */ +    SDL_SCANCODE_J,             /* VirtualKey.J -- 74 */ +    SDL_SCANCODE_K,             /* VirtualKey.K -- 75 */ +    SDL_SCANCODE_L,             /* VirtualKey.L -- 76 */ +    SDL_SCANCODE_M,             /* VirtualKey.M -- 77 */ +    SDL_SCANCODE_N,             /* VirtualKey.N -- 78 */ +    SDL_SCANCODE_O,             /* VirtualKey.O -- 79 */ +    SDL_SCANCODE_P,             /* VirtualKey.P -- 80 */ +    SDL_SCANCODE_Q,             /* VirtualKey.Q -- 81 */ +    SDL_SCANCODE_R,             /* VirtualKey.R -- 82 */ +    SDL_SCANCODE_S,             /* VirtualKey.S -- 83 */ +    SDL_SCANCODE_T,             /* VirtualKey.T -- 84 */ +    SDL_SCANCODE_U,             /* VirtualKey.U -- 85 */ +    SDL_SCANCODE_V,             /* VirtualKey.V -- 86 */ +    SDL_SCANCODE_W,             /* VirtualKey.W -- 87 */ +    SDL_SCANCODE_X,             /* VirtualKey.X -- 88 */ +    SDL_SCANCODE_Y,             /* VirtualKey.Y -- 89 */ +    SDL_SCANCODE_Z,             /* VirtualKey.Z -- 90 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.LeftWindows -- 91  (maybe SDL_SCANCODE_APPLICATION or SDL_SCANCODE_LGUI ?) */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.RightWindows -- 92  (maybe SDL_SCANCODE_APPLICATION or SDL_SCANCODE_RGUI ?) */ +    SDL_SCANCODE_APPLICATION,   /* VirtualKey.Application -- 93 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 94 */ +    SDL_SCANCODE_SLEEP,         /* VirtualKey.Sleep -- 95 */ +    SDL_SCANCODE_KP_0,          /* VirtualKey.NumberPad0 -- 96 */ +    SDL_SCANCODE_KP_1,          /* VirtualKey.NumberPad1 -- 97 */ +    SDL_SCANCODE_KP_2,          /* VirtualKey.NumberPad2 -- 98 */ +    SDL_SCANCODE_KP_3,          /* VirtualKey.NumberPad3 -- 99 */ +    SDL_SCANCODE_KP_4,          /* VirtualKey.NumberPad4 -- 100 */ +    SDL_SCANCODE_KP_5,          /* VirtualKey.NumberPad5 -- 101 */ +    SDL_SCANCODE_KP_6,          /* VirtualKey.NumberPad6 -- 102 */ +    SDL_SCANCODE_KP_7,          /* VirtualKey.NumberPad7 -- 103 */ +    SDL_SCANCODE_KP_8,          /* VirtualKey.NumberPad8 -- 104 */ +    SDL_SCANCODE_KP_9,          /* VirtualKey.NumberPad9 -- 105 */ +    SDL_SCANCODE_KP_MULTIPLY,   /* VirtualKey.Multiply -- 106 */ +    SDL_SCANCODE_KP_PLUS,       /* VirtualKey.Add -- 107 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Separator -- 108 */ +    SDL_SCANCODE_KP_MINUS,      /* VirtualKey.Subtract -- 109 */ +    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Decimal -- 110  (maybe SDL_SCANCODE_DECIMALSEPARATOR, SDL_SCANCODE_KP_DECIMAL, or SDL_SCANCODE_KP_PERIOD ?) */ +    SDL_SCANCODE_KP_DIVIDE,     /* VirtualKey.Divide -- 111 */ +    SDL_SCANCODE_F1,            /* VirtualKey.F1 -- 112 */ +    SDL_SCANCODE_F2,            /* VirtualKey.F2 -- 113 */ +    SDL_SCANCODE_F3,            /* VirtualKey.F3 -- 114 */ +    SDL_SCANCODE_F4,            /* VirtualKey.F4 -- 115 */ +    SDL_SCANCODE_F5,            /* VirtualKey.F5 -- 116 */ +    SDL_SCANCODE_F6,            /* VirtualKey.F6 -- 117 */ +    SDL_SCANCODE_F7,            /* VirtualKey.F7 -- 118 */ +    SDL_SCANCODE_F8,            /* VirtualKey.F8 -- 119 */ +    SDL_SCANCODE_F9,            /* VirtualKey.F9 -- 120 */ +    SDL_SCANCODE_F10,           /* VirtualKey.F10 -- 121 */ +    SDL_SCANCODE_F11,           /* VirtualKey.F11 -- 122 */ +    SDL_SCANCODE_F12,           /* VirtualKey.F12 -- 123 */ +    SDL_SCANCODE_F13,           /* VirtualKey.F13 -- 124 */ +    SDL_SCANCODE_F14,           /* VirtualKey.F14 -- 125 */ +    SDL_SCANCODE_F15,           /* VirtualKey.F15 -- 126 */ +    SDL_SCANCODE_F16,           /* VirtualKey.F16 -- 127 */ +    SDL_SCANCODE_F17,           /* VirtualKey.F17 -- 128 */ +    SDL_SCANCODE_F18,           /* VirtualKey.F18 -- 129 */ +    SDL_SCANCODE_F19,           /* VirtualKey.F19 -- 130 */ +    SDL_SCANCODE_F20,           /* VirtualKey.F20 -- 131 */ +    SDL_SCANCODE_F21,           /* VirtualKey.F21 -- 132 */ +    SDL_SCANCODE_F22,           /* VirtualKey.F22 -- 133 */ +    SDL_SCANCODE_F23,           /* VirtualKey.F23 -- 134 */ +    SDL_SCANCODE_F24,           /* VirtualKey.F24 -- 135 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 136 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 137 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 138 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 139 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 140 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 141 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 142 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 143 */ +    SDL_SCANCODE_NUMLOCKCLEAR,  /* VirtualKey.NumberKeyLock -- 144 */ +    SDL_SCANCODE_SCROLLLOCK,    /* VirtualKey.Scroll -- 145 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 146 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 147 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 148 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 149 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 150 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 151 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 152 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 153 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 154 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 155 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 156 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 157 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 158 */ +    SDL_SCANCODE_UNKNOWN,       /* -- 159 */ +    SDL_SCANCODE_LSHIFT,        /* VirtualKey.LeftShift -- 160 */ +    SDL_SCANCODE_RSHIFT,        /* VirtualKey.RightShift -- 161 */ +    SDL_SCANCODE_LCTRL,         /* VirtualKey.LeftControl -- 162 */ +    SDL_SCANCODE_RCTRL,         /* VirtualKey.RightControl -- 163 */ +    SDL_SCANCODE_MENU,          /* VirtualKey.LeftMenu -- 164 */ +    SDL_SCANCODE_MENU,          /* VirtualKey.RightMenu -- 165 */ +    SDL_SCANCODE_AC_BACK,       /* VirtualKey.GoBack -- 166 : The go back key. */ +    SDL_SCANCODE_AC_FORWARD,    /* VirtualKey.GoForward -- 167 : The go forward key. */ +    SDL_SCANCODE_AC_REFRESH,    /* VirtualKey.Refresh -- 168 : The refresh key. */ +    SDL_SCANCODE_AC_STOP,       /* VirtualKey.Stop -- 169 : The stop key. */ +    SDL_SCANCODE_AC_SEARCH,     /* VirtualKey.Search -- 170 : The search key. */ +    SDL_SCANCODE_AC_BOOKMARKS,  /* VirtualKey.Favorites -- 171 : The favorites key. */ +    SDL_SCANCODE_AC_HOME        /* VirtualKey.GoHome -- 172 : The go home key. */ +}; + +/* Attempt to translate a keycode that isn't listed in WinRT's VirtualKey enum. + */ +static SDL_Scancode +WINRT_TranslateUnofficialKeycode(int keycode) +{ +    switch (keycode) { +        case 173: return SDL_SCANCODE_MUTE;         /* VK_VOLUME_MUTE */ +        case 174: return SDL_SCANCODE_VOLUMEDOWN;   /* VK_VOLUME_DOWN */ +        case 175: return SDL_SCANCODE_VOLUMEUP;     /* VK_VOLUME_UP */ +        case 176: return SDL_SCANCODE_AUDIONEXT;    /* VK_MEDIA_NEXT_TRACK */ +        case 177: return SDL_SCANCODE_AUDIOPREV;    /* VK_MEDIA_PREV_TRACK */ +        // case 178: return ;                       /* VK_MEDIA_STOP */ +        case 179: return SDL_SCANCODE_AUDIOPLAY;    /* VK_MEDIA_PLAY_PAUSE */ +        case 180: return SDL_SCANCODE_MAIL;         /* VK_LAUNCH_MAIL */ +        case 181: return SDL_SCANCODE_MEDIASELECT;  /* VK_LAUNCH_MEDIA_SELECT */ +        // case 182: return ;                       /* VK_LAUNCH_APP1 */ +        case 183: return SDL_SCANCODE_CALCULATOR;   /* VK_LAUNCH_APP2 */ +        // case 184: return ;                       /* ... reserved ... */ +        // case 185: return ;                       /* ... reserved ... */ +        case 186: return SDL_SCANCODE_SEMICOLON;    /* VK_OEM_1, ';:' key on US standard keyboards */ +        case 187: return SDL_SCANCODE_EQUALS;       /* VK_OEM_PLUS */ +        case 188: return SDL_SCANCODE_COMMA;        /* VK_OEM_COMMA */ +        case 189: return SDL_SCANCODE_MINUS;        /* VK_OEM_MINUS */ +        case 190: return SDL_SCANCODE_PERIOD;       /* VK_OEM_PERIOD */ +        case 191: return SDL_SCANCODE_SLASH;        /* VK_OEM_2, '/?' key on US standard keyboards */ +        case 192: return SDL_SCANCODE_GRAVE;        /* VK_OEM_3, '`~' key on US standard keyboards */ +        // ? +        // ... reserved or unassigned ... +        // ? +        case 219: return SDL_SCANCODE_LEFTBRACKET;  /* VK_OEM_4, '[{' key on US standard keyboards */ +        case 220: return SDL_SCANCODE_BACKSLASH;    /* VK_OEM_5, '\|' key on US standard keyboards */ +        case 221: return SDL_SCANCODE_RIGHTBRACKET; /* VK_OEM_6, ']}' key on US standard keyboards */ +        case 222: return SDL_SCANCODE_APOSTROPHE;   /* VK_OEM_7, 'single/double quote' on US standard keyboards */ +        default: break; +    } +    return SDL_SCANCODE_UNKNOWN; +} + +static SDL_Scancode +WINRT_TranslateKeycode(int keycode, unsigned int nativeScancode) +{ +    // TODO, WinRT: try filling out the WinRT keycode table as much as possible, using the Win32 table for interpretation hints + +    SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; + +    /* HACK ALERT: At least one VirtualKey constant (Shift) with a left/right +     * designation might not get reported with its correct handedness, however +     * its hardware scan code can fill in the gaps.  If this is detected, +     * use the hardware scan code to try telling if the left, or the right +     * side's key was used. +     * +     * If Microsoft ever allows MapVirtualKey or MapVirtualKeyEx to be used +     * in WinRT apps, or something similar to these (it doesn't appear to be, +     * at least not for Windows [Phone] 8/8.1, as of Oct 24, 2014), then this +     * hack might become deprecated, or obsolete. +     */ +    if (nativeScancode < SDL_arraysize(windows_scancode_table)) { +        switch (keycode) { +            case 16:    // VirtualKey.Shift +                switch (windows_scancode_table[nativeScancode]) { +                    case SDL_SCANCODE_LSHIFT: +                    case SDL_SCANCODE_RSHIFT: +                        return windows_scancode_table[nativeScancode]; +                } +                break; +             +            // Add others, as necessary. +            // +            // Unfortunately, this hack doesn't seem to work in determining +            // handedness with Control keys. + +            default: +                break; +        } +    } + +    /* Try to get a documented, WinRT, 'VirtualKey' next (as documented at +       http://msdn.microsoft.com/en-us/library/windows/apps/windows.system.virtualkey.aspx ). +       If that fails, fall back to a Win32 virtual key. +       If that fails, attempt to fall back to a scancode-derived key. +    */ +    if (keycode < SDL_arraysize(WinRT_Official_Keycodes)) { +        scancode = WinRT_Official_Keycodes[keycode]; +    } +    if (scancode == SDL_SCANCODE_UNKNOWN) { +        scancode = WINRT_TranslateUnofficialKeycode(keycode); +    } +    if (scancode == SDL_SCANCODE_UNKNOWN) { +        if (nativeScancode < SDL_arraysize(windows_scancode_table)) { +            scancode = windows_scancode_table[nativeScancode]; +        } +    } +    /* +    if (scancode == SDL_SCANCODE_UNKNOWN) { +        SDL_Log("WinRT TranslateKeycode, unknown keycode=%d\n", (int)keycode); +    } +    */ +    return scancode; +} + +void +WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args) +{ +    SDL_Scancode sdlScancode = WINRT_TranslateKeycode((int)args->VirtualKey, args->KeyStatus.ScanCode); +#if 0 +    SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode); +    SDL_Log("key down, handled=%s, ext?=%s, released?=%s, menu key down?=%s, " +            "repeat count=%d, native scan code=0x%x, was down?=%s, vkey=%d, " +            "sdl scan code=%d (%s), sdl key code=%d (%s)\n", +        (args->Handled ? "1" : "0"), +        (args->KeyStatus.IsExtendedKey ? "1" : "0"), +        (args->KeyStatus.IsKeyReleased ? "1" : "0"), +        (args->KeyStatus.IsMenuKeyDown ? "1" : "0"), +        args->KeyStatus.RepeatCount, +        args->KeyStatus.ScanCode, +        (args->KeyStatus.WasKeyDown ? "1" : "0"), +        args->VirtualKey, +        sdlScancode, +        SDL_GetScancodeName(sdlScancode), +        keycode, +        SDL_GetKeyName(keycode)); +    //args->Handled = true; +#endif +    SDL_SendKeyboardKey(SDL_PRESSED, sdlScancode); +} + +void +WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args) +{ +    SDL_Scancode sdlScancode = WINRT_TranslateKeycode((int)args->VirtualKey, args->KeyStatus.ScanCode); +#if 0 +    SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode); +    SDL_Log("key up, handled=%s, ext?=%s, released?=%s, menu key down?=%s, " +            "repeat count=%d, native scan code=0x%x, was down?=%s, vkey=%d, " +            "sdl scan code=%d (%s), sdl key code=%d (%s)\n", +        (args->Handled ? "1" : "0"), +        (args->KeyStatus.IsExtendedKey ? "1" : "0"), +        (args->KeyStatus.IsKeyReleased ? "1" : "0"), +        (args->KeyStatus.IsMenuKeyDown ? "1" : "0"), +        args->KeyStatus.RepeatCount, +        args->KeyStatus.ScanCode, +        (args->KeyStatus.WasKeyDown ? "1" : "0"), +        args->VirtualKey, +        sdlScancode, +        SDL_GetScancodeName(sdlScancode), +        keycode, +        SDL_GetKeyName(keycode)); +    //args->Handled = true; +#endif +    SDL_SendKeyboardKey(SDL_RELEASED, sdlScancode); +} + +void +WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^args) +{ +    wchar_t src_ucs2[2]; +    char dest_utf8[16]; +    int result; + +    /* Setup src */ +    src_ucs2[0] = args->KeyCode; +    src_ucs2[1] = L'\0'; + +    /* Convert the text, then send an SDL_TEXTINPUT event. */ +    result = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)&src_ucs2, -1, (LPSTR)dest_utf8, sizeof(dest_utf8), NULL, NULL); +    if (result > 0) { +        SDL_SendKeyboardText(dest_utf8); +    } +} + + +#if NTDDI_VERSION >= NTDDI_WIN10 + +SDL_bool WINRT_HasScreenKeyboardSupport(_THIS) +{ +    return SDL_TRUE; +} + +void WINRT_ShowScreenKeyboard(_THIS, SDL_Window *window) +{ +    using namespace Windows::UI::ViewManagement; +    InputPane ^ inputPane = InputPane::GetForCurrentView(); +    if (inputPane) { +        inputPane->TryShow(); +    } +} + +void WINRT_HideScreenKeyboard(_THIS, SDL_Window *window) +{ +    using namespace Windows::UI::ViewManagement; +    InputPane ^ inputPane = InputPane::GetForCurrentView(); +    if (inputPane) { +        inputPane->TryHide(); +    } +} + +SDL_bool WINRT_IsScreenKeyboardShown(_THIS, SDL_Window *window) +{ +    using namespace Windows::UI::ViewManagement; +    InputPane ^ inputPane = InputPane::GetForCurrentView(); +    if (inputPane) { +        // dludwig@pobox.com: checking inputPane->Visible doesn't seem to detect visibility, +        //   at least not on the Windows Phone 10.0.10240.0 emulator.  Checking +        //   the size of inputPane->OccludedRect, however, does seem to work. +        Windows::Foundation::Rect rect = inputPane->OccludedRect; +        if (rect.Width > 0 && rect.Height > 0) { +            return SDL_TRUE; +        } +    } +    return SDL_FALSE; +} + +#endif  // NTDDI_VERSION >= ... + +#endif // SDL_VIDEO_DRIVER_WINRT diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmessagebox.cpp b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmessagebox.cpp new file mode 100644 index 0000000..3576a3f --- /dev/null +++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmessagebox.cpp @@ -0,0 +1,112 @@ +/* +  Simple DirectMedia Layer +  Copyright (C) 1997-2018 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 + +extern "C" { +#include "SDL_messagebox.h" +#include "../../core/windows/SDL_windows.h" +} + +#include "SDL_winrtevents_c.h" + +#include <windows.ui.popups.h> +using namespace Platform; +using namespace Windows::Foundation; +using namespace Windows::UI::Popups; + +static String ^ +WINRT_UTF8ToPlatformString(const char * str) +{ +    wchar_t * wstr = WIN_UTF8ToString(str); +    String ^ rtstr = ref new String(wstr); +    SDL_free(wstr); +    return rtstr; +} + +extern "C" int +WINRT_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ +#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (NTDDI_VERSION == NTDDI_WIN8) +    /* Sadly, Windows Phone 8 doesn't include the MessageDialog class that +     * Windows 8.x/RT does, even though MSDN's reference documentation for +     * Windows Phone 8 mentions it. +     *  +     * The .NET runtime on Windows Phone 8 does, however, include a +     * MessageBox class.  Perhaps this could be called, somehow? +     */ +    return SDL_SetError("SDL_messagebox support is not available for Windows Phone 8.0"); +#else +    SDL_VideoDevice *_this = SDL_GetVideoDevice(); + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +    const int maxbuttons = 2; +    const char * platform = "Windows Phone 8.1+"; +#else +    const int maxbuttons = 3; +    const char * platform = "Windows 8.x"; +#endif + +    if (messageboxdata->numbuttons > maxbuttons) { +        return SDL_SetError("WinRT's MessageDialog only supports %d buttons, at most, on %s. %d were requested.", +            maxbuttons, platform, messageboxdata->numbuttons); +    } + +    /* Build a MessageDialog object and its buttons */ +    MessageDialog ^ dialog = ref new MessageDialog(WINRT_UTF8ToPlatformString(messageboxdata->message)); +    dialog->Title = WINRT_UTF8ToPlatformString(messageboxdata->title); +    for (int i = 0; i < messageboxdata->numbuttons; ++i) { +        UICommand ^ button = ref new UICommand(WINRT_UTF8ToPlatformString(messageboxdata->buttons[i].text)); +        button->Id = safe_cast<IntPtr>(i); +        dialog->Commands->Append(button); +        if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) { +            dialog->CancelCommandIndex = i; +        } +        if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) { +            dialog->DefaultCommandIndex = i; +        } +    } + +    /* Display the MessageDialog, then wait for it to be closed */ +    /* TODO, WinRT: Find a way to redraw MessageDialog instances if a GPU device-reset occurs during the following event-loop */ +    auto operation = dialog->ShowAsync(); +    while (operation->Status == Windows::Foundation::AsyncStatus::Started) { +        WINRT_PumpEvents(_this); +    } + +    /* Retrieve results from the MessageDialog and process them accordingly */ +    if (operation->Status != Windows::Foundation::AsyncStatus::Completed) { +        return SDL_SetError("An unknown error occurred in displaying the WinRT MessageDialog"); +    } +    if (buttonid) { +        IntPtr results = safe_cast<IntPtr>(operation->GetResults()->Id); +        int clicked_index = results.ToInt32(); +        *buttonid = messageboxdata->buttons[clicked_index].buttonid; +    } +    return 0; +#endif /* if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP / else */ +} + +#endif /* SDL_VIDEO_DRIVER_WINRT */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmessagebox.h b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmessagebox.h new file mode 100644 index 0000000..204cf4a --- /dev/null +++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmessagebox.h @@ -0,0 +1,29 @@ +/* +  Simple DirectMedia Layer +  Copyright (C) 1997-2018 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 + +extern int WINRT_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +#endif /* SDL_VIDEO_DRIVER_WINRT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmouse.cpp b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmouse.cpp new file mode 100644 index 0000000..093a1b9 --- /dev/null +++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmouse.cpp @@ -0,0 +1,224 @@ +/* +  Simple DirectMedia Layer +  Copyright (C) 1997-2018 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 + +/* + * Windows includes: + */ +#include <Windows.h> +#include <windows.ui.core.h> +using namespace Windows::UI::Core; +using Windows::UI::Core::CoreCursor; + +/* + * SDL includes: + */ +extern "C" { +#include "SDL_assert.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_touch_c.h" +#include "../SDL_sysvideo.h" +#include "SDL_events.h" +#include "SDL_log.h" +} + +#include "../../core/winrt/SDL_winrtapp_direct3d.h" +#include "SDL_winrtvideo_cpp.h" +#include "SDL_winrtmouse_c.h" + + +extern "C" SDL_bool WINRT_UsingRelativeMouseMode = SDL_FALSE; + + +static SDL_Cursor * +WINRT_CreateSystemCursor(SDL_SystemCursor id) +{ +    SDL_Cursor *cursor; +    CoreCursorType cursorType = CoreCursorType::Arrow; + +    switch(id) +    { +    default: +        SDL_assert(0); +        return NULL; +    case SDL_SYSTEM_CURSOR_ARROW:     cursorType = CoreCursorType::Arrow; break; +    case SDL_SYSTEM_CURSOR_IBEAM:     cursorType = CoreCursorType::IBeam; break; +    case SDL_SYSTEM_CURSOR_WAIT:      cursorType = CoreCursorType::Wait; break; +    case SDL_SYSTEM_CURSOR_CROSSHAIR: cursorType = CoreCursorType::Cross; break; +    case SDL_SYSTEM_CURSOR_WAITARROW: cursorType = CoreCursorType::Wait; break; +    case SDL_SYSTEM_CURSOR_SIZENWSE:  cursorType = CoreCursorType::SizeNorthwestSoutheast; break; +    case SDL_SYSTEM_CURSOR_SIZENESW:  cursorType = CoreCursorType::SizeNortheastSouthwest; break; +    case SDL_SYSTEM_CURSOR_SIZEWE:    cursorType = CoreCursorType::SizeWestEast; break; +    case SDL_SYSTEM_CURSOR_SIZENS:    cursorType = CoreCursorType::SizeNorthSouth; break; +    case SDL_SYSTEM_CURSOR_SIZEALL:   cursorType = CoreCursorType::SizeAll; break; +    case SDL_SYSTEM_CURSOR_NO:        cursorType = CoreCursorType::UniversalNo; break; +    case SDL_SYSTEM_CURSOR_HAND:      cursorType = CoreCursorType::Hand; break; +    } + +    cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor)); +    if (cursor) { +        /* Create a pointer to a COM reference to a cursor.  The extra +           pointer is used (on top of the COM reference) to allow the cursor +           to be referenced by the SDL_cursor's driverdata field, which is +           a void pointer. +        */ +        CoreCursor ^* theCursor = new CoreCursor^(nullptr); +        *theCursor = ref new CoreCursor(cursorType, 0); +        cursor->driverdata = (void *) theCursor; +    } else { +        SDL_OutOfMemory(); +    } + +    return cursor; +} + +static SDL_Cursor * +WINRT_CreateDefaultCursor() +{ +    return WINRT_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); +} + +static void +WINRT_FreeCursor(SDL_Cursor * cursor) +{ +    if (cursor->driverdata) { +        CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata; +        *theCursor = nullptr;       // Release the COM reference to the CoreCursor +        delete theCursor;           // Delete the pointer to the COM reference +    } +    SDL_free(cursor); +} + +static int +WINRT_ShowCursor(SDL_Cursor * cursor) +{ +    // TODO, WinRT, XAML: make WINRT_ShowCursor work when XAML support is enabled. +    if ( ! CoreWindow::GetForCurrentThread()) { +        return 0; +    } + +    CoreWindow ^ coreWindow = CoreWindow::GetForCurrentThread(); +    if (cursor) { +        CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata; +        coreWindow->PointerCursor = *theCursor; +    } else { +        // HACK ALERT: TL;DR - Hiding the cursor in WinRT/UWP apps is weird, and +        //   a Win32-style cursor resource file must be directly included in apps, +        //   otherwise hiding the cursor will cause mouse-motion data to never be +        //   received. +        // +        // Here's the lengthy explanation: +        // +        // There are two ways to hide a cursor in WinRT/UWP apps. +        // Both involve setting the WinRT CoreWindow's (which is somewhat analogous +        // to a Win32 HWND) 'PointerCursor' property. +        // +        // The first way to hide a cursor sets PointerCursor to nullptr.  This +        // is, arguably, the easiest to implement for an app.  It does have an +        // unfortunate side-effect: it'll prevent mouse-motion events from being +        // sent to the app (via CoreWindow). +        // +        // The second way to hide a cursor sets PointerCursor to a transparent +        // cursor.  This allows mouse-motion events to be sent to the app, but is +        // more difficult to set up, as: +        //   1. WinRT/UWP, while providing a few stock cursors, does not provide +        //      a completely transparent cursor. +        //   2. WinRT/UWP allows apps to provide custom-built cursors, but *ONLY* +        //      if they are linked directly inside the app, via Win32-style +        //      cursor resource files.  APIs to create cursors at runtime are +        //      not provided to apps, and attempting to link-to or use Win32 +        //      cursor-creation APIs could cause an app to fail Windows Store +        //      certification. +        // +        // SDL can use either means of hiding the cursor.  It provides a Win32-style +        // set of cursor resource files in its source distribution, inside +        // src/main/winrt/.  If those files are linked to an SDL-for-WinRT/UWP app +        // (by including them in a MSVC project, for example), SDL will attempt to +        // use those, if and when the cursor is hidden via SDL APIs.  If those +        // files are not linked in, SDL will attempt to hide the cursor via the +        // 'set PointerCursor to nullptr' means (which, if you recall, causes +        // mouse-motion data to NOT be sent to the app!). +        // +        // Tech notes: +        //  - SDL's blank cursor resource uses a resource ID of 5000. +        //  - SDL's cursor resources consist of the following two files: +        //     - src/main/winrt/SDL2-WinRTResource_BlankCursor.cur -- cursor pixel data +        //     - src/main/winrt/SDL2-WinRTResources.rc             -- declares the cursor resource, and its ID (of 5000) +        // + +        const unsigned int win32CursorResourceID = 5000;   +        CoreCursor ^ blankCursor = ref new CoreCursor(CoreCursorType::Custom, win32CursorResourceID); + +        // Set 'PointerCursor' to 'blankCursor' in a way that shouldn't throw +        // an exception if the app hasn't loaded that resource. +        ABI::Windows::UI::Core::ICoreCursor * iblankCursor = reinterpret_cast<ABI::Windows::UI::Core::ICoreCursor *>(blankCursor); +        ABI::Windows::UI::Core::ICoreWindow * icoreWindow = reinterpret_cast<ABI::Windows::UI::Core::ICoreWindow *>(coreWindow); +        HRESULT hr = icoreWindow->put_PointerCursor(iblankCursor); +        if (FAILED(hr)) { +            // The app doesn't contain the cursor resource, or some other error +            // occurred.  Just use the other, but mouse-motion-preventing, means of +            // hiding the cursor. +            coreWindow->PointerCursor = nullptr; +        } +    } +    return 0; +} + +static int +WINRT_SetRelativeMouseMode(SDL_bool enabled) +{ +    WINRT_UsingRelativeMouseMode = enabled; +    return 0; +} + +void +WINRT_InitMouse(_THIS) +{ +    SDL_Mouse *mouse = SDL_GetMouse(); + +    /* DLudwig, Dec 3, 2012: WinRT does not currently provide APIs for +       the following features, AFAIK: +        - custom cursors  (multiple system cursors are, however, available) +        - programmatically moveable cursors +    */ + +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP +    //mouse->CreateCursor = WINRT_CreateCursor; +    mouse->CreateSystemCursor = WINRT_CreateSystemCursor; +    mouse->ShowCursor = WINRT_ShowCursor; +    mouse->FreeCursor = WINRT_FreeCursor; +    //mouse->WarpMouse = WINRT_WarpMouse; +    mouse->SetRelativeMouseMode = WINRT_SetRelativeMouseMode; + +    SDL_SetDefaultCursor(WINRT_CreateDefaultCursor()); +#endif +} + +void +WINRT_QuitMouse(_THIS) +{ +} + +#endif /* SDL_VIDEO_DRIVER_WINRT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmouse_c.h b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmouse_c.h new file mode 100644 index 0000000..22a80fc --- /dev/null +++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmouse_c.h @@ -0,0 +1,40 @@ +/* +  Simple DirectMedia Layer +  Copyright (C) 1997-2018 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_config.h" + +#ifndef SDL_winrtmouse_h_ +#define SDL_winrtmouse_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +extern void WINRT_InitMouse(_THIS); +extern void WINRT_QuitMouse(_THIS); +extern SDL_bool WINRT_UsingRelativeMouseMode; + +#ifdef __cplusplus +} +#endif + +#endif /* SDL_winrtmouse_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtopengles.cpp b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtopengles.cpp new file mode 100644 index 0000000..7874501 --- /dev/null +++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtopengles.cpp @@ -0,0 +1,203 @@ +/* +  Simple DirectMedia Layer +  Copyright (C) 1997-2018 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 && SDL_VIDEO_OPENGL_EGL + +/* EGL implementation of SDL OpenGL support */ + +#include "SDL_winrtvideo_cpp.h" +extern "C" { +#include "SDL_winrtopengles.h" +#include "SDL_loadso.h" +#include "../SDL_egl_c.h" +} + +/* Windows includes */ +#include <wrl/client.h> +using namespace Windows::UI::Core; + +/* ANGLE/WinRT constants */ +static const int ANGLE_D3D_FEATURE_LEVEL_ANY = 0; +#define EGL_PLATFORM_ANGLE_ANGLE                        0x3202 +#define EGL_PLATFORM_ANGLE_TYPE_ANGLE                   0x3203 +#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE      0x3204 +#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE      0x3205 +#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE             0x3208 +#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE            0x3209 +#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE       0x320B +#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE  0x320F + +#define EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER   0x320B + + +/* + * SDL/EGL top-level implementation + */ + +extern "C" int +WINRT_GLES_LoadLibrary(_THIS, const char *path) +{ +    SDL_VideoData *video_data = (SDL_VideoData *)_this->driverdata; + +    if (SDL_EGL_LoadLibrary(_this, path, EGL_DEFAULT_DISPLAY, 0) != 0) { +        return -1; +    } + +    /* Load ANGLE/WinRT-specific functions */ +    CreateWinrtEglWindow_Old_Function CreateWinrtEglWindow = (CreateWinrtEglWindow_Old_Function) SDL_LoadFunction(_this->egl_data->egl_dll_handle, "CreateWinrtEglWindow"); +    if (CreateWinrtEglWindow) { +        /* 'CreateWinrtEglWindow' was found, which means that an an older +         * version of ANGLE/WinRT is being used.  Continue setting up EGL, +         * as appropriate to this version of ANGLE. +         */ + +        /* Create an ANGLE/WinRT EGL-window */ +        /* TODO, WinRT: check for XAML usage before accessing the CoreWindow, as not doing so could lead to a crash */ +        CoreWindow ^ native_win = CoreWindow::GetForCurrentThread(); +        Microsoft::WRL::ComPtr<IUnknown> cpp_win = reinterpret_cast<IUnknown *>(native_win); +        HRESULT result = CreateWinrtEglWindow(cpp_win, ANGLE_D3D_FEATURE_LEVEL_ANY, &(video_data->winrtEglWindow)); +        if (FAILED(result)) { +            return -1; +        } + +        /* Call eglGetDisplay and eglInitialize as appropriate.  On other +         * platforms, this would probably get done by SDL_EGL_LoadLibrary, +         * however ANGLE/WinRT's current implementation (as of Mar 22, 2014) of +         * eglGetDisplay requires that a C++ object be passed into it, so the +         * call will be made in this file, a C++ file, instead. +         */ +        Microsoft::WRL::ComPtr<IUnknown> cpp_display = video_data->winrtEglWindow; +        _this->egl_data->egl_display = ((eglGetDisplay_Old_Function)_this->egl_data->eglGetDisplay)(cpp_display); +        if (!_this->egl_data->egl_display) { +            return SDL_EGL_SetError("Could not get Windows 8.0 EGL display", "eglGetDisplay"); +        } + +        if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) { +            return SDL_EGL_SetError("Could not initialize Windows 8.0 EGL", "eglInitialize"); +        } +    } else { +        /* Declare some ANGLE/EGL initialization property-sets, as suggested by +         * MSOpenTech's ANGLE-for-WinRT template apps: +         */ +        const EGLint defaultDisplayAttributes[] = +        { +            EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, +            EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, +            EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, +            EGL_NONE, +        }; + +        const EGLint fl9_3DisplayAttributes[] = +        { +            EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, +            EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9, +            EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3, +            EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, +            EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, +            EGL_NONE, +        }; + +        const EGLint warpDisplayAttributes[] = +        { +            EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, +            EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, +            EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, +            EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, +            EGL_NONE, +        }; + +        /* 'CreateWinrtEglWindow' was NOT found, which either means that a +         * newer version of ANGLE/WinRT is being used, or that we don't have +         * a valid copy of ANGLE. +         * +         * Try loading ANGLE as if it were the newer version. +         */ +        eglGetPlatformDisplayEXT_Function eglGetPlatformDisplayEXT = (eglGetPlatformDisplayEXT_Function)_this->egl_data->eglGetProcAddress("eglGetPlatformDisplayEXT"); +        if (!eglGetPlatformDisplayEXT) { +            return SDL_EGL_SetError("Could not retrieve ANGLE/WinRT display function(s)", "eglGetProcAddress"); +        } + +#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) +        /* Try initializing EGL at D3D11 Feature Level 10_0+ (which is not +         * supported on WinPhone 8.x. +         */ +        _this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes); +        if (!_this->egl_data->egl_display) { +            return SDL_EGL_SetError("Could not get EGL display for Direct3D 10_0+", "eglGetPlatformDisplayEXT"); +        } + +        if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) +#endif +        { +            /* Try initializing EGL at D3D11 Feature Level 9_3, in case the +             * 10_0 init fails, or we're on Windows Phone (which only supports +             * 9_3). +             */ +            _this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes); +            if (!_this->egl_data->egl_display) { +                return SDL_EGL_SetError("Could not get EGL display for Direct3D 9_3", "eglGetPlatformDisplayEXT"); +            } + +            if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) { +                /* Try initializing EGL at D3D11 Feature Level 11_0 on WARP +                 * (a Windows-provided, software rasterizer) if all else fails. +                 */ +                _this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes); +                if (!_this->egl_data->egl_display) { +                    return SDL_EGL_SetError("Could not get EGL display for Direct3D WARP", "eglGetPlatformDisplayEXT"); +                } + +                if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) { +                    return SDL_EGL_SetError("Could not initialize WinRT 8.x+ EGL", "eglInitialize"); +                } +            } +        } +    } + +    return 0; +} + +extern "C" void +WINRT_GLES_UnloadLibrary(_THIS) +{ +    SDL_VideoData *video_data = (SDL_VideoData *)_this->driverdata; + +    /* Release SDL's own COM reference to the ANGLE/WinRT IWinrtEglWindow */ +    if (video_data->winrtEglWindow) { +        video_data->winrtEglWindow->Release(); +        video_data->winrtEglWindow = nullptr; +    } + +    /* Perform the bulk of the unloading */ +    SDL_EGL_UnloadLibrary(_this); +} + +extern "C" { +SDL_EGL_CreateContext_impl(WINRT) +SDL_EGL_SwapWindow_impl(WINRT) +SDL_EGL_MakeCurrent_impl(WINRT) +} + +#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtopengles.h b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtopengles.h new file mode 100644 index 0000000..a222c2b --- /dev/null +++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtopengles.h @@ -0,0 +1,70 @@ +/* +  Simple DirectMedia Layer +  Copyright (C) 1997-2018 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_config.h" + +#ifndef SDL_winrtopengles_h_ +#define SDL_winrtopengles_h_ + +#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL + +#include "../SDL_sysvideo.h" +#include "../SDL_egl_c.h" + +/* OpenGLES functions */ +#define WINRT_GLES_GetAttribute SDL_EGL_GetAttribute +#define WINRT_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define WINRT_GLES_SetSwapInterval SDL_EGL_SetSwapInterval +#define WINRT_GLES_GetSwapInterval SDL_EGL_GetSwapInterval +#define WINRT_GLES_DeleteContext SDL_EGL_DeleteContext + +extern int WINRT_GLES_LoadLibrary(_THIS, const char *path); +extern void WINRT_GLES_UnloadLibrary(_THIS); +extern SDL_GLContext WINRT_GLES_CreateContext(_THIS, SDL_Window * window); +extern int WINRT_GLES_SwapWindow(_THIS, SDL_Window * window); +extern int WINRT_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); + + +#ifdef __cplusplus + +/* Typedefs for ANGLE/WinRT's C++-based native-display and native-window types, + * which are used when calling eglGetDisplay and eglCreateWindowSurface. + */ +typedef Microsoft::WRL::ComPtr<IUnknown> WINRT_EGLNativeWindowType_Old; + +/* Function pointer typedefs for 'old' ANGLE/WinRT's functions, which may + * require that C++ objects be passed in: + */ +typedef EGLDisplay (EGLAPIENTRY *eglGetDisplay_Old_Function)(WINRT_EGLNativeWindowType_Old); +typedef EGLSurface (EGLAPIENTRY *eglCreateWindowSurface_Old_Function)(EGLDisplay, EGLConfig, WINRT_EGLNativeWindowType_Old, const EGLint *); +typedef HRESULT (EGLAPIENTRY *CreateWinrtEglWindow_Old_Function)(Microsoft::WRL::ComPtr<IUnknown>, int, IUnknown ** result); + +#endif /* __cplusplus */ + +/* Function pointer typedefs for 'new' ANGLE/WinRT functions, which, unlike + * the old functions, do not require C++ support and work with plain C. + */ +typedef EGLDisplay (EGLAPIENTRY *eglGetPlatformDisplayEXT_Function)(EGLenum, void *, const EGLint *); + +#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */ + +#endif /* SDL_winrtopengles_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtpointerinput.cpp b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtpointerinput.cpp new file mode 100644 index 0000000..bc438f2 --- /dev/null +++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtpointerinput.cpp @@ -0,0 +1,415 @@ +/* +  Simple DirectMedia Layer +  Copyright (C) 1997-2018 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 + +/* SDL includes */ +#include "SDL_winrtevents_c.h" +#include "SDL_winrtmouse_c.h" +#include "SDL_winrtvideo_cpp.h" +#include "SDL_assert.h" +#include "SDL_system.h" + +extern "C" { +#include "../SDL_sysvideo.h" +#include "../../events/SDL_events_c.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_touch_c.h" +} + +/* File-specific globals: */ +static SDL_TouchID WINRT_TouchID = 1; +static unsigned int WINRT_LeftFingerDown = 0; + + +void +WINRT_InitTouch(_THIS) +{ +    SDL_AddTouch(WINRT_TouchID, ""); +} + + +// +// Applies necessary geometric transformations to raw cursor positions: +// +Windows::Foundation::Point +WINRT_TransformCursorPosition(SDL_Window * window, +                              Windows::Foundation::Point rawPosition, +                              WINRT_CursorNormalizationType normalization) +{ +    using namespace Windows::UI::Core; +    using namespace Windows::Graphics::Display; + +    if (!window) { +        return rawPosition; +    } + +    SDL_WindowData * windowData = (SDL_WindowData *) window->driverdata; +    if (windowData->coreWindow == nullptr) { +        // For some reason, the window isn't associated with a CoreWindow. +        // This might end up being the case as XAML support is extended. +        // For now, if there's no CoreWindow attached to the SDL_Window, +        // don't do any transforms. + +        // TODO, WinRT: make sure touch input coordinate ranges are correct when using XAML support +        return rawPosition; +    } + +    // The CoreWindow can only be accessed on certain thread(s). +    SDL_assert(CoreWindow::GetForCurrentThread() != nullptr); + +    CoreWindow ^ nativeWindow = windowData->coreWindow.Get(); +    Windows::Foundation::Point outputPosition; + +    // Compute coordinates normalized from 0..1. +    // If the coordinates need to be sized to the SDL window, +    // we'll do that after. +#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION > NTDDI_WIN8) +    outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width; +    outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height; +#else +    switch (WINRT_DISPLAY_PROPERTY(CurrentOrientation)) +    { +        case DisplayOrientations::Portrait: +            outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width; +            outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height; +            break; +        case DisplayOrientations::PortraitFlipped: +            outputPosition.X = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width); +            outputPosition.Y = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height); +            break; +        case DisplayOrientations::Landscape: +            outputPosition.X = rawPosition.Y / nativeWindow->Bounds.Height; +            outputPosition.Y = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width); +            break; +        case DisplayOrientations::LandscapeFlipped: +            outputPosition.X = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height); +            outputPosition.Y = rawPosition.X / nativeWindow->Bounds.Width; +            break; +        default: +            break; +    } +#endif + +    if (normalization == TransformToSDLWindowSize) { +        outputPosition.X *= ((float32) window->w); +        outputPosition.Y *= ((float32) window->h); +    } + +    return outputPosition; +} + +static inline int +_lround(float arg) +{ +    if (arg >= 0.0f) { +        return (int)floor(arg + 0.5f); +    } else { +        return (int)ceil(arg - 0.5f); +    } +} + +Uint8 +WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt) +{ +    using namespace Windows::UI::Input; + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +    return SDL_BUTTON_LEFT; +#else +    switch (pt->Properties->PointerUpdateKind) +    { +        case PointerUpdateKind::LeftButtonPressed: +        case PointerUpdateKind::LeftButtonReleased: +            return SDL_BUTTON_LEFT; + +        case PointerUpdateKind::RightButtonPressed: +        case PointerUpdateKind::RightButtonReleased: +            return SDL_BUTTON_RIGHT; + +        case PointerUpdateKind::MiddleButtonPressed: +        case PointerUpdateKind::MiddleButtonReleased: +            return SDL_BUTTON_MIDDLE; + +        case PointerUpdateKind::XButton1Pressed: +        case PointerUpdateKind::XButton1Released: +            return SDL_BUTTON_X1; + +        case PointerUpdateKind::XButton2Pressed: +        case PointerUpdateKind::XButton2Released: +            return SDL_BUTTON_X2; + +        default: +            break; +    } +#endif + +    return 0; +} + +//const char * +//WINRT_ConvertPointerUpdateKindToString(Windows::UI::Input::PointerUpdateKind kind) +//{ +//    using namespace Windows::UI::Input; +// +//    switch (kind) +//    { +//        case PointerUpdateKind::Other: +//            return "Other"; +//        case PointerUpdateKind::LeftButtonPressed: +//            return "LeftButtonPressed"; +//        case PointerUpdateKind::LeftButtonReleased: +//            return "LeftButtonReleased"; +//        case PointerUpdateKind::RightButtonPressed: +//            return "RightButtonPressed"; +//        case PointerUpdateKind::RightButtonReleased: +//            return "RightButtonReleased"; +//        case PointerUpdateKind::MiddleButtonPressed: +//            return "MiddleButtonPressed"; +//        case PointerUpdateKind::MiddleButtonReleased: +//            return "MiddleButtonReleased"; +//        case PointerUpdateKind::XButton1Pressed: +//            return "XButton1Pressed"; +//        case PointerUpdateKind::XButton1Released: +//            return "XButton1Released"; +//        case PointerUpdateKind::XButton2Pressed: +//            return "XButton2Pressed"; +//        case PointerUpdateKind::XButton2Released: +//            return "XButton2Released"; +//    } +// +//    return ""; +//} + +static bool +WINRT_IsTouchEvent(Windows::UI::Input::PointerPoint ^pointerPoint) +{ +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +    return true; +#else +    using namespace Windows::Devices::Input; +    switch (pointerPoint->PointerDevice->PointerDeviceType) { +        case PointerDeviceType::Touch: +        case PointerDeviceType::Pen: +            return true; +        default: +            return false; +    } +#endif +} + +void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ +    if (!window) { +        return; +    } + +    Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); + +    if ( ! WINRT_IsTouchEvent(pointerPoint)) { +        SDL_SendMouseButton(window, 0, SDL_PRESSED, button); +    } else { +        Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); +        Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize); + +        if (!WINRT_LeftFingerDown) { +            if (button) { +                SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, (int)windowPoint.X, (int)windowPoint.Y); +                SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_PRESSED, button); +            } + +            WINRT_LeftFingerDown = pointerPoint->PointerId; +        } + +        SDL_SendTouch( +            WINRT_TouchID, +            (SDL_FingerID) pointerPoint->PointerId, +            SDL_TRUE, +            normalizedPoint.X, +            normalizedPoint.Y, +            pointerPoint->Properties->Pressure); +    } +} + +void +WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ +    if (!window || WINRT_UsingRelativeMouseMode) { +        return; +    } + +    Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); +    Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize); + +    if ( ! WINRT_IsTouchEvent(pointerPoint)) { +        SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y); +    } else { +        if (pointerPoint->PointerId == WINRT_LeftFingerDown) { +            SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, (int)windowPoint.X, (int)windowPoint.Y); +        } + +        SDL_SendTouchMotion( +            WINRT_TouchID, +            (SDL_FingerID) pointerPoint->PointerId, +            normalizedPoint.X, +            normalizedPoint.Y, +            pointerPoint->Properties->Pressure); +    } +} + +void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ +    if (!window) { +        return; +    } + +    Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); + +    if (!WINRT_IsTouchEvent(pointerPoint)) { +        SDL_SendMouseButton(window, 0, SDL_RELEASED, button); +    } else { +        Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); + +        if (WINRT_LeftFingerDown == pointerPoint->PointerId) { +            if (button) { +                SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_RELEASED, button); +            } +            WINRT_LeftFingerDown = 0; +        } + +        SDL_SendTouch( +            WINRT_TouchID, +            (SDL_FingerID) pointerPoint->PointerId, +            SDL_FALSE, +            normalizedPoint.X, +            normalizedPoint.Y, +            pointerPoint->Properties->Pressure); +    } +} + +void WINRT_ProcessPointerEnteredEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ +    if (!window) { +        return; +    } + +    if (!WINRT_IsTouchEvent(pointerPoint)) { +        SDL_SetMouseFocus(window); +    } +} + +void WINRT_ProcessPointerExitedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ +    if (!window) { +        return; +    } + +    if (!WINRT_IsTouchEvent(pointerPoint)) { +        SDL_SetMouseFocus(NULL); +    } +} + +void +WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ +    if (!window) { +        return; +    } + +    float motion = (float) pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA; +    SDL_SendMouseWheel(window, 0, 0, (float) motion, SDL_MOUSEWHEEL_NORMAL); +} + +void +WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args) +{ +    if (!window || !WINRT_UsingRelativeMouseMode) { +        return; +    } + +    // DLudwig, 2012-12-28: On some systems, namely Visual Studio's Windows +    // Simulator, as well as Windows 8 in a Parallels 8 VM, MouseEventArgs' +    // MouseDelta field often reports very large values.  More information +    // on this can be found at the following pages on MSDN: +    //  - http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/a3c789fa-f1c5-49c4-9c0a-7db88d0f90f8 +    //  - https://connect.microsoft.com/VisualStudio/Feedback/details/756515 +    // +    // The values do not appear to be as large when running on some systems, +    // most notably a Surface RT.  Furthermore, the values returned by +    // CoreWindow's PointerMoved event, and sent to this class' OnPointerMoved +    // method, do not ever appear to be large, even when MouseEventArgs' +    // MouseDelta is reporting to the contrary. +    // +    // On systems with the large-values behavior, it appears that the values +    // get reported as if the screen's size is 65536 units in both the X and Y +    // dimensions.  This can be viewed by using Windows' now-private, "Raw Input" +    // APIs.  (GetRawInputData, RegisterRawInputDevices, WM_INPUT, etc.) +    // +    // MSDN's documentation on MouseEventArgs' MouseDelta field (at +    // http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.input.mouseeventargs.mousedelta ), +    // does not seem to indicate (to me) that its values should be so large.  It +    // says that its values should be a "change in screen location".  I could +    // be misinterpreting this, however a post on MSDN from a Microsoft engineer (see: +    // http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/09a9868e-95bb-4858-ba1a-cb4d2c298d62 ), +    // indicates that these values are in DIPs, which is the same unit used +    // by CoreWindow's PointerMoved events (via the Position field in its CurrentPoint +    // property.  See http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.input.pointerpoint.position.aspx +    // for details.) +    // +    // To note, PointerMoved events are sent a 'RawPosition' value (via the +    // CurrentPoint property in MouseEventArgs), however these do not seem +    // to exhibit the same large-value behavior. +    // +    // The values passed via PointerMoved events can't always be used for relative +    // mouse motion, unfortunately.  Its values are bound to the cursor's position, +    // which stops when it hits one of the screen's edges.  This can be a problem in +    // first person shooters, whereby it is normal for mouse motion to travel far +    // along any one axis for a period of time.  MouseMoved events do not have the +    // screen-bounding limitation, and can be used regardless of where the system's +    // cursor is. +    // +    // One possible workaround would be to programmatically set the cursor's +    // position to the screen's center (when SDL's relative mouse mode is enabled), +    // however WinRT does not yet seem to have the ability to set the cursor's +    // position via a public API.  Win32 did this via an API call, SetCursorPos, +    // however WinRT makes this function be private.  Apps that use it won't get +    // approved for distribution in the Windows Store.  I've yet to be able to find +    // a suitable, store-friendly counterpart for WinRT. +    // +    // There may be some room for a workaround whereby OnPointerMoved's values +    // are compared to the values from OnMouseMoved in order to detect +    // when this bug is active.  A suitable transformation could then be made to +    // OnMouseMoved's values.  For now, however, the system-reported values are sent +    // to SDL with minimal transformation: from native screen coordinates (in DIPs) +    // to SDL window coordinates. +    // +    const Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y); +    const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs, TransformToSDLWindowSize); +    SDL_SendMouseMotion( +        window, +        0, +        1, +        _lround(mouseDeltaInSDLWindowCoords.X), +        _lround(mouseDeltaInSDLWindowCoords.Y)); +} + +#endif // SDL_VIDEO_DRIVER_WINRT diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtvideo.cpp b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtvideo.cpp new file mode 100644 index 0000000..99bfd07 --- /dev/null +++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtvideo.cpp @@ -0,0 +1,842 @@ +/* +  Simple DirectMedia Layer +  Copyright (C) 1997-2018 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" +//#include "SDL_log.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 int +WINRT_Available(void) +{ +    return (1); +} + +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_Available, 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) < 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) < 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: */ diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtvideo_cpp.h b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtvideo_cpp.h new file mode 100644 index 0000000..91e967e --- /dev/null +++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtvideo_cpp.h @@ -0,0 +1,106 @@ +/* +  Simple DirectMedia Layer +  Copyright (C) 1997-2018 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. +*/ + +/* Windows includes: */ +#include <windows.h> +#ifdef __cplusplus_winrt +#include <agile.h> +#endif + +/* SDL includes: */ +#include "SDL_video.h" +#include "SDL_events.h" + +#if NTDDI_VERSION >= NTDDI_WINBLUE  /* ApplicationView's functionality only becomes +                                       useful for SDL in Win[Phone] 8.1 and up. +                                       Plus, it is not available at all in WinPhone 8.0. */ +#define SDL_WINRT_USE_APPLICATIONVIEW 1 +#endif + +extern "C" { +#include "../SDL_sysvideo.h" +#include "../SDL_egl_c.h" +} + +/* Private display data */ +typedef struct SDL_VideoData { +    /* An object created by ANGLE/WinRT (OpenGL ES 2 for WinRT) that gets +     * passed to eglGetDisplay and eglCreateWindowSurface: +     */ +    IUnknown *winrtEglWindow; + +    /* Event token(s), for unregistering WinRT event handler(s). +       These are just a struct with a 64-bit integer inside them +    */ +    Windows::Foundation::EventRegistrationToken gameBarIsInputRedirectedToken; + +    /* A WinRT DisplayRequest, used for implementing SDL_*ScreenSaver() functions. +     * This is really a pointer to a 'ABI::Windows::System::Display::IDisplayRequest *', +     * It's casted to 'IUnknown *', to help with building SDL. +    */ +    IUnknown *displayRequest; +} SDL_VideoData; + +/* The global, WinRT, SDL Window. +   For now, SDL/WinRT only supports one window (due to platform limitations of +   WinRT. +*/ +extern SDL_Window * WINRT_GlobalSDLWindow; + +/* Updates one or more SDL_Window flags, by querying the OS' native windowing APIs. +   SDL_Window flags that can be updated should be specified in 'mask'. +*/ +extern void WINRT_UpdateWindowFlags(SDL_Window * window, Uint32 mask); +extern "C" Uint32 WINRT_DetectWindowFlags(SDL_Window * window);  /* detects flags w/o applying them */ + +/* Display mode internals */ +//typedef struct +//{ +//    Windows::Graphics::Display::DisplayOrientations currentOrientation; +//} SDL_DisplayModeData; + +#ifdef __cplusplus_winrt + +/* A convenience macro to get a WinRT display property */ +#if NTDDI_VERSION > NTDDI_WIN8 +#define WINRT_DISPLAY_PROPERTY(NAME) (Windows::Graphics::Display::DisplayInformation::GetForCurrentView()->NAME) +#else +#define WINRT_DISPLAY_PROPERTY(NAME) (Windows::Graphics::Display::DisplayProperties::NAME) +#endif + +/* Converts DIPS to/from physical pixels */ +#define WINRT_DIPS_TO_PHYSICAL_PIXELS(DIPS)     ((int)(0.5f + (((float)(DIPS) * (float)WINRT_DISPLAY_PROPERTY(LogicalDpi)) / 96.f))) +#define WINRT_PHYSICAL_PIXELS_TO_DIPS(PHYSPIX)  (((float)(PHYSPIX) * 96.f)/WINRT_DISPLAY_PROPERTY(LogicalDpi)) + +/* Internal window data */ +struct SDL_WindowData +{ +    SDL_Window *sdlWindow; +    Platform::Agile<Windows::UI::Core::CoreWindow> coreWindow; +#ifdef SDL_VIDEO_OPENGL_EGL +    EGLSurface egl_surface; +#endif +#if SDL_WINRT_USE_APPLICATIONVIEW +    Windows::UI::ViewManagement::ApplicationView ^ appView; +#endif +}; + +#endif // ifdef __cplusplus_winrt  | 
