1/////////////////////////////////////////////////////////////////////////////
2// Name:        src/mac/classic/app.cpp
3// Purpose:     wxApp
4// Author:      Stefan Csomor
5// Modified by:
6// Created:     1998-01-01
7// RCS-ID:      $Id: app.cpp 40943 2006-08-31 19:31:43Z ABX $
8// Copyright:   (c) Stefan Csomor
9// Licence:     wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15    #pragma hdrstop
16#endif
17
18#include "wx/app.h"
19
20#ifndef WX_PRECOMP
21    #include "wx/intl.h"
22    #include "wx/log.h"
23    #include "wx/utils.h"
24    #include "wx/window.h"
25    #include "wx/frame.h"
26    #include "wx/dc.h"
27    #include "wx/button.h"
28    #include "wx/menu.h"
29    #include "wx/pen.h"
30    #include "wx/brush.h"
31    #include "wx/palette.h"
32    #include "wx/icon.h"
33    #include "wx/cursor.h"
34    #include "wx/dialog.h"
35    #include "wx/msgdlg.h"
36    #include "wx/textctrl.h"
37    #include "wx/memory.h"
38    #include "wx/gdicmn.h"
39    #include "wx/module.h"
40#endif
41
42#include "wx/tooltip.h"
43#include "wx/docview.h"
44#include "wx/filename.h"
45
46#include <string.h>
47
48// mac
49
50#ifndef __DARWIN__
51    #if __option(profile)
52        #include <profiler.h>
53    #endif
54#endif
55
56#include "apprsrc.h"
57
58#include "wx/mac/uma.h"
59#include "wx/mac/macnotfy.h"
60
61#ifdef __DARWIN__
62#  include <CoreServices/CoreServices.h>
63#  if defined(WXMAKINGDLL_CORE)
64#    include <mach-o/dyld.h>
65#  endif
66#else
67#  include <Sound.h>
68#  include <Threads.h>
69#  include <ToolUtils.h>
70#  include <DiskInit.h>
71#  include <Devices.h>
72#endif
73
74extern wxList wxPendingDelete;
75extern wxList *wxWinMacWindowList;
76extern wxList *wxWinMacControlList;
77#if wxUSE_THREADS
78extern size_t g_numberOfThreads;
79#endif // wxUSE_THREADS
80
81// statics for implementation
82
83static bool s_inYield = false;
84
85#if TARGET_CARBON
86static bool s_inReceiveEvent = false ;
87static EventTime sleepTime = kEventDurationNoWait ;
88#else
89static long sleepTime = 0 ;
90#endif
91
92IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
93BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
94    EVT_IDLE(wxApp::OnIdle)
95    EVT_END_SESSION(wxApp::OnEndSession)
96    EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
97END_EVENT_TABLE()
98
99const short    kMacMinHeap = (29 * 1024) ;
100// platform specific static variables
101
102const short kwxMacMenuBarResource = 1 ;
103const short kwxMacAppleMenuId = 1 ;
104
105WXHRGN    wxApp::s_macCursorRgn = NULL;
106wxWindow* wxApp::s_captureWindow = NULL ;
107int       wxApp::s_lastMouseDown = 0 ;
108long      wxApp::sm_lastMessageTime = 0;
109long      wxApp::s_lastModifiers = 0 ;
110
111
112bool      wxApp::s_macSupportPCMenuShortcuts = true ;
113long      wxApp::s_macAboutMenuItemId = wxID_ABOUT ;
114long      wxApp::s_macPreferencesMenuItemId = wxID_PREFERENCES ;
115long      wxApp::s_macExitMenuItemId = wxID_EXIT ;
116wxString  wxApp::s_macHelpMenuTitleName = wxT("&Help") ;
117
118// Normally we're not a plugin
119bool      wxApp::sm_isEmbedded = false;
120//----------------------------------------------------------------------
121// Core Apple Event Support
122//----------------------------------------------------------------------
123
124pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
125pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
126pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
127pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
128pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
129
130pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
131{
132    return wxTheApp->MacHandleAEODoc( (AppleEvent*) event , reply) ;
133}
134
135pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
136{
137    return wxTheApp->MacHandleAEOApp( (AppleEvent*) event , reply ) ;
138}
139
140pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
141{
142    return wxTheApp->MacHandleAEPDoc( (AppleEvent*) event , reply ) ;
143}
144
145pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
146{
147    return wxTheApp->MacHandleAEQuit( (AppleEvent*) event , reply) ;
148}
149
150pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
151{
152    return wxTheApp->MacHandleAERApp( (AppleEvent*) event , reply) ;
153}
154
155// AEODoc Calls MacOpenFile on each of the files passed
156
157short wxApp::MacHandleAEODoc(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply))
158{
159    AEDescList docList;
160    AEKeyword keywd;
161    DescType returnedType;
162    Size actualSize;
163    long itemsInList;
164    FSSpec theSpec;
165    OSErr err;
166    short i;
167    err = AEGetParamDesc((AppleEvent *)event, keyDirectObject, typeAEList,&docList);
168    if (err != noErr)
169        return err;
170
171    err = AECountItems(&docList, &itemsInList);
172    if (err != noErr)
173        return err;
174
175    ProcessSerialNumber PSN ;
176    PSN.highLongOfPSN = 0 ;
177    PSN.lowLongOfPSN = kCurrentProcess ;
178    SetFrontProcess( &PSN ) ;
179
180    for (i = 1; i <= itemsInList; i++) {
181        AEGetNthPtr(&docList, i, typeFSS, &keywd, &returnedType,
182        (Ptr) & theSpec, sizeof(theSpec), &actualSize);
183        wxString fName = wxMacFSSpec2MacFilename(&theSpec);
184        MacOpenFile(fName);
185    }
186    return noErr;
187}
188
189// AEPDoc Calls MacPrintFile on each of the files passed
190
191short wxApp::MacHandleAEPDoc(const WXEVENTREF event , WXEVENTREF WXUNUSED(reply))
192{
193    AEDescList docList;
194    AEKeyword keywd;
195    DescType returnedType;
196    Size actualSize;
197    long itemsInList;
198    FSSpec theSpec;
199    OSErr err;
200    short i;
201    err = AEGetParamDesc((AppleEvent *)event, keyDirectObject, typeAEList,&docList);
202    if (err != noErr)
203        return err;
204
205    err = AECountItems(&docList, &itemsInList);
206    if (err != noErr)
207        return err;
208
209    ProcessSerialNumber PSN ;
210    PSN.highLongOfPSN = 0 ;
211    PSN.lowLongOfPSN = kCurrentProcess ;
212    SetFrontProcess( &PSN ) ;
213
214    for (i = 1; i <= itemsInList; i++) {
215        AEGetNthPtr(&docList, i, typeFSS, &keywd, &returnedType,
216        (Ptr) & theSpec, sizeof(theSpec), &actualSize);
217        wxString fName = wxMacFSSpec2MacFilename(&theSpec);
218        MacPrintFile(fName);
219    }
220    return noErr;
221}
222
223// AEOApp calls MacNewFile
224
225short wxApp::MacHandleAEOApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
226{
227    MacNewFile() ;
228    return noErr ;
229}
230
231// AEQuit attempts to quit the application
232
233short wxApp::MacHandleAEQuit(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
234{
235    wxWindow* win = GetTopWindow() ;
236    if ( win )
237    {
238        wxCommandEvent exitEvent(wxEVT_COMMAND_MENU_SELECTED, s_macExitMenuItemId);
239        if (!win->ProcessEvent(exitEvent))
240            win->Close(true) ;
241    }
242    else
243    {
244        ExitMainLoop() ;
245    }
246    return noErr ;
247}
248
249// AEROApp calls MacReopenApp
250
251short wxApp::MacHandleAERApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
252{
253    MacReopenApp() ;
254    return noErr ;
255}
256
257
258//----------------------------------------------------------------------
259// Support Routines linking the Mac...File Calls to the Document Manager
260//----------------------------------------------------------------------
261
262void wxApp::MacOpenFile(const wxString & fileName )
263{
264    wxDocManager* dm = wxDocManager::GetDocumentManager() ;
265    if ( dm )
266        dm->CreateDocument(fileName , wxDOC_SILENT ) ;
267}
268
269void wxApp::MacPrintFile(const wxString & fileName )
270{
271    wxDocManager* dm = wxDocManager::GetDocumentManager() ;
272    if ( dm )
273    {
274        wxDocument *doc = dm->CreateDocument(fileName , wxDOC_SILENT ) ;
275        if ( doc )
276        {
277            wxView* view = doc->GetFirstView() ;
278            if( view )
279            {
280                wxPrintout *printout = view->OnCreatePrintout();
281                if (printout)
282                {
283                    wxPrinter printer;
284                    printer.Print(view->GetFrame(), printout, true);
285                    delete printout;
286                }
287            }
288            if (doc->Close())
289            {
290                doc->DeleteAllViews();
291                dm->RemoveDocument(doc) ;
292            }
293        }
294    }
295}
296
297void wxApp::MacNewFile()
298{
299}
300
301void wxApp::MacReopenApp()
302{
303    // eventually check for open docs, if none, call MacNewFile
304}
305
306//----------------------------------------------------------------------
307// Carbon Event Handler
308//----------------------------------------------------------------------
309
310#if TARGET_CARBON
311
312    static const EventTypeSpec eventList[] =
313    {
314        { kEventClassCommand, kEventProcessCommand } ,
315        { kEventClassCommand, kEventCommandUpdateStatus } ,
316
317        { kEventClassMenu, kEventMenuOpening },
318        { kEventClassMenu, kEventMenuClosed },
319        { kEventClassMenu, kEventMenuTargetItem },
320
321        { kEventClassApplication , kEventAppActivated } ,
322        { kEventClassApplication , kEventAppDeactivated } ,
323        // handling the quit event is not recommended by apple
324        // rather using the quit apple event - which we do
325
326        { kEventClassAppleEvent , kEventAppleEvent } ,
327
328        { kEventClassMouse , kEventMouseDown } ,
329        { kEventClassMouse , kEventMouseMoved } ,
330        { kEventClassMouse , kEventMouseUp } ,
331        { kEventClassMouse , kEventMouseDragged } ,
332        { 'WXMC' , 'WXMC' }
333    } ;
334
335static pascal OSStatus
336MenuEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
337{
338    wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar();
339
340    if ( mbar )
341    {
342        wxFrame* win = mbar->GetFrame();
343        if ( win )
344        {
345
346            // VZ: we could find the menu from its handle here by examining all
347            //     the menus in the menu bar recursively but knowing that neither
348            //     wxMSW nor wxGTK do it why bother...
349#if 0
350            MenuRef menuRef;
351
352            GetEventParameter(event,
353                              kEventParamDirectObject,
354                              typeMenuRef, NULL,
355                              sizeof(menuRef), NULL,
356                              &menuRef);
357#endif // 0
358
359            wxEventType type=0;
360            MenuCommand cmd=0;
361            switch (GetEventKind(event))
362            {
363                case kEventMenuOpening:
364                    type = wxEVT_MENU_OPEN;
365                    break;
366                case kEventMenuClosed:
367                    type = wxEVT_MENU_CLOSE;
368                    break;
369                case kEventMenuTargetItem:
370                    type = wxEVT_MENU_HIGHLIGHT;
371                    GetEventParameter(event, kEventParamMenuCommand,
372                                      typeMenuCommand, NULL,
373                                      sizeof(cmd), NULL, &cmd);
374                    if (cmd == 0) return eventNotHandledErr;
375                    break;
376                default:
377                    wxFAIL_MSG(wxT("Unexpected menu event kind"));
378                    break;
379            }
380
381            wxMenuEvent wxevent(type, cmd);
382            wxevent.SetEventObject(win);
383
384            (void)win->GetEventHandler()->ProcessEvent(wxevent);
385        }
386    }
387
388    return eventNotHandledErr;
389}
390
391// due to the rather low-level event API of wxWidgets, we cannot use RunApplicationEventLoop
392// but have to use ReceiveNextEvent dealing with events manually, therefore we also have
393// to deal with clicks in the menu bar explicitly
394
395pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) ;
396
397static pascal OSStatus MouseEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
398{
399    OSStatus result = eventNotHandledErr ;
400
401    Point point ;
402    UInt32 modifiers = 0;
403    EventMouseButton button = 0 ;
404    UInt32 click = 0 ;
405
406    GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL,
407        sizeof( Point ), NULL, &point );
408    GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL,
409        sizeof( UInt32 ), NULL, &modifiers );
410    GetEventParameter( event, kEventParamMouseButton, typeMouseButton, NULL,
411        sizeof( EventMouseButton ), NULL, &button );
412    GetEventParameter( event, kEventParamClickCount, typeUInt32, NULL,
413        sizeof( UInt32 ), NULL, &click );
414
415    if ( button == 0 || GetEventKind( event ) == kEventMouseUp )
416        modifiers += btnState ;
417
418
419    switch( GetEventKind(event) )
420    {
421        case kEventMouseDown :
422        {
423            WindowRef window ;
424
425            short windowPart = ::FindWindow(point, &window);
426
427            if ( windowPart == inMenuBar )
428            {
429                MenuSelect( point ) ;
430                result = noErr ;
431            }
432        }
433        break ;
434        case kEventMouseDragged :
435        case kEventMouseUp :
436        {
437            if ( wxTheApp->s_captureWindow )
438                wxMacWindowEventHandler( handler , event , (void*) wxTheApp->s_captureWindow->MacGetTopLevelWindow() ) ;
439        }
440        break ;
441        case kEventMouseMoved :
442        {
443            wxTheApp->MacHandleMouseMovedEvent( point.h , point.v , modifiers , EventTimeToTicks( GetEventTime( event ) ) ) ;
444            result = noErr ;
445            break ;
446        }
447        break ;
448    }
449
450    return result ;
451}
452
453static pascal OSStatus CommandEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
454{
455    OSStatus result = eventNotHandledErr ;
456
457    HICommand command ;
458
459    GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL,
460        sizeof( HICommand ), NULL, &command );
461
462    MenuCommand id = command.commandID ;
463    if ( id == kHICommandPreferences )
464        id = wxApp::s_macPreferencesMenuItemId ;
465
466    wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ;
467    wxMenu* menu = NULL ;
468    wxMenuItem* item = NULL ;
469
470    if ( mbar )
471    {
472        item = mbar->FindItem( id , &menu ) ;
473        // it is not 100 % sure that an menu of id 0 is really ours, safety check
474        if ( id == 0 && menu != NULL && menu->GetHMenu() != command.menu.menuRef )
475        {
476            item = NULL ;
477            menu = NULL ;
478        }
479    }
480
481    if ( item == NULL || menu == NULL || mbar == NULL )
482        return result ;
483
484       switch( GetEventKind( event ) )
485       {
486           case kEventProcessCommand :
487           {
488                if (item->IsCheckable())
489                {
490                    item->Check( !item->IsChecked() ) ;
491                }
492
493                menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
494                result = noErr ;
495            }
496               break ;
497        case kEventCommandUpdateStatus:
498            // eventually trigger an updateui round
499            result = noErr ;
500            break ;
501           default :
502               break ;
503       }
504
505    return result ;
506}
507
508static pascal OSStatus ApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
509{
510    OSStatus result = eventNotHandledErr ;
511    switch ( GetEventKind( event ) )
512    {
513        case kEventAppActivated :
514            {
515                if ( wxTheApp )
516                    wxTheApp->MacResume( true ) ;
517                result = noErr ;
518            }
519            break ;
520        case kEventAppDeactivated :
521            {
522                if ( wxTheApp )
523                    wxTheApp->MacSuspend( true ) ;
524                result = noErr ;
525            }
526            break ;
527        default :
528            break ;
529    }
530    return result ;
531}
532
533pascal OSStatus wxAppEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
534{
535    OSStatus result = eventNotHandledErr ;
536    switch( GetEventClass( event ) )
537    {
538        case kEventClassCommand :
539            result = CommandEventHandler( handler , event , data ) ;
540            break ;
541        case kEventClassApplication :
542            result = ApplicationEventHandler( handler , event , data ) ;
543            break ;
544        case kEventClassMenu :
545            result = MenuEventHandler( handler , event , data ) ;
546            break ;
547        case kEventClassMouse :
548            result = MouseEventHandler( handler , event , data ) ;
549            break ;
550        case kEventClassAppleEvent :
551            {
552                EventRecord rec ;
553                wxMacConvertEventToRecord( event , &rec ) ;
554                result = AEProcessAppleEvent( &rec ) ;
555            }
556            break ;
557        default :
558            break ;
559    }
560
561    return result ;
562}
563
564DEFINE_ONE_SHOT_HANDLER_GETTER( wxAppEventHandler )
565
566#endif
567
568#if defined(WXMAKINGDLL_CORE) && !defined(__DARWIN__)
569// we know it's there ;-)
570WXIMPORT char std::__throws_bad_alloc ;
571#endif
572
573bool wxApp::Initialize(int& argc, wxChar **argv)
574{
575    int error = 0 ;
576
577    // Mac-specific
578
579    UMAInitToolbox( 4, sm_isEmbedded ) ;
580    SetEventMask( everyEvent ) ;
581    UMAShowWatchCursor() ;
582
583#if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
584    // open shared library resources from here since we don't have
585    //   __wxinitialize in Mach-O shared libraries
586    wxStAppResource::OpenSharedLibraryResource(NULL);
587#endif
588
589#ifndef __DARWIN__
590    // test the minimal configuration necessary
591
592#  if !TARGET_CARBON
593    long theSystem ;
594    long theMachine;
595
596    if (Gestalt(gestaltMachineType, &theMachine) != noErr)
597    {
598        error = kMacSTRWrongMachine;
599    }
600    else if (theMachine < gestaltMacPlus)
601    {
602        error = kMacSTRWrongMachine;
603    }
604    else if (Gestalt(gestaltSystemVersion, &theSystem) != noErr )
605    {
606        error = kMacSTROldSystem  ;
607    }
608    else if ( theSystem < 0x0860 )
609    {
610        error = kMacSTROldSystem  ;
611    }
612    else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap)
613    {
614        error = kMacSTRSmallSize;
615    }
616#  endif
617    /*
618    else
619    {
620        if ( !UMAHasAppearance() )
621        {
622            error = kMacSTRNoPre8Yet ;
623        }
624    }
625    */
626#endif
627
628    // if we encountered any problems so far, give the error code and exit immediately
629
630  if ( error )
631  {
632        wxStAppResource resload ;
633        short itemHit;
634        Str255 message;
635
636        GetIndString(message, 128, error);
637        UMAShowArrowCursor() ;
638        ParamText("\pFatal Error", message, (ConstStr255Param)"\p", (ConstStr255Param)"\p");
639        itemHit = Alert(128, nil);
640        return false ;
641  }
642
643#ifndef __DARWIN__
644#  if __option(profile)
645    ProfilerInit( collectDetailed, bestTimeBase , 40000 , 50 ) ;
646#  endif
647#endif
648
649#ifndef __DARWIN__
650    // now avoid exceptions thrown for new (bad_alloc)
651    // FIXME CS for some changes outside wxMac does not compile anymore
652#if 0
653    std::__throws_bad_alloc = 0 ;
654#endif
655
656#endif
657
658    s_macCursorRgn = ::NewRgn() ;
659
660    // Mac OS X passes a process serial number command line argument when
661    // the application is launched from the Finder. This argument must be
662    // removed from the command line arguments before being handled by the
663    // application (otherwise applications would need to handle it)
664    if ( argc > 1 )
665    {
666        static const wxChar *ARG_PSN = _T("-psn_");
667        if ( wxStrncmp(argv[1], ARG_PSN, wxStrlen(ARG_PSN)) == 0 )
668        {
669            // remove this argument
670            --argc;
671            memmove(argv + 1, argv + 2, argc * sizeof(char *));
672        }
673    }
674
675    if ( !wxAppBase::Initialize(argc, argv) )
676        return false;
677
678#if wxUSE_INTL
679    wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
680#endif
681
682
683    wxWinMacWindowList = new wxList(wxKEY_INTEGER);
684    wxWinMacControlList = new wxList(wxKEY_INTEGER);
685
686    wxMacCreateNotifierTable() ;
687
688    UMAShowArrowCursor() ;
689
690    return true;
691}
692
693bool wxApp::OnInitGui()
694{
695    if( !wxAppBase::OnInitGui() )
696        return false ;
697
698#if TARGET_CARBON
699    InstallStandardEventHandler( GetApplicationEventTarget() ) ;
700
701    if (!sm_isEmbedded)
702    {
703        InstallApplicationEventHandler(
704            GetwxAppEventHandlerUPP(),
705            GetEventTypeCount(eventList), eventList, wxTheApp, (EventHandlerRef *)&(wxTheApp->m_macEventHandler));
706    }
707#endif
708
709    if (!sm_isEmbedded)
710    {
711#if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
712        AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
713                               NewAEEventHandlerUPP(AEHandleODoc) ,
714                               0 , FALSE ) ;
715        AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
716                               NewAEEventHandlerUPP(AEHandleOApp) ,
717                               0 , FALSE ) ;
718        AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
719                               NewAEEventHandlerUPP(AEHandlePDoc) ,
720                               0 , FALSE ) ;
721        AEInstallEventHandler( kCoreEventClass , kAEReopenApplication ,
722                               NewAEEventHandlerUPP(AEHandleRApp) ,
723                               0 , FALSE ) ;
724        AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
725                               NewAEEventHandlerUPP(AEHandleQuit) ,
726                               0 , FALSE ) ;
727#else
728        AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
729                               NewAEEventHandlerProc(AEHandleODoc) ,
730                               0 , FALSE ) ;
731        AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
732                               NewAEEventHandlerProc(AEHandleOApp) ,
733                               0 , FALSE ) ;
734        AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
735                               NewAEEventHandlerProc(AEHandlePDoc) ,
736                               0 , FALSE ) ;
737        AEInstallEventHandler( kCoreEventClass , kAEReopenApplication ,
738                               NewAEEventHandlerProc(AEHandleRApp) ,
739                               0 , FALSE ) ;
740        AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
741                               NewAEEventHandlerProc(AEHandleQuit) ,
742                               0 , FALSE ) ;
743#endif
744    }
745
746    return true ;
747}
748
749void wxApp::CleanUp()
750{
751    wxToolTip::RemoveToolTips() ;
752
753    // One last chance for pending objects to be cleaned up
754    wxTheApp->DeletePendingObjects();
755
756    wxMacDestroyNotifierTable() ;
757
758    delete wxWinMacWindowList ;
759    wxWinMacWindowList = NULL;
760
761    delete wxWinMacControlList ;
762    wxWinMacControlList = NULL;
763
764#ifndef __DARWIN__
765#  if __option(profile)
766    ProfilerDump( (StringPtr)"\papp.prof" ) ;
767    ProfilerTerm() ;
768#  endif
769#endif
770
771#if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
772    // close shared library resources from here since we don't have
773    //   __wxterminate in Mach-O shared libraries
774    wxStAppResource::CloseSharedLibraryResource();
775#endif
776
777    UMACleanupToolbox() ;
778    if (s_macCursorRgn) {
779        ::DisposeRgn((RgnHandle)s_macCursorRgn);
780    }
781
782    #if 0
783        TerminateAE() ;
784    #endif
785
786    wxAppBase::CleanUp();
787}
788
789//----------------------------------------------------------------------
790// misc initialization stuff
791//----------------------------------------------------------------------
792
793// extern variable for shared library resource id
794// need to be able to find it with NSLookupAndBindSymbol
795short gSharedLibraryResource = kResFileNotOpened ;
796
797#if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
798CFBundleRef gSharedLibraryBundle = NULL;
799#endif /* WXMAKINGDLL_CORE && __DARWIN__ */
800
801wxStAppResource::wxStAppResource()
802{
803    m_currentRefNum = CurResFile() ;
804    if ( gSharedLibraryResource != kResFileNotOpened )
805    {
806        UseResFile( gSharedLibraryResource ) ;
807    }
808}
809
810wxStAppResource::~wxStAppResource()
811{
812    if ( m_currentRefNum != kResFileNotOpened )
813    {
814        UseResFile( m_currentRefNum ) ;
815    }
816}
817
818void wxStAppResource::OpenSharedLibraryResource(const void *initBlock)
819{
820    gSharedLibraryResource = kResFileNotOpened;
821
822#ifdef WXMAKINGDLL_CORE
823    if ( initBlock != NULL ) {
824        const CFragInitBlock *theInitBlock = (const CFragInitBlock *)initBlock;
825        FSSpec *fileSpec = NULL;
826
827        if (theInitBlock->fragLocator.where == kDataForkCFragLocator) {
828            fileSpec = theInitBlock->fragLocator.u.onDisk.fileSpec;
829        }
830        else if (theInitBlock->fragLocator.where == kResourceCFragLocator) {
831            fileSpec = theInitBlock->fragLocator.u.inSegs.fileSpec;
832        }
833
834        if (fileSpec != NULL) {
835            gSharedLibraryResource =  FSpOpenResFile(fileSpec, fsRdPerm);
836        }
837    }
838    else {
839#ifdef __DARWIN__
840        // Open the shared library resource file if it is not yet open
841        NSSymbol    theSymbol;
842        NSModule    theModule;
843        const char *theLibPath;
844
845        gSharedLibraryBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWidgets"));
846        if (gSharedLibraryBundle != NULL) {
847            // wxWidgets has been bundled into a framework
848            //   load the framework resources
849
850            gSharedLibraryResource = CFBundleOpenBundleResourceMap(gSharedLibraryBundle);
851        }
852        else {
853            // wxWidgets is a simple dynamic shared library
854            //   load the resources from the data fork of a separate resource file
855            wxString theResPath;
856            wxString theName;
857            FSRef  theResRef;
858            OSErr  theErr = noErr;
859
860            // get the library path
861            theSymbol = NSLookupAndBindSymbol("_gSharedLibraryResource");
862            theModule = NSModuleForSymbol(theSymbol);
863            theLibPath = NSLibraryNameForModule(theModule);
864
865            // if we call wxLogDebug from here then, as wxTheApp hasn't been
866            // created yet when we're called from wxApp::Initialize(), wxLog
867            // is going to create a default stderr-based log target instead of
868            // the expected normal GUI one -- don't do it, if we really want
869            // to see this message just use fprintf() here
870#if 0
871            wxLogDebug( wxT("wxMac library installation name is '%s'"),
872                        theLibPath );
873#endif
874
875            // allocate copy to replace .dylib.* extension with .rsrc
876            if (theLibPath != NULL) {
877#if wxUSE_UNICODE
878                theResPath = wxString(theLibPath, wxConvLocal);
879#else
880                theResPath = wxString(theLibPath);
881#endif
882                // replace '_core' with '' in case of multi-lib build
883                theResPath.Replace(wxT("_core"), wxEmptyString);
884                // replace ".dylib" shared library extension with ".rsrc"
885                theResPath.Replace(wxT(".dylib"), wxT(".rsrc"));
886                // Find the begining of the filename
887                theName = theResPath.AfterLast('/');
888
889#if 0
890                wxLogDebug( wxT("wxMac resources file name is '%s'"),
891                            theResPath.mb_str() );
892#endif
893
894                theErr = FSPathMakeRef((UInt8 *) theResPath.mb_str(), &theResRef, false);
895                if (theErr != noErr) {
896                    // try in current directory (using name only)
897                    theErr = FSPathMakeRef((UInt8 *) theName.mb_str(), &theResRef, false);
898                }
899
900                // open the resource file
901                if (theErr == noErr) {
902                    theErr = FSOpenResourceFile( &theResRef, 0, NULL, fsRdPerm,
903                                                 &gSharedLibraryResource);
904                }
905                if (theErr != noErr) {
906#ifdef __WXDEBUG__
907                    wxLogDebug( wxT("unable to open wxMac resource file '%s'\n"),
908                                theResPath.mb_str() );
909#endif // __WXDEBUG__
910                }
911
912            }
913        }
914#endif /* __DARWIN__ */
915    }
916#endif /* WXMAKINGDLL_CORE */
917}
918
919void wxStAppResource::CloseSharedLibraryResource()
920{
921#ifdef WXMAKINGDLL_CORE
922    // Close the shared library resource file
923    if (gSharedLibraryResource != kResFileNotOpened) {
924#ifdef __DARWIN__
925        if (gSharedLibraryBundle != NULL) {
926            CFBundleCloseBundleResourceMap(gSharedLibraryBundle,
927                                           gSharedLibraryResource);
928            gSharedLibraryBundle = NULL;
929        }
930        else
931#endif /* __DARWIN__ */
932        {
933            CloseResFile(gSharedLibraryResource);
934        }
935        gSharedLibraryResource = kResFileNotOpened;
936    }
937#endif /* WXMAKINGDLL_CORE */
938}
939
940#if defined(WXMAKINGDLL_CORE) && !defined(__DARWIN__)
941
942// for shared libraries we have to manually get the correct resource
943// ref num upon initializing and releasing when terminating, therefore
944// the __wxinitialize and __wxterminate must be used
945
946extern "C" {
947    void __sinit(void);    /*    (generated by linker)    */
948    pascal OSErr __initialize(const CFragInitBlock *theInitBlock);
949    pascal void __terminate(void);
950}
951
952pascal OSErr __wxinitialize(const CFragInitBlock *theInitBlock)
953{
954    wxStAppResource::OpenSharedLibraryResource( theInitBlock ) ;
955    return __initialize( theInitBlock ) ;
956}
957
958pascal void __wxterminate(void)
959{
960    wxStAppResource::CloseSharedLibraryResource() ;
961    __terminate() ;
962}
963
964#endif /* WXMAKINGDLL_CORE && !__DARWIN__ */
965
966#if TARGET_CARBON
967
968bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec)
969{
970    bool converted = ConvertEventRefToEventRecord( event,rec) ;
971    OSStatus err = noErr ;
972    if ( !converted )
973    {
974        switch( GetEventClass( event ) )
975        {
976            case kEventClassKeyboard :
977            {
978                converted = true ;
979                switch( GetEventKind(event) )
980                {
981                    case kEventRawKeyDown :
982                        rec->what = keyDown ;
983                        break ;
984                    case kEventRawKeyRepeat :
985                        rec->what = autoKey ;
986                        break ;
987                    case kEventRawKeyUp :
988                        rec->what = keyUp ;
989                        break ;
990                    case kEventRawKeyModifiersChanged :
991                        rec->what = nullEvent ;
992                        break ;
993                    default :
994                        converted = false ;
995                        break ;
996                }
997                if ( converted )
998                {
999                    UInt32 keyCode ;
1000                    unsigned char charCode ;
1001                    UInt32 modifiers ;
1002                    GetMouse( &rec->where) ;
1003
1004                    err = GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers);
1005                    err = GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode);
1006                    err = GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode);
1007                    rec->modifiers = modifiers ;
1008                    rec->message = (keyCode << 8 ) + charCode ;
1009                }
1010            }
1011            break ;
1012            case kEventClassTextInput :
1013            {
1014                switch( GetEventKind( event ) )
1015                {
1016                    case kEventTextInputUnicodeForKeyEvent :
1017                        {
1018                            EventRef rawEvent ;
1019                            err = GetEventParameter( event , kEventParamTextInputSendKeyboardEvent ,typeEventRef,NULL,sizeof(rawEvent),NULL,&rawEvent ) ;
1020                            converted = true ;
1021                            {
1022                                UInt32 keyCode ;
1023                                unsigned char charCode ;
1024                                UInt32 modifiers ;
1025                                GetMouse( &rec->where) ;
1026                                rec->what = keyDown ;
1027                                err = GetEventParameter(rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers);
1028                                err = GetEventParameter(rawEvent, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode);
1029                                err = GetEventParameter(rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode);
1030                                rec->modifiers = modifiers ;
1031                                rec->message = (keyCode << 8 ) + charCode ;
1032                            }
1033                       }
1034                        break ;
1035                    default :
1036                        break ;
1037                }
1038            }
1039            break ;
1040        }
1041    }
1042
1043    return converted ;
1044}
1045
1046/*
1047pascal OSStatus wxMacApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
1048{
1049    OSStatus result = eventNotHandledErr ;
1050
1051    EventRecord rec ;
1052    switch ( GetEventClass( event ) )
1053    {
1054        case kEventClassKeyboard :
1055            if ( wxMacConvertEventToRecord( event , &rec ) )
1056            {
1057                wxTheApp->MacHandleModifierEvents( &rec ) ;
1058                wxTheApp->MacHandleOneEvent( &rec ) ;
1059                result = noErr ;
1060            }
1061            break ;
1062        case kEventClassTextInput :
1063            if ( wxMacConvertEventToRecord( event , &rec ) )
1064            {
1065                wxTheApp->MacHandleModifierEvents( &rec ) ;
1066                wxTheApp->MacHandleOneEvent( &rec ) ;
1067                result = noErr ;
1068            }
1069            break ;
1070        default :
1071            break ;
1072    }
1073    return result ;
1074}
1075*/
1076#endif
1077
1078wxApp::wxApp()
1079{
1080    m_printMode = wxPRINT_WINDOWS;
1081    m_auto3D = true;
1082
1083    m_macCurrentEvent = NULL ;
1084#if TARGET_CARBON
1085    m_macCurrentEventHandlerCallRef = NULL ;
1086#endif
1087}
1088
1089int wxApp::MainLoop()
1090{
1091    m_keepGoing = true;
1092
1093    while (m_keepGoing)
1094    {
1095        MacDoOneEvent() ;
1096    }
1097
1098    return 0;
1099}
1100
1101void wxApp::ExitMainLoop()
1102{
1103    m_keepGoing = false;
1104}
1105
1106// Is a message/event pending?
1107bool wxApp::Pending()
1108{
1109#if TARGET_CARBON
1110    // without the receive event (with pull param = false ) nothing is ever reported
1111    EventRef theEvent;
1112    ReceiveNextEvent (0, NULL, kEventDurationNoWait, false, &theEvent);
1113    return GetNumEventsInQueue( GetMainEventQueue() ) > 0 ;
1114#else
1115    EventRecord event ;
1116
1117    return EventAvail( everyEvent , &event ) ;
1118#endif
1119}
1120
1121// Dispatch a message.
1122bool wxApp::Dispatch()
1123{
1124    MacDoOneEvent() ;
1125
1126    return true;
1127}
1128
1129void wxApp::OnIdle(wxIdleEvent& event)
1130{
1131    wxAppBase::OnIdle(event);
1132
1133    // If they are pending events, we must process them: pending events are
1134    // either events to the threads other than main or events posted with
1135    // wxPostEvent() functions
1136    wxMacProcessNotifierAndPendingEvents();
1137
1138  if(!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar())
1139    wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar();
1140}
1141
1142void wxApp::WakeUpIdle()
1143{
1144    wxMacWakeUp() ;
1145}
1146
1147void wxApp::Exit()
1148{
1149    wxApp::CleanUp();
1150    ::ExitToShell() ;
1151}
1152
1153void wxApp::OnEndSession(wxCloseEvent& WXUNUSED(event))
1154{
1155    if (GetTopWindow())
1156        GetTopWindow()->Close(true);
1157}
1158
1159// Default behaviour: close the application with prompts. The
1160// user can veto the close, and therefore the end session.
1161void wxApp::OnQueryEndSession(wxCloseEvent& event)
1162{
1163    if (GetTopWindow())
1164    {
1165        if (!GetTopWindow()->Close(!event.CanVeto()))
1166            event.Veto(true);
1167    }
1168}
1169
1170extern "C" void wxCYield() ;
1171void wxCYield()
1172{
1173    wxYield() ;
1174}
1175
1176// Yield to other processes
1177
1178bool wxApp::Yield(bool onlyIfNeeded)
1179{
1180    if (s_inYield)
1181    {
1182        if ( !onlyIfNeeded )
1183        {
1184            wxFAIL_MSG( wxT("wxYield called recursively" ) );
1185        }
1186
1187        return false;
1188    }
1189
1190    s_inYield = true;
1191
1192#if wxUSE_THREADS
1193    YieldToAnyThread() ;
1194#endif
1195    // by definition yield should handle all non-processed events
1196#if TARGET_CARBON
1197    EventRef theEvent;
1198
1199    OSStatus status = noErr ;
1200    do
1201    {
1202        s_inReceiveEvent = true ;
1203        status = ReceiveNextEvent(0, NULL,kEventDurationNoWait,true,&theEvent) ;
1204        s_inReceiveEvent = false ;
1205
1206        if ( status == eventLoopTimedOutErr )
1207        {
1208            // make sure next time the event loop will trigger idle events
1209            sleepTime = kEventDurationNoWait ;
1210        }
1211        else if ( status == eventLoopQuitErr )
1212        {
1213            // according to QA1061 this may also occur when a WakeUp Process
1214            // is executed
1215        }
1216        else
1217        {
1218            MacHandleOneEvent( theEvent ) ;
1219            ReleaseEvent(theEvent);
1220        }
1221    } while( status == noErr ) ;
1222#else
1223    EventRecord event ;
1224
1225    // having a larger value here leads to large performance slowdowns
1226    // so we cannot give background apps more processor time here
1227    // we do so however having a large sleep value in the main event loop
1228    sleepTime = 0 ;
1229
1230    while ( !IsExiting() && WaitNextEvent(everyEvent, &event,sleepTime, (RgnHandle) wxApp::s_macCursorRgn))
1231    {
1232        MacHandleModifierEvents( &event ) ;
1233        MacHandleOneEvent( &event );
1234        if ( event.what != kHighLevelEvent )
1235            SetRectRgn( (RgnHandle) wxApp::s_macCursorRgn , event.where.h , event.where.v ,  event.where.h + 1 , event.where.v + 1 ) ;
1236    }
1237    MacHandleModifierEvents( &event ) ;
1238#endif
1239
1240    wxMacProcessNotifierAndPendingEvents() ;
1241    s_inYield = false;
1242
1243    return true;
1244}
1245
1246// platform specifics
1247
1248void wxApp::MacSuspend( bool convertClipboard )
1249{
1250#if !TARGET_CARBON
1251    // we have to deactive the top level windows manually
1252
1253    wxWindowListNode* node = wxTopLevelWindows.GetFirst();
1254    while (node)
1255    {
1256        wxTopLevelWindow* win = (wxTopLevelWindow*) node->Data();
1257#if TARGET_CARBON
1258#if 0 //  having problems right now with that
1259        if (!win->HasFlag(wxSTAY_ON_TOP))
1260#endif
1261#endif
1262            win->MacActivate( ((EventRecord*) MacGetCurrentEvent())->when , false ) ;
1263
1264        node = node->GetNext();
1265    }
1266
1267    ::HideFloatingWindows() ;
1268#endif
1269    s_lastMouseDown = 0 ;
1270
1271    if( convertClipboard )
1272    {
1273        MacConvertPrivateToPublicScrap() ;
1274    }
1275}
1276
1277extern wxList wxModalDialogs;
1278
1279void wxApp::MacResume( bool convertClipboard )
1280{
1281    s_lastMouseDown = 0 ;
1282    if( convertClipboard )
1283    {
1284        MacConvertPublicToPrivateScrap() ;
1285    }
1286
1287#if !TARGET_CARBON
1288    ::ShowFloatingWindows() ;
1289    // raise modal dialogs in case a non modal window was selected to activate the app
1290
1291    wxNode* node = wxModalDialogs.GetFirst();
1292    while (node)
1293    {
1294        wxDialog* dialog = (wxDialog *) node->GetData();
1295        dialog->Raise();
1296
1297        node = node->GetNext();
1298    }
1299#endif
1300}
1301
1302void wxApp::MacConvertPrivateToPublicScrap()
1303{
1304}
1305
1306void wxApp::MacConvertPublicToPrivateScrap()
1307{
1308}
1309
1310void wxApp::MacDoOneEvent()
1311{
1312#if TARGET_CARBON
1313    EventRef theEvent;
1314
1315    s_inReceiveEvent = true ;
1316    OSStatus status = ReceiveNextEvent(0, NULL,sleepTime,true,&theEvent) ;
1317    s_inReceiveEvent = false ;
1318    if ( status == eventLoopTimedOutErr )
1319    {
1320        if ( wxTheApp->ProcessIdle() )
1321            sleepTime = kEventDurationNoWait ;
1322        else
1323        {
1324#if wxUSE_THREADS
1325            if (g_numberOfThreads)
1326            {
1327                sleepTime = kEventDurationNoWait;
1328            }
1329            else
1330#endif // wxUSE_THREADS
1331            {
1332                sleepTime = kEventDurationSecond;
1333            }
1334        }
1335    }
1336    else if ( status == eventLoopQuitErr )
1337    {
1338        // according to QA1061 this may also occur when a WakeUp Process
1339        // is executed
1340    }
1341    else
1342    {
1343        MacHandleOneEvent( theEvent ) ;
1344        ReleaseEvent(theEvent);
1345        sleepTime = kEventDurationNoWait ;
1346    }
1347#else
1348      EventRecord event ;
1349
1350    EventMask eventMask = everyEvent ;
1351
1352    if (WaitNextEvent(eventMask, &event, sleepTime, (RgnHandle) s_macCursorRgn))
1353    {
1354        MacHandleModifierEvents( &event ) ;
1355        MacHandleOneEvent( &event );
1356    }
1357    else
1358    {
1359        MacHandleModifierEvents( &event ) ;
1360        // idlers
1361        WindowPtr window = ::FrontWindow() ;
1362        if ( window )
1363            ::IdleControls( window ) ;
1364
1365        if ( wxTheApp->ProcessIdle() )
1366            sleepTime = kEventDurationNoWait;
1367        else
1368        {
1369#if wxUSE_THREADS
1370            if (g_numberOfThreads)
1371            {
1372                sleepTime = kEventDurationNoWait;
1373            }
1374            else
1375#endif // wxUSE_THREADS
1376            {
1377                sleepTime = kEventDurationSecond;
1378            }
1379        }
1380    }
1381    if ( event.what != kHighLevelEvent )
1382        SetRectRgn( (RgnHandle) s_macCursorRgn , event.where.h , event.where.v ,  event.where.h + 1 , event.where.v + 1 ) ;
1383#endif
1384    // repeaters
1385
1386    DeletePendingObjects() ;
1387    wxMacProcessNotifierAndPendingEvents() ;
1388}
1389
1390/*virtual*/ void wxApp::MacHandleUnhandledEvent( WXEVENTREF evr )
1391{
1392    // Override to process unhandled events as you please
1393}
1394
1395void wxApp::MacHandleOneEvent( WXEVENTREF evr )
1396{
1397#if TARGET_CARBON
1398    EventTargetRef theTarget;
1399    theTarget = GetEventDispatcherTarget();
1400    m_macCurrentEvent = evr ;
1401    OSStatus status = SendEventToEventTarget ((EventRef) evr , theTarget);
1402    if(status == eventNotHandledErr)
1403    {
1404        MacHandleUnhandledEvent(evr);
1405    }
1406#else
1407    EventRecord* ev = (EventRecord*) evr ;
1408    m_macCurrentEvent = ev ;
1409
1410    wxApp::sm_lastMessageTime = ev->when ;
1411
1412    switch (ev->what)
1413    {
1414        case mouseDown:
1415            MacHandleMouseDownEvent( ev ) ;
1416            if ( ev->modifiers & controlKey )
1417                s_lastMouseDown = 2;
1418            else
1419                s_lastMouseDown = 1;
1420            break;
1421        case mouseUp:
1422            if ( s_lastMouseDown == 2 )
1423            {
1424                ev->modifiers |= controlKey ;
1425            }
1426            else
1427            {
1428                ev->modifiers &= ~controlKey ;
1429            }
1430            MacHandleMouseUpEvent( ev ) ;
1431            s_lastMouseDown = 0;
1432            break;
1433        case activateEvt:
1434            MacHandleActivateEvent( ev ) ;
1435            break;
1436        case updateEvt:
1437            // In embedded mode we first let the UnhandledEvent function
1438            // try to handle the update event. If we handle it ourselves
1439            // first and then pass it on, the host's windows won't update.
1440            MacHandleUnhandledEvent(ev);
1441            MacHandleUpdateEvent( ev ) ;
1442            break;
1443        case keyDown:
1444        case autoKey:
1445            MacHandleKeyDownEvent( ev ) ;
1446            break;
1447        case keyUp:
1448            MacHandleKeyUpEvent( ev ) ;
1449            break;
1450        case diskEvt:
1451            MacHandleDiskEvent( ev ) ;
1452            break;
1453        case osEvt:
1454            MacHandleOSEvent( ev ) ;
1455            break;
1456        case kHighLevelEvent:
1457            MacHandleHighLevelEvent( ev ) ;
1458            break;
1459        default:
1460            break;
1461    }
1462#endif
1463    wxMacProcessNotifierAndPendingEvents() ;
1464}
1465
1466#if !TARGET_CARBON
1467bool s_macIsInModalLoop = false ;
1468
1469void wxApp::MacHandleModifierEvents( WXEVENTREF evr )
1470{
1471    EventRecord* ev = (EventRecord*) evr ;
1472    if ( ev->modifiers != s_lastModifiers && wxWindow::FindFocus() != NULL )
1473    {
1474        wxKeyEvent event(wxEVT_KEY_DOWN);
1475
1476        event.m_shiftDown = ev->modifiers & shiftKey;
1477        event.m_controlDown = ev->modifiers & controlKey;
1478        event.m_altDown = ev->modifiers & optionKey;
1479        event.m_metaDown = ev->modifiers & cmdKey;
1480
1481        event.m_x = ev->where.h;
1482        event.m_y = ev->where.v;
1483        event.SetTimestamp( ev->when );
1484        wxWindow* focus = wxWindow::FindFocus() ;
1485        event.SetEventObject(focus);
1486
1487        if ( (ev->modifiers ^ s_lastModifiers ) & controlKey )
1488        {
1489            event.m_keyCode = WXK_CONTROL ;
1490            event.SetEventType( ( ev->modifiers & controlKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
1491            focus->GetEventHandler()->ProcessEvent( event ) ;
1492        }
1493        if ( (ev->modifiers ^ s_lastModifiers ) & shiftKey )
1494        {
1495            event.m_keyCode = WXK_SHIFT ;
1496            event.SetEventType( ( ev->modifiers & shiftKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
1497            focus->GetEventHandler()->ProcessEvent( event ) ;
1498        }
1499        if ( (ev->modifiers ^ s_lastModifiers ) & optionKey )
1500        {
1501            event.m_keyCode = WXK_ALT ;
1502            event.SetEventType( ( ev->modifiers & optionKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
1503            focus->GetEventHandler()->ProcessEvent( event ) ;
1504        }
1505        if ( ( ev->modifiers ^ s_lastModifiers ) & cmdKey )
1506        {
1507            event.m_keyCode = WXK_COMMAND ;
1508            event.SetEventType( ( ev->modifiers & cmdKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
1509            focus->GetEventHandler()->ProcessEvent( event ) ;
1510        }
1511        s_lastModifiers = ev->modifiers ;
1512    }
1513}
1514
1515void wxApp::MacHandleHighLevelEvent( WXEVENTREF evr )
1516{
1517    // we must avoid reentrancy problems when processing high level events eg printing
1518    bool former = s_inYield ;
1519    s_inYield = true ;
1520    EventRecord* ev = (EventRecord*) evr ;
1521    ::AEProcessAppleEvent( ev ) ;
1522    s_inYield = former ;
1523}
1524
1525void wxApp::MacHandleMouseDownEvent( WXEVENTREF evr )
1526{
1527    EventRecord* ev = (EventRecord*) evr ;
1528    wxToolTip::RemoveToolTips() ;
1529
1530    WindowRef window;
1531    WindowRef frontWindow = ::FrontNonFloatingWindow() ;
1532    WindowAttributes frontWindowAttributes = NULL ;
1533    if ( frontWindow )
1534        ::GetWindowAttributes( frontWindow , &frontWindowAttributes ) ;
1535
1536    short windowPart = ::FindWindow(ev->where, &window);
1537    wxTopLevelWindowMac* win = wxFindWinFromMacWindow( (WXWindow) window ) ;
1538    if ( wxPendingDelete.Member(win) )
1539        return ;
1540
1541    BitMap screenBits;
1542    GetQDGlobalsScreenBits( &screenBits );
1543
1544    switch (windowPart)
1545    {
1546        case inMenuBar :
1547            if ( s_macIsInModalLoop )
1548            {
1549                SysBeep ( 30 ) ;
1550            }
1551            else
1552            {
1553                UInt32 menuresult = MenuSelect(ev->where) ;
1554               MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) );
1555                s_lastMouseDown = 0;
1556            }
1557            break ;
1558        case inSysWindow :
1559            SystemClick( ev , window ) ;
1560            s_lastMouseDown = 0;
1561            break ;
1562        case inDrag :
1563            if ( window != frontWindow && s_macIsInModalLoop && !(ev->modifiers & cmdKey ) )
1564            {
1565                SysBeep ( 30 ) ;
1566            }
1567            else
1568            {
1569                DragWindow(window, ev->where, &screenBits.bounds);
1570                if (win)
1571                {
1572                    GrafPtr port ;
1573                    GetPort( &port ) ;
1574                    Point pt = { 0, 0 } ;
1575                    SetPortWindowPort(window) ;
1576                    LocalToGlobal( &pt ) ;
1577                    SetPort( port ) ;
1578                        win->SetSize( pt.h , pt.v , -1 ,
1579                            -1 , wxSIZE_USE_EXISTING);
1580                }
1581                s_lastMouseDown = 0;
1582            }
1583            break ;
1584        case inGoAway:
1585            if (TrackGoAway(window, ev->where))
1586            {
1587                if ( win )
1588                    win->Close() ;
1589            }
1590            s_lastMouseDown = 0;
1591            break;
1592        case inGrow:
1593          {
1594                Rect newContentRect ;
1595                Rect constraintRect ;
1596                constraintRect.top = win->GetMinHeight() ;
1597                if ( constraintRect.top == -1 )
1598                    constraintRect.top  = 0 ;
1599                constraintRect.left = win->GetMinWidth() ;
1600                if ( constraintRect.left == -1 )
1601                    constraintRect.left  = 0 ;
1602                constraintRect.right = win->GetMaxWidth() ;
1603                if ( constraintRect.right == -1 )
1604                    constraintRect.right  = 32000 ;
1605                constraintRect.bottom = win->GetMaxHeight() ;
1606                if ( constraintRect.bottom == -1 )
1607                    constraintRect.bottom = 32000 ;
1608
1609                Boolean growResult = ResizeWindow( window , ev->where ,
1610                    &constraintRect , &newContentRect ) ;
1611                if ( growResult )
1612                {
1613                    win->SetSize( newContentRect.left , newContentRect.top ,
1614                        newContentRect.right - newContentRect.left ,
1615                        newContentRect.bottom - newContentRect.top, wxSIZE_USE_EXISTING);
1616                }
1617                s_lastMouseDown = 0;
1618          }
1619            break;
1620        case inZoomIn:
1621        case inZoomOut:
1622                if (TrackBox(window, ev->where, windowPart))
1623                {
1624                    // TODO setup size event
1625                    ZoomWindow( window , windowPart , false ) ;
1626                    if (win)
1627                    {
1628                        Rect tempRect ;
1629                        GrafPtr port ;
1630                        GetPort( &port ) ;
1631                        Point pt = { 0, 0 } ;
1632                        SetPortWindowPort(window) ;
1633                        LocalToGlobal( &pt ) ;
1634                        SetPort( port ) ;
1635
1636                        GetWindowPortBounds(window, &tempRect ) ;
1637                        win->SetSize( pt.h , pt.v , tempRect.right-tempRect.left ,
1638                            tempRect.bottom-tempRect.top, wxSIZE_USE_EXISTING);
1639                    }
1640                }
1641            s_lastMouseDown = 0;
1642            break;
1643        case inCollapseBox :
1644                // TODO setup size event
1645            s_lastMouseDown = 0;
1646            break ;
1647
1648        case inContent :
1649                {
1650                    GrafPtr port ;
1651                    GetPort( &port ) ;
1652                    SetPortWindowPort(window) ;
1653                    SetPort( port ) ;
1654                }
1655                if ( window != frontWindow && wxTheApp->s_captureWindow == NULL )
1656                {
1657                    if ( s_macIsInModalLoop )
1658                    {
1659                        SysBeep ( 30 ) ;
1660                    }
1661                    else if ( UMAIsWindowFloating( window ) )
1662                    {
1663                        if ( win )
1664                            win->MacMouseDown( ev , windowPart ) ;
1665                    }
1666                    else
1667                    {
1668                        // Activate window first
1669                        ::SelectWindow( window ) ;
1670
1671                        // Send event later
1672                        if ( win )
1673                            win->MacMouseDown( ev , windowPart ) ;
1674                    }
1675                }
1676                else
1677                {
1678                    if ( win )
1679                        win->MacMouseDown( ev , windowPart ) ;
1680                }
1681            break ;
1682        default:
1683            break;
1684    }
1685}
1686
1687void wxApp::MacHandleMouseUpEvent( WXEVENTREF evr )
1688{
1689    EventRecord* ev = (EventRecord*) evr ;
1690    WindowRef window;
1691
1692    short windowPart = inNoWindow ;
1693    if ( wxTheApp->s_captureWindow )
1694    {
1695        window = (WindowRef) s_captureWindow->MacGetRootWindow() ;
1696        windowPart = inContent ;
1697    }
1698    else
1699    {
1700        windowPart = ::FindWindow(ev->where, &window) ;
1701    }
1702
1703    switch (windowPart)
1704    {
1705        case inMenuBar :
1706            break ;
1707        case inSysWindow :
1708            break ;
1709        default:
1710            {
1711                wxTopLevelWindowMac* win = wxFindWinFromMacWindow( (WXWindow) window ) ;
1712                if ( win )
1713                    win->MacMouseUp( ev , windowPart ) ;
1714            }
1715            break;
1716    }
1717}
1718
1719#endif
1720
1721long wxMacTranslateKey(unsigned char key, unsigned char code) ;
1722long wxMacTranslateKey(unsigned char key, unsigned char code)
1723{
1724    long retval = key ;
1725    switch (key)
1726    {
1727        case kHomeCharCode :
1728                 retval = WXK_HOME;
1729          break;
1730        case kEnterCharCode :
1731                 retval = WXK_RETURN;
1732          break;
1733        case kEndCharCode :
1734                 retval = WXK_END;
1735          break;
1736        case kHelpCharCode :
1737                 retval = WXK_HELP;
1738          break;
1739        case kBackspaceCharCode :
1740                 retval = WXK_BACK;
1741          break;
1742        case kTabCharCode :
1743                 retval = WXK_TAB;
1744          break;
1745        case kPageUpCharCode :
1746                 retval = WXK_PAGEUP;
1747          break;
1748        case kPageDownCharCode :
1749                 retval = WXK_PAGEDOWN;
1750          break;
1751        case kReturnCharCode :
1752                 retval = WXK_RETURN;
1753          break;
1754            case kFunctionKeyCharCode :
1755            {
1756                switch( code )
1757                {
1758                    case 0x7a :
1759                        retval = WXK_F1 ;
1760                        break;
1761                    case 0x78 :
1762                        retval = WXK_F2 ;
1763                        break;
1764                    case 0x63 :
1765                        retval = WXK_F3 ;
1766                        break;
1767                    case 0x76 :
1768                        retval = WXK_F4 ;
1769                        break;
1770                    case 0x60 :
1771                        retval = WXK_F5 ;
1772                        break;
1773                    case 0x61 :
1774                        retval = WXK_F6 ;
1775                        break;
1776                    case 0x62:
1777                        retval = WXK_F7 ;
1778                        break;
1779                    case 0x64 :
1780                        retval = WXK_F8 ;
1781                        break;
1782                    case 0x65 :
1783                        retval = WXK_F9 ;
1784                        break;
1785                    case 0x6D :
1786                        retval = WXK_F10 ;
1787                        break;
1788                    case 0x67 :
1789                        retval = WXK_F11 ;
1790                        break;
1791                    case 0x6F :
1792                        retval = WXK_F12 ;
1793                        break;
1794                    case 0x69 :
1795                        retval = WXK_F13 ;
1796                        break;
1797                    case 0x6B :
1798                        retval = WXK_F14 ;
1799                        break;
1800                    case 0x71 :
1801                        retval = WXK_F15 ;
1802                        break;
1803                }
1804            }
1805            break ;
1806            case kEscapeCharCode :
1807                retval = WXK_ESCAPE ;
1808            break ;
1809            case kLeftArrowCharCode :
1810                retval = WXK_LEFT ;
1811            break ;
1812            case kRightArrowCharCode :
1813                retval = WXK_RIGHT ;
1814            break ;
1815            case kUpArrowCharCode :
1816                retval = WXK_UP ;
1817            break ;
1818            case kDownArrowCharCode :
1819                retval = WXK_DOWN ;
1820            break ;
1821            case kDeleteCharCode :
1822                retval = WXK_DELETE ;
1823             default:
1824            break ;
1825     } // end switch
1826
1827    return retval;
1828}
1829
1830int wxKeyCodeToMacModifier(wxKeyCode key)
1831{
1832    switch (key)
1833    {
1834    case WXK_START:
1835    case WXK_MENU:
1836        return cmdKey;
1837
1838    case WXK_SHIFT:
1839        return shiftKey;
1840
1841    case WXK_CAPITAL:
1842        return alphaLock;
1843
1844    case WXK_ALT:
1845        return optionKey;
1846
1847    case WXK_CONTROL:
1848        return controlKey;
1849
1850    default:
1851        return 0;
1852    }
1853}
1854
1855bool wxGetKeyState(wxKeyCode key) //virtual key code if < 10.2.x, else see below
1856{
1857    wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key !=
1858        WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons"));
1859
1860    KeyMap keymap;
1861    GetKeys(keymap);
1862    return !!(BitTst(keymap, (sizeof(KeyMap)*8) - key));
1863}
1864
1865#if !TARGET_CARBON
1866void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr )
1867{
1868    EventRecord* ev = (EventRecord*) evr ;
1869    wxToolTip::RemoveToolTips() ;
1870
1871    UInt32 menuresult = UMAMenuEvent(ev) ;
1872    if ( HiWord( menuresult ) )
1873    {
1874        if ( !s_macIsInModalLoop )
1875            MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ) ;
1876    }
1877    else
1878    {
1879         wxWindow* focus = wxWindow::FindFocus() ;
1880
1881        if ( MacSendKeyDownEvent( focus , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) == false )
1882        {
1883#if 0
1884            // we must handle control keys the other way round, otherwise text content is updated too late
1885            // has not been handled -> perform default
1886            wxControl* control = wxDynamicCast( focus , wxControl ) ;
1887            if ( control &&  control->GetMacControl() != NULL )
1888            {
1889                short keycode ;
1890                short keychar ;
1891                keychar = short(ev->message & charCodeMask);
1892                keycode = short(ev->message & keyCodeMask) >> 8 ;
1893                ::HandleControlKey( (ControlHandle) control->GetMacControl() , keycode , keychar , ev->modifiers ) ;
1894            }
1895#endif
1896        }
1897    }
1898}
1899
1900void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr )
1901{
1902    EventRecord* ev = (EventRecord*) evr ;
1903    wxToolTip::RemoveToolTips() ;
1904
1905    UInt32 menuresult = UMAMenuEvent(ev) ;
1906    if ( HiWord( menuresult ) )
1907    {
1908    }
1909    else
1910    {
1911        MacSendKeyUpEvent( wxWindow::FindFocus() , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) ;
1912    }
1913}
1914
1915#endif
1916
1917bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey )
1918{
1919    if ( !focus )
1920        return false ;
1921
1922    short keycode ;
1923    short keychar ;
1924    keychar = short(keymessage & charCodeMask);
1925    keycode = short(keymessage & keyCodeMask) >> 8 ;
1926
1927    if ( modifiers & ( controlKey|shiftKey|optionKey ) )
1928    {
1929        // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
1930        // and look at the character after
1931        UInt32 state = 0;
1932        UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state);
1933        keychar = short(keyInfo & charCodeMask);
1934        keycode = short(keyInfo & keyCodeMask) >> 8 ;
1935    }
1936    long keyval = wxMacTranslateKey(keychar, keycode) ;
1937    long realkeyval = keyval ;
1938    if ( keyval == keychar )
1939    {
1940        // we are not on a special character combo -> pass the real os event-value to EVT_CHAR, but not to EVT_KEY (make upper first)
1941        realkeyval = short(keymessage & charCodeMask) ;
1942        keyval = wxToupper( keyval ) ;
1943    }
1944
1945    wxKeyEvent event(wxEVT_KEY_DOWN);
1946    bool handled = false ;
1947    event.m_shiftDown = modifiers & shiftKey;
1948    event.m_controlDown = modifiers & controlKey;
1949    event.m_altDown = modifiers & optionKey;
1950    event.m_metaDown = modifiers & cmdKey;
1951    event.m_keyCode = keyval ;
1952
1953    event.m_x = wherex;
1954    event.m_y = wherey;
1955    event.SetTimestamp(when);
1956    event.SetEventObject(focus);
1957    handled = focus->GetEventHandler()->ProcessEvent( event ) ;
1958    if ( handled && event.GetSkipped() )
1959        handled = false ;
1960    if ( !handled )
1961    {
1962#if wxUSE_ACCEL
1963        if (!handled)
1964        {
1965            wxWindow *ancestor = focus;
1966            while (ancestor)
1967            {
1968                int command = ancestor->GetAcceleratorTable()->GetCommand( event );
1969                if (command != -1)
1970                {
1971                    wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
1972                    handled = ancestor->GetEventHandler()->ProcessEvent( command_event );
1973                    break;
1974                }
1975                if (ancestor->IsTopLevel())
1976                    break;
1977                ancestor = ancestor->GetParent();
1978            }
1979        }
1980#endif // wxUSE_ACCEL
1981    }
1982    if (!handled)
1983    {
1984        event.Skip( false ) ;
1985        event.SetEventType( wxEVT_CHAR ) ;
1986        // raw value again
1987        event.m_keyCode = realkeyval ;
1988
1989        handled = focus->GetEventHandler()->ProcessEvent( event ) ;
1990        if ( handled && event.GetSkipped() )
1991            handled = false ;
1992    }
1993    if ( !handled &&
1994         (keyval == WXK_TAB) &&
1995// CS: copied the change below from wxGTK
1996// VZ: testing for wxTE_PROCESS_TAB shouldn't be done here the control may
1997//     have this style, yet choose not to process this particular TAB in which
1998//     case TAB must still work as a navigational character
1999#if 0
2000         (!focus->HasFlag(wxTE_PROCESS_TAB)) &&
2001#endif
2002         (focus->GetParent()) &&
2003         (focus->GetParent()->HasFlag( wxTAB_TRAVERSAL)) )
2004    {
2005        wxNavigationKeyEvent new_event;
2006        new_event.SetEventObject( focus );
2007        new_event.SetDirection( !event.ShiftDown() );
2008        /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
2009        new_event.SetWindowChange( event.ControlDown() );
2010        new_event.SetCurrentFocus( focus );
2011        handled = focus->GetEventHandler()->ProcessEvent( new_event );
2012        if ( handled && new_event.GetSkipped() )
2013            handled = false ;
2014    }
2015    // backdoor handler for default return and command escape
2016    if ( !handled && (!focus->IsKindOf(CLASSINFO(wxControl) ) || !focus->MacCanFocus() ) )
2017    {
2018        // if window is not having a focus still testing for default enter or cancel
2019        // TODO add the UMA version for ActiveNonFloatingWindow
2020        wxWindow* focus = wxFindWinFromMacWindow( (WXWindow) FrontWindow() ) ;
2021        if ( focus )
2022        {
2023            if ( keyval == WXK_RETURN )
2024            {
2025                wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow);
2026                if ( tlw && tlw->GetDefaultItem() )
2027                {
2028                    wxButton *def = wxDynamicCast(tlw->GetDefaultItem(), wxButton);
2029                    if ( def && def->IsEnabled() )
2030                    {
2031                        wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
2032                        event.SetEventObject(def);
2033                        def->Command(event);
2034                        return true ;
2035                    }
2036                }
2037            }
2038            /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
2039            else if (keyval == WXK_ESCAPE || (keyval == '.' && modifiers & cmdKey ) )
2040            {
2041                wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL);
2042                new_event.SetEventObject( focus );
2043                handled = focus->GetEventHandler()->ProcessEvent( new_event );
2044            }
2045        }
2046    }
2047    return handled ;
2048}
2049
2050bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey )
2051{
2052    if ( !focus )
2053        return false ;
2054
2055    short keycode ;
2056    short keychar ;
2057    keychar = short(keymessage & charCodeMask);
2058    keycode = short(keymessage & keyCodeMask) >> 8 ;
2059    if ( modifiers & ( controlKey|shiftKey|optionKey ) )
2060    {
2061        // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
2062        // and look at the character after
2063        UInt32 state = 0;
2064        UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state);
2065        keychar = short(keyInfo & charCodeMask);
2066        keycode = short(keyInfo & keyCodeMask) >> 8 ;
2067    }
2068    long keyval = wxMacTranslateKey(keychar, keycode) ;
2069
2070    if ( keyval == keychar )
2071    {
2072        keyval = wxToupper( keyval ) ;
2073    }
2074    bool handled = false ;
2075
2076    wxKeyEvent event(wxEVT_KEY_UP);
2077    event.m_shiftDown = modifiers & shiftKey;
2078    event.m_controlDown = modifiers & controlKey;
2079    event.m_altDown = modifiers & optionKey;
2080    event.m_metaDown = modifiers & cmdKey;
2081    event.m_keyCode = keyval ;
2082
2083    event.m_x = wherex;
2084    event.m_y = wherey;
2085    event.SetTimestamp(when);
2086    event.SetEventObject(focus);
2087    handled = focus->GetEventHandler()->ProcessEvent( event ) ;
2088
2089    return handled ;
2090}
2091
2092#if !TARGET_CARBON
2093void wxApp::MacHandleActivateEvent( WXEVENTREF evr )
2094{
2095    EventRecord* ev = (EventRecord*) evr ;
2096    WindowRef window = (WindowRef) ev->message ;
2097    if ( window )
2098    {
2099        bool activate = (ev->modifiers & activeFlag ) ;
2100        WindowClass wclass ;
2101        ::GetWindowClass ( window , &wclass ) ;
2102        if ( wclass == kFloatingWindowClass )
2103        {
2104            // if it is a floater we activate/deactivate the front non-floating window instead
2105            window = ::FrontNonFloatingWindow() ;
2106        }
2107        wxTopLevelWindowMac* win = wxFindWinFromMacWindow( (WXWindow) window ) ;
2108        if ( win )
2109            win->MacActivate( ev->when , activate ) ;
2110    }
2111}
2112
2113void wxApp::MacHandleUpdateEvent( WXEVENTREF evr )
2114{
2115    EventRecord* ev = (EventRecord*) evr ;
2116    WindowRef window = (WindowRef) ev->message ;
2117    wxTopLevelWindowMac * win = wxFindWinFromMacWindow( (WXWindow) window ) ;
2118    if ( win )
2119    {
2120        if ( !wxPendingDelete.Member(win) )
2121            win->MacUpdate( ev->when ) ;
2122    }
2123    else
2124    {
2125        // since there is no way of telling this foreign window to update itself
2126        // we have to invalidate the update region otherwise we keep getting the same
2127        // event over and over again
2128        BeginUpdate( window ) ;
2129        EndUpdate( window ) ;
2130    }
2131}
2132
2133void wxApp::MacHandleDiskEvent( WXEVENTREF evr )
2134{
2135    EventRecord* ev = (EventRecord*) evr ;
2136    if ( HiWord( ev->message ) != noErr )
2137  {
2138        OSErr err ;
2139        Point point ;
2140         SetPt( &point , 100 , 100 ) ;
2141
2142          err = DIBadMount( point , ev->message ) ;
2143        wxASSERT( err == noErr ) ;
2144    }
2145}
2146
2147void wxApp::MacHandleOSEvent( WXEVENTREF evr )
2148{
2149    EventRecord* ev = (EventRecord*) evr ;
2150    switch( ( ev->message & osEvtMessageMask ) >> 24 )
2151    {
2152        case suspendResumeMessage :
2153            {
2154                bool isResuming = ev->message & resumeFlag ;
2155                bool convertClipboard = ev->message & convertClipboardFlag ;
2156
2157                bool doesActivate = UMAGetProcessModeDoesActivateOnFGSwitch() ;
2158                if ( isResuming )
2159                {
2160                    WindowRef oldFrontWindow = NULL ;
2161                    WindowRef newFrontWindow = NULL ;
2162
2163                    // in case we don't take care of activating ourselves, we have to synchronize
2164                    // our idea of the active window with the process manager's - which it already activated
2165
2166                    if ( !doesActivate )
2167                        oldFrontWindow = ::FrontNonFloatingWindow() ;
2168
2169                    MacResume( convertClipboard ) ;
2170
2171                    newFrontWindow = ::FrontNonFloatingWindow() ;
2172
2173                    if ( oldFrontWindow )
2174                    {
2175                        wxTopLevelWindowMac* win = wxFindWinFromMacWindow( (WXWindow) oldFrontWindow ) ;
2176                        if ( win )
2177                            win->MacActivate( ev->when , false ) ;
2178                    }
2179                    if ( newFrontWindow )
2180                    {
2181                        wxTopLevelWindowMac* win = wxFindWinFromMacWindow( (WXWindow) newFrontWindow ) ;
2182                        if ( win )
2183                            win->MacActivate( ev->when , true ) ;
2184                    }
2185                }
2186                else
2187                {
2188                    MacSuspend( convertClipboard ) ;
2189                }
2190            }
2191            break ;
2192        case mouseMovedMessage :
2193            {
2194                WindowRef window;
2195
2196                wxWindow* currentMouseWindow = NULL ;
2197
2198                if (s_captureWindow )
2199                {
2200                    currentMouseWindow = s_captureWindow ;
2201                }
2202                else
2203                {
2204                    wxWindow::MacGetWindowFromPoint( wxPoint( ev->where.h , ev->where.v ) ,
2205                                                             &currentMouseWindow ) ;
2206                }
2207
2208                if ( currentMouseWindow != wxWindow::s_lastMouseWindow )
2209                {
2210                    wxMouseEvent event ;
2211
2212                    bool isDown = !(ev->modifiers & btnState) ; // 1 is for up
2213                    bool controlDown = ev->modifiers & controlKey ; // for simulating right mouse
2214
2215                    event.m_leftDown = isDown && !controlDown;
2216                    event.m_middleDown = false;
2217                    event.m_rightDown = isDown && controlDown;
2218                    event.m_shiftDown = ev->modifiers & shiftKey;
2219                    event.m_controlDown = ev->modifiers & controlKey;
2220                    event.m_altDown = ev->modifiers & optionKey;
2221                    event.m_metaDown = ev->modifiers & cmdKey;
2222                    event.m_x = ev->where.h;
2223                    event.m_y = ev->where.v;
2224                    event.SetTimestamp( ev->when );
2225                    event.SetEventObject(this);
2226
2227                    if ( wxWindow::s_lastMouseWindow )
2228                    {
2229                        wxMouseEvent eventleave(event);
2230                        eventleave.SetEventType( wxEVT_LEAVE_WINDOW );
2231                        wxWindow::s_lastMouseWindow->ScreenToClient( &eventleave.m_x, &eventleave.m_y );
2232                        eventleave.SetEventObject( wxWindow::s_lastMouseWindow ) ;
2233
2234                        wxWindow::s_lastMouseWindow->GetEventHandler()->ProcessEvent(eventleave);
2235                    }
2236                    if ( currentMouseWindow )
2237                    {
2238                        wxMouseEvent evententer(event);
2239                        evententer.SetEventType( wxEVT_ENTER_WINDOW );
2240                        currentMouseWindow->ScreenToClient( &evententer.m_x, &evententer.m_y );
2241                        evententer.SetEventObject( currentMouseWindow ) ;
2242                        currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
2243                    }
2244                    wxWindow::s_lastMouseWindow = currentMouseWindow ;
2245                }
2246
2247                short windowPart = inNoWindow ;
2248
2249                if ( s_captureWindow )
2250                {
2251                    window = (WindowRef) s_captureWindow->MacGetRootWindow() ;
2252                    windowPart = inContent ;
2253                }
2254                else
2255                {
2256                    windowPart = ::FindWindow(ev->where, &window);
2257                }
2258
2259                switch (windowPart)
2260                {
2261                    case inContent :
2262                        {
2263                            wxTopLevelWindowMac* win = wxFindWinFromMacWindow( (WXWindow) window ) ;
2264                            if ( win )
2265                                win->MacMouseMoved( ev , windowPart ) ;
2266                            else
2267                            {
2268                                if ( wxIsBusy() )
2269                                {
2270                                }
2271                                else
2272                                    UMAShowArrowCursor();
2273                             }
2274                        }
2275                        break;
2276                    default :
2277                        {
2278                            if ( wxIsBusy() )
2279                            {
2280                            }
2281                            else
2282                                UMAShowArrowCursor();
2283                        }
2284                        break ;
2285                }
2286            }
2287            break ;
2288
2289    }
2290}
2291#else
2292
2293void wxApp::MacHandleMouseMovedEvent(wxInt32 x , wxInt32 y ,wxUint32 modifiers , long timestamp)
2294{
2295    WindowRef window;
2296
2297    wxWindow* currentMouseWindow = NULL ;
2298
2299    if (s_captureWindow )
2300    {
2301        currentMouseWindow = s_captureWindow ;
2302    }
2303    else
2304    {
2305        wxWindow::MacGetWindowFromPoint( wxPoint( x, y ) , &currentMouseWindow ) ;
2306    }
2307
2308    if ( currentMouseWindow != wxWindow::s_lastMouseWindow )
2309    {
2310        wxMouseEvent event ;
2311
2312        bool isDown = !(modifiers & btnState) ; // 1 is for up
2313        bool controlDown = modifiers & controlKey ; // for simulating right mouse
2314
2315        event.m_leftDown = isDown && !controlDown;
2316
2317        event.m_middleDown = false;
2318        event.m_rightDown = isDown && controlDown;
2319
2320        event.m_shiftDown = modifiers & shiftKey;
2321        event.m_controlDown = modifiers & controlKey;
2322        event.m_altDown = modifiers & optionKey;
2323        event.m_metaDown = modifiers & cmdKey;
2324
2325        event.m_x = x;
2326        event.m_y = y;
2327        event.SetTimestamp(timestamp);
2328
2329        if ( wxWindow::s_lastMouseWindow )
2330        {
2331            wxMouseEvent eventleave(event);
2332            eventleave.SetEventType( wxEVT_LEAVE_WINDOW );
2333            wxWindow::s_lastMouseWindow->ScreenToClient( &eventleave.m_x, &eventleave.m_y );
2334            eventleave.SetEventObject( wxWindow::s_lastMouseWindow ) ;
2335
2336#if wxUSE_TOOLTIPS
2337            wxToolTip::RelayEvent( wxWindow::s_lastMouseWindow , eventleave);
2338#endif // wxUSE_TOOLTIPS
2339            wxWindow::s_lastMouseWindow->GetEventHandler()->ProcessEvent(eventleave);
2340        }
2341        if ( currentMouseWindow )
2342        {
2343            wxMouseEvent evententer(event);
2344            evententer.SetEventType( wxEVT_ENTER_WINDOW );
2345            currentMouseWindow->ScreenToClient( &evententer.m_x, &evententer.m_y );
2346            evententer.SetEventObject( currentMouseWindow ) ;
2347#if wxUSE_TOOLTIPS
2348            wxToolTip::RelayEvent( currentMouseWindow , evententer);
2349#endif // wxUSE_TOOLTIPS
2350            currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
2351        }
2352        wxWindow::s_lastMouseWindow = currentMouseWindow ;
2353    }
2354
2355    short windowPart = inNoWindow ;
2356
2357    if ( s_captureWindow )
2358    {
2359        window = (WindowRef) s_captureWindow->MacGetRootWindow() ;
2360        windowPart = inContent ;
2361    }
2362    else
2363    {
2364        Point pt= { y , x } ;
2365        windowPart = ::FindWindow(pt , &window);
2366    }
2367
2368    switch (windowPart)
2369    {
2370        case inContent :
2371            {
2372                wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
2373                if ( win )
2374                    win->MacFireMouseEvent( nullEvent , x , y , modifiers , timestamp ) ;
2375                else
2376                {
2377                    if ( wxIsBusy() )
2378                    {
2379                    }
2380                    else
2381                        UMAShowArrowCursor();
2382                 }
2383            }
2384            break;
2385        default :
2386            {
2387                if ( wxIsBusy() )
2388                {
2389                }
2390                else
2391                    UMAShowArrowCursor();
2392            }
2393            break ;
2394    }
2395}
2396#endif
2397
2398void wxApp::MacHandleMenuCommand( wxUint32 id )
2399{
2400    wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ;
2401    wxFrame* frame = mbar->GetFrame();
2402    wxCHECK_RET( mbar != NULL && frame != NULL, wxT("error in menu item callback") );
2403    if ( frame )
2404    {
2405        frame->ProcessCommand(id);
2406    }
2407}
2408
2409#if !TARGET_CARBON
2410void wxApp::MacHandleMenuSelect( int macMenuId , int macMenuItemNum )
2411{
2412    if (macMenuId == 0)
2413         return; // no menu item selected
2414
2415    if (macMenuId == kwxMacAppleMenuId && macMenuItemNum > 1)
2416    {
2417        #if ! TARGET_CARBON
2418        Str255        deskAccessoryName ;
2419        GrafPtr        savedPort ;
2420
2421        GetMenuItemText(GetMenuHandle(kwxMacAppleMenuId), macMenuItemNum, deskAccessoryName);
2422        GetPort(&savedPort);
2423        OpenDeskAcc(deskAccessoryName);
2424        SetPort(savedPort);
2425        #endif
2426    }
2427    else
2428    {
2429        MenuCommand id ;
2430        GetMenuItemCommandID( GetMenuHandle(macMenuId) , macMenuItemNum , &id ) ;
2431        MacHandleMenuCommand( id ) ;
2432    }
2433    HiliteMenu(0);
2434}
2435#endif
2436