]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/app.cpp
oops, fixed typo breaking iconv constness detection in the previous commit
[wxWidgets.git] / src / gtk / app.cpp
index cc85a29c9f5f9800f196c3734e093a5a279feaae..86a0258e1b51858cb529f629ab03edf4731d9da3 100644 (file)
 #include "wx/module.h"
 #include "wx/image.h"
 
 #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"
 #endif
 
 #include <unistd.h>
 #if wxUSE_THREADS
     #include "wx/thread.h"
 #endif
 
 #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
 
 //-----------------------------------------------------------------------------
 // global data
@@ -58,14 +61,15 @@ static GtkWidget *gs_RootWindow = (GtkWidget*) NULL;
 // local functions
 //-----------------------------------------------------------------------------
 
 // local functions
 //-----------------------------------------------------------------------------
 
-/* forward declaration */
-gint   wxapp_idle_callback( gpointer WXUNUSED(data) );
-gint   wxapp_pending_callback( gpointer WXUNUSED(data) );
-void   wxapp_install_idle_handler();
+extern "C"
+{
+    gint wxapp_idle_callback( gpointer WXUNUSED(data) );
+    gint wxapp_pending_callback( gpointer WXUNUSED(data) );
+}
 
 
-#if wxUSE_THREADS
-gint   wxapp_wakeup_timerout_callback( gpointer WXUNUSED(data) );
-#endif
+void wxapp_install_thread_wakeup();
+void wxapp_uninstall_thread_wakeup();
+void wxapp_install_idle_handler();
 
 //-----------------------------------------------------------------------------
 // wxExit
 
 //-----------------------------------------------------------------------------
 // wxExit
@@ -80,10 +84,21 @@ void wxExit()
 // wxYield
 //-----------------------------------------------------------------------------
 
 // wxYield
 //-----------------------------------------------------------------------------
 
