]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/clipbrd.cpp
[ 1508778 ] Fix for wxOwnerDrawnComboBox list selection rendering.
[wxWidgets.git] / src / gtk / clipbrd.cpp
index c6edc527b1d980eff1b786ecec9ab9c15fb36e7a..92cc30b09076bb2cfd487c0d5aefa0676f48160c 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        gtk/clipbrd.cpp
+// Name:        src/gtk/clipbrd.cpp
 // Purpose:
 // Author:      Robert Roebling
 // Id:          $Id$
 // Purpose:
 // Author:      Robert Roebling
 // Id:          $Id$
@@ -7,28 +7,21 @@
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "clipbrd.h"
-#endif
-
-#include "wx/clipbrd.h"
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
 
 #if wxUSE_CLIPBOARD
 
 
 #if wxUSE_CLIPBOARD
 
-#include "wx/dataobj.h"
-#include "wx/utils.h"
-#include "wx/log.h"
+#include "wx/clipbrd.h"
 
 
-#include <glib.h>
-#include <gdk/gdk.h>
-#include <gtk/gtk.h>
+#ifndef WX_PRECOMP
+    #include "wx/log.h"
+    #include "wx/utils.h"
+#endif
 
 
-//-----------------------------------------------------------------------------
-// thread system
-//-----------------------------------------------------------------------------
+#include "wx/dataobj.h"
 
 
-#if wxUSE_THREADS
-#endif
+#include "wx/gtk/private.h"
 
 //-----------------------------------------------------------------------------
 // data
 
 //-----------------------------------------------------------------------------
 // data
 
 GdkAtom  g_clipboardAtom   = 0;
 GdkAtom  g_targetsAtom     = 0;
 
 GdkAtom  g_clipboardAtom   = 0;
 GdkAtom  g_targetsAtom     = 0;
+GdkAtom  g_timestampAtom   = 0;
+
+#if wxUSE_UNICODE
+extern GdkAtom g_altTextAtom;
+#endif
 
 // the trace mask we use with wxLogTrace() - call
 // wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here
 
 // the trace mask we use with wxLogTrace() - call
 // wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here
@@ -71,26 +69,25 @@ struct _GtkSelectionData
 // "selection_received" for targets
 //-----------------------------------------------------------------------------
 
 // "selection_received" for targets
 //-----------------------------------------------------------------------------
 
+extern "C" {
 static void
 targets_selection_received( GtkWidget *WXUNUSED(widget),
                             GtkSelectionData *selection_data,
 static void
 targets_selection_received( GtkWidget *WXUNUSED(widget),
                             GtkSelectionData *selection_data,
-#if (GTK_MINOR_VERSION > 0)
                             guint32 WXUNUSED(time),
                             guint32 WXUNUSED(time),
-#endif
                             wxClipboard *clipboard )
 {
     if ( wxTheClipboard && selection_data->length > 0 )
     {
                             wxClipboard *clipboard )
 {
     if ( wxTheClipboard && selection_data->length > 0 )
     {
-        /* make sure we got the data in the correct form */
+        // make sure we got the data in the correct form
         GdkAtom type = selection_data->type;
         if ( type != GDK_SELECTION_TYPE_ATOM )
         {
         GdkAtom type = selection_data->type;
         if ( type != GDK_SELECTION_TYPE_ATOM )
         {
-            if ( strcmp(gdk_atom_name(type), "TARGETS") )
+            if ( strcmp(wxGtkString(gdk_atom_name(type)), "TARGETS") )
             {
                 wxLogTrace( TRACE_CLIPBOARD,
                             _T("got unsupported clipboard target") );
 
             {
                 wxLogTrace( TRACE_CLIPBOARD,
                             _T("got unsupported clipboard target") );
 
-                clipboard->m_waiting = FALSE;
+                clipboard->m_waiting = false;
                 return;
             }
         }
                 return;
             }
         }
@@ -113,33 +110,37 @@ targets_selection_received( GtkWidget *WXUNUSED(widget),
                         wxT("selection received for targets, format %s"),
                         format.GetId().c_str() );
 
                         wxT("selection received for targets, format %s"),
                         format.GetId().c_str() );
 
+//            printf( "format %s requested %s\n",
+//                    gdk_atom_name( atoms[i] ),
+//                    gdk_atom_name( clipboard->m_targetRequested ) );
+
             if (format == clipboard->m_targetRequested)
             {
             if (format == clipboard->m_targetRequested)
             {
-                clipboard->m_waiting = FALSE;
-                clipboard->m_formatSupported = TRUE;
+                clipboard->m_waiting = false;
+                clipboard->m_formatSupported = true;
                 return;
             }
         }
     }
 
                 return;
             }
         }
     }
 
