]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/clipbrd.cpp
Add 1 to the width returned by DoGetBestSize in order to work around a
[wxWidgets.git] / src / gtk / clipbrd.cpp
CommitLineData
dc86cb34 1/////////////////////////////////////////////////////////////////////////////
e4db172a 2// Name: src/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
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
67756da4 24#include "wx/gtk/private.h"
83624f79 25
dc86cb34
RR
26//-----------------------------------------------------------------------------
27// data
28//-----------------------------------------------------------------------------
29
fd0eed64 30GdkAtom g_clipboardAtom = 0;
b527aac5 31GdkAtom g_targetsAtom = 0;
d394f0c9 32GdkAtom g_timestampAtom = 0;
fd0eed64 33
5e081315 34#if wxUSE_UNICODE
c7d6d883
RR
35extern GdkAtom g_altTextAtom;
36#endif
37
61b04ac6
VZ
38// the trace mask we use with wxLogTrace() - call
39// wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here
40// (there will be a *lot* of them!)
cbf97a6c 41static const wxChar *TRACE_CLIPBOARD = _T("clipboard");
61b04ac6 42
dc86cb34 43//-----------------------------------------------------------------------------
b527aac5 44// reminder
dc86cb34
RR
45//-----------------------------------------------------------------------------
46
b527aac5 47/* The contents of a selection are returned in a GtkSelectionData
270c23f7 48 structure. selection/target identify the request.
b527aac5
RR
49 type specifies the type of the return; if length < 0, and
50 the data should be ignored. This structure has object semantics -
51 no fields should be modified directly, they should not be created
52 directly, and pointers to them should not be stored beyond the duration of
53 a callback. (If the last is changed, we'll need to add reference
54 counting)
55
56struct _GtkSelectionData
dc86cb34 57{
b527aac5
RR
58 GdkAtom selection;
59 GdkAtom target;
60 GdkAtom type;
61b04ac6 61 gint format;
b527aac5 62 guchar *data;
61b04ac6 63 gint length;
b527aac5
RR
64};
65
66*/
dc86cb34 67
b527aac5
RR
68//-----------------------------------------------------------------------------
69// "selection_received" for targets
70//-----------------------------------------------------------------------------
71
865bb325 72extern "C" {
b527aac5 73static void
270c23f7
VZ
74targets_selection_received( GtkWidget *WXUNUSED(widget),
75 GtkSelectionData *selection_data,
034be888 76 guint32 WXUNUSED(time),
66633398 77 wxClipboard *clipboard )
dc86cb34 78{
270c23f7 79 if ( wxTheClipboard && selection_data->length > 0 )
034be888 80 {
ca11abde 81 // make sure we got the data in the correct form
270c23f7
VZ
82 GdkAtom type = selection_data->type;
83 if ( type != GDK_SELECTION_TYPE_ATOM )
84 {
67756da4 85 if ( strcmp(wxGtkString(gdk_atom_name(type)), "TARGETS") )
61b04ac6
VZ
86 {
87 wxLogTrace( TRACE_CLIPBOARD,
88 _T("got unsupported clipboard target") );
89
de6185e2 90 clipboard->m_waiting = false;
61b04ac6
VZ
91 return;
92 }
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 {
e4db172a
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
e4db172a 183 wxTheClipboard->m_formatSupported = true;
de6185e2 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{
e4db172a 196 if (!wxTheClipboard) return true;
270c23f7 197
aeeb6a44
RR
198 if (event->selection == GDK_SELECTION_PRIMARY)
199 {
e4db172a 200 wxTheClipboard->m_ownsPrimarySelection = false;
aeeb6a44
RR
201 }
202 else
203 if (event->selection == g_clipboardAtom)
204 {
e4db172a 205 wxTheClipboard->m_ownsClipboard = false;
aeeb6a44
RR
206 }
207 else
208 {
e4db172a 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
e4db172a 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 272 format.GetId().c_str(),
67756da4
MR
273 wxString::FromAscii(wxGtkString(gdk_atom_name(selection_data->target))).c_str(),
274 wxString::FromAscii(wxGtkString(gdk_atom_name(selection_data->type))).c_str(),
275 wxString::FromAscii(wxGtkString(gdk_atom_name(selection_data->selection))).c_str(),
d394f0c9 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
ebe47451
VS
291 // NB: GTK+ requires special treatment of UTF8_STRING data, the text
292 // would show as UTF-8 data interpreted as latin1 (?) in other
293 // GTK+ apps if we used gtk_selection_data_set()
294 if (format == wxDataFormat(wxDF_UNICODETEXT))
295 {
296 gtk_selection_data_set_text(
297 selection_data,
298 (const gchar*)d,
2c906a49 299 size );
ebe47451
VS
300 }
301 else
ebe47451
VS
302 {
303 gtk_selection_data_set(
304 selection_data,
305 GDK_SELECTION_TYPE_STRING,
306 8*sizeof(gchar),
307 (unsigned char*) d,
2c906a49 308 size );
ebe47451 309 }
33754c4d
VZ
310
311 free(d);
fd0eed64 312}
865bb325 313}
dc86cb34
RR
314
315//-----------------------------------------------------------------------------
316// wxClipboard
317//-----------------------------------------------------------------------------
318
319IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
320
321wxClipboard::wxClipboard()
322{
de6185e2
WS
323 m_open = false;
324 m_waiting = false;
8b53e5a2 325
de6185e2
WS
326 m_ownsClipboard = false;
327 m_ownsPrimarySelection = false;
aeeb6a44 328
1dd989e1 329 m_data = (wxDataObject*) NULL;
8b53e5a2 330 m_receivedData = (wxDataObject*) NULL;
99c67c77 331
034be888 332 /* we use m_targetsWidget to query what formats are available */
270c23f7 333
034be888
RR
334 m_targetsWidget = gtk_window_new( GTK_WINDOW_POPUP );
335 gtk_widget_realize( m_targetsWidget );
336
9fa72bd2
MR
337 g_signal_connect (m_targetsWidget, "selection_received",
338 G_CALLBACK (targets_selection_received), this);
270c23f7 339
034be888 340 /* we use m_clipboardWidget to get and to offer data */
270c23f7 341
8b53e5a2
RR
342 m_clipboardWidget = gtk_window_new( GTK_WINDOW_POPUP );
343 gtk_widget_realize( m_clipboardWidget );
344
9fa72bd2
MR
345 g_signal_connect (m_clipboardWidget, "selection_received",
346 G_CALLBACK (selection_received), this);
034be888 347
9fa72bd2
MR
348 g_signal_connect (m_clipboardWidget, "selection_clear_event",
349 G_CALLBACK (selection_clear_clip), NULL);
270c23f7 350
8b53e5a2 351 if (!g_clipboardAtom) g_clipboardAtom = gdk_atom_intern( "CLIPBOARD", FALSE );
8b53e5a2 352 if (!g_targetsAtom) g_targetsAtom = gdk_atom_intern ("TARGETS", FALSE);
d394f0c9 353 if (!g_timestampAtom) g_timestampAtom = gdk_atom_intern ("TIMESTAMP", FALSE);
270c23f7 354
de6185e2 355 m_formatSupported = false;
8b53e5a2 356 m_targetRequested = 0;
270c23f7 357
de6185e2 358 m_usePrimary = false;
dc86cb34
RR
359}
360
361wxClipboard::~wxClipboard()
b527aac5 362{
270c23f7
VZ
363 Clear();
364
8b53e5a2 365 if (m_clipboardWidget) gtk_widget_destroy( m_clipboardWidget );
034be888 366 if (m_targetsWidget) gtk_widget_destroy( m_targetsWidget );
b527aac5
RR
367}
368
369void wxClipboard::Clear()
dc86cb34 370{
1dd989e1
RR
371 if (m_data)
372 {
b453e1b2
RR
373#if wxUSE_THREADS
374 /* disable GUI threads */
b453e1b2 375#endif
270c23f7 376
ca11abde
RR
377 // As we have data we also own the clipboard. Once we no longer own
378 // it, clear_selection is called which will set m_data to zero
aeeb6a44 379 if (gdk_selection_owner_get( g_clipboardAtom ) == m_clipboardWidget->window)
8b53e5a2 380 {
e4db172a 381 m_waiting = true;
270c23f7 382
b02da6b1
VZ
383 gtk_selection_owner_set( (GtkWidget*) NULL, g_clipboardAtom,
384 (guint32) GDK_CURRENT_TIME );
270c23f7 385
e5ea3f7a 386 while (m_waiting) gtk_main_iteration();
8b53e5a2 387 }
270c23f7 388
aeeb6a44
RR
389 if (gdk_selection_owner_get( GDK_SELECTION_PRIMARY ) == m_clipboardWidget->window)
390 {
de6185e2 391 m_waiting = true;
270c23f7 392
b02da6b1
VZ
393 gtk_selection_owner_set( (GtkWidget*) NULL, GDK_SELECTION_PRIMARY,
394 (guint32) GDK_CURRENT_TIME );
270c23f7 395
e5ea3f7a 396 while (m_waiting) gtk_main_iteration();
aeeb6a44 397 }
270c23f7 398
1dd989e1 399 if (m_data)
270c23f7 400 {
66633398
VZ
401 delete m_data;
402 m_data = (wxDataObject*) NULL;
403 }
270c23f7 404
b453e1b2
RR
405#if wxUSE_THREADS
406 /* re-enable GUI threads */
b453e1b2 407#endif
8b53e5a2 408 }
270c23f7 409
8b53e5a2 410 m_targetRequested = 0;
de6185e2 411 m_formatSupported = false;
8b53e5a2
RR
412}
413
414bool wxClipboard::Open()
415{
de6185e2 416 wxCHECK_MSG( !m_open, false, wxT("clipboard already open") );
270c23f7 417
de6185e2 418 m_open = true;
270c23f7 419
de6185e2 420 return true;
dc86cb34
RR
421}
422
75ce0581 423bool wxClipboard::SetData( wxDataObject *data )
dc86cb34 424{
de6185e2 425 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
270c23f7 426
de6185e2 427 wxCHECK_MSG( data, false, wxT("data is invalid") );
270c23f7 428
0d2a2b60 429 Clear();
75ce0581
RR
430
431 return AddData( data );
432}
433
434bool wxClipboard::AddData( wxDataObject *data )
435{
de6185e2 436 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
270c23f7 437
de6185e2 438 wxCHECK_MSG( data, false, wxT("data is invalid") );
270c23f7 439
ca11abde 440 // we can only store one wxDataObject
1dd989e1 441 Clear();
270c23f7 442
1dd989e1
RR
443 m_data = data;
444
ca11abde 445 // get formats from wxDataObjects
b068c4e8
RR
446 wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ];
447 m_data->GetAllFormats( array );
11e1c70d 448
ca11abde 449 // primary selection or clipboard
11e1c70d
RR
450 GdkAtom clipboard = m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
451 : g_clipboardAtom;
452
d394f0c9
MR
453 // by default provide TIMESTAMP as a target
454 gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget),
455 clipboard,
456 g_timestampAtom,
457 0 );
270c23f7 458
b068c4e8
RR
459 for (size_t i = 0; i < m_data->GetFormatCount(); i++)
460 {
61b04ac6
VZ
461 wxLogTrace( TRACE_CLIPBOARD,
462 wxT("wxClipboard now supports atom %s"),
463 array[i].GetId().c_str() );
11e1c70d 464
3d257b8d 465// printf( "added %s\n",
ca11abde 466// gdk_atom_name( array[i].GetFormatId() ) );
3d257b8d 467
11e1c70d 468 gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget),
270c23f7
VZ
469 clipboard,
470 array[i],
11e1c70d 471 0 ); /* what is info ? */
b068c4e8
RR
472 }
473
474 delete[] array;
270c23f7 475
9fa72bd2 476 g_signal_connect (m_clipboardWidget, "selection_get",
d394f0c9
MR
477 G_CALLBACK (selection_handler),
478 GUINT_TO_POINTER (gtk_get_current_event_time()) );
d345e841 479
b453e1b2 480#if wxUSE_THREADS
11e1c70d 481 /* disable GUI threads */
b453e1b2 482#endif
270c23f7 483
75ce0581 484 /* Tell the world we offer clipboard data */
11e1c70d
RR
485 bool res = (gtk_selection_owner_set( m_clipboardWidget,
486 clipboard,
b02da6b1 487 (guint32) GDK_CURRENT_TIME ));
270c23f7 488
11e1c70d
RR
489 if (m_usePrimary)
490 m_ownsPrimarySelection = res;
491 else
492 m_ownsClipboard = res;
270c23f7 493
b453e1b2
RR
494#if wxUSE_THREADS
495 /* re-enable GUI threads */
b453e1b2 496#endif
270c23f7 497
11e1c70d 498 return res;
8b53e5a2 499}
db1b4961 500
8b53e5a2
RR
501void wxClipboard::Close()
502{
223d09f6 503 wxCHECK_RET( m_open, wxT("clipboard not open") );
270c23f7 504
de6185e2 505 m_open = false;
dc86cb34
RR
506}
507
f536e0f2
VZ
508bool wxClipboard::IsOpened() const
509{
510 return m_open;
511}
512
e1ee679c 513bool wxClipboard::IsSupported( const wxDataFormat& format )
b527aac5 514{
e5d6aa22 515 /* reentrance problems */
de6185e2 516 if (m_waiting) return false;
270c23f7 517
e5d6aa22 518 /* store requested format to be asked for by callbacks */
1dd989e1 519 m_targetRequested = format;
270c23f7 520
61b04ac6
VZ
521 wxLogTrace( TRACE_CLIPBOARD,
522 wxT("wxClipboard:IsSupported: requested format: %s"),
523 format.GetId().c_str() );
eff869aa 524
de6185e2 525 wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") );
270c23f7 526
de6185e2 527 m_formatSupported = false;
270c23f7
VZ
528
529 /* perform query. this will set m_formatSupported to
de6185e2 530 true if m_targetRequested is supported.
270c23f7 531 also, we have to wait for the "answer" from the
034be888 532 clipboard owner which is an asynchronous process.
de6185e2 533 therefore we set m_waiting = true here and wait
270c23f7 534 until the callback "targets_selection_received"
de6185e2 535 sets it to false */
034be888 536
de6185e2 537 m_waiting = true;
ca35e608 538
034be888 539 gtk_selection_convert( m_targetsWidget,
66633398 540 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 541 : g_clipboardAtom,
66633398 542 g_targetsAtom,
b02da6b1 543 (guint32) GDK_CURRENT_TIME );
ca35e608 544
034be888 545 while (m_waiting) gtk_main_iteration();
270c23f7 546
5e081315 547#if wxUSE_UNICODE
c7d6d883
RR
548 if (!m_formatSupported && format == wxDataFormat(wxDF_UNICODETEXT))
549 {
550 // Another try with plain STRING format
551 extern GdkAtom g_altTextAtom;
552 return IsSupported(g_altTextAtom);
553 }
554#endif
555
ebe47451 556 return m_formatSupported;
270c23f7
VZ
557}
558
e1ee679c 559bool wxClipboard::GetData( wxDataObject& data )
75ce0581 560{
de6185e2 561 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
270c23f7 562
b068c4e8
RR
563 /* get formats from wxDataObjects */
564 wxDataFormat *array = new wxDataFormat[ data.GetFormatCount() ];
565 data.GetAllFormats( array );
270c23f7 566
b068c4e8
RR
567 for (size_t i = 0; i < data.GetFormatCount(); i++)
568 {
e5d6aa22 569 wxDataFormat format( array[i] );
270c23f7 570
61b04ac6
VZ
571 wxLogTrace( TRACE_CLIPBOARD,
572 wxT("wxClipboard::GetData: requested format: %s"),
573 format.GetId().c_str() );
270c23f7 574
b068c4e8 575 /* is data supported by clipboard ? */
270c23f7 576
11e1c70d
RR
577 /* store requested format to be asked for by callbacks */
578 m_targetRequested = format;
270c23f7 579
de6185e2 580 wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") );
270c23f7 581
de6185e2 582 m_formatSupported = false;
270c23f7
VZ
583
584 /* perform query. this will set m_formatSupported to
de6185e2 585 true if m_targetRequested is supported.
270c23f7 586 also, we have to wait for the "answer" from the
11e1c70d 587 clipboard owner which is an asynchronous process.
de6185e2 588 therefore we set m_waiting = true here and wait
270c23f7 589 until the callback "targets_selection_received"
de6185e2 590 sets it to false */
11e1c70d 591
de6185e2 592 m_waiting = true;
11e1c70d
RR
593
594 gtk_selection_convert( m_targetsWidget,
595 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 596 : g_clipboardAtom,
11e1c70d 597 g_targetsAtom,
b02da6b1 598 (guint32) GDK_CURRENT_TIME );
11e1c70d
RR
599
600 while (m_waiting) gtk_main_iteration();
270c23f7 601
11e1c70d 602 if (!m_formatSupported) continue;
270c23f7 603
b068c4e8
RR
604 /* store pointer to data object to be filled up by callbacks */
605 m_receivedData = &data;
270c23f7 606
b068c4e8 607 /* store requested format to be asked for by callbacks */
e5d6aa22 608 m_targetRequested = format;
270c23f7 609
de6185e2 610 wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") );
270c23f7 611
b068c4e8 612 /* start query */
de6185e2 613 m_formatSupported = false;
270c23f7
VZ
614
615 /* ask for clipboard contents. this will set
de6185e2 616 m_formatSupported to true if m_targetRequested
b068c4e8 617 is supported.
270c23f7 618 also, we have to wait for the "answer" from the
b068c4e8 619 clipboard owner which is an asynchronous process.
de6185e2 620 therefore we set m_waiting = true here and wait
270c23f7 621 until the callback "targets_selection_received"
de6185e2 622 sets it to false */
b068c4e8 623
de6185e2 624 m_waiting = true;
b068c4e8 625
47cf53ef
VZ
626 wxLogTrace( TRACE_CLIPBOARD,
627 wxT("wxClipboard::GetData: format found, start convert") );
270c23f7 628
b068c4e8 629 gtk_selection_convert( m_clipboardWidget,
66633398 630 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 631 : g_clipboardAtom,
66633398 632 m_targetRequested,
b02da6b1 633 (guint32) GDK_CURRENT_TIME );
270c23f7 634
b068c4e8 635 while (m_waiting) gtk_main_iteration();
b527aac5 636
b068c4e8 637 /* this is a true error as we checked for the presence of such data before */
de6185e2 638 wxCHECK_MSG( m_formatSupported, false, wxT("error retrieving data from clipboard") );
270c23f7 639
66633398 640 /* return success */
b068c4e8 641 delete[] array;
de6185e2 642 return true;
b068c4e8 643 }
270c23f7 644
47cf53ef
VZ
645 wxLogTrace( TRACE_CLIPBOARD,
646 wxT("wxClipboard::GetData: format not found") );
270c23f7 647
b068c4e8
RR
648 /* return failure */
649 delete[] array;
de6185e2 650 return false;
b527aac5
RR
651}
652
ac57418f 653#endif
ac57418f 654 // wxUSE_CLIPBOARD