]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk1/app.cpp
fixed status bar drawing broken by previous compilation fix
[wxWidgets.git] / src / gtk1 / app.cpp
index 4cd16593da2dcf5f29a81d6ec499bbaf3db8ebac..60780e3d703dcd03c7381f1fb721219c37de144a 100644 (file)
 #include "wx/module.h"
 #include "wx/image.h"
 
+#ifdef __WXUNIVERSAL__
+    #include "wx/univ/theme.h"
+    #include "wx/univ/renderer.h"
+#endif
+
 #if wxUSE_THREADS
-#include "wx/thread.h"
+    #include "wx/thread.h"
 #endif
 
-#include "unistd.h"
+#include <unistd.h>
+#include "wx/gtk/win_gtk.h"
 
-#include "glib.h"
-#include "gdk/gdk.h"
-#include "gtk/gtk.h"
+#include <gtk/gtk.h>
 
-#include "wx/gtk/win_gtk.h"
 
 //-----------------------------------------------------------------------------
 // global data
 wxApp *wxTheApp = (wxApp *)  NULL;
 wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
 
-extern wxResourceCache *wxTheResourceCache;
 extern bool g_isIdle;
 
-unsigned char g_palette[64*3] =
-{
-  0x0,  0x0,  0x0,
-  0xff, 0xff, 0xff,
-  0xff, 0x0,  0x0,
-  0xff, 0xff, 0x0,
-  0x0,  0xff, 0x0,
-  0x0,  0x0,  0xff,
-  0x0,  0xff, 0xff,
-  0x99, 0x99, 0x99,
-  0xff, 0x88, 0x0,
-  0x88, 0x0,  0x0,
-  0x0,  0x88, 0x88,
-  0x88, 0x88, 0x0,
-  0xff, 0xcc, 0x97,
-  0xbb, 0xbb, 0xbb,
-  0x9f, 0x6b, 0x42,
-  0x55, 0x55, 0x55,
-  0xdd, 0xdd, 0xdd,
-  0x77, 0x77, 0x77,
-  0x33, 0x33, 0x33,
-  0xcc, 0x0,  0x0,
-  0xff, 0x44, 0x0,
-  0xff, 0xcc, 0x0,
-  0xcc, 0xcc, 0x0,
-  0x60, 0x60, 0x0,
-  0x0,  0x43, 0x0,
-  0x0,  0x7f, 0x0,
-  0x0,  0xcc, 0x0,
-  0x0,  0x44, 0x44,
-  0x0,  0x0,  0x44,
-  0x0,  0x0,  0x88,
-  0xef, 0xb1, 0x7b,
-  0xdf, 0x98, 0x5f,
-  0xbf, 0x87, 0x56,
-  0x7f, 0x57, 0x26,
-  0x5f, 0x39, 0xc,
-  0x3f, 0x1c, 0x0,
-  0x21, 0x0,  0x0,
-  0x0,  0x43, 0x87,
-  0x2d, 0x70, 0xaf,
-  0x5a, 0x9e, 0xd7,
-  0x87, 0xcc, 0xff,
-  0xff, 0xe0, 0xba,
-  0x21, 0x43, 0xf,
-  0x3d, 0x5d, 0x25,
-  0x59, 0x78, 0x3a,
-  0x75, 0x93, 0x4f,
-  0x91, 0xae, 0x64,
-  0xad, 0xc8, 0x7a,
-  0xf0, 0xa8, 0xef,
-  0xd0, 0x88, 0xd0,
-  0xaf, 0x66, 0xaf,
-  0x8e, 0x44, 0x8e,
-  0x6d, 0x22, 0x6d,
-  0x4b, 0x0,  0x4b,
-  0xff, 0xc0, 0xbc,
-  0xff, 0x93, 0x91,
-  0xff, 0x66, 0x67,
-  0xd8, 0xf2, 0xbf,
-  0xff, 0xc9, 0x68,
-  0xff, 0x96, 0x67,
-  0xa5, 0x60, 0xff,
-  0x51, 0xff, 0x99,
-  0x3f, 0xa5, 0x63,
-  0x98, 0x90, 0x67
-};
+bool   g_mainThreadLocked = FALSE;
+gint   g_pendingTag = 0;
+
+static GtkWidget *gs_RootWindow = (GtkWidget*) NULL;
 
 //-----------------------------------------------------------------------------
 // local functions
 //-----------------------------------------------------------------------------
 
