]> git.saurik.com Git - wxWidgets.git/blame - src/motif/clipbrd.cpp
Removed dead code.
[wxWidgets.git] / src / motif / clipbrd.cpp
CommitLineData
4bb6408c
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: clipbrd.cpp
3// Purpose: Clipboard functionality
4// Author: Julian Smart
dd38c875 5// Modified by: Mattia Barbon (added support for generic wxDataObjects)
4bb6408c
JS
6// Created: 17/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation
14#pragma implementation "clipbrd.h"
15#endif
16
dfe1eee3
VZ
17#include "wx/defs.h"
18
19#if wxUSE_CLIPBOARD
20
4bb6408c 21#include "wx/app.h"
4bb6408c
JS
22#include "wx/bitmap.h"
23#include "wx/utils.h"
4bb6408c 24#include "wx/clipbrd.h"
2d120f83 25#include "wx/dataobj.h"
dd38c875 26#include "wx/ptr_scpd.h"
2d120f83 27
338dd992
JJ
28#ifdef __VMS__
29#pragma message disable nosimpint
30#endif
2d120f83
JS
31#include <Xm/Xm.h>
32#include <Xm/CutPaste.h>
338dd992
JJ
33#ifdef __VMS__
34#pragma message enable nosimpint
35#endif
4bb6408c 36
dd38c875 37#include "wx/motif/private.h"
2d120f83 38
4bb6408c
JS
39bool wxOpenClipboard()
40{
dd38c875 41 return wxTheClipboard->Open();
4bb6408c
JS
42}
43
44bool wxCloseClipboard()
45{
dd38c875
MB
46 wxTheClipboard->Close();
47
48 return true;
4bb6408c
JS
49}
50
51bool wxEmptyClipboard()
52{
dd38c875
MB
53 wxTheClipboard->Clear();
54 return true;
4bb6408c
JS
55}
56
57bool wxClipboardOpen()
58{
dd38c875 59 return wxTheClipboard->IsOpened();
4bb6408c
JS
60}
61
2d120f83 62bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
4bb6408c 63{
dd38c875
MB
64 return wxTheClipboard->IsSupported( dataFormat );
65}
2d120f83 66
dd38c875
MB
67bool wxSetClipboardData(wxDataFormat dataFormat, wxObject *obj,
68 int WXUNUSED(width), int WXUNUSED(height))
69{
70 wxDataObject* dobj = NULL;
2d120f83 71
dd38c875
MB
72 if( dataFormat == wxDF_TEXT )
73 {
74 wxChar* data = (wxChar*)obj;
75 dobj = new wxTextDataObject( data );
76 }
77 else if( dataFormat = wxDF_BITMAP )
78 {
79 wxBitmap* data = (wxBitmap*)obj;
80 dobj = new wxBitmapDataObject( *data );
81 }
2d120f83 82
dd38c875
MB
83 if( !dobj )
84 return false;
4bb6408c 85
dd38c875 86 return wxTheClipboard->SetData( dobj );
4bb6408c
JS
87}
88
2d120f83 89wxObject *wxGetClipboardData(wxDataFormat dataFormat, long *len)
4bb6408c 90{
dd38c875
MB
91 wxDataObject* dobj = NULL;
92 wxTextDataObject* tobj = NULL;
93 wxBitmapDataObject* bobj = NULL;
2d120f83 94
dd38c875
MB
95 if( dataFormat == wxDF_TEXT )
96 {
97 dobj = tobj = new wxTextDataObject;
98 }
99 else if( dataFormat = wxDF_BITMAP )
100 {
101 dobj = bobj = new wxBitmapDataObject;
102 }
2d120f83 103
dd38c875
MB
104 if( !dobj || !wxTheClipboard->GetData( *dobj ) )
105 return NULL;
2d120f83 106
dd38c875 107 if( tobj )
2d120f83 108 {
dd38c875
MB
109 wxString text = tobj->GetText();
110 wxChar* buf = new wxChar[text.length() + 1];
111
112 if( len ) *len = text.length();
113 return (wxObject*)wxStrcpy( buf, text.c_str() );
114 }
115 else if( bobj )
116 {
117 if( len ) *len = 0;
118 return new wxBitmap( bobj->GetBitmap() );
2d120f83
JS
119 }
120
dd38c875 121 return NULL; // just in case...
4bb6408c
JS
122}
123
dd38c875 124wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat)
4bb6408c 125{
2d120f83 126 // Only wxDF_TEXT supported
da175b2c 127 if (dataFormat == wxDF_TEXT)
2d120f83
JS
128 return wxDF_TEXT;
129 else
da175b2c 130 return wxDF_INVALID;
4bb6408c
JS
131}
132
dd38c875 133wxDataFormat wxRegisterClipboardFormat(char *WXUNUSED(formatName))
4bb6408c 134{
2d120f83 135 // Not supported
dd38c875 136 return wxDF_INVALID;
4bb6408c
JS
137}
138
dd38c875
MB
139bool wxGetClipboardFormatName(wxDataFormat dataFormat, char *formatName,
140 int maxCount)
4bb6408c 141{
dd38c875
MB
142 wxStrncpy( formatName, dataFormat.GetId().c_str(), maxCount );
143
144 return true;
4bb6408c
JS
145}
146
2d120f83
JS
147//-----------------------------------------------------------------------------
148// wxClipboard
149//-----------------------------------------------------------------------------
4bb6408c 150
47be989f
MB
151struct wxDataIdToDataObject
152{
153 wxDataIdToDataObject( wxDataObject* o, long d, size_t s )
154 : object( o ), size( s ), dataId( d ) { }
155
156 wxDataObject* object;
157 size_t size;
158 long dataId;
159};
160
161#include "wx/listimpl.cpp"
162
163WX_DEFINE_LIST(wxDataObjectList);
164WX_DEFINE_LIST(wxDataIdToDataObjectList);
165
166static void wxClipboardCallback( Widget widget, long* data_id,
167 long* priv, int* reason );
168
169
2d120f83 170IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
4bb6408c 171
4bb6408c
JS
172wxClipboard::wxClipboard()
173{
dd38c875 174 m_open = false;
4bb6408c
JS
175}
176
177wxClipboard::~wxClipboard()
178{
2d120f83 179 Clear();
4bb6408c
JS
180}
181
2d120f83 182void wxClipboard::Clear()
4bb6408c 183{
fd304d98 184 wxDataObjectList::Node* node = m_data.GetFirst();
2d120f83
JS
185 while (node)
186 {
47be989f 187 delete node->GetData();
fd304d98 188 node = node->GetNext();
2d120f83
JS
189 }
190 m_data.Clear();
47be989f
MB
191
192 for( wxDataIdToDataObjectList::Node* node2 = m_idToObject.GetFirst();
193 node2; node2 = node2->GetNext() )
194 delete node->GetData();
195 m_idToObject.Clear();
4bb6408c
JS
196}
197
2d120f83 198bool wxClipboard::Open()
4bb6408c 199{
dd38c875 200 wxCHECK_MSG( !m_open, false, "clipboard already open" );
2d120f83 201
dd38c875 202 m_open = true;
4bb6408c 203
dd38c875 204 return true;
2d120f83 205}
4bb6408c 206
2d120f83
JS
207bool wxClipboard::SetData( wxDataObject *data )
208{
dd38c875
MB
209 wxCHECK_MSG( data, false, "data is invalid" );
210 wxCHECK_MSG( m_open, false, "clipboard not open" );
2d120f83 211
12db77ca
VZ
212 Clear();
213
214 return AddData( data );
215}
216
dd38c875
MB
217wxDECLARE_SCOPED_ARRAY( wxDataFormat, wxDataFormatScopedArray );
218wxDEFINE_SCOPED_ARRAY( wxDataFormat, wxDataFormatScopedArray );
219
47be989f
MB
220void wxClipboardCallback( Widget xwidget, long* data_id,
221 long* priv, int* reason )
222{
223 Display* xdisplay = XtDisplay( xwidget );
224 Window xwindow = XtWindow( xwidget );
225 wxDataObject* dobj = NULL;
226 size_t size = 0;
227
228 for( wxDataIdToDataObjectList::Node* node2 =
229 wxTheClipboard->m_idToObject.GetFirst();
230 node2; node2 = node2->GetNext() )
231 {
232 wxDataIdToDataObject* dido = node2->GetData();
233 if( dido->dataId == *data_id )
234 {
235 dobj = dido->object;
236 size = dido->size;
237 break;
238 }
239 }
240
241 if( !dobj ) return;
242
243 wxCharBuffer buffer(size);
244 size_t count = dobj->GetFormatCount( wxDataObject::Get );
245 wxDataFormatScopedArray dfarr( new wxDataFormat[count] );
246 dobj->GetAllFormats( dfarr.get(), wxDataObject::Get );
247
248 if( !dobj->GetDataHere( dfarr[*priv], buffer.data() ) )
249 return;
250
251 while( XmClipboardCopyByName( xdisplay, xwindow, *data_id,
252 buffer.data(), size, 0 )
253 == XmClipboardLocked );
254}
255
12db77ca
VZ
256bool wxClipboard::AddData( wxDataObject *data )
257{
dd38c875
MB
258 wxCHECK_MSG( data, false, "data is invalid" );
259 wxCHECK_MSG( m_open, false, "clipboard not open" );
260
261 m_data.Append( data );
262
263 Display* xdisplay = wxGlobalDisplay();
47be989f
MB
264 Widget xwidget = (Widget)wxTheApp->GetTopLevelWidget();
265 Window xwindow = XtWindow( xwidget );
dd38c875
MB
266 wxXmString label( wxTheApp->GetAppName() );
267 Time timestamp = XtLastTimestampProcessed( xdisplay );
268 long itemId;
269
270 int retval;
12db77ca 271
dd38c875 272 while( ( retval = XmClipboardStartCopy( xdisplay, xwindow, label(),
47be989f
MB
273 timestamp, xwidget,
274 wxClipboardCallback,
dd38c875
MB
275 &itemId ) )
276 == XmClipboardLocked );
277 if( retval != XmClipboardSuccess )
278 return false;
279
280 size_t count = data->GetFormatCount( wxDataObject::Get );
281 wxDataFormatScopedArray dfarr( new wxDataFormat[count] );
282 data->GetAllFormats( dfarr.get(), wxDataObject::Get );
283
284 for( size_t i = 0; i < count; ++i )
2d120f83 285 {
dd38c875 286 size_t size = data->GetDataSize( dfarr[i] );
47be989f 287 long data_id;
dd38c875
MB
288 wxString id = dfarr[i].GetId();
289
290 while( ( retval = XmClipboardCopy( xdisplay, xwindow, itemId,
291 wxConstCast(id.c_str(), char),
47be989f 292 NULL, size, i, &data_id ) )
dd38c875 293 == XmClipboardLocked );
47be989f
MB
294
295 m_idToObject.Append( new wxDataIdToDataObject( data, data_id, size ) );
2d120f83 296 }
dd38c875
MB
297
298 while( XmClipboardEndCopy( xdisplay, xwindow, itemId )
299 == XmClipboardLocked );
300
301 return true;
2d120f83 302}
4bb6408c 303
2d120f83
JS
304void wxClipboard::Close()
305{
306 wxCHECK_RET( m_open, "clipboard not open" );
307
dd38c875 308 m_open = false;
4bb6408c
JS
309}
310
dd38c875 311bool wxClipboard::IsSupported(const wxDataFormat& format)
4bb6408c 312{
dd38c875
MB
313 Display* xdisplay = wxGlobalDisplay();
314 Window xwindow = XtWindow( (Widget)wxTheApp->GetTopLevelWidget() );
315 bool isSupported = false;
316 int retval, count;
317 unsigned long max_name_length;
318 wxString id = format.GetId();
319
320 while( ( retval = XmClipboardLock( xdisplay, xwindow ) )
321 == XmClipboardLocked );
322 if( retval != XmClipboardSuccess )
323 return false;
324
325 if( XmClipboardInquireCount( xdisplay, xwindow, &count, &max_name_length )
326 == XmClipboardSuccess )
2d120f83 327 {
dd38c875
MB
328 wxCharBuffer buf( max_name_length + 1 );
329 unsigned long copied;
330
331 for( int i = 0; i < count; ++i )
2d120f83 332 {
dd38c875
MB
333 if( XmClipboardInquireFormat( xdisplay, xwindow, i + 1,
334 (XtPointer)buf.data(),
335 max_name_length, &copied )
336 != XmClipboardSuccess )
337 continue;
338
339 buf.data()[copied] = '\0';
340
341 if( buf == id )
2d120f83 342 {
dd38c875
MB
343 isSupported = true;
344 break;
2d120f83 345 }
2d120f83
JS
346 }
347 }
4bb6408c 348
dd38c875 349 XmClipboardUnlock( xdisplay, xwindow, False );
2d120f83 350
dd38c875 351 return isSupported;
2d120f83 352}
4bb6408c 353
dd38c875 354class wxClipboardEndRetrieve
2d120f83 355{
dd38c875
MB
356public:
357 wxClipboardEndRetrieve( Display* display, Window window )
358 : m_display( display ), m_window( window ) { }
359 ~wxClipboardEndRetrieve()
360 {
361 while( XmClipboardEndRetrieve( m_display, m_window )
362 == XmClipboardLocked );
363 }
364private:
365 Display* m_display;
366 Window m_window;
367};
2d120f83 368
dd38c875 369bool wxClipboard::GetData( wxDataObject& data )
4bb6408c 370{
dd38c875
MB
371 wxCHECK_MSG( m_open, false, "clipboard not open" );
372
373 Display* xdisplay = wxGlobalDisplay();
374 Window xwindow = XtWindow( (Widget)wxTheApp->GetTopLevelWidget() );
375 Time timestamp = XtLastTimestampProcessed( xdisplay );
376
377 wxDataFormat chosenFormat;
378 int retval;
379
380 ///////////////////////////////////////////////////////////////////////////
381 // determine if the cliboard holds any format we like
382 ///////////////////////////////////////////////////////////////////////////
383 while( ( retval = XmClipboardStartRetrieve( xdisplay, xwindow,
384 timestamp ) )
385 == XmClipboardLocked );
386 if( retval != XmClipboardSuccess )
387 return false;
388
389 wxClipboardEndRetrieve endRetrieve( xdisplay, xwindow );
390
391 int count;
392 unsigned long max_name_length;
393 size_t dfcount = data.GetFormatCount( wxDataObject::Set );
394 wxDataFormatScopedArray dfarr( new wxDataFormat[dfcount] );
395 data.GetAllFormats( dfarr.get(), wxDataObject::Set );
2d120f83 396
dd38c875
MB
397 if( XmClipboardInquireCount( xdisplay, xwindow, &count, &max_name_length )
398 == XmClipboardSuccess )
399 {
400 wxCharBuffer buf( max_name_length + 1 );
401 unsigned long copied;
4bb6408c 402
dd38c875
MB
403 for( int i = 0; i < count; ++i )
404 {
405 if( XmClipboardInquireFormat( xdisplay, xwindow, i + 1,
406 (XtPointer)buf.data(),
407 max_name_length, &copied )
408 != XmClipboardSuccess )
409 continue;
4bb6408c 410
dd38c875 411 buf.data()[copied] = '\0';
4bb6408c 412
dd38c875
MB
413 // try preferred format
414 if( buf == data.GetPreferredFormat( wxDataObject::Set ).GetId() )
415 {
416 chosenFormat = data.GetPreferredFormat( wxDataObject::Set );
417 break;
418 }
2d120f83 419
dd38c875
MB
420 // try all other formats
421 for( size_t i = 0; i < dfcount; ++i )
422 {
423 if( buf == dfarr[i].GetId() )
424 chosenFormat = dfarr[i];
425 }
426 }
2d120f83 427 }
4bb6408c 428
dd38c875
MB
429 if( chosenFormat == wxDF_INVALID )
430 return false;
431
432 ///////////////////////////////////////////////////////////////////////////
433 // now retrieve the data
434 ///////////////////////////////////////////////////////////////////////////
435 unsigned long length, dummy1;
436 long dummy2;
437 wxString id = chosenFormat.GetId();
438
439 while( ( retval = XmClipboardInquireLength( xdisplay, xwindow,
440 wxConstCast(id.c_str(), char),
441 &length ) )
442 == XmClipboardLocked );
443 if( retval != XmClipboardSuccess )
444 return false;
445
446 wxCharBuffer buf(length);
447
448 while( ( retval = XmClipboardRetrieve( xdisplay, xwindow,
449 wxConstCast(id.c_str(), char),
450 (XtPointer)buf.data(),
451 length, &dummy1, &dummy2 ) )
452 == XmClipboardLocked );
453 if( retval != XmClipboardSuccess )
454 return false;
455
456 if( !data.SetData( chosenFormat, length, buf.data() ) )
457 return false;
458
459 return true;
4bb6408c
JS
460}
461
dfe1eee3 462#endif // wxUSE_CLIPBOARD