-    clipboard->m_waiting = FALSE;
+    clipboard->m_waiting = false;
+}
 }
 
 //-----------------------------------------------------------------------------
 // "selection_received" for the actual data
 //-----------------------------------------------------------------------------
 
 }
 
 //-----------------------------------------------------------------------------
 // "selection_received" for the actual data
 //-----------------------------------------------------------------------------
 
+extern "C" {
 static void
 selection_received( GtkWidget *WXUNUSED(widget),
                     GtkSelectionData *selection_data,
 static void
 selection_received( GtkWidget *WXUNUSED(widget),
                     GtkSelectionData *selection_data,
-#if (GTK_MINOR_VERSION > 0)
                     guint32 WXUNUSED(time),
                     guint32 WXUNUSED(time),
-#endif
                     wxClipboard *clipboard )
 {
     if (!wxTheClipboard)
     {
                     wxClipboard *clipboard )
 {
     if (!wxTheClipboard)
     {
-        clipboard->m_waiting = FALSE;
+        clipboard->m_waiting = false;
         return;
     }
 
         return;
     }
 
@@ -147,60 +148,65 @@ selection_received( GtkWidget *WXUNUSED(widget),
 
     if (!data_object)
     {
 
     if (!data_object)
     {
-        clipboard->m_waiting = FALSE;
+        clipboard->m_waiting = false;
         return;
     }
 
     if (selection_data->length <= 0)
     {
         return;
     }
 
     if (selection_data->length <= 0)
     {
-        clipboard->m_waiting = FALSE;
+        clipboard->m_waiting = false;
         return;
     }
 
     wxDataFormat format( selection_data->target );
 
         return;
     }
 
     wxDataFormat format( selection_data->target );
 
-    /* make sure we got the data in the correct format */
+    // make sure we got the data in the correct format
     if (!data_object->IsSupportedFormat( format ) )
     {
     if (!data_object->IsSupportedFormat( format ) )
     {
-        clipboard->m_waiting = FALSE;
+        clipboard->m_waiting = false;
         return;
     }
 
         return;
     }
 
-    /* make sure we got the data in the correct form (selection type).
-       if so, copy data to target object */
+#if 0
+    This seems to cause problems somehow
+    // make sure we got the data in the correct form (selection type).
+    // if so, copy data to target object
     if (selection_data->type != GDK_SELECTION_TYPE_STRING)
     {
     if (selection_data->type != GDK_SELECTION_TYPE_STRING)
     {
-        clipboard->m_waiting = FALSE;
+        clipboard->m_waiting = false;
         return;
     }
         return;
     }
+#endif
 
     data_object->SetData( format, (size_t) selection_data->length, (const char*) selection_data->data );
 
 
     data_object->SetData( format, (size_t) selection_data->length, (const char*) selection_data->data );
 
-    wxTheClipboard->m_formatSupported = TRUE;
-    clipboard->m_waiting = FALSE;
+    wxTheClipboard->m_formatSupported = true;
+    clipboard->m_waiting = false;
+}
 }
 
 //-----------------------------------------------------------------------------
 // "selection_clear"
 //-----------------------------------------------------------------------------
 
 }
 
 //-----------------------------------------------------------------------------
 // "selection_clear"
 //-----------------------------------------------------------------------------
 
+extern "C" {
 static gint
 selection_clear_clip( GtkWidget *WXUNUSED(widget), GdkEventSelection *event )
 {
 static gint
 selection_clear_clip( GtkWidget *WXUNUSED(widget), GdkEventSelection *event )
 {
-    if (!wxTheClipboard) return TRUE;
+    if (!wxTheClipboard) return true;
 
     if (event->selection == GDK_SELECTION_PRIMARY)
     {
 
     if (event->selection == GDK_SELECTION_PRIMARY)
     {
-        wxTheClipboard->m_ownsPrimarySelection = FALSE;
+        wxTheClipboard->m_ownsPrimarySelection = false;
     }
     else
     if (event->selection == g_clipboardAtom)
     {
     }
     else
     if (event->selection == g_clipboardAtom)
     {
-        wxTheClipboard->m_ownsClipboard = FALSE;
+        wxTheClipboard->m_ownsClipboard = false;
     }
     else
     {
     }
     else
     {
-        wxTheClipboard->m_waiting = FALSE;
+        wxTheClipboard->m_waiting = false;
         return FALSE;
     }
 
         return FALSE;
     }
 
@@ -217,20 +223,22 @@ selection_clear_clip( GtkWidget *WXUNUSED(widget), GdkEventSelection *event )
         }
     }
 
         }
     }
 
