diff --git a/src/core/winrt/SDL_winrtapp_xaml.cpp b/src/core/winrt/SDL_winrtapp_xaml.cpp index 6c0aeabf4..5b129d142 100644 --- a/src/core/winrt/SDL_winrtapp_xaml.cpp +++ b/src/core/winrt/SDL_winrtapp_xaml.cpp @@ -1,160 +1,160 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2013 Sam Lantinga - - 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 -#include - -#if WINAPI_FAMILY == WINAPI_FAMILY_APP -#include -#endif - - -/* SDL includes */ -#include "../../SDL_internal.h" -#include "SDL.h" -#include "../../video/winrt/SDL_winrtevents_c.h" -#include "../../video/winrt/SDL_winrtvideo_cpp.h" -#include "SDL_winrtapp_common.h" -#include "SDL_winrtapp_xaml.h" - - - -/* SDL-internal globals: */ -SDL_bool WINRT_XAMLWasEnabled = SDL_FALSE; - -#if WINAPI_FAMILY == WINAPI_FAMILY_APP -extern "C" -ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative = NULL; -static Windows::Foundation::EventRegistrationToken WINRT_XAMLAppEventToken; -#endif - - -/* - * Input event handlers (XAML) - */ -#if WINAPI_FAMILY == WINAPI_FAMILY_APP - -static void -WINRT_OnPointerPressedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) -{ - WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); -} - -static void -WINRT_OnPointerMovedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) -{ - WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); -} - -static void -WINRT_OnPointerReleasedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) -{ - WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); -} - -static void -WINRT_OnPointerWheelChangedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) -{ - WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); -} - -#endif // WINAPI_FAMILY == WINAPI_FAMILY_APP - - -/* - * XAML-to-SDL Rendering Callback - */ -#if WINAPI_FAMILY == WINAPI_FAMILY_APP - -static void -WINRT_OnRenderViaXAML(_In_ Platform::Object^ sender, _In_ Platform::Object^ args) -{ - WINRT_CycleXAMLThread(); -} - -#endif // WINAPI_FAMILY == WINAPI_FAMILY_APP - - -/* - * SDL + XAML Initialization - */ - -int -SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void * backgroundPanelAsIInspectable) -{ -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - return SDL_SetError("XAML support is not yet available in Windows Phone."); -#else - // Declare C++/CX namespaces: - using namespace Platform; - using namespace Windows::Foundation; - using namespace Windows::UI::Core; - using namespace Windows::UI::Xaml; - using namespace Windows::UI::Xaml::Controls; - using namespace Windows::UI::Xaml::Input; - using namespace Windows::UI::Xaml::Media; - - // Make sure we have a valid XAML element (to draw onto): - if ( ! backgroundPanelAsIInspectable) { - return SDL_SetError("'backgroundPanelAsIInspectable' can't be NULL"); - } - - Platform::Object ^ backgroundPanel = reinterpret_cast((IInspectable *) backgroundPanelAsIInspectable); - SwapChainBackgroundPanel ^swapChainBackgroundPanel = dynamic_cast(backgroundPanel); - if ( ! swapChainBackgroundPanel) { - return SDL_SetError("An unknown or unsupported type of XAML control was specified."); - } - - // Setup event handlers: - swapChainBackgroundPanel->PointerPressed += ref new PointerEventHandler(WINRT_OnPointerPressedViaXAML); - swapChainBackgroundPanel->PointerReleased += ref new PointerEventHandler(WINRT_OnPointerReleasedViaXAML); - swapChainBackgroundPanel->PointerWheelChanged += ref new PointerEventHandler(WINRT_OnPointerWheelChangedViaXAML); - swapChainBackgroundPanel->PointerMoved += ref new PointerEventHandler(WINRT_OnPointerMovedViaXAML); - - // Setup for rendering: - IInspectable *panelInspectable = (IInspectable*) reinterpret_cast(swapChainBackgroundPanel); - panelInspectable->QueryInterface(__uuidof(ISwapChainBackgroundPanelNative), (void **)&WINRT_GlobalSwapChainBackgroundPanelNative); - - WINRT_XAMLAppEventToken = CompositionTarget::Rendering::add(ref new EventHandler(WINRT_OnRenderViaXAML)); - - // Make sure the app is ready to call the SDL-centric main() function: - WINRT_SDLAppEntryPoint = mainFunction; - SDL_SetMainReady(); - - // Make sure video-init knows that we're initializing XAML: - SDL_bool oldXAMLWasEnabledValue = WINRT_XAMLWasEnabled; - WINRT_XAMLWasEnabled = SDL_TRUE; - - // Make sure video modes are detected now, while we still have access to the WinRT - // CoreWindow. WinRT will not allow the app's CoreWindow to be accessed via the - // SDL/WinRT thread. - if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { - // SDL_InitSubSystem will, on error, set the SDL error. Let that propogate to - // the caller to here: - WINRT_XAMLWasEnabled = oldXAMLWasEnabledValue; - return -1; - } - - // All done, for now. - return 0; -#endif // WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP / else -} +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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 +#include + +#if WINAPI_FAMILY == WINAPI_FAMILY_APP +#include +#endif + + +/* SDL includes */ +#include "../../SDL_internal.h" +#include "SDL.h" +#include "../../video/winrt/SDL_winrtevents_c.h" +#include "../../video/winrt/SDL_winrtvideo_cpp.h" +#include "SDL_winrtapp_common.h" +#include "SDL_winrtapp_xaml.h" + + + +/* SDL-internal globals: */ +SDL_bool WINRT_XAMLWasEnabled = SDL_FALSE; + +#if WINAPI_FAMILY == WINAPI_FAMILY_APP +extern "C" +ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative = NULL; +static Windows::Foundation::EventRegistrationToken WINRT_XAMLAppEventToken; +#endif + + +/* + * Input event handlers (XAML) + */ +#if WINAPI_FAMILY == WINAPI_FAMILY_APP + +static void +WINRT_OnPointerPressedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +{ + WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); +} + +static void +WINRT_OnPointerMovedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +{ + WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); +} + +static void +WINRT_OnPointerReleasedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +{ + WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); +} + +static void +WINRT_OnPointerWheelChangedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +{ + WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); +} + +#endif // WINAPI_FAMILY == WINAPI_FAMILY_APP + + +/* + * XAML-to-SDL Rendering Callback + */ +#if WINAPI_FAMILY == WINAPI_FAMILY_APP + +static void +WINRT_OnRenderViaXAML(_In_ Platform::Object^ sender, _In_ Platform::Object^ args) +{ + WINRT_CycleXAMLThread(); +} + +#endif // WINAPI_FAMILY == WINAPI_FAMILY_APP + + +/* + * SDL + XAML Initialization + */ + +int +SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void * backgroundPanelAsIInspectable) +{ +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + return SDL_SetError("XAML support is not yet available in Windows Phone."); +#else + // Declare C++/CX namespaces: + using namespace Platform; + using namespace Windows::Foundation; + using namespace Windows::UI::Core; + using namespace Windows::UI::Xaml; + using namespace Windows::UI::Xaml::Controls; + using namespace Windows::UI::Xaml::Input; + using namespace Windows::UI::Xaml::Media; + + // Make sure we have a valid XAML element (to draw onto): + if ( ! backgroundPanelAsIInspectable) { + return SDL_SetError("'backgroundPanelAsIInspectable' can't be NULL"); + } + + Platform::Object ^ backgroundPanel = reinterpret_cast((IInspectable *) backgroundPanelAsIInspectable); + SwapChainBackgroundPanel ^swapChainBackgroundPanel = dynamic_cast(backgroundPanel); + if ( ! swapChainBackgroundPanel) { + return SDL_SetError("An unknown or unsupported type of XAML control was specified."); + } + + // Setup event handlers: + swapChainBackgroundPanel->PointerPressed += ref new PointerEventHandler(WINRT_OnPointerPressedViaXAML); + swapChainBackgroundPanel->PointerReleased += ref new PointerEventHandler(WINRT_OnPointerReleasedViaXAML); + swapChainBackgroundPanel->PointerWheelChanged += ref new PointerEventHandler(WINRT_OnPointerWheelChangedViaXAML); + swapChainBackgroundPanel->PointerMoved += ref new PointerEventHandler(WINRT_OnPointerMovedViaXAML); + + // Setup for rendering: + IInspectable *panelInspectable = (IInspectable*) reinterpret_cast(swapChainBackgroundPanel); + panelInspectable->QueryInterface(__uuidof(ISwapChainBackgroundPanelNative), (void **)&WINRT_GlobalSwapChainBackgroundPanelNative); + + WINRT_XAMLAppEventToken = CompositionTarget::Rendering::add(ref new EventHandler(WINRT_OnRenderViaXAML)); + + // Make sure the app is ready to call the SDL-centric main() function: + WINRT_SDLAppEntryPoint = mainFunction; + SDL_SetMainReady(); + + // Make sure video-init knows that we're initializing XAML: + SDL_bool oldXAMLWasEnabledValue = WINRT_XAMLWasEnabled; + WINRT_XAMLWasEnabled = SDL_TRUE; + + // Make sure video modes are detected now, while we still have access to the WinRT + // CoreWindow. WinRT will not allow the app's CoreWindow to be accessed via the + // SDL/WinRT thread. + if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { + // SDL_InitSubSystem will, on error, set the SDL error. Let that propogate to + // the caller to here: + WINRT_XAMLWasEnabled = oldXAMLWasEnabledValue; + return -1; + } + + // All done, for now. + return 0; +#endif // WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP / else +}