X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b96a8bdb6038061d99dd45642450e3c664ce7a44..421a84317fc3d53ac4fd64613f1af2d19018efc5:/src/mac/app.cpp diff --git a/src/mac/app.cpp b/src/mac/app.cpp index ecb1667576..58ee11d265 100644 --- a/src/mac/app.cpp +++ b/src/mac/app.cpp @@ -1,11 +1,11 @@ ///////////////////////////////////////////////////////////////////////////// // Name: app.cpp // Purpose: wxApp -// Author: AUTHOR +// Author: Stefan Csomor // Modified by: -// Created: ??/??/98 +// Created: 1998-01-01 // RCS-ID: $Id$ -// Copyright: (c) AUTHOR +// Copyright: (c) Stefan Csomor // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -36,9 +36,7 @@ #include "wx/tooltip.h" #include "wx/textctrl.h" #include "wx/menu.h" -#if wxUSE_WX_RESOURCES -# include "wx/resource.h" -#endif +#include "wx/docview.h" #include @@ -68,19 +66,28 @@ # include #endif -extern char *wxBuffer; extern wxList wxPendingDelete; extern wxList *wxWinMacWindowList; extern wxList *wxWinMacControlList; -wxApp *wxTheApp = NULL; +// statics for implementation + +static bool s_inYield = FALSE; +static bool s_inOnIdle = FALSE; + +#if TARGET_CARBON +static bool s_inReceiveEvent = FALSE ; +static EventTime sleepTime = kEventDurationNoWait ; +#else +static long sleepTime = 0 ; +#endif #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) + EVT_END_SESSION(wxApp::OnEndSession) + EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession) END_EVENT_TABLE() #endif @@ -101,290 +108,375 @@ long wxApp::s_lastModifiers = 0 ; bool wxApp::s_macDefaultEncodingIsPC = true ; bool wxApp::s_macSupportPCMenuShortcuts = true ; long wxApp::s_macAboutMenuItemId = wxID_ABOUT ; -wxString wxApp::s_macHelpMenuTitleName = "&Help" ; +long wxApp::s_macPreferencesMenuItemId = 0 ; +long wxApp::s_macExitMenuItemId = wxID_EXIT ; +wxString wxApp::s_macHelpMenuTitleName = wxT("&Help") ; + +//---------------------------------------------------------------------- +// Core Apple Event Support +//---------------------------------------------------------------------- pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ; 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 AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) { - // GD: UNUSED wxApp* app = (wxApp*) refcon ; return wxTheApp->MacHandleAEODoc( (AppleEvent*) event , reply) ; } pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) { - // GD: UNUSED wxApp* app = (wxApp*) refcon ; return wxTheApp->MacHandleAEOApp( (AppleEvent*) event , reply ) ; } pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) { - // GD: UNUSED wxApp* app = (wxApp*) refcon ; return wxTheApp->MacHandleAEPDoc( (AppleEvent*) event , reply ) ; } pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) { - // GD: UNUSED wxApp* app = (wxApp*) refcon ; return wxTheApp->MacHandleAEQuit( (AppleEvent*) event , reply) ; } -short wxApp::MacHandleAEODoc(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply)) +// AEODoc Calls MacOpenFile on each of the files passed + +short wxApp::MacHandleAEODoc(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply)) { - SysBeep(40) ; + AEDescList docList; + AEKeyword keywd; + DescType returnedType; + Size actualSize; + long itemsInList; + FSSpec theSpec; + OSErr err; + short i; + err = AEGetParamDesc((AppleEvent *)event, keyDirectObject, typeAEList,&docList); + if (err != noErr) + return err; + + err = AECountItems(&docList, &itemsInList); + if (err != noErr) + return err; + ProcessSerialNumber PSN ; PSN.highLongOfPSN = 0 ; PSN.lowLongOfPSN = kCurrentProcess ; SetFrontProcess( &PSN ) ; - return noErr ; + + for (i = 1; i <= itemsInList; i++) { + AEGetNthPtr(&docList, i, typeFSS, &keywd, &returnedType, + (Ptr) & theSpec, sizeof(theSpec), &actualSize); + wxString fName = wxMacFSSpec2MacFilename(&theSpec); + MacOpenFile(fName); + } + return noErr; } -short wxApp::MacHandleAEPDoc(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply)) +// AEPDoc Calls MacPrintFile on each of the files passed + +short wxApp::MacHandleAEPDoc(const WXEVENTREF event , WXEVENTREF WXUNUSED(reply)) { - return noErr ; + AEDescList docList; + AEKeyword keywd; + DescType returnedType; + Size actualSize; + long itemsInList; + FSSpec theSpec; + OSErr err; + short i; + err = AEGetParamDesc((AppleEvent *)event, keyDirectObject, typeAEList,&docList); + if (err != noErr) + return err; + + err = AECountItems(&docList, &itemsInList); + if (err != noErr) + return err; + + ProcessSerialNumber PSN ; + PSN.highLongOfPSN = 0 ; + 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); + MacPrintFile(fName); + } + return noErr; } +// AEOApp calls MacNewFile + short wxApp::MacHandleAEOApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply)) { + MacNewFile() ; return noErr ; } +// AEQuit attempts to quit the application + short wxApp::MacHandleAEQuit(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply)) { - wxWindow* win = GetTopWindow() ; + /* wxWindow* win = GetTopWindow() ; if ( win ) { win->Close(TRUE ) ; } else + */ { ExitMainLoop() ; } return noErr ; } -char StringMac[] = "\x0d\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" - "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" - "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf" - "\xb1\xb4\xb5\xb6\xbb\xbc\xbe\xbf" - "\xc0\xc1\xc2\xc4\xc7\xc8\xc9\xcb\xcc\xcd\xce\xcf" - "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xca\xdb" ; - -char StringANSI[] = "\x0a\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8" - "\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC" - "\x86\xBA\xA2\xA3\xA7\x95\xB6\xDF\xAE\xA9\x99\xB4\xA8\xC6\xD8" - "\xB1\xA5\xB5\xF0\xAA\xBA\xE6\xF8" - "\xBF\xA1\xAC\x83\xAB\xBB\x85\xC0\xC3\xD5\x8C\x9C" - "\x96\x97\x93\x94\x91\x92\xF7\xFF\xA0\x80" ; - -void wxMacConvertFromPC( const char *from , char *to , int len ) +//---------------------------------------------------------------------- +// Support Routines linking the Mac...File Calls to the Document Manager +//---------------------------------------------------------------------- + +void wxApp::MacOpenFile(const wxString & fileName ) { - char *c ; - if ( from == to ) - { - for( int i = 0 ; i < len ; ++ i ) - { - c = strchr( StringANSI , *from ) ; - if ( c != NULL ) - { - *to = StringMac[ c - StringANSI] ; - } - ++to ; - ++from ; - } - } - else - { - for( int i = 0 ; i < len ; ++ i ) - { - c = strchr( StringANSI , *from ) ; - if ( c != NULL ) - { - *to = StringMac[ c - StringANSI] ; - } - else - { - *to = *from ; - } - ++to ; - ++from ; - } - } + wxDocManager* dm = wxDocManager::GetDocumentManager() ; + if ( dm ) + dm->CreateDocument(fileName , wxDOC_SILENT ) ; } -void wxMacConvertToPC( const char *from , char *to , int len ) +void wxApp::MacPrintFile(const wxString & fileName ) { - char *c ; - if ( from == to ) + wxDocManager* dm = wxDocManager::GetDocumentManager() ; + if ( dm ) { - for( int i = 0 ; i < len ; ++ i ) + wxDocument *doc = dm->CreateDocument(fileName , wxDOC_SILENT ) ; + if ( doc ) { - c = strchr( StringMac , *from ) ; - if ( c != NULL ) + wxView* view = doc->GetFirstView() ; + if( view ) { - *to = StringANSI[ c - StringMac] ; - } - ++to ; - ++from ; - } - } - else - { - for( int i = 0 ; i < len ; ++ i ) - { - c = strchr( StringMac , *from ) ; - if ( c != NULL ) - { - *to = StringANSI[ c - StringMac] ; + wxPrintout *printout = view->OnCreatePrintout(); + if (printout) + { + wxPrinter printer; + printer.Print(view->GetFrame(), printout, TRUE); + delete printout; + } } - else + if (doc->Close()) { - *to = *from ; + doc->DeleteAllViews(); + dm->RemoveDocument(doc) ; } - ++to ; - ++from ; } } } -void wxMacConvertFromPC( char * p ) +void wxApp::MacNewFile() { - char *ptr = p ; - int len = strlen ( p ) ; - - wxMacConvertFromPC( ptr , ptr , len ) ; } -void wxMacConvertFromPCForControls( char * p ) -{ - char *ptr = p ; - int len = strlen ( p ) ; +//---------------------------------------------------------------------- +// Carbon Event Handler +//---------------------------------------------------------------------- - wxMacConvertFromPC( ptr , ptr , len ) ; - for ( unsigned int i = 0 ; i < strlen ( ptr ) ; i++ ) +#if TARGET_CARBON + + static const EventTypeSpec eventList[] = { - if ( ptr[i] == '&' && ptr[i]+1 != ' ' ) - { - memmove( &ptr[i] , &ptr[i+1] , strlen( &ptr[i+1] ) + 1) ; - } - } -} + { kEventClassCommand, kEventProcessCommand } , + { kEventClassCommand, kEventCommandUpdateStatus } , + + { kEventClassMenu, kEventMenuOpening }, + { kEventClassMenu, kEventMenuClosed }, + + { kEventClassApplication , kEventAppActivated } , + { kEventClassApplication , kEventAppDeactivated } , + // handling the quit event is not recommended by apple + // rather using the quit apple event - which we do -void wxMacConvertFromPC( unsigned char *p ) + { kEventClassAppleEvent , kEventAppleEvent } , + + { kEventClassMouse , kEventMouseDown } , + { 'WXMC' , 'WXMC' } + } ; + +static pascal OSStatus +MenuEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { - char *ptr = (char*) p + 1 ; - int len = p[0] ; + // FIXME: this doesn't work for multiple windows + wxWindow *win = wxTheApp->GetTopWindow(); + 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 + + wxMenuEvent wxevent(GetEventKind(event) == kEventMenuOpening + ? wxEVT_MENU_OPEN + : wxEVT_MENU_CLOSE); + wxevent.SetEventObject(win); + + (void)win->GetEventHandler()->ProcessEvent(wxevent); + } - wxMacConvertFromPC( ptr , ptr , len ) ; + return eventNotHandledErr; } -extern char *wxBuffer ; +// 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 -wxString wxMacMakeMacStringFromPC( const char * p ) +static pascal OSStatus MouseEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { - const char *ptr = p ; - int len = strlen ( p ) ; - char *buf = wxBuffer ; + OSStatus result = eventNotHandledErr ; - if ( len >= BUFSIZ + 512 ) + switch( GetEventKind(event) ) { - buf = new char [len+1] ; + case kEventMouseDown : + { + Point point ; + WindowRef window ; + + GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL, + sizeof( Point ), NULL, &point ); + short windowPart = ::FindWindow(point, &window); + + if ( windowPart == inMenuBar ) + { + MenuSelect( point ) ; + result = noErr ; + } + } + break ; } - wxMacConvertFromPC( ptr , buf , len ) ; - buf[len] = 0 ; - wxString result( buf ) ; - if ( buf != wxBuffer ) - delete buf ; return result ; } - -void wxMacConvertToPC( char * p ) +static pascal OSStatus CommandEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { - char *ptr = p ; - int len = strlen ( p ) ; + OSStatus result = eventNotHandledErr ; - wxMacConvertToPC( ptr , ptr , len ) ; -} + HICommand command ; -void wxMacConvertToPC( unsigned char *p ) -{ - char *ptr = (char*) p + 1 ; - int len = p[0] ; + GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL, + sizeof( HICommand ), NULL, &command ); - wxMacConvertToPC( ptr , ptr , len ) ; -} + MenuCommand id = command.commandID ; + if ( id == kHICommandPreferences ) + id = wxApp::s_macPreferencesMenuItemId ; -wxString wxMacMakePCStringFromMac( const char * p ) -{ - const char *ptr = p ; - int len = strlen ( p ) ; - char *buf = wxBuffer ; + wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ; + wxMenu* menu = NULL ; + wxMenuItem* item = NULL ; - if ( len >= BUFSIZ + 512 ) - { - buf = new char [len+1] ; - } + if ( mbar ) + item = mbar->FindItem( id , &menu ) ; - wxMacConvertToPC( ptr , buf , len ) ; - buf[len] = 0 ; + if ( item == NULL || menu == NULL || mbar == NULL ) + return result ; + + switch( GetEventKind( event ) ) + { + case kEventProcessCommand : + { + if (item->IsCheckable()) + { + item->Check( !item->IsChecked() ) ; + } + + menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ; + result = noErr ; + } + break ; + case kEventCommandUpdateStatus: + // eventually trigger an updateui round + result = noErr ; + break ; + default : + break ; + } - wxString result( buf ) ; - if ( buf != wxBuffer ) - delete buf ; return result ; } -wxString wxMacMakeStringFromMacString( const char* from , bool mac2pcEncoding ) +static pascal OSStatus ApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { - if (mac2pcEncoding) - { - return wxMacMakePCStringFromMac( from ) ; - } - else + OSStatus result = eventNotHandledErr ; + switch ( GetEventKind( event ) ) { - return wxString( from ) ; + case kEventAppActivated : + { + if ( wxTheApp ) + wxTheApp->MacResume( true ) ; + result = noErr ; + } + break ; + case kEventAppDeactivated : + { + if ( wxTheApp ) + wxTheApp->MacSuspend( true ) ; + result = noErr ; + } + break ; + default : + break ; } + return result ; } -wxString wxMacMakeStringFromPascal( StringPtr from , bool mac2pcEncoding ) +pascal OSStatus wxAppEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { - // this is safe since a pascal string can never be larger than 256 bytes - char s[256] ; - CopyPascalStringToC( from , s ) ; - if (mac2pcEncoding) - { - return wxMacMakePCStringFromMac( s ) ; - } - else + OSStatus result = eventNotHandledErr ; + switch( GetEventClass( event ) ) { - return wxString( s ) ; + case kEventClassCommand : + result = CommandEventHandler( handler , event , data ) ; + break ; + case kEventClassApplication : + result = ApplicationEventHandler( handler , event , data ) ; + break ; + case kEventClassMenu : + result = MenuEventHandler( handler , event , data ) ; + break ; + case kEventClassMouse : + result = MouseEventHandler( handler , event , data ) ; + break ; + case kEventClassAppleEvent : + { + EventRecord rec ; + wxMacConvertEventToRecord( event , &rec ) ; + result = AEProcessAppleEvent( &rec ) ; + } + break ; + default : + break ; } -} -void wxMacStringToPascal( const char * from , StringPtr to , bool pc2macEncoding ) -{ - if (pc2macEncoding) - { - CopyCStringToPascal( wxMacMakeMacStringFromPC( from ) , to ) ; - } - else - { - CopyCStringToPascal( from , to ) ; - } + return result ; } +DEFINE_ONE_SHOT_HANDLER_GETTER( wxAppEventHandler ) + +#endif + #if defined(WXMAKINGDLL) && !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 ; @@ -400,34 +492,6 @@ bool wxApp::Initialize() wxStAppResource::OpenSharedLibraryResource(NULL); #endif -#if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340) - AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments , - NewAEEventHandlerUPP(AEHandleODoc) , - (long) wxTheApp , FALSE ) ; - AEInstallEventHandler( kCoreEventClass , kAEOpenApplication , - NewAEEventHandlerUPP(AEHandleOApp) , - (long) wxTheApp , FALSE ) ; - AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments , - NewAEEventHandlerUPP(AEHandlePDoc) , - (long) wxTheApp , FALSE ) ; - AEInstallEventHandler( kCoreEventClass , kAEQuitApplication , - NewAEEventHandlerUPP(AEHandleQuit) , - (long) wxTheApp , FALSE ) ; -#else - AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments , - NewAEEventHandlerProc(AEHandleODoc) , - (long) wxTheApp , FALSE ) ; - AEInstallEventHandler( kCoreEventClass , kAEOpenApplication , - NewAEEventHandlerProc(AEHandleOApp) , - (long) wxTheApp , FALSE ) ; - AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments , - NewAEEventHandlerProc(AEHandlePDoc) , - (long) wxTheApp , FALSE ) ; - AEInstallEventHandler( kCoreEventClass , kAEQuitApplication , - NewAEEventHandlerProc(AEHandleQuit) , - (long) wxTheApp , FALSE ) ; -#endif - #ifndef __DARWIN__ // test the minimal configuration necessary @@ -490,151 +554,115 @@ bool wxApp::Initialize() #ifndef __DARWIN__ // now avoid exceptions thrown for new (bad_alloc) - std::__throws_bad_alloc = FALSE ; + // FIXME CS for some changes outside wxMac does not compile anymore +#if 0 + std::__throws_bad_alloc = 0 ; #endif - s_macCursorRgn = ::NewRgn() ; - - wxBuffer = new char[BUFSIZ + 512]; - - wxClassInfo::InitializeClasses(); - -#if wxUSE_RESOURCES -// wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion); #endif + wxMacSetupConverters() ; -#if wxUSE_THREADS - wxPendingEventsLocker = new wxCriticalSection; -#endif + s_macCursorRgn = ::NewRgn() ; - wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING); - wxTheColourDatabase->Initialize(); + // 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, sizeof(ARG_PSN) - 1) == 0 ) + { + // remove this argument + memmove(argv, argv + 1, argc--); + } + } -#ifdef __WXDEBUG__ -#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 -#endif + if ( !wxAppBase::Initialize(argc, argv) ) + return false; - wxWinMacWindowList = new wxList(wxKEY_INTEGER); - wxWinMacControlList = new wxList(wxKEY_INTEGER); + wxWinMacWindowList = new wxList(wxKEY_INTEGER); + wxWinMacControlList = new wxList(wxKEY_INTEGER); - wxInitializeStockLists(); - wxInitializeStockObjects(); + wxMacCreateNotifierTable() ; -#if wxUSE_WX_RESOURCES - wxInitializeResourceSystem(); -#endif + UMAShowArrowCursor() ; - wxBitmap::InitStandardHandlers(); + return true; +} - wxModule::RegisterModules(); - if (!wxModule::InitializeModules()) { - return FALSE; - } +bool wxApp::OnInitGui() +{ + if( !wxAppBase::OnInitGui() ) + return false ; - wxMacCreateNotifierTable() ; +#if TARGET_CARBON + InstallStandardEventHandler( GetApplicationEventTarget() ) ; + InstallApplicationEventHandler( + GetwxAppEventHandlerUPP(), + GetEventTypeCount(eventList), eventList, wxTheApp, (EventHandlerRef *)&(wxTheApp->m_macEventHandler)); +#endif - UMAShowArrowCursor() ; +#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 ) ; +#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 ) ; +#endif - return TRUE; + 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(); - -#if wxUSE_WX_RESOURCES - wxCleanUpResourceSystem(); -#endif - - wxDeleteStockObjects() ; - - // Destroy all GDI lists, etc. - wxDeleteStockLists(); - - delete wxTheColourDatabase; - wxTheColourDatabase = NULL; - - wxBitmap::CleanUpHandlers(); - - delete[] wxBuffer; - wxBuffer = NULL; - wxMacDestroyNotifierTable() ; - if (wxWinMacWindowList) { - delete wxWinMacWindowList ; - } - if (wxWinMacControlList) { - delete wxWinMacControlList ; - } - delete wxPendingEvents; -#if wxUSE_THREADS - delete wxPendingEventsLocker; - // 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) - ProfilerDump( "\papp.prof" ) ; + ProfilerDump( (StringPtr)"\papp.prof" ) ; ProfilerTerm() ; # 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__) // 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) { @@ -644,10 +672,12 @@ void wxApp::CleanUp() #if 0 TerminateAE() ; #endif + + wxAppBase::CleanUp(); } //---------------------------------------------------------------------- -// wxEntry +// misc initialization stuff //---------------------------------------------------------------------- // extern variable for shared library resource id @@ -723,6 +753,16 @@ void wxStAppResource::OpenSharedLibraryResource(const void *initBlock) 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 theResPath = strdup(theLibPath); if (theResPath != NULL) { @@ -736,7 +776,10 @@ void wxStAppResource::OpenSharedLibraryResource(const void *initBlock) // overwrite extension with ".rsrc" strcpy(theExt, ".rsrc"); - wxLogDebug( theResPath ); +#if 0 + wxLogDebug( wxT("wxMac resources file name is '%s'"), + theResPath ); +#endif theErr = FSPathMakeRef((UInt8 *) theResPath, &theResRef, false); if (theErr != noErr) { @@ -744,14 +787,21 @@ void wxStAppResource::OpenSharedLibraryResource(const void *initBlock) theErr = FSPathMakeRef((UInt8 *) theName, &theResRef, false); } - // free duplicated resource file path - free(theResPath); - // open the resource file if (theErr == noErr) { theErr = FSOpenResourceFile( &theResRef, 0, NULL, fsRdPerm, &gSharedLibraryResource); } + if (theErr != noErr) { +#ifdef __WXDEBUG__ + fprintf(stderr, + wxT("unable to open wxMac resource file '%s'\n"), + theResPath ); +#endif // __WXDEBUG__ + } + + // free duplicated resource file path + free(theResPath); } } #endif /* __DARWIN__ */ @@ -787,7 +837,7 @@ void wxStAppResource::CloseSharedLibraryResource() // the __wxinitialize and __wxterminate must be used extern "C" { - void __sinit(void); /* (generated by linker) */ + void __sinit(void); /* (generated by linker) */ pascal OSErr __initialize(const CFragInitBlock *theInitBlock); pascal void __terminate(void); } @@ -806,119 +856,6 @@ pascal void __wxterminate(void) #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) { - char theArg[6] = ""; - strncpy(theArg, argv[1], 5); - - if (strcmp(theArg, "-psn_") == 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; - wxTheApp->argv = argv; - - // 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; -} - #if TARGET_CARBON bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) @@ -999,6 +936,7 @@ bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) return converted ; } +/* pascal OSStatus wxMacApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { OSStatus result = eventNotHandledErr ; @@ -1027,42 +965,14 @@ pascal OSStatus wxMacApplicationEventHandler( EventHandlerCallRef handler , Even } return result ; } - -#endif - -bool wxApp::OnInit() -{ - if ( ! wxAppBase::OnInit() ) - return FALSE ; - -#if 0 // TARGET_CARBON - static const EventTypeSpec eventList[] = - { - { kEventClassKeyboard, kEventRawKeyDown } , - { kEventClassKeyboard, kEventRawKeyRepeat } , - { kEventClassKeyboard, kEventRawKeyUp } , - { kEventClassKeyboard, kEventRawKeyModifiersChanged } , - - { kEventClassTextInput , kEventTextInputUnicodeForKeyEvent } , - } ; - - InstallApplicationEventHandler(NewEventHandlerUPP(wxMacApplicationEventHandler) - , WXSIZEOF(eventList), eventList, this, NULL); +*/ #endif - return TRUE ; -} -// 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; @@ -1080,37 +990,31 @@ bool wxApp::Initialized() int wxApp::MainLoop() { - m_keepGoing = TRUE; + m_keepGoing = TRUE; - while (m_keepGoing) - { + while (m_keepGoing) + { MacDoOneEvent() ; - } - - return 0; -} - -// Returns TRUE if more time is needed. -bool wxApp::ProcessIdle() -{ - wxIdleEvent event; - event.SetEventObject(this); - ProcessEvent(event); + } - return event.MoreRequested(); + return 0; } void wxApp::ExitMainLoop() { - m_keepGoing = FALSE; + m_keepGoing = FALSE; } // Is a message/event pending? bool wxApp::Pending() { +#if TARGET_CARBON + return GetNumEventsInQueue( GetMainEventQueue() ) > 0 ; +#else EventRecord event ; - return EventAvail( everyEvent , &event ) ; + return EventAvail( everyEvent , &event ) ; +#endif } // Dispatch a message. @@ -1119,106 +1023,26 @@ void wxApp::Dispatch() MacDoOneEvent() ; } -void wxApp::OnIdle(wxIdleEvent& event) -{ - static bool s_inOnIdle = FALSE; - - // 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); - - // 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; -} - -void wxWakeUpIdle() -{ - wxMacWakeUp() ; -} - -// Send idle event to all top-level windows -bool wxApp::SendIdleEvents() -{ - bool needMore = FALSE; - wxNode* node = wxTopLevelWindows.First(); - while (node) - { - wxWindow* win = (wxWindow*) node->Data(); - if (SendIdleEvents(win)) - needMore = TRUE; - - node = node->Next(); - } - 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; - - wxNode* node = win->GetChildren().First(); - while (node) - { - wxWindow* win = (wxWindow*) node->Data(); - if (SendIdleEvents(win)) - needMore = TRUE; - - node = node->Next(); - } - return needMore ; -} - -void wxApp::DeletePendingObjects() +void wxApp::OnIdle(wxIdleEvent& event) { - wxNode *node = wxPendingDelete.First(); - while (node) - { - wxObject *obj = (wxObject *)node->Data(); - - delete obj; - - if (wxPendingDelete.Member(obj)) - delete node; + 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(); - // Deleting one object may have deleted other pending - // objects, so start from beginning of list again. - node = wxPendingDelete.First(); - } + if(!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar()) + wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar(); } -void wxExit() +void wxApp::WakeUpIdle() { - wxLogError(_("Fatal error: exiting")); + wxMacWakeUp() ; +} +void wxApp::Exit() +{ wxApp::CleanUp(); ::ExitToShell() ; } @@ -1250,8 +1074,6 @@ void wxCYield() bool wxApp::Yield(bool onlyIfNeeded) { - static bool s_inYield = FALSE; - if (s_inYield) { if ( !onlyIfNeeded ) @@ -1267,21 +1089,52 @@ bool wxApp::Yield(bool onlyIfNeeded) #if wxUSE_THREADS YieldToAnyThread() ; #endif + // by definition yield should handle all non-processed events +#if TARGET_CARBON + EventRef theEvent; + + OSStatus status = noErr ; + do + { + 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 + { + MacHandleOneEvent( theEvent ) ; + ReleaseEvent(theEvent); + } + } while( status == noErr ) ; +#else EventRecord event ; - long sleepTime = 1 ; //::GetCaretTime(); + // having a larger value here leads to large performance slowdowns + // so we cannot give background apps more processor time here + // we do so however having a large sleep value in the main event loop + sleepTime = 0 ; - while ( !wxTheApp->IsExiting() && WaitNextEvent(everyEvent, &event,sleepTime, (RgnHandle) wxApp::s_macCursorRgn)) + while ( !IsExiting() && WaitNextEvent(everyEvent, &event,sleepTime, (RgnHandle) wxApp::s_macCursorRgn)) { - wxTheApp->MacHandleModifierEvents( &event ) ; - wxTheApp->MacHandleOneEvent( &event ); + MacHandleModifierEvents( &event ) ; + MacHandleOneEvent( &event ); if ( event.what != kHighLevelEvent ) SetRectRgn( (RgnHandle) wxApp::s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ; } - wxTheApp->MacHandleModifierEvents( &event ) ; + MacHandleModifierEvents( &event ) ; +#endif wxMacProcessNotifierAndPendingEvents() ; - s_inYield = FALSE; return TRUE; @@ -1291,24 +1144,31 @@ bool wxApp::Yield(bool onlyIfNeeded) void wxApp::MacSuspend( bool convertClipboard ) { +#if !TARGET_CARBON // we have to deactive the top level windows manually - wxNode* node = wxTopLevelWindows.First(); + wxWindowListNode* node = wxTopLevelWindows.GetFirst(); while (node) { wxTopLevelWindow* win = (wxTopLevelWindow*) node->Data(); - win->MacActivate( MacGetCurrentEvent() , false ) ; +#if TARGET_CARBON +#if 0 // having problems right now with that + if (!win->HasFlag(wxSTAY_ON_TOP)) +#endif +#endif + win->MacActivate( ((EventRecord*) MacGetCurrentEvent())->when , false ) ; - node = node->Next(); + node = node->GetNext(); } + ::HideFloatingWindows() ; +#endif s_lastMouseDown = 0 ; + if( convertClipboard ) { MacConvertPrivateToPublicScrap() ; } - - ::HideFloatingWindows() ; } extern wxList wxModalDialogs; @@ -1321,18 +1181,19 @@ void wxApp::MacResume( bool convertClipboard ) MacConvertPublicToPrivateScrap() ; } +#if !TARGET_CARBON ::ShowFloatingWindows() ; - // raise modal dialogs in case a non modal window was selected to activate the app - wxNode* node = wxModalDialogs.First(); + wxNode* node = wxModalDialogs.GetFirst(); while (node) { - wxDialog* dialog = (wxDialog *) node->Data(); + wxDialog* dialog = (wxDialog *) node->GetData(); dialog->Raise(); - node = node->Next(); + node = node->GetNext(); } +#endif } void wxApp::MacConvertPrivateToPublicScrap() @@ -1345,11 +1206,36 @@ void wxApp::MacConvertPublicToPrivateScrap() void wxApp::MacDoOneEvent() { - EventRecord event ; +#if TARGET_CARBON + EventRef theEvent; + + s_inReceiveEvent = true ; + OSStatus status = ReceiveNextEvent(0, NULL,sleepTime,true,&theEvent) ; + s_inReceiveEvent = false ; + if ( status == eventLoopTimedOutErr ) + { + if ( wxTheApp->ProcessIdle() ) + sleepTime = kEventDurationNoWait ; + else + sleepTime = kEventDurationForever ; + } + else if ( status == eventLoopQuitErr ) + { + // according to QA1061 this may also occur when a WakeUp Process + // is executed + } + else + { + MacHandleOneEvent( theEvent ) ; + ReleaseEvent(theEvent); + sleepTime = kEventDurationNoWait ; + } +#else + EventRecord event ; - long sleepTime = 1; // GetCaretTime() / 4 ; + EventMask eventMask = everyEvent ; - if (WaitNextEvent(everyEvent, &event, sleepTime, (RgnHandle) s_macCursorRgn)) + if (WaitNextEvent(eventMask, &event, sleepTime, (RgnHandle) s_macCursorRgn)) { MacHandleModifierEvents( &event ) ; MacHandleOneEvent( &event ); @@ -1362,74 +1248,28 @@ void wxApp::MacDoOneEvent() if ( window ) ::IdleControls( window ) ; - wxTheApp->ProcessIdle() ; + if ( wxTheApp->ProcessIdle() ) + sleepTime = 0 ; + else + sleepTime = GetCaretTime() / 2 ; } if ( event.what != kHighLevelEvent ) SetRectRgn( (RgnHandle) s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ; - +#endif // repeaters DeletePendingObjects() ; wxMacProcessNotifierAndPendingEvents() ; } -void wxApp::MacHandleModifierEvents( WXEVENTREF evr ) -{ - EventRecord* ev = (EventRecord*) evr ; -#if TARGET_CARBON - if ( ev->what == mouseDown || ev->what == mouseUp || ev->what == activateEvt || - ev->what == keyDown || ev->what == autoKey || ev->what == keyUp || ev->what == nullEvent ) - { - // in these cases the modifiers are already correctly setup by carbon - } - else - { - EventRecord nev ; - WaitNextEvent( 0 , &nev , 0 , NULL ) ; - ev->modifiers = nev.modifiers ; - // KeyModifiers unfortunately don't include btnState... -// ev->modifiers = GetCurrentKeyModifiers() ; - } -#endif - if ( ev->modifiers != s_lastModifiers && wxWindow::FindFocus() != NULL ) - { - wxKeyEvent event(wxEVT_KEY_DOWN); - - event.m_shiftDown = ev->modifiers & shiftKey; - event.m_controlDown = ev->modifiers & controlKey; - event.m_altDown = ev->modifiers & optionKey; - event.m_metaDown = ev->modifiers & cmdKey; - - event.m_x = ev->where.h; - event.m_y = ev->where.v; - event.m_timeStamp = ev->when; - wxWindow* focus = wxWindow::FindFocus() ; - event.SetEventObject(focus); - - if ( (ev->modifiers ^ s_lastModifiers ) & controlKey ) - { - event.m_keyCode = WXK_CONTROL ; - event.SetEventType( ( ev->modifiers & controlKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ; - focus->GetEventHandler()->ProcessEvent( event ) ; - } - if ( (ev->modifiers ^ s_lastModifiers ) & shiftKey ) - { - event.m_keyCode = WXK_SHIFT ; - event.SetEventType( ( ev->modifiers & shiftKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ; - focus->GetEventHandler()->ProcessEvent( event ) ; - } - if ( (ev->modifiers ^ s_lastModifiers ) & optionKey ) - { - event.m_keyCode = WXK_ALT ; - event.SetEventType( ( ev->modifiers & optionKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ; - focus->GetEventHandler()->ProcessEvent( event ) ; - } - s_lastModifiers = ev->modifiers ; - } -} - void wxApp::MacHandleOneEvent( WXEVENTREF evr ) { +#if TARGET_CARBON + EventTargetRef theTarget; + theTarget = GetEventDispatcherTarget(); + m_macCurrentEvent = evr ; + SendEventToEventTarget ((EventRef) evr , theTarget); +#else EventRecord* ev = (EventRecord*) evr ; m_macCurrentEvent = ev ; @@ -1481,17 +1321,63 @@ void wxApp::MacHandleOneEvent( WXEVENTREF evr ) default: break; } +#endif wxMacProcessNotifierAndPendingEvents() ; } +#if !TARGET_CARBON +bool s_macIsInModalLoop = false ; + +void wxApp::MacHandleModifierEvents( WXEVENTREF evr ) +{ + EventRecord* ev = (EventRecord*) evr ; + if ( ev->modifiers != s_lastModifiers && wxWindow::FindFocus() != NULL ) + { + wxKeyEvent event(wxEVT_KEY_DOWN); + + event.m_shiftDown = ev->modifiers & shiftKey; + event.m_controlDown = ev->modifiers & controlKey; + event.m_altDown = ev->modifiers & optionKey; + event.m_metaDown = ev->modifiers & cmdKey; + + event.m_x = ev->where.h; + event.m_y = ev->where.v; + event.m_timeStamp = ev->when; + wxWindow* focus = wxWindow::FindFocus() ; + event.SetEventObject(focus); + + if ( (ev->modifiers ^ s_lastModifiers ) & controlKey ) + { + event.m_keyCode = WXK_CONTROL ; + event.SetEventType( ( ev->modifiers & controlKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ; + focus->GetEventHandler()->ProcessEvent( event ) ; + } + if ( (ev->modifiers ^ s_lastModifiers ) & shiftKey ) + { + event.m_keyCode = WXK_SHIFT ; + event.SetEventType( ( ev->modifiers & shiftKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ; + focus->GetEventHandler()->ProcessEvent( event ) ; + } + if ( (ev->modifiers ^ s_lastModifiers ) & optionKey ) + { + event.m_keyCode = WXK_ALT ; + event.SetEventType( ( ev->modifiers & optionKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ; + focus->GetEventHandler()->ProcessEvent( event ) ; + } + s_lastModifiers = ev->modifiers ; + } +} + void wxApp::MacHandleHighLevelEvent( WXEVENTREF evr ) { + // we must avoid reentrancy problems when processing high level events eg printing + bool former = s_inYield ; + s_inYield = TRUE ; EventRecord* ev = (EventRecord*) evr ; ::AEProcessAppleEvent( ev ) ; + s_inYield = former ; } -bool s_macIsInModalLoop = false ; - void wxApp::MacHandleMouseDownEvent( WXEVENTREF evr ) { EventRecord* ev = (EventRecord*) evr ; @@ -1521,16 +1407,14 @@ void wxApp::MacHandleMouseDownEvent( WXEVENTREF evr ) else { UInt32 menuresult = MenuSelect(ev->where) ; - MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ); + MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ); s_lastMouseDown = 0; } break ; -#if !TARGET_CARBON case inSysWindow : SystemClick( ev , window ) ; s_lastMouseDown = 0; break ; -#endif case inDrag : if ( window != frontWindow && s_macIsInModalLoop && !(ev->modifiers & cmdKey ) ) { @@ -1563,23 +1447,28 @@ void wxApp::MacHandleMouseDownEvent( WXEVENTREF evr ) break; case inGrow: { - int growResult = GrowWindow(window , ev->where, &screenBits.bounds); - if (growResult != 0) + Rect newContentRect ; + Rect constraintRect ; + constraintRect.top = win->GetMinHeight() ; + if ( constraintRect.top == -1 ) + constraintRect.top = 0 ; + constraintRect.left = win->GetMinWidth() ; + if ( constraintRect.left == -1 ) + constraintRect.left = 0 ; + constraintRect.right = win->GetMaxWidth() ; + if ( constraintRect.right == -1 ) + constraintRect.right = 32000 ; + constraintRect.bottom = win->GetMaxHeight() ; + if ( constraintRect.bottom == -1 ) + constraintRect.bottom = 32000 ; + + Boolean growResult = ResizeWindow( window , ev->where , + &constraintRect , &newContentRect ) ; + if ( growResult ) { - int newWidth = LoWord(growResult); - int newHeight = HiWord(growResult); - int oldWidth, oldHeight; - - - if (win) - { - win->GetSize(&oldWidth, &oldHeight); - if (newWidth == 0) - newWidth = oldWidth; - if (newHeight == 0) - newHeight = oldHeight; - win->SetSize( -1, -1 , newWidth, newHeight, wxSIZE_USE_EXISTING); - } + win->SetSize( newContentRect.left , newContentRect.top , + newContentRect.right - newContentRect.left , + newContentRect.bottom - newContentRect.top, wxSIZE_USE_EXISTING); } s_lastMouseDown = 0; } @@ -1643,7 +1532,6 @@ void wxApp::MacHandleMouseDownEvent( WXEVENTREF evr ) win->MacMouseDown( ev , windowPart ) ; } break ; - default: break; } @@ -1655,15 +1543,15 @@ void wxApp::MacHandleMouseUpEvent( WXEVENTREF evr ) WindowRef window; short windowPart = inNoWindow ; - if ( wxTheApp->s_captureWindow ) - { - window = (WindowRef) s_captureWindow->MacGetRootWindow() ; - windowPart = inContent ; - } - else - { - windowPart = ::FindWindow(ev->where, &window) ; - } + if ( wxTheApp->s_captureWindow ) + { + window = (WindowRef) s_captureWindow->MacGetRootWindow() ; + windowPart = inContent ; + } + else + { + windowPart = ::FindWindow(ev->where, &window) ; + } switch (windowPart) { @@ -1681,6 +1569,8 @@ void wxApp::MacHandleMouseUpEvent( WXEVENTREF evr ) } } +#endif + long wxMacTranslateKey(unsigned char key, unsigned char code) ; long wxMacTranslateKey(unsigned char key, unsigned char code) { @@ -1790,6 +1680,7 @@ long wxMacTranslateKey(unsigned char key, unsigned char code) return retval; } +#if !TARGET_CARBON void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr ) { EventRecord* ev = (EventRecord*) evr ; @@ -1804,7 +1695,7 @@ void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr ) else { wxWindow* focus = wxWindow::FindFocus() ; - + if ( MacSendKeyDownEvent( focus , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) == false ) { // has not been handled -> perform default @@ -1821,16 +1712,33 @@ void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr ) } } +void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr ) +{ + EventRecord* ev = (EventRecord*) evr ; + wxToolTip::RemoveToolTips() ; + + UInt32 menuresult = UMAMenuEvent(ev) ; + if ( HiWord( menuresult ) ) + { + } + else + { + MacSendKeyUpEvent( wxWindow::FindFocus() , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) ; + } +} + +#endif + bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey ) { if ( !focus ) return false ; - + short keycode ; short keychar ; keychar = short(keymessage & charCodeMask); keycode = short(keymessage & keyCodeMask) >> 8 ; - + if ( modifiers & ( controlKey|shiftKey|optionKey ) ) { // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier @@ -1841,14 +1749,14 @@ bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifi keycode = short(keyInfo & keyCodeMask) >> 8 ; } long keyval = wxMacTranslateKey(keychar, keycode) ; - long realkeyval = keyval ; - if ( keyval == keychar ) - { - // we are not on a special character combo -> pass the real os event-value to EVT_CHAR, but not to EVT_KEY (make upper first) - realkeyval = short(keymessage & charCodeMask) ; - keyval = wxToupper( keyval ) ; - } - + long realkeyval = keyval ; + if ( keyval == keychar ) + { + // we are not on a special character combo -> pass the real os event-value to EVT_CHAR, but not to EVT_KEY (make upper first) + realkeyval = short(keymessage & charCodeMask) ; + keyval = wxToupper( keyval ) ; + } + wxKeyEvent event(wxEVT_KEY_DOWN); bool handled = false ; event.m_shiftDown = modifiers & shiftKey; @@ -1951,22 +1859,6 @@ bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifi return handled ; } - -void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr ) -{ - EventRecord* ev = (EventRecord*) evr ; - wxToolTip::RemoveToolTips() ; - - UInt32 menuresult = UMAMenuEvent(ev) ; - if ( HiWord( menuresult ) ) - { - } - else - { - MacSendKeyUpEvent( wxWindow::FindFocus() , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) ; - } -} - bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey ) { if ( !focus ) @@ -1987,10 +1879,10 @@ bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifier } long keyval = wxMacTranslateKey(keychar, keycode) ; - if ( keyval == keychar ) - { - keyval = wxToupper( keyval ) ; - } + if ( keyval == keychar ) + { + keyval = wxToupper( keyval ) ; + } bool handled = false ; wxKeyEvent event(wxEVT_KEY_UP); @@ -2008,6 +1900,8 @@ bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifier return handled ; } + +#if !TARGET_CARBON void wxApp::MacHandleActivateEvent( WXEVENTREF evr ) { EventRecord* ev = (EventRecord*) evr ; @@ -2024,7 +1918,7 @@ void wxApp::MacHandleActivateEvent( WXEVENTREF evr ) } wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ; if ( win ) - win->MacActivate( ev , activate ) ; + win->MacActivate( ev->when , activate ) ; } } @@ -2053,14 +1947,12 @@ void wxApp::MacHandleDiskEvent( WXEVENTREF evr ) EventRecord* ev = (EventRecord*) evr ; if ( HiWord( ev->message ) != noErr ) { - #if !TARGET_CARBON OSErr err ; Point point ; SetPt( &point , 100 , 100 ) ; err = DIBadMount( point , ev->message ) ; wxASSERT( err == noErr ) ; -#endif } } @@ -2072,11 +1964,8 @@ void wxApp::MacHandleOSEvent( WXEVENTREF evr ) case suspendResumeMessage : { bool isResuming = ev->message & resumeFlag ; -#if !TARGET_CARBON bool convertClipboard = ev->message & convertClipboardFlag ; -#else - bool convertClipboard = false; -#endif + bool doesActivate = UMAGetProcessModeDoesActivateOnFGSwitch() ; if ( isResuming ) { @@ -2097,31 +1986,18 @@ void wxApp::MacHandleOSEvent( WXEVENTREF evr ) { wxTopLevelWindowMac* win = wxFindWinFromMacWindow( oldFrontWindow ) ; if ( win ) - win->MacActivate( ev , false ) ; + win->MacActivate( ev->when , false ) ; } if ( newFrontWindow ) { wxTopLevelWindowMac* win = wxFindWinFromMacWindow( newFrontWindow ) ; if ( win ) - win->MacActivate( ev , true ) ; + win->MacActivate( ev->when , true ) ; } } else { MacSuspend( convertClipboard ) ; - - // in case this suspending did close an active window, another one might - // have surfaced -> lets deactivate that one - -/* TODO : find out what to do on systems < 10 , perhaps FrontNonFloatingWindow - WindowRef newActiveWindow = ::ActiveNonFloatingWindow() ; - if ( newActiveWindow ) - { - wxWindow* win = wxFindWinFromMacWindow( newActiveWindow ) ; - if ( win ) - win->MacActivate( ev , false ) ; - } -*/ } } break ; @@ -2131,15 +2007,15 @@ void wxApp::MacHandleOSEvent( WXEVENTREF evr ) wxWindow* currentMouseWindow = NULL ; - if (s_captureWindow ) - { - currentMouseWindow = s_captureWindow ; - } - else - { - wxWindow::MacGetWindowFromPoint( wxPoint( ev->where.h , ev->where.v ) , - ¤tMouseWindow ) ; - } + if (s_captureWindow ) + { + currentMouseWindow = s_captureWindow ; + } + else + { + wxWindow::MacGetWindowFromPoint( wxPoint( ev->where.h , ev->where.v ) , + ¤tMouseWindow ) ; + } if ( currentMouseWindow != wxWindow::s_lastMouseWindow ) { @@ -2182,16 +2058,16 @@ void wxApp::MacHandleOSEvent( WXEVENTREF evr ) short windowPart = inNoWindow ; - if ( s_captureWindow ) - { - window = (WindowRef) s_captureWindow->MacGetRootWindow() ; - windowPart = inContent ; - } - else - { - windowPart = ::FindWindow(ev->where, &window); - } - + if ( s_captureWindow ) + { + window = (WindowRef) s_captureWindow->MacGetRootWindow() ; + windowPart = inContent ; + } + else + { + windowPart = ::FindWindow(ev->where, &window); + } + switch (windowPart) { case inContent : @@ -2224,7 +2100,20 @@ void wxApp::MacHandleOSEvent( WXEVENTREF evr ) } } +#endif + +void wxApp::MacHandleMenuCommand( wxUint32 id ) +{ + wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ; + wxFrame* frame = mbar->GetFrame(); + wxCHECK_RET( mbar != NULL && frame != NULL, wxT("error in menu item callback") ); + if ( frame ) + { + frame->ProcessCommand(id); + } +} +#if !TARGET_CARBON void wxApp::MacHandleMenuSelect( int macMenuId , int macMenuItemNum ) { if (macMenuId == 0) @@ -2244,35 +2133,10 @@ void wxApp::MacHandleMenuSelect( int macMenuId , int macMenuItemNum ) } else { - wxWindow* frontwindow = wxFindWinFromMacWindow( ::FrontWindow() ) ; - if ( frontwindow && wxMenuBar::MacGetInstalledMenuBar() ) - wxMenuBar::MacGetInstalledMenuBar()->MacMenuSelect( frontwindow->GetEventHandler() , 0 , macMenuId , macMenuItemNum ) ; + MenuCommand id ; + GetMenuItemCommandID( GetMenuHandle(macMenuId) , macMenuItemNum , &id ) ; + MacHandleMenuCommand( id ) ; } HiliteMenu(0); } - -/* -long wxApp::MacTranslateKey(char key, int mods) -{ -} - -void wxApp::MacAdjustCursor() -{ -} - -*/ -/* -void -wxApp::macAdjustCursor() -{ - if (ev->what != kHighLevelEvent) - { - wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow()); - if (theMacWxFrame) - { - if (!theMacWxFrame->MacAdjustCursor(ev->where)) - ::SetCursor(&(qd.arrow)); - } - } -} -*/ +#endif