/////////////////////////////////////////////////////////////////////////////
-// Name: src/mac/carbon/app.cpp
+// Name: src/osx/carbon/app.cpp
// Purpose: wxApp
// Author: Stefan Csomor
// Modified by:
#include "wx/filename.h"
#include "wx/link.h"
#include "wx/thread.h"
+#include "wx/evtloop.h"
#include <string.h>
// mac
-
+#if wxOSX_USE_CARBON
#include "wx/osx/uma.h"
+#else
+#include "wx/osx/private.h"
+#endif
-#ifdef __DARWIN__
-# include <CoreServices/CoreServices.h>
-# if defined(WXMAKINGDLL_CORE)
-# include <mach-o/dyld.h>
-# endif
+#if defined(WXMAKINGDLL_CORE)
+# include <mach-o/dyld.h>
#endif
// Keep linker from discarding wxStockGDIMac
wxFORCE_LINK_MODULE(gdiobj)
-// statics for implementation
-static bool s_inYield = false;
-static bool s_inReceiveEvent = false ;
-static EventTime sleepTime = kEventDurationNoWait ;
-
-
IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
EVT_IDLE(wxApp::OnIdle)
bool wxApp::sm_isEmbedded = false; // Normally we're not a plugin
+#if wxOSX_USE_COCOA_OR_CARBON
+
//----------------------------------------------------------------------
// Core Apple Event Support
//----------------------------------------------------------------------
+AEEventHandlerUPP sODocHandler = NULL ;
+AEEventHandlerUPP sGURLHandler = NULL ;
+AEEventHandlerUPP sOAppHandler = NULL ;
+AEEventHandlerUPP sPDocHandler = NULL ;
+AEEventHandlerUPP sRAppHandler = NULL ;
+AEEventHandlerUPP sQuitHandler = NULL ;
+
pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ;
pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ;
pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ;
pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ;
pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ;
+pascal OSErr AEHandleGURL( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ;
pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , SRefCon WXUNUSED(refcon) )
{
return noErr ;
}
+#endif
+
//----------------------------------------------------------------------
// Support Routines linking the Mac...File Calls to the Document Manager
//----------------------------------------------------------------------
// if no native match they just return the passed-in id
+#if wxOSX_USE_CARBON
+
struct IdPair
{
UInt32 macId ;
}
else
{
- URefCon refCon ;
+ URefCon refCon = NULL ;
GetMenuItemRefCon( command.menu.menuRef , command.menu.menuItemIndex , &refCon ) ;
itemMenu = wxFindMenuFromMacMenu( command.menu.menuRef ) ;
- if ( itemMenu != NULL )
- item = (wxMenuItem*) refCon ;
+ if ( itemMenu != NULL && refCon != 0)
+ item = ((wxMenuItemImpl*) refCon)->GetWXPeer() ;
}
}
#endif
return itemMenu ;
}
+#endif
+
//----------------------------------------------------------------------
// Carbon Event Handler
//----------------------------------------------------------------------
+#if wxOSX_USE_CARBON
+
static const EventTypeSpec eventList[] =
{
{ kEventClassCommand, kEventProcessCommand } ,
if ( menu )
{
- wxEventType type=0;
- MenuCommand cmd=0;
switch (GetEventKind(event))
{
case kEventMenuOpening:
- type = wxEVT_MENU_OPEN;
+ menu->HandleMenuOpened();
break;
case kEventMenuClosed:
- type = wxEVT_MENU_CLOSE;
+ menu->HandleMenuClosed();
break;
case kEventMenuTargetItem:
- cmd = cEvent.GetParameter<MenuCommand>(kEventParamMenuCommand,typeMenuCommand) ;
- if (cmd != 0)
- type = wxEVT_MENU_HIGHLIGHT;
+ {
+ HICommand command ;
+
+ command.menu.menuRef = menuRef;
+ command.menu.menuItemIndex = cEvent.GetParameter<MenuItemIndex>(kEventParamMenuItemIndex,typeMenuItemIndex) ;
+ command.commandID = cEvent.GetParameter<MenuCommand>(kEventParamMenuCommand,typeMenuCommand) ;
+ if (command.commandID != 0)
+ {
+ wxMenuItem* item = NULL ;
+ wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ;
+ if ( itemMenu && item )
+ itemMenu->HandleMenuItemHighlighted( item );
+ }
+ }
break;
default:
break;
}
- if ( type )
- {
- wxMenuEvent wxevent(type, cmd, menu);
- wxevent.SetEventObject(menu);
-
- wxEvtHandler* handler = menu->GetEventHandler();
- if (handler && handler->ProcessEvent(wxevent))
- {
- // handled
- }
- else
- {
- wxWindow *win = menu->GetInvokingWindow();
- if (win)
- win->HandleWindowEvent(wxevent);
- }
- }
}
#endif
return eventNotHandledErr;
}
-#ifndef __LP64__
static pascal OSStatus
wxMacAppCommandEventHandler( EventHandlerCallRef WXUNUSED(handler) ,
EventRef event ,
wxMenuItem* item = NULL ;
wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ;
- int id = wxMacCommandToId( command.commandID ) ;
if ( item )
{
switch ( cEvent.GetKind() )
{
case kEventProcessCommand :
- result = itemMenu->MacHandleCommandProcess( item, id );
+ if ( itemMenu->HandleCommandProcess( item ) )
+ result = noErr;
break ;
case kEventCommandUpdateStatus:
- result = itemMenu->MacHandleCommandUpdateStatus( item, id );
+ if ( itemMenu->HandleCommandUpdateStatus( item ) )
+ result = noErr;
break ;
default :
}
return result ;
}
-#endif
static pascal OSStatus
wxMacAppApplicationEventHandler( EventHandlerCallRef WXUNUSED(handler) ,
}
DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacAppEventHandler )
+#endif
-#ifdef __WXDEBUG__
+#if defined( __WXDEBUG__ ) && wxOSX_USE_COCOA_OR_CARBON
pascal static void
wxMacAssertOutputHandler(OSType WXUNUSED(componentSignature),
{
// Mac-specific
-#ifdef __WXDEBUG__
+#if defined( __WXDEBUG__ ) && wxOSX_USE_COCOA_OR_CARBON
InstallDebugAssertOutputHandler( NewDebugAssertOutputHandlerUPP( wxMacAssertOutputHandler ) );
#endif
- UMAInitToolbox( 4, sm_isEmbedded ) ;
-// TODO CHECK Can Be Removed SetEventMask( everyEvent ) ;
-
// Mac OS X passes a process serial number command line argument when
// the application is launched from the Finder. This argument must be
// removed from the command line arguments before being handled by the
/* connect posted events to common-mode run loop so that wxPostEvent events
are handled even while we're in the menu or on a scrollbar */
+ /*
CFRunLoopSourceContext event_posted_context = {0};
event_posted_context.perform = macPostedEventCallback;
m_macEventPosted = CFRunLoopSourceCreate(NULL,0,&event_posted_context);
CFRunLoopAddSource(CFRunLoopGetCurrent(), m_macEventPosted, kCFRunLoopCommonModes);
// run loop takes ownership
CFRelease(m_macEventPosted);
-
+ */
return true;
}
-AEEventHandlerUPP sODocHandler = NULL ;
-AEEventHandlerUPP sGURLHandler = NULL ;
-AEEventHandlerUPP sOAppHandler = NULL ;
-AEEventHandlerUPP sPDocHandler = NULL ;
-AEEventHandlerUPP sRAppHandler = NULL ;
-AEEventHandlerUPP sQuitHandler = NULL ;
+bool wxApp::CallOnInit()
+{
+ wxMacAutoreleasePool autoreleasepool;
+ return OnInit();
+}
bool wxApp::OnInitGui()
{
if ( !wxAppBase::OnInitGui() )
return false ;
-#ifndef __LP64__
+
+ if ( !DoInitGui() )
+ return false;
+
+ return true ;
+}
+
+bool wxApp::ProcessIdle()
+{
+ wxMacAutoreleasePool autoreleasepool;
+ return wxAppBase::ProcessIdle();
+}
+
+#if wxOSX_USE_CARBON
+bool wxApp::DoInitGui()
+{
InstallStandardEventHandler( GetApplicationEventTarget() ) ;
if (!sm_isEmbedded)
{
GetwxMacAppEventHandlerUPP(),
GetEventTypeCount(eventList), eventList, wxTheApp, (EventHandlerRef *)&(wxTheApp->m_macEventHandler));
}
-#endif
if (!sm_isEmbedded)
{
if ( !wxMacInitCocoa() )
return false;
-
- return true ;
+
+ return true;
}
-void wxApp::CleanUp()
+void wxApp::DoCleanUp()
{
-#if wxUSE_TOOLTIPS
- wxToolTip::RemoveToolTips() ;
-#endif
-
- if (m_macEventPosted)
- {
- CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m_macEventPosted, kCFRunLoopCommonModes);
- m_macEventPosted = NULL;
- }
-
- // One last chance for pending objects to be cleaned up
- wxTheApp->DeletePendingObjects();
-
if (!sm_isEmbedded)
RemoveEventHandler( (EventHandlerRef)(wxTheApp->m_macEventHandler) );
DisposeAEEventHandlerUPP( sRAppHandler ) ;
DisposeAEEventHandlerUPP( sQuitHandler ) ;
}
+}
+
+#endif
+
+void wxApp::CleanUp()
+{
+#if wxUSE_TOOLTIPS
+ wxToolTip::RemoveToolTips() ;
+#endif
+
+ if (m_macEventPosted)
+ {
+ CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m_macEventPosted, kCFRunLoopCommonModes);
+ m_macEventPosted = NULL;
+ }
+
+ DoCleanUp();
wxAppBase::CleanUp();
}
// misc initialization stuff
//----------------------------------------------------------------------
-#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
+#if wxOSX_USE_CARBON && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec)
{
OSStatus err = noErr ;
m_macEventPosted = NULL ;
}
+CFMutableArrayRef GetAutoReleaseArray()
+{
+ static CFMutableArrayRef array = 0;
+ if ( array == 0)
+ array= CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks);
+ return array;
+}
+
+void wxApp::MacAddToAutorelease( void* cfrefobj )
+{
+ CFArrayAppendValue( GetAutoReleaseArray(), cfrefobj );
+}
+
void wxApp::OnIdle(wxIdleEvent& WXUNUSED(event))
{
// If they are pending events, we must process them: pending events are
// either events to the threads other than main or events posted with
// wxPostEvent() functions
#ifndef __WXUNIVERSAL__
+#if wxUSE_MENUS
if (!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar())
wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar();
#endif
+#endif
+ CFArrayRemoveAllValues( GetAutoReleaseArray() );
}
void wxApp::WakeUpIdle()
bool wxApp::Yield(bool onlyIfNeeded)
{
- if (s_inYield)
- {
- if ( !onlyIfNeeded )
- {
- wxFAIL_MSG( wxT("wxYield called recursively" ) );
- }
-
- return false;
- }
-
#if wxUSE_THREADS
// Yielding from a non-gui thread needs to bail out, otherwise we end up
// possibly sending events in the thread too.
}
#endif // wxUSE_THREADS
- s_inYield = true;
-
- // by definition yield should handle all non-processed events
-
- EventRef theEvent;
+ static bool s_inYield = false;
- OSStatus status = noErr ;
-
- while ( status == noErr )
+ if (s_inYield)
{
- s_inReceiveEvent = true ;
- status = ReceiveNextEvent(0, NULL,kEventDurationNoWait,true,&theEvent) ;
- s_inReceiveEvent = false ;
-
- if ( status == eventLoopTimedOutErr )
- {
- // make sure next time the event loop will trigger idle events
- sleepTime = kEventDurationNoWait ;
- }
- else if ( status == eventLoopQuitErr )
- {
- // according to QA1061 this may also occur when a WakeUp Process
- // is executed
- }
- else
+ if ( !onlyIfNeeded )
{
- MacHandleOneEvent( theEvent ) ;
- ReleaseEvent(theEvent);
+ wxFAIL_MSG( wxT("wxYield called recursively" ) );
}
- }
- s_inYield = false;
-
- return true;
-}
+ return false;
+ }
-void wxApp::MacDoOneEvent()
-{
- wxMacAutoreleasePool autoreleasepool;
- EventRef theEvent;
+ s_inYield = true;
- s_inReceiveEvent = true ;
- OSStatus status = ReceiveNextEvent(0, NULL, sleepTime, true, &theEvent) ;
- s_inReceiveEvent = false ;
+#if wxUSE_LOG
+ // disable log flushing from here because a call to wxYield() shouldn't
+ // normally result in message boxes popping up &c
+ wxLog::Suspend();
+#endif // wxUSE_LOG
- switch (status)
+ wxEventLoop * const
+ loop = wx_static_cast(wxEventLoop *, wxEventLoop::GetActive());
+ if ( loop )
{
- case eventLoopTimedOutErr :
- if ( wxTheApp->ProcessIdle() )
- sleepTime = kEventDurationNoWait ;
- else
- sleepTime = kEventDurationSecond;
- break;
-
- case eventLoopQuitErr :
- // according to QA1061 this may also occur
- // when a WakeUp Process is executed
- break;
-
- default:
- MacHandleOneEvent( theEvent ) ;
- ReleaseEvent( theEvent );
- sleepTime = kEventDurationNoWait ;
- break;
+ // process all pending events:
+ while ( loop->Pending() )
+ loop->Dispatch();
}
- // repeaters
+
+ // it's necessary to call ProcessIdle() to update the frames sizes which
+ // might have been changed (it also will update other things set from
+ // OnUpdateUI() which is a nice (and desired) side effect)
+ while ( ProcessIdle() ) {}
+
+#if wxUSE_LOG
+ wxLog::Resume();
+#endif // wxUSE_LOG
+ s_inYield = false;
- DeletePendingObjects() ;
+ return true;
}
// virtual
// Override to process unhandled events as you please
}
-CFMutableArrayRef GetAutoReleaseArray()
-{
- static CFMutableArrayRef array = 0;
- if ( array == 0)
- array= CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks);
- return array;
-}
-
-void wxApp::MacHandleOneEvent( WXEVENTREF evr )
-{
- EventTargetRef theTarget;
- theTarget = GetEventDispatcherTarget();
- m_macCurrentEvent = evr ;
-
- OSStatus status = SendEventToEventTarget((EventRef) evr , theTarget);
- if (status == eventNotHandledErr)
- MacHandleUnhandledEvent(evr);
-
-#if wxUSE_THREADS
- wxMutexGuiLeaveOrEnter();
-#endif // wxUSE_THREADS
-
- CFArrayRemoveAllValues( GetAutoReleaseArray() );
-}
-
-void wxApp::MacAddToAutorelease( void* cfrefobj )
-{
- CFArrayAppendValue( GetAutoReleaseArray(), cfrefobj );
-}
+#if wxOSX_USE_CARBON
long wxMacTranslateKey(unsigned char key, unsigned char code)
{
return 0;
}
}
+#endif
wxMouseState wxGetMouseState()
{
ms.SetX(pt.x);
ms.SetY(pt.y);
+#if wxOSX_USE_CARBON
UInt32 buttons = GetCurrentButtonState();
ms.SetLeftDown( (buttons & 0x01) != 0 );
ms.SetMiddleDown( (buttons & 0x04) != 0 );
ms.SetShiftDown(modifiers & shiftKey);
ms.SetAltDown(modifiers & optionKey);
ms.SetMetaDown(modifiers & cmdKey);
-
+#else
+ // TODO
+#endif
return ms;
}
{
if ( !focus )
return false ;
-
wxKeyEvent event(wxEVT_CHAR) ;
MacCreateKeyEvent( event, focus , keymessage , modifiers , when , wherex , wherey , uniChar ) ;
long keyval = event.m_keyCode ;
bool handled = false ;
+#if wxOSX_USE_CARBON
wxNonOwnedWindow *tlw = focus->MacGetTopLevelWindow() ;
if (tlw)
}
// backdoor handler for default return and command escape
- if ( !handled && (!focus->IsKindOf(CLASSINFO(wxControl) ) || !focus->MacCanFocus() ) )
+ if ( !handled && (!focus->IsKindOf(CLASSINFO(wxControl) ) || !focus->AcceptsFocus() ) )
{
// if window is not having a focus still testing for default enter or cancel
// TODO: add the UMA version for ActiveNonFloatingWindow
#ifndef __LP64__
- wxWindow* focus = wxFindWinFromMacWindow( FrontWindow() ) ;
+ wxWindow* focus = wxNonOwnedWindow::GetFromWXWindow( (WXWindow) FrontWindow() ) ;
if ( focus )
{
if ( keyval == WXK_RETURN || keyval == WXK_NUMPAD_ENTER )
}
#endif
}
+#endif
return handled ;
}
// This method handles common code for SendKeyDown, SendKeyUp, and SendChar events.
void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar )
{
+#if wxOSX_USE_CARBON
short keycode, keychar ;
keychar = short(keymessage & charCodeMask);
event.m_y = wherey;
event.SetTimestamp(when);
event.SetEventObject(focus);
+#endif
}
void wxApp::MacHideApp()
{
+#if wxOSX_USE_CARBON
wxMacCarbonEvent event( kEventClassCommand , kEventCommandProcess );
HICommand command;
memset( &command, 0 , sizeof(command) );
command.commandID = kHICommandHide ;
event.SetParameter<HICommand>(kEventParamDirectObject, command );
SendEventToApplication( event );
+#endif
}