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