-extern void wxFlushResources();
-
 /* forward declaration */
-gint        wxapp_idle_callback( gpointer WXUNUSED(data) );
-void        wxapp_install_idle_handler();
-static gint wxapp_wakeup_timerout_callback( gpointer WXUNUSED(data) );
+gint   wxapp_idle_callback( gpointer WXUNUSED(data) );
+gint   wxapp_pending_callback( gpointer WXUNUSED(data) );
+void   wxapp_install_idle_handler();
+
+#if wxUSE_THREADS
+gint   wxapp_wakeup_timerout_callback( gpointer WXUNUSED(data) );
+#endif
 
 //-----------------------------------------------------------------------------
 // wxExit
@@ -142,18 +83,38 @@ void wxExit()
 // wxYield
 //-----------------------------------------------------------------------------
 
+static bool gs_inYield = FALSE;
+
 bool wxYield()
 {
-    bool has_idle = (wxTheApp->m_idleTag != 0);
+#if wxUSE_THREADS
+    if ( !wxThread::IsMain() )
+    {
+        // can't call gtk_main_iteration() from other threads like this
+        return TRUE;
+    }
+#endif // wxUSE_THREADS
 
-    if (has_idle)
+#ifdef __WXDEBUG__
+    if (gs_inYield)
+        wxFAIL_MSG( wxT("wxYield called recursively" ) );
+#endif
+
+    gs_inYield = TRUE;
+
+    if (!g_isIdle)
     {
-        /* We need to temporarily remove idle callbacks or the loop will
-           never finish. */
+        // We need to remove idle callbacks or the loop will
+        // never finish.
         gtk_idle_remove( wxTheApp->m_idleTag );
         wxTheApp->m_idleTag = 0;
+        g_isIdle = TRUE;
     }
 
+    // disable log flushing from here because a call to wxYield() shouldn't
+    // normally result in message boxes popping up &c
+    wxLog::Suspend();
+
     while (gtk_events_pending())
         gtk_main_iteration();
 
@@ -162,119 +123,190 @@ bool wxYield()
        OnUpdateUI() which is a nice (and desired) side effect) */
     while (wxTheApp->ProcessIdle()) { }
 
-    if (has_idle)
-    {
-        /* re-add idle handler */
-        wxTheApp->m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL );
-    }
+    // let the logs be flashed again
+    wxLog::Resume();
+
+    gs_inYield = FALSE;
 
     return TRUE;
 }
 
+//-----------------------------------------------------------------------------
+// wxYieldIfNeeded
+// Like wxYield, but fails silently if the yield is recursive.
+//-----------------------------------------------------------------------------
+
+bool wxYieldIfNeeded()
+{
+    if (gs_inYield)
+        return FALSE;
+
+    return wxYield();
+}
+
 //-----------------------------------------------------------------------------
 // wxWakeUpIdle
 //-----------------------------------------------------------------------------
 
 void wxWakeUpIdle()
 {
-    if (g_isIdle) 
+#if wxUSE_THREADS
+    if (!wxThread::IsMain())
+        wxMutexGuiEnter();
+#endif
+
+    if (g_isIdle)
         wxapp_install_idle_handler();
+
+#if wxUSE_THREADS
+    if (!wxThread::IsMain())
+        wxMutexGuiLeave();
+#endif
 }
 
 //-----------------------------------------------------------------------------
 // local functions
 //-----------------------------------------------------------------------------
 
