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