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