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