X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e0954e729dabaad5603d9970d123d6b96ed73463..6362d82b3ed82aa6795e4ad03160820f94c9e4d4:/src/common/appbase.cpp?ds=sidebyside diff --git a/src/common/appbase.cpp b/src/common/appbase.cpp index 9f3be56cc8..5a741b70ac 100644 --- a/src/common/appbase.cpp +++ b/src/common/appbase.cpp @@ -44,30 +44,25 @@ #include "wx/msgout.h" #include "wx/ptr_scpd.h" #include "wx/tokenzr.h" +#include "wx/thread.h" +#if wxUSE_EXCEPTIONS && wxUSE_STL + #include + #include +#endif + +#ifndef __WXPALMOS5__ #if !defined(__WXMSW__) || defined(__WXMICROWIN__) #include // for SIGTRAP used by wxTrap() #endif //Win/Unix #include +#endif // ! __WXPALMOS5__ #if wxUSE_FONTMAP #include "wx/fontmap.h" #endif // wxUSE_FONTMAP -#if defined(__DARWIN__) && defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS - // For MacTypes.h for Debugger function - #include -#endif - -#if defined(__WXMAC__) - #ifdef __DARWIN__ - #include - #else - #include "wx/mac/private.h" // includes mac headers - #endif -#endif // __WXMAC__ - #ifdef __WXDEBUG__ #if wxUSE_STACKWALKER #include "wx/stackwalk.h" @@ -75,6 +70,8 @@ #include "wx/msw/debughlp.h" #endif #endif // wxUSE_STACKWALKER + + #include "wx/recguard.h" #endif // __WXDEBUG__ // wxABI_VERSION can be defined when compiling applications but it should be @@ -114,6 +111,8 @@ wxAppConsole *wxAppConsoleBase::ms_appInstance = NULL; wxAppInitializerFunction wxAppConsoleBase::ms_appInitFn = NULL; +wxSocketManager *wxAppTraitsBase::ms_manager = NULL; + // ---------------------------------------------------------------------------- // wxEventLoopPtr // ---------------------------------------------------------------------------- @@ -134,7 +133,7 @@ wxAppConsoleBase::wxAppConsoleBase() m_traits = NULL; m_mainLoop = NULL; - ms_appInstance = wx_static_cast(wxAppConsole *, this); + ms_appInstance = static_cast(this); #ifdef __WXDEBUG__ SetTraceMasks(); @@ -157,22 +156,18 @@ wxAppConsoleBase::~wxAppConsoleBase() // initilization/cleanup // ---------------------------------------------------------------------------- -bool wxAppConsoleBase::Initialize(int& argcOrig, wxChar **argvOrig) +bool wxAppConsoleBase::Initialize(int& WXUNUSED(argc), wxChar **argv) { #if wxUSE_INTL GetTraits()->SetLocale(); #endif // wxUSE_INTL - // remember the command line arguments - argc = argcOrig; - argv = argvOrig; - #if wxUSE_THREADS wxPendingEventsLocker = new wxCriticalSection; #endif #ifndef __WXPALMOS__ - if ( m_appName.empty() && argv ) + if ( m_appName.empty() && argv && argv[0] ) { // the application name is, by default, the name of its executable file wxFileName::SplitPath(argv[0], NULL, &m_appName, NULL); @@ -284,6 +279,13 @@ wxAppTraits *wxAppConsoleBase::GetTraits() return m_traits; } +/* static */ +wxAppTraits *wxAppConsoleBase::GetTraitsIfExists() +{ + wxAppConsole * const app = GetInstance(); + return app ? app->GetTraits() : NULL; +} + // ---------------------------------------------------------------------------- // event processing // ---------------------------------------------------------------------------- @@ -325,16 +327,13 @@ bool wxAppConsoleBase::Dispatch() bool wxAppConsoleBase::HasPendingEvents() const { - // ensure that we're the only thread to modify the pending events list wxENTER_CRIT_SECT( *wxPendingEventsLocker ); - if ( !wxPendingEvents ) - { - wxLEAVE_CRIT_SECT( *wxPendingEventsLocker ); - return false; - } + bool has = wxPendingEvents && !wxPendingEvents->IsEmpty(); + wxLEAVE_CRIT_SECT( *wxPendingEventsLocker ); - return true; + + return has; } /* static */ @@ -352,27 +351,27 @@ void wxAppConsoleBase::ProcessPendingEvents() return; #endif - if ( !HasPendingEvents() ) - return; - wxENTER_CRIT_SECT( *wxPendingEventsLocker ); - // iterate until the list becomes empty - wxList::compatibility_iterator node = wxPendingEvents->GetFirst(); - while (node) + if (wxPendingEvents) { - wxEvtHandler *handler = (wxEvtHandler *)node->GetData(); - wxPendingEvents->Erase(node); - - // In ProcessPendingEvents(), new handlers might be add - // and we can safely leave the critical section here. - wxLEAVE_CRIT_SECT( *wxPendingEventsLocker ); + // iterate until the list becomes empty: the handlers remove themselves + // from it when they don't have any more pending events + wxList::compatibility_iterator node = wxPendingEvents->GetFirst(); + while (node) + { + // In ProcessPendingEvents(), new handlers might be add + // and we can safely leave the critical section here. + wxLEAVE_CRIT_SECT( *wxPendingEventsLocker ); - handler->ProcessPendingEvents(); + wxEvtHandler *handler = (wxEvtHandler *)node->GetData(); + handler->ProcessPendingEvents(); - wxENTER_CRIT_SECT( *wxPendingEventsLocker ); + wxENTER_CRIT_SECT( *wxPendingEventsLocker ); - node = wxPendingEvents->GetFirst(); + // restart as the iterators could have been invalidated + node = wxPendingEvents->GetFirst(); + } } wxLEAVE_CRIT_SECT( *wxPendingEventsLocker ); @@ -414,12 +413,38 @@ wxAppConsoleBase::HandleEvent(wxEvtHandler *handler, (handler->*func)(event); } +void wxAppConsoleBase::OnUnhandledException() +{ +#ifdef __WXDEBUG__ + // we're called from an exception handler so we can re-throw the exception + // to recover its type + wxString what; + try + { + throw; + } +#if wxUSE_STL + catch ( std::exception& e ) + { + what.Printf("std::exception of type \"%s\", what() = \"%s\"", + typeid(e).name(), e.what()); + } +#endif // wxUSE_STL + catch ( ... ) + { + what = "unknown exception"; + } + + wxMessageOutputBest().Printf( + "*** Caught unhandled %s; terminating\n", what + ); +#endif // __WXDEBUG__ +} + // ---------------------------------------------------------------------------- // exceptions support // ---------------------------------------------------------------------------- -#if wxUSE_EXCEPTIONS - bool wxAppConsoleBase::OnExceptionInMainLoop() { throw; @@ -430,9 +455,6 @@ bool wxAppConsoleBase::OnExceptionInMainLoop() #endif } -#endif // wxUSE_EXCEPTIONS - - #endif // wxUSE_EXCEPTIONS // ---------------------------------------------------------------------------- @@ -441,7 +463,7 @@ bool wxAppConsoleBase::OnExceptionInMainLoop() #if wxUSE_CMDLINE_PARSER -#define OPTION_VERBOSE _T("verbose") +#define OPTION_VERBOSE "verbose" void wxAppConsoleBase::OnInitCmdLine(wxCmdLineParser& parser) { @@ -450,8 +472,8 @@ void wxAppConsoleBase::OnInitCmdLine(wxCmdLineParser& parser) { { wxCMD_LINE_SWITCH, - _T("h"), - _T("help"), + "h", + "help", gettext_noop("show this help message"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP @@ -460,7 +482,7 @@ void wxAppConsoleBase::OnInitCmdLine(wxCmdLineParser& parser) #if wxUSE_LOG { wxCMD_LINE_SWITCH, - wxEmptyString, + NULL, OPTION_VERBOSE, gettext_noop("generate verbose log messages"), wxCMD_LINE_VAL_NONE, @@ -469,14 +491,7 @@ void wxAppConsoleBase::OnInitCmdLine(wxCmdLineParser& parser) #endif // wxUSE_LOG // terminator - { - wxCMD_LINE_NONE, - wxEmptyString, - wxEmptyString, - wxEmptyString, - wxCMD_LINE_VAL_NONE, - 0x0 - } + wxCMD_LINE_DESC_END }; parser.SetDesc(cmdLineDesc); @@ -626,13 +641,6 @@ void wxConsoleAppTraitsBase::RemoveFromPendingDelete(wxObject * WXUNUSED(object) // nothing to do } -#if wxUSE_SOCKETS -GSocketGUIFunctionsTable* wxConsoleAppTraitsBase::GetSocketGUIFunctionsTable() -{ - return NULL; -} -#endif - // ---------------------------------------------------------------------------- // wxAppTraits // ---------------------------------------------------------------------------- @@ -640,11 +648,40 @@ GSocketGUIFunctionsTable* wxConsoleAppTraitsBase::GetSocketGUIFunctionsTable() #if wxUSE_INTL void wxAppTraitsBase::SetLocale() { - setlocale(LC_ALL, ""); + wxSetlocale(LC_ALL, ""); wxUpdateLocaleIsUtf8(); } #endif +#if wxUSE_THREADS +void wxMutexGuiEnterImpl(); +void wxMutexGuiLeaveImpl(); + +void wxAppTraitsBase::MutexGuiEnter() +{ + wxMutexGuiEnterImpl(); +} + +void wxAppTraitsBase::MutexGuiLeave() +{ + wxMutexGuiLeaveImpl(); +} + +void WXDLLIMPEXP_BASE wxMutexGuiEnter() +{ + wxAppTraits * const traits = wxAppConsoleBase::GetTraitsIfExists(); + if ( traits ) + traits->MutexGuiEnter(); +} + +void WXDLLIMPEXP_BASE wxMutexGuiLeave() +{ + wxAppTraits * const traits = wxAppConsoleBase::GetTraitsIfExists(); + if ( traits ) + traits->MutexGuiLeave(); +} +#endif // wxUSE_THREADS + #ifdef __WXDEBUG__ bool wxAppTraitsBase::ShowAssertDialog(const wxString& msgOriginal) @@ -772,12 +809,6 @@ void wxTrap() { #if defined(__WXMSW__) && !defined(__WXMICROWIN__) DebugBreak(); -#elif defined(__WXMAC__) && !defined(__DARWIN__) - #if __powerc - Debugger(); - #else - SysBreak(); - #endif #elif defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS Debugger(); #elif defined(__UNIX__) @@ -795,20 +826,17 @@ static void wxDoOnAssert(const wxString& szFile, const wxString& szMsg = wxEmptyString) { // FIXME MT-unsafe - static bool s_bInAssert = false; + static int s_bInAssert = 0; - if ( s_bInAssert ) + wxRecursionGuard guard(s_bInAssert); + if ( guard.IsInside() ) { - // He-e-e-e-elp!! we're trapped in endless loop + // can't use assert here to avoid infinite loops, so just trap wxTrap(); - s_bInAssert = false; - return; } - s_bInAssert = true; - if ( !wxTheApp ) { // by default, show the assert dialog box -- we can't customize this @@ -822,8 +850,6 @@ static void wxDoOnAssert(const wxString& szFile, wxTheApp->OnAssertFailure(szFile.c_str(), nLine, szFunc.c_str(), szCond.c_str(), szMsg.c_str()); } - - s_bInAssert = false; } void wxOnAssert(const wxString& szFile, @@ -919,6 +945,7 @@ static void LINKAGEMODE SetTraceMasks() #endif // wxUSE_LOG } +static bool DoShowAssertDialog(const wxString& msg) { // under MSW we can show the dialog even in the console mode @@ -931,7 +958,7 @@ bool DoShowAssertDialog(const wxString& msg) wxT("You can also choose [Cancel] to suppress ") wxT("further warnings."); - switch ( ::MessageBox(NULL, msgDlg, _T("wxWidgets Debug Alert"), + switch ( ::MessageBox(NULL, msgDlg.wx_str(), _T("wxWidgets Debug Alert"), MB_YESNOCANCEL | MB_ICONSTOP ) ) { case IDYES: @@ -999,7 +1026,7 @@ void ShowAssertDialog(const wxString& szFile, #if defined(__WXMSW__) && !defined(__WXMICROWIN__) msg << wxT("\r\n"); - OutputDebugString(msg ); + OutputDebugString(msg.wx_str()); #else // send to stderr wxFprintf(stderr, wxT("%s\n"), msg.c_str());