-gint wxapp_idle_callback( gpointer WXUNUSED(data) )
+gint wxapp_pending_callback( gpointer WXUNUSED(data) )
 {
     if (!wxTheApp) return TRUE;
 
-#if (GTK_MINOR_VERSION > 0)
-    /* when getting called from GDK's idle handler we
-       are no longer within GDK's grab on the GUI
-       thread so we must lock it here ourselves */
-    GDK_THREADS_ENTER ();
-#endif
+    // when getting called from GDK's time-out handler
+    // we are no longer within GDK's grab on the GUI
+    // thread so we must lock it here ourselves
+    gdk_threads_enter();
 
-    /* sent idle event to all who request them */
-    while (wxTheApp->ProcessIdle()) { }
+    // Sent idle event to all who request them
+    wxTheApp->ProcessPendingEvents();
 
-    /* we don't want any more idle events until the next event is
-       sent to wxGTK */
-    gtk_idle_remove( wxTheApp->m_idleTag );
-    wxTheApp->m_idleTag = 0;
+    g_pendingTag = 0;
 
-    /* indicate that we are now in idle mode - even so deeply
+    /* flush the logged messages if any */
+#if wxUSE_LOG
+    wxLog::FlushActive();
+#endif // wxUSE_LOG
+
+    // Release lock again
+    gdk_threads_leave();
+
+    // Return FALSE to indicate that no more idle events are
+    // to be sent (single shot instead of continuous stream)
+    return FALSE;
+}
+
+gint wxapp_idle_callback( gpointer WXUNUSED(data) )
+{
+    if (!wxTheApp)
+        return TRUE;
+
+#ifdef __WXDEBUG__
+    // don't generate the idle events while the assert modal dialog is shown,
+    // this completely confuses the apps which don't expect to be reentered
+    // from some safely-looking functions
+    if ( wxTheApp->IsInAssert() )
+    {
+        return TRUE;
+    }
+#endif // __WXDEBUG__
+
+    // when getting called from GDK's time-out handler
+    // we are no longer within GDK's grab on the GUI
+    // thread so we must lock it here ourselves
+    gdk_threads_enter();
+
+    /* Indicate that we are now in idle mode - even so deeply
        in idle mode that we don't get any idle events anymore.
        this is like wxMSW where an idle event is sent only
        once each time after the event queue has been completely
        emptied */
     g_isIdle = TRUE;
+    wxTheApp->m_idleTag = 0;
 
-#if (GTK_MINOR_VERSION > 0)
-    /* release lock again */
-    GDK_THREADS_LEAVE ();
-#endif
+    // Sent idle event to all who request them as long as they do
+    while (wxTheApp->ProcessIdle())
+        ;
 
-    return TRUE;
+    // Release lock again
+    gdk_threads_leave();
+
+    // Return FALSE to indicate that no more idle events are
+    // to be sent (single shot instead of continuous stream)
+    return FALSE;
 }
 
 void wxapp_install_idle_handler()
 {
     wxASSERT_MSG( wxTheApp->m_idleTag == 0, wxT("attempt to install idle handler twice") );
 
-    /* this routine gets called by all event handlers
-       indicating that the idle is over. */
+    g_isIdle = FALSE;
 
-    wxTheApp->m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL );
+    if (g_pendingTag == 0)
+        g_pendingTag = gtk_idle_add_priority( 900, wxapp_pending_callback, (gpointer) NULL );
 
-    g_isIdle = FALSE;
+    /* This routine gets called by all event handlers
+       indicating that the idle is over. It may also
+       get called from other thread for sending events
+       to the main thread (and processing these in
+       idle time). Very low priority. */
+
+    wxTheApp->m_idleTag = gtk_idle_add_priority( 1000, wxapp_idle_callback, (gpointer) NULL );
 }
 
 #if wxUSE_THREADS
 
