]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/app.cpp
correct boundaries for carbon
[wxWidgets.git] / src / mac / app.cpp
index f863e938af6c5d279b12ae3248c959c9db283fde..0b4b57cc2ff36bb79c4031d5c5b06f97eaf99d81 100644 (file)
@@ -37,6 +37,7 @@
 #include "wx/textctrl.h"
 #include "wx/menu.h"
 #include "wx/docview.h"
+#include "wx/filename.h"
 
 #include <string.h>
 
@@ -69,6 +70,9 @@
 extern wxList wxPendingDelete;
 extern wxList *wxWinMacWindowList;
 extern wxList *wxWinMacControlList;
+#if wxUSE_THREADS
+extern size_t g_numberOfThreads;
+#endif // wxUSE_THREADS
 
 // statics for implementation
 
@@ -110,6 +114,8 @@ long      wxApp::s_macPreferencesMenuItemId = wxID_PREFERENCES ;
 long      wxApp::s_macExitMenuItemId = wxID_EXIT ;
 wxString  wxApp::s_macHelpMenuTitleName = wxT("&Help") ;
 
+// Normally we're not a plugin
+bool      wxApp::sm_isEmbedded = false;
 //----------------------------------------------------------------------
 // Core Apple Event Support
 //----------------------------------------------------------------------
@@ -118,6 +124,7 @@ pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long re
 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 AEHandleRApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
 
 pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
 {
@@ -139,6 +146,11 @@ pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long WX
     return wxTheApp->MacHandleAEQuit( (AppleEvent*) event , reply) ;
 }
 
+pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
+{
+    return wxTheApp->MacHandleAERApp( (AppleEvent*) event , reply) ;
+}
+
 // AEODoc Calls MacOpenFile on each of the files passed
 
 short wxApp::MacHandleAEODoc(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply))
