]> git.saurik.com Git - wxWidgets.git/blobdiff - src/motif/app.cpp
ADDED wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK
[wxWidgets.git] / src / motif / app.cpp
index d8df53ed4c0c2b359abc9f2d45284efe38b5c573..622e9c126eee70ae7311533beec2d36a43816772 100644 (file)
 #include "wx/resource.h"
 #endif
 
-#if wxUSE_POSTSCRIPT
-#include "wx/postscrp.h"
-#endif
-
 #include <Xm/Xm.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
@@ -71,18 +67,12 @@ bool wxApp::Initialize()
     wxBuffer = new char[BUFSIZ + 512];
 #endif
 
-#if (WXDEBUG && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
-
-    streambuf* sBuf = new wxDebugStreamBuf;
-    ostream* oStr = new ostream(sBuf) ;
-    wxDebugContext::SetStream(oStr, sBuf);
-
-#endif
-  
     wxClassInfo::InitializeClasses();
 
     wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
     wxTheColourDatabase->Initialize();
+
+    wxInitializeStockLists();
     wxInitializeStockObjects();
 
 #if wxUSE_WX_RESOURCES
@@ -91,9 +81,11 @@ bool wxApp::Initialize()
 
   // For PostScript printing
 #if wxUSE_POSTSCRIPT
+/* Done using wxModule now
     wxInitializePrintSetupData();
     wxThePrintPaperDatabase = new wxPrintPaperDatabase;
     wxThePrintPaperDatabase->CreateDatabase();
+*/
 #endif
 
     wxBitmap::InitStandardHandlers();
@@ -137,9 +129,11 @@ void wxApp::CleanUp()
     wxTheColourDatabase = NULL;
 
 #if wxUSE_POSTSCRIPT
+/* Done using wxModule now
     wxInitializePrintSetupData(FALSE);
     delete wxThePrintPaperDatabase;
     wxThePrintPaperDatabase = NULL;
+*/
 #endif
 
     wxBitmap::CleanUpHandlers();
@@ -149,6 +143,22 @@ void wxApp::CleanUp()
 
     wxClassInfo::CleanUpClasses();
 
+    delete wxTheApp;
+    wxTheApp = NULL;
+  
+#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
@@ -157,8 +167,19 @@ void wxApp::CleanUp()
 
 int wxEntry( 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 FALSE;
+
     if (!wxTheApp)
     {
       if (!wxApp::GetInitializerFunction())
@@ -189,11 +210,19 @@ int wxEntry( int argc, char *argv[] )
     // into wxTopLevelWindows by getting created
     // in OnInit().
   
-    if (!wxTheApp->OnInit()) return 0;
-
     int retValue = 0;
-  
-    if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun();
+    if (wxTheApp->OnInit())
+    {
+      if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun();
+    }
+
+    // flush the logged messages if any
+    wxLog *pLog = wxLog::GetActiveTarget();
+    if ( pLog != NULL && pLog->HasPendingMessages() )
+      pLog->Flush();
+
+    delete wxLog::SetActiveTarget(new wxLogStderr); // So dialog boxes aren't used
+                                   // for further messages
 
     if (wxTheApp->GetTopWindow())
     {
@@ -207,23 +236,6 @@ int wxEntry( int argc, char *argv[] )
   
     wxApp::CleanUp();
 
-    delete wxTheApp;
-    wxTheApp = NULL;
-  
-#if (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() > 0)
-    {
-      wxTrace("There were memory leaks.\n");
-      wxDebugContext::Dump();
-      wxDebugContext::PrintStatistics();
-    }
-    wxDebugContext::SetStream(NULL, NULL);
-#endif
-  
     return retValue;
 };
 
@@ -247,6 +259,7 @@ wxApp::wxApp()
     m_appContext = (WXAppContext) NULL;
     m_topLevelWidget = (WXWidget) NULL;
     m_maxRequestSize = 0;
+    m_initialDisplay = (WXDisplay*) 0;
 }
 
 bool wxApp::Initialized()
@@ -278,34 +291,55 @@ int wxApp::MainLoop()
     while (m_keepGoing)
     {
       XtAppNextEvent( (XtAppContext) wxTheApp->GetAppContext(), &event);
-      if(event.type == PropertyNotify)
-      {
-        HandlePropertyChange((WXEvent*) &event);
-      } else
-      {
-        // Terry Gitnick <terryg@scientech.com> - 1/21/98
-         /* if resize event, don't resize until the last resize event for this
-            window is recieved. Prevents flicker as windows are resized. */
-        if (event.type == ResizeRequest)
-        {
-           Display *disp = XtDisplay((Widget) wxTheApp->GetTopLevelWidget());
-           Window win = event.xany.window;
-           XEvent report;
-           //  to avoid flicker
-           report = event;
-           while( XCheckTypedWindowEvent (disp, win, ResizeRequest, &report));
-        }
-
-        XtDispatchEvent(&event);
 
-        DeletePendingObjects();
-      }
+      ProcessXEvent((WXEvent*) & event);
+      ProcessIdle();
     }
 
     return 0;
 }
 