-static bool gs_inYield = FALSE;
-
-bool wxYield()
+bool wxApp::Yield(bool onlyIfNeeded)
 {
 {
+    // MT-FIXME
+    static bool s_inYield = FALSE;
+
+    if ( s_inYield )
+    {
+        if ( !onlyIfNeeded )
+        {
+            wxFAIL_MSG( wxT("wxYield called recursively" ) );
+        }
+
+        return FALSE;
+    }
+
 #if wxUSE_THREADS
     if ( !wxThread::IsMain() )
     {
 #if wxUSE_THREADS
     if ( !wxThread::IsMain() )
     {
@@ -92,19 +107,14 @@ bool wxYield()
     }
 #endif // wxUSE_THREADS
 
     }
 #endif // wxUSE_THREADS
 
-#ifdef __WXDEBUG__
-    if (gs_inYield)
-        wxFAIL_MSG( wxT("wxYield called recursively" ) );
-#endif
-
-    gs_inYield = TRUE;
+    s_inYield = TRUE;
 
     if (!g_isIdle)
     {
         // We need to remove idle callbacks or the loop will
         // never finish.
 
     if (!g_isIdle)
     {
         // We need to remove idle callbacks or the loop will
         // never finish.
-        gtk_idle_remove( wxTheApp->m_idleTag );
-        wxTheApp->m_idleTag = 0;
+        gtk_idle_remove( m_idleTag );
+        m_idleTag = 0;
         g_isIdle = TRUE;
     }
 
         g_isIdle = TRUE;
     }
 
@@ -118,29 +128,18 @@ bool wxYield()
     /* 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) */
     /* 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 ( ProcessIdle() )
+    {
+    }
 
     // let the logs be flashed again
     wxLog::Resume();
 
 
     // let the logs be flashed again
     wxLog::Resume();
 
-    gs_inYield = FALSE;
+    s_inYield = FALSE;
 
     return TRUE;
 }
 
 
     return TRUE;
 }
 
-//-----------------------------------------------------------------------------
-// wxYieldIfNeeded
-// Like wxYield, but fails silently if the yield is recursive.
-//-----------------------------------------------------------------------------
-
-bool wxYieldIfNeeded()
-{
-    if (gs_inYield)
-        return FALSE;
-
-    return wxYield();
-}
-
 //-----------------------------------------------------------------------------
 // wxWakeUpIdle
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // wxWakeUpIdle
 //-----------------------------------------------------------------------------
@@ -165,6 +164,28 @@ void wxWakeUpIdle()
 // local functions
 //-----------------------------------------------------------------------------
 
 // local functions
 //-----------------------------------------------------------------------------
 
+void wxapp_install_idle_handler()
+{
+    wxASSERT_MSG( wxTheApp->m_idleTag == 0, wxT("attempt to install idle handler twice") );
+
+    g_isIdle = FALSE;
+
+    if (g_pendingTag == 0)
+        g_pendingTag = gtk_idle_add_priority( 900, wxapp_pending_callback, (gpointer) NULL );
+
+    /* 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 );
+}
+
+// the callback functions must be extern "C" to comply with GTK+ declarations
+extern "C"
+{
+
 gint wxapp_pending_callback( gpointer WXUNUSED(data) )
 {
     if (!wxTheApp) return TRUE;
 gint wxapp_pending_callback( gpointer WXUNUSED(data) )
 {
     if (!wxTheApp) return TRUE;
@@ -198,12 +219,12 @@ gint wxapp_idle_callback( gpointer WXUNUSED(data) )
         return TRUE;
 
 #ifdef __WXDEBUG__
         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() )
     {
     if ( wxTheApp->IsInAssert() )
     {
-        // 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
-        return FALSE;
+        return TRUE;
     }
 #endif // __WXDEBUG__
 
     }
 #endif // __WXDEBUG__
 
@@ -220,8 +241,9 @@ gint wxapp_idle_callback( gpointer WXUNUSED(data) )
     g_isIdle = TRUE;
     wxTheApp->m_idleTag = 0;
 
     g_isIdle = TRUE;
     wxTheApp->m_idleTag = 0;
 
-    // Sent idle event to all who request them
-    while (wxTheApp->ProcessIdle()) { }
+    // Sent idle event to all who request them as long as they do
+    while (wxTheApp->ProcessIdle())
+        ;
 
     // Release lock again
     gdk_threads_leave();
 
     // Release lock again
     gdk_threads_leave();
@@ -231,24 +253,42 @@ gint wxapp_idle_callback( gpointer WXUNUSED(data) )
     return FALSE;
 }
 
     return FALSE;
 }
 
-void wxapp_install_idle_handler()
+#if wxUSE_THREADS
+
+gint wxapp_wakeup_timerout_callback( gpointer WXUNUSED(data) )
 {
 {
-    wxASSERT_MSG( wxTheApp->m_idleTag == 0, wxT("attempt to install idle handler twice") );
+    // 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();
 
 
-    g_isIdle = FALSE;
+    wxapp_uninstall_thread_wakeup();
 
 
-    if (g_pendingTag == 0)
-        g_pendingTag = gtk_idle_add_priority( 900, wxapp_pending_callback, (gpointer) NULL );
+    // unblock other threads wishing to do some GUI things
+    wxMutexGuiLeave();
 
 
-    /* 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. */
+    g_mainThreadLocked = TRUE;
 
 
-    wxTheApp->m_idleTag = gtk_idle_add_priority( 1000, wxapp_idle_callback, (gpointer) NULL );
+    // wake up other threads
+    wxUsleep( 1 );
+
+    // block other thread again
+    wxMutexGuiEnter();
+
+    g_mainThreadLocked = FALSE;
+
+    wxapp_install_thread_wakeup();
+
+    // release lock again
+    gdk_threads_leave();
+
+    return TRUE;
 }
 
 }
 
