X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b28d3abf7eb85e8a8d056076d2812977105a28e1..59c962bf54667cab735353b2ec3b7a2438464f22:/src/x11/app.cpp diff --git a/src/x11/app.cpp b/src/x11/app.cpp index 9e840d40a5..62cb336b78 100644 --- a/src/x11/app.cpp +++ b/src/x11/app.cpp @@ -79,6 +79,7 @@ static int wxXErrorHandler(Display *dpy, XErrorEvent *xevent) #endif // __WXDEBUG__ long wxApp::sm_lastMessageTime = 0; +WXDisplay *wxApp::ms_display = NULL; bool wxApp::Initialize() { @@ -102,8 +103,6 @@ bool wxApp::Initialize() wxInitializeResourceSystem(); #endif - wxBitmap::InitStandardHandlers(); - wxWidgetHashTable = new wxHashTable(wxKEY_INTEGER); wxModule::RegisterModules(); @@ -123,27 +122,21 @@ void wxApp::CleanUp() wxCleanUpResourceSystem(); #endif - wxDeleteStockObjects() ; - - // Destroy all GDI lists, etc. - - wxDeleteStockLists(); - delete wxTheColourDatabase; wxTheColourDatabase = NULL; - wxBitmap::CleanUpHandlers(); + wxDeleteStockObjects(); + + wxDeleteStockLists(); + + delete wxTheApp; + wxTheApp = NULL; delete[] wxBuffer; wxBuffer = NULL; wxClassInfo::CleanUpClasses(); - delete wxTheApp; - wxTheApp = 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; delete wxPendingEventsLocker; @@ -168,6 +161,46 @@ void wxApp::CleanUp() delete wxLog::SetActiveTarget(NULL); } +// NB: argc and argv may be changed here, pass by reference! +int wxEntryStart( int& argc, char *argv[] ) +{ +#ifdef __WXDEBUG__ + // install the X error handler + gs_pfnXErrorHandler = XSetErrorHandler( wxXErrorHandler ); +#endif // __WXDEBUG__ + + Display* xdisplay = XOpenDisplay(NULL); + + if (!xdisplay) + { + wxLogError( _("wxWindows could not open display. Exiting.") ); + return -1; + } + + wxApp::ms_display = (WXDisplay*) xdisplay; + + XSelectInput( xdisplay, XDefaultRootWindow(xdisplay), PropertyChangeMask); + +// wxSetDetectableAutoRepeat( TRUE ); + + if (!wxApp::Initialize()) + return -1; + + return 0; +} + + +int wxEntryInitGui() +{ + int retValue = 0; + + if ( !wxTheApp->OnInitGui() ) + retValue = -1; + + return retValue; +} + + int wxEntry( int argc, char *argv[] ) { #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT @@ -179,9 +212,9 @@ int wxEntry( int argc, char *argv[] ) // checked, but this is a reasonable compromise. wxDebugContext::SetCheckpoint(); #endif - - if (!wxApp::Initialize()) - return FALSE; + int err = wxEntryStart(argc, argv); + if (err) + return err; if (!wxTheApp) { @@ -206,14 +239,18 @@ int wxEntry( int argc, char *argv[] ) wxTheApp->argc = argc; wxTheApp->argv = argv; - // GUI-specific initialization, such as creating an app context. - wxTheApp->OnInitGui(); + int retValue; + retValue = wxEntryInitGui(); // Here frames insert themselves automatically into wxTopLevelWindows by // getting created in OnInit(). + if ( retValue == 0 ) + { + if ( !wxTheApp->OnInit() ) + retValue = -1; + } - int retValue = 0; - if (wxTheApp->OnInit()) + if ( retValue == 0 ) { if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun(); } @@ -257,7 +294,6 @@ wxApp::wxApp() m_mainColormap = (WXColormap) NULL; m_topLevelWidget = (WXWindow) NULL; m_maxRequestSize = 0; - m_initialDisplay = (WXDisplay*) 0; m_mainLoop = NULL; } @@ -293,8 +329,17 @@ void wxApp::ProcessXEvent(WXEvent* _event) // Find the first wxWindow that corresponds to this event window // TODO: may need to translate coordinates from actualWindow // to window, if the receiving window != wxWindow window - while (window && !(win = wxGetWindowFromTable(window))) - window = wxGetWindowParent(window); + // while (window && !(win = wxGetWindowFromTable(window))) + // window = wxGetWindowParent(window); + + // Because we're receiving events after a window + // has been destroyed, assume a 1:1 match between + // Window and wxWindow, so if it's not in the table, + // it must have been destroyed. + + win = wxGetWindowFromTable(window); + if (!win) + return; switch (event->type) { @@ -349,7 +394,7 @@ void wxApp::ProcessXEvent(WXEvent* _event) if (event->xclient.message_type == wm_protocols) { - if (event->xclient.data.l[0] == wm_delete_window) + if ((Atom) (event->xclient.data.l[0]) == wm_delete_window) { if (win) { @@ -359,6 +404,16 @@ void wxApp::ProcessXEvent(WXEvent* _event) } return; } + case ConfigureNotify: + { + if (win) + { + wxSizeEvent sizeEvent( wxSize(event->xconfigure.width,event->xconfigure.height), win->GetId() ); + sizeEvent.SetEventObject( win ); + + win->GetEventHandler()->ProcessEvent( sizeEvent ); + } + } case ResizeRequest: { /* Terry Gitnick - 1/21/98 @@ -391,12 +446,9 @@ void wxApp::ProcessXEvent(WXEvent* _event) { if (win) { + // Schedule update for later win->GetUpdateRegion().Union( event->xexpose.x, event->xexpose.y, event->xexpose.width, event->xexpose.height); - if (event->xexpose.count == 0) - { - win->X11SendPaintEvents(); // TODO let an idle handler do that - } } return; @@ -492,41 +544,28 @@ void wxApp::HandlePropertyChange(WXEvent *event) void wxApp::OnIdle(wxIdleEvent& event) { - static bool inOnIdle = FALSE; + static bool s_inOnIdle = FALSE; // Avoid recursion (via ProcessEvent default case) - if (inOnIdle) + if (s_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 + s_inOnIdle = TRUE; - // Flush pending events. + // Resend in the main thread events which have been prepared in other + // threads ProcessPendingEvents(); - // 'Garbage' collection of windows deleted with Close(). + // '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; + s_inOnIdle = FALSE; } void wxWakeUpIdle() @@ -560,7 +599,10 @@ bool wxApp::SendIdleEvents(wxWindow* win) wxIdleEvent event; event.SetEventObject(win); - win->ProcessEvent(event); + + win->GetEventHandler()->ProcessEvent(event); + + win->OnInternalIdle(); if (event.MoreRequested()) needMore = TRUE; @@ -574,7 +616,8 @@ bool wxApp::SendIdleEvents(wxWindow* win) node = node->Next(); } - return needMore ; + + return needMore; } void wxApp::DeletePendingObjects() @@ -598,27 +641,17 @@ void wxApp::DeletePendingObjects() // Create an application context bool wxApp::OnInitGui() { - // TODO: parse argv and get display to pass to XOpenDisplay - Display* dpy = XOpenDisplay(NULL); - m_initialDisplay = (WXDisplay*) dpy; - - if (!dpy) { - wxString className(wxTheApp->GetClassName()); - wxLogError(_("wxWindows could not open display for '%s': exiting."), - (const char*) className); - exit(-1); - } - XSelectInput((Display*) m_initialDisplay, - XDefaultRootWindow((Display*) m_initialDisplay), - PropertyChangeMask); - -#ifdef __WXDEBUG__ - // install the X error handler - gs_pfnXErrorHandler = XSetErrorHandler(wxXErrorHandler); -#endif // __WXDEBUG__ - - GetMainColormap(dpy); - m_maxRequestSize = XMaxRequestSize((Display*) dpy); + // Eventually this line will be removed, but for + // now we don't want to try popping up a dialog + // for error messages. + delete wxLog::SetActiveTarget(new wxLogStderr); + + if (!wxAppBase::OnInitGui()) + return FALSE; + + + GetMainColormap( wxApp::GetDisplay() ); + m_maxRequestSize = XMaxRequestSize( (Display*) wxApp::GetDisplay() ); return TRUE; } @@ -643,8 +676,12 @@ Window wxGetWindowParent(Window window) { Window parent, root = 0; unsigned int noChildren = 0; - if (XQueryTree((Display*) wxGetDisplay(), window, & root, & parent, - NULL, & noChildren)) + Window* children = NULL; + int res = XQueryTree((Display*) wxGetDisplay(), window, & root, & parent, + & children, & noChildren); + if (children) + XFree(children); + if (res) return parent; else return (Window) 0; @@ -725,6 +762,19 @@ wxApp::GetStdIcon(int which) const } } +void wxApp::OnAssert(const wxChar *file, int line, const wxChar *msg) +{ + // While the GUI isn't working that well, just print out the + // message. +#if 0 + wxAppBase::OnAssert(file, line, msg); +#else + wxString msg2; + msg2.Printf("At file %s:%d: %s", file, line, msg); + wxLogDebug(msg2); +#endif +} + // ---------------------------------------------------------------------------- // accessors for C modules // ----------------------------------------------------------------------------