]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/app.cpp
fix for bug reported by Robert and Julian, probably causes other problems
[wxWidgets.git] / src / mac / app.cpp
index cd7e8d2423f29c1a3192e22f2232fe552b0fa93c..f19403201a7e873a38ec04cbfdf864550fda6ea2 100644 (file)
@@ -57,6 +57,9 @@
 
 #ifdef __DARWIN__
 #  include <CoreServices/CoreServices.h>
+#  if defined(WXMAKINGDLL)
+#    include <mach-o/dyld.h>
+#  endif
 #else
 #  include <Sound.h>
 #  include <Threads.h>
@@ -88,15 +91,15 @@ const short    kMacMinHeap = (29 * 1024) ;
 const short kwxMacMenuBarResource = 1 ;
 const short kwxMacAppleMenuId = 1 ;
 
-WXHRGN            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;
 
-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 ) ;
@@ -373,48 +376,60 @@ void wxMacStringToPascal( const char * from , StringPtr to , bool pc2macEncoding
       CopyCStringToPascal( from , to ) ;
     }
 }
-#ifdef WXMAKINGDLL
-#ifndef __DARWIN__
+
+#if defined(WXMAKINGDLL) && !defined(__DARWIN__)
 // we know it's there ;-)
 WXIMPORT char std::__throws_bad_alloc ;
 #endif
-#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;
 
@@ -438,7 +453,7 @@ bool wxApp::Initialize()
     {
         error = kMacSTRSmallSize;
     }
-    #endif
+#  endif
     /*
     else
     {
@@ -466,26 +481,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
-
-  wxClassInfo::InitializeClasses();
+    wxBuffer = new char[BUFSIZ + 512];
+  
+    wxClassInfo::InitializeClasses();
 
 #if wxUSE_RESOURCES
 //    wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion);
@@ -494,8 +504,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
@@ -529,6 +540,7 @@ bool wxApp::Initialize()
 
   wxMacCreateNotifierTable() ;
 
+
   UMAShowArrowCursor() ;
 
   return TRUE;
@@ -551,50 +563,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[] wxBuffer;
-  wxBuffer = NULL;
+    delete wxTheColourDatabase;
+    wxTheColourDatabase = NULL;
 
-  wxMacDestroyNotifierTable() ;
-  if (wxWinMacWindowList)
-    delete wxWinMacWindowList ;
+    wxBitmap::CleanUpHandlers();
 
-  if (wxWinMacControlList)
-    delete wxWinMacControlList ;
+    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
@@ -615,10 +628,17 @@ 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)
+    if (s_macCursorRgn) {
         ::DisposeRgn((RgnHandle)s_macCursorRgn);
-
+    }
+    
     #if 0
         TerminateAE() ;
     #endif
@@ -628,62 +648,161 @@ void wxApp::CleanUp()
 // wxEntry
 //----------------------------------------------------------------------
 
-short gCurrentResource = -1 ;
+// 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()
 {
     m_currentRefNum = CurResFile() ;
-    if ( gCurrentResource != -1 )
+    if ( gSharedLibraryResource != kResFileNotOpened )
     {
-        UseResFile( gCurrentResource ) ;
+        UseResFile( gSharedLibraryResource ) ;
     }
 }
 
 wxStAppResource::~wxStAppResource()
 {
-    if ( m_currentRefNum != -1 )
+    if ( m_currentRefNum != kResFileNotOpened )
     {
         UseResFile( m_currentRefNum ) ;
     }
 }
 
+void wxStAppResource::OpenSharedLibraryResource(const void *initBlock)
+{
+    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 */
+}
 
-// 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 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 */
+}
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#if defined(WXMAKINGDLL) && !defined(__DARWIN__)
 
-void __sinit(void);    /*      (generated by linker)   */
-pascal OSErr __initialize(const CFragInitBlock *theInitBlock);
-pascal void __terminate(void);
+// 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
 
-#ifdef __cplusplus
+extern "C" {
+    void __sinit(void);        /*      (generated by linker)   */
+    pascal OSErr __initialize(const CFragInitBlock *theInitBlock);
+    pascal void __terminate(void);
 }
-#endif
 
 pascal OSErr __wxinitialize(const CFragInitBlock *theInitBlock)
 {
-   gCurrentResource = -1;
-   
-   if (theInitBlock->fragLocator.where == kDataForkCFragLocator) {
-      gCurrentResource = 
-         FSpOpenResFile(theInitBlock->fragLocator.u.onDisk.fileSpec, 
-                              fsRdPerm);
-   }
-   return __initialize( theInitBlock ) ;
+    wxStAppResource::OpenSharedLibraryResource( theInitBlock ) ;
+    return __initialize( theInitBlock ) ;
 }
 
 pascal void __wxterminate(void)
 {
-    if (gCurrentResource != -1)
-      CloseResFile(gCurrentResource);
+    wxStAppResource::CloseSharedLibraryResource() ;
     __terminate() ;
 }
-#endif
+
+#endif /* WXMAKINGDLL && !__DARWIN__ */
 
 int WXDLLEXPORT wxEntryStart( int argc, char *argv[] )
 {
@@ -702,7 +821,6 @@ void WXDLLEXPORT wxEntryCleanup()
 
 int wxEntry( int argc, char *argv[] , bool enterLoop )
 {
-    gCurrentResource = CurResFile() ;
 #ifdef __MWERKS__
 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
     // This seems to be necessary since there are 'rogue'
@@ -738,10 +856,10 @@ int wxEntry( int argc, char *argv[] , bool enterLoop )
     // application (otherwise applications would need to handle it)
 
     if (argc > 1) {
-        char buf[6] = "";
-        strncpy(buf, argv[1], 5);
+        char theArg[6] = "";
+        strncpy(theArg, argv[1], 5);
         
-        if (strcmp(buf, "-psn_") == 0) {
+        if (strcmp(theArg, "-psn_") == 0) {
             // assume the argument is always the only one and remove it
             --argc;
         }
@@ -799,6 +917,136 @@ 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->MacHandleOneEvent( &rec ) ;
+                result = noErr ;
+            }
+            break ;
+        case kEventClassTextInput :
+            if ( wxMacConvertEventToRecord( event , &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;
 
@@ -1470,7 +1718,7 @@ void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr )
     if ( HiWord( menuresult ) )
     {
         if ( !s_macIsInModalLoop )
-        MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ) ;
+            MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ) ;
     }
     else
     {
@@ -1479,80 +1727,101 @@ void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr )
         keychar = short(ev->message & charCodeMask);
         keycode = short(ev->message & keyCodeMask) >> 8 ;
         long keyval = wxMacTranslateKey(keychar, keycode) ;
-        bool handled = false ;
         wxWindow* focus = wxWindow::FindFocus() ;
-        if ( focus )
-        {
 
-            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);
-            handled = focus->GetEventHandler()->ProcessEvent( event ) ;
-            if ( !handled )
+        if ( MacSendKeyDownEvent( focus , keyval , 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 )
             {
+                ::HandleControlKey( (ControlHandle) control->GetMacControl() , keycode , keychar , ev->modifiers ) ;
+            }
+        }
+    }
+}
+
+bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keyval , long modifiers , long when , short wherex , short wherey )
+{
+    bool handled = false ;
+    // it is wxWindows Convention to have Ctrl Key Combinations at ASCII char value
+    if ( modifiers & controlKey && keyval >= 0 && keyval < 0x20 )
+    {
+        keyval += 0x40 ;
+    }
+    wxKeyEvent event(wxEVT_KEY_DOWN);
+    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 ) ;
+    if ( handled && event.GetSkipped() )
+        handled = false ;
+    if ( !handled )
+    {
 #if wxUSE_ACCEL
-                if (!handled)
+        if (!handled)
+        {
+            wxWindow *ancestor = focus;
+            while (ancestor)
+            {
+                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 ( !handled &&
-                 (keyval == WXK_TAB) &&
-                 (!focus->HasFlag(wxTE_PROCESS_TAB)) &&
-                 (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 (ancestor->IsTopLevel())
+                    break;
+                ancestor = ancestor->GetParent();
             }
         }
-        if ( !handled )
-        {
-            // if window is not having a focus still testing for default enter or cancel
-            // TODO add the UMA version for ActiveNonFloatingWindow
-          focus = wxFindWinFromMacWindow( FrontWindow() ) ;
+#endif // wxUSE_ACCEL
+    }
+    if (!handled)
+    {
+        event.Skip( FALSE ) ;
+        event.SetEventType( wxEVT_CHAR ) ;
+
+        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 )
@@ -1564,21 +1833,22 @@ void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr )
                      wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
                      event.SetEventObject(def);
                      def->Command(event);
-                     return ;
+                     return true ;
                 }
             }
             /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
-            else if (keyval == WXK_ESCAPE || (keyval == '.' && ev->modifiers & cmdKey ) )
+            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 );
             }
           }
-        }
     }
+    return handled ;
 }
 
+
 void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr )
 {
     EventRecord* ev = (EventRecord*) evr ;
@@ -1594,27 +1864,39 @@ void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr )
         short keychar ;
         keychar = short(ev->message & charCodeMask);
         keycode = short(ev->message & keyCodeMask) >> 8 ;
+        long keyval = wxMacTranslateKey(keychar, keycode) ;
 
         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 ) ;
-        }
+        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 )
+{
+    bool handled = false ;
+    // it is wxWindows Convention to have Ctrl Key Combinations at ASCII char value
+    if ( modifiers & controlKey && keyval >= 0 && keyval < 0x20 )
+    {
+        keyval += 0x40 ;
+    }
+    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 = 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 ;