#include "wx/image.h"
#if wxUSE_THREADS
-#include "wx/thread.h"
+ #include "wx/thread.h"
#endif
#include <unistd.h>
extern bool g_isIdle;
+bool g_mainThreadLocked = FALSE;
+
+GtkWidget *wxRootWindow = (GtkWidget*) NULL;
+
//-----------------------------------------------------------------------------
// local functions
//-----------------------------------------------------------------------------
while (gtk_events_pending())
gtk_main_iteration();
+ if (has_idle)
+ {
+ /* re-add idle handler (very low priority) */
+ wxTheApp->m_idleTag = gtk_idle_add_priority( 1000, wxapp_idle_callback, (gpointer) NULL );
+ }
+
+ // disable log flushing from here because a call to wxYield() shouldn't
+ // normally result in message boxes popping up &c
+ wxLog::Suspend();
+
/* it's necessary to call ProcessIdle() to update the frames sizes which
might have been changed (it also will update other things set from
OnUpdateUI() which is a nice (and desired) side effect) */
- while (wxTheApp->ProcessIdle()) { }
+ 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();
return TRUE;
}
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
}
//-----------------------------------------------------------------------------
{
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
-
- /* sent idle event to all who request them */
- while (wxTheApp->ProcessIdle()) { }
+ // 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();
/* we don't want any more idle events until the next event is
sent to wxGTK */
emptied */
g_isIdle = TRUE;
-#if (GTK_MINOR_VERSION > 0)
- /* release lock again */
- GDK_THREADS_LEAVE ();
-#endif
+ /* sent idle event to all who request them */
+ while (wxTheApp->ProcessIdle()) { }
+
+ // release lock again
+ gdk_threads_leave();
return TRUE;
}
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). */
+ idle time). Very low priority. */
-#if wxUSE_THREADS
- if (!wxThread::IsMain())
- GDK_THREADS_ENTER ();
-#endif
-
- wxTheApp->m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL );
+ wxTheApp->m_idleTag = gtk_idle_add_priority( 1000, wxapp_idle_callback, (gpointer) NULL );
g_isIdle = FALSE;
-
-#if wxUSE_THREADS
- if (!wxThread::IsMain())
- GDK_THREADS_LEAVE ();
-#endif
}
#if wxUSE_THREADS
{
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()
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;
}
m_topWindow = (wxWindow *) NULL;
m_exitOnFrameDelete = TRUE;
- m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL );
+ m_idleTag = gtk_idle_add_priority( 1000, wxapp_idle_callback, (gpointer) NULL );
#if wxUSE_THREADS
m_wakeUpTimerTag = 0;
#endif
m_colorCube = (unsigned char*) NULL;
+
+ m_useBestVisual = FALSE;
}
wxApp::~wxApp()
/* 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())
+
+ 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;
/* '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();
event.RequestMore(TRUE);
s_inOnIdle = FALSE;
+
+ /* flush the logged messages if any */
+#if wxUSE_LOG
+ wxLog::FlushActive();
+#endif // wxUSE_LOG
}
bool wxApp::SendIdleEvents()
wxIdleEvent event;
event.SetEventObject(win);
- win->ProcessEvent(event);
+ win->GetEventHandler()->ProcessEvent(event);
win->OnInternalIdle();
wxPendingEventsLocker = new wxCriticalSection();
#endif
-/*
- wxTheFontNameDirectory = new wxFontNameDirectory;
- wxTheFontNameDirectory->Initialize();
-*/
-
wxTheColourDatabase = new wxColourDatabase( wxKEY_STRING );
wxTheColourDatabase->Initialize();
wxInitializeStockLists();
wxInitializeStockObjects();
+#if wxUSE_WX_RESOURCES
+ wxInitializeResourceSystem();
+#endif
+
wxModule::RegisterModules();
if (!wxModule::InitializeModules()) return FALSE;
{
wxModule::CleanUpModules();
+#if wxUSE_WX_RESOURCES
+ wxCleanUpResourceSystem();
+#endif
+
if (wxTheColourDatabase)
delete wxTheColourDatabase;
- wxTheColourDatabase = (wxColourDatabase*) NULL;
-/*
- if (wxTheFontNameDirectory) delete wxTheFontNameDirectory;
- wxTheFontNameDirectory = (wxFontNameDirectory*) NULL;
-*/
+ wxTheColourDatabase = (wxColourDatabase*) NULL;
wxDeleteStockObjects();
// 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 */
+#ifdef __VMS__
+ if ((vms_gtk_major_version() == 1) &&
+ (vms_gtk_minor_version() == 2) &&
+ (vms_gtk_micro_version() < 4))
+#else
+ if ((gtk_major_version == 1) &&
+ (gtk_minor_version == 2) &&
+ (gtk_micro_version < 4))
+#endif
+ {
+ printf( "wxWindows warning: GUI threading disabled due to outdated GTK version\n" );
+ }
+ else
+ {
+ g_thread_init(NULL);
+ }
+#endif
+
gtk_set_locale();
-#if wxUSE_WCHAR_T
+#if defined(__WXGTK20__)
+ // gtk+ 2.0 supports Unicode through UTF-8 strings
+ wxConvCurrent = &wxConvUTF8;
+#elif wxUSE_WCHAR_T
if (!wxOKlibc()) wxConvCurrent = &wxConvLocal;
#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;
+
+ wxRootWindow = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+ gtk_widget_realize( wxRootWindow );
+
+ 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[] )
+{
+ int err = wxEntryStart(argc, argv);
+ if (err)
+ return err;
if (!wxTheApp)
{
#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
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().
if (wxTheApp->Initialized())
{
- retValue = wxTheApp->OnRun();
+ wxTheApp->OnRun();
wxWindow *topWindow = wxTheApp->GetTopWindow();
if (topWindow)
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;
}