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