+static int g_threadUninstallLevel = 0;
+
 void wxapp_install_thread_wakeup()
 {
+    g_threadUninstallLevel++;
+
+    if (g_threadUninstallLevel != 1) return;
+
     if (wxTheApp->m_wakeUpTimerTag) return;
 
-    wxTheApp->m_wakeUpTimerTag = gtk_timeout_add( 100, wxapp_wakeup_timerout_callback, (gpointer) NULL );
+    wxTheApp->m_wakeUpTimerTag = gtk_timeout_add( 50, wxapp_wakeup_timerout_callback, (gpointer) NULL );
 }
 
 void wxapp_uninstall_thread_wakeup()
 {
+    g_threadUninstallLevel--;
+
+    if (g_threadUninstallLevel != 0) return;
+
     if (!wxTheApp->m_wakeUpTimerTag) return;
 
     gtk_timeout_remove( wxTheApp->m_wakeUpTimerTag );
     wxTheApp->m_wakeUpTimerTag = 0;
 }
 
-static gint wxapp_wakeup_timerout_callback( gpointer WXUNUSED(data) )
+gint wxapp_wakeup_timerout_callback( gpointer WXUNUSED(data) )
 {
-    wxapp_uninstall_thread_wakeup();
-
-#if (GTK_MINOR_VERSION > 0)
     // when getting called from GDK's time-out handler
     // we are no longer within GDK's grab on the GUI
     // thread so we must lock it here ourselves
-    GDK_THREADS_ENTER ();
-#endif
+    gdk_threads_enter();
+
+    wxapp_uninstall_thread_wakeup();
 
     // unblock other threads wishing to do some GUI things
     wxMutexGuiLeave();
 
+    g_mainThreadLocked = TRUE;
+
     // wake up other threads
     wxUsleep( 1 );
 
     // block other thread again
     wxMutexGuiEnter();
 
-#if (GTK_MINOR_VERSION > 0)
-    // release lock again
-    GDK_THREADS_LEAVE ();
-#endif
+    g_mainThreadLocked = FALSE;
 
     wxapp_install_thread_wakeup();
 
+    // release lock again
+    gdk_threads_leave();
+
     return TRUE;
 }
 
@@ -292,12 +324,13 @@ END_EVENT_TABLE()
 
 wxApp::wxApp()
 {
-    wxTheApp = this;
-
-    m_topWindow = (wxWindow *) NULL;
-    m_exitOnFrameDelete = TRUE;
+    m_initialized = FALSE;
+#ifdef __WXDEBUG__
+    m_isInAssert = FALSE;
+#endif // __WXDEBUG__
 
-    m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL );
+    m_idleTag = 0;
+    wxapp_install_idle_handler();
 
 #if wxUSE_THREADS
     m_wakeUpTimerTag = 0;
@@ -305,6 +338,9 @@ wxApp::wxApp()
 #endif
 
     m_colorCube = (unsigned char*) NULL;
+    
+    // this is NULL for a "regular" wxApp, but is set (and freed) by a wxGLApp
+    m_glVisualInfo = (void *) NULL;
 }
 
 wxApp::~wxApp()
@@ -320,51 +356,53 @@ wxApp::~wxApp()
 
 bool wxApp::OnInitGui()
 {
+    if ( !wxAppBase::OnInitGui() )
+        return FALSE;
+
     GdkVisual *visual = gdk_visual_get_system();
 
+    // if this is a wxGLApp (derived from wxApp), and we've already
+    // chosen a specific visual, then derive the GdkVisual from that
+    if (m_glVisualInfo != NULL) {
+#ifdef __WXGTK20__
+        /* seems gtk_widget_set_default_visual no longer exists? */
+        GdkVisual* vis = gtk_widget_get_default_visual();
+#else
+        GdkVisual* vis = gdkx_visual_get( 
+            ((XVisualInfo *) m_glVisualInfo) ->visualid );
+        gtk_widget_set_default_visual( vis );
+#endif
+
+        GdkColormap *colormap = gdk_colormap_new( vis, FALSE );
+        gtk_widget_set_default_colormap( colormap );
+
+        visual = vis;
+    }
+    
     /* on some machines, the default visual is just 256 colours, so
        we make sure we get the best. this can sometimes be wasteful,
        of course, but what do these guys pay $30.000 for? */
-/*
-    if (gdk_visual_get_best() != gdk_visual_get_system())
+
+    else if ((gdk_visual_get_best() != gdk_visual_get_system()) &&
+        (m_useBestVisual))
     {
+#ifdef __WXGTK20__
+        /* seems gtk_widget_set_default_visual no longer exists? */
+        GdkVisual* vis = gtk_widget_get_default_visual();
+#else
         GdkVisual* vis = gdk_visual_get_best();
         gtk_widget_set_default_visual( vis );
+#endif
 
         GdkColormap *colormap = gdk_colormap_new( vis, FALSE );
         gtk_widget_set_default_colormap( colormap );
 
         visual = vis;
     }
