src/video/windowsrt/SDL_WinRTApp.cpp
changeset 8384 bc7a52629e1e
parent 8383 1f415392ccf0
child 8385 e954dfbf2ecc
equal deleted inserted replaced
8383:1f415392ccf0 8384:bc7a52629e1e
    40 using namespace Windows::Foundation;
    40 using namespace Windows::Foundation;
    41 using namespace Windows::Graphics::Display;
    41 using namespace Windows::Graphics::Display;
    42 using namespace concurrency;
    42 using namespace concurrency;
    43 
    43 
    44 SDL_WinRTApp::SDL_WinRTApp() :
    44 SDL_WinRTApp::SDL_WinRTApp() :
    45 	m_windowClosed(false),
    45     m_windowClosed(false),
    46 	m_windowVisible(true),
    46     m_windowVisible(true),
    47     m_sdlWindowData(NULL),
    47     m_sdlWindowData(NULL),
    48     m_useRelativeMouseMode(false)
    48     m_useRelativeMouseMode(false)
    49 {
    49 {
    50 }
    50 }
    51 
    51 
    52 void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView)
    52 void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView)
    53 {
    53 {
    54 	applicationView->Activated +=
    54     applicationView->Activated +=
    55         ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &SDL_WinRTApp::OnActivated);
    55         ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &SDL_WinRTApp::OnActivated);
    56 
    56 
    57 	CoreApplication::Suspending +=
    57     CoreApplication::Suspending +=
    58         ref new EventHandler<SuspendingEventArgs^>(this, &SDL_WinRTApp::OnSuspending);
    58         ref new EventHandler<SuspendingEventArgs^>(this, &SDL_WinRTApp::OnSuspending);
    59 
    59 
    60 	CoreApplication::Resuming +=
    60     CoreApplication::Resuming +=
    61         ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnResuming);
    61         ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnResuming);
    62 
    62 
    63 	m_renderer = ref new SDL_winrtrenderer();
    63     m_renderer = ref new SDL_winrtrenderer();
    64 }
    64 }
    65 
    65 
    66 void SDL_WinRTApp::SetWindow(CoreWindow^ window)
    66 void SDL_WinRTApp::SetWindow(CoreWindow^ window)
    67 {
    67 {
    68 	window->SizeChanged += 
    68     window->SizeChanged += 
    69         ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &SDL_WinRTApp::OnWindowSizeChanged);
    69         ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &SDL_WinRTApp::OnWindowSizeChanged);
    70 
    70 
    71 	window->VisibilityChanged +=
    71     window->VisibilityChanged +=
    72 		ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &SDL_WinRTApp::OnVisibilityChanged);
    72         ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &SDL_WinRTApp::OnVisibilityChanged);
    73 
    73 
    74 	window->Closed += 
    74     window->Closed += 
    75         ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &SDL_WinRTApp::OnWindowClosed);
    75         ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &SDL_WinRTApp::OnWindowClosed);
    76 
    76 
    77 	window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
    77     window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
    78 
    78 
    79 	window->PointerPressed +=
    79     window->PointerPressed +=
    80 		ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerPressed);
    80         ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerPressed);
    81 
    81 
    82     window->PointerReleased +=
    82     window->PointerReleased +=
    83 		ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerReleased);
    83         ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerReleased);
    84 
    84 
    85 	window->PointerMoved +=
    85     window->PointerMoved +=
    86 		ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerMoved);
    86         ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerMoved);
    87 
    87 
    88     // Retrieves relative-only mouse movements:
    88     // Retrieves relative-only mouse movements:
    89     Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved +=
    89     Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved +=
    90         ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(this, &SDL_WinRTApp::OnMouseMoved);
    90         ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(this, &SDL_WinRTApp::OnMouseMoved);
    91 
    91 
    92     window->KeyDown +=
    92     window->KeyDown +=
    93 		ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyDown);
    93         ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyDown);
    94 
    94 
    95 	window->KeyUp +=
    95     window->KeyUp +=
    96 		ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyUp);
    96         ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyUp);
    97 
    97 
    98 
    98 
    99 	m_renderer->Initialize(CoreWindow::GetForCurrentThread());
    99     m_renderer->Initialize(CoreWindow::GetForCurrentThread());
   100 }
   100 }
   101 
   101 
   102 void SDL_WinRTApp::Load(Platform::String^ entryPoint)
   102 void SDL_WinRTApp::Load(Platform::String^ entryPoint)
   103 {
   103 {
   104 }
   104 }
   115     }
   115     }
   116 }
   116 }
   117 
   117 
   118 void SDL_WinRTApp::PumpEvents()
   118 void SDL_WinRTApp::PumpEvents()
   119 {
   119 {
   120 	if (!m_windowClosed)
   120     if (!m_windowClosed)
   121 	{
   121     {
   122 		if (m_windowVisible)
   122         if (m_windowVisible)
   123 		{
   123         {
   124 			CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
   124             CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
   125 		}
   125         }
   126 		else
   126         else
   127 		{
   127         {
   128 			CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
   128             CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
   129 		}
   129         }
   130 	}
   130     }
   131 }
   131 }
   132 
   132 
   133 void SDL_WinRTApp::UpdateWindowFramebuffer(SDL_Surface * surface, SDL_Rect * rects, int numrects)
   133 void SDL_WinRTApp::UpdateWindowFramebuffer(SDL_Surface * surface, SDL_Rect * rects, int numrects)
   134 {
   134 {
   135     if (!m_windowClosed && m_windowVisible)
   135     if (!m_windowClosed && m_windowVisible)
   136 	{
   136     {
   137 		m_renderer->Render(surface, rects, numrects);
   137         m_renderer->Render(surface, rects, numrects);
   138 		m_renderer->Present(); // This call is synchronized to the display frame rate.
   138         m_renderer->Present(); // This call is synchronized to the display frame rate.
   139 	}
   139     }
   140 }
   140 }
   141 
   141 
   142 void SDL_WinRTApp::Uninitialize()
   142 void SDL_WinRTApp::Uninitialize()
   143 {
   143 {
   144 }
   144 }
   145 
   145 
   146 void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
   146 void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
   147 {
   147 {
   148 	m_renderer->UpdateForWindowSizeChange();
   148     m_renderer->UpdateForWindowSizeChange();
   149 }
   149 }
   150 
   150 
   151 void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
   151 void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
   152 {
   152 {
   153 	m_windowVisible = args->Visible;
   153     m_windowVisible = args->Visible;
   154 }
   154 }
   155 
   155 
   156 void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
   156 void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
   157 {
   157 {
   158 	m_windowClosed = true;
   158     m_windowClosed = true;
   159 }
   159 }
   160 
   160 
   161 void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
   161 void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
   162 {
   162 {
   163     if (m_sdlWindowData)
   163     if (m_sdlWindowData)
   164     {
   164     {
   165     	SDL_SendMouseButton(m_sdlWindowData->sdlWindow, SDL_PRESSED, SDL_BUTTON_LEFT);
   165         SDL_SendMouseButton(m_sdlWindowData->sdlWindow, SDL_PRESSED, SDL_BUTTON_LEFT);
   166     }
   166     }
   167 }
   167 }
   168 
   168 
   169 void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
   169 void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
   170 {
   170 {
   171     if (m_sdlWindowData)
   171     if (m_sdlWindowData)
   172     {
   172     {
   173     	SDL_SendMouseButton(m_sdlWindowData->sdlWindow, SDL_RELEASED, SDL_BUTTON_LEFT);
   173         SDL_SendMouseButton(m_sdlWindowData->sdlWindow, SDL_RELEASED, SDL_BUTTON_LEFT);
   174     }
   174     }
   175 }
   175 }
   176 
   176 
   177 static inline int _lround(float arg) {
   177 static inline int _lround(float arg) {
   178     if (arg >= 0.0f) {
   178     if (arg >= 0.0f) {
   490     SDL_SendKeyboardKey(SDL_RELEASED, TranslateKeycode((int)args->VirtualKey));
   490     SDL_SendKeyboardKey(SDL_RELEASED, TranslateKeycode((int)args->VirtualKey));
   491 }
   491 }
   492 
   492 
   493 void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
   493 void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
   494 {
   494 {
   495 	CoreWindow::GetForCurrentThread()->Activate();
   495     CoreWindow::GetForCurrentThread()->Activate();
   496 }
   496 }
   497 
   497 
   498 static int SDLCALL RemoveAppSuspendAndResumeEvents(void * userdata, SDL_Event * event)
   498 static int SDLCALL RemoveAppSuspendAndResumeEvents(void * userdata, SDL_Event * event)
   499 {
   499 {
   500     if (event->type == SDL_WINDOWEVENT)
   500     if (event->type == SDL_WINDOWEVENT)
   515     return 1;
   515     return 1;
   516 }
   516 }
   517 
   517 
   518 void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
   518 void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
   519 {
   519 {
   520 	// Save app state asynchronously after requesting a deferral. Holding a deferral
   520     // Save app state asynchronously after requesting a deferral. Holding a deferral
   521 	// indicates that the application is busy performing suspending operations. Be
   521     // indicates that the application is busy performing suspending operations. Be
   522 	// aware that a deferral may not be held indefinitely. After about five seconds,
   522     // aware that a deferral may not be held indefinitely. After about five seconds,
   523 	// the app will be forced to exit.
   523     // the app will be forced to exit.
   524 	SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
   524     SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
   525 	create_task([this, deferral]()
   525     create_task([this, deferral]()
   526 	{
   526     {
   527         // Send a window-minimized event immediately to observers.
   527         // Send a window-minimized event immediately to observers.
   528         // CoreDispatcher::ProcessEvents, which is the backbone on which
   528         // CoreDispatcher::ProcessEvents, which is the backbone on which
   529         // SDL_WinRTApp::PumpEvents is built, will not return to its caller
   529         // SDL_WinRTApp::PumpEvents is built, will not return to its caller
   530         // once it sends out a suspend event.  Any events posted to SDL's
   530         // once it sends out a suspend event.  Any events posted to SDL's
   531         // event queue won't get received until the WinRT app is resumed.
   531         // event queue won't get received until the WinRT app is resumed.
   539         if (m_sdlWindowData)
   539         if (m_sdlWindowData)
   540         {
   540         {
   541             SDL_SendWindowEvent(m_sdlWindowData->sdlWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0);   // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently)
   541             SDL_SendWindowEvent(m_sdlWindowData->sdlWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0);   // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently)
   542             SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0);
   542             SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0);
   543         }
   543         }
   544 		deferral->Complete();
   544         deferral->Complete();
   545 	});
   545     });
   546 }
   546 }
   547 
   547 
   548 void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args)
   548 void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args)
   549 {
   549 {
   550 	// Restore any data or state that was unloaded on suspend. By default, data
   550     // Restore any data or state that was unloaded on suspend. By default, data
   551 	// and state are persisted when resuming from suspend. Note that this event
   551     // and state are persisted when resuming from suspend. Note that this event
   552 	// does not occur if the app was previously terminated.
   552     // does not occur if the app was previously terminated.
   553     if (m_sdlWindowData)
   553     if (m_sdlWindowData)
   554     {
   554     {
   555         SDL_SendWindowEvent(m_sdlWindowData->sdlWindow, SDL_WINDOWEVENT_RESTORED, 0, 0);    // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently)
   555         SDL_SendWindowEvent(m_sdlWindowData->sdlWindow, SDL_WINDOWEVENT_RESTORED, 0, 0);    // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently)
   556 
   556 
   557         // Remove the app-resume event from the queue, as is done with the
   557         // Remove the app-resume event from the queue, as is done with the
   617 
   617 
   618 __declspec(dllexport) int SDL_WinRT_RunApplication(SDL_WinRT_MainFunction mainFunction)
   618 __declspec(dllexport) int SDL_WinRT_RunApplication(SDL_WinRT_MainFunction mainFunction)
   619 {
   619 {
   620     SDL_WinRT_main = mainFunction;
   620     SDL_WinRT_main = mainFunction;
   621     auto direct3DApplicationSource = ref new Direct3DApplicationSource();
   621     auto direct3DApplicationSource = ref new Direct3DApplicationSource();
   622 	CoreApplication::Run(direct3DApplicationSource);
   622     CoreApplication::Run(direct3DApplicationSource);
   623 	return 0;
   623     return 0;
   624 }
   624 }