#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_WINRT
#include <roapi.h>
#include <windows.foundation.h>
#include <windows.system.h>
extern "C" {
#include "SDL_mouse.h"
#include "../SDL_sysvideo.h"
}
#include "SDL_winrtvideo_cpp.h"
static Platform::WeakReference WINRT_MainThreadDispatcher;
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;
};
static GUID IID_IGameBarStatics_ = { MAKELONG(0xA292, 0x1DB9), 0xCC78, 0x4173, { 0xBE, 0x45, 0xB6, 0x1E, 0x67, 0x28, 0x3E, 0xA7 } };
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)SDL_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) {
return;
}
gameBar = WINRT_GetGameBar();
if (!gameBar) {
return;
}
if (SUCCEEDED(gameBar->get_IsInputRedirected(&isInputRedirected))) {
if ( ! isInputRedirected) {
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) {
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