-    wxTheClipboard->m_waiting = FALSE;
+    wxTheClipboard->m_waiting = false;
     return TRUE;
 }
     return TRUE;
 }
+}
 
 //-----------------------------------------------------------------------------
 // selection handler for supplying data
 //-----------------------------------------------------------------------------
 
 
 //-----------------------------------------------------------------------------
 // selection handler for supplying data
 //-----------------------------------------------------------------------------
 
+extern "C" {
 static void
 selection_handler( GtkWidget *WXUNUSED(widget),
                    GtkSelectionData *selection_data,
                    guint WXUNUSED(info),
                    guint WXUNUSED(time),
 static void
 selection_handler( GtkWidget *WXUNUSED(widget),
                    GtkSelectionData *selection_data,
                    guint WXUNUSED(info),
                    guint WXUNUSED(time),
-                   gpointer WXUNUSED(data) )
+                   gpointer signal_data )
 {
     if (!wxTheClipboard) return;
 
 {
     if (!wxTheClipboard) return;
 
@@ -238,8 +246,37 @@ selection_handler( GtkWidget *WXUNUSED(widget),
 
     wxDataObject *data = wxTheClipboard->m_data;
 
 
     wxDataObject *data = wxTheClipboard->m_data;
 
+    // ICCCM says that TIMESTAMP is a required atom.
+    // In particular, it satisfies Klipper, which polls
+    // TIMESTAMP to see if the clipboards content has changed.
+    // It shall return the time which was used to set the data.
+    if (selection_data->target == g_timestampAtom)
+    {
+        guint timestamp = GPOINTER_TO_UINT (signal_data);
+        gtk_selection_data_set(selection_data,
+                               GDK_SELECTION_TYPE_INTEGER,
+                               32,
+                               (guchar*)&(timestamp),
+                               sizeof(timestamp));
+        wxLogTrace(TRACE_CLIPBOARD,
+                   _T("Clipboard TIMESTAMP requested, returning timestamp=%u"),
+                   timestamp);
+        return;
+    }
+
     wxDataFormat format( selection_data->target );
 
     wxDataFormat format( selection_data->target );
 
+#ifdef __WXDEBUG__
+    wxLogTrace(TRACE_CLIPBOARD,
+               _T("clipboard data in format %s, GtkSelectionData is target=%s type=%s selection=%s timestamp=%u"),
+               format.GetId().c_str(),
+               wxString::FromAscii(wxGtkString(gdk_atom_name(selection_data->target))).c_str(),
+               wxString::FromAscii(wxGtkString(gdk_atom_name(selection_data->type))).c_str(),
+               wxString::FromAscii(wxGtkString(gdk_atom_name(selection_data->selection))).c_str(),
+               GPOINTER_TO_UINT( signal_data )
+               );
+#endif
+
     if (!data->IsSupportedFormat( format )) return;
 
     int size = data->GetDataSize( format );
     if (!data->IsSupportedFormat( format )) return;
 
     int size = data->GetDataSize( format );
@@ -248,32 +285,32 @@ selection_handler( GtkWidget *WXUNUSED(widget),
 
     void *d = malloc(size);
 
 
     void *d = malloc(size);
 
+    // Text data will be in UTF8 in Unicode mode.
     data->GetDataHere( selection_data->target, d );
 
     data->GetDataHere( selection_data->target, d );
 
-    // transform Unicode text into multibyte before putting it on clipboard
-#if wxUSE_UNICODE
-    if ( format.GetType() == wxDF_TEXT )
+    // NB: GTK+ requires special treatment of UTF8_STRING data, the text
+    //     would show as UTF-8 data interpreted as latin1 (?) in other
+    //     GTK+ apps if we used gtk_selection_data_set()
+    if (format == wxDataFormat(wxDF_UNICODETEXT))
     {
     {
-        const wchar_t *wstr = (const wchar_t *)d;
-        size_t len = wxConvCurrent->WC2MB(NULL, wstr, 0);
-        char *str = malloc(len + 1);
-        wxConvCurrent->WC2MB(str, wstr, len);
-        str[len] = '\0';
-
-        free(d);
-        d = str;
+        gtk_selection_data_set_text(
+            selection_data,
+            (const gchar*)d,
+            size );
+    }
+    else
+    {
+        gtk_selection_data_set(
+            selection_data,
+            GDK_SELECTION_TYPE_STRING,
+            8*sizeof(gchar),
+            (unsigned char*) d,
+            size );
     }
     }
-#endif // wxUSE_UNICODE
-
-    gtk_selection_data_set(
-        selection_data,
-        GDK_SELECTION_TYPE_STRING,
-        8*sizeof(gchar),
-        (unsigned char*) d,
-        size );
 
     free(d);
 }
 
     free(d);
 }
+}
 
 //-----------------------------------------------------------------------------
 // wxClipboard
 
 //-----------------------------------------------------------------------------
 // wxClipboard
@@ -283,10 +320,11 @@ IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
 
 wxClipboard::wxClipboard()
 {
 
 wxClipboard::wxClipboard()
 {
-    m_open = FALSE;
+    m_open = false;
+    m_waiting = false;
 
 
-    m_ownsClipboard = FALSE;
-    m_ownsPrimarySelection = FALSE;
+    m_ownsClipboard = false;
+    m_ownsPrimarySelection = false;
 
     m_data = (wxDataObject*) NULL;
     m_receivedData = (wxDataObject*) NULL;
 
     m_data = (wxDataObject*) NULL;
     m_receivedData = (wxDataObject*) NULL;
@@ -296,33 +334,28 @@ wxClipboard::wxClipboard()
     m_targetsWidget = gtk_window_new( GTK_WINDOW_POPUP );
     gtk_widget_realize( m_targetsWidget );
 
     m_targetsWidget = gtk_window_new( GTK_WINDOW_POPUP );
     gtk_widget_realize( m_targetsWidget );
 
-    gtk_signal_connect( GTK_OBJECT(m_targetsWidget),
-                        "selection_received",
-                        GTK_SIGNAL_FUNC( targets_selection_received ),
-                        (gpointer) this );
+    g_signal_connect (m_targetsWidget, "selection_received",
+                      G_CALLBACK (targets_selection_received), this);
 
     /* we use m_clipboardWidget to get and to offer data */
 
     m_clipboardWidget = gtk_window_new( GTK_WINDOW_POPUP );
     gtk_widget_realize( m_clipboardWidget );
 
 
     /* we use m_clipboardWidget to get and to offer data */
 
     m_clipboardWidget = gtk_window_new( GTK_WINDOW_POPUP );
     gtk_widget_realize( m_clipboardWidget );
 
-    gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
-                        "selection_received",
-                        GTK_SIGNAL_FUNC( selection_received ),
-                        (gpointer) this );
+    g_signal_connect (m_clipboardWidget, "selection_received",
+                      G_CALLBACK (selection_received), this);
 
 
-    gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
-                        "selection_clear_event",
-                        GTK_SIGNAL_FUNC( selection_clear_clip ),
-                        (gpointer) NULL );
+    g_signal_connect (m_clipboardWidget, "selection_clear_event",
+                      G_CALLBACK (selection_clear_clip), NULL);
 
     if (!g_clipboardAtom) g_clipboardAtom = gdk_atom_intern( "CLIPBOARD", FALSE );
     if (!g_targetsAtom) g_targetsAtom = gdk_atom_intern ("TARGETS", FALSE);
 
     if (!g_clipboardAtom) g_clipboardAtom = gdk_atom_intern( "CLIPBOARD", FALSE );
     if (!g_targetsAtom) g_targetsAtom = gdk_atom_intern ("TARGETS", FALSE);
+    if (!g_timestampAtom) g_timestampAtom = gdk_atom_intern ("TIMESTAMP", FALSE);
 
 
-    m_formatSupported = FALSE;
+    m_formatSupported = false;
     m_targetRequested = 0;
 
     m_targetRequested = 0;
 
-    m_usePrimary = FALSE;
+    m_usePrimary = false;
 }
 
 wxClipboard::~wxClipboard()
 }
 
 wxClipboard::~wxClipboard()
