1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/utils.cpp
3 // Purpose: Various utilities
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
16 #include "wx/apptrait.h"
19 #include "wx/mac/uma.h"
21 #include "wx/toplevel.h"
33 #include "MoreFilesX.h"
41 #if TARGET_API_MAC_OSX
42 #include <CoreServices/CoreServices.h>
44 #include <DriverServices.h>
45 #include <Multiprocessing.h>
49 #include <Carbon/Carbon.h>
51 #include <ATSUnicode.h>
52 #include <TextCommon.h>
53 #include <TextEncodingConverter.h>
57 #include "wx/mac/private.h"
59 #if defined(__MWERKS__) && wxUSE_UNICODE
63 // ---------------------------------------------------------------------------
64 // code used in both base and GUI compilation
65 // ---------------------------------------------------------------------------
67 // our OS version is the same in non GUI and GUI cases
68 static int DoGetOSVersion(int *majorVsn
, int *minorVsn
)
72 // are there x-platform conventions ?
74 Gestalt(gestaltSystemVersion
, &theSystem
) ;
76 *minorVsn
= (theSystem
& 0xFF) ;
79 *majorVsn
= (theSystem
>> 8) ;
91 // ----------------------------------------------------------------------------
93 // ----------------------------------------------------------------------------
95 #if defined(__WXDEBUG__) && defined(__WXMAC__) && !defined(__DARWIN__) && defined(__MWERKS__) && (__MWERKS__ >= 0x2400)
97 // MetroNub stuff doesn't seem to work in CodeWarrior 5.3 Carbon builds...
99 #ifndef __MetroNubUtils__
100 #include "MetroNubUtils.h"
107 #if TARGET_API_MAC_CARBON
109 #include <CodeFragments.h>
111 extern "C" long CallUniversalProc(UniversalProcPtr theProcPtr
, ProcInfoType procInfo
, ...);
113 ProcPtr gCallUniversalProc_Proc
= NULL
;
117 static MetroNubUserEntryBlock
* gMetroNubEntry
= NULL
;
119 static long fRunOnce
= false;
122 Boolean
IsMetroNubInstalled()
129 gMetroNubEntry
= NULL
;
131 if (Gestalt(gestaltSystemVersion
, &value
) == noErr
&& value
< 0x1000)
133 // look for MetroNub's Gestalt selector
134 if (Gestalt(kMetroNubUserSignature
, &result
) == noErr
)
136 #if TARGET_API_MAC_CARBON
137 if (gCallUniversalProc_Proc
== NULL
)
139 CFragConnectionID connectionID
;
142 ProcPtr symbolAddress
;
144 CFragSymbolClass symbolClass
;
146 symbolAddress
= NULL
;
147 err
= GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch
, kFindCFrag
,
148 &connectionID
, &mainAddress
, errorString
);
152 gCallUniversalProc_Proc
= NULL
;
156 err
= FindSymbol(connectionID
, "\pCallUniversalProc",
157 (Ptr
*) &gCallUniversalProc_Proc
, &symbolClass
);
161 gCallUniversalProc_Proc
= NULL
;
168 MetroNubUserEntryBlock
* block
= (MetroNubUserEntryBlock
*)result
;
170 // make sure the version of the API is compatible
171 if (block
->apiLowVersion
<= kMetroNubUserAPIVersion
&&
172 kMetroNubUserAPIVersion
<= block
->apiHiVersion
)
175 gMetroNubEntry
= block
;
184 #if TARGET_API_MAC_CARBON
185 return (gMetroNubEntry
!= NULL
&& gCallUniversalProc_Proc
!= NULL
);
187 return (gMetroNubEntry
!= NULL
);
191 Boolean
IsMWDebuggerRunning()
193 if (IsMetroNubInstalled())
194 return CallIsDebuggerRunningProc(gMetroNubEntry
->isDebuggerRunning
);
199 Boolean
AmIBeingMWDebugged()
201 if (IsMetroNubInstalled())
202 return CallAmIBeingDebuggedProc(gMetroNubEntry
->amIBeingDebugged
);
207 extern bool WXDLLEXPORT
wxIsDebuggerRunning()
209 return IsMWDebuggerRunning() && AmIBeingMWDebugged();
214 extern bool WXDLLEXPORT
wxIsDebuggerRunning()
219 #endif // defined(__WXMAC__) && !defined(__DARWIN__) && (__MWERKS__ >= 0x2400)
223 // defined in unix/utilsunx.cpp for Mac OS X
225 // get full hostname (with domain name if possible)
226 bool wxGetFullHostName(wxChar
*buf
, int maxSize
)
228 return wxGetHostName(buf
, maxSize
);
231 // Get user ID e.g. jacs
232 bool wxGetUserId(wxChar
*buf
, int maxSize
)
234 return wxGetUserName( buf
, maxSize
) ;
237 const wxChar
* wxGetHomeDir(wxString
*pstr
)
239 *pstr
= wxMacFindFolder( (short) kOnSystemDisk
, kPreferencesFolderType
, kDontCreateFolder
) ;
240 return pstr
->c_str() ;
243 // Get hostname only (without domain name)
244 bool wxGetHostName(wxChar
*buf
, int maxSize
)
246 // Gets Chooser name of user by examining a System resource.
249 const short kComputerNameID
= -16413;
251 short oldResFile
= CurResFile() ;
253 StringHandle chooserName
= (StringHandle
)::GetString(kComputerNameID
);
254 UseResFile(oldResFile
);
256 if (chooserName
&& *chooserName
)
258 HLock( (Handle
) chooserName
) ;
259 wxString name
= wxMacMakeStringFromPascal( *chooserName
) ;
260 HUnlock( (Handle
) chooserName
) ;
261 ReleaseResource( (Handle
) chooserName
) ;
262 wxStrncpy( buf
, name
, maxSize
- 1 ) ;
268 // Get user name e.g. Stefan Csomor
269 bool wxGetUserName(wxChar
*buf
, int maxSize
)
271 // Gets Chooser name of user by examining a System resource.
274 const short kChooserNameID
= -16096;
276 short oldResFile
= CurResFile() ;
278 StringHandle chooserName
= (StringHandle
)::GetString(kChooserNameID
);
279 UseResFile(oldResFile
);
281 if (chooserName
&& *chooserName
)
283 HLock( (Handle
) chooserName
) ;
284 wxString name
= wxMacMakeStringFromPascal( *chooserName
) ;
285 HUnlock( (Handle
) chooserName
) ;
286 ReleaseResource( (Handle
) chooserName
) ;
287 wxStrncpy( buf
, name
, maxSize
- 1 ) ;
293 int wxKill(long pid
, wxSignal sig
, wxKillError
*rc
, int flags
)
299 WXDLLEXPORT
bool wxGetEnv(const wxString
& var
, wxString
*value
)
301 // TODO : under classic there is no environement support, under X yes
305 // set the env var name to the given value, return true on success
306 WXDLLEXPORT
bool wxSetEnv(const wxString
& var
, const wxChar
*value
)
308 // TODO : under classic there is no environement support, under X yes
312 // Execute a program in an Interactive Shell
313 bool wxShell(const wxString
& command
)
319 // Shutdown or reboot the PC
320 bool wxShutdown(wxShutdownFlags wFlags
)
326 wxPowerType
wxGetPowerType()
329 return wxPOWER_UNKNOWN
;
332 wxBatteryState
wxGetBatteryState()
335 return wxBATTERY_UNKNOWN_STATE
;
338 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
339 wxMemorySize
wxGetFreeMemory()
341 return (wxMemorySize
)FreeMem() ;
346 void wxMicroSleep(unsigned long microseconds
)
348 AbsoluteTime wakeup
= AddDurationToAbsolute( microseconds
* durationMicrosecond
, UpTime());
349 MPDelayUntil( & wakeup
);
352 void wxMilliSleep(unsigned long milliseconds
)
354 AbsoluteTime wakeup
= AddDurationToAbsolute( milliseconds
, UpTime());
355 MPDelayUntil( & wakeup
);
358 void wxSleep(int nSecs
)
360 wxMilliSleep(1000*nSecs
);
365 // Consume all events until no more left
370 #endif // !__DARWIN__
378 wxToolkitInfo
& wxConsoleAppTraits::GetToolkitInfo()
380 static wxToolkitInfo info
;
382 info
.os
= DoGetOSVersion(&info
.versionMajor
, &info
.versionMinor
);
383 info
.name
= _T("wxBase");
392 wxToolkitInfo
& wxGUIAppTraits::GetToolkitInfo()
394 static wxToolkitInfo info
;
396 info
.os
= DoGetOSVersion(&info
.versionMajor
, &info
.versionMinor
);
397 info
.shortName
= _T("mac");
398 info
.name
= _T("wxMac");
400 #ifdef __WXUNIVERSAL__
401 info
.shortName
<< _T("univ");
402 info
.name
<< _T("/wxUniversal");
408 // Reading and writing resources (eg WIN.INI, .Xdefaults)
410 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
)
416 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
)
419 buf
.Printf(wxT("%.4f"), value
);
421 return wxWriteResource(section
, entry
, buf
, file
);
424 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
)
427 buf
.Printf(wxT("%ld"), value
);
429 return wxWriteResource(section
, entry
, buf
, file
);
432 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
)
435 buf
.Printf(wxT("%d"), value
);
437 return wxWriteResource(section
, entry
, buf
, file
);
440 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
)
446 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
)
449 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
452 *value
= (float)strtod(s
, NULL
);
459 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
)
462 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
465 *value
= strtol(s
, NULL
, 10);
472 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
)
475 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
478 *value
= (int)strtol(s
, NULL
, 10);
484 #endif // wxUSE_RESOURCES
486 int gs_wxBusyCursorCount
= 0;
487 extern wxCursor gMacCurrentCursor
;
488 wxCursor gMacStoredActiveCursor
;
490 // Set the cursor to the busy cursor for all windows
491 void wxBeginBusyCursor(const wxCursor
*cursor
)
493 if (gs_wxBusyCursorCount
++ == 0)
495 gMacStoredActiveCursor
= gMacCurrentCursor
;
496 cursor
->MacInstall() ;
498 //else: nothing to do, already set
501 // Restore cursor to normal
502 void wxEndBusyCursor()
504 wxCHECK_RET( gs_wxBusyCursorCount
> 0,
505 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
507 if (--gs_wxBusyCursorCount
== 0)
509 gMacStoredActiveCursor
.MacInstall() ;
510 gMacStoredActiveCursor
= wxNullCursor
;
514 // true if we're between the above two calls
517 return (gs_wxBusyCursorCount
> 0);
524 wxString
wxMacFindFolderNoSeparator( short vol
,
526 Boolean createFolder
)
531 if ( FSFindFolder( vol
, folderType
, createFolder
, &fsRef
) == noErr
)
533 strDir
= wxMacFSRefToPath( &fsRef
);
539 wxString
wxMacFindFolder( short vol
,
541 Boolean createFolder
)
543 return wxMacFindFolderNoSeparator(vol
, folderType
, createFolder
) + wxFILE_SEP_PATH
;
550 // Check whether this window wants to process messages, e.g. Stop button
551 // in long calculations.
552 bool wxCheckForInterrupt(wxWindow
*wnd
)
558 void wxGetMousePosition( int* x
, int* y
)
563 LocalToGlobal( &pt
) ;
568 // Return true if we have a colour display
569 bool wxColourDisplay()
574 // Returns depth of screen
578 SetRect(&globRect
, -32760, -32760, 32760, 32760);
579 GDHandle theMaxDevice
;
582 theMaxDevice
= GetMaxDevice(&globRect
);
583 if (theMaxDevice
!= NULL
)
584 theDepth
= (**(**theMaxDevice
).gdPMap
).pixelSize
;
589 // Get size of display
590 void wxDisplaySize(int *width
, int *height
)
593 GetQDGlobalsScreenBits( &screenBits
);
596 *width
= screenBits
.bounds
.right
- screenBits
.bounds
.left
;
599 *height
= screenBits
.bounds
.bottom
- screenBits
.bounds
.top
;
602 void wxDisplaySizeMM(int *width
, int *height
)
604 wxDisplaySize(width
, height
);
605 // on mac 72 is fixed (at least now ;-)
606 float cvPt2Mm
= 25.4 / 72;
609 *width
= int( *width
* cvPt2Mm
);
612 *height
= int( *height
* cvPt2Mm
);
615 void wxClientDisplayRect(int *x
, int *y
, int *width
, int *height
)
619 GetAvailableWindowPositioningBounds( GetMainDevice() , &r
) ;
625 *width
= r
.right
- r
.left
;
627 *height
= r
.bottom
- r
.top
;
630 wxWindow
* wxFindWindowAtPoint(const wxPoint
& pt
)
632 return wxGenericFindWindowAtPoint(pt
);
639 wxString
wxGetOsDescription()
641 #ifdef WXWIN_OS_DESCRIPTION
642 // use configure generated description if available
643 return wxString(wxT("MacOS (")) + wxT(WXWIN_OS_DESCRIPTION
) + wxString(wxT(")"));
645 return wxT("MacOS") ; //TODO:define further
650 wxChar
*wxGetUserHome (const wxString
& user
)
656 bool wxGetDiskSpace(const wxString
& path
, wxDiskspaceSize_t
*pTotal
, wxDiskspaceSize_t
*pFree
)
665 int pos
= p
.Find(':') ;
666 if ( pos
!= wxNOT_FOUND
)
674 err
= wxMacPathToFSRef( p
, &fsRef
) ;
677 FSVolumeRefNum vRefNum
;
678 err
= FSGetVRefNum( &fsRef
, &vRefNum
) ;
681 UInt64 freeBytes
, totalBytes
;
682 err
= FSGetVInfo( vRefNum
, NULL
, &freeBytes
, &totalBytes
) ;
686 *pTotal
= wxDiskspaceSize_t( totalBytes
) ;
688 *pFree
= wxDiskspaceSize_t( freeBytes
) ;
693 return err
== noErr
;
695 #endif // !__DARWIN__
697 //---------------------------------------------------------------------------
698 // wxMac Specific utility functions
699 //---------------------------------------------------------------------------
701 void wxMacStringToPascal( const wxString
&from
, StringPtr to
)
703 wxCharBuffer buf
= from
.mb_str( wxConvLocal
) ;
704 int len
= strlen(buf
) ;
709 memcpy( (char*) &to
[1] , buf
, len
) ;
712 wxString
wxMacMakeStringFromPascal( ConstStringPtr from
)
714 return wxString( (char*) &from
[1] , wxConvLocal
, from
[0] ) ;
717 // ----------------------------------------------------------------------------
718 // Common Event Support
719 // ----------------------------------------------------------------------------
721 extern ProcessSerialNumber gAppProcess
;
725 ProcessSerialNumber psn
;
727 psn
.highLongOfPSN
= 0 ;
728 psn
.lowLongOfPSN
= kCurrentProcess
;
729 SameProcess( &gAppProcess
, &psn
, &isSame
) ;
733 OSStatus err
= noErr
;
736 // lead sometimes to race conditions, although all calls used should be thread safe ...
737 static wxMacCarbonEvent s_wakeupEvent
;
738 if ( !s_wakeupEvent
.IsValid() )
740 err
= s_wakeupEvent
.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
741 kEventAttributeNone
) ;
746 if ( IsEventInQueue( GetMainEventQueue() , s_wakeupEvent
) )
748 s_wakeupEvent
.SetCurrentTime() ;
749 err
= PostEventToQueue(GetMainEventQueue(), s_wakeupEvent
,
750 kEventPriorityHigh
);
753 wxMacCarbonEvent wakeupEvent
;
754 wakeupEvent
.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
755 kEventAttributeNone
) ;
756 err
= PostEventToQueue(GetMainEventQueue(), wakeupEvent
,
757 kEventPriorityHigh
);
760 PostEvent( nullEvent
, 0 ) ;
765 WakeUpProcess( &gAppProcess
) ;
773 // ----------------------------------------------------------------------------
774 // Native Struct Conversions
775 // ----------------------------------------------------------------------------
777 void wxMacRectToNative( const wxRect
*wx
, Rect
*n
)
781 n
->right
= wx
->x
+ wx
->width
;
782 n
->bottom
= wx
->y
+ wx
->height
;
785 void wxMacNativeToRect( const Rect
*n
, wxRect
* wx
)
789 wx
->width
= n
->right
- n
->left
;
790 wx
->height
= n
->bottom
- n
->top
;
793 void wxMacPointToNative( const wxPoint
* wx
, Point
*n
)
799 void wxMacNativeToPoint( const Point
*n
, wxPoint
* wx
)
805 // ----------------------------------------------------------------------------
806 // Carbon Event Support
807 // ----------------------------------------------------------------------------
809 OSStatus
wxMacCarbonEvent::GetParameter(EventParamName inName
, EventParamType inDesiredType
, UInt32 inBufferSize
, void * outData
)
811 return ::GetEventParameter( m_eventRef
, inName
, inDesiredType
, NULL
, inBufferSize
, NULL
, outData
) ;
814 OSStatus
wxMacCarbonEvent::SetParameter(EventParamName inName
, EventParamType inType
, UInt32 inBufferSize
, const void * inData
)
816 return ::SetEventParameter( m_eventRef
, inName
, inType
, inBufferSize
, inData
) ;
819 // ----------------------------------------------------------------------------
820 // Control Access Support
821 // ----------------------------------------------------------------------------
823 wxMacControl::wxMacControl(wxWindow
* peer
, bool isRootControl
)
827 m_isRootControl
= isRootControl
;
828 m_isCompositing
= peer
->MacGetTopLevelWindow()->MacUsesCompositing() ;
831 wxMacControl::wxMacControl( wxWindow
* peer
, ControlRef control
)
835 m_isCompositing
= peer
->MacGetTopLevelWindow()->MacUsesCompositing() ;
836 m_controlRef
= control
;
839 wxMacControl::wxMacControl( wxWindow
* peer
, WXWidget control
)
843 m_isCompositing
= peer
->MacGetTopLevelWindow()->MacUsesCompositing() ;
844 m_controlRef
= (ControlRef
) control
;
847 wxMacControl::~wxMacControl()
851 void wxMacControl::Init()
854 m_controlRef
= NULL
;
855 m_needsFocusRect
= false ;
856 m_isCompositing
= false ;
857 m_isRootControl
= false ;
860 void wxMacControl::Dispose()
862 ::DisposeControl( m_controlRef
) ;
863 m_controlRef
= NULL
;
866 void wxMacControl::SetReference( SInt32 data
)
868 SetControlReference( m_controlRef
, data
) ;
871 OSStatus
wxMacControl::GetData(ControlPartCode inPartCode
, ResType inTag
, Size inBufferSize
, void * inOutBuffer
, Size
* outActualSize
) const
873 return ::GetControlData( m_controlRef
, inPartCode
, inTag
, inBufferSize
, inOutBuffer
, outActualSize
) ;
876 OSStatus
wxMacControl::GetDataSize(ControlPartCode inPartCode
, ResType inTag
, Size
* outActualSize
) const
878 return ::GetControlDataSize( m_controlRef
, inPartCode
, inTag
, outActualSize
) ;
881 OSStatus
wxMacControl::SetData(ControlPartCode inPartCode
, ResType inTag
, Size inSize
, const void * inData
)
883 return ::SetControlData( m_controlRef
, inPartCode
, inTag
, inSize
, inData
) ;
886 OSStatus
wxMacControl::SendEvent( EventRef event
, OptionBits inOptions
)
888 #if TARGET_API_MAC_OSX
889 return SendEventToEventTargetWithOptions( event
,
890 HIObjectGetEventTarget( (HIObjectRef
) m_controlRef
), inOptions
);
892 #pragma unused(inOptions)
893 return SendEventToEventTarget(event
,GetControlEventTarget( m_controlRef
) ) ;
897 OSStatus
wxMacControl::SendHICommand( HICommand
&command
, OptionBits inOptions
)
899 wxMacCarbonEvent
event( kEventClassCommand
, kEventCommandProcess
) ;
901 event
.SetParameter
<HICommand
>(kEventParamDirectObject
,command
) ;
903 return SendEvent( event
, inOptions
) ;
906 OSStatus
wxMacControl::SendHICommand( UInt32 commandID
, OptionBits inOptions
)
910 memset( &command
, 0 , sizeof(command
) ) ;
911 command
.commandID
= commandID
;
912 return SendHICommand( command
, inOptions
) ;
915 void wxMacControl::Flash( ControlPartCode part
, UInt32 ticks
)
917 unsigned long finalTicks
;
919 HiliteControl( m_controlRef
, part
) ;
920 Delay( ticks
, &finalTicks
) ;
921 HiliteControl( m_controlRef
, kControlNoPart
) ;
924 SInt32
wxMacControl::GetValue() const
926 return ::GetControl32BitValue( m_controlRef
) ;
929 SInt32
wxMacControl::GetMaximum() const
931 return ::GetControl32BitMaximum( m_controlRef
) ;
934 SInt32
wxMacControl::GetMinimum() const
936 return ::GetControl32BitMinimum( m_controlRef
) ;
939 void wxMacControl::SetValue( SInt32 v
)
941 ::SetControl32BitValue( m_controlRef
, v
) ;
944 void wxMacControl::SetMinimum( SInt32 v
)
946 ::SetControl32BitMinimum( m_controlRef
, v
) ;
949 void wxMacControl::SetMaximum( SInt32 v
)
951 ::SetControl32BitMaximum( m_controlRef
, v
) ;
954 void wxMacControl::SetValueAndRange( SInt32 value
, SInt32 minimum
, SInt32 maximum
)
956 ::SetControl32BitMinimum( m_controlRef
, minimum
) ;
957 ::SetControl32BitMaximum( m_controlRef
, maximum
) ;
958 ::SetControl32BitValue( m_controlRef
, value
) ;
961 OSStatus
wxMacControl::SetFocus( ControlFocusPart focusPart
)
963 return SetKeyboardFocus( GetControlOwner( m_controlRef
), m_controlRef
, focusPart
) ;
966 bool wxMacControl::HasFocus() const
969 GetKeyboardFocus( GetUserFocusWindow() , &control
) ;
970 return control
== m_controlRef
;
973 void wxMacControl::SetNeedsFocusRect( bool needs
)
975 m_needsFocusRect
= needs
;
978 bool wxMacControl::NeedsFocusRect() const
980 return m_needsFocusRect
;
983 void wxMacControl::VisibilityChanged(bool shown
)
987 void wxMacControl::SuperChangedPosition()
991 void wxMacControl::SetFont( const wxFont
& font
, const wxColour
& foreground
, long windowStyle
)
994 ControlFontStyleRec fontStyle
;
995 if ( font
.MacGetThemeFontID() != kThemeCurrentPortFont
)
997 switch ( font
.MacGetThemeFontID() )
999 case kThemeSmallSystemFont
:
1000 fontStyle
.font
= kControlFontSmallSystemFont
;
1003 case 109 : // mini font
1004 fontStyle
.font
= -5 ;
1007 case kThemeSystemFont
:
1008 fontStyle
.font
= kControlFontBigSystemFont
;
1012 fontStyle
.font
= kControlFontBigSystemFont
;
1016 fontStyle
.flags
= kControlUseFontMask
;
1020 fontStyle
.font
= font
.MacGetFontNum() ;
1021 fontStyle
.style
= font
.MacGetFontStyle() ;
1022 fontStyle
.size
= font
.MacGetFontSize() ;
1023 fontStyle
.flags
= kControlUseFontMask
| kControlUseFaceMask
| kControlUseSizeMask
;
1026 fontStyle
.just
= teJustLeft
;
1027 fontStyle
.flags
|= kControlUseJustMask
;
1028 if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_CENTER_HORIZONTAL
)
1029 fontStyle
.just
= teJustCenter
;
1030 else if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_RIGHT
)
1031 fontStyle
.just
= teJustRight
;
1034 // we only should do this in case of a non-standard color, as otherwise 'disabled' controls
1035 // won't get grayed out by the system anymore
1037 if ( foreground
!= *wxBLACK
)
1039 fontStyle
.foreColor
= MAC_WXCOLORREF( foreground
.GetPixel() ) ;
1040 fontStyle
.flags
|= kControlUseForeColorMask
;
1043 ::SetControlFontStyle( m_controlRef
, &fontStyle
);
1046 void wxMacControl::SetBackground( const wxBrush
&WXUNUSED(brush
) )
1049 // setting up a color proc is not recommended anymore
1052 void wxMacControl::SetRange( SInt32 minimum
, SInt32 maximum
)
1054 ::SetControl32BitMinimum( m_controlRef
, minimum
) ;
1055 ::SetControl32BitMaximum( m_controlRef
, maximum
) ;
1058 short wxMacControl::HandleKey( SInt16 keyCode
, SInt16 charCode
, EventModifiers modifiers
)
1060 return HandleControlKey( m_controlRef
, keyCode
, charCode
, modifiers
) ;
1063 void wxMacControl::SetActionProc( ControlActionUPP actionProc
)
1065 SetControlAction( m_controlRef
, actionProc
) ;
1068 void wxMacControl::SetViewSize( SInt32 viewSize
)
1070 SetControlViewSize(m_controlRef
, viewSize
) ;
1073 SInt32
wxMacControl::GetViewSize() const
1075 return GetControlViewSize( m_controlRef
) ;
1078 bool wxMacControl::IsVisible() const
1080 return IsControlVisible( m_controlRef
) ;
1083 void wxMacControl::SetVisibility( bool visible
, bool redraw
)
1085 SetControlVisibility( m_controlRef
, visible
, redraw
) ;
1088 bool wxMacControl::IsEnabled() const
1090 #if TARGET_API_MAC_OSX
1091 return IsControlEnabled( m_controlRef
) ;
1093 return IsControlActive( m_controlRef
) ;
1097 bool wxMacControl::IsActive() const
1099 return IsControlActive( m_controlRef
) ;
1102 void wxMacControl::Enable( bool enable
)
1104 #if TARGET_API_MAC_OSX
1106 EnableControl( m_controlRef
) ;
1108 DisableControl( m_controlRef
) ;
1111 ActivateControl( m_controlRef
) ;
1113 DeactivateControl( m_controlRef
) ;
1117 void wxMacControl::SetDrawingEnabled( bool enable
)
1119 #if TARGET_API_MAC_OSX
1120 HIViewSetDrawingEnabled( m_controlRef
, enable
) ;
1124 #if TARGET_API_MAC_OSX
1125 bool wxMacControl::GetNeedsDisplay() const
1127 #if TARGET_API_MAC_OSX
1128 if ( m_isCompositing
)
1130 return HIViewGetNeedsDisplay( m_controlRef
) ;
1138 Rect controlBounds
;
1139 GetControlBounds( m_controlRef
, &controlBounds
) ;
1140 RgnHandle rgn
= NewRgn() ;
1141 GetWindowRegion ( GetControlOwner( m_controlRef
) , kWindowUpdateRgn
, rgn
) ;
1142 Boolean intersect
= RectInRgn ( &controlBounds
, rgn
) ;
1150 void wxMacControl::SetNeedsDisplay( RgnHandle where
)
1155 #if TARGET_API_MAC_OSX
1156 if ( m_isCompositing
)
1158 HIViewSetNeedsDisplayInRegion( m_controlRef
, where
, true ) ;
1163 Rect controlBounds
;
1164 GetControlBounds( m_controlRef
, &controlBounds
) ;
1165 RgnHandle update
= NewRgn() ;
1166 CopyRgn( where
, update
) ;
1167 OffsetRgn( update
, controlBounds
.left
, controlBounds
.top
) ;
1168 InvalWindowRgn( GetControlOwner( m_controlRef
) , update
) ;
1172 void wxMacControl::SetNeedsDisplay( Rect
* where
)
1177 #if TARGET_API_MAC_OSX
1178 if ( m_isCompositing
)
1180 if ( where
!= NULL
)
1182 RgnHandle update
= NewRgn() ;
1183 RectRgn( update
, where
) ;
1184 HIViewSetNeedsDisplayInRegion( m_controlRef
, update
, true ) ;
1185 DisposeRgn( update
) ;
1188 HIViewSetNeedsDisplay( m_controlRef
, true ) ;
1193 Rect controlBounds
;
1195 GetControlBounds( m_controlRef
, &controlBounds
) ;
1198 Rect whereLocal
= *where
;
1199 OffsetRect( &whereLocal
, controlBounds
.left
, controlBounds
.top
) ;
1200 SectRect( &controlBounds
, &whereLocal
, &controlBounds
) ;
1203 InvalWindowRect( GetControlOwner( m_controlRef
) , &controlBounds
) ;
1207 void wxMacControl::Convert( wxPoint
*pt
, wxMacControl
*from
, wxMacControl
*to
)
1209 #if TARGET_API_MAC_OSX
1210 if ( from
->m_peer
->MacGetTopLevelWindow()->MacUsesCompositing() )
1216 HIViewConvertPoint( &hiPoint
, from
->m_controlRef
, to
->m_controlRef
) ;
1217 pt
->x
= (int)hiPoint
.x
;
1218 pt
->y
= (int)hiPoint
.y
;
1223 Rect fromRect
, toRect
;
1225 GetControlBounds( from
->m_controlRef
, &fromRect
) ;
1226 GetControlBounds( to
->m_controlRef
, &toRect
) ;
1227 if ( from
->m_isRootControl
)
1228 fromRect
.left
= fromRect
.top
= 0 ;
1229 if ( to
->m_isRootControl
)
1230 toRect
.left
= toRect
.top
= 0 ;
1232 pt
->x
= pt
->x
+ fromRect
.left
- toRect
.left
;
1233 pt
->y
= pt
->y
+ fromRect
.top
- toRect
.top
;
1237 void wxMacControl::SetRect( Rect
*r
)
1239 #if TARGET_API_MAC_OSX
1240 if ( m_isCompositing
)
1242 //A HIRect is actually a CGRect on OSX - which consists of two structures -
1243 //CGPoint and CGSize, which have two floats each
1244 HIRect hir
= { { r
->left
, r
->top
}, { r
->right
- r
->left
, r
->bottom
- r
->top
} } ;
1245 HIViewSetFrame ( m_controlRef
, &hir
) ;
1246 // eventuall we might have to do a SetVisibility( false , true ) ;
1247 // before and a SetVisibility( true , true ) ; after
1252 bool vis
= IsVisible() ;
1256 GetControlBounds( m_controlRef
, &former
) ;
1257 InvalWindowRect( GetControlOwner( m_controlRef
) , &former
) ;
1260 Rect controlBounds
= *r
;
1262 // since the rect passed in is always (even in non-compositing) relative
1263 // to the (native) parent, we have to adjust to window relative here
1264 wxMacControl
* parent
= m_peer
->GetParent()->GetPeer() ;
1265 if ( !parent
->m_isRootControl
)
1268 GetControlBounds( parent
->m_controlRef
, &superRect
) ;
1269 OffsetRect( &controlBounds
, superRect
.left
, superRect
.top
) ;
1272 SetControlBounds( m_controlRef
, &controlBounds
) ;
1274 InvalWindowRect( GetControlOwner( m_controlRef
) , &controlBounds
) ;
1278 void wxMacControl::GetRect( Rect
*r
)
1280 GetControlBounds( m_controlRef
, r
) ;
1281 if ( !m_isCompositing
)
1283 // correct the case of the root control
1284 if ( m_isRootControl
)
1286 WindowRef wr
= GetControlOwner( m_controlRef
) ;
1287 GetWindowBounds( wr
, kWindowContentRgn
, r
) ;
1288 r
->right
-= r
->left
;
1289 r
->bottom
-= r
->top
;
1295 wxMacControl
* parent
= m_peer
->GetParent()->GetPeer() ;
1296 if ( !parent
->m_isRootControl
)
1299 GetControlBounds( parent
->m_controlRef
, &superRect
) ;
1300 OffsetRect( r
, -superRect
.left
, -superRect
.top
) ;
1306 void wxMacControl::GetRectInWindowCoords( Rect
*r
)
1308 UMAGetControlBoundsInWindowCoords( m_controlRef
, r
) ;
1311 void wxMacControl::GetBestRect( Rect
*r
)
1313 short baselineoffset
;
1315 GetBestControlRect( m_controlRef
, r
, &baselineoffset
) ;
1318 void wxMacControl::SetLabel( const wxString
&title
)
1320 wxFontEncoding encoding
;
1323 encoding
= m_font
.GetEncoding();
1325 encoding
= wxFont::GetDefaultEncoding();
1327 UMASetControlTitle( m_controlRef
, title
, encoding
) ;
1330 void wxMacControl::GetFeatures( UInt32
* features
)
1332 GetControlFeatures( m_controlRef
, features
) ;
1335 OSStatus
wxMacControl::GetRegion( ControlPartCode partCode
, RgnHandle region
)
1337 OSStatus err
= GetControlRegion( m_controlRef
, partCode
, region
) ;
1338 if ( !m_isCompositing
)
1340 if ( !m_isRootControl
)
1344 GetControlBounds(m_controlRef
, &r
) ;
1345 if ( !EmptyRgn( region
) )
1346 OffsetRgn( region
, -r
.left
, -r
.top
) ;
1353 OSStatus
wxMacControl::SetZOrder( bool above
, wxMacControl
* other
)
1355 #if TARGET_API_MAC_OSX
1356 return HIViewSetZOrder( m_controlRef
,above
? kHIViewZOrderAbove
: kHIViewZOrderBelow
,
1357 (other
!= NULL
) ? other
->m_controlRef
: NULL
) ;
1363 #if TARGET_API_MAC_OSX
1364 // SetNeedsDisplay would not invalidate the children
1365 static void InvalidateControlAndChildren( HIViewRef control
)
1367 HIViewSetNeedsDisplay( control
, true ) ;
1368 UInt16 childrenCount
= 0 ;
1369 OSStatus err
= CountSubControls( control
, &childrenCount
) ;
1370 if ( err
== errControlIsNotEmbedder
)
1373 wxASSERT_MSG( err
== noErr
, wxT("Unexpected error when accessing subcontrols") ) ;
1375 for ( UInt16 i
= childrenCount
; i
>=1 ; --i
)
1379 err
= GetIndexedSubControl( control
, i
, & child
) ;
1380 if ( err
== errControlIsNotEmbedder
)
1383 InvalidateControlAndChildren( child
) ;
1388 void wxMacControl::InvalidateWithChildren()
1390 #if TARGET_API_MAC_OSX
1391 InvalidateControlAndChildren( m_controlRef
) ;
1395 void wxMacControl::ScrollRect( wxRect
*r
, int dx
, int dy
)
1397 wxASSERT( r
!= NULL
) ;
1399 #if TARGET_API_MAC_OSX
1400 if ( m_isCompositing
)
1402 HIRect scrollarea
= CGRectMake( r
->x
, r
->y
, r
->width
, r
->height
) ;
1403 HIViewScrollRect ( m_controlRef
, &scrollarea
, dx
,dy
) ;
1410 GetControlBounds( m_controlRef
, &bounds
) ;
1411 bounds
.left
+= r
->x
;
1412 bounds
.top
+= r
->y
;
1413 bounds
.bottom
= bounds
.top
+ r
->height
;
1414 bounds
.right
= bounds
.left
+ r
->width
;
1415 wxMacWindowClipper
clip( m_peer
) ;
1416 RgnHandle updateRgn
= NewRgn() ;
1417 ::ScrollRect( &bounds
, dx
, dy
, updateRgn
) ;
1418 InvalWindowRgn( GetControlOwner( m_controlRef
) , updateRgn
) ;
1419 DisposeRgn( updateRgn
);
1427 OSStatus
wxMacControl::SetTabEnabled( SInt16 tabNo
, bool enable
)
1429 return ::SetTabEnabled( m_controlRef
, tabNo
, enable
) ;
1436 #ifdef __WXMAC_OSX__
1437 // snippets from Sketch Sample from Apple :
1439 #define kGenericRGBProfilePathStr "/System/Library/ColorSync/Profiles/Generic RGB Profile.icc"
1442 This function locates, opens, and returns the profile reference for the calibrated
1443 Generic RGB color space. It is up to the caller to call CMCloseProfile when done
1444 with the profile reference this function returns.
1446 CMProfileRef
wxMacOpenGenericProfile()
1448 static CMProfileRef cachedRGBProfileRef
= NULL
;
1450 // we only create the profile reference once
1451 if (cachedRGBProfileRef
== NULL
)
1453 CMProfileLocation loc
;
1455 loc
.locType
= cmPathBasedProfile
;
1456 strcpy(loc
.u
.pathLoc
.path
, kGenericRGBProfilePathStr
);
1458 verify_noerr( CMOpenProfile(&cachedRGBProfileRef
, &loc
) );
1461 // clone the profile reference so that the caller has their own reference, not our cached one
1462 if (cachedRGBProfileRef
)
1463 CMCloneProfileRef(cachedRGBProfileRef
);
1465 return cachedRGBProfileRef
;
1469 Return the generic RGB color space. This is a 'get' function and the caller should
1470 not release the returned value unless the caller retains it first. Usually callers
1471 of this routine will immediately use the returned colorspace with CoreGraphics
1472 so they typically do not need to retain it themselves.
1474 This function creates the generic RGB color space once and hangs onto it so it can
1475 return it whenever this function is called.
1478 CGColorSpaceRef
wxMacGetGenericRGBColorSpace()
1480 static wxMacCFRefHolder
<CGColorSpaceRef
> genericRGBColorSpace
;
1482 if (genericRGBColorSpace
== NULL
)
1484 if ( UMAGetSystemVersion() >= 0x1040 )
1486 genericRGBColorSpace
.Set( CGColorSpaceCreateWithName( CFSTR("kCGColorSpaceGenericRGB") ) ) ;
1490 CMProfileRef genericRGBProfile
= wxMacOpenGenericProfile();
1492 if (genericRGBProfile
)
1494 genericRGBColorSpace
.Set( CGColorSpaceCreateWithPlatformColorSpace(genericRGBProfile
) ) ;
1496 wxASSERT_MSG( genericRGBColorSpace
!= NULL
, wxT("couldn't create the generic RGB color space") ) ;
1498 // we opened the profile so it is up to us to close it
1499 CMCloseProfile(genericRGBProfile
);
1504 return genericRGBColorSpace
;
1508 wxMacPortSaver::wxMacPortSaver( GrafPtr port
)
1510 ::GetPort( &m_port
) ;
1514 wxMacPortSaver::~wxMacPortSaver()
1516 ::SetPort( m_port
) ;