]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/clipbrd.cpp
* Fixed wxToolbar95 and wxToolbarGTK to emit TOOL_ENTER event with id==-1 when the...
[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
e5d6aa22 247 /* this will fail for composite formats */
b068c4e8 248 if (format.GetType() == wxDF_TEXT)
8b53e5a2 249 {
66633398
VZ
250 wxTextDataObject *text_object = (wxTextDataObject*) data;
251 wxString text( text_object->GetText() );
1dd989e1 252
93c5dd39 253#if wxUSE_UNICODE
66633398
VZ
254 const wxWX2MBbuf s = text.mbc_str();
255 int len = strlen(s);
93c5dd39 256#else // more efficient in non-Unicode
66633398
VZ
257 const char *s = text.c_str();
258 int len = (int) text.Length();
93c5dd39 259#endif
270c23f7
VZ
260 gtk_selection_data_set(
261 selection_data,
262 GDK_SELECTION_TYPE_STRING,
66633398
VZ
263 8*sizeof(gchar),
264 (unsigned char*) (const char*) s,
270c23f7
VZ
265 len );
266
66633398 267 return;
1dd989e1
RR
268 }
269
b068c4e8 270 int size = data->GetDataSize( format );
270c23f7 271
1dd989e1 272 if (size == 0) return;
270c23f7 273
1dd989e1 274 char *d = new char[size];
270c23f7 275
1dd989e1
RR
276 data->GetDataHere( selection_data->target, (void*) d );
277
270c23f7
VZ
278 gtk_selection_data_set(
279 selection_data,
280 GDK_SELECTION_TYPE_STRING,
281 8*sizeof(gchar),
66633398 282 (unsigned char*) d,
270c23f7 283 size );
fd0eed64 284}
dc86cb34
RR
285
286//-----------------------------------------------------------------------------
287// wxClipboard
288//-----------------------------------------------------------------------------
289
290IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
291
292wxClipboard::wxClipboard()
293{
8b53e5a2
RR
294 m_open = FALSE;
295
aeeb6a44
RR
296 m_ownsClipboard = FALSE;
297 m_ownsPrimarySelection = FALSE;
298
1dd989e1 299 m_data = (wxDataObject*) NULL;
8b53e5a2 300 m_receivedData = (wxDataObject*) NULL;
99c67c77 301
034be888 302 /* we use m_targetsWidget to query what formats are available */
270c23f7 303
034be888
RR
304 m_targetsWidget = gtk_window_new( GTK_WINDOW_POPUP );
305 gtk_widget_realize( m_targetsWidget );
306
270c23f7 307 gtk_signal_connect( GTK_OBJECT(m_targetsWidget),
034be888 308 "selection_received",
270c23f7 309 GTK_SIGNAL_FUNC( targets_selection_received ),
66633398 310 (gpointer) this );
270c23f7 311
034be888 312 /* we use m_clipboardWidget to get and to offer data */
270c23f7 313
8b53e5a2
RR
314 m_clipboardWidget = gtk_window_new( GTK_WINDOW_POPUP );
315 gtk_widget_realize( m_clipboardWidget );
316
270c23f7 317 gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
034be888 318 "selection_received",
270c23f7 319 GTK_SIGNAL_FUNC( selection_received ),
66633398 320 (gpointer) this );
034be888 321
270c23f7 322 gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
8b53e5a2 323 "selection_clear_event",
270c23f7 324 GTK_SIGNAL_FUNC( selection_clear_clip ),
66633398 325 (gpointer) NULL );
270c23f7 326
8b53e5a2 327 if (!g_clipboardAtom) g_clipboardAtom = gdk_atom_intern( "CLIPBOARD", FALSE );
8b53e5a2 328 if (!g_targetsAtom) g_targetsAtom = gdk_atom_intern ("TARGETS", FALSE);
270c23f7 329
8b53e5a2
RR
330 m_formatSupported = FALSE;
331 m_targetRequested = 0;
270c23f7 332
7e2c43b8 333 m_usePrimary = FALSE;
dc86cb34
RR
334}
335
336wxClipboard::~wxClipboard()
b527aac5 337{
270c23f7
VZ
338 Clear();
339
8b53e5a2 340 if (m_clipboardWidget) gtk_widget_destroy( m_clipboardWidget );
034be888 341 if (m_targetsWidget) gtk_widget_destroy( m_targetsWidget );
b527aac5
RR
342}
343
344void wxClipboard::Clear()
dc86cb34 345{
1dd989e1
RR
346 if (m_data)
347 {
b453e1b2
RR
348#if wxUSE_THREADS
349 /* disable GUI threads */
350 wxapp_uninstall_thread_wakeup();
351#endif
270c23f7 352
8b53e5a2
RR
353 /* As we have data we also own the clipboard. Once we no longer own
354 it, clear_selection is called which will set m_data to zero */
aeeb6a44 355 if (gdk_selection_owner_get( g_clipboardAtom ) == m_clipboardWidget->window)
8b53e5a2 356 {
e5ea3f7a 357 m_waiting = TRUE;
270c23f7 358
b02da6b1
VZ
359 gtk_selection_owner_set( (GtkWidget*) NULL, g_clipboardAtom,
360 (guint32) GDK_CURRENT_TIME );
270c23f7 361
e5ea3f7a 362 while (m_waiting) gtk_main_iteration();
8b53e5a2 363 }
270c23f7 364
aeeb6a44
RR
365 if (gdk_selection_owner_get( GDK_SELECTION_PRIMARY ) == m_clipboardWidget->window)
366 {
e5ea3f7a 367 m_waiting = TRUE;
270c23f7 368
b02da6b1
VZ
369 gtk_selection_owner_set( (GtkWidget*) NULL, GDK_SELECTION_PRIMARY,
370 (guint32) GDK_CURRENT_TIME );
270c23f7 371
e5ea3f7a 372 while (m_waiting) gtk_main_iteration();
aeeb6a44 373 }
270c23f7 374
1dd989e1 375 if (m_data)
270c23f7 376 {
66633398
VZ
377 delete m_data;
378 m_data = (wxDataObject*) NULL;
379 }
270c23f7 380
b453e1b2
RR
381#if wxUSE_THREADS
382 /* re-enable GUI threads */
383 wxapp_install_thread_wakeup();
384#endif
8b53e5a2 385 }
270c23f7 386
8b53e5a2 387 m_targetRequested = 0;
8b53e5a2
RR
388 m_formatSupported = FALSE;
389}
390
391bool wxClipboard::Open()
392{
223d09f6 393 wxCHECK_MSG( !m_open, FALSE, wxT("clipboard already open") );
270c23f7 394
8b53e5a2 395 m_open = TRUE;
270c23f7 396
8b53e5a2 397 return TRUE;
dc86cb34
RR
398}
399
75ce0581 400bool wxClipboard::SetData( wxDataObject *data )
dc86cb34 401{
223d09f6 402 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
270c23f7 403
223d09f6 404 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
270c23f7 405
0d2a2b60 406 Clear();
75ce0581
RR
407
408 return AddData( data );
409}
410
411bool wxClipboard::AddData( wxDataObject *data )
412{
223d09f6 413 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
270c23f7 414
223d09f6 415 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
270c23f7 416
b068c4e8 417 /* we can only store one wxDataObject */
1dd989e1 418 Clear();
270c23f7 419
1dd989e1
RR
420 m_data = data;
421
b068c4e8
RR
422 /* get formats from wxDataObjects */
423 wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ];
424 m_data->GetAllFormats( array );
11e1c70d
RR
425
426 /* primary selection or clipboard */
427 GdkAtom clipboard = m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
428 : g_clipboardAtom;
429
270c23f7 430
b068c4e8
RR
431 for (size_t i = 0; i < m_data->GetFormatCount(); i++)
432 {
61b04ac6
VZ
433 wxLogTrace( TRACE_CLIPBOARD,
434 wxT("wxClipboard now supports atom %s"),
435 array[i].GetId().c_str() );
11e1c70d
RR
436
437 gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget),
270c23f7
VZ
438 clipboard,
439 array[i],
11e1c70d 440 0 ); /* what is info ? */
b068c4e8
RR
441 }
442
443 delete[] array;
270c23f7
VZ
444
445 gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
d345e841 446 "selection_get",
270c23f7 447 GTK_SIGNAL_FUNC(selection_handler),
66633398 448 (gpointer) NULL );
d345e841 449
b453e1b2 450#if wxUSE_THREADS
11e1c70d
RR
451 /* disable GUI threads */
452 wxapp_uninstall_thread_wakeup();
b453e1b2 453#endif
270c23f7 454
75ce0581 455 /* Tell the world we offer clipboard data */
11e1c70d
RR
456 bool res = (gtk_selection_owner_set( m_clipboardWidget,
457 clipboard,
b02da6b1 458 (guint32) GDK_CURRENT_TIME ));
270c23f7 459
11e1c70d
RR
460 if (m_usePrimary)
461 m_ownsPrimarySelection = res;
462 else
463 m_ownsClipboard = res;
270c23f7 464
b453e1b2
RR
465#if wxUSE_THREADS
466 /* re-enable GUI threads */
467 wxapp_install_thread_wakeup();
468#endif
270c23f7 469
11e1c70d 470 return res;
8b53e5a2 471}
db1b4961 472
8b53e5a2
RR
473void wxClipboard::Close()
474{
223d09f6 475 wxCHECK_RET( m_open, wxT("clipboard not open") );
270c23f7 476
8b53e5a2 477 m_open = FALSE;
dc86cb34
RR
478}
479
f536e0f2
VZ
480bool wxClipboard::IsOpened() const
481{
482 return m_open;
483}
484
e1ee679c 485bool wxClipboard::IsSupported( const wxDataFormat& format )
b527aac5 486{
e5d6aa22 487 /* reentrance problems */
eff869aa 488 if (m_waiting) return FALSE;
270c23f7 489
e5d6aa22 490 /* store requested format to be asked for by callbacks */
1dd989e1 491 m_targetRequested = format;
270c23f7 492
72a7edf0 493#if 0
61b04ac6
VZ
494 wxLogTrace( TRACE_CLIPBOARD,
495 wxT("wxClipboard:IsSupported: requested format: %s"),
496 format.GetId().c_str() );
72a7edf0 497#endif
eff869aa 498
223d09f6 499 wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
270c23f7 500
8b53e5a2 501 m_formatSupported = FALSE;
270c23f7
VZ
502
503 /* perform query. this will set m_formatSupported to
034be888 504 TRUE if m_targetRequested is supported.
270c23f7 505 also, we have to wait for the "answer" from the
034be888
RR
506 clipboard owner which is an asynchronous process.
507 therefore we set m_waiting = TRUE here and wait
270c23f7 508 until the callback "targets_selection_received"
034be888
RR
509 sets it to FALSE */
510
511 m_waiting = TRUE;
ca35e608 512
034be888 513 gtk_selection_convert( m_targetsWidget,
66633398 514 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 515 : g_clipboardAtom,
66633398 516 g_targetsAtom,
b02da6b1 517 (guint32) GDK_CURRENT_TIME );
ca35e608 518
034be888 519 while (m_waiting) gtk_main_iteration();
270c23f7 520
8b53e5a2 521 if (!m_formatSupported) return FALSE;
270c23f7 522
75ce0581 523 return TRUE;
270c23f7
VZ
524}
525
e1ee679c 526bool wxClipboard::GetData( wxDataObject& data )
75ce0581 527{
223d09f6 528 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
270c23f7 529
b068c4e8
RR
530 /* get formats from wxDataObjects */
531 wxDataFormat *array = new wxDataFormat[ data.GetFormatCount() ];
532 data.GetAllFormats( array );
270c23f7 533
b068c4e8
RR
534 for (size_t i = 0; i < data.GetFormatCount(); i++)
535 {
e5d6aa22 536 wxDataFormat format( array[i] );
270c23f7 537
61b04ac6
VZ
538 wxLogTrace( TRACE_CLIPBOARD,
539 wxT("wxClipboard::GetData: requested format: %s"),
540 format.GetId().c_str() );
270c23f7 541
b068c4e8 542 /* is data supported by clipboard ? */
270c23f7 543
11e1c70d
RR
544 /* store requested format to be asked for by callbacks */
545 m_targetRequested = format;
270c23f7 546
11e1c70d 547 wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
270c23f7 548
11e1c70d 549 m_formatSupported = FALSE;
270c23f7
VZ
550
551 /* perform query. this will set m_formatSupported to
11e1c70d 552 TRUE if m_targetRequested is supported.
270c23f7 553 also, we have to wait for the "answer" from the
11e1c70d
RR
554 clipboard owner which is an asynchronous process.
555 therefore we set m_waiting = TRUE here and wait
270c23f7 556 until the callback "targets_selection_received"
11e1c70d
RR
557 sets it to FALSE */
558
559 m_waiting = TRUE;
560
561 gtk_selection_convert( m_targetsWidget,
562 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 563 : g_clipboardAtom,
11e1c70d 564 g_targetsAtom,
b02da6b1 565 (guint32) GDK_CURRENT_TIME );
11e1c70d
RR
566
567 while (m_waiting) gtk_main_iteration();
270c23f7 568
11e1c70d 569 if (!m_formatSupported) continue;
270c23f7 570
b068c4e8
RR
571 /* store pointer to data object to be filled up by callbacks */
572 m_receivedData = &data;
270c23f7 573
b068c4e8 574 /* store requested format to be asked for by callbacks */
e5d6aa22 575 m_targetRequested = format;
270c23f7 576
b068c4e8 577 wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
270c23f7 578
b068c4e8
RR
579 /* start query */
580 m_formatSupported = FALSE;
270c23f7
VZ
581
582 /* ask for clipboard contents. this will set
583 m_formatSupported to TRUE if m_targetRequested
b068c4e8 584 is supported.
270c23f7 585 also, we have to wait for the "answer" from the
b068c4e8
RR
586 clipboard owner which is an asynchronous process.
587 therefore we set m_waiting = TRUE here and wait
270c23f7 588 until the callback "targets_selection_received"
b068c4e8
RR
589 sets it to FALSE */
590
591 m_waiting = TRUE;
592
47cf53ef
VZ
593 wxLogTrace( TRACE_CLIPBOARD,
594 wxT("wxClipboard::GetData: format found, start convert") );
270c23f7 595
b068c4e8 596 gtk_selection_convert( m_clipboardWidget,
66633398 597 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 598 : g_clipboardAtom,
66633398 599 m_targetRequested,
b02da6b1 600 (guint32) GDK_CURRENT_TIME );
270c23f7 601
b068c4e8 602 while (m_waiting) gtk_main_iteration();
b527aac5 603
b068c4e8
RR
604 /* this is a true error as we checked for the presence of such data before */
605 wxCHECK_MSG( m_formatSupported, FALSE, wxT("error retrieving data from clipboard") );
270c23f7 606
66633398 607 /* return success */
b068c4e8
RR
608 delete[] array;
609 return TRUE;
610 }
270c23f7 611
47cf53ef
VZ
612 wxLogTrace( TRACE_CLIPBOARD,
613 wxT("wxClipboard::GetData: format not found") );
270c23f7 614
b068c4e8
RR
615 /* return failure */
616 delete[] array;
617 return FALSE;
b527aac5
RR
618}
619
ac57418f 620#endif
ac57418f
RR
621 // wxUSE_CLIPBOARD
622