// 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
#include "wx/scopedarray.h"
#include "wx/scopeguard.h"
+#include "wx/evtloop.h"
#include "wx/gtk/private.h"
// 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
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)
- wxTheApp->YieldFor(wxEVT_CATEGORY_CLIPBOARD);
+ wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_CLIPBOARD);
}
// this method must be called by GTK+ callbacks to indicate that we got the
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;
}
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]);
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);
if ( !clipboard )
return;
- wxDataObject * const data = clipboard->GTKGetDataObject();
+ wxDataObject * const data = clipboard->GTKGetDataObject(
+ gtk_selection_data_get_selection(selection_data));
if ( !data )
return;
// 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,
(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;
{
gtk_selection_data_set(
selection_data,
- GDK_SELECTION_TYPE_STRING,
+ format.GetFormatId(),
8*sizeof(gchar),
(const guchar*)buf.data(),
size );
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<GtkSelectionData*>(&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<GtkSelectionData*>(&sel)),
+ gtk_selection_data_get_data(const_cast<GtkSelectionData*>(&sel)));
m_formatSupported = true;
}
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();
}
// 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();
}
}
-#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]);
wxClipboard::wxClipboard()
{
+ m_idSelectionGetHandler = 0;
+
m_open = false;
m_dataPrimary =
void wxClipboard::GTKClearData(Kind kind)
{
wxDataObject *&data = Data(kind);
- if ( data )
- {
- delete data;
- data = NULL;
- }
+ wxDELETE(data);
}
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;
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);
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();
{
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++ )
{
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