]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/intl.cpp
implemented fallback for AlphaBlend() for the systems not supporting it
[wxWidgets.git] / src / common / intl.cpp
index 92185e3f22b979524be07d631e1819cae854df7c..339b71aad0872aa2750c471a47c14ee469988cc2 100644 (file)
@@ -6,7 +6,7 @@
 // Created:     29/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
-// Licence:     wxWindows license
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
@@ -611,6 +611,8 @@ bool wxLocale::Init(const wxChar *szName,
   {
     // the argument to setlocale()
     szLocale = szShort;
+
+    wxCHECK_MSG( szLocale, FALSE, _T("no locale to set in wxLocale::Init()") );
   }
   m_pszOldLocale = wxSetlocale(LC_ALL, szLocale);
   if ( m_pszOldLocale == NULL )
@@ -709,6 +711,17 @@ bool wxLocale::Init(int language, int flags)
         return FALSE;
     }
 #elif defined(__WIN32__)
+
+    #if wxUSE_UNICODE && (defined(__VISUALC__) || defined(__MINGW32__))
+        // NB: setlocale() from msvcrt.dll (used by VC++ and Mingw)
+        //     can't set locale to language that can only be written using
+        //     Unicode.  Therefore wxSetlocale call failed, but we don't want
+        //     to report it as an error -- so that at least message catalogs
+        //     can be used. Watch for code marked with
+        //     #ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS bellow.
+        #define SETLOCALE_FAILS_ON_UNICODE_LANGS
+    #endif
+    
     wxMB2WXbuf retloc = wxT("C");
     if (language != wxLANGUAGE_DEFAULT)
     {
@@ -719,42 +732,58 @@ bool wxLocale::Init(int language, int flags)
         }
         else
         {
+            int codepage = -1;
             wxUint32 lcid = MAKELCID(MAKELANGID(info->WinLang, info->WinSublang),
                                      SORT_DEFAULT);
-            if (SetThreadLocale(lcid))
+            SetThreadLocale(lcid);
+            // NB: we must translate LCID to CRT's setlocale string ourselves,
+            //     because SetThreadLocale does not modify change the
+            //     interpretation of setlocale(LC_ALL, "") call:
+            wxChar buffer[256];
+            buffer[0] = wxT('\0');
+            GetLocaleInfo(lcid, LOCALE_SENGLANGUAGE, buffer, 256);
+            locale << buffer;
+            if (GetLocaleInfo(lcid, LOCALE_SENGCOUNTRY, buffer, 256) > 0)
+                locale << wxT("_") << buffer;
+            if (GetLocaleInfo(lcid, LOCALE_IDEFAULTANSICODEPAGE, buffer, 256) > 0)
+            {
+                codepage = wxAtoi(buffer);
+                if (codepage != 0)
+                    locale << wxT(".") << buffer;
+            }
+            if (locale.IsEmpty())
             {
-                retloc = wxSetlocale(LC_ALL, wxEmptyString);
+                wxLogLastError(wxT("SetThreadLocale"));
+                wxLogError(wxT("Cannot set locale to language %s."), name.c_str());
+                return FALSE;
             }
             else
             {
-                // Windows9X doesn't support SetThreadLocale, so we must
-                // translate LCID to CRT's setlocale string ourselves
-                locale.Empty();
-                if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
-                {
-                    wxChar buffer[256];
-                    buffer[0] = wxT('\0');
-                    GetLocaleInfo(lcid, LOCALE_SENGLANGUAGE, buffer, 256);
-                    locale << buffer;
-                    if (GetLocaleInfo(lcid, LOCALE_SENGCOUNTRY, buffer, 256) > 0)
-                        locale << wxT("_") << buffer;
-                }
-                if (locale.IsEmpty())
-                {
-                    wxLogLastError(wxT("SetThreadLocale"));
-                    wxLogError(wxT("Cannot set locale to language %s."), name.c_str());
-                    return FALSE;
-                }
-                else
+                retloc = wxSetlocale(LC_ALL, locale);
+#ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS
+                if (codepage == 0 && (const wxChar*)retloc == NULL)
                 {
-                    retloc = wxSetlocale(LC_ALL, locale);
+                    retloc = wxT("C");
                 }
+#endif
             }
         }
     }
     else
     {
         retloc = wxSetlocale(LC_ALL, wxEmptyString);
+#ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS
+        if ((const wxChar*)retloc == NULL)
+        {
+            wxChar buffer[16];
+            if (GetLocaleInfo(LOCALE_USER_DEFAULT,
+                              LOCALE_IDEFAULTANSICODEPAGE, buffer, 16) > 0 &&
+                 wxStrcmp(buffer, wxT("0")) == 0)
+            {
+                retloc = wxT("C");
+            }
+        }
+#endif
     }
 
     if ( !retloc )
