From 27902c01cc74d5d50378aa31eb6c59730d9287ab Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Mon, 8 Apr 2024 12:57:12 +0200 Subject: Fixed choosing preferred language on Windows The linker could not find _nl_locale_name_default. Maybe it could be fixed by linking to another library, but it would likely not yield the preferred behavior. Instead, we now use GetUserPreferredUILanguages to set the LANG environment variable with one or more languages and let gettext choose the best fitting available translation. Also fixed the directory from which the translations are loaded to match the installation directory, --- CMakeLists.txt | 4 ++-- src/main.cpp | 43 ++++++++++++++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 889d8482..b13ead11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,14 +25,14 @@ SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake/Modules) FIND_PACKAGE(Gettext) OPTION(WITH_OPENGL "Enable OpenGL support" ON) -OPTION(ENABLE_NLS "Enable building of tranlations" ON) +OPTION(ENABLE_NLS "Enable building of translations" ON) OPTION(ENABLE_MANASERV "Enable Manaserv support" ON) OPTION(USE_SYSTEM_GUICHAN "Use system Guichan" ON) IF (WIN32) SET(PKG_DATADIR ".") + SET(LOCALEDIR "share/locale") SET(PKG_BINDIR ".") - SET(LOCALEDIR ".") ELSE (WIN32) SET(PKG_DATADIR ${CMAKE_INSTALL_PREFIX}/share/mana CACHE PATH "Mana datadir") SET(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale) diff --git a/src/main.cpp b/src/main.cpp index 7b9e921e..68a6b0c3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,6 +33,9 @@ #ifdef __MINGW32__ #include #endif +#if ENABLE_NLS && defined(_WIN32) +#include +#endif static void printHelp() { @@ -178,24 +181,42 @@ static void parseOptions(int argc, char *argv[], Client::Options &options) } } -#ifdef _WIN32 -//extern "C" char const *_nl_locale_name_default(void); -#endif - static void initInternationalization() { #if ENABLE_NLS #ifdef _WIN32 -// SetEnvironmentVariable("LANG", _nl_locale_name_default()); - // mingw doesn't like LOCALEDIR to be defined for some reason - bindtextdomain("mana", "translations/"); -#else - bindtextdomain("mana", LOCALEDIR); -#endif + // On Windows we need to set the LANG environment variable to get the + // correct translation, because this isn't set by default. + ULONG numLanguages = 0; + ULONG bufferSize = 0; + if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numLanguages, nullptr, &bufferSize)) + return; + if (numLanguages == 0 || bufferSize < 2) + return; + + std::wstring localeNamesW(bufferSize, L'\0'); + if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numLanguages, localeNamesW.data(), &bufferSize)) + return; + + // Replace the null characters used as separators with a colon, except for + // the last two. Also replace - with _, since gettext expects de_DE rather + // than de-DE. + for (size_t i = 0; i < localeNamesW.size() - 2; ++i) { + auto &c = localeNamesW[i]; + if (c == L'\0') + c = L':'; + else if (c == L'-') + c = L'_'; + } + + _wputenv_s(L"LANG", localeNamesW.c_str()); +#endif // _WIN32 + setlocale(LC_MESSAGES, ""); + bindtextdomain("mana", LOCALEDIR); bind_textdomain_codeset("mana", "UTF-8"); textdomain("mana"); -#endif +#endif // ENABLE_NLS } -- cgit v1.2.3-60-g2f50