/* depending on the platform, Unicode build can either store wxStrings as
wchar_t* or UTF-8 encoded char*: */
#if wxUSE_UNICODE
+ // FIXME-UTF8: what would be better place for this?
+ #if defined(wxUSE_UTF8_LOCALE_ONLY) && !defined(wxUSE_UNICODE_UTF8)
+ #error "wxUSE_UTF8_LOCALE_ONLY only makes sense with wxUSE_UNICODE_UTF8"
+ #endif
+ #ifndef wxUSE_UTF8_LOCALE_ONLY
+ #define wxUSE_UTF8_LOCALE_ONLY 0
+ #endif
+
#ifndef wxUSE_UNICODE_UTF8
#define wxUSE_UNICODE_UTF8 0
#endif
#include <stdio.h> /* we use FILE below */
+#ifdef __cplusplus
+ #if wxUSE_UNICODE_UTF8
+ // flag indicating whether the current locale uses UTF-8 or not; must be
+ // updated every time the locale is changed!
+ #if !wxUSE_UTF8_LOCALE_ONLY
+ extern WXDLLIMPEXP_BASE bool wxLocaleIsUtf8;
+ #endif
+ // function used to update the flag:
+ extern WXDLLIMPEXP_BASE void wxUpdateLocaleIsUtf8();
+ #else // !wxUSE_UNICODE_UTF8
+ inline WXDLLIMPEXP_BASE void wxUpdateLocaleIsUtf8() {}
+ #endif // wxUSE_UNICODE_UTF8/!wxUSE_UNICODE_UTF8
+#endif // __cplusplus
+
#if defined(HAVE_STRTOK_R) && defined(__DARWIN__) && defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS
char *strtok_r(char *, const char *, char **);
#endif
#define wxToupper(c) _totupper((wxUChar)(wxChar)(c))
/* locale.h functons */
- #define wxSetlocale _tsetlocale
+ #define wxSetlocale_ _tsetlocale
/* string.h functions */
#define wxStrcat _tcscat
#define wxToupper toupper
/* locale.h functons */
- #define wxSetlocale setlocale
+ #define wxSetlocale_ setlocale
/* string.h functions */
#define wxStrcat strcat
#endif
#ifdef __cplusplus
-#ifndef wxSetlocale
-class WXDLLIMPEXP_BASE wxWCharBuffer;
-WXDLLIMPEXP_BASE wxWCharBuffer wxSetlocale(int category, const wxChar *locale);
-#endif
-#endif
+ #ifndef wxSetlocale_
+ class WXDLLIMPEXP_BASE wxWCharBuffer;
+ WXDLLIMPEXP_BASE wxWCharBuffer wxSetlocale_(int category, const wxChar *locale);
+ WXDLLIMPEXP_BASE wxWCharBuffer wxSetlocale(int category, const wxChar *locale);
+ #else
+ WXDLLIMPEXP_BASE const wxChar *wxSetlocale(int category, const wxChar *locale);
+ #endif // defined(wxSetlocale_)
+#endif // __cplusplus
/* stdio.h functions */
#ifdef wxNEED_WX_STDIO_H
void wxAppTraitsBase::SetLocale()
{
setlocale(LC_ALL, "");
+ wxUpdateLocaleIsUtf8();
}
#endif
#if defined(__UNIX__) && wxUSE_UNICODE && !defined(__WXMAC__)
-static wxWCharBuffer wxSetlocaleTryUTF(int c, const wxChar *lc)
+static wxWCharBuffer wxSetlocaleTryUTF8(int c, const wxChar *lc)
{
- wxMB2WXbuf l = wxSetlocale(c, lc);
- if ( !l && lc && lc[0] != 0 )
+ wxMB2WXbuf l;
+
+ // NB: We prefer to set UTF-8 locale if it's possible and only fall back to
+ // non-UTF-8 locale if it fails
+
+ if ( lc && lc[0] != 0 )
{
wxString buf(lc);
wxString buf2;
l = wxSetlocale(c, buf2.c_str());
}
}
+
+ // if we can't set UTF-8 locale, try non-UTF-8 one:
+ if ( !l )
+ l = wxSetlocale(c, lc);
+
return l;
}
#else
-#define wxSetlocaleTryUTF(c, lc) wxSetlocale(c, lc)
+#define wxSetlocaleTryUTF8(c, lc) wxSetlocale(c, lc)
#endif
bool wxLocale::Init(int language, int flags)
if (language != wxLANGUAGE_DEFAULT)
locale = info->CanonicalName;
- wxMB2WXbuf retloc = wxSetlocaleTryUTF(LC_ALL, locale);
+ wxMB2WXbuf retloc = wxSetlocaleTryUTF8(LC_ALL, locale);
const wxString langOnly = locale.Left(2);
if ( !retloc )
{
// Some C libraries don't like xx_YY form and require xx only
- retloc = wxSetlocaleTryUTF(LC_ALL, langOnly);
+ retloc = wxSetlocaleTryUTF8(LC_ALL, langOnly);
}
#if wxUSE_FONTMAP
if ( !localeAlt.empty() )
{
- retloc = wxSetlocaleTryUTF(LC_ALL, localeAlt);
+ retloc = wxSetlocaleTryUTF8(LC_ALL, localeAlt);
if ( !retloc )
- retloc = wxSetlocaleTryUTF(LC_ALL, localeAlt.Left(2));
+ retloc = wxSetlocaleTryUTF8(LC_ALL, localeAlt.Left(2));
}
}
// Test if setting the locale works, then set it back.
wxMB2WXbuf oldLocale = wxSetlocale(LC_ALL, wxEmptyString);
- wxMB2WXbuf tmp = wxSetlocaleTryUTF(LC_ALL, info->CanonicalName);
+ wxMB2WXbuf tmp = wxSetlocaleTryUTF8(LC_ALL, info->CanonicalName);
if ( !tmp )
{
// Some C libraries don't like xx_YY form and require xx only
- tmp = wxSetlocaleTryUTF(LC_ALL, info->CanonicalName.Left(2));
+ tmp = wxSetlocaleTryUTF8(LC_ALL, info->CanonicalName.Left(2));
if ( !tmp )
return false;
}
}
#endif
-#ifndef wxSetlocale
-WXDLLEXPORT wxWCharBuffer wxSetlocale(int category, const wxChar *locale)
+#ifndef wxSetlocale_
+wxWCharBuffer wxSetlocale_(int category, const wxChar *locale)
{
char *localeOld = setlocale(category, wxConvLibc.cWX2MB(locale));
return wxWCharBuffer(wxConvLibc.cMB2WC(localeOld));
}
-#endif
+
+wxWCharBuffer wxSetlocale(int category, const wxChar *locale)
+{
+ wxWCharBuffer rv = wxSetlocale_(category, locale);
+ if ( rv )
+ wxUpdateLocaleIsUtf8();
+ return rv;
+}
+#else // defined(wxSetlocale_)
+const wxChar *wxSetlocale(int category, const wxChar *locale)
+{
+ const wxChar *rv = wxSetlocale_(category, locale);
+ if ( rv )
+ wxUpdateLocaleIsUtf8();
+ return rv;
+}
+#endif // wxSetlocale_ defined or not
#if wxUSE_WCHAR_T && !defined(HAVE_WCSLEN)
WXDLLEXPORT size_t wxWcslen(const wchar_t *s)
}
#endif
+
+
+// ----------------------------------------------------------------------------
+// wxLocaleIsUtf8
+// ----------------------------------------------------------------------------
+
+#if wxUSE_UNICODE_UTF8
+
+#if !wxUSE_UTF8_LOCALE_ONLY
+bool wxLocaleIsUtf8 = false; // the safer setting if not known
+#endif
+
+static bool wxIsLocaleUtf8()
+{
+ // NB: we intentionally don't use wxLocale::GetSystemEncodingName(),
+ // because a) it may be unavailable in some builds and b) has slightly
+ // different semantics (default locale instead of current)
+
+#if defined(HAVE_LANGINFO_H) && defined(CODESET)
+ // GNU libc provides current character set this way (this conforms to
+ // Unix98)
+ const char *charset = nl_langinfo(CODESET);
+ if ( charset )
+ {
+ // "UTF-8" is used by modern glibc versions, but test other variants
+ // as well, just in case:
+ return strcmp(charset, "UTF-8") == 0 ||
+ strcmp(charset, "utf-8") == 0 ||
+ strcmp(charset, "UTF8") == 0 ||
+ strcmp(charset, "utf8") == 0;
+ }
+ else // nl_langinfo() failed
+#endif
+ {
+ // we don't know what charset libc is using, so assume the worst
+ // to be safe:
+ return false;
+ }
+}
+
+void wxUpdateLocaleIsUtf8()
+{
+#if wxUSE_UTF8_LOCALE_ONLY
+ if ( !wxIsLocaleUtf8() )
+ {
+ wxLogFatalError(_T("This program requires UTF-8 locale to run."));
+ }
+#else // !wxUSE_UTF8_LOCALE_ONLY
+ wxLocaleIsUtf8 = wxIsLocaleUtf8();
+#endif
+}
+
+#endif // wxUSE_UTF8_LOCALE_ONLY
#else
init_result = gtk_init_check( &argcGTK, &argvGTK );
#endif
+ wxUpdateLocaleIsUtf8();
if ( argcGTK != argc )
{
void wxGUIAppTraits::SetLocale()
{
gtk_set_locale();
+ wxUpdateLocaleIsUtf8();
}
#endif