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