-*/
 
     /* Nothing to do for 15, 16, 24, 32 bit displays */
     if (visual->depth > 8) return TRUE;
 
-        /* this initiates the standard palette as defined by GdkImlib
-           in the GNOME libraries. it ensures that all GNOME applications
-           use the same 64 colormap entries on 8-bit displays so you
-           can use several rather graphics-heavy applications at the
-           same time.
-           NOTE: this doesn't really seem to work this way... */
-
-        /*
-        GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE );
-
-        for (int i = 0; i < 64; i++)
-        {
-            GdkColor col;
-            col.red    = g_palette[i*3 + 0] << 8;
-            col.green  = g_palette[i*3 + 1] << 8;
-            col.blue   = g_palette[i*3 + 2] << 8;
-            col.pixel  = 0;
-
-            gdk_color_alloc( cmap, &col );
-        }
-
-        gtk_widget_set_default_colormap( cmap );
-        */
-
     /* initialize color cube for 8-bit color reduction dithering */
 
     GdkColormap *cmap = gtk_widget_get_default_colormap();
@@ -447,13 +485,6 @@ void wxApp::OnIdle( wxIdleEvent &event )
     /* 'Garbage' collection of windows deleted with Close(). */
     DeletePendingObjects();
 
-    /* flush the logged messages if any */
-#if wxUSE_LOG
-    wxLog *log = wxLog::GetActiveTarget();
-    if (log != NULL && log->HasPendingMessages())
-        log->Flush();
-#endif // wxUSE_LOG
-
     /* Send OnIdle events to all windows */
     bool needMore = SendIdleEvents();
 
@@ -486,7 +517,7 @@ bool wxApp::SendIdleEvents( wxWindow* win )
     wxIdleEvent event;
     event.SetEventObject(win);
 
-    win->ProcessEvent(event);
+    win->GetEventHandler()->ProcessEvent(event);
 
     win->OnInternalIdle();
 
@@ -513,7 +544,8 @@ int wxApp::MainLoop()
 
 void wxApp::ExitMainLoop()
 {
-    gtk_main_quit();
+    if (gtk_main_level() > 0)
+        gtk_main_quit();
 }
 
 bool wxApp::Initialized()
@@ -554,6 +586,10 @@ bool wxApp::Initialize()
     wxClassInfo::InitializeClasses();
 
     wxSystemSettings::Init();
+    
+#if wxUSE_INTL
+    wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
+#endif
 
     // 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.
@@ -562,11 +598,6 @@ bool wxApp::Initialize()
     wxPendingEventsLocker = new wxCriticalSection();
 #endif
 
-/*
-    wxTheFontNameDirectory =  new wxFontNameDirectory;
-    wxTheFontNameDirectory->Initialize();
-*/
-
     wxTheColourDatabase = new wxColourDatabase( wxKEY_STRING );
     wxTheColourDatabase->Initialize();
 
@@ -574,8 +605,6 @@ bool wxApp::Initialize()
     wxInitializeStockObjects();
 
 #if wxUSE_WX_RESOURCES
