1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/locale/src/windows/nsWin32Locale.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,746 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "mozilla/ArrayUtils.h" 1.10 + 1.11 +#include "nscore.h" 1.12 +#include "nsString.h" 1.13 +#include "nsXPCOMStrings.h" 1.14 +#include "nsReadableUtils.h" 1.15 +#include "nsWin32Locale.h" 1.16 +#include "prprf.h" 1.17 +#include <windows.h> 1.18 +#include "nsCRT.h" 1.19 + 1.20 +using namespace mozilla; 1.21 + 1.22 +struct iso_pair 1.23 +{ 1.24 + const char* iso_code; 1.25 + DWORD win_code; 1.26 +}; 1.27 + 1.28 +struct iso_map 1.29 +{ 1.30 + const char* iso_code; 1.31 + DWORD win_code; 1.32 + iso_pair sublang_list[20]; 1.33 +}; 1.34 + 1.35 +nsWin32Locale::LocaleNameToLCIDPtr nsWin32Locale::localeNameToLCID = nullptr; 1.36 +nsWin32Locale::LCIDToLocaleNamePtr nsWin32Locale::lcidToLocaleName = nullptr; 1.37 + 1.38 +// Older versions of VC++ and Win32 SDK and mingw don't have 1.39 +// macros for languages and sublanguages recently added to Win32. 1.40 +// see http://www.tug.org/ftp/tex/texinfo/intl/localename.c 1.41 + 1.42 +#ifndef LANG_URDU 1.43 +#define LANG_URDU 0x20 1.44 +#endif 1.45 +#ifndef LANG_ARMENIAN 1.46 +#define LANG_ARMENIAN 0x2b 1.47 +#endif 1.48 +#ifndef LANG_AZERI 1.49 +#define LANG_AZERI 0x2c 1.50 +#endif 1.51 +#ifndef LANG_MACEDONIAN 1.52 +#define LANG_MACEDONIAN 0x2f 1.53 +#endif 1.54 +#ifndef LANG_GEORGIAN 1.55 +#define LANG_GEORGIAN 0x37 1.56 +#endif 1.57 +#ifndef LANG_HINDI 1.58 +#define LANG_HINDI 0x39 1.59 +#endif 1.60 +#ifndef LANG_MALAY 1.61 +#define LANG_MALAY 0x3e 1.62 +#endif 1.63 +#ifndef LANG_KAZAK 1.64 +#define LANG_KAZAK 0x3f 1.65 +#endif 1.66 +#ifndef LANG_KYRGYZ 1.67 +#define LANG_KYRGYZ 0x40 1.68 +#endif 1.69 +#ifndef LANG_SWAHILI 1.70 +#define LANG_SWAHILI 0x41 1.71 +#endif 1.72 +#ifndef LANG_UZBEK 1.73 +#define LANG_UZBEK 0x43 1.74 +#endif 1.75 +#ifndef LANG_TATAR 1.76 +#define LANG_TATAR 0x44 1.77 +#endif 1.78 +#ifndef LANG_PUNJABI 1.79 +#define LANG_PUNJABI 0x46 1.80 +#endif 1.81 +#ifndef LANG_GUJARAT 1.82 +#define LANG_GUJARAT 0x47 1.83 +#endif 1.84 +#ifndef LANG_TAMIL 1.85 +#define LANG_TAMIL 0x49 1.86 +#endif 1.87 +#ifndef LANG_TELUGU 1.88 +#define LANG_TELUGU 0x4a 1.89 +#endif 1.90 +#ifndef LANG_KANNADA 1.91 +#define LANG_KANNADA 0x4b 1.92 +#endif 1.93 +#ifndef LANG_MARATHI 1.94 +#define LANG_MARATHI 0x4e 1.95 +#endif 1.96 +#ifndef LANG_SANSKRIT 1.97 +#define LANG_SANSKRIT 0x4f 1.98 +#endif 1.99 +#ifndef LANG_MONGOLIAN 1.100 +#define LANG_MONGOLIAN 0x50 1.101 +#endif 1.102 +#ifndef LANG_GALICIAN 1.103 +#define LANG_GALICIAN 0x56 1.104 +#endif 1.105 +#ifndef LANG_KONKANI 1.106 +#define LANG_KONKANI 0x57 1.107 +#endif 1.108 +#ifndef LANG_DIVEHI 1.109 +#define LANG_DIVEHI 0x65 1.110 +#endif 1.111 + 1.112 +#ifndef SUBLANG_MALAY_MALAYSIA 1.113 +#define SUBLANG_MALAY_MALAYSIA 0x01 1.114 +#endif 1.115 +#ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM 1.116 +#define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02 1.117 +#endif 1.118 +#ifndef SUBLANG_CHINESE_MACAU 1.119 +#define SUBLANG_CHINESE_MACAU 0x05 1.120 +#endif 1.121 +#ifndef SUBLANG_FRENCH_MONACO 1.122 +#define SUBLANG_FRENCH_MONACO 0x06 1.123 +#endif 1.124 +#ifndef SUBLANG_ENGLISH_ZIMBABWE 1.125 +#define SUBLANG_ENGLISH_ZIMBABWE 0x0c 1.126 +#endif 1.127 +#ifndef SUBLANG_ENGLISH_PHILIPPINES 1.128 +#define SUBLANG_ENGLISH_PHILIPPINES 0x0d 1.129 +#endif 1.130 + 1.131 + 1.132 +// 1.133 +// This list is used to map between ISO language 1.134 +// References : 1.135 +// http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html 1.136 +// http://www.loc.gov/standards/iso639-2/ 1.137 +// http://www.ethnologue.com/ 1.138 +// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_19ir.asp 1.139 +// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_61df.asp 1.140 + 1.141 +static const 1.142 +iso_map iso_list[] = 1.143 +{ 1.144 + {"af", LANG_AFRIKAANS, { 1.145 + { "ZA", SUBLANG_DEFAULT }, 1.146 + { "",0}} 1.147 + }, 1.148 + { "ar", LANG_ARABIC, { 1.149 + { "SA", SUBLANG_ARABIC_SAUDI_ARABIA }, 1.150 + { "IQ", SUBLANG_ARABIC_IRAQ }, 1.151 + { "EG", SUBLANG_ARABIC_EGYPT }, 1.152 + { "LY", SUBLANG_ARABIC_LIBYA }, 1.153 + { "DZ", SUBLANG_ARABIC_ALGERIA }, 1.154 + { "MA", SUBLANG_ARABIC_MOROCCO }, 1.155 + { "TN", SUBLANG_ARABIC_TUNISIA }, 1.156 + { "OM", SUBLANG_ARABIC_OMAN }, 1.157 + { "YE", SUBLANG_ARABIC_YEMEN }, 1.158 + { "SY", SUBLANG_ARABIC_SYRIA }, 1.159 + { "JO", SUBLANG_ARABIC_JORDAN }, 1.160 + { "LB", SUBLANG_ARABIC_LEBANON }, 1.161 + { "KW", SUBLANG_ARABIC_KUWAIT }, 1.162 + { "AE", SUBLANG_ARABIC_UAE }, 1.163 + { "BH", SUBLANG_ARABIC_BAHRAIN }, 1.164 + { "QA", SUBLANG_ARABIC_QATAR }, 1.165 + {"",0}} 1.166 + }, 1.167 + {"az", LANG_AZERI, { 1.168 + { "AZ",SUBLANG_DEFAULT }, // XXX Latin vs Cyrillic vs Arabic 1.169 + { "",0}} 1.170 + }, 1.171 + {"be", LANG_BELARUSIAN, { 1.172 + { "BY",SUBLANG_DEFAULT }, 1.173 + { "",0}} 1.174 + }, 1.175 + {"bg", LANG_BULGARIAN, { 1.176 + { "BG", SUBLANG_DEFAULT }, 1.177 + { "",0}} 1.178 + }, 1.179 + {"ca", LANG_CATALAN, { 1.180 + { "ES", SUBLANG_DEFAULT}, 1.181 + { "",0}} 1.182 + }, 1.183 + {"cs", LANG_CZECH, { 1.184 + { "CZ", SUBLANG_DEFAULT}, 1.185 + {"",0}} 1.186 + }, 1.187 + { "da", LANG_DANISH, { 1.188 + { "DK", SUBLANG_DEFAULT }, 1.189 + { "",0}} 1.190 + }, 1.191 + { "de", LANG_GERMAN, { 1.192 + { "DE", SUBLANG_GERMAN }, 1.193 + { "CH", SUBLANG_GERMAN_SWISS }, 1.194 + { "AT", SUBLANG_GERMAN_AUSTRIAN }, 1.195 + { "LU", SUBLANG_GERMAN_LUXEMBOURG }, 1.196 + { "LI", SUBLANG_GERMAN_LIECHTENSTEIN }, 1.197 + { "" , 0}} 1.198 + }, 1.199 + {"dv", LANG_DIVEHI, { 1.200 + { "MV", SUBLANG_DEFAULT}, 1.201 + { "", 0}} 1.202 + }, 1.203 + {"el", LANG_GREEK, { 1.204 + { "GR", SUBLANG_DEFAULT}, 1.205 + { "", 0}} 1.206 + }, 1.207 + { "en", LANG_ENGLISH, { 1.208 + { "US", SUBLANG_ENGLISH_US }, 1.209 + { "GB", SUBLANG_ENGLISH_UK }, 1.210 + { "AU", SUBLANG_ENGLISH_AUS }, 1.211 + { "CA", SUBLANG_ENGLISH_CAN }, 1.212 + { "NZ", SUBLANG_ENGLISH_NZ }, 1.213 + { "IE", SUBLANG_ENGLISH_EIRE }, 1.214 + { "ZA", SUBLANG_ENGLISH_SOUTH_AFRICA }, 1.215 + { "JM", SUBLANG_ENGLISH_JAMAICA }, 1.216 + { "BZ", SUBLANG_ENGLISH_BELIZE }, 1.217 + { "TT", SUBLANG_ENGLISH_TRINIDAD }, 1.218 + { "ZW", SUBLANG_ENGLISH_ZIMBABWE }, 1.219 + { "PH", SUBLANG_ENGLISH_PHILIPPINES }, 1.220 + { "",0}} 1.221 + }, 1.222 + { "es", LANG_SPANISH, { // XXX : SUBLANG_SPANISH_MODERN 1.223 + { "ES", SUBLANG_SPANISH }, 1.224 + { "MX", SUBLANG_SPANISH_MEXICAN }, 1.225 + { "GT", SUBLANG_SPANISH_GUATEMALA }, 1.226 + { "CR", SUBLANG_SPANISH_COSTA_RICA }, 1.227 + { "PA", SUBLANG_SPANISH_PANAMA }, 1.228 + { "DO", SUBLANG_SPANISH_DOMINICAN_REPUBLIC }, 1.229 + { "VE", SUBLANG_SPANISH_VENEZUELA }, 1.230 + { "CO", SUBLANG_SPANISH_COLOMBIA }, 1.231 + { "PE", SUBLANG_SPANISH_PERU }, 1.232 + { "AR", SUBLANG_SPANISH_ARGENTINA }, 1.233 + { "EC", SUBLANG_SPANISH_ECUADOR }, 1.234 + { "CL", SUBLANG_SPANISH_CHILE }, 1.235 + { "UY", SUBLANG_SPANISH_URUGUAY }, 1.236 + { "PY", SUBLANG_SPANISH_PARAGUAY }, 1.237 + { "BO", SUBLANG_SPANISH_BOLIVIA }, 1.238 + { "SV", SUBLANG_SPANISH_EL_SALVADOR }, 1.239 + { "HN", SUBLANG_SPANISH_HONDURAS }, 1.240 + { "NI", SUBLANG_SPANISH_NICARAGUA }, 1.241 + { "PR", SUBLANG_SPANISH_PUERTO_RICO }, 1.242 + { "", 0 }} 1.243 + }, 1.244 + {"et", LANG_ESTONIAN, { 1.245 + { "EE", SUBLANG_DEFAULT }, 1.246 + { "", 0}} 1.247 + }, 1.248 + {"eu", LANG_BASQUE, { 1.249 + { "ES" , SUBLANG_DEFAULT }, 1.250 + { "" , 0 }} 1.251 + }, 1.252 + {"fa", LANG_FARSI, { 1.253 + { "IR", SUBLANG_DEFAULT}, 1.254 + { "", 0}} 1.255 + }, 1.256 + {"fi", LANG_FINNISH, { 1.257 + { "FI", SUBLANG_DEFAULT }, 1.258 + { "",0}} 1.259 + }, 1.260 + {"fo", LANG_FAEROESE, { 1.261 + { "FO", SUBLANG_DEFAULT }, 1.262 + { "", 0}} 1.263 + }, 1.264 + { "fr", LANG_FRENCH, { 1.265 + { "FR", SUBLANG_FRENCH }, 1.266 + { "BE", SUBLANG_FRENCH_BELGIAN }, 1.267 + { "CA", SUBLANG_FRENCH_CANADIAN }, 1.268 + { "CH", SUBLANG_FRENCH_SWISS }, 1.269 + { "LU", SUBLANG_FRENCH_LUXEMBOURG }, 1.270 + { "MC", SUBLANG_FRENCH_MONACO }, 1.271 + {"",0}} 1.272 + }, 1.273 + { "gl", LANG_GALICIAN, { 1.274 + { "ES", SUBLANG_DEFAULT }, 1.275 + { "", 0}} 1.276 + }, 1.277 + { "gu", LANG_GUJARATI, { 1.278 + { "IN", SUBLANG_DEFAULT }, 1.279 + { "", 0}} 1.280 + }, 1.281 + {"he", LANG_HEBREW, { 1.282 + { "IL", SUBLANG_DEFAULT}, 1.283 + { "", 0}} 1.284 + }, 1.285 + {"hi", LANG_HINDI, { 1.286 + { "IN", SUBLANG_DEFAULT }, 1.287 + { "", 0}} 1.288 + }, 1.289 + /* Duplicate the SUBLANG codes for Croatian and Serbian, because the Windows 1.290 + LANG code is the same for both */ 1.291 + {"hr", LANG_CROATIAN, { 1.292 + { "CS", SUBLANG_SERBIAN_LATIN }, 1.293 + { "SP", SUBLANG_SERBIAN_CYRILLIC }, 1.294 + { "HR", SUBLANG_DEFAULT}, 1.295 + { "" ,0 }} 1.296 + }, 1.297 + {"hu", LANG_HUNGARIAN, { 1.298 + { "HU", SUBLANG_DEFAULT }, 1.299 + { "" , 0 }} 1.300 + }, 1.301 + {"hy", LANG_ARMENIAN, { 1.302 + { "AM", SUBLANG_DEFAULT}, 1.303 + { "" ,0 }} 1.304 + }, 1.305 + {"id", LANG_INDONESIAN, { 1.306 + { "ID", SUBLANG_DEFAULT }, 1.307 + {"", 0}} 1.308 + }, 1.309 + {"is", LANG_ICELANDIC, { 1.310 + { "IS", SUBLANG_DEFAULT }, 1.311 + { "", 0}} 1.312 + }, 1.313 + { "it", LANG_ITALIAN, { 1.314 + { "IT", SUBLANG_ITALIAN }, 1.315 + { "CH", SUBLANG_ITALIAN_SWISS }, 1.316 + { "", 0}} 1.317 + }, 1.318 + {"iw", LANG_HEBREW, { 1.319 + { "IL", SUBLANG_DEFAULT}, 1.320 + { "", 0}} 1.321 + }, 1.322 + {"ja", LANG_JAPANESE, { 1.323 + { "JP", SUBLANG_DEFAULT }, 1.324 + { "", 0}} 1.325 + }, 1.326 + { "ka", LANG_GEORGIAN, { 1.327 + { "GE", SUBLANG_DEFAULT }, 1.328 + { "", 0}} 1.329 + }, 1.330 + { "kk", LANG_KAZAK, { 1.331 + { "KZ", SUBLANG_DEFAULT }, // KAZAKHSTAN 1.332 + { "", 0}} 1.333 + }, 1.334 + { "kn", LANG_KANNADA, { 1.335 + { "IN", SUBLANG_DEFAULT }, 1.336 + { "", 0}} 1.337 + }, 1.338 + { "ko", LANG_KOREAN, { 1.339 + { "KR", SUBLANG_KOREAN }, 1.340 + { "", 0}} 1.341 + }, 1.342 + { "kok", LANG_KONKANI, { 1.343 + { "IN", SUBLANG_DEFAULT }, 1.344 + { "", 0}} 1.345 + }, 1.346 + { "ky", LANG_KYRGYZ, { 1.347 + { "KG", SUBLANG_DEFAULT }, // Kygyzstan 1.348 + { "", 0}} 1.349 + }, 1.350 + {"lt", LANG_LITHUANIAN, { 1.351 + { "LT", SUBLANG_DEFAULT }, 1.352 + { "" ,0 }} 1.353 + }, 1.354 + {"lv", LANG_LATVIAN, { 1.355 + { "LV", SUBLANG_DEFAULT}, 1.356 + { "", 0}} 1.357 + }, 1.358 + {"mk", LANG_MACEDONIAN, { 1.359 + { "MK", SUBLANG_DEFAULT }, 1.360 + { "", 0 }} 1.361 + }, 1.362 + { "mn", LANG_MONGOLIAN, { 1.363 + { "MN", SUBLANG_DEFAULT }, 1.364 + { "", 0}} 1.365 + }, 1.366 + { "mr", LANG_MARATHI, { 1.367 + { "IN", SUBLANG_DEFAULT }, 1.368 + { "", 0}} 1.369 + }, 1.370 + {"ms", LANG_MALAY, { 1.371 + { "MY", SUBLANG_MALAY_MALAYSIA }, 1.372 + { "BN", SUBLANG_MALAY_BRUNEI_DARUSSALAM }, // XXX 1.373 + { "", 0}} 1.374 + }, 1.375 + {"nb", LANG_NORWEGIAN, { 1.376 + { "NO", SUBLANG_NORWEGIAN_BOKMAL }, 1.377 + { "", SUBLANG_NORWEGIAN_BOKMAL}} 1.378 + }, 1.379 + {"nl", LANG_DUTCH, { 1.380 + {"NL", SUBLANG_DUTCH }, 1.381 + {"BE", SUBLANG_DUTCH_BELGIAN }, 1.382 + { "", 0}} 1.383 + }, 1.384 + {"nn", LANG_NORWEGIAN, { 1.385 + { "NO", SUBLANG_NORWEGIAN_NYNORSK }, 1.386 + { "", SUBLANG_NORWEGIAN_NYNORSK}} 1.387 + }, 1.388 + {"no", LANG_NORWEGIAN, { 1.389 + { "NO", SUBLANG_DEFAULT }, 1.390 + { "", 0}} 1.391 + }, 1.392 + { "pa", LANG_PUNJABI, { 1.393 + { "IN", SUBLANG_DEFAULT }, 1.394 + { "", 0}} 1.395 + }, 1.396 + {"pl", LANG_POLISH, { 1.397 + { "PL", SUBLANG_DEFAULT }, 1.398 + { "", 0}} 1.399 + }, 1.400 + { "pt", LANG_PORTUGUESE, { 1.401 + { "PT", SUBLANG_PORTUGUESE }, 1.402 + { "BR", SUBLANG_PORTUGUESE_BRAZILIAN }, 1.403 + {"",0}} 1.404 + }, 1.405 + {"ro", LANG_ROMANIAN, { 1.406 + { "RO", SUBLANG_DEFAULT }, 1.407 + { "", 0}} 1.408 + }, 1.409 + {"ru", LANG_RUSSIAN, { 1.410 + { "RU", SUBLANG_DEFAULT }, 1.411 + { "", 0 }} 1.412 + }, 1.413 + { "sa", LANG_SANSKRIT, { 1.414 + { "IN", SUBLANG_DEFAULT }, 1.415 + { "", 0}} 1.416 + }, 1.417 + {"sk", LANG_SLOVAK, { 1.418 + { "SK", SUBLANG_DEFAULT }, 1.419 + { "", 0}} 1.420 + }, 1.421 + {"sl", LANG_SLOVENIAN, { 1.422 + { "SI", SUBLANG_DEFAULT }, 1.423 + { "", 0}} 1.424 + }, 1.425 + {"sq", LANG_ALBANIAN, { 1.426 + { "AL", SUBLANG_DEFAULT }, 1.427 + { "", 0}} 1.428 + }, 1.429 + /* Duplicate the SUBLANG codes for Croatian and Serbian, because the Windows 1.430 + LANG code is the same for both */ 1.431 + {"sr", LANG_SERBIAN, { 1.432 + { "CS", SUBLANG_SERBIAN_LATIN }, 1.433 + { "SP", SUBLANG_SERBIAN_CYRILLIC }, 1.434 + { "HR", SUBLANG_DEFAULT }, 1.435 + { "", 0}} 1.436 + }, 1.437 + { "sv", LANG_SWEDISH, { 1.438 + { "SE", SUBLANG_SWEDISH }, 1.439 + { "FI", SUBLANG_SWEDISH_FINLAND }, 1.440 + { "", 0 }} 1.441 + }, 1.442 + {"sw", LANG_SWAHILI, { 1.443 + { "KE", SUBLANG_DEFAULT }, 1.444 + { "", 0}} 1.445 + }, 1.446 + { "ta", LANG_TAMIL, { 1.447 + { "IN", SUBLANG_DEFAULT }, 1.448 + { "", 0}} 1.449 + }, 1.450 + { "te", LANG_TELUGU, { 1.451 + { "IN", SUBLANG_DEFAULT }, 1.452 + { "", 0}} 1.453 + }, 1.454 + {"th", LANG_THAI, { 1.455 + {"TH", SUBLANG_DEFAULT}, 1.456 + {"",0}} 1.457 + }, 1.458 + {"tr", LANG_TURKISH, { 1.459 + { "TR", SUBLANG_DEFAULT }, 1.460 + { "", 0}} 1.461 + }, 1.462 + { "tt", LANG_TATAR, { 1.463 + { "RU", SUBLANG_DEFAULT }, 1.464 + { "", 0}} 1.465 + }, 1.466 + {"uk", LANG_UKRAINIAN, { 1.467 + { "UA", SUBLANG_DEFAULT }, 1.468 + { "", 0}} 1.469 + }, 1.470 + {"ur", LANG_URDU, { 1.471 + { "PK", SUBLANG_URDU_PAKISTAN }, 1.472 + { "IN", SUBLANG_URDU_INDIA }, 1.473 + { "", 0}} 1.474 + }, 1.475 + {"uz", LANG_UZBEK, { // XXX : Cyrillic, Latin 1.476 + { "UZ", SUBLANG_DEFAULT }, 1.477 + { "", 0}} 1.478 + }, 1.479 + {"vi", LANG_VIETNAMESE, { 1.480 + { "VN", SUBLANG_DEFAULT }, 1.481 + { "", 0}} 1.482 + }, 1.483 + { "zh", LANG_CHINESE, { 1.484 + { "TW", SUBLANG_CHINESE_TRADITIONAL }, 1.485 + { "CN", SUBLANG_CHINESE_SIMPLIFIED }, 1.486 + { "HK", SUBLANG_CHINESE_HONGKONG }, 1.487 + { "SG", SUBLANG_CHINESE_SINGAPORE }, 1.488 + { "MO", SUBLANG_CHINESE_MACAU }, 1.489 + { "",0}} 1.490 + } 1.491 +}; 1.492 + 1.493 +#define LENGTH_MAPPING_LIST ArrayLength(iso_list) 1.494 + 1.495 +// 1.496 +// This list maps ISO 2 digit country codes to Win32 country codes. 1.497 +// This list must be kept in alphabetic (by iso code) order and synchronized 1.498 +// with the list above. This is only used in debug builds to check the consistentcy 1.499 +// of the internal tables. 1.500 +// 1.501 +#ifdef DEBUG 1.502 +static const 1.503 +iso_pair dbg_list[] = 1.504 +{ 1.505 + {"af", LANG_AFRIKAANS}, 1.506 + {"ar", LANG_ARABIC}, 1.507 + {"az", LANG_AZERI}, 1.508 + {"be", LANG_BELARUSIAN}, 1.509 + {"bg", LANG_BULGARIAN}, 1.510 + {"ca", LANG_CATALAN}, 1.511 + {"cs", LANG_CZECH}, 1.512 + {"da", LANG_DANISH}, 1.513 + {"de", LANG_GERMAN}, 1.514 + {"dv", LANG_DIVEHI}, 1.515 + {"el", LANG_GREEK}, 1.516 + {"en", LANG_ENGLISH}, 1.517 + {"es", LANG_SPANISH}, 1.518 + {"et", LANG_ESTONIAN}, 1.519 + {"eu", LANG_BASQUE}, 1.520 + {"fa", LANG_FARSI}, 1.521 + {"fi", LANG_FINNISH}, 1.522 + {"fo", LANG_FAEROESE}, 1.523 + {"fr", LANG_FRENCH}, 1.524 + {"gl", LANG_GALICIAN}, 1.525 + {"gu", LANG_GUJARATI}, 1.526 + {"he", LANG_HEBREW}, 1.527 + {"hi", LANG_HINDI}, 1.528 + {"hr", LANG_CROATIAN}, 1.529 + {"hu", LANG_HUNGARIAN}, 1.530 + {"hy", LANG_ARMENIAN}, 1.531 + {"id", LANG_INDONESIAN}, 1.532 + {"in", LANG_INDONESIAN}, 1.533 + {"is", LANG_ICELANDIC}, 1.534 + {"it", LANG_ITALIAN}, 1.535 + {"iw", LANG_HEBREW}, 1.536 + {"ja", LANG_JAPANESE}, 1.537 + {"ka", LANG_GEORGIAN}, 1.538 + {"kn", LANG_KANNADA}, 1.539 + {"ko", LANG_KOREAN}, 1.540 + {"kok", LANG_KONKANI}, 1.541 + {"lt", LANG_LITHUANIAN}, 1.542 + {"lv", LANG_LATVIAN}, 1.543 + {"mk", LANG_MACEDONIAN}, 1.544 + {"mn", LANG_MONGOLIAN}, 1.545 + {"mr", LANG_MARATHI}, 1.546 + {"ms", LANG_MALAY}, 1.547 + {"nb", LANG_NORWEGIAN}, 1.548 + {"nl", LANG_DUTCH}, 1.549 + {"nn", LANG_NORWEGIAN}, 1.550 + {"no", LANG_NORWEGIAN}, 1.551 + {"pa", LANG_PUNJABI}, 1.552 + {"pl", LANG_POLISH}, 1.553 + {"pt", LANG_PORTUGUESE}, 1.554 + {"ro", LANG_ROMANIAN}, 1.555 + {"ru", LANG_RUSSIAN}, 1.556 + {"sa", LANG_SANSKRIT}, 1.557 + {"sk", LANG_SLOVAK}, 1.558 + {"sl", LANG_SLOVENIAN}, 1.559 + {"sq", LANG_ALBANIAN}, 1.560 + {"sr", LANG_SERBIAN}, 1.561 + {"sv", LANG_SWEDISH}, 1.562 + {"sw", LANG_SWAHILI}, 1.563 + {"ta", LANG_TAMIL}, 1.564 + {"te", LANG_TELUGU}, 1.565 + {"th", LANG_THAI}, 1.566 + {"tr", LANG_TURKISH}, 1.567 + {"tt", LANG_TATAR}, 1.568 + {"uk", LANG_UKRAINIAN}, 1.569 + {"ur", LANG_URDU}, 1.570 + {"uz", LANG_UZBEK}, 1.571 + {"vi", LANG_VIETNAMESE}, 1.572 + {"zh", LANG_CHINESE}, 1.573 + {"",0} 1.574 +}; 1.575 +#endif 1.576 + 1.577 +#define CROATIAN_ISO_CODE "hr" 1.578 +#define SERBIAN_ISO_CODE "sr" 1.579 + 1.580 +void 1.581 +nsWin32Locale::initFunctionPointers(void) 1.582 +{ 1.583 + static bool sInitialized = false; 1.584 + // We use the Vista and above functions if we have them 1.585 + if (!sInitialized) { 1.586 + HMODULE kernelDLL = GetModuleHandleW(L"kernel32.dll"); 1.587 + if (kernelDLL) { 1.588 + localeNameToLCID = (LocaleNameToLCIDPtr) GetProcAddress(kernelDLL, "LocaleNameToLCID"); 1.589 + lcidToLocaleName = (LCIDToLocaleNamePtr) GetProcAddress(kernelDLL, "LCIDToLocaleName"); 1.590 + } 1.591 + sInitialized = true; 1.592 + } 1.593 +} 1.594 + 1.595 +// 1.596 +// the mapping routines are a first approximation to get us going on 1.597 +// the tier-1 languages. we are making an assumption that we can map 1.598 +// language and country codes separately on Windows, which isn't true 1.599 +// 1.600 +nsresult 1.601 +nsWin32Locale::GetPlatformLocale(const nsAString& locale, LCID* winLCID) 1.602 +{ 1.603 + initFunctionPointers (); 1.604 + 1.605 + if (localeNameToLCID) { 1.606 + nsAutoString locale_autostr(locale); 1.607 + LCID lcid = localeNameToLCID(locale_autostr.get(), 0); 1.608 + // The function returning 0 means that the locale name couldn't be matched, 1.609 + // so we fallback to the old function 1.610 + if (lcid != 0) 1.611 + { 1.612 + *winLCID = lcid; 1.613 + return NS_OK; 1.614 + } 1.615 + } 1.616 + 1.617 + char locale_string[9] = {'\0','\0','\0','\0','\0','\0','\0','\0','\0'}; 1.618 + char* language_code; 1.619 + char* country_code; 1.620 + size_t i, j; 1.621 + 1.622 + // parse the locale 1.623 + const char16_t* data; 1.624 + j = NS_StringGetData(locale, &data); 1.625 + for (i = 0; i < 7 && i < j; i++) { 1.626 + locale_string[i] = data[i] == '-' ? '\0' : data[i]; 1.627 + } 1.628 + 1.629 + language_code = locale_string; 1.630 + country_code = locale_string + strlen(locale_string) + 1; 1.631 + 1.632 + // convert parsed locale to Windows LCID 1.633 + for(i=0;i<LENGTH_MAPPING_LIST;i++) { 1.634 + if (strcmp(language_code,iso_list[i].iso_code)==0) { 1.635 + for(j=0;iso_list[i].sublang_list[j].win_code;j++) { 1.636 + if (strcmp(country_code,iso_list[i].sublang_list[j].iso_code)==0) { 1.637 + *winLCID = MAKELCID(MAKELANGID(iso_list[i].win_code,iso_list[i].sublang_list[j].win_code),SORT_DEFAULT); 1.638 + return NS_OK; 1.639 + } 1.640 + } 1.641 + // here we have a language match but no country match 1.642 + *winLCID = MAKELCID(MAKELANGID(iso_list[i].win_code,SUBLANG_DEFAULT),SORT_DEFAULT); 1.643 + return NS_OK; 1.644 + } 1.645 + } 1.646 + 1.647 + return NS_ERROR_FAILURE; 1.648 +} 1.649 + 1.650 +#ifndef LOCALE_NAME_MAX_LENGTH 1.651 +#define LOCALE_NAME_MAX_LENGTH 85 1.652 +#endif 1.653 + 1.654 +void 1.655 +nsWin32Locale::GetXPLocale(LCID winLCID, nsAString& locale) 1.656 +{ 1.657 + initFunctionPointers (); 1.658 + 1.659 + if (lcidToLocaleName) 1.660 + { 1.661 + WCHAR ret_locale[LOCALE_NAME_MAX_LENGTH]; 1.662 + int rv = lcidToLocaleName(winLCID, ret_locale, LOCALE_NAME_MAX_LENGTH, 0); 1.663 + // rv 0 means that the function failed to match up the LCID, so we fallback 1.664 + // to the old function 1.665 + if (rv != 0) 1.666 + { 1.667 + locale.Assign(ret_locale); 1.668 + return; 1.669 + } 1.670 + } 1.671 + 1.672 + DWORD lang_id, sublang_id; 1.673 + size_t i, j; 1.674 + 1.675 + lang_id = PRIMARYLANGID(LANGIDFROMLCID(winLCID)); 1.676 + sublang_id = SUBLANGID(LANGIDFROMLCID(winLCID)); 1.677 + 1.678 + /* Special-case Norwegian Bokmal and Norwegian Nynorsk, which have the same 1.679 + LANG_ID on Windows, but have separate ISO-639-2 codes */ 1.680 + if (lang_id == LANG_NORWEGIAN) { 1.681 + if (sublang_id == SUBLANG_NORWEGIAN_BOKMAL) { 1.682 + locale.AssignASCII("nb-NO"); 1.683 + } else if (sublang_id == SUBLANG_NORWEGIAN_NYNORSK) { 1.684 + locale.AssignASCII("nn-NO"); 1.685 + } else { 1.686 + locale.AssignASCII("no-NO"); 1.687 + } 1.688 + return; 1.689 + } 1.690 + 1.691 + for(i=0;i<LENGTH_MAPPING_LIST;i++) { 1.692 + if (lang_id==iso_list[i].win_code) { 1.693 + /* Special-case Croatian and Serbian, which have the same LANG_ID on 1.694 + Windows, but have been split into separate ISO-639-2 codes */ 1.695 + if (lang_id == LANG_CROATIAN) { 1.696 + if (sublang_id == SUBLANG_DEFAULT) { 1.697 + locale.AssignLiteral(CROATIAN_ISO_CODE); 1.698 + } else { 1.699 + locale.AssignLiteral(SERBIAN_ISO_CODE); 1.700 + } 1.701 + } else { 1.702 + locale.AssignASCII(iso_list[i].iso_code); 1.703 + } 1.704 + for(j=0;iso_list[i].sublang_list[j].win_code;j++) { 1.705 + if (sublang_id == iso_list[i].sublang_list[j].win_code) { 1.706 + locale.Append(char16_t('-')); 1.707 + locale.AppendASCII(iso_list[i].sublang_list[j].iso_code); 1.708 + break; 1.709 + } 1.710 + } 1.711 + return; 1.712 + } 1.713 + } 1.714 + 1.715 + // 1.716 + // didn't find any match. fall back to en-US, which is better 1.717 + // than unusable buttons without 'OK', 'Cancel', etc (bug 224546) 1.718 + // 1.719 + locale.AssignLiteral("en-US"); 1.720 + return; 1.721 +} 1.722 + 1.723 +#ifdef DEBUG 1.724 +void 1.725 +test_internal_tables(void) 1.726 +{ 1.727 + size_t i; 1.728 + 1.729 + for(i=1;i<LENGTH_MAPPING_LIST;i++) { 1.730 + if (strcmp(dbg_list[i-1].iso_code,dbg_list[i].iso_code)>=0) 1.731 + fprintf(stderr,"nsLocale: language_list %s and %s are not ordered\n",dbg_list[i-1].iso_code,dbg_list[i].iso_code); 1.732 + } 1.733 + 1.734 + i=0; 1.735 + while(strlen(dbg_list[i].iso_code)!=0) { 1.736 + i++; 1.737 + } 1.738 + if (i!=LENGTH_MAPPING_LIST) 1.739 + fprintf(stderr,"nsLocale: language_list length is %d, reported length is %d\n",i,LENGTH_MAPPING_LIST); 1.740 + 1.741 + for(i=0;i<LENGTH_MAPPING_LIST;i++) { 1.742 + if (strcmp(iso_list[i].iso_code,dbg_list[i].iso_code)!=0) { 1.743 + fprintf(stderr,"nsLocale: iso_list and dbg_list differet at item: %d\n",i); 1.744 + } 1.745 + } 1.746 +} 1.747 + 1.748 +#endif 1.749 +