]> git.saurik.com Git - wxWidgets.git/blame - src/os2/clipbrd.cpp
(Flickery) fix for droppings when there are no notebook pages
[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 8// Copyright: (c) David Webster
65571936 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
9923c37d 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
9923c37d 127#if 0
37f214d5
DW
128#if wxUSE_DRAG_AND_DROP
129static bool wxSetClipboardData(wxDataObject *data)
0e320a79 130{
37f214d5
DW
131 // TODO:
132/*
133 size_t size = data->GetDataSize();
134 HANDLE hGlobal = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size);
135 if ( !hGlobal )
136 {
137 wxLogSysError(_("Failed to allocate %dKb of memory for clipboard "
138 "transfer."), size / 1024);
139
140 return FALSE;
141 }
142
143 LPVOID lpGlobalMemory = ::GlobalLock(hGlobal);
144
145 data->GetDataHere(lpGlobalMemory);
146
147 GlobalUnlock(hGlobal);
148
149 wxDataFormat format = data->GetPreferredFormat();
150 if ( !::SetClipboardData(format, hGlobal) )
151 {
152 wxLogSysError(_("Failed to set clipboard data in format %s"),
153 wxDataObject::GetFormatName(format));
154
155 return FALSE;
156 }
157*/
158 return TRUE;
159}
160#endif // wxUSE_DRAG_AND_DROP
9923c37d 161#endif
37f214d5
DW
162
163bool wxSetClipboardData(wxDataFormat dataFormat,
164 const void *data,
165 int width, int height)
166{
167// TODO:
168/*
169 HANDLE handle = 0; // return value of SetClipboardData
170 switch (dataFormat)
171 {
172 case wxDF_BITMAP:
173 {
174 wxBitmap *bitmap = (wxBitmap *)data;
175
176 HDC hdcMem = CreateCompatibleDC((HDC) NULL);
177 HDC hdcSrc = CreateCompatibleDC((HDC) NULL);
178 HBITMAP old = (HBITMAP)
179 ::SelectObject(hdcSrc, (HBITMAP)bitmap->GetHBITMAP());
180 HBITMAP hBitmap = CreateCompatibleBitmap(hdcSrc,
181 bitmap->GetWidth(),
182 bitmap->GetHeight());
183 if (!hBitmap)
184 {
185 SelectObject(hdcSrc, old);
186 DeleteDC(hdcMem);
187 DeleteDC(hdcSrc);
188 return FALSE;
189 }
190
191 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hBitmap);
192 BitBlt(hdcMem, 0, 0, bitmap->GetWidth(), bitmap->GetHeight(),
193 hdcSrc, 0, 0, SRCCOPY);
194
195 // Select new bitmap out of memory DC
196 SelectObject(hdcMem, old1);
197
198 // Set the data
199 handle = ::SetClipboardData(CF_BITMAP, hBitmap);
200
201 // Clean up
202 SelectObject(hdcSrc, old);
203 DeleteDC(hdcSrc);
204 DeleteDC(hdcMem);
205 break;
206 }
207
208 case wxDF_DIB:
209 {
210#if wxUSE_IMAGE_LOADING_IN_MSW
211 wxBitmap *bitmap = (wxBitmap *)data;
212 HBITMAP hBitmap = (HBITMAP)bitmap->GetHBITMAP();
213 // NULL palette means to use the system one
214 HANDLE hDIB = wxBitmapToDIB(hBitmap, (HPALETTE)NULL);
215 handle = SetClipboardData(CF_DIB, hDIB);
216#endif
217 break;
218 }
219
220#if wxUSE_METAFILE
221 case wxDF_METAFILE:
222 {
223 wxMetafile *wxMF = (wxMetafile *)data;
224 HANDLE data = GlobalAlloc(GHND, sizeof(METAFILEPICT) + 1);
225 METAFILEPICT *mf = (METAFILEPICT *)GlobalLock(data);
226
227 mf->mm = wxMF->GetWindowsMappingMode();
228 mf->xExt = width;
229 mf->yExt = height;
230 mf->hMF = (HMETAFILE) wxMF->GetHMETAFILE();
231 GlobalUnlock(data);
232 wxMF->SetHMETAFILE((WXHANDLE) NULL);
233
234 handle = SetClipboardData(CF_METAFILEPICT, data);
235 break;
236 }
237#endif
238 case CF_SYLK:
239 case CF_DIF:
240 case CF_TIFF:
241 case CF_PALETTE:
242 default:
243 {
244 wxLogError(_("Unsupported clipboard format."));
245 return FALSE;
246 }
247
248 case wxDF_OEMTEXT:
249 dataFormat = wxDF_TEXT;
250 // fall through
251
252 case wxDF_TEXT:
253 {
254 char *s = (char *)data;
255
256 width = strlen(s) + 1;
257 height = 1;
258 DWORD l = (width * height);
259 HANDLE hGlobalMemory = GlobalAlloc(GHND, l);
260 if ( hGlobalMemory )
261 {
262 LPSTR lpGlobalMemory = (LPSTR)GlobalLock(hGlobalMemory);
263
264 memcpy(lpGlobalMemory, s, l);
265
266 GlobalUnlock(hGlobalMemory);
267 }
268
269 handle = SetClipboardData(dataFormat, hGlobalMemory);
270 break;
271 }
272 }
273
274 if ( handle == 0 )
275 {
276 wxLogSysError(_("Failed to set clipboard data."));
277
278 return FALSE;
279 }
280*/
281 return TRUE;
0e320a79
DW
282}
283
37f214d5 284void *wxGetClipboardData(wxDataFormat dataFormat, long *len)
0e320a79 285{
9923c37d 286// void *retval = NULL;
37f214d5
DW
287// TODO:
288/*
289 switch ( dataFormat )
290 {
291 case wxDF_BITMAP:
292 {
293 BITMAP bm;
294 HBITMAP hBitmap = (HBITMAP) GetClipboardData(CF_BITMAP);
295 if (!hBitmap)
296 break;
297
298 HDC hdcMem = CreateCompatibleDC((HDC) NULL);
299 HDC hdcSrc = CreateCompatibleDC((HDC) NULL);
300
301 HBITMAP old = (HBITMAP) ::SelectObject(hdcSrc, hBitmap);
302 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
303
304 HBITMAP hNewBitmap = CreateBitmapIndirect(&bm);
305
306 if (!hNewBitmap)
307 {
308 SelectObject(hdcSrc, old);
309 DeleteDC(hdcMem);
310 DeleteDC(hdcSrc);
311 break;
312 }
313
314 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hNewBitmap);
315 BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight,
316 hdcSrc, 0, 0, SRCCOPY);
317
318 // Select new bitmap out of memory DC
319 SelectObject(hdcMem, old1);
320
321 // Clean up
322 SelectObject(hdcSrc, old);
323 DeleteDC(hdcSrc);
324 DeleteDC(hdcMem);
325
326 // Create and return a new wxBitmap
327 wxBitmap *wxBM = new wxBitmap;
328 wxBM->SetHBITMAP((WXHBITMAP) hNewBitmap);
329 wxBM->SetWidth(bm.bmWidth);
330 wxBM->SetHeight(bm.bmHeight);
331 wxBM->SetDepth(bm.bmPlanes);
332 wxBM->SetOk(TRUE);
333 retval = wxBM;
334 break;
335 }
336
337 case wxDF_METAFILE:
338 case CF_SYLK:
339 case CF_DIF:
340 case CF_TIFF:
341 case CF_PALETTE:
342 case wxDF_DIB:
343 {
344 wxLogError(_("Unsupported clipboard format."));
345 return FALSE;
346 }
347
348 case wxDF_OEMTEXT:
349 dataFormat = wxDF_TEXT;
350 // fall through
351
352 case wxDF_TEXT:
353 {
354 HANDLE hGlobalMemory = ::GetClipboardData(dataFormat);
355 if (!hGlobalMemory)
356 break;
357
358 DWORD hsize = ::GlobalSize(hGlobalMemory);
359 if (len)
360 *len = hsize;
361
362 char *s = new char[hsize];
363 if (!s)
364 break;
365
366 LPSTR lpGlobalMemory = (LPSTR)::GlobalLock(hGlobalMemory);
367
368 memcpy(s, lpGlobalMemory, hsize);
369
370 ::GlobalUnlock(hGlobalMemory);
371
372 retval = s;
373 break;
374 }
375
376 default:
377 {
378 HANDLE hGlobalMemory = ::GetClipboardData(dataFormat);
379 if ( !hGlobalMemory )
380 break;
381
382 DWORD size = ::GlobalSize(hGlobalMemory);
383 if ( len )
384 *len = size;
385
386 void *buf = malloc(size);
387 if ( !buf )
388 break;
389
390 LPSTR lpGlobalMemory = (LPSTR)::GlobalLock(hGlobalMemory);
391
392 memcpy(buf, lpGlobalMemory, size);
393
394 ::GlobalUnlock(hGlobalMemory);
395
396 retval = buf;
397 break;
398 }
399 }
400
401 if ( !retval )
402 {
403 wxLogSysError(_("Failed to retrieve data from the clipboard."));
404 }
405
406 return retval;
407*/
0e320a79
DW
408 return NULL;
409}
410
37f214d5 411wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat)
0e320a79 412{
37f214d5
DW
413 // TODO: return ::EnumClipboardFormats(dataFormat);
414 return dataFormat;
0e320a79
DW
415}
416
37f214d5 417int wxRegisterClipboardFormat(wxChar *formatName)
0e320a79 418{
37f214d5
DW
419 // TODO: return ::RegisterClipboardFormat(formatName);
420 return 0;
0e320a79
DW
421}
422
37f214d5
DW
423bool wxGetClipboardFormatName(wxDataFormat dataFormat,
424 wxChar *formatName,
425 int maxCount)
0e320a79 426{
37f214d5
DW
427 // TODO: return ::GetClipboardFormatName((int)dataFormat, formatName, maxCount) > 0;
428 return 0;
0e320a79
DW
429}
430
37f214d5
DW
431// ---------------------------------------------------------------------------
432// wxClipboard
433// ---------------------------------------------------------------------------
0e320a79 434
37f214d5 435IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
0e320a79 436
0e320a79
DW
437wxClipboard::wxClipboard()
438{
0e320a79
DW
439}
440
441wxClipboard::~wxClipboard()
442{
37f214d5 443 Clear();
0e320a79
DW
444}
445
37f214d5 446void wxClipboard::Clear()
0e320a79 447{
37f214d5 448}
0e320a79 449
6dddc146
DW
450bool wxClipboard::Flush()
451{
452 // TODO:
453 return FALSE;
454}
455
37f214d5
DW
456bool wxClipboard::Open()
457{
458 return wxOpenClipboard();
0e320a79
DW
459}
460
6dddc146
DW
461bool wxClipboard::IsOpened() const
462{
463 return wxIsClipboardOpened();
464}
465
37f214d5 466bool wxClipboard::SetData( wxDataObject *data )
0e320a79 467{
37f214d5
DW
468 (void)wxEmptyClipboard();
469 // TODO:
470 /*
471 if ( data )
472 return AddData(data);
473 else
474 return TRUE;
475 */
476 return TRUE;
477}
0e320a79 478
37f214d5
DW
479bool wxClipboard::AddData( wxDataObject *data )
480{
481 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
0e320a79 482
37f214d5
DW
483#if wxUSE_DRAG_AND_DROP
484 wxCHECK_MSG( wxIsClipboardOpened(), FALSE, wxT("clipboard not open") );
0e320a79 485
2dab12be 486// wxDataFormat format = data->GetPreferredFormat();
37f214d5
DW
487// TODO:
488/*
489 switch ( format )
490 {
491 case wxDF_TEXT:
492 case wxDF_OEMTEXT:
493 {
494 wxTextDataObject* textDataObject = (wxTextDataObject*) data;
495 wxString str(textDataObject->GetText());
496 return wxSetClipboardData(format, str.c_str());
497 }
498
499 case wxDF_BITMAP:
500 case wxDF_DIB:
501 {
502 wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
503 wxBitmap bitmap(bitmapDataObject->GetBitmap());
2dab12be 504 return wxSetClipboardData(data->GetPreferredFormat(), &bitmap);
37f214d5
DW
505 }
506
507#if wxUSE_METAFILE
508 case wxDF_METAFILE:
509 {
510 wxMetafileDataObject* metaFileDataObject =
511 (wxMetafileDataObject*) data;
512 wxMetafile metaFile = metaFileDataObject->GetMetafile();
513 return wxSetClipboardData(wxDF_METAFILE, &metaFile,
514 metaFileDataObject->GetWidth(),
515 metaFileDataObject->GetHeight());
516 }
517#endif // wxUSE_METAFILE
518
519 default:
520 return wxSetClipboardData(data);
0e320a79 521 }
37f214d5
DW
522#else // !wxUSE_DRAG_AND_DROP
523*/
524 return FALSE;
19193a2c
KB
525#else
526 return FALSE;
37f214d5 527#endif // wxUSE_DRAG_AND_DROP/!wxUSE_DRAG_AND_DROP
0e320a79
DW
528}
529
37f214d5 530void wxClipboard::Close()
0e320a79 531{
37f214d5 532 wxCloseClipboard();
0e320a79
DW
533}
534
2af18715 535bool wxClipboard::IsSupported( const wxDataFormat& format )
0e320a79 536{
37f214d5
DW
537 return wxIsClipboardFormatAvailable(format);
538}
0e320a79 539
efe7d6ff 540bool wxClipboard::GetData( wxDataObject& data )
37f214d5
DW
541{
542 wxCHECK_MSG( wxIsClipboardOpened(), FALSE, wxT("clipboard not open") );
0e320a79 543
37f214d5 544#if wxUSE_DRAG_AND_DROP
2dab12be 545// wxDataFormat format = data.GetPreferredFormat();
37f214d5
DW
546 // TODO:
547/*
548 switch ( format )
549 {
550 case wxDF_TEXT:
551 case wxDF_OEMTEXT:
552 {
efe7d6ff 553 wxTextDataObject& textDataObject = (wxTextDataObject&) data;
37f214d5
DW
554 char* s = (char*) wxGetClipboardData(format);
555 if ( s )
556 {
efe7d6ff 557 textDataObject.SetText(s);
37f214d5
DW
558 delete[] s;
559 return TRUE;
560 }
561 else
562 return FALSE;
563 }
564
565 case wxDF_BITMAP:
566 case wxDF_DIB:
567 {
efe7d6ff 568 wxBitmapDataObject& bitmapDataObject = (wxBitmapDataObject &)data;
2dab12be 569 wxBitmap* bitmap = (wxBitmap *)wxGetClipboardData(data->GetPreferredFormat());
37f214d5
DW
570 if (bitmap)
571 {
efe7d6ff 572 bitmapDataObject.SetBitmap(* bitmap);
37f214d5
DW
573 delete bitmap;
574 return TRUE;
575 }
576 else
577 return FALSE;
578 }
579#if wxUSE_METAFILE
580 case wxDF_METAFILE:
581 {
efe7d6ff 582 wxMetafileDataObject& metaFileDataObject = (wxMetafileDataObject &)data;
37f214d5
DW
583 wxMetafile* metaFile = (wxMetafile *)wxGetClipboardData(wxDF_METAFILE);
584 if (metaFile)
585 {
efe7d6ff 586 metaFileDataObject.SetMetafile(*metaFile);
37f214d5
DW
587 delete metaFile;
588 return TRUE;
589 }
590 else
591 return FALSE;
592 }
593#endif
594 default:
595 {
596 long len;
597 void *buf = wxGetClipboardData(format, &len);
598 if ( buf )
599 {
600 // FIXME this is for testing only!!
efe7d6ff 601 ((wxPrivateDataObject &)data).SetData(buf, len);
37f214d5
DW
602 free(buf);
603
604 return TRUE;
605 }
606 }
607
608 return FALSE;
609 }
610#else
611*/
612 return FALSE;
19193a2c
KB
613#else
614 return FALSE;
37f214d5
DW
615#endif
616}
0e320a79 617
37f214d5
DW
618#else
619 #error "Please turn wxUSE_CLIPBOARD on to compile this file."
620#endif // wxUSE_CLIPBOARD
621