From c9a45f288c4ae4f760e420780e86d31469b21ea3 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 11 Sep 2015 17:32:49 +0200 Subject: [PATCH] Proper display language detection on Windows --- direct/src/plugin/p3dCert.cxx | 56 ++++++++++++++++++++++++++- direct/src/plugin/p3dCert_strings.cxx | 2 +- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/direct/src/plugin/p3dCert.cxx b/direct/src/plugin/p3dCert.cxx index 6fa6c7d3e6..0d84e1058e 100644 --- a/direct/src/plugin/p3dCert.cxx +++ b/direct/src/plugin/p3dCert.cxx @@ -38,6 +38,7 @@ #define WIN32_LEAN_AND_MEAN #include #include +#include #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; } diff --git a/direct/src/plugin/p3dCert_strings.cxx b/direct/src/plugin/p3dCert_strings.cxx index 1f111cd645..bd191768e0 100644 --- a/direct/src/plugin/p3dCert_strings.cxx +++ b/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] = {