@@ -219,18 +231,29 @@ short wxApp::MacHandleAEOApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNU
 
 short wxApp::MacHandleAEQuit(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
 {
-       wxWindow* win = GetTopWindow() ;
+    wxWindow* win = GetTopWindow() ;
     if ( win )
     {
-        win->Close(TRUE ) ;
+        wxCommandEvent exitEvent(wxEVT_COMMAND_MENU_SELECTED, s_macExitMenuItemId);
+        if (!win->ProcessEvent(exitEvent))
+            win->Close(TRUE ) ;
     }
-       else
+    else
     {
         ExitMainLoop() ;
     }
     return noErr ;
 }
 
+// AEROApp calls MacReopenApp
+
+short wxApp::MacHandleAERApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
+{
+    MacReopenApp() ;
+    return noErr ;
+}
+
+
 //----------------------------------------------------------------------
 // Support Routines linking the Mac...File Calls to the Document Manager
 //----------------------------------------------------------------------
@@ -274,6 +297,11 @@ void wxApp::MacNewFile()
 {
 }
 
+void wxApp::MacReopenApp()
+{
+    // eventually check for open docs, if none, call MacNewFile
+}
+
 //----------------------------------------------------------------------
 // Carbon Event Handler
 //----------------------------------------------------------------------
@@ -287,6 +315,7 @@ void wxApp::MacNewFile()
 
         { kEventClassMenu, kEventMenuOpening },
         { kEventClassMenu, kEventMenuClosed },
+        { kEventClassMenu, kEventMenuTargetItem },
 
         { kEventClassApplication , kEventAppActivated } ,
         { kEventClassApplication , kEventAppDeactivated } ,
@@ -305,8 +334,9 @@ void wxApp::MacNewFile()
 static pascal OSStatus
 MenuEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
 {
-    // FIXME: this doesn't work for multiple windows
-    wxWindow *win = wxTheApp->GetTopWindow();
+    wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar();
+    wxFrame* win = mbar->GetFrame();
+    
     if ( win )
     {
         // VZ: we could find the menu from its handle here by examining all
@@ -322,9 +352,29 @@ MenuEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
                           &menuRef);
 #endif // 0
 
-        wxMenuEvent wxevent(GetEventKind(event) == kEventMenuOpening
-                        ? wxEVT_MENU_OPEN
-                        : wxEVT_MENU_CLOSE);
+        wxEventType type=0;        
+        MenuCommand cmd=0;
+        switch (GetEventKind(event))
+        {
+            case kEventMenuOpening:
+                type = wxEVT_MENU_OPEN;
+                break;
+            case kEventMenuClosed:
+                type = wxEVT_MENU_CLOSE;
+                break;
+            case kEventMenuTargetItem:
+                type = wxEVT_MENU_HIGHLIGHT;
+                GetEventParameter(event, kEventParamMenuCommand,
+                                  typeMenuCommand, NULL,
+                                  sizeof(cmd), NULL, &cmd);
+                if (cmd == 0) return eventNotHandledErr;
+                break;
+            default:
+                wxFAIL_MSG(wxT("Unexpected menu event kind"));
+                break;
+        }
+
+        wxMenuEvent wxevent(type, cmd);
         wxevent.SetEventObject(win);
 
         (void)win->GetEventHandler()->ProcessEvent(wxevent);
@@ -521,7 +571,7 @@ bool wxApp::Initialize(int& argc, wxChar **argv)
 
     // Mac-specific
 
-    UMAInitToolbox( 4 ) ;
+    UMAInitToolbox( 4, sm_isEmbedded ) ;
     SetEventMask( everyEvent ) ;
     UMAShowWatchCursor() ;
 
@@ -609,16 +659,22 @@ bool wxApp::Initialize(int& argc, wxChar **argv)
     if ( argc > 1 )
     {
         static const wxChar *ARG_PSN = _T("-psn_");
-        if ( wxStrncmp(argv[1], ARG_PSN, sizeof(ARG_PSN) - 1) == 0 )
+        if ( wxStrncmp(argv[1], ARG_PSN, wxStrlen(ARG_PSN)) == 0 )
         {
             // remove this argument
-            memmove(argv, argv + 1, argc--);
+            --argc;
+            memmove(argv + 1, argv + 2, argc * sizeof(char *));
         }
     }
 
     if ( !wxAppBase::Initialize(argc, argv) )
         return false;
 
+#if wxUSE_INTL
+    wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
+#endif
+
+
     wxWinMacWindowList = new wxList(wxKEY_INTEGER);
     wxWinMacControlList = new wxList(wxKEY_INTEGER);
 
@@ -637,38 +693,50 @@ bool wxApp::OnInitGui()
 #if TARGET_CARBON
     InstallStandardEventHandler( GetApplicationEventTarget() ) ;
 
-    InstallApplicationEventHandler(
-        GetwxAppEventHandlerUPP(),
-        GetEventTypeCount(eventList), eventList, wxTheApp, (EventHandlerRef *)&(wxTheApp->m_macEventHandler));
+    if (!sm_isEmbedded)
+    {
+        InstallApplicationEventHandler(
+            GetwxAppEventHandlerUPP(),
+            GetEventTypeCount(eventList), eventList, wxTheApp, (EventHandlerRef *)&(wxTheApp->m_macEventHandler));
+    }
 #endif
 
+    if (!sm_isEmbedded)
+    {
 #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 ) ;
+        AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
+                               NewAEEventHandlerUPP(AEHandleODoc) ,
+                               0 , FALSE ) ;
+        AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
+                               NewAEEventHandlerUPP(AEHandleOApp) ,
+                               0 , FALSE ) ;
+        AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
+                               NewAEEventHandlerUPP(AEHandlePDoc) ,
+                               0 , FALSE ) ;
+        AEInstallEventHandler( kCoreEventClass , kAEReopenApplication ,
+                               NewAEEventHandlerUPP(AEHandleRApp) ,
+                               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 ) ;
+        AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
+                               NewAEEventHandlerProc(AEHandleODoc) ,
+                               0 , FALSE ) ;
+        AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
+                               NewAEEventHandlerProc(AEHandleOApp) ,
+                               0 , FALSE ) ;
+        AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
+                               NewAEEventHandlerProc(AEHandlePDoc) ,
+                               0 , FALSE ) ;
+        AEInstallEventHandler( kCoreEventClass , kAEReopenApplication ,
+                               NewAEEventHandlerProc(AEHandleRApp) ,
+                               0 , FALSE ) ;
+        AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
+                               NewAEEventHandlerProc(AEHandleQuit) ,
+                               0 , FALSE ) ;
 #endif
+    }
 
     return TRUE ;
 }
@@ -801,7 +869,11 @@ void wxStAppResource::OpenSharedLibraryResource(const void *initBlock)
 
             // allocate copy to replace .dylib.* extension with .rsrc
             if (theLibPath != NULL) {
-                theResPath = theLibPath;
+#if wxUSE_UNICODE
+                theResPath = wxString(theLibPath, wxConvLocal);
+#else
+                theResPath = wxString(theLibPath);
+#endif
                 // replace '_core' with '' in case of multi-lib build
                 theResPath.Replace(wxT("_core"), wxEmptyString);
                 // replace ".dylib" shared library extension with ".rsrc"
@@ -827,9 +899,8 @@ void wxStAppResource::OpenSharedLibraryResource(const void *initBlock)
                 }
                 if (theErr != noErr) {
 #ifdef __WXDEBUG__
-                    fprintf(stderr,
-                            wxT("unable to open wxMac resource file '%s'\n"),
-                            theResPath.mb_str() );
+                    wxLogDebug( wxT("unable to open wxMac resource file '%s'\n"),
+                                theResPath.mb_str() );
 #endif // __WXDEBUG__
                 }
 
