SDL: windows: fix Unicode function and type inconsistencies

From 37b86a6d2fee03136af4eddf14255f10353cfb6b Mon Sep 17 00:00:00 2001
From: nmlgc <[EMAIL REDACTED]>
Date: Sat, 12 Apr 2025 20:04:27 +0200
Subject: [PATCH] windows: fix Unicode function and type inconsistencies

The surrounding code in all of these instances expects the Unicode
variants. Previously, this code mixed Unicode and ANSI/ASCII calls if
`UNICODE` was undefined, which caused type and logic errors. Explicitly
spelling out the W removes any reliance on that macro.
---
 .../mediafoundation/SDL_camera_mediafoundation.c |  4 ++--
 src/core/windows/SDL_windows.c                   | 16 ++++++++--------
 src/filesystem/windows/SDL_sysfilesystem.c       |  2 +-
 src/joystick/windows/SDL_dinputjoystick.c        |  2 +-
 src/video/windows/SDL_windowsclipboard.c         |  4 ++--
 src/video/windows/SDL_windowsmodes.c             | 10 +++++-----
 src/video/windows/SDL_windowsmodes.h             |  2 +-
 src/video/windows/SDL_windowswindow.c            |  8 ++++----
 8 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/src/camera/mediafoundation/SDL_camera_mediafoundation.c b/src/camera/mediafoundation/SDL_camera_mediafoundation.c
index d9d627d0ab26a..aec728ea8f919 100644
--- a/src/camera/mediafoundation/SDL_camera_mediafoundation.c
+++ b/src/camera/mediafoundation/SDL_camera_mediafoundation.c
@@ -741,7 +741,7 @@ static bool MEDIAFOUNDATION_OpenDevice(SDL_Camera *device, const SDL_CameraSpec
     SDL_Log("CAMERA: opening device with symlink of '%s'", utf8symlink);
     #endif
 
-    wstrsymlink = WIN_UTF8ToString(utf8symlink);
+    wstrsymlink = WIN_UTF8ToStringW(utf8symlink);
     if (!wstrsymlink) {
         goto failed;
     }
@@ -901,7 +901,7 @@ static char *QueryActivationObjectString(IMFActivate *activation, const GUID *pg
         return NULL;
     }
 
-    char *utf8str = WIN_StringToUTF8(wstr);
+    char *utf8str = WIN_StringToUTF8W(wstr);
     CoTaskMemFree(wstr);
     return utf8str;
 }
diff --git a/src/core/windows/SDL_windows.c b/src/core/windows/SDL_windows.c
index 3259e787d4eb6..d96d8e0bbadcf 100644
--- a/src/core/windows/SDL_windows.c
+++ b/src/core/windows/SDL_windows.c
@@ -261,7 +261,7 @@ char *WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid)
     char *result = NULL;
 
     if (WIN_IsEqualGUID(guid, &nullguid)) {
-        return WIN_StringToUTF8(name); // No GUID, go with what we've got.
+        return WIN_StringToUTF8W(name); // No GUID, go with what we've got.
     }
 
     ptr = (const unsigned char *)guid;
@@ -270,37 +270,37 @@ char *WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid)
                        ptr[3], ptr[2], ptr[1], ptr[0], ptr[5], ptr[4], ptr[7], ptr[6],
                        ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15]);
 
-    strw = WIN_UTF8ToString(keystr);
+    strw = WIN_UTF8ToStringW(keystr);
     rc = (RegOpenKeyExW(HKEY_LOCAL_MACHINE, strw, 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS);
     SDL_free(strw);
     if (!rc) {
-        return WIN_StringToUTF8(name); // oh well.
+        return WIN_StringToUTF8W(name); // oh well.
     }
 
     rc = (RegQueryValueExW(hkey, L"Name", NULL, NULL, NULL, &len) == ERROR_SUCCESS);
     if (!rc) {
         RegCloseKey(hkey);
-        return WIN_StringToUTF8(name); // oh well.
+        return WIN_StringToUTF8W(name); // oh well.
     }
 
     strw = (WCHAR *)SDL_malloc(len + sizeof(WCHAR));
     if (!strw) {
         RegCloseKey(hkey);
-        return WIN_StringToUTF8(name); // oh well.
+        return WIN_StringToUTF8W(name); // oh well.
     }
 
     rc = (RegQueryValueExW(hkey, L"Name", NULL, NULL, (LPBYTE)strw, &len) == ERROR_SUCCESS);
     RegCloseKey(hkey);
     if (!rc) {
         SDL_free(strw);
-        return WIN_StringToUTF8(name); // oh well.
+        return WIN_StringToUTF8W(name); // oh well.
     }
 
     strw[len / 2] = 0; // make sure it's null-terminated.
 
-    result = WIN_StringToUTF8(strw);
+    result = WIN_StringToUTF8W(strw);
     SDL_free(strw);
-    return result ? result : WIN_StringToUTF8(name);
+    return result ? result : WIN_StringToUTF8W(name);
 #endif
 }
 
diff --git a/src/filesystem/windows/SDL_sysfilesystem.c b/src/filesystem/windows/SDL_sysfilesystem.c
index 39ba414895177..a4c033f068a03 100644
--- a/src/filesystem/windows/SDL_sysfilesystem.c
+++ b/src/filesystem/windows/SDL_sysfilesystem.c
@@ -181,7 +181,7 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app)
 char *SDL_SYS_GetUserFolder(SDL_Folder folder)
 {
     typedef HRESULT (WINAPI *pfnSHGetKnownFolderPath)(REFGUID /* REFKNOWNFOLDERID */, DWORD, HANDLE, PWSTR*);
-    HMODULE lib = LoadLibrary(L"Shell32.dll");
+    HMODULE lib = LoadLibraryW(L"Shell32.dll");
     pfnSHGetKnownFolderPath pSHGetKnownFolderPath = NULL;
     char *result = NULL;
 
diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c
index b00218d969c0e..a96388239f2e9 100644
--- a/src/joystick/windows/SDL_dinputjoystick.c
+++ b/src/joystick/windows/SDL_dinputjoystick.c
@@ -293,7 +293,7 @@ static bool QueryDeviceName(LPDIRECTINPUTDEVICE8 device, Uint16 vendor_id, Uint1
     }
 
     *manufacturer_string = NULL;
-    *product_string = WIN_StringToUTF8(dipstr.wsz);
+    *product_string = WIN_StringToUTF8W(dipstr.wsz);
 
     return true;
 }
diff --git a/src/video/windows/SDL_windowsclipboard.c b/src/video/windows/SDL_windowsclipboard.c
index 39f86ef32f34c..4d1e97666f788 100644
--- a/src/video/windows/SDL_windowsclipboard.c
+++ b/src/video/windows/SDL_windowsclipboard.c
@@ -193,7 +193,7 @@ static bool WIN_SetClipboardText(SDL_VideoDevice *_this, const char *mime_type)
     clipboard_data = _this->clipboard_callback(_this->clipboard_userdata, mime_type, &clipboard_data_size);
     if (clipboard_data && clipboard_data_size > 0) {
         SIZE_T i, size;
-        LPTSTR tstr = (WCHAR *)SDL_iconv_string("UTF-16LE", "UTF-8", (const char *)clipboard_data, clipboard_data_size);
+        LPWSTR tstr = (WCHAR *)SDL_iconv_string("UTF-16LE", "UTF-8", (const char *)clipboard_data, clipboard_data_size);
         if (!tstr) {
             return SDL_SetError("Couldn't convert text from UTF-8");
         }
@@ -210,7 +210,7 @@ static bool WIN_SetClipboardText(SDL_VideoDevice *_this, const char *mime_type)
         // Save the data to the clipboard
         hMem = GlobalAlloc(GMEM_MOVEABLE, size);
         if (hMem) {
-            LPTSTR dst = (LPTSTR)GlobalLock(hMem);
+            LPWSTR dst = (LPWSTR)GlobalLock(hMem);
             if (dst) {
                 // Copy the text over, adding carriage returns as necessary
                 for (i = 0; tstr[i]; ++i) {
diff --git a/src/video/windows/SDL_windowsmodes.c b/src/video/windows/SDL_windowsmodes.c
index 77ebab29a5765..34c5bd7316b01 100644
--- a/src/video/windows/SDL_windowsmodes.c
+++ b/src/video/windows/SDL_windowsmodes.c
@@ -46,7 +46,7 @@ static void WIN_UpdateDisplayMode(SDL_VideoDevice *_this, LPCWSTR deviceName, DW
     data->DeviceMode.dmFields = (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS);
 
     // NOLINTNEXTLINE(bugprone-assignment-in-if-condition): No simple way to extract the assignment
-    if (index == ENUM_CURRENT_SETTINGS && (hdc = CreateDC(deviceName, NULL, NULL, NULL)) != NULL) {
+    if (index == ENUM_CURRENT_SETTINGS && (hdc = CreateDCW(deviceName, NULL, NULL, NULL)) != NULL) {
         char bmi_data[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
         LPBITMAPINFO bmi;
         HBITMAP hbm;
@@ -158,7 +158,7 @@ static void WIN_ReleaseDXGIOutput(void *dxgi_output)
 #endif
 }
 
-static SDL_DisplayOrientation WIN_GetNaturalOrientation(DEVMODE *mode)
+static SDL_DisplayOrientation WIN_GetNaturalOrientation(DEVMODEW *mode)
 {
     int width = mode->dmPelsWidth;
     int height = mode->dmPelsHeight;
@@ -177,7 +177,7 @@ static SDL_DisplayOrientation WIN_GetNaturalOrientation(DEVMODE *mode)
     }
 }
 
-static SDL_DisplayOrientation WIN_GetDisplayOrientation(DEVMODE *mode)
+static SDL_DisplayOrientation WIN_GetDisplayOrientation(DEVMODEW *mode)
 {
     if (WIN_GetNaturalOrientation(mode) == SDL_ORIENTATION_LANDSCAPE) {
         switch (mode->dmDisplayOrientation) {
@@ -208,7 +208,7 @@ static SDL_DisplayOrientation WIN_GetDisplayOrientation(DEVMODE *mode)
     }
 }
 
-static void WIN_GetRefreshRate(void *dxgi_output, DEVMODE *mode, int *numerator, int *denominator)
+static void WIN_GetRefreshRate(void *dxgi_output, DEVMODEW *mode, int *numerator, int *denominator)
 {
     // We're not currently using DXGI to query display modes, so fake NTSC timings
     switch (mode->dmDisplayFrequency) {
@@ -274,7 +274,7 @@ static float WIN_GetContentScale(SDL_VideoDevice *_this, HMONITOR hMonitor)
 static bool WIN_GetDisplayMode(SDL_VideoDevice *_this, void *dxgi_output, HMONITOR hMonitor, LPCWSTR deviceName, DWORD index, SDL_DisplayMode *mode, SDL_DisplayOrientation *natural_orientation, SDL_DisplayOrientation *current_orientation)
 {
     SDL_DisplayModeData *data;
-    DEVMODE devmode;
+    DEVMODEW devmode;
 
     devmode.dmSize = sizeof(devmode);
     devmode.dmDriverExtra = 0;
diff --git a/src/video/windows/SDL_windowsmodes.h b/src/video/windows/SDL_windowsmodes.h
index 3d294c31f0e4b..e49817ca9540c 100644
--- a/src/video/windows/SDL_windowsmodes.h
+++ b/src/video/windows/SDL_windowsmodes.h
@@ -41,7 +41,7 @@ struct SDL_DisplayData
 
 struct SDL_DisplayModeData
 {
-    DEVMODE DeviceMode;
+    DEVMODEW DeviceMode;
 };
 
 extern bool WIN_InitModes(SDL_VideoDevice *_this);
diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c
index 079f3ba345203..f61dc0e8f8d24 100644
--- a/src/video/windows/SDL_windowswindow.c
+++ b/src/video/windows/SDL_windowswindow.c
@@ -1450,7 +1450,7 @@ void *WIN_GetWindowICCProfile(SDL_VideoDevice *_this, SDL_Window *window, size_t
     char *filename_utf8;
     void *iccProfileData = NULL;
 
-    filename_utf8 = WIN_StringToUTF8(data->ICMFileName);
+    filename_utf8 = WIN_StringToUTF8W(data->ICMFileName);
     if (filename_utf8) {
         iccProfileData = SDL_LoadFile(filename_utf8, size);
         if (!iccProfileData) {
@@ -2061,7 +2061,7 @@ static STDMETHODIMP SDLDropTarget_Drop(SDLDropTarget *target,
                              ". In Drop Text for   GlobalLock, format %08x '%s', memory (%lu) %p",
                              fetc.cfFormat, format_mime, (unsigned long)bsize, buffer);
                 if (buffer) {
-                    buffer = WIN_StringToUTF8((const wchar_t *)buffer);
+                    buffer = WIN_StringToUTF8W((const wchar_t *)buffer);
                     if (buffer) {
                         const size_t lbuffer = SDL_strlen((const char *)buffer);
                         SDL_LogTrace(SDL_LOG_CATEGORY_INPUT,
@@ -2208,8 +2208,8 @@ void WIN_AcceptDragAndDrop(SDL_Window *window, bool accept)
                 drop_target->lpVtbl = vtDropTarget;
                 drop_target->window = window;
                 drop_target->hwnd = data->hwnd;
-                drop_target->format_file = RegisterClipboardFormat(L"text/uri-list");
-                drop_target->format_text = RegisterClipboardFormat(L"text/plain;charset=utf-8");
+                drop_target->format_file = RegisterClipboardFormatW(L"text/uri-list");
+                drop_target->format_text = RegisterClipboardFormatW(L"text/plain;charset=utf-8");
                 data->drop_target = drop_target;
                 SDLDropTarget_AddRef(drop_target);
                 RegisterDragDrop(data->hwnd, (LPDROPTARGET)drop_target);