X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2fca5a00045426b4e59c14a575b2baa3628e3847..bf60426831535738b1b784629f08e9dd00bf9ecc:/src/mac/app.cpp diff --git a/src/mac/app.cpp b/src/mac/app.cpp index 1fe4f67e18..3fd3606748 100644 --- a/src/mac/app.cpp +++ b/src/mac/app.cpp @@ -36,6 +36,8 @@ #include "wx/tooltip.h" #include "wx/textctrl.h" #include "wx/menu.h" +#include "wx/docview.h" + #if wxUSE_WX_RESOURCES # include "wx/resource.h" #endif @@ -68,19 +70,30 @@ # include #endif -extern char *wxBuffer; extern wxList wxPendingDelete; extern wxList *wxWinMacWindowList; extern wxList *wxWinMacControlList; +// 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 + wxApp *wxTheApp = NULL; #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,283 +114,339 @@ 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_macExitMenuItemId = wxID_EXIT ; wxString wxApp::s_macHelpMenuTitleName = "&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; +} + +// AEPDoc Calls MacPrintFile on each of the files passed + +short wxApp::MacHandleAEPDoc(const WXEVENTREF event , WXEVENTREF WXUNUSED(reply)) +{ + 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; } -short wxApp::MacHandleAEPDoc(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply)) -{ - return noErr ; -} +// AEOApp calls MacNewFile short wxApp::MacHandleAEOApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply)) { + MacNewFile() ; return noErr ; } +// AEQuit attempts to quite 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" ; +//---------------------------------------------------------------------- +// Support Routines linking the Mac...File Calls to the Document Manager +//---------------------------------------------------------------------- -void wxMacConvertFromPC( const char *from , char *to , int len ) +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 ( ptr[i] == '&' && ptr[i]+1 != ' ' ) - { - memmove( &ptr[i] , &ptr[i+1] , strlen( &ptr[i+1] ) + 1) ; - } - } -} +#if TARGET_CARBON -void wxMacConvertFromPC( unsigned char *p ) -{ - char *ptr = (char*) p + 1 ; - int len = p[0] ; + static const EventTypeSpec eventList[] = + { + { kEventClassCommand, kEventProcessCommand } , + { kEventClassCommand, kEventCommandUpdateStatus } , + + { kEventClassApplication , kEventAppActivated } , + { kEventClassApplication , kEventAppDeactivated } , + // handling the quit event is not recommended by apple + // rather using the quit apple event - which we do + + { kEventClassAppleEvent , kEventAppleEvent } , + + { kEventClassMouse , kEventMouseDown } , + } ; - wxMacConvertFromPC( ptr , ptr , len ) ; +static pascal OSStatus MenuEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) +{ + OSStatus result = eventNotHandledErr ; + UInt32 kind = GetEventKind( event ) ; + + return result ; } -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 ; - - if ( len >= BUFSIZ + 512 ) + OSStatus result = eventNotHandledErr ; + + 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 ; + + GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL, + sizeof( HICommand ), NULL, &command ); + + MenuCommand id = command.commandID ; + if ( id == kHICommandPreferences ) + id = wxApp::s_macPreferencesMenuItemId ; + + wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ; + wxMenu* menu = NULL ; + wxMenuItem* item = NULL ; + + if ( mbar ) + item = mbar->FindItem( id , &menu ) ; + + 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 ; + } + + return result ; } -void wxMacConvertToPC( unsigned char *p ) +static pascal OSStatus ApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { - char *ptr = (char*) p + 1 ; - int len = p[0] ; - - wxMacConvertToPC( ptr , ptr , len ) ; + OSStatus result = eventNotHandledErr ; + switch ( GetEventKind( event ) ) + { + case kEventAppActivated : + { + wxTheApp->MacResume( true ) ; + result = noErr ; + } + break ; + case kEventAppDeactivated : + { + wxTheApp->MacSuspend( true ) ; + result = noErr ; + } + break ; + default : + break ; + } + return result ; } -wxString wxMacMakePCStringFromMac( const char * p ) +pascal OSStatus wxAppEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { - const char *ptr = p ; - int len = strlen ( p ) ; - char *buf = wxBuffer ; - - if ( len >= BUFSIZ + 512 ) + OSStatus result = eventNotHandledErr ; + switch( GetEventClass( event ) ) { - buf = new char [len+1] ; + 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 ; } - wxMacConvertToPC( ptr , buf , len ) ; - buf[len] = 0 ; - - wxString result( buf ) ; - if ( buf != wxBuffer ) - delete buf ; return result ; } -wxString wxMacMakeStringFromMacString( const char* from , bool mac2pcEncoding ) -{ - if (mac2pcEncoding) - { - return wxMacMakePCStringFromMac( from ) ; - } - else - { - return wxString( from ) ; - } -} - -wxString wxMacMakeStringFromPascal( StringPtr from , bool mac2pcEncoding ) -{ - // 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 - { - return wxString( s ) ; - } -} +DEFINE_ONE_SHOT_HANDLER_GETTER( wxAppEventHandler ) -void wxMacStringToPascal( const char * from , StringPtr to , bool pc2macEncoding ) -{ - if (pc2macEncoding) - { - CopyCStringToPascal( wxMacMakeMacStringFromPC( from ) , to ) ; - } - else - { - CopyCStringToPascal( from , to ) ; - } -} +#endif #if defined(WXMAKINGDLL) && !defined(__DARWIN__) // we know it's there ;-) @@ -399,34 +468,6 @@ bool wxApp::Initialize() // __wxinitialize in Mach-O shared libraries 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,13 +531,15 @@ 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 + #endif s_macCursorRgn = ::NewRgn() ; - wxBuffer = new char[BUFSIZ + 512]; - wxClassInfo::InitializeClasses(); #if wxUSE_RESOURCES @@ -506,7 +549,7 @@ bool wxApp::Initialize() #if wxUSE_THREADS wxPendingEventsLocker = new wxCriticalSection; #endif - + wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING); wxTheColourDatabase->Initialize(); @@ -542,12 +585,55 @@ bool wxApp::Initialize() wxMacCreateNotifierTable() ; - UMAShowArrowCursor() ; return TRUE; } +bool wxApp::OnInitGui() +{ + if( !wxAppBase::OnInitGui() ) + return false ; + +#if TARGET_CARBON + InstallStandardEventHandler( GetApplicationEventTarget() ) ; + + InstallApplicationEventHandler( + GetwxAppEventHandlerUPP(), + GetEventTypeCount(eventList), eventList, wxTheApp, &((EventHandlerRef)wxTheApp->m_macEventHandler)); +#endif + +#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 ; +} + void wxApp::CleanUp() { wxToolTip::RemoveToolTips() ; @@ -581,9 +667,6 @@ void wxApp::CleanUp() wxBitmap::CleanUpHandlers(); - delete[] wxBuffer; - wxBuffer = NULL; - wxMacDestroyNotifierTable() ; if (wxWinMacWindowList) { delete wxWinMacWindowList ; @@ -592,7 +675,7 @@ void wxApp::CleanUp() delete wxWinMacControlList ; } delete wxPendingEvents; - + #if wxUSE_THREADS delete wxPendingEventsLocker; // If we don't do the following, we get an apparent memory leak. @@ -635,12 +718,12 @@ void wxApp::CleanUp() // __wxterminate in Mach-O shared libraries wxStAppResource::CloseSharedLibraryResource(); #endif - + UMACleanupToolbox() ; if (s_macCursorRgn) { ::DisposeRgn((RgnHandle)s_macCursorRgn); } - + #if 0 TerminateAE() ; #endif @@ -683,14 +766,14 @@ void wxStAppResource::OpenSharedLibraryResource(const void *initBlock) 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); } @@ -701,12 +784,12 @@ void wxStAppResource::OpenSharedLibraryResource(const void *initBlock) 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 { @@ -717,12 +800,15 @@ void wxStAppResource::OpenSharedLibraryResource(const void *initBlock) char *theExt; FSRef theResRef; OSErr theErr = noErr; - + // get the library path theSymbol = NSLookupAndBindSymbol("_gSharedLibraryResource"); theModule = NSModuleForSymbol(theSymbol); theLibPath = NSLibraryNameForModule(theModule); + wxLogDebug( wxT("wxMac library installation name is '%s'"), + theLibPath ); + // allocate copy to replace .dylib.* extension with .rsrc theResPath = strdup(theLibPath); if (theResPath != NULL) { @@ -735,23 +821,28 @@ void wxStAppResource::OpenSharedLibraryResource(const void *initBlock) theExt = strstr(theName, ".dylib"); // overwrite extension with ".rsrc" strcpy(theExt, ".rsrc"); - - wxLogDebug( theResPath ); + + wxLogDebug( wxT("wxMac resources file name is '%s'"), + theResPath ); theErr = FSPathMakeRef((UInt8 *) theResPath, &theResRef, false); if (theErr != noErr) { // try in current directory (using name only) 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) { + wxLogDebug( wxT("unable to open wxMac resource file '%s'"), + theResPath ); + } + + // free duplicated resource file path + free(theResPath); } } #endif /* __DARWIN__ */ @@ -776,7 +867,7 @@ void wxStAppResource::CloseSharedLibraryResource() CloseResFile(gSharedLibraryResource); } gSharedLibraryResource = kResFileNotOpened; - } + } #endif /* WXMAKINGDLL */ } @@ -858,14 +949,11 @@ int wxEntry( int argc, char *argv[] , bool enterLoop ) // application (otherwise applications would need to handle it) if (argc > 1) { - char theArg[6] = ""; - strncpy(theArg, argv[1], 5); - - if (strcmp(theArg, "-psn_") == 0) { + 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 @@ -932,7 +1020,7 @@ bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) case kEventClassKeyboard : { converted = true ; - switch( GetEventKind(event) ) + switch( GetEventKind(event) ) { case kEventRawKeyDown : rec->what = keyDown ; @@ -995,14 +1083,15 @@ bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) break ; } } - + return converted ; } +/* pascal OSStatus wxMacApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { OSStatus result = eventNotHandledErr ; - + EventRecord rec ; switch ( GetEventClass( event ) ) { @@ -1027,30 +1116,9 @@ 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; @@ -1067,7 +1135,6 @@ wxApp::wxApp() argv = NULL; m_printMode = wxPRINT_WINDOWS; - m_exitOnFrameDelete = TRUE; m_auto3D = TRUE; } @@ -1081,14 +1148,14 @@ bool wxApp::Initialized() int wxApp::MainLoop() { - m_keepGoing = TRUE; + m_keepGoing = TRUE; - while (m_keepGoing) - { - MacDoOneEvent() ; - } + while (m_keepGoing) + { + MacDoOneEvent() ; + } - return 0; + return 0; } // Returns TRUE if more time is needed. @@ -1103,15 +1170,26 @@ bool wxApp::ProcessIdle() void wxApp::ExitMainLoop() { - m_keepGoing = FALSE; +#if TARGET_CARBON + if (s_inReceiveEvent) + QuitApplicationEventLoop() ; + else + m_keepGoing = FALSE; +#else + m_keepGoing = FALSE; +#endif } // 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. @@ -1122,8 +1200,6 @@ void wxApp::Dispatch() void wxApp::OnIdle(wxIdleEvent& event) { - static bool s_inOnIdle = FALSE; - // Avoid recursion (via ProcessEvent default case) if ( s_inOnIdle ) return; @@ -1251,8 +1327,6 @@ void wxCYield() bool wxApp::Yield(bool onlyIfNeeded) { - static bool s_inYield = FALSE; - if (s_inYield) { if ( !onlyIfNeeded ) @@ -1268,21 +1342,51 @@ 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 ) + { + m_keepGoing = false ; + } + 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 + long 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; @@ -1292,24 +1396,26 @@ 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(); while (node) { wxTopLevelWindow* win = (wxTopLevelWindow*) node->Data(); - win->MacActivate( MacGetCurrentEvent() , false ) ; + win->MacActivate( ((EventRecord*) MacGetCurrentEvent())->when , false ) ; node = node->Next(); } - + + ::HideFloatingWindows() ; +#endif s_lastMouseDown = 0 ; + if( convertClipboard ) { MacConvertPrivateToPublicScrap() ; } - - ::HideFloatingWindows() ; } extern wxList wxModalDialogs; @@ -1321,9 +1427,9 @@ 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(); @@ -1331,9 +1437,10 @@ void wxApp::MacResume( bool convertClipboard ) { wxDialog* dialog = (wxDialog *) node->Data(); dialog->Raise(); - + node = node->Next(); } +#endif } void wxApp::MacConvertPrivateToPublicScrap() @@ -1346,11 +1453,34 @@ 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 ) + { + m_keepGoing = false ; + } + else + { + MacHandleOneEvent( theEvent ) ; + ReleaseEvent(theEvent); + } +#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 ); @@ -1363,70 +1493,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 - { - 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 ; @@ -1478,17 +1566,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 ; @@ -1518,16 +1652,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 ) ) { @@ -1560,23 +1692,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; } @@ -1640,7 +1777,6 @@ void wxApp::MacHandleMouseDownEvent( WXEVENTREF evr ) win->MacMouseDown( ev , windowPart ) ; } break ; - default: break; } @@ -1656,7 +1792,7 @@ void wxApp::MacHandleMouseUpEvent( WXEVENTREF evr ) { window = (WindowRef) s_captureWindow->MacGetRootWindow() ; windowPart = inContent ; - } + } else { windowPart = ::FindWindow(ev->where, &window) ; @@ -1678,40 +1814,42 @@ void wxApp::MacHandleMouseUpEvent( WXEVENTREF evr ) } } +#endif + long wxMacTranslateKey(unsigned char key, unsigned char code) ; long wxMacTranslateKey(unsigned char key, unsigned char code) { long retval = key ; switch (key) { - case 0x01 : + case kHomeCharCode : retval = WXK_HOME; break; - case 0x03 : + case kEnterCharCode : retval = WXK_RETURN; break; - case 0x04 : + case kEndCharCode : retval = WXK_END; break; - case 0x05 : + case kHelpCharCode : retval = WXK_HELP; break; - case 0x08 : + case kBackspaceCharCode : retval = WXK_BACK; break; - case 0x09 : + case kTabCharCode : retval = WXK_TAB; break; - case 0x0b : + case kPageUpCharCode : retval = WXK_PAGEUP; break; - case 0x0c : + case kPageDownCharCode : retval = WXK_PAGEDOWN; break; - case 0x0d : + case kReturnCharCode : retval = WXK_RETURN; break; - case 0x10 : + case kFunctionKeyCharCode : { switch( code ) { @@ -1763,22 +1901,22 @@ long wxMacTranslateKey(unsigned char key, unsigned char code) } } break ; - case 0x1b : + case kEscapeCharCode : retval = WXK_ESCAPE ; break ; - case 0x1c : + case kLeftArrowCharCode : retval = WXK_LEFT ; break ; - case 0x1d : + case kRightArrowCharCode : retval = WXK_RIGHT ; break ; - case 0x1e : + case kUpArrowCharCode : retval = WXK_UP ; break ; - case 0x1f : + case kDownArrowCharCode : retval = WXK_DOWN ; break ; - case 0x7F : + case kDeleteCharCode : retval = WXK_DELETE ; default: break ; @@ -1787,6 +1925,7 @@ long wxMacTranslateKey(unsigned char key, unsigned char code) return retval; } +#if !TARGET_CARBON void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr ) { EventRecord* ev = (EventRecord*) evr ; @@ -1800,39 +1939,76 @@ void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr ) } else { - short keycode ; - short keychar ; - keychar = short(ev->message & charCodeMask); - keycode = short(ev->message & keyCodeMask) >> 8 ; - wxWindow* focus = wxWindow::FindFocus() ; - // it is wxWindows Convention to have Ctrl Key Combinations at ASCII char value - if ( (ev->modifiers & controlKey) && keychar >= 0 && keychar < 0x20 ) - { - keychar += 0x40 ; - } - long keyval = wxMacTranslateKey(keychar, keycode) ; - - if ( MacSendKeyDownEvent( focus , keyval , ev->modifiers , ev->when , ev->where.h , ev->where.v ) == false ) + 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 wxControl* control = wxDynamicCast( focus , wxControl ) ; if ( control && control->GetMacControl() != NULL ) { + short keycode ; + short keychar ; + keychar = short(ev->message & charCodeMask); + keycode = short(ev->message & keyCodeMask) >> 8 ; ::HandleControlKey( (ControlHandle) control->GetMacControl() , keycode , keychar , ev->modifiers ) ; } } } } -bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keyval , long modifiers , long when , short wherex , short wherey ) +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 + // and look at the character after + 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 ; + 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; event.m_controlDown = modifiers & controlKey; event.m_altDown = modifiers & optionKey; event.m_metaDown = modifiers & cmdKey; - event.m_keyCode = wxToupper(keyval ); + event.m_keyCode = keyval ; event.m_x = wherex; event.m_y = wherey; @@ -1867,7 +2043,8 @@ bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keyval , long modifiers { event.Skip( FALSE ) ; event.SetEventType( wxEVT_CHAR ) ; - event.m_keyCode = keyval ; + // raw value again + event.m_keyCode = realkeyval ; handled = focus->GetEventHandler()->ProcessEvent( event ) ; if ( handled && event.GetSkipped() ) @@ -1927,55 +2104,49 @@ bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keyval , long modifiers return handled ; } - -void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr ) +bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey ) { - EventRecord* ev = (EventRecord*) evr ; - wxToolTip::RemoveToolTips() ; + if ( !focus ) + return false ; - UInt32 menuresult = UMAMenuEvent(ev) ; - if ( HiWord( menuresult ) ) + 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 + // and look at the character after + UInt32 state = 0; + UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state); + keychar = short(keyInfo & charCodeMask); + keycode = short(keyInfo & keyCodeMask) >> 8 ; } - else - { - short keycode ; - short keychar ; - keychar = short(ev->message & charCodeMask); - keycode = short(ev->message & keyCodeMask) >> 8 ; - // it is wxWindows Convention to have Ctrl Key Combinations at ASCII char value - if ( (ev->modifiers & controlKey) && keychar >= 0 && keychar < 0x20 ) - { - keychar += 0x40 ; - } - long keyval = wxMacTranslateKey(keychar, keycode) ; + long keyval = wxMacTranslateKey(keychar, keycode) ; - wxWindow* focus = wxWindow::FindFocus() ; - bool handled = MacSendKeyUpEvent( focus , keyval , ev->modifiers , ev->when , ev->where.h , ev->where.v ) ; - // we don't have to do anything under classic here - } -} - -bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keyval , long modifiers , long when , short wherex , short wherey ) -{ + if ( keyval == keychar ) + { + keyval = wxToupper( keyval ) ; + } bool handled = false ; - if ( focus ) - { - wxKeyEvent event(wxEVT_KEY_UP); - event.m_shiftDown = modifiers & shiftKey; - event.m_controlDown = modifiers & controlKey; - event.m_altDown = modifiers & optionKey; - event.m_metaDown = modifiers & cmdKey; - event.m_keyCode = wxToupper(keyval ); - - event.m_x = wherex; - event.m_y = wherey; - event.m_timeStamp = when; - event.SetEventObject(focus); - handled = focus->GetEventHandler()->ProcessEvent( event ) ; - } + + wxKeyEvent event(wxEVT_KEY_UP); + event.m_shiftDown = modifiers & shiftKey; + event.m_controlDown = modifiers & controlKey; + event.m_altDown = modifiers & optionKey; + event.m_metaDown = modifiers & cmdKey; + event.m_keyCode = keyval ; + + event.m_x = wherex; + event.m_y = wherey; + event.m_timeStamp = when; + event.SetEventObject(focus); + handled = focus->GetEventHandler()->ProcessEvent( event ) ; + return handled ; } + +#if !TARGET_CARBON void wxApp::MacHandleActivateEvent( WXEVENTREF evr ) { EventRecord* ev = (EventRecord*) evr ; @@ -1992,7 +2163,7 @@ void wxApp::MacHandleActivateEvent( WXEVENTREF evr ) } wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ; if ( win ) - win->MacActivate( ev , activate ) ; + win->MacActivate( ev->when , activate ) ; } } @@ -2021,14 +2192,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 } } @@ -2040,11 +2209,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 ) { @@ -2065,31 +2231,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 ; @@ -2099,8 +2252,16 @@ void wxApp::MacHandleOSEvent( WXEVENTREF evr ) wxWindow* currentMouseWindow = NULL ; - 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 ) { wxMouseEvent event ; @@ -2119,14 +2280,14 @@ void wxApp::MacHandleOSEvent( WXEVENTREF evr ) event.m_y = ev->where.v; event.m_timeStamp = ev->when; event.SetEventObject(this); - + 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 ) ; - + wxWindow::s_lastMouseWindow->GetEventHandler()->ProcessEvent(eventleave); } if ( currentMouseWindow ) @@ -2140,34 +2301,72 @@ void wxApp::MacHandleOSEvent( WXEVENTREF evr ) wxWindow::s_lastMouseWindow = currentMouseWindow ; } - short windowPart = ::FindWindow(ev->where, &window); - + short windowPart = inNoWindow ; + + if ( s_captureWindow ) + { + window = (WindowRef) s_captureWindow->MacGetRootWindow() ; + windowPart = inContent ; + } + else + { + windowPart = ::FindWindow(ev->where, &window); + } + switch (windowPart) { - // fixes for setting the cursor back from dominic mazzoni - case inMenuBar : - UMAShowArrowCursor(); - break ; - case inSysWindow : - UMAShowArrowCursor(); - break ; - default: + case inContent : { wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ; if ( win ) win->MacMouseMoved( ev , windowPart ) ; else - UMAShowArrowCursor(); - + { + if ( wxIsBusy() ) + { + } + else + UMAShowArrowCursor(); + } } break; + default : + { + if ( wxIsBusy() ) + { + } + else + UMAShowArrowCursor(); + } + break ; } } break ; } } +#endif +void wxApp::MacHandleMenuCommand( wxUint32 id ) +{ + wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ; + wxMenu* menu = NULL ; + wxMenuItem* item = NULL ; + if ( mbar ) + { + item = mbar->FindItem( id , &menu ) ; + } + wxCHECK_RET( item != NULL && menu != NULL && mbar != NULL, wxT("error in menu item callback") ); + + if (item->IsCheckable()) + { + item->Check( !item->IsChecked() ) ; + } + + menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ; +} + +#if !TARGET_CARBON void wxApp::MacHandleMenuSelect( int macMenuId , int macMenuItemNum ) { if (macMenuId == 0) @@ -2187,35 +2386,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 \ No newline at end of file