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