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