+#define wxMAC_USE_THEME_BORDER 1
+
+// ---------------------------------------------------------------------------
+// Utility Routines to move between different coordinate systems
+// ---------------------------------------------------------------------------
+
+/*
+ * Right now we have the following setup :
+ * a border that is not part of the native control is always outside the
+ * control's border (otherwise we loose all native intelligence, future ways
+ * may be to have a second embedding control responsible for drawing borders
+ * and backgrounds eventually)
+ * so all this border calculations have to be taken into account when calling
+ * native methods or getting native oriented data
+ * so we have three coordinate systems here
+ * wx client coordinates
+ * wx window coordinates (including window frames)
+ * native coordinates
+ */
+
+//
+// originating from native control
+//
+
+
+void wxMacNativeToWindow( const wxWindow* window , RgnHandle handle )
+{
+ OffsetRgn( handle , window->MacGetLeftBorderSize() , window->MacGetTopBorderSize() ) ;
+}
+
+void wxMacNativeToWindow( const wxWindow* window , Rect *rect )
+{
+ OffsetRect( rect , window->MacGetLeftBorderSize() , window->MacGetTopBorderSize() ) ;
+}
+
+//
+// directed towards native control
+//
+
+void wxMacWindowToNative( const wxWindow* window , RgnHandle handle )
+{
+ OffsetRgn( handle , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() );
+}
+
+void wxMacWindowToNative( const wxWindow* window , Rect *rect )
+{
+ OffsetRect( rect , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() ) ;
+}
+
+
+// ---------------------------------------------------------------------------
+// Carbon Events
+// ---------------------------------------------------------------------------
+
+extern long wxMacTranslateKey(unsigned char key, unsigned char code) ;
+pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessage , SInt16 iDepth , Boolean iIsColor ) ;
+
+#if TARGET_API_MAC_OSX
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3
+enum {
+ kEventControlVisibilityChanged = 157
+};
+#endif
+
+#endif
+
+static const EventTypeSpec eventList[] =
+{
+ { kEventClassControl , kEventControlHit } ,
+#if TARGET_API_MAC_OSX
+ { kEventClassControl , kEventControlDraw } ,
+ { kEventClassControl , kEventControlVisibilityChanged } ,
+ { kEventClassControl , kEventControlEnabledStateChanged } ,
+ { kEventClassControl , kEventControlHiliteChanged } ,
+ { kEventClassControl , kEventControlSetFocusPart } ,
+
+ { kEventClassService , kEventServiceGetTypes },
+ { kEventClassService , kEventServiceCopy },
+ { kEventClassService , kEventServicePaste },
+
+ // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
+// { kEventClassControl , kEventControlBoundsChanged } ,
+#endif
+} ;
+
+static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ OSStatus result = eventNotHandledErr ;
+
+ wxMacCarbonEvent cEvent( event ) ;
+
+ ControlRef controlRef ;
+ wxWindowMac* thisWindow = (wxWindowMac*) data ;
+
+ cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
+
+ switch( GetEventKind( event ) )
+ {
+#if TARGET_API_MAC_OSX
+ case kEventControlDraw :
+ {
+ RgnHandle updateRgn = NULL ;
+ RgnHandle allocatedRgn = NULL ;
+ wxRegion visRegion = thisWindow->MacGetVisibleRegion() ;
+ if ( cEvent.GetParameter<RgnHandle>(kEventParamRgnHandle, &updateRgn) != noErr )
+ {
+ updateRgn = (RgnHandle) visRegion.GetWXHRGN() ;
+ }
+ else
+ {
+ if ( thisWindow->MacGetLeftBorderSize() != 0 || thisWindow->MacGetTopBorderSize() != 0 )
+ {
+ allocatedRgn = NewRgn() ;
+ CopyRgn( updateRgn , allocatedRgn ) ;
+ // hide the given region by the new region that must be shifted
+ wxMacNativeToWindow( thisWindow , allocatedRgn ) ;
+ updateRgn = allocatedRgn ;
+ }
+ }
+
+#if 0
+ // in case we would need a coregraphics compliant background erase first
+ // now usable to track redraws
+ CGContextRef cgContext = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef) ;
+ if ( thisWindow->MacIsUserPane() )
+ {
+ static float color = 0.5 ;
+ static channel = 0 ;
+ HIRect bounds;
+ HIViewGetBounds( controlRef, &bounds );
+ CGContextSetRGBFillColor( cgContext, channel == 0 ? color : 0.5 ,
+ channel == 1 ? color : 0.5 , channel == 2 ? color : 0.5 , 1 );
+ CGContextFillRect( cgContext, bounds );
+ color += 0.1 ;
+ if ( color > 0.9 )
+ {
+ color = 0.5 ;
+ channel++ ;
+ if ( channel == 3 )
+ channel = 0 ;
+ }
+ }
+#endif
+ if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) )
+ result = noErr ;
+ if ( allocatedRgn )
+ DisposeRgn( allocatedRgn ) ;
+ }
+ break ;
+ case kEventControlVisibilityChanged :
+ thisWindow->MacVisibilityChanged() ;
+ break ;
+ case kEventControlEnabledStateChanged :
+ thisWindow->MacEnabledStateChanged() ;
+ break ;
+ case kEventControlHiliteChanged :
+ thisWindow->MacHiliteChanged() ;
+ break ;
+ case kEventControlSetFocusPart :
+ {
+ Boolean focusEverything = false ;
+ ControlPartCode controlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
+ if ( cEvent.GetParameter<Boolean>(kEventParamControlFocusEverything , &focusEverything ) == noErr )
+ {
+ }
+ if ( controlPart == kControlFocusNoPart )
+ {
+ #if wxUSE_CARET
+ if ( thisWindow->GetCaret() )
+ {
+ thisWindow->GetCaret()->OnKillFocus();
+ }
+ #endif // wxUSE_CARET
+ wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
+ event.SetEventObject(thisWindow);
+ thisWindow->GetEventHandler()->ProcessEvent(event) ;
+ }
+ else
+ {
+ // panel wants to track the window which was the last to have focus in it
+ wxChildFocusEvent eventFocus(thisWindow);
+ thisWindow->GetEventHandler()->ProcessEvent(eventFocus);
+
+ #if wxUSE_CARET
+ if ( thisWindow->GetCaret() )
+ {
+ thisWindow->GetCaret()->OnSetFocus();
+ }
+ #endif // wxUSE_CARET
+
+ wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
+ event.SetEventObject(thisWindow);
+ thisWindow->GetEventHandler()->ProcessEvent(event) ;
+ }
+ if ( thisWindow->MacIsUserPane() )
+ result = noErr ;
+ }
+ break ;
+#endif
+ case kEventControlHit :
+ {
+ result = thisWindow->MacControlHit( handler , event ) ;
+ }
+ break ;
+ default :
+ break ;
+ }
+ return result ;
+}
+
+static pascal OSStatus wxMacWindowServiceEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ OSStatus result = eventNotHandledErr ;
+
+ wxMacCarbonEvent cEvent( event ) ;
+
+ ControlRef controlRef ;
+ wxWindowMac* thisWindow = (wxWindowMac*) data ;
+ wxTextCtrl* textCtrl = wxDynamicCast( thisWindow , wxTextCtrl ) ;
+ cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
+
+ switch( GetEventKind( event ) )
+ {
+ case kEventServiceGetTypes :
+ if( textCtrl )
+ {
+ long from, to ;
+ textCtrl->GetSelection( &from , &to ) ;
+
+ CFMutableArrayRef copyTypes = 0 , pasteTypes = 0;
+ if( from != to )
+ copyTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServiceCopyTypes , typeCFMutableArrayRef ) ;
+ if ( textCtrl->IsEditable() )
+ pasteTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServicePasteTypes , typeCFMutableArrayRef ) ;
+
+ static const OSType textDataTypes[] = { kTXNTextData /* , 'utxt' , 'PICT', 'MooV', 'AIFF' */ };
+ for ( size_t i = 0 ; i < WXSIZEOF(textDataTypes) ; ++i )
+ {
+ CFStringRef typestring = CreateTypeStringWithOSType(textDataTypes[i]);
+ if ( typestring )
+ {
+ if ( copyTypes )
+ CFArrayAppendValue (copyTypes, typestring) ;
+ if ( pasteTypes )
+ CFArrayAppendValue (pasteTypes, typestring) ;
+ CFRelease( typestring ) ;
+ }
+ }
+ result = noErr ;
+ }
+ break ;
+ case kEventServiceCopy :
+ if ( textCtrl )
+ {
+ long from, to ;
+ textCtrl->GetSelection( &from , &to ) ;
+ wxString val = textCtrl->GetValue() ;
+ val = val.Mid( from , to - from ) ;
+ ScrapRef scrapRef = cEvent.GetParameter< ScrapRef > ( kEventParamScrapRef , typeScrapRef ) ;
+ verify_noerr( ClearScrap( &scrapRef ) ) ;
+ verify_noerr( PutScrapFlavor( scrapRef , kTXNTextData , 0 , val.Length() , val.c_str() ) ) ;
+ result = noErr ;
+ }
+ break ;
+ case kEventServicePaste :
+ if ( textCtrl )
+ {
+ ScrapRef scrapRef = cEvent.GetParameter< ScrapRef > ( kEventParamScrapRef , typeScrapRef ) ;
+ Size textSize, pastedSize ;
+ verify_noerr( GetScrapFlavorSize (scrapRef, kTXNTextData, &textSize) ) ;
+ textSize++ ;
+ char *content = new char[textSize] ;
+ GetScrapFlavorData (scrapRef, kTXNTextData, &pastedSize, content );
+ content[textSize-1] = 0 ;
+#if wxUSE_UNICODE
+ textCtrl->WriteText( wxString( content , wxConvLocal ) );
+#else
+ textCtrl->WriteText( wxString( content ) ) ;
+#endif
+ delete[] content ;
+ result = noErr ;
+ }
+ break ;
+ }
+
+ return result ;
+}