1/////////////////////////////////////////////////////////////////////////////
2// Name:        src/mac/carbon/uma.cpp
3// Purpose:     UMA support
4// Author:      Stefan Csomor
5// Modified by:
6// Created:     04/01/98
7// RCS-ID:      $Id: uma.cpp 57897 2009-01-07 20:07:09Z SC $
8// Copyright:   (c) Stefan Csomor
9// Licence:     The wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
14#if wxUSE_GUI
15
16#include "wx/toplevel.h"
17#include "wx/dc.h"
18
19#ifndef __DARWIN__
20#  include <MacTextEditor.h>
21#  include <Navigation.h>
22#  if defined(TARGET_CARBON)
23#    if PM_USE_SESSION_APIS
24#      include <PMCore.h>
25#    endif
26#    include <PMApplication.h>
27#  else
28#    include <Printing.h>
29#  endif
30#endif
31
32#include "wx/mac/uma.h"
33
34// since we have decided that we only support 8.6 upwards we are
35// checking for these minimum requirements in the startup code of
36// the application so all wxWidgets code can safely assume that appearance 1.1
37// windows manager, control manager, navigation services etc. are
38// present
39
40static SInt32 sUMASystemVersion = 0 ;
41
42long UMAGetSystemVersion() { return sUMASystemVersion ; }
43
44void UMACleanupToolbox()
45{
46}
47
48void UMAInitToolbox( UInt16 inMoreMastersCalls, bool isEmbedded )
49{
50    ::InitCursor();
51
52    if ( Gestalt(gestaltSystemVersion, &sUMASystemVersion) != noErr)
53        sUMASystemVersion = 0x0000 ;
54
55#ifndef __LP64__
56    {
57        FontFamilyID fontId ;
58        Str255 fontName ;
59        SInt16 fontSize ;
60        Style fontStyle ;
61
62        GetThemeFont(kThemeSmallSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;
63        GetFNum( fontName, &fontId );
64
65        TXNMacOSPreferredFontDescription fontDescriptions[] =
66        {
67            { fontId , (fontSize << 16) , kTXNDefaultFontStyle, kTXNSystemDefaultEncoding }
68        } ;
69        int noOfFontDescriptions = sizeof( fontDescriptions ) / sizeof(TXNMacOSPreferredFontDescription) ;
70
71        OptionBits options = 0 ;
72
73        if ( UMAGetSystemVersion() < 0x1000 )
74            options |= kTXNAlwaysUseQuickDrawTextMask ;
75
76        TXNInitTextension( fontDescriptions,  noOfFontDescriptions, options );
77    }
78#endif
79
80    UMASetSystemIsInitialized( true );
81}
82
83// process manager
84long UMAGetProcessMode()
85{
86    OSErr err ;
87    ProcessInfoRec processinfo;
88    ProcessSerialNumber procno ;
89
90    procno.highLongOfPSN = 0 ;
91    procno.lowLongOfPSN = kCurrentProcess ;
92    processinfo.processInfoLength = sizeof(ProcessInfoRec);
93    processinfo.processName = NULL;
94#ifndef __LP64__
95    processinfo.processAppSpec = NULL;
96#endif
97
98    err = ::GetProcessInformation( &procno , &processinfo ) ;
99    wxASSERT( err == noErr ) ;
100
101    return processinfo.processMode ;
102}
103
104bool UMAGetProcessModeDoesActivateOnFGSwitch()
105{
106    return UMAGetProcessMode() & modeDoesActivateOnFGSwitch ;
107}
108
109// menu manager
110
111MenuRef UMANewMenu( SInt16 id , const wxString& title , wxFontEncoding encoding )
112{
113    wxString str = wxStripMenuCodes( title ) ;
114    MenuRef menu ;
115
116#if TARGET_CARBON
117    CreateNewMenu( id , 0 , &menu ) ;
118    SetMenuTitleWithCFString( menu , wxMacCFStringHolder(str , encoding ) ) ;
119#else
120    Str255 ptitle ;
121    wxMacStringToPascal( str , ptitle ) ;
122    menu = ::NewMenu( id , ptitle ) ;
123#endif
124
125    return menu ;
126}
127
128void UMASetMenuTitle( MenuRef menu , const wxString& title , wxFontEncoding encoding )
129{
130    wxString str = wxStripMenuCodes( title ) ;
131
132#if TARGET_CARBON
133    SetMenuTitleWithCFString( menu , wxMacCFStringHolder(str , encoding) ) ;
134
135#else
136    Str255 ptitle ;
137    wxMacStringToPascal( str , ptitle ) ;
138    SetMenuTitle( menu , ptitle ) ;
139#endif
140}
141
142void UMASetMenuItemText( MenuRef menu,  MenuItemIndex item, const wxString& title, wxFontEncoding encoding )
143{
144    // we don't strip the accels here anymore, must be done before
145    wxString str = title ;
146
147#if TARGET_CARBON
148    SetMenuItemTextWithCFString( menu , item , wxMacCFStringHolder(str , encoding) ) ;
149
150#else
151    Str255 ptitle ;
152    wxMacStringToPascal( str , ptitle ) ;
153    SetMenuItemText( menu , item , ptitle ) ;
154#endif
155}
156
157UInt32 UMAMenuEvent( EventRecord *inEvent )
158{
159    return MenuEvent( inEvent ) ;
160}
161
162void UMAEnableMenuItem( MenuRef inMenu , MenuItemIndex inItem , bool enable)
163{
164    if ( enable )
165        EnableMenuItem( inMenu , inItem ) ;
166    else
167        DisableMenuItem( inMenu , inItem ) ;
168}
169
170void UMAAppendSubMenuItem( MenuRef menu , const wxString& title, wxFontEncoding encoding , SInt16 id )
171{
172    AppendMenuItemTextWithCFString( menu,
173                                CFSTR("A"), 0, 0,NULL);
174    UMASetMenuItemText( menu, (SInt16) ::CountMenuItems(menu), title , encoding );
175    SetMenuItemHierarchicalID( menu , CountMenuItems( menu ) , id ) ;
176}
177
178void UMAInsertSubMenuItem( MenuRef menu , const wxString& title, wxFontEncoding encoding , MenuItemIndex item , SInt16 id  )
179{
180    InsertMenuItemTextWithCFString( menu,
181                CFSTR("A"), item, 0, 0);
182
183    UMASetMenuItemText( menu, item+1, title , encoding );
184    SetMenuItemHierarchicalID( menu , item+1 , id ) ;
185}
186
187void UMASetMenuItemShortcut( MenuRef menu , MenuItemIndex item , wxAcceleratorEntry *entry )
188{
189    if ( !entry )
190    {
191        SetMenuItemModifiers( menu, item , kMenuNoModifiers );
192        SetMenuItemKeyGlyph( menu, item , kMenuNullGlyph );
193        SetItemCmd( menu, item , 0 );
194        return ;
195    }
196
197    UInt8 modifiers = 0 ;
198    SInt16 key = entry->GetKeyCode() ;
199    if ( key )
200    {
201        bool explicitCommandKey = (entry->GetFlags() & wxACCEL_CMD);
202        if ( !explicitCommandKey )
203            modifiers |= kMenuNoCommandModifier ;
204
205        if (entry->GetFlags() & wxACCEL_ALT)
206            modifiers |= kMenuOptionModifier ;
207
208        if (entry->GetFlags() & wxACCEL_SHIFT)
209            modifiers |= kMenuShiftModifier ;
210
211        if (entry->GetFlags() & wxACCEL_CTRL)
212            modifiers |= kMenuControlModifier ;
213
214
215        SInt16 glyph = 0 ;
216        SInt16 macKey = key ;
217        if ( key >= WXK_F1 && key <= WXK_F15 )
218        {
219
220            // for some reasons this must be 0 right now
221            // everything else leads to just the first function key item
222            // to be selected. Thanks to Ryan Wilcox for finding out.
223            macKey = 0 ;
224            glyph = kMenuF1Glyph + ( key - WXK_F1 ) ;
225            if ( key >= WXK_F13 )
226                glyph += 12 ;
227        }
228        else
229        {
230            switch ( key )
231            {
232                case WXK_BACK :
233                    macKey = kBackspaceCharCode ;
234                    glyph = kMenuDeleteLeftGlyph ;
235                    break ;
236
237                case WXK_TAB :
238                    macKey = kTabCharCode ;
239                    glyph = kMenuTabRightGlyph ;
240                    break ;
241
242                case kEnterCharCode :
243                    macKey = kEnterCharCode ;
244                    glyph = kMenuEnterGlyph ;
245                    break ;
246
247                case WXK_RETURN :
248                    macKey = kReturnCharCode ;
249                    glyph = kMenuReturnGlyph ;
250                    break ;
251
252                case WXK_ESCAPE :
253                    macKey = kEscapeCharCode ;
254                    glyph = kMenuEscapeGlyph ;
255                    break ;
256
257                case WXK_SPACE :
258                    macKey = ' ' ;
259                    glyph = kMenuSpaceGlyph ;
260                    break ;
261
262                case WXK_DELETE :
263                    macKey = kDeleteCharCode ;
264                    glyph = kMenuDeleteRightGlyph ;
265                    break ;
266
267                case WXK_CLEAR :
268                    macKey = kClearCharCode ;
269                    glyph = kMenuClearGlyph ;
270                    break ;
271
272                case WXK_PAGEUP :
273                    macKey = kPageUpCharCode ;
274                    glyph = kMenuPageUpGlyph ;
275                    break ;
276
277                case WXK_PAGEDOWN :
278                    macKey = kPageDownCharCode ;
279                    glyph = kMenuPageDownGlyph ;
280                    break ;
281
282                case WXK_LEFT :
283                    macKey = kLeftArrowCharCode ;
284                    glyph = kMenuLeftArrowGlyph ;
285                    break ;
286
287                case WXK_UP :
288                    macKey = kUpArrowCharCode ;
289                    glyph = kMenuUpArrowGlyph ;
290                    break ;
291
292                case WXK_RIGHT :
293                    macKey = kRightArrowCharCode ;
294                    glyph = kMenuRightArrowGlyph ;
295                    break ;
296
297                case WXK_DOWN :
298                    macKey = kDownArrowCharCode ;
299                    glyph = kMenuDownArrowGlyph ;
300                    break ;
301
302                case WXK_HOME :
303                    macKey = kHomeCharCode ;
304                    glyph = kMenuNorthwestArrowGlyph ;
305                    break ;
306
307                case WXK_END :
308                    macKey = kEndCharCode ;
309                    glyph = kMenuSoutheastArrowGlyph ;
310                    break ;
311                default :
312                    macKey = toupper( key ) ;
313                    break ;
314            }
315        }
316
317        // 1d and 1e have special meaning to SetItemCmd, so
318        // do not use for these character codes.
319        if (key != WXK_UP && key != WXK_RIGHT && key != WXK_DOWN && key != WXK_LEFT)
320            SetItemCmd( menu, item , macKey );
321
322        SetMenuItemModifiers( menu, item , modifiers ) ;
323
324        if ( glyph )
325            SetMenuItemKeyGlyph( menu, item , glyph ) ;
326    }
327}
328
329void UMAAppendMenuItem( MenuRef menu , const wxString& title, wxFontEncoding encoding , wxAcceleratorEntry *entry )
330{
331    AppendMenuItemTextWithCFString( menu,
332                                CFSTR("A"), 0, 0,NULL);
333    // don't attempt to interpret metacharacters like a '-' at the beginning (would become a separator otherwise)
334    ChangeMenuItemAttributes( menu , ::CountMenuItems(menu), kMenuItemAttrIgnoreMeta , 0 ) ;
335    UMASetMenuItemText(menu, (SInt16) ::CountMenuItems(menu), title , encoding );
336    UMASetMenuItemShortcut( menu , (SInt16) ::CountMenuItems(menu), entry ) ;
337}
338
339void UMAInsertMenuItem( MenuRef menu , const wxString& title, wxFontEncoding encoding , MenuItemIndex item , wxAcceleratorEntry *entry )
340{
341    InsertMenuItemTextWithCFString( menu,
342                CFSTR("A"), item, 0, 0);
343
344    // don't attempt to interpret metacharacters like a '-' at the beginning (would become a separator otherwise)
345    ChangeMenuItemAttributes( menu , item+1, kMenuItemAttrIgnoreMeta , 0 ) ;
346    UMASetMenuItemText(menu, item+1 , title , encoding );
347    UMASetMenuItemShortcut( menu , item+1 , entry ) ;
348}
349
350// quickdraw
351
352#if !TARGET_CARBON
353
354int gPrOpenCounter = 0 ;
355
356OSStatus UMAPrOpen()
357{
358    OSErr err = noErr ;
359
360    ++gPrOpenCounter ;
361
362    if ( gPrOpenCounter == 1 )
363    {
364        PrOpen() ;
365        err = PrError() ;
366        wxASSERT( err == noErr ) ;
367    }
368
369    return err ;
370}
371
372OSStatus UMAPrClose()
373{
374    OSErr err = noErr ;
375
376    wxASSERT( gPrOpenCounter >= 1 ) ;
377
378    if ( gPrOpenCounter == 1 )
379    {
380        PrClose() ;
381        err = PrError() ;
382        wxASSERT( err == noErr ) ;
383    }
384
385    --gPrOpenCounter ;
386
387    return err ;
388}
389
390pascal QDGlobalsPtr GetQDGlobalsPtr() ;
391pascal QDGlobalsPtr GetQDGlobalsPtr()
392{
393    return QDGlobalsPtr (* (Ptr*) LMGetCurrentA5 ( ) - 0xCA);
394}
395
396#endif
397
398void UMAShowWatchCursor()
399{
400    SetThemeCursor(kThemeWatchCursor);
401}
402
403void UMAShowArrowCursor()
404{
405    SetThemeCursor(kThemeArrowCursor);
406}
407
408// window manager
409
410GrafPtr UMAGetWindowPort( WindowRef inWindowRef )
411{
412    wxASSERT( inWindowRef != NULL ) ;
413
414#if TARGET_CARBON
415    return (GrafPtr) GetWindowPort( inWindowRef ) ;
416#else
417    return (GrafPtr) inWindowRef ;
418#endif
419}
420
421void UMADisposeWindow( WindowRef inWindowRef )
422{
423    wxASSERT( inWindowRef != NULL ) ;
424
425    DisposeWindow( inWindowRef ) ;
426}
427
428void UMASetWTitle( WindowRef inWindowRef , const wxString& title , wxFontEncoding encoding )
429{
430#if TARGET_CARBON
431    SetWindowTitleWithCFString( inWindowRef , wxMacCFStringHolder(title , encoding) ) ;
432
433#else
434    Str255 ptitle ;
435    wxMacStringToPascal( title , ptitle ) ;
436    SetWTitle( inWindowRef , ptitle ) ;
437#endif
438}
439
440// appearance additions
441
442void UMASetControlTitle( ControlRef inControl , const wxString& title , wxFontEncoding encoding )
443{
444#if TARGET_CARBON
445    SetControlTitleWithCFString( inControl , wxMacCFStringHolder(title , encoding) ) ;
446
447#else
448    Str255 ptitle ;
449    wxMacStringToPascal( title , ptitle ) ;
450    SetControlTitle( inControl , ptitle ) ;
451#endif
452}
453
454void UMAActivateControl( ControlRef inControl )
455{
456#if TARGET_API_MAC_OSX
457    ::ActivateControl( inControl ) ;
458
459#else
460    // we have to add the control after again to the update rgn
461    // otherwise updates get lost
462    if ( !IsControlActive( inControl ) )
463    {
464        bool visible = IsControlVisible( inControl ) ;
465        if ( visible )
466            SetControlVisibility( inControl , false , false ) ;
467
468        ::ActivateControl( inControl ) ;
469
470        if ( visible )
471        {
472            SetControlVisibility( inControl , true , false ) ;
473
474            Rect ctrlBounds ;
475            InvalWindowRect( GetControlOwner(inControl), UMAGetControlBoundsInWindowCoords(inControl, &ctrlBounds) ) ;
476        }
477    }
478#endif
479}
480
481void UMAMoveControl( ControlRef inControl , short x , short y )
482{
483#if TARGET_API_MAC_OSX
484    ::MoveControl( inControl , x , y ) ;
485
486#else
487    bool visible = IsControlVisible( inControl ) ;
488    if ( visible )
489    {
490        SetControlVisibility( inControl , false , false ) ;
491        Rect ctrlBounds ;
492        InvalWindowRect( GetControlOwner(inControl), GetControlBounds(inControl, &ctrlBounds) ) ;
493    }
494
495    ::MoveControl( inControl , x , y ) ;
496
497    if ( visible )
498    {
499        SetControlVisibility( inControl , true , false ) ;
500        Rect ctrlBounds ;
501        InvalWindowRect( GetControlOwner(inControl), GetControlBounds(inControl, &ctrlBounds) ) ;
502    }
503#endif
504}
505
506void UMASizeControl( ControlRef inControl , short x , short y )
507{
508#if TARGET_API_MAC_OSX
509    ::SizeControl( inControl , x , y ) ;
510
511#else
512    bool visible = IsControlVisible( inControl ) ;
513    if ( visible )
514    {
515        SetControlVisibility( inControl , false , false ) ;
516        Rect ctrlBounds ;
517        InvalWindowRect( GetControlOwner(inControl), GetControlBounds(inControl, &ctrlBounds) ) ;
518    }
519
520    ::SizeControl( inControl , x , y ) ;
521
522    if ( visible )
523    {
524        SetControlVisibility( inControl , true , false ) ;
525        Rect ctrlBounds ;
526        InvalWindowRect( GetControlOwner(inControl), GetControlBounds(inControl, &ctrlBounds) ) ;
527    }
528#endif
529}
530
531void UMADeactivateControl( ControlRef inControl )
532{
533#if TARGET_API_MAC_OSX
534    ::DeactivateControl( inControl ) ;
535
536#else
537    // we have to add the control after again to the update rgn
538    // otherwise updates get lost
539    bool visible = IsControlVisible( inControl ) ;
540    if ( visible )
541        SetControlVisibility( inControl , false , false ) ;
542
543    ::DeactivateControl( inControl ) ;
544
545    if ( visible )
546    {
547        SetControlVisibility( inControl , true , false ) ;
548        Rect ctrlBounds ;
549        InvalWindowRect( GetControlOwner(inControl), UMAGetControlBoundsInWindowCoords(inControl, &ctrlBounds) ) ;
550    }
551#endif
552}
553
554// shows the control and adds the region to the update region
555void UMAShowControl( ControlRef inControl )
556{
557    SetControlVisibility( inControl , true , false ) ;
558    HIViewSetNeedsDisplay( inControl, true );
559}
560
561// hides the control and adds the region to the update region
562void UMAHideControl( ControlRef inControl )
563{
564    SetControlVisibility( inControl , false , false ) ;
565    HIViewSetNeedsDisplay( inControl, true );
566}
567
568// keyboard focus
569OSErr UMASetKeyboardFocus( WindowPtr inWindow,
570                                 ControlRef inControl,
571                                 ControlFocusPart inPart )
572{
573    OSErr err = noErr;
574#ifndef __LP64__
575    GrafPtr port ;
576
577    GetPort( &port ) ;
578    SetPortWindowPort( inWindow ) ;
579#endif
580
581    err = SetKeyboardFocus( inWindow , inControl , inPart ) ;
582#ifndef __LP64__
583    SetPort( port ) ;
584#endif
585
586    return err ;
587}
588
589bool UMAIsWindowFloating( WindowRef inWindow )
590{
591    WindowClass cl ;
592
593    GetWindowClass( inWindow , &cl ) ;
594    return cl == kFloatingWindowClass ;
595}
596
597bool UMAIsWindowModal( WindowRef inWindow )
598{
599    WindowClass cl ;
600
601    GetWindowClass( inWindow , &cl ) ;
602    return cl < kFloatingWindowClass ;
603}
604
605// others
606
607void UMAHighlightAndActivateWindow( WindowRef inWindowRef , bool inActivate )
608{
609    if ( inWindowRef )
610    {
611//        bool isHighlighted = IsWindowHighlited( inWindowRef ) ;
612//        if ( inActivate != isHighlighted )
613#ifndef __LP64__
614        GrafPtr port ;
615        GetPort( &port ) ;
616        SetPortWindowPort( inWindowRef ) ;
617#endif
618        HiliteWindow( inWindowRef , inActivate ) ;
619        ControlRef control = NULL ;
620        ::GetRootControl( inWindowRef , &control ) ;
621        if ( control )
622        {
623            if ( inActivate )
624                UMAActivateControl( control ) ;
625            else
626                UMADeactivateControl( control ) ;
627        }
628#ifndef __LP64__
629        SetPort( port ) ;
630#endif
631    }
632}
633
634OSStatus UMADrawThemePlacard( const Rect *inRect , ThemeDrawState inState )
635{
636#ifndef __LP64__
637    return ::DrawThemePlacard( inRect , inState ) ;
638#else
639    return noErr;
640#endif
641}
642
643#if !TARGET_CARBON
644static OSStatus helpMenuStatus = noErr ;
645static MenuItemIndex firstCustomItemIndex = 0 ;
646#endif
647
648OSStatus UMAGetHelpMenu(
649    MenuRef *        outHelpMenu,
650    MenuItemIndex *  outFirstCustomItemIndex)
651{
652#if TARGET_CARBON
653    return HMGetHelpMenu( outHelpMenu , outFirstCustomItemIndex ) ;
654
655#else
656    MenuRef helpMenuHandle ;
657
658    helpMenuStatus = HMGetHelpMenuHandle( &helpMenuHandle ) ;
659    if ( firstCustomItemIndex == 0 && helpMenuStatus == noErr )
660        firstCustomItemIndex = CountMenuItems( helpMenuHandle ) + 1 ;
661
662    if ( outFirstCustomItemIndex )
663        *outFirstCustomItemIndex = firstCustomItemIndex ;
664
665    *outHelpMenu = helpMenuHandle ;
666
667    return helpMenuStatus ;
668#endif
669}
670
671#ifndef __LP64__
672
673wxMacPortStateHelper::wxMacPortStateHelper( GrafPtr newport )
674{
675    m_clip = NULL ;
676    Setup( newport ) ;
677}
678
679wxMacPortStateHelper::wxMacPortStateHelper()
680{
681    m_clip = NULL ;
682}
683
684void wxMacPortStateHelper::Setup( GrafPtr newport )
685{
686    GetPort( &m_oldPort ) ;
687    SetPort( newport ) ;
688    SetOrigin(0, 0);
689
690    wxASSERT_MSG( m_clip == NULL , wxT("Cannot call setup twice") ) ;
691    m_clip = NewRgn() ;
692    GetClip( m_clip );
693    m_textFont = GetPortTextFont( (CGrafPtr) newport );
694    m_textSize = GetPortTextSize( (CGrafPtr) newport );
695    m_textStyle = GetPortTextFace( (CGrafPtr) newport );
696    m_textMode = GetPortTextMode( (CGrafPtr) newport );
697    GetThemeDrawingState( &m_drawingState ) ;
698    m_currentPort = newport ;
699}
700
701void wxMacPortStateHelper::Clear()
702{
703    if ( m_clip )
704    {
705        DisposeRgn( m_clip ) ;
706        DisposeThemeDrawingState( m_drawingState ) ;
707        m_clip = NULL ;
708    }
709}
710
711wxMacPortStateHelper::~wxMacPortStateHelper()
712{
713    if ( m_clip )
714    {
715        SetPort( m_currentPort ) ;
716        SetClip( m_clip ) ;
717        DisposeRgn( m_clip ) ;
718        TextFont( m_textFont );
719        TextSize( m_textSize );
720        TextFace( m_textStyle );
721        TextMode( m_textMode );
722        SetThemeDrawingState( m_drawingState , true ) ;
723        SetPort( m_oldPort ) ;
724    }
725}
726
727#endif
728
729Rect * UMAGetControlBoundsInWindowCoords( ControlRef theControl, Rect *bounds )
730{
731    GetControlBounds( theControl , bounds ) ;
732
733#if TARGET_API_MAC_OSX
734    WindowRef tlwref = GetControlOwner( theControl ) ;
735
736    wxTopLevelWindowMac* tlwwx = wxFindWinFromMacWindow( tlwref ) ;
737    if ( tlwwx != NULL )
738    {
739        ControlRef rootControl = tlwwx->GetPeer()->GetControlRef() ;
740        HIPoint hiPoint = CGPointMake( 0 , 0 ) ;
741        HIViewConvertPoint( &hiPoint , HIViewGetSuperview(theControl) , rootControl ) ;
742        OffsetRect( bounds , (short) hiPoint.x , (short) hiPoint.y ) ;
743    }
744#endif
745
746    return bounds ;
747}
748
749size_t UMAPutBytesCFRefCallback( void *info, const void *bytes, size_t count )
750{
751    CFMutableDataRef data = (CFMutableDataRef) info;
752    if ( data )
753    {
754        CFDataAppendBytes( data, (const UInt8*) bytes, count );
755    }
756    return count;
757}
758
759void UMAReleaseCFDataProviderCallback( void *info, const void *data, size_t count )
760{
761    if ( info )
762        CFRelease( (CFDataRef) info );
763}
764
765void UMAReleaseCFDataConsumerCallback( void *info )
766{
767    if ( info )
768        CFRelease( (CFDataRef) info );
769}
770
771CGDataProviderRef UMACGDataProviderCreateWithCFData( CFDataRef data )
772{
773    if ( data == NULL )
774        return NULL;
775
776#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
777    if( &CGDataProviderCreateWithCFData != NULL )
778    {
779        return CGDataProviderCreateWithCFData( data );
780    }
781#endif
782
783    // make sure we keep it until done
784    CFRetain( data );
785    CGDataProviderRef provider = CGDataProviderCreateWithData( (void*) data , CFDataGetBytePtr( data ) ,
786        CFDataGetLength( data ), UMAReleaseCFDataProviderCallback );
787    // if provider couldn't be created, release the data again
788    if ( provider == NULL )
789        CFRelease( data );
790    return provider;
791}
792
793CGDataConsumerRef UMACGDataConsumerCreateWithCFData( CFMutableDataRef data )
794{
795    if ( data == NULL )
796        return NULL;
797
798#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
799    if( &CGDataConsumerCreateWithCFData != NULL )
800    {
801        return CGDataConsumerCreateWithCFData( data );
802    }
803#endif
804    // make sure we keep it until done
805    CFRetain( data );
806    CGDataConsumerCallbacks callbacks;
807    callbacks.putBytes = UMAPutBytesCFRefCallback;
808    callbacks.releaseConsumer = UMAReleaseCFDataConsumerCallback;
809    CGDataConsumerRef consumer = CGDataConsumerCreate( data , &callbacks );
810    // if consumer couldn't be created, release the data again
811    if ( consumer == NULL )
812        CFRelease( data );
813    return consumer;
814}
815#endif  // wxUSE_GUI
816
817#if wxUSE_BASE
818
819static bool sUMASystemInitialized = false ;
820
821bool UMASystemIsInitialized()
822{
823    return sUMASystemInitialized ;
824}
825
826void UMASetSystemIsInitialized(bool val)
827{
828    sUMASystemInitialized = val;
829}
830
831#endif // wxUSE_BASE
832