X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c847adaacfb0f0392aa2bcf01289e308120d3484..3c393c0a564ec9197b8441d9c106f46509c99729:/src/mac/carbon/app.cpp diff --git a/src/mac/carbon/app.cpp b/src/mac/carbon/app.cpp index f92a72d827..7f666b955e 100644 --- a/src/mac/carbon/app.cpp +++ b/src/mac/carbon/app.cpp @@ -9,11 +9,11 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "app.h" #endif -#include "wx/defs.h" +#include "wx/wxprec.h" #include "wx/window.h" #include "wx/frame.h" @@ -49,7 +49,7 @@ #endif #endif -#include "apprsrc.h" +// #include "apprsrc.h" #include "wx/mac/uma.h" #include "wx/mac/macnotfy.h" @@ -69,25 +69,33 @@ extern wxList wxPendingDelete; +// set wxMAC_USE_RAEL to 1 if RunApplicationEventLoop should be used +// if 0 the lower level CarbonEventLoop will be used +// on the long run RAEL should replace the low level event loop +// we will have to clean up event handling to make sure we don't +// miss handling of things like pending events etc +// perhaps we will also have to pipe events through an ueber-event-handler +// to make sure we have one place to do all these house-keeping functions + +#define wxMAC_USE_RAEL 0 + #if wxUSE_THREADS extern size_t g_numberOfThreads; #endif // wxUSE_THREADS // statics for implementation -static bool s_inYield = FALSE; +static bool s_inYield = false; -static bool s_inReceiveEvent = FALSE ; +static bool s_inReceiveEvent = false ; static EventTime sleepTime = kEventDurationNoWait ; -#if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler) BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) EVT_IDLE(wxApp::OnIdle) EVT_END_SESSION(wxApp::OnEndSession) EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession) END_EVENT_TABLE() -#endif const short kMacMinHeap = (29 * 1024) ; @@ -155,7 +163,6 @@ short wxApp::MacHandleAEODoc(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply)) DescType returnedType; Size actualSize; long itemsInList; - FSSpec theSpec; OSErr err; short i; err = AEGetParamDesc((AppleEvent *)event, keyDirectObject, typeAEList,&docList); @@ -171,10 +178,15 @@ short wxApp::MacHandleAEODoc(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply)) PSN.lowLongOfPSN = kCurrentProcess ; SetFrontProcess( &PSN ) ; - for (i = 1; i <= itemsInList; i++) { - AEGetNthPtr(&docList, i, typeFSS, &keywd, &returnedType, - (Ptr) & theSpec, sizeof(theSpec), &actualSize); - wxString fName = wxMacFSSpec2MacFilename(&theSpec); + for (i = 1; i <= itemsInList; i++) + { + wxString fName ; + + FSRef theRef ; + AEGetNthPtr(&docList, i, typeFSRef, &keywd, &returnedType, + (Ptr) & theRef, sizeof(theRef), &actualSize); + fName = wxMacFSRefToPath( &theRef ) ; + MacOpenFile(fName); } return noErr; @@ -189,7 +201,6 @@ short wxApp::MacHandleAEPDoc(const WXEVENTREF event , WXEVENTREF WXUNUSED(reply) DescType returnedType; Size actualSize; long itemsInList; - FSSpec theSpec; OSErr err; short i; err = AEGetParamDesc((AppleEvent *)event, keyDirectObject, typeAEList,&docList); @@ -206,9 +217,13 @@ short wxApp::MacHandleAEPDoc(const WXEVENTREF event , WXEVENTREF WXUNUSED(reply) SetFrontProcess( &PSN ) ; for (i = 1; i <= itemsInList; i++) { - AEGetNthPtr(&docList, i, typeFSS, &keywd, &returnedType, - (Ptr) & theSpec, sizeof(theSpec), &actualSize); - wxString fName = wxMacFSSpec2MacFilename(&theSpec); + wxString fName ; + + FSRef theRef ; + AEGetNthPtr(&docList, i, typeFSRef, &keywd, &returnedType, + (Ptr) & theRef, sizeof(theRef), &actualSize); + fName = wxMacFSRefToPath( &theRef ) ; + MacPrintFile(fName); } return noErr; @@ -231,7 +246,7 @@ short wxApp::MacHandleAEQuit(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNU { wxCommandEvent exitEvent(wxEVT_COMMAND_MENU_SELECTED, s_macExitMenuItemId); if (!win->ProcessEvent(exitEvent)) - win->Close(TRUE ) ; + win->Close(true) ; } else { @@ -249,19 +264,26 @@ short wxApp::MacHandleAERApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNU } + //---------------------------------------------------------------------- // Support Routines linking the Mac...File Calls to the Document Manager //---------------------------------------------------------------------- void wxApp::MacOpenFile(const wxString & fileName ) { +#if wxUSE_DOC_VIEW_ARCHITECTURE wxDocManager* dm = wxDocManager::GetDocumentManager() ; if ( dm ) dm->CreateDocument(fileName , wxDOC_SILENT ) ; +#endif } + void wxApp::MacPrintFile(const wxString & fileName ) { +#if wxUSE_DOC_VIEW_ARCHITECTURE + +#if wxUSE_PRINTING_ARCHITECTURE wxDocManager* dm = wxDocManager::GetDocumentManager() ; if ( dm ) { @@ -275,7 +297,7 @@ void wxApp::MacPrintFile(const wxString & fileName ) if (printout) { wxPrinter printer; - printer.Print(view->GetFrame(), printout, TRUE); + printer.Print(view->GetFrame(), printout, true); delete printout; } } @@ -286,15 +308,50 @@ void wxApp::MacPrintFile(const wxString & fileName ) } } } +#endif //print + +#endif //docview } + + void wxApp::MacNewFile() { } void wxApp::MacReopenApp() { - // eventually check for open docs, if none, call MacNewFile + // HIG says : + // if there is no open window -> create a new one + // if all windows are hidden -> show the first + // if some windows are not hidden -> do nothing + + wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst(); + if ( node == NULL ) + { + MacNewFile() ; + } + else + { + wxTopLevelWindow* firstIconized = NULL ; + while (node) + { + wxTopLevelWindow* win = (wxTopLevelWindow*) node->GetData(); + if ( win->IsIconized() == false ) + { + firstIconized = NULL ; + break ; + } + else + { + if ( firstIconized == NULL ) + firstIconized = win ; + } + node = node->GetNext(); + } + if ( firstIconized ) + firstIconized->Iconize( false ) ; + } } //---------------------------------------------------------------------- @@ -327,54 +384,49 @@ static const EventTypeSpec eventList[] = static pascal OSStatus wxMacAppMenuEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { - wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar(); - - if ( mbar ) + wxMacCarbonEvent cEvent( event ) ; + MenuRef menuRef = cEvent.GetParameter(kEventParamDirectObject) ; + wxMenu* menu = wxFindMenuFromMacMenu( menuRef ) ; + + if ( menu ) { - wxFrame* win = mbar->GetFrame(); - if ( win ) + wxEventType type=0; + MenuCommand cmd=0; + switch (GetEventKind(event)) { - - // 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: + case kEventMenuOpening: + type = wxEVT_MENU_OPEN; + break; + case kEventMenuClosed: + type = wxEVT_MENU_CLOSE; + break; + case kEventMenuTargetItem: + cmd = cEvent.GetParameter(kEventParamMenuCommand,typeMenuCommand) ; + if (cmd != 0) 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; - } + break; + default: + wxFAIL_MSG(wxT("Unexpected menu event kind")); + break; + } - wxMenuEvent wxevent(type, cmd); - wxevent.SetEventObject(win); + if ( type ) + { + wxMenuEvent wxevent(type, cmd, menu); + wxevent.SetEventObject(menu); - (void)win->GetEventHandler()->ProcessEvent(wxevent); - } + wxEvtHandler* handler = menu->GetEventHandler(); + if (handler && handler->ProcessEvent(wxevent)) + { + // handled + } + else + { + wxWindow *win = menu->GetInvokingWindow(); + if (win) + win->GetEventHandler()->ProcessEvent(wxevent); + } + } } return eventNotHandledErr; @@ -386,32 +438,31 @@ static pascal OSStatus wxMacAppCommandEventHandler( EventHandlerCallRef handler HICommand command ; - GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL, - sizeof( HICommand ), NULL, &command ); + wxMacCarbonEvent cEvent( event ) ; + cEvent.GetParameter(kEventParamDirectObject,typeHICommand,&command) ; + wxMenuItem* item = NULL ; MenuCommand id = command.commandID ; + // for items we don't really control if ( id == kHICommandPreferences ) + { id = wxApp::s_macPreferencesMenuItemId ; - wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ; - wxMenu* menu = NULL ; - 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 ) + wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ; + if ( mbar ) { - item = NULL ; - menu = NULL ; + wxMenu* menu = NULL ; + item = mbar->FindItem( id , &menu ) ; } } + else if ( id != 0 && command.menu.menuRef != 0 && command.menu.menuItemIndex != 0 ) + { + GetMenuItemRefCon( command.menu.menuRef , command.menu.menuItemIndex , (UInt32*) &item ) ; + } - if ( item == NULL || menu == NULL || mbar == NULL ) - return result ; - - switch( GetEventKind( event ) ) + if ( item ) + { + switch( cEvent.GetKind() ) { case kEventProcessCommand : { @@ -420,18 +471,18 @@ static pascal OSStatus wxMacAppCommandEventHandler( EventHandlerCallRef handler item->Check( !item->IsChecked() ) ; } - menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ; + item->GetMenu()->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ; result = noErr ; } - break ; + break ; case kEventCommandUpdateStatus: // eventually trigger an updateui round result = noErr ; break ; - default : - break ; - } - + default : + break ; + } + } return result ; } @@ -462,6 +513,10 @@ static pascal OSStatus wxMacAppApplicationEventHandler( EventHandlerCallRef hand pascal OSStatus wxMacAppEventHandler( 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 ) ) { @@ -475,7 +530,17 @@ pascal OSStatus wxMacAppEventHandler( EventHandlerCallRef handler , EventRef eve result = wxMacAppMenuEventHandler( handler , event , data ) ; break ; case kEventClassMouse : - result = wxMacTopLevelMouseEventHandler( handler , event , data ) ; + { + wxMacCarbonEvent cEvent( event ) ; + + WindowRef window ; + Point screenMouseLocation = cEvent.GetParameter(kEventParamMouseLocation) ; + ::FindWindow(screenMouseLocation, &window); + // only send this event in case it had not already been sent to a tlw, as we get + // double events otherwise (in case event.skip) was called + if ( window == NULL ) + result = wxMacTopLevelMouseEventHandler( handler , event , NULL ) ; + } break ; case kEventClassAppleEvent : { @@ -488,6 +553,8 @@ pascal OSStatus wxMacAppEventHandler( EventHandlerCallRef handler , EventRef eve break ; } + wxTheApp->MacSetCurrentEvent( formerEvent, formerEventHandlerCallRef ) ; + return result ; } @@ -498,8 +565,10 @@ DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacAppEventHandler ) WXIMPORT char std::__throws_bad_alloc ; #endif -pascal static void wxMacAssertOutputHandler(OSType componentSignature, UInt32 options, - const char *assertionString, const char *exceptionLabelString, +#if __WXDEBUG__ + +pascal static void wxMacAssertOutputHandler(OSType componentSignature, UInt32 options, + const char *assertionString, const char *exceptionLabelString, const char *errorString, const char *fileName, long lineNumber, void *value, ConstStr255Param outputMsg) { // flow into assert handling @@ -521,10 +590,10 @@ pascal static void wxMacAssertOutputHandler(OSType componentSignature, UInt32 op #if 1 // flow into log - wxLogDebug( wxT("AssertMacros: %s %s %s file: %s, line: %ld (value %p)\n"), - assertionStr.c_str() , - exceptionStr.c_str() , - errorStr.c_str(), + wxLogDebug( wxT("AssertMacros: %s %s %s file: %s, line: %ld (value %p)\n"), + assertionStr.c_str() , + exceptionStr.c_str() , + errorStr.c_str(), fileNameStr.c_str(), lineNumber , value ) ; #else @@ -534,6 +603,18 @@ pascal static void wxMacAssertOutputHandler(OSType componentSignature, UInt32 op #endif } +#endif //__WXDEBUG__ + +#ifdef __WXMAC_OSX__ +extern "C" { + /* m_macEventPosted run loop source callback: */ + void macPostedEventCallback(void *unused); +} + +void macPostedEventCallback(void *unused) { + wxTheApp->ProcessPendingEvents(); } +#endif + bool wxApp::Initialize(int& argc, wxChar **argv) { // Mac-specific @@ -545,12 +626,6 @@ bool wxApp::Initialize(int& argc, wxChar **argv) SetEventMask( everyEvent ) ; UMAShowWatchCursor() ; -#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); -#endif - #ifndef __DARWIN__ # if __option(profile) ProfilerInit( collectDetailed, bestTimeBase , 40000 , 50 ) ; @@ -590,14 +665,43 @@ bool wxApp::Initialize(int& argc, wxChar **argv) wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding()); #endif +#if TARGET_API_MAC_OSX + // these might be the startup dirs, set them to the 'usual' dir containing the app bundle + wxString startupCwd = wxGetCwd() ; + if ( startupCwd == wxT("/") || startupCwd.Right(15) == wxT("/Contents/MacOS") ) + { + CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle() ) ; + CFURLRef urlParent = CFURLCreateCopyDeletingLastPathComponent( kCFAllocatorDefault , url ) ; + CFRelease( url ) ; + CFStringRef path = CFURLCopyFileSystemPath ( urlParent , kCFURLPOSIXPathStyle ) ; + CFRelease( urlParent ) ; + wxString cwd = wxMacCFStringHolder(path).AsString(wxLocale::GetSystemEncoding()); + wxSetWorkingDirectory( cwd ) ; + } +#endif wxMacCreateNotifierTable() ; +#ifdef __WXMAC_OSX__ + /* 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); +#endif + UMAShowArrowCursor() ; return true; } +AEEventHandlerUPP sODocHandler = NULL ; +AEEventHandlerUPP sOAppHandler = NULL ; +AEEventHandlerUPP sPDocHandler = NULL ; +AEEventHandlerUPP sRAppHandler = NULL ; +AEEventHandlerUPP sQuitHandler = NULL ; + bool wxApp::OnInitGui() { if( !wxAppBase::OnInitGui() ) @@ -614,29 +718,40 @@ bool wxApp::OnInitGui() if (!sm_isEmbedded) { + sODocHandler = NewAEEventHandlerUPP(AEHandleODoc) ; + sOAppHandler = NewAEEventHandlerUPP(AEHandleOApp) ; + sPDocHandler = NewAEEventHandlerUPP(AEHandlePDoc) ; + sRAppHandler = NewAEEventHandlerUPP(AEHandleRApp) ; + sQuitHandler = NewAEEventHandlerUPP(AEHandleQuit) ; + AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments , - NewAEEventHandlerUPP(AEHandleODoc) , - 0 , FALSE ) ; + sODocHandler , 0 , FALSE ) ; AEInstallEventHandler( kCoreEventClass , kAEOpenApplication , - NewAEEventHandlerUPP(AEHandleOApp) , - 0 , FALSE ) ; + sOAppHandler , 0 , FALSE ) ; AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments , - NewAEEventHandlerUPP(AEHandlePDoc) , - 0 , FALSE ) ; + sPDocHandler , 0 , FALSE ) ; AEInstallEventHandler( kCoreEventClass , kAEReopenApplication , - NewAEEventHandlerUPP(AEHandleRApp) , - 0 , FALSE ) ; + sRAppHandler , 0 , FALSE ) ; AEInstallEventHandler( kCoreEventClass , kAEQuitApplication , - NewAEEventHandlerUPP(AEHandleQuit) , - 0 , FALSE ) ; + sQuitHandler , 0 , FALSE ) ; } - return TRUE ; + return true ; } void wxApp::CleanUp() { +#if wxUSE_TOOLTIPS wxToolTip::RemoveToolTips() ; +#endif + +#ifdef __WXMAC_OSX__ + if (m_macEventPosted) + { + CFRelease(m_macEventPosted); + } + m_macEventPosted = NULL; +#endif // One last chance for pending objects to be cleaned up wxTheApp->DeletePendingObjects(); @@ -650,174 +765,42 @@ void wxApp::CleanUp() # endif #endif -#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 - UMACleanupToolbox() ; if (s_macCursorRgn) { ::DisposeRgn((RgnHandle)s_macCursorRgn); } - #if 0 - TerminateAE() ; - #endif - - wxAppBase::CleanUp(); -} - -//---------------------------------------------------------------------- -// 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_CORE) && defined(__DARWIN__) -CFBundleRef gSharedLibraryBundle = NULL; -#endif /* WXMAKINGDLL_CORE && __DARWIN__ */ - -wxStAppResource::wxStAppResource() -{ - m_currentRefNum = CurResFile() ; - if ( gSharedLibraryResource != kResFileNotOpened ) + if (!sm_isEmbedded) { - UseResFile( gSharedLibraryResource ) ; + RemoveEventHandler( (EventHandlerRef)(wxTheApp->m_macEventHandler) ); } -} -wxStAppResource::~wxStAppResource() -{ - if ( m_currentRefNum != kResFileNotOpened ) + if (!sm_isEmbedded) { - UseResFile( m_currentRefNum ) ; + AERemoveEventHandler( kCoreEventClass , kAEOpenDocuments , + sODocHandler , FALSE ) ; + AERemoveEventHandler( kCoreEventClass , kAEOpenApplication , + sOAppHandler , FALSE ) ; + AERemoveEventHandler( kCoreEventClass , kAEPrintDocuments , + sPDocHandler , FALSE ) ; + AERemoveEventHandler( kCoreEventClass , kAEReopenApplication , + sRAppHandler , FALSE ) ; + AERemoveEventHandler( kCoreEventClass , kAEQuitApplication , + sQuitHandler , FALSE ) ; + + DisposeAEEventHandlerUPP( sODocHandler ) ; + DisposeAEEventHandlerUPP( sOAppHandler ) ; + DisposeAEEventHandlerUPP( sPDocHandler ) ; + DisposeAEEventHandlerUPP( sRAppHandler ) ; + DisposeAEEventHandlerUPP( sQuitHandler ) ; } -} - -void wxStAppResource::OpenSharedLibraryResource(const void *initBlock) -{ - gSharedLibraryResource = kResFileNotOpened; - -#ifdef WXMAKINGDLL_CORE - if ( initBlock != NULL ) { - const CFragInitBlock *theInitBlock = (const CFragInitBlock *)initBlock; - FSSpec *fileSpec = NULL; - - if (theInitBlock->fragLocator.where == kDataForkCFragLocator) { - fileSpec = theInitBlock->fragLocator.u.onDisk.fileSpec; - } - else if (theInitBlock->fragLocator.where == kResourceCFragLocator) { - fileSpec = theInitBlock->fragLocator.u.inSegs.fileSpec; - } - - if (fileSpec != NULL) { - gSharedLibraryResource = FSpOpenResFile(fileSpec, fsRdPerm); - } - } - else { -#ifdef __DARWIN__ - // Open the shared library resource file if it is not yet open - NSSymbol theSymbol; - NSModule theModule; - const char *theLibPath; - - gSharedLibraryBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWindows")); - if (gSharedLibraryBundle != NULL) { - // wxWindows has been bundled into a framework - // load the framework resources - - gSharedLibraryResource = CFBundleOpenBundleResourceMap(gSharedLibraryBundle); - } - else { - // wxWindows is a simple dynamic shared library - // load the resources from the data fork of a separate resource file - wxString theResPath; - wxString theName; - FSRef theResRef; - OSErr theErr = noErr; - - // get the library path - theSymbol = NSLookupAndBindSymbol("_gSharedLibraryResource"); - theModule = NSModuleForSymbol(theSymbol); - theLibPath = NSLibraryNameForModule(theModule); - - // if we call wxLogDebug from here then, as wxTheApp hasn't been - // created yet when we're called from wxApp::Initialize(), wxLog - // is going to create a default stderr-based log target instead of - // the expected normal GUI one -- don't do it, if we really want - // to see this message just use fprintf() here -#if 0 - wxLogDebug( wxT("wxMac library installation name is '%s'"), - theLibPath ); -#endif - - // allocate copy to replace .dylib.* extension with .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.mb_str() ); -#endif - - theErr = FSPathMakeRef((UInt8 *) theResPath.mb_str(), &theResRef, false); - if (theErr != noErr) { - // try in current directory (using name only) - theErr = FSPathMakeRef((UInt8 *) theName.mb_str(), &theResRef, false); - } - - // open the resource file - if (theErr == noErr) { - theErr = FSOpenResourceFile( &theResRef, 0, NULL, fsRdPerm, - &gSharedLibraryResource); - } - if (theErr != noErr) { -#ifdef __WXDEBUG__ - wxLogDebug( wxT("unable to open wxMac resource file '%s'\n"), - theResPath.mb_str() ); -#endif // __WXDEBUG__ - } - } - } -#endif /* __DARWIN__ */ - } -#endif /* WXMAKINGDLL_CORE */ + wxAppBase::CleanUp(); } -void wxStAppResource::CloseSharedLibraryResource() -{ -#ifdef WXMAKINGDLL_CORE - // Close the shared library resource file - if (gSharedLibraryResource != kResFileNotOpened) { -#ifdef __DARWIN__ - if (gSharedLibraryBundle != NULL) { - CFBundleCloseBundleResourceMap(gSharedLibraryBundle, - gSharedLibraryResource); - gSharedLibraryBundle = NULL; - } - else -#endif /* __DARWIN__ */ - { - CloseResFile(gSharedLibraryResource); - } - gSharedLibraryResource = kResFileNotOpened; - } -#endif /* WXMAKINGDLL_CORE */ -} +//---------------------------------------------------------------------- +// misc initialization stuff +//---------------------------------------------------------------------- #if defined(WXMAKINGDLL_CORE) && !defined(__DARWIN__) @@ -833,13 +816,11 @@ extern "C" { pascal OSErr __wxinitialize(const CFragInitBlock *theInitBlock) { - wxStAppResource::OpenSharedLibraryResource( theInitBlock ) ; return __initialize( theInitBlock ) ; } pascal void __wxterminate(void) { - wxStAppResource::CloseSharedLibraryResource() ; __terminate() ; } @@ -925,27 +906,35 @@ bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) wxApp::wxApp() { - m_printMode = wxPRINT_WINDOWS; + m_printMode = wxPRINT_WINDOWS; - m_macCurrentEvent = NULL ; - m_macCurrentEventHandlerCallRef = NULL ; + m_macCurrentEvent = NULL ; + m_macCurrentEventHandlerCallRef = NULL ; +#ifdef __WXMAC_OSX__ + m_macEventPosted = NULL ; +#endif } int wxApp::MainLoop() { - m_keepGoing = TRUE; - + m_keepGoing = true; +#if wxMAC_USE_RAEL + RunApplicationEventLoop() ; +#else while (m_keepGoing) { MacDoOneEvent() ; } - +#endif return 0; } void wxApp::ExitMainLoop() { - m_keepGoing = FALSE; + m_keepGoing = false; +#if wxMAC_USE_RAEL + QuitApplicationEventLoop() ; +#endif } // Is a message/event pending? @@ -954,7 +943,7 @@ bool wxApp::Pending() // without the receive event (with pull param = false ) nothing is ever reported EventRef theEvent; ReceiveNextEvent (0, NULL, kEventDurationNoWait, false, &theEvent); - return GetNumEventsInQueue( GetMainEventQueue() ) > 0 ; + return GetNumEventsInQueue( GetMainEventQueue() ) > 0 ; } // Dispatch a message. @@ -980,6 +969,12 @@ void wxApp::OnIdle(wxIdleEvent& event) void wxApp::WakeUpIdle() { +#ifdef __WXMAC_OSX__ + if (m_macEventPosted) + { + CFRunLoopSourceSignal(m_macEventPosted); + } +#endif wxMacWakeUp() ; } @@ -992,7 +987,7 @@ void wxApp::Exit() void wxApp::OnEndSession(wxCloseEvent& WXUNUSED(event)) { if (GetTopWindow()) - GetTopWindow()->Close(TRUE); + GetTopWindow()->Close(true); } // Default behaviour: close the application with prompts. The @@ -1002,7 +997,7 @@ void wxApp::OnQueryEndSession(wxCloseEvent& event) if (GetTopWindow()) { if (!GetTopWindow()->Close(!event.CanVeto())) - event.Veto(TRUE); + event.Veto(true); } } @@ -1023,14 +1018,11 @@ bool wxApp::Yield(bool onlyIfNeeded) wxFAIL_MSG( wxT("wxYield called recursively" ) ); } - return FALSE; + return false; } - s_inYield = TRUE; + s_inYield = true; -#if wxUSE_THREADS - YieldToAnyThread() ; -#endif // by definition yield should handle all non-processed events EventRef theEvent; @@ -1060,9 +1052,9 @@ bool wxApp::Yield(bool onlyIfNeeded) } while( status == noErr ) ; wxMacProcessNotifierAndPendingEvents() ; - s_inYield = FALSE; + s_inYield = false; - return TRUE; + return true; } void wxApp::MacDoOneEvent() @@ -1077,18 +1069,7 @@ void wxApp::MacDoOneEvent() if ( wxTheApp->ProcessIdle() ) sleepTime = kEventDurationNoWait ; else - { -#if wxUSE_THREADS - if (g_numberOfThreads) - { - sleepTime = kEventDurationNoWait; - } - else -#endif // wxUSE_THREADS - { - sleepTime = kEventDurationSecond; - } - } + sleepTime = kEventDurationSecond; } else if ( status == eventLoopQuitErr ) { @@ -1109,7 +1090,7 @@ void wxApp::MacDoOneEvent() /*virtual*/ void wxApp::MacHandleUnhandledEvent( WXEVENTREF evr ) { - // Override to process unhandled events as you please + // Override to process unhandled events as you please } void wxApp::MacHandleOneEvent( WXEVENTREF evr ) @@ -1123,6 +1104,9 @@ void wxApp::MacHandleOneEvent( WXEVENTREF evr ) MacHandleUnhandledEvent(evr); } wxMacProcessNotifierAndPendingEvents() ; +#if wxUSE_THREADS + wxMutexGuiLeaveOrEnter(); +#endif // wxUSE_THREADS } long wxMacTranslateKey(unsigned char key, unsigned char code) ; @@ -1132,102 +1116,118 @@ long wxMacTranslateKey(unsigned char key, unsigned char code) switch (key) { case kHomeCharCode : - retval = WXK_HOME; - break; + retval = WXK_HOME; + break; + case kEnterCharCode : - retval = WXK_RETURN; - break; + retval = WXK_RETURN; + break; case kEndCharCode : - retval = WXK_END; - break; + retval = WXK_END; + break; + case kHelpCharCode : - retval = WXK_HELP; - break; + retval = WXK_HELP; + break; + case kBackspaceCharCode : - retval = WXK_BACK; - break; + retval = WXK_BACK; + break; + case kTabCharCode : - retval = WXK_TAB; - break; + retval = WXK_TAB; + break; + case kPageUpCharCode : - retval = WXK_PAGEUP; - break; + retval = WXK_PAGEUP; + break; + case kPageDownCharCode : - retval = WXK_PAGEDOWN; - break; + retval = WXK_PAGEDOWN; + break; + case kReturnCharCode : - retval = WXK_RETURN; - break; - case kFunctionKeyCharCode : + retval = WXK_RETURN; + break; + + case kFunctionKeyCharCode : + { + switch( code ) { - switch( code ) - { - case 0x7a : - retval = WXK_F1 ; - break; - case 0x78 : - retval = WXK_F2 ; - break; - case 0x63 : - retval = WXK_F3 ; - break; - case 0x76 : - retval = WXK_F4 ; - break; - case 0x60 : - retval = WXK_F5 ; - break; - case 0x61 : - retval = WXK_F6 ; - break; - case 0x62: - retval = WXK_F7 ; - break; - case 0x64 : - retval = WXK_F8 ; - break; - case 0x65 : - retval = WXK_F9 ; - break; - case 0x6D : - retval = WXK_F10 ; - break; - case 0x67 : - retval = WXK_F11 ; - break; - case 0x6F : - retval = WXK_F12 ; - break; - case 0x69 : - retval = WXK_F13 ; - break; - case 0x6B : - retval = WXK_F14 ; - break; - case 0x71 : - retval = WXK_F15 ; - break; - } + case 0x7a : + retval = WXK_F1 ; + break; + case 0x78 : + retval = WXK_F2 ; + break; + case 0x63 : + retval = WXK_F3 ; + break; + case 0x76 : + retval = WXK_F4 ; + break; + case 0x60 : + retval = WXK_F5 ; + break; + case 0x61 : + retval = WXK_F6 ; + break; + case 0x62: + retval = WXK_F7 ; + break; + case 0x64 : + retval = WXK_F8 ; + break; + case 0x65 : + retval = WXK_F9 ; + break; + case 0x6D : + retval = WXK_F10 ; + break; + case 0x67 : + retval = WXK_F11 ; + break; + case 0x6F : + retval = WXK_F12 ; + break; + case 0x69 : + retval = WXK_F13 ; + break; + case 0x6B : + retval = WXK_F14 ; + break; + case 0x71 : + retval = WXK_F15 ; + break; } + } + break ; + + case kEscapeCharCode : + retval = WXK_ESCAPE ; break ; - case kEscapeCharCode : - retval = WXK_ESCAPE ; + + case kLeftArrowCharCode : + retval = WXK_LEFT ; break ; - case kLeftArrowCharCode : - retval = WXK_LEFT ; + + case kRightArrowCharCode : + retval = WXK_RIGHT ; break ; - case kRightArrowCharCode : - retval = WXK_RIGHT ; + + case kUpArrowCharCode : + retval = WXK_UP ; break ; - case kUpArrowCharCode : - retval = WXK_UP ; + + case kDownArrowCharCode : + retval = WXK_DOWN ; break ; - case kDownArrowCharCode : - retval = WXK_DOWN ; + + case kDeleteCharCode : + retval = WXK_DELETE ; break ; - case kDeleteCharCode : - retval = WXK_DELETE ; - default: + + default: break ; } // end switch @@ -1259,26 +1259,25 @@ int wxMacKeyCodeToModifier(wxKeyCode key) } } +#ifndef __DARWIN__ 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... + wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key != + WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons")); + //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() & wxMacKeyCodeToModifier(key)); + return !!(GetCurrentKeyModifiers() & wxMacKeyCodeToModifier(key)); //else -// KeyMapByteArray keymap; +// KeyMapByteArray keymap; // GetKeys((BigEndianLong*)keymap); // return !!(BitTst(keymap, (sizeof(KeyMapByteArray)*8) - iKey)); -//#endif } +#endif -bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey ) +bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) { if ( !focus ) return false ; @@ -1295,7 +1294,6 @@ bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifi UInt32 state = 0; UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state); keychar = short(keyInfo & charCodeMask); - keycode = short(keyInfo & keyCodeMask) >> 8 ; } long keyval = wxMacTranslateKey(keychar, keycode) ; long realkeyval = keyval ; @@ -1306,6 +1304,39 @@ bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifi keyval = wxToupper( keyval ) ; } + // Check for NUMPAD keys + if (keyval >= '0' && keyval <= '9' && keycode >= 82 && keycode <= 92) + { + keyval = keyval - '0' + WXK_NUMPAD0; + } + else if (keycode >= 67 && keycode <= 81) + { + switch (keycode) + { + case 76 : + keyval = WXK_NUMPAD_ENTER; + break; + case 81: + keyval = WXK_NUMPAD_EQUAL; + break; + case 67: + keyval = WXK_NUMPAD_MULTIPLY; + break; + case 75: + keyval = WXK_NUMPAD_DIVIDE; + break; + case 78: + keyval = WXK_NUMPAD_SUBTRACT; + break; + case 69: + keyval = WXK_NUMPAD_ADD; + break; + case 65: + keyval = WXK_NUMPAD_DECIMAL; + break; + } // end switch + } + wxKeyEvent event(wxEVT_KEY_DOWN); bool handled = false ; event.m_shiftDown = modifiers & shiftKey; @@ -1313,39 +1344,59 @@ bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifi event.m_altDown = modifiers & optionKey; event.m_metaDown = modifiers & cmdKey; event.m_keyCode = keyval ; - +#if wxUSE_UNICODE + event.m_uniChar = uniChar ; +#endif + event.m_rawCode = keymessage; + event.m_rawFlags = modifiers; event.m_x = wherex; event.m_y = wherey; - event.m_timeStamp = when; + event.SetTimestamp(when); event.SetEventObject(focus); handled = focus->GetEventHandler()->ProcessEvent( event ) ; if ( handled && event.GetSkipped() ) handled = false ; + +#if wxUSE_ACCEL if ( !handled ) { -#if wxUSE_ACCEL - if (!handled) + wxWindow *ancestor = focus; + while (ancestor) { - wxWindow *ancestor = focus; - while (ancestor) + int command = ancestor->GetAcceleratorTable()->GetCommand( event ); + if (command != -1) { - int command = ancestor->GetAcceleratorTable()->GetCommand( event ); - if (command != -1) - { - wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command ); - handled = ancestor->GetEventHandler()->ProcessEvent( command_event ); - break; - } - if (ancestor->IsTopLevel()) - break; - ancestor = ancestor->GetParent(); + wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command ); + handled = ancestor->GetEventHandler()->ProcessEvent( command_event ); + break; } + if (ancestor->IsTopLevel()) + break; + ancestor = ancestor->GetParent(); } -#endif // wxUSE_ACCEL } +#endif // wxUSE_ACCEL + if (!handled) { - event.Skip( FALSE ) ; + wxTopLevelWindowMac *tlw = focus->MacGetTopLevelWindow() ; + + if (tlw) + { + event.Skip( false ) ; + event.SetEventType( wxEVT_CHAR_HOOK ); + // raw value again + event.m_keyCode = realkeyval ; + + handled = tlw->GetEventHandler()->ProcessEvent( event ); + if ( handled && event.GetSkipped() ) + handled = false ; + } + } + + if ( !handled ) + { + event.Skip( false ) ; event.SetEventType( wxEVT_CHAR ) ; // raw value again event.m_keyCode = realkeyval ; @@ -1354,27 +1405,25 @@ bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifi if ( handled && event.GetSkipped() ) handled = false ; } - if ( !handled && - (keyval == WXK_TAB) && -// CS: copied the change below from wxGTK -// VZ: testing for wxTE_PROCESS_TAB shouldn't be done here the control may -// have this style, yet choose not to process this particular TAB in which -// case TAB must still work as a navigational character -#if 0 - (!focus->HasFlag(wxTE_PROCESS_TAB)) && -#endif - (focus->GetParent()) && - (focus->GetParent()->HasFlag( wxTAB_TRAVERSAL)) ) + if ( !handled && (keyval == WXK_TAB) ) { - wxNavigationKeyEvent new_event; - new_event.SetEventObject( focus ); - new_event.SetDirection( !event.ShiftDown() ); - /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ - new_event.SetWindowChange( event.ControlDown() ); - new_event.SetCurrentFocus( focus ); - handled = focus->GetEventHandler()->ProcessEvent( new_event ); - if ( handled && new_event.GetSkipped() ) - handled = false ; + wxWindow* iter = focus->GetParent() ; + while( iter && !handled ) + { + if ( iter->HasFlag( wxTAB_TRAVERSAL ) ) + { + wxNavigationKeyEvent new_event; + new_event.SetEventObject( focus ); + new_event.SetDirection( !event.ShiftDown() ); + /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ + new_event.SetWindowChange( event.ControlDown() ); + new_event.SetCurrentFocus( focus ); + handled = focus->GetParent()->GetEventHandler()->ProcessEvent( new_event ); + if ( handled && new_event.GetSkipped() ) + handled = false ; + } + iter = iter->GetParent() ; + } } // backdoor handler for default return and command escape if ( !handled && (!focus->IsKindOf(CLASSINFO(wxControl) ) || !focus->MacCanFocus() ) ) @@ -1394,7 +1443,7 @@ bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifi event.SetEventObject(def); def->Command(event); return true ; - } + } } /* generate wxID_CANCEL if command-. or has been pressed (typically in dialogs) */ else if (keyval == WXK_ESCAPE || (keyval == '.' && modifiers & cmdKey ) ) @@ -1408,7 +1457,7 @@ bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifi return handled ; } -bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey ) +bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) { if ( !focus ) return false ; @@ -1424,7 +1473,6 @@ bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifier UInt32 state = 0; UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state); keychar = short(keyInfo & charCodeMask); - keycode = short(keyInfo & keyCodeMask) >> 8 ; } long keyval = wxMacTranslateKey(keychar, keycode) ; @@ -1432,6 +1480,40 @@ bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifier { keyval = wxToupper( keyval ) ; } + + // Check for NUMPAD keys + if (keyval >= '0' && keyval <= '9' && keycode >= 82 && keycode <= 92) + { + keyval = keyval - '0' + WXK_NUMPAD0; + } + else if (keycode >= 67 && keycode <= 81) + { + switch (keycode) + { + case 76 : + keyval = WXK_NUMPAD_ENTER; + break; + case 81: + keyval = WXK_NUMPAD_EQUAL; + break; + case 67: + keyval = WXK_NUMPAD_MULTIPLY; + break; + case 75: + keyval = WXK_NUMPAD_DIVIDE; + break; + case 78: + keyval = WXK_NUMPAD_SUBTRACT; + break; + case 69: + keyval = WXK_NUMPAD_ADD; + break; + case 65: + keyval = WXK_NUMPAD_DECIMAL; + break; + } // end switch + } + bool handled = false ; wxKeyEvent event(wxEVT_KEY_UP); @@ -1440,10 +1522,15 @@ bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifier event.m_altDown = modifiers & optionKey; event.m_metaDown = modifiers & cmdKey; event.m_keyCode = keyval ; +#if wxUSE_UNICODE + event.m_uniChar = uniChar ; +#endif + event.m_rawCode = keymessage; + event.m_rawFlags = modifiers; event.m_x = wherex; event.m_y = wherey; - event.m_timeStamp = when; + event.SetTimestamp(when); event.SetEventObject(focus); handled = focus->GetEventHandler()->ProcessEvent( event ) ;