@@ -766,11 +795,18 @@ bool wxLocale::Init(int language, int flags)
     wxMB2WXbuf retloc = wxSetlocale(LC_ALL , wxEmptyString);
 #else
     return FALSE;
+    #define WX_NO_LOCALE_SUPPORT
 #endif
 
-    return Init(name, canonical, retloc,
-                (flags & wxLOCALE_LOAD_DEFAULT) != 0,
-                (flags & wxLOCALE_CONV_ENCODING) != 0);
+#ifndef WX_NO_LOCALE_SUPPORT
+     wxChar *szLocale = retloc ? wxStrdup(retloc) : NULL;
+    bool ret = Init(name, canonical, retloc,
+                    (flags & wxLOCALE_LOAD_DEFAULT) != 0,
+                    (flags & wxLOCALE_CONV_ENCODING) != 0);
+    if (szLocale)
+        free(szLocale);
+    return ret;
+#endif
 }
 
 
@@ -915,279 +951,279 @@ void wxLocale::AddCatalogLookupPathPrefix(const wxString& prefix)
         }
     }
 #elif defined(__WXMAC__)
-    const char* lc = NULL ;
+    const wxChar * lc = NULL ;
     long lang = GetScriptVariable( smSystemScript, smScriptLang) ;
     switch( GetScriptManagerVariable( smRegionCode ) ) {
       case verUS :
-        lc = "en_US" ;
+        lc = wxT("en_US") ;
         break ;
       case verFrance :
-        lc = "fr_FR" ;
+        lc = wxT("fr_FR") ;
         break ;
       case verBritain :
-        lc = "en_GB" ;
+        lc = wxT("en_GB") ;
         break ;
       case verGermany :
-        lc = "de_DE" ;
+        lc = wxT("de_DE") ;
         break ;
       case verItaly :
-        lc = "it_IT" ;
+        lc = wxT("it_IT") ;
         break ;
       case verNetherlands :
-        lc = "nl_NL" ;
+        lc = wxT("nl_NL") ;
         break ;
       case verFlemish :
-        lc = "nl_BE" ;
+        lc = wxT("nl_BE") ;
         break ;
       case verSweden :
-        lc = "sv_SE" ;
+        lc = wxT("sv_SE" );
         break ;
       case verSpain :
-        lc = "es_ES" ;
+        lc = wxT("es_ES" );
         break ;
       case verDenmark :
-        lc = "da_DK" ;
+        lc = wxT("da_DK") ;
         break ;
       case verPortugal :
-        lc = "pt_PT" ;
+        lc = wxT("pt_PT") ;
         break ;
       case verFrCanada:
-        lc = "fr_CA" ;
+        lc = wxT("fr_CA") ;
         break ;
       case verNorway:
-        lc = "no_NO" ;
+        lc = wxT("no_NO") ;
         break ;
       case verIsrael:
-        lc = "iw_IL" ;
+        lc = wxT("iw_IL") ;
         break ;
       case verJapan:
-        lc = "ja_JP" ;
+        lc = wxT("ja_JP") ;
         break ;
       case verAustralia:
-        lc = "en_AU" ;
+        lc = wxT("en_AU") ;
         break ;
       case verArabic:
-        lc = "ar" ;
+        lc = wxT("ar") ;
         break ;
       case verFinland:
-        lc = "fi_FI" ;
+        lc = wxT("fi_FI") ;
         break ;
       case verFrSwiss:
-        lc = "fr_CH" ;
+        lc = wxT("fr_CH") ;
         break ;
       case verGrSwiss:
-        lc = "de_CH" ;
+        lc = wxT("de_CH") ;
         break ;
       case verGreece:
-        lc = "el_GR" ;
+        lc = wxT("el_GR") ;
         break ;
       case verIceland:
-        lc = "is_IS" ;
+        lc = wxT("is_IS") ;
         break ;
       case verMalta:
-        lc = "mt_MT" ;
+        lc = wxT("mt_MT") ;
         break ;
       case verCyprus:
       // _CY is not part of wx, so we have to translate according to the system language
         if ( lang == langGreek ) {
-          lc = "el_GR" ;
+          lc = wxT("el_GR") ;
         }
         else if ( lang == langTurkish ) {
-          lc = "tr_TR" ;
+          lc = wxT("tr_TR") ;
         }
         break ;
       case verTurkey:
-        lc = "tr_TR" ;
+        lc = wxT("tr_TR") ;
         break ;
       case verYugoCroatian:
-        lc = "hr_HR" ;
+        lc = wxT("hr_HR") ;
         break ;
       case verIndiaHindi:
-        lc = "hi_IN" ;
+        lc = wxT("hi_IN") ;
         break ;
       case verPakistanUrdu:
-        lc = "ur_PK" ;
+        lc = wxT("ur_PK") ;
         break ;
       case verTurkishModified:
-        lc = "tr_TR" ;
+        lc = wxT("tr_TR") ;
         break ;
       case verItalianSwiss:
-        lc = "it_CH" ;
+        lc = wxT("it_CH") ;
         break ;
       case verInternational:
-        lc = "en" ;
+        lc = wxT("en") ;
         break ;
       case verRomania:
-        lc = "ro_RO" ;
+        lc = wxT("ro_RO") ;
         break ;
       case verGreecePoly:
-        lc = "el_GR" ;
+        lc = wxT("el_GR") ;
         break ;
       case verLithuania:
-        lc = "lt_LT" ;
+        lc = wxT("lt_LT") ;
         break ;
       case verPoland:
-        lc = "pl_PL" ;
+        lc = wxT("pl_PL") ;
         break ;
       case verMagyar :
       case verHungary:
-        lc = "hu_HU" ;
+        lc = wxT("hu_HU") ;
         break ;
       case verEstonia:
-        lc = "et_EE" ;
+        lc = wxT("et_EE") ;
         break ;
       case verLatvia:
-        lc = "lv_LV" ;
+        lc = wxT("lv_LV") ;
         break ;
       case verSami:
         // not known
         break ;
       case verFaroeIsl:
-        lc = "fo_FO" ;
+        lc = wxT("fo_FO") ;
         break ;
       case verIran:
-        lc = "fa_IR" ;
+        lc = wxT("fa_IR") ;
         break ;
       case verRussia:
-        lc = "ru_RU" ;
+        lc = wxT("ru_RU") ;
         break ;
        case verIreland:
-        lc = "ga_IE" ;
+        lc = wxT("ga_IE") ;
         break ;
       case verKorea:
-        lc = "ko_KR" ;
+        lc = wxT("ko_KR") ;
         break ;
       case verChina:
-        lc = "zh_CN" ;
+        lc = wxT("zh_CN") ;
         break ;
       case verTaiwan:
-        lc = "zh_TW" ;
+        lc = wxT("zh_TW") ;
         break ;
       case verThailand:
-        lc = "th_TH" ;
+        lc = wxT("th_TH") ;
         break ;
       case verCzech:
-        lc = "cs_CZ" ;
+        lc = wxT("cs_CZ") ;
         break ;
       case verSlovak:
-        lc = "sk_SK" ;
+        lc = wxT("sk_SK") ;
         break ;
       case verBengali:
-        lc = "bn" ;
+        lc = wxT("bn") ;
         break ;
       case verByeloRussian:
-        lc = "be_BY" ;
+        lc = wxT("be_BY") ;
         break ;
       case verUkraine:
-        lc = "uk_UA" ;
+        lc = wxT("uk_UA") ;
         break ;
       case verGreeceAlt:
-        lc = "el_GR" ;
+        lc = wxT("el_GR") ;
         break ;
       case verSerbian:
-        lc = "sr_YU" ;
+        lc = wxT("sr_YU") ;
         break ;
       case verSlovenian:
-        lc = "sl_SI" ;
+        lc = wxT("sl_SI") ;
         break ;
       case verMacedonian:
-        lc = "mk_MK" ;
+        lc = wxT("mk_MK") ;
         break ;
       case verCroatia:
-        lc = "hr_HR" ;
+        lc = wxT("hr_HR") ;
         break ;
       case verBrazil:
-        lc = "pt_BR " ;
+        lc = wxT("pt_BR ") ;
         break ;
       case verBulgaria:
-        lc = "bg_BG" ;
+        lc = wxT("bg_BG") ;
         break ;
       case verCatalonia:
-        lc = "ca_ES" ;
+        lc = wxT("ca_ES") ;
         break ;
       case verScottishGaelic:
-        lc = "gd" ;
+        lc = wxT("gd") ;
         break ;
       case verManxGaelic:
-        lc = "gv" ;
+        lc = wxT("gv") ;
         break ;
       case verBreton:
-        lc = "br" ;
+        lc = wxT("br") ;
         break ;
       case verNunavut:
-        lc = "iu_CA" ;
+        lc = wxT("iu_CA") ;
         break ;
       case verWelsh:
-        lc = "cy" ;
+        lc = wxT("cy") ;
         break ;
       case verIrishGaelicScript:
-        lc = "ga_IE" ;
+        lc = wxT("ga_IE") ;
         break ;
       case verEngCanada:
-        lc = "en_CA" ;
+        lc = wxT("en_CA") ;
         break ;
       case verBhutan:
-        lc = "dz_BT" ;
+        lc = wxT("dz_BT") ;
         break ;
       case verArmenian:
-        lc = "hy_AM" ;
+        lc = wxT("hy_AM") ;
         break ;
       case verGeorgian:
-        lc = "ka_GE" ;
+        lc = wxT("ka_GE") ;
         break ;
       case verSpLatinAmerica:
-        lc = "es_AR" ;
+        lc = wxT("es_AR") ;
         break ;
       case verTonga:
-        lc = "to_TO" ;
+        lc = wxT("to_TO" );
         break ;
       case verFrenchUniversal:
-        lc = "fr_FR" ;
+        lc = wxT("fr_FR") ;
         break ;
       case verAustria:
-        lc = "de_AT" ;
+        lc = wxT("de_AT") ;
         break ;
       case verGujarati:
-        lc = "gu_IN" ;
+        lc = wxT("gu_IN") ;
         break ;
       case verPunjabi:
-        lc = "pa" ;
+        lc = wxT("pa") ;
         break ;
       case verIndiaUrdu:
-        lc = "ur_IN" ;
+        lc = wxT("ur_IN") ;
         break ;
       case verVietnam:
-        lc = "vi_VN" ;
+        lc = wxT("vi_VN") ;
         break ;
       case verFrBelgium:
-        lc = "fr_BE" ;
+        lc = wxT("fr_BE") ;
         break ;
       case verUzbek:
-        lc = "uz_UZ" ;
+        lc = wxT("uz_UZ") ;
         break ;
       case verSingapore:
-        lc = "zh_SG" ;
+        lc = wxT("zh_SG") ;
         break ;
       case verNynorsk:
-        lc = "nn_NO" ;
+        lc = wxT("nn_NO") ;
         break ;
       case verAfrikaans:
-        lc = "af_ZA" ;
+        lc = wxT("af_ZA") ;
         break ;
       case verEsperanto:
-        lc = "eo" ;
+        lc = wxT("eo") ;
         break ;
       case verMarathi:
-        lc = "mr_IN" ;
+        lc = wxT("mr_IN") ;
         break ;
       case verTibetan:
-        lc = "bo" ;
+        lc = wxT("bo") ;
         break ;
       case verNepal:
-        lc = "ne_NP" ;
+        lc = wxT("ne_NP") ;
         break ;
       case verGreenland:
-        lc = "kl_GL" ;
+        lc = wxT("kl_GL") ;
         break ;
       default :
         break ;
@@ -1386,7 +1422,7 @@ const wxLanguageInfo *wxLocale::GetLanguageInfo(int lang)
 {
     CreateLanguagesDB();
 
-    size_t count = ms_languagesDB->GetCount();
+    const size_t count = ms_languagesDB->GetCount();
     for ( size_t i = 0; i < count; i++ )
     {
         if ( ms_languagesDB->Item(i).Language == lang )
@@ -1398,6 +1434,42 @@ const wxLanguageInfo *wxLocale::GetLanguageInfo(int lang)
     return NULL;
 }
 
+/* static */
+const wxLanguageInfo *wxLocale::FindLanguageInfo(const wxString& locale)
+{
+    CreateLanguagesDB();
+
+    const wxLanguageInfo *infoRet = NULL;
+
+    const size_t count = ms_languagesDB->GetCount();
+    for ( size_t i = 0; i < count; i++ )
+    {
+        const wxLanguageInfo *info = &ms_languagesDB->Item(i);
+
+        if ( wxStricmp(locale, info->CanonicalName) == 0 ||
+                wxStricmp(locale, info->Description) == 0 )
+        {
+            // exact match, stop searching
+            infoRet = info;
+            break;
+        }
+
+        if ( wxStricmp(locale, info->CanonicalName.BeforeFirst(_T('_'))) == 0 )
+        {
+            // a match -- but maybe we'll find an exact one later, so continue
+            // looking
+            //
+            // OTOH, maybe we had already found a language match and in this
+            // case don't overwrite it becauce the entry for the default
+            // country always appears first in ms_languagesDB
+            if ( !infoRet )
+                infoRet = info;
+        }
+    }
+
+    return infoRet;
+}
+
 wxString wxLocale::GetSysName() const
 {
     return wxSetlocale(LC_ALL, NULL);
@@ -2170,7 +2242,7 @@ void wxLocale::InitLanguagesDB()
    LNG(wxLANGUAGE_CATALAN,                    "ca_ES", LANG_CATALAN   , SUBLANG_DEFAULT                   , "Catalan")
    LNG(wxLANGUAGE_CHINESE,                    "zh_CN", LANG_CHINESE   , SUBLANG_DEFAULT                   , "Chinese")
    LNG(wxLANGUAGE_CHINESE_SIMPLIFIED,         "zh_CN", LANG_CHINESE   , SUBLANG_CHINESE_SIMPLIFIED        , "Chinese (Simplified)")
-   LNG(wxLANGUAGE_CHINESE_TRADITIONAL,        "zh_CN", LANG_CHINESE   , SUBLANG_CHINESE_TRADITIONAL       , "Chinese (Traditional)")
+   LNG(wxLANGUAGE_CHINESE_TRADITIONAL,        "zh_TW", LANG_CHINESE   , SUBLANG_CHINESE_TRADITIONAL       , "Chinese (Traditional)")
    LNG(wxLANGUAGE_CHINESE_HONGKONG,           "zh_HK", LANG_CHINESE   , SUBLANG_CHINESE_HONGKONG          , "Chinese (Hongkong)")
    LNG(wxLANGUAGE_CHINESE_MACAU,              "zh_MO", LANG_CHINESE   , SUBLANG_CHINESE_MACAU             , "Chinese (Macau)")
    LNG(wxLANGUAGE_CHINESE_SINGAPORE,          "zh_SG", LANG_CHINESE   , SUBLANG_CHINESE_SINGAPORE         , "Chinese (Singapore)")