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(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
wxMacFindFolder( short vol
,
526 Boolean createFolder
)
531 if ( FSFindFolder( vol
, folderType
, createFolder
, &fsRef
) == noErr
)
532 strDir
= wxMacFSRefToPath( &fsRef
) + wxFILE_SEP_PATH
;
541 // Check whether this window wants to process messages, e.g. Stop button
542 // in long calculations.
543 bool wxCheckForInterrupt(wxWindow
*wnd
)
549 void wxGetMousePosition( int* x
, int* y
)
554 LocalToGlobal( &pt
) ;
559 // Return true if we have a colour display
560 bool wxColourDisplay()
565 // Returns depth of screen
569 SetRect(&globRect
, -32760, -32760, 32760, 32760);
570 GDHandle theMaxDevice
;
573 theMaxDevice
= GetMaxDevice(&globRect
);
574 if (theMaxDevice
!= NULL
)
575 theDepth
= (**(**theMaxDevice
).gdPMap
).pixelSize
;
580 // Get size of display
581 void wxDisplaySize(int *width
, int *height
)
584 GetQDGlobalsScreenBits( &screenBits
);
587 *width
= screenBits
.bounds
.right
- screenBits
.bounds
.left
;
590 *height
= screenBits
.bounds
.bottom
- screenBits
.bounds
.top
;
593 void wxDisplaySizeMM(int *width
, int *height
)
595 wxDisplaySize(width
, height
);
596 // on mac 72 is fixed (at least now ;-)
597 float cvPt2Mm
= 25.4 / 72;
600 *width
= int( *width
* cvPt2Mm
);
603 *height
= int( *height
* cvPt2Mm
);
606 void wxClientDisplayRect(int *x
, int *y
, int *width
, int *height
)
610 GetAvailableWindowPositioningBounds( GetMainDevice() , &r
) ;
616 *width
= r
.right
- r
.left
;
618 *height
= r
.bottom
- r
.top
;
621 wxWindow
* wxFindWindowAtPoint(const wxPoint
& pt
)
623 return wxGenericFindWindowAtPoint(pt
);
630 wxString
wxGetOsDescription()
632 #ifdef WXWIN_OS_DESCRIPTION
633 // use configure generated description if available
634 return wxString(wxT("MacOS (")) + wxT(WXWIN_OS_DESCRIPTION
) + wxString(wxT(")"));
636 return wxT("MacOS") ; //TODO:define further
641 wxChar
*wxGetUserHome (const wxString
& user
)
647 bool wxGetDiskSpace(const wxString
& path
, wxDiskspaceSize_t
*pTotal
, wxDiskspaceSize_t
*pFree
)
656 int pos
= p
.Find(':') ;
657 if ( pos
!= wxNOT_FOUND
)
665 err
= wxMacPathToFSRef( p
, &fsRef
) ;
668 FSVolumeRefNum vRefNum
;
669 err
= FSGetVRefNum( &fsRef
, &vRefNum
) ;
672 UInt64 freeBytes
, totalBytes
;
673 err
= FSGetVInfo( vRefNum
, NULL
, &freeBytes
, &totalBytes
) ;
677 *pTotal
= wxDiskspaceSize_t( totalBytes
) ;
679 *pFree
= wxDiskspaceSize_t( freeBytes
) ;
684 return err
== noErr
;
686 #endif // !__DARWIN__
688 //---------------------------------------------------------------------------
689 // wxMac Specific utility functions
690 //---------------------------------------------------------------------------
692 void wxMacStringToPascal( const wxString
&from
, StringPtr to
)
694 wxCharBuffer buf
= from
.mb_str( wxConvLocal
) ;
695 int len
= strlen(buf
) ;
700 memcpy( (char*) &to
[1] , buf
, len
) ;
703 wxString
wxMacMakeStringFromPascal( ConstStringPtr from
)
705 return wxString( (char*) &from
[1] , wxConvLocal
, from
[0] ) ;
708 // ----------------------------------------------------------------------------
709 // Common Event Support
710 // ----------------------------------------------------------------------------
712 extern ProcessSerialNumber gAppProcess
;
716 ProcessSerialNumber psn
;
718 psn
.highLongOfPSN
= 0 ;
719 psn
.lowLongOfPSN
= kCurrentProcess
;
720 SameProcess( &gAppProcess
, &psn
, &isSame
) ;
724 OSStatus err
= noErr
;
727 // lead sometimes to race conditions, although all calls used should be thread safe ...
728 static wxMacCarbonEvent s_wakeupEvent
;
729 if ( !s_wakeupEvent
.IsValid() )
731 err
= s_wakeupEvent
.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
732 kEventAttributeNone
) ;
737 if ( IsEventInQueue( GetMainEventQueue() , s_wakeupEvent
) )
739 s_wakeupEvent
.SetCurrentTime() ;
740 err
= PostEventToQueue(GetMainEventQueue(), s_wakeupEvent
,
741 kEventPriorityHigh
);
744 wxMacCarbonEvent wakeupEvent
;
745 wakeupEvent
.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
746 kEventAttributeNone
) ;
747 err
= PostEventToQueue(GetMainEventQueue(), wakeupEvent
,
748 kEventPriorityHigh
);
751 PostEvent( nullEvent
, 0 ) ;
756 WakeUpProcess( &gAppProcess
) ;
764 // ----------------------------------------------------------------------------
765 // Native Struct Conversions
766 // ----------------------------------------------------------------------------
768 void wxMacRectToNative( const wxRect
*wx
, Rect
*n
)
772 n
->right
= wx
->x
+ wx
->width
;
773 n
->bottom
= wx
->y
+ wx
->height
;
776 void wxMacNativeToRect( const Rect
*n
, wxRect
* wx
)
780 wx
->width
= n
->right
- n
->left
;
781 wx
->height
= n
->bottom
- n
->top
;
784 void wxMacPointToNative( const wxPoint
* wx
, Point
*n
)
790 void wxMacNativeToPoint( const Point
*n
, wxPoint
* wx
)
796 // ----------------------------------------------------------------------------
797 // Carbon Event Support
798 // ----------------------------------------------------------------------------
800 OSStatus
wxMacCarbonEvent::GetParameter(EventParamName inName
, EventParamType inDesiredType
, UInt32 inBufferSize
, void * outData
)
802 return ::GetEventParameter( m_eventRef
, inName
, inDesiredType
, NULL
, inBufferSize
, NULL
, outData
) ;
805 OSStatus
wxMacCarbonEvent::SetParameter(EventParamName inName
, EventParamType inType
, UInt32 inBufferSize
, const void * inData
)
807 return ::SetEventParameter( m_eventRef
, inName
, inType
, inBufferSize
, inData
) ;
810 // ----------------------------------------------------------------------------
811 // Control Access Support
812 // ----------------------------------------------------------------------------
814 wxMacControl::wxMacControl(wxWindow
* peer
, bool isRootControl
)
818 m_isRootControl
= isRootControl
;
819 m_isCompositing
= peer
->MacGetTopLevelWindow()->MacUsesCompositing() ;
822 wxMacControl::wxMacControl( wxWindow
* peer
, ControlRef control
)
826 m_isCompositing
= peer
->MacGetTopLevelWindow()->MacUsesCompositing() ;
827 m_controlRef
= control
;
830 wxMacControl::wxMacControl( wxWindow
* peer
, WXWidget control
)
834 m_isCompositing
= peer
->MacGetTopLevelWindow()->MacUsesCompositing() ;
835 m_controlRef
= (ControlRef
) control
;
838 wxMacControl::~wxMacControl()
842 void wxMacControl::Init()
845 m_controlRef
= NULL
;
846 m_needsFocusRect
= false ;
847 m_isCompositing
= false ;
848 m_isRootControl
= false ;
851 void wxMacControl::Dispose()
853 ::DisposeControl( m_controlRef
) ;
854 m_controlRef
= NULL
;
857 void wxMacControl::SetReference( SInt32 data
)
859 SetControlReference( m_controlRef
, data
) ;
862 OSStatus
wxMacControl::GetData(ControlPartCode inPartCode
, ResType inTag
, Size inBufferSize
, void * inOutBuffer
, Size
* outActualSize
) const
864 return ::GetControlData( m_controlRef
, inPartCode
, inTag
, inBufferSize
, inOutBuffer
, outActualSize
) ;
867 OSStatus
wxMacControl::GetDataSize(ControlPartCode inPartCode
, ResType inTag
, Size
* outActualSize
) const
869 return ::GetControlDataSize( m_controlRef
, inPartCode
, inTag
, outActualSize
) ;
872 OSStatus
wxMacControl::SetData(ControlPartCode inPartCode
, ResType inTag
, Size inSize
, const void * inData
)
874 return ::SetControlData( m_controlRef
, inPartCode
, inTag
, inSize
, inData
) ;
877 OSStatus
wxMacControl::SendEvent( EventRef event
, OptionBits inOptions
)
879 #if TARGET_API_MAC_OSX
880 return SendEventToEventTargetWithOptions( event
,
881 HIObjectGetEventTarget( (HIObjectRef
) m_controlRef
), inOptions
);
883 #pragma unused(inOptions)
884 return SendEventToEventTarget(event
,GetControlEventTarget( m_controlRef
) ) ;
888 OSStatus
wxMacControl::SendHICommand( HICommand
&command
, OptionBits inOptions
)
890 wxMacCarbonEvent
event( kEventClassCommand
, kEventCommandProcess
) ;
892 event
.SetParameter
<HICommand
>(kEventParamDirectObject
,command
) ;
894 return SendEvent( event
, inOptions
) ;
897 OSStatus
wxMacControl::SendHICommand( UInt32 commandID
, OptionBits inOptions
)
901 memset( &command
, 0 , sizeof(command
) ) ;
902 command
.commandID
= commandID
;
903 return SendHICommand( command
, inOptions
) ;
906 void wxMacControl::Flash( ControlPartCode part
, UInt32 ticks
)
908 unsigned long finalTicks
;
910 HiliteControl( m_controlRef
, part
) ;
911 Delay( ticks
, &finalTicks
) ;
912 HiliteControl( m_controlRef
, kControlNoPart
) ;
915 SInt32
wxMacControl::GetValue() const
917 return ::GetControl32BitValue( m_controlRef
) ;
920 SInt32
wxMacControl::GetMaximum() const
922 return ::GetControl32BitMaximum( m_controlRef
) ;
925 SInt32
wxMacControl::GetMinimum() const
927 return ::GetControl32BitMinimum( m_controlRef
) ;
930 void wxMacControl::SetValue( SInt32 v
)
932 ::SetControl32BitValue( m_controlRef
, v
) ;
935 void wxMacControl::SetMinimum( SInt32 v
)
937 ::SetControl32BitMinimum( m_controlRef
, v
) ;
940 void wxMacControl::SetMaximum( SInt32 v
)
942 ::SetControl32BitMaximum( m_controlRef
, v
) ;
945 void wxMacControl::SetValueAndRange( SInt32 value
, SInt32 minimum
, SInt32 maximum
)
947 ::SetControl32BitMinimum( m_controlRef
, minimum
) ;
948 ::SetControl32BitMaximum( m_controlRef
, maximum
) ;
949 ::SetControl32BitValue( m_controlRef
, value
) ;
952 OSStatus
wxMacControl::SetFocus( ControlFocusPart focusPart
)
954 return SetKeyboardFocus( GetControlOwner( m_controlRef
), m_controlRef
, focusPart
) ;
957 bool wxMacControl::HasFocus() const
960 GetKeyboardFocus( GetUserFocusWindow() , &control
) ;
961 return control
== m_controlRef
;
964 void wxMacControl::SetNeedsFocusRect( bool needs
)
966 m_needsFocusRect
= needs
;
969 bool wxMacControl::NeedsFocusRect() const
971 return m_needsFocusRect
;
974 void wxMacControl::VisibilityChanged(bool shown
)
978 void wxMacControl::SuperChangedPosition()
982 void wxMacControl::SetFont( const wxFont
& font
, const wxColour
& foreground
, long windowStyle
)
985 ControlFontStyleRec fontStyle
;
986 if ( font
.MacGetThemeFontID() != kThemeCurrentPortFont
)
988 switch ( font
.MacGetThemeFontID() )
990 case kThemeSmallSystemFont
:
991 fontStyle
.font
= kControlFontSmallSystemFont
;
994 case 109 : // mini font
995 fontStyle
.font
= -5 ;
998 case kThemeSystemFont
:
999 fontStyle
.font
= kControlFontBigSystemFont
;
1003 fontStyle
.font
= kControlFontBigSystemFont
;
1007 fontStyle
.flags
= kControlUseFontMask
;
1011 fontStyle
.font
= font
.MacGetFontNum() ;
1012 fontStyle
.style
= font
.MacGetFontStyle() ;
1013 fontStyle
.size
= font
.MacGetFontSize() ;
1014 fontStyle
.flags
= kControlUseFontMask
| kControlUseFaceMask
| kControlUseSizeMask
;
1017 fontStyle
.just
= teJustLeft
;
1018 fontStyle
.flags
|= kControlUseJustMask
;
1019 if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_CENTER_HORIZONTAL
)
1020 fontStyle
.just
= teJustCenter
;
1021 else if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_RIGHT
)
1022 fontStyle
.just
= teJustRight
;
1025 // we only should do this in case of a non-standard color, as otherwise 'disabled' controls
1026 // won't get grayed out by the system anymore
1028 if ( foreground
!= *wxBLACK
)
1030 fontStyle
.foreColor
= MAC_WXCOLORREF( foreground
.GetPixel() ) ;
1031 fontStyle
.flags
|= kControlUseForeColorMask
;
1034 ::SetControlFontStyle( m_controlRef
, &fontStyle
);
1037 void wxMacControl::SetBackground( const wxBrush
&WXUNUSED(brush
) )
1040 // setting up a color proc is not recommended anymore
1043 void wxMacControl::SetRange( SInt32 minimum
, SInt32 maximum
)
1045 ::SetControl32BitMinimum( m_controlRef
, minimum
) ;
1046 ::SetControl32BitMaximum( m_controlRef
, maximum
) ;
1049 short wxMacControl::HandleKey( SInt16 keyCode
, SInt16 charCode
, EventModifiers modifiers
)
1051 return HandleControlKey( m_controlRef
, keyCode
, charCode
, modifiers
) ;
1054 void wxMacControl::SetActionProc( ControlActionUPP actionProc
)
1056 SetControlAction( m_controlRef
, actionProc
) ;
1059 void wxMacControl::SetViewSize( SInt32 viewSize
)
1061 SetControlViewSize(m_controlRef
, viewSize
) ;
1064 SInt32
wxMacControl::GetViewSize() const
1066 return GetControlViewSize( m_controlRef
) ;
1069 bool wxMacControl::IsVisible() const
1071 return IsControlVisible( m_controlRef
) ;
1074 void wxMacControl::SetVisibility( bool visible
, bool redraw
)
1076 SetControlVisibility( m_controlRef
, visible
, redraw
) ;
1079 bool wxMacControl::IsEnabled() const
1081 #if TARGET_API_MAC_OSX
1082 return IsControlEnabled( m_controlRef
) ;
1084 return IsControlActive( m_controlRef
) ;
1088 bool wxMacControl::IsActive() const
1090 return IsControlActive( m_controlRef
) ;
1093 void wxMacControl::Enable( bool enable
)
1095 #if TARGET_API_MAC_OSX
1097 EnableControl( m_controlRef
) ;
1099 DisableControl( m_controlRef
) ;
1102 ActivateControl( m_controlRef
) ;
1104 DeactivateControl( m_controlRef
) ;
1108 void wxMacControl::SetDrawingEnabled( bool enable
)
1110 #if TARGET_API_MAC_OSX
1111 HIViewSetDrawingEnabled( m_controlRef
, enable
) ;
1115 #if TARGET_API_MAC_OSX
1116 bool wxMacControl::GetNeedsDisplay() const
1118 #if TARGET_API_MAC_OSX
1119 if ( m_isCompositing
)
1121 return HIViewGetNeedsDisplay( m_controlRef
) ;
1129 Rect controlBounds
;
1130 GetControlBounds( m_controlRef
, &controlBounds
) ;
1131 RgnHandle rgn
= NewRgn() ;
1132 GetWindowRegion ( GetControlOwner( m_controlRef
) , kWindowUpdateRgn
, rgn
) ;
1133 Boolean intersect
= RectInRgn ( &controlBounds
, rgn
) ;
1141 void wxMacControl::SetNeedsDisplay( RgnHandle where
)
1146 #if TARGET_API_MAC_OSX
1147 if ( m_isCompositing
)
1149 HIViewSetNeedsDisplayInRegion( m_controlRef
, where
, true ) ;
1154 Rect controlBounds
;
1155 GetControlBounds( m_controlRef
, &controlBounds
) ;
1156 RgnHandle update
= NewRgn() ;
1157 CopyRgn( where
, update
) ;
1158 OffsetRgn( update
, controlBounds
.left
, controlBounds
.top
) ;
1159 InvalWindowRgn( GetControlOwner( m_controlRef
) , update
) ;
1163 void wxMacControl::SetNeedsDisplay( Rect
* where
)
1168 #if TARGET_API_MAC_OSX
1169 if ( m_isCompositing
)
1171 if ( where
!= NULL
)
1173 RgnHandle update
= NewRgn() ;
1174 RectRgn( update
, where
) ;
1175 HIViewSetNeedsDisplayInRegion( m_controlRef
, update
, true ) ;
1176 DisposeRgn( update
) ;
1179 HIViewSetNeedsDisplay( m_controlRef
, true ) ;
1184 Rect controlBounds
;
1186 GetControlBounds( m_controlRef
, &controlBounds
) ;
1189 Rect whereLocal
= *where
;
1190 OffsetRect( &whereLocal
, controlBounds
.left
, controlBounds
.top
) ;
1191 SectRect( &controlBounds
, &whereLocal
, &controlBounds
) ;
1194 InvalWindowRect( GetControlOwner( m_controlRef
) , &controlBounds
) ;
1198 void wxMacControl::Convert( wxPoint
*pt
, wxMacControl
*from
, wxMacControl
*to
)
1200 #if TARGET_API_MAC_OSX
1201 if ( from
->m_peer
->MacGetTopLevelWindow()->MacUsesCompositing() )
1207 HIViewConvertPoint( &hiPoint
, from
->m_controlRef
, to
->m_controlRef
) ;
1208 pt
->x
= (int)hiPoint
.x
;
1209 pt
->y
= (int)hiPoint
.y
;
1214 Rect fromRect
, toRect
;
1216 GetControlBounds( from
->m_controlRef
, &fromRect
) ;
1217 GetControlBounds( to
->m_controlRef
, &toRect
) ;
1218 if ( from
->m_isRootControl
)
1219 fromRect
.left
= fromRect
.top
= 0 ;
1220 if ( to
->m_isRootControl
)
1221 toRect
.left
= toRect
.top
= 0 ;
1223 pt
->x
= pt
->x
+ fromRect
.left
- toRect
.left
;
1224 pt
->y
= pt
->y
+ fromRect
.top
- toRect
.top
;
1228 void wxMacControl::SetRect( Rect
*r
)
1230 #if TARGET_API_MAC_OSX
1231 if ( m_isCompositing
)
1233 //A HIRect is actually a CGRect on OSX - which consists of two structures -
1234 //CGPoint and CGSize, which have two floats each
1235 HIRect hir
= { { r
->left
, r
->top
}, { r
->right
- r
->left
, r
->bottom
- r
->top
} } ;
1236 HIViewSetFrame ( m_controlRef
, &hir
) ;
1237 // eventuall we might have to do a SetVisibility( false , true ) ;
1238 // before and a SetVisibility( true , true ) ; after
1243 bool vis
= IsVisible() ;
1247 GetControlBounds( m_controlRef
, &former
) ;
1248 InvalWindowRect( GetControlOwner( m_controlRef
) , &former
) ;
1251 Rect controlBounds
= *r
;
1253 // since the rect passed in is always (even in non-compositing) relative
1254 // to the (native) parent, we have to adjust to window relative here
1255 wxMacControl
* parent
= m_peer
->GetParent()->GetPeer() ;
1256 if ( !parent
->m_isRootControl
)
1259 GetControlBounds( parent
->m_controlRef
, &superRect
) ;
1260 OffsetRect( &controlBounds
, superRect
.left
, superRect
.top
) ;
1263 SetControlBounds( m_controlRef
, &controlBounds
) ;
1265 InvalWindowRect( GetControlOwner( m_controlRef
) , &controlBounds
) ;
1269 void wxMacControl::GetRect( Rect
*r
)
1271 GetControlBounds( m_controlRef
, r
) ;
1272 if ( !m_isCompositing
)
1274 // correct the case of the root control
1275 if ( m_isRootControl
)
1277 WindowRef wr
= GetControlOwner( m_controlRef
) ;
1278 GetWindowBounds( wr
, kWindowContentRgn
, r
) ;
1279 r
->right
-= r
->left
;
1280 r
->bottom
-= r
->top
;
1286 wxMacControl
* parent
= m_peer
->GetParent()->GetPeer() ;
1287 if ( !parent
->m_isRootControl
)
1290 GetControlBounds( parent
->m_controlRef
, &superRect
) ;
1291 OffsetRect( r
, -superRect
.left
, -superRect
.top
) ;
1297 void wxMacControl::GetRectInWindowCoords( Rect
*r
)
1299 UMAGetControlBoundsInWindowCoords( m_controlRef
, r
) ;
1302 void wxMacControl::GetBestRect( Rect
*r
)
1304 short baselineoffset
;
1306 GetBestControlRect( m_controlRef
, r
, &baselineoffset
) ;
1309 void wxMacControl::SetLabel( const wxString
&title
)
1311 wxFontEncoding encoding
;
1314 encoding
= m_font
.GetEncoding();
1316 encoding
= wxFont::GetDefaultEncoding();
1318 UMASetControlTitle( m_controlRef
, title
, encoding
) ;
1321 void wxMacControl::GetFeatures( UInt32
* features
)
1323 GetControlFeatures( m_controlRef
, features
) ;
1326 OSStatus
wxMacControl::GetRegion( ControlPartCode partCode
, RgnHandle region
)
1328 OSStatus err
= GetControlRegion( m_controlRef
, partCode
, region
) ;
1329 if ( !m_isCompositing
)
1331 if ( !m_isRootControl
)
1335 GetControlBounds(m_controlRef
, &r
) ;
1336 if ( !EmptyRgn( region
) )
1337 OffsetRgn( region
, -r
.left
, -r
.top
) ;
1344 OSStatus
wxMacControl::SetZOrder( bool above
, wxMacControl
* other
)
1346 #if TARGET_API_MAC_OSX
1347 return HIViewSetZOrder( m_controlRef
,above
? kHIViewZOrderAbove
: kHIViewZOrderBelow
,
1348 (other
!= NULL
) ? other
->m_controlRef
: NULL
) ;
1354 #if TARGET_API_MAC_OSX
1355 // SetNeedsDisplay would not invalidate the children
1356 static void InvalidateControlAndChildren( HIViewRef control
)
1358 HIViewSetNeedsDisplay( control
, true ) ;
1359 UInt16 childrenCount
= 0 ;
1360 OSStatus err
= CountSubControls( control
, &childrenCount
) ;
1361 if ( err
== errControlIsNotEmbedder
)
1364 wxASSERT_MSG( err
== noErr
, wxT("Unexpected error when accessing subcontrols") ) ;
1366 for ( UInt16 i
= childrenCount
; i
>=1 ; --i
)
1370 err
= GetIndexedSubControl( control
, i
, & child
) ;
1371 if ( err
== errControlIsNotEmbedder
)
1374 InvalidateControlAndChildren( child
) ;
1379 void wxMacControl::InvalidateWithChildren()
1381 #if TARGET_API_MAC_OSX
1382 InvalidateControlAndChildren( m_controlRef
) ;
1386 void wxMacControl::ScrollRect( wxRect
*r
, int dx
, int dy
)
1388 wxASSERT( r
!= NULL
) ;
1390 #if TARGET_API_MAC_OSX
1391 if ( m_isCompositing
)
1393 HIRect scrollarea
= CGRectMake( r
->x
, r
->y
, r
->width
, r
->height
) ;
1394 HIViewScrollRect ( m_controlRef
, &scrollarea
, dx
,dy
) ;
1401 GetControlBounds( m_controlRef
, &bounds
) ;
1402 bounds
.left
+= r
->x
;
1403 bounds
.top
+= r
->y
;
1404 bounds
.bottom
= bounds
.top
+ r
->height
;
1405 bounds
.right
= bounds
.left
+ r
->width
;
1406 wxMacWindowClipper
clip( m_peer
) ;
1407 RgnHandle updateRgn
= NewRgn() ;
1408 ::ScrollRect( &bounds
, dx
, dy
, updateRgn
) ;
1409 InvalWindowRgn( GetControlOwner( m_controlRef
) , updateRgn
) ;
1410 DisposeRgn( updateRgn
);
1418 OSStatus
wxMacControl::SetTabEnabled( SInt16 tabNo
, bool enable
)
1420 return ::SetTabEnabled( m_controlRef
, tabNo
, enable
) ;
1427 #ifdef __WXMAC_OSX__
1428 // snippets from Sketch Sample from Apple :
1430 #define kGenericRGBProfilePathStr "/System/Library/ColorSync/Profiles/Generic RGB Profile.icc"
1433 This function locates, opens, and returns the profile reference for the calibrated
1434 Generic RGB color space. It is up to the caller to call CMCloseProfile when done
1435 with the profile reference this function returns.
1437 CMProfileRef
wxMacOpenGenericProfile()
1439 static CMProfileRef cachedRGBProfileRef
= NULL
;
1441 // we only create the profile reference once
1442 if (cachedRGBProfileRef
== NULL
)
1444 CMProfileLocation loc
;
1446 loc
.locType
= cmPathBasedProfile
;
1447 strcpy(loc
.u
.pathLoc
.path
, kGenericRGBProfilePathStr
);
1449 verify_noerr( CMOpenProfile(&cachedRGBProfileRef
, &loc
) );
1452 // clone the profile reference so that the caller has their own reference, not our cached one
1453 if (cachedRGBProfileRef
)
1454 CMCloneProfileRef(cachedRGBProfileRef
);
1456 return cachedRGBProfileRef
;
1460 Return the generic RGB color space. This is a 'get' function and the caller should
1461 not release the returned value unless the caller retains it first. Usually callers
1462 of this routine will immediately use the returned colorspace with CoreGraphics
1463 so they typically do not need to retain it themselves.
1465 This function creates the generic RGB color space once and hangs onto it so it can
1466 return it whenever this function is called.
1469 CGColorSpaceRef
wxMacGetGenericRGBColorSpace()
1471 static wxMacCFRefHolder
<CGColorSpaceRef
> genericRGBColorSpace
;
1473 if (genericRGBColorSpace
== NULL
)
1475 if ( UMAGetSystemVersion() >= 0x1040 )
1477 genericRGBColorSpace
.Set( CGColorSpaceCreateWithName( CFSTR("kCGColorSpaceGenericRGB") ) ) ;
1481 CMProfileRef genericRGBProfile
= wxMacOpenGenericProfile();
1483 if (genericRGBProfile
)
1485 genericRGBColorSpace
.Set( CGColorSpaceCreateWithPlatformColorSpace(genericRGBProfile
) ) ;
1487 wxASSERT_MSG( genericRGBColorSpace
!= NULL
, wxT("couldn't create the generic RGB color space") ) ;
1489 // we opened the profile so it is up to us to close it
1490 CMCloseProfile(genericRGBProfile
);
1495 return genericRGBColorSpace
;
1499 wxMacPortSaver::wxMacPortSaver( GrafPtr port
)
1501 ::GetPort( &m_port
) ;
1505 wxMacPortSaver::~wxMacPortSaver()
1507 ::SetPort( m_port
) ;