X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dd38c87578df7a24a491401c943988e2bc89b62b..a63d48fa138e9eaa3079172ace9a804ba5b0415e:/src/motif/app.cpp diff --git a/src/motif/app.cpp b/src/motif/app.cpp index bd25cba57d..d17e8fc734 100644 --- a/src/motif/app.cpp +++ b/src/motif/app.cpp @@ -9,7 +9,7 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "app.h" #endif @@ -66,14 +66,12 @@ static WXWidget wxCreateTopLevelWidget( WXDisplay* display ); extern wxList wxPendingDelete; extern bool wxAddIdleCallback(); -wxApp *wxTheApp = NULL; - wxHashTable *wxWidgetHashTable = NULL; IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler) BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) - EVT_IDLE(wxApp::OnIdle) + EVT_IDLE(wxAppBase::OnIdle) END_EVENT_TABLE() #ifdef __WXDEBUG__ @@ -88,192 +86,41 @@ END_EVENT_TABLE() } #endif // __WXDEBUG__ -bool wxApp::Initialize() +bool wxApp::Initialize(int& argc, wxChar **argv) { - wxClassInfo::InitializeClasses(); - - // GL: I'm annoyed ... I don't know where to put this and I don't want to - // create a module for that as it's part of the core. -#if wxUSE_THREADS - wxPendingEventsLocker = new wxCriticalSection(); -#endif - - wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING); - wxTheColourDatabase->Initialize(); - - wxInitializeStockLists(); - wxInitializeStockObjects(); + if ( !wxAppBase::Initialize(argc, argv) ) + return false; wxWidgetHashTable = new wxHashTable(wxKEY_INTEGER); - wxModule::RegisterModules(); - if (!wxModule::InitializeModules()) return FALSE; - - return TRUE; + return true; } void wxApp::CleanUp() { - wxModule::CleanUpModules(); - - wxDeleteStockObjects() ; - - // Destroy all GDI lists, etc. - - wxDeleteStockLists(); - - delete wxTheColourDatabase; - wxTheColourDatabase = NULL; - - wxClassInfo::CleanUpClasses(); - - delete wxTheApp; - wxTheApp = NULL; - delete wxWidgetHashTable; wxWidgetHashTable = NULL; - // GL: I'm annoyed ... I don't know where to put this and I don't want to - // create a module for that as it's part of the core. -#if wxUSE_THREADS - delete wxPendingEvents; - wxPendingEvents = NULL; - delete wxPendingEventsLocker; - wxPendingEventsLocker = NULL; -#endif - -#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT - // At this point we want to check if there are any memory - // blocks that aren't part of the wxDebugContext itself, - // as a special case. Then when dumping we need to ignore - // wxDebugContext, too. - if (wxDebugContext::CountObjectsLeft(TRUE) > 0) - { - wxLogDebug("There were memory leaks.\n"); - wxDebugContext::Dump(); - wxDebugContext::PrintStatistics(); - } -#endif - - // do it as the very last thing because everything else can log messages - wxLog::DontCreateOnDemand(); - // do it as the very last thing because everything else can log messages - delete wxLog::SetActiveTarget(NULL); -} - -// ============================================================================ -// wxEntry* -// ============================================================================ - -int wxEntryStart( int argc, char* argv[] ) -{ -#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT - // This seems to be necessary since there are 'rogue' - // objects present at this point (perhaps global objects?) - // Setting a checkpoint will ignore them as far as the - // memory checking facility is concerned. - // Of course you may argue that memory allocated in globals should be - // checked, but this is a reasonable compromise. - wxDebugContext::SetCheckpoint(); -#endif - - if (!wxApp::Initialize()) - return -1; - - return 0; + wxAppBase::CleanUp(); } -int wxEntryInitGui() +void wxApp::Exit() { - int retValue = 0; - - // GUI-specific initialization, such as creating an app context. - if (!wxTheApp->OnInitGui()) - retValue = -1; - - return retValue; -} - -void wxEntryCleanup() -{ - // So dialog boxes aren't used for further messages - delete wxLog::SetActiveTarget(new wxLogStderr); - - // flush the logged messages if any - wxLog *pLog = wxLog::GetActiveTarget(); - if ( pLog != NULL && pLog->HasPendingMessages() ) - pLog->Flush(); - wxApp::CleanUp(); -} -int wxEntry( int argc, char *argv[] ) -{ - int retValue = 0; - - retValue = wxEntryStart( argc, argv ); - if (retValue) return retValue; - - if (!wxTheApp) - { - if (!wxApp::GetInitializerFunction()) - { - printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" ); - return 0; - }; - - wxTheApp = (wxApp*) (* wxApp::GetInitializerFunction()) (); - }; - - if (!wxTheApp) - { - printf( "wxWindows error: wxTheApp == NULL\n" ); - return 0; - }; - - wxTheApp->SetClassName(wxFileNameFromPath(argv[0])); - wxTheApp->SetAppName(wxFileNameFromPath(argv[0])); - - wxTheApp->argc = argc; - wxTheApp->argv = argv; - - // GUI-specific initialization, such as creating an app context. - retValue = wxEntryInitGui(); - if (retValue) return retValue; - - // Here frames insert themselves automatically into wxTopLevelWindows by - // getting created in OnInit(). - - if (wxTheApp->OnInit()) - { - if (wxTheApp->Initialized()) - wxTheApp->OnRun(); - } - - if (wxTheApp->GetTopWindow()) - { - delete wxTheApp->GetTopWindow(); - wxTheApp->SetTopWindow(NULL); - } - - wxTheApp->DeletePendingObjects(); - - retValue = wxTheApp->OnExit(); - - wxEntryCleanup(); - - return retValue; + wxAppConsole::Exit(); } -// Static member initialization -wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL; +// ============================================================================ +// wxApp +// ============================================================================ wxApp::wxApp() { argc = 0; argv = NULL; - m_eventLoop = new wxEventLoop; + m_mainLoop = new wxEventLoop; m_mainColormap = (WXColormap) NULL; m_appContext = (WXAppContext) NULL; m_initialDisplay = (WXDisplay*) 0; @@ -282,7 +129,7 @@ wxApp::wxApp() wxApp::~wxApp() { - delete m_eventLoop; + delete m_mainLoop; for( wxPerDisplayDataMap::iterator it = m_perDisplayData->begin(), end = m_perDisplayData->end(); @@ -294,15 +141,7 @@ wxApp::~wxApp() delete m_perDisplayData; - wxTheApp = NULL; -} - -bool wxApp::Initialized() -{ - if (GetTopWindow()) - return TRUE; - else - return FALSE; + wxApp::SetInstance(NULL); } int wxApp::MainLoop() @@ -318,45 +157,11 @@ int wxApp::MainLoop() XDefaultRootWindow(XtDisplay((Widget) wxTheApp->GetTopLevelWidget())), PropertyChangeMask); - m_eventLoop->Run(); + m_mainLoop->Run(); return 0; } -// Processes an idle event. -// Returns TRUE if more time is needed. -bool wxApp::ProcessIdle() -{ - wxIdleEvent event; - - return ProcessEvent(event) && event.MoreRequested(); -} - -void wxApp::ExitMainLoop() -{ - if( m_eventLoop->IsRunning() ) - m_eventLoop->Exit(); -} - -// Is a message/event pending? -bool wxApp::Pending() -{ - return m_eventLoop->Pending(); -#if 0 - XFlush(XtDisplay( (Widget) wxTheApp->GetTopLevelWidget() )); - - // Fix by Doug from STI, to prevent a stall if non-X event - // is found. - return ((XtAppPending( (XtAppContext) GetAppContext() ) & XtIMXEvent) != 0) ; -#endif -} - -// Dispatch a message. -void wxApp::Dispatch() -{ - m_eventLoop->Dispatch(); -} - // This should be redefined in a derived class for // handling property change events for XAtom IPC. void wxApp::HandlePropertyChange(WXEvent *event) @@ -365,104 +170,6 @@ void wxApp::HandlePropertyChange(WXEvent *event) XtDispatchEvent((XEvent*) event); /* let Motif do the work */ } -void wxApp::OnIdle(wxIdleEvent& event) -{ - static bool inOnIdle = FALSE; - - // Avoid recursion (via ProcessEvent default case) - if (inOnIdle) - return; - - inOnIdle = TRUE; - - // If there are pending events, we must process them: pending events - // are either events to the threads other than main or events posted - // with wxPostEvent() functions - // GRG: I have moved this here so that all pending events are processed - // before starting to delete any objects. This behaves better (in - // particular, wrt wxPostEvent) and is coherent with wxGTK's current - // behaviour. Also removed the '#if wxUSE_THREADS' around it. - // Changed Mar/2000 before 2.1.14 - - // Flush pending events. - ProcessPendingEvents(); - - // 'Garbage' collection of windows deleted with Close(). - DeletePendingObjects(); - - // flush the logged messages if any - wxLog *pLog = wxLog::GetActiveTarget(); - if ( pLog != NULL && pLog->HasPendingMessages() ) - pLog->Flush(); - - // Send OnIdle events to all windows - bool needMore = SendIdleEvents(); - - if (needMore) - event.RequestMore(TRUE); - - inOnIdle = FALSE; -} - -// Send idle event to all top-level windows -bool wxApp::SendIdleEvents() -{ - bool needMore = FALSE; - - wxWindowList::Node* node = wxTopLevelWindows.GetFirst(); - while (node) - { - wxWindow* win = node->GetData(); - if (SendIdleEvents(win)) - needMore = TRUE; - node = node->GetNext(); - } - - return needMore; -} - -// Send idle event to window and all subwindows -bool wxApp::SendIdleEvents(wxWindow* win) -{ - bool needMore = FALSE; - - wxIdleEvent event; - event.SetEventObject(win); - win->GetEventHandler()->ProcessEvent(event); - - if (event.MoreRequested()) - needMore = TRUE; - - wxWindowList::Node* node = win->GetChildren().GetFirst(); - while (node) - { - wxWindow* win = node->GetData(); - if (SendIdleEvents(win)) - needMore = TRUE; - - node = node->GetNext(); - } - return needMore ; -} - -void wxApp::DeletePendingObjects() -{ - wxList::Node *node = wxPendingDelete.GetFirst(); - while (node) - { - wxObject *obj = node->GetData(); - - delete obj; - - if (wxPendingDelete.Member(obj)) - delete node; - - // Deleting one object may have deleted other pending - // objects, so start from beginning of list again. - node = wxPendingDelete.GetFirst(); - } -} - static char *fallbackResources[] = { "*menuBar.marginHeight: 0", "*menuBar.shadowThickness: 1", @@ -564,6 +271,7 @@ WXWidget wxCreateTopLevelWidget( WXDisplay* display ) applicationShellWidgetClass, (Display*)display, NULL, 0 ); + XtSetMappedWhenManaged( tlw, False ); XtRealizeWidget( tlw ); XtAddCallback( tlw, XmNdestroyCallback, @@ -592,26 +300,11 @@ void wxApp::SetTopLevelWidget(WXDisplay* display, WXWidget widget) (*m_perDisplayData)[display].m_topLevelWidget = (Widget)widget; } -void wxExit() -{ - int retValue = 0; - if (wxTheApp) - retValue = wxTheApp->OnExit(); - - wxApp::CleanUp(); - /* - * Exit in some platform-specific way. - * Not recommended that the app calls this: - * only for emergencies. - */ - exit(retValue); -} - // Yield to other processes bool wxApp::Yield(bool onlyIfNeeded) { - bool s_inYield = FALSE; + static bool s_inYield = FALSE; if ( s_inYield ) {