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