@@ -1010,14 +1081,6 @@ wxApp::wxApp()
 #endif
 }
 
-bool wxApp::Initialized()
-{
-  if (GetTopWindow())
-    return TRUE;
-  else
-    return FALSE;
-}
-
 int wxApp::MainLoop()
 {
     m_keepGoing = TRUE;
@@ -1249,7 +1312,18 @@ void wxApp::MacDoOneEvent()
         if ( wxTheApp->ProcessIdle() )
             sleepTime = kEventDurationNoWait ;
         else
-            sleepTime = kEventDurationForever ;
+        {
+#if wxUSE_THREADS
+            if (g_numberOfThreads)
+            {
+                sleepTime = kEventDurationNoWait;
+            }
+            else
+#endif // wxUSE_THREADS
+            {
+                sleepTime = kEventDurationSecond;
+            }
+        }
     }
     else if ( status == eventLoopQuitErr )
     {
@@ -1281,9 +1355,20 @@ void wxApp::MacDoOneEvent()
             ::IdleControls( window ) ;
 
         if ( wxTheApp->ProcessIdle() )
-            sleepTime = ;
+            sleepTime = kEventDurationNoWait;
         else
-            sleepTime = GetCaretTime() / 2 ;
+        {
+#if wxUSE_THREADS
+            if (g_numberOfThreads)
+            {
+                sleepTime = kEventDurationNoWait;
+            }
+            else
+#endif // wxUSE_THREADS
+            {
+                sleepTime = kEventDurationSecond;
+            }
+        }
     }
     if ( event.what != kHighLevelEvent )
         SetRectRgn( (RgnHandle) s_macCursorRgn , event.where.h , event.where.v ,  event.where.h + 1 , event.where.v + 1 ) ;
@@ -1294,13 +1379,22 @@ void wxApp::MacDoOneEvent()
     wxMacProcessNotifierAndPendingEvents() ;
 }
 
+/*virtual*/ void wxApp::MacHandleUnhandledEvent( WXEVENTREF evr )
+{
+    // Override to process unhandled events as you please    
+}
+
 void wxApp::MacHandleOneEvent( WXEVENTREF evr )
 {
 #if TARGET_CARBON
     EventTargetRef theTarget;
     theTarget = GetEventDispatcherTarget();
     m_macCurrentEvent = evr ;
-    SendEventToEventTarget ((EventRef) evr , theTarget);
+    OSStatus status = SendEventToEventTarget ((EventRef) evr , theTarget);
+    if(status == eventNotHandledErr)
+    {
+        MacHandleUnhandledEvent(evr);
+    }
 #else
     EventRecord* ev = (EventRecord*) evr ;
     m_macCurrentEvent = ev ;
@@ -1332,6 +1426,10 @@ void wxApp::MacHandleOneEvent( WXEVENTREF evr )
             MacHandleActivateEvent( ev ) ;
             break;
         case updateEvt:
+            // In embedded mode we first let the UnhandledEvent function
+            // try to handle the update event. If we handle it ourselves
+            // first and then pass it on, the host's windows won't update.
+            MacHandleUnhandledEvent(ev);
             MacHandleUpdateEvent( ev ) ;
             break;
         case keyDown:
@@ -1721,6 +1819,49 @@ long wxMacTranslateKey(unsigned char key, unsigned char code)
     return retval;
 }
 
+int wxKeyCodeToMacModifier(wxKeyCode key)
+{
+    switch (key)
+    {
+    case WXK_START:
+    case WXK_MENU:
+        return cmdKey;
+
+    case WXK_SHIFT:
+        return shiftKey;
+
+    case WXK_CAPITAL:
+        return alphaLock;
+
+    case WXK_ALT:
+        return optionKey;
+
+    case WXK_CONTROL:
+        return controlKey;
+
+    default:
+        return 0;
+    }
+}
+
+bool wxGetKeyState(wxKeyCode key) //virtual key code if < 10.2.x, else see below
+{
+//#ifdef __DARWIN__
+//     wxHIDKeyboard keyboard;
+//     return keyboard.IsActive(key);
+//#else
+// TODO:  Have it use HID Manager on OSX...
+//if OS X > 10.2 (i.e. 10.2.x)
+//a known apple bug prevents the system from determining led
+//states with GetKeys... can only determine caps lock led
+   return !!(GetCurrentKeyModifiers() & wxKeyCodeToMacModifier(key)); 
+//else
+//  KeyMapByteArray keymap; 
+//  GetKeys((BigEndianLong*)keymap);
+//  return !!(BitTst(keymap, (sizeof(KeyMapByteArray)*8) - iKey));
+//#endif
+}
+
 #if !TARGET_CARBON
 void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr )
 {