]> git.saurik.com Git - wxWidgets.git/blame - src/motif/clipbrd.cpp
wxMSW update for CW, wxMac updated
[wxWidgets.git] / src / motif / clipbrd.cpp
CommitLineData
4bb6408c
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: clipbrd.cpp
3// Purpose: Clipboard functionality
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation
14#pragma implementation "clipbrd.h"
15#endif
16
dfe1eee3
VZ
17#include "wx/defs.h"
18
19#if wxUSE_CLIPBOARD
20
4bb6408c
JS
21#include "wx/app.h"
22#include "wx/frame.h"
23#include "wx/bitmap.h"
24#include "wx/utils.h"
25#include "wx/metafile.h"
26#include "wx/clipbrd.h"
2d120f83
JS
27#include "wx/dataobj.h"
28
338dd992
JJ
29#ifdef __VMS__
30#pragma message disable nosimpint
31#endif
2d120f83
JS
32#include <Xm/Xm.h>
33#include <Xm/CutPaste.h>
338dd992
JJ
34#ifdef __VMS__
35#pragma message enable nosimpint
36#endif
4bb6408c
JS
37
38#include <string.h>
39
40#if !USE_SHARED_LIBRARY
2d120f83
JS
41// IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
42// IMPLEMENT_ABSTRACT_CLASS(wxClipboardClient, wxObject)
4bb6408c
JS
43#endif
44
2d120f83
JS
45static bool gs_clipboardIsOpen = FALSE;
46
4bb6408c
JS
47bool wxOpenClipboard()
48{
2d120f83
JS
49 if (!gs_clipboardIsOpen)
50 {
51 gs_clipboardIsOpen = TRUE;
52 return TRUE;
53 }
54 else
55 return FALSE;
4bb6408c
JS
56}
57
58bool wxCloseClipboard()
59{
2d120f83
JS
60 if (gs_clipboardIsOpen)
61 {
62 gs_clipboardIsOpen = FALSE;
63 return TRUE;
64 }
65 else
66 return FALSE;
4bb6408c
JS
67}
68
69bool wxEmptyClipboard()
70{
2d120f83
JS
71 // No equivalent in Motif
72 return TRUE;
4bb6408c
JS
73}
74
75bool wxClipboardOpen()
76{
2d120f83 77 return gs_clipboardIsOpen;
4bb6408c
JS
78}
79
2d120f83 80bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
4bb6408c 81{
2d120f83
JS
82 // Only text is supported.
83 if (dataFormat != wxDF_TEXT)
84 return FALSE;
85
86 unsigned long numBytes = 0;
87 long privateId = 0;
88
89 Window window = (Window) 0;
90 if (wxTheApp->GetTopWindow())
91 window = XtWindow( (Widget) wxTheApp->GetTopWindow()->GetTopWidget() );
92
93 int success = XmClipboardRetrieve((Display*) wxGetDisplay(),
9b64e798 94 window, "TEXT", (XtPointer) 0, 0, & numBytes, & privateId) ;
2d120f83
JS
95
96 // Assume only text is supported. If we have anything at all,
97 // or the clipboard is locked so we're not sure, we say we support it.
98 if (success == ClipboardNoData)
99 return FALSE;
100 else
101 return TRUE;
4bb6408c
JS
102}
103
af111fc3 104bool wxSetClipboardData(wxDataFormat dataFormat, wxObject *obj, int WXUNUSED(width), int WXUNUSED(height))
4bb6408c 105{
2d120f83
JS
106 if (dataFormat != wxDF_TEXT)
107 return FALSE;
108
109 char* data = (char*) obj;
110
111 XmString text = XmStringCreateSimple ("CLIPBOARD");
112 Window window = (Window) 0;
113 if (wxTheApp->GetTopWindow())
114 window = XtWindow( (Widget) wxTheApp->GetTopWindow()->GetTopWidget() );
115
116 long itemId = 0;
117 int result = 0;
118
119 while ((result =
120 XmClipboardStartCopy((Display*) wxGetDisplay(),
121 window,
122 text,
123 XtLastTimestampProcessed((Display*) wxGetDisplay()),
124 (Widget) 0,
125 (XmCutPasteProc) 0,
126 & itemId)) != ClipboardSuccess)
127
128 ;
129
130 XmStringFree (text);
131
132 long dataId = 0;
133 while ((result =
134 XmClipboardCopy((Display*) wxGetDisplay(),
135 window,
136 itemId,
9b64e798 137 "TEXT",
2d120f83
JS
138 (XtPointer) data,
139 strlen(data) + 1,
140 0,
141 & dataId)) != ClipboardSuccess)
142
143 ;
144
145 while (( result =
146 XmClipboardEndCopy((Display*) wxGetDisplay(),
147 window, itemId) ) != ClipboardSuccess)
148
149 ;
150
151 return TRUE;
4bb6408c
JS
152}
153
2d120f83 154wxObject *wxGetClipboardData(wxDataFormat dataFormat, long *len)
4bb6408c 155{
2d120f83
JS
156 if (dataFormat != wxDF_TEXT)
157 return (wxObject*) NULL;
158
159 bool done = FALSE;
160 long id = 0;
161 unsigned long numBytes = 0;
162 int result = 0;
163 Window window = (Window) 0;
164 if (wxTheApp->GetTopWindow())
165 window = XtWindow( (Widget) wxTheApp->GetTopWindow()->GetTopWidget() );
166
167 int currentDataSize = 256;
168 char* data = new char[currentDataSize];
169
170 while (!done)
171 {
172 if (result == ClipboardTruncate)
173 {
174 delete[] data;
175 currentDataSize = 2*currentDataSize;
176 data = new char[currentDataSize];
177 }
178 result = XmClipboardRetrieve((Display*) wxGetDisplay(),
179 window,
9b64e798 180 "TEXT",
2d120f83
JS
181 (XtPointer) data,
182 currentDataSize,
183 &numBytes,
184 &id);
185
186 switch (result)
187 {
188 case ClipboardSuccess:
189 {
190 if (len)
191 *len = strlen(data) + 1;
192 return (wxObject*) data;
193 break;
194 }
195 case ClipboardTruncate:
196 case ClipboardLocked:
197 {
198 break;
199 }
200 default:
201 case ClipboardNoData:
202 {
203 return (wxObject*) NULL;
204 break;
205 }
206 }
207
208 }
209
4bb6408c
JS
210 return NULL;
211}
212
2d120f83 213wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat)
4bb6408c 214{
2d120f83 215 // Only wxDF_TEXT supported
da175b2c 216 if (dataFormat == wxDF_TEXT)
2d120f83
JS
217 return wxDF_TEXT;
218 else
da175b2c 219 return wxDF_INVALID;
4bb6408c
JS
220}
221
af111fc3 222wxDataFormat wxRegisterClipboardFormat(char *WXUNUSED(formatName))
4bb6408c 223{
2d120f83 224 // Not supported
da175b2c 225 return (wxDataFormat) wxDF_INVALID;
4bb6408c
JS
226}
227
af111fc3 228bool wxGetClipboardFormatName(wxDataFormat dataFormat, char *formatName, int WXUNUSED(maxCount))
4bb6408c 229{
2d120f83
JS
230 // Only wxDF_TEXT supported
231 if (dataFormat == wxDF_TEXT)
232 {
9b64e798 233 strcpy(formatName, "TEXT");
2d120f83
JS
234 return TRUE;
235 }
236 else
237 return FALSE;
4bb6408c
JS
238}
239
2d120f83
JS
240//-----------------------------------------------------------------------------
241// wxClipboard
242//-----------------------------------------------------------------------------
4bb6408c 243
2d120f83 244IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
4bb6408c 245
4bb6408c
JS
246wxClipboard::wxClipboard()
247{
2d120f83 248 m_open = FALSE;
4bb6408c
JS
249}
250
251wxClipboard::~wxClipboard()
252{
2d120f83 253 Clear();
4bb6408c
JS
254}
255
2d120f83 256void wxClipboard::Clear()
4bb6408c 257{
2d120f83
JS
258 wxNode* node = m_data.First();
259 while (node)
260 {
261 wxDataObject* data = (wxDataObject*) node->Data();
262 delete data;
263 node = node->Next();
264 }
265 m_data.Clear();
4bb6408c
JS
266}
267
2d120f83 268bool wxClipboard::Open()
4bb6408c 269{
2d120f83
JS
270 wxCHECK_MSG( !m_open, FALSE, "clipboard already open" );
271
272 m_open = TRUE;
4bb6408c 273
2d120f83
JS
274 return wxOpenClipboard();
275}
4bb6408c 276
2d120f83
JS
277bool wxClipboard::SetData( wxDataObject *data )
278{
279 wxCHECK_MSG( data, FALSE, "data is invalid" );
280 wxCHECK_MSG( m_open, FALSE, "clipboard not open" );
281
12db77ca
VZ
282 Clear();
283
284 return AddData( data );
285}
286
287bool wxClipboard::AddData( wxDataObject *data )
288{
289 wxCHECK_MSG( data, FALSE, "data is invalid" );
290 wxCHECK_MSG( m_open, FALSE, "clipboard not open" );
291
292 wxDataFormat::NativeFormat format = data->GetPreferredFormat().GetType();
293 switch ( format )
2d120f83
JS
294 {
295 case wxDF_TEXT:
296 case wxDF_OEMTEXT:
297 {
298 wxTextDataObject* textDataObject = (wxTextDataObject*) data;
299 wxString str(textDataObject->GetText());
12db77ca 300 return wxSetClipboardData(format, (wxObject*) (const char*) str);
2d120f83 301 }
12db77ca 302#if 0
2d120f83
JS
303 case wxDF_BITMAP:
304 case wxDF_DIB:
305 {
306 wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
307 wxBitmap bitmap(bitmapDataObject->GetBitmap());
12db77ca 308 return wxSetClipboardData(data->GetType(), & bitmap);
2d120f83
JS
309 break;
310 }
12db77ca 311#endif // 0
2d120f83 312 }
4bb6408c 313
2d120f83
JS
314 return FALSE;
315}
4bb6408c 316
2d120f83
JS
317void wxClipboard::Close()
318{
319 wxCHECK_RET( m_open, "clipboard not open" );
320
321 m_open = FALSE;
322 wxCloseClipboard();
4bb6408c
JS
323}
324
12db77ca 325bool wxClipboard::IsSupported( const wxDataFormat& format)
4bb6408c 326{
2d120f83 327 return wxIsClipboardFormatAvailable(format);
4bb6408c
JS
328}
329
12db77ca 330bool wxClipboard::GetData( wxDataObject& data )
4bb6408c 331{
2d120f83
JS
332 wxCHECK_MSG( m_open, FALSE, "clipboard not open" );
333
12db77ca
VZ
334 wxDataFormat::NativeFormat format = data.GetPreferredFormat().GetType();
335 switch ( format )
2d120f83
JS
336 {
337 case wxDF_TEXT:
338 case wxDF_OEMTEXT:
339 {
12db77ca
VZ
340 wxTextDataObject& textDataObject = (wxTextDataObject &) data;
341 char* s = (char*) wxGetClipboardData(format);
2d120f83
JS
342 if (s)
343 {
12db77ca 344 textDataObject.SetText(s);
2d120f83
JS
345 delete[] s;
346 return TRUE;
347 }
348 else
349 return FALSE;
350 break;
351 }
da175b2c 352/*
2d120f83
JS
353 case wxDF_BITMAP:
354 case wxDF_DIB:
355 {
356 wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
12db77ca 357 wxBitmap* bitmap = (wxBitmap*) wxGetClipboardData(data->GetType());
2d120f83
JS
358 if (bitmap)
359 {
360 bitmapDataObject->SetBitmap(* bitmap);
361 delete bitmap;
362 return TRUE;
363 }
364 else
365 return FALSE;
366 break;
367 }
da175b2c 368*/
2d120f83
JS
369 default:
370 {
371 return FALSE;
372 }
373 }
374 return FALSE;
375}
4bb6408c 376
2d120f83
JS
377#if 0
378
379/*
380* Old clipboard implementation by Matthew Flatt
381*/
382
383wxClipboard *wxTheClipboard = NULL;
384
385void wxInitClipboard()
386{
387 if (!wxTheClipboard)
388 wxTheClipboard = new wxClipboard;
389}
4bb6408c 390
2d120f83
JS
391wxClipboard::wxClipboard()
392{
393 clipOwner = NULL;
4bb6408c 394 cbString = NULL;
4bb6408c
JS
395}
396
2d120f83
JS
397wxClipboard::~wxClipboard()
398{
399 if (clipOwner)
400 clipOwner->BeingReplaced();
401 if (cbString)
402 delete[] cbString;
403}
404
405static int FormatStringToID(char *str)
4bb6408c 406{
9b64e798 407 if (!strcmp(str, "TEXT"))
2d120f83
JS
408 return wxDF_TEXT;
409
410 return wxRegisterClipboardFormat(str);
411}
4bb6408c 412
2d120f83
JS
413void wxClipboard::SetClipboardClient(wxClipboardClient *client, long time)
414{
415 bool got_selection;
416
417 if (clipOwner)
418 clipOwner->BeingReplaced();
419 clipOwner = client;
420 if (cbString) {
421 delete[] cbString;
422 cbString = NULL;
423 }
424
425 if (wxOpenClipboard()) {
426 char **formats, *data;
427 int i;
428 int ftype;
429 long size;
430
431 formats = clipOwner->formats.ListToArray(FALSE);
432 for (i = clipOwner->formats.Number(); i--; ) {
433 ftype = FormatStringToID(formats[i]);
434 data = clipOwner->GetData(formats[i], &size);
435 if (!wxSetClipboardData(ftype, (wxObject *)data, size, 1)) {
436 got_selection = FALSE;
437 break;
438 }
439 }
440
441 if (i < 0)
442 got_selection = wxCloseClipboard();
443 } else
444 got_selection = FALSE;
445
446 got_selection = FALSE; // Assume another process takes over
447
448 if (!got_selection) {
449 clipOwner->BeingReplaced();
450 clipOwner = NULL;
451 }
452}
4bb6408c 453
2d120f83
JS
454wxClipboardClient *wxClipboard::GetClipboardClient()
455{
456 return clipOwner;
4bb6408c
JS
457}
458
2d120f83 459void wxClipboard::SetClipboardString(char *str, long time)
4bb6408c 460{
2d120f83
JS
461 bool got_selection;
462
463 if (clipOwner) {
464 clipOwner->BeingReplaced();
465 clipOwner = NULL;
466 }
467 if (cbString)
468 delete[] cbString;
469
470 cbString = str;
471
4bb6408c 472 if (wxOpenClipboard()) {
2d120f83
JS
473 if (!wxSetClipboardData(wxDF_TEXT, (wxObject *)str))
474 got_selection = FALSE;
475 else
476 got_selection = wxCloseClipboard();
4bb6408c 477 } else
2d120f83
JS
478 got_selection = FALSE;
479
480 got_selection = FALSE; // Assume another process takes over
481
482 if (!got_selection) {
483 delete[] cbString;
484 cbString = NULL;
485 }
486}
487
488char *wxClipboard::GetClipboardString(long time)
489{
490 char *str;
491 long length;
492
9b64e798 493 str = GetClipboardData("TEXT", &length, time);
2d120f83
JS
494 if (!str) {
495 str = new char[1];
496 *str = 0;
497 }
498
499 return str;
500}
4bb6408c 501
2d120f83
JS
502char *wxClipboard::GetClipboardData(char *format, long *length, long time)
503{
504 if (clipOwner) {
505 if (clipOwner->formats.Member(format))
506 return clipOwner->GetData(format, length);
507 else
508 return NULL;
509 } else if (cbString) {
9b64e798 510 if (!strcmp(format, "TEXT"))
2d120f83
JS
511 return copystring(cbString);
512 else
513 return NULL;
514 } else {
515 if (wxOpenClipboard()) {
516 receivedString = (char *)wxGetClipboardData(FormatStringToID(format),
517 length);
518 wxCloseClipboard();
519 } else
520 receivedString = NULL;
521
522 return receivedString;
523 }
4bb6408c 524}
2d120f83 525#endif
4bb6408c 526
dfe1eee3 527#endif // wxUSE_CLIPBOARD