+ static bool inKillFocusEvent = false ;
+
+ if ( !inKillFocusEvent )
+ {
+ inKillFocusEvent = true ;
+ wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
+ event.SetEventObject(thisWindow);
+ thisWindow->GetEventHandler()->ProcessEvent(event) ;
+ inKillFocusEvent = false ;
+ }
+ }
+ 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
+
+ wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
+ event.SetEventObject(thisWindow);
+ thisWindow->GetEventHandler()->ProcessEvent(event) ;
+ }
+
+ if ( thisWindow->MacIsUserPane() )
+ result = noErr ;
+ }
+ break ;
+
+ 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 ;
+
+ default:
+ break ;
+ }
+
+ return result ;
+}
+
+pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ OSStatus result = eventNotHandledErr ;
+ wxWindowMac* focus = (wxWindowMac*) data ;
+
+ wchar_t* uniChars = NULL ;
+ UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
+
+ UniChar* charBuf = NULL;
+ UInt32 dataSize = 0 ;
+ int numChars = 0 ;
+ UniChar buf[2] ;
+ if ( GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, 0 , &dataSize, NULL ) == noErr )
+ {
+ numChars = dataSize / sizeof( UniChar) + 1;
+ charBuf = buf ;
+
+ if ( (size_t) numChars * 2 > sizeof(buf) )
+ charBuf = new UniChar[ numChars ] ;
+ else
+ charBuf = buf ;
+
+ uniChars = new wchar_t[ numChars ] ;
+ GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, dataSize , NULL , charBuf ) ;
+ charBuf[ numChars - 1 ] = 0;
+#if SIZEOF_WCHAR_T == 2
+ uniChars = (wchar_t*) charBuf ;
+ memcpy( uniChars , charBuf , numChars * 2 ) ;
+#else
+ // the resulting string will never have more chars than the utf16 version, so this is safe
+ wxMBConvUTF16 converter ;
+ numChars = converter.MB2WC( uniChars , (const char*)charBuf , numChars ) ;
+#endif
+ }
+
+ switch ( GetEventKind( event ) )
+ {
+ case kEventTextInputUpdateActiveInputArea :
+ {
+ // An IME input event may return several characters, but we need to send one char at a time to
+ // EVT_CHAR
+ for (int pos=0 ; pos < numChars ; pos++)
+ {
+ WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;
+ WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
+ wxTheApp->MacSetCurrentEvent( event , handler ) ;
+
+ UInt32 message = (0 << 8) + ((char)uniChars[pos] );
+ if ( wxTheApp->MacSendCharEvent(
+ focus , message , 0 , when , 0 , 0 , uniChars[pos] ) )
+ {
+ result = noErr ;
+ }
+
+ wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;
+ }
+ }
+ break ;
+ case kEventTextInputUnicodeForKeyEvent :
+ {
+ UInt32 keyCode, modifiers ;
+ Point point ;
+ EventRef rawEvent ;
+ unsigned char charCode ;
+
+ GetEventParameter( event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent ) ;
+ GetEventParameter( rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode );
+ GetEventParameter( rawEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
+ GetEventParameter( rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers );
+ GetEventParameter( rawEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &point );
+
+ UInt32 message = (keyCode << 8) + charCode;
+
+ // An IME input event may return several characters, but we need to send one char at a time to
+ // EVT_CHAR
+ for (int pos=0 ; pos < numChars ; pos++)
+ {
+ WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;
+ WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
+ wxTheApp->MacSetCurrentEvent( event , handler ) ;
+
+ if ( wxTheApp->MacSendCharEvent(
+ focus , message , modifiers , when , point.h , point.v , uniChars[pos] ) )
+ {
+ result = noErr ;
+ }
+
+ wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;
+ }
+ }
+ break;
+ default:
+ break ;
+ }
+
+ delete [] uniChars ;
+ if ( charBuf != buf )
+ delete [] charBuf ;
+
+ return result ;
+}
+
+static pascal OSStatus wxMacWindowCommandEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ OSStatus result = eventNotHandledErr ;
+ wxWindowMac* focus = (wxWindowMac*) data ;
+
+ HICommand command ;
+
+ wxMacCarbonEvent cEvent( event ) ;
+ cEvent.GetParameter<HICommand>(kEventParamDirectObject,typeHICommand,&command) ;
+
+ wxMenuItem* item = NULL ;
+ wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ;
+ int id = wxMacCommandToId( command.commandID ) ;
+
+ if ( item )
+ {
+ wxASSERT( itemMenu != NULL ) ;
+
+ switch ( cEvent.GetKind() )
+ {
+ case kEventProcessCommand :
+ {
+ if (item->IsCheckable())
+ item->Check( !item->IsChecked() ) ;
+
+ if ( itemMenu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) )
+ result = noErr ;
+ else
+ {
+ wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED , id);
+ event.SetEventObject(focus);
+ event.SetInt(item->IsCheckable() ? item->IsChecked() : -1);
+
+ if ( focus->GetEventHandler()->ProcessEvent(event) )
+ result = noErr ;
+ }
+ }
+ break ;
+
+ case kEventCommandUpdateStatus:
+ {
+ wxUpdateUIEvent event(id);
+ event.SetEventObject( itemMenu );
+
+ bool processed = false;
+
+ // Try the menu's event handler
+ {
+ wxEvtHandler *handler = itemMenu->GetEventHandler();
+ if ( handler )
+ processed = handler->ProcessEvent(event);
+ }
+
+ // Try the window the menu was popped up from
+ // (and up through the hierarchy)
+ if ( !processed )
+ {
+ const wxMenuBase *menu = itemMenu;
+ while ( menu )
+ {
+ wxWindow *win = menu->GetInvokingWindow();
+ if ( win )
+ {
+ processed = win->GetEventHandler()->ProcessEvent(event);
+ break;
+ }
+
+ menu = menu->GetParent();
+ }
+ }
+
+ if ( !processed )
+ {
+ processed = focus->GetEventHandler()->ProcessEvent(event);
+ }
+
+ if ( processed )
+ {
+ // if anything changed, update the changed attribute
+ if (event.GetSetText())
+ itemMenu->SetLabel(id, event.GetText());
+ if (event.GetSetChecked())
+ itemMenu->Check(id, event.GetChecked());
+ if (event.GetSetEnabled())
+ itemMenu->Enable(id, event.GetEnabled());
+
+ result = noErr ;
+ }
+ }
+ break ;
+
+ default :
+ break ;
+ }
+ }
+ return result ;
+}
+
+pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ EventRef formerEvent = (EventRef) wxTheApp->MacGetCurrentEvent() ;
+ EventHandlerCallRef formerEventHandlerCallRef = (EventHandlerCallRef) wxTheApp->MacGetCurrentEventHandlerCallRef() ;
+ wxTheApp->MacSetCurrentEvent( event , handler ) ;
+ OSStatus result = eventNotHandledErr ;
+
+ switch ( GetEventClass( event ) )
+ {
+ case kEventClassCommand :
+ result = wxMacWindowCommandEventHandler( handler , event , data ) ;
+ break ;
+
+ case kEventClassControl :
+ result = wxMacWindowControlEventHandler( handler, event, data ) ;
+ break ;
+
+ case kEventClassService :
+ result = wxMacWindowServiceEventHandler( handler, event , data ) ;
+ break ;
+
+ case kEventClassTextInput :
+ result = wxMacUnicodeTextEventHandler( handler , event , data ) ;
+ break ;
+
+ default :
+ break ;
+ }
+
+ wxTheApp->MacSetCurrentEvent( formerEvent, formerEventHandlerCallRef ) ;
+
+ return result ;
+}
+
+DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler )
+
+#if !TARGET_API_MAC_OSX
+
+// ---------------------------------------------------------------------------
+// UserPane events for non OSX builds
+// ---------------------------------------------------------------------------
+
+static pascal void wxMacControlUserPaneDrawProc(ControlRef control, SInt16 part)
+{
+ wxWindow * win = wxFindControlFromMacControl(control) ;
+ if ( win )
+ win->MacControlUserPaneDrawProc(part) ;
+}
+wxMAC_DEFINE_PROC_GETTER( ControlUserPaneDrawUPP , wxMacControlUserPaneDrawProc ) ;
+
+static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control, Point where)
+{
+ wxWindow * win = wxFindControlFromMacControl(control) ;
+ if ( win )
+ return win->MacControlUserPaneHitTestProc(where.h , where.v) ;
+ else
+ return kControlNoPart ;
+}
+wxMAC_DEFINE_PROC_GETTER( ControlUserPaneHitTestUPP , wxMacControlUserPaneHitTestProc ) ;
+
+static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef control, Point startPt, ControlActionUPP actionProc)
+{
+ wxWindow * win = wxFindControlFromMacControl(control) ;
+ if ( win )
+ return win->MacControlUserPaneTrackingProc( startPt.h , startPt.v , (void*) actionProc) ;
+ else
+ return kControlNoPart ;
+}
+wxMAC_DEFINE_PROC_GETTER( ControlUserPaneTrackingUPP , wxMacControlUserPaneTrackingProc ) ;
+
+static pascal void wxMacControlUserPaneIdleProc(ControlRef control)
+{
+ wxWindow * win = wxFindControlFromMacControl(control) ;
+ if ( win )
+ win->MacControlUserPaneIdleProc() ;
+}
+wxMAC_DEFINE_PROC_GETTER( ControlUserPaneIdleUPP , wxMacControlUserPaneIdleProc ) ;
+
+static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers)
+{
+ wxWindow * win = wxFindControlFromMacControl(control) ;
+ if ( win )
+ return win->MacControlUserPaneKeyDownProc(keyCode,charCode,modifiers) ;
+ else
+ return kControlNoPart ;
+}
+wxMAC_DEFINE_PROC_GETTER( ControlUserPaneKeyDownUPP , wxMacControlUserPaneKeyDownProc ) ;
+
+static pascal void wxMacControlUserPaneActivateProc(ControlRef control, Boolean activating)
+{
+ wxWindow * win = wxFindControlFromMacControl(control) ;
+ if ( win )
+ win->MacControlUserPaneActivateProc(activating) ;
+}
+wxMAC_DEFINE_PROC_GETTER( ControlUserPaneActivateUPP , wxMacControlUserPaneActivateProc ) ;
+
+static pascal ControlPartCode wxMacControlUserPaneFocusProc(ControlRef control, ControlFocusPart action)
+{
+ wxWindow * win = wxFindControlFromMacControl(control) ;
+ if ( win )
+ return win->MacControlUserPaneFocusProc(action) ;
+ else
+ return kControlNoPart ;
+}
+wxMAC_DEFINE_PROC_GETTER( ControlUserPaneFocusUPP , wxMacControlUserPaneFocusProc ) ;
+
+static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control, ControlBackgroundPtr info)
+{
+ wxWindow * win = wxFindControlFromMacControl(control) ;
+ if ( win )
+ win->MacControlUserPaneBackgroundProc(info) ;
+}
+wxMAC_DEFINE_PROC_GETTER( ControlUserPaneBackgroundUPP , wxMacControlUserPaneBackgroundProc ) ;
+
+void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part)
+{
+ int x = 0 , y = 0;
+ RgnHandle rgn = NewRgn() ;
+ GetClip( rgn ) ;
+ MacWindowToRootWindow( &x, &y ) ;
+ OffsetRgn( rgn , -x , -y ) ;
+ wxMacWindowStateSaver sv( this ) ;
+ SectRgn( rgn , (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , rgn ) ;
+ MacDoRedraw( rgn , 0 ) ;
+ DisposeRgn( rgn ) ;
+}
+
+wxInt16 wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
+{
+ return kControlNoPart ;
+}
+
+wxInt16 wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc)
+{
+ return kControlNoPart ;
+}
+
+void wxWindowMac::MacControlUserPaneIdleProc()
+{
+}
+
+wxInt16 wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
+{
+ return kControlNoPart ;
+}
+
+void wxWindowMac::MacControlUserPaneActivateProc(bool activating)
+{
+}
+
+wxInt16 wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action)
+{
+ if ( AcceptsFocus() )
+ return 1 ;
+ else
+ return kControlNoPart ;
+}
+
+void wxWindowMac::MacControlUserPaneBackgroundProc(void* info)
+{
+}
+
+#endif
+
+// ---------------------------------------------------------------------------
+// Scrollbar Tracking for all
+// ---------------------------------------------------------------------------
+
+pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode ) ;
+pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode )
+{
+ if ( partCode != 0)
+ {
+ wxWindow* wx = wxFindControlFromMacControl( control ) ;
+ if ( wx )
+ wx->MacHandleControlClick( (WXWidget) control , partCode , true /* stillDown */ ) ;
+ }
+}
+wxMAC_DEFINE_PROC_GETTER( ControlActionUPP , wxMacLiveScrollbarActionProc ) ;