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