X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dde19c2180ef8d6415af7bb2492bfcb0a2d5c7e4..67afffcd05e53e20503b7b64215b6c272ac75e47:/src/gtk/clipbrd.cpp diff --git a/src/gtk/clipbrd.cpp b/src/gtk/clipbrd.cpp index 2938ec3861..c1c9c9c99b 100644 --- a/src/gtk/clipbrd.cpp +++ b/src/gtk/clipbrd.cpp @@ -2,7 +2,6 @@ // Name: src/gtk/clipbrd.cpp // Purpose: wxClipboard implementation for wxGTK // Author: Robert Roebling, Vadim Zeitlin -// Id: $Id$ // Copyright: (c) 1998 Robert Roebling // (c) 2007 Vadim Zeitlin // Licence: wxWindows licence @@ -53,7 +52,7 @@ extern GdkAtom g_altTextAtom; // the trace mask we use with wxLogTrace() - call // wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here // (there will be a *lot* of them!) -#define TRACE_CLIPBOARD _T("clipboard") +#define TRACE_CLIPBOARD wxT("clipboard") // ---------------------------------------------------------------------------- // wxClipboardSync: used to perform clipboard operations synchronously @@ -69,12 +68,17 @@ class wxClipboardSync public: wxClipboardSync(wxClipboard& clipboard) { - wxASSERT_MSG( !ms_clipboard, _T("reentrancy in clipboard code") ); + wxASSERT_MSG( !ms_clipboard, wxT("reentrancy in clipboard code") ); ms_clipboard = &clipboard; } ~wxClipboardSync() { +#if wxUSE_CONSOLE_EVENTLOOP + // ensure that there is a running event loop: this might not be the + // case if we're called before the main event loop startup + wxEventLoopGuarantor ensureEventLoop; +#endif while (ms_clipboard) wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_CLIPBOARD); } @@ -84,7 +88,7 @@ public: static void OnDone(wxClipboard * WXUNUSED_UNLESS_DEBUG(clipboard)) { wxASSERT_MSG( clipboard == ms_clipboard, - _T("got notification for alien clipboard") ); + wxT("got notification for alien clipboard") ); ms_clipboard = NULL; } @@ -128,34 +132,36 @@ targets_selection_received( GtkWidget *WXUNUSED(widget), wxON_BLOCK_EXIT1(wxClipboardSync::OnDone, clipboard); - if ( !selection_data || selection_data->length <= 0 ) + if (!selection_data) + return; + + const int selection_data_length = gtk_selection_data_get_length(selection_data); + if (selection_data_length <= 0) return; // make sure we got the data in the correct form - GdkAtom type = selection_data->type; + GdkAtom type = gtk_selection_data_get_data_type(selection_data); if ( type != GDK_SELECTION_TYPE_ATOM ) { if ( strcmp(wxGtkString(gdk_atom_name(type)), "TARGETS") != 0 ) { wxLogTrace( TRACE_CLIPBOARD, - _T("got unsupported clipboard target") ); + wxT("got unsupported clipboard target") ); return; } } -#ifdef __WXDEBUG__ // it's not really a format, of course, but we can reuse its GetId() method // to format this atom as string - wxDataFormat clip(selection_data->selection); + wxDataFormat clip(gtk_selection_data_get_selection(selection_data)); wxLogTrace( TRACE_CLIPBOARD, wxT("Received available formats for clipboard %s"), clip.GetId().c_str() ); -#endif // __WXDEBUG__ // the atoms we received, holding a list of targets (= formats) - const GdkAtom * const atoms = (GdkAtom *)selection_data->data; - for ( size_t i = 0; i < selection_data->length/sizeof(GdkAtom); i++ ) + const GdkAtom* const atoms = (GdkAtom*)gtk_selection_data_get_data(selection_data); + for (size_t i = 0; i < selection_data_length / sizeof(GdkAtom); i++) { const wxDataFormat format(atoms[i]); @@ -192,7 +198,7 @@ selection_received( GtkWidget *WXUNUSED(widget), wxON_BLOCK_EXIT1(wxClipboardSync::OnDone, clipboard); - if ( !selection_data || selection_data->length <= 0 ) + if (!selection_data || gtk_selection_data_get_length(selection_data) <= 0) return; clipboard->GTKOnSelectionReceived(*selection_data); @@ -259,7 +265,8 @@ selection_handler( GtkWidget *WXUNUSED(widget), if ( !clipboard ) return; - wxDataObject * const data = clipboard->GTKGetDataObject(); + wxDataObject * const data = clipboard->GTKGetDataObject( + gtk_selection_data_get_selection(selection_data)); if ( !data ) return; @@ -267,7 +274,7 @@ selection_handler( GtkWidget *WXUNUSED(widget), // 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) + if (gtk_selection_data_get_target(selection_data) == g_timestampAtom) { guint timestamp = GPOINTER_TO_UINT (signal_data); gtk_selection_data_set(selection_data, @@ -276,23 +283,21 @@ selection_handler( GtkWidget *WXUNUSED(widget), (guchar*)&(timestamp), sizeof(timestamp)); wxLogTrace(TRACE_CLIPBOARD, - _T("Clipboard TIMESTAMP requested, returning timestamp=%u"), + wxT("Clipboard TIMESTAMP requested, returning timestamp=%u"), timestamp); return; } - wxDataFormat format( selection_data->target ); + wxDataFormat format(gtk_selection_data_get_target(selection_data)); -#ifdef __WXDEBUG__ wxLogTrace(TRACE_CLIPBOARD, - _T("clipboard data in format %s, GtkSelectionData is target=%s type=%s selection=%s timestamp=%u"), + wxT("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(), + wxString::FromAscii(wxGtkString(gdk_atom_name(gtk_selection_data_get_target(selection_data)))).c_str(), + wxString::FromAscii(wxGtkString(gdk_atom_name(gtk_selection_data_get_data_type(selection_data)))).c_str(), + wxString::FromAscii(wxGtkString(gdk_atom_name(gtk_selection_data_get_selection(selection_data)))).c_str(), GPOINTER_TO_UINT( signal_data ) ); -#endif // __WXDEBUG__ if ( !data->IsSupportedFormat( format ) ) return; @@ -322,7 +327,7 @@ selection_handler( GtkWidget *WXUNUSED(widget), { gtk_selection_data_set( selection_data, - GDK_SELECTION_TYPE_STRING, + format.GetFormatId(), 8*sizeof(gchar), (const guchar*)buf.data(), size ); @@ -332,16 +337,18 @@ selection_handler( GtkWidget *WXUNUSED(widget), void wxClipboard::GTKOnSelectionReceived(const GtkSelectionData& sel) { - wxCHECK_RET( m_receivedData, _T("should be inside GetData()") ); + wxCHECK_RET( m_receivedData, wxT("should be inside GetData()") ); - const wxDataFormat format(sel.target); - wxLogTrace(TRACE_CLIPBOARD, _T("Received selection %s"), + const wxDataFormat format(gtk_selection_data_get_target(const_cast(&sel))); + wxLogTrace(TRACE_CLIPBOARD, wxT("Received selection %s"), format.GetId().c_str()); - if ( !m_receivedData->IsSupportedFormat(format) ) + if ( !m_receivedData->IsSupportedFormat(format, wxDataObject::Set) ) return; - m_receivedData->SetData(format, sel.length, sel.data); + m_receivedData->SetData(format, + gtk_selection_data_get_length(const_cast(&sel)), + gtk_selection_data_get_data(const_cast(&sel))); m_formatSupported = true; } @@ -365,7 +372,11 @@ async_targets_selection_received( GtkWidget *WXUNUSED(widget), wxClipboardEvent *event = new wxClipboardEvent(wxEVT_CLIPBOARD_CHANGED); event->SetEventObject( clipboard ); - if ( !selection_data || selection_data->length <= 0 ) + int selection_data_length = 0; + if (selection_data) + selection_data_length = gtk_selection_data_get_length(selection_data); + + if (selection_data_length <= 0) { clipboard->m_sink->QueueEvent( event ); clipboard->m_sink.Release(); @@ -373,13 +384,13 @@ async_targets_selection_received( GtkWidget *WXUNUSED(widget), } // make sure we got the data in the correct form - GdkAtom type = selection_data->type; + GdkAtom type = gtk_selection_data_get_data_type(selection_data); if ( type != GDK_SELECTION_TYPE_ATOM ) { if ( strcmp(wxGtkString(gdk_atom_name(type)), "TARGETS") != 0 ) { wxLogTrace( TRACE_CLIPBOARD, - _T("got unsupported clipboard target") ); + wxT("got unsupported clipboard target") ); clipboard->m_sink->QueueEvent( event ); clipboard->m_sink.Release(); @@ -387,18 +398,16 @@ async_targets_selection_received( GtkWidget *WXUNUSED(widget), } } -#ifdef __WXDEBUG__ // it's not really a format, of course, but we can reuse its GetId() method // to format this atom as string - wxDataFormat clip(selection_data->selection); + wxDataFormat clip(gtk_selection_data_get_selection(selection_data)); wxLogTrace( TRACE_CLIPBOARD, wxT("Received available formats for clipboard %s"), clip.GetId().c_str() ); -#endif // __WXDEBUG__ // the atoms we received, holding a list of targets (= formats) - const GdkAtom * const atoms = (GdkAtom *)selection_data->data; - for ( size_t i = 0; i < selection_data->length/sizeof(GdkAtom); i++ ) + const GdkAtom* const atoms = (GdkAtom*)gtk_selection_data_get_data(selection_data); + for (size_t i = 0; i < selection_data_length / sizeof(GdkAtom); i++) { const wxDataFormat format(atoms[i]); @@ -424,6 +433,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject) wxClipboard::wxClipboard() { + m_idSelectionGetHandler = 0; + m_open = false; m_dataPrimary = @@ -487,11 +498,7 @@ GdkAtom wxClipboard::GTKGetClipboardAtom() const void wxClipboard::GTKClearData(Kind kind) { wxDataObject *&data = Data(kind); - if ( data ) - { - delete data; - data = NULL; - } + wxDELETE(data); } bool wxClipboard::SetSelectionOwner(bool set) @@ -501,12 +508,12 @@ bool wxClipboard::SetSelectionOwner(bool set) set ? m_clipboardWidget : NULL, GTKGetClipboardAtom(), (guint32)GDK_CURRENT_TIME - ); + ) != 0; if ( !rc ) { - wxLogTrace(TRACE_CLIPBOARD, _T("Failed to %sset selection owner"), - set ? _T("") : _T("un")); + wxLogTrace(TRACE_CLIPBOARD, wxT("Failed to %sset selection owner"), + set ? wxT("") : wxT("un")); } return rc; @@ -570,8 +577,10 @@ bool wxClipboard::DoIsSupported(const wxDataFormat& format) void wxClipboard::Clear() { + gtk_selection_clear_targets( m_clipboardWidget, GTKGetClipboardAtom() ); + if ( gdk_selection_owner_get(GTKGetClipboardAtom()) == - m_clipboardWidget->window ) + gtk_widget_get_window(m_clipboardWidget) ) { wxClipboardSync sync(*this); @@ -634,9 +643,13 @@ bool wxClipboard::AddData( wxDataObject *data ) AddSupportedTarget(format); } - g_signal_connect (m_clipboardWidget, "selection_get", + if ( !m_idSelectionGetHandler ) + { + m_idSelectionGetHandler = g_signal_connect ( + m_clipboardWidget, "selection_get", G_CALLBACK (selection_handler), GUINT_TO_POINTER (gtk_get_current_event_time()) ); + } // tell the world we offer clipboard data return SetSelectionOwner(); @@ -674,10 +687,11 @@ bool wxClipboard::GetData( wxDataObject& data ) { wxCHECK_MSG( m_open, false, wxT("clipboard not open") ); - // get all supported formats from wxDataObjects - const size_t count = data.GetFormatCount(); + // get all supported formats from wxDataObjects: notice that we are setting + // the object data, so we need them in "Set" direction + const size_t count = data.GetFormatCount(wxDataObject::Set); wxDataFormatArray formats(new wxDataFormat[count]); - data.GetAllFormats(formats.get()); + data.GetAllFormats(formats.get(), wxDataObject::Set); for ( size_t i = 0; i < count; i++ ) { @@ -731,4 +745,27 @@ bool wxClipboard::GetData( wxDataObject& data ) return false; } +wxDataObject* wxClipboard::GTKGetDataObject( GdkAtom atom ) +{ + if ( atom == GDK_NONE ) + return Data(); + + if ( atom == GDK_SELECTION_PRIMARY ) + { + wxLogTrace(TRACE_CLIPBOARD, wxT("Primary selection requested" )); + + return Data( wxClipboard::Primary ); + } + else if ( atom == g_clipboardAtom ) + { + wxLogTrace(TRACE_CLIPBOARD, wxT("Clipboard data requested" )); + + return Data( wxClipboard::Clipboard ); + } + else // some other selection, we're not concerned + { + return (wxDataObject*)NULL; + } +} + #endif // wxUSE_CLIPBOARD