X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/246428310e0924dd9332187a51ad68f5932ac7a7..ecd6e7ea8900f8a1f9011ce616f96d978c084398:/src/common/strconv.cpp diff --git a/src/common/strconv.cpp b/src/common/strconv.cpp index 840a24d54b..dd806d2c1c 100644 --- a/src/common/strconv.cpp +++ b/src/common/strconv.cpp @@ -1317,28 +1317,12 @@ void wxCSConv::SetName(const wxChar *charset) } } -static inline bool DoesntNeedConv(wxFontEncoding enc) -{ - return enc == wxFONTENCODING_DEFAULT || - enc == wxFONTENCODING_SYSTEM || - enc == wxFONTENCODING_ISO8859_1; -} - wxMBConv *wxCSConv::DoCreate() const { -#if wxUSE_FONTMAP - wxFontMapper * const fontMapper = wxFontMapper::Get(); - - wxFontEncoding encFromName = m_name ? fontMapper->CharsetToEncoding(m_name) - : wxFONTENCODING_SYSTEM; -#endif // wxUSE_FONTMAP - - // check for the special case of ASCII charset - if ( (!m_name && DoesntNeedConv(m_encoding)) -#if wxUSE_FONTMAP - || (m_name && DoesntNeedConv(encFromName)) -#endif // wxUSE_FONTMAP - ) + // check for the special case of ASCII or ISO8859-1 charset: as we have + // special knowledge of it anyhow, we don't need to create a special + // conversion object + if ( m_encoding == wxFONTENCODING_ISO8859_1 ) { // don't convert at all return NULL; @@ -1354,9 +1338,18 @@ wxMBConv *wxCSConv::DoCreate() const // step (1) #ifdef HAVE_ICONV +#if !wxUSE_FONTMAP if ( m_name ) +#endif // !wxUSE_FONTMAP { - wxMBConv_iconv *conv = new wxMBConv_iconv(m_name); + wxString name(m_name); + +#if wxUSE_FONTMAP + if ( name.empty() ) + name = wxFontMapper::Get()->GetEncodingName(m_encoding); +#endif // wxUSE_FONTMAP + + wxMBConv_iconv *conv = new wxMBConv_iconv(name); if ( conv->IsOk() ) return conv; @@ -1378,8 +1371,13 @@ wxMBConv *wxCSConv::DoCreate() const // step (2) wxFontEncoding enc = m_encoding; #if wxUSE_FONTMAP - if ( enc == wxFONTENCODING_SYSTEM ) - enc = encFromName; + if ( enc == wxFONTENCODING_SYSTEM && m_name ) + { + // use "false" to suppress interactive dialogs -- we can be called from + // anywhere and popping up a dialog from here is the last thing we want to + // do + enc = wxFontMapper::Get()->CharsetToEncoding(m_name, false); + } #endif // wxUSE_FONTMAP switch ( enc ) @@ -1419,8 +1417,19 @@ wxMBConv *wxCSConv::DoCreate() const } #endif // wxUSE_FONTMAP - wxLogError(_("Cannot convert from the charset '%s'!"), - m_name ? m_name + // NB: This is a hack to prevent deadlock. What could otherwise happen + // in Unicode build: wxConvLocal creation ends up being here + // because of some failure and logs the error. But wxLog will try to + // attach timestamp, for which it will need wxConvLocal (to convert + // time to char* and then wchar_t*), but that fails, tries to log + // error, but wxLog has a (already locked) critical section that + // guards static buffer. + static bool alreadyLoggingError = false; + if (!alreadyLoggingError) + { + alreadyLoggingError = true; + wxLogError(_("Cannot convert from the charset '%s'!"), + m_name ? m_name : #if wxUSE_FONTMAP wxFontMapper::GetEncodingDescription(m_encoding).c_str() @@ -1428,6 +1437,8 @@ wxMBConv *wxCSConv::DoCreate() const wxString::Format(_("encoding %s"), m_encoding).c_str() #endif // wxUSE_FONTMAP/!wxUSE_FONTMAP ); + alreadyLoggingError = false; + } return NULL; } @@ -1443,7 +1454,7 @@ void wxCSConv::CreateConvIfNeeded() const // encoding for this system if ( !m_name && m_encoding == wxFONTENCODING_SYSTEM ) { - self->m_encoding = wxLocale::GetSystemEncoding(); + self->m_name = wxStrdup(wxLocale::GetSystemEncodingName()); } #endif // wxUSE_INTL