From 47be989f6bee132748c4051577251e72c0b0c045 Mon Sep 17 00:00:00 2001 From: Mattia Barbon Date: Mon, 12 May 2003 19:55:35 +0000 Subject: [PATCH] Implemented copy-on-demand for wxClipboard. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@20612 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/motif/clipbrd.h | 7 +++- src/motif/clipbrd.cpp | 83 +++++++++++++++++++++++++++++++------- 2 files changed, 74 insertions(+), 16 deletions(-) diff --git a/include/wx/motif/clipbrd.h b/include/wx/motif/clipbrd.h index 5a420ed322..1e16040456 100644 --- a/include/wx/motif/clipbrd.h +++ b/include/wx/motif/clipbrd.h @@ -19,9 +19,12 @@ #if wxUSE_CLIPBOARD class wxDataObject; +struct wxDataIdToDataObject; #include "wx/list.h" + WX_DECLARE_LIST(wxDataObject, wxDataObjectList); +WX_DECLARE_LIST(wxDataIdToDataObject, wxDataIdToDataObjectList); bool WXDLLEXPORT wxOpenClipboard(); bool WXDLLEXPORT wxClipboardOpen(); @@ -72,11 +75,11 @@ public: { m_usePrimary = primary; } // implementation from now on - bool m_open; wxDataObjectList m_data; bool m_usePrimary; - + wxDataIdToDataObjectList m_idToObject; + private: DECLARE_DYNAMIC_CLASS(wxClipboard) }; diff --git a/src/motif/clipbrd.cpp b/src/motif/clipbrd.cpp index 17f2e17e27..9c09d7ff2b 100644 --- a/src/motif/clipbrd.cpp +++ b/src/motif/clipbrd.cpp @@ -25,9 +25,6 @@ #include "wx/dataobj.h" #include "wx/ptr_scpd.h" -#include "wx/listimpl.cpp" -WX_DEFINE_LIST(wxDataObjectList); - #ifdef __VMS__ #pragma message disable nosimpint #endif @@ -151,6 +148,25 @@ bool wxGetClipboardFormatName(wxDataFormat dataFormat, char *formatName, // wxClipboard //----------------------------------------------------------------------------- +struct wxDataIdToDataObject +{ + wxDataIdToDataObject( wxDataObject* o, long d, size_t s ) + : object( o ), size( s ), dataId( d ) { } + + wxDataObject* object; + size_t size; + long dataId; +}; + +#include "wx/listimpl.cpp" + +WX_DEFINE_LIST(wxDataObjectList); +WX_DEFINE_LIST(wxDataIdToDataObjectList); + +static void wxClipboardCallback( Widget widget, long* data_id, + long* priv, int* reason ); + + IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject) wxClipboard::wxClipboard() @@ -168,11 +184,15 @@ void wxClipboard::Clear() wxDataObjectList::Node* node = m_data.GetFirst(); while (node) { - wxDataObject* data = node->GetData(); - delete data; + delete node->GetData(); node = node->GetNext(); } m_data.Clear(); + + for( wxDataIdToDataObjectList::Node* node2 = m_idToObject.GetFirst(); + node2; node2 = node2->GetNext() ) + delete node->GetData(); + m_idToObject.Clear(); } bool wxClipboard::Open() @@ -197,6 +217,42 @@ bool wxClipboard::SetData( wxDataObject *data ) wxDECLARE_SCOPED_ARRAY( wxDataFormat, wxDataFormatScopedArray ); wxDEFINE_SCOPED_ARRAY( wxDataFormat, wxDataFormatScopedArray ); +void wxClipboardCallback( Widget xwidget, long* data_id, + long* priv, int* reason ) +{ + Display* xdisplay = XtDisplay( xwidget ); + Window xwindow = XtWindow( xwidget ); + wxDataObject* dobj = NULL; + size_t size = 0; + + for( wxDataIdToDataObjectList::Node* node2 = + wxTheClipboard->m_idToObject.GetFirst(); + node2; node2 = node2->GetNext() ) + { + wxDataIdToDataObject* dido = node2->GetData(); + if( dido->dataId == *data_id ) + { + dobj = dido->object; + size = dido->size; + break; + } + } + + if( !dobj ) return; + + wxCharBuffer buffer(size); + size_t count = dobj->GetFormatCount( wxDataObject::Get ); + wxDataFormatScopedArray dfarr( new wxDataFormat[count] ); + dobj->GetAllFormats( dfarr.get(), wxDataObject::Get ); + + if( !dobj->GetDataHere( dfarr[*priv], buffer.data() ) ) + return; + + while( XmClipboardCopyByName( xdisplay, xwindow, *data_id, + buffer.data(), size, 0 ) + == XmClipboardLocked ); +} + bool wxClipboard::AddData( wxDataObject *data ) { wxCHECK_MSG( data, false, "data is invalid" ); @@ -205,7 +261,8 @@ bool wxClipboard::AddData( wxDataObject *data ) m_data.Append( data ); Display* xdisplay = wxGlobalDisplay(); - Window xwindow = XtWindow( (Widget)wxTheApp->GetTopLevelWidget() ); + Widget xwidget = (Widget)wxTheApp->GetTopLevelWidget(); + Window xwindow = XtWindow( xwidget ); wxXmString label( wxTheApp->GetAppName() ); Time timestamp = XtLastTimestampProcessed( xdisplay ); long itemId; @@ -213,8 +270,8 @@ bool wxClipboard::AddData( wxDataObject *data ) int retval; while( ( retval = XmClipboardStartCopy( xdisplay, xwindow, label(), - timestamp, (Widget)NULL, - (XmCutPasteProc)NULL, + timestamp, xwidget, + wxClipboardCallback, &itemId ) ) == XmClipboardLocked ); if( retval != XmClipboardSuccess ) @@ -227,17 +284,15 @@ bool wxClipboard::AddData( wxDataObject *data ) for( size_t i = 0; i < count; ++i ) { size_t size = data->GetDataSize( dfarr[i] ); - wxCharBuffer buffer(size); - - if( !data->GetDataHere( dfarr[i], buffer.data() ) ) - continue; - + long data_id; wxString id = dfarr[i].GetId(); while( ( retval = XmClipboardCopy( xdisplay, xwindow, itemId, wxConstCast(id.c_str(), char), - buffer.data(), size, 0, NULL ) ) + NULL, size, i, &data_id ) ) == XmClipboardLocked ); + + m_idToObject.Append( new wxDataIdToDataObject( data, data_id, size ) ); } while( XmClipboardEndCopy( xdisplay, xwindow, itemId ) -- 2.47.2