1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: UMA support
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: The wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
17 #include <MacTextEditor.h>
20 # include <Navigation.h>
21 # if defined(TARGET_CARBON)
22 # if PM_USE_SESSION_APIS
25 # include <PMApplication.h>
27 # include <Printing.h>
34 #include "wx/mac/uma.h"
37 // since we have decided that we only support 8.6 upwards we are
38 // checking for these minimum requirements in the startup code of
39 // the application so all wxWindows code can safely assume that appearance 1.1
40 // windows manager, control manager, navigation services etc. are
43 static bool sUMAHasAppearance
= false ;
44 static long sUMAAppearanceVersion
= 0 ;
45 static long sUMASystemVersion
= 0 ;
46 static bool sUMAHasAquaLayout
= false ;
48 extern int gAGABackgroundColor
;
49 bool UMAHasAppearance() { return sUMAHasAppearance
; }
50 long UMAGetAppearanceVersion() { return sUMAAppearanceVersion
; }
51 long UMAGetSystemVersion() { return sUMASystemVersion
; }
53 static bool sUMAHasWindowManager
= false ;
54 static long sUMAWindowManagerAttr
= 0 ;
56 bool UMAHasWindowManager() { return sUMAHasWindowManager
; }
57 long UMAGetWindowManagerAttr() { return sUMAWindowManagerAttr
; }
58 bool UMAHasAquaLayout() { return sUMAHasAquaLayout
; }
61 void UMACleanupToolbox()
63 if ( sUMAHasAppearance
)
65 UnregisterAppearanceClient() ;
67 if ( NavServicesAvailable() )
71 if ( TXNTerminateTextension
!= (void*) kUnresolvedCFragSymbolAddress
)
72 TXNTerminateTextension( ) ;
74 void UMAInitToolbox( UInt16 inMoreMastersCalls
)
78 for (long i
= 1; i
<= inMoreMastersCalls
; i
++)
81 ::InitGraf(&qd
.thePort
);
86 ::FlushEvents(everyEvent
, 0);
89 PurgeSpace(&total
, &contig
);
94 if ( Gestalt(gestaltSystemVersion
, &sUMASystemVersion
) != noErr
)
95 sUMASystemVersion
= 0x0000 ;
98 if ( Gestalt( gestaltAppearanceAttr
, &theAppearance
) == noErr
)
100 sUMAHasAppearance
= true ;
101 RegisterAppearanceClient();
102 if ( Gestalt( gestaltAppearanceVersion
, &theAppearance
) == noErr
)
104 sUMAAppearanceVersion
= theAppearance
;
108 sUMAAppearanceVersion
= 0x0100 ;
111 if ( Gestalt( gestaltWindowMgrAttr
, &sUMAWindowManagerAttr
) == noErr
)
113 sUMAHasWindowManager
= sUMAWindowManagerAttr
& gestaltWindowMgrPresent
;
117 // Call currently implicitely done : InitFloatingWindows() ;
119 if ( sUMAHasWindowManager
)
120 InitFloatingWindows() ;
125 if ( NavServicesAvailable() )
131 Gestalt( gestaltMenuMgrAttr
, &menuMgrAttr
) ;
132 if ( menuMgrAttr
& gestaltMenuMgrAquaLayoutMask
)
133 sUMAHasAquaLayout
= true ;
135 if ( TXNInitTextension
!= (void*) kUnresolvedCFragSymbolAddress
)
137 FontFamilyID fontId
;
141 GetThemeFont(kThemeSmallSystemFont
, GetApplicationScript() , fontName
, &fontSize
, &fontStyle
) ;
142 GetFNum( fontName
, &fontId
);
144 TXNMacOSPreferredFontDescription fontDescriptions
[] =
146 { fontId
, (fontSize
<< 16) ,kTXNDefaultFontStyle
, kTXNSystemDefaultEncoding
} ,
148 int noOfFontDescriptions
= sizeof( fontDescriptions
) / sizeof(TXNMacOSPreferredFontDescription
) ;
149 #if 0 // TARGET_CARBON
150 --noOfFontDescriptions
;
152 // kTXNAlwaysUseQuickDrawTextMask might be desirable because of speed increases but it crashes the app under OS X upon key stroke
153 OptionBits options
= kTXNWantMoviesMask
| kTXNWantSoundMask
| kTXNWantGraphicsMask
;
155 if ( !UMAHasAquaLayout() )
158 options
|= kTXNAlwaysUseQuickDrawTextMask
;
160 TXNInitTextension(fontDescriptions
, noOfFontDescriptions
, options
);
164 UMASetSystemIsInitialized(true);
169 Boolean CanUseATSUI()
172 OSErr err = Gestalt(gestaltATSUVersion, &result);
173 return (err == noErr);
177 long UMAGetProcessMode()
180 ProcessInfoRec processinfo
;
181 ProcessSerialNumber procno
;
183 procno
.highLongOfPSN
= NULL
;
184 procno
.lowLongOfPSN
= kCurrentProcess
;
185 processinfo
.processInfoLength
= sizeof(ProcessInfoRec
);
186 processinfo
.processName
= NULL
;
187 processinfo
.processAppSpec
= NULL
;
189 err
= ::GetProcessInformation( &procno
, &processinfo
) ;
190 wxASSERT( err
== noErr
) ;
191 return processinfo
.processMode
;
194 bool UMAGetProcessModeDoesActivateOnFGSwitch()
196 return UMAGetProcessMode() & modeDoesActivateOnFGSwitch
;
201 MenuRef
UMANewMenu( SInt16 id
, const wxString
& title
)
203 wxString str
= wxStripMenuCodes( title
) ;
206 CreateNewMenu( id
, 0 , &menu
) ;
207 SetMenuTitleWithCFString( menu
, wxMacCFStringHolder(str
) ) ;
210 wxMacStringToPascal( str
, ptitle
) ;
211 menu
= ::NewMenu( id
, ptitle
) ;
216 void UMASetMenuTitle( MenuRef menu
, const wxString
& title
)
218 wxString str
= wxStripMenuCodes( title
) ;
220 SetMenuTitleWithCFString( menu
, wxMacCFStringHolder(str
) ) ;
223 wxMacStringToPascal( str
, ptitle
) ;
224 SetMenuTitle( menu
, ptitle
) ;
228 void UMASetMenuItemText( MenuRef menu
, MenuItemIndex item
, const wxString
& title
)
230 wxString str
= wxStripMenuCodes( title
) ;
232 SetMenuItemTextWithCFString( menu
, item
, wxMacCFStringHolder(str
) ) ;
235 wxMacStringToPascal( str
, ptitle
) ;
236 SetMenuItemText( menu
, item
, ptitle
) ;
241 UInt32
UMAMenuEvent( EventRecord
*inEvent
)
243 return MenuEvent( inEvent
) ;
246 void UMAEnableMenuItem( MenuRef inMenu
, MenuItemIndex inItem
, bool enable
)
249 EnableMenuItem( inMenu
, inItem
) ;
251 DisableMenuItem( inMenu
, inItem
) ;
254 void UMAAppendSubMenuItem( MenuRef menu
, const wxString
& title
, SInt16 id
)
256 MacAppendMenu(menu
, "\pA");
257 UMASetMenuItemText(menu
, (SInt16
) ::CountMenuItems(menu
), title
);
258 SetMenuItemHierarchicalID( menu
, CountMenuItems( menu
) , id
) ;
261 void UMAInsertSubMenuItem( MenuRef menu
, const wxString
& title
, MenuItemIndex item
, SInt16 id
)
263 MacInsertMenuItem(menu
, "\pA" , item
);
264 UMASetMenuItemText(menu
, item
, title
);
265 SetMenuItemHierarchicalID( menu
, item
, id
) ;
268 void UMASetMenuItemShortcut( MenuRef menu
, MenuItemIndex item
, wxAcceleratorEntry
*entry
)
273 UInt8 modifiers
= 0 ;
274 SInt16 key
= entry
->GetKeyCode() ;
277 bool explicitCommandKey
= false ;
279 if ( entry
->GetFlags() & wxACCEL_CTRL
)
281 explicitCommandKey
= true ;
284 if (entry
->GetFlags() & wxACCEL_ALT
)
286 modifiers
|= kMenuOptionModifier
;
289 if (entry
->GetFlags() & wxACCEL_SHIFT
)
291 modifiers
|= kMenuShiftModifier
;
295 SInt16 macKey
= key
;
296 if ( key
>= WXK_F1
&& key
<= WXK_F15
)
298 // for some reasons this must be 0 right now
299 // everything else leads to just the first function key item
300 // to be selected. Thanks to Ryan Wilcox for finding out.
302 glyph
= kMenuF1Glyph
+ ( key
- WXK_F1
) ;
303 if ( key
>= WXK_F13
)
305 if ( !explicitCommandKey
)
306 modifiers
|= kMenuNoCommandModifier
;
313 macKey
= kBackspaceCharCode
;
314 glyph
= kMenuDeleteLeftGlyph
;
317 macKey
= kTabCharCode
;
318 glyph
= kMenuTabRightGlyph
;
320 case kEnterCharCode
:
321 macKey
= kEnterCharCode
;
322 glyph
= kMenuEnterGlyph
;
325 macKey
= kReturnCharCode
;
326 glyph
= kMenuReturnGlyph
;
329 macKey
= kEscapeCharCode
;
330 glyph
= kMenuEscapeGlyph
;
334 glyph
= kMenuSpaceGlyph
;
337 macKey
= kDeleteCharCode
;
338 glyph
= kMenuDeleteRightGlyph
;
341 macKey
= kClearCharCode
;
342 glyph
= kMenuClearGlyph
;
344 case WXK_PRIOR
: // PAGE UP
345 macKey
= kPageUpCharCode
;
346 glyph
= kMenuPageUpGlyph
;
349 macKey
= kPageDownCharCode
;
350 glyph
= kMenuPageDownGlyph
;
353 macKey
= kLeftArrowCharCode
;
354 glyph
= kMenuLeftArrowGlyph
;
357 macKey
= kUpArrowCharCode
;
358 glyph
= kMenuUpArrowGlyph
;
361 macKey
= kRightArrowCharCode
;
362 glyph
= kMenuRightArrowGlyph
;
365 macKey
= kDownArrowCharCode
;
366 glyph
= kMenuDownArrowGlyph
;
371 SetItemCmd( menu
, item
, macKey
);
372 SetMenuItemModifiers(menu
, item
, modifiers
) ;
375 SetMenuItemKeyGlyph(menu
, item
, glyph
) ;
379 void UMAAppendMenuItem( MenuRef menu
, const wxString
& title
, wxAcceleratorEntry
*entry
)
381 MacAppendMenu(menu
, "\pA");
382 UMASetMenuItemText(menu
, (SInt16
) ::CountMenuItems(menu
), title
);
383 UMASetMenuItemShortcut( menu
, (SInt16
) ::CountMenuItems(menu
), entry
) ;
386 void UMAInsertMenuItem( MenuRef menu
, const wxString
& title
, MenuItemIndex item
, wxAcceleratorEntry
*entry
)
388 MacInsertMenuItem( menu
, "\pA" , item
) ;
389 UMASetMenuItemText(menu
, item
+1 , title
);
390 UMASetMenuItemShortcut( menu
, item
+1 , entry
) ;
397 int gPrOpenCounter
= 0 ;
403 if ( gPrOpenCounter
== 1 )
407 wxASSERT( err
== noErr
) ;
412 OSStatus
UMAPrClose()
415 wxASSERT( gPrOpenCounter
>= 1 ) ;
416 if ( gPrOpenCounter
== 1 )
420 wxASSERT( err
== noErr
) ;
426 pascal QDGlobalsPtr
GetQDGlobalsPtr (void) ;
427 pascal QDGlobalsPtr
GetQDGlobalsPtr (void)
429 return QDGlobalsPtr (* (Ptr
*) LMGetCurrentA5 ( ) - 0xCA);
434 void UMAShowWatchCursor()
438 CursHandle watchFob
= GetCursor (watchCursor
);
445 // Cursor preservedArrow;
446 // GetQDGlobalsArrow (&preservedArrow);
447 // SetQDGlobalsArrow (*watchFob);
449 // SetQDGlobalsArrow (&preservedArrow);
450 SetCursor (*watchFob
);
452 SetCursor (*watchFob
);
457 void UMAShowArrowCursor()
461 SetCursor (GetQDGlobalsArrow (&arrow
));
463 SetCursor (&(qd
.arrow
));
469 GrafPtr
UMAGetWindowPort( WindowRef inWindowRef
)
471 wxASSERT( inWindowRef
!= NULL
) ;
473 return (GrafPtr
) GetWindowPort( inWindowRef
) ;
475 return (GrafPtr
) inWindowRef
;
479 void UMADisposeWindow( WindowRef inWindowRef
)
481 wxASSERT( inWindowRef
!= NULL
) ;
482 DisposeWindow( inWindowRef
) ;
485 void UMASetWTitle( WindowRef inWindowRef
, const wxString
& title
)
488 SetWindowTitleWithCFString( inWindowRef
, wxMacCFStringHolder(title
) ) ;
491 wxMacStringToPascal( title
, ptitle
) ;
492 SetWTitle( inWindowRef
, ptitle
) ;
496 void UMAGetWTitleC( WindowRef inWindowRef
, char *title
)
498 GetWTitle( inWindowRef
, (unsigned char*)title
) ;
500 p2cstrcpy( title
, (unsigned char *)title
) ;
502 p2cstr( (unsigned char*)title
) ;
506 // appearance additions
508 void UMASetControlTitle( ControlHandle inControl
, const wxString
& title
)
511 SetControlTitleWithCFString( inControl
, wxMacCFStringHolder(title
) ) ;
514 wxMacStringToPascal( title
, ptitle
) ;
515 SetControlTitle( inControl
, ptitle
) ;
519 void UMAActivateControl( ControlHandle inControl
)
521 // we have to add the control after again to the update rgn
522 // otherwise updates get lost
523 if ( !IsControlActive( inControl
) )
525 bool visible
= IsControlVisible( inControl
) ;
527 SetControlVisibility( inControl
, false , false ) ;
528 ::ActivateControl( inControl
) ;
530 SetControlVisibility( inControl
, true , false ) ;
532 InvalWindowRect(GetControlOwner(inControl
),GetControlBounds(inControl
,&ctrlBounds
) ) ;
537 void UMADrawControl( ControlHandle inControl
)
539 WindowRef theWindow
= GetControlOwner(inControl
) ;
540 RgnHandle updateRgn
= NewRgn() ;
541 GetWindowUpdateRgn( theWindow
, updateRgn
) ;
542 Point zero
= { 0 , 0 } ;
543 LocalToGlobal( &zero
) ;
544 OffsetRgn( updateRgn
, -zero
.h
, -zero
.v
) ;
545 ::DrawControlInCurrentPort( inControl
) ;
546 InvalWindowRgn( theWindow
, updateRgn
) ;
547 DisposeRgn( updateRgn
) ;
550 void UMAMoveControl( ControlHandle inControl
, short x
, short y
)
552 bool visible
= IsControlVisible( inControl
) ;
554 SetControlVisibility( inControl
, false , false ) ;
556 InvalWindowRect(GetControlOwner(inControl
),GetControlBounds(inControl
,&ctrlBounds
) ) ;
558 ::MoveControl( inControl
, x
, y
) ;
560 SetControlVisibility( inControl
, true , false ) ;
562 InvalWindowRect(GetControlOwner(inControl
),GetControlBounds(inControl
,&ctrlBounds
) ) ;
566 void UMASizeControl( ControlHandle inControl
, short x
, short y
)
568 bool visible
= IsControlVisible( inControl
) ;
570 SetControlVisibility( inControl
, false , false ) ;
572 InvalWindowRect(GetControlOwner(inControl
),GetControlBounds(inControl
,&ctrlBounds
) ) ;
574 ::SizeControl( inControl
, x
, y
) ;
576 SetControlVisibility( inControl
, true , false ) ;
578 InvalWindowRect(GetControlOwner(inControl
),GetControlBounds(inControl
,&ctrlBounds
) ) ;
582 void UMADeactivateControl( ControlHandle inControl
)
584 // we have to add the control after again to the update rgn
585 // otherwise updates get lost
586 bool visible
= IsControlVisible( inControl
) ;
588 SetControlVisibility( inControl
, false , false ) ;
589 ::DeactivateControl( inControl
) ;
591 SetControlVisibility( inControl
, true , false ) ;
593 InvalWindowRect(GetControlOwner(inControl
),GetControlBounds(inControl
,&ctrlBounds
) ) ;
596 // shows the control and adds the region to the update region
597 void UMAShowControl (ControlHandle inControl
)
599 SetControlVisibility( inControl
, true , false ) ;
601 InvalWindowRect(GetControlOwner(inControl
),GetControlBounds(inControl
,&ctrlBounds
) ) ;
604 // shows the control and adds the region to the update region
605 void UMAHideControl (ControlHandle inControl
)
607 SetControlVisibility( inControl
, false , false ) ;
609 InvalWindowRect(GetControlOwner(inControl
),GetControlBounds(inControl
,&ctrlBounds
) ) ;
612 OSErr
UMASetKeyboardFocus (WindowPtr inWindow
,
613 ControlHandle inControl
,
614 ControlFocusPart inPart
)
620 SetPortWindowPort( inWindow
) ;
622 err
= SetKeyboardFocus( inWindow
, inControl
, inPart
) ;
629 void UMAUpdateControls( WindowPtr inWindow
, RgnHandle inRgn
)
631 RgnHandle updateRgn
= NewRgn() ;
632 GetWindowUpdateRgn( inWindow
, updateRgn
) ;
634 Point zero
= { 0 , 0 } ;
635 LocalToGlobal( &zero
) ;
636 OffsetRgn( updateRgn
, -zero
.h
, -zero
.v
) ;
638 UpdateControls( inWindow
, inRgn
) ;
639 InvalWindowRgn( inWindow
, updateRgn
) ;
640 DisposeRgn( updateRgn
) ;
643 bool UMAIsWindowFloating( WindowRef inWindow
)
647 GetWindowClass( inWindow
, &cl
) ;
648 return cl
== kFloatingWindowClass
;
651 bool UMAIsWindowModal( WindowRef inWindow
)
655 GetWindowClass( inWindow
, &cl
) ;
656 return cl
< kFloatingWindowClass
;
661 void UMAHighlightAndActivateWindow( WindowRef inWindowRef
, bool inActivate
)
665 // bool isHighlighted = IsWindowHighlited( inWindowRef ) ;
666 // if ( inActivate != isHightlited )
669 SetPortWindowPort( inWindowRef
) ;
670 HiliteWindow( inWindowRef
, inActivate
) ;
671 ControlHandle control
= NULL
;
672 ::GetRootControl( inWindowRef
, & control
) ;
676 UMAActivateControl( control
) ;
678 UMADeactivateControl( control
) ;
684 OSStatus
UMADrawThemePlacard( const Rect
*inRect
, ThemeDrawState inState
)
686 return ::DrawThemePlacard( inRect
, inState
) ;
690 static OSStatus helpMenuStatus
= noErr
;
691 static MenuItemIndex firstCustomItemIndex
= 0 ;
694 OSStatus
UMAGetHelpMenu(
695 MenuRef
* outHelpMenu
,
696 MenuItemIndex
* outFirstCustomItemIndex
)
699 return HMGetHelpMenu( outHelpMenu
, outFirstCustomItemIndex
) ;
701 MenuRef helpMenuHandle
;
702 helpMenuStatus
= HMGetHelpMenuHandle( &helpMenuHandle
) ;
703 if ( firstCustomItemIndex
== 0 && helpMenuStatus
== noErr
)
705 firstCustomItemIndex
= CountMenuItems( helpMenuHandle
) + 1 ;
707 if ( outFirstCustomItemIndex
)
709 *outFirstCustomItemIndex
= firstCustomItemIndex
;
711 *outHelpMenu
= helpMenuHandle
;
712 return helpMenuStatus
;
716 wxMacPortStateHelper::wxMacPortStateHelper( GrafPtr newport
)
722 wxMacPortStateHelper::wxMacPortStateHelper()
727 void wxMacPortStateHelper::Setup( GrafPtr newport
)
729 GetPort( &m_oldPort
) ;
731 wxASSERT_MSG( m_clip
== NULL
, wxT("Cannot call setup twice") ) ;
734 m_textFont
= GetPortTextFont( (CGrafPtr
) newport
);
735 m_textSize
= GetPortTextSize( (CGrafPtr
) newport
);
736 m_textStyle
= GetPortTextFace( (CGrafPtr
) newport
);
737 m_textMode
= GetPortTextMode( (CGrafPtr
) newport
);
738 GetThemeDrawingState( &m_drawingState
) ;
739 m_currentPort
= newport
;
741 void wxMacPortStateHelper::Clear()
745 DisposeRgn( m_clip
) ;
746 DisposeThemeDrawingState( m_drawingState
) ;
751 wxMacPortStateHelper::~wxMacPortStateHelper()
755 SetPort( m_currentPort
) ;
757 DisposeRgn( m_clip
) ;
758 TextFont( m_textFont
);
759 TextSize( m_textSize
);
760 TextFace( m_textStyle
);
761 TextMode( m_textMode
);
762 SetThemeDrawingState( m_drawingState
, true ) ;
763 SetPort( m_oldPort
) ;
767 OSStatus
UMAPutScrap( Size size
, OSType type
, void *data
)
769 OSStatus err
= noErr
;
771 err
= PutScrap( size
, type
, data
) ;
774 err
= GetCurrentScrap (&scrap
);
777 err
= PutScrapFlavor (scrap
, type
, 0, size
, data
);
787 static bool sUMASystemInitialized
= false ;
789 bool UMASystemIsInitialized()
791 return sUMASystemInitialized
;
794 void UMASetSystemIsInitialized(bool val
)
796 sUMASystemInitialized
= val
;