+#endif // wxUSE_THREADS
+
+} // extern "C"
+
 #if wxUSE_THREADS
 
 static int g_threadUninstallLevel = 0;
 #if wxUSE_THREADS
 
 static int g_threadUninstallLevel = 0;
@@ -276,38 +316,22 @@ void wxapp_uninstall_thread_wakeup()
     wxTheApp->m_wakeUpTimerTag = 0;
 }
 
     wxTheApp->m_wakeUpTimerTag = 0;
 }
 
-gint wxapp_wakeup_timerout_callback( gpointer WXUNUSED(data) )
-{
-    // 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();
-
-    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();
-
-    g_mainThreadLocked = FALSE;
-
-    wxapp_install_thread_wakeup();
+#endif // wxUSE_THREADS
 
 
-    // release lock again
-    gdk_threads_leave();
+//-----------------------------------------------------------------------------
+// Access to the root window global
+//-----------------------------------------------------------------------------
 
 
-    return TRUE;
+GtkWidget* wxGetRootWindow()
+{
+    if (gs_RootWindow == NULL)
+    {
+        gs_RootWindow = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+        gtk_widget_realize( gs_RootWindow );
+    }
+    return gs_RootWindow;
 }
 
 }
 
-#endif // wxUSE_THREADS
-
 //-----------------------------------------------------------------------------
 // wxApp
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // wxApp
 //-----------------------------------------------------------------------------
@@ -334,6 +358,9 @@ wxApp::wxApp()
 #endif
 
     m_colorCube = (unsigned char*) NULL;
 #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()
 }
 
 wxApp::~wxApp()
@@ -354,12 +381,30 @@ bool wxApp::OnInitGui()
 
     GdkVisual *visual = gdk_visual_get_system();
 
 
     GdkVisual *visual = gdk_visual_get_system();
 
-    /* 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 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.
 
 
-    if ((gdk_visual_get_best() != gdk_visual_get_system()) &&
-        (m_useBestVisual))
+    else
+    if ((gdk_visual_get_best() != gdk_visual_get_system()) && (m_useBestVisual))
     {
 #ifdef __WXGTK20__
         /* seems gtk_widget_set_default_visual no longer exists? */
     {
 #ifdef __WXGTK20__
         /* seems gtk_widget_set_default_visual no longer exists? */
@@ -375,10 +420,10 @@ bool wxApp::OnInitGui()
         visual = vis;
     }
 
         visual = vis;
     }
 
-    /* Nothing to do for 15, 16, 24, 32 bit displays */
+    // Nothing to do for 15, 16, 24, 32 bit displays
     if (visual->depth > 8) return TRUE;
 
     if (visual->depth > 8) return TRUE;
 
-    /* initialize color cube for 8-bit color reduction dithering */
+    // initialize color cube for 8-bit color reduction dithering
 
     GdkColormap *cmap = gtk_widget_get_default_colormap();
 
 
     GdkColormap *cmap = gtk_widget_get_default_colormap();
 
@@ -415,16 +460,11 @@ bool wxApp::OnInitGui()
                 }
                 else
                 {
                 }
                 else
                 {
-#if (GTK_MINOR_VERSION > 0)
-                    /* assume 8-bit true or static colors. this really
-                       exists. */
+                    // assume 8-bit true or static colors. this really exists
                     GdkVisual* vis = gdk_colormap_get_visual( cmap );
                     index = (r >> (5 - vis->red_prec)) << vis->red_shift;
                     index |= (g >> (5 - vis->green_prec)) << vis->green_shift;
                     index |= (b >> (5 - vis->blue_prec)) << vis->blue_shift;
                     GdkVisual* vis = gdk_colormap_get_visual( cmap );
                     index = (r >> (5 - vis->red_prec)) << vis->red_shift;
                     index |= (g >> (5 - vis->green_prec)) << vis->green_shift;
                     index |= (b >> (5 - vis->blue_prec)) << vis->blue_shift;
-#else
-                    wxFAIL_MSG( wxT("Unsupported graphics hardware") );
-#endif
                 }
                 m_colorCube[ (r*1024) + (g*32) + b ] = index;
             }
                 }
                 m_colorCube[ (r*1024) + (g*32) + b ] = index;
             }
