]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/clipbrd.cpp
implementing pure carbon event behaviour, getting rid of doubly executed events
[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
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
c7d6d883
RR
39#if defined(__WXGTK20__) && wxUSE_UNICODE
40extern GdkAtom g_altTextAtom;
41#endif
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
865bb325 77extern "C" {
b527aac5 78static void
270c23f7
VZ
79targets_selection_received( GtkWidget *WXUNUSED(widget),
80 GtkSelectionData *selection_data,
034be888 81 guint32 WXUNUSED(time),
66633398 82 wxClipboard *clipboard )
dc86cb34 83{
270c23f7 84 if ( wxTheClipboard && selection_data->length > 0 )
034be888 85 {
ca11abde 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 117
3d257b8d 118// printf( "format %s requested %s\n",
ca11abde
RR
119// gdk_atom_name( atoms[i] ),
120// gdk_atom_name( clipboard->m_targetRequested ) );
121
270c23f7
VZ
122 if (format == clipboard->m_targetRequested)
123 {
124 clipboard->m_waiting = FALSE;
125 clipboard->m_formatSupported = TRUE;
126 return;
127 }
8b53e5a2
RR
128 }
129 }
b527aac5 130
034be888 131 clipboard->m_waiting = FALSE;
dc86cb34 132}
865bb325 133}
dc86cb34
RR
134
135//-----------------------------------------------------------------------------
b527aac5 136// "selection_received" for the actual data
dc86cb34
RR
137//-----------------------------------------------------------------------------
138
865bb325 139extern "C" {
270c23f7
VZ
140static void
141selection_received( GtkWidget *WXUNUSED(widget),
142 GtkSelectionData *selection_data,
034be888 143 guint32 WXUNUSED(time),
66633398 144 wxClipboard *clipboard )
dc86cb34 145{
034be888
RR
146 if (!wxTheClipboard)
147 {
148 clipboard->m_waiting = FALSE;
149 return;
150 }
270c23f7 151
8b53e5a2 152 wxDataObject *data_object = clipboard->m_receivedData;
1dd989e1 153
034be888
RR
154 if (!data_object)
155 {
156 clipboard->m_waiting = FALSE;
157 return;
158 }
270c23f7 159
034be888
RR
160 if (selection_data->length <= 0)
161 {
162 clipboard->m_waiting = FALSE;
163 return;
164 }
270c23f7 165
b068c4e8 166 wxDataFormat format( selection_data->target );
270c23f7 167
ca11abde 168 // make sure we got the data in the correct format
b068c4e8 169 if (!data_object->IsSupportedFormat( format ) )
034be888
RR
170 {
171 clipboard->m_waiting = FALSE;
172 return;
173 }
e2acb9ae 174
c7d6d883
RR
175#if 0
176 This seems to cause problems somehow
177 // make sure we got the data in the correct form (selection type).
178 // if so, copy data to target object
e5d6aa22 179 if (selection_data->type != GDK_SELECTION_TYPE_STRING)
8b53e5a2 180 {
e5d6aa22
RR
181 clipboard->m_waiting = FALSE;
182 return;
8b53e5a2 183 }
c7d6d883 184#endif
270c23f7 185
e5d6aa22 186 data_object->SetData( format, (size_t) selection_data->length, (const char*) selection_data->data );
270c23f7 187
8b53e5a2 188 wxTheClipboard->m_formatSupported = TRUE;
034be888 189 clipboard->m_waiting = FALSE;
dc86cb34 190}
865bb325 191}
fd0eed64
RR
192
193//-----------------------------------------------------------------------------
194// "selection_clear"
195//-----------------------------------------------------------------------------
196
865bb325 197extern "C" {
fd0eed64 198static gint
aeeb6a44 199selection_clear_clip( GtkWidget *WXUNUSED(widget), GdkEventSelection *event )
fd0eed64 200{
8b53e5a2 201 if (!wxTheClipboard) return TRUE;
270c23f7 202
aeeb6a44
RR
203 if (event->selection == GDK_SELECTION_PRIMARY)
204 {
205 wxTheClipboard->m_ownsPrimarySelection = FALSE;
206 }
207 else
208 if (event->selection == g_clipboardAtom)
209 {
210 wxTheClipboard->m_ownsClipboard = FALSE;
211 }
212 else
213 {
e5ea3f7a 214 wxTheClipboard->m_waiting = FALSE;
aeeb6a44
RR
215 return FALSE;
216 }
270c23f7 217
aeeb6a44
RR
218 if ((!wxTheClipboard->m_ownsPrimarySelection) &&
219 (!wxTheClipboard->m_ownsClipboard))
220 {
db2d879a 221 /* the clipboard is no longer in our hands. we can the delete clipboard data. */
1dd989e1 222 if (wxTheClipboard->m_data)
66633398 223 {
47cf53ef 224 wxLogTrace(TRACE_CLIPBOARD, wxT("wxClipboard will get cleared" ));
270c23f7 225
66633398
VZ
226 delete wxTheClipboard->m_data;
227 wxTheClipboard->m_data = (wxDataObject*) NULL;
228 }
aeeb6a44 229 }
270c23f7 230
e5ea3f7a 231 wxTheClipboard->m_waiting = FALSE;
8b53e5a2 232 return TRUE;
fd0eed64 233}
865bb325 234}
fd0eed64
RR
235
236//-----------------------------------------------------------------------------
237// selection handler for supplying data
238//-----------------------------------------------------------------------------
239
865bb325 240extern "C" {
fd0eed64 241static void
19d89516
VZ
242selection_handler( GtkWidget *WXUNUSED(widget),
243 GtkSelectionData *selection_data,
244 guint WXUNUSED(info),
245 guint WXUNUSED(time),
246 gpointer WXUNUSED(data) )
fd0eed64 247{
8b53e5a2 248 if (!wxTheClipboard) return;
270c23f7 249
1dd989e1 250 if (!wxTheClipboard->m_data) return;
270c23f7 251
1dd989e1 252 wxDataObject *data = wxTheClipboard->m_data;
270c23f7 253
b068c4e8
RR
254 wxDataFormat format( selection_data->target );
255
ebe47451
VS
256#ifdef __WXDEBUG__
257 wxLogTrace(TRACE_CLIPBOARD,
258 _T("clipboard data in format %s, GtkSelectionData is target=%s type=%s selection=%s"),
259 format.GetId().c_str(),
260 wxString::FromAscii(gdk_atom_name(selection_data->target)).c_str(),
261 wxString::FromAscii(gdk_atom_name(selection_data->type)).c_str(),
262 wxString::FromAscii(gdk_atom_name(selection_data->selection)).c_str()
263 );
264#endif
3d257b8d 265
b068c4e8 266 if (!data->IsSupportedFormat( format )) return;
270c23f7 267
b068c4e8 268 int size = data->GetDataSize( format );
270c23f7 269
1dd989e1 270 if (size == 0) return;
270c23f7 271
33754c4d
VZ
272 void *d = malloc(size);
273
ca11abde 274 // Text data will be in UTF8 in Unicode mode.
33754c4d 275 data->GetDataHere( selection_data->target, d );
270c23f7 276
ebe47451
VS
277 // NB: GTK+ requires special treatment of UTF8_STRING data, the text
278 // would show as UTF-8 data interpreted as latin1 (?) in other
279 // GTK+ apps if we used gtk_selection_data_set()
280 if (format == wxDataFormat(wxDF_UNICODETEXT))
281 {
282 gtk_selection_data_set_text(
283 selection_data,
284 (const gchar*)d,
c4e87706 285 size-1 );
ebe47451
VS
286 }
287 else
ebe47451
VS
288 {
289 gtk_selection_data_set(
290 selection_data,
291 GDK_SELECTION_TYPE_STRING,
292 8*sizeof(gchar),
293 (unsigned char*) d,
c4e87706 294 size-1 );
ebe47451 295 }
33754c4d
VZ
296
297 free(d);
fd0eed64 298}
865bb325 299}
dc86cb34
RR
300
301//-----------------------------------------------------------------------------
302// wxClipboard
303//-----------------------------------------------------------------------------
304
305IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
306
307wxClipboard::wxClipboard()
308{
8b53e5a2 309 m_open = FALSE;
3fc93ebd 310 m_waiting = FALSE;
8b53e5a2 311
aeeb6a44
RR
312 m_ownsClipboard = FALSE;
313 m_ownsPrimarySelection = FALSE;
314
1dd989e1 315 m_data = (wxDataObject*) NULL;
8b53e5a2 316 m_receivedData = (wxDataObject*) NULL;
99c67c77 317
034be888 318 /* we use m_targetsWidget to query what formats are available */
270c23f7 319
034be888
RR
320 m_targetsWidget = gtk_window_new( GTK_WINDOW_POPUP );
321 gtk_widget_realize( m_targetsWidget );
322
9fa72bd2
MR
323 g_signal_connect (m_targetsWidget, "selection_received",
324 G_CALLBACK (targets_selection_received), this);
270c23f7 325
034be888 326 /* we use m_clipboardWidget to get and to offer data */
270c23f7 327
8b53e5a2
RR
328 m_clipboardWidget = gtk_window_new( GTK_WINDOW_POPUP );
329 gtk_widget_realize( m_clipboardWidget );
330
9fa72bd2
MR
331 g_signal_connect (m_clipboardWidget, "selection_received",
332 G_CALLBACK (selection_received), this);
034be888 333
9fa72bd2
MR
334 g_signal_connect (m_clipboardWidget, "selection_clear_event",
335 G_CALLBACK (selection_clear_clip), NULL);
270c23f7 336
8b53e5a2 337 if (!g_clipboardAtom) g_clipboardAtom = gdk_atom_intern( "CLIPBOARD", FALSE );
8b53e5a2 338 if (!g_targetsAtom) g_targetsAtom = gdk_atom_intern ("TARGETS", FALSE);
270c23f7 339
8b53e5a2
RR
340 m_formatSupported = FALSE;
341 m_targetRequested = 0;
270c23f7 342
7e2c43b8 343 m_usePrimary = FALSE;
dc86cb34
RR
344}
345
346wxClipboard::~wxClipboard()
b527aac5 347{
270c23f7
VZ
348 Clear();
349
8b53e5a2 350 if (m_clipboardWidget) gtk_widget_destroy( m_clipboardWidget );
034be888 351 if (m_targetsWidget) gtk_widget_destroy( m_targetsWidget );
b527aac5
RR
352}
353
354void wxClipboard::Clear()
dc86cb34 355{
1dd989e1
RR
356 if (m_data)
357 {
b453e1b2
RR
358#if wxUSE_THREADS
359 /* disable GUI threads */
b453e1b2 360#endif
270c23f7 361
ca11abde
RR
362 // As we have data we also own the clipboard. Once we no longer own
363 // it, clear_selection is called which will set m_data to zero
aeeb6a44 364 if (gdk_selection_owner_get( g_clipboardAtom ) == m_clipboardWidget->window)
8b53e5a2 365 {
e5ea3f7a 366 m_waiting = TRUE;
270c23f7 367
b02da6b1
VZ
368 gtk_selection_owner_set( (GtkWidget*) NULL, g_clipboardAtom,
369 (guint32) GDK_CURRENT_TIME );
270c23f7 370
e5ea3f7a 371 while (m_waiting) gtk_main_iteration();
8b53e5a2 372 }
270c23f7 373
aeeb6a44
RR
374 if (gdk_selection_owner_get( GDK_SELECTION_PRIMARY ) == m_clipboardWidget->window)
375 {
e5ea3f7a 376 m_waiting = TRUE;
270c23f7 377
b02da6b1
VZ
378 gtk_selection_owner_set( (GtkWidget*) NULL, GDK_SELECTION_PRIMARY,
379 (guint32) GDK_CURRENT_TIME );
270c23f7 380
e5ea3f7a 381 while (m_waiting) gtk_main_iteration();
aeeb6a44 382 }
270c23f7 383
1dd989e1 384 if (m_data)
270c23f7 385 {
66633398
VZ
386 delete m_data;
387 m_data = (wxDataObject*) NULL;
388 }
270c23f7 389
b453e1b2
RR
390#if wxUSE_THREADS
391 /* re-enable GUI threads */
b453e1b2 392#endif
8b53e5a2 393 }
270c23f7 394
8b53e5a2 395 m_targetRequested = 0;
8b53e5a2
RR
396 m_formatSupported = FALSE;
397}
398
399bool wxClipboard::Open()
400{
223d09f6 401 wxCHECK_MSG( !m_open, FALSE, wxT("clipboard already open") );
270c23f7 402
8b53e5a2 403 m_open = TRUE;
270c23f7 404
8b53e5a2 405 return TRUE;
dc86cb34
RR
406}
407
75ce0581 408bool wxClipboard::SetData( wxDataObject *data )
dc86cb34 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
0d2a2b60 414 Clear();
75ce0581
RR
415
416 return AddData( data );
417}
418
419bool wxClipboard::AddData( wxDataObject *data )
420{
223d09f6 421 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
270c23f7 422
223d09f6 423 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
270c23f7 424
ca11abde 425 // we can only store one wxDataObject
1dd989e1 426 Clear();
270c23f7 427
1dd989e1
RR
428 m_data = data;
429
ca11abde 430 // get formats from wxDataObjects
b068c4e8
RR
431 wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ];
432 m_data->GetAllFormats( array );
11e1c70d 433
ca11abde 434 // primary selection or clipboard
11e1c70d
RR
435 GdkAtom clipboard = m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
436 : g_clipboardAtom;
437
270c23f7 438
b068c4e8
RR
439 for (size_t i = 0; i < m_data->GetFormatCount(); i++)
440 {
61b04ac6
VZ
441 wxLogTrace( TRACE_CLIPBOARD,
442 wxT("wxClipboard now supports atom %s"),
443 array[i].GetId().c_str() );
11e1c70d 444
3d257b8d 445// printf( "added %s\n",
ca11abde 446// gdk_atom_name( array[i].GetFormatId() ) );
3d257b8d 447
11e1c70d 448 gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget),
270c23f7
VZ
449 clipboard,
450 array[i],
11e1c70d 451 0 ); /* what is info ? */
b068c4e8
RR
452 }
453
454 delete[] array;
270c23f7 455
9fa72bd2
MR
456 g_signal_connect (m_clipboardWidget, "selection_get",
457 G_CALLBACK (selection_handler), NULL);
d345e841 458
b453e1b2 459#if wxUSE_THREADS
11e1c70d 460 /* disable GUI threads */
b453e1b2 461#endif
270c23f7 462
75ce0581 463 /* Tell the world we offer clipboard data */
11e1c70d
RR
464 bool res = (gtk_selection_owner_set( m_clipboardWidget,
465 clipboard,
b02da6b1 466 (guint32) GDK_CURRENT_TIME ));
270c23f7 467
11e1c70d
RR
468 if (m_usePrimary)
469 m_ownsPrimarySelection = res;
470 else
471 m_ownsClipboard = res;
270c23f7 472
b453e1b2
RR
473#if wxUSE_THREADS
474 /* re-enable GUI threads */
b453e1b2 475#endif
270c23f7 476
11e1c70d 477 return res;
8b53e5a2 478}
db1b4961 479
8b53e5a2
RR
480void wxClipboard::Close()
481{
223d09f6 482 wxCHECK_RET( m_open, wxT("clipboard not open") );
270c23f7 483
8b53e5a2 484 m_open = FALSE;
dc86cb34
RR
485}
486
f536e0f2
VZ
487bool wxClipboard::IsOpened() const
488{
489 return m_open;
490}
491
e1ee679c 492bool wxClipboard::IsSupported( const wxDataFormat& format )
b527aac5 493{
e5d6aa22 494 /* reentrance problems */
eff869aa 495 if (m_waiting) return FALSE;
270c23f7 496
e5d6aa22 497 /* store requested format to be asked for by callbacks */
1dd989e1 498 m_targetRequested = format;
270c23f7 499
61b04ac6
VZ
500 wxLogTrace( TRACE_CLIPBOARD,
501 wxT("wxClipboard:IsSupported: requested format: %s"),
502 format.GetId().c_str() );
eff869aa 503
223d09f6 504 wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
270c23f7 505
8b53e5a2 506 m_formatSupported = FALSE;
270c23f7
VZ
507
508 /* perform query. this will set m_formatSupported to
034be888 509 TRUE if m_targetRequested is supported.
270c23f7 510 also, we have to wait for the "answer" from the
034be888
RR
511 clipboard owner which is an asynchronous process.
512 therefore we set m_waiting = TRUE here and wait
270c23f7 513 until the callback "targets_selection_received"
034be888
RR
514 sets it to FALSE */
515
516 m_waiting = TRUE;
ca35e608 517
034be888 518 gtk_selection_convert( m_targetsWidget,
66633398 519 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 520 : g_clipboardAtom,
66633398 521 g_targetsAtom,
b02da6b1 522 (guint32) GDK_CURRENT_TIME );
ca35e608 523
034be888 524 while (m_waiting) gtk_main_iteration();
270c23f7 525
c7d6d883
RR
526#if defined(__WXGTK20__) && wxUSE_UNICODE
527 if (!m_formatSupported && format == wxDataFormat(wxDF_UNICODETEXT))
528 {
529 // Another try with plain STRING format
530 extern GdkAtom g_altTextAtom;
531 return IsSupported(g_altTextAtom);
532 }
533#endif
534
ebe47451 535 return m_formatSupported;
270c23f7
VZ
536}
537
e1ee679c 538bool wxClipboard::GetData( wxDataObject& data )
75ce0581 539{
223d09f6 540 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
270c23f7 541
b068c4e8
RR
542 /* get formats from wxDataObjects */
543 wxDataFormat *array = new wxDataFormat[ data.GetFormatCount() ];
544 data.GetAllFormats( array );
270c23f7 545
b068c4e8
RR
546 for (size_t i = 0; i < data.GetFormatCount(); i++)
547 {
e5d6aa22 548 wxDataFormat format( array[i] );
270c23f7 549
61b04ac6
VZ
550 wxLogTrace( TRACE_CLIPBOARD,
551 wxT("wxClipboard::GetData: requested format: %s"),
552 format.GetId().c_str() );
270c23f7 553
b068c4e8 554 /* is data supported by clipboard ? */
270c23f7 555
11e1c70d
RR
556 /* store requested format to be asked for by callbacks */
557 m_targetRequested = format;
270c23f7 558
11e1c70d 559 wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
270c23f7 560
11e1c70d 561 m_formatSupported = FALSE;
270c23f7
VZ
562
563 /* perform query. this will set m_formatSupported to
11e1c70d 564 TRUE if m_targetRequested is supported.
270c23f7 565 also, we have to wait for the "answer" from the
11e1c70d
RR
566 clipboard owner which is an asynchronous process.
567 therefore we set m_waiting = TRUE here and wait
270c23f7 568 until the callback "targets_selection_received"
11e1c70d
RR
569 sets it to FALSE */
570
571 m_waiting = TRUE;
572
573 gtk_selection_convert( m_targetsWidget,
574 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 575 : g_clipboardAtom,
11e1c70d 576 g_targetsAtom,
b02da6b1 577 (guint32) GDK_CURRENT_TIME );
11e1c70d
RR
578
579 while (m_waiting) gtk_main_iteration();
270c23f7 580
11e1c70d 581 if (!m_formatSupported) continue;
270c23f7 582
b068c4e8
RR
583 /* store pointer to data object to be filled up by callbacks */
584 m_receivedData = &data;
270c23f7 585
b068c4e8 586 /* store requested format to be asked for by callbacks */
e5d6aa22 587 m_targetRequested = format;
270c23f7 588
b068c4e8 589 wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
270c23f7 590
b068c4e8
RR
591 /* start query */
592 m_formatSupported = FALSE;
270c23f7
VZ
593
594 /* ask for clipboard contents. this will set
595 m_formatSupported to TRUE if m_targetRequested
b068c4e8 596 is supported.
270c23f7 597 also, we have to wait for the "answer" from the
b068c4e8
RR
598 clipboard owner which is an asynchronous process.
599 therefore we set m_waiting = TRUE here and wait
270c23f7 600 until the callback "targets_selection_received"
b068c4e8
RR
601 sets it to FALSE */
602
603 m_waiting = TRUE;
604
47cf53ef
VZ
605 wxLogTrace( TRACE_CLIPBOARD,
606 wxT("wxClipboard::GetData: format found, start convert") );
270c23f7 607
b068c4e8 608 gtk_selection_convert( m_clipboardWidget,
66633398 609 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 610 : g_clipboardAtom,
66633398 611 m_targetRequested,
b02da6b1 612 (guint32) GDK_CURRENT_TIME );
270c23f7 613
b068c4e8 614 while (m_waiting) gtk_main_iteration();
b527aac5 615
b068c4e8
RR
616 /* this is a true error as we checked for the presence of such data before */
617 wxCHECK_MSG( m_formatSupported, FALSE, wxT("error retrieving data from clipboard") );
270c23f7 618
66633398 619 /* return success */
b068c4e8
RR
620 delete[] array;
621 return TRUE;
622 }
270c23f7 623
47cf53ef
VZ
624 wxLogTrace( TRACE_CLIPBOARD,
625 wxT("wxClipboard::GetData: format not found") );
270c23f7 626
b068c4e8
RR
627 /* return failure */
628 delete[] array;
629 return FALSE;
b527aac5
RR
630}
631
ac57418f 632#endif
ac57418f
RR
633 // wxUSE_CLIPBOARD
634