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