Browse Source

Proper display language detection on Windows

rdb 10 years ago
parent
commit
c9a45f288c
2 changed files with 56 additions and 2 deletions
  1. 55 1
      direct/src/plugin/p3dCert.cxx
  2. 1 1
      direct/src/plugin/p3dCert_strings.cxx

+ 55 - 1
direct/src/plugin/p3dCert.cxx

@@ -38,6 +38,7 @@
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <shellapi.h>
+#include <malloc.h>
 
 #define snprintf sprintf_s
 #endif
@@ -48,7 +49,51 @@
 
 static LanguageIndex li = LI_default;
 
-#ifdef __APPLE__
+#if defined(_WIN32)
+static LanguageIndex detect_language() {
+  // This function was introduced in Windows Vista; it may not be available
+  // on older systems.
+  typedef BOOL (*GUPL)(DWORD, PULONG, PZZWSTR, PULONG);
+  GUPL pGetUserPreferredUILanguages = (GUPL)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
+                                                           TEXT("GetUserPreferredUILanguages"));
+  if (pGetUserPreferredUILanguages != NULL) {
+    ULONG num_langs = 0;
+    ULONG buffer_size = 0;
+    pGetUserPreferredUILanguages(8, &num_langs, NULL, &buffer_size);
+    PZZWSTR buffer = (PZZWSTR)_alloca(buffer_size);
+    if (pGetUserPreferredUILanguages(8, &num_langs, buffer, &buffer_size)) {
+      for (ULONG i = 0; i < num_langs; ++i) {
+        size_t len = wcslen(buffer);
+        if (len >= 2 && (buffer[2] == 0 || buffer[2] == L'-')) {
+          // It may be a two-letter code; match it in our list.
+          for (int j = 0; j < LI_COUNT; ++j) {
+            const char *lang_code = language_codes[j];
+            if (lang_code != NULL && lang_code[0] == buffer[0] &&
+                                     lang_code[1] == buffer[1]) {
+              return (LanguageIndex)j;
+            }
+          }
+        }
+        buffer += len + 1;
+      }
+    }
+  }
+
+  // Fall back to the old Windows XP function.
+  LANGID lang = GetUserDefaultUILanguage() & 0x3ff;
+  if (lang == 0) {
+    return LI_default;
+  }
+
+  for (int i = 0; i < LI_COUNT; ++i) {
+    if (language_ids[i] != 0 && language_ids[i] == lang) {
+      return (LanguageIndex)i;
+    }
+  }
+  return LI_default;
+}
+
+#elif defined(__APPLE__)
 static LanguageIndex detect_language() {
   // Get and iterate through the list of preferred languages.
   CFArrayRef langs = CFLocaleCopyPreferredLanguages();
@@ -86,6 +131,7 @@ static LanguageIndex detect_language() {
   CFRelease(langs);
   return LI_default;
 }
+
 #else
 static LanguageIndex detect_language() {
   // First consult the LANGUAGE variable, which is a GNU extension that can
@@ -364,12 +410,20 @@ read_cert_file(const string &cert_filename) {
 #endif  // _WIN32
 
   if (fp == NULL) {
+#ifdef _WIN32
+    wcerr << L"Couldn't read " << cert_filename.c_str() << L"\n";
+#else
     cerr << "Couldn't read " << cert_filename.c_str() << "\n";
+#endif
     return;
   }
   _cert = PEM_read_X509(fp, NULL, NULL, (void *)"");
   if (_cert == NULL) {
+#ifdef _WIN32
+    wcerr << L"Could not read certificate in " << cert_filename.c_str() << L".\n";
+#else
     cerr << "Could not read certificate in " << cert_filename.c_str() << ".\n";
+#endif
     fclose(fp);
     return;
   }

+ 1 - 1
direct/src/plugin/p3dCert_strings.cxx

@@ -27,7 +27,7 @@ const char *language_codes[LI_COUNT] =
 
 // https://msdn.microsoft.com/en-us/library/windows/desktop/dd318693%28v=vs.85%29.aspx
 const unsigned char language_ids[LI_COUNT] =
-  {0x09, 0x13, 0x07, 0x0A, 0x10, 0, 0x19};
+  {0x09, 0x13, 0x07, 0x0A, 0x10, 0x8F, 0x19};
 
 const char *
 run_title[LI_COUNT] = {