@@ -434,6 +474,20 @@ bool wxApp::OnInitGui()
     return TRUE;
 }
 
     return TRUE;
 }
 
+GdkVisual *wxApp::GetGdkVisual()
+{
+    GdkVisual *visual = NULL;
+    
+    if (m_glVisualInfo)
+        visual = gdkx_visual_get( ((XVisualInfo *) m_glVisualInfo)->visualid );
+    else
+        visual = gdk_window_get_visual( wxGetRootWindow()->window );
+        
+    wxASSERT( visual );
+    
+    return visual;
+}
+
 bool wxApp::ProcessIdle()
 {
     wxIdleEvent event;
 bool wxApp::ProcessIdle()
 {
     wxIdleEvent event;
@@ -560,8 +614,6 @@ bool wxApp::Initialize()
 
     wxClassInfo::InitializeClasses();
 
 
     wxClassInfo::InitializeClasses();
 
-    wxSystemSettings::Init();
-    
 #if wxUSE_INTL
     wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
 #endif
 #if wxUSE_INTL
     wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
 #endif
@@ -616,8 +668,6 @@ void wxApp::CleanUp()
     delete wxPendingEventsLocker;
 #endif
 
     delete wxPendingEventsLocker;
 #endif
 
-    wxSystemSettings::Done();
-
     delete[] wxBuffer;
 
     wxClassInfo::CleanUpClasses();
     delete[] wxBuffer;
 
     wxClassInfo::CleanUpClasses();
@@ -642,29 +692,16 @@ void wxApp::CleanUp()
 #endif // wxUSE_LOG
 }
 
 #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
 //-----------------------------------------------------------------------------
 
 //-----------------------------------------------------------------------------
 // wxEntry
 //-----------------------------------------------------------------------------
 
-
-int wxEntryStart( int argc, char *argv[] )
+// NB: argc and argv may be changed here, pass by reference!
+int wxEntryStart( int& argc, char *argv[] )
 {
 #if wxUSE_THREADS
 {
 #if wxUSE_THREADS
-    /* GTK 1.2 up to version 1.2.3 has broken threads */
-   if ((gtk_major_version == 1) &&
+    // 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))
     {
         (gtk_minor_version == 2) &&
         (gtk_micro_version < 4))
     {
@@ -741,7 +778,6 @@ void wxEntryCleanup()
 }
 
 
 }
 
 
-
 int wxEntry( int argc, char *argv[] )
 {
 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
 int wxEntry( int argc, char *argv[] )
 {
 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
@@ -839,13 +875,19 @@ int wxEntry( int argc, char *argv[] )
     return retValue;
 }
 
     return retValue;
 }
 
+#ifndef __WXUNIVERSAL__
+
+// XPM hack: make the arrays const
+#define static static const
+
 #include "wx/gtk/info.xpm"
 #include "wx/gtk/error.xpm"
 #include "wx/gtk/question.xpm"
 #include "wx/gtk/warning.xpm"
 
 #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
+#undef static
+
+wxIcon wxApp::GetStdIcon(int which) const
 {
     switch(which)
     {
 {
     switch(which)
     {
@@ -866,6 +908,13 @@ wxApp::GetStdIcon(int which) const
             return wxIcon(error_xpm);
     }
 }
             return wxIcon(error_xpm);
     }
 }
+#else
+wxIcon wxApp::GetStdIcon(int which) const
+{
+    return wxTheme::Get()->GetRenderer()->GetStdIcon(which);
+}
+#endif // !__WXUNIVERSAL__
+
 
 #ifdef __WXDEBUG__
 
 
 #ifdef __WXDEBUG__