summaryrefslogtreecommitdiff
path: root/source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar.cpp
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-05-11 22:54:56 +0800
committerchai <chaifix@163.com>2019-05-11 22:54:56 +0800
commit9645be0af1b1d5cb0ad5892d5464e1b23c51b550 (patch)
tree129c716bed8e93312421c3adb2f8e7c4f811602d /source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar.cpp
Diffstat (limited to 'source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar.cpp')
-rw-r--r--source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar.cpp196
1 files changed, 196 insertions, 0 deletions
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: */