diff options
Diffstat (limited to 'source/3rd-party/SDL2/src/core/winrt')
6 files changed, 1237 insertions, 0 deletions
diff --git a/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_common.cpp b/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_common.cpp new file mode 100644 index 0000000..887b47e --- /dev/null +++ b/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_common.cpp @@ -0,0 +1,66 @@ +/* + 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" + +#include "SDL_system.h" +#include "SDL_winrtapp_direct3d.h" +#include "SDL_winrtapp_xaml.h" + +#include <wrl.h> + +int (*WINRT_SDLAppEntryPoint)(int, char **) = NULL; + +extern "C" DECLSPEC int +SDL_WinRTRunApp(int (*mainFunction)(int, char **), void * xamlBackgroundPanel) +{ + if (xamlBackgroundPanel) { + return SDL_WinRTInitXAMLApp(mainFunction, xamlBackgroundPanel); + } else { + if (FAILED(Windows::Foundation::Initialize(RO_INIT_MULTITHREADED))) { + return 1; + } + return SDL_WinRTInitNonXAMLApp(mainFunction); + } +} + + +extern "C" DECLSPEC SDL_WinRT_DeviceFamily +SDL_WinRTGetDeviceFamily() +{ +#if NTDDI_VERSION >= NTDDI_WIN10 /* !!! FIXME: I have no idea if this is the right test. This is a UWP API, I think. Older windows should...just return "mobile"? I don't know. --ryan. */ + Platform::String^ deviceFamily = Windows::System::Profile::AnalyticsInfo::VersionInfo->DeviceFamily; + + if (deviceFamily->Equals("Windows.Desktop")) + { + return SDL_WINRT_DEVICEFAMILY_DESKTOP; + } + else if (deviceFamily->Equals("Windows.Mobile")) + { + return SDL_WINRT_DEVICEFAMILY_MOBILE; + } + else if (deviceFamily->Equals("Windows.Xbox")) + { + return SDL_WINRT_DEVICEFAMILY_XBOX; + } +#endif + + return SDL_WINRT_DEVICEFAMILY_UNKNOWN; +}
\ No newline at end of file diff --git a/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_common.h b/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_common.h new file mode 100644 index 0000000..d68704c --- /dev/null +++ b/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_common.h @@ -0,0 +1,31 @@ +/* + 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_winrtapp_common_h_ +#define SDL_winrtapp_common_h_ + +/* A pointer to the app's C-style main() function (which is a different + function than the WinRT app's actual entry point). + */ +extern int (*WINRT_SDLAppEntryPoint)(int, char **); + +#endif // SDL_winrtapp_common_h_ diff --git a/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_direct3d.cpp b/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_direct3d.cpp new file mode 100644 index 0000000..6fa0bea --- /dev/null +++ b/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -0,0 +1,855 @@ +/* + 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" + +/* Standard C++11 includes */ +#include <functional> +#include <string> +#include <sstream> +using namespace std; + + +/* Windows includes */ +#include "ppltasks.h" +using namespace concurrency; +using namespace Windows::ApplicationModel; +using namespace Windows::ApplicationModel::Core; +using namespace Windows::ApplicationModel::Activation; +using namespace Windows::Devices::Input; +using namespace Windows::Graphics::Display; +using namespace Windows::Foundation; +using namespace Windows::System; +using namespace Windows::UI::Core; +using namespace Windows::UI::Input; + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +using namespace Windows::Phone::UI::Input; +#endif + + +/* SDL includes */ +extern "C" { +#include "SDL_assert.h" +#include "SDL_events.h" +#include "SDL_hints.h" +#include "SDL_log.h" +#include "SDL_main.h" +#include "SDL_stdinc.h" +#include "SDL_render.h" +#include "../../video/SDL_sysvideo.h" +//#include "../../SDL_hints_c.h" +#include "../../events/SDL_events_c.h" +#include "../../events/SDL_keyboard_c.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_windowevents_c.h" +#include "../../render/SDL_sysrender.h" +#include "../windows/SDL_windows.h" +} + +#include "../../video/winrt/SDL_winrtevents_c.h" +#include "../../video/winrt/SDL_winrtvideo_cpp.h" +#include "SDL_winrtapp_common.h" +#include "SDL_winrtapp_direct3d.h" + +#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED +/* Calling IDXGIDevice3::Trim on the active Direct3D 11.x device is necessary + * when Windows 8.1 apps are about to get suspended. + */ +extern "C" void D3D11_Trim(SDL_Renderer *); +#endif + + +// Compile-time debugging options: +// To enable, uncomment; to disable, comment them out. +//#define LOG_POINTER_EVENTS 1 +//#define LOG_WINDOW_EVENTS 1 +//#define LOG_ORIENTATION_EVENTS 1 + + +// HACK, DLudwig: record a reference to the global, WinRT 'app'/view. +// SDL/WinRT will use this throughout its code. +// +// TODO, WinRT: consider replacing SDL_WinRTGlobalApp with something +// non-global, such as something created inside +// SDL_InitSubSystem(SDL_INIT_VIDEO), or something inside +// SDL_CreateWindow(). +SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr; + +ref class SDLApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource +{ +public: + virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView(); +}; + +IFrameworkView^ SDLApplicationSource::CreateView() +{ + // TODO, WinRT: see if this function (CreateView) can ever get called + // more than once. For now, just prevent it from ever assigning + // SDL_WinRTGlobalApp more than once. + SDL_assert(!SDL_WinRTGlobalApp); + SDL_WinRTApp ^ app = ref new SDL_WinRTApp(); + if (!SDL_WinRTGlobalApp) + { + SDL_WinRTGlobalApp = app; + } + return app; +} + +int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **)) +{ + WINRT_SDLAppEntryPoint = mainFunction; + auto direct3DApplicationSource = ref new SDLApplicationSource(); + CoreApplication::Run(direct3DApplicationSource); + return 0; +} + +static void SDLCALL +WINRT_SetDisplayOrientationsPreference(void *userdata, const char *name, const char *oldValue, const char *newValue) +{ + SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0); + + /* HACK: prevent SDL from altering an app's .appxmanifest-set orientation + * from being changed on startup, by detecting when SDL_HINT_ORIENTATIONS + * is getting registered. + * + * TODO, WinRT: consider reading in an app's .appxmanifest file, and apply its orientation when 'newValue == NULL'. + */ + if ((oldValue == NULL) && (newValue == NULL)) { + return; + } + + // Start with no orientation flags, then add each in as they're parsed + // from newValue. + unsigned int orientationFlags = 0; + if (newValue) { + std::istringstream tokenizer(newValue); + while (!tokenizer.eof()) { + std::string orientationName; + std::getline(tokenizer, orientationName, ' '); + if (orientationName == "LandscapeLeft") { + orientationFlags |= (unsigned int) DisplayOrientations::LandscapeFlipped; + } else if (orientationName == "LandscapeRight") { + orientationFlags |= (unsigned int) DisplayOrientations::Landscape; + } else if (orientationName == "Portrait") { + orientationFlags |= (unsigned int) DisplayOrientations::Portrait; + } else if (orientationName == "PortraitUpsideDown") { + orientationFlags |= (unsigned int) DisplayOrientations::PortraitFlipped; + } + } + } + + // If no valid orientation flags were specified, use a reasonable set of defaults: + if (!orientationFlags) { + // TODO, WinRT: consider seeing if an app's default orientation flags can be found out via some API call(s). + orientationFlags = (unsigned int) ( \ + DisplayOrientations::Landscape | + DisplayOrientations::LandscapeFlipped | + DisplayOrientations::Portrait | + DisplayOrientations::PortraitFlipped); + } + + // Set the orientation/rotation preferences. Please note that this does + // not constitute a 100%-certain lock of a given set of possible + // orientations. According to Microsoft's documentation on WinRT [1] + // when a device is not capable of being rotated, Windows may ignore + // the orientation preferences, and stick to what the device is capable of + // displaying. + // + // [1] Documentation on the 'InitialRotationPreference' setting for a + // Windows app's manifest file describes how some orientation/rotation + // preferences may be ignored. See + // http://msdn.microsoft.com/en-us/library/windows/apps/hh700343.aspx + // for details. Microsoft's "Display orientation sample" also gives an + // outline of how Windows treats device rotation + // (http://code.msdn.microsoft.com/Display-Orientation-Sample-19a58e93). + WINRT_DISPLAY_PROPERTY(AutoRotationPreferences) = (DisplayOrientations) orientationFlags; +} + +static void +WINRT_ProcessWindowSizeChange() // TODO: Pass an SDL_Window-identifying thing into WINRT_ProcessWindowSizeChange() +{ + CoreWindow ^ coreWindow = CoreWindow::GetForCurrentThread(); + if (coreWindow) { + if (WINRT_GlobalSDLWindow) { + SDL_Window * window = WINRT_GlobalSDLWindow; + SDL_WindowData * data = (SDL_WindowData *) window->driverdata; + + int x = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Left); + int y = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Top); + 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) + /* WinPhone 8.0 always keeps its native window size in portrait, + regardless of orientation. This changes in WinPhone 8.1, + in which the native window's size changes along with + orientation. + + Attempt to emulate WinPhone 8.1's behavior on WinPhone 8.0, with + regards to window size. This fixes a rendering bug that occurs + when a WinPhone 8.0 app is rotated to either 90 or 270 degrees. + */ + const DisplayOrientations currentOrientation = WINRT_DISPLAY_PROPERTY(CurrentOrientation); + switch (currentOrientation) { + case DisplayOrientations::Landscape: + case DisplayOrientations::LandscapeFlipped: { + int tmp = w; + w = h; + h = tmp; + } break; + } +#endif + + const Uint32 latestFlags = WINRT_DetectWindowFlags(window); + if (latestFlags & SDL_WINDOW_MAXIMIZED) { + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0); + } else { + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0); + } + + WINRT_UpdateWindowFlags(window, SDL_WINDOW_FULLSCREEN_DESKTOP); + + /* The window can move during a resize event, such as when maximizing + or resizing from a corner */ + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h); + } + } +} + +SDL_WinRTApp::SDL_WinRTApp() : + m_windowClosed(false), + m_windowVisible(true) +{ +} + +void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView) +{ + applicationView->Activated += + ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &SDL_WinRTApp::OnAppActivated); + + CoreApplication::Suspending += + ref new EventHandler<SuspendingEventArgs^>(this, &SDL_WinRTApp::OnSuspending); + + CoreApplication::Resuming += + ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnResuming); + + CoreApplication::Exiting += + ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnExiting); + +#if NTDDI_VERSION >= NTDDI_WIN10 + /* HACK ALERT! Xbox One doesn't seem to detect gamepads unless something + gets registered to receive Win10's Windows.Gaming.Input.Gamepad.GamepadAdded + events. We'll register an event handler for these events here, to make + sure that gamepad detection works later on, if requested. + */ + Windows::Gaming::Input::Gamepad::GamepadAdded += + ref new Windows::Foundation::EventHandler<Windows::Gaming::Input::Gamepad^>( + this, &SDL_WinRTApp::OnGamepadAdded + ); +#endif +} + +#if NTDDI_VERSION > NTDDI_WIN8 +void SDL_WinRTApp::OnOrientationChanged(DisplayInformation^ sender, Object^ args) +#else +void SDL_WinRTApp::OnOrientationChanged(Object^ sender) +#endif +{ +#if LOG_ORIENTATION_EVENTS==1 + { + CoreWindow^ window = CoreWindow::GetForCurrentThread(); + if (window) { + SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, CoreWindow Bounds={%f,%f,%f,%f}\n", + __FUNCTION__, + WINRT_DISPLAY_PROPERTY(CurrentOrientation), + WINRT_DISPLAY_PROPERTY(NativeOrientation), + WINRT_DISPLAY_PROPERTY(AutoRotationPreferences), + window->Bounds.X, + window->Bounds.Y, + window->Bounds.Width, + window->Bounds.Height); + } else { + SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d\n", + __FUNCTION__, + WINRT_DISPLAY_PROPERTY(CurrentOrientation), + WINRT_DISPLAY_PROPERTY(NativeOrientation), + WINRT_DISPLAY_PROPERTY(AutoRotationPreferences)); + } + } +#endif + + WINRT_ProcessWindowSizeChange(); + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + // HACK: Make sure that orientation changes + // lead to the Direct3D renderer's viewport getting updated: + // + // For some reason, this doesn't seem to need to be done on Windows 8.x, + // even when going from Landscape to LandscapeFlipped. It only seems to + // be needed on Windows Phone, at least when I tested on my devices. + // I'm not currently sure why this is, but it seems to work fine. -- David L. + // + // TODO, WinRT: do more extensive research into why orientation changes on Win 8.x don't need D3D changes, or if they might, in some cases + SDL_Window * window = WINRT_GlobalSDLWindow; + if (window) { + SDL_WindowData * data = (SDL_WindowData *)window->driverdata; + int w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width); + int h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height); + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_SIZE_CHANGED, w, h); + } +#endif + +} + +void SDL_WinRTApp::SetWindow(CoreWindow^ window) +{ +#if LOG_WINDOW_EVENTS==1 + SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, window bounds={%f, %f, %f,%f}\n", + __FUNCTION__, + WINRT_DISPLAY_PROPERTY(CurrentOrientation), + WINRT_DISPLAY_PROPERTY(NativeOrientation), + WINRT_DISPLAY_PROPERTY(AutoRotationPreferences), + window->Bounds.X, + window->Bounds.Y, + window->Bounds.Width, + window->Bounds.Height); +#endif + + window->SizeChanged += + ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &SDL_WinRTApp::OnWindowSizeChanged); + + window->VisibilityChanged += + ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &SDL_WinRTApp::OnVisibilityChanged); + + window->Activated += + ref new TypedEventHandler<CoreWindow^, WindowActivatedEventArgs^>(this, &SDL_WinRTApp::OnWindowActivated); + + window->Closed += + ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &SDL_WinRTApp::OnWindowClosed); + +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP + window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0); +#endif + + window->PointerPressed += + ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerPressed); + + window->PointerMoved += + ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerMoved); + + window->PointerReleased += + ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerReleased); + + window->PointerEntered += + ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerEntered); + + window->PointerExited += + ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerExited); + + window->PointerWheelChanged += + ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerWheelChanged); + +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP + // Retrieves relative-only mouse movements: + Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved += + ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(this, &SDL_WinRTApp::OnMouseMoved); +#endif + + window->KeyDown += + ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyDown); + + window->KeyUp += + ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyUp); + + window->CharacterReceived += + ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(this, &SDL_WinRTApp::OnCharacterReceived); + +#if NTDDI_VERSION >= NTDDI_WIN10 + Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->BackRequested += + ref new EventHandler<BackRequestedEventArgs^>(this, &SDL_WinRTApp::OnBackButtonPressed); +#elif WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + HardwareButtons::BackPressed += + ref new EventHandler<BackPressedEventArgs^>(this, &SDL_WinRTApp::OnBackButtonPressed); +#endif + +#if NTDDI_VERSION > NTDDI_WIN8 + DisplayInformation::GetForCurrentView()->OrientationChanged += + ref new TypedEventHandler<Windows::Graphics::Display::DisplayInformation^, Object^>(this, &SDL_WinRTApp::OnOrientationChanged); +#else + DisplayProperties::OrientationChanged += + ref new DisplayPropertiesEventHandler(this, &SDL_WinRTApp::OnOrientationChanged); +#endif + + // Register the hint, SDL_HINT_ORIENTATIONS, with SDL. + // TODO, WinRT: see if an app's default orientation can be found out via WinRT API(s), then set the initial value of SDL_HINT_ORIENTATIONS accordingly. + SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference, NULL); + +#if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10) // for Windows 8/8.1/RT apps... (and not Phone apps) + // Make sure we know when a user has opened the app's settings pane. + // This is needed in order to display a privacy policy, which needs + // to be done for network-enabled apps, as per Windows Store requirements. + using namespace Windows::UI::ApplicationSettings; + SettingsPane::GetForCurrentView()->CommandsRequested += + ref new TypedEventHandler<SettingsPane^, SettingsPaneCommandsRequestedEventArgs^> + (this, &SDL_WinRTApp::OnSettingsPaneCommandsRequested); +#endif +} + +void SDL_WinRTApp::Load(Platform::String^ entryPoint) +{ +} + +void SDL_WinRTApp::Run() +{ + SDL_SetMainReady(); + if (WINRT_SDLAppEntryPoint) + { + // TODO, WinRT: pass the C-style main() a reasonably realistic + // representation of command line arguments. + int argc = 0; + char **argv = NULL; + WINRT_SDLAppEntryPoint(argc, argv); + } +} + +static bool IsSDLWindowEventPending(SDL_WindowEventID windowEventID) +{ + SDL_Event events[128]; + const int count = SDL_PeepEvents(events, sizeof(events)/sizeof(SDL_Event), SDL_PEEKEVENT, SDL_WINDOWEVENT, SDL_WINDOWEVENT); + for (int i = 0; i < count; ++i) { + if (events[i].window.event == windowEventID) { + return true; + } + } + return false; +} + +bool SDL_WinRTApp::ShouldWaitForAppResumeEvents() +{ + /* Don't wait if the app is visible: */ + if (m_windowVisible) { + return false; + } + + /* Don't wait until the window-hide events finish processing. + * Do note that if an app-suspend event is sent (as indicated + * by SDL_APP_WILLENTERBACKGROUND and SDL_APP_DIDENTERBACKGROUND + * events), then this code may be a moot point, as WinRT's + * own event pump (aka ProcessEvents()) will pause regardless + * of what we do here. This happens on Windows Phone 8, to note. + * Windows 8.x apps, on the other hand, may get a chance to run + * these. + */ + if (IsSDLWindowEventPending(SDL_WINDOWEVENT_HIDDEN)) { + return false; + } else if (IsSDLWindowEventPending(SDL_WINDOWEVENT_FOCUS_LOST)) { + return false; + } else if (IsSDLWindowEventPending(SDL_WINDOWEVENT_MINIMIZED)) { + return false; + } + + return true; +} + +void SDL_WinRTApp::PumpEvents() +{ + if (!m_windowClosed) { + if (!ShouldWaitForAppResumeEvents()) { + /* This is the normal way in which events should be pumped. + * 'ProcessAllIfPresent' will make ProcessEvents() process anywhere + * from zero to N events, and will then return. + */ + CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); + } else { + /* This style of event-pumping, with 'ProcessOneAndAllPending', + * will cause anywhere from one to N events to be processed. If + * at least one event is processed, the call will return. If + * no events are pending, then the call will wait until one is + * available, and will not return (to the caller) until this + * happens! This should only occur when the app is hidden. + */ + CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending); + } + } +} + +void SDL_WinRTApp::Uninitialize() +{ +} + +#if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10) +void SDL_WinRTApp::OnSettingsPaneCommandsRequested( + Windows::UI::ApplicationSettings::SettingsPane ^p, + Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args) +{ + using namespace Platform; + using namespace Windows::UI::ApplicationSettings; + using namespace Windows::UI::Popups; + + String ^privacyPolicyURL = nullptr; // a URL to an app's Privacy Policy + String ^privacyPolicyLabel = nullptr; // label/link text + const char *tmpHintValue = NULL; // SDL_GetHint-retrieved value, used immediately + wchar_t *tmpStr = NULL; // used for UTF8 to UCS2 conversion + + // Setup a 'Privacy Policy' link, if one is available (via SDL_GetHint): + tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_URL); + if (tmpHintValue && tmpHintValue[0] != '\0') { + // Convert the privacy policy's URL to UCS2: + tmpStr = WIN_UTF8ToString(tmpHintValue); + privacyPolicyURL = ref new String(tmpStr); + SDL_free(tmpStr); + + // Optionally retrieve custom label-text for the link. If this isn't + // available, a default value will be used instead. + tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_LABEL); + if (tmpHintValue && tmpHintValue[0] != '\0') { + tmpStr = WIN_UTF8ToString(tmpHintValue); + privacyPolicyLabel = ref new String(tmpStr); + SDL_free(tmpStr); + } else { + privacyPolicyLabel = ref new String(L"Privacy Policy"); + } + + // Register the link, along with a handler to be called if and when it is + // clicked: + auto cmd = ref new SettingsCommand(L"privacyPolicy", privacyPolicyLabel, + ref new UICommandInvokedHandler([=](IUICommand ^) { + Windows::System::Launcher::LaunchUriAsync(ref new Uri(privacyPolicyURL)); + })); + args->Request->ApplicationCommands->Append(cmd); + } +} +#endif // if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10) + +void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) +{ +#if LOG_WINDOW_EVENTS==1 + SDL_Log("%s, size={%f,%f}, bounds={%f,%f,%f,%f}, current orientation=%d, native orientation=%d, auto rot. pref=%d, WINRT_GlobalSDLWindow?=%s\n", + __FUNCTION__, + args->Size.Width, args->Size.Height, + sender->Bounds.X, sender->Bounds.Y, sender->Bounds.Width, sender->Bounds.Height, + WINRT_DISPLAY_PROPERTY(CurrentOrientation), + WINRT_DISPLAY_PROPERTY(NativeOrientation), + WINRT_DISPLAY_PROPERTY(AutoRotationPreferences), + (WINRT_GlobalSDLWindow ? "yes" : "no")); +#endif + + WINRT_ProcessWindowSizeChange(); +} + +void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) +{ +#if LOG_WINDOW_EVENTS==1 + SDL_Log("%s, visible?=%s, bounds={%f,%f,%f,%f}, WINRT_GlobalSDLWindow?=%s\n", + __FUNCTION__, + (args->Visible ? "yes" : "no"), + sender->Bounds.X, sender->Bounds.Y, + sender->Bounds.Width, sender->Bounds.Height, + (WINRT_GlobalSDLWindow ? "yes" : "no")); +#endif + + m_windowVisible = args->Visible; + if (WINRT_GlobalSDLWindow) { + SDL_bool wasSDLWindowSurfaceValid = WINRT_GlobalSDLWindow->surface_valid; + Uint32 latestWindowFlags = WINRT_DetectWindowFlags(WINRT_GlobalSDLWindow); + if (args->Visible) { + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_SHOWN, 0, 0); + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0); + if (latestWindowFlags & SDL_WINDOW_MAXIMIZED) { + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_MAXIMIZED, 0, 0); + } else { + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_RESTORED, 0, 0); + } + } else { + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_HIDDEN, 0, 0); + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0); + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0); + } + + // HACK: Prevent SDL's window-hide handling code, which currently + // triggers a fake window resize (possibly erronously), from + // marking the SDL window's surface as invalid. + // + // A better solution to this probably involves figuring out if the + // fake window resize can be prevented. + WINRT_GlobalSDLWindow->surface_valid = wasSDLWindowSurfaceValid; + } +} + +void SDL_WinRTApp::OnWindowActivated(CoreWindow^ sender, WindowActivatedEventArgs^ args) +{ +#if LOG_WINDOW_EVENTS==1 + SDL_Log("%s, WINRT_GlobalSDLWindow?=%s\n\n", + __FUNCTION__, + (WINRT_GlobalSDLWindow ? "yes" : "no")); +#endif + + /* There's no property in Win 8.x to tell whether a window is active or + not. [De]activation events are, however, sent to the app. We'll just + record those, in case the CoreWindow gets wrapped by an SDL_Window at + some future time. + */ + sender->CustomProperties->Insert("SDLHelperWindowActivationState", args->WindowActivationState); + + SDL_Window * window = WINRT_GlobalSDLWindow; + if (window) { + if (args->WindowActivationState != CoreWindowActivationState::Deactivated) { + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0); + if (SDL_GetKeyboardFocus() != window) { + SDL_SetKeyboardFocus(window); + } + + /* Send a mouse-motion event as appropriate. + This doesn't work when called from OnPointerEntered, at least + not in WinRT CoreWindow apps (as OnPointerEntered doesn't + appear to be called after window-reactivation, at least not + in Windows 10, Build 10586.3 (November 2015 update, non-beta). + + Don't do it on WinPhone 8.0 though, as CoreWindow's 'PointerPosition' + property isn't available. + */ +#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION >= NTDDI_WINBLUE) + Point cursorPos = WINRT_TransformCursorPosition(window, sender->PointerPosition, TransformToSDLWindowSize); + SDL_SendMouseMotion(window, 0, 0, (int)cursorPos.X, (int)cursorPos.Y); +#endif + + /* TODO, WinRT: see if the Win32 bugfix from https://hg.libsdl.org/SDL/rev/d278747da408 needs to be applied (on window activation) */ + //WIN_CheckAsyncMouseRelease(data); + + /* TODO, WinRT: implement clipboard support, if possible */ + ///* + // * FIXME: Update keyboard state + // */ + //WIN_CheckClipboardUpdate(data->videodata); + + // HACK: Resetting the mouse-cursor here seems to fix + // https://bugzilla.libsdl.org/show_bug.cgi?id=3217, whereby a + // WinRT app's mouse cursor may switch to Windows' 'wait' cursor, + // after a user alt-tabs back into a full-screened SDL app. + // This bug does not appear to reproduce 100% of the time. + // It may be a bug in Windows itself (v.10.0.586.36, as tested, + // and the most-recent as of this writing). + SDL_SetCursor(NULL); + } else { + if (SDL_GetKeyboardFocus() == window) { + SDL_SetKeyboardFocus(NULL); + } + } + } +} + +void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) +{ +#if LOG_WINDOW_EVENTS==1 + SDL_Log("%s\n", __FUNCTION__); +#endif + m_windowClosed = true; +} + +void SDL_WinRTApp::OnAppActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) +{ + CoreWindow::GetForCurrentThread()->Activate(); +} + +void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args) +{ + // Save app state asynchronously after requesting a deferral. Holding a deferral + // indicates that the application is busy performing suspending operations. Be + // aware that a deferral may not be held indefinitely. After about five seconds, + // the app will be forced to exit. + + // ... but first, let the app know it's about to go to the background. + // The separation of events may be important, given that the deferral + // runs in a separate thread. This'll make SDL_APP_WILLENTERBACKGROUND + // the only event among the two that runs in the main thread. Given + // that a few WinRT operations can only be done from the main thread + // (things that access the WinRT CoreWindow are one example of this), + // this could be important. + SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND); + + SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral(); + create_task([this, deferral]() + { + // Send an app did-enter-background event immediately to observers. + // CoreDispatcher::ProcessEvents, which is the backbone on which + // SDL_WinRTApp::PumpEvents is built, will not return to its caller + // once it sends out a suspend event. Any events posted to SDL's + // event queue won't get received until the WinRT app is resumed. + // SDL_AddEventWatch() may be used to receive app-suspend events on + // WinRT. + SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND); + + // Let the Direct3D 11 renderer prepare for the app to be backgrounded. + // This is necessary for Windows 8.1, possibly elsewhere in the future. + // More details at: http://msdn.microsoft.com/en-us/library/windows/apps/Hh994929.aspx +#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED + if (WINRT_GlobalSDLWindow) { + SDL_Renderer * renderer = SDL_GetRenderer(WINRT_GlobalSDLWindow); + if (renderer && (SDL_strcmp(renderer->info.name, "direct3d11") == 0)) { + D3D11_Trim(renderer); + } + } +#endif + + deferral->Complete(); + }); +} + +void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args) +{ + // Restore any data or state that was unloaded on suspend. By default, data + // and state are persisted when resuming from suspend. Note that these events + // do not occur if the app was previously terminated. + SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND); + SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND); +} + +void SDL_WinRTApp::OnExiting(Platform::Object^ sender, Platform::Object^ args) +{ + SDL_SendAppEvent(SDL_APP_TERMINATING); +} + +static void +WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint) +{ + Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint; + SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d\n", + header, + pt->Position.X, pt->Position.Y, + transformedPoint.X, transformedPoint.Y, + pt->Properties->MouseWheelDelta, + pt->FrameId, + pt->PointerId, + WINRT_GetSDLButtonForPointerPoint(pt)); +} + +void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); +#endif + + WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); +#endif + + WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); +#endif + + WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnPointerEntered(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer entered", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); +#endif + + WINRT_ProcessPointerEnteredEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnPointerExited(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer exited", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); +#endif + + WINRT_ProcessPointerExitedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); +#endif + + WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args) +{ + WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args); +} + +void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) +{ + WINRT_ProcessKeyDownEvent(args); +} + +void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) +{ + WINRT_ProcessKeyUpEvent(args); +} + +void SDL_WinRTApp::OnCharacterReceived(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CharacterReceivedEventArgs^ args) +{ + WINRT_ProcessCharacterReceivedEvent(args); +} + +template <typename BackButtonEventArgs> +static void WINRT_OnBackButtonPressed(BackButtonEventArgs ^ args) +{ + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_AC_BACK); + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_AC_BACK); + + if (SDL_GetHintBoolean(SDL_HINT_WINRT_HANDLE_BACK_BUTTON, SDL_FALSE)) { + args->Handled = true; + } +} + +#if NTDDI_VERSION >= NTDDI_WIN10 +void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ args) + +{ + WINRT_OnBackButtonPressed(args); +} +#elif WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args) + +{ + WINRT_OnBackButtonPressed(args); +} +#endif + +#if NTDDI_VERSION >= NTDDI_WIN10 +void SDL_WinRTApp::OnGamepadAdded(Platform::Object ^sender, Windows::Gaming::Input::Gamepad ^gamepad) +{ + /* HACK ALERT: Nothing needs to be done here, as this method currently + only exists to allow something to be registered with Win10's + GamepadAdded event, an operation that seems to be necessary to get + Xinput-based detection to work on Xbox One. + */ +} +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_direct3d.h b/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_direct3d.h new file mode 100644 index 0000000..7f52592 --- /dev/null +++ b/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_direct3d.h @@ -0,0 +1,92 @@ +/* + 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 <Windows.h> + +extern int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **)); + +ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFrameworkView +{ +public: + SDL_WinRTApp(); + + // IFrameworkView Methods. + virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView); + virtual void SetWindow(Windows::UI::Core::CoreWindow^ window); + virtual void Load(Platform::String^ entryPoint); + virtual void Run(); + virtual void Uninitialize(); + +internal: + // SDL-specific methods + void PumpEvents(); + +protected: + bool ShouldWaitForAppResumeEvents(); + + // Event Handlers. + +#if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10) // for Windows 8/8.1/RT apps... (and not Phone apps) + void OnSettingsPaneCommandsRequested( + Windows::UI::ApplicationSettings::SettingsPane ^p, + Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args); +#endif // if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10) + +#if NTDDI_VERSION > NTDDI_WIN8 + void OnOrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args); +#else + void OnOrientationChanged(Platform::Object^ sender); +#endif + void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args); + void OnLogicalDpiChanged(Platform::Object^ sender); + void OnAppActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args); + void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ args); + void OnResuming(Platform::Object^ sender, Platform::Object^ args); + void OnExiting(Platform::Object^ sender, Platform::Object^ args); + void OnWindowActivated(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowActivatedEventArgs^ args); + void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args); + void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args); + void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); + void OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); + void OnPointerWheelChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); + void OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); + void OnPointerEntered(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); + void OnPointerExited(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); + void OnMouseMoved(Windows::Devices::Input::MouseDevice^ mouseDevice, Windows::Devices::Input::MouseEventArgs^ args); + void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args); + void OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args); + void OnCharacterReceived(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CharacterReceivedEventArgs^ args); + +#if NTDDI_VERSION >= NTDDI_WIN10 + void OnBackButtonPressed(Platform::Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ args); +#elif WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args); +#endif + +#if NTDDI_VERSION >= NTDDI_WIN10 + void OnGamepadAdded(Platform::Object ^sender, Windows::Gaming::Input::Gamepad ^gamepad); +#endif + +private: + bool m_windowClosed; + bool m_windowVisible; +}; + +extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; diff --git a/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_xaml.cpp b/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_xaml.cpp new file mode 100644 index 0000000..7e2aac8 --- /dev/null +++ b/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_xaml.cpp @@ -0,0 +1,160 @@ +/* + 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 <agile.h> +#include <Windows.h> + +#if WINAPI_FAMILY == WINAPI_FAMILY_APP +#include <windows.ui.xaml.media.dxinterop.h> +#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<Object ^>((IInspectable *) backgroundPanelAsIInspectable); + SwapChainBackgroundPanel ^swapChainBackgroundPanel = dynamic_cast<SwapChainBackgroundPanel ^>(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<IInspectable*>(swapChainBackgroundPanel); + panelInspectable->QueryInterface(__uuidof(ISwapChainBackgroundPanelNative), (void **)&WINRT_GlobalSwapChainBackgroundPanelNative); + + WINRT_XAMLAppEventToken = CompositionTarget::Rendering::add(ref new EventHandler<Object^>(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 +} diff --git a/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_xaml.h b/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_xaml.h new file mode 100644 index 0000000..85b4305 --- /dev/null +++ b/source/3rd-party/SDL2/src/core/winrt/SDL_winrtapp_xaml.h @@ -0,0 +1,33 @@ +/* + 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_winrtapp_xaml_h_ +#define SDL_winrtapp_xaml_h_ + +#include "SDL_stdinc.h" + +#ifdef __cplusplus +extern SDL_bool WINRT_XAMLWasEnabled; +extern int SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void * backgroundPanelAsIInspectable); +#endif // ifdef __cplusplus + +#endif // SDL_winrtapp_xaml_h_ |