1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/uma.cpp
3 // Purpose: UMA support
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: The wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
14 #include "wx/mac/uma.h"
18 #include "wx/toplevel.h"
21 #include "wx/mac/uma.h"
23 // since we have decided that we only support 8.6 upwards we are
24 // checking for these minimum requirements in the startup code of
25 // the application so all wxWidgets code can safely assume that appearance 1.1
26 // windows manager, control manager, navigation services etc. are
29 static SInt32 sUMASystemVersion
= 0 ;
31 long UMAGetSystemVersion() { return sUMASystemVersion
; }
33 void UMACleanupToolbox()
37 void UMAInitToolbox( UInt16
WXUNUSED(inMoreMastersCalls
),
38 bool WXUNUSED(isEmbedded
) )
42 if ( Gestalt(gestaltSystemVersion
, &sUMASystemVersion
) != noErr
)
43 sUMASystemVersion
= 0x0000 ;
52 GetThemeFont(kThemeSmallSystemFont
, GetApplicationScript() , fontName
, &fontSize
, &fontStyle
) ;
53 GetFNum( fontName
, &fontId
);
55 TXNMacOSPreferredFontDescription fontDescriptions
[] =
57 { fontId
, (fontSize
<< 16) , kTXNDefaultFontStyle
, kTXNSystemDefaultEncoding
}
59 int noOfFontDescriptions
= sizeof( fontDescriptions
) / sizeof(TXNMacOSPreferredFontDescription
) ;
61 OptionBits options
= 0 ;
63 if ( UMAGetSystemVersion() < 0x1000 )
64 options
|= kTXNAlwaysUseQuickDrawTextMask
;
66 TXNInitTextension( fontDescriptions
, noOfFontDescriptions
, options
);
70 UMASetSystemIsInitialized( true );
74 long UMAGetProcessMode()
77 ProcessInfoRec processinfo
;
78 ProcessSerialNumber procno
;
80 procno
.highLongOfPSN
= 0 ;
81 procno
.lowLongOfPSN
= kCurrentProcess
;
82 processinfo
.processInfoLength
= sizeof(ProcessInfoRec
);
83 processinfo
.processName
= NULL
;
85 processinfo
.processAppSpec
= NULL
;
88 err
= ::GetProcessInformation( &procno
, &processinfo
) ;
89 wxASSERT( err
== noErr
) ;
91 return processinfo
.processMode
;
94 bool UMAGetProcessModeDoesActivateOnFGSwitch()
96 return UMAGetProcessMode() & modeDoesActivateOnFGSwitch
;
101 MenuRef
UMANewMenu( SInt16 id
, const wxString
& title
, wxFontEncoding encoding
)
103 wxString str
= wxStripMenuCodes( title
) ;
106 CreateNewMenu( id
, 0 , &menu
) ;
107 SetMenuTitleWithCFString( menu
, wxMacCFStringHolder(str
, encoding
) ) ;
112 void UMASetMenuTitle( MenuRef menu
, const wxString
& title
, wxFontEncoding encoding
)
114 wxString str
= wxStripMenuCodes( title
) ;
116 SetMenuTitleWithCFString( menu
, wxMacCFStringHolder(str
, encoding
) ) ;
119 void UMASetMenuItemText( MenuRef menu
, MenuItemIndex item
, const wxString
& title
, wxFontEncoding encoding
)
121 // we don't strip the accels here anymore, must be done before
122 wxString str
= title
;
124 SetMenuItemTextWithCFString( menu
, item
, wxMacCFStringHolder(str
, encoding
) ) ;
127 UInt32
UMAMenuEvent( EventRecord
*inEvent
)
129 return MenuEvent( inEvent
) ;
132 void UMAEnableMenuItem( MenuRef inMenu
, MenuItemIndex inItem
, bool enable
)
135 EnableMenuItem( inMenu
, inItem
) ;
137 DisableMenuItem( inMenu
, inItem
) ;
140 void UMAAppendSubMenuItem( MenuRef menu
, const wxString
& title
, wxFontEncoding encoding
, SInt16 id
)
142 AppendMenuItemTextWithCFString( menu
,
143 CFSTR("A"), 0, 0,NULL
);
144 UMASetMenuItemText( menu
, (SInt16
) ::CountMenuItems(menu
), title
, encoding
);
145 SetMenuItemHierarchicalID( menu
, CountMenuItems( menu
) , id
) ;
148 void UMAInsertSubMenuItem( MenuRef menu
, const wxString
& title
, wxFontEncoding encoding
, MenuItemIndex item
, SInt16 id
)
150 InsertMenuItemTextWithCFString( menu
,
151 CFSTR("A"), item
, 0, 0);
153 UMASetMenuItemText( menu
, item
+1, title
, encoding
);
154 SetMenuItemHierarchicalID( menu
, item
+1 , id
) ;
157 void UMASetMenuItemShortcut( MenuRef menu
, MenuItemIndex item
, wxAcceleratorEntry
*entry
)
162 UInt8 modifiers
= 0 ;
163 SInt16 key
= entry
->GetKeyCode() ;
166 bool explicitCommandKey
= (entry
->GetFlags() & wxACCEL_CTRL
);
168 if (entry
->GetFlags() & wxACCEL_ALT
)
169 modifiers
|= kMenuOptionModifier
;
171 if (entry
->GetFlags() & wxACCEL_SHIFT
)
172 modifiers
|= kMenuShiftModifier
;
175 SInt16 macKey
= key
;
176 if ( key
>= WXK_F1
&& key
<= WXK_F15
)
178 if ( !explicitCommandKey
)
179 modifiers
|= kMenuNoCommandModifier
;
181 // for some reasons this must be 0 right now
182 // everything else leads to just the first function key item
183 // to be selected. Thanks to Ryan Wilcox for finding out.
185 glyph
= kMenuF1Glyph
+ ( key
- WXK_F1
) ;
186 if ( key
>= WXK_F13
)
194 macKey
= kBackspaceCharCode
;
195 glyph
= kMenuDeleteLeftGlyph
;
199 macKey
= kTabCharCode
;
200 glyph
= kMenuTabRightGlyph
;
203 case kEnterCharCode
:
204 macKey
= kEnterCharCode
;
205 glyph
= kMenuEnterGlyph
;
209 macKey
= kReturnCharCode
;
210 glyph
= kMenuReturnGlyph
;
214 macKey
= kEscapeCharCode
;
215 glyph
= kMenuEscapeGlyph
;
220 glyph
= kMenuSpaceGlyph
;
224 macKey
= kDeleteCharCode
;
225 glyph
= kMenuDeleteRightGlyph
;
229 macKey
= kClearCharCode
;
230 glyph
= kMenuClearGlyph
;
234 macKey
= kPageUpCharCode
;
235 glyph
= kMenuPageUpGlyph
;
239 macKey
= kPageDownCharCode
;
240 glyph
= kMenuPageDownGlyph
;
244 macKey
= kLeftArrowCharCode
;
245 glyph
= kMenuLeftArrowGlyph
;
249 macKey
= kUpArrowCharCode
;
250 glyph
= kMenuUpArrowGlyph
;
254 macKey
= kRightArrowCharCode
;
255 glyph
= kMenuRightArrowGlyph
;
259 macKey
= kDownArrowCharCode
;
260 glyph
= kMenuDownArrowGlyph
;
264 macKey
= kHomeCharCode
;
265 glyph
= kMenuNorthwestArrowGlyph
;
269 macKey
= kEndCharCode
;
270 glyph
= kMenuSoutheastArrowGlyph
;
273 macKey
= toupper( key
) ;
277 // we now allow non command key shortcuts
278 // remove in case this gives problems
279 if ( !explicitCommandKey
)
280 modifiers
|= kMenuNoCommandModifier
;
283 // 1d and 1e have special meaning to SetItemCmd, so
284 // do not use for these character codes.
285 if (key
!= WXK_UP
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_LEFT
)
286 SetItemCmd( menu
, item
, macKey
);
288 SetMenuItemModifiers( menu
, item
, modifiers
) ;
291 SetMenuItemKeyGlyph( menu
, item
, glyph
) ;
295 void UMAAppendMenuItem( MenuRef menu
, const wxString
& title
, wxFontEncoding encoding
, wxAcceleratorEntry
*entry
)
297 AppendMenuItemTextWithCFString( menu
,
298 CFSTR("A"), 0, 0,NULL
);
299 // don't attempt to interpret metacharacters like a '-' at the beginning (would become a separator otherwise)
300 ChangeMenuItemAttributes( menu
, ::CountMenuItems(menu
), kMenuItemAttrIgnoreMeta
, 0 ) ;
301 UMASetMenuItemText(menu
, (SInt16
) ::CountMenuItems(menu
), title
, encoding
);
302 UMASetMenuItemShortcut( menu
, (SInt16
) ::CountMenuItems(menu
), entry
) ;
305 void UMAInsertMenuItem( MenuRef menu
, const wxString
& title
, wxFontEncoding encoding
, MenuItemIndex item
, wxAcceleratorEntry
*entry
)
307 InsertMenuItemTextWithCFString( menu
,
308 CFSTR("A"), item
, 0, 0);
310 // don't attempt to interpret metacharacters like a '-' at the beginning (would become a separator otherwise)
311 ChangeMenuItemAttributes( menu
, item
+1, kMenuItemAttrIgnoreMeta
, 0 ) ;
312 UMASetMenuItemText(menu
, item
+1 , title
, encoding
);
313 UMASetMenuItemShortcut( menu
, item
+1 , entry
) ;
316 void UMAShowWatchCursor()
318 SetThemeCursor(kThemeWatchCursor
);
321 void UMAShowArrowCursor()
323 SetThemeCursor(kThemeArrowCursor
);
328 GrafPtr
UMAGetWindowPort( WindowRef inWindowRef
)
330 wxASSERT( inWindowRef
!= NULL
) ;
332 return (GrafPtr
) GetWindowPort( inWindowRef
) ;
335 void UMADisposeWindow( WindowRef inWindowRef
)
337 wxASSERT( inWindowRef
!= NULL
) ;
339 DisposeWindow( inWindowRef
) ;
342 void UMASetWTitle( WindowRef inWindowRef
, const wxString
& title
, wxFontEncoding encoding
)
344 SetWindowTitleWithCFString( inWindowRef
, wxMacCFStringHolder(title
, encoding
) ) ;
347 // appearance additions
349 void UMASetControlTitle( ControlRef inControl
, const wxString
& title
, wxFontEncoding encoding
)
351 SetControlTitleWithCFString( inControl
, wxMacCFStringHolder(title
, encoding
) ) ;
354 void UMAActivateControl( ControlRef inControl
)
356 ::ActivateControl( inControl
) ;
359 void UMAMoveControl( ControlRef inControl
, short x
, short y
)
361 ::MoveControl( inControl
, x
, y
) ;
364 void UMASizeControl( ControlRef inControl
, short x
, short y
)
366 ::SizeControl( inControl
, x
, y
) ;
369 void UMADeactivateControl( ControlRef inControl
)
371 ::DeactivateControl( inControl
) ;
374 // shows the control and adds the region to the update region
375 void UMAShowControl( ControlRef inControl
)
377 SetControlVisibility( inControl
, true , false ) ;
378 HIViewSetNeedsDisplay( inControl
, true );
381 // hides the control and adds the region to the update region
382 void UMAHideControl( ControlRef inControl
)
384 SetControlVisibility( inControl
, false , false ) ;
385 HIViewSetNeedsDisplay( inControl
, true );
389 OSErr
UMASetKeyboardFocus( WindowPtr inWindow
,
390 ControlRef inControl
,
391 ControlFocusPart inPart
)
398 SetPortWindowPort( inWindow
) ;
401 err
= SetKeyboardFocus( inWindow
, inControl
, inPart
) ;
409 bool UMAIsWindowFloating( WindowRef inWindow
)
413 GetWindowClass( inWindow
, &cl
) ;
414 return cl
== kFloatingWindowClass
;
417 bool UMAIsWindowModal( WindowRef inWindow
)
421 GetWindowClass( inWindow
, &cl
) ;
422 return cl
< kFloatingWindowClass
;
427 void UMAHighlightAndActivateWindow( WindowRef inWindowRef
, bool inActivate
)
431 // bool isHighlighted = IsWindowHighlited( inWindowRef ) ;
432 // if ( inActivate != isHighlighted )
436 SetPortWindowPort( inWindowRef
) ;
438 HiliteWindow( inWindowRef
, inActivate
) ;
439 ControlRef control
= NULL
;
440 ::GetRootControl( inWindowRef
, &control
) ;
444 UMAActivateControl( control
) ;
446 UMADeactivateControl( control
) ;
454 OSStatus
UMADrawThemePlacard( const Rect
*inRect
, ThemeDrawState inState
)
457 return ::DrawThemePlacard( inRect
, inState
) ;
463 static OSStatus
UMAGetHelpMenu(
464 MenuRef
* outHelpMenu
,
465 MenuItemIndex
* outFirstCustomItemIndex
,
466 bool allowHelpMenuCreation
);
468 static OSStatus
UMAGetHelpMenu(
469 MenuRef
* outHelpMenu
,
470 MenuItemIndex
* outFirstCustomItemIndex
,
471 bool allowHelpMenuCreation
)
473 static bool s_createdHelpMenu
= false ;
475 if ( !s_createdHelpMenu
&& !allowHelpMenuCreation
)
480 OSStatus status
= HMGetHelpMenu( outHelpMenu
, outFirstCustomItemIndex
) ;
481 s_createdHelpMenu
= ( status
== noErr
) ;
485 OSStatus
UMAGetHelpMenu(
486 MenuRef
* outHelpMenu
,
487 MenuItemIndex
* outFirstCustomItemIndex
)
489 return UMAGetHelpMenu( outHelpMenu
, outFirstCustomItemIndex
, true );
492 OSStatus
UMAGetHelpMenuDontCreate(
493 MenuRef
* outHelpMenu
,
494 MenuItemIndex
* outFirstCustomItemIndex
)
496 return UMAGetHelpMenu( outHelpMenu
, outFirstCustomItemIndex
, false );
501 wxMacPortStateHelper::wxMacPortStateHelper( GrafPtr newport
)
507 wxMacPortStateHelper::wxMacPortStateHelper()
512 void wxMacPortStateHelper::Setup( GrafPtr newport
)
514 GetPort( &m_oldPort
) ;
518 wxASSERT_MSG( m_clip
== NULL
, wxT("Cannot call setup twice") ) ;
521 m_textFont
= GetPortTextFont( (CGrafPtr
) newport
);
522 m_textSize
= GetPortTextSize( (CGrafPtr
) newport
);
523 m_textStyle
= GetPortTextFace( (CGrafPtr
) newport
);
524 m_textMode
= GetPortTextMode( (CGrafPtr
) newport
);
525 GetThemeDrawingState( &m_drawingState
) ;
526 m_currentPort
= newport
;
529 void wxMacPortStateHelper::Clear()
533 DisposeRgn( m_clip
) ;
534 DisposeThemeDrawingState( m_drawingState
) ;
539 wxMacPortStateHelper::~wxMacPortStateHelper()
543 SetPort( m_currentPort
) ;
545 DisposeRgn( m_clip
) ;
546 TextFont( m_textFont
);
547 TextSize( m_textSize
);
548 TextFace( m_textStyle
);
549 TextMode( m_textMode
);
550 SetThemeDrawingState( m_drawingState
, true ) ;
551 SetPort( m_oldPort
) ;
557 Rect
* UMAGetControlBoundsInWindowCoords( ControlRef theControl
, Rect
*bounds
)
559 GetControlBounds( theControl
, bounds
) ;
561 #if TARGET_API_MAC_OSX
562 WindowRef tlwref
= GetControlOwner( theControl
) ;
564 wxTopLevelWindowMac
* tlwwx
= wxFindWinFromMacWindow( tlwref
) ;
567 ControlRef rootControl
= tlwwx
->GetPeer()->GetControlRef() ;
568 HIPoint hiPoint
= CGPointMake( 0 , 0 ) ;
569 HIViewConvertPoint( &hiPoint
, HIViewGetSuperview(theControl
) , rootControl
) ;
570 OffsetRect( bounds
, (short) hiPoint
.x
, (short) hiPoint
.y
) ;
577 size_t UMAPutBytesCFRefCallback( void *info
, const void *bytes
, size_t count
)
579 CFMutableDataRef data
= (CFMutableDataRef
) info
;
582 CFDataAppendBytes( data
, (const UInt8
*) bytes
, count
);
587 void UMAReleaseCFDataProviderCallback( void *info
, const void *data
, size_t count
)
590 CFRelease( (CFDataRef
) info
);
593 void UMAReleaseCFDataConsumerCallback( void *info
)
596 CFRelease( (CFDataRef
) info
);
599 CGDataProviderRef
UMACGDataProviderCreateWithCFData( CFDataRef data
)
604 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
605 if( &CGDataProviderCreateWithCFData
!= NULL
)
607 return CGDataProviderCreateWithCFData( data
);
611 // make sure we keep it until done
613 CGDataProviderRef provider
= CGDataProviderCreateWithData( (void*) data
, CFDataGetBytePtr( data
) ,
614 CFDataGetLength( data
), UMAReleaseCFDataProviderCallback
);
615 // if provider couldn't be created, release the data again
616 if ( provider
== NULL
)
621 CGDataConsumerRef
UMACGDataConsumerCreateWithCFData( CFMutableDataRef data
)
626 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
627 if( &CGDataConsumerCreateWithCFData
!= NULL
)
629 return CGDataConsumerCreateWithCFData( data
);
632 // make sure we keep it until done
634 CGDataConsumerCallbacks callbacks
;
635 callbacks
.putBytes
= UMAPutBytesCFRefCallback
;
636 callbacks
.releaseConsumer
= UMAReleaseCFDataConsumerCallback
;
637 CGDataConsumerRef consumer
= CGDataConsumerCreate( data
, &callbacks
);
638 // if consumer couldn't be created, release the data again
639 if ( consumer
== NULL
)
647 static bool sUMASystemInitialized
= false ;
649 bool UMASystemIsInitialized()
651 return sUMASystemInitialized
;
654 void UMASetSystemIsInitialized(bool val
)
656 sUMASystemInitialized
= val
;