sdl2-compat: initial attempt at winrt support -- completely untested

From 0dcc4c29873c83dd10c1b340e5efe3cc0f6e8ac4 Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Thu, 10 Aug 2023 20:47:02 +0300
Subject: [PATCH] initial attempt at winrt support -- completely untested

Reference issue: https://github.com/libsdl-org/sdl2-compat/issues/57
---
 CMakeLists.txt             | 11 ++++++-
 src/sdl2_compat.c          | 13 ++++++--
 src/sdl2_compat_winrt.cpp  | 66 ++++++++++++++++++++++++++++++++++++++
 src/sdl3_include_wrapper.h |  7 ----
 4 files changed, 87 insertions(+), 10 deletions(-)
 create mode 100644 src/sdl2_compat_winrt.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index afa0a54..83645bf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -163,6 +163,12 @@ if(APPLE)
   endif()
 endif()
 
+if(WINDOWS_STORE)
+  list(APPEND SDL2COMPAT_SRCS
+    "src/sdl2_compat_winrt.cpp"
+  )
+endif()
+
 if(WIN32)
   list(APPEND SDL2COMPAT_SRCS
     "src/version.rc"
@@ -279,7 +285,10 @@ if(MINGW)
     endif()
   endif()
 endif()
-if(MSVC)
+if(WINDOWS_STORE)
+  set_target_properties(SDL2 PROPERTIES DEFINE_SYMBOL "SDL_BUILDING_WINRT=1")
+  target_compile_options(SDL2 PRIVATE "-ZW")
+elseif(MSVC)
   # Don't try to link with the default set of libraries.
   target_compile_options(SDL2 PRIVATE /GS-)
   if(SDL_CPU_X86)  # don't emit SSE2 in x86 builds
diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index 674c1a1..408eb53 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -217,10 +217,15 @@ SDL2COMPAT_itoa(char *dst, int val)
 /* FIXME: Updated library names after https://github.com/libsdl-org/SDL/issues/5626 solidifies.  */
 static char loaderror[256];
 #if defined(_WIN32)
+    static HMODULE Loaded_SDL3 = NULL;
     #define DIRSEP "\\"
+    #ifdef SDL_BUILDING_WINRT
+    #define SDL3_LIBNAME L"SDL3.dll"
+    #define LoadSDL3Library() ((Loaded_SDL3 = LoadPackagedLibrary(SDL3_LIBNAME,0)) != NULL)
+    #else
     #define SDL3_LIBNAME "SDL3.dll"
-    static HMODULE Loaded_SDL3 = NULL;
     #define LoadSDL3Library() ((Loaded_SDL3 = LoadLibraryA(SDL3_LIBNAME)) != NULL)
+    #endif
     #define LookupSDL3Sym(sym) (void *)GetProcAddress(Loaded_SDL3, sym)
     #define CloseSDL3Library() { if (Loaded_SDL3) { FreeLibrary(Loaded_SDL3); Loaded_SDL3 = NULL; } }
 #elif defined(__APPLE__)
@@ -587,6 +592,7 @@ LoadSDL3(void)
     return okay;
 }
 
+#ifndef SDL_BUILDING_WINRT
 #if defined(_MSC_VER) && defined(_M_IX86)
 #include "x86_msvc.h"
 #endif
@@ -617,8 +623,11 @@ void *memset(void *dst, int c, size_t len)
     return SDL3_memset(dst, c, len);
 }
 #endif
+#endif  /* ! WINRT */
 
-#if defined(_WIN32)
+#ifdef SDL_BUILDING_WINRT
+EXTERN_C void error_dialog(const char *errorMsg);
+#elif defined(_WIN32)
 static void error_dialog(const char *errorMsg)
 {
     MessageBoxA(NULL, errorMsg, "Error", MB_OK | MB_SETFOREGROUND | MB_ICONSTOP);
diff --git a/src/sdl2_compat_winrt.cpp b/src/sdl2_compat_winrt.cpp
new file mode 100644
index 0000000..027cf9b
--- /dev/null
+++ b/src/sdl2_compat_winrt.cpp
@@ -0,0 +1,66 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2022 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.
+*/
+
+/* This file contains some WinRT-specific support code */
+
+#include <windows.h>
+
+#include <windows.ui.popups.h>
+using namespace Platform;
+using namespace Windows::Foundation;
+using namespace Windows::UI::Popups;
+
+static String ^ WINRT_PlatformString(const WCHAR *wstr)
+{
+    String ^ rtstr = ref new String(wstr);
+    return rtstr;
+}
+
+static String ^ WINRT_UTF8ToPlatformString(const char *str)
+{
+    WCHAR wstr[256];
+    unsigned int i;
+    for (i = 0; i < (ARRAYSIZE(wstr) - 1) && str[i]; i++) {
+        wstr[i] = (WCHAR) str[i]; /* low-ASCII maps to WCHAR directly. */
+    }
+    wstr[i] = 0;
+    return WINRT_PlatformString(wstr);
+}
+
+extern "C"
+void error_dialog(const char *errorMsg)
+{
+    /* Build a MessageDialog object and its buttons */
+    MessageDialog ^ dialog = ref new MessageDialog(WINRT_UTF8ToPlatformString(errorMsg));
+    dialog->Title = WINRT_PlatformString(L"Error");
+    UICommand ^ button = ref new UICommand(WINRT_PlatformString(L"OK"));
+    button->Id = IntPtr(0);
+    dialog->Commands->Append(button);
+    dialog->CancelCommandIndex = 0;
+    dialog->DefaultCommandIndex = 0;
+    /* Display the MessageDialog, then wait for it to be closed */
+    auto operation = dialog->ShowAsync();
+    while (operation->Status == Windows::Foundation::AsyncStatus::Started) {
+      /* do anything here? */ ;
+    }
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/sdl3_include_wrapper.h b/src/sdl3_include_wrapper.h
index 04f5cac..a939116 100644
--- a/src/sdl3_include_wrapper.h
+++ b/src/sdl3_include_wrapper.h
@@ -925,13 +925,6 @@
 #define SDL_WriteS32BE IGNORE_THIS_VERSION_OF_SDL_WriteS32BE
 #define SDL_WriteS64LE IGNORE_THIS_VERSION_OF_SDL_WriteS64LE
 
-#if defined(SDL_HAVE_WINAPIFAMILY_H)
-#include <winapifamily.h>
-#if (!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP))
-#define SDL2COMPAT_WINRT 1
-#endif
-#endif
-
 #define SDL_FUNCTION_POINTER_IS_VOID_POINTER 1
 #define SDL_DISABLE_OLD_NAMES 1
 #define __BUILDING_SDL2_COMPAT__ 1