src/video/windowsrt/SDL_WinRTApp.cpp
author David Ludwig <dludwig@pobox.com>
Sun, 28 Oct 2012 20:47:33 -0400
changeset 8332 ea83d191cc17
parent 8331 737dc8a4f49f
child 8333 49973bfb8d23
permissions -rw-r--r--
WinRT: added mouse button event support
     1 #include "SDLmain_WinRT_common.h"
     2 #include "SDL_WinRTApp.h"
     3 
     4 extern "C" {
     5 #include "SDL_assert.h"
     6 #include "SDL_stdinc.h"
     7 #include "../SDL_sysvideo.h"
     8 #include "../../events/SDL_mouse_c.h"
     9 #include "SDL_events.h"
    10 }
    11 
    12 // HACK, DLudwig: The C-style main() will get loaded via the app's
    13 // WinRT-styled main(), which is part of SDLmain_for_WinRT.cpp.
    14 // This seems wrong on some level, but does seem to work.
    15 typedef int (*SDL_WinRT_MainFunction)(int, char **);
    16 static SDL_WinRT_MainFunction SDL_WinRT_main = nullptr;
    17 
    18 // HACK, DLudwig: record a reference to the global, Windows RT 'app'/view.
    19 // SDL/WinRT will use this throughout its code.
    20 //
    21 // TODO, WinRT: consider replacing SDL_WinRTGlobalApp with something
    22 // non-global, such as something created inside
    23 // SDL_InitSubSystem(SDL_INIT_VIDEO), or something inside
    24 // SDL_CreateWindow().
    25 SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr;
    26 
    27 
    28 using namespace Windows::ApplicationModel;
    29 using namespace Windows::ApplicationModel::Core;
    30 using namespace Windows::ApplicationModel::Activation;
    31 using namespace Windows::UI::Core;
    32 using namespace Windows::System;
    33 using namespace Windows::Foundation;
    34 using namespace Windows::Graphics::Display;
    35 using namespace concurrency;
    36 
    37 SDL_WinRTApp::SDL_WinRTApp() :
    38 	m_windowClosed(false),
    39 	m_windowVisible(true)
    40 {
    41 }
    42 
    43 void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView)
    44 {
    45 	applicationView->Activated +=
    46         ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &SDL_WinRTApp::OnActivated);
    47 
    48 	CoreApplication::Suspending +=
    49         ref new EventHandler<SuspendingEventArgs^>(this, &SDL_WinRTApp::OnSuspending);
    50 
    51 	CoreApplication::Resuming +=
    52         ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnResuming);
    53 
    54 	m_renderer = ref new CubeRenderer();
    55 }
    56 
    57 void SDL_WinRTApp::SetWindow(CoreWindow^ window)
    58 {
    59 	window->SizeChanged += 
    60         ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &SDL_WinRTApp::OnWindowSizeChanged);
    61 
    62 	window->VisibilityChanged +=
    63 		ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &SDL_WinRTApp::OnVisibilityChanged);
    64 
    65 	window->Closed += 
    66         ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &SDL_WinRTApp::OnWindowClosed);
    67 
    68 	window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
    69 
    70 	window->PointerPressed +=
    71 		ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerPressed);
    72 
    73     window->PointerReleased +=
    74 		ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerReleased);
    75 
    76 	window->PointerMoved +=
    77 		ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerMoved);
    78 
    79 	m_renderer->Initialize(CoreWindow::GetForCurrentThread());
    80 }
    81 
    82 void SDL_WinRTApp::Load(Platform::String^ entryPoint)
    83 {
    84 }
    85 
    86 void SDL_WinRTApp::Run()
    87 {
    88     if (SDL_WinRT_main)
    89     {
    90         // TODO, WinRT: pass the C-style main() a reasonably realistic
    91         // representation of command line arguments.
    92         int argc = 0;
    93         char **argv = NULL;
    94         SDL_WinRT_main(argc, argv);
    95     }
    96 }
    97 
    98 void SDL_WinRTApp::PumpEvents()
    99 {
   100 	if (!m_windowClosed)
   101 	{
   102 		if (m_windowVisible)
   103 		{
   104 			CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
   105 			m_renderer->Update(0.0f, 0.0f);
   106 			m_renderer->Render();
   107 			m_renderer->Present(); // This call is synchronized to the display frame rate.
   108 		}
   109 		else
   110 		{
   111 			CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
   112 		}
   113 	}
   114 }
   115 
   116 void SDL_WinRTApp::Uninitialize()
   117 {
   118 }
   119 
   120 void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
   121 {
   122 	m_renderer->UpdateForWindowSizeChange();
   123 }
   124 
   125 void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
   126 {
   127 	m_windowVisible = args->Visible;
   128 }
   129 
   130 void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
   131 {
   132 	m_windowClosed = true;
   133 }
   134 
   135 void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
   136 {
   137     // TODO, WinRT: consider attaching the SDL_Window to the mouse down button event
   138 	SDL_SendMouseButton(NULL, SDL_PRESSED, SDL_BUTTON_LEFT);
   139 }
   140 
   141 void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
   142 {
   143     // TODO, WinRT: consider attaching the SDL_Window to the mouse up button event
   144 	SDL_SendMouseButton(NULL, SDL_RELEASED, SDL_BUTTON_LEFT);
   145 }
   146 
   147 void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args)
   148 {
   149 	// Insert your code here.
   150 }
   151 
   152 void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
   153 {
   154 	CoreWindow::GetForCurrentThread()->Activate();
   155 }
   156 
   157 void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
   158 {
   159 	// Save app state asynchronously after requesting a deferral. Holding a deferral
   160 	// indicates that the application is busy performing suspending operations. Be
   161 	// aware that a deferral may not be held indefinitely. After about five seconds,
   162 	// the app will be forced to exit.
   163 	SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
   164 
   165 	create_task([this, deferral]()
   166 	{
   167 		// Insert your code here.
   168 
   169 		deferral->Complete();
   170 	});
   171 }
   172  
   173 void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args)
   174 {
   175 	// Restore any data or state that was unloaded on suspend. By default, data
   176 	// and state are persisted when resuming from suspend. Note that this event
   177 	// does not occur if the app was previously terminated.
   178 }
   179 
   180 SDL_DisplayMode SDL_WinRTApp::GetMainDisplayMode()
   181 {
   182     SDL_DisplayMode mode;
   183     SDL_zero(mode);
   184     mode.format = SDL_PIXELFORMAT_RGB888;
   185     mode.w = (int) CoreWindow::GetForCurrentThread()->Bounds.Width;
   186     mode.h = (int) CoreWindow::GetForCurrentThread()->Bounds.Height;
   187     mode.refresh_rate = 0;  // TODO, WinRT: see if refresh rate data is available, or relevant (for WinRT apps)
   188     mode.driverdata = NULL;
   189     return mode;
   190 }
   191 
   192 IFrameworkView^ Direct3DApplicationSource::CreateView()
   193 {
   194     // TODO, WinRT: see if this function (CreateView) can ever get called
   195     // more than once.  For now, just prevent it from ever assigning
   196     // SDL_WinRTGlobalApp more than once.
   197     SDL_assert(!SDL_WinRTGlobalApp);
   198     SDL_WinRTApp ^ app = ref new SDL_WinRTApp();
   199     if (!SDL_WinRTGlobalApp)
   200     {
   201         SDL_WinRTGlobalApp = app;
   202     }
   203     return app;
   204 }
   205 
   206 __declspec(dllexport) int SDL_WinRT_RunApplication(SDL_WinRT_MainFunction mainFunction)
   207 {
   208     SDL_WinRT_main = mainFunction;
   209     auto direct3DApplicationSource = ref new Direct3DApplicationSource();
   210 	CoreApplication::Run(direct3DApplicationSource);
   211 	return 0;
   212 }