]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/clipbrd.cpp
gdk_draw_pixmap -> gdk_draw_drawable
[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
67756da4 21#include "wx/gtk/private.h"
83624f79 22
b453e1b2
RR
23//-----------------------------------------------------------------------------
24// thread system
25//-----------------------------------------------------------------------------
26
27#if wxUSE_THREADS
b453e1b2
RR
28#endif
29
dc86cb34
RR
30//-----------------------------------------------------------------------------
31// data
32//-----------------------------------------------------------------------------
33
fd0eed64 34GdkAtom g_clipboardAtom = 0;
b527aac5 35GdkAtom g_targetsAtom = 0;
d394f0c9 36GdkAtom g_timestampAtom = 0;
fd0eed64 37
c7d6d883
RR
38#if defined(__WXGTK20__) && wxUSE_UNICODE
39extern GdkAtom g_altTextAtom;
40#endif
41
61b04ac6
VZ
42// the trace mask we use with wxLogTrace() - call
43// wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here
44// (there will be a *lot* of them!)
cbf97a6c 45static const wxChar *TRACE_CLIPBOARD = _T("clipboard");
61b04ac6 46
dc86cb34 47//-----------------------------------------------------------------------------
b527aac5 48// reminder
dc86cb34
RR
49//-----------------------------------------------------------------------------
50
b527aac5 51/* The contents of a selection are returned in a GtkSelectionData
270c23f7 52 structure. selection/target identify the request.
b527aac5
RR
53 type specifies the type of the return; if length < 0, and
54 the data should be ignored. This structure has object semantics -
55 no fields should be modified directly, they should not be created
56 directly, and pointers to them should not be stored beyond the duration of
57 a callback. (If the last is changed, we'll need to add reference
58 counting)
59
60struct _GtkSelectionData
dc86cb34 61{
b527aac5
RR
62 GdkAtom selection;
63 GdkAtom target;
64 GdkAtom type;
61b04ac6 65 gint format;
b527aac5 66 guchar *data;
61b04ac6 67 gint length;
b527aac5
RR
68};
69
70*/
dc86cb34 71
b527aac5
RR
72//-----------------------------------------------------------------------------
73// "selection_received" for targets
74//-----------------------------------------------------------------------------
75
865bb325 76extern "C" {
b527aac5 77static void
270c23f7
VZ
78targets_selection_received( GtkWidget *WXUNUSED(widget),
79 GtkSelectionData *selection_data,
034be888 80 guint32 WXUNUSED(time),
66633398 81 wxClipboard *clipboard )
dc86cb34 82{
270c23f7 83 if ( wxTheClipboard && selection_data->length > 0 )
034be888 84 {
ca11abde 85 // make sure we got the data in the correct form
270c23f7
VZ
86 GdkAtom type = selection_data->type;
87 if ( type != GDK_SELECTION_TYPE_ATOM )
88 {
67756da4 89 if ( strcmp(wxGtkString(gdk_atom_name(type)), "TARGETS") )
61b04ac6
VZ
90 {
91 wxLogTrace( TRACE_CLIPBOARD,
92 _T("got unsupported clipboard target") );
93
94 clipboard->m_waiting = FALSE;
95 return;
96 }
270c23f7 97 }
b527aac5 98
61b04ac6 99#ifdef __WXDEBUG__
270c23f7 100 wxDataFormat clip( selection_data->selection );
61b04ac6
VZ
101 wxLogTrace( TRACE_CLIPBOARD,
102 wxT("selection received for targets, clipboard %s"),
103 clip.GetId().c_str() );
104#endif // __WXDEBUG__
270c23f7
VZ
105
106 // the atoms we received, holding a list of targets (= formats)
107 GdkAtom *atoms = (GdkAtom *)selection_data->data;
11e1c70d 108
270c23f7 109 for (unsigned int i=0; i<selection_data->length/sizeof(GdkAtom); i++)
8b53e5a2 110 {
270c23f7
VZ
111 wxDataFormat format( atoms[i] );
112
61b04ac6
VZ
113 wxLogTrace( TRACE_CLIPBOARD,
114 wxT("selection received for targets, format %s"),
115 format.GetId().c_str() );
270c23f7 116
3d257b8d 117// printf( "format %s requested %s\n",
ca11abde
RR
118// gdk_atom_name( atoms[i] ),
119// gdk_atom_name( clipboard->m_targetRequested ) );
120
270c23f7
VZ
121 if (format == clipboard->m_targetRequested)
122 {
123 clipboard->m_waiting = FALSE;
124 clipboard->m_formatSupported = TRUE;
125 return;
126 }
8b53e5a2
RR
127 }
128 }
b527aac5 129
034be888 130 clipboard->m_waiting = FALSE;
dc86cb34 131}
865bb325 132}
dc86cb34
RR
133
134//-----------------------------------------------------------------------------
b527aac5 135// "selection_received" for the actual data
dc86cb34
RR
136//-----------------------------------------------------------------------------
137
865bb325 138extern "C" {
270c23f7
VZ
139static void
140selection_received( GtkWidget *WXUNUSED(widget),
141 GtkSelectionData *selection_data,
034be888 142 guint32 WXUNUSED(time),
66633398 143 wxClipboard *clipboard )
dc86cb34 144{
034be888
RR
145 if (!wxTheClipboard)
146 {
147 clipboard->m_waiting = FALSE;
148 return;
149 }
270c23f7 150
8b53e5a2 151 wxDataObject *data_object = clipboard->m_receivedData;
1dd989e1 152
034be888
RR
153 if (!data_object)
154 {
155 clipboard->m_waiting = FALSE;
156 return;
157 }
270c23f7 158
034be888
RR
159 if (selection_data->length <= 0)
160 {
161 clipboard->m_waiting = FALSE;
162 return;
163 }
270c23f7 164
b068c4e8 165 wxDataFormat format( selection_data->target );
270c23f7 166
ca11abde 167 // make sure we got the data in the correct format
b068c4e8 168 if (!data_object->IsSupportedFormat( format ) )
034be888
RR
169 {
170 clipboard->m_waiting = FALSE;
171 return;
172 }
e2acb9ae 173
c7d6d883
RR
174#if 0
175 This seems to cause problems somehow
176 // make sure we got the data in the correct form (selection type).
177 // if so, copy data to target object
e5d6aa22 178 if (selection_data->type != GDK_SELECTION_TYPE_STRING)
8b53e5a2 179 {
e5d6aa22
RR
180 clipboard->m_waiting = FALSE;
181 return;
8b53e5a2 182 }
c7d6d883 183#endif
270c23f7 184
e5d6aa22 185 data_object->SetData( format, (size_t) selection_data->length, (const char*) selection_data->data );
270c23f7 186
8b53e5a2 187 wxTheClipboard->m_formatSupported = TRUE;
034be888 188 clipboard->m_waiting = FALSE;
dc86cb34 189}
865bb325 190}
fd0eed64
RR
191
192//-----------------------------------------------------------------------------
193// "selection_clear"
194//-----------------------------------------------------------------------------
195
865bb325 196extern "C" {
fd0eed64 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 232}
865bb325 233}
fd0eed64
RR
234
235//-----------------------------------------------------------------------------
236// selection handler for supplying data
237//-----------------------------------------------------------------------------
238
865bb325 239extern "C" {
fd0eed64 240static void
19d89516
VZ
241selection_handler( GtkWidget *WXUNUSED(widget),
242 GtkSelectionData *selection_data,
243 guint WXUNUSED(info),
244 guint WXUNUSED(time),
d394f0c9 245 gpointer signal_data )
fd0eed64 246{
8b53e5a2 247 if (!wxTheClipboard) return;
270c23f7 248
1dd989e1 249 if (!wxTheClipboard->m_data) return;
270c23f7 250
1dd989e1 251 wxDataObject *data = wxTheClipboard->m_data;
270c23f7 252
d394f0c9
MR
253 // ICCCM says that TIMESTAMP is a required atom.
254 // In particular, it satisfies Klipper, which polls
255 // TIMESTAMP to see if the clipboards content has changed.
256 // It shall return the time which was used to set the data.
257 if (selection_data->target == g_timestampAtom)
258 {
259 uint timestamp = GPOINTER_TO_UINT (signal_data);
260 gtk_selection_data_set(selection_data,
261 GDK_SELECTION_TYPE_INTEGER,
262 32,
263 (guchar*)&(timestamp),
264 sizeof(timestamp));
265 wxLogTrace(TRACE_CLIPBOARD,
266 _T("Clipboard TIMESTAMP requested, returning timestamp=%u"),
267 timestamp);
268 return;
269 }
270
b068c4e8
RR
271 wxDataFormat format( selection_data->target );
272
ebe47451
VS
273#ifdef __WXDEBUG__
274 wxLogTrace(TRACE_CLIPBOARD,
d394f0c9 275 _T("clipboard data in format %s, GtkSelectionData is target=%s type=%s selection=%s timestamp=%u"),
ebe47451 276 format.GetId().c_str(),
67756da4
MR
277 wxString::FromAscii(wxGtkString(gdk_atom_name(selection_data->target))).c_str(),
278 wxString::FromAscii(wxGtkString(gdk_atom_name(selection_data->type))).c_str(),
279 wxString::FromAscii(wxGtkString(gdk_atom_name(selection_data->selection))).c_str(),
d394f0c9 280 GPOINTER_TO_UINT( signal_data )
ebe47451
VS
281 );
282#endif
3d257b8d 283
b068c4e8 284 if (!data->IsSupportedFormat( format )) return;
270c23f7 285
b068c4e8 286 int size = data->GetDataSize( format );
270c23f7 287
1dd989e1 288 if (size == 0) return;
270c23f7 289
33754c4d
VZ
290 void *d = malloc(size);
291
ca11abde 292 // Text data will be in UTF8 in Unicode mode.
33754c4d 293 data->GetDataHere( selection_data->target, d );
270c23f7 294
ebe47451
VS
295 // NB: GTK+ requires special treatment of UTF8_STRING data, the text
296 // would show as UTF-8 data interpreted as latin1 (?) in other
297 // GTK+ apps if we used gtk_selection_data_set()
298 if (format == wxDataFormat(wxDF_UNICODETEXT))
299 {
300 gtk_selection_data_set_text(
301 selection_data,
302 (const gchar*)d,
2c906a49 303 size );
ebe47451
VS
304 }
305 else
ebe47451
VS
306 {
307 gtk_selection_data_set(
308 selection_data,
309 GDK_SELECTION_TYPE_STRING,
310 8*sizeof(gchar),
311 (unsigned char*) d,
2c906a49 312 size );
ebe47451 313 }
33754c4d
VZ
314
315 free(d);
fd0eed64 316}
865bb325 317}
dc86cb34
RR
318
319//-----------------------------------------------------------------------------
320// wxClipboard
321//-----------------------------------------------------------------------------
322
323IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
324
325wxClipboard::wxClipboard()
326{
8b53e5a2 327 m_open = FALSE;
3fc93ebd 328 m_waiting = FALSE;
8b53e5a2 329
aeeb6a44
RR
330 m_ownsClipboard = FALSE;
331 m_ownsPrimarySelection = FALSE;
332
1dd989e1 333 m_data = (wxDataObject*) NULL;
8b53e5a2 334 m_receivedData = (wxDataObject*) NULL;
99c67c77 335
034be888 336 /* we use m_targetsWidget to query what formats are available */
270c23f7 337
034be888
RR
338 m_targetsWidget = gtk_window_new( GTK_WINDOW_POPUP );
339 gtk_widget_realize( m_targetsWidget );
340
9fa72bd2
MR
341 g_signal_connect (m_targetsWidget, "selection_received",
342 G_CALLBACK (targets_selection_received), this);
270c23f7 343
034be888 344 /* we use m_clipboardWidget to get and to offer data */
270c23f7 345
8b53e5a2
RR
346 m_clipboardWidget = gtk_window_new( GTK_WINDOW_POPUP );
347 gtk_widget_realize( m_clipboardWidget );
348
9fa72bd2
MR
349 g_signal_connect (m_clipboardWidget, "selection_received",
350 G_CALLBACK (selection_received), this);
034be888 351
9fa72bd2
MR
352 g_signal_connect (m_clipboardWidget, "selection_clear_event",
353 G_CALLBACK (selection_clear_clip), NULL);
270c23f7 354
8b53e5a2 355 if (!g_clipboardAtom) g_clipboardAtom = gdk_atom_intern( "CLIPBOARD", FALSE );
8b53e5a2 356 if (!g_targetsAtom) g_targetsAtom = gdk_atom_intern ("TARGETS", FALSE);
d394f0c9 357 if (!g_timestampAtom) g_timestampAtom = gdk_atom_intern ("TIMESTAMP", FALSE);
270c23f7 358
8b53e5a2
RR
359 m_formatSupported = FALSE;
360 m_targetRequested = 0;
270c23f7 361
7e2c43b8 362 m_usePrimary = FALSE;
dc86cb34
RR
363}
364
365wxClipboard::~wxClipboard()
b527aac5 366{
270c23f7
VZ
367 Clear();
368
8b53e5a2 369 if (m_clipboardWidget) gtk_widget_destroy( m_clipboardWidget );
034be888 370 if (m_targetsWidget) gtk_widget_destroy( m_targetsWidget );
b527aac5
RR
371}
372
373void wxClipboard::Clear()
dc86cb34 374{
1dd989e1
RR
375 if (m_data)
376 {
b453e1b2
RR
377#if wxUSE_THREADS
378 /* disable GUI threads */
b453e1b2 379#endif
270c23f7 380
ca11abde
RR
381 // As we have data we also own the clipboard. Once we no longer own
382 // it, clear_selection is called which will set m_data to zero
aeeb6a44 383 if (gdk_selection_owner_get( g_clipboardAtom ) == m_clipboardWidget->window)
8b53e5a2 384 {
e5ea3f7a 385 m_waiting = TRUE;
270c23f7 386
b02da6b1
VZ
387 gtk_selection_owner_set( (GtkWidget*) NULL, g_clipboardAtom,
388 (guint32) GDK_CURRENT_TIME );
270c23f7 389
e5ea3f7a 390 while (m_waiting) gtk_main_iteration();
8b53e5a2 391 }
270c23f7 392
aeeb6a44
RR
393 if (gdk_selection_owner_get( GDK_SELECTION_PRIMARY ) == m_clipboardWidget->window)
394 {
e5ea3f7a 395 m_waiting = TRUE;
270c23f7 396
b02da6b1
VZ
397 gtk_selection_owner_set( (GtkWidget*) NULL, GDK_SELECTION_PRIMARY,
398 (guint32) GDK_CURRENT_TIME );
270c23f7 399
e5ea3f7a 400 while (m_waiting) gtk_main_iteration();
aeeb6a44 401 }
270c23f7 402
1dd989e1 403 if (m_data)
270c23f7 404 {
66633398
VZ
405 delete m_data;
406 m_data = (wxDataObject*) NULL;
407 }
270c23f7 408
b453e1b2
RR
409#if wxUSE_THREADS
410 /* re-enable GUI threads */
b453e1b2 411#endif
8b53e5a2 412 }
270c23f7 413
8b53e5a2 414 m_targetRequested = 0;
8b53e5a2
RR
415 m_formatSupported = FALSE;
416}
417
418bool wxClipboard::Open()
419{
223d09f6 420 wxCHECK_MSG( !m_open, FALSE, wxT("clipboard already open") );
270c23f7 421
8b53e5a2 422 m_open = TRUE;
270c23f7 423
8b53e5a2 424 return TRUE;
dc86cb34
RR
425}
426
75ce0581 427bool wxClipboard::SetData( wxDataObject *data )
dc86cb34 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
0d2a2b60 433 Clear();
75ce0581
RR
434
435 return AddData( data );
436}
437
438bool wxClipboard::AddData( wxDataObject *data )
439{
223d09f6 440 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
270c23f7 441
223d09f6 442 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
270c23f7 443
ca11abde 444 // we can only store one wxDataObject
1dd989e1 445 Clear();
270c23f7 446
1dd989e1
RR
447 m_data = data;
448
ca11abde 449 // get formats from wxDataObjects
b068c4e8
RR
450 wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ];
451 m_data->GetAllFormats( array );
11e1c70d 452
ca11abde 453 // primary selection or clipboard
11e1c70d
RR
454 GdkAtom clipboard = m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
455 : g_clipboardAtom;
456
d394f0c9
MR
457 // by default provide TIMESTAMP as a target
458 gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget),
459 clipboard,
460 g_timestampAtom,
461 0 );
270c23f7 462
b068c4e8
RR
463 for (size_t i = 0; i < m_data->GetFormatCount(); i++)
464 {
61b04ac6
VZ
465 wxLogTrace( TRACE_CLIPBOARD,
466 wxT("wxClipboard now supports atom %s"),
467 array[i].GetId().c_str() );
11e1c70d 468
3d257b8d 469// printf( "added %s\n",
ca11abde 470// gdk_atom_name( array[i].GetFormatId() ) );
3d257b8d 471
11e1c70d 472 gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget),
270c23f7
VZ
473 clipboard,
474 array[i],
11e1c70d 475 0 ); /* what is info ? */
b068c4e8
RR
476 }
477
478 delete[] array;
270c23f7 479
9fa72bd2 480 g_signal_connect (m_clipboardWidget, "selection_get",
d394f0c9
MR
481 G_CALLBACK (selection_handler),
482 GUINT_TO_POINTER (gtk_get_current_event_time()) );
d345e841 483
b453e1b2 484#if wxUSE_THREADS
11e1c70d 485 /* disable GUI threads */
b453e1b2 486#endif
270c23f7 487
75ce0581 488 /* Tell the world we offer clipboard data */
11e1c70d
RR
489 bool res = (gtk_selection_owner_set( m_clipboardWidget,
490 clipboard,
b02da6b1 491 (guint32) GDK_CURRENT_TIME ));
270c23f7 492
11e1c70d
RR
493 if (m_usePrimary)
494 m_ownsPrimarySelection = res;
495 else
496 m_ownsClipboard = res;
270c23f7 497
b453e1b2
RR
498#if wxUSE_THREADS
499 /* re-enable GUI threads */
b453e1b2 500#endif
270c23f7 501
11e1c70d 502 return res;
8b53e5a2 503}
db1b4961 504
8b53e5a2
RR
505void wxClipboard::Close()
506{
223d09f6 507 wxCHECK_RET( m_open, wxT("clipboard not open") );
270c23f7 508
8b53e5a2 509 m_open = FALSE;
dc86cb34
RR
510}
511
f536e0f2
VZ
512bool wxClipboard::IsOpened() const
513{
514 return m_open;
515}
516
e1ee679c 517bool wxClipboard::IsSupported( const wxDataFormat& format )
b527aac5 518{
e5d6aa22 519 /* reentrance problems */
eff869aa 520 if (m_waiting) return FALSE;
270c23f7 521
e5d6aa22 522 /* store requested format to be asked for by callbacks */
1dd989e1 523 m_targetRequested = format;
270c23f7 524
61b04ac6
VZ
525 wxLogTrace( TRACE_CLIPBOARD,
526 wxT("wxClipboard:IsSupported: requested format: %s"),
527 format.GetId().c_str() );
eff869aa 528
223d09f6 529 wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
270c23f7 530
8b53e5a2 531 m_formatSupported = FALSE;
270c23f7
VZ
532
533 /* perform query. this will set m_formatSupported to
034be888 534 TRUE if m_targetRequested is supported.
270c23f7 535 also, we have to wait for the "answer" from the
034be888
RR
536 clipboard owner which is an asynchronous process.
537 therefore we set m_waiting = TRUE here and wait
270c23f7 538 until the callback "targets_selection_received"
034be888
RR
539 sets it to FALSE */
540
541 m_waiting = TRUE;
ca35e608 542
034be888 543 gtk_selection_convert( m_targetsWidget,
66633398 544 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 545 : g_clipboardAtom,
66633398 546 g_targetsAtom,
b02da6b1 547 (guint32) GDK_CURRENT_TIME );
ca35e608 548
034be888 549 while (m_waiting) gtk_main_iteration();
270c23f7 550
c7d6d883
RR
551#if defined(__WXGTK20__) && wxUSE_UNICODE
552 if (!m_formatSupported && format == wxDataFormat(wxDF_UNICODETEXT))
553 {
554 // Another try with plain STRING format
555 extern GdkAtom g_altTextAtom;
556 return IsSupported(g_altTextAtom);
557 }
558#endif
559
ebe47451 560 return m_formatSupported;
270c23f7
VZ
561}
562
e1ee679c 563bool wxClipboard::GetData( wxDataObject& data )
75ce0581 564{
223d09f6 565 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
270c23f7 566
b068c4e8
RR
567 /* get formats from wxDataObjects */
568 wxDataFormat *array = new wxDataFormat[ data.GetFormatCount() ];
569 data.GetAllFormats( array );
270c23f7 570
b068c4e8
RR
571 for (size_t i = 0; i < data.GetFormatCount(); i++)
572 {
e5d6aa22 573 wxDataFormat format( array[i] );
270c23f7 574
61b04ac6
VZ
575 wxLogTrace( TRACE_CLIPBOARD,
576 wxT("wxClipboard::GetData: requested format: %s"),
577 format.GetId().c_str() );
270c23f7 578
b068c4e8 579 /* is data supported by clipboard ? */
270c23f7 580
11e1c70d
RR
581 /* store requested format to be asked for by callbacks */
582 m_targetRequested = format;
270c23f7 583
11e1c70d 584 wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
270c23f7 585
11e1c70d 586 m_formatSupported = FALSE;
270c23f7
VZ
587
588 /* perform query. this will set m_formatSupported to
11e1c70d 589 TRUE if m_targetRequested is supported.
270c23f7 590 also, we have to wait for the "answer" from the
11e1c70d
RR
591 clipboard owner which is an asynchronous process.
592 therefore we set m_waiting = TRUE here and wait
270c23f7 593 until the callback "targets_selection_received"
11e1c70d
RR
594 sets it to FALSE */
595
596 m_waiting = TRUE;
597
598 gtk_selection_convert( m_targetsWidget,
599 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 600 : g_clipboardAtom,
11e1c70d 601 g_targetsAtom,
b02da6b1 602 (guint32) GDK_CURRENT_TIME );
11e1c70d
RR
603
604 while (m_waiting) gtk_main_iteration();
270c23f7 605
11e1c70d 606 if (!m_formatSupported) continue;
270c23f7 607
b068c4e8
RR
608 /* store pointer to data object to be filled up by callbacks */
609 m_receivedData = &data;
270c23f7 610
b068c4e8 611 /* store requested format to be asked for by callbacks */
e5d6aa22 612 m_targetRequested = format;
270c23f7 613
b068c4e8 614 wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
270c23f7 615
b068c4e8
RR
616 /* start query */
617 m_formatSupported = FALSE;
270c23f7
VZ
618
619 /* ask for clipboard contents. this will set
620 m_formatSupported to TRUE if m_targetRequested
b068c4e8 621 is supported.
270c23f7 622 also, we have to wait for the "answer" from the
b068c4e8
RR
623 clipboard owner which is an asynchronous process.
624 therefore we set m_waiting = TRUE here and wait
270c23f7 625 until the callback "targets_selection_received"
b068c4e8
RR
626 sets it to FALSE */
627
628 m_waiting = TRUE;
629
47cf53ef
VZ
630 wxLogTrace( TRACE_CLIPBOARD,
631 wxT("wxClipboard::GetData: format found, start convert") );
270c23f7 632
b068c4e8 633 gtk_selection_convert( m_clipboardWidget,
66633398 634 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 635 : g_clipboardAtom,
66633398 636 m_targetRequested,
b02da6b1 637 (guint32) GDK_CURRENT_TIME );
270c23f7 638
b068c4e8 639 while (m_waiting) gtk_main_iteration();
b527aac5 640
b068c4e8
RR
641 /* this is a true error as we checked for the presence of such data before */
642 wxCHECK_MSG( m_formatSupported, FALSE, wxT("error retrieving data from clipboard") );
270c23f7 643
66633398 644 /* return success */
b068c4e8
RR
645 delete[] array;
646 return TRUE;
647 }
270c23f7 648
47cf53ef
VZ
649 wxLogTrace( TRACE_CLIPBOARD,
650 wxT("wxClipboard::GetData: format not found") );
270c23f7 651
b068c4e8
RR
652 /* return failure */
653 delete[] array;
654 return FALSE;
b527aac5
RR
655}
656
ac57418f 657#endif
ac57418f 658 // wxUSE_CLIPBOARD