]> git.saurik.com Git - wxWidgets.git/blob - src/os2/clipbrd.cpp
Apply minimal DC patch.
[wxWidgets.git] / src / os2 / clipbrd.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: 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 #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"
33 #endif
34
35 #include "wx/log.h"
36 #include "wx/clipbrd.h"
37
38 #include <string.h>
39
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);
48 #endif
49
50 // ===========================================================================
51 // implementation
52 // ===========================================================================
53
54 // ---------------------------------------------------------------------------
55 // old-style clipboard functions using Windows API
56 // ---------------------------------------------------------------------------
57
58 static bool gs_wxClipboardIsOpen = FALSE;
59
60 bool wxOpenClipboard()
61 {
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 */
82 return FALSE;
83 }
84
85 bool wxCloseClipboard()
86 {
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;
100 }
101
102 bool wxEmptyClipboard()
103 {
104 // TODO:
105 /*
106 if ( ::EmptyClipboard() == 0 )
107 {
108 wxLogSysError(_("Failed to empty the clipboard."));
109
110 return FALSE;
111 }
112 */
113 return TRUE;
114 }
115
116 bool wxIsClipboardOpened()
117 {
118 return gs_wxClipboardIsOpen;
119 }
120
121 bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
122 {
123 // TODO: return ::IsClipboardFormatAvailable(dataFormat) != 0;
124 return FALSE;
125 }
126
127 #if 0
128 #if wxUSE_DRAG_AND_DROP
129 static bool wxSetClipboardData(wxDataObject *data)
130 {
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
161 #endif
162
163 bool 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;
282 }
283
284 void *wxGetClipboardData(wxDataFormat dataFormat, long *len)
285 {
286 // void *retval = NULL;
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 */
408 return NULL;
409 }
410
411 wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat)
412 {
413 // TODO: return ::EnumClipboardFormats(dataFormat);
414 return dataFormat;
415 }
416
417 int wxRegisterClipboardFormat(wxChar *formatName)
418 {
419 // TODO: return ::RegisterClipboardFormat(formatName);
420 return 0;
421 }
422
423 bool wxGetClipboardFormatName(wxDataFormat dataFormat,
424 wxChar *formatName,
425 int maxCount)
426 {
427 // TODO: return ::GetClipboardFormatName((int)dataFormat, formatName, maxCount) > 0;
428 return 0;
429 }
430
431 // ---------------------------------------------------------------------------
432 // wxClipboard
433 // ---------------------------------------------------------------------------
434
435 IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
436
437 wxClipboard::wxClipboard()
438 {
439 }
440
441 wxClipboard::~wxClipboard()
442 {
443 Clear();
444 }
445
446 void wxClipboard::Clear()
447 {
448 }
449
450 bool wxClipboard::Flush()
451 {
452 // TODO:
453 return FALSE;
454 }
455
456 bool wxClipboard::Open()
457 {
458 return wxOpenClipboard();
459 }
460
461 bool wxClipboard::IsOpened() const
462 {
463 return wxIsClipboardOpened();
464 }
465
466 bool wxClipboard::SetData( wxDataObject *data )
467 {
468 (void)wxEmptyClipboard();
469 // TODO:
470 /*
471 if ( data )
472 return AddData(data);
473 else
474 return TRUE;
475 */
476 return TRUE;
477 }
478
479 bool wxClipboard::AddData( wxDataObject *data )
480 {
481 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
482
483 #if wxUSE_DRAG_AND_DROP
484 wxCHECK_MSG( wxIsClipboardOpened(), FALSE, wxT("clipboard not open") );
485
486 // wxDataFormat format = data->GetPreferredFormat();
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());
504 return wxSetClipboardData(data->GetPreferredFormat(), &bitmap);
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);
521 }
522 #else // !wxUSE_DRAG_AND_DROP
523 */
524 return FALSE;
525 #else
526 return FALSE;
527 #endif // wxUSE_DRAG_AND_DROP/!wxUSE_DRAG_AND_DROP
528 }
529
530 void wxClipboard::Close()
531 {
532 wxCloseClipboard();
533 }
534
535 bool wxClipboard::IsSupported( const wxDataFormat& format )
536 {
537 return wxIsClipboardFormatAvailable(format);
538 }
539
540 bool wxClipboard::GetData( wxDataObject& data )
541 {
542 wxCHECK_MSG( wxIsClipboardOpened(), FALSE, wxT("clipboard not open") );
543
544 #if wxUSE_DRAG_AND_DROP
545 // wxDataFormat format = data.GetPreferredFormat();
546 // TODO:
547 /*
548 switch ( format )
549 {
550 case wxDF_TEXT:
551 case wxDF_OEMTEXT:
552 {
553 wxTextDataObject& textDataObject = (wxTextDataObject&) data;
554 char* s = (char*) wxGetClipboardData(format);
555 if ( s )
556 {
557 textDataObject.SetText(s);
558 delete[] s;
559 return TRUE;
560 }
561 else
562 return FALSE;
563 }
564
565 case wxDF_BITMAP:
566 case wxDF_DIB:
567 {
568 wxBitmapDataObject& bitmapDataObject = (wxBitmapDataObject &)data;
569 wxBitmap* bitmap = (wxBitmap *)wxGetClipboardData(data->GetPreferredFormat());
570 if (bitmap)
571 {
572 bitmapDataObject.SetBitmap(* bitmap);
573 delete bitmap;
574 return TRUE;
575 }
576 else
577 return FALSE;
578 }
579 #if wxUSE_METAFILE
580 case wxDF_METAFILE:
581 {
582 wxMetafileDataObject& metaFileDataObject = (wxMetafileDataObject &)data;
583 wxMetafile* metaFile = (wxMetafile *)wxGetClipboardData(wxDF_METAFILE);
584 if (metaFile)
585 {
586 metaFileDataObject.SetMetafile(*metaFile);
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!!
601 ((wxPrivateDataObject &)data).SetData(buf, len);
602 free(buf);
603
604 return TRUE;
605 }
606 }
607
608 return FALSE;
609 }
610 #else
611 */
612 return FALSE;
613 #else
614 return FALSE;
615 #endif
616 }
617
618 #else
619 #error "Please turn wxUSE_CLIPBOARD on to compile this file."
620 #endif // wxUSE_CLIPBOARD
621