Now compiling
[wxWidgets.git] / src / x11 / clipbrd.cpp
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
43 static bool gs_clipboardIsOpen = FALSE;
44
45 bool wxOpenClipboard()
46 {
47 if (!gs_clipboardIsOpen)
48 {
49 gs_clipboardIsOpen = TRUE;
50 return TRUE;
51 }
52 else
53 return FALSE;
54 }
55
56 bool wxCloseClipboard()
57 {
58 if (gs_clipboardIsOpen)
59 {
60 gs_clipboardIsOpen = FALSE;
61 return TRUE;
62 }
63 else
64 return FALSE;
65 }
66
67 bool wxEmptyClipboard()
68 {
69 // No equivalent in Motif
70 return TRUE;
71 }
72
73 bool wxClipboardOpen()
74 {
75 return gs_clipboardIsOpen;
76 }
77
78 bool 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
106 bool 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
160 wxObject *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
223 wxDataFormat 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
232 wxDataFormat wxRegisterClipboardFormat(char *WXUNUSED(formatName))
233 {
234 // Not supported
235 return (wxDataFormat) wxDF_INVALID;
236 }
237
238 bool 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
254 IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
255
256 wxClipboard::wxClipboard()
257 {
258 m_open = FALSE;
259 }
260
261 wxClipboard::~wxClipboard()
262 {
263 Clear();
264 }
265
266 void 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
278 bool wxClipboard::Open()
279 {
280 wxCHECK_MSG( !m_open, FALSE, "clipboard already open" );
281
282 m_open = TRUE;
283
284 return wxOpenClipboard();
285 }
286
287 bool 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
297 bool 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
327 void wxClipboard::Close()
328 {
329 wxCHECK_RET( m_open, "clipboard not open" );
330
331 m_open = FALSE;
332 wxCloseClipboard();
333 }
334
335 bool wxClipboard::IsSupported( const wxDataFormat& format)
336 {
337 return wxIsClipboardFormatAvailable(format);
338 }
339
340 bool 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
393 wxClipboard *wxTheClipboard = NULL;
394
395 void wxInitClipboard()
396 {
397 if (!wxTheClipboard)
398 wxTheClipboard = new wxClipboard;
399 }
400
401 wxClipboard::wxClipboard()
402 {
403 clipOwner = NULL;
404 cbString = NULL;
405 }
406
407 wxClipboard::~wxClipboard()
408 {
409 if (clipOwner)
410 clipOwner->BeingReplaced();
411 if (cbString)
412 delete[] cbString;
413 }
414
415 static int FormatStringToID(char *str)
416 {
417 if (!strcmp(str, "TEXT"))
418 return wxDF_TEXT;
419
420 return wxRegisterClipboardFormat(str);
421 }
422
423 void 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
464 wxClipboardClient *wxClipboard::GetClipboardClient()
465 {
466 return clipOwner;
467 }
468
469 void 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
498 char *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
512 char *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