Atlas - SDL_winrtgamebar.cpp

Home / ext / SDL2 / src / video / winrt Lines: 1 | Size: 6635 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "../../SDL_internal.h" 22 23#if SDL_VIDEO_DRIVER_WINRT 24 25/* Windows includes */ 26#include <roapi.h> 27#include <windows.foundation.h> 28#include <EventToken.h> 29 30 31/* SDL includes */ 32extern "C" { 33#include "SDL_mouse.h" 34#include "../SDL_sysvideo.h" 35} 36#include "SDL_winrtvideo_cpp.h" 37 38 39/* Game Bar events can come in off the main thread. Use the following 40 WinRT CoreDispatcher to deal with them on SDL's thread. 41*/ 42static Platform::WeakReference WINRT_MainThreadDispatcher; 43 44 45/* Win10's initial SDK (the 10.0.10240.0 release) does not include references 46 to Game Bar APIs, as the Game Bar was released via Win10 10.0.10586.0. 47 48 Declare its WinRT/COM interface here, to allow compilation with earlier 49 Windows SDKs. 50*/ 51MIDL_INTERFACE("1DB9A292-CC78-4173-BE45-B61E67283EA7") 52IGameBarStatics_ : public IInspectable 53{ 54public: 55 virtual HRESULT STDMETHODCALLTYPE add_VisibilityChanged( 56 __FIEventHandler_1_IInspectable *handler, 57 Windows::Foundation::EventRegistrationToken *token) = 0; 58 59 virtual HRESULT STDMETHODCALLTYPE remove_VisibilityChanged( 60 Windows::Foundation::EventRegistrationToken token) = 0; 61 62 virtual HRESULT STDMETHODCALLTYPE add_IsInputRedirectedChanged( 63 __FIEventHandler_1_IInspectable *handler, 64 Windows::Foundation::EventRegistrationToken *token) = 0; 65 66 virtual HRESULT STDMETHODCALLTYPE remove_IsInputRedirectedChanged( 67 Windows::Foundation::EventRegistrationToken token) = 0; 68 69 virtual HRESULT STDMETHODCALLTYPE get_Visible( 70 boolean *value) = 0; 71 72 virtual HRESULT STDMETHODCALLTYPE get_IsInputRedirected( 73 boolean *value) = 0; 74}; 75 76/* Declare the game bar's COM GUID */ 77static GUID IID_IGameBarStatics_ = { MAKELONG(0xA292, 0x1DB9), 0xCC78, 0x4173, { 0xBE, 0x45, 0xB6, 0x1E, 0x67, 0x28, 0x3E, 0xA7 } }; 78 79/* Retrieves a pointer to the game bar, or NULL if it is not available. 80 If a pointer is returned, it's ->Release() method must be called 81 after the caller has finished using it. 82*/ 83static IGameBarStatics_ * 84WINRT_GetGameBar() 85{ 86 wchar_t *wClassName = L"Windows.Gaming.UI.GameBar"; 87 HSTRING hClassName; 88 IActivationFactory *pActivationFactory = NULL; 89 IGameBarStatics_ *pGameBar = NULL; 90 HRESULT hr; 91 92 hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName); 93 if (FAILED(hr)) { 94 goto done; 95 } 96 97 hr = Windows::Foundation::GetActivationFactory(hClassName, &pActivationFactory); 98 if (FAILED(hr)) { 99 goto done; 100 } 101 102 pActivationFactory->QueryInterface(IID_IGameBarStatics_, (void **) &pGameBar); 103 104done: 105 if (pActivationFactory) { 106 pActivationFactory->Release(); 107 } 108 if (hClassName) { 109 ::WindowsDeleteString(hClassName); 110 } 111 return pGameBar; 112} 113 114static void 115WINRT_HandleGameBarIsInputRedirected_MainThread() 116{ 117 IGameBarStatics_ *gameBar; 118 boolean isInputRedirected = 0; 119 if (!WINRT_MainThreadDispatcher) { 120 /* The game bar event handler has been deregistered! */ 121 return; 122 } 123 gameBar = WINRT_GetGameBar(); 124 if (!gameBar) { 125 /* Shouldn't happen, but just in case... */ 126 return; 127 } 128 if (SUCCEEDED(gameBar->get_IsInputRedirected(&isInputRedirected))) { 129 if ( ! isInputRedirected) { 130 /* Input-control is now back to the SDL app. Restore the cursor, 131 in case Windows does not (it does not in either Win10 132 10.0.10240.0 or 10.0.10586.0, maybe later version(s) too. 133 */ 134 SDL_Cursor *cursor = SDL_GetCursor(); 135 SDL_SetCursor(cursor); 136 } 137 } 138 gameBar->Release(); 139} 140 141static void 142WINRT_HandleGameBarIsInputRedirected_NonMainThread(Platform::Object ^ o1, Platform::Object ^o2) 143{ 144 Windows::UI::Core::CoreDispatcher ^dispatcher = WINRT_MainThreadDispatcher.Resolve<Windows::UI::Core::CoreDispatcher>(); 145 if (dispatcher) { 146 dispatcher->RunAsync( 147 Windows::UI::Core::CoreDispatcherPriority::Normal, 148 ref new Windows::UI::Core::DispatchedHandler(&WINRT_HandleGameBarIsInputRedirected_MainThread)); 149 } 150} 151 152void 153WINRT_InitGameBar(_THIS) 154{ 155 SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; 156 IGameBarStatics_ *gameBar = WINRT_GetGameBar(); 157 if (gameBar) { 158 /* GameBar.IsInputRedirected events can come in via something other than 159 the main/SDL thread. 160 161 Get a WinRT 'CoreDispatcher' that can be used to call back into the 162 SDL thread. 163 */ 164 WINRT_MainThreadDispatcher = Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher; 165 Windows::Foundation::EventHandler<Platform::Object ^> ^handler = \ 166 ref new Windows::Foundation::EventHandler<Platform::Object ^>(&WINRT_HandleGameBarIsInputRedirected_NonMainThread); 167 __FIEventHandler_1_IInspectable * pHandler = reinterpret_cast<__FIEventHandler_1_IInspectable *>(handler); 168 gameBar->add_IsInputRedirectedChanged(pHandler, &driverdata->gameBarIsInputRedirectedToken); 169 gameBar->Release(); 170 } 171} 172 173void 174WINRT_QuitGameBar(_THIS) 175{ 176 SDL_VideoData *driverdata; 177 IGameBarStatics_ *gameBar; 178 if (!_this || !_this->driverdata) { 179 return; 180 } 181 gameBar = WINRT_GetGameBar(); 182 if (!gameBar) { 183 return; 184 } 185 driverdata = (SDL_VideoData *)_this->driverdata; 186 if (driverdata->gameBarIsInputRedirectedToken.Value) { 187 gameBar->remove_IsInputRedirectedChanged(driverdata->gameBarIsInputRedirectedToken); 188 driverdata->gameBarIsInputRedirectedToken.Value = 0; 189 } 190 WINRT_MainThreadDispatcher = nullptr; 191 gameBar->Release(); 192} 193 194#endif /* SDL_VIDEO_DRIVER_WINRT */ 195 196/* vi: set ts=4 sw=4 expandtab: */ 197
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.