From 58dd08648794d853c534c95942ea6d2cac683bd1 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 22 Sep 2013 12:26:53 -0400 Subject: [PATCH] WinRT: unified the two, public, app-init functions This function, SDL_WinRTRunApp, can be used to help launch either XAML or non-XAML/Direct3D-only based apps. --- .../SDL/SDL-WinPhone_VS2012.vcxproj | 7 ++++++ .../SDL/SDL-WinPhone_VS2012.vcxproj.filters | 6 +++++ VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj | 9 +++++++ .../SDL/SDL-WinRT_VS2012.vcxproj.filters | 6 +++++ include/SDL_main.h | 24 +++++++++++++++++-- include/SDL_system.h | 15 ------------ src/core/winrt/SDL_winrtapp_direct3d.cpp | 15 ++++-------- src/core/winrt/SDL_winrtapp_direct3d.h | 4 ++++ src/core/winrt/SDL_winrtapp_xaml.cpp | 13 +++++----- src/core/winrt/SDL_winrtapp_xaml.h | 2 +- src/main/winrt/SDL_winrt_main_NonXAML.cpp | 13 +++------- src/video/winrt/SDL_winrtevents.cpp | 9 +++++-- 12 files changed, 77 insertions(+), 46 deletions(-) diff --git a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj index fce026f16d62e..501c929c14504 100644 --- a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj +++ b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj @@ -197,6 +197,7 @@ + @@ -269,6 +270,12 @@ true + + true + true + true + true + true true diff --git a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters index 9e2d8ee273c2c..346e0735d0579 100644 --- a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters @@ -339,6 +339,9 @@ Source Files + + Source Files + @@ -605,6 +608,9 @@ Source Files + + Source Files + diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj index c383a26150a67..0be3fc4e0caa7 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj @@ -47,6 +47,14 @@ true + + true + true + true + true + true + true + true true @@ -244,6 +252,7 @@ + diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters index fad8ce82bae84..ffeb7165ff53c 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters @@ -276,6 +276,9 @@ Source Files + + Source Files + @@ -608,6 +611,9 @@ Source Files + + Source Files + diff --git a/include/SDL_main.h b/include/SDL_main.h index 876ee341ad857..8151b4a1a6e26 100644 --- a/include/SDL_main.h +++ b/include/SDL_main.h @@ -44,8 +44,10 @@ creating an instance of IFrameworkView in the process. Please note that #include'ing SDL_main.h is not enough to get a main() - function working. The file, src/main/winrt/SDL_WinRT_main.cpp, or a copy - of it, must be compiled into the app itself. + function working. In non-XAML apps, the file, + src/main/winrt/SDL_WinRT_main_NonXAML.cpp, or a copy of it, must be compiled + into the app itself. In XAML apps, the function, SDL_WinRTRunApp must be + called, with a pointer to the Direct3D-hosted XAML control passed in. */ #define SDL_MAIN_NEEDED @@ -125,6 +127,24 @@ extern DECLSPEC void SDLCALL SDL_UnregisterApp(void); #endif /* __WIN32__ */ +#ifdef __WINRT__ + +/** + * \brief Initializes and launches an SDL/WinRT application. + * + * \param mainFunction The SDL app's C-style main(). + * \param xamlBackgroundPanel An optional, XAML-based, background panel. + * For Non-XAML apps, this value must be set to NULL. For XAML apps, + * pass in a pointer to a SwapChainBackgroundPanel, casted to an + * IInspectable (via reinterpret_cast). + * \ret 0 on success, -1 on failure. On failure, use SDL_GetError to retrieve more + * information on the failure. + */ +extern DECLSPEC int SDLCALL SDL_WinRTRunApp(int (*mainFunction)(int, char **), void * xamlBackgroundPanel); + +#endif /* __WINRT__ */ + + #ifdef __cplusplus } #endif diff --git a/include/SDL_system.h b/include/SDL_system.h index 447d5f7436025..056d07fcd31ac 100644 --- a/include/SDL_system.h +++ b/include/SDL_system.h @@ -155,21 +155,6 @@ extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path */ extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType); -#ifdef __cplusplus_winrt -/** - * \brief Initializes a WinRT and XAML based application. - * - * \param backgroundPanel The XAML background panel to draw onto and receive - * events from. - * \param mainFunction The SDL app's C-style main(). - * \ret 0 on success, -1 on failure. On failure, use SDL_GetError to retrieve more - * information on the failure. - */ -/* TODO, WinRT: consider making SDL_WinRTInitXAMLApp accept a void pointer to IUnknown, rather than a C++/CX reference */ -extern DECLSPEC int SDLCALL SDL_WinRTInitXAMLApp(Platform::Object^ backgroundPanel, int (*mainFunction)(int, char **)); - -#endif // ifdef __cplusplus_winrt - #endif /* __WINRT__ */ diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp index 7bcd528d7ea6a..a5027fa4e6be1 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -38,6 +38,7 @@ extern "C" { #include "../../video/winrt/SDL_winrtevents_c.h" #include "../../video/winrt/SDL_winrtvideo_cpp.h" +#include "SDL_winrtapp_common.h" #include "SDL_winrtapp_direct3d.h" @@ -48,12 +49,6 @@ extern "C" { //#define LOG_ORIENTATION_EVENTS 1 -// HACK, DLudwig: The C-style main() will get loaded via the app's -// WinRT-styled main(), which is part of SDLmain_for_WinRT.cpp. -// This seems wrong on some level, but does seem to work. -typedef int (*SDL_WinRT_MainFunction)(int, char **); -static SDL_WinRT_MainFunction SDL_WinRT_main = nullptr; - // HACK, DLudwig: record a reference to the global, WinRT 'app'/view. // SDL/WinRT will use this throughout its code. // @@ -83,9 +78,9 @@ IFrameworkView^ SDLApplicationSource::CreateView() return app; } -__declspec(dllexport) int SDL_WinRT_RunApplication(SDL_WinRT_MainFunction mainFunction) +int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **)) { - SDL_WinRT_main = mainFunction; + WINRT_SDLAppEntryPoint = mainFunction; auto direct3DApplicationSource = ref new SDLApplicationSource(); CoreApplication::Run(direct3DApplicationSource); return 0; @@ -328,13 +323,13 @@ void SDL_WinRTApp::Load(Platform::String^ entryPoint) void SDL_WinRTApp::Run() { SDL_SetMainReady(); - if (SDL_WinRT_main) + if (WINRT_SDLAppEntryPoint) { // TODO, WinRT: pass the C-style main() a reasonably realistic // representation of command line arguments. int argc = 0; char **argv = NULL; - SDL_WinRT_main(argc, argv); + WINRT_SDLAppEntryPoint(argc, argv); } } diff --git a/src/core/winrt/SDL_winrtapp_direct3d.h b/src/core/winrt/SDL_winrtapp_direct3d.h index d9cf33e9e0789..837afdca65f07 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.h +++ b/src/core/winrt/SDL_winrtapp_direct3d.h @@ -1,5 +1,9 @@ #pragma once +#include + +extern int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **)); + ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFrameworkView { public: diff --git a/src/core/winrt/SDL_winrtapp_xaml.cpp b/src/core/winrt/SDL_winrtapp_xaml.cpp index 055569377ce72..8b8a8ee63fbe4 100644 --- a/src/core/winrt/SDL_winrtapp_xaml.cpp +++ b/src/core/winrt/SDL_winrtapp_xaml.cpp @@ -32,13 +32,13 @@ #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; -int (*WINRT_XAMLAppMainFunction)(int, char **) = NULL; #if WINAPI_FAMILY == WINAPI_FAMILY_APP ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative = NULL; @@ -96,8 +96,8 @@ WINRT_OnRenderViaXAML(_In_ Platform::Object^ sender, _In_ Platform::Object^ args * SDL + XAML Initialization */ -extern "C" int -SDL_WinRTInitXAMLApp(Platform::Object ^backgroundPanel, int (*mainFunction)(int, char **)) +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."); @@ -112,10 +112,11 @@ SDL_WinRTInitXAMLApp(Platform::Object ^backgroundPanel, int (*mainFunction)(int, using namespace Windows::UI::Xaml::Media; // Make sure we have a valid XAML element (to draw onto): - if ( ! backgroundPanel) { - return SDL_SetError("'backgroundPanel' can't be NULL"); + if ( ! backgroundPanelAsIInspectable) { + return SDL_SetError("'backgroundPanelAsIInspectable' can't be NULL"); } + Platform::Object ^ backgroundPanel = reinterpret_cast((IInspectable *) backgroundPanelAsIInspectable); SwapChainBackgroundPanel ^swapChainBackgroundPanel = dynamic_cast(backgroundPanel); if ( ! swapChainBackgroundPanel) { return SDL_SetError("An unknown or unsupported type of XAML control was specified."); @@ -134,7 +135,7 @@ SDL_WinRTInitXAMLApp(Platform::Object ^backgroundPanel, int (*mainFunction)(int, WINRT_XAMLAppEventToken = CompositionTarget::Rendering::add(ref new EventHandler(WINRT_OnRenderViaXAML)); // Make sure the app is ready to call the SDL-centric main() function: - WINRT_XAMLAppMainFunction = mainFunction; + WINRT_SDLAppEntryPoint = mainFunction; SDL_SetMainReady(); // Make sure video-init knows that we're initializing XAML: diff --git a/src/core/winrt/SDL_winrtapp_xaml.h b/src/core/winrt/SDL_winrtapp_xaml.h index 2beaad8072de7..875b768aa68c3 100644 --- a/src/core/winrt/SDL_winrtapp_xaml.h +++ b/src/core/winrt/SDL_winrtapp_xaml.h @@ -27,7 +27,7 @@ #ifdef __cplusplus extern SDL_bool WINRT_XAMLWasEnabled; -extern int (*WINRT_XAMLAppMainFunction)(int, char **); +extern int SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void * backgroundPanelAsIInspectable); #endif // ifdef __cplusplus #endif // ifndef _SDL_winrtapp_xaml_h diff --git a/src/main/winrt/SDL_winrt_main_NonXAML.cpp b/src/main/winrt/SDL_winrt_main_NonXAML.cpp index 6e61a40c0f769..19eb7b91965eb 100644 --- a/src/main/winrt/SDL_winrt_main_NonXAML.cpp +++ b/src/main/winrt/SDL_winrt_main_NonXAML.cpp @@ -1,4 +1,5 @@ +#include #include /* At least one file in any SDL/WinRT app appears to require compilation @@ -27,13 +28,6 @@ #endif #endif - -/* The app's C-style main will be passed into SDL.dll as a function - pointer, and called at the appropriate time. -*/ -extern __declspec(dllimport) int SDL_WinRT_RunApplication(int (*)(int, char **)); -extern "C" int SDL_main(int, char **); - /* Prevent MSVC++ from warning about threading models when defining our custom WinMain. The threading model will instead be set via a direct call to Windows::Foundation::Initialize (rather than via an attributed @@ -51,13 +45,12 @@ extern "C" int SDL_main(int, char **); #pragma comment(lib, "runtimeobject.lib") #endif -int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int) +int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { if (FAILED(Windows::Foundation::Initialize(RO_INIT_MULTITHREADED))) { return 1; } - SDL_WinRT_RunApplication(SDL_main); + SDL_WinRTRunApp(SDL_main, NULL); return 0; } - diff --git a/src/video/winrt/SDL_winrtevents.cpp b/src/video/winrt/SDL_winrtevents.cpp index b766177831a29..021ad406c17dc 100644 --- a/src/video/winrt/SDL_winrtevents.cpp +++ b/src/video/winrt/SDL_winrtevents.cpp @@ -33,6 +33,7 @@ using Windows::UI::Core::CoreCursor; * SDL includes: */ #include "SDL_winrtevents_c.h" +#include "../../core/winrt/SDL_winrtapp_common.h" #include "../../core/winrt/SDL_winrtapp_direct3d.h" #include "../../core/winrt/SDL_winrtapp_xaml.h" #include "SDL_assert.h" @@ -55,7 +56,7 @@ WINRT_PumpEvents(_THIS) { if (SDL_WinRTGlobalApp) { SDL_WinRTGlobalApp->PumpEvents(); - } else if (WINRT_XAMLAppMainFunction) { + } else if (WINRT_XAMLWasEnabled) { WINRT_YieldXAMLThread(); } } @@ -95,7 +96,11 @@ WINRT_YieldXAMLThread() static int WINRT_XAMLThreadMain(void * userdata) { - return WINRT_XAMLAppMainFunction(0, NULL); + // TODO, WinRT: pass the C-style main() a reasonably realistic + // representation of command line arguments. + int argc = 0; + char **argv = NULL; + return WINRT_SDLAppEntryPoint(argc, argv); } void