1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: UMA support
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: The wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
14 #include <MacTextEditor.h>
17 # include <Navigation.h>
18 # if defined(TARGET_CARBON)
19 # if PM_USE_SESSION_APIS
22 # include <PMApplication.h>
24 # include <Printing.h>
31 #include "wx/mac/uma.h"
33 // since we have decided that we only support 8.6 upwards we are
34 // checking for these minimum requirements in the startup code of
35 // the application so all wxWindows code can safely assume that appearance 1.1
36 // windows manager, control manager, navigation services etc. are
39 static bool sUMAHasAppearance
= false ;
40 static long sUMAAppearanceVersion
= 0 ;
41 static long sUMASystemVersion
= 0 ;
42 static bool sUMAHasAquaLayout
= false ;
43 static bool sUMASystemInitialized
= false ;
45 extern int gAGABackgroundColor
;
46 bool UMAHasAppearance() { return sUMAHasAppearance
; }
47 long UMAGetAppearanceVersion() { return sUMAAppearanceVersion
; }
48 long UMAGetSystemVersion() { return sUMASystemVersion
; }
50 static bool sUMAHasWindowManager
= false ;
51 static long sUMAWindowManagerAttr
= 0 ;
53 bool UMAHasWindowManager() { return sUMAHasWindowManager
; }
54 long UMAGetWindowManagerAttr() { return sUMAWindowManagerAttr
; }
55 bool UMAHasAquaLayout() { return sUMAHasAquaLayout
; }
56 bool UMASystemIsInitialized() { return sUMASystemInitialized
; }
58 void UMACleanupToolbox()
60 if ( sUMAHasAppearance
)
62 UnregisterAppearanceClient() ;
64 if ( NavServicesAvailable() )
68 if ( TXNTerminateTextension
!= (void*) kUnresolvedCFragSymbolAddress
)
69 TXNTerminateTextension( ) ;
71 void UMAInitToolbox( UInt16 inMoreMastersCalls
)
75 for (long i
= 1; i
<= inMoreMastersCalls
; i
++)
78 ::InitGraf(&qd
.thePort
);
83 ::FlushEvents(everyEvent
, 0);
86 PurgeSpace(&total
, &contig
);
91 if ( Gestalt(gestaltSystemVersion
, &sUMASystemVersion
) != noErr
)
92 sUMASystemVersion
= 0x0000 ;
95 if ( Gestalt( gestaltAppearanceAttr
, &theAppearance
) == noErr
)
97 sUMAHasAppearance
= true ;
98 RegisterAppearanceClient();
99 if ( Gestalt( gestaltAppearanceVersion
, &theAppearance
) == noErr
)
101 sUMAAppearanceVersion
= theAppearance
;
105 sUMAAppearanceVersion
= 0x0100 ;
108 if ( Gestalt( gestaltWindowMgrAttr
, &sUMAWindowManagerAttr
) == noErr
)
110 sUMAHasWindowManager
= sUMAWindowManagerAttr
& gestaltWindowMgrPresent
;
114 // Call currently implicitely done : InitFloatingWindows() ;
116 if ( sUMAHasWindowManager
)
117 InitFloatingWindows() ;
122 if ( NavServicesAvailable() )
128 Gestalt( gestaltMenuMgrAttr
, &menuMgrAttr
) ;
129 if ( menuMgrAttr
& gestaltMenuMgrAquaLayoutMask
)
130 sUMAHasAquaLayout
= true ;
132 if ( TXNInitTextension
!= (void*) kUnresolvedCFragSymbolAddress
)
134 FontFamilyID fontId
;
138 GetThemeFont(kThemeSmallSystemFont
, GetApplicationScript() , fontName
, &fontSize
, &fontStyle
) ;
139 GetFNum( fontName
, &fontId
);
141 TXNMacOSPreferredFontDescription fontDescriptions
[] =
143 { fontId
, (fontSize
<< 16) ,kTXNDefaultFontStyle
, kTXNSystemDefaultEncoding
} ,
145 int noOfFontDescriptions
= sizeof( fontDescriptions
) / sizeof(TXNMacOSPreferredFontDescription
) ;
146 #if 0 // TARGET_CARBON
147 --noOfFontDescriptions
;
149 // kTXNAlwaysUseQuickDrawTextMask might be desirable because of speed increases but it crashes the app under OS X upon key stroke
150 OptionBits options
= kTXNWantMoviesMask
| kTXNWantSoundMask
| kTXNWantGraphicsMask
;
152 if ( !UMAHasAquaLayout() )
155 options
|= kTXNAlwaysUseQuickDrawTextMask
;
157 TXNInitTextension(fontDescriptions
, noOfFontDescriptions
, options
);
161 sUMASystemInitialized
= true ;
166 Boolean CanUseATSUI()
169 OSErr err = Gestalt(gestaltATSUVersion, &result);
170 return (err == noErr);
174 long UMAGetProcessMode()
177 ProcessInfoRec processinfo
;
178 ProcessSerialNumber procno
;
180 procno
.highLongOfPSN
= NULL
;
181 procno
.lowLongOfPSN
= kCurrentProcess
;
182 processinfo
.processInfoLength
= sizeof(ProcessInfoRec
);
183 processinfo
.processName
= NULL
;
184 processinfo
.processAppSpec
= NULL
;
186 err
= ::GetProcessInformation( &procno
, &processinfo
) ;
187 wxASSERT( err
== noErr
) ;
188 return processinfo
.processMode
;
191 bool UMAGetProcessModeDoesActivateOnFGSwitch()
193 return UMAGetProcessMode() & modeDoesActivateOnFGSwitch
;
198 MenuRef
UMANewMenu( SInt16 id
, const wxString
& title
)
200 wxString str
= wxStripMenuCodes( title
) ;
203 CreateNewMenu( id
, 0 , &menu
) ;
204 SetMenuTitleWithCFString( menu
, wxMacCFStringHolder(str
) ) ;
207 wxMacStringToPascal( str
, ptitle
) ;
208 menu
= ::NewMenu( id
, ptitle
) ;
213 void UMASetMenuTitle( MenuRef menu
, const wxString
& title
)
215 wxString str
= wxStripMenuCodes( title
) ;
217 SetMenuTitleWithCFString( menu
, wxMacCFStringHolder(str
) ) ;
220 wxMacStringToPascal( str
, ptitle
) ;
221 SetMenuTitle( menu
, ptitle
) ;
225 void UMASetMenuItemText( MenuRef menu
, MenuItemIndex item
, const wxString
& title
)
227 wxString str
= wxStripMenuCodes( title
) ;
229 SetMenuItemTextWithCFString( menu
, item
, wxMacCFStringHolder(str
) ) ;
232 wxMacStringToPascal( str
, ptitle
) ;
233 SetMenuItemText( menu
, item
, ptitle
) ;
238 UInt32
UMAMenuEvent( EventRecord
*inEvent
)
240 return MenuEvent( inEvent
) ;
243 void UMAEnableMenuItem( MenuRef inMenu
, MenuItemIndex inItem
, bool enable
)
246 EnableMenuItem( inMenu
, inItem
) ;
248 DisableMenuItem( inMenu
, inItem
) ;
251 void UMAAppendSubMenuItem( MenuRef menu
, const wxString
& title
, SInt16 id
)
253 MacAppendMenu(menu
, "\pA");
254 UMASetMenuItemText(menu
, (SInt16
) ::CountMenuItems(menu
), title
);
255 SetMenuItemHierarchicalID( menu
, CountMenuItems( menu
) , id
) ;
258 void UMAInsertSubMenuItem( MenuRef menu
, const wxString
& title
, MenuItemIndex item
, SInt16 id
)
260 MacInsertMenuItem(menu
, "\pA" , item
);
261 UMASetMenuItemText(menu
, item
, title
);
262 SetMenuItemHierarchicalID( menu
, item
, id
) ;
265 void UMASetMenuItemShortcut( MenuRef menu
, MenuItemIndex item
, wxAcceleratorEntry
*entry
)
270 UInt8 modifiers
= 0 ;
271 SInt16 key
= entry
->GetKeyCode() ;
274 bool explicitCommandKey
= false ;
276 if ( entry
->GetFlags() & wxACCEL_CTRL
)
278 explicitCommandKey
= true ;
281 if (entry
->GetFlags() & wxACCEL_ALT
)
283 modifiers
|= kMenuOptionModifier
;
286 if (entry
->GetFlags() & wxACCEL_SHIFT
)
288 modifiers
|= kMenuShiftModifier
;
292 SInt16 macKey
= key
;
293 if ( key
>= WXK_F1
&& key
<= WXK_F15
)
295 macKey
= kFunctionKeyCharCode
;
296 glyph
= kMenuF1Glyph
+ ( key
- WXK_F1
) ;
297 if ( key
>= WXK_F13
)
299 if ( !explicitCommandKey
)
300 modifiers
|= kMenuNoCommandModifier
;
305 macKey
+= ( 0x7a << 8 ) ;
308 macKey
+= ( 0x78 << 8 ) ;
311 macKey
+= ( 0x63 << 8 ) ;
314 macKey
+= ( 0x76 << 8 ) ;
317 macKey
+= ( 0x60 << 8 ) ;
320 macKey
+= ( 0x61 << 8 ) ;
323 macKey
+= ( 0x62 << 8 ) ;
326 macKey
+= ( 0x64 << 8 ) ;
329 macKey
+= ( 0x65 << 8 ) ;
332 macKey
+= ( 0x6D << 8 ) ;
335 macKey
+= ( 0x67 << 8 ) ;
338 macKey
+= ( 0x6F << 8 ) ;
341 macKey
+= ( 0x69 << 8 ) ;
344 macKey
+= ( 0x6B << 8 ) ;
347 macKey
+= ( 0x71 << 8 ) ;
352 // unfortunately this does not yet trigger the right key ,
353 // for some reason mac justs picks the first function key menu
354 // defined, so we turn this off
363 macKey
= kBackspaceCharCode
;
364 glyph
= kMenuDeleteLeftGlyph
;
367 macKey
= kTabCharCode
;
368 glyph
= kMenuTabRightGlyph
;
370 case kEnterCharCode
:
371 macKey
= kEnterCharCode
;
372 glyph
= kMenuEnterGlyph
;
375 macKey
= kReturnCharCode
;
376 glyph
= kMenuReturnGlyph
;
379 macKey
= kEscapeCharCode
;
380 glyph
= kMenuEscapeGlyph
;
384 glyph
= kMenuSpaceGlyph
;
387 macKey
= kDeleteCharCode
;
388 glyph
= kMenuDeleteRightGlyph
;
391 macKey
= kClearCharCode
;
392 glyph
= kMenuClearGlyph
;
394 case WXK_PRIOR
: // PAGE UP
395 macKey
= kPageUpCharCode
;
396 glyph
= kMenuPageUpGlyph
;
399 macKey
= kPageDownCharCode
;
400 glyph
= kMenuPageDownGlyph
;
403 macKey
= kLeftArrowCharCode
;
404 glyph
= kMenuLeftArrowGlyph
;
407 macKey
= kUpArrowCharCode
;
408 glyph
= kMenuUpArrowGlyph
;
411 macKey
= kRightArrowCharCode
;
412 glyph
= kMenuRightArrowGlyph
;
415 macKey
= kDownArrowCharCode
;
416 glyph
= kMenuDownArrowGlyph
;
421 SetItemCmd( menu
, item
, macKey
);
422 SetMenuItemModifiers(menu
, item
, modifiers
) ;
425 SetMenuItemKeyGlyph(menu
, item
, glyph
) ;
429 void UMAAppendMenuItem( MenuRef menu
, const wxString
& title
, wxAcceleratorEntry
*entry
)
431 MacAppendMenu(menu
, "\pA");
432 UMASetMenuItemText(menu
, (SInt16
) ::CountMenuItems(menu
), title
);
433 UMASetMenuItemShortcut( menu
, (SInt16
) ::CountMenuItems(menu
), entry
) ;
436 void UMAInsertMenuItem( MenuRef menu
, const wxString
& title
, MenuItemIndex item
, wxAcceleratorEntry
*entry
)
438 MacInsertMenuItem( menu
, "\p" , item
) ;
439 UMASetMenuItemText(menu
, item
, title
);
440 UMASetMenuItemShortcut( menu
, item
, entry
) ;
445 int gPrOpenCounter
= 0 ;
447 OSStatus
UMAPrOpen(void *macPrintSession
)
452 if ( gPrOpenCounter
== 1 )
456 wxASSERT( err
== noErr
) ;
460 OSStatus err
= noErr
;
462 if ( gPrOpenCounter
== 1 )
464 #if PM_USE_SESSION_APIS
465 err
= PMCreateSession((PMPrintSession
*)macPrintSession
) ;
469 wxASSERT( err
== noErr
) ;
475 OSStatus
UMAPrClose(void *macPrintSession
)
479 wxASSERT( gPrOpenCounter
>= 1 ) ;
480 if ( gPrOpenCounter
== 1 )
484 wxASSERT( err
== noErr
) ;
489 OSStatus err
= noErr
;
490 wxASSERT( gPrOpenCounter
>= 1 ) ;
491 if ( gPrOpenCounter
== 1 )
493 #if PM_USE_SESSION_APIS
494 err
= PMRelease(*(PMPrintSession
*)macPrintSession
) ;
495 *(PMPrintSession
*)macPrintSession
= kPMNoReference
;
507 pascal QDGlobalsPtr
GetQDGlobalsPtr (void) ;
508 pascal QDGlobalsPtr
GetQDGlobalsPtr (void)
510 return QDGlobalsPtr (* (Ptr
*) LMGetCurrentA5 ( ) - 0xCA);
515 void UMAShowWatchCursor()
519 CursHandle watchFob
= GetCursor (watchCursor
);
526 // Cursor preservedArrow;
527 // GetQDGlobalsArrow (&preservedArrow);
528 // SetQDGlobalsArrow (*watchFob);
530 // SetQDGlobalsArrow (&preservedArrow);
531 SetCursor (*watchFob
);
533 SetCursor (*watchFob
);
538 void UMAShowArrowCursor()
542 SetCursor (GetQDGlobalsArrow (&arrow
));
544 SetCursor (&(qd
.arrow
));
550 GrafPtr
UMAGetWindowPort( WindowRef inWindowRef
)
552 wxASSERT( inWindowRef
!= NULL
) ;
554 return (GrafPtr
) GetWindowPort( inWindowRef
) ;
556 return (GrafPtr
) inWindowRef
;
560 void UMADisposeWindow( WindowRef inWindowRef
)
562 wxASSERT( inWindowRef
!= NULL
) ;
563 DisposeWindow( inWindowRef
) ;
566 void UMASetWTitle( WindowRef inWindowRef
, const wxString
& title
)
569 SetWindowTitleWithCFString( inWindowRef
, wxMacCFStringHolder(title
) ) ;
572 wxMacStringToPascal( title
, ptitle
) ;
573 SetWTitle( inWindowRef
, ptitle
) ;
577 void UMAGetWTitleC( WindowRef inWindowRef
, char *title
)
579 GetWTitle( inWindowRef
, (unsigned char*)title
) ;
581 p2cstrcpy( title
, (unsigned char *)title
) ;
583 p2cstr( (unsigned char*)title
) ;
587 // appearance additions
589 void UMASetControlTitle( ControlHandle inControl
, const wxString
& title
)
592 SetControlTitleWithCFString( inControl
, wxMacCFStringHolder(title
) ) ;
595 wxMacStringToPascal( title
, ptitle
) ;
596 SetControlTitle( inControl
, ptitle
) ;
600 void UMAActivateControl( ControlHandle inControl
)
602 // we have to add the control after again to the update rgn
603 // otherwise updates get lost
604 if ( !IsControlActive( inControl
) )
606 bool visible
= IsControlVisible( inControl
) ;
608 SetControlVisibility( inControl
, false , false ) ;
609 ::ActivateControl( inControl
) ;
611 SetControlVisibility( inControl
, true , false ) ;
613 InvalWindowRect(GetControlOwner(inControl
),GetControlBounds(inControl
,&ctrlBounds
) ) ;
618 void UMADrawControl( ControlHandle inControl
)
620 WindowRef theWindow
= GetControlOwner(inControl
) ;
621 RgnHandle updateRgn
= NewRgn() ;
622 GetWindowUpdateRgn( theWindow
, updateRgn
) ;
623 Point zero
= { 0 , 0 } ;
624 LocalToGlobal( &zero
) ;
625 OffsetRgn( updateRgn
, -zero
.h
, -zero
.v
) ;
626 ::DrawControlInCurrentPort( inControl
) ;
627 InvalWindowRgn( theWindow
, updateRgn
) ;
628 DisposeRgn( updateRgn
) ;
631 void UMAMoveControl( ControlHandle inControl
, short x
, short y
)
633 bool visible
= IsControlVisible( inControl
) ;
635 SetControlVisibility( inControl
, false , false ) ;
637 InvalWindowRect(GetControlOwner(inControl
),GetControlBounds(inControl
,&ctrlBounds
) ) ;
639 ::MoveControl( inControl
, x
, y
) ;
641 SetControlVisibility( inControl
, true , false ) ;
643 InvalWindowRect(GetControlOwner(inControl
),GetControlBounds(inControl
,&ctrlBounds
) ) ;
647 void UMASizeControl( ControlHandle inControl
, short x
, short y
)
649 bool visible
= IsControlVisible( inControl
) ;
651 SetControlVisibility( inControl
, false , false ) ;
653 InvalWindowRect(GetControlOwner(inControl
),GetControlBounds(inControl
,&ctrlBounds
) ) ;
655 ::SizeControl( inControl
, x
, y
) ;
657 SetControlVisibility( inControl
, true , false ) ;
659 InvalWindowRect(GetControlOwner(inControl
),GetControlBounds(inControl
,&ctrlBounds
) ) ;
663 void UMADeactivateControl( ControlHandle inControl
)
665 // we have to add the control after again to the update rgn
666 // otherwise updates get lost
667 bool visible
= IsControlVisible( inControl
) ;
669 SetControlVisibility( inControl
, false , false ) ;
670 ::DeactivateControl( inControl
) ;
672 SetControlVisibility( inControl
, true , false ) ;
674 InvalWindowRect(GetControlOwner(inControl
),GetControlBounds(inControl
,&ctrlBounds
) ) ;
677 // shows the control and adds the region to the update region
678 void UMAShowControl (ControlHandle inControl
)
680 SetControlVisibility( inControl
, true , false ) ;
682 InvalWindowRect(GetControlOwner(inControl
),GetControlBounds(inControl
,&ctrlBounds
) ) ;
685 // shows the control and adds the region to the update region
686 void UMAHideControl (ControlHandle inControl
)
688 SetControlVisibility( inControl
, false , false ) ;
690 InvalWindowRect(GetControlOwner(inControl
),GetControlBounds(inControl
,&ctrlBounds
) ) ;
693 OSErr
UMASetKeyboardFocus (WindowPtr inWindow
,
694 ControlHandle inControl
,
695 ControlFocusPart inPart
)
701 SetPortWindowPort( inWindow
) ;
703 err
= SetKeyboardFocus( inWindow
, inControl
, inPart
) ;
710 void UMAUpdateControls( WindowPtr inWindow
, RgnHandle inRgn
)
712 RgnHandle updateRgn
= NewRgn() ;
713 GetWindowUpdateRgn( inWindow
, updateRgn
) ;
715 Point zero
= { 0 , 0 } ;
716 LocalToGlobal( &zero
) ;
717 OffsetRgn( updateRgn
, -zero
.h
, -zero
.v
) ;
719 UpdateControls( inWindow
, inRgn
) ;
720 InvalWindowRgn( inWindow
, updateRgn
) ;
721 DisposeRgn( updateRgn
) ;
724 bool UMAIsWindowFloating( WindowRef inWindow
)
728 GetWindowClass( inWindow
, &cl
) ;
729 return cl
== kFloatingWindowClass
;
732 bool UMAIsWindowModal( WindowRef inWindow
)
736 GetWindowClass( inWindow
, &cl
) ;
737 return cl
< kFloatingWindowClass
;
742 void UMAHighlightAndActivateWindow( WindowRef inWindowRef
, bool inActivate
)
746 // bool isHighlighted = IsWindowHighlited( inWindowRef ) ;
747 // if ( inActivate != isHightlited )
750 SetPortWindowPort( inWindowRef
) ;
751 HiliteWindow( inWindowRef
, inActivate
) ;
752 ControlHandle control
= NULL
;
753 ::GetRootControl( inWindowRef
, & control
) ;
757 UMAActivateControl( control
) ;
759 UMADeactivateControl( control
) ;
765 OSStatus
UMADrawThemePlacard( const Rect
*inRect
, ThemeDrawState inState
)
767 return ::DrawThemePlacard( inRect
, inState
) ;
771 static OSStatus helpMenuStatus
= noErr
;
772 static MenuItemIndex firstCustomItemIndex
= 0 ;
775 OSStatus
UMAGetHelpMenu(
776 MenuRef
* outHelpMenu
,
777 MenuItemIndex
* outFirstCustomItemIndex
)
780 return HMGetHelpMenu( outHelpMenu
, outFirstCustomItemIndex
) ;
782 MenuRef helpMenuHandle
;
783 helpMenuStatus
= HMGetHelpMenuHandle( &helpMenuHandle
) ;
784 if ( firstCustomItemIndex
== 0 && helpMenuStatus
== noErr
)
786 firstCustomItemIndex
= CountMenuItems( helpMenuHandle
) + 1 ;
788 if ( outFirstCustomItemIndex
)
790 *outFirstCustomItemIndex
= firstCustomItemIndex
;
792 *outHelpMenu
= helpMenuHandle
;
793 return helpMenuStatus
;
797 wxMacPortStateHelper::wxMacPortStateHelper( GrafPtr newport
)
803 wxMacPortStateHelper::wxMacPortStateHelper()
808 void wxMacPortStateHelper::Setup( GrafPtr newport
)
810 GetPort( &m_oldPort
) ;
812 wxASSERT_MSG( m_clip
== NULL
, wxT("Cannot call setup twice") ) ;
815 m_textFont
= GetPortTextFont( (CGrafPtr
) newport
);
816 m_textSize
= GetPortTextSize( (CGrafPtr
) newport
);
817 m_textStyle
= GetPortTextFace( (CGrafPtr
) newport
);
818 m_textMode
= GetPortTextMode( (CGrafPtr
) newport
);
819 GetThemeDrawingState( &m_drawingState
) ;
820 m_currentPort
= newport
;
822 void wxMacPortStateHelper::Clear()
826 DisposeRgn( m_clip
) ;
827 DisposeThemeDrawingState( m_drawingState
) ;
832 wxMacPortStateHelper::~wxMacPortStateHelper()
836 SetPort( m_currentPort
) ;
838 DisposeRgn( m_clip
) ;
839 TextFont( m_textFont
);
840 TextSize( m_textSize
);
841 TextFace( m_textStyle
);
842 TextMode( m_textMode
);
843 SetThemeDrawingState( m_drawingState
, true ) ;
844 SetPort( m_oldPort
) ;
848 OSStatus
UMAPutScrap( Size size
, OSType type
, void *data
)
850 OSStatus err
= noErr
;
852 err
= PutScrap( size
, type
, data
) ;
855 err
= GetCurrentScrap (&scrap
);
858 err
= PutScrapFlavor (scrap
, type
, 0, size
, data
);