+// Processes an X event.
+void wxApp::ProcessXEvent(WXEvent* _event)
+{
+    XEvent* event = (XEvent*) _event;
+
+    if ((event->type == KeyPress) && CheckForAccelerator(_event))
+    {
+        // Do nothing! We intercepted and processed the event as an accelerator.
+        return;
+    }
+    else if (event->type == PropertyNotify)
+    {
+        HandlePropertyChange(_event);
+        return;
+    }
+    else if (event->type == ResizeRequest)
+    {
+        /* Terry Gitnick <terryg@scientech.com> - 1/21/98
+         * If resize event, don't resize until the last resize event for this
+         * window is recieved. Prevents flicker as windows are resized.
+         */
+
+        Display *disp = XtDisplay((Widget) wxTheApp->GetTopLevelWidget());
+        Window win = event->xany.window;
+        XEvent report;
+        //  to avoid flicker
+        report = * event;
+        while( XCheckTypedWindowEvent (disp, win, ResizeRequest, &report));
+
+        // TODO: when implementing refresh optimization, we can use
+        // XtAddExposureToRegion to expand the window's paint region.
+
+        XtDispatchEvent(event);
+    }
+    else
+    {
+        XtDispatchEvent(event);
+    }
+}
+
 // Returns TRUE if more time is needed.
 bool wxApp::ProcessIdle()
 {
@@ -325,13 +359,20 @@ void wxApp::ExitMainLoop()
 bool wxApp::Pending()
 {
     XFlush(XtDisplay( (Widget) wxTheApp->GetTopLevelWidget() ));
-    return (XtAppPending( (XtAppContext) wxTheApp->GetAppContext() ) != 0) ;
+
+    // Fix by Doug from STI, to prevent a stall if non-X event
+    // is found.
+    return ((XtAppPending( (XtAppContext) GetAppContext() ) & XtIMXEvent) != 0) ;
 }
 
 // Dispatch a message.
 void wxApp::Dispatch()
 {
-    XtAppProcessEvent( (XtAppContext) wxTheApp->GetAppContext(), XtIMAll);
+//    XtAppProcessEvent( (XtAppContext) wxTheApp->GetAppContext(), XtIMAll);
+
+    XEvent event;
+    XtAppNextEvent((XtAppContext) GetAppContext(), &event);
+    ProcessXEvent((WXEvent*) & event);
 }
 
 // This should be redefined in a derived class for
@@ -397,7 +438,7 @@ bool wxApp::SendIdleEvents(wxWindow* win)
     if (event.MoreRequested())
         needMore = TRUE;
 
-       wxNode* node = win->GetChildren()->First();
+       wxNode* node = win->GetChildren().First();
        while (node)
        {
                wxWindow* win = (wxWindow*) node->Data();
@@ -458,6 +499,8 @@ bool wxApp::OnInitGui()
       cerr << "wxWindows could not open display for " << wxTheApp->GetClassName() << ": exiting.\n";
       exit(-1);
     }
+    m_initialDisplay = (WXDisplay*) dpy;
+
     wxTheApp->m_topLevelWidget = (WXWidget) XtAppCreateShell((String)NULL, (const char*) wxTheApp->GetClassName(),
                                      applicationShellWidgetClass,dpy,
                                      NULL,0) ;
@@ -489,6 +532,41 @@ WXColormap wxApp::GetMainColormap(WXDisplay* display)
     return (WXColormap) c;
 }
 
+// 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
+        Widget widget = XtWindowToWidget((Display*) wxGetDisplay(), xEvent->xany.window);
+        wxWindow* win = NULL;
+
+        // Find the first wxWindow that corresponds to this event window
+        while (widget && !(win = wxGetWindowFromTable(widget)))
+            widget = XtParent(widget);
+
+        if (!widget || !win)
+            return FALSE;
+
+        wxKeyEvent keyEvent(wxEVT_CHAR);
+        wxTranslateKeyEvent(keyEvent, win, (Widget) 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;