michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "mozilla/ArrayUtils.h" michael@0: michael@0: #include "nscore.h" michael@0: #include "nsString.h" michael@0: #include "nsXPCOMStrings.h" michael@0: #include "nsReadableUtils.h" michael@0: #include "nsWin32Locale.h" michael@0: #include "prprf.h" michael@0: #include michael@0: #include "nsCRT.h" michael@0: michael@0: using namespace mozilla; michael@0: michael@0: struct iso_pair michael@0: { michael@0: const char* iso_code; michael@0: DWORD win_code; michael@0: }; michael@0: michael@0: struct iso_map michael@0: { michael@0: const char* iso_code; michael@0: DWORD win_code; michael@0: iso_pair sublang_list[20]; michael@0: }; michael@0: michael@0: nsWin32Locale::LocaleNameToLCIDPtr nsWin32Locale::localeNameToLCID = nullptr; michael@0: nsWin32Locale::LCIDToLocaleNamePtr nsWin32Locale::lcidToLocaleName = nullptr; michael@0: michael@0: // Older versions of VC++ and Win32 SDK and mingw don't have michael@0: // macros for languages and sublanguages recently added to Win32. michael@0: // see http://www.tug.org/ftp/tex/texinfo/intl/localename.c michael@0: michael@0: #ifndef LANG_URDU michael@0: #define LANG_URDU 0x20 michael@0: #endif michael@0: #ifndef LANG_ARMENIAN michael@0: #define LANG_ARMENIAN 0x2b michael@0: #endif michael@0: #ifndef LANG_AZERI michael@0: #define LANG_AZERI 0x2c michael@0: #endif michael@0: #ifndef LANG_MACEDONIAN michael@0: #define LANG_MACEDONIAN 0x2f michael@0: #endif michael@0: #ifndef LANG_GEORGIAN michael@0: #define LANG_GEORGIAN 0x37 michael@0: #endif michael@0: #ifndef LANG_HINDI michael@0: #define LANG_HINDI 0x39 michael@0: #endif michael@0: #ifndef LANG_MALAY michael@0: #define LANG_MALAY 0x3e michael@0: #endif michael@0: #ifndef LANG_KAZAK michael@0: #define LANG_KAZAK 0x3f michael@0: #endif michael@0: #ifndef LANG_KYRGYZ michael@0: #define LANG_KYRGYZ 0x40 michael@0: #endif michael@0: #ifndef LANG_SWAHILI michael@0: #define LANG_SWAHILI 0x41 michael@0: #endif michael@0: #ifndef LANG_UZBEK michael@0: #define LANG_UZBEK 0x43 michael@0: #endif michael@0: #ifndef LANG_TATAR michael@0: #define LANG_TATAR 0x44 michael@0: #endif michael@0: #ifndef LANG_PUNJABI michael@0: #define LANG_PUNJABI 0x46 michael@0: #endif michael@0: #ifndef LANG_GUJARAT michael@0: #define LANG_GUJARAT 0x47 michael@0: #endif michael@0: #ifndef LANG_TAMIL michael@0: #define LANG_TAMIL 0x49 michael@0: #endif michael@0: #ifndef LANG_TELUGU michael@0: #define LANG_TELUGU 0x4a michael@0: #endif michael@0: #ifndef LANG_KANNADA michael@0: #define LANG_KANNADA 0x4b michael@0: #endif michael@0: #ifndef LANG_MARATHI michael@0: #define LANG_MARATHI 0x4e michael@0: #endif michael@0: #ifndef LANG_SANSKRIT michael@0: #define LANG_SANSKRIT 0x4f michael@0: #endif michael@0: #ifndef LANG_MONGOLIAN michael@0: #define LANG_MONGOLIAN 0x50 michael@0: #endif michael@0: #ifndef LANG_GALICIAN michael@0: #define LANG_GALICIAN 0x56 michael@0: #endif michael@0: #ifndef LANG_KONKANI michael@0: #define LANG_KONKANI 0x57 michael@0: #endif michael@0: #ifndef LANG_DIVEHI michael@0: #define LANG_DIVEHI 0x65 michael@0: #endif michael@0: michael@0: #ifndef SUBLANG_MALAY_MALAYSIA michael@0: #define SUBLANG_MALAY_MALAYSIA 0x01 michael@0: #endif michael@0: #ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM michael@0: #define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02 michael@0: #endif michael@0: #ifndef SUBLANG_CHINESE_MACAU michael@0: #define SUBLANG_CHINESE_MACAU 0x05 michael@0: #endif michael@0: #ifndef SUBLANG_FRENCH_MONACO michael@0: #define SUBLANG_FRENCH_MONACO 0x06 michael@0: #endif michael@0: #ifndef SUBLANG_ENGLISH_ZIMBABWE michael@0: #define SUBLANG_ENGLISH_ZIMBABWE 0x0c michael@0: #endif michael@0: #ifndef SUBLANG_ENGLISH_PHILIPPINES michael@0: #define SUBLANG_ENGLISH_PHILIPPINES 0x0d michael@0: #endif michael@0: michael@0: michael@0: // michael@0: // This list is used to map between ISO language michael@0: // References : michael@0: // http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html michael@0: // http://www.loc.gov/standards/iso639-2/ michael@0: // http://www.ethnologue.com/ michael@0: // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_19ir.asp michael@0: // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_61df.asp michael@0: michael@0: static const michael@0: iso_map iso_list[] = michael@0: { michael@0: {"af", LANG_AFRIKAANS, { michael@0: { "ZA", SUBLANG_DEFAULT }, michael@0: { "",0}} michael@0: }, michael@0: { "ar", LANG_ARABIC, { michael@0: { "SA", SUBLANG_ARABIC_SAUDI_ARABIA }, michael@0: { "IQ", SUBLANG_ARABIC_IRAQ }, michael@0: { "EG", SUBLANG_ARABIC_EGYPT }, michael@0: { "LY", SUBLANG_ARABIC_LIBYA }, michael@0: { "DZ", SUBLANG_ARABIC_ALGERIA }, michael@0: { "MA", SUBLANG_ARABIC_MOROCCO }, michael@0: { "TN", SUBLANG_ARABIC_TUNISIA }, michael@0: { "OM", SUBLANG_ARABIC_OMAN }, michael@0: { "YE", SUBLANG_ARABIC_YEMEN }, michael@0: { "SY", SUBLANG_ARABIC_SYRIA }, michael@0: { "JO", SUBLANG_ARABIC_JORDAN }, michael@0: { "LB", SUBLANG_ARABIC_LEBANON }, michael@0: { "KW", SUBLANG_ARABIC_KUWAIT }, michael@0: { "AE", SUBLANG_ARABIC_UAE }, michael@0: { "BH", SUBLANG_ARABIC_BAHRAIN }, michael@0: { "QA", SUBLANG_ARABIC_QATAR }, michael@0: {"",0}} michael@0: }, michael@0: {"az", LANG_AZERI, { michael@0: { "AZ",SUBLANG_DEFAULT }, // XXX Latin vs Cyrillic vs Arabic michael@0: { "",0}} michael@0: }, michael@0: {"be", LANG_BELARUSIAN, { michael@0: { "BY",SUBLANG_DEFAULT }, michael@0: { "",0}} michael@0: }, michael@0: {"bg", LANG_BULGARIAN, { michael@0: { "BG", SUBLANG_DEFAULT }, michael@0: { "",0}} michael@0: }, michael@0: {"ca", LANG_CATALAN, { michael@0: { "ES", SUBLANG_DEFAULT}, michael@0: { "",0}} michael@0: }, michael@0: {"cs", LANG_CZECH, { michael@0: { "CZ", SUBLANG_DEFAULT}, michael@0: {"",0}} michael@0: }, michael@0: { "da", LANG_DANISH, { michael@0: { "DK", SUBLANG_DEFAULT }, michael@0: { "",0}} michael@0: }, michael@0: { "de", LANG_GERMAN, { michael@0: { "DE", SUBLANG_GERMAN }, michael@0: { "CH", SUBLANG_GERMAN_SWISS }, michael@0: { "AT", SUBLANG_GERMAN_AUSTRIAN }, michael@0: { "LU", SUBLANG_GERMAN_LUXEMBOURG }, michael@0: { "LI", SUBLANG_GERMAN_LIECHTENSTEIN }, michael@0: { "" , 0}} michael@0: }, michael@0: {"dv", LANG_DIVEHI, { michael@0: { "MV", SUBLANG_DEFAULT}, michael@0: { "", 0}} michael@0: }, michael@0: {"el", LANG_GREEK, { michael@0: { "GR", SUBLANG_DEFAULT}, michael@0: { "", 0}} michael@0: }, michael@0: { "en", LANG_ENGLISH, { michael@0: { "US", SUBLANG_ENGLISH_US }, michael@0: { "GB", SUBLANG_ENGLISH_UK }, michael@0: { "AU", SUBLANG_ENGLISH_AUS }, michael@0: { "CA", SUBLANG_ENGLISH_CAN }, michael@0: { "NZ", SUBLANG_ENGLISH_NZ }, michael@0: { "IE", SUBLANG_ENGLISH_EIRE }, michael@0: { "ZA", SUBLANG_ENGLISH_SOUTH_AFRICA }, michael@0: { "JM", SUBLANG_ENGLISH_JAMAICA }, michael@0: { "BZ", SUBLANG_ENGLISH_BELIZE }, michael@0: { "TT", SUBLANG_ENGLISH_TRINIDAD }, michael@0: { "ZW", SUBLANG_ENGLISH_ZIMBABWE }, michael@0: { "PH", SUBLANG_ENGLISH_PHILIPPINES }, michael@0: { "",0}} michael@0: }, michael@0: { "es", LANG_SPANISH, { // XXX : SUBLANG_SPANISH_MODERN michael@0: { "ES", SUBLANG_SPANISH }, michael@0: { "MX", SUBLANG_SPANISH_MEXICAN }, michael@0: { "GT", SUBLANG_SPANISH_GUATEMALA }, michael@0: { "CR", SUBLANG_SPANISH_COSTA_RICA }, michael@0: { "PA", SUBLANG_SPANISH_PANAMA }, michael@0: { "DO", SUBLANG_SPANISH_DOMINICAN_REPUBLIC }, michael@0: { "VE", SUBLANG_SPANISH_VENEZUELA }, michael@0: { "CO", SUBLANG_SPANISH_COLOMBIA }, michael@0: { "PE", SUBLANG_SPANISH_PERU }, michael@0: { "AR", SUBLANG_SPANISH_ARGENTINA }, michael@0: { "EC", SUBLANG_SPANISH_ECUADOR }, michael@0: { "CL", SUBLANG_SPANISH_CHILE }, michael@0: { "UY", SUBLANG_SPANISH_URUGUAY }, michael@0: { "PY", SUBLANG_SPANISH_PARAGUAY }, michael@0: { "BO", SUBLANG_SPANISH_BOLIVIA }, michael@0: { "SV", SUBLANG_SPANISH_EL_SALVADOR }, michael@0: { "HN", SUBLANG_SPANISH_HONDURAS }, michael@0: { "NI", SUBLANG_SPANISH_NICARAGUA }, michael@0: { "PR", SUBLANG_SPANISH_PUERTO_RICO }, michael@0: { "", 0 }} michael@0: }, michael@0: {"et", LANG_ESTONIAN, { michael@0: { "EE", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: {"eu", LANG_BASQUE, { michael@0: { "ES" , SUBLANG_DEFAULT }, michael@0: { "" , 0 }} michael@0: }, michael@0: {"fa", LANG_FARSI, { michael@0: { "IR", SUBLANG_DEFAULT}, michael@0: { "", 0}} michael@0: }, michael@0: {"fi", LANG_FINNISH, { michael@0: { "FI", SUBLANG_DEFAULT }, michael@0: { "",0}} michael@0: }, michael@0: {"fo", LANG_FAEROESE, { michael@0: { "FO", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: { "fr", LANG_FRENCH, { michael@0: { "FR", SUBLANG_FRENCH }, michael@0: { "BE", SUBLANG_FRENCH_BELGIAN }, michael@0: { "CA", SUBLANG_FRENCH_CANADIAN }, michael@0: { "CH", SUBLANG_FRENCH_SWISS }, michael@0: { "LU", SUBLANG_FRENCH_LUXEMBOURG }, michael@0: { "MC", SUBLANG_FRENCH_MONACO }, michael@0: {"",0}} michael@0: }, michael@0: { "gl", LANG_GALICIAN, { michael@0: { "ES", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: { "gu", LANG_GUJARATI, { michael@0: { "IN", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: {"he", LANG_HEBREW, { michael@0: { "IL", SUBLANG_DEFAULT}, michael@0: { "", 0}} michael@0: }, michael@0: {"hi", LANG_HINDI, { michael@0: { "IN", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: /* Duplicate the SUBLANG codes for Croatian and Serbian, because the Windows michael@0: LANG code is the same for both */ michael@0: {"hr", LANG_CROATIAN, { michael@0: { "CS", SUBLANG_SERBIAN_LATIN }, michael@0: { "SP", SUBLANG_SERBIAN_CYRILLIC }, michael@0: { "HR", SUBLANG_DEFAULT}, michael@0: { "" ,0 }} michael@0: }, michael@0: {"hu", LANG_HUNGARIAN, { michael@0: { "HU", SUBLANG_DEFAULT }, michael@0: { "" , 0 }} michael@0: }, michael@0: {"hy", LANG_ARMENIAN, { michael@0: { "AM", SUBLANG_DEFAULT}, michael@0: { "" ,0 }} michael@0: }, michael@0: {"id", LANG_INDONESIAN, { michael@0: { "ID", SUBLANG_DEFAULT }, michael@0: {"", 0}} michael@0: }, michael@0: {"is", LANG_ICELANDIC, { michael@0: { "IS", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: { "it", LANG_ITALIAN, { michael@0: { "IT", SUBLANG_ITALIAN }, michael@0: { "CH", SUBLANG_ITALIAN_SWISS }, michael@0: { "", 0}} michael@0: }, michael@0: {"iw", LANG_HEBREW, { michael@0: { "IL", SUBLANG_DEFAULT}, michael@0: { "", 0}} michael@0: }, michael@0: {"ja", LANG_JAPANESE, { michael@0: { "JP", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: { "ka", LANG_GEORGIAN, { michael@0: { "GE", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: { "kk", LANG_KAZAK, { michael@0: { "KZ", SUBLANG_DEFAULT }, // KAZAKHSTAN michael@0: { "", 0}} michael@0: }, michael@0: { "kn", LANG_KANNADA, { michael@0: { "IN", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: { "ko", LANG_KOREAN, { michael@0: { "KR", SUBLANG_KOREAN }, michael@0: { "", 0}} michael@0: }, michael@0: { "kok", LANG_KONKANI, { michael@0: { "IN", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: { "ky", LANG_KYRGYZ, { michael@0: { "KG", SUBLANG_DEFAULT }, // Kygyzstan michael@0: { "", 0}} michael@0: }, michael@0: {"lt", LANG_LITHUANIAN, { michael@0: { "LT", SUBLANG_DEFAULT }, michael@0: { "" ,0 }} michael@0: }, michael@0: {"lv", LANG_LATVIAN, { michael@0: { "LV", SUBLANG_DEFAULT}, michael@0: { "", 0}} michael@0: }, michael@0: {"mk", LANG_MACEDONIAN, { michael@0: { "MK", SUBLANG_DEFAULT }, michael@0: { "", 0 }} michael@0: }, michael@0: { "mn", LANG_MONGOLIAN, { michael@0: { "MN", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: { "mr", LANG_MARATHI, { michael@0: { "IN", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: {"ms", LANG_MALAY, { michael@0: { "MY", SUBLANG_MALAY_MALAYSIA }, michael@0: { "BN", SUBLANG_MALAY_BRUNEI_DARUSSALAM }, // XXX michael@0: { "", 0}} michael@0: }, michael@0: {"nb", LANG_NORWEGIAN, { michael@0: { "NO", SUBLANG_NORWEGIAN_BOKMAL }, michael@0: { "", SUBLANG_NORWEGIAN_BOKMAL}} michael@0: }, michael@0: {"nl", LANG_DUTCH, { michael@0: {"NL", SUBLANG_DUTCH }, michael@0: {"BE", SUBLANG_DUTCH_BELGIAN }, michael@0: { "", 0}} michael@0: }, michael@0: {"nn", LANG_NORWEGIAN, { michael@0: { "NO", SUBLANG_NORWEGIAN_NYNORSK }, michael@0: { "", SUBLANG_NORWEGIAN_NYNORSK}} michael@0: }, michael@0: {"no", LANG_NORWEGIAN, { michael@0: { "NO", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: { "pa", LANG_PUNJABI, { michael@0: { "IN", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: {"pl", LANG_POLISH, { michael@0: { "PL", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: { "pt", LANG_PORTUGUESE, { michael@0: { "PT", SUBLANG_PORTUGUESE }, michael@0: { "BR", SUBLANG_PORTUGUESE_BRAZILIAN }, michael@0: {"",0}} michael@0: }, michael@0: {"ro", LANG_ROMANIAN, { michael@0: { "RO", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: {"ru", LANG_RUSSIAN, { michael@0: { "RU", SUBLANG_DEFAULT }, michael@0: { "", 0 }} michael@0: }, michael@0: { "sa", LANG_SANSKRIT, { michael@0: { "IN", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: {"sk", LANG_SLOVAK, { michael@0: { "SK", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: {"sl", LANG_SLOVENIAN, { michael@0: { "SI", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: {"sq", LANG_ALBANIAN, { michael@0: { "AL", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: /* Duplicate the SUBLANG codes for Croatian and Serbian, because the Windows michael@0: LANG code is the same for both */ michael@0: {"sr", LANG_SERBIAN, { michael@0: { "CS", SUBLANG_SERBIAN_LATIN }, michael@0: { "SP", SUBLANG_SERBIAN_CYRILLIC }, michael@0: { "HR", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: { "sv", LANG_SWEDISH, { michael@0: { "SE", SUBLANG_SWEDISH }, michael@0: { "FI", SUBLANG_SWEDISH_FINLAND }, michael@0: { "", 0 }} michael@0: }, michael@0: {"sw", LANG_SWAHILI, { michael@0: { "KE", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: { "ta", LANG_TAMIL, { michael@0: { "IN", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: { "te", LANG_TELUGU, { michael@0: { "IN", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: {"th", LANG_THAI, { michael@0: {"TH", SUBLANG_DEFAULT}, michael@0: {"",0}} michael@0: }, michael@0: {"tr", LANG_TURKISH, { michael@0: { "TR", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: { "tt", LANG_TATAR, { michael@0: { "RU", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: {"uk", LANG_UKRAINIAN, { michael@0: { "UA", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: {"ur", LANG_URDU, { michael@0: { "PK", SUBLANG_URDU_PAKISTAN }, michael@0: { "IN", SUBLANG_URDU_INDIA }, michael@0: { "", 0}} michael@0: }, michael@0: {"uz", LANG_UZBEK, { // XXX : Cyrillic, Latin michael@0: { "UZ", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: {"vi", LANG_VIETNAMESE, { michael@0: { "VN", SUBLANG_DEFAULT }, michael@0: { "", 0}} michael@0: }, michael@0: { "zh", LANG_CHINESE, { michael@0: { "TW", SUBLANG_CHINESE_TRADITIONAL }, michael@0: { "CN", SUBLANG_CHINESE_SIMPLIFIED }, michael@0: { "HK", SUBLANG_CHINESE_HONGKONG }, michael@0: { "SG", SUBLANG_CHINESE_SINGAPORE }, michael@0: { "MO", SUBLANG_CHINESE_MACAU }, michael@0: { "",0}} michael@0: } michael@0: }; michael@0: michael@0: #define LENGTH_MAPPING_LIST ArrayLength(iso_list) michael@0: michael@0: // michael@0: // This list maps ISO 2 digit country codes to Win32 country codes. michael@0: // This list must be kept in alphabetic (by iso code) order and synchronized michael@0: // with the list above. This is only used in debug builds to check the consistentcy michael@0: // of the internal tables. michael@0: // michael@0: #ifdef DEBUG michael@0: static const michael@0: iso_pair dbg_list[] = michael@0: { michael@0: {"af", LANG_AFRIKAANS}, michael@0: {"ar", LANG_ARABIC}, michael@0: {"az", LANG_AZERI}, michael@0: {"be", LANG_BELARUSIAN}, michael@0: {"bg", LANG_BULGARIAN}, michael@0: {"ca", LANG_CATALAN}, michael@0: {"cs", LANG_CZECH}, michael@0: {"da", LANG_DANISH}, michael@0: {"de", LANG_GERMAN}, michael@0: {"dv", LANG_DIVEHI}, michael@0: {"el", LANG_GREEK}, michael@0: {"en", LANG_ENGLISH}, michael@0: {"es", LANG_SPANISH}, michael@0: {"et", LANG_ESTONIAN}, michael@0: {"eu", LANG_BASQUE}, michael@0: {"fa", LANG_FARSI}, michael@0: {"fi", LANG_FINNISH}, michael@0: {"fo", LANG_FAEROESE}, michael@0: {"fr", LANG_FRENCH}, michael@0: {"gl", LANG_GALICIAN}, michael@0: {"gu", LANG_GUJARATI}, michael@0: {"he", LANG_HEBREW}, michael@0: {"hi", LANG_HINDI}, michael@0: {"hr", LANG_CROATIAN}, michael@0: {"hu", LANG_HUNGARIAN}, michael@0: {"hy", LANG_ARMENIAN}, michael@0: {"id", LANG_INDONESIAN}, michael@0: {"in", LANG_INDONESIAN}, michael@0: {"is", LANG_ICELANDIC}, michael@0: {"it", LANG_ITALIAN}, michael@0: {"iw", LANG_HEBREW}, michael@0: {"ja", LANG_JAPANESE}, michael@0: {"ka", LANG_GEORGIAN}, michael@0: {"kn", LANG_KANNADA}, michael@0: {"ko", LANG_KOREAN}, michael@0: {"kok", LANG_KONKANI}, michael@0: {"lt", LANG_LITHUANIAN}, michael@0: {"lv", LANG_LATVIAN}, michael@0: {"mk", LANG_MACEDONIAN}, michael@0: {"mn", LANG_MONGOLIAN}, michael@0: {"mr", LANG_MARATHI}, michael@0: {"ms", LANG_MALAY}, michael@0: {"nb", LANG_NORWEGIAN}, michael@0: {"nl", LANG_DUTCH}, michael@0: {"nn", LANG_NORWEGIAN}, michael@0: {"no", LANG_NORWEGIAN}, michael@0: {"pa", LANG_PUNJABI}, michael@0: {"pl", LANG_POLISH}, michael@0: {"pt", LANG_PORTUGUESE}, michael@0: {"ro", LANG_ROMANIAN}, michael@0: {"ru", LANG_RUSSIAN}, michael@0: {"sa", LANG_SANSKRIT}, michael@0: {"sk", LANG_SLOVAK}, michael@0: {"sl", LANG_SLOVENIAN}, michael@0: {"sq", LANG_ALBANIAN}, michael@0: {"sr", LANG_SERBIAN}, michael@0: {"sv", LANG_SWEDISH}, michael@0: {"sw", LANG_SWAHILI}, michael@0: {"ta", LANG_TAMIL}, michael@0: {"te", LANG_TELUGU}, michael@0: {"th", LANG_THAI}, michael@0: {"tr", LANG_TURKISH}, michael@0: {"tt", LANG_TATAR}, michael@0: {"uk", LANG_UKRAINIAN}, michael@0: {"ur", LANG_URDU}, michael@0: {"uz", LANG_UZBEK}, michael@0: {"vi", LANG_VIETNAMESE}, michael@0: {"zh", LANG_CHINESE}, michael@0: {"",0} michael@0: }; michael@0: #endif michael@0: michael@0: #define CROATIAN_ISO_CODE "hr" michael@0: #define SERBIAN_ISO_CODE "sr" michael@0: michael@0: void michael@0: nsWin32Locale::initFunctionPointers(void) michael@0: { michael@0: static bool sInitialized = false; michael@0: // We use the Vista and above functions if we have them michael@0: if (!sInitialized) { michael@0: HMODULE kernelDLL = GetModuleHandleW(L"kernel32.dll"); michael@0: if (kernelDLL) { michael@0: localeNameToLCID = (LocaleNameToLCIDPtr) GetProcAddress(kernelDLL, "LocaleNameToLCID"); michael@0: lcidToLocaleName = (LCIDToLocaleNamePtr) GetProcAddress(kernelDLL, "LCIDToLocaleName"); michael@0: } michael@0: sInitialized = true; michael@0: } michael@0: } michael@0: michael@0: // michael@0: // the mapping routines are a first approximation to get us going on michael@0: // the tier-1 languages. we are making an assumption that we can map michael@0: // language and country codes separately on Windows, which isn't true michael@0: // michael@0: nsresult michael@0: nsWin32Locale::GetPlatformLocale(const nsAString& locale, LCID* winLCID) michael@0: { michael@0: initFunctionPointers (); michael@0: michael@0: if (localeNameToLCID) { michael@0: nsAutoString locale_autostr(locale); michael@0: LCID lcid = localeNameToLCID(locale_autostr.get(), 0); michael@0: // The function returning 0 means that the locale name couldn't be matched, michael@0: // so we fallback to the old function michael@0: if (lcid != 0) michael@0: { michael@0: *winLCID = lcid; michael@0: return NS_OK; michael@0: } michael@0: } michael@0: michael@0: char locale_string[9] = {'\0','\0','\0','\0','\0','\0','\0','\0','\0'}; michael@0: char* language_code; michael@0: char* country_code; michael@0: size_t i, j; michael@0: michael@0: // parse the locale michael@0: const char16_t* data; michael@0: j = NS_StringGetData(locale, &data); michael@0: for (i = 0; i < 7 && i < j; i++) { michael@0: locale_string[i] = data[i] == '-' ? '\0' : data[i]; michael@0: } michael@0: michael@0: language_code = locale_string; michael@0: country_code = locale_string + strlen(locale_string) + 1; michael@0: michael@0: // convert parsed locale to Windows LCID michael@0: for(i=0;i=0) michael@0: fprintf(stderr,"nsLocale: language_list %s and %s are not ordered\n",dbg_list[i-1].iso_code,dbg_list[i].iso_code); michael@0: } michael@0: michael@0: i=0; michael@0: while(strlen(dbg_list[i].iso_code)!=0) { michael@0: i++; michael@0: } michael@0: if (i!=LENGTH_MAPPING_LIST) michael@0: fprintf(stderr,"nsLocale: language_list length is %d, reported length is %d\n",i,LENGTH_MAPPING_LIST); michael@0: michael@0: for(i=0;i