]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/clipbrd.cpp
Include wx/sizer.h and wx/layout.h according to precompiled headers of wx/wx.h (with...
[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"
e4db172a 20#endif
ac57418f 21
e1ee679c 22#include "wx/dataobj.h"
034be888 23
071a2d78
RR
24#include <glib.h>
25#include <gdk/gdk.h>
26#include <gtk/gtk.h>
83624f79 27
dc86cb34
RR
28//-----------------------------------------------------------------------------
29// data
30//-----------------------------------------------------------------------------
31
fd0eed64 32GdkAtom g_clipboardAtom = 0;
b527aac5 33GdkAtom g_targetsAtom = 0;
d394f0c9 34GdkAtom g_timestampAtom = 0;
fd0eed64 35
61b04ac6
VZ
36// the trace mask we use with wxLogTrace() - call
37// wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here
38// (there will be a *lot* of them!)
cbf97a6c 39static const wxChar *TRACE_CLIPBOARD = _T("clipboard");
61b04ac6 40
dc86cb34 41//-----------------------------------------------------------------------------
b527aac5 42// reminder
dc86cb34
RR
43//-----------------------------------------------------------------------------
44
b527aac5 45/* The contents of a selection are returned in a GtkSelectionData
270c23f7 46 structure. selection/target identify the request.
b527aac5
RR
47 type specifies the type of the return; if length < 0, and
48 the data should be ignored. This structure has object semantics -
49 no fields should be modified directly, they should not be created
50 directly, and pointers to them should not be stored beyond the duration of
51 a callback. (If the last is changed, we'll need to add reference
52 counting)
53
54struct _GtkSelectionData
dc86cb34 55{
b527aac5
RR
56 GdkAtom selection;
57 GdkAtom target;
58 GdkAtom type;
61b04ac6 59 gint format;
b527aac5 60 guchar *data;
61b04ac6 61 gint length;
b527aac5
RR
62};
63
64*/
dc86cb34 65
b527aac5
RR
66//-----------------------------------------------------------------------------
67// "selection_received" for targets
68//-----------------------------------------------------------------------------
69
865bb325 70extern "C" {
b527aac5 71static void
270c23f7
VZ
72targets_selection_received( GtkWidget *WXUNUSED(widget),
73 GtkSelectionData *selection_data,
034be888 74 guint32 WXUNUSED(time),
66633398 75 wxClipboard *clipboard )
dc86cb34 76{
270c23f7 77 if ( wxTheClipboard && selection_data->length > 0 )
034be888 78 {
ca11abde 79 // make sure we got the data in the correct form
270c23f7
VZ
80 GdkAtom type = selection_data->type;
81 if ( type != GDK_SELECTION_TYPE_ATOM )
82 {
d394f0c9
MR
83 gchar* atom_name = gdk_atom_name(type);
84 if ( strcmp(atom_name, "TARGETS") )
61b04ac6
VZ
85 {
86 wxLogTrace( TRACE_CLIPBOARD,
87 _T("got unsupported clipboard target") );
88
de6185e2 89 clipboard->m_waiting = false;
d394f0c9 90 g_free(atom_name);
61b04ac6
VZ
91 return;
92 }
d394f0c9 93 g_free(atom_name);
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 {
de6185e2
WS
120 clipboard->m_waiting = false;
121 clipboard->m_formatSupported = true;
270c23f7
VZ
122 return;
123 }
8b53e5a2
RR
124 }
125 }
b527aac5 126
de6185e2 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 {
de6185e2 144 clipboard->m_waiting = false;
034be888
RR
145 return;
146 }
270c23f7 147
8b53e5a2 148 wxDataObject *data_object = clipboard->m_receivedData;
1dd989e1 149
034be888
RR
150 if (!data_object)
151 {
de6185e2 152 clipboard->m_waiting = false;
034be888
RR
153 return;
154 }
270c23f7 155
034be888
RR
156 if (selection_data->length <= 0)
157 {
de6185e2 158 clipboard->m_waiting = false;
034be888
RR
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 166 {
de6185e2 167 clipboard->m_waiting = false;
034be888
RR
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 {
de6185e2 177 clipboard->m_waiting = false;
e5d6aa22 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
de6185e2
WS
184 wxTheClipboard->m_formatSupported = true;
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 {
de6185e2 201 wxTheClipboard->m_ownsPrimarySelection = false;
aeeb6a44
RR
202 }
203 else
204 if (event->selection == g_clipboardAtom)
205 {
de6185e2 206 wxTheClipboard->m_ownsClipboard = false;
aeeb6a44
RR
207 }
208 else
209 {
de6185e2 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
de6185e2 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),
d394f0c9 242 gpointer signal_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
d394f0c9
MR
250 // ICCCM says that TIMESTAMP is a required atom.
251 // In particular, it satisfies Klipper, which polls
252 // TIMESTAMP to see if the clipboards content has changed.
253 // It shall return the time which was used to set the data.
254 if (selection_data->target == g_timestampAtom)
255 {
d704d2f5 256 guint timestamp = GPOINTER_TO_UINT (signal_data);
d394f0c9
MR
257 gtk_selection_data_set(selection_data,
258 GDK_SELECTION_TYPE_INTEGER,
259 32,
260 (guchar*)&(timestamp),
261 sizeof(timestamp));
262 wxLogTrace(TRACE_CLIPBOARD,
263 _T("Clipboard TIMESTAMP requested, returning timestamp=%u"),
264 timestamp);
265 return;
266 }
267
b068c4e8
RR
268 wxDataFormat format( selection_data->target );
269
ebe47451
VS
270#ifdef __WXDEBUG__
271 wxLogTrace(TRACE_CLIPBOARD,
d394f0c9 272 _T("clipboard data in format %s, GtkSelectionData is target=%s type=%s selection=%s timestamp=%u"),
ebe47451
VS
273 format.GetId().c_str(),
274 wxString::FromAscii(gdk_atom_name(selection_data->target)).c_str(),
275 wxString::FromAscii(gdk_atom_name(selection_data->type)).c_str(),
d394f0c9
MR
276 wxString::FromAscii(gdk_atom_name(selection_data->selection)).c_str(),
277 GPOINTER_TO_UINT( signal_data )
ebe47451
VS
278 );
279#endif
3d257b8d 280
b068c4e8 281 if (!data->IsSupportedFormat( format )) return;
270c23f7 282
b068c4e8 283 int size = data->GetDataSize( format );
270c23f7 284
1dd989e1 285 if (size == 0) return;
270c23f7 286
33754c4d
VZ
287 void *d = malloc(size);
288
ca11abde 289 // Text data will be in UTF8 in Unicode mode.
33754c4d 290 data->GetDataHere( selection_data->target, d );
270c23f7 291
3cbab641 292 gtk_selection_data_set(
ebe47451
VS
293 selection_data,
294 GDK_SELECTION_TYPE_STRING,
3cbab641 295 8 * sizeof(gchar),
ebe47451 296 (unsigned char*) d,
2c906a49 297 size );
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{
de6185e2
WS
311 m_open = false;
312 m_waiting = false;
8b53e5a2 313
de6185e2
WS
314 m_ownsClipboard = false;
315 m_ownsPrimarySelection = false;
aeeb6a44 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);
d394f0c9 347 if (!g_timestampAtom) g_timestampAtom = gdk_atom_intern ("TIMESTAMP", FALSE);
270c23f7 348
de6185e2 349 m_formatSupported = false;
8b53e5a2 350 m_targetRequested = 0;
270c23f7 351
de6185e2 352 m_usePrimary = false;
dc86cb34
RR
353}
354
355wxClipboard::~wxClipboard()
b527aac5 356{
270c23f7
VZ
357 Clear();
358
8b53e5a2 359 if (m_clipboardWidget) gtk_widget_destroy( m_clipboardWidget );
034be888 360 if (m_targetsWidget) gtk_widget_destroy( m_targetsWidget );
b527aac5
RR
361}
362
363void wxClipboard::Clear()
dc86cb34 364{
1dd989e1
RR
365 if (m_data)
366 {
b453e1b2
RR
367#if wxUSE_THREADS
368 /* disable GUI threads */
b453e1b2 369#endif
270c23f7 370
ca11abde
RR
371 // As we have data we also own the clipboard. Once we no longer own
372 // it, clear_selection is called which will set m_data to zero
aeeb6a44 373 if (gdk_selection_owner_get( g_clipboardAtom ) == m_clipboardWidget->window)
8b53e5a2 374 {
de6185e2 375 m_waiting = true;
270c23f7 376
b02da6b1
VZ
377 gtk_selection_owner_set( (GtkWidget*) NULL, g_clipboardAtom,
378 (guint32) GDK_CURRENT_TIME );
270c23f7 379
e5ea3f7a 380 while (m_waiting) gtk_main_iteration();
8b53e5a2 381 }
270c23f7 382
aeeb6a44
RR
383 if (gdk_selection_owner_get( GDK_SELECTION_PRIMARY ) == m_clipboardWidget->window)
384 {
de6185e2 385 m_waiting = true;
270c23f7 386
b02da6b1
VZ
387 gtk_selection_owner_set( (GtkWidget*) NULL, GDK_SELECTION_PRIMARY,
388 (guint32) GDK_CURRENT_TIME );
270c23f7 389
e5ea3f7a 390 while (m_waiting) gtk_main_iteration();
aeeb6a44 391 }
270c23f7 392
1dd989e1 393 if (m_data)
270c23f7 394 {
66633398
VZ
395 delete m_data;
396 m_data = (wxDataObject*) NULL;
397 }
270c23f7 398
b453e1b2
RR
399#if wxUSE_THREADS
400 /* re-enable GUI threads */
b453e1b2 401#endif
8b53e5a2 402 }
270c23f7 403
8b53e5a2 404 m_targetRequested = 0;
de6185e2 405 m_formatSupported = false;
8b53e5a2
RR
406}
407
408bool wxClipboard::Open()
409{
de6185e2 410 wxCHECK_MSG( !m_open, false, wxT("clipboard already open") );
270c23f7 411
de6185e2 412 m_open = true;
270c23f7 413
de6185e2 414 return true;
dc86cb34
RR
415}
416
75ce0581 417bool wxClipboard::SetData( wxDataObject *data )
dc86cb34 418{
de6185e2 419 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
270c23f7 420
de6185e2 421 wxCHECK_MSG( data, false, wxT("data is invalid") );
270c23f7 422
0d2a2b60 423 Clear();
75ce0581
RR
424
425 return AddData( data );
426}
427
428bool wxClipboard::AddData( wxDataObject *data )
429{
de6185e2 430 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
270c23f7 431
de6185e2 432 wxCHECK_MSG( data, false, wxT("data is invalid") );
270c23f7 433
ca11abde 434 // we can only store one wxDataObject
1dd989e1 435 Clear();
270c23f7 436
1dd989e1
RR
437 m_data = data;
438
ca11abde 439 // get formats from wxDataObjects
b068c4e8
RR
440 wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ];
441 m_data->GetAllFormats( array );
11e1c70d 442
ca11abde 443 // primary selection or clipboard
11e1c70d
RR
444 GdkAtom clipboard = m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
445 : g_clipboardAtom;
446
d394f0c9
MR
447 // by default provide TIMESTAMP as a target
448 gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget),
449 clipboard,
450 g_timestampAtom,
451 0 );
270c23f7 452
b068c4e8
RR
453 for (size_t i = 0; i < m_data->GetFormatCount(); i++)
454 {
61b04ac6
VZ
455 wxLogTrace( TRACE_CLIPBOARD,
456 wxT("wxClipboard now supports atom %s"),
457 array[i].GetId().c_str() );
11e1c70d 458
3d257b8d 459// printf( "added %s\n",
ca11abde 460// gdk_atom_name( array[i].GetFormatId() ) );
3d257b8d 461
11e1c70d 462 gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget),
270c23f7
VZ
463 clipboard,
464 array[i],
11e1c70d 465 0 ); /* what is info ? */
b068c4e8
RR
466 }
467
468 delete[] array;
270c23f7
VZ
469
470 gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
d345e841 471 "selection_get",
270c23f7 472 GTK_SIGNAL_FUNC(selection_handler),
4b84311a 473 GUINT_TO_POINTER( gdk_event_get_time(gtk_get_current_event()) ) );
d345e841 474
b453e1b2 475#if wxUSE_THREADS
11e1c70d 476 /* disable GUI threads */
b453e1b2 477#endif
270c23f7 478
75ce0581 479 /* Tell the world we offer clipboard data */
11e1c70d
RR
480 bool res = (gtk_selection_owner_set( m_clipboardWidget,
481 clipboard,
b02da6b1 482 (guint32) GDK_CURRENT_TIME ));
270c23f7 483
11e1c70d
RR
484 if (m_usePrimary)
485 m_ownsPrimarySelection = res;
486 else
487 m_ownsClipboard = res;
270c23f7 488
b453e1b2
RR
489#if wxUSE_THREADS
490 /* re-enable GUI threads */
b453e1b2 491#endif
270c23f7 492
11e1c70d 493 return res;
8b53e5a2 494}
db1b4961 495
8b53e5a2
RR
496void wxClipboard::Close()
497{
223d09f6 498 wxCHECK_RET( m_open, wxT("clipboard not open") );
270c23f7 499
de6185e2 500 m_open = false;
dc86cb34
RR
501}
502
f536e0f2
VZ
503bool wxClipboard::IsOpened() const
504{
505 return m_open;
506}
507
e1ee679c 508bool wxClipboard::IsSupported( const wxDataFormat& format )
b527aac5 509{
e5d6aa22 510 /* reentrance problems */
de6185e2 511 if (m_waiting) return false;
270c23f7 512
e5d6aa22 513 /* store requested format to be asked for by callbacks */
1dd989e1 514 m_targetRequested = format;
270c23f7 515
61b04ac6
VZ
516 wxLogTrace( TRACE_CLIPBOARD,
517 wxT("wxClipboard:IsSupported: requested format: %s"),
518 format.GetId().c_str() );
eff869aa 519
de6185e2 520 wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") );
270c23f7 521
de6185e2 522 m_formatSupported = false;
270c23f7
VZ
523
524 /* perform query. this will set m_formatSupported to
de6185e2 525 true if m_targetRequested is supported.
270c23f7 526 also, we have to wait for the "answer" from the
034be888 527 clipboard owner which is an asynchronous process.
de6185e2 528 therefore we set m_waiting = true here and wait
270c23f7 529 until the callback "targets_selection_received"
de6185e2 530 sets it to false */
034be888 531
de6185e2 532 m_waiting = true;
ca35e608 533
034be888 534 gtk_selection_convert( m_targetsWidget,
66633398 535 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 536 : g_clipboardAtom,
66633398 537 g_targetsAtom,
b02da6b1 538 (guint32) GDK_CURRENT_TIME );
ca35e608 539
034be888 540 while (m_waiting) gtk_main_iteration();
270c23f7 541
ebe47451 542 return m_formatSupported;
270c23f7
VZ
543}
544
e1ee679c 545bool wxClipboard::GetData( wxDataObject& data )
75ce0581 546{
de6185e2 547 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
270c23f7 548
b068c4e8
RR
549 /* get formats from wxDataObjects */
550 wxDataFormat *array = new wxDataFormat[ data.GetFormatCount() ];
551 data.GetAllFormats( array );
270c23f7 552
b068c4e8
RR
553 for (size_t i = 0; i < data.GetFormatCount(); i++)
554 {
e5d6aa22 555 wxDataFormat format( array[i] );
270c23f7 556
61b04ac6
VZ
557 wxLogTrace( TRACE_CLIPBOARD,
558 wxT("wxClipboard::GetData: requested format: %s"),
559 format.GetId().c_str() );
270c23f7 560
b068c4e8 561 /* is data supported by clipboard ? */
270c23f7 562
11e1c70d
RR
563 /* store requested format to be asked for by callbacks */
564 m_targetRequested = format;
270c23f7 565
de6185e2 566 wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") );
270c23f7 567
de6185e2 568 m_formatSupported = false;
270c23f7
VZ
569
570 /* perform query. this will set m_formatSupported to
de6185e2 571 true if m_targetRequested is supported.
270c23f7 572 also, we have to wait for the "answer" from the
11e1c70d 573 clipboard owner which is an asynchronous process.
de6185e2 574 therefore we set m_waiting = true here and wait
270c23f7 575 until the callback "targets_selection_received"
de6185e2 576 sets it to false */
11e1c70d 577
de6185e2 578 m_waiting = true;
11e1c70d
RR
579
580 gtk_selection_convert( m_targetsWidget,
581 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 582 : g_clipboardAtom,
11e1c70d 583 g_targetsAtom,
b02da6b1 584 (guint32) GDK_CURRENT_TIME );
11e1c70d
RR
585
586 while (m_waiting) gtk_main_iteration();
270c23f7 587
11e1c70d 588 if (!m_formatSupported) continue;
270c23f7 589
b068c4e8
RR
590 /* store pointer to data object to be filled up by callbacks */
591 m_receivedData = &data;
270c23f7 592
b068c4e8 593 /* store requested format to be asked for by callbacks */
e5d6aa22 594 m_targetRequested = format;
270c23f7 595
de6185e2 596 wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") );
270c23f7 597
b068c4e8 598 /* start query */
de6185e2 599 m_formatSupported = false;
270c23f7
VZ
600
601 /* ask for clipboard contents. this will set
de6185e2 602 m_formatSupported to true if m_targetRequested
b068c4e8 603 is supported.
270c23f7 604 also, we have to wait for the "answer" from the
b068c4e8 605 clipboard owner which is an asynchronous process.
de6185e2 606 therefore we set m_waiting = true here and wait
270c23f7 607 until the callback "targets_selection_received"
de6185e2 608 sets it to false */
b068c4e8 609
de6185e2 610 m_waiting = true;
b068c4e8 611
47cf53ef
VZ
612 wxLogTrace( TRACE_CLIPBOARD,
613 wxT("wxClipboard::GetData: format found, start convert") );
270c23f7 614
b068c4e8 615 gtk_selection_convert( m_clipboardWidget,
66633398 616 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 617 : g_clipboardAtom,
66633398 618 m_targetRequested,
b02da6b1 619 (guint32) GDK_CURRENT_TIME );
270c23f7 620
b068c4e8 621 while (m_waiting) gtk_main_iteration();
b527aac5 622
b068c4e8 623 /* this is a true error as we checked for the presence of such data before */
de6185e2 624 wxCHECK_MSG( m_formatSupported, false, wxT("error retrieving data from clipboard") );
270c23f7 625
66633398 626 /* return success */
b068c4e8 627 delete[] array;
de6185e2 628 return true;
b068c4e8 629 }
270c23f7 630
47cf53ef
VZ
631 wxLogTrace( TRACE_CLIPBOARD,
632 wxT("wxClipboard::GetData: format not found") );
270c23f7 633
b068c4e8
RR
634 /* return failure */
635 delete[] array;
de6185e2 636 return false;
b527aac5
RR
637}
638
ac57418f 639#endif
ac57418f 640 // wxUSE_CLIPBOARD