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