]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/motif/clipbrd.cpp
*** empty log message ***
[wxWidgets.git] / src / motif / clipbrd.cpp
... / ...
CommitLineData
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
17#include "wx/defs.h"
18
19#if wxUSE_CLIPBOARD
20
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"
27#include "wx/dataobj.h"
28
29#ifdef __VMS__
30#pragma message disable nosimpint
31#endif
32#include <Xm/Xm.h>
33#include <Xm/CutPaste.h>
34#ifdef __VMS__
35#pragma message enable nosimpint
36#endif
37
38#include <string.h>
39
40// IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
41// IMPLEMENT_ABSTRACT_CLASS(wxClipboardClient, wxObject)
42
43static bool gs_clipboardIsOpen = FALSE;
44
45bool wxOpenClipboard()
46{
47 if (!gs_clipboardIsOpen)
48 {
49 gs_clipboardIsOpen = TRUE;
50 return TRUE;
51 }
52 else
53 return FALSE;
54}
55
56bool wxCloseClipboard()
57{
58 if (gs_clipboardIsOpen)
59 {
60 gs_clipboardIsOpen = FALSE;
61 return TRUE;
62 }
63 else
64 return FALSE;
65}
66
67bool wxEmptyClipboard()
68{
69 // No equivalent in Motif
70 return TRUE;
71}
72
73bool wxClipboardOpen()
74{
75 return gs_clipboardIsOpen;
76}
77
78bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
79{
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(),
92 window, "TEXT", (XtPointer) 0, 0, & numBytes, & privateId) ;
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;
100}
101
102bool wxSetClipboardData(wxDataFormat dataFormat, wxObject *obj, int WXUNUSED(width), int WXUNUSED(height))
103{
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,
135 "TEXT",
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;
150}
151
152wxObject *wxGetClipboardData(wxDataFormat dataFormat, long *len)
153{
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,
178 "TEXT",
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
208 return NULL;
209}
210
211wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat)
212{
213 // Only wxDF_TEXT supported
214 if (dataFormat == wxDF_TEXT)
215 return wxDF_TEXT;
216 else
217 return wxDF_INVALID;
218}
219
220wxDataFormat wxRegisterClipboardFormat(char *WXUNUSED(formatName))
221{
222 // Not supported
223 return (wxDataFormat) wxDF_INVALID;
224}
225
226bool wxGetClipboardFormatName(wxDataFormat dataFormat, char *formatName, int WXUNUSED(maxCount))
227{
228 // Only wxDF_TEXT supported
229 if (dataFormat == wxDF_TEXT)
230 {
231 strcpy(formatName, "TEXT");
232 return TRUE;
233 }
234 else
235 return FALSE;
236}
237
238//-----------------------------------------------------------------------------
239// wxClipboard
240//-----------------------------------------------------------------------------
241
242IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
243
244wxClipboard::wxClipboard()
245{
246 m_open = FALSE;
247}
248
249wxClipboard::~wxClipboard()
250{
251 Clear();
252}
253
254void wxClipboard::Clear()
255{
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();
264}
265
266bool wxClipboard::Open()
267{
268 wxCHECK_MSG( !m_open, FALSE, "clipboard already open" );
269
270 m_open = TRUE;
271
272 return wxOpenClipboard();
273}
274
275bool wxClipboard::SetData( wxDataObject *data )
276{
277 wxCHECK_MSG( data, FALSE, "data is invalid" );
278 wxCHECK_MSG( m_open, FALSE, "clipboard not open" );
279
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 )
292 {
293 case wxDF_TEXT:
294 case wxDF_OEMTEXT:
295 {
296 wxTextDataObject* textDataObject = (wxTextDataObject*) data;
297 wxString str(textDataObject->GetText());
298 return wxSetClipboardData(format, (wxObject*) (const char*) str);
299 }
300#if 0
301 case wxDF_BITMAP:
302 case wxDF_DIB:
303 {
304 wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
305 wxBitmap bitmap(bitmapDataObject->GetBitmap());
306 return wxSetClipboardData(data->GetType(), & bitmap);
307 break;
308 }
309#endif // 0
310 }
311
312 return FALSE;
313}
314
315void wxClipboard::Close()
316{
317 wxCHECK_RET( m_open, "clipboard not open" );
318
319 m_open = FALSE;
320 wxCloseClipboard();
321}
322
323bool wxClipboard::IsSupported( const wxDataFormat& format)
324{
325 return wxIsClipboardFormatAvailable(format);
326}
327
328bool wxClipboard::GetData( wxDataObject& data )
329{
330 wxCHECK_MSG( m_open, FALSE, "clipboard not open" );
331
332 wxDataFormat::NativeFormat format = data.GetPreferredFormat().GetType();
333 switch ( format )
334 {
335 case wxDF_TEXT:
336 case wxDF_OEMTEXT:
337 {
338 wxTextDataObject& textDataObject = (wxTextDataObject &) data;
339 char* s = (char*) wxGetClipboardData(format);
340 if (s)
341 {
342 textDataObject.SetText(s);
343 delete[] s;
344 return TRUE;
345 }
346 else
347 return FALSE;
348 break;
349 }
350/*
351 case wxDF_BITMAP:
352 case wxDF_DIB:
353 {
354 wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
355 wxBitmap* bitmap = (wxBitmap*) wxGetClipboardData(data->GetType());
356 if (bitmap)
357 {
358 bitmapDataObject->SetBitmap(* bitmap);
359 delete bitmap;
360 return TRUE;
361 }
362 else
363 return FALSE;
364 break;
365 }
366*/
367 default:
368 {
369 return FALSE;
370 }
371 }
372 return FALSE;
373}
374
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}
388
389wxClipboard::wxClipboard()
390{
391 clipOwner = NULL;
392 cbString = NULL;
393}
394
395wxClipboard::~wxClipboard()
396{
397 if (clipOwner)
398 clipOwner->BeingReplaced();
399 if (cbString)
400 delete[] cbString;
401}
402
403static int FormatStringToID(char *str)
404{
405 if (!strcmp(str, "TEXT"))
406 return wxDF_TEXT;
407
408 return wxRegisterClipboardFormat(str);
409}
410
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}
451
452wxClipboardClient *wxClipboard::GetClipboardClient()
453{
454 return clipOwner;
455}
456
457void wxClipboard::SetClipboardString(char *str, long time)
458{
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
470 if (wxOpenClipboard()) {
471 if (!wxSetClipboardData(wxDF_TEXT, (wxObject *)str))
472 got_selection = FALSE;
473 else
474 got_selection = wxCloseClipboard();
475 } else
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
491 str = GetClipboardData("TEXT", &length, time);
492 if (!str) {
493 str = new char[1];
494 *str = 0;
495 }
496
497 return str;
498}
499
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) {
508 if (!strcmp(format, "TEXT"))
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 }
522}
523#endif
524
525#endif // wxUSE_CLIPBOARD