@@ -341,11 +374,11 @@ void wxClipboard::Clear()
         /* disable GUI threads */
 #endif
 
         /* disable GUI threads */
 #endif
 
-        /*  As we have data we also own the clipboard. Once we no longer own
-            it, clear_selection is called which will set m_data to zero */
+        //  As we have data we also own the clipboard. Once we no longer own
+        //  it, clear_selection is called which will set m_data to zero
         if (gdk_selection_owner_get( g_clipboardAtom ) == m_clipboardWidget->window)
         {
         if (gdk_selection_owner_get( g_clipboardAtom ) == m_clipboardWidget->window)
         {
-            m_waiting = TRUE;
+            m_waiting = true;
 
             gtk_selection_owner_set( (GtkWidget*) NULL, g_clipboardAtom,
                                      (guint32) GDK_CURRENT_TIME );
 
             gtk_selection_owner_set( (GtkWidget*) NULL, g_clipboardAtom,
                                      (guint32) GDK_CURRENT_TIME );
@@ -355,7 +388,7 @@ void wxClipboard::Clear()
 
         if (gdk_selection_owner_get( GDK_SELECTION_PRIMARY ) == m_clipboardWidget->window)
         {
 
         if (gdk_selection_owner_get( GDK_SELECTION_PRIMARY ) == m_clipboardWidget->window)
         {
-            m_waiting = TRUE;
+            m_waiting = true;
 
             gtk_selection_owner_set( (GtkWidget*) NULL, GDK_SELECTION_PRIMARY,
                                      (guint32) GDK_CURRENT_TIME );
 
             gtk_selection_owner_set( (GtkWidget*) NULL, GDK_SELECTION_PRIMARY,
                                      (guint32) GDK_CURRENT_TIME );
@@ -375,23 +408,23 @@ void wxClipboard::Clear()
     }
 
     m_targetRequested = 0;
     }
 
     m_targetRequested = 0;
-    m_formatSupported = FALSE;
+    m_formatSupported = false;
 }
 
 bool wxClipboard::Open()
 {
 }
 
 bool wxClipboard::Open()
 {
-    wxCHECK_MSG( !m_open, FALSE, wxT("clipboard already open") );
+    wxCHECK_MSG( !m_open, false, wxT("clipboard already open") );
 
 
-    m_open = TRUE;
+    m_open = true;
 
 
-    return TRUE;
+    return true;
 }
 
 bool wxClipboard::SetData( wxDataObject *data )
 {
 }
 
 bool wxClipboard::SetData( wxDataObject *data )
 {
-    wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
+    wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
 
 
-    wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
+    wxCHECK_MSG( data, false, wxT("data is invalid") );
 
     Clear();
 
 
     Clear();
 
@@ -400,23 +433,28 @@ bool wxClipboard::SetData( wxDataObject *data )
 
 bool wxClipboard::AddData( wxDataObject *data )
 {
 
 bool wxClipboard::AddData( wxDataObject *data )
 {
-    wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
+    wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
 
 
-    wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
+    wxCHECK_MSG( data, false, wxT("data is invalid") );
 
 
-    /* we can only store one wxDataObject */
+    // we can only store one wxDataObject
     Clear();
 
     m_data = data;
 
     Clear();
 
     m_data = data;
 
-    /* get formats from wxDataObjects */
+    // get formats from wxDataObjects
     wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ];
     m_data->GetAllFormats( array );
 
     wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ];
     m_data->GetAllFormats( array );
 
-    /* primary selection or clipboard */
+    // primary selection or clipboard
     GdkAtom clipboard = m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
                                      : g_clipboardAtom;
 
     GdkAtom clipboard = m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
                                      : g_clipboardAtom;
 
+    // by default provide TIMESTAMP as a target
+    gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget),
+                              clipboard,
+                              g_timestampAtom,
+                              0 );
 
     for (size_t i = 0; i < m_data->GetFormatCount(); i++)
     {
 
     for (size_t i = 0; i < m_data->GetFormatCount(); i++)
     {
@@ -424,6 +462,9 @@ bool wxClipboard::AddData( wxDataObject *data )
                     wxT("wxClipboard now supports atom %s"),
                     array[i].GetId().c_str() );
 
                     wxT("wxClipboard now supports atom %s"),
                     array[i].GetId().c_str() );
 
+//        printf( "added %s\n",
+//                    gdk_atom_name( array[i].GetFormatId() ) );
+
         gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget),
                                   clipboard,
                                   array[i],
         gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget),
                                   clipboard,
                                   array[i],
@@ -432,10 +473,9 @@ bool wxClipboard::AddData( wxDataObject *data )
 
     delete[] array;
 
 
     delete[] array;
 
-    gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
-                        "selection_get",
-                        GTK_SIGNAL_FUNC(selection_handler),
-                        (gpointer) NULL );
+    g_signal_connect (m_clipboardWidget, "selection_get",
+                      G_CALLBACK (selection_handler),
+                      GUINT_TO_POINTER (gtk_get_current_event_time()) );
 
 #if wxUSE_THREADS
     /* disable GUI threads */
 
 #if wxUSE_THREADS
     /* disable GUI threads */
@@ -462,7 +502,7 @@ void wxClipboard::Close()
 {
     wxCHECK_RET( m_open, wxT("clipboard not open") );
 
 {
     wxCHECK_RET( m_open, wxT("clipboard not open") );
 
-    m_open = FALSE;
+    m_open = false;
 }
 
 bool wxClipboard::IsOpened() const
 }
 
 bool wxClipboard::IsOpened() const
@@ -473,30 +513,28 @@ bool wxClipboard::IsOpened() const
 bool wxClipboard::IsSupported( const wxDataFormat& format )
 {
     /* reentrance problems */
 bool wxClipboard::IsSupported( const wxDataFormat& format )
 {
     /* reentrance problems */
-    if (m_waiting) return FALSE;
+    if (m_waiting) return false;
 
     /* store requested format to be asked for by callbacks */
     m_targetRequested = format;
 
 
     /* store requested format to be asked for by callbacks */
     m_targetRequested = format;
 
-#if 0
     wxLogTrace( TRACE_CLIPBOARD,
                 wxT("wxClipboard:IsSupported: requested format: %s"),
                 format.GetId().c_str() );
     wxLogTrace( TRACE_CLIPBOARD,
                 wxT("wxClipboard:IsSupported: requested format: %s"),
                 format.GetId().c_str() );
-#endif
 
 
-    wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
+    wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") );
 
 
-    m_formatSupported = FALSE;
+    m_formatSupported = false;
 
     /* perform query. this will set m_formatSupported to
 
     /* perform query. this will set m_formatSupported to
-       TRUE if m_targetRequested is supported.
+       true if m_targetRequested is supported.
        also, we have to wait for the "answer" from the
        clipboard owner which is an asynchronous process.
        also, we have to wait for the "answer" from the
        clipboard owner which is an asynchronous process.
-       therefore we set m_waiting = TRUE here and wait
+       therefore we set m_waiting = true here and wait
        until the callback "targets_selection_received"
        until the callback "targets_selection_received"
-       sets it to FALSE */
+       sets it to false */
 
 
-    m_waiting = TRUE;
+    m_waiting = true;
 
     gtk_selection_convert( m_targetsWidget,
                            m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
 
     gtk_selection_convert( m_targetsWidget,
                            m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
@@ -506,14 +544,21 @@ bool wxClipboard::IsSupported( const wxDataFormat& format )
 
     while (m_waiting) gtk_main_iteration();
 
 
     while (m_waiting) gtk_main_iteration();
 
-    if (!m_formatSupported) return FALSE;
+#if wxUSE_UNICODE
+    if (!m_formatSupported && format == wxDataFormat(wxDF_UNICODETEXT))
+    {
+        // Another try with plain STRING format
+        extern GdkAtom g_altTextAtom;
+        return IsSupported(g_altTextAtom);
+    }
+#endif
 
 
-    return TRUE;
+    return m_formatSupported;
 }
 
 bool wxClipboard::GetData( wxDataObject& data )
 {
 }
 
 bool wxClipboard::GetData( wxDataObject& data )
 {
-    wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
+    wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
 
     /* get formats from wxDataObjects */
     wxDataFormat *array = new wxDataFormat[ data.GetFormatCount() ];
 
     /* get formats from wxDataObjects */
     wxDataFormat *array = new wxDataFormat[ data.GetFormatCount() ];
@@ -532,19 +577,19 @@ bool wxClipboard::GetData( wxDataObject& data )
         /* store requested format to be asked for by callbacks */
         m_targetRequested = format;
 
         /* store requested format to be asked for by callbacks */
         m_targetRequested = format;
 
-        wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
+        wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") );
 
 
-        m_formatSupported = FALSE;
+        m_formatSupported = false;
 
        /* perform query. this will set m_formatSupported to
 
        /* perform query. this will set m_formatSupported to
-          TRUE if m_targetRequested is supported.
+          true if m_targetRequested is supported.
           also, we have to wait for the "answer" from the
           clipboard owner which is an asynchronous process.
           also, we have to wait for the "answer" from the
           clipboard owner which is an asynchronous process.
-          therefore we set m_waiting = TRUE here and wait
+          therefore we set m_waiting = true here and wait
           until the callback "targets_selection_received"
           until the callback "targets_selection_received"
-          sets it to FALSE */
+          sets it to false */
 
 
-        m_waiting = TRUE;
+        m_waiting = true;
 
         gtk_selection_convert( m_targetsWidget,
                            m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
 
         gtk_selection_convert( m_targetsWidget,
                            m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
@@ -562,21 +607,21 @@ bool wxClipboard::GetData( wxDataObject& data )
         /* store requested format to be asked for by callbacks */
         m_targetRequested = format;
 
         /* store requested format to be asked for by callbacks */
         m_targetRequested = format;
 
-        wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
+        wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") );
 
         /* start query */
 
         /* start query */
-        m_formatSupported = FALSE;
+        m_formatSupported = false;
 
         /* ask for clipboard contents.  this will set
 
         /* ask for clipboard contents.  this will set
-           m_formatSupported to TRUE if m_targetRequested
+           m_formatSupported to true if m_targetRequested
            is supported.
            also, we have to wait for the "answer" from the
            clipboard owner which is an asynchronous process.
            is supported.
            also, we have to wait for the "answer" from the
            clipboard owner which is an asynchronous process.
-           therefore we set m_waiting = TRUE here and wait
+           therefore we set m_waiting = true here and wait
            until the callback "targets_selection_received"
            until the callback "targets_selection_received"
-           sets it to FALSE */
+           sets it to false */
 
 
-        m_waiting = TRUE;
+        m_waiting = true;
 
         wxLogTrace( TRACE_CLIPBOARD,
                     wxT("wxClipboard::GetData: format found, start convert") );
 
         wxLogTrace( TRACE_CLIPBOARD,
                     wxT("wxClipboard::GetData: format found, start convert") );
@@ -590,11 +635,11 @@ bool wxClipboard::GetData( wxDataObject& data )
         while (m_waiting) gtk_main_iteration();
 
         /* this is a true error as we checked for the presence of such data before */
         while (m_waiting) gtk_main_iteration();
 
         /* this is a true error as we checked for the presence of such data before */
-        wxCHECK_MSG( m_formatSupported, FALSE, wxT("error retrieving data from clipboard") );
+        wxCHECK_MSG( m_formatSupported, false, wxT("error retrieving data from clipboard") );
 
         /* return success */
         delete[] array;
 
         /* return success */
         delete[] array;
-        return TRUE;
+        return true;
     }
 
     wxLogTrace( TRACE_CLIPBOARD,
     }
 
     wxLogTrace( TRACE_CLIPBOARD,
@@ -602,9 +647,8 @@ bool wxClipboard::GetData( wxDataObject& data )
 
     /* return failure */
     delete[] array;
 
     /* return failure */
     delete[] array;
-    return FALSE;
+    return false;
 }
 
 #endif
   // wxUSE_CLIPBOARD
 }
 
 #endif
   // wxUSE_CLIPBOARD
-