oops, fixed typo breaking iconv constness detection in the previous commit
[wxWidgets.git] / src / gtk / clipbrd.cpp
CommitLineData
dc86cb34 1/////////////////////////////////////////////////////////////////////////////
61b04ac6 2// Name: gtk/clipbrd.cpp
dc86cb34
RR
3// Purpose:
4// Author: Robert Roebling
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
61b04ac6 7// Licence: wxWindows licence
dc86cb34
RR
8/////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
11#pragma implementation "clipbrd.h"
12#endif
13
14#include "wx/clipbrd.h"
15
06cfab17 16#if wxUSE_CLIPBOARD
ac57418f 17
e1ee679c 18#include "wx/dataobj.h"
034be888 19#include "wx/utils.h"
b068c4e8 20#include "wx/log.h"
034be888 21
071a2d78
RR
22#include <glib.h>
23#include <gdk/gdk.h>
24#include <gtk/gtk.h>
83624f79 25
b453e1b2
RR
26//-----------------------------------------------------------------------------
27// thread system
28//-----------------------------------------------------------------------------
29
30#if wxUSE_THREADS
31extern void wxapp_install_thread_wakeup();
32extern void wxapp_uninstall_thread_wakeup();
33#endif
34
dc86cb34
RR
35//-----------------------------------------------------------------------------
36// data
37//-----------------------------------------------------------------------------
38
fd0eed64 39GdkAtom g_clipboardAtom = 0;
b527aac5 40GdkAtom g_targetsAtom = 0;
fd0eed64 41
61b04ac6
VZ
42// the trace mask we use with wxLogTrace() - call
43// wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here
44// (there will be a *lot* of them!)
cbf97a6c 45static const wxChar *TRACE_CLIPBOARD = _T("clipboard");
61b04ac6 46
dc86cb34 47//-----------------------------------------------------------------------------
b527aac5 48// reminder
dc86cb34
RR
49//-----------------------------------------------------------------------------
50
b527aac5 51/* The contents of a selection are returned in a GtkSelectionData
270c23f7 52 structure. selection/target identify the request.
b527aac5
RR
53 type specifies the type of the return; if length < 0, and
54 the data should be ignored. This structure has object semantics -
55 no fields should be modified directly, they should not be created
56 directly, and pointers to them should not be stored beyond the duration of
57 a callback. (If the last is changed, we'll need to add reference
58 counting)
59
60struct _GtkSelectionData
dc86cb34 61{
b527aac5
RR
62 GdkAtom selection;
63 GdkAtom target;
64 GdkAtom type;
61b04ac6 65 gint format;
b527aac5 66 guchar *data;
61b04ac6 67 gint length;
b527aac5
RR
68};
69
70*/
dc86cb34 71
b527aac5
RR
72//-----------------------------------------------------------------------------
73// "selection_received" for targets
74//-----------------------------------------------------------------------------
75
76static void
270c23f7
VZ
77targets_selection_received( GtkWidget *WXUNUSED(widget),
78 GtkSelectionData *selection_data,
034be888
RR
79#if (GTK_MINOR_VERSION > 0)
80 guint32 WXUNUSED(time),
81#endif
66633398 82 wxClipboard *clipboard )
dc86cb34 83{
270c23f7 84 if ( wxTheClipboard && selection_data->length > 0 )
034be888 85 {
270c23f7 86 /* make sure we got the data in the correct form */
270c23f7
VZ
87 GdkAtom type = selection_data->type;
88 if ( type != GDK_SELECTION_TYPE_ATOM )
89 {
61b04ac6
VZ
90 if ( strcmp(gdk_atom_name(type), "TARGETS") )
91 {
92 wxLogTrace( TRACE_CLIPBOARD,
93 _T("got unsupported clipboard target") );
94
95 clipboard->m_waiting = FALSE;
96 return;
97 }
270c23f7 98 }
b527aac5 99
61b04ac6 100#ifdef __WXDEBUG__
270c23f7 101 wxDataFormat clip( selection_data->selection );
61b04ac6
VZ
102 wxLogTrace( TRACE_CLIPBOARD,
103 wxT("selection received for targets, clipboard %s"),
104 clip.GetId().c_str() );
105#endif // __WXDEBUG__
270c23f7
VZ
106
107 // the atoms we received, holding a list of targets (= formats)
108 GdkAtom *atoms = (GdkAtom *)selection_data->data;
11e1c70d 109
270c23f7 110 for (unsigned int i=0; i<selection_data->length/sizeof(GdkAtom); i++)
8b53e5a2 111 {
270c23f7
VZ
112 wxDataFormat format( atoms[i] );
113
61b04ac6
VZ
114 wxLogTrace( TRACE_CLIPBOARD,
115 wxT("selection received for targets, format %s"),
116 format.GetId().c_str() );
270c23f7
VZ
117
118 if (format == clipboard->m_targetRequested)
119 {
120 clipboard->m_waiting = FALSE;
121 clipboard->m_formatSupported = TRUE;
122 return;
123 }
8b53e5a2
RR
124 }
125 }
b527aac5 126
034be888 127 clipboard->m_waiting = FALSE;
dc86cb34
RR
128}
129
130//-----------------------------------------------------------------------------
b527aac5 131// "selection_received" for the actual data
dc86cb34
RR
132//-----------------------------------------------------------------------------
133
270c23f7
VZ
134static void
135selection_received( GtkWidget *WXUNUSED(widget),
136 GtkSelectionData *selection_data,
034be888
RR
137#if (GTK_MINOR_VERSION > 0)
138 guint32 WXUNUSED(time),
139#endif
66633398 140 wxClipboard *clipboard )
dc86cb34 141{
034be888
RR
142 if (!wxTheClipboard)
143 {
144 clipboard->m_waiting = FALSE;
145 return;
146 }
270c23f7 147
8b53e5a2 148 wxDataObject *data_object = clipboard->m_receivedData;
1dd989e1 149
034be888
RR
150 if (!data_object)
151 {
152 clipboard->m_waiting = FALSE;
153 return;
154 }
270c23f7 155
034be888
RR
156 if (selection_data->length <= 0)
157 {
158 clipboard->m_waiting = FALSE;
159 return;
160 }
270c23f7 161
b068c4e8 162 wxDataFormat format( selection_data->target );
270c23f7 163
034be888 164 /* make sure we got the data in the correct format */
b068c4e8 165 if (!data_object->IsSupportedFormat( format ) )
034be888
RR
166 {
167 clipboard->m_waiting = FALSE;
168 return;
169 }
e2acb9ae 170
034be888
RR
171 /* make sure we got the data in the correct form (selection type).
172 if so, copy data to target object */
e5d6aa22 173 if (selection_data->type != GDK_SELECTION_TYPE_STRING)
8b53e5a2 174 {
e5d6aa22
RR
175 clipboard->m_waiting = FALSE;
176 return;
8b53e5a2 177 }
270c23f7 178
e5d6aa22 179 data_object->SetData( format, (size_t) selection_data->length, (const char*) selection_data->data );
270c23f7 180
8b53e5a2 181 wxTheClipboard->m_formatSupported = TRUE;
034be888 182 clipboard->m_waiting = FALSE;
dc86cb34 183}
fd0eed64
RR
184
185//-----------------------------------------------------------------------------
186// "selection_clear"
187//-----------------------------------------------------------------------------
188
189static gint
aeeb6a44 190selection_clear_clip( GtkWidget *WXUNUSED(widget), GdkEventSelection *event )
fd0eed64 191{
8b53e5a2 192 if (!wxTheClipboard) return TRUE;
270c23f7 193
aeeb6a44
RR
194 if (event->selection == GDK_SELECTION_PRIMARY)
195 {
196 wxTheClipboard->m_ownsPrimarySelection = FALSE;
197 }
198 else
199 if (event->selection == g_clipboardAtom)
200 {
201 wxTheClipboard->m_ownsClipboard = FALSE;
202 }
203 else
204 {
e5ea3f7a 205 wxTheClipboard->m_waiting = FALSE;
aeeb6a44
RR
206 return FALSE;
207 }
270c23f7 208
aeeb6a44
RR
209 if ((!wxTheClipboard->m_ownsPrimarySelection) &&
210 (!wxTheClipboard->m_ownsClipboard))
211 {
db2d879a 212 /* the clipboard is no longer in our hands. we can the delete clipboard data. */
1dd989e1 213 if (wxTheClipboard->m_data)
66633398 214 {
47cf53ef 215 wxLogTrace(TRACE_CLIPBOARD, wxT("wxClipboard will get cleared" ));
270c23f7 216
66633398
VZ
217 delete wxTheClipboard->m_data;
218 wxTheClipboard->m_data = (wxDataObject*) NULL;
219 }
aeeb6a44 220 }
270c23f7 221
e5ea3f7a 222 wxTheClipboard->m_waiting = FALSE;
8b53e5a2 223 return TRUE;
fd0eed64
RR
224}
225
226//-----------------------------------------------------------------------------
227// selection handler for supplying data
228//-----------------------------------------------------------------------------
229
230static void
19d89516
VZ
231selection_handler( GtkWidget *WXUNUSED(widget),
232 GtkSelectionData *selection_data,
233 guint WXUNUSED(info),
234 guint WXUNUSED(time),
235 gpointer WXUNUSED(data) )
fd0eed64 236{
8b53e5a2 237 if (!wxTheClipboard) return;
270c23f7 238
1dd989e1 239 if (!wxTheClipboard->m_data) return;
270c23f7 240
1dd989e1 241 wxDataObject *data = wxTheClipboard->m_data;
270c23f7 242
b068c4e8
RR
243 wxDataFormat format( selection_data->target );
244
245 if (!data->IsSupportedFormat( format )) return;
270c23f7 246
b068c4e8 247 int size = data->GetDataSize( format );
270c23f7 248
1dd989e1 249 if (size == 0) return;
270c23f7 250
33754c4d
VZ
251 void *d = malloc(size);
252
253 data->GetDataHere( selection_data->target, d );
270c23f7 254
33754c4d
VZ
255 // transform Unicode text into multibyte before putting it on clipboard
256#if wxUSE_UNICODE
257 if ( format.GetType() == wxDF_TEXT )
258 {
259 const wchar_t *wstr = (const wchar_t *)d;
260 size_t len = wxConvCurrent->WC2MB(NULL, wstr, 0);
261 char *str = malloc(len + 1);
262 wxConvCurrent->WC2MB(str, wstr, len);
263 str[len] = '\0';
264
265 free(d);
266 d = str;
267 }
268#endif // wxUSE_UNICODE
1dd989e1 269
270c23f7
VZ
270 gtk_selection_data_set(
271 selection_data,
272 GDK_SELECTION_TYPE_STRING,
273 8*sizeof(gchar),
66633398 274 (unsigned char*) d,
270c23f7 275 size );
33754c4d
VZ
276
277 free(d);
fd0eed64 278}
dc86cb34
RR
279
280//-----------------------------------------------------------------------------
281// wxClipboard
282//-----------------------------------------------------------------------------
283
284IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
285
286wxClipboard::wxClipboard()
287{
8b53e5a2
RR
288 m_open = FALSE;
289
aeeb6a44
RR
290 m_ownsClipboard = FALSE;
291 m_ownsPrimarySelection = FALSE;
292
1dd989e1 293 m_data = (wxDataObject*) NULL;
8b53e5a2 294 m_receivedData = (wxDataObject*) NULL;
99c67c77 295
034be888 296 /* we use m_targetsWidget to query what formats are available */
270c23f7 297
034be888
RR
298 m_targetsWidget = gtk_window_new( GTK_WINDOW_POPUP );
299 gtk_widget_realize( m_targetsWidget );
300
270c23f7 301 gtk_signal_connect( GTK_OBJECT(m_targetsWidget),
034be888 302 "selection_received",
270c23f7 303 GTK_SIGNAL_FUNC( targets_selection_received ),
66633398 304 (gpointer) this );
270c23f7 305
034be888 306 /* we use m_clipboardWidget to get and to offer data */
270c23f7 307
8b53e5a2
RR
308 m_clipboardWidget = gtk_window_new( GTK_WINDOW_POPUP );
309 gtk_widget_realize( m_clipboardWidget );
310
270c23f7 311 gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
034be888 312 "selection_received",
270c23f7 313 GTK_SIGNAL_FUNC( selection_received ),
66633398 314 (gpointer) this );
034be888 315
270c23f7 316 gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
8b53e5a2 317 "selection_clear_event",
270c23f7 318 GTK_SIGNAL_FUNC( selection_clear_clip ),
66633398 319 (gpointer) NULL );
270c23f7 320
8b53e5a2 321 if (!g_clipboardAtom) g_clipboardAtom = gdk_atom_intern( "CLIPBOARD", FALSE );
8b53e5a2 322 if (!g_targetsAtom) g_targetsAtom = gdk_atom_intern ("TARGETS", FALSE);
270c23f7 323
8b53e5a2
RR
324 m_formatSupported = FALSE;
325 m_targetRequested = 0;
270c23f7 326
7e2c43b8 327 m_usePrimary = FALSE;
dc86cb34
RR
328}
329
330wxClipboard::~wxClipboard()
b527aac5 331{
270c23f7
VZ
332 Clear();
333
8b53e5a2 334 if (m_clipboardWidget) gtk_widget_destroy( m_clipboardWidget );
034be888 335 if (m_targetsWidget) gtk_widget_destroy( m_targetsWidget );
b527aac5
RR
336}
337
338void wxClipboard::Clear()
dc86cb34 339{
1dd989e1
RR
340 if (m_data)
341 {
b453e1b2
RR
342#if wxUSE_THREADS
343 /* disable GUI threads */
344 wxapp_uninstall_thread_wakeup();
345#endif
270c23f7 346
8b53e5a2
RR
347 /* As we have data we also own the clipboard. Once we no longer own
348 it, clear_selection is called which will set m_data to zero */
aeeb6a44 349 if (gdk_selection_owner_get( g_clipboardAtom ) == m_clipboardWidget->window)
8b53e5a2 350 {
e5ea3f7a 351 m_waiting = TRUE;
270c23f7 352
b02da6b1
VZ
353 gtk_selection_owner_set( (GtkWidget*) NULL, g_clipboardAtom,
354 (guint32) GDK_CURRENT_TIME );
270c23f7 355
e5ea3f7a 356 while (m_waiting) gtk_main_iteration();
8b53e5a2 357 }
270c23f7 358
aeeb6a44
RR
359 if (gdk_selection_owner_get( GDK_SELECTION_PRIMARY ) == m_clipboardWidget->window)
360 {
e5ea3f7a 361 m_waiting = TRUE;
270c23f7 362
b02da6b1
VZ
363 gtk_selection_owner_set( (GtkWidget*) NULL, GDK_SELECTION_PRIMARY,
364 (guint32) GDK_CURRENT_TIME );
270c23f7 365
e5ea3f7a 366 while (m_waiting) gtk_main_iteration();
aeeb6a44 367 }
270c23f7 368
1dd989e1 369 if (m_data)
270c23f7 370 {
66633398
VZ
371 delete m_data;
372 m_data = (wxDataObject*) NULL;
373 }
270c23f7 374
b453e1b2
RR
375#if wxUSE_THREADS
376 /* re-enable GUI threads */
377 wxapp_install_thread_wakeup();
378#endif
8b53e5a2 379 }
270c23f7 380
8b53e5a2 381 m_targetRequested = 0;
8b53e5a2
RR
382 m_formatSupported = FALSE;
383}
384
385bool wxClipboard::Open()
386{
223d09f6 387 wxCHECK_MSG( !m_open, FALSE, wxT("clipboard already open") );
270c23f7 388
8b53e5a2 389 m_open = TRUE;
270c23f7 390
8b53e5a2 391 return TRUE;
dc86cb34
RR
392}
393
75ce0581 394bool wxClipboard::SetData( wxDataObject *data )
dc86cb34 395{
223d09f6 396 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
270c23f7 397
223d09f6 398 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
270c23f7 399
0d2a2b60 400 Clear();
75ce0581
RR
401
402 return AddData( data );
403}
404
405bool wxClipboard::AddData( wxDataObject *data )
406{
223d09f6 407 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
270c23f7 408
223d09f6 409 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
270c23f7 410
b068c4e8 411 /* we can only store one wxDataObject */
1dd989e1 412 Clear();
270c23f7 413
1dd989e1
RR
414 m_data = data;
415
b068c4e8
RR
416 /* get formats from wxDataObjects */
417 wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ];
418 m_data->GetAllFormats( array );
11e1c70d
RR
419
420 /* primary selection or clipboard */
421 GdkAtom clipboard = m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
422 : g_clipboardAtom;
423
270c23f7 424
b068c4e8
RR
425 for (size_t i = 0; i < m_data->GetFormatCount(); i++)
426 {
61b04ac6
VZ
427 wxLogTrace( TRACE_CLIPBOARD,
428 wxT("wxClipboard now supports atom %s"),
429 array[i].GetId().c_str() );
11e1c70d
RR
430
431 gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget),
270c23f7
VZ
432 clipboard,
433 array[i],
11e1c70d 434 0 ); /* what is info ? */
b068c4e8
RR
435 }
436
437 delete[] array;
270c23f7
VZ
438
439 gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
d345e841 440 "selection_get",
270c23f7 441 GTK_SIGNAL_FUNC(selection_handler),
66633398 442 (gpointer) NULL );
d345e841 443
b453e1b2 444#if wxUSE_THREADS
11e1c70d
RR
445 /* disable GUI threads */
446 wxapp_uninstall_thread_wakeup();
b453e1b2 447#endif
270c23f7 448
75ce0581 449 /* Tell the world we offer clipboard data */
11e1c70d
RR
450 bool res = (gtk_selection_owner_set( m_clipboardWidget,
451 clipboard,
b02da6b1 452 (guint32) GDK_CURRENT_TIME ));
270c23f7 453
11e1c70d
RR
454 if (m_usePrimary)
455 m_ownsPrimarySelection = res;
456 else
457 m_ownsClipboard = res;
270c23f7 458
b453e1b2
RR
459#if wxUSE_THREADS
460 /* re-enable GUI threads */
461 wxapp_install_thread_wakeup();
462#endif
270c23f7 463
11e1c70d 464 return res;
8b53e5a2 465}
db1b4961 466
8b53e5a2
RR
467void wxClipboard::Close()
468{
223d09f6 469 wxCHECK_RET( m_open, wxT("clipboard not open") );
270c23f7 470
8b53e5a2 471 m_open = FALSE;
dc86cb34
RR
472}
473
f536e0f2
VZ
474bool wxClipboard::IsOpened() const
475{
476 return m_open;
477}
478
e1ee679c 479bool wxClipboard::IsSupported( const wxDataFormat& format )
b527aac5 480{
e5d6aa22 481 /* reentrance problems */
eff869aa 482 if (m_waiting) return FALSE;
270c23f7 483
e5d6aa22 484 /* store requested format to be asked for by callbacks */
1dd989e1 485 m_targetRequested = format;
270c23f7 486
72a7edf0 487#if 0
61b04ac6
VZ
488 wxLogTrace( TRACE_CLIPBOARD,
489 wxT("wxClipboard:IsSupported: requested format: %s"),
490 format.GetId().c_str() );
72a7edf0 491#endif
eff869aa 492
223d09f6 493 wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
270c23f7 494
8b53e5a2 495 m_formatSupported = FALSE;
270c23f7
VZ
496
497 /* perform query. this will set m_formatSupported to
034be888 498 TRUE if m_targetRequested is supported.
270c23f7 499 also, we have to wait for the "answer" from the
034be888
RR
500 clipboard owner which is an asynchronous process.
501 therefore we set m_waiting = TRUE here and wait
270c23f7 502 until the callback "targets_selection_received"
034be888
RR
503 sets it to FALSE */
504
505 m_waiting = TRUE;
ca35e608 506
034be888 507 gtk_selection_convert( m_targetsWidget,
66633398 508 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 509 : g_clipboardAtom,
66633398 510 g_targetsAtom,
b02da6b1 511 (guint32) GDK_CURRENT_TIME );
ca35e608 512
034be888 513 while (m_waiting) gtk_main_iteration();
270c23f7 514
8b53e5a2 515 if (!m_formatSupported) return FALSE;
270c23f7 516
75ce0581 517 return TRUE;
270c23f7
VZ
518}
519
e1ee679c 520bool wxClipboard::GetData( wxDataObject& data )
75ce0581 521{
223d09f6 522 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
270c23f7 523
b068c4e8
RR
524 /* get formats from wxDataObjects */
525 wxDataFormat *array = new wxDataFormat[ data.GetFormatCount() ];
526 data.GetAllFormats( array );
270c23f7 527
b068c4e8
RR
528 for (size_t i = 0; i < data.GetFormatCount(); i++)
529 {
e5d6aa22 530 wxDataFormat format( array[i] );
270c23f7 531
61b04ac6
VZ
532 wxLogTrace( TRACE_CLIPBOARD,
533 wxT("wxClipboard::GetData: requested format: %s"),
534 format.GetId().c_str() );
270c23f7 535
b068c4e8 536 /* is data supported by clipboard ? */
270c23f7 537
11e1c70d
RR
538 /* store requested format to be asked for by callbacks */
539 m_targetRequested = format;
270c23f7 540
11e1c70d 541 wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
270c23f7 542
11e1c70d 543 m_formatSupported = FALSE;
270c23f7
VZ
544
545 /* perform query. this will set m_formatSupported to
11e1c70d 546 TRUE if m_targetRequested is supported.
270c23f7 547 also, we have to wait for the "answer" from the
11e1c70d
RR
548 clipboard owner which is an asynchronous process.
549 therefore we set m_waiting = TRUE here and wait
270c23f7 550 until the callback "targets_selection_received"
11e1c70d
RR
551 sets it to FALSE */
552
553 m_waiting = TRUE;
554
555 gtk_selection_convert( m_targetsWidget,
556 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 557 : g_clipboardAtom,
11e1c70d 558 g_targetsAtom,
b02da6b1 559 (guint32) GDK_CURRENT_TIME );
11e1c70d
RR
560
561 while (m_waiting) gtk_main_iteration();
270c23f7 562
11e1c70d 563 if (!m_formatSupported) continue;
270c23f7 564
b068c4e8
RR
565 /* store pointer to data object to be filled up by callbacks */
566 m_receivedData = &data;
270c23f7 567
b068c4e8 568 /* store requested format to be asked for by callbacks */
e5d6aa22 569 m_targetRequested = format;
270c23f7 570
b068c4e8 571 wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
270c23f7 572
b068c4e8
RR
573 /* start query */
574 m_formatSupported = FALSE;
270c23f7
VZ
575
576 /* ask for clipboard contents. this will set
577 m_formatSupported to TRUE if m_targetRequested
b068c4e8 578 is supported.
270c23f7 579 also, we have to wait for the "answer" from the
b068c4e8
RR
580 clipboard owner which is an asynchronous process.
581 therefore we set m_waiting = TRUE here and wait
270c23f7 582 until the callback "targets_selection_received"
b068c4e8
RR
583 sets it to FALSE */
584
585 m_waiting = TRUE;
586
47cf53ef
VZ
587 wxLogTrace( TRACE_CLIPBOARD,
588 wxT("wxClipboard::GetData: format found, start convert") );
270c23f7 589
b068c4e8 590 gtk_selection_convert( m_clipboardWidget,
66633398 591 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 592 : g_clipboardAtom,
66633398 593 m_targetRequested,
b02da6b1 594 (guint32) GDK_CURRENT_TIME );
270c23f7 595
b068c4e8 596 while (m_waiting) gtk_main_iteration();
b527aac5 597
b068c4e8
RR
598 /* this is a true error as we checked for the presence of such data before */
599 wxCHECK_MSG( m_formatSupported, FALSE, wxT("error retrieving data from clipboard") );
270c23f7 600
66633398 601 /* return success */
b068c4e8
RR
602 delete[] array;
603 return TRUE;
604 }
270c23f7 605
47cf53ef
VZ
606 wxLogTrace( TRACE_CLIPBOARD,
607 wxT("wxClipboard::GetData: format not found") );
270c23f7 608
b068c4e8
RR
609 /* return failure */
610 delete[] array;
611 return FALSE;
b527aac5
RR
612}
613
ac57418f 614#endif
ac57418f
RR
615 // wxUSE_CLIPBOARD
616