]> git.saurik.com Git - wxWidgets.git/blob - src/os2/clipbrd.cpp
Add wxEvtHandler::CallAfter() for asynchronous method calls.
[wxWidgets.git] / src / os2 / clipbrd.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/clipbrd.cpp
3 // Purpose: Clipboard functionality
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/13/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #if wxUSE_CLIPBOARD
16
17 #include "wx/clipbrd.h"
18
19 #ifndef WX_PRECOMP
20 #include "wx/object.h"
21 #include "wx/event.h"
22 #include "wx/app.h"
23 #include "wx/frame.h"
24 #include "wx/bitmap.h"
25 #include "wx/utils.h"
26 #include "wx/intl.h"
27 #include "wx/log.h"
28 #include "wx/dataobj.h"
29 #endif
30
31 #if wxUSE_METAFILE
32 #include "wx/metafile.h"
33 #endif
34
35 #include <string.h>
36
37 #include "wx/os2/private.h"
38
39 // wxDataObject is tied to OLE/drag and drop implementation,
40 // therefore so is wxClipboard :-(
41
42 // ===========================================================================
43 // implementation
44 // ===========================================================================
45
46 // ---------------------------------------------------------------------------
47 // old-style clipboard functions using Windows API
48 // ---------------------------------------------------------------------------
49
50 static bool gs_wxClipboardIsOpen = false;
51
52 bool wxOpenClipboard()
53 {
54 wxCHECK_MSG( !gs_wxClipboardIsOpen, true, wxT("clipboard already opened.") );
55 // TODO:
56 /*
57 wxWindow *win = wxTheApp->GetTopWindow();
58 if ( win )
59 {
60 gs_wxClipboardIsOpen = ::OpenClipboard((HWND)win->GetHWND()) != 0;
61
62 if ( !gs_wxClipboardIsOpen )
63 {
64 wxLogSysError(_("Failed to open the clipboard."));
65 }
66
67 return gs_wxClipboardIsOpen;
68 }
69 else
70 {
71 wxLogDebug(wxT("Cannot open clipboard without a main window."));
72
73 return false;
74 }
75 */
76 return false;
77 }
78
79 bool wxCloseClipboard()
80 {
81 wxCHECK_MSG( gs_wxClipboardIsOpen, false, wxT("clipboard is not opened") );
82 // TODO:
83 /*
84 gs_wxClipboardIsOpen = false;
85
86 if ( ::CloseClipboard() == 0 )
87 {
88 wxLogSysError(_("Failed to close the clipboard."));
89
90 return false;
91 }
92 */
93 return true;
94 }
95
96 bool wxEmptyClipboard()
97 {
98 // TODO:
99 /*
100 if ( ::EmptyClipboard() == 0 )
101 {
102 wxLogSysError(_("Failed to empty the clipboard."));
103
104 return false;
105 }
106 */
107 return true;
108 }
109
110 bool wxIsClipboardOpened()
111 {
112 return gs_wxClipboardIsOpen;
113 }
114
115 bool wxIsClipboardFormatAvailable(wxDataFormat WXUNUSED(dataFormat))
116 {
117 // TODO: return ::IsClipboardFormatAvailable(dataFormat) != 0;
118 return false;
119 }
120
121 #if 0
122 #if wxUSE_DRAG_AND_DROP
123 static bool wxSetClipboardData(wxDataObject *data)
124 {
125 // TODO:
126 /*
127 size_t size = data->GetDataSize();
128 HANDLE hGlobal = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size);
129 if ( !hGlobal )
130 {
131 wxLogSysError(_("Failed to allocate %dKb of memory for clipboard "
132 "transfer."), size / 1024);
133
134 return false;
135 }
136
137 LPVOID lpGlobalMemory = ::GlobalLock(hGlobal);
138
139 data->GetDataHere(lpGlobalMemory);
140
141 GlobalUnlock(hGlobal);
142
143 wxDataFormat format = data->GetPreferredFormat();
144 if ( !::SetClipboardData(format, hGlobal) )
145 {
146 wxLogSysError(_("Failed to set clipboard data in format %s"),
147 wxDataObject::GetFormatName(format));
148
149 return false;
150 }
151 */
152 return true;
153 }
154 #endif // wxUSE_DRAG_AND_DROP
155 #endif
156
157 bool wxSetClipboardData(wxDataFormat WXUNUSED(dataFormat),
158 const void *WXUNUSED(data),
159 int WXUNUSED(width), int WXUNUSED(height))
160 {
161 // TODO:
162 /*
163 HANDLE handle = 0; // return value of SetClipboardData
164 switch (dataFormat)
165 {
166 case wxDF_BITMAP:
167 {
168 wxBitmap *bitmap = (wxBitmap *)data;
169
170 HDC hdcMem = CreateCompatibleDC((HDC) NULL);
171 HDC hdcSrc = CreateCompatibleDC((HDC) NULL);
172 HBITMAP old = (HBITMAP)
173 ::SelectObject(hdcSrc, (HBITMAP)bitmap->GetHBITMAP());
174 HBITMAP hBitmap = CreateCompatibleBitmap(hdcSrc,
175 bitmap->GetWidth(),
176 bitmap->GetHeight());
177 if (!hBitmap)
178 {
179 SelectObject(hdcSrc, old);
180 DeleteDC(hdcMem);
181 DeleteDC(hdcSrc);
182 return false;
183 }
184
185 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hBitmap);
186 BitBlt(hdcMem, 0, 0, bitmap->GetWidth(), bitmap->GetHeight(),
187 hdcSrc, 0, 0, SRCCOPY);
188
189 // Select new bitmap out of memory DC
190 SelectObject(hdcMem, old1);
191
192 // Set the data
193 handle = ::SetClipboardData(CF_BITMAP, hBitmap);
194
195 // Clean up
196 SelectObject(hdcSrc, old);
197 DeleteDC(hdcSrc);
198 DeleteDC(hdcMem);
199 break;
200 }
201
202 case wxDF_DIB:
203 {
204 #if wxUSE_IMAGE_LOADING_IN_MSW
205 wxBitmap *bitmap = (wxBitmap *)data;
206 HBITMAP hBitmap = (HBITMAP)bitmap->GetHBITMAP();
207 // NULL palette means to use the system one
208 HANDLE hDIB = wxBitmapToDIB(hBitmap, (HPALETTE)NULL);
209 handle = SetClipboardData(CF_DIB, hDIB);
210 #endif
211 break;
212 }
213
214 #if wxUSE_METAFILE
215 case wxDF_METAFILE:
216 {
217 wxMetafile *wxMF = (wxMetafile *)data;
218 HANDLE data = GlobalAlloc(GHND, sizeof(METAFILEPICT) + 1);
219 METAFILEPICT *mf = (METAFILEPICT *)GlobalLock(data);
220
221 mf->mm = wxMF->GetWindowsMappingMode();
222 mf->xExt = width;
223 mf->yExt = height;
224 mf->hMF = (HMETAFILE) wxMF->GetHMETAFILE();
225 GlobalUnlock(data);
226 wxMF->SetHMETAFILE((WXHANDLE) NULL);
227
228 handle = SetClipboardData(CF_METAFILEPICT, data);
229 break;
230 }
231 #endif
232 case CF_SYLK:
233 case CF_DIF:
234 case CF_TIFF:
235 case CF_PALETTE:
236 default:
237 {
238 wxLogError(_("Unsupported clipboard format."));
239 return false;
240 }
241
242 case wxDF_OEMTEXT:
243 dataFormat = wxDF_TEXT;
244 // fall through
245
246 case wxDF_TEXT:
247 {
248 char *s = (char *)data;
249
250 width = strlen(s) + 1;
251 height = 1;
252 DWORD l = (width * height);
253 HANDLE hGlobalMemory = GlobalAlloc(GHND, l);
254 if ( hGlobalMemory )
255 {
256 LPSTR lpGlobalMemory = (LPSTR)GlobalLock(hGlobalMemory);
257
258 memcpy(lpGlobalMemory, s, l);
259
260 GlobalUnlock(hGlobalMemory);
261 }
262
263 handle = SetClipboardData(dataFormat, hGlobalMemory);
264 break;
265 }
266 }
267
268 if ( handle == 0 )
269 {
270 wxLogSysError(_("Failed to set clipboard data."));
271
272 return false;
273 }
274 */
275 return true;
276 }
277
278 void *wxGetClipboardData(wxDataFormat WXUNUSED(dataFormat), long *WXUNUSED(len))
279 {
280 // void *retval = NULL;
281 // TODO:
282 /*
283 switch ( dataFormat )
284 {
285 case wxDF_BITMAP:
286 {
287 BITMAP bm;
288 HBITMAP hBitmap = (HBITMAP) GetClipboardData(CF_BITMAP);
289 if (!hBitmap)
290 break;
291
292 HDC hdcMem = CreateCompatibleDC((HDC) NULL);
293 HDC hdcSrc = CreateCompatibleDC((HDC) NULL);
294
295 HBITMAP old = (HBITMAP) ::SelectObject(hdcSrc, hBitmap);
296 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
297
298 HBITMAP hNewBitmap = CreateBitmapIndirect(&bm);
299
300 if (!hNewBitmap)
301 {
302 SelectObject(hdcSrc, old);
303 DeleteDC(hdcMem);
304 DeleteDC(hdcSrc);
305 break;
306 }
307
308 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hNewBitmap);
309 BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight,
310 hdcSrc, 0, 0, SRCCOPY);
311
312 // Select new bitmap out of memory DC
313 SelectObject(hdcMem, old1);
314
315 // Clean up
316 SelectObject(hdcSrc, old);
317 DeleteDC(hdcSrc);
318 DeleteDC(hdcMem);
319
320 // Create and return a new wxBitmap
321 wxBitmap *wxBM = new wxBitmap;
322 wxBM->SetHBITMAP((WXHBITMAP) hNewBitmap);
323 wxBM->SetWidth(bm.bmWidth);
324 wxBM->SetHeight(bm.bmHeight);
325 wxBM->SetDepth(bm.bmPlanes);
326 wxBM->SetOk(true);
327 retval = wxBM;
328 break;
329 }
330
331 case wxDF_METAFILE:
332 case CF_SYLK:
333 case CF_DIF:
334 case CF_TIFF:
335 case CF_PALETTE:
336 case wxDF_DIB:
337 {
338 wxLogError(_("Unsupported clipboard format."));
339 return NULL;
340 }
341
342 case wxDF_OEMTEXT:
343 dataFormat = wxDF_TEXT;
344 // fall through
345
346 case wxDF_TEXT:
347 {
348 HANDLE hGlobalMemory = ::GetClipboardData(dataFormat);
349 if (!hGlobalMemory)
350 break;
351
352 DWORD hsize = ::GlobalSize(hGlobalMemory);
353 if (len)
354 *len = hsize;
355
356 char *s = new char[hsize];
357 if (!s)
358 break;
359
360 LPSTR lpGlobalMemory = (LPSTR)::GlobalLock(hGlobalMemory);
361
362 memcpy(s, lpGlobalMemory, hsize);
363
364 ::GlobalUnlock(hGlobalMemory);
365
366 retval = s;
367 break;
368 }
369
370 default:
371 {
372 HANDLE hGlobalMemory = ::GetClipboardData(dataFormat);
373 if ( !hGlobalMemory )
374 break;
375
376 DWORD size = ::GlobalSize(hGlobalMemory);
377 if ( len )
378 *len = size;
379
380 void *buf = malloc(size);
381 if ( !buf )
382 break;
383
384 LPSTR lpGlobalMemory = (LPSTR)::GlobalLock(hGlobalMemory);
385
386 memcpy(buf, lpGlobalMemory, size);
387
388 ::GlobalUnlock(hGlobalMemory);
389
390 retval = buf;
391 break;
392 }
393 }
394
395 if ( !retval )
396 {
397 wxLogSysError(_("Failed to retrieve data from the clipboard."));
398 }
399
400 return retval;
401 */
402 return NULL;
403 }
404
405 wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat)
406 {
407 // TODO: return ::EnumClipboardFormats(dataFormat);
408 return dataFormat;
409 }
410
411 int wxRegisterClipboardFormat(wxChar *WXUNUSED(formatName))
412 {
413 // TODO: return ::RegisterClipboardFormat(formatName);
414 return 0;
415 }
416
417 bool wxGetClipboardFormatName(wxDataFormat WXUNUSED(dataFormat),
418 wxChar *WXUNUSED(formatName),
419 int WXUNUSED(maxCount))
420 {
421 // TODO: return ::GetClipboardFormatName((int)dataFormat, formatName, maxCount) > 0;
422 return 0;
423 }
424
425 // ---------------------------------------------------------------------------
426 // wxClipboard
427 // ---------------------------------------------------------------------------
428
429 IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
430
431 wxClipboard::wxClipboard()
432 {
433 }
434
435 wxClipboard::~wxClipboard()
436 {
437 Clear();
438 }
439
440 void wxClipboard::Clear()
441 {
442 }
443
444 bool wxClipboard::Flush()
445 {
446 // TODO:
447 return false;
448 }
449
450 bool wxClipboard::Open()
451 {
452 return wxOpenClipboard();
453 }
454
455 bool wxClipboard::IsOpened() const
456 {
457 return wxIsClipboardOpened();
458 }
459
460 bool wxClipboard::SetData( wxDataObject *WXUNUSED(data) )
461 {
462 (void)wxEmptyClipboard();
463 // TODO:
464 /*
465 if ( data )
466 return AddData(data);
467 else
468 return true;
469 */
470 return true;
471 }
472
473 bool wxClipboard::AddData( wxDataObject *data )
474 {
475 wxCHECK_MSG( data, false, wxT("data is invalid") );
476
477 #if wxUSE_DRAG_AND_DROP
478 wxCHECK_MSG( wxIsClipboardOpened(), false, wxT("clipboard not open") );
479
480 // wxDataFormat format = data->GetPreferredFormat();
481 // TODO:
482 /*
483 switch ( format )
484 {
485 case wxDF_TEXT:
486 case wxDF_OEMTEXT:
487 {
488 wxTextDataObject* textDataObject = (wxTextDataObject*) data;
489 wxString str(textDataObject->GetText());
490 return wxSetClipboardData(format, str.c_str());
491 }
492
493 case wxDF_BITMAP:
494 case wxDF_DIB:
495 {
496 wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
497 wxBitmap bitmap(bitmapDataObject->GetBitmap());
498 return wxSetClipboardData(data->GetPreferredFormat(), &bitmap);
499 }
500
501 #if wxUSE_METAFILE
502 case wxDF_METAFILE:
503 {
504 wxMetafileDataObject* metaFileDataObject =
505 (wxMetafileDataObject*) data;
506 wxMetafile metaFile = metaFileDataObject->GetMetafile();
507 return wxSetClipboardData(wxDF_METAFILE, &metaFile,
508 metaFileDataObject->GetWidth(),
509 metaFileDataObject->GetHeight());
510 }
511 #endif // wxUSE_METAFILE
512
513 default:
514 return wxSetClipboardData(data);
515 }
516 #else // !wxUSE_DRAG_AND_DROP
517 */
518 return false;
519 #else
520 return false;
521 #endif // wxUSE_DRAG_AND_DROP/!wxUSE_DRAG_AND_DROP
522 }
523
524 void wxClipboard::Close()
525 {
526 wxCloseClipboard();
527 }
528
529 bool wxClipboard::IsSupported( const wxDataFormat& format )
530 {
531 return wxIsClipboardFormatAvailable(format);
532 }
533
534 bool wxClipboard::GetData( wxDataObject& WXUNUSED(data) )
535 {
536 wxCHECK_MSG( wxIsClipboardOpened(), false, wxT("clipboard not open") );
537
538 #if wxUSE_DRAG_AND_DROP
539 // wxDataFormat format = data.GetPreferredFormat();
540 // TODO:
541 /*
542 switch ( format )
543 {
544 case wxDF_TEXT:
545 case wxDF_OEMTEXT:
546 {
547 wxTextDataObject& textDataObject = (wxTextDataObject&) data;
548 char* s = (char*) wxGetClipboardData(format);
549 if ( s )
550 {
551 textDataObject.SetText(s);
552 delete[] s;
553 return true;
554 }
555 else
556 return false;
557 }
558
559 case wxDF_BITMAP:
560 case wxDF_DIB:
561 {
562 wxBitmapDataObject& bitmapDataObject = (wxBitmapDataObject &)data;
563 wxBitmap* bitmap = (wxBitmap *)wxGetClipboardData(data->GetPreferredFormat());
564 if (bitmap)
565 {
566 bitmapDataObject.SetBitmap(* bitmap);
567 delete bitmap;
568 return true;
569 }
570 else
571 return false;
572 }
573 #if wxUSE_METAFILE
574 case wxDF_METAFILE:
575 {
576 wxMetafileDataObject& metaFileDataObject = (wxMetafileDataObject &)data;
577 wxMetafile* metaFile = (wxMetafile *)wxGetClipboardData(wxDF_METAFILE);
578 if (metaFile)
579 {
580 metaFileDataObject.SetMetafile(*metaFile);
581 delete metaFile;
582 return true;
583 }
584 else
585 return false;
586 }
587 #endif
588 default:
589 {
590 long len;
591 void *buf = wxGetClipboardData(format, &len);
592 if ( buf )
593 {
594 // FIXME this is for testing only!
595 ((wxPrivateDataObject &)data).SetData(buf, len);
596 free(buf);
597
598 return true;
599 }
600 }
601
602 return false;
603 }
604 #else
605 */
606 return false;
607 #else
608 return false;
609 #endif
610 }
611
612 #endif // wxUSE_CLIPBOARD