21 #include "../../SDL_internal.h"
32 using namespace concurrency;
33 using namespace Windows::ApplicationModel;
34 using namespace Windows::ApplicationModel::Core;
35 using namespace Windows::ApplicationModel::Activation;
36 using namespace Windows::Devices::Input;
37 using namespace Windows::Graphics::Display;
38 using namespace Windows::Foundation;
39 using namespace Windows::System;
40 using namespace Windows::UI::Core;
41 using namespace Windows::UI::Input;
43 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
44 using namespace Windows::Phone::UI::Input;
57 #include "../../video/SDL_sysvideo.h"
59 #include "../../events/SDL_events_c.h"
60 #include "../../events/SDL_keyboard_c.h"
61 #include "../../events/SDL_mouse_c.h"
62 #include "../../events/SDL_windowevents_c.h"
63 #include "../../render/SDL_sysrender.h"
64 #include "../windows/SDL_windows.h"
67 #include "../../video/winrt/SDL_winrtevents_c.h"
68 #include "../../video/winrt/SDL_winrtvideo_cpp.h"
72 #if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED
96 ref class SDLApplicationSource
sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
99 virtual Windows::ApplicationModel::Core::IFrameworkView^
CreateView();
102 IFrameworkView^ SDLApplicationSource::CreateView()
108 SDL_WinRTApp ^ app =
ref new SDL_WinRTApp();
119 auto direct3DApplicationSource =
ref new SDLApplicationSource();
135 if ((oldValue ==
NULL) && (newValue ==
NULL)) {
141 unsigned int orientationFlags = 0;
143 std::istringstream tokenizer(newValue);
144 while (!tokenizer.eof()) {
146 std::getline(tokenizer, orientationName,
' ');
147 if (orientationName ==
"LandscapeLeft") {
148 orientationFlags |= (
unsigned int) DisplayOrientations::LandscapeFlipped;
149 }
else if (orientationName ==
"LandscapeRight") {
150 orientationFlags |= (
unsigned int) DisplayOrientations::Landscape;
151 }
else if (orientationName ==
"Portrait") {
152 orientationFlags |= (
unsigned int) DisplayOrientations::Portrait;
153 }
else if (orientationName ==
"PortraitUpsideDown") {
154 orientationFlags |= (
unsigned int) DisplayOrientations::PortraitFlipped;
160 if (!orientationFlags) {
162 orientationFlags = (
unsigned int) ( \
163 DisplayOrientations::Landscape |
164 DisplayOrientations::LandscapeFlipped |
165 DisplayOrientations::Portrait |
166 DisplayOrientations::PortraitFlipped);
183 WINRT_DISPLAY_PROPERTY(AutoRotationPreferences) = (DisplayOrientations) orientationFlags;
189 CoreWindow ^ coreWindow = CoreWindow::GetForCurrentThread();
195 int x = WINRT_DIPS_TO_PHYSICAL_PIXELS(
data->coreWindow->Bounds.Left);
196 int y = WINRT_DIPS_TO_PHYSICAL_PIXELS(
data->coreWindow->Bounds.Top);
197 int w = WINRT_DIPS_TO_PHYSICAL_PIXELS(
data->coreWindow->Bounds.Width);
198 int h = WINRT_DIPS_TO_PHYSICAL_PIXELS(
data->coreWindow->Bounds.Height);
200 #if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (NTDDI_VERSION == NTDDI_WIN8)
210 const DisplayOrientations currentOrientation = WINRT_DISPLAY_PROPERTY(CurrentOrientation);
211 switch (currentOrientation) {
212 case DisplayOrientations::Landscape:
213 case DisplayOrientations::LandscapeFlipped: {
238 SDL_WinRTApp::SDL_WinRTApp() :
239 m_windowClosed(false),
240 m_windowVisible(true)
244 void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView)
246 applicationView->Activated +=
247 ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(
this, &SDL_WinRTApp::OnAppActivated);
249 CoreApplication::Suspending +=
250 ref new EventHandler<SuspendingEventArgs^>(
this, &SDL_WinRTApp::OnSuspending);
252 CoreApplication::Resuming +=
253 ref new EventHandler<Platform::Object^>(
this, &SDL_WinRTApp::OnResuming);
255 CoreApplication::Exiting +=
256 ref new EventHandler<Platform::Object^>(
this, &SDL_WinRTApp::OnExiting);
258 #if NTDDI_VERSION >= NTDDI_WIN10
264 Windows::Gaming::Input::Gamepad::GamepadAdded +=
265 ref new Windows::Foundation::EventHandler<Windows::Gaming::Input::Gamepad^>(
266 this, &SDL_WinRTApp::OnGamepadAdded
271 #if NTDDI_VERSION > NTDDI_WIN8
272 void SDL_WinRTApp::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
274 void SDL_WinRTApp::OnOrientationChanged(Object^ sender)
277 #if LOG_ORIENTATION_EVENTS==1
279 CoreWindow^
window = CoreWindow::GetForCurrentThread();
281 SDL_Log(
"%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, CoreWindow Bounds={%f,%f,%f,%f}\n",
283 WINRT_DISPLAY_PROPERTY(CurrentOrientation),
284 WINRT_DISPLAY_PROPERTY(NativeOrientation),
285 WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
291 SDL_Log(
"%s, current orientation=%d, native orientation=%d, auto rot. pref=%d\n",
293 WINRT_DISPLAY_PROPERTY(CurrentOrientation),
294 WINRT_DISPLAY_PROPERTY(NativeOrientation),
295 WINRT_DISPLAY_PROPERTY(AutoRotationPreferences));
302 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
315 int w = WINRT_DIPS_TO_PHYSICAL_PIXELS(
data->coreWindow->Bounds.Width);
316 int h = WINRT_DIPS_TO_PHYSICAL_PIXELS(
data->coreWindow->Bounds.Height);
323 void SDL_WinRTApp::SetWindow(CoreWindow^
window)
325 #if LOG_WINDOW_EVENTS==1
326 SDL_Log(
"%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, window bounds={%f, %f, %f,%f}\n",
328 WINRT_DISPLAY_PROPERTY(CurrentOrientation),
329 WINRT_DISPLAY_PROPERTY(NativeOrientation),
330 WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
338 ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(
this, &SDL_WinRTApp::OnWindowSizeChanged);
340 window->VisibilityChanged +=
341 ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(
this, &SDL_WinRTApp::OnVisibilityChanged);
344 ref new TypedEventHandler<CoreWindow^, WindowActivatedEventArgs^>(
this, &SDL_WinRTApp::OnWindowActivated);
347 ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(
this, &SDL_WinRTApp::OnWindowClosed);
349 #if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
350 window->PointerCursor =
ref new CoreCursor(CoreCursorType::Arrow, 0);
354 ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(
this, &SDL_WinRTApp::OnPointerPressed);
357 ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(
this, &SDL_WinRTApp::OnPointerMoved);
359 window->PointerReleased +=
360 ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(
this, &SDL_WinRTApp::OnPointerReleased);
363 ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(
this, &SDL_WinRTApp::OnPointerEntered);
366 ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(
this, &SDL_WinRTApp::OnPointerExited);
368 window->PointerWheelChanged +=
369 ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(
this, &SDL_WinRTApp::OnPointerWheelChanged);
371 #if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
373 Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved +=
374 ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(
this, &SDL_WinRTApp::OnMouseMoved);
378 ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(
this, &SDL_WinRTApp::OnKeyDown);
381 ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(
this, &SDL_WinRTApp::OnKeyUp);
383 window->CharacterReceived +=
384 ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(
this, &SDL_WinRTApp::OnCharacterReceived);
386 #if NTDDI_VERSION >= NTDDI_WIN10
387 Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->BackRequested +=
388 ref new EventHandler<BackRequestedEventArgs^>(
this, &SDL_WinRTApp::OnBackButtonPressed);
389 #elif WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
390 HardwareButtons::BackPressed +=
391 ref new EventHandler<BackPressedEventArgs^>(
this, &SDL_WinRTApp::OnBackButtonPressed);
394 #if NTDDI_VERSION > NTDDI_WIN8
395 DisplayInformation::GetForCurrentView()->OrientationChanged +=
396 ref new TypedEventHandler<Windows::Graphics::Display::DisplayInformation^, Object^>(
this, &SDL_WinRTApp::OnOrientationChanged);
398 DisplayProperties::OrientationChanged +=
399 ref new DisplayPropertiesEventHandler(
this, &SDL_WinRTApp::OnOrientationChanged);
406 #if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10) // for Windows 8/8.1/RT apps... (and not Phone apps)
410 using namespace Windows::UI::ApplicationSettings;
411 SettingsPane::GetForCurrentView()->CommandsRequested +=
412 ref new TypedEventHandler<SettingsPane^, SettingsPaneCommandsRequestedEventArgs^>
413 (
this, &SDL_WinRTApp::OnSettingsPaneCommandsRequested);
417 void SDL_WinRTApp::Load(Platform::String^ entryPoint)
446 bool SDL_WinRTApp::ShouldWaitForAppResumeEvents()
449 if (m_windowVisible) {
473 void SDL_WinRTApp::PumpEvents()
475 if (!m_windowClosed) {
476 if (!ShouldWaitForAppResumeEvents()) {
481 CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
490 CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
495 void SDL_WinRTApp::Uninitialize()
499 #if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10)
500 void SDL_WinRTApp::OnSettingsPaneCommandsRequested(
501 Windows::UI::ApplicationSettings::SettingsPane ^
p,
502 Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args)
504 using namespace Platform;
505 using namespace Windows::UI::ApplicationSettings;
506 using namespace Windows::UI::Popups;
508 String ^privacyPolicyURL =
nullptr;
509 String ^privacyPolicyLabel =
nullptr;
510 const char *tmpHintValue =
NULL;
511 wchar_t *tmpStr =
NULL;
515 if (tmpHintValue && tmpHintValue[0] !=
'\0') {
518 privacyPolicyURL =
ref new String(tmpStr);
524 if (tmpHintValue && tmpHintValue[0] !=
'\0') {
526 privacyPolicyLabel =
ref new String(tmpStr);
529 privacyPolicyLabel =
ref new String(L
"Privacy Policy");
534 auto cmd =
ref new SettingsCommand(L
"privacyPolicy", privacyPolicyLabel,
535 ref new UICommandInvokedHandler([=](IUICommand ^) {
536 Windows::System::Launcher::LaunchUriAsync(
ref new Uri(privacyPolicyURL));
538 args->Request->ApplicationCommands->Append(cmd);
541 #endif // if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10)
543 void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
545 #if LOG_WINDOW_EVENTS==1
546 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",
548 args->Size.Width, args->Size.Height,
549 sender->Bounds.X, sender->Bounds.Y, sender->Bounds.Width, sender->Bounds.Height,
550 WINRT_DISPLAY_PROPERTY(CurrentOrientation),
551 WINRT_DISPLAY_PROPERTY(NativeOrientation),
552 WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
559 void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
561 #if LOG_WINDOW_EVENTS==1
562 SDL_Log(
"%s, visible?=%s, bounds={%f,%f,%f,%f}, WINRT_GlobalSDLWindow?=%s\n",
564 (args->Visible ?
"yes" :
"no"),
565 sender->Bounds.X, sender->Bounds.Y,
566 sender->Bounds.Width, sender->Bounds.Height,
570 m_windowVisible = args->Visible;
598 void SDL_WinRTApp::OnWindowActivated(CoreWindow^ sender, WindowActivatedEventArgs^ args)
600 #if LOG_WINDOW_EVENTS==1
601 SDL_Log(
"%s, WINRT_GlobalSDLWindow?=%s\n\n",
611 sender->CustomProperties->Insert(
"SDLHelperWindowActivationState", args->WindowActivationState);
615 if (args->WindowActivationState != CoreWindowActivationState::Deactivated) {
630 #if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION >= NTDDI_WINBLUE)
631 Point cursorPos = WINRT_TransformCursorPosition(
window, sender->PointerPosition, TransformToSDLWindowSize);
660 void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
662 #if LOG_WINDOW_EVENTS==1
665 m_windowClosed =
true;
668 void SDL_WinRTApp::OnAppActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
670 CoreWindow::GetForCurrentThread()->Activate();
673 void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
689 SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
690 create_task([
this, deferral]()
704 #if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED
713 deferral->Complete();
717 void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args)
726 void SDL_WinRTApp::OnExiting(Platform::Object^ sender, Platform::Object^ args)
732 WINRT_LogPointerEvent(
const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint)
734 Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint;
735 SDL_Log(
"%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d\n",
737 pt->Position.X, pt->Position.Y,
738 transformedPoint.X, transformedPoint.Y,
739 pt->Properties->MouseWheelDelta,
742 WINRT_GetSDLButtonForPointerPoint(pt));
745 void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
747 #if LOG_POINTER_EVENTS
754 void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args)
756 #if LOG_POINTER_EVENTS
763 void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
765 #if LOG_POINTER_EVENTS
772 void SDL_WinRTApp::OnPointerEntered(CoreWindow^ sender, PointerEventArgs^ args)
774 #if LOG_POINTER_EVENTS
781 void SDL_WinRTApp::OnPointerExited(CoreWindow^ sender, PointerEventArgs^ args)
783 #if LOG_POINTER_EVENTS
790 void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args)
792 #if LOG_POINTER_EVENTS
799 void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args)
804 void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
806 WINRT_ProcessKeyDownEvent(args);
809 void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
811 WINRT_ProcessKeyUpEvent(args);
814 void SDL_WinRTApp::OnCharacterReceived(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CharacterReceivedEventArgs^ args)
816 WINRT_ProcessCharacterReceivedEvent(args);
819 template <
typename BackButtonEventArgs>
826 args->Handled =
true;
830 #if NTDDI_VERSION >= NTDDI_WIN10
831 void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ args)
836 #elif WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
837 void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args)
844 #if NTDDI_VERSION >= NTDDI_WIN10
845 void SDL_WinRTApp::OnGamepadAdded(Platform::Object ^sender, Windows::Gaming::Input::Gamepad ^gamepad)