-    wxTheResourceCache = new wxResourceCache( wxKEY_STRING );
-
     wxInitializeResourceSystem();
 #endif
 
@@ -590,23 +619,13 @@ void wxApp::CleanUp()
     wxModule::CleanUpModules();
 
 #if wxUSE_WX_RESOURCES
-    wxFlushResources();
-
-    if (wxTheResourceCache)
-        delete wxTheResourceCache;
-    wxTheResourceCache = (wxResourceCache*) NULL;
-
     wxCleanUpResourceSystem();
 #endif
 
     if (wxTheColourDatabase)
         delete wxTheColourDatabase;
-    wxTheColourDatabase = (wxColourDatabase*) NULL;
 
-/*
-    if (wxTheFontNameDirectory) delete wxTheFontNameDirectory;
-    wxTheFontNameDirectory = (wxFontNameDirectory*) NULL;
-*/
+    wxTheColourDatabase = (wxColourDatabase*) NULL;
 
     wxDeleteStockObjects();
 
@@ -630,7 +649,7 @@ void wxApp::CleanUp()
 
     // check for memory leaks
 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
-    if (wxDebugContext::CountObjectsLeft() > 0)
+    if (wxDebugContext::CountObjectsLeft(TRUE) > 0)
     {
         wxLogDebug(wxT("There were memory leaks.\n"));
         wxDebugContext::Dump();
@@ -648,26 +667,120 @@ void wxApp::CleanUp()
 #endif // wxUSE_LOG
 }
 
+//-----------------------------------------------------------------------------
+// Access to the root window global
+//-----------------------------------------------------------------------------
+
+GtkWidget* wxGetRootWindow()
+{
+    if (gs_RootWindow == NULL) {
+        gs_RootWindow = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+        gtk_widget_realize( gs_RootWindow );
+    }
+    return gs_RootWindow;
+}
+
 //-----------------------------------------------------------------------------
 // wxEntry
 //-----------------------------------------------------------------------------
 
