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