X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b513212d2eab4daacd56606d6c7d489639e3215b..61aa560b2d217d4ae0a6d5c35c22317a3f65fe5d:/src/x11/app.cpp?ds=inline diff --git a/src/x11/app.cpp b/src/x11/app.cpp index b85b9855d6..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,11 +329,18 @@ 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 = wxGetParentWindow(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; - // TODO: shouldn't all the ProcessEvents below - // be win->GetEventHandler()->ProcessEvent? switch (event->type) { case KeyPress: @@ -305,13 +348,6 @@ void wxApp::ProcessXEvent(WXEvent* _event) if (win && !win->IsEnabled()) return; - if (CheckForAccelerator(_event)) - { - // Do nothing! We intercepted and processed the event as an - // accelerator. - return; - } - else { if (win) { @@ -358,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) { @@ -368,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 @@ -400,14 +446,9 @@ void wxApp::ProcessXEvent(WXEvent* _event) { if (win) { - win->AddUpdateRect(event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height); - - if (event -> xexpose.count == 0) - { - win->DoPaint(); - win->ClearUpdateRects(); - } + // Schedule update for later + win->GetUpdateRegion().Union( event->xexpose.x, event->xexpose.y, + event->xexpose.width, event->xexpose.height); } return; @@ -503,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() @@ -571,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; @@ -585,7 +616,8 @@ bool wxApp::SendIdleEvents(wxWindow* win) node = node->Next(); } - return needMore ; + + return needMore; } void wxApp::DeletePendingObjects() @@ -609,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; } @@ -654,48 +676,17 @@ 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; } -// Returns TRUE if an accelerator has been processed -bool wxApp::CheckForAccelerator(WXEvent* event) -{ - XEvent* xEvent = (XEvent*) event; - if (xEvent->xany.type == KeyPress) - { - // Find a wxWindow for this window - // TODO: should get display for the window, not the current display - Window window = xEvent->xany.window; - wxWindow* win = NULL; - - // Find the first wxWindow that corresponds to this event window - while (window && !(win = wxGetWindowFromTable(window))) - window = wxGetWindowParent(window); - - if (!window || !win) - return FALSE; - - wxKeyEvent keyEvent(wxEVT_CHAR); - wxTranslateKeyEvent(keyEvent, win, (Window) 0, xEvent); - - // Now we have a wxKeyEvent and we have a wxWindow. - // Go up the hierarchy until we find a matching accelerator, - // or we get to the top. - while (win) - { - if (win->ProcessAccelerator(keyEvent)) - return TRUE; - win = win->GetParent(); - } - return FALSE; - } - return FALSE; -} - void wxExit() { int retValue = 0; @@ -771,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 // ----------------------------------------------------------------------------