-int wxEntry( int argc, char *argv[] )
+
+int wxEntryStart( int argc, char *argv[] )
 {
+#if wxUSE_THREADS
+    /* GTK 1.2 up to version 1.2.3 has broken threads */
+   if ((gtk_major_version == 1) &&
+        (gtk_minor_version == 2) &&
+        (gtk_micro_version < 4))
+    {
+        printf( "wxWindows warning: GUI threading disabled due to outdated GTK version\n" );
+    }
+    else
+    {
+        g_thread_init(NULL);
+    }
+#endif
+
     gtk_set_locale();
 
+    // We should have the wxUSE_WCHAR_T test on the _outside_
 #if wxUSE_WCHAR_T
+#if defined(__WXGTK20__)
+    // gtk+ 2.0 supports Unicode through UTF-8 strings
+    wxConvCurrent = &wxConvUTF8;
+#else
     if (!wxOKlibc()) wxConvCurrent = &wxConvLocal;
+#endif
 #else
     if (!wxOKlibc()) wxConvCurrent = (wxMBConv*) NULL;
 #endif
 
+    gdk_threads_enter();
+
     gtk_init( &argc, &argv );
 
     wxSetDetectableAutoRepeat( TRUE );
 
     if (!wxApp::Initialize())
+    {
+        gdk_threads_leave();
         return -1;
+    }
+
+    return 0;
+}
+
+
+int wxEntryInitGui()
+{
+    int retValue = 0;
+
+    if ( !wxTheApp->OnInitGui() )
+        retValue = -1;
+
+    wxGetRootWindow();
+
+    return retValue;
+}
+
+
+void wxEntryCleanup()
+{
+#if wxUSE_LOG
+    // flush the logged messages if any
+    wxLog *log = wxLog::GetActiveTarget();
+    if (log != NULL && log->HasPendingMessages())
+        log->Flush();
+
+    // continuing to use user defined log target is unsafe from now on because
+    // some resources may be already unavailable, so replace it by something
+    // more safe
+    wxLog *oldlog = wxLog::SetActiveTarget(new wxLogStderr);
+    if ( oldlog )
+        delete oldlog;
+#endif // wxUSE_LOG
+
+    wxApp::CleanUp();
+
+    gdk_threads_leave();
+}
+
+
+
+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
+    int err = wxEntryStart(argc, argv);
+    if (err)
+        return err;
 
     if (!wxTheApp)
     {
@@ -687,9 +800,10 @@ int wxEntry( int argc, char *argv[] )
 #if wxUSE_UNICODE
     wxTheApp->argv = new wxChar*[argc+1];
     int mb_argc = 0;
-    while (mb_argc < argc) {
-      wxTheApp->argv[mb_argc] = wxStrdup(wxConvLibc.cMB2WX(argv[mb_argc]));
-      mb_argc++;
+    while (mb_argc < argc)
+    {
+        wxTheApp->argv[mb_argc] = wxStrdup(wxConvLibc.cMB2WX(argv[mb_argc]));
+        mb_argc++;
     }
     wxTheApp->argv[mb_argc] = (wxChar *)NULL;
 #else
@@ -700,10 +814,8 @@ int wxEntry( int argc, char *argv[] )
     wxStripExtension( name );
     wxTheApp->SetAppName( name );
 
-    int retValue = 0;
-
-    if ( !wxTheApp->OnInitGui() )
-        retValue = -1;
+    int retValue;
+    retValue = wxEntryInitGui();
 
     // Here frames insert themselves automatically into wxTopLevelWindows by
     // getting created in OnInit().
@@ -724,7 +836,7 @@ int wxEntry( int argc, char *argv[] )
 
         if (wxTheApp->Initialized())
         {
-            retValue = wxTheApp->OnRun();
+            wxTheApp->OnRun();
 
             wxWindow *topWindow = wxTheApp->GetTopWindow();
             if (topWindow)
@@ -742,36 +854,24 @@ int wxEntry( int argc, char *argv[] )
                     wxTheApp->SetTopWindow( (wxWindow*) NULL );
                 }
             }
-            wxTheApp->OnExit();
+
+            retValue = wxTheApp->OnExit();
         }
     }
 
-#if wxUSE_LOG
-    // flush the logged messages if any
-    wxLog *log = wxLog::GetActiveTarget();
-    if (log != NULL && log->HasPendingMessages())
-        log->Flush();
-
-    // continuing to use user defined log target is unsafe from now on because
-    // some resources may be already unavailable, so replace it by something
-    // more safe
-    wxLog *oldlog = wxLog::SetActiveTarget(new wxLogStderr);
-    if ( oldlog )
-        delete oldlog;
-#endif // wxUSE_LOG
-
-    wxApp::CleanUp();
+    wxEntryCleanup();
 
     return retValue;
 }
 
+#ifndef __WXUNIVERSAL__
+
 #include "wx/gtk/info.xpm"
 #include "wx/gtk/error.xpm"
 #include "wx/gtk/question.xpm"
 #include "wx/gtk/warning.xpm"
 
-wxIcon
-wxApp::GetStdIcon(int which) const
+wxIcon wxApp::GetStdIcon(int which) const
 {
     switch(which)
     {
@@ -792,3 +892,24 @@ wxApp::GetStdIcon(int which) const
             return wxIcon(error_xpm);
     }
 }
+#else
+wxIcon wxApp::GetStdIcon(int which) const
+{
+    return wxTheme::Get()->GetRenderer()->GetStdIcon(which);
+}
+#endif // !__WXUNIVERSAL__
+
+
+#ifdef __WXDEBUG__
+
+void wxApp::OnAssert(const wxChar *file, int line, const wxChar *msg)
+{
+    m_isInAssert = TRUE;
+
+    wxAppBase::OnAssert(file, line, msg);
+
+    m_isInAssert = FALSE;
+}
+
+#endif // __WXDEBUG__
+