Commit 58dd08648794d853c534c95942ea6d2cac683bd1

David Ludwig 2013-09-22T12:26:53

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.

diff --git a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj
index fce026f..501c929 100644
--- a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj
+++ b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj
@@ -197,6 +197,7 @@
     <ClInclude Include="..\..\src\audio\SDL_wave.h" />
     <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h" />
     <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
+    <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_common.h" />
     <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_direct3d.h" />
     <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_xaml.h" />
     <ClInclude Include="..\..\src\events\blank_cursor.h" />
@@ -269,6 +270,12 @@
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
     </ClCompile>
     <ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
+    <ClCompile Include="..\..\src\core\winrt\SDL_winrtapp_common.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+    </ClCompile>
     <ClCompile Include="..\..\src\core\winrt\SDL_winrtapp_direct3d.cpp">
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
diff --git a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters
index 9e2d8ee..346e073 100644
--- a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters
+++ b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters
@@ -339,6 +339,9 @@
     <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_xaml.h">
       <Filter>Source Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_common.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\atomic\SDL_atomic.c">
@@ -605,6 +608,9 @@
     <ClCompile Include="..\..\src\core\winrt\SDL_winrtapp_xaml.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\core\winrt\SDL_winrtapp_common.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <FxCompile Include="..\..\src\render\direct3d11\SDL_D3D11_PixelShader_FixedColor.hlsl">
diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj
index c383a26..0be3fc4 100644
--- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj
+++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj
@@ -47,6 +47,14 @@
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
     </ClCompile>
     <ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
+    <ClCompile Include="..\..\src\core\winrt\SDL_winrtapp_common.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
+    </ClCompile>
     <ClCompile Include="..\..\src\core\winrt\SDL_winrtapp_direct3d.cpp">
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
@@ -244,6 +252,7 @@
     <ClInclude Include="..\..\src\audio\SDL_wave.h" />
     <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h" />
     <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
+    <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_common.h" />
     <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_direct3d.h" />
     <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_xaml.h" />
     <ClInclude Include="..\..\src\events\blank_cursor.h" />
diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters
index fad8ce8..ffeb716 100644
--- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters
+++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters
@@ -276,6 +276,9 @@
     <ClCompile Include="..\..\src\core\winrt\SDL_winrtapp_xaml.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\core\winrt\SDL_winrtapp_common.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\include\begin_code.h">
@@ -608,6 +611,9 @@
     <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_xaml.h">
       <Filter>Source Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_common.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Filter Include="Header Files">
diff --git a/include/SDL_main.h b/include/SDL_main.h
index 876ee34..8151b4a 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 447d5f7..056d07f 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 7bcd528..a5027fa 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 d9cf33e..837afdc 100644
--- a/src/core/winrt/SDL_winrtapp_direct3d.h
+++ b/src/core/winrt/SDL_winrtapp_direct3d.h
@@ -1,5 +1,9 @@
 #pragma once
 
+#include <Windows.h>
+
+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 0555693..8b8a8ee 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<Object ^>((IInspectable *) backgroundPanelAsIInspectable);
     SwapChainBackgroundPanel ^swapChainBackgroundPanel = dynamic_cast<SwapChainBackgroundPanel ^>(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<Object^>(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 2beaad8..875b768 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 6e61a40..19eb7b9 100644
--- a/src/main/winrt/SDL_winrt_main_NonXAML.cpp
+++ b/src/main/winrt/SDL_winrt_main_NonXAML.cpp
@@ -1,4 +1,5 @@
 
+#include <SDL_main.h>
 #include <wrl.h>
 
 /* 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 b766177..021ad40 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