intl/locale/src/windows/nsWin32Locale.cpp

changeset 0
6474c204b198
     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 +

mercurial