X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/89ebf1c919fbd662b2b9440573cf7d268023419c..867e99f57d01aaf89e5b470a2db97c95a0ac621f:/src/mac/carbon/app.cpp diff --git a/src/mac/carbon/app.cpp b/src/mac/carbon/app.cpp index b27475c3f1..6473c26f07 100644 --- a/src/mac/carbon/app.cpp +++ b/src/mac/carbon/app.cpp @@ -13,8 +13,11 @@ #pragma implementation "app.h" #endif +#include "wx/defs.h" + #include "wx/window.h" #include "wx/frame.h" +#include "wx/button.h" #include "wx/app.h" #include "wx/utils.h" #include "wx/gdicmn.h" @@ -34,7 +37,7 @@ #include "wx/textctrl.h" #include "wx/menu.h" #if wxUSE_WX_RESOURCES -#include "wx/resource.h" +# include "wx/resource.h" #endif #include @@ -52,13 +55,17 @@ #include "wx/mac/uma.h" #include "wx/mac/macnotfy.h" -#if wxUSE_SOCKETS - #ifdef __DARWIN__ - #include - #else - #include - #include - #endif +#ifdef __DARWIN__ +# include +# if defined(WXMAKINGDLL) +# include +# endif +#else +# include +# include +# include +# include +# include #endif extern char *wxBuffer; @@ -84,15 +91,17 @@ const short kMacMinHeap = (29 * 1024) ; const short kwxMacMenuBarResource = 1 ; const short kwxMacAppleMenuId = 1 ; -RgnHandle wxApp::s_macCursorRgn = NULL; -wxWindow* wxApp::s_captureWindow = NULL ; -int wxApp::s_lastMouseDown = 0 ; -long wxApp::sm_lastMessageTime = 0; +WXHRGN wxApp::s_macCursorRgn = NULL; +wxWindow* wxApp::s_captureWindow = NULL ; +int wxApp::s_lastMouseDown = 0 ; +long wxApp::sm_lastMessageTime = 0; +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" ; + +bool wxApp::s_macDefaultEncodingIsPC = true ; +bool wxApp::s_macSupportPCMenuShortcuts = true ; +long wxApp::s_macAboutMenuItemId = wxID_ABOUT ; +wxString wxApp::s_macHelpMenuTitleName = "&Help" ; pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ; pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ; @@ -100,31 +109,31 @@ pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long re pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long refcon ) ; -pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long refcon ) +pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) { - wxApp* app = (wxApp*) refcon ; + // GD: UNUSED wxApp* app = (wxApp*) refcon ; return wxTheApp->MacHandleAEODoc( (AppleEvent*) event , reply) ; } -pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long refcon ) +pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) { - wxApp* app = (wxApp*) refcon ; + // GD: UNUSED wxApp* app = (wxApp*) refcon ; return wxTheApp->MacHandleAEOApp( (AppleEvent*) event , reply ) ; } -pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long refcon ) +pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) { - wxApp* app = (wxApp*) refcon ; + // GD: UNUSED wxApp* app = (wxApp*) refcon ; return wxTheApp->MacHandleAEPDoc( (AppleEvent*) event , reply ) ; } -pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long refcon ) +pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) { - wxApp* app = (wxApp*) refcon ; + // GD: UNUSED wxApp* app = (wxApp*) refcon ; return wxTheApp->MacHandleAEQuit( (AppleEvent*) event , reply) ; } -OSErr wxApp::MacHandleAEODoc(const AppleEvent *event , AppleEvent *reply) +short wxApp::MacHandleAEODoc(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply)) { SysBeep(40) ; ProcessSerialNumber PSN ; @@ -134,17 +143,17 @@ OSErr wxApp::MacHandleAEODoc(const AppleEvent *event , AppleEvent *reply) return noErr ; } -OSErr wxApp::MacHandleAEPDoc(const AppleEvent *event , AppleEvent *reply) +short wxApp::MacHandleAEPDoc(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply)) { return noErr ; } -OSErr wxApp::MacHandleAEOApp(const AppleEvent *event , AppleEvent *reply) +short wxApp::MacHandleAEOApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply)) { return noErr ; } -OSErr wxApp::MacHandleAEQuit(const AppleEvent *event , AppleEvent *reply) +short wxApp::MacHandleAEQuit(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply)) { wxWindow* win = GetTopWindow() ; if ( win ) @@ -158,7 +167,7 @@ OSErr wxApp::MacHandleAEQuit(const AppleEvent *event , AppleEvent *reply) return noErr ; } -char StringMac[] = "\x0d\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" +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" @@ -256,7 +265,7 @@ void wxMacConvertFromPCForControls( char * p ) int len = strlen ( p ) ; wxMacConvertFromPC( ptr , ptr , len ) ; - for ( int i = 0 ; i < strlen ( ptr ) ; i++ ) + for ( unsigned int i = 0 ; i < strlen ( ptr ) ; i++ ) { if ( ptr[i] == '&' && ptr[i]+1 != ' ' ) { @@ -370,41 +379,59 @@ void wxMacStringToPascal( const char * from , StringPtr to , bool pc2macEncoding } } +#if defined(WXMAKINGDLL) && !defined(__DARWIN__) +// we know it's there ;-) +WXIMPORT char std::__throws_bad_alloc ; +#endif + bool wxApp::Initialize() { - int error = 0 ; + int error = 0 ; - // Mac-specific + // Mac-specific - UMAInitToolbox( 4 ) ; - SetEventMask( everyEvent ) ; + UMAInitToolbox( 4 ) ; + SetEventMask( everyEvent ) ; UMAShowWatchCursor() ; +#if defined(WXMAKINGDLL) && defined(__DARWIN__) + // open shared library resources from here since we don't have + // __wxinitialize in Mach-O shared libraries + wxStAppResource::OpenSharedLibraryResource(NULL); +#endif + #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340) - AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments , NewAEEventHandlerUPP(AEHandleODoc) , + AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments , + NewAEEventHandlerUPP(AEHandleODoc) , (long) wxTheApp , FALSE ) ; - AEInstallEventHandler( kCoreEventClass , kAEOpenApplication , NewAEEventHandlerUPP(AEHandleOApp) , + AEInstallEventHandler( kCoreEventClass , kAEOpenApplication , + NewAEEventHandlerUPP(AEHandleOApp) , (long) wxTheApp , FALSE ) ; - AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments , NewAEEventHandlerUPP(AEHandlePDoc) , + AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments , + NewAEEventHandlerUPP(AEHandlePDoc) , (long) wxTheApp , FALSE ) ; - AEInstallEventHandler( kCoreEventClass , kAEQuitApplication , NewAEEventHandlerUPP(AEHandleQuit) , + 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 ) ; + 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 + // test the minimal configuration necessary - #if !TARGET_CARBON +# if !TARGET_CARBON long theSystem ; long theMachine; @@ -428,7 +455,7 @@ bool wxApp::Initialize() { error = kMacSTRSmallSize; } - #endif +# endif /* else { @@ -444,6 +471,7 @@ bool wxApp::Initialize() if ( error ) { + wxStAppResource resload ; short itemHit; Str255 message; @@ -455,26 +483,21 @@ bool wxApp::Initialize() } #ifndef __DARWIN__ - #if __option(profile) +# if __option(profile) ProfilerInit( collectDetailed, bestTimeBase , 20000 , 40 ) ; - #endif +# endif #endif - // now avoid exceptions thrown for new (bad_alloc) - #ifndef __DARWIN__ - std::__throws_bad_alloc = FALSE ; + // now avoid exceptions thrown for new (bad_alloc) + std::__throws_bad_alloc = FALSE ; #endif s_macCursorRgn = ::NewRgn() ; -#ifdef __WXMSW__ - wxBuffer = new char[1500]; -#else - wxBuffer = new char[BUFSIZ + 512]; -#endif + wxBuffer = new char[BUFSIZ + 512]; - wxClassInfo::InitializeClasses(); + wxClassInfo::InitializeClasses(); #if wxUSE_RESOURCES // wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion); @@ -483,8 +506,9 @@ bool wxApp::Initialize() #if wxUSE_THREADS wxPendingEventsLocker = new wxCriticalSection; #endif - wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING); - wxTheColourDatabase->Initialize(); + + wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING); + wxTheColourDatabase->Initialize(); #ifdef __WXDEBUG__ #if wxUSE_LOG @@ -499,6 +523,9 @@ bool wxApp::Initialize() #endif // wxUSE_LOG #endif + wxWinMacWindowList = new wxList(wxKEY_INTEGER); + wxWinMacControlList = new wxList(wxKEY_INTEGER); + wxInitializeStockLists(); wxInitializeStockObjects(); @@ -513,11 +540,9 @@ bool wxApp::Initialize() return FALSE; } - wxWinMacWindowList = new wxList(wxKEY_INTEGER); - wxWinMacControlList = new wxList(wxKEY_INTEGER); - wxMacCreateNotifierTable() ; + UMAShowArrowCursor() ; return TRUE; @@ -525,6 +550,7 @@ bool wxApp::Initialize() 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 @@ -539,47 +565,51 @@ void wxApp::CleanUp() // One last chance for pending objects to be cleaned up wxTheApp->DeletePendingObjects(); - wxModule::CleanUpModules(); + wxModule::CleanUpModules(); #if wxUSE_WX_RESOURCES - wxCleanUpResourceSystem(); + wxCleanUpResourceSystem(); #endif - wxDeleteStockObjects() ; + wxDeleteStockObjects() ; // Destroy all GDI lists, etc. wxDeleteStockLists(); - delete wxTheColourDatabase; - wxTheColourDatabase = NULL; - - wxBitmap::CleanUpHandlers(); + delete wxTheColourDatabase; + wxTheColourDatabase = NULL; - delete[] wxBuffer; - wxBuffer = NULL; + wxBitmap::CleanUpHandlers(); - wxMacDestroyNotifierTable() ; - if (wxWinMacWindowList) - delete wxWinMacWindowList ; + 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 - wxClassInfo::CleanUpClasses(); + wxClassInfo::CleanUpClasses(); #ifndef __DARWIN__ - #if __option(profile) - ProfilerDump( "\papp.prof" ) ; - ProfilerTerm() ; - #endif +# if __option(profile) + ProfilerDump( "\papp.prof" ) ; + ProfilerTerm() ; +# endif #endif - delete wxTheApp; - wxTheApp = NULL; + 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 @@ -600,9 +630,16 @@ void wxApp::CleanUp() 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 + UMACleanupToolbox() ; - if (s_macCursorRgn) - ::DisposeRgn(s_macCursorRgn); + if (s_macCursorRgn) { + ::DisposeRgn((RgnHandle)s_macCursorRgn); + } #if 0 TerminateAE() ; @@ -613,23 +650,176 @@ void wxApp::CleanUp() // wxEntry //---------------------------------------------------------------------- -int wxEntryStart( int argc, char *argv[] ) +// extern variable for shared library resource id +// need to be able to find it with NSLookupAndBindSymbol +short gSharedLibraryResource = kResFileNotOpened ; + +#if defined(WXMAKINGDLL) && defined(__DARWIN__) +CFBundleRef gSharedLibraryBundle = NULL; +#endif /* WXMAKINGDLL && __DARWIN__ */ + +wxStAppResource::wxStAppResource() { - return wxApp::Initialize(); + m_currentRefNum = CurResFile() ; + if ( gSharedLibraryResource != kResFileNotOpened ) + { + UseResFile( gSharedLibraryResource ) ; + } } +wxStAppResource::~wxStAppResource() +{ + if ( m_currentRefNum != kResFileNotOpened ) + { + UseResFile( m_currentRefNum ) ; + } +} -int wxEntryInitGui() +void wxStAppResource::OpenSharedLibraryResource(const void *initBlock) { - return wxTheApp->OnInitGui(); + gSharedLibraryResource = kResFileNotOpened; + +#ifdef WXMAKINGDLL + if ( initBlock != NULL ) { + const CFragInitBlock *theInitBlock = (const CFragInitBlock *)initBlock; + FSSpec *fileSpec = NULL; + + if (theInitBlock->fragLocator.where == kDataForkCFragLocator) { + fileSpec = theInitBlock->fragLocator.u.onDisk.fileSpec; + } + else if (theInitBlock->fragLocator.where == kResourceCFragLocator) { + fileSpec = theInitBlock->fragLocator.u.inSegs.fileSpec; + } + + if (fileSpec != NULL) { + gSharedLibraryResource = FSpOpenResFile(fileSpec, fsRdPerm); + } + } + else { +#ifdef __DARWIN__ + // Open the shared library resource file if it is not yet open + NSSymbol theSymbol; + NSModule theModule; + const char *theLibPath; + + gSharedLibraryBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWindows")); + if (gSharedLibraryBundle != NULL) { + // wxWindows has been bundled into a framework + // load the framework resources + + gSharedLibraryResource = CFBundleOpenBundleResourceMap(gSharedLibraryBundle); + } + else { + // wxWindows is a simple dynamic shared library + // load the resources from the data fork of a separate resource file + char *theResPath; + char *theName; + char *theExt; + FSRef theResRef; + OSErr theErr = noErr; + + // get the library path + theSymbol = NSLookupAndBindSymbol("_gSharedLibraryResource"); + theModule = NSModuleForSymbol(theSymbol); + theLibPath = NSLibraryNameForModule(theModule); + + // allocate copy to replace .dylib.* extension with .rsrc + theResPath = strdup(theLibPath); + if (theResPath != NULL) { + theName = strrchr(theResPath, '/'); + if (theName == NULL) { + // no directory elements in path + theName = theResPath; + } + // find ".dylib" shared library extension + theExt = strstr(theName, ".dylib"); + // overwrite extension with ".rsrc" + strcpy(theExt, ".rsrc"); + + wxLogDebug( 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); + } + } + } +#endif /* __DARWIN__ */ + } +#endif /* WXMAKINGDLL */ } +void wxStAppResource::CloseSharedLibraryResource() +{ +#ifdef WXMAKINGDLL + // Close the shared library resource file + if (gSharedLibraryResource != kResFileNotOpened) { +#ifdef __DARWIN__ + if (gSharedLibraryBundle != NULL) { + CFBundleCloseBundleResourceMap(gSharedLibraryBundle, + gSharedLibraryResource); + gSharedLibraryBundle = NULL; + } + else +#endif /* __DARWIN__ */ + { + CloseResFile(gSharedLibraryResource); + } + gSharedLibraryResource = kResFileNotOpened; + } +#endif /* WXMAKINGDLL */ +} + +#if defined(WXMAKINGDLL) && !defined(__DARWIN__) + +// for shared libraries we have to manually get the correct resource +// ref num upon initializing and releasing when terminating, therefore +// the __wxinitialize and __wxterminate must be used -void wxEntryCleanup() +extern "C" { + void __sinit(void); /* (generated by linker) */ + pascal OSErr __initialize(const CFragInitBlock *theInitBlock); + pascal void __terminate(void); +} + +pascal OSErr __wxinitialize(const CFragInitBlock *theInitBlock) { - wxApp::CleanUp(); + wxStAppResource::OpenSharedLibraryResource( theInitBlock ) ; + return __initialize( theInitBlock ) ; +} + +pascal void __wxterminate(void) +{ + wxStAppResource::CloseSharedLibraryResource() ; + __terminate() ; } +#endif /* WXMAKINGDLL && !__DARWIN__ */ + +int WXDLLEXPORT wxEntryStart( int WXUNUSED(argc), char *WXUNUSED(argv)[] ) +{ + return wxApp::Initialize(); +} + +int WXDLLEXPORT wxEntryInitGui() +{ + return wxTheApp->OnInitGui(); +} + +void WXDLLEXPORT wxEntryCleanup() +{ + wxApp::CleanUp(); +} int wxEntry( int argc, char *argv[] , bool enterLoop ) { @@ -661,7 +851,22 @@ int wxEntry( int argc, char *argv[] , bool enterLoop ) wxCHECK_MSG( wxTheApp, 0, wxT("You have to define an instance of wxApp!") ); -#ifndef __DARWIN__ +#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 @@ -672,7 +877,6 @@ int wxEntry( int argc, char *argv[] , bool enterLoop ) // GUI-specific initialization, such as creating an app context. wxEntryInitGui(); - // Here frames insert themselves automatically // into wxTopLevelWindows by getting created // in OnInit(). @@ -715,6 +919,138 @@ int wxEntry( int argc, char *argv[] , bool enterLoop ) return retValue; } +#if TARGET_CARBON + +bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) +{ + bool converted = ConvertEventRefToEventRecord( event,rec) ; + OSStatus err = noErr ; + if ( !converted ) + { + switch( GetEventClass( event ) ) + { + case kEventClassKeyboard : + { + converted = true ; + switch( GetEventKind(event) ) + { + case kEventRawKeyDown : + rec->what = keyDown ; + break ; + case kEventRawKeyRepeat : + rec->what = autoKey ; + break ; + case kEventRawKeyUp : + rec->what = keyUp ; + break ; + case kEventRawKeyModifiersChanged : + rec->what = nullEvent ; + break ; + default : + converted = false ; + break ; + } + if ( converted ) + { + UInt32 keyCode ; + unsigned char charCode ; + UInt32 modifiers ; + GetMouse( &rec->where) ; + + err = GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers); + err = GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode); + err = GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode); + rec->modifiers = modifiers ; + rec->message = (keyCode << 8 ) + charCode ; + } + } + break ; + case kEventClassTextInput : + { + switch( GetEventKind( event ) ) + { + case kEventTextInputUnicodeForKeyEvent : + { + EventRef rawEvent ; + err = GetEventParameter( event , kEventParamTextInputSendKeyboardEvent ,typeEventRef,NULL,sizeof(rawEvent),NULL,&rawEvent ) ; + converted = true ; + { + UInt32 keyCode ; + unsigned char charCode ; + UInt32 modifiers ; + GetMouse( &rec->where) ; + rec->what = keyDown ; + err = GetEventParameter(rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers); + err = GetEventParameter(rawEvent, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode); + err = GetEventParameter(rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode); + rec->modifiers = modifiers ; + rec->message = (keyCode << 8 ) + charCode ; + } + } + break ; + default : + break ; + } + } + break ; + } + } + + return converted ; +} + +pascal OSStatus wxMacApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) +{ + OSStatus result = eventNotHandledErr ; + + EventRecord rec ; + switch ( GetEventClass( event ) ) + { + case kEventClassKeyboard : + if ( wxMacConvertEventToRecord( event , &rec ) ) + { + wxTheApp->MacHandleModifierEvents( &rec ) ; + wxTheApp->MacHandleOneEvent( &rec ) ; + result = noErr ; + } + break ; + case kEventClassTextInput : + if ( wxMacConvertEventToRecord( event , &rec ) ) + { + wxTheApp->MacHandleModifierEvents( &rec ) ; + wxTheApp->MacHandleOneEvent( &rec ) ; + result = noErr ; + } + break ; + default : + break ; + } + 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; @@ -723,13 +1059,14 @@ wxApp::wxApp() m_topWindow = NULL; wxTheApp = this; - m_wantDebugOutput = TRUE ; +#if WXWIN_COMPATIBILITY_2_2 + m_wantDebugOutput = TRUE; +#endif argc = 0; argv = NULL; m_printMode = wxPRINT_WINDOWS; - m_exitOnFrameDelete = TRUE; m_auto3D = TRUE; } @@ -878,29 +1215,6 @@ void wxApp::DeletePendingObjects() } } -wxIcon -wxApp::GetStdIcon(int which) const -{ - switch(which) - { - case wxICON_INFORMATION: - return wxIcon("wxICON_INFO"); - - case wxICON_QUESTION: - return wxIcon("wxICON_QUESTION"); - - case wxICON_EXCLAMATION: - return wxIcon("wxICON_WARNING"); - - default: - wxFAIL_MSG(wxT("requested non existent standard icon")); - // still fall through - - case wxICON_HAND: - return wxIcon("wxICON_ERROR"); - } -} - void wxExit() { wxLogError(_("Fatal error: exiting")); @@ -957,12 +1271,14 @@ bool wxApp::Yield(bool onlyIfNeeded) long sleepTime = 1 ; //::GetCaretTime(); - while ( !wxTheApp->IsExiting() && WaitNextEvent(everyEvent, &event,sleepTime, wxApp::s_macCursorRgn)) + while ( !wxTheApp->IsExiting() && WaitNextEvent(everyEvent, &event,sleepTime, (RgnHandle) wxApp::s_macCursorRgn)) { + wxTheApp->MacHandleModifierEvents( &event ) ; wxTheApp->MacHandleOneEvent( &event ); if ( event.what != kHighLevelEvent ) - SetRectRgn( wxApp::s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ; + SetRectRgn( (RgnHandle) wxApp::s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ; } + wxTheApp->MacHandleModifierEvents( &event ) ; wxMacProcessNotifierAndPendingEvents() ; @@ -975,30 +1291,48 @@ bool wxApp::Yield(bool onlyIfNeeded) void wxApp::MacSuspend( bool convertClipboard ) { - // we have to deactive the window manually + // we have to deactive the top level windows manually - wxWindow* window = GetTopWindow() ; - if ( window ) - window->MacActivate( MacGetCurrentEvent() , false ) ; + wxNode* node = wxTopLevelWindows.First(); + while (node) + { + wxTopLevelWindow* win = (wxTopLevelWindow*) node->Data(); + win->MacActivate( MacGetCurrentEvent() , false ) ; - s_lastMouseDown = 0 ; - if( convertClipboard ) - { - MacConvertPrivateToPublicScrap() ; - } + node = node->Next(); + } + + s_lastMouseDown = 0 ; + if( convertClipboard ) + { + MacConvertPrivateToPublicScrap() ; + } - ::HideFloatingWindows() ; + ::HideFloatingWindows() ; } +extern wxList wxModalDialogs; + void wxApp::MacResume( bool convertClipboard ) { - s_lastMouseDown = 0 ; - if( convertClipboard ) - { - MacConvertPublicToPrivateScrap() ; - } + s_lastMouseDown = 0 ; + if( convertClipboard ) + { + MacConvertPublicToPrivateScrap() ; + } + + ::ShowFloatingWindows() ; + + // raise modal dialogs in case a non modal window was selected to activate the app - ::ShowFloatingWindows() ; + wxNode* node = wxModalDialogs.First(); + while (node) + { + wxDialog* dialog = (wxDialog *) node->Data(); + dialog->Raise(); + + node = node->Next(); + } } void wxApp::MacConvertPrivateToPublicScrap() @@ -1015,12 +1349,14 @@ void wxApp::MacDoOneEvent() long sleepTime = 1; // GetCaretTime() / 4 ; - if (WaitNextEvent(everyEvent, &event, sleepTime, s_macCursorRgn)) + if (WaitNextEvent(everyEvent, &event, sleepTime, (RgnHandle) s_macCursorRgn)) { + MacHandleModifierEvents( &event ) ; MacHandleOneEvent( &event ); } else { + MacHandleModifierEvents( &event ) ; // idlers WindowPtr window = ::FrontWindow() ; if ( window ) @@ -1029,7 +1365,7 @@ void wxApp::MacDoOneEvent() wxTheApp->ProcessIdle() ; } if ( event.what != kHighLevelEvent ) - SetRectRgn( s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ; + SetRectRgn( (RgnHandle) s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ; // repeaters @@ -1037,8 +1373,64 @@ void wxApp::MacDoOneEvent() wxMacProcessNotifierAndPendingEvents() ; } -void wxApp::MacHandleOneEvent( EventRecord *ev ) +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 ) { + EventRecord* ev = (EventRecord*) evr ; m_macCurrentEvent = ev ; wxApp::sm_lastMessageTime = ev->when ; @@ -1092,15 +1484,17 @@ void wxApp::MacHandleOneEvent( EventRecord *ev ) wxMacProcessNotifierAndPendingEvents() ; } -void wxApp::MacHandleHighLevelEvent( EventRecord *ev ) +void wxApp::MacHandleHighLevelEvent( WXEVENTREF evr ) { + EventRecord* ev = (EventRecord*) evr ; ::AEProcessAppleEvent( ev ) ; } bool s_macIsInModalLoop = false ; -void wxApp::MacHandleMouseDownEvent( EventRecord *ev ) +void wxApp::MacHandleMouseDownEvent( WXEVENTREF evr ) { + EventRecord* ev = (EventRecord*) evr ; wxToolTip::RemoveToolTips() ; WindowRef window; @@ -1110,7 +1504,7 @@ void wxApp::MacHandleMouseDownEvent( EventRecord *ev ) ::GetWindowAttributes( frontWindow , &frontWindowAttributes ) ; short windowPart = ::FindWindow(ev->where, &window); - wxWindow* win = wxFindWinFromMacWindow( window ) ; + wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ; if ( wxPendingDelete.Member(win) ) return ; @@ -1150,12 +1544,7 @@ void wxApp::MacHandleMouseDownEvent( EventRecord *ev ) GrafPtr port ; GetPort( &port ) ; Point pt = { 0, 0 } ; - #if TARGET_CARBON - SetPort( GetWindowPort(window) ) ; - #else - SetPort( (window) ) ; - #endif - SetOrigin( 0 , 0 ) ; + SetPortWindowPort(window) ; LocalToGlobal( &pt ) ; SetPort( port ) ; win->SetSize( pt.h , pt.v , -1 , @@ -1189,7 +1578,7 @@ void wxApp::MacHandleMouseDownEvent( EventRecord *ev ) newWidth = oldWidth; if (newHeight == 0) newHeight = oldHeight; - win->SetSize( -1, -1, newWidth, newHeight, wxSIZE_USE_EXISTING); + win->SetSize( -1, -1 , newWidth, newHeight, wxSIZE_USE_EXISTING); } } s_lastMouseDown = 0; @@ -1204,9 +1593,15 @@ void wxApp::MacHandleMouseDownEvent( EventRecord *ev ) if (win) { Rect tempRect ; + GrafPtr port ; + GetPort( &port ) ; + Point pt = { 0, 0 } ; + SetPortWindowPort(window) ; + LocalToGlobal( &pt ) ; + SetPort( port ) ; GetWindowPortBounds(window, &tempRect ) ; - win->SetSize( -1, -1, tempRect.right-tempRect.left , + win->SetSize( pt.h , pt.v , tempRect.right-tempRect.left , tempRect.bottom-tempRect.top, wxSIZE_USE_EXISTING); } } @@ -1221,12 +1616,7 @@ void wxApp::MacHandleMouseDownEvent( EventRecord *ev ) { GrafPtr port ; GetPort( &port ) ; - #if TARGET_CARBON - SetPort( GetWindowPort(window) ) ; - #else - SetPort( (window) ) ; - #endif - SetOrigin( 0 , 0 ) ; + SetPortWindowPort(window) ; SetPort( port ) ; } if ( window != frontWindow && wxTheApp->s_captureWindow == NULL ) @@ -1259,11 +1649,21 @@ void wxApp::MacHandleMouseDownEvent( EventRecord *ev ) } } -void wxApp::MacHandleMouseUpEvent( EventRecord *ev ) +void wxApp::MacHandleMouseUpEvent( WXEVENTREF evr ) { + EventRecord* ev = (EventRecord*) evr ; WindowRef window; - short windowPart = ::FindWindow(ev->where, &window); + short windowPart = inNoWindow ; + if ( wxTheApp->s_captureWindow ) + { + window = (WindowRef) s_captureWindow->MacGetRootWindow() ; + windowPart = inContent ; + } + else + { + windowPart = ::FindWindow(ev->where, &window) ; + } switch (windowPart) { @@ -1273,7 +1673,7 @@ void wxApp::MacHandleMouseUpEvent( EventRecord *ev ) break ; default: { - wxWindow* win = wxFindWinFromMacWindow( window ) ; + wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ; if ( win ) win->MacMouseUp( ev , windowPart ) ; } @@ -1287,34 +1687,34 @@ 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 ) { @@ -1366,22 +1766,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 ; @@ -1390,105 +1790,164 @@ long wxMacTranslateKey(unsigned char key, unsigned char code) return retval; } -void wxApp::MacHandleKeyDownEvent( EventRecord *ev ) +void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr ) { + EventRecord* ev = (EventRecord*) evr ; wxToolTip::RemoveToolTips() ; UInt32 menuresult = UMAMenuEvent(ev) ; if ( HiWord( menuresult ) ) { if ( !s_macIsInModalLoop ) - MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ) ; + MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ) ; } else { - short keycode ; - short keychar ; - keychar = short(ev->message & charCodeMask); - keycode = short(ev->message & keyCodeMask) >> 8 ; + 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 ) ; + } + } + } +} - wxWindow* focus = wxWindow::FindFocus() ; - if ( focus ) +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) ) + { + // 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)) | keycode, &state); + keychar = short(keyInfo & charCodeMask); + keycode = short(keyInfo & keyCodeMask) >> 8 ; + } + long keyval = wxMacTranslateKey(keychar, keycode) ; + + 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_x = wherex; + event.m_y = wherey; + event.m_timeStamp = when; + event.SetEventObject(focus); + handled = focus->GetEventHandler()->ProcessEvent( event ) ; + if ( handled && event.GetSkipped() ) + handled = false ; + if ( !handled ) + { +#if wxUSE_ACCEL + if (!handled) { - long keyval = wxMacTranslateKey(keychar, keycode) ; - - 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_keyCode = keyval; - event.m_x = ev->where.h; - event.m_y = ev->where.v; - event.m_timeStamp = ev->when; - event.SetEventObject(focus); - bool handled = focus->GetEventHandler()->ProcessEvent( event ) ; - if ( !handled ) + wxWindow *ancestor = focus; + while (ancestor) { - #if wxUSE_ACCEL - if (!handled) + int command = ancestor->GetAcceleratorTable()->GetCommand( event ); + if (command != -1) { - wxWindow *ancestor = focus; - /* - while (ancestor) - { - int command = ancestor->GetAcceleratorTable()->GetCommand( event ); - if (command != -1) - { - wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command ); - handled = ancestor->GetEventHandler()->ProcessEvent( command_event ); - break; - } - if (ancestor->m_isFrame) - break; - ancestor = ancestor->GetParent(); - } - */ + wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command ); + handled = ancestor->GetEventHandler()->ProcessEvent( command_event ); + break; } - #endif // wxUSE_ACCEL - } - if (!handled) - { - wxKeyEvent event(wxEVT_CHAR); - 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_keyCode = keyval; - event.m_x = ev->where.h; - event.m_y = ev->where.v; - event.m_timeStamp = ev->when; - event.SetEventObject(focus); - handled = focus->GetEventHandler()->ProcessEvent( event ) ; + if (ancestor->IsTopLevel()) + break; + ancestor = ancestor->GetParent(); } - if ( !handled && - (keyval == WXK_TAB) && - (!focus->HasFlag(wxTE_PROCESS_TAB)) && - (focus->GetParent()) && - (focus->GetParent()->HasFlag( wxTAB_TRAVERSAL)) ) + } +#endif // wxUSE_ACCEL + } + if (!handled) + { + event.Skip( FALSE ) ; + event.SetEventType( wxEVT_CHAR ) ; + // raw value again + event.m_keyCode = keyval ; + + handled = focus->GetEventHandler()->ProcessEvent( event ) ; + if ( handled && event.GetSkipped() ) + handled = false ; + } + if ( !handled && + (keyval == WXK_TAB) && +// CS: copied the change below from wxGTK +// VZ: testing for wxTE_PROCESS_TAB shouldn't be done here the control may +// have this style, yet choose not to process this particular TAB in which +// case TAB must still work as a navigational character +#if 0 + (!focus->HasFlag(wxTE_PROCESS_TAB)) && +#endif + (focus->GetParent()) && + (focus->GetParent()->HasFlag( wxTAB_TRAVERSAL)) ) + { + wxNavigationKeyEvent new_event; + new_event.SetEventObject( focus ); + new_event.SetDirection( !event.ShiftDown() ); + /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ + new_event.SetWindowChange( event.ControlDown() ); + new_event.SetCurrentFocus( focus ); + handled = focus->GetEventHandler()->ProcessEvent( new_event ); + if ( handled && new_event.GetSkipped() ) + handled = false ; + } + // backdoor handler for default return and command escape + if ( !handled && (!focus->IsKindOf(CLASSINFO(wxControl) ) || !focus->MacCanFocus() ) ) + { + // if window is not having a focus still testing for default enter or cancel + // TODO add the UMA version for ActiveNonFloatingWindow + wxWindow* focus = wxFindWinFromMacWindow( FrontWindow() ) ; + if ( focus ) + { + if ( keyval == WXK_RETURN ) { - wxNavigationKeyEvent new_event; - new_event.SetEventObject( focus ); - new_event.SetDirection( !event.ShiftDown() ); - /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ - new_event.SetWindowChange( event.ControlDown() ); - new_event.SetCurrentFocus( focus ); - handled = focus->GetEventHandler()->ProcessEvent( new_event ); + wxButton *def = wxDynamicCast(focus->GetDefaultItem(), + wxButton); + if ( def && def->IsEnabled() ) + { + wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() ); + event.SetEventObject(def); + def->Command(event); + return true ; + } } /* generate wxID_CANCEL if command-. or has been pressed (typically in dialogs) */ - if ( (!handled) && - (keyval == '.' && event.ControlDown() ) ) + else if (keyval == WXK_ESCAPE || (keyval == '.' && modifiers & cmdKey ) ) { - wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL); - new_event.SetEventObject( focus ); - handled = focus->GetEventHandler()->ProcessEvent( new_event ); + wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL); + new_event.SetEventObject( focus ); + handled = focus->GetEventHandler()->ProcessEvent( new_event ); } - } + } } + return handled ; } -void wxApp::MacHandleKeyUpEvent( EventRecord *ev ) + +void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr ) { + EventRecord* ev = (EventRecord*) evr ; wxToolTip::RemoveToolTips() ; UInt32 menuresult = UMAMenuEvent(ev) ; @@ -1497,33 +1956,50 @@ void wxApp::MacHandleKeyUpEvent( EventRecord *ev ) } else { - short keycode ; - short keychar ; - keychar = short(ev->message & charCodeMask); - keycode = short(ev->message & keyCodeMask) >> 8 ; - - wxWindow* focus = wxWindow::FindFocus() ; - if ( focus ) - { - long keyval = wxMacTranslateKey(keychar, keycode) ; - - wxKeyEvent event(wxEVT_KEY_UP); - 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_keyCode = keyval; - event.m_x = ev->where.h; - event.m_y = ev->where.v; - event.m_timeStamp = ev->when; - event.SetEventObject(focus); - bool handled = focus->GetEventHandler()->ProcessEvent( event ) ; - } + MacSendKeyUpEvent( wxWindow::FindFocus() , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) ; } } -void wxApp::MacHandleActivateEvent( EventRecord *ev ) +bool wxApp::MacSendKeyUpEvent( 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) ) + { + // 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)) | keycode, &state); + keychar = short(keyInfo & charCodeMask); + keycode = short(keyInfo & keyCodeMask) >> 8 ; + } + long keyval = wxMacTranslateKey(keychar, keycode) ; + + bool handled = false ; + + 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 ) ; + + return handled ; +} +void wxApp::MacHandleActivateEvent( WXEVENTREF evr ) { + EventRecord* ev = (EventRecord*) evr ; WindowRef window = (WindowRef) ev->message ; if ( window ) { @@ -1535,20 +2011,21 @@ void wxApp::MacHandleActivateEvent( EventRecord *ev ) // if it is a floater we activate/deactivate the front non-floating window instead window = ::FrontNonFloatingWindow() ; } - wxWindow* win = wxFindWinFromMacWindow( window ) ; + wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ; if ( win ) win->MacActivate( ev , activate ) ; } } -void wxApp::MacHandleUpdateEvent( EventRecord *ev ) +void wxApp::MacHandleUpdateEvent( WXEVENTREF evr ) { + EventRecord* ev = (EventRecord*) evr ; WindowRef window = (WindowRef) ev->message ; - wxWindow * win = wxFindWinFromMacWindow( window ) ; + wxTopLevelWindowMac * win = wxFindWinFromMacWindow( window ) ; if ( win ) { if ( !wxPendingDelete.Member(win) ) - win->MacUpdate( ev ) ; + win->MacUpdate( ev->when ) ; } else { @@ -1560,8 +2037,9 @@ void wxApp::MacHandleUpdateEvent( EventRecord *ev ) } } -void wxApp::MacHandleDiskEvent( EventRecord *ev ) +void wxApp::MacHandleDiskEvent( WXEVENTREF evr ) { + EventRecord* ev = (EventRecord*) evr ; if ( HiWord( ev->message ) != noErr ) { #if !TARGET_CARBON @@ -1575,8 +2053,9 @@ void wxApp::MacHandleDiskEvent( EventRecord *ev ) } } -void wxApp::MacHandleOSEvent( EventRecord *ev ) +void wxApp::MacHandleOSEvent( WXEVENTREF evr ) { + EventRecord* ev = (EventRecord*) evr ; switch( ( ev->message & osEvtMessageMask ) >> 24 ) { case suspendResumeMessage : @@ -1605,13 +2084,13 @@ void wxApp::MacHandleOSEvent( EventRecord *ev ) if ( oldFrontWindow ) { - wxWindow* win = wxFindWinFromMacWindow( oldFrontWindow ) ; + wxTopLevelWindowMac* win = wxFindWinFromMacWindow( oldFrontWindow ) ; if ( win ) win->MacActivate( ev , false ) ; } if ( newFrontWindow ) { - wxWindow* win = wxFindWinFromMacWindow( newFrontWindow ) ; + wxTopLevelWindowMac* win = wxFindWinFromMacWindow( newFrontWindow ) ; if ( win ) win->MacActivate( ev , true ) ; } @@ -1641,8 +2120,15 @@ void wxApp::MacHandleOSEvent( EventRecord *ev ) 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 ) { @@ -1665,54 +2151,62 @@ void wxApp::MacHandleOSEvent( EventRecord *ev ) if ( wxWindow::s_lastMouseWindow ) { - wxMouseEvent eventleave(event ) ; - eventleave.SetEventType( wxEVT_LEAVE_WINDOW ) ; + 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 ) { - wxMouseEvent evententer(event ) ; - evententer.SetEventType( wxEVT_ENTER_WINDOW ) ; + wxMouseEvent evententer(event); + evententer.SetEventType( wxEVT_ENTER_WINDOW ); + currentMouseWindow->ScreenToClient( &evententer.m_x, &evententer.m_y ); + evententer.SetEventObject( currentMouseWindow ) ; currentMouseWindow->GetEventHandler()->ProcessEvent(evententer); } 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 : { - // if ( s_lastMouseDown == 0 ) - // ev->modifiers |= btnState ; - - // Calling GetNextEvent with a zero event mask will always - // pass back a null event. However, it fills the EventRecord - // with the state of the modifier keys. This is needed since - // the modifier state returned by WaitForNextEvent often is - // wrong mouse move events. The attempt above to correct this - // didn't always work (under OS X at least). - - EventRecord tmp; - ::GetNextEvent(0, &tmp); - ev->modifiers = tmp.modifiers; - - wxWindow* win = wxFindWinFromMacWindow( window ) ; + wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ; if ( win ) win->MacMouseMoved( ev , windowPart ) ; else - UMAShowArrowCursor(); - + { + if ( wxIsBusy() ) + { + } + else + UMAShowArrowCursor(); + } } break; + default : + { + if ( wxIsBusy() ) + { + } + else + UMAShowArrowCursor(); + } + break ; } } break ;