Back to index

lightning-sunbird  0.9+nobinonly
nsIWin32LocaleImpl.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsISupports.h"
00039 #include "nscore.h"
00040 #include "nsString.h"
00041 #include "nsReadableUtils.h"
00042 #include "nsILocale.h"
00043 #include "nsIwin32LocaleImpl.h"
00044 #include "nsLocaleCID.h"
00045 #include "prprf.h"
00046 #include <windows.h>
00047 #include "nsCRT.h"
00048  #include "nsReadableUtils.h"
00049 
00050 #define USER_DEFINED_PRIMARYLANG   0x0200
00051 #define USER_DEFINED_SUBLANGUAGE   0x20
00052 
00053 
00054 struct iso_pair 
00055 {
00056        const char*   iso_code;
00057        DWORD       win_code;
00058 };
00059 
00060 struct iso_map
00061 {
00062        const char* iso_code;
00063        DWORD       win_code;
00064        iso_pair    sublang_list[20];
00065 };
00066 
00067 // Older versions of VC++ and Win32 SDK  and mingw don't have 
00068 // macros for languages and sublanguages recently added to Win32. 
00069 // see http://www.tug.org/ftp/tex/texinfo/intl/localename.c
00070 
00071 #ifndef LANG_URDU
00072 #define LANG_URDU                           0x20
00073 #endif
00074 #ifndef LANG_ARMENIAN
00075 #define LANG_ARMENIAN                       0x2b
00076 #endif
00077 #ifndef LANG_AZERI
00078 #define LANG_AZERI                          0x2c
00079 #endif
00080 #ifndef LANG_MACEDONIAN
00081 #define LANG_MACEDONIAN                     0x2f
00082 #endif
00083 #ifndef LANG_GEORGIAN
00084 #define LANG_GEORGIAN                       0x37
00085 #endif
00086 #ifndef LANG_HINDI
00087 #define LANG_HINDI                          0x39
00088 #endif
00089 #ifndef LANG_MALAY
00090 #define LANG_MALAY                          0x3e
00091 #endif
00092 #ifndef LANG_KAZAK
00093 #define LANG_KAZAK                          0x3f
00094 #endif
00095 #ifndef LANG_KYRGYZ
00096 #define LANG_KYRGYZ                         0x40
00097 #endif
00098 #ifndef LANG_SWAHILI
00099 #define LANG_SWAHILI                        0x41
00100 #endif
00101 #ifndef LANG_UZBEK
00102 #define LANG_UZBEK                          0x43
00103 #endif
00104 #ifndef LANG_TATAR
00105 #define LANG_TATAR                          0x44
00106 #endif
00107 #ifndef LANG_PUNJABI
00108 #define LANG_PUNJABI                        0x46
00109 #endif
00110 #ifndef LANG_GUJARAT
00111 #define LANG_GUJARAT                        0x47
00112 #endif
00113 #ifndef LANG_TAMIL
00114 #define LANG_TAMIL                          0x49
00115 #endif
00116 #ifndef LANG_TELUGU
00117 #define LANG_TELUGU                         0x4a
00118 #endif
00119 #ifndef LANG_KANNADA
00120 #define LANG_KANNADA                        0x4b
00121 #endif
00122 #ifndef LANG_MARATHI
00123 #define LANG_MARATHI                        0x4e
00124 #endif
00125 #ifndef LANG_SANSKRIT
00126 #define LANG_SANSKRIT                       0x4f
00127 #endif
00128 #ifndef LANG_MONGOLIAN
00129 #define LANG_MONGOLIAN                      0x50
00130 #endif
00131 #ifndef LANG_GALICIAN
00132 #define LANG_GALICIAN                       0x56
00133 #endif
00134 #ifndef LANG_KONKANI
00135 #define LANG_KONKANI                        0x57
00136 #endif
00137 #ifndef LANG_DIVEHI
00138 #define LANG_DIVEHI                         0x65
00139 #endif
00140 
00141 #ifndef SUBLANG_MALAY_MALAYSIA
00142 #define SUBLANG_MALAY_MALAYSIA              0x01
00143 #endif
00144 #ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM
00145 #define SUBLANG_MALAY_BRUNEI_DARUSSALAM     0x02
00146 #endif
00147 #ifndef SUBLANG_CHINESE_MACAU
00148 #define SUBLANG_CHINESE_MACAU               0x05
00149 #endif
00150 #ifndef SUBLANG_FRENCH_MONACO
00151 #define SUBLANG_FRENCH_MONACO               0x06
00152 #endif
00153 #ifndef SUBLANG_ENGLISH_ZIMBABWE
00154 #define SUBLANG_ENGLISH_ZIMBABWE            0x0c
00155 #endif
00156 #ifndef SUBLANG_ENGLISH_PHILIPPINES
00157 #define SUBLANG_ENGLISH_PHILIPPINES         0x0d
00158 #endif
00159 
00160 
00161 // Turn this on when ParseLocaleString(), GetXPLocale(), and 
00162 // GetPlatformLocale() are fixed to support three letter lang codes.
00163 #undef THREE_LETTER_LANG_CODE_SUPPORTED
00164 
00165 //
00166 // This list is used to map between ISO language
00167 // References : 
00168 // http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html
00169 // http://www.loc.gov/standards/iso639-2/
00170 // http://www.ethnologue.com/
00171 // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_19ir.asp
00172 // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_61df.asp
00173  
00174 static const
00175 iso_map iso_list[] =
00176 {
00177        {"af", LANG_AFRIKAANS, {
00178               { "ZA", SUBLANG_DEFAULT },
00179               { "",0}}
00180        },
00181        { "ar", LANG_ARABIC, {
00182               { "SA", SUBLANG_ARABIC_SAUDI_ARABIA }, 
00183               { "IQ", SUBLANG_ARABIC_IRAQ },  
00184               { "EG",       SUBLANG_ARABIC_EGYPT },     
00185               { "LY", SUBLANG_ARABIC_LIBYA },
00186               { "DZ", SUBLANG_ARABIC_ALGERIA },
00187               { "MA", SUBLANG_ARABIC_MOROCCO },
00188               { "TN", SUBLANG_ARABIC_TUNISIA },
00189               { "OM", SUBLANG_ARABIC_OMAN }, 
00190               { "YE", SUBLANG_ARABIC_YEMEN },
00191               { "SY", SUBLANG_ARABIC_SYRIA },
00192               { "JO", SUBLANG_ARABIC_JORDAN },
00193               { "LB", SUBLANG_ARABIC_LEBANON },
00194               { "KW", SUBLANG_ARABIC_KUWAIT },
00195               { "AE", SUBLANG_ARABIC_UAE },
00196               { "BH", SUBLANG_ARABIC_BAHRAIN },
00197               { "QA", SUBLANG_ARABIC_QATAR },
00198               {"",0}}
00199        },
00200        {"az", LANG_AZERI, {
00201               { "AZ",SUBLANG_DEFAULT },  // XXX Latin vs Cyrillic vs Arabic
00202               { "",0}}
00203        },
00204        {"be", LANG_BELARUSIAN, {
00205               { "BY",SUBLANG_DEFAULT },
00206               { "",0}}
00207        },
00208        {"bg", LANG_BULGARIAN, {
00209               { "BG", SUBLANG_DEFAULT },
00210               { "",0}}
00211        },
00212        {"ca", LANG_CATALAN, {
00213               { "ES", SUBLANG_DEFAULT},
00214               { "",0}}
00215        },
00216        {"cs", LANG_CZECH, {
00217               { "CZ", SUBLANG_DEFAULT},
00218               {"",0}}
00219        },
00220        { "da", LANG_DANISH, { 
00221               { "DK", SUBLANG_DEFAULT },
00222               { "",0}}
00223        },
00224        { "de", LANG_GERMAN, {
00225               { "DE", SUBLANG_GERMAN },
00226               { "CH", SUBLANG_GERMAN_SWISS },
00227               { "AT", SUBLANG_GERMAN_AUSTRIAN },
00228               { "LU", SUBLANG_GERMAN_LUXEMBOURG },
00229               { "LI", SUBLANG_GERMAN_LIECHTENSTEIN },
00230               { "" , 0}}
00231        },
00232        {"dv", LANG_DIVEHI, {
00233               { "MV", SUBLANG_DEFAULT},
00234               { "", 0}}
00235        },
00236        {"el", LANG_GREEK, {
00237               { "GR", SUBLANG_DEFAULT},
00238               { "", 0}}
00239        },
00240        { "en", LANG_ENGLISH, {
00241               { "US", SUBLANG_ENGLISH_US },
00242               { "GB", SUBLANG_ENGLISH_UK },
00243               { "AU", SUBLANG_ENGLISH_AUS },
00244               { "CA", SUBLANG_ENGLISH_CAN },
00245               { "NZ", SUBLANG_ENGLISH_NZ },
00246               { "IE", SUBLANG_ENGLISH_EIRE },
00247               { "ZA", SUBLANG_ENGLISH_SOUTH_AFRICA },
00248               { "JM", SUBLANG_ENGLISH_JAMAICA },
00249               { "BZ", SUBLANG_ENGLISH_BELIZE },
00250               { "TT", SUBLANG_ENGLISH_TRINIDAD },
00251               { "ZW", SUBLANG_ENGLISH_ZIMBABWE },
00252               { "PH", SUBLANG_ENGLISH_PHILIPPINES },
00253               { "",0}}
00254        },
00255        { "es", LANG_SPANISH, {  // XXX : SUBLANG_SPANISH_MODERN
00256               { "ES", SUBLANG_SPANISH },
00257               { "MX", SUBLANG_SPANISH_MEXICAN },
00258               { "GT", SUBLANG_SPANISH_GUATEMALA },
00259               { "CR", SUBLANG_SPANISH_COSTA_RICA },
00260               { "PA", SUBLANG_SPANISH_PANAMA },
00261               { "DO", SUBLANG_SPANISH_DOMINICAN_REPUBLIC },
00262               { "VE", SUBLANG_SPANISH_VENEZUELA },
00263               { "CO", SUBLANG_SPANISH_COLOMBIA },
00264               { "PE", SUBLANG_SPANISH_PERU },
00265               { "AR", SUBLANG_SPANISH_ARGENTINA },
00266               { "EC", SUBLANG_SPANISH_ECUADOR },
00267               { "CL", SUBLANG_SPANISH_CHILE },
00268               { "UY", SUBLANG_SPANISH_URUGUAY },
00269               { "PY", SUBLANG_SPANISH_PARAGUAY },
00270               { "BO", SUBLANG_SPANISH_BOLIVIA },
00271               { "SV", SUBLANG_SPANISH_EL_SALVADOR },
00272               { "HN", SUBLANG_SPANISH_HONDURAS },
00273               { "NI", SUBLANG_SPANISH_NICARAGUA },
00274            { "PR", SUBLANG_SPANISH_PUERTO_RICO },
00275               { "", 0 }}
00276        },
00277        {"et", LANG_ESTONIAN, {
00278               { "EE", SUBLANG_DEFAULT },
00279               { "", 0}}
00280        },
00281        {"eu", LANG_BASQUE, {
00282               { "ES" , SUBLANG_DEFAULT },
00283               { "" , 0 }}
00284        },
00285        {"fa", LANG_FARSI, {
00286               { "IR", SUBLANG_DEFAULT},
00287               { "", 0}}
00288        },
00289        {"fi", LANG_FINNISH, {
00290               { "FI", SUBLANG_DEFAULT },
00291               { "",0}}
00292        },
00293        {"fo", LANG_FAEROESE, {
00294               { "FO", SUBLANG_DEFAULT },
00295               { "", 0}}
00296        },
00297        { "fr", LANG_FRENCH, {
00298               { "FR", SUBLANG_FRENCH },
00299               { "BE", SUBLANG_FRENCH_BELGIAN },
00300               { "CA", SUBLANG_FRENCH_CANADIAN },
00301               { "CH", SUBLANG_FRENCH_SWISS },
00302               { "LU", SUBLANG_FRENCH_LUXEMBOURG },
00303               { "MC", SUBLANG_FRENCH_MONACO },
00304               {"",0}}
00305        },
00306        { "gl", LANG_GALICIAN, {
00307               { "ES", SUBLANG_DEFAULT }, 
00308               { "", 0}}
00309        },
00310        { "gu", LANG_GUJARATI, {
00311               { "IN", SUBLANG_DEFAULT }, 
00312               { "", 0}}
00313        },
00314        {"he", LANG_HEBREW, {
00315               { "IL", SUBLANG_DEFAULT},
00316               { "", 0}}
00317        },
00318        {"hi", LANG_HINDI, {
00319               { "IN", SUBLANG_DEFAULT },
00320               { "", 0}}
00321        },
00322        /* Duplicate the SUBLANG codes for Croatian and Serbian, because the Windows
00323           LANG code is the same for both */
00324        {"hr", LANG_CROATIAN, {
00325               { "CS", SUBLANG_SERBIAN_LATIN },
00326               { "SP", SUBLANG_SERBIAN_CYRILLIC },
00327               { "HR", SUBLANG_DEFAULT},
00328               { "" ,0 }}
00329        },
00330        {"hu", LANG_HUNGARIAN, {
00331               { "HU", SUBLANG_DEFAULT },
00332               { "" , 0 }}
00333        },
00334        {"hy", LANG_ARMENIAN, {
00335               { "AM", SUBLANG_DEFAULT},
00336               { "" ,0 }}
00337        },
00338        {"id", LANG_INDONESIAN, {
00339               { "ID", SUBLANG_DEFAULT },
00340               {"", 0}}
00341        },
00342        {"is", LANG_ICELANDIC, {
00343               { "IS", SUBLANG_DEFAULT },
00344               { "", 0}}
00345        },
00346        { "it", LANG_ITALIAN, {
00347               { "IT", SUBLANG_ITALIAN },
00348               { "CH", SUBLANG_ITALIAN_SWISS },
00349               { "", 0}}
00350        },
00351        {"iw", LANG_HEBREW, {
00352               { "IL", SUBLANG_DEFAULT},
00353               { "", 0}}
00354        },
00355        {"ja", LANG_JAPANESE, {
00356               { "JP", SUBLANG_DEFAULT },
00357               { "", 0}}
00358        },
00359        { "ka", LANG_GEORGIAN, {
00360               { "GE", SUBLANG_DEFAULT },
00361               { "", 0}}
00362        },
00363        { "kk", LANG_KAZAK, {
00364               { "KZ", SUBLANG_DEFAULT }, // KAZAKHSTAN
00365               { "", 0}}
00366        },
00367        { "kn", LANG_KANNADA, {
00368               { "IN", SUBLANG_DEFAULT }, 
00369               { "", 0}}
00370        },
00371        { "ko", LANG_KOREAN, {
00372               { "KR", SUBLANG_KOREAN },
00373               { "", 0}}
00374        },
00375 #ifdef THREE_LETTER_LANG_CODE_SUPPORTED
00376        { "kok", LANG_KONKANI, {
00377               { "IN", SUBLANG_DEFAULT }, 
00378               { "", 0}}
00379        },
00380 #endif
00381        { "ky", LANG_KYRGYZ, {
00382               { "KG", SUBLANG_DEFAULT }, // Kygyzstan
00383               { "", 0}}
00384        },
00385        {"lt", LANG_LITHUANIAN, {
00386               { "LT", SUBLANG_DEFAULT },
00387               { "" ,0 }}
00388        },
00389        {"lv", LANG_LATVIAN, {
00390               { "LV", SUBLANG_DEFAULT},
00391               { "", 0}}
00392        },
00393        {"mk", LANG_MACEDONIAN, {
00394               { "MK", SUBLANG_DEFAULT },
00395               { "", 0 }}
00396        },
00397        { "mn", LANG_MONGOLIAN, {
00398               { "MN", SUBLANG_DEFAULT }, 
00399               { "", 0}}
00400        },
00401        { "mr", LANG_MARATHI, {
00402               { "IN", SUBLANG_DEFAULT }, 
00403               { "", 0}}
00404        },
00405        {"ms", LANG_MALAY, {
00406               { "MY", SUBLANG_MALAY_MALAYSIA },
00407               { "BN", SUBLANG_MALAY_BRUNEI_DARUSSALAM }, // XXX
00408               { "", 0}}
00409        },
00410        {"nl", LANG_DUTCH, {
00411               {"NL", SUBLANG_DUTCH },
00412               {"BE", SUBLANG_DUTCH_BELGIAN },
00413               { "", 0}}
00414        },
00415        {"no", LANG_NORWEGIAN, {     // XXX : Nynorsk vs Bokmal 
00416               { "NO",  SUBLANG_DEFAULT },
00417               { "", 0}}
00418        },
00419        { "pa", LANG_PUNJABI, {
00420               { "IN", SUBLANG_DEFAULT }, 
00421               { "", 0}}
00422        },
00423        {"pl", LANG_POLISH, {
00424               { "PL", SUBLANG_DEFAULT },
00425               { "", 0}}
00426        },
00427        { "pt", LANG_PORTUGUESE, {
00428               { "PT", SUBLANG_PORTUGUESE },
00429               { "BR", SUBLANG_PORTUGUESE_BRAZILIAN },
00430               {"",0}}
00431        },
00432        {"ro", LANG_ROMANIAN, {
00433               { "RO", SUBLANG_DEFAULT },
00434               { "", 0}}
00435        },
00436        {"ru", LANG_RUSSIAN, {
00437               { "RU", SUBLANG_DEFAULT },
00438               { "", 0 }}
00439        },
00440        { "sa", LANG_SANSKRIT, {
00441               { "IN", SUBLANG_DEFAULT }, 
00442               { "", 0}}
00443        },
00444        {"sk", LANG_SLOVAK, {
00445               { "SK", SUBLANG_DEFAULT },
00446               { "", 0}}
00447        },
00448        {"sl", LANG_SLOVENIAN, {
00449               { "SI", SUBLANG_DEFAULT },
00450               { "", 0}}
00451        },
00452        {"sq", LANG_ALBANIAN, {
00453               { "AL", SUBLANG_DEFAULT },
00454               { "", 0}}
00455        },            
00456        /* Duplicate the SUBLANG codes for Croatian and Serbian, because the Windows
00457           LANG code is the same for both */
00458        {"sr", LANG_SERBIAN, {
00459               { "CS", SUBLANG_SERBIAN_LATIN },
00460               { "SP", SUBLANG_SERBIAN_CYRILLIC },
00461               { "HR", SUBLANG_DEFAULT },
00462               { "", 0}}
00463        },
00464        { "sv", LANG_SWEDISH, {
00465               { "SE", SUBLANG_SWEDISH },
00466               { "FI", SUBLANG_SWEDISH_FINLAND },
00467               { "", 0 }}
00468        },
00469        {"sw", LANG_SWAHILI, {
00470               { "KE", SUBLANG_DEFAULT },
00471               { "", 0}}
00472        },
00473        { "ta", LANG_TAMIL, {
00474               { "IN", SUBLANG_DEFAULT }, 
00475               { "", 0}}
00476        },
00477        { "te", LANG_TELUGU, {
00478               { "IN", SUBLANG_DEFAULT }, 
00479               { "", 0}}
00480        },
00481        {"th", LANG_THAI, {
00482               {"TH", SUBLANG_DEFAULT},
00483               {"",0}}
00484        },
00485        {"tr", LANG_TURKISH, {
00486               { "TR", SUBLANG_DEFAULT },
00487               { "", 0}}
00488        },
00489        { "tt", LANG_TATAR, {
00490               { "RU", SUBLANG_DEFAULT }, 
00491               { "", 0}}
00492        },
00493        {"uk", LANG_UKRAINIAN, {
00494               { "UA", SUBLANG_DEFAULT },
00495               { "", 0}}
00496        },
00497        {"ur", LANG_URDU, {
00498               { "PK", SUBLANG_URDU_PAKISTAN },
00499               { "IN", SUBLANG_URDU_INDIA },
00500               { "", 0}}
00501        },
00502        {"uz", LANG_UZBEK, {   // XXX : Cyrillic, Latin
00503               { "UZ", SUBLANG_DEFAULT },
00504               { "", 0}}
00505        },
00506        {"vi", LANG_VIETNAMESE, {
00507               { "VN", SUBLANG_DEFAULT },
00508               { "", 0}}
00509        },
00510        { "zh", LANG_CHINESE, {
00511               { "TW", SUBLANG_CHINESE_TRADITIONAL },
00512               { "CN", SUBLANG_CHINESE_SIMPLIFIED },
00513               { "HK", SUBLANG_CHINESE_HONGKONG },
00514               { "SG", SUBLANG_CHINESE_SINGAPORE },
00515               { "MO", SUBLANG_CHINESE_MACAU },
00516               { "",0}}
00517        }
00518 };
00519 
00520 #define LENGTH_MAPPING_LIST        NS_ARRAY_LENGTH(iso_list)
00521        
00522 //
00523 // This list maps ISO 2 digit country codes to Win32 country codes.
00524 // This list must be kept in alphabetic (by iso code) order and synchronized
00525 // with the list above.  This is only used in debug builds to check the consistentcy
00526 // of the internal tables.
00527 //
00528 #ifdef DEBUG
00529 static const
00530 iso_pair dbg_list[] =
00531 {
00532        {"af", LANG_AFRIKAANS},            
00533        {"ar", LANG_ARABIC},
00534        {"az", LANG_AZERI},
00535        {"be", LANG_BELARUSIAN},
00536        {"bg", LANG_BULGARIAN},
00537        {"ca", LANG_CATALAN},
00538        {"cs", LANG_CZECH},
00539        {"da", LANG_DANISH},
00540        {"de", LANG_GERMAN},
00541        {"dv",  LANG_DIVEHI},
00542        {"el", LANG_GREEK},
00543        {"en", LANG_ENGLISH},
00544        {"es", LANG_SPANISH},
00545        {"et", LANG_ESTONIAN},
00546        {"eu", LANG_BASQUE},
00547        {"fa", LANG_FARSI},
00548        {"fi", LANG_FINNISH},
00549        {"fo", LANG_FAEROESE},
00550        {"fr", LANG_FRENCH},
00551        {"gl",  LANG_GALICIAN},
00552        {"gu",  LANG_GUJARATI},
00553        {"he", LANG_HEBREW},
00554        {"hi", LANG_HINDI},
00555        {"hr", LANG_CROATIAN},
00556        {"hu", LANG_HUNGARIAN},
00557        {"hy", LANG_ARMENIAN},
00558        {"id", LANG_INDONESIAN},
00559        {"in", LANG_INDONESIAN},
00560        {"is", LANG_ICELANDIC},
00561        {"it", LANG_ITALIAN},
00562        {"iw", LANG_HEBREW},
00563        {"ja", LANG_JAPANESE},
00564        {"ka", LANG_GEORGIAN},
00565        {"kn",  LANG_KANNADA},
00566        {"ko", LANG_KOREAN},
00567 #ifdef THREE_LETTER_LANG_CODE_SUPPORTED
00568        {"kok", LANG_KONKANI},
00569 #endif
00570        {"lt", LANG_LITHUANIAN},
00571        {"lv", LANG_LATVIAN},
00572        {"mk", LANG_MACEDONIAN},
00573        {"mn",  LANG_MONGOLIAN},
00574        {"mr",  LANG_MARATHI},
00575        {"ms", LANG_MALAY},
00576        {"nl", LANG_DUTCH},
00577        {"no", LANG_NORWEGIAN},
00578        {"pa",  LANG_PUNJABI},
00579        {"pl", LANG_POLISH},
00580        {"pt", LANG_PORTUGUESE},
00581        {"ro", LANG_ROMANIAN},
00582        {"ru", LANG_RUSSIAN},
00583        {"sa",  LANG_SANSKRIT},
00584        {"sk", LANG_SLOVAK},
00585        {"sl", LANG_SLOVENIAN},
00586        {"sq", LANG_ALBANIAN},             
00587        {"sr", LANG_SERBIAN},
00588        {"sv", LANG_SWEDISH},
00589        {"sw", LANG_SWAHILI},
00590        {"ta",  LANG_TAMIL},
00591        {"te",  LANG_TELUGU},
00592        {"th", LANG_THAI},
00593        {"tr", LANG_TURKISH},
00594        {"tt",  LANG_TATAR},
00595        {"uk", LANG_UKRAINIAN},
00596        {"ur", LANG_URDU},
00597        {"uz", LANG_UZBEK},
00598        {"vi", LANG_VIETNAMESE},
00599        {"zh", LANG_CHINESE},
00600        {"",0}
00601 };
00602 #endif
00603 
00604 #define CROATIAN_ISO_CODE "hr"
00605 #define SERBIAN_ISO_CODE "sr"
00606 
00607 /* nsIWin32LocaleImpl */
00608 NS_IMPL_ISUPPORTS1(nsIWin32LocaleImpl,nsIWin32Locale)
00609 
00610 nsIWin32LocaleImpl::nsIWin32LocaleImpl(void)
00611 {
00612 }
00613 
00614 nsIWin32LocaleImpl::~nsIWin32LocaleImpl(void)
00615 {
00616 
00617 }
00618 
00619 //
00620 // the mapping routines are a first approximation to get us going on
00621 // the tier-1 languages.  we are making an assumption that we can map
00622 // language and country codes separately on Windows, which isn't true
00623 //
00624 
00625 NS_IMETHODIMP
00626 nsIWin32LocaleImpl::GetPlatformLocale(const nsAString& locale,LCID* winLCID)
00627 {
00628   char    language_code[3];
00629   char    country_code[3];
00630   char    region_code[3];
00631   int     i,j;
00632 
00633   if (!ParseLocaleString(NS_LossyConvertUTF16toASCII(locale).get(),language_code,country_code,region_code)) {
00634     *winLCID = MAKELCID(MAKELANGID(USER_DEFINED_PRIMARYLANG,USER_DEFINED_SUBLANGUAGE),
00635                         SORT_DEFAULT);
00636     return NS_OK;
00637   }
00638   // we have a LL-CC-RR style string
00639 
00640   for(i=0;i<LENGTH_MAPPING_LIST;i++) {
00641     if (strcmp(language_code,iso_list[i].iso_code)==0) {
00642       for(j=0;iso_list[i].sublang_list[j].win_code;j++) {
00643         if (strcmp(country_code,iso_list[i].sublang_list[j].iso_code)==0) {
00644           *winLCID = MAKELCID(MAKELANGID(iso_list[i].win_code,iso_list[i].sublang_list[j].win_code),SORT_DEFAULT);
00645           return NS_OK;
00646         }
00647       }
00648       // here we have a language match but no country match
00649       *winLCID = MAKELCID(MAKELANGID(iso_list[i].win_code,SUBLANG_DEFAULT),SORT_DEFAULT);
00650       return NS_OK;
00651     }
00652   }
00653     
00654   return NS_ERROR_FAILURE;
00655 }
00656 
00657 NS_IMETHODIMP
00658 nsIWin32LocaleImpl::GetXPLocale(LCID winLCID, nsAString& locale)
00659 {
00660   DWORD    lang_id, sublang_id;
00661   int      i,j;
00662 
00663   lang_id = PRIMARYLANGID(LANGIDFROMLCID(winLCID));
00664   sublang_id = SUBLANGID(LANGIDFROMLCID(winLCID));
00665 
00666   for(i=0;i<LENGTH_MAPPING_LIST;i++) {
00667     if (lang_id==iso_list[i].win_code) {
00668       /* Special-case Croatian and Serbian, which have the same LANG_ID on
00669          Windows, but have been split into separate ISO-639-2 codes */
00670       if (lang_id == LANG_CROATIAN) {
00671         if (sublang_id == SUBLANG_DEFAULT) {
00672           locale.AssignLiteral(CROATIAN_ISO_CODE);
00673         } else {
00674           locale.AssignLiteral(SERBIAN_ISO_CODE);
00675         }
00676       } else {
00677         locale.AssignASCII(iso_list[i].iso_code);
00678       }
00679       for(j=0;iso_list[i].sublang_list[j].win_code;j++) {
00680         if (sublang_id == iso_list[i].sublang_list[j].win_code) {
00681           locale.Append(PRUnichar('-'));
00682           locale.AppendASCII(iso_list[i].sublang_list[j].iso_code);
00683           break;
00684         }
00685       }
00686       return NS_OK;
00687     }
00688   }
00689 
00690   //
00691   // didn't find any match. fall back to en-US, which is better 
00692   // than unusable buttons without 'OK', 'Cancel', etc (bug 224546)       
00693   //
00694   locale.AssignLiteral("en-US"); 
00695   return NS_OK;
00696 
00697 }
00698 
00699 //
00700 // returns PR_FALSE/PR_TRUE depending on if it was of the form LL-CC-RR
00701 PRBool
00702 nsIWin32LocaleImpl::ParseLocaleString(const char* locale_string, char* language, char* country, char* region)
00703 {
00704        size_t        len = strlen(locale_string);
00705 
00706        if (len==0 || (len!=2 && len!=5 && len!=8))
00707               return PR_FALSE;
00708        
00709        if (len==2) {
00710               language[0]=locale_string[0];
00711               language[1]=locale_string[1];
00712               language[2]=0;
00713               country[0]=0;
00714               region[0]=0;
00715        } else if (len==5) {
00716               language[0]=locale_string[0];
00717               language[1]=locale_string[1];
00718               language[2]=0;
00719               country[0]=locale_string[3];
00720               country[1]=locale_string[4];
00721               country[2]=0;
00722               region[0]=0;
00723               if (locale_string[2]!='-') return PR_FALSE;
00724        } else if (len==8) {
00725               language[0]=locale_string[0];
00726               language[1]=locale_string[1];
00727               language[2]=0;
00728               country[0]=locale_string[3];
00729               country[1]=locale_string[4];
00730               country[2]=0;
00731               region[0]=locale_string[6];
00732               region[1]=locale_string[7];
00733               region[2]=0;
00734               if (locale_string[2]!='-' || locale_string[5]!='-') return PR_FALSE;
00735        } else {
00736               return PR_FALSE;
00737        }
00738 
00739        return PR_TRUE;
00740 }
00741 
00742 
00743 #ifdef DEBUG
00744 void
00745 test_internal_tables(void)
00746 {
00747        int    i;
00748 
00749        for(i=1;i<LENGTH_MAPPING_LIST;i++) {
00750               if (strcmp(dbg_list[i-1].iso_code,dbg_list[i].iso_code)>=0)
00751                      fprintf(stderr,"nsLocale: language_list %s and %s are not ordered\n",dbg_list[i-1].iso_code,dbg_list[i].iso_code);
00752        }
00753 
00754        i=0;
00755        while(strlen(dbg_list[i].iso_code)!=0) {
00756               i++;
00757        }
00758        if (i!=LENGTH_MAPPING_LIST)
00759               fprintf(stderr,"nsLocale: language_list length is %d, reported length is %d\n",i,LENGTH_MAPPING_LIST);
00760 
00761        for(i=0;i<LENGTH_MAPPING_LIST;i++) {
00762               if (strcmp(iso_list[i].iso_code,dbg_list[i].iso_code)!=0) {
00763                      fprintf(stderr,"nsLocale: iso_list and dbg_list differet at item: %d\n",i);
00764               }
00765        }
00766 }
00767 
00768 #endif
00769