diff options
author | Jacek Antonelli | 2008-08-15 23:45:50 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:50 -0500 |
commit | 2a4dea528f670b9bb1f77ef27a8a1dd16603d114 (patch) | |
tree | 95c68e362703c9099d571ecbdc6142b1cda1e005 /linden/indra/llcommon/llfindlocale.cpp | |
parent | Second Life viewer sources 1.20.6 (diff) | |
download | meta-impy-2a4dea528f670b9bb1f77ef27a8a1dd16603d114.zip meta-impy-2a4dea528f670b9bb1f77ef27a8a1dd16603d114.tar.gz meta-impy-2a4dea528f670b9bb1f77ef27a8a1dd16603d114.tar.bz2 meta-impy-2a4dea528f670b9bb1f77ef27a8a1dd16603d114.tar.xz |
Second Life viewer sources 1.20.7
Diffstat (limited to 'linden/indra/llcommon/llfindlocale.cpp')
-rw-r--r-- | linden/indra/llcommon/llfindlocale.cpp | 525 |
1 files changed, 525 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llfindlocale.cpp b/linden/indra/llcommon/llfindlocale.cpp new file mode 100644 index 0000000..47da974 --- /dev/null +++ b/linden/indra/llcommon/llfindlocale.cpp | |||
@@ -0,0 +1,525 @@ | |||
1 | /** | ||
2 | * @file llfindlocale.cpp | ||
3 | * @brief Detect system language setting | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2008&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2008, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | ||
22 | * By copying, modifying or distributing this software, you acknowledge | ||
23 | * that you have read and understood your obligations described above, | ||
24 | * and agree to abide by those obligations. | ||
25 | * | ||
26 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
27 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
28 | * COMPLETENESS OR PERFORMANCE. | ||
29 | * $/LicenseInfo$ | ||
30 | */ | ||
31 | |||
32 | /* Yes, this was originally C code. */ | ||
33 | |||
34 | #include "linden_common.h" | ||
35 | |||
36 | #include <stdlib.h> | ||
37 | #include <string.h> | ||
38 | #include <ctype.h> | ||
39 | |||
40 | #ifdef WIN32 | ||
41 | #include <windows.h> | ||
42 | #include <winnt.h> | ||
43 | #endif | ||
44 | |||
45 | #include "llfindlocale.h" | ||
46 | |||
47 | static int | ||
48 | is_lcchar(const int c) { | ||
49 | return isalnum(c); | ||
50 | } | ||
51 | |||
52 | static void | ||
53 | lang_country_variant_from_envstring(const char *str, | ||
54 | char **lang, | ||
55 | char **country, | ||
56 | char **variant) { | ||
57 | int end = 0; | ||
58 | int start; | ||
59 | |||
60 | /* get lang, if any */ | ||
61 | start = end; | ||
62 | while (is_lcchar(str[end])) { | ||
63 | ++end; | ||
64 | } | ||
65 | if (start != end) { | ||
66 | int i; | ||
67 | int len = end - start; | ||
68 | char *s = (char*)malloc(len + 1); | ||
69 | for (i=0; i<len; ++i) { | ||
70 | s[i] = tolower(str[start + i]); | ||
71 | } | ||
72 | s[i] = '\0'; | ||
73 | *lang = s; | ||
74 | } else { | ||
75 | *lang = NULL; | ||
76 | } | ||
77 | |||
78 | if (str[end] && str[end]!=':') { /* not at end of str */ | ||
79 | ++end; | ||
80 | } | ||
81 | |||
82 | /* get country, if any */ | ||
83 | start = end; | ||
84 | while (is_lcchar(str[end])) { | ||
85 | ++end; | ||
86 | } | ||
87 | if (start != end) { | ||
88 | int i; | ||
89 | int len = end - start; | ||
90 | char *s = (char*)malloc(len + 1); | ||
91 | for (i=0; i<len; ++i) { | ||
92 | s[i] = toupper(str[start + i]); | ||
93 | } | ||
94 | s[i] = '\0'; | ||
95 | *country = s; | ||
96 | } else { | ||
97 | *country = NULL; | ||
98 | } | ||
99 | |||
100 | if (str[end] && str[end]!=':') { /* not at end of str */ | ||
101 | ++end; | ||
102 | } | ||
103 | |||
104 | /* get variant, if any */ | ||
105 | start = end; | ||
106 | while (str[end] && str[end]!=':') { | ||
107 | ++end; | ||
108 | } | ||
109 | if (start != end) { | ||
110 | int i; | ||
111 | int len = end - start; | ||
112 | char *s = (char*)malloc(len + 1); | ||
113 | for (i=0; i<len; ++i) { | ||
114 | s[i] = str[start + i]; | ||
115 | } | ||
116 | s[i] = '\0'; | ||
117 | *variant = s; | ||
118 | } else { | ||
119 | *variant = NULL; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | |||
124 | static int | ||
125 | accumulate_locstring(const char *str, FL_Locale *l) { | ||
126 | char *lang = NULL; | ||
127 | char *country = NULL; | ||
128 | char *variant = NULL; | ||
129 | if (str) { | ||
130 | lang_country_variant_from_envstring(str, &lang, &country, &variant); | ||
131 | if (lang) { | ||
132 | l->lang = lang; | ||
133 | l->country = country; | ||
134 | l->variant = variant; | ||
135 | return 1; | ||
136 | } | ||
137 | } | ||
138 | free(lang); free(country); free(variant); | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | |||
143 | static int | ||
144 | accumulate_env(const char *name, FL_Locale *l) { | ||
145 | char *env; | ||
146 | char *lang = NULL; | ||
147 | char *country = NULL; | ||
148 | char *variant = NULL; | ||
149 | env = getenv(name); | ||
150 | if (env) { | ||
151 | return accumulate_locstring(env, l); | ||
152 | } | ||
153 | free(lang); free(country); free(variant); | ||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | |||
158 | static void | ||
159 | canonise_fl(FL_Locale *l) { | ||
160 | /* this function fixes some common locale-specifying mistakes */ | ||
161 | /* en_UK -> en_GB */ | ||
162 | if (l->lang && 0 == strcmp(l->lang, "en")) { | ||
163 | if (l->country && 0 == strcmp(l->country, "UK")) { | ||
164 | free((void*)l->country); | ||
165 | l->country = strdup("GB"); | ||
166 | } | ||
167 | } | ||
168 | /* ja_JA -> ja_JP */ | ||
169 | if (l->lang && 0 == strcmp(l->lang, "ja")) { | ||
170 | if (l->country && 0 == strcmp(l->country, "JA")) { | ||
171 | free((void*)l->country); | ||
172 | l->country = strdup("JP"); | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | |||
177 | |||
178 | #ifdef WIN32 | ||
179 | #include <stdio.h> | ||
180 | #define ML(pn,sn) MAKELANGID(LANG_##pn, SUBLANG_##pn##_##sn) | ||
181 | #define MLN(pn) MAKELANGID(LANG_##pn, SUBLANG_DEFAULT) | ||
182 | #define RML(pn,sn) MAKELANGID(LANG_##pn, SUBLANG_##sn) | ||
183 | typedef struct { | ||
184 | LANGID id; | ||
185 | char* code; | ||
186 | } IDToCode; | ||
187 | static const IDToCode both_to_code[] = { | ||
188 | {ML(ENGLISH,US), "en_US.ISO_8859-1"}, | ||
189 | {ML(ENGLISH,CAN), "en_CA"}, /* english / canadian */ | ||
190 | {ML(ENGLISH,UK), "en_GB"}, | ||
191 | {ML(ENGLISH,EIRE), "en_IE"}, | ||
192 | {ML(ENGLISH,AUS), "en_AU"}, | ||
193 | {MLN(GERMAN), "de_DE"}, | ||
194 | {MLN(SPANISH), "es_ES"}, | ||
195 | {ML(SPANISH,MEXICAN), "es_MX"}, | ||
196 | {MLN(FRENCH), "fr_FR"}, | ||
197 | {ML(FRENCH,CANADIAN), "fr_CA"}, | ||
198 | {ML(FRENCH,BELGIAN), "fr_BE"}, /* ? */ | ||
199 | {ML(DUTCH,BELGIAN), "nl_BE"}, /* ? */ | ||
200 | {ML(PORTUGUESE,BRAZILIAN), "pt_BR"}, | ||
201 | {MLN(PORTUGUESE), "pt_PT"}, | ||
202 | {MLN(SWEDISH), "sv_SE"}, | ||
203 | {ML(CHINESE,HONGKONG), "zh_HK"}, | ||
204 | /* these are machine-generated and not yet verified */ | ||
205 | {RML(AFRIKAANS,DEFAULT), "af_ZA"}, | ||
206 | {RML(ALBANIAN,DEFAULT), "sq_AL"}, | ||
207 | {RML(ARABIC,ARABIC_ALGERIA), "ar_DZ"}, | ||
208 | {RML(ARABIC,ARABIC_BAHRAIN), "ar_BH"}, | ||
209 | {RML(ARABIC,ARABIC_EGYPT), "ar_EG"}, | ||
210 | {RML(ARABIC,ARABIC_IRAQ), "ar_IQ"}, | ||
211 | {RML(ARABIC,ARABIC_JORDAN), "ar_JO"}, | ||
212 | {RML(ARABIC,ARABIC_KUWAIT), "ar_KW"}, | ||
213 | {RML(ARABIC,ARABIC_LEBANON), "ar_LB"}, | ||
214 | {RML(ARABIC,ARABIC_LIBYA), "ar_LY"}, | ||
215 | {RML(ARABIC,ARABIC_MOROCCO), "ar_MA"}, | ||
216 | {RML(ARABIC,ARABIC_OMAN), "ar_OM"}, | ||
217 | {RML(ARABIC,ARABIC_QATAR), "ar_QA"}, | ||
218 | {RML(ARABIC,ARABIC_SAUDI_ARABIA), "ar_SA"}, | ||
219 | {RML(ARABIC,ARABIC_SYRIA), "ar_SY"}, | ||
220 | {RML(ARABIC,ARABIC_TUNISIA), "ar_TN"}, | ||
221 | {RML(ARABIC,ARABIC_UAE), "ar_AE"}, | ||
222 | {RML(ARABIC,ARABIC_YEMEN), "ar_YE"}, | ||
223 | {RML(ARMENIAN,DEFAULT), "hy_AM"}, | ||
224 | {RML(AZERI,AZERI_CYRILLIC), "az_AZ"}, | ||
225 | {RML(AZERI,AZERI_LATIN), "az_AZ"}, | ||
226 | {RML(BASQUE,DEFAULT), "eu_ES"}, | ||
227 | {RML(BELARUSIAN,DEFAULT), "be_BY"}, | ||
228 | /*{RML(BRETON,DEFAULT), "br_FR"},*/ | ||
229 | {RML(BULGARIAN,DEFAULT), "bg_BG"}, | ||
230 | {RML(CATALAN,DEFAULT), "ca_ES"}, | ||
231 | {RML(CHINESE,CHINESE_HONGKONG), "zh_HK"}, | ||
232 | {RML(CHINESE,CHINESE_MACAU), "zh_MO"}, | ||
233 | {RML(CHINESE,CHINESE_SIMPLIFIED), "zh_CN"}, | ||
234 | {RML(CHINESE,CHINESE_SINGAPORE), "zh_SG"}, | ||
235 | {RML(CHINESE,CHINESE_TRADITIONAL), "zh_TW"}, | ||
236 | /*{RML(CORNISH,DEFAULT), "kw_GB"},*/ | ||
237 | {RML(CZECH,DEFAULT), "cs_CZ"}, | ||
238 | {RML(DANISH,DEFAULT), "da_DK"}, | ||
239 | {RML(DUTCH,DUTCH), "nl_NL"}, | ||
240 | {RML(DUTCH,DUTCH_BELGIAN), "nl_BE"}, | ||
241 | /*{RML(DUTCH,DUTCH_SURINAM), "nl_SR"},*/ | ||
242 | {RML(ENGLISH,ENGLISH_AUS), "en_AU"}, | ||
243 | {RML(ENGLISH,ENGLISH_BELIZE), "en_BZ"}, | ||
244 | {RML(ENGLISH,ENGLISH_CAN), "en_CA"}, | ||
245 | {RML(ENGLISH,ENGLISH_CARIBBEAN), "en_CB"}, | ||
246 | {RML(ENGLISH,ENGLISH_EIRE), "en_IE"}, | ||
247 | {RML(ENGLISH,ENGLISH_JAMAICA), "en_JM"}, | ||
248 | {RML(ENGLISH,ENGLISH_NZ), "en_NZ"}, | ||
249 | {RML(ENGLISH,ENGLISH_PHILIPPINES), "en_PH"}, | ||
250 | {RML(ENGLISH,ENGLISH_SOUTH_AFRICA), "en_ZA"}, | ||
251 | {RML(ENGLISH,ENGLISH_TRINIDAD), "en_TT"}, | ||
252 | {RML(ENGLISH,ENGLISH_UK), "en_GB"}, | ||
253 | {RML(ENGLISH,ENGLISH_US), "en_US"}, | ||
254 | {RML(ENGLISH,ENGLISH_ZIMBABWE), "en_ZW"}, | ||
255 | /*{RML(ESPERANTO,DEFAULT), "eo_"},*/ | ||
256 | {RML(ESTONIAN,DEFAULT), "et_EE"}, | ||
257 | {RML(FAEROESE,DEFAULT), "fo_FO"}, | ||
258 | {RML(FARSI,DEFAULT), "fa_IR"}, | ||
259 | {RML(FINNISH,DEFAULT), "fi_FI"}, | ||
260 | {RML(FRENCH,FRENCH), "fr_FR"}, | ||
261 | {RML(FRENCH,FRENCH_BELGIAN), "fr_BE"}, | ||
262 | {RML(FRENCH,FRENCH_CANADIAN), "fr_CA"}, | ||
263 | {RML(FRENCH,FRENCH_LUXEMBOURG), "fr_LU"}, | ||
264 | {RML(FRENCH,FRENCH_MONACO), "fr_MC"}, | ||
265 | {RML(FRENCH,FRENCH_SWISS), "fr_CH"}, | ||
266 | /*{RML(GAELIC,GAELIC), "ga_IE"},*/ | ||
267 | /*{RML(GAELIC,GAELIC_MANX), "gv_GB"},*/ | ||
268 | /*{RML(GAELIC,GAELIC_SCOTTISH), "gd_GB"},*/ | ||
269 | /*{RML(GALICIAN,DEFAULT), "gl_ES"},*/ | ||
270 | {RML(GEORGIAN,DEFAULT), "ka_GE"}, | ||
271 | {RML(GERMAN,GERMAN), "de_DE"}, | ||
272 | {RML(GERMAN,GERMAN_AUSTRIAN), "de_AT"}, | ||
273 | {RML(GERMAN,GERMAN_LIECHTENSTEIN), "de_LI"}, | ||
274 | {RML(GERMAN,GERMAN_LUXEMBOURG), "de_LU"}, | ||
275 | {RML(GERMAN,GERMAN_SWISS), "de_CH"}, | ||
276 | {RML(GREEK,DEFAULT), "el_GR"}, | ||
277 | {RML(GUJARATI,DEFAULT), "gu_IN"}, | ||
278 | {RML(HEBREW,DEFAULT), "he_IL"}, | ||
279 | {RML(HINDI,DEFAULT), "hi_IN"}, | ||
280 | {RML(HUNGARIAN,DEFAULT), "hu_HU"}, | ||
281 | {RML(ICELANDIC,DEFAULT), "is_IS"}, | ||
282 | {RML(INDONESIAN,DEFAULT), "id_ID"}, | ||
283 | {RML(ITALIAN,ITALIAN), "it_IT"}, | ||
284 | {RML(ITALIAN,ITALIAN_SWISS), "it_CH"}, | ||
285 | {RML(JAPANESE,DEFAULT), "ja_JP"}, | ||
286 | {RML(KANNADA,DEFAULT), "kn_IN"}, | ||
287 | {RML(KAZAK,DEFAULT), "kk_KZ"}, | ||
288 | {RML(KONKANI,DEFAULT), "kok_IN"}, | ||
289 | {RML(KOREAN,KOREAN), "ko_KR"}, | ||
290 | /*{RML(KYRGYZ,DEFAULT), "ky_KG"},*/ | ||
291 | {RML(LATVIAN,DEFAULT), "lv_LV"}, | ||
292 | {RML(LITHUANIAN,LITHUANIAN), "lt_LT"}, | ||
293 | {RML(MACEDONIAN,DEFAULT), "mk_MK"}, | ||
294 | {RML(MALAY,MALAY_BRUNEI_DARUSSALAM), "ms_BN"}, | ||
295 | {RML(MALAY,MALAY_MALAYSIA), "ms_MY"}, | ||
296 | {RML(MARATHI,DEFAULT), "mr_IN"}, | ||
297 | /*{RML(MONGOLIAN,DEFAULT), "mn_MN"},*/ | ||
298 | {RML(NORWEGIAN,NORWEGIAN_BOKMAL), "nb_NO"}, | ||
299 | {RML(NORWEGIAN,NORWEGIAN_NYNORSK), "nn_NO"}, | ||
300 | {RML(POLISH,DEFAULT), "pl_PL"}, | ||
301 | {RML(PORTUGUESE,PORTUGUESE), "pt_PT"}, | ||
302 | {RML(PORTUGUESE,PORTUGUESE_BRAZILIAN), "pt_BR"}, | ||
303 | {RML(PUNJABI,DEFAULT), "pa_IN"}, | ||
304 | {RML(ROMANIAN,DEFAULT), "ro_RO"}, | ||
305 | {RML(RUSSIAN,DEFAULT), "ru_RU"}, | ||
306 | {RML(SANSKRIT,DEFAULT), "sa_IN"}, | ||
307 | {RML(SERBIAN,DEFAULT), "hr_HR"}, | ||
308 | {RML(SERBIAN,SERBIAN_CYRILLIC), "sr_SP"}, | ||
309 | {RML(SERBIAN,SERBIAN_LATIN), "sr_SP"}, | ||
310 | {RML(SLOVAK,DEFAULT), "sk_SK"}, | ||
311 | {RML(SLOVENIAN,DEFAULT), "sl_SI"}, | ||
312 | {RML(SPANISH,SPANISH), "es_ES"}, | ||
313 | {RML(SPANISH,SPANISH_ARGENTINA), "es_AR"}, | ||
314 | {RML(SPANISH,SPANISH_BOLIVIA), "es_BO"}, | ||
315 | {RML(SPANISH,SPANISH_CHILE), "es_CL"}, | ||
316 | {RML(SPANISH,SPANISH_COLOMBIA), "es_CO"}, | ||
317 | {RML(SPANISH,SPANISH_COSTA_RICA), "es_CR"}, | ||
318 | {RML(SPANISH,SPANISH_DOMINICAN_REPUBLIC), "es_DO"}, | ||
319 | {RML(SPANISH,SPANISH_ECUADOR), "es_EC"}, | ||
320 | {RML(SPANISH,SPANISH_EL_SALVADOR), "es_SV"}, | ||
321 | {RML(SPANISH,SPANISH_GUATEMALA), "es_GT"}, | ||
322 | {RML(SPANISH,SPANISH_HONDURAS), "es_HN"}, | ||
323 | {RML(SPANISH,SPANISH_MEXICAN), "es_MX"}, | ||
324 | {RML(SPANISH,SPANISH_MODERN), "es_ES"}, | ||
325 | {RML(SPANISH,SPANISH_NICARAGUA), "es_NI"}, | ||
326 | {RML(SPANISH,SPANISH_PANAMA), "es_PA"}, | ||
327 | {RML(SPANISH,SPANISH_PARAGUAY), "es_PY"}, | ||
328 | {RML(SPANISH,SPANISH_PERU), "es_PE"}, | ||
329 | {RML(SPANISH,SPANISH_PUERTO_RICO), "es_PR"}, | ||
330 | {RML(SPANISH,SPANISH_URUGUAY), "es_UY"}, | ||
331 | {RML(SPANISH,SPANISH_VENEZUELA), "es_VE"}, | ||
332 | {RML(SWAHILI,DEFAULT), "sw_KE"}, | ||
333 | {RML(SWEDISH,SWEDISH), "sv_SE"}, | ||
334 | {RML(SWEDISH,SWEDISH_FINLAND), "sv_FI"}, | ||
335 | /*{RML(SYRIAC,DEFAULT), "syr_SY"},*/ | ||
336 | {RML(TAMIL,DEFAULT), "ta_IN"}, | ||
337 | {RML(TATAR,DEFAULT), "tt_TA"}, | ||
338 | {RML(TELUGU,DEFAULT), "te_IN"}, | ||
339 | {RML(THAI,DEFAULT), "th_TH"}, | ||
340 | {RML(TURKISH,DEFAULT), "tr_TR"}, | ||
341 | {RML(UKRAINIAN,DEFAULT), "uk_UA"}, | ||
342 | {RML(URDU,URDU_PAKISTAN), "ur_PK"}, | ||
343 | {RML(UZBEK,UZBEK_CYRILLIC), "uz_UZ"}, | ||
344 | {RML(UZBEK,UZBEK_LATIN), "uz_UZ"}, | ||
345 | {RML(VIETNAMESE,DEFAULT), "vi_VN"}, | ||
346 | /*{RML(WALON,DEFAULT), "wa_BE"},*/ | ||
347 | /*{RML(WELSH,DEFAULT), "cy_GB"},*/ | ||
348 | }; | ||
349 | static const IDToCode primary_to_code[] = { | ||
350 | {LANG_AFRIKAANS, "af"}, | ||
351 | {LANG_ARABIC, "ar"}, | ||
352 | {LANG_AZERI, "az"}, | ||
353 | {LANG_BULGARIAN, "bg"}, | ||
354 | /*{LANG_BRETON, "br"},*/ | ||
355 | {LANG_BELARUSIAN, "by"}, | ||
356 | {LANG_CATALAN, "ca"}, | ||
357 | {LANG_CZECH, "cs"}, | ||
358 | /*{LANG_WELSH, "cy"},*/ | ||
359 | {LANG_DANISH, "da"}, | ||
360 | {LANG_GERMAN, "de"}, | ||
361 | {LANG_GREEK, "el"}, | ||
362 | {LANG_ENGLISH, "en"}, | ||
363 | /*{LANG_ESPERANTO, "eo"},*/ | ||
364 | {LANG_SPANISH, "es"}, | ||
365 | {LANG_ESTONIAN, "et"}, | ||
366 | {LANG_BASQUE, "eu"}, | ||
367 | {LANG_FARSI, "fa"}, | ||
368 | {LANG_FINNISH, "fi"}, | ||
369 | {LANG_FAEROESE, "fo"}, | ||
370 | {LANG_FRENCH, "fr"}, | ||
371 | /*{LANG_GAELIC, "ga"},*/ | ||
372 | /*{LANG_GALICIAN, "gl"},*/ | ||
373 | {LANG_GUJARATI, "gu"}, | ||
374 | {LANG_HEBREW, "he"}, | ||
375 | {LANG_HINDI, "hi"}, | ||
376 | {LANG_SERBIAN, "hr"}, | ||
377 | {LANG_HUNGARIAN, "hu"}, | ||
378 | {LANG_ARMENIAN, "hy"}, | ||
379 | {LANG_INDONESIAN, "id"}, | ||
380 | {LANG_ITALIAN, "it"}, | ||
381 | {LANG_JAPANESE, "ja"}, | ||
382 | {LANG_GEORGIAN, "ka"}, | ||
383 | {LANG_KAZAK, "kk"}, | ||
384 | {LANG_KANNADA, "kn"}, | ||
385 | {LANG_KOREAN, "ko"}, | ||
386 | /*{LANG_KYRGYZ, "ky"},*/ | ||
387 | {LANG_LITHUANIAN, "lt"}, | ||
388 | {LANG_LATVIAN, "lv"}, | ||
389 | {LANG_MACEDONIAN, "mk"}, | ||
390 | /*{LANG_MONGOLIAN, "mn"},*/ | ||
391 | {LANG_MARATHI, "mr"}, | ||
392 | {LANG_MALAY, "ms"}, | ||
393 | {LANG_NORWEGIAN, "nb"}, | ||
394 | {LANG_DUTCH, "nl"}, | ||
395 | {LANG_NORWEGIAN, "nn"}, | ||
396 | {LANG_NORWEGIAN, "no"},/* unofficial? */ | ||
397 | {LANG_PUNJABI, "pa"}, | ||
398 | {LANG_POLISH, "pl"}, | ||
399 | {LANG_PORTUGUESE, "pt"}, | ||
400 | {LANG_ROMANIAN, "ro"}, | ||
401 | {LANG_RUSSIAN, "ru"}, | ||
402 | {LANG_SLOVAK, "sk"}, | ||
403 | {LANG_SLOVENIAN, "sl"}, | ||
404 | {LANG_ALBANIAN, "sq"}, | ||
405 | {LANG_SERBIAN, "sr"}, | ||
406 | {LANG_SWEDISH, "sv"}, | ||
407 | {LANG_SWAHILI, "sw"}, | ||
408 | {LANG_TAMIL, "ta"}, | ||
409 | {LANG_THAI, "th"}, | ||
410 | {LANG_TURKISH, "tr"}, | ||
411 | {LANG_TATAR, "tt"}, | ||
412 | {LANG_UKRAINIAN, "uk"}, | ||
413 | {LANG_URDU, "ur"}, | ||
414 | {LANG_UZBEK, "uz"}, | ||
415 | {LANG_VIETNAMESE, "vi"}, | ||
416 | /*{LANG_WALON, "wa"},*/ | ||
417 | {LANG_CHINESE, "zh"}, | ||
418 | }; | ||
419 | static int num_primary_to_code = | ||
420 | sizeof(primary_to_code) / sizeof(*primary_to_code); | ||
421 | static int num_both_to_code = | ||
422 | sizeof(both_to_code) / sizeof(*both_to_code); | ||
423 | |||
424 | static const int | ||
425 | lcid_to_fl(LCID lcid, | ||
426 | FL_Locale *rtn) { | ||
427 | LANGID langid = LANGIDFROMLCID(lcid); | ||
428 | LANGID primary_lang = PRIMARYLANGID(langid); | ||
429 | /*LANGID sub_lang = SUBLANGID(langid);*/ | ||
430 | int i; | ||
431 | /* try to find an exact primary/sublanguage combo that we know about */ | ||
432 | for (i=0; i<num_both_to_code; ++i) { | ||
433 | if (both_to_code[i].id == langid) { | ||
434 | accumulate_locstring(both_to_code[i].code, rtn); | ||
435 | return 1; | ||
436 | } | ||
437 | } | ||
438 | /* fallback to just checking the primary language id */ | ||
439 | for (i=0; i<num_primary_to_code; ++i) { | ||
440 | if (primary_to_code[i].id == primary_lang) { | ||
441 | accumulate_locstring(primary_to_code[i].code, rtn); | ||
442 | return 1; | ||
443 | } | ||
444 | } | ||
445 | return 0; | ||
446 | } | ||
447 | #endif | ||
448 | |||
449 | |||
450 | FL_Success | ||
451 | FL_FindLocale(FL_Locale **locale, FL_Domain domain) { | ||
452 | FL_Success success = FL_FAILED; | ||
453 | FL_Locale *rtn = (FL_Locale*)malloc(sizeof(FL_Locale)); | ||
454 | rtn->lang = NULL; | ||
455 | rtn->country = NULL; | ||
456 | rtn->variant = NULL; | ||
457 | |||
458 | #ifdef WIN32 | ||
459 | /* win32 >= mswindows95 */ | ||
460 | { | ||
461 | LCID lcid = GetThreadLocale(); | ||
462 | if (lcid_to_fl(lcid, rtn)) { | ||
463 | success = FL_CONFIDENT; | ||
464 | } | ||
465 | if (success == FL_FAILED) { | ||
466 | /* assume US English on mswindows systems unless we know otherwise */ | ||
467 | if (accumulate_locstring("en_US.ISO_8859-1", rtn)) { | ||
468 | success = FL_DEFAULT_GUESS; | ||
469 | } | ||
470 | } | ||
471 | } | ||
472 | #else | ||
473 | /* assume unixoid */ | ||
474 | { | ||
475 | /* examples: */ | ||
476 | /* sv_SE.ISO_8859-1 */ | ||
477 | /* fr_FR.ISO8859-1 */ | ||
478 | /* no_NO_NB */ | ||
479 | /* no_NO_NY */ | ||
480 | /* no_NO */ | ||
481 | /* de_DE */ | ||
482 | /* try the various vars in decreasing order of authority */ | ||
483 | if (accumulate_env("LC_ALL", rtn) || | ||
484 | accumulate_env("LC_MESSAGES", rtn) || | ||
485 | accumulate_env("LANG", rtn) || | ||
486 | accumulate_env("LANGUAGE", rtn)) { | ||
487 | success = FL_CONFIDENT; | ||
488 | } | ||
489 | if (success == FL_FAILED) { | ||
490 | /* assume US English on unixoid systems unless we know otherwise */ | ||
491 | if (accumulate_locstring("en_US.ISO_8859-1", rtn)) { | ||
492 | success = FL_DEFAULT_GUESS; | ||
493 | } | ||
494 | } | ||
495 | } | ||
496 | #endif | ||
497 | |||
498 | if (success != FL_FAILED) { | ||
499 | canonise_fl(rtn); | ||
500 | } | ||
501 | |||
502 | *locale = rtn; | ||
503 | return success; | ||
504 | } | ||
505 | |||
506 | |||
507 | void | ||
508 | FL_FreeLocale(FL_Locale **locale) { | ||
509 | if (locale) { | ||
510 | FL_Locale *l = *locale; | ||
511 | if (l) { | ||
512 | if (l->lang) { | ||
513 | free((void*)l->lang); | ||
514 | } | ||
515 | if (l->country) { | ||
516 | free((void*)l->country); | ||
517 | } | ||
518 | if (l->variant) { | ||
519 | free((void*)l->variant); | ||
520 | } | ||
521 | free(l); | ||
522 | *locale = NULL; | ||
523 | } | ||
524 | } | ||
525 | } | ||