+/* forward declaration */
+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
+//-----------------------------------------------------------------------------
+
+void wxExit()
+{
+ gtk_main_quit();
+}
+
+//-----------------------------------------------------------------------------
+// wxYield
+//-----------------------------------------------------------------------------
+
+bool wxYield()
+{
+ bool has_idle = (wxTheApp->m_idleTag != 0);
+
+ if (has_idle)
+ {
+ /* We need to temporarily remove idle callbacks or the loop will
+ never finish. */
+ gtk_idle_remove( wxTheApp->m_idleTag );
+ wxTheApp->m_idleTag = 0;
+ }
+
+ 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()) { }
+
+ // let the logs be flashed again
+ wxLog::Resume();
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// wxWakeUpIdle
+//-----------------------------------------------------------------------------
+
+void wxWakeUpIdle()
+{
+#if wxUSE_THREADS
+ if (!wxThread::IsMain())
+ wxMutexGuiEnter();
+#endif
+
+ if (g_isIdle)
+ wxapp_install_idle_handler();
+
+#if wxUSE_THREADS
+ if (!wxThread::IsMain())
+ wxMutexGuiLeave();
+#endif
+}