#include "wx/textctrl.h"
#include "wx/menu.h"
#include "wx/docview.h"
+#include "wx/filename.h"
#include <string.h>
#ifdef __DARWIN__
# include <CoreServices/CoreServices.h>
-# if defined(WXMAKINGDLL)
+# if defined(WXMAKINGDLL_CORE)
# include <mach-o/dyld.h>
# endif
#else
extern wxList wxPendingDelete;
extern wxList *wxWinMacWindowList;
extern wxList *wxWinMacControlList;
+#if wxUSE_THREADS
+extern size_t g_numberOfThreads;
+#endif // wxUSE_THREADS
// statics for implementation
static bool s_inYield = FALSE;
-static bool s_inOnIdle = FALSE;
#if TARGET_CARBON
static bool s_inReceiveEvent = FALSE ;
static long sleepTime = 0 ;
#endif
-wxApp *wxTheApp = NULL;
-
#if !USE_SHARED_LIBRARY
IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
long wxApp::s_lastModifiers = 0 ;
-bool wxApp::s_macDefaultEncodingIsPC = true ;
bool wxApp::s_macSupportPCMenuShortcuts = true ;
long wxApp::s_macAboutMenuItemId = wxID_ABOUT ;
-long wxApp::s_macPreferencesMenuItemId = 0 ;
+long wxApp::s_macPreferencesMenuItemId = wxID_PREFERENCES ;
long wxApp::s_macExitMenuItemId = wxID_EXIT ;
wxString wxApp::s_macHelpMenuTitleName = wxT("&Help") ;
+// Normally we're not a plugin
+bool wxApp::sm_isEmbedded = false;
//----------------------------------------------------------------------
// Core Apple Event Support
//----------------------------------------------------------------------
pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
+pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
{
return wxTheApp->MacHandleAEQuit( (AppleEvent*) event , reply) ;
}
+pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
+{
+ return wxTheApp->MacHandleAERApp( (AppleEvent*) event , reply) ;
+}
+
// AEODoc Calls MacOpenFile on each of the files passed
short wxApp::MacHandleAEODoc(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply))
short wxApp::MacHandleAEQuit(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
{
- /* wxWindow* win = GetTopWindow() ;
+ wxWindow* win = GetTopWindow() ;
if ( win )
{
win->Close(TRUE ) ;
}
- else
- */
+ else
{
ExitMainLoop() ;
}
return noErr ;
}
+// AEROApp calls MacReopenApp
+
+short wxApp::MacHandleAERApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
+{
+ MacReopenApp() ;
+ return noErr ;
+}
+
+
//----------------------------------------------------------------------
// Support Routines linking the Mac...File Calls to the Document Manager
//----------------------------------------------------------------------
{
}
+void wxApp::MacReopenApp()
+{
+ // eventually check for open docs, if none, call MacNewFile
+}
+
//----------------------------------------------------------------------
// Carbon Event Handler
//----------------------------------------------------------------------
{ kEventClassCommand, kEventProcessCommand } ,
{ kEventClassCommand, kEventCommandUpdateStatus } ,
+ { kEventClassMenu, kEventMenuOpening },
+ { kEventClassMenu, kEventMenuClosed },
+ { kEventClassMenu, kEventMenuTargetItem },
+
{ kEventClassApplication , kEventAppActivated } ,
{ kEventClassApplication , kEventAppDeactivated } ,
// handling the quit event is not recommended by apple
{ kEventClassAppleEvent , kEventAppleEvent } ,
{ kEventClassMouse , kEventMouseDown } ,
+ { kEventClassMouse , kEventMouseMoved } ,
+ { kEventClassMouse , kEventMouseUp } ,
+ { kEventClassMouse , kEventMouseDragged } ,
{ 'WXMC' , 'WXMC' }
} ;
-static pascal OSStatus MenuEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+static pascal OSStatus
+MenuEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
{
- return eventNotHandledErr ;
+ wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar();
+ wxFrame* win = mbar->GetFrame();
+
+ if ( win )
+ {
+ // VZ: we could find the menu from its handle here by examining all
+ // the menus in the menu bar recursively but knowing that neither
+ // wxMSW nor wxGTK do it why bother...
+#if 0
+ MenuRef menuRef;
+
+ GetEventParameter(event,
+ kEventParamDirectObject,
+ typeMenuRef, NULL,
+ sizeof(menuRef), NULL,
+ &menuRef);
+#endif // 0
+
+ wxEventType type=0;
+ MenuCommand cmd=0;
+ switch (GetEventKind(event))
+ {
+ case kEventMenuOpening:
+ type = wxEVT_MENU_OPEN;
+ break;
+ case kEventMenuClosed:
+ type = wxEVT_MENU_CLOSE;
+ break;
+ case kEventMenuTargetItem:
+ type = wxEVT_MENU_HIGHLIGHT;
+ GetEventParameter(event, kEventParamMenuCommand,
+ typeMenuCommand, NULL,
+ sizeof(cmd), NULL, &cmd);
+ if (cmd == 0) return eventNotHandledErr;
+ break;
+ default:
+ wxFAIL_MSG(wxT("Unexpected menu event kind"));
+ break;
+ }
+
+ wxMenuEvent wxevent(type, cmd);
+ wxevent.SetEventObject(win);
+
+ (void)win->GetEventHandler()->ProcessEvent(wxevent);
+ }
+
+ return eventNotHandledErr;
}
// due to the rather low-level event API of wxWindows, we cannot use RunApplicationEventLoop
// but have to use ReceiveNextEvent dealing with events manually, therefore we also have
// deal with clicks in the menu bar explicitely
+pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) ;
+
static pascal OSStatus MouseEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
{
OSStatus result = eventNotHandledErr ;
+ Point point ;
+ UInt32 modifiers = 0;
+ EventMouseButton button = 0 ;
+ UInt32 click = 0 ;
+
+ GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL,
+ sizeof( Point ), NULL, &point );
+ GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL,
+ sizeof( UInt32 ), NULL, &modifiers );
+ GetEventParameter( event, kEventParamMouseButton, typeMouseButton, NULL,
+ sizeof( EventMouseButton ), NULL, &button );
+ GetEventParameter( event, kEventParamClickCount, typeUInt32, NULL,
+ sizeof( UInt32 ), NULL, &click );
+
+ if ( button == 0 || GetEventKind( event ) == kEventMouseUp )
+ modifiers += btnState ;
+
+
switch( GetEventKind(event) )
{
case kEventMouseDown :
{
- Point point ;
WindowRef window ;
- GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL,
- sizeof( Point ), NULL, &point );
short windowPart = ::FindWindow(point, &window);
if ( windowPart == inMenuBar )
}
}
break ;
+ case kEventMouseDragged :
+ case kEventMouseUp :
+ {
+ if ( wxTheApp->s_captureWindow )
+ wxMacWindowEventHandler( handler , event , (void*) wxTheApp->s_captureWindow->MacGetTopLevelWindow() ) ;
+ }
+ break ;
+ case kEventMouseMoved :
+ {
+ wxTheApp->MacHandleMouseMovedEvent( point.h , point.v , modifiers , EventTimeToTicks( GetEventTime( event ) ) ) ;
+ result = noErr ;
+ break ;
+ }
+ break ;
}
return result ;
wxMenuItem* item = NULL ;
if ( mbar )
+ {
item = mbar->FindItem( id , &menu ) ;
+ // it is not 100 % sure that an menu of id 0 is really ours, safety check
+ if ( id == 0 && menu != NULL && menu->GetHMenu() != command.menu.menuRef )
+ {
+ item = NULL ;
+ menu = NULL ;
+ }
+ }
if ( item == NULL || menu == NULL || mbar == NULL )
return result ;
break ;
case kEventCommandUpdateStatus:
// eventually trigger an updateui round
- result = noErr ;
+ result = noErr ;
break ;
default :
break ;
#endif
-#if defined(WXMAKINGDLL) && !defined(__DARWIN__)
+#if defined(WXMAKINGDLL_CORE) && !defined(__DARWIN__)
// we know it's there ;-)
WXIMPORT char std::__throws_bad_alloc ;
#endif
-bool wxApp::Initialize()
+bool wxApp::Initialize(int& argc, wxChar **argv)
{
int error = 0 ;
// Mac-specific
- UMAInitToolbox( 4 ) ;
+ UMAInitToolbox( 4, sm_isEmbedded ) ;
SetEventMask( everyEvent ) ;
UMAShowWatchCursor() ;
-#if defined(WXMAKINGDLL) && defined(__DARWIN__)
+#if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
// open shared library resources from here since we don't have
// __wxinitialize in Mach-O shared libraries
wxStAppResource::OpenSharedLibraryResource(NULL);
#ifndef __DARWIN__
# if __option(profile)
- ProfilerInit( collectDetailed, bestTimeBase , 20000 , 40 ) ;
+ ProfilerInit( collectDetailed, bestTimeBase , 40000 , 50 ) ;
# endif
#endif
#endif
#endif
- wxMacSetupConverters() ;
s_macCursorRgn = ::NewRgn() ;
- wxClassInfo::InitializeClasses();
+ // 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
+ // application (otherwise applications would need to handle it)
+ if ( argc > 1 )
+ {
+ static const wxChar *ARG_PSN = _T("-psn_");
+ if ( wxStrncmp(argv[1], ARG_PSN, wxStrlen(ARG_PSN)) == 0 )
+ {
+ // remove this argument
+ --argc;
+ memmove(argv + 1, argv + 2, argc * sizeof(char *));
+ }
+ }
-#if wxUSE_RESOURCES
-// wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion);
-#endif
+ if ( !wxAppBase::Initialize(argc, argv) )
+ return false;
-#if wxUSE_THREADS
- wxPendingEventsLocker = new wxCriticalSection;
+#if wxUSE_INTL
+ wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
#endif
- wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
- wxTheColourDatabase->Initialize();
wxWinMacWindowList = new wxList(wxKEY_INTEGER);
wxWinMacControlList = new wxList(wxKEY_INTEGER);
- wxInitializeStockLists();
- wxInitializeStockObjects();
-
- wxBitmap::InitStandardHandlers();
-
- wxModule::RegisterModules();
- if (!wxModule::InitializeModules()) {
- return FALSE;
- }
-
wxMacCreateNotifierTable() ;
UMAShowArrowCursor() ;
- return TRUE;
+ return true;
}
bool wxApp::OnInitGui()
#if TARGET_CARBON
InstallStandardEventHandler( GetApplicationEventTarget() ) ;
- InstallApplicationEventHandler(
- GetwxAppEventHandlerUPP(),
- GetEventTypeCount(eventList), eventList, wxTheApp, &((EventHandlerRef)wxTheApp->m_macEventHandler));
+ if (!sm_isEmbedded)
+ {
+ InstallApplicationEventHandler(
+ GetwxAppEventHandlerUPP(),
+ GetEventTypeCount(eventList), eventList, wxTheApp, (EventHandlerRef *)&(wxTheApp->m_macEventHandler));
+ }
#endif
+ if (!sm_isEmbedded)
+ {
#if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
- AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
- NewAEEventHandlerUPP(AEHandleODoc) ,
- 0 , FALSE ) ;
- AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
- NewAEEventHandlerUPP(AEHandleOApp) ,
- 0 , FALSE ) ;
- AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
- NewAEEventHandlerUPP(AEHandlePDoc) ,
- 0 , FALSE ) ;
- AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
- NewAEEventHandlerUPP(AEHandleQuit) ,
- 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
+ NewAEEventHandlerUPP(AEHandleODoc) ,
+ 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
+ NewAEEventHandlerUPP(AEHandleOApp) ,
+ 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
+ NewAEEventHandlerUPP(AEHandlePDoc) ,
+ 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEReopenApplication ,
+ NewAEEventHandlerUPP(AEHandleRApp) ,
+ 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
+ NewAEEventHandlerUPP(AEHandleQuit) ,
+ 0 , FALSE ) ;
#else
- AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
- NewAEEventHandlerProc(AEHandleODoc) ,
- 0 , FALSE ) ;
- AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
- NewAEEventHandlerProc(AEHandleOApp) ,
- 0 , FALSE ) ;
- AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
- NewAEEventHandlerProc(AEHandlePDoc) ,
- 0 , FALSE ) ;
- AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
- NewAEEventHandlerProc(AEHandleQuit) ,
- 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
+ NewAEEventHandlerProc(AEHandleODoc) ,
+ 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
+ NewAEEventHandlerProc(AEHandleOApp) ,
+ 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
+ NewAEEventHandlerProc(AEHandlePDoc) ,
+ 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEReopenApplication ,
+ NewAEEventHandlerProc(AEHandleRApp) ,
+ 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
+ NewAEEventHandlerProc(AEHandleQuit) ,
+ 0 , FALSE ) ;
#endif
+ }
return TRUE ;
}
void wxApp::CleanUp()
{
wxToolTip::RemoveToolTips() ;
-#if wxUSE_LOG
- // flush the logged messages if any and install a 'safer' log target: the
- // default one (wxLogGui) can't be used after the resources are freed just
- // below and the user suppliedo ne might be even more unsafe (using any
- // wxWindows GUI function is unsafe starting from now)
- wxLog::DontCreateOnDemand();
-
- // this will flush the old messages if any
- delete wxLog::SetActiveTarget(new wxLogStderr);
-#endif // wxUSE_LOG
// One last chance for pending objects to be cleaned up
wxTheApp->DeletePendingObjects();
- wxModule::CleanUpModules();
-
- wxDeleteStockObjects() ;
-
- // Destroy all GDI lists, etc.
- wxDeleteStockLists();
-
- delete wxTheColourDatabase;
- wxTheColourDatabase = NULL;
-
- wxBitmap::CleanUpHandlers();
-
wxMacDestroyNotifierTable() ;
- if (wxWinMacWindowList) {
- delete wxWinMacWindowList ;
- }
- if (wxWinMacControlList) {
- delete wxWinMacControlList ;
- }
- delete wxPendingEvents;
- wxPendingEvents = NULL;
-#if wxUSE_THREADS
- delete wxPendingEventsLocker;
- // There is still more cleanup code that will try to use this if not NULL.
- wxPendingEventsLocker = NULL;
- // If we don't do the following, we get an apparent memory leak.
- ((wxEvtHandler&) wxDefaultValidator).ClearEventLocker();
-#endif
+ delete wxWinMacWindowList ;
+ wxWinMacWindowList = NULL;
- wxClassInfo::CleanUpClasses();
+ delete wxWinMacControlList ;
+ wxWinMacControlList = NULL;
#ifndef __DARWIN__
# if __option(profile)
# endif
#endif
- delete wxTheApp;
- wxTheApp = NULL;
-
-#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
- // At this point we want to check if there are any memory
- // blocks that aren't part of the wxDebugContext itself,
- // as a special case. Then when dumping we need to ignore
- // wxDebugContext, too.
- if (wxDebugContext::CountObjectsLeft(TRUE) > 0)
- {
- wxLogDebug(wxT("There were memory leaks."));
- wxDebugContext::Dump();
- wxDebugContext::PrintStatistics();
- }
- // wxDebugContext::SetStream(NULL, NULL);
-#endif
-
-#if wxUSE_LOG
- // do it as the very last thing because everything else can log messages
- delete wxLog::SetActiveTarget(NULL);
-#endif // wxUSE_LOG
-
-#if defined(WXMAKINGDLL) && defined(__DARWIN__)
+#if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
// close shared library resources from here since we don't have
// __wxterminate in Mach-O shared libraries
wxStAppResource::CloseSharedLibraryResource();
#endif
- wxMacCleanupConverters() ;
UMACleanupToolbox() ;
if (s_macCursorRgn) {
#if 0
TerminateAE() ;
#endif
+
+ wxAppBase::CleanUp();
}
//----------------------------------------------------------------------
-// wxEntry
+// misc initialization stuff
//----------------------------------------------------------------------
// extern variable for shared library resource id
// need to be able to find it with NSLookupAndBindSymbol
short gSharedLibraryResource = kResFileNotOpened ;
-#if defined(WXMAKINGDLL) && defined(__DARWIN__)
+#if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
CFBundleRef gSharedLibraryBundle = NULL;
-#endif /* WXMAKINGDLL && __DARWIN__ */
+#endif /* WXMAKINGDLL_CORE && __DARWIN__ */
wxStAppResource::wxStAppResource()
{
{
gSharedLibraryResource = kResFileNotOpened;
-#ifdef WXMAKINGDLL
+#ifdef WXMAKINGDLL_CORE
if ( initBlock != NULL ) {
const CFragInitBlock *theInitBlock = (const CFragInitBlock *)initBlock;
FSSpec *fileSpec = NULL;
else {
// wxWindows is a simple dynamic shared library
// load the resources from the data fork of a separate resource file
- char *theResPath;
- char *theName;
- char *theExt;
+ wxString theResPath;
+ wxString theName;
FSRef theResRef;
OSErr theErr = noErr;
#endif
// allocate copy to replace .dylib.* extension with .rsrc
- theResPath = strdup(theLibPath);
- if (theResPath != NULL) {
- theName = strrchr(theResPath, '/');
- if (theName == NULL) {
- // no directory elements in path
- theName = theResPath;
- }
- // find ".dylib" shared library extension
- theExt = strstr(theName, ".dylib");
- // overwrite extension with ".rsrc"
- strcpy(theExt, ".rsrc");
+ if (theLibPath != NULL) {
+#if wxUSE_UNICODE
+ theResPath = wxString(theLibPath, wxConvLocal);
+#else
+ theResPath = wxString(theLibPath);
+#endif
+ // replace '_core' with '' in case of multi-lib build
+ theResPath.Replace(wxT("_core"), wxEmptyString);
+ // replace ".dylib" shared library extension with ".rsrc"
+ theResPath.Replace(wxT(".dylib"), wxT(".rsrc"));
+ // Find the begining of the filename
+ theName = theResPath.AfterLast('/');
#if 0
wxLogDebug( wxT("wxMac resources file name is '%s'"),
- theResPath );
+ theResPath.mb_str() );
#endif
- theErr = FSPathMakeRef((UInt8 *) theResPath, &theResRef, false);
+ theErr = FSPathMakeRef((UInt8 *) theResPath.mb_str(), &theResRef, false);
if (theErr != noErr) {
// try in current directory (using name only)
- theErr = FSPathMakeRef((UInt8 *) theName, &theResRef, false);
+ theErr = FSPathMakeRef((UInt8 *) theName.mb_str(), &theResRef, false);
}
// open the resource file
}
if (theErr != noErr) {
#ifdef __WXDEBUG__
- fprintf(stderr,
- wxT("unable to open wxMac resource file '%s'\n"),
- theResPath );
+ wxLogDebug( wxT("unable to open wxMac resource file '%s'\n"),
+ theResPath.mb_str() );
#endif // __WXDEBUG__
}
- // free duplicated resource file path
- free(theResPath);
}
}
#endif /* __DARWIN__ */
}
-#endif /* WXMAKINGDLL */
+#endif /* WXMAKINGDLL_CORE */
}
void wxStAppResource::CloseSharedLibraryResource()
{
-#ifdef WXMAKINGDLL
+#ifdef WXMAKINGDLL_CORE
// Close the shared library resource file
if (gSharedLibraryResource != kResFileNotOpened) {
#ifdef __DARWIN__
}
gSharedLibraryResource = kResFileNotOpened;
}
-#endif /* WXMAKINGDLL */
+#endif /* WXMAKINGDLL_CORE */
}
-#if defined(WXMAKINGDLL) && !defined(__DARWIN__)
+#if defined(WXMAKINGDLL_CORE) && !defined(__DARWIN__)
// for shared libraries we have to manually get the correct resource
// ref num upon initializing and releasing when terminating, therefore
__terminate() ;
}
-#endif /* WXMAKINGDLL && !__DARWIN__ */
-
-int WXDLLEXPORT wxEntryStart( int WXUNUSED(argc), char *WXUNUSED(argv)[] )
-{
- return wxApp::Initialize();
-}
-
-int WXDLLEXPORT wxEntryInitGui()
-{
- return wxTheApp->OnInitGui();
-}
-
-void WXDLLEXPORT wxEntryCleanup()
-{
- wxApp::CleanUp();
-}
-
-int wxEntry( int argc, char *argv[] , bool enterLoop )
-{
-#ifdef __MWERKS__
-#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
- // This seems to be necessary since there are 'rogue'
- // objects present at this point (perhaps global objects?)
- // Setting a checkpoint will ignore them as far as the
- // memory checking facility is concerned.
- // Of course you may argue that memory allocated in globals should be
- // checked, but this is a reasonable compromise.
- wxDebugContext::SetCheckpoint();
-#endif
-#endif
- if (!wxEntryStart(argc, argv)) {
- return 0;
- }
- // create the application object or ensure that one already exists
- if (!wxTheApp)
- {
- // The app may have declared a global application object, but we recommend
- // the IMPLEMENT_APP macro is used instead, which sets an initializer
- // function for delayed, dynamic app object construction.
- wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
- wxT("No initializer - use IMPLEMENT_APP macro.") );
-
- wxTheApp = (wxApp*) (*wxApp::GetInitializerFunction()) ();
- }
-
- wxCHECK_MSG( wxTheApp, 0, wxT("You have to define an instance of wxApp!") );
-
-#ifdef __DARWIN__
- // 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
- // application (otherwise applications would need to handle it)
-
- if (argc > 1) {
- if (strncmp(argv[1], "-psn_", 5) == 0) {
- // assume the argument is always the only one and remove it
- --argc;
- }
- }
-#else
- argc = 0 ; // currently we don't support files as parameters
-#endif
- // we could try to get the open apple events here to adjust argc and argv better
-
- wxTheApp->argc = argc;
-#if wxUSE_UNICODE
- wxTheApp->argv = new wxChar*[argc+1];
- int mb_argc ;
- for ( mb_argc = 0; mb_argc < argc; mb_argc++ )
- {
- wxTheApp->argv[mb_argc] = wxStrdup(wxConvLocal.cMB2WX(argv[mb_argc]));
- }
- wxTheApp->argv[mb_argc] = (wxChar *)NULL;
-#else
- wxTheApp->argv = argv;
-#endif
-
- // GUI-specific initialization, such as creating an app context.
- wxEntryInitGui();
-
- // Here frames insert themselves automatically
- // into wxTopLevelWindows by getting created
- // in OnInit().
-
- int retValue = 0;
-
- if ( wxTheApp->OnInit() )
- {
- if ( enterLoop )
- {
- retValue = wxTheApp->OnRun();
- }
- else
- // We want to initialize, but not run or exit immediately.
- return 1;
- }
- //else: app initialization failed, so we skipped OnRun()
-
- wxWindow *topWindow = wxTheApp->GetTopWindow();
- if ( topWindow )
- {
- // Forcibly delete the window.
- if ( topWindow->IsKindOf(CLASSINFO(wxFrame)) ||
- topWindow->IsKindOf(CLASSINFO(wxDialog)) )
- {
- topWindow->Close(TRUE);
- wxTheApp->DeletePendingObjects();
- }
- else
- {
- delete topWindow;
- wxTheApp->SetTopWindow(NULL);
- }
- }
-
- wxTheApp->OnExit();
-
- wxEntryCleanup();
-
- return retValue;
-}
+#endif /* WXMAKINGDLL_CORE && !__DARWIN__ */
#if TARGET_CARBON
*/
#endif
-// Static member initialization
-wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
-
wxApp::wxApp()
{
- m_topWindow = NULL;
- wxTheApp = this;
-
-#if WXWIN_COMPATIBILITY_2_2
- m_wantDebugOutput = TRUE;
-#endif
-
- argc = 0;
- argv = NULL;
-
m_printMode = wxPRINT_WINDOWS;
m_auto3D = TRUE;
-}
-bool wxApp::Initialized()
-{
- if (GetTopWindow())
- return TRUE;
- else
- return FALSE;
+ m_macCurrentEvent = NULL ;
+#if TARGET_CARBON
+ m_macCurrentEventHandlerCallRef = NULL ;
+#endif
}
int wxApp::MainLoop()
return 0;
}
-// Returns TRUE if more time is needed.
-bool wxApp::ProcessIdle()
-{
- wxIdleEvent event;
- event.SetEventObject(this);
- ProcessEvent(event);
-
- return event.MoreRequested();
-}
-
void wxApp::ExitMainLoop()
{
m_keepGoing = FALSE;
#else
EventRecord event ;
- return EventAvail( everyEvent , &event ) ;
+ return EventAvail( everyEvent , &event ) ;
#endif
}
// Dispatch a message.
-void wxApp::Dispatch()
+bool wxApp::Dispatch()
{
MacDoOneEvent() ;
+
+ return true;
}
void wxApp::OnIdle(wxIdleEvent& event)
{
- // Avoid recursion (via ProcessEvent default case)
- if ( s_inOnIdle )
- return;
-
-
- s_inOnIdle = TRUE;
-
- // 'Garbage' collection of windows deleted with Close().
- DeletePendingObjects();
-
- // flush the logged messages if any
- wxLog *pLog = wxLog::GetActiveTarget();
- if ( pLog != NULL && pLog->HasPendingMessages() )
- pLog->Flush();
-
- // Send OnIdle events to all windows
- bool needMore = SendIdleEvents();
-
- if (needMore)
- event.RequestMore(TRUE);
+ wxAppBase::OnIdle(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
wxMacProcessNotifierAndPendingEvents();
- s_inOnIdle = FALSE;
if(!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar())
wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar();
}
-void wxWakeUpIdle()
+void wxApp::WakeUpIdle()
{
wxMacWakeUp() ;
}
-// Send idle event to all top-level windows
-bool wxApp::SendIdleEvents()
-{
- bool needMore = FALSE;
- wxWindowListNode* node = wxTopLevelWindows.GetFirst();
- while (node)
- {
- wxWindow* win = node->GetData();
- if (SendIdleEvents(win))
- needMore = TRUE;
-
- node = node->GetNext();
- }
- return needMore;
-}
-
-// Send idle event to window and all subwindows
-bool wxApp::SendIdleEvents(wxWindow* win)
-{
- bool needMore = FALSE;
-
- wxIdleEvent event;
- event.SetEventObject(win);
- win->ProcessEvent(event);
-
- if (event.MoreRequested())
- needMore = TRUE;
-
- wxWindowListNode* node = win->GetChildren().GetFirst();
- while (node)
- {
- wxWindow* win = node->GetData();
- if (SendIdleEvents(win))
- needMore = TRUE;
-
- node = node->GetNext();
- }
- return needMore ;
-}
-
-void wxApp::DeletePendingObjects()
-{
- wxNode *node = wxPendingDelete.GetFirst();
- while (node)
- {
- wxObject *obj = (wxObject *)node->GetData();
-
- delete obj;
-
- if (wxPendingDelete.Member(obj))
- delete node;
-
- // Deleting one object may have deleted other pending
- // objects, so start from beginning of list again.
- node = wxPendingDelete.GetFirst();
- }
-}
-
-void wxExit()
+void wxApp::Exit()
{
- wxLogError(_("Fatal error: exiting"));
-
wxApp::CleanUp();
::ExitToShell() ;
}
#if TARGET_CARBON
#if 0 // having problems right now with that
if (!win->HasFlag(wxSTAY_ON_TOP))
-#endif
+#endif
#endif
win->MacActivate( ((EventRecord*) MacGetCurrentEvent())->when , false ) ;
if ( wxTheApp->ProcessIdle() )
sleepTime = kEventDurationNoWait ;
else
- sleepTime = kEventDurationForever ;
+ {
+#if wxUSE_THREADS
+ if (g_numberOfThreads)
+ {
+ sleepTime = kEventDurationNoWait;
+ }
+ else
+#endif // wxUSE_THREADS
+ {
+ sleepTime = kEventDurationSecond;
+ }
+ }
}
else if ( status == eventLoopQuitErr )
{
::IdleControls( window ) ;
if ( wxTheApp->ProcessIdle() )
- sleepTime = 0 ;
+ sleepTime = kEventDurationNoWait;
else
- sleepTime = GetCaretTime() / 2 ;
+ {
+#if wxUSE_THREADS
+ if (g_numberOfThreads)
+ {
+ sleepTime = kEventDurationNoWait;
+ }
+ else
+#endif // wxUSE_THREADS
+ {
+ sleepTime = kEventDurationSecond;
+ }
+ }
}
if ( event.what != kHighLevelEvent )
SetRectRgn( (RgnHandle) s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ;
wxMacProcessNotifierAndPendingEvents() ;
}
+/*virtual*/ void wxApp::MacHandleUnhandledEvent( WXEVENTREF evr )
+{
+ // Override to process unhandled events as you please
+}
+
void wxApp::MacHandleOneEvent( WXEVENTREF evr )
{
#if TARGET_CARBON
EventTargetRef theTarget;
theTarget = GetEventDispatcherTarget();
m_macCurrentEvent = evr ;
- SendEventToEventTarget ((EventRef) evr , theTarget);
+ OSStatus status = SendEventToEventTarget ((EventRef) evr , theTarget);
+ if(status == eventNotHandledErr)
+ {
+ MacHandleUnhandledEvent(evr);
+ }
#else
EventRecord* ev = (EventRecord*) evr ;
m_macCurrentEvent = ev ;
MacHandleActivateEvent( ev ) ;
break;
case updateEvt:
+ // In embedded mode we first let the UnhandledEvent function
+ // try to handle the update event. If we handle it ourselves
+ // first and then pass it on, the host's windows won't update.
+ MacHandleUnhandledEvent(ev);
MacHandleUpdateEvent( ev ) ;
break;
case keyDown:
event.SetEventType( ( ev->modifiers & optionKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
focus->GetEventHandler()->ProcessEvent( event ) ;
}
+ if ( ( ev->modifiers ^ s_lastModifiers ) & cmdKey )
+ {
+ event.m_keyCode = WXK_COMMAND ;
+ event.SetEventType( ( ev->modifiers & cmdKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
+ focus->GetEventHandler()->ProcessEvent( event ) ;
+ }
s_lastModifiers = ev->modifiers ;
}
}
}
else
{
+ // Activate window first
+ ::SelectWindow( window ) ;
+
+ // Send event later
if ( win )
win->MacMouseDown( ev , windowPart ) ;
- ::SelectWindow( window ) ;
}
}
else
return retval;
}
+int wxKeyCodeToMacModifier(wxKeyCode key)
+{
+ switch (key)
+ {
+ case WXK_START:
+ case WXK_MENU:
+ return cmdKey;
+
+ case WXK_SHIFT:
+ return shiftKey;
+
+ case WXK_CAPITAL:
+ return alphaLock;
+
+ case WXK_ALT:
+ return optionKey;
+
+ case WXK_CONTROL:
+ return controlKey;
+
+ default:
+ return 0;
+ }
+}
+
+bool wxGetKeyState(wxKeyCode key) //virtual key code if < 10.2.x, else see below
+{
+//#ifdef __DARWIN__
+// wxHIDKeyboard keyboard;
+// return keyboard.IsActive(key);
+//#else
+// TODO: Have it use HID Manager on OSX...
+//if OS X > 10.2 (i.e. 10.2.x)
+//a known apple bug prevents the system from determining led
+//states with GetKeys... can only determine caps lock led
+ return !!(GetCurrentKeyModifiers() & wxKeyCodeToMacModifier(key));
+//else
+// KeyMapByteArray keymap;
+// GetKeys((BigEndianLong*)keymap);
+// return !!(BitTst(keymap, (sizeof(KeyMapByteArray)*8) - iKey));
+//#endif
+}
+
#if !TARGET_CARBON
void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr )
{
if ( MacSendKeyDownEvent( focus , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) == false )
{
+#if 0
+ // we must handle control keys the other way round, otherwise text content is updated too late
// has not been handled -> perform default
wxControl* control = wxDynamicCast( focus , wxControl ) ;
if ( control && control->GetMacControl() != NULL )
keycode = short(ev->message & keyCodeMask) >> 8 ;
::HandleControlKey( (ControlHandle) control->GetMacControl() , keycode , keychar , ev->modifiers ) ;
}
+#endif
}
}
}
}
}
+#else
+
+void wxApp::MacHandleMouseMovedEvent(wxInt32 x , wxInt32 y ,wxUint32 modifiers , long timestamp)
+{
+ WindowRef window;
+
+ wxWindow* currentMouseWindow = NULL ;
+
+ if (s_captureWindow )
+ {
+ currentMouseWindow = s_captureWindow ;
+ }
+ else
+ {
+ wxWindow::MacGetWindowFromPoint( wxPoint( x, y ) , ¤tMouseWindow ) ;
+ }
+
+ if ( currentMouseWindow != wxWindow::s_lastMouseWindow )
+ {
+ wxMouseEvent event ;
+
+ bool isDown = !(modifiers & btnState) ; // 1 is for up
+ bool controlDown = modifiers & controlKey ; // for simulating right mouse
+
+ event.m_leftDown = isDown && !controlDown;
+
+ event.m_middleDown = FALSE;
+ event.m_rightDown = isDown && controlDown;
+
+ event.m_shiftDown = modifiers & shiftKey;
+ event.m_controlDown = modifiers & controlKey;
+ event.m_altDown = modifiers & optionKey;
+ event.m_metaDown = modifiers & cmdKey;
+
+ event.m_x = x;
+ event.m_y = y;
+ event.m_timeStamp = timestamp;
+
+ if ( wxWindow::s_lastMouseWindow )
+ {
+ wxMouseEvent eventleave(event);
+ eventleave.SetEventType( wxEVT_LEAVE_WINDOW );
+ wxWindow::s_lastMouseWindow->ScreenToClient( &eventleave.m_x, &eventleave.m_y );
+ eventleave.SetEventObject( wxWindow::s_lastMouseWindow ) ;
+
+#if wxUSE_TOOLTIPS
+ wxToolTip::RelayEvent( wxWindow::s_lastMouseWindow , eventleave);
+#endif // wxUSE_TOOLTIPS
+ wxWindow::s_lastMouseWindow->GetEventHandler()->ProcessEvent(eventleave);
+ }
+ if ( currentMouseWindow )
+ {
+ wxMouseEvent evententer(event);
+ evententer.SetEventType( wxEVT_ENTER_WINDOW );
+ currentMouseWindow->ScreenToClient( &evententer.m_x, &evententer.m_y );
+ evententer.SetEventObject( currentMouseWindow ) ;
+#if wxUSE_TOOLTIPS
+ wxToolTip::RelayEvent( currentMouseWindow , evententer);
+#endif // wxUSE_TOOLTIPS
+ currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
+ }
+ wxWindow::s_lastMouseWindow = currentMouseWindow ;
+ }
+
+ short windowPart = inNoWindow ;
+
+ if ( s_captureWindow )
+ {
+ window = (WindowRef) s_captureWindow->MacGetRootWindow() ;
+ windowPart = inContent ;
+ }
+ else
+ {
+ Point pt= { y , x } ;
+ windowPart = ::FindWindow(pt , &window);
+ }
+
+ switch (windowPart)
+ {
+ case inContent :
+ {
+ wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
+ if ( win )
+ win->MacFireMouseEvent( nullEvent , x , y , modifiers , timestamp ) ;
+ else
+ {
+ if ( wxIsBusy() )
+ {
+ }
+ else
+ UMAShowArrowCursor();
+ }
+ }
+ break;
+ default :
+ {
+ if ( wxIsBusy() )
+ {
+ }
+ else
+ UMAShowArrowCursor();
+ }
+ break ;
+ }
+}
#endif
void wxApp::MacHandleMenuCommand( wxUint32 id )