X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d02cb44ecf4991eb6dd480d24852f5ef238a5317..15c6934360d27110bc36ca747ca6be9f3412c5dc:/src/x11/app.cpp?ds=sidebyside diff --git a/src/x11/app.cpp b/src/x11/app.cpp index ebcb2d9da1..4d43a26b17 100644 --- a/src/x11/app.cpp +++ b/src/x11/app.cpp @@ -29,6 +29,7 @@ #include "wx/log.h" #include "wx/intl.h" #include "wx/evtloop.h" +#include "wx/cmdline.h" #if wxUSE_THREADS #include "wx/thread.h" @@ -53,15 +54,12 @@ #include -extern char *wxBuffer; extern wxList wxPendingDelete; wxApp *wxTheApp = NULL; wxHashTable *wxWidgetHashTable = NULL; -static Window wxGetParentWindow(Window window); - IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler) BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) @@ -81,11 +79,10 @@ static int wxXErrorHandler(Display *dpy, XErrorEvent *xevent) #endif // __WXDEBUG__ long wxApp::sm_lastMessageTime = 0; +WXDisplay *wxApp::ms_display = NULL; bool wxApp::Initialize() { - wxBuffer = new char[BUFSIZ + 512]; - wxClassInfo::InitializeClasses(); // GL: I'm annoyed ... I don't know where to put this and I don't want to @@ -104,8 +101,6 @@ bool wxApp::Initialize() wxInitializeResourceSystem(); #endif - wxBitmap::InitStandardHandlers(); - wxWidgetHashTable = new wxHashTable(wxKEY_INTEGER); wxModule::RegisterModules(); @@ -125,27 +120,18 @@ void wxApp::CleanUp() wxCleanUpResourceSystem(); #endif - wxDeleteStockObjects() ; - - // Destroy all GDI lists, etc. - - wxDeleteStockLists(); - delete wxTheColourDatabase; wxTheColourDatabase = NULL; - wxBitmap::CleanUpHandlers(); - - delete[] wxBuffer; - wxBuffer = NULL; - - wxClassInfo::CleanUpClasses(); + wxDeleteStockObjects(); + + wxDeleteStockLists(); 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. + wxClassInfo::CleanUpClasses(); + #if wxUSE_THREADS delete wxPendingEvents; delete wxPendingEventsLocker; @@ -170,6 +156,56 @@ void wxApp::CleanUp() delete wxLog::SetActiveTarget(NULL); } +// This is set within wxEntryStart -- too early on +// to put these in wxTheApp +static int g_newArgc = 0; +static wxChar** g_newArgv = 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__ + + /// TODO +#if 0 + // Parse the arguments. +#endif + + 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 @@ -181,9 +217,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) { @@ -205,17 +241,31 @@ int wxEntry( int argc, char *argv[] ) wxTheApp->SetClassName(wxFileNameFromPath(argv[0])); wxTheApp->SetAppName(wxFileNameFromPath(argv[0])); - wxTheApp->argc = argc; - wxTheApp->argv = argv; + // The command line may have been changed + // by stripping out -display etc. + if (g_newArgc > 0) + { + wxTheApp->argc = g_newArgc; + wxTheApp->argv = g_newArgv; + } + else + { + 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(); } @@ -259,7 +309,6 @@ wxApp::wxApp() m_mainColormap = (WXColormap) NULL; m_topLevelWidget = (WXWindow) NULL; m_maxRequestSize = 0; - m_initialDisplay = (WXDisplay*) 0; m_mainLoop = NULL; } @@ -295,11 +344,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: @@ -347,13 +403,16 @@ void wxApp::ProcessXEvent(WXEvent* _event) return; } case ClientMessage: - { + { + if (win && !win->IsEnabled()) + return; + Atom wm_delete_window = XInternAtom(wxGlobalDisplay(), "WM_DELETE_WINDOW", True);; Atom wm_protocols = XInternAtom(wxGlobalDisplay(), "WM_PROTOCOLS", True);; 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) { @@ -363,6 +422,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 @@ -395,12 +464,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; @@ -450,6 +516,10 @@ void wxApp::ProcessXEvent(WXEvent* _event) } default: { +#ifdef __WXDEBUG__ + //wxString eventName = wxGetXEventName(XEvent& event); + //wxLogDebug(wxT("Event %s not handled"), eventName.c_str()); +#endif break; } } @@ -496,41 +566,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() @@ -564,7 +621,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; @@ -578,7 +638,8 @@ bool wxApp::SendIdleEvents(wxWindow* win) node = node->Next(); } - return needMore ; + + return needMore; } void wxApp::DeletePendingObjects() @@ -602,27 +663,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,12 +694,20 @@ WXColormap wxApp::GetMainColormap(WXDisplay* display) return (WXColormap) c; } -Window wxGetParentWindow(Window window) +Window wxGetWindowParent(Window window) { + wxASSERT_MSG( window, "invalid window" ); + + return (Window) 0; + 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; @@ -729,13 +788,16 @@ wxApp::GetStdIcon(int which) const } } -// ---------------------------------------------------------------------------- -// accessors for C modules -// ---------------------------------------------------------------------------- - -#if 0 -extern "C" XtAppContext wxGetAppContext() +void wxApp::OnAssert(const wxChar *file, int line, const wxChar *msg) { - return (XtAppContext)wxTheApp->GetAppContext(); -} + // 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 +} +