+ if (!wxTheClipboard) return true;
+
+ if (event->selection == GDK_SELECTION_PRIMARY)
+ {
+ wxTheClipboard->m_ownsPrimarySelection = false;
+ }
+ else
+ if (event->selection == g_clipboardAtom)
+ {
+ wxTheClipboard->m_ownsClipboard = false;
+ }
+ else
+ {
+ wxTheClipboard->m_waiting = false;
+ return FALSE;
+ }
+
+ if ((!wxTheClipboard->m_ownsPrimarySelection) &&
+ (!wxTheClipboard->m_ownsClipboard))
+ {
+ /* the clipboard is no longer in our hands. we can the delete clipboard data. */
+ if (wxTheClipboard->m_data)
+ {
+ wxLogTrace(TRACE_CLIPBOARD, wxT("wxClipboard will get cleared" ));
+
+ delete wxTheClipboard->m_data;
+ wxTheClipboard->m_data = (wxDataObject*) NULL;
+ }
+ }
+
+ wxTheClipboard->m_waiting = false;
+ return TRUE;
+}
+}
+
+//-----------------------------------------------------------------------------
+// selection handler for supplying data
+//-----------------------------------------------------------------------------
+
+extern "C" {
+static void
+selection_handler( GtkWidget *WXUNUSED(widget),
+ GtkSelectionData *selection_data,
+ guint WXUNUSED(info),
+ guint WXUNUSED(time),
+ gpointer signal_data )
+{
+ if (!wxTheClipboard) return;
+
+ if (!wxTheClipboard->m_data) return;
+
+ 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 );
+
+#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 (size == 0) return;
+
+ void *d = malloc(size);
+
+ // Text data will be in UTF8 in Unicode mode.
+ data->GetDataHere( selection_data->target, d );
+
+ // 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))
+ {
+ 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 );
+ }
+
+ free(d);
+}