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