2008-03-15 10:53:10 -07:00
|
|
|
/*
|
|
|
|
This file is part of Warzone 2100.
|
|
|
|
Copyright (C) 2005-2008 Warzone Resurrection Project
|
|
|
|
|
|
|
|
Warzone 2100 is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
Warzone 2100 is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with Warzone 2100; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
#include "frame.h"
|
|
|
|
|
2008-03-23 12:29:41 -07:00
|
|
|
#include <locale.h>
|
2008-03-22 12:11:29 -07:00
|
|
|
#include <physfs.h>
|
2008-03-15 10:53:10 -07:00
|
|
|
|
|
|
|
|
|
|
|
/* Always use fallbacks on Windows */
|
|
|
|
#if defined(WZ_OS_WIN)
|
|
|
|
# undef LOCALEDIR
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if !defined(LOCALEDIR)
|
|
|
|
# define LOCALEDIR "locale"
|
|
|
|
#endif
|
|
|
|
|
2008-03-23 12:22:09 -07:00
|
|
|
|
|
|
|
#if defined(WZ_OS_WIN)
|
2008-04-05 09:22:05 -07:00
|
|
|
static const struct
|
2008-03-22 11:30:08 -07:00
|
|
|
{
|
2008-03-23 12:22:09 -07:00
|
|
|
const char * language;
|
|
|
|
const char * name;
|
|
|
|
USHORT usPrimaryLanguage;
|
|
|
|
} map[] = {
|
|
|
|
{ "", N_("System locale"), LANG_NEUTRAL },
|
|
|
|
# if defined(ENABLE_NLS)
|
|
|
|
{ "da", N_("Danish"), LANG_DANISH },
|
|
|
|
{ "de", N_("German"), LANG_GERMAN },
|
|
|
|
{ "en", N_("English"), LANG_ENGLISH },
|
|
|
|
{ "fr", N_("French"), LANG_FRENCH },
|
|
|
|
{ "it", N_("Italian"), LANG_ITALIAN },
|
|
|
|
{ "nl", N_("Dutch"), LANG_DUTCH },
|
|
|
|
{ "nb", N_("Norwegian"), LANG_NORWEGIAN },
|
|
|
|
{ "pt", N_("Portuegese"), LANG_PORTUGUESE },
|
|
|
|
{ "ru", N_("Russian"), LANG_RUSSIAN },
|
|
|
|
{ "sv", N_("Swedish"), LANG_SWEDISH },
|
|
|
|
# endif
|
2008-03-22 11:30:08 -07:00
|
|
|
};
|
2008-03-23 12:22:09 -07:00
|
|
|
#else
|
2008-04-05 09:22:05 -07:00
|
|
|
static const struct
|
2008-03-22 11:30:08 -07:00
|
|
|
{
|
2008-03-23 12:22:09 -07:00
|
|
|
const char *language;
|
|
|
|
const char *name;
|
|
|
|
const char *locale;
|
|
|
|
const char *localeFallback;
|
|
|
|
} map[] = {
|
2008-03-22 11:30:08 -07:00
|
|
|
{ "", N_("System locale"), "", "" },
|
2008-03-23 12:22:09 -07:00
|
|
|
# if defined(ENABLE_NLS)
|
|
|
|
{ "en", N_("English"), "en_US.UTF-8", "en_US" },
|
|
|
|
{ "nb", N_("Norwegian"), "nb_NO.UTF-8", "nb_NO" },
|
|
|
|
{ "de", N_("German"), "de_DE.UTF-8", "de_DE" },
|
|
|
|
{ "da", N_("Danish"), "da_DK.UTF-8", "da_DK" },
|
|
|
|
{ "fr", N_("French"), "fr_FR.UTF-8", "fr_FR" },
|
|
|
|
{ "it", N_("Italian"), "it_IT.UTF-8", "it_IT" },
|
|
|
|
{ "la", N_("Latin"), "la.UTF-8", "la" },
|
|
|
|
{ "nl", N_("Dutch"), "nl_NL.UTF-8", "nl_NL" },
|
|
|
|
{ "pt", N_("Portuegese"), "pt_PT.UTF-8", "pt_PT" },
|
|
|
|
{ "ru", N_("Russian"), "ru_RU.UTF-8", "ru_RU" },
|
|
|
|
# endif
|
2008-03-22 11:30:08 -07:00
|
|
|
};
|
2008-03-23 12:22:09 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
static unsigned int selectedLanguage = 0;
|
2008-03-22 11:30:08 -07:00
|
|
|
|
|
|
|
|
2008-03-23 12:22:09 -07:00
|
|
|
/*!
|
|
|
|
* Return the language part of the selected locale
|
|
|
|
*/
|
|
|
|
#if !defined(ENABLE_NLS)
|
|
|
|
const char* getLanguage(void)
|
2008-03-22 11:30:08 -07:00
|
|
|
{
|
2008-03-23 12:22:09 -07:00
|
|
|
return "";
|
|
|
|
}
|
|
|
|
#elif defined(WZ_OS_WIN)
|
|
|
|
const char *getLanguage(void)
|
|
|
|
{
|
|
|
|
USHORT usPrimaryLanguage = PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale()));
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
if (selectedLanguage == 0)
|
|
|
|
{
|
|
|
|
return ""; // Return empty string for system default
|
|
|
|
}
|
2008-03-22 11:30:08 -07:00
|
|
|
|
2008-03-23 12:22:09 -07:00
|
|
|
for (i = 0; i < ARRAY_SIZE(map); i++)
|
2008-03-22 11:30:08 -07:00
|
|
|
{
|
2008-03-23 12:22:09 -07:00
|
|
|
if (usPrimaryLanguage == map[i].usPrimaryLanguage)
|
2008-03-22 11:30:08 -07:00
|
|
|
{
|
2008-03-23 12:22:09 -07:00
|
|
|
return map[i].language;
|
2008-03-22 11:30:08 -07:00
|
|
|
}
|
|
|
|
}
|
2008-03-15 10:53:10 -07:00
|
|
|
|
2008-03-23 12:22:09 -07:00
|
|
|
return "";
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
const char *getLanguage(void)
|
2008-03-15 10:53:10 -07:00
|
|
|
{
|
|
|
|
static char language[4] = { '\0' }; // ISO639 language code has to fit in!
|
2008-03-23 12:22:09 -07:00
|
|
|
const char *localeName = setlocale(LC_MESSAGES, NULL);
|
2008-03-22 11:30:08 -07:00
|
|
|
char *delim = NULL;
|
2008-03-15 10:53:10 -07:00
|
|
|
|
2008-03-23 12:22:09 -07:00
|
|
|
if (selectedLanguage == 0 || localeName == NULL)
|
2008-03-22 11:30:08 -07:00
|
|
|
{
|
2008-03-23 12:22:09 -07:00
|
|
|
return ""; // Return empty string for system default and errors
|
2008-03-22 11:30:08 -07:00
|
|
|
}
|
2008-03-15 10:53:10 -07:00
|
|
|
|
2008-05-25 06:46:49 -07:00
|
|
|
sstrcpy(language, localeName);
|
2008-03-15 10:53:10 -07:00
|
|
|
|
2008-03-22 11:30:08 -07:00
|
|
|
delim = strchr(language, '_');
|
2008-03-15 10:53:10 -07:00
|
|
|
|
2008-03-22 11:30:08 -07:00
|
|
|
if ( !delim )
|
|
|
|
{
|
|
|
|
delim = strchr(language, '.');
|
|
|
|
}
|
2008-03-15 10:53:10 -07:00
|
|
|
|
2008-03-23 12:22:09 -07:00
|
|
|
if ( delim ) // Cut after '_' or '.'
|
2008-03-22 11:30:08 -07:00
|
|
|
{
|
|
|
|
*delim = '\0';
|
2008-03-15 10:53:10 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return language;
|
|
|
|
}
|
2008-03-23 12:22:09 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
const char* getLanguageName(void)
|
|
|
|
{
|
|
|
|
const char *language = getLanguage();
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(map); i++)
|
|
|
|
{
|
|
|
|
if (strcmp(language, map[i].language) == 0)
|
|
|
|
{
|
|
|
|
return gettext(map[i].name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-03-24 09:51:17 -07:00
|
|
|
ASSERT(false, "getLanguageName: Unknown language");
|
2008-03-23 12:22:09 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-03-15 10:53:10 -07:00
|
|
|
|
2008-03-23 12:22:09 -07:00
|
|
|
|
|
|
|
#if defined(ENABLE_NLS)
|
|
|
|
# if defined(WZ_OS_WIN)
|
|
|
|
static BOOL setLocaleWindows(USHORT usPrimaryLanguage)
|
|
|
|
{
|
|
|
|
BOOL success = SUCCEEDED( SetThreadLocale( MAKELCID( MAKELANGID(usPrimaryLanguage, SUBLANG_DEFAULT), SORT_DEFAULT ) ) );
|
|
|
|
|
|
|
|
if (!success)
|
|
|
|
debug(LOG_ERROR, "Failed to set locale to \"%d\"", usPrimaryLanguage);
|
|
|
|
else
|
|
|
|
debug(LOG_WZ, "Requested locale \"%d\"", usPrimaryLanguage);
|
|
|
|
|
|
|
|
setlocale(LC_NUMERIC, "C"); // set radix character to the period (".")
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
# else
|
2008-03-15 10:53:10 -07:00
|
|
|
/*!
|
2008-03-22 11:30:08 -07:00
|
|
|
* Set the prefered locale
|
2008-03-15 10:53:10 -07:00
|
|
|
* \param locale The locale, NOT just the language part
|
2008-03-23 12:22:09 -07:00
|
|
|
* \note Use this instead of setlocale(), because we need the default radix character
|
2008-03-15 10:53:10 -07:00
|
|
|
*/
|
2008-03-23 12:22:09 -07:00
|
|
|
static BOOL setLocaleUnix(const char* locale)
|
2008-03-15 10:53:10 -07:00
|
|
|
{
|
2008-03-23 12:22:09 -07:00
|
|
|
const char *actualLocale = setlocale(LC_ALL, locale);
|
2008-03-23 07:18:23 -07:00
|
|
|
|
2008-03-23 12:22:09 -07:00
|
|
|
if (actualLocale == NULL)
|
|
|
|
debug(LOG_ERROR, "Failed to set locale to \"%s\"", locale);
|
|
|
|
else
|
|
|
|
debug(LOG_WZ, "Requested locale \"%s\", got \"%s\" instead", locale, actualLocale);
|
2008-03-22 11:30:08 -07:00
|
|
|
|
2008-03-15 10:53:10 -07:00
|
|
|
setlocale(LC_NUMERIC, "C"); // set radix character to the period (".")
|
2008-03-22 11:30:08 -07:00
|
|
|
|
2008-03-23 12:22:09 -07:00
|
|
|
return (actualLocale != NULL);
|
2008-03-15 10:53:10 -07:00
|
|
|
}
|
2008-03-23 12:22:09 -07:00
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
2008-03-15 10:53:10 -07:00
|
|
|
|
2008-03-23 12:22:09 -07:00
|
|
|
BOOL setLanguage(const char *language)
|
2008-03-22 11:30:08 -07:00
|
|
|
{
|
2008-03-23 12:22:09 -07:00
|
|
|
#if !defined(ENABLE_NLS)
|
2008-03-24 09:51:17 -07:00
|
|
|
return true;
|
2008-03-23 12:22:09 -07:00
|
|
|
#else
|
|
|
|
unsigned int i;
|
2008-03-22 11:30:08 -07:00
|
|
|
|
2008-03-23 12:22:09 -07:00
|
|
|
for (i = 0; i < ARRAY_SIZE(map); i++)
|
2008-03-22 11:30:08 -07:00
|
|
|
{
|
2008-03-23 12:22:09 -07:00
|
|
|
if (strcmp(language, map[i].language) == 0)
|
2008-03-22 11:30:08 -07:00
|
|
|
{
|
2008-03-23 12:22:09 -07:00
|
|
|
selectedLanguage = i;
|
|
|
|
debug(LOG_WZ, "Setting language to \"%s\" (%s)", map[i].name, map[i].language);
|
|
|
|
|
|
|
|
# if defined(WZ_OS_WIN)
|
|
|
|
return setLocaleWindows(map[i].usPrimaryLanguage);
|
|
|
|
# else
|
|
|
|
return setLocaleUnix(map[i].locale) || setLocaleUnix(map[i].localeFallback);
|
|
|
|
# endif
|
2008-03-22 11:30:08 -07:00
|
|
|
}
|
|
|
|
}
|
2008-03-23 12:22:09 -07:00
|
|
|
|
|
|
|
debug(LOG_ERROR, "Requested language \"%s\" not supported.", language);
|
|
|
|
|
2008-03-24 09:51:17 -07:00
|
|
|
return false;
|
2008-03-23 12:22:09 -07:00
|
|
|
#endif
|
2008-03-22 11:30:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-23 12:22:09 -07:00
|
|
|
void setNextLanguage(void)
|
|
|
|
{
|
|
|
|
selectedLanguage++;
|
|
|
|
if (selectedLanguage > ARRAY_SIZE(map) - 1)
|
2008-03-22 11:30:08 -07:00
|
|
|
{
|
2008-03-23 12:22:09 -07:00
|
|
|
selectedLanguage = 0;
|
2008-03-22 11:30:08 -07:00
|
|
|
}
|
2008-03-23 12:22:09 -07:00
|
|
|
|
|
|
|
if (!setLanguage(map[selectedLanguage].language) && selectedLanguage != 0)
|
2008-03-22 11:30:08 -07:00
|
|
|
{
|
2008-03-23 12:22:09 -07:00
|
|
|
setNextLanguage(); // try next
|
2008-03-22 11:30:08 -07:00
|
|
|
}
|
|
|
|
}
|
2008-03-15 10:53:10 -07:00
|
|
|
|
2008-03-23 12:22:09 -07:00
|
|
|
|
2008-03-15 10:53:10 -07:00
|
|
|
void initI18n(void)
|
|
|
|
{
|
2008-03-23 12:22:09 -07:00
|
|
|
const char *textdomainDirectory = NULL;
|
2008-03-22 11:30:08 -07:00
|
|
|
|
2008-03-23 12:22:09 -07:00
|
|
|
if (!setLanguage("")) // set to system default
|
2008-03-22 11:30:08 -07:00
|
|
|
{
|
|
|
|
// no system default?
|
2008-03-23 12:22:09 -07:00
|
|
|
debug(LOG_ERROR, "initI18n: No system language found");
|
2008-03-22 11:30:08 -07:00
|
|
|
}
|
2008-03-15 10:53:10 -07:00
|
|
|
#if defined(WZ_OS_WIN)
|
|
|
|
{
|
|
|
|
// Retrieve an absolute path to the locale directory
|
|
|
|
char localeDir[PATH_MAX];
|
2008-05-25 06:46:49 -07:00
|
|
|
sstrcpy(localeDir, PHYSFS_getBaseDir());
|
|
|
|
sstrcat(localeDir, "\\" LOCALEDIR);
|
2008-03-15 10:53:10 -07:00
|
|
|
|
|
|
|
// Set locale directory and translation domain name
|
2008-03-23 12:22:09 -07:00
|
|
|
textdomainDirectory = bindtextdomain(PACKAGE, localeDir);
|
2008-03-15 10:53:10 -07:00
|
|
|
}
|
|
|
|
#else
|
2008-03-23 12:22:09 -07:00
|
|
|
textdomainDirectory = bindtextdomain(PACKAGE, LOCALEDIR);
|
2008-03-15 10:53:10 -07:00
|
|
|
#endif
|
2008-03-23 12:22:09 -07:00
|
|
|
if (!textdomainDirectory)
|
2008-03-22 11:30:08 -07:00
|
|
|
{
|
|
|
|
debug(LOG_ERROR, "initI18n: bindtextdomain failed!");
|
|
|
|
}
|
|
|
|
|
|
|
|
(void)bind_textdomain_codeset(PACKAGE, "UTF-8");
|
2008-03-15 10:53:10 -07:00
|
|
|
(void)textdomain(PACKAGE);
|
|
|
|
}
|