X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/50a743c9e44893725a4ffd56af4853797b3768dd..87f0b1323b7ac77f02133b836c8dfee63b0fd387:/src/common/init.cpp diff --git a/src/common/init.cpp b/src/common/init.cpp index 326ef09333..ee45254523 100644 --- a/src/common/init.cpp +++ b/src/common/init.cpp @@ -34,23 +34,30 @@ #include "wx/init.h" #include "wx/thread.h" -#include "wx/ptr_scpd.h" +#include "wx/scopedptr.h" #include "wx/except.h" -#if defined(__WXMSW__) && defined(__WXDEBUG__) +#if defined(__WINDOWS__) + #include "wx/msw/private.h" #include "wx/msw/msvcrt.h" - static struct EnableMemLeakChecking - { - EnableMemLeakChecking() + #ifdef wxCrtSetDbgFlag + static struct EnableMemLeakChecking { - // do check for memory leaks on program exit (another useful flag - // is _CRTDBG_DELAY_FREE_MEM_DF which doesn't free deallocated - // memory which may be used to simulate low-memory condition) - wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF); - } - } gs_enableLeakChecks; -#endif // __WXMSW__ && __WXDEBUG__ + EnableMemLeakChecking() + { + // check for memory leaks on program exit (another useful flag + // is _CRTDBG_DELAY_FREE_MEM_DF which doesn't free deallocated + // memory which may be used to simulate low-memory condition) + wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF); + } + } gs_enableLeakChecks; + #endif // wxCrtSetDbgFlag +#endif // __WINDOWS__ + +#if wxUSE_UNICODE && defined(__WXOSX__) + #include +#endif // ---------------------------------------------------------------------------- // private classes @@ -62,9 +69,10 @@ class wxDummyConsoleApp : public wxAppConsole public: wxDummyConsoleApp() { } - virtual int OnRun() { wxFAIL_MSG( _T("unreachable code") ); return 0; } + virtual int OnRun() { wxFAIL_MSG( wxT("unreachable code") ); return 0; } + virtual bool DoYield(bool, long) { return true; } - DECLARE_NO_COPY_CLASS(wxDummyConsoleApp) + wxDECLARE_NO_COPY_CLASS(wxDummyConsoleApp); }; // we need a special kind of auto pointer to wxApp which not only deletes the @@ -93,7 +101,7 @@ public: wxApp::SetInstance(ptr); } - DECLARE_NO_COPY_CLASS(wxAppPtr) + wxDECLARE_NO_COPY_CLASS(wxAppPtr); }; // class to ensure that wxAppBase::CleanUp() is called if our Initialize() @@ -110,14 +118,6 @@ private: wxAppConsole *m_app; }; -// another tiny class which simply exists to ensure that wxEntryCleanup is -// always called -class wxCleanupOnExit -{ -public: - ~wxCleanupOnExit() { wxEntryCleanup(); } -}; - // ---------------------------------------------------------------------------- // private functions // ---------------------------------------------------------------------------- @@ -160,7 +160,7 @@ static struct InitData wchar_t **argv; #endif // wxUSE_UNICODE - DECLARE_NO_COPY_CLASS(InitData) + wxDECLARE_NO_COPY_CLASS(InitData); } gs_initData; // ============================================================================ @@ -179,7 +179,11 @@ static void ConvertArgsToUnicode(int argc, char **argv) int wargc = 0; for ( int i = 0; i < argc; i++ ) { +#ifdef __DARWIN__ + wxWCharBuffer buf(wxConvFileName->cMB2WX(argv[i])); +#else wxWCharBuffer buf(wxConvLocal.cMB2WX(argv[i])); +#endif if ( !buf ) { wxLogWarning(_("Command line argument %d couldn't be converted to Unicode and will be ignored."), @@ -204,8 +208,7 @@ static void FreeConvertedArgs() free(gs_initData.argv[i]); } - delete [] gs_initData.argv; - gs_initData.argv = NULL; + wxDELETEA(gs_initData.argv); gs_initData.argc = 0; } } @@ -219,18 +222,48 @@ static void FreeConvertedArgs() // initialization which is always done (not customizable) before wxApp creation static bool DoCommonPreInit() { +#if wxUSE_UNICODE && defined(__WXOSX__) + // In OS X and iOS, wchar_t CRT functions convert to char* and fail under + // some locales. The safest fix is to set LC_CTYPE to UTF-8 to ensure that + // they can handle any input. + // + // Note that this must be done for any app, Cocoa or console, whether or + // not it uses wxLocale. + // + // See http://stackoverflow.com/questions/11713745/why-does-the-printf-family-of-functions-care-about-locale + setlocale(LC_CTYPE, "UTF-8"); +#endif // wxUSE_UNICODE && defined(__WXOSX__) + #if wxUSE_LOG // Reset logging in case we were cleaned up and are being reinitialized. wxLog::DoCreateOnDemand(); - // install temporary log sink: we can't use wxLogGui before wxApp is - // constructed and if we use wxLogStderr, all messages during - // initialization simply disappear under Windows + // force wxLog to create a log target now: we do it because wxTheApp + // doesn't exist yet so wxLog will create a special log target which is + // safe to use even when the GUI is not available while without this call + // we could create wxApp in wxEntryStart() below, then log an error about + // e.g. failure to establish connection to the X server and wxLog would + // send it to wxLogGui (because wxTheApp does exist already) which, of + // course, can't be used in this case // - // note that we will delete this log target below - delete wxLog::SetActiveTarget(new wxLogBuffer); + // notice also that this does nothing if the user had set up a custom log + // target before -- which is fine as we want to give him this possibility + // (as it's impossible to override logging by overriding wxAppTraits:: + // CreateLogTarget() before wxApp is created) and we just assume he knows + // what he is doing + wxLog::GetActiveTarget(); #endif // wxUSE_LOG +#ifdef __WINDOWS__ + // GUI applications obtain HINSTANCE in their WinMain() but we also need to + // initialize the global wxhInstance variable for the console programs as + // they may need it too, so set it here if it wasn't done yet + if ( !wxGetInstance() ) + { + wxSetInstance(::GetModuleHandle(NULL)); + } +#endif // __WINDOWS__ + return true; } @@ -255,9 +288,7 @@ bool wxEntryStart(int& argc, wxChar **argv) // initialize wxRTTI if ( !DoCommonPreInit() ) - { return false; - } // first of all, we need an application object @@ -290,15 +321,14 @@ bool wxEntryStart(int& argc, wxChar **argv) // -------------------------------------------- if ( !app->Initialize(argc, argv) ) - { return false; - } - wxCallAppCleanup callAppCleanup(app.get()); + // remember, possibly modified (e.g. due to removal of toolkit-specific + // parameters), command line arguments in member variables + app->argc = argc; + app->argv = argv; - // for compatibility call the old initialization function too - if ( !app->OnInitGui() ) - return false; + wxCallAppCleanup callAppCleanup(app.get()); // common initialization after wxTheApp creation @@ -352,14 +382,15 @@ bool wxEntryStart(int& argc, char **argv) static void DoCommonPreCleanup() { #if wxUSE_LOG - // flush the logged messages if any and install a 'safer' log target: the - // default one (wxLogGui) can't be used after the resources are freed just - // below and the user supplied one might be even more unsafe (using any - // wxWidgets GUI function is unsafe starting from now) - wxLog::DontCreateOnDemand(); - - // this will flush the old messages if any - delete wxLog::SetActiveTarget(new wxLogStderr); + // flush the logged messages if any and don't use the current probably + // unsafe log target any more: the default one (wxLogGui) can't be used + // after the resources are freed which happens when we return and the user + // supplied one might be even more unsafe (using any wxWidgets GUI function + // is unsafe starting from now) + // + // notice that wxLog will still recreate a default log target if any + // messages are logged but that one will be safe to use until the very end + delete wxLog::SetActiveTarget(NULL); #endif // wxUSE_LOG } @@ -379,7 +410,18 @@ static void DoCommonPostCleanup() delete wxMessageOutput::Set(NULL); #if wxUSE_LOG + // call this first as it has a side effect: in addition to flushing all + // logs for this thread, it also flushes everything logged from other + // threads + wxLog::FlushActive(); + // and now delete the last logger as well + // + // we still don't disable log target auto-vivification even if any log + // objects created now will result in memory leaks because it seems better + // to leak memory which doesn't matter much considering the application is + // exiting anyhow than to not show messages which could still be logged + // from the user code (e.g. static dtors and such) delete wxLog::SetActiveTarget(NULL); #endif // wxUSE_LOG } @@ -411,14 +453,16 @@ void wxEntryCleanup() // ---------------------------------------------------------------------------- // for MSW the real wxEntry is defined in msw/main.cpp -#ifndef __WXMSW__ +#ifndef __WINDOWS__ #define wxEntryReal wxEntry -#endif // !__WXMSW__ +#endif // !__WINDOWS__ int wxEntryReal(int& argc, wxChar **argv) { // library initialization - if ( !wxEntryStart(argc, argv) ) + wxInitializer initializer(argc, argv); + + if ( !initializer.IsOk() ) { #if wxUSE_LOG // flush any log messages explaining why we failed @@ -427,15 +471,8 @@ int wxEntryReal(int& argc, wxChar **argv) return -1; } - // if wxEntryStart succeeded, we must call wxEntryCleanup even if the code - // below returns or throws - wxCleanupOnExit cleanupOnExit; - - WX_SUPPRESS_UNUSED_WARN(cleanupOnExit); - wxTRY { - // app initialization if ( !wxTheApp->CallOnInit() ) { @@ -474,6 +511,11 @@ int wxEntry(int& argc, char **argv) // wxInitialize/wxUninitialize // ---------------------------------------------------------------------------- +bool wxInitialize() +{ + return wxInitialize(0, (wxChar**)NULL); +} + bool wxInitialize(int argc, wxChar **argv) { wxCRIT_SECT_LOCKER(lockInit, gs_initData.csInit); @@ -487,6 +529,21 @@ bool wxInitialize(int argc, wxChar **argv) return wxEntryStart(argc, argv); } +#if wxUSE_UNICODE +bool wxInitialize(int argc, char **argv) +{ + wxCRIT_SECT_LOCKER(lockInit, gs_initData.csInit); + + if ( gs_initData.nInitCount++ ) + { + // already initialized + return true; + } + + return wxEntryStart(argc, argv); +} +#endif // wxUSE_UNICODE + void wxUninitialize() { wxCRIT_SECT_LOCKER(lockInit, gs_initData.csInit);