summaryrefslogtreecommitdiff
path: root/source/3rd-party/SDL2/src/core/windows/SDL_windows.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/3rd-party/SDL2/src/core/windows/SDL_windows.c')
-rw-r--r--source/3rd-party/SDL2/src/core/windows/SDL_windows.c233
1 files changed, 233 insertions, 0 deletions
diff --git a/source/3rd-party/SDL2/src/core/windows/SDL_windows.c b/source/3rd-party/SDL2/src/core/windows/SDL_windows.c
new file mode 100644
index 0000000..4da7d07
--- /dev/null
+++ b/source/3rd-party/SDL2/src/core/windows/SDL_windows.c
@@ -0,0 +1,233 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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 defined(__WIN32__) || defined(__WINRT__)
+
+#include "SDL_windows.h"
+#include "SDL_error.h"
+#include "SDL_assert.h"
+
+#include <objbase.h> /* for CoInitialize/CoUninitialize (Win32 only) */
+
+#ifndef _WIN32_WINNT_VISTA
+#define _WIN32_WINNT_VISTA 0x0600
+#endif
+#ifndef _WIN32_WINNT_WIN7
+#define _WIN32_WINNT_WIN7 0x0601
+#endif
+
+
+/* Sets an error message based on an HRESULT */
+int
+WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr)
+{
+ TCHAR buffer[1024];
+ char *message;
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 0,
+ buffer, SDL_arraysize(buffer), NULL);
+ message = WIN_StringToUTF8(buffer);
+ SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ": " : "", message);
+ SDL_free(message);
+ return -1;
+}
+
+/* Sets an error message based on GetLastError() */
+int
+WIN_SetError(const char *prefix)
+{
+ return WIN_SetErrorFromHRESULT(prefix, GetLastError());
+}
+
+HRESULT
+WIN_CoInitialize(void)
+{
+ /* SDL handles any threading model, so initialize with the default, which
+ is compatible with OLE and if that doesn't work, try multi-threaded mode.
+
+ If you need multi-threaded mode, call CoInitializeEx() before SDL_Init()
+ */
+#ifdef __WINRT__
+ /* DLudwig: On WinRT, it is assumed that COM was initialized in main().
+ CoInitializeEx is available (not CoInitialize though), however
+ on WinRT, main() is typically declared with the [MTAThread]
+ attribute, which, AFAIK, should initialize COM.
+ */
+ return S_OK;
+#else
+ HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ if (hr == RPC_E_CHANGED_MODE) {
+ hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
+ }
+
+ /* S_FALSE means success, but someone else already initialized. */
+ /* You still need to call CoUninitialize in this case! */
+ if (hr == S_FALSE) {
+ return S_OK;
+ }
+
+ return hr;
+#endif
+}
+
+void
+WIN_CoUninitialize(void)
+{
+#ifndef __WINRT__
+ CoUninitialize();
+#endif
+}
+
+#ifndef __WINRT__
+static BOOL
+IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
+{
+ OSVERSIONINFOEXW osvi;
+ DWORDLONG const dwlConditionMask = VerSetConditionMask(
+ VerSetConditionMask(
+ VerSetConditionMask(
+ 0, VER_MAJORVERSION, VER_GREATER_EQUAL ),
+ VER_MINORVERSION, VER_GREATER_EQUAL ),
+ VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL );
+
+ SDL_zero(osvi);
+ osvi.dwOSVersionInfoSize = sizeof(osvi);
+ osvi.dwMajorVersion = wMajorVersion;
+ osvi.dwMinorVersion = wMinorVersion;
+ osvi.wServicePackMajor = wServicePackMajor;
+
+ return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
+}
+#endif
+
+BOOL WIN_IsWindowsVistaOrGreater(void)
+{
+#ifdef __WINRT__
+ return TRUE;
+#else
+ return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0);
+#endif
+}
+
+BOOL WIN_IsWindows7OrGreater(void)
+{
+#ifdef __WINRT__
+ return TRUE;
+#else
+ return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0);
+#endif
+}
+
+/*
+WAVExxxCAPS gives you 31 bytes for the device name, and just truncates if it's
+longer. However, since WinXP, you can use the WAVExxxCAPS2 structure, which
+will give you a name GUID. The full name is in the Windows Registry under
+that GUID, located here: HKLM\System\CurrentControlSet\Control\MediaCategories
+
+Note that drivers can report GUID_NULL for the name GUID, in which case,
+Windows makes a best effort to fill in those 31 bytes in the usual place.
+This info summarized from MSDN:
+
+http://web.archive.org/web/20131027093034/http://msdn.microsoft.com/en-us/library/windows/hardware/ff536382(v=vs.85).aspx
+
+Always look this up in the registry if possible, because the strings are
+different! At least on Win10, I see "Yeti Stereo Microphone" in the
+Registry, and a unhelpful "Microphone(Yeti Stereo Microph" in winmm. Sigh.
+
+(Also, DirectSound shouldn't be limited to 32 chars, but its device enum
+has the same problem.)
+
+WASAPI doesn't need this. This is just for DirectSound/WinMM.
+*/
+char *
+WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid)
+{
+#if __WINRT__
+ return WIN_StringToUTF8(name); /* No registry access on WinRT/UWP, go with what we've got. */
+#else
+ static const GUID nullguid = { 0 };
+ const unsigned char *ptr;
+ char keystr[128];
+ WCHAR *strw = NULL;
+ SDL_bool rc;
+ HKEY hkey;
+ DWORD len = 0;
+ char *retval = NULL;
+
+ if (WIN_IsEqualGUID(guid, &nullguid)) {
+ return WIN_StringToUTF8(name); /* No GUID, go with what we've got. */
+ }
+
+ ptr = (const unsigned char *) guid;
+ SDL_snprintf(keystr, sizeof (keystr),
+ "System\\CurrentControlSet\\Control\\MediaCategories\\{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
+ 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);
+ rc = (RegOpenKeyExW(HKEY_LOCAL_MACHINE, strw, 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS);
+ SDL_free(strw);
+ if (!rc) {
+ return WIN_StringToUTF8(name); /* oh well. */
+ }
+
+ rc = (RegQueryValueExW(hkey, L"Name", NULL, NULL, NULL, &len) == ERROR_SUCCESS);
+ if (!rc) {
+ RegCloseKey(hkey);
+ return WIN_StringToUTF8(name); /* oh well. */
+ }
+
+ strw = (WCHAR *) SDL_malloc(len + sizeof (WCHAR));
+ if (!strw) {
+ RegCloseKey(hkey);
+ return WIN_StringToUTF8(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. */
+ }
+
+ strw[len / 2] = 0; /* make sure it's null-terminated. */
+
+ retval = WIN_StringToUTF8(strw);
+ SDL_free(strw);
+ return retval ? retval : WIN_StringToUTF8(name);
+#endif /* if __WINRT__ / else */
+}
+
+BOOL
+WIN_IsEqualGUID(const GUID * a, const GUID * b)
+{
+ return (SDL_memcmp(a, b, sizeof (*a)) == 0);
+}
+
+BOOL
+WIN_IsEqualIID(REFIID a, REFIID b)
+{
+ return (SDL_memcmp(a, b, sizeof (*a)) == 0);
+}
+
+#endif /* __WIN32__ || __WINRT__ */
+
+/* vi: set ts=4 sw=4 expandtab: */