]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/clipbrd.cpp
allow changing the page from keyboard in property sheet like controls even when the...
[wxWidgets.git] / src / gtk1 / clipbrd.cpp
CommitLineData
dc86cb34 1/////////////////////////////////////////////////////////////////////////////
e4db172a 2// Name: src/gtk1/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
e4db172a
WS
13#if wxUSE_CLIPBOARD
14
dc86cb34
RR
15#include "wx/clipbrd.h"
16
e4db172a
WS
17#ifndef WX_PRECOMP
18 #include "wx/log.h"
de6185e2 19 #include "wx/utils.h"
28f92d74 20 #include "wx/dataobj.h"
e4db172a 21#endif
ac57418f 22
071a2d78
RR
23#include <glib.h>
24#include <gdk/gdk.h>
25#include <gtk/gtk.h>
83624f79 26
dc86cb34
RR
27//-----------------------------------------------------------------------------
28// data
29//-----------------------------------------------------------------------------
30
fd0eed64 31GdkAtom g_clipboardAtom = 0;
b527aac5 32GdkAtom g_targetsAtom = 0;
d394f0c9 33GdkAtom g_timestampAtom = 0;
fd0eed64 34
61b04ac6
VZ
35// the trace mask we use with wxLogTrace() - call
36// wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here
37// (there will be a *lot* of them!)
cbf97a6c 38static const wxChar *TRACE_CLIPBOARD = _T("clipboard");
61b04ac6 39
dc86cb34 40//-----------------------------------------------------------------------------
b527aac5 41// reminder
dc86cb34
RR
42//-----------------------------------------------------------------------------
43
b527aac5 44/* The contents of a selection are returned in a GtkSelectionData
270c23f7 45 structure. selection/target identify the request.
b527aac5
RR
46 type specifies the type of the return; if length < 0, and
47 the data should be ignored. This structure has object semantics -
48 no fields should be modified directly, they should not be created
49 directly, and pointers to them should not be stored beyond the duration of
50 a callback. (If the last is changed, we'll need to add reference
51 counting)
52
53struct _GtkSelectionData
dc86cb34 54{
b527aac5
RR
55 GdkAtom selection;
56 GdkAtom target;
57 GdkAtom type;
61b04ac6 58 gint format;
b527aac5 59 guchar *data;
61b04ac6 60 gint length;
b527aac5
RR
61};
62
63*/
dc86cb34 64
b527aac5
RR
65//-----------------------------------------------------------------------------
66// "selection_received" for targets
67//-----------------------------------------------------------------------------
68
865bb325 69extern "C" {
b527aac5 70static void
270c23f7
VZ
71targets_selection_received( GtkWidget *WXUNUSED(widget),
72 GtkSelectionData *selection_data,
034be888 73 guint32 WXUNUSED(time),
66633398 74 wxClipboard *clipboard )
dc86cb34 75{
270c23f7 76 if ( wxTheClipboard && selection_data->length > 0 )
034be888 77 {
ca11abde 78 // make sure we got the data in the correct form
270c23f7
VZ
79 GdkAtom type = selection_data->type;
80 if ( type != GDK_SELECTION_TYPE_ATOM )
81 {
d394f0c9
MR
82 gchar* atom_name = gdk_atom_name(type);
83 if ( strcmp(atom_name, "TARGETS") )
61b04ac6
VZ
84 {
85 wxLogTrace( TRACE_CLIPBOARD,
86 _T("got unsupported clipboard target") );
87
de6185e2 88 clipboard->m_waiting = false;
d394f0c9 89 g_free(atom_name);
61b04ac6
VZ
90 return;
91 }
d394f0c9 92 g_free(atom_name);
270c23f7 93 }
b527aac5 94
61b04ac6 95#ifdef __WXDEBUG__
270c23f7 96 wxDataFormat clip( selection_data->selection );
61b04ac6
VZ
97 wxLogTrace( TRACE_CLIPBOARD,
98 wxT("selection received for targets, clipboard %s"),
99 clip.GetId().c_str() );
100#endif // __WXDEBUG__
270c23f7
VZ
101
102 // the atoms we received, holding a list of targets (= formats)
103 GdkAtom *atoms = (GdkAtom *)selection_data->data;
11e1c70d 104
270c23f7 105 for (unsigned int i=0; i<selection_data->length/sizeof(GdkAtom); i++)
8b53e5a2 106 {
270c23f7
VZ
107 wxDataFormat format( atoms[i] );
108
61b04ac6
VZ
109 wxLogTrace( TRACE_CLIPBOARD,
110 wxT("selection received for targets, format %s"),
111 format.GetId().c_str() );
270c23f7 112
3d257b8d 113// printf( "format %s requested %s\n",
ca11abde
RR
114// gdk_atom_name( atoms[i] ),
115// gdk_atom_name( clipboard->m_targetRequested ) );
116
270c23f7
VZ
117 if (format == clipboard->m_targetRequested)
118 {
de6185e2
WS
119 clipboard->m_waiting = false;
120 clipboard->m_formatSupported = true;
270c23f7
VZ
121 return;
122 }
8b53e5a2
RR
123 }
124 }
b527aac5 125
de6185e2 126 clipboard->m_waiting = false;
dc86cb34 127}
865bb325 128}
dc86cb34
RR
129
130//-----------------------------------------------------------------------------
b527aac5 131// "selection_received" for the actual data
dc86cb34
RR
132//-----------------------------------------------------------------------------
133
865bb325 134extern "C" {
270c23f7
VZ
135static void
136selection_received( GtkWidget *WXUNUSED(widget),
137 GtkSelectionData *selection_data,
034be888 138 guint32 WXUNUSED(time),
66633398 139 wxClipboard *clipboard )
dc86cb34 140{
034be888
RR
141 if (!wxTheClipboard)
142 {
de6185e2 143 clipboard->m_waiting = false;
034be888
RR
144 return;
145 }
270c23f7 146
8b53e5a2 147 wxDataObject *data_object = clipboard->m_receivedData;
1dd989e1 148
034be888
RR
149 if (!data_object)
150 {
de6185e2 151 clipboard->m_waiting = false;
034be888
RR
152 return;
153 }
270c23f7 154
034be888
RR
155 if (selection_data->length <= 0)
156 {
de6185e2 157 clipboard->m_waiting = false;
034be888
RR
158 return;
159 }
270c23f7 160
b068c4e8 161 wxDataFormat format( selection_data->target );
270c23f7 162
ca11abde 163 // make sure we got the data in the correct format
b068c4e8 164 if (!data_object->IsSupportedFormat( format ) )
034be888 165 {
de6185e2 166 clipboard->m_waiting = false;
034be888
RR
167 return;
168 }
e2acb9ae 169
c7d6d883
RR
170#if 0
171 This seems to cause problems somehow
172 // make sure we got the data in the correct form (selection type).
173 // if so, copy data to target object
e5d6aa22 174 if (selection_data->type != GDK_SELECTION_TYPE_STRING)
8b53e5a2 175 {
de6185e2 176 clipboard->m_waiting = false;
e5d6aa22 177 return;
8b53e5a2 178 }
c7d6d883 179#endif
270c23f7 180
e5d6aa22 181 data_object->SetData( format, (size_t) selection_data->length, (const char*) selection_data->data );
270c23f7 182
de6185e2
WS
183 wxTheClipboard->m_formatSupported = true;
184 clipboard->m_waiting = false;
dc86cb34 185}
865bb325 186}
fd0eed64
RR
187
188//-----------------------------------------------------------------------------
189// "selection_clear"
190//-----------------------------------------------------------------------------
191
865bb325 192extern "C" {
fd0eed64 193static gint
aeeb6a44 194selection_clear_clip( GtkWidget *WXUNUSED(widget), GdkEventSelection *event )
fd0eed64 195{
8b53e5a2 196 if (!wxTheClipboard) return TRUE;
270c23f7 197
aeeb6a44
RR
198 if (event->selection == GDK_SELECTION_PRIMARY)
199 {
de6185e2 200 wxTheClipboard->m_ownsPrimarySelection = false;
aeeb6a44
RR
201 }
202 else
203 if (event->selection == g_clipboardAtom)
204 {
de6185e2 205 wxTheClipboard->m_ownsClipboard = false;
aeeb6a44
RR
206 }
207 else
208 {
de6185e2 209 wxTheClipboard->m_waiting = false;
aeeb6a44
RR
210 return FALSE;
211 }
270c23f7 212
aeeb6a44
RR
213 if ((!wxTheClipboard->m_ownsPrimarySelection) &&
214 (!wxTheClipboard->m_ownsClipboard))
215 {
db2d879a 216 /* the clipboard is no longer in our hands. we can the delete clipboard data. */
1dd989e1 217 if (wxTheClipboard->m_data)
66633398 218 {
47cf53ef 219 wxLogTrace(TRACE_CLIPBOARD, wxT("wxClipboard will get cleared" ));
270c23f7 220
66633398
VZ
221 delete wxTheClipboard->m_data;
222 wxTheClipboard->m_data = (wxDataObject*) NULL;
223 }
aeeb6a44 224 }
270c23f7 225
de6185e2 226 wxTheClipboard->m_waiting = false;
8b53e5a2 227 return TRUE;
fd0eed64 228}
865bb325 229}
fd0eed64
RR
230
231//-----------------------------------------------------------------------------
232// selection handler for supplying data
233//-----------------------------------------------------------------------------
234
865bb325 235extern "C" {
fd0eed64 236static void
19d89516
VZ
237selection_handler( GtkWidget *WXUNUSED(widget),
238 GtkSelectionData *selection_data,
239 guint WXUNUSED(info),
240 guint WXUNUSED(time),
d394f0c9 241 gpointer signal_data )
fd0eed64 242{
8b53e5a2 243 if (!wxTheClipboard) return;
270c23f7 244
1dd989e1 245 if (!wxTheClipboard->m_data) return;
270c23f7 246
1dd989e1 247 wxDataObject *data = wxTheClipboard->m_data;
270c23f7 248
d394f0c9
MR
249 // ICCCM says that TIMESTAMP is a required atom.
250 // In particular, it satisfies Klipper, which polls
251 // TIMESTAMP to see if the clipboards content has changed.
252 // It shall return the time which was used to set the data.
253 if (selection_data->target == g_timestampAtom)
254 {
d704d2f5 255 guint timestamp = GPOINTER_TO_UINT (signal_data);
d394f0c9
MR
256 gtk_selection_data_set(selection_data,
257 GDK_SELECTION_TYPE_INTEGER,
258 32,
259 (guchar*)&(timestamp),
260 sizeof(timestamp));
261 wxLogTrace(TRACE_CLIPBOARD,
262 _T("Clipboard TIMESTAMP requested, returning timestamp=%u"),
263 timestamp);
264 return;
265 }
266
b068c4e8
RR
267 wxDataFormat format( selection_data->target );
268
ebe47451
VS
269#ifdef __WXDEBUG__
270 wxLogTrace(TRACE_CLIPBOARD,
d394f0c9 271 _T("clipboard data in format %s, GtkSelectionData is target=%s type=%s selection=%s timestamp=%u"),
ebe47451
VS
272 format.GetId().c_str(),
273 wxString::FromAscii(gdk_atom_name(selection_data->target)).c_str(),
274 wxString::FromAscii(gdk_atom_name(selection_data->type)).c_str(),
d394f0c9
MR
275 wxString::FromAscii(gdk_atom_name(selection_data->selection)).c_str(),
276 GPOINTER_TO_UINT( signal_data )
ebe47451
VS
277 );
278#endif
3d257b8d 279
b068c4e8 280 if (!data->IsSupportedFormat( format )) return;
270c23f7 281
b068c4e8 282 int size = data->GetDataSize( format );
270c23f7 283
1dd989e1 284 if (size == 0) return;
270c23f7 285
33754c4d
VZ
286 void *d = malloc(size);
287
ca11abde 288 // Text data will be in UTF8 in Unicode mode.
33754c4d 289 data->GetDataHere( selection_data->target, d );
270c23f7 290
3cbab641 291 gtk_selection_data_set(
ebe47451
VS
292 selection_data,
293 GDK_SELECTION_TYPE_STRING,
3cbab641 294 8 * sizeof(gchar),
ebe47451 295 (unsigned char*) d,
2c906a49 296 size );
33754c4d
VZ
297
298 free(d);
fd0eed64 299}
865bb325 300}
dc86cb34
RR
301
302//-----------------------------------------------------------------------------
303// wxClipboard
304//-----------------------------------------------------------------------------
305
306IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
307
308wxClipboard::wxClipboard()
309{
de6185e2
WS
310 m_open = false;
311 m_waiting = false;
8b53e5a2 312
de6185e2
WS
313 m_ownsClipboard = false;
314 m_ownsPrimarySelection = false;
aeeb6a44 315
1dd989e1 316 m_data = (wxDataObject*) NULL;
8b53e5a2 317 m_receivedData = (wxDataObject*) NULL;
99c67c77 318
034be888 319 /* we use m_targetsWidget to query what formats are available */
270c23f7 320
034be888
RR
321 m_targetsWidget = gtk_window_new( GTK_WINDOW_POPUP );
322 gtk_widget_realize( m_targetsWidget );
323
270c23f7 324 gtk_signal_connect( GTK_OBJECT(m_targetsWidget),
034be888 325 "selection_received",
270c23f7 326 GTK_SIGNAL_FUNC( targets_selection_received ),
66633398 327 (gpointer) this );
270c23f7 328
034be888 329 /* we use m_clipboardWidget to get and to offer data */
270c23f7 330
8b53e5a2
RR
331 m_clipboardWidget = gtk_window_new( GTK_WINDOW_POPUP );
332 gtk_widget_realize( m_clipboardWidget );
333
270c23f7 334 gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
034be888 335 "selection_received",
270c23f7 336 GTK_SIGNAL_FUNC( selection_received ),
66633398 337 (gpointer) this );
034be888 338
270c23f7 339 gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
8b53e5a2 340 "selection_clear_event",
270c23f7 341 GTK_SIGNAL_FUNC( selection_clear_clip ),
66633398 342 (gpointer) NULL );
270c23f7 343
8b53e5a2 344 if (!g_clipboardAtom) g_clipboardAtom = gdk_atom_intern( "CLIPBOARD", FALSE );
8b53e5a2 345 if (!g_targetsAtom) g_targetsAtom = gdk_atom_intern ("TARGETS", FALSE);
d394f0c9 346 if (!g_timestampAtom) g_timestampAtom = gdk_atom_intern ("TIMESTAMP", FALSE);
270c23f7 347
de6185e2 348 m_formatSupported = false;
8b53e5a2 349 m_targetRequested = 0;
270c23f7 350
de6185e2 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 {
de6185e2 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 {
de6185e2 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;
de6185e2 404 m_formatSupported = false;
8b53e5a2
RR
405}
406
407bool wxClipboard::Open()
408{
de6185e2 409 wxCHECK_MSG( !m_open, false, wxT("clipboard already open") );
270c23f7 410
de6185e2 411 m_open = true;
270c23f7 412
de6185e2 413 return true;
dc86cb34
RR
414}
415
75ce0581 416bool wxClipboard::SetData( wxDataObject *data )
dc86cb34 417{
de6185e2 418 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
270c23f7 419
de6185e2 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{
de6185e2 429 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
270c23f7 430
de6185e2 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
d394f0c9
MR
446 // by default provide TIMESTAMP as a target
447 gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget),
448 clipboard,
449 g_timestampAtom,
450 0 );
270c23f7 451
b068c4e8
RR
452 for (size_t i = 0; i < m_data->GetFormatCount(); i++)
453 {
61b04ac6
VZ
454 wxLogTrace( TRACE_CLIPBOARD,
455 wxT("wxClipboard now supports atom %s"),
456 array[i].GetId().c_str() );
11e1c70d 457
3d257b8d 458// printf( "added %s\n",
ca11abde 459// gdk_atom_name( array[i].GetFormatId() ) );
3d257b8d 460
11e1c70d 461 gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget),
270c23f7
VZ
462 clipboard,
463 array[i],
11e1c70d 464 0 ); /* what is info ? */
b068c4e8
RR
465 }
466
467 delete[] array;
270c23f7
VZ
468
469 gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
d345e841 470 "selection_get",
270c23f7 471 GTK_SIGNAL_FUNC(selection_handler),
4b84311a 472 GUINT_TO_POINTER( gdk_event_get_time(gtk_get_current_event()) ) );
d345e841 473
b453e1b2 474#if wxUSE_THREADS
11e1c70d 475 /* disable GUI threads */
b453e1b2 476#endif
270c23f7 477
75ce0581 478 /* Tell the world we offer clipboard data */
11e1c70d
RR
479 bool res = (gtk_selection_owner_set( m_clipboardWidget,
480 clipboard,
b02da6b1 481 (guint32) GDK_CURRENT_TIME ));
270c23f7 482
11e1c70d
RR
483 if (m_usePrimary)
484 m_ownsPrimarySelection = res;
485 else
486 m_ownsClipboard = res;
270c23f7 487
b453e1b2
RR
488#if wxUSE_THREADS
489 /* re-enable GUI threads */
b453e1b2 490#endif
270c23f7 491
11e1c70d 492 return res;
8b53e5a2 493}
db1b4961 494
8b53e5a2
RR
495void wxClipboard::Close()
496{
223d09f6 497 wxCHECK_RET( m_open, wxT("clipboard not open") );
270c23f7 498
de6185e2 499 m_open = false;
dc86cb34
RR
500}
501
f536e0f2
VZ
502bool wxClipboard::IsOpened() const
503{
504 return m_open;
505}
506
e1ee679c 507bool wxClipboard::IsSupported( const wxDataFormat& format )
b527aac5 508{
e5d6aa22 509 /* reentrance problems */
de6185e2 510 if (m_waiting) return false;
270c23f7 511
e5d6aa22 512 /* store requested format to be asked for by callbacks */
1dd989e1 513 m_targetRequested = format;
270c23f7 514
61b04ac6
VZ
515 wxLogTrace( TRACE_CLIPBOARD,
516 wxT("wxClipboard:IsSupported: requested format: %s"),
517 format.GetId().c_str() );
eff869aa 518
de6185e2 519 wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") );
270c23f7 520
de6185e2 521 m_formatSupported = false;
270c23f7
VZ
522
523 /* perform query. this will set m_formatSupported to
de6185e2 524 true if m_targetRequested is supported.
270c23f7 525 also, we have to wait for the "answer" from the
034be888 526 clipboard owner which is an asynchronous process.
de6185e2 527 therefore we set m_waiting = true here and wait
270c23f7 528 until the callback "targets_selection_received"
de6185e2 529 sets it to false */
034be888 530
de6185e2 531 m_waiting = true;
ca35e608 532
034be888 533 gtk_selection_convert( m_targetsWidget,
66633398 534 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 535 : g_clipboardAtom,
66633398 536 g_targetsAtom,
b02da6b1 537 (guint32) GDK_CURRENT_TIME );
ca35e608 538
034be888 539 while (m_waiting) gtk_main_iteration();
270c23f7 540
ebe47451 541 return m_formatSupported;
270c23f7
VZ
542}
543
e1ee679c 544bool wxClipboard::GetData( wxDataObject& data )
75ce0581 545{
de6185e2 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
de6185e2 565 wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") );
270c23f7 566
de6185e2 567 m_formatSupported = false;
270c23f7
VZ
568
569 /* perform query. this will set m_formatSupported to
de6185e2 570 true if m_targetRequested is supported.
270c23f7 571 also, we have to wait for the "answer" from the
11e1c70d 572 clipboard owner which is an asynchronous process.
de6185e2 573 therefore we set m_waiting = true here and wait
270c23f7 574 until the callback "targets_selection_received"
de6185e2 575 sets it to false */
11e1c70d 576
de6185e2 577 m_waiting = true;
11e1c70d
RR
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
de6185e2 595 wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") );
270c23f7 596
b068c4e8 597 /* start query */
de6185e2 598 m_formatSupported = false;
270c23f7
VZ
599
600 /* ask for clipboard contents. this will set
de6185e2 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 604 clipboard owner which is an asynchronous process.
de6185e2 605 therefore we set m_waiting = true here and wait
270c23f7 606 until the callback "targets_selection_received"
de6185e2 607 sets it to false */
b068c4e8 608
de6185e2 609 m_waiting = true;
b068c4e8 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 622 /* this is a true error as we checked for the presence of such data before */
de6185e2 623 wxCHECK_MSG( m_formatSupported, false, wxT("error retrieving data from clipboard") );
270c23f7 624
66633398 625 /* return success */
b068c4e8 626 delete[] array;
de6185e2 627 return true;
b068c4e8 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;
de6185e2 635 return false;
b527aac5
RR
636}
637
ac57418f 638#endif
ac57418f 639 // wxUSE_CLIPBOARD