]> git.saurik.com Git - wxWidgets.git/blame - src/osx/carbon/dataobj.cpp
Also accept VT_R4 (float) VARIANTs in wxMSW OLE code.
[wxWidgets.git] / src / osx / carbon / dataobj.cpp
CommitLineData
489468fe 1///////////////////////////////////////////////////////////////////////////////
524c47aa 2// Name: src/osx/carbon/dataobj.cpp
489468fe
SC
3// Purpose: implementation of wxDataObject class
4// Author: Stefan Csomor
5// Modified by:
6// Created: 10/21/99
7// RCS-ID: $Id$
8// Copyright: (c) 1999 Stefan Csomor
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#if wxUSE_DATAOBJ
16
17#include "wx/dataobj.h"
18
19#ifndef WX_PRECOMP
20 #include "wx/intl.h"
21 #include "wx/log.h"
22 #include "wx/dcmemory.h"
23 #include "wx/image.h"
24#endif
25
26#include "wx/mstream.h"
27#include "wx/metafile.h"
28#include "wx/tokenzr.h"
29
524c47aa 30#include "wx/osx/private.h"
489468fe 31
afd5d91c 32#if wxOSX_USE_COCOA_OR_CARBON
489468fe
SC
33 #include <QuickTime/QuickTime.h>
34#endif
35
36
37// ----------------------------------------------------------------------------
38// wxDataFormat
39// ----------------------------------------------------------------------------
40
41wxDataFormat::wxDataFormat()
42{
43 m_type = wxDF_INVALID;
44 m_format = 0;
45}
46
47wxDataFormat::wxDataFormat( wxDataFormatId vType )
48{
49 m_format = 0;
50 m_type = wxDF_INVALID;
51 SetType( vType );
52}
53
54wxDataFormat::wxDataFormat( const wxChar *zId )
55{
56 m_format = 0;
57 m_type = wxDF_INVALID;
58 SetId( zId );
59}
60
61wxDataFormat::wxDataFormat( const wxString& rId )
62{
63 m_format = 0;
64 m_type = wxDF_INVALID;
65 SetId( rId );
66}
67
68wxDataFormat::wxDataFormat(const wxDataFormat& rFormat)
69{
70 if ( rFormat.m_format )
71 m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)rFormat.m_format);
72 else
73 m_format = 0;
74 m_type = rFormat.m_type;
75 m_id = rFormat.m_id;
76}
77
78wxDataFormat::wxDataFormat( NativeFormat vFormat )
79{
80 m_format = 0;
81 m_type = wxDF_INVALID;
82 SetId( vFormat );
83}
84
85wxDataFormat::~wxDataFormat()
86{
87 if ( m_format != 0 )
88 {
89 CFRelease( (CFStringRef) m_format );
90 m_format = 0;
91 }
92}
93
94// in order to be correct for 10.3 we restrict to the available types there
95// http://developer.apple.com/qa/qa2005/qa1406.html
96// TODO : Use UTCoreTypes.h constants once we support 10.4+ only
97
98wxDataFormat& wxDataFormat::operator=(const wxDataFormat& rFormat)
99{
100 if ( m_format != 0 )
101 {
102 CFRelease( (CFStringRef) m_format );
103 m_format = 0;
104 }
105 if ( rFormat.m_format )
106 m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)rFormat.m_format);
107 m_type = rFormat.m_type;
108 m_id = rFormat.m_id;
109 return *this;
110}
111
112void wxDataFormat::SetType( wxDataFormatId dataType )
113{
114 m_type = dataType;
115 if ( m_format != 0 )
116 {
117 CFRelease( (CFStringRef) m_format );
118 m_format = 0;
119 }
120
121 switch (m_type)
122 {
123 case wxDF_TEXT:
124 m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.plain-text") );
125 break;
126
127 case wxDF_UNICODETEXT:
128 m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.utf16-plain-text") );
129 break;
130
131 case wxDF_BITMAP:
132 m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.tiff") );
133 break;
134 case wxDF_METAFILE:
135 m_format = (long) CFStringCreateCopy( NULL, CFSTR("com.adobe.pdf") );
136 break;
137
138 case wxDF_FILENAME:
139 m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.file-url") );
140 break;
141
142 default:
143 wxFAIL_MSG( wxT("invalid data format") );
144 break;
145 }
146}
147
148wxString wxDataFormat::GetId() const
149{
150 return wxCFStringRef(wxCFRetain((CFStringRef)m_format)).AsString();
151}
152
153void wxDataFormat::SetId( NativeFormat format )
154{
155 if ( m_format != 0 )
156 {
157 CFRelease( (CFStringRef) m_format );
158 m_format = 0;
159 }
160 m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)format);
03647350 161 if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.utf16-plain-text") ) )
489468fe
SC
162 {
163 m_type = wxDF_UNICODETEXT;
90dad08e
SC
164 }
165 else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.utf16-external-plain-text") ) )
166 {
167 m_type = wxDF_UNICODETEXT;
03647350 168 }
489468fe
SC
169 else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.plain-text") ) )
170 {
171 m_type = wxDF_TEXT;
172 }
03647350 173 else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.tiff") ) )
489468fe
SC
174 {
175 m_type = wxDF_BITMAP;
176 }
03647350 177 else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("com.adobe.pdf") ) )
489468fe
SC
178 {
179 m_type = wxDF_METAFILE;
180 }
03647350 181 else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.file-url") ) )
489468fe
SC
182 {
183 m_type = wxDF_FILENAME;
184 }
03647350 185 else
489468fe
SC
186 {
187 m_type = wxDF_PRIVATE;
188 m_id = wxCFStringRef( (CFStringRef) CFRetain((CFStringRef) format )).AsString();
189 }
190}
191
192void wxDataFormat::SetId( const wxString& zId )
193{
194 m_type = wxDF_PRIVATE;
195 m_id = zId;
196 if ( m_format != 0 )
197 {
198 CFRelease( (CFStringRef) m_format );
199 m_format = 0;
200 }
201 // since it is private, no need to conform to anything ...
202 m_format = (long) wxCFRetain( (CFStringRef) wxCFStringRef(m_id) );
203}
204
205bool wxDataFormat::operator==(const wxDataFormat& format) const
206{
207 if (IsStandard() || format.IsStandard())
208 return (format.m_type == m_type);
209 else
210 return ( UTTypeConformsTo( (CFStringRef) m_format , (CFStringRef) format.m_format ) );
211}
212
213//-------------------------------------------------------------------------
214// wxDataObject
215//-------------------------------------------------------------------------
216
217wxDataObject::wxDataObject()
218{
219}
220
221bool wxDataObject::IsSupportedFormat( const wxDataFormat& rFormat, Direction vDir ) const
222{
223 size_t nFormatCount = GetFormatCount( vDir );
224 bool found = false;
225
226 if (nFormatCount == 1)
227 {
228 found = (rFormat == GetPreferredFormat());
229 }
230 else
231 {
232 wxDataFormat *pFormats = new wxDataFormat[nFormatCount];
233 GetAllFormats( pFormats, vDir );
234
235 for (size_t n = 0; n < nFormatCount; n++)
236 {
237 if (pFormats[n] == rFormat)
238 {
239 found = true;
240 break;
241 }
242 }
243
244 delete [] pFormats;
245 }
246
247 return found;
248}
249
250void wxDataObject::AddToPasteboard( void * pb, int itemID )
251{
252 PasteboardRef pasteboard = (PasteboardRef) pb;
253 // get formats from wxDataObjects
254 wxDataFormat *array = new wxDataFormat[ GetFormatCount() ];
255 GetAllFormats( array );
256
257 for (size_t i = 0; i < GetFormatCount(); i++)
258 {
259 wxDataFormat thisFormat = array[ i ];
03647350
VZ
260
261 // add four bytes at the end for data objs like text that
489468fe
SC
262 // have a datasize = strlen but still need a buffer for the
263 // string including trailing zero
03647350 264
489468fe
SC
265 size_t datasize = GetDataSize( thisFormat );
266 size_t sz = datasize + 4;
267 void* buf = malloc( sz );
268 if ( buf != NULL )
269 {
270 // empty the buffer because in some case GetDataHere does not fill buf
271 memset( buf, 0, sz );
272 if ( GetDataHere( array[ i ], buf ) )
273 {
274 int counter = 1 ;
275 if ( thisFormat.GetType() == wxDF_FILENAME )
276 {
277 // the data is D-normalized UTF8 strings of filenames delimited with \n
278 char *fname = strtok((char*) buf,"\n");
279 while (fname != NULL)
280 {
281 // translate the filepath into a fileurl and put that into the pasteobard
282 CFStringRef path = CFStringCreateWithBytes(NULL,(UInt8*)fname,strlen(fname),kCFStringEncodingUTF8,false);
283 CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path , kCFURLPOSIXPathStyle, false);
284 CFRelease(path);
285 CFDataRef data = CFURLCreateData(NULL,url,kCFStringEncodingUTF8,true);
286 CFRelease(url);
287 PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) counter,
288 (CFStringRef) thisFormat.GetFormatId() , data, kPasteboardFlavorNoFlags);
289 CFRelease( data );
290 counter++;
291 fname = strtok (NULL,"\n");
292 }
03647350 293
489468fe
SC
294 }
295 else
296 {
297 CFDataRef data = CFDataCreate( kCFAllocatorDefault, (UInt8*)buf, datasize );
298 if ( thisFormat.GetType() == wxDF_TEXT )
299 PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) itemID,
300 CFSTR("com.apple.traditional-mac-plain-text") , data, kPasteboardFlavorNoFlags);
301 else
302 PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) itemID,
303 (CFStringRef) thisFormat.GetFormatId() , data, kPasteboardFlavorNoFlags);
304 CFRelease( data );
305 }
306 }
307 free( buf );
308 }
309 }
310
311 delete [] array;
312}
313
314bool wxDataObject::IsFormatInPasteboard( void * pb, const wxDataFormat &dataFormat )
315{
316 PasteboardRef pasteboard = (PasteboardRef) pb;
317 bool hasData = false;
318 OSStatus err = noErr;
319 ItemCount itemCount;
320
321 // we synchronize here once again, so we don't mind which flags get returned
322 PasteboardSynchronize( pasteboard );
323
324 err = PasteboardGetItemCount( pasteboard, &itemCount );
325 if ( err == noErr )
326 {
327 for( UInt32 itemIndex = 1; itemIndex <= itemCount && hasData == false ; itemIndex++ )
328 {
329 PasteboardItemID itemID;
330 CFArrayRef flavorTypeArray;
331 CFIndex flavorCount;
03647350 332
489468fe
SC
333 err = PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID );
334 if ( err != noErr )
335 continue;
03647350 336
489468fe
SC
337 err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray );
338 if ( err != noErr )
339 continue;
03647350 340
489468fe 341 flavorCount = CFArrayGetCount( flavorTypeArray );
03647350 342
489468fe
SC
343 for( CFIndex flavorIndex = 0; flavorIndex < flavorCount && hasData == false ; flavorIndex++ )
344 {
345 CFStringRef flavorType;
03647350 346
489468fe
SC
347 flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray,
348 flavorIndex );
03647350 349
489468fe
SC
350 wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType );
351 if ( dataFormat == flavorFormat )
352 hasData = true;
353 else if ( dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT )
354 hasData = true;
355 }
356 CFRelease (flavorTypeArray);
357 }
358 }
359
360 return hasData;
361}
362
363bool wxDataObject::GetFromPasteboard( void * pb )
364{
365 PasteboardRef pasteboard = (PasteboardRef) pb;
366 size_t formatcount = GetFormatCount() + 1;
367 wxDataFormat *array = new wxDataFormat[ formatcount ];
368 array[0] = GetPreferredFormat();
369 GetAllFormats( &array[1] );
370 ItemCount itemCount = 0;
371 wxString filenamesPassed;
372 bool transferred = false;
373
374 // we synchronize here once again, so we don't mind which flags get returned
375 PasteboardSynchronize( pasteboard );
376
377 OSStatus err = PasteboardGetItemCount( pasteboard, &itemCount );
378 if ( err == noErr )
379 {
380 for (size_t i = 0; !transferred && i < formatcount; i++)
381 {
382 // go through the data in our order of preference
383 wxDataFormat dataFormat = array[ i ];
384
385 for( UInt32 itemIndex = 1; itemIndex <= itemCount && transferred == false ; itemIndex++ )
386 {
387 PasteboardItemID itemID = 0;
388 CFArrayRef flavorTypeArray = NULL;
389 CFIndex flavorCount = 0;
390
391 err = PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID );
392 if ( err != noErr )
393 continue;
394
395 err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray );
396 if ( err != noErr )
397 continue;
03647350 398
489468fe
SC
399 flavorCount = CFArrayGetCount( flavorTypeArray );
400
401 for( CFIndex flavorIndex = 0; !transferred && flavorIndex < flavorCount ; flavorIndex++ )
402 {
403 CFStringRef flavorType;
404 CFDataRef flavorData;
405 CFIndex flavorDataSize;
03647350 406
489468fe
SC
407 flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray,
408 flavorIndex );
409
d89af57a
SC
410 // avoid utf8 being treated closer to plain-text than unicode by forcing a conversion
411 if ( UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text") ) )
412 {
413 flavorType = CFSTR("public.utf16-plain-text");
414 }
489468fe 415 wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType );
03647350 416
489468fe
SC
417 if ( dataFormat == flavorFormat )
418 {
419 err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType , &flavorData );
420 if ( err == noErr )
421 {
422 flavorDataSize = CFDataGetLength( flavorData );
423 if (dataFormat.GetType() == wxDF_FILENAME )
424 {
425 // revert the translation and decomposition to arrive at a proper utf8 string again
426 CFURLRef url = CFURLCreateWithBytes( kCFAllocatorDefault, CFDataGetBytePtr( flavorData ), flavorDataSize, kCFStringEncodingUTF8, NULL );
427 CFStringRef cfString = CFURLCopyFileSystemPath( url, kCFURLPOSIXPathStyle );
428 CFRelease( url );
429 CFMutableStringRef cfMutableString = CFStringCreateMutableCopy(NULL, 0, cfString);
430 CFRelease( cfString );
431 CFStringNormalize(cfMutableString,kCFStringNormalizationFormC);
432 wxString path = wxCFStringRef(cfMutableString).AsString();
433 if (!path.empty())
434 filenamesPassed += path + wxT("\n");
435 }
436 else
437 {
438 // because some data implementation expect trailing a trailing NUL, we add some headroom
439 void *buf = malloc( flavorDataSize + 4 );
440 if ( buf )
441 {
442 memset( buf, 0, flavorDataSize + 4 );
443 memcpy( buf, CFDataGetBytePtr( flavorData ), flavorDataSize );
03647350 444
489468fe
SC
445 if (dataFormat.GetType() == wxDF_TEXT)
446 wxMacConvertNewlines10To13( (char*) buf );
447 SetData( flavorFormat, flavorDataSize, buf );
448 transferred = true;
449 free( buf );
450 }
451 }
452 CFRelease (flavorData);
453 }
454 }
455 else if ( dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT )
456 {
457 err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType, &flavorData );
458 if ( err == noErr )
459 {
460 flavorDataSize = CFDataGetLength( flavorData );
461 void *asciibuf = malloc( flavorDataSize + 1 );
462 if ( asciibuf )
463 {
464 memset( asciibuf, 0, flavorDataSize + 1 );
465 memcpy( asciibuf, CFDataGetBytePtr( flavorData ), flavorDataSize );
466 CFRelease (flavorData);
467
468 SetData( wxDF_TEXT, flavorDataSize, asciibuf );
469 transferred = true;
470 free( asciibuf );
471 }
472 else
473 CFRelease (flavorData);
474 }
475 }
476 }
477 CFRelease( flavorTypeArray );
478 }
6636ef8d 479 if ( !filenamesPassed.empty() )
489468fe
SC
480 {
481 wxCharBuffer buf = filenamesPassed.fn_str();
482 SetData( wxDF_FILENAME, strlen( buf ), (const char*)buf );
483 transferred = true;
484 }
485 }
486 }
487 return transferred;
488}
489
490bool wxDataObject::HasDataInPasteboard( void * pb )
491{
492 PasteboardRef pasteboard = (PasteboardRef) pb;
493 size_t formatcount = GetFormatCount() + 1;
494 wxDataFormat *array = new wxDataFormat[ formatcount ];
495 array[0] = GetPreferredFormat();
496 GetAllFormats( &array[1] );
497 ItemCount itemCount = 0;
498 bool hasData = false;
499
500 // we synchronize here once again, so we don't mind which flags get returned
501 PasteboardSynchronize( pasteboard );
502
503 OSStatus err = PasteboardGetItemCount( pasteboard, &itemCount );
504 if ( err == noErr )
505 {
506 for (size_t i = 0; !hasData && i < formatcount; i++)
507 {
508 // go through the data in our order of preference
509 wxDataFormat dataFormat = array[ i ];
510
511 for( UInt32 itemIndex = 1; itemIndex <= itemCount && hasData == false ; itemIndex++ )
512 {
513 PasteboardItemID itemID = 0;
514 CFArrayRef flavorTypeArray = NULL;
515 CFIndex flavorCount = 0;
516
517 err = PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID );
518 if ( err != noErr )
519 continue;
520
521 err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray );
522 if ( err != noErr )
523 continue;
03647350 524
489468fe
SC
525 flavorCount = CFArrayGetCount( flavorTypeArray );
526
527 for( CFIndex flavorIndex = 0; !hasData && flavorIndex < flavorCount ; flavorIndex++ )
528 {
529 CFStringRef flavorType;
03647350 530
489468fe
SC
531 flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray,
532 flavorIndex );
533
534 wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType );
03647350
VZ
535
536 if ( dataFormat == flavorFormat ||
c9e98a88 537 (dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT) )
489468fe
SC
538 {
539 hasData = true;
540 }
541 }
542 CFRelease( flavorTypeArray );
543 }
544 }
545 }
546 return hasData;
547}
548
549// ----------------------------------------------------------------------------
550// wxTextDataObject
551// ----------------------------------------------------------------------------
552
553#if wxUSE_UNICODE
554void wxTextDataObject::GetAllFormats(wxDataFormat *formats,
555 wxDataObjectBase::Direction WXUNUSED(dir)) const
556{
557 *formats++ = wxDataFormat( wxDF_TEXT );
558 *formats = wxDataFormat( wxDF_UNICODETEXT );
559}
560#endif
561
562// ----------------------------------------------------------------------------
563// wxFileDataObject
564// ----------------------------------------------------------------------------
565
566void wxFileDataObject::GetFileNames( wxCharBuffer &buf ) const
567{
568 wxString filenames;
569
570 for (size_t i = 0; i < m_filenames.GetCount(); i++)
571 {
572 filenames += m_filenames[i];
573 filenames += wxT('\n');
574 }
575
576 buf = filenames.fn_str();
577}
578
579bool wxFileDataObject::GetDataHere( void *pBuf ) const
580{
581 if (pBuf == NULL)
582 return false;
583
584 wxCharBuffer buf;
585 size_t buffLength;
586
587 GetFileNames( buf );
588 buffLength = strlen( buf );
589 memcpy( pBuf, (const char*)buf, buffLength + 1 );
590
591 return true;
592}
593
594size_t wxFileDataObject::GetDataSize() const
595{
596 wxCharBuffer buf;
597 size_t buffLength;
598
599 GetFileNames( buf );
600 buffLength = strlen( buf );
601 // terminating 0
602 return buffLength + 1;
603}
604
605bool wxFileDataObject::SetData( size_t WXUNUSED(nSize), const void *pBuf )
606{
607 wxString filenames;
608
609#if wxUSE_UNICODE
610 filenames = wxString( (const char*)pBuf, *wxConvFileName );
611#else
612 filenames = wxString (wxConvLocal.cWC2WX(wxConvFileName->cMB2WC( (const char*)pBuf)));
613#endif
614
615 m_filenames = wxStringTokenize( filenames, wxT("\n"), wxTOKEN_STRTOK );
616
617 return true;
618}
619
620void wxFileDataObject::AddFile( const wxString& rFilename )
621{
622 m_filenames.Add( rFilename );
623}
624
625// ----------------------------------------------------------------------------
626// wxBitmapDataObject
627// ----------------------------------------------------------------------------
628
629wxBitmapDataObject::wxBitmapDataObject()
630{
631 Init();
632}
633
634wxBitmapDataObject::wxBitmapDataObject( const wxBitmap& rBitmap )
635: wxBitmapDataObjectBase( rBitmap )
636{
637 Init();
638
a1b806b9 639 if (m_bitmap.IsOk())
489468fe 640 {
03647350 641 SetBitmap( rBitmap );
489468fe
SC
642 }
643}
644
645wxBitmapDataObject::~wxBitmapDataObject()
646{
647 Clear();
648}
649
650void wxBitmapDataObject::SetBitmap( const wxBitmap& rBitmap )
651{
652 Clear();
653 wxBitmapDataObjectBase::SetBitmap( rBitmap );
a1b806b9 654 if (m_bitmap.IsOk())
489468fe
SC
655 {
656 CGImageRef cgImageRef = (CGImageRef) m_bitmap.CreateCGImage();
657
658 CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0);
659 CGImageDestinationRef destination = CGImageDestinationCreateWithData( data , kUTTypeTIFF , 1 , NULL );
660 if ( destination )
661 {
662 CGImageDestinationAddImage( destination, cgImageRef, NULL );
663 CGImageDestinationFinalize( destination );
664 CFRelease( destination );
665 }
666 m_pictHandle = NewHandle(CFDataGetLength(data));
667 if ( m_pictHandle )
668 {
669 memcpy( *(Handle)m_pictHandle, (const char *)CFDataGetBytePtr(data), CFDataGetLength(data) );
670 }
671 CFRelease( data );
672
673 CGImageRelease(cgImageRef);
674 }
675}
676
677void wxBitmapDataObject::Init()
678{
679 m_pictHandle = NULL;
680 m_pictCreated = false;
681}
682
683void wxBitmapDataObject::Clear()
684{
685 if (m_pictHandle != NULL)
686 {
687 DisposeHandle( (Handle) m_pictHandle );
688 m_pictHandle = NULL;
689 }
690 m_pictCreated = false;
691}
692
693bool wxBitmapDataObject::GetDataHere( void *pBuf ) const
694{
695 if (m_pictHandle == NULL)
696 {
697 wxFAIL_MSG( wxT("attempt to copy empty bitmap failed") );
698 return false;
699 }
700
701 if (pBuf == NULL)
702 return false;
703
704 memcpy( pBuf, *(Handle)m_pictHandle, GetHandleSize( (Handle)m_pictHandle ) );
705
706 return true;
707}
708
709size_t wxBitmapDataObject::GetDataSize() const
710{
711 if (m_pictHandle != NULL)
712 return GetHandleSize( (Handle)m_pictHandle );
713 else
714 return 0;
715}
716
717Handle MacCreateDataReferenceHandle(Handle theDataHandle)
718{
719 Handle dataRef = NULL;
720 OSErr err = noErr;
721
722 // Create a data reference handle for our data.
723 err = PtrToHand( &theDataHandle, &dataRef, sizeof(Handle));
724
725 return dataRef;
726}
727
728bool wxBitmapDataObject::SetData( size_t nSize, const void *pBuf )
729{
730 Clear();
731
732 if ((pBuf == NULL) || (nSize == 0))
733 return false;
734
735 Handle picHandle = NewHandle( nSize );
736 memcpy( *picHandle, pBuf, nSize );
737 m_pictHandle = picHandle;
738 CGImageRef cgImageRef = 0;
739
740 CFDataRef data = CFDataCreateWithBytesNoCopy( kCFAllocatorDefault, (const UInt8*) pBuf, nSize, kCFAllocatorNull);
741 CGImageSourceRef source = CGImageSourceCreateWithData( data, NULL );
742 if ( source )
743 {
744 cgImageRef = CGImageSourceCreateImageAtIndex(source, 0, NULL);
c9e98a88 745 CFRelease( source );
489468fe 746 }
489468fe
SC
747 CFRelease( data );
748
749 if ( cgImageRef )
750 {
751 m_bitmap.Create( CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
752 CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
753 // since our context is upside down we dont use CGContextDrawImage
754 wxMacDrawCGImage( (CGContextRef) m_bitmap.GetHBITMAP() , &r, cgImageRef ) ;
755 CGImageRelease(cgImageRef);
756 cgImageRef = NULL;
757 }
758
a1b806b9 759 return m_bitmap.IsOk();
489468fe
SC
760}
761
762#endif