1 #include "Localization.h"
2
3 #ifdef BBGE_BUILD_UNIX
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <unistd.h>
7 #endif
8
9 #ifdef BBGE_BUILD_MACOSX
10 #include <CoreFoundation/CFLocale.h>
11 #include <CoreFoundation/CFString.h>
12
13 // veeery clunky.
_CFToStdString(CFStringRef cs)14 static std::string _CFToStdString(CFStringRef cs)
15 {
16 char buf[1024];
17 CFStringGetCString(cs, &buf[0], 1024, kCFStringEncodingUTF8);
18 return &buf[0];
19 }
20 #endif
21
22 static std::string s_locale;
23 static std::string s_modpath;
24
setUsedLocale(const std::string & s)25 void setUsedLocale(const std::string& s)
26 {
27 s_locale = s;
28 }
29
getUsedLocale()30 const char *getUsedLocale()
31 {
32 return s_locale.c_str();
33 }
34
setLocalisationModPath(const std::string & s)35 void setLocalisationModPath(const std::string& s)
36 {
37 s_modpath = s;
38 stringToLower(s_modpath);
39 }
40
41 // hackish
42 // intended to be used only for paths which are known to start with the mod path,
43 // but can deal with it if this is not the case
localisePathInternalModpath(const std::string & path)44 std::string localisePathInternalModpath(const std::string &path)
45 {
46 std::string tmp = path;
47 stringToLower(tmp);
48
49 if(!strncmp(tmp.c_str(), s_modpath.c_str(), s_modpath.length()))
50 return localisePath(path, s_modpath);
51
52 return localisePath(path);
53 }
54
localisePath(const std::string & path,const std::string & modpath)55 std::string localisePath(const std::string &path, const std::string& modpath /* = "" */)
56 {
57 if (s_locale.empty() || s_locale == "-")
58 return path;
59 if(path.length() < modpath.length())
60 return path;
61
62 const std::string fname = path.substr(modpath.length());
63
64 /* we first try with complete locale name, i.e "locales/en_US/" */
65 std::string localisedPath = modpath + "locales/" + s_locale + "/" + fname;
66
67 if (exists(localisedPath.c_str()))
68 return localisedPath;
69
70 /* ok didn't work, let's retry with only language part of locale name, i.e "locales/en/" */
71 const size_t found = s_locale.find('_');
72
73 /* hmm, seems like we didn't have a full locale name anyway, use original path */
74 if (found == std::string::npos)
75 return path;
76
77 localisedPath = modpath + "locales/" + s_locale.substr(0,found) + "/" + fname;
78
79 /* hooray we found a file! */
80 if (exists(localisedPath.c_str()))
81 return localisedPath;
82
83 /* seems like we don't have a localized version of the file available, use original path */
84 return path;
85 }
86
getSystemLocale()87 std::string getSystemLocale()
88 {
89 std::string localeStr;
90
91 #ifdef BBGE_BUILD_WINDOWS
92 LCID lcid = GetThreadLocale();
93
94 char buf[100];
95 char ctry[100];
96
97 if (GetLocaleInfo(lcid, LOCALE_SISO639LANGNAME, buf, sizeof buf) != 0)
98 {
99 localeStr = buf;
100
101 if (GetLocaleInfo(lcid, LOCALE_SISO3166CTRYNAME, ctry, sizeof ctry) != 0)
102 {
103 localeStr += "_";
104 localeStr += ctry;
105 }
106 }
107 #elif BBGE_BUILD_MACOSX
108 CFLocaleRef locale = CFLocaleCopyCurrent();
109 CFStringRef buf;
110
111 if ((buf = (CFStringRef)CFLocaleGetValue(locale, kCFLocaleLanguageCode)) != NULL)
112 {
113 localeStr = _CFToStdString(buf);
114
115 if ((buf = (CFStringRef)CFLocaleGetValue(locale, kCFLocaleCountryCode)) != NULL)
116 {
117 localeStr += "_";
118 localeStr += _CFToStdString(buf);
119 }
120 }
121
122 CFRelease(locale);
123
124 #else
125 const char *lang = (const char *)getenv("LANG");
126
127 if (lang && *lang)
128 {
129 localeStr = lang;
130
131 size_t found = localeStr.find('.');
132
133 if (found != std::string::npos)
134 localeStr.resize(found);
135 }
136 #endif
137
138 return localeStr;
139 }
140
141