Commit 119dff5546329c31b033b8ddc1f06091fc901681

David Ludwig 2014-03-23T22:07:01

WinRT: Implemented SDL_ShowMessageBox for Windows 8.x/RT hosts This change does not include message box support for Windows Phone 8, which does not offer the same message box APIs that Windows 8.x/RT does.

diff --git a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj
index 1a450ea..bc81762 100644
--- a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj
+++ b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj
@@ -253,6 +253,7 @@
     <ClInclude Include="..\..\src\video\SDL_shape_internals.h" />
     <ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtevents_c.h" />
+    <ClInclude Include="..\..\src\video\winrt\SDL_winrtmessagebox.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtmouse_c.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtvideo_cpp.h" />
   </ItemGroup>
@@ -388,6 +389,12 @@
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
     </ClCompile>
+    <ClCompile Include="..\..\src\video\winrt\SDL_winrtmessagebox.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\video\winrt\SDL_winrtmouse.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 e753153..7dabdc3 100644
--- a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters
+++ b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters
@@ -354,6 +354,9 @@
     <ClInclude Include="..\..\src\render\direct3d11\SDL_render_winrt.h">
       <Filter>Source Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\video\winrt\SDL_winrtmessagebox.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\atomic\SDL_atomic.c">
@@ -638,5 +641,8 @@
     <ClCompile Include="..\..\src\render\direct3d11\SDL_render_winrt.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\video\winrt\SDL_winrtmessagebox.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj
index d19b9d0..315bee8 100644
--- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj
+++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj
@@ -177,6 +177,14 @@
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
     </ClCompile>
+    <ClCompile Include="..\..\src\video\winrt\SDL_winrtmessagebox.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\video\winrt\SDL_winrtmouse.cpp">
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
@@ -331,6 +339,7 @@
     <ClInclude Include="..\..\src\video\SDL_shape_internals.h" />
     <ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtevents_c.h" />
+    <ClInclude Include="..\..\src\video\winrt\SDL_winrtmessagebox.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtmouse_c.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtopengles.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtvideo_cpp.h" />
diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters
index b5050af..a536f33 100644
--- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters
+++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters
@@ -295,6 +295,9 @@
     <ClCompile Include="..\..\src\power\winrt\SDL_syspower.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\video\winrt\SDL_winrtmessagebox.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\include\begin_code.h">
@@ -666,6 +669,9 @@
     <ClInclude Include="..\..\src\video\SDL_egl_c.h">
       <Filter>Source Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\video\winrt\SDL_winrtmessagebox.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Filter Include="Header Files">
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 139bc15..18f65d0 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -3221,6 +3221,9 @@ SDL_IsScreenKeyboardShown(SDL_Window *window)
 #if SDL_VIDEO_DRIVER_WINDOWS
 #include "windows/SDL_windowsmessagebox.h"
 #endif
+#if SDL_VIDEO_DRIVER_WINRT
+#include "winrt/SDL_winrtmessagebox.h"
+#endif
 #if SDL_VIDEO_DRIVER_COCOA
 #include "cocoa/SDL_cocoamessagebox.h"
 #endif
@@ -3280,6 +3283,13 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
         retval = 0;
     }
 #endif
+#if SDL_VIDEO_DRIVER_WINRT
+    if (retval == -1 &&
+        SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WINRT) &&
+        WINRT_ShowMessageBox(messageboxdata, buttonid) == 0) {
+        retval = 0;
+    }
+#endif
 #if SDL_VIDEO_DRIVER_COCOA
     if (retval == -1 &&
         SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_COCOA) &&
diff --git a/src/video/winrt/SDL_winrtmessagebox.cpp b/src/video/winrt/SDL_winrtmessagebox.cpp
new file mode 100644
index 0000000..71d9911
--- /dev/null
+++ b/src/video/winrt/SDL_winrtmessagebox.cpp
@@ -0,0 +1,103 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINRT
+
+extern "C" {
+#include "SDL_messagebox.h"
+#include "../../core/windows/SDL_windows.h"
+}
+
+#include "SDL_winrtevents_c.h"
+
+#include <windows.ui.popups.h>
+using namespace Platform;
+using namespace Windows::Foundation;
+using namespace Windows::UI::Popups;
+
+static String ^
+WINRT_UTF8ToPlatformString(const char * str)
+{
+    wchar_t * wstr = WIN_UTF8ToString(str);
+    String ^ rtstr = ref new String(wstr);
+    SDL_free(wstr);
+    return rtstr;
+}
+
+extern "C" int
+WINRT_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
+    /* Sadly, Windows Phone 8 doesn't include the MessageDialog class that
+     * Windows 8.x/RT does, even though MSDN's reference documentation for
+     * Windows Phone 8 mentions it.
+     * 
+     * The .NET runtime on Windows Phone 8 does, however, include a
+     * MessageBox class.  Perhaps this could be called, somehow?
+     */
+    return SDL_SetError("SDL_messagebox support is not available for Windows Phone");
+#else
+    SDL_VideoDevice *_this = SDL_GetVideoDevice();
+
+    if (messageboxdata->numbuttons > 3) {
+        return SDL_SetError("WinRT's MessageDialog only supports 3 buttons, at most. %d were requested.", messageboxdata->numbuttons);
+    }
+
+    /* Build a MessageDialog object and its buttons */
+    MessageDialog ^ dialog = ref new MessageDialog(WINRT_UTF8ToPlatformString(messageboxdata->message));
+    dialog->Title = WINRT_UTF8ToPlatformString(messageboxdata->title);
+    for (int i = 0; i < messageboxdata->numbuttons; ++i) {
+        UICommand ^ button = ref new UICommand(WINRT_UTF8ToPlatformString(messageboxdata->buttons[i].text));
+        button->Id = safe_cast<IntPtr>(i);
+        dialog->Commands->Append(button);
+        if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
+            dialog->CancelCommandIndex = i;
+        }
+        if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
+            dialog->DefaultCommandIndex = i;
+        }
+    }
+
+    /* Display the MessageDialog, then wait for it to be closed */
+    /* TODO, WinRT: Find a way to redraw MessageDialog instances if a GPU device-reset occurs during the following event-loop */
+    auto operation = dialog->ShowAsync();
+    while (operation->Status == Windows::Foundation::AsyncStatus::Started) {
+        WINRT_PumpEvents(_this);
+    }
+
+    /* Retrieve results from the MessageDialog and process them accordingly */
+    if (operation->Status != Windows::Foundation::AsyncStatus::Completed) {
+        return SDL_SetError("An unknown error occurred in displaying the WinRT MessageDialog");
+    }
+    if (buttonid) {
+        IntPtr results = safe_cast<IntPtr>(operation->GetResults()->Id);
+        int clicked_index = results.ToInt32();
+        *buttonid = messageboxdata->buttons[clicked_index].buttonid;
+    }
+    return 0;
+#endif /* if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP / else */
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINRT */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/src/video/winrt/SDL_winrtmessagebox.h b/src/video/winrt/SDL_winrtmessagebox.h
new file mode 100644
index 0000000..63e23c5
--- /dev/null
+++ b/src/video/winrt/SDL_winrtmessagebox.h
@@ -0,0 +1,29 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINRT
+
+extern int WINRT_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
+
+#endif /* SDL_VIDEO_DRIVER_WINRT */
+
+/* vi: set ts=4 sw=4 expandtab: */