1 /////////////////////////////////////////////////////////////////////////////
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "app.h"
16 #include "wx/window.h"
18 #include "wx/button.h"
21 #include "wx/gdicmn.h"
24 #include "wx/cursor.h"
27 #include "wx/palette.h"
29 #include "wx/dialog.h"
30 #include "wx/msgdlg.h"
32 #include "wx/module.h"
33 #include "wx/memory.h"
34 #include "wx/tooltip.h"
35 #include "wx/textctrl.h"
37 #if wxUSE_WX_RESOURCES
38 #include "wx/resource.h"
53 #include "wx/mac/uma.h"
54 #include "wx/mac/macnotfy.h"
58 #include <CoreServices/CoreServices.h>
62 extern char *wxBuffer
;
63 extern wxList wxPendingDelete
;
64 extern wxList
*wxWinMacWindowList
;
65 extern wxList
*wxWinMacControlList
;
67 wxApp
*wxTheApp
= NULL
;
69 #if !USE_SHARED_LIBRARY
70 IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
)
71 BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
)
72 EVT_IDLE(wxApp::OnIdle
)
73 EVT_END_SESSION(wxApp::OnEndSession
)
74 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession
)
79 const short kMacMinHeap
= (29 * 1024) ;
80 // platform specific static variables
82 const short kwxMacMenuBarResource
= 1 ;
83 const short kwxMacAppleMenuId
= 1 ;
85 WXHRGN
wxApp::s_macCursorRgn
= NULL
;
86 wxWindow
* wxApp::s_captureWindow
= NULL
;
87 int wxApp::s_lastMouseDown
= 0 ;
88 long wxApp::sm_lastMessageTime
= 0;
90 bool wxApp::s_macDefaultEncodingIsPC
= true ;
91 bool wxApp::s_macSupportPCMenuShortcuts
= true ;
92 long wxApp::s_macAboutMenuItemId
= wxID_ABOUT
;
93 wxString
wxApp::s_macHelpMenuTitleName
= "&Help" ;
95 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
96 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
97 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
98 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
101 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
)
103 wxApp
* app
= (wxApp
*) refcon
;
104 return wxTheApp
->MacHandleAEODoc( (AppleEvent
*) event
, reply
) ;
107 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
)
109 wxApp
* app
= (wxApp
*) refcon
;
110 return wxTheApp
->MacHandleAEOApp( (AppleEvent
*) event
, reply
) ;
113 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
)
115 wxApp
* app
= (wxApp
*) refcon
;
116 return wxTheApp
->MacHandleAEPDoc( (AppleEvent
*) event
, reply
) ;
119 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
)
121 wxApp
* app
= (wxApp
*) refcon
;
122 return wxTheApp
->MacHandleAEQuit( (AppleEvent
*) event
, reply
) ;
125 short wxApp::MacHandleAEODoc(const WXEVENTREF event
, WXEVENTREF reply
)
128 ProcessSerialNumber PSN
;
129 PSN
.highLongOfPSN
= 0 ;
130 PSN
.lowLongOfPSN
= kCurrentProcess
;
131 SetFrontProcess( &PSN
) ;
135 short wxApp::MacHandleAEPDoc(const WXEVENTREF event
, WXEVENTREF reply
)
140 short wxApp::MacHandleAEOApp(const WXEVENTREF event
, WXEVENTREF reply
)
145 short wxApp::MacHandleAEQuit(const WXEVENTREF event
, WXEVENTREF reply
)
147 wxWindow
* win
= GetTopWindow() ;
159 char StringMac
[] = "\x0d\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
160 "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
161 "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf"
162 "\xb1\xb4\xb5\xb6\xbb\xbc\xbe\xbf"
163 "\xc0\xc1\xc2\xc4\xc7\xc8\xc9\xcb\xcc\xcd\xce\xcf"
164 "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xca\xdb" ;
166 char StringANSI
[] = "\x0a\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8"
167 "\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC"
168 "\x86\xBA\xA2\xA3\xA7\x95\xB6\xDF\xAE\xA9\x99\xB4\xA8\xC6\xD8"
169 "\xB1\xA5\xB5\xF0\xAA\xBA\xE6\xF8"
170 "\xBF\xA1\xAC\x83\xAB\xBB\x85\xC0\xC3\xD5\x8C\x9C"
171 "\x96\x97\x93\x94\x91\x92\xF7\xFF\xA0\x80" ;
173 void wxMacConvertFromPC( const char *from
, char *to
, int len
)
178 for( int i
= 0 ; i
< len
; ++ i
)
180 c
= strchr( StringANSI
, *from
) ;
183 *to
= StringMac
[ c
- StringANSI
] ;
191 for( int i
= 0 ; i
< len
; ++ i
)
193 c
= strchr( StringANSI
, *from
) ;
196 *to
= StringMac
[ c
- StringANSI
] ;
208 void wxMacConvertToPC( const char *from
, char *to
, int len
)
213 for( int i
= 0 ; i
< len
; ++ i
)
215 c
= strchr( StringMac
, *from
) ;
218 *to
= StringANSI
[ c
- StringMac
] ;
226 for( int i
= 0 ; i
< len
; ++ i
)
228 c
= strchr( StringMac
, *from
) ;
231 *to
= StringANSI
[ c
- StringMac
] ;
243 void wxMacConvertFromPC( char * p
)
246 int len
= strlen ( p
) ;
248 wxMacConvertFromPC( ptr
, ptr
, len
) ;
251 void wxMacConvertFromPCForControls( char * p
)
254 int len
= strlen ( p
) ;
256 wxMacConvertFromPC( ptr
, ptr
, len
) ;
257 for ( int i
= 0 ; i
< strlen ( ptr
) ; i
++ )
259 if ( ptr
[i
] == '&' && ptr
[i
]+1 != ' ' )
261 memmove( &ptr
[i
] , &ptr
[i
+1] , strlen( &ptr
[i
+1] ) + 1) ;
266 void wxMacConvertFromPC( unsigned char *p
)
268 char *ptr
= (char*) p
+ 1 ;
271 wxMacConvertFromPC( ptr
, ptr
, len
) ;
274 extern char *wxBuffer
;
276 wxString
wxMacMakeMacStringFromPC( const char * p
)
278 const char *ptr
= p
;
279 int len
= strlen ( p
) ;
280 char *buf
= wxBuffer
;
282 if ( len
>= BUFSIZ
+ 512 )
284 buf
= new char [len
+1] ;
287 wxMacConvertFromPC( ptr
, buf
, len
) ;
289 wxString
result( buf
) ;
290 if ( buf
!= wxBuffer
)
296 void wxMacConvertToPC( char * p
)
299 int len
= strlen ( p
) ;
301 wxMacConvertToPC( ptr
, ptr
, len
) ;
304 void wxMacConvertToPC( unsigned char *p
)
306 char *ptr
= (char*) p
+ 1 ;
309 wxMacConvertToPC( ptr
, ptr
, len
) ;
312 wxString
wxMacMakePCStringFromMac( const char * p
)
314 const char *ptr
= p
;
315 int len
= strlen ( p
) ;
316 char *buf
= wxBuffer
;
318 if ( len
>= BUFSIZ
+ 512 )
320 buf
= new char [len
+1] ;
323 wxMacConvertToPC( ptr
, buf
, len
) ;
326 wxString
result( buf
) ;
327 if ( buf
!= wxBuffer
)
332 wxString
wxMacMakeStringFromMacString( const char* from
, bool mac2pcEncoding
)
336 return wxMacMakePCStringFromMac( from
) ;
340 return wxString( from
) ;
344 wxString
wxMacMakeStringFromPascal( StringPtr from
, bool mac2pcEncoding
)
346 // this is safe since a pascal string can never be larger than 256 bytes
348 CopyPascalStringToC( from
, s
) ;
351 return wxMacMakePCStringFromMac( s
) ;
355 return wxString( s
) ;
359 void wxMacStringToPascal( const char * from
, StringPtr to
, bool pc2macEncoding
)
363 CopyCStringToPascal( wxMacMakeMacStringFromPC( from
) , to
) ;
367 CopyCStringToPascal( from
, to
) ;
371 bool wxApp::Initialize()
377 UMAInitToolbox( 4 ) ;
378 SetEventMask( everyEvent
) ;
379 UMAShowWatchCursor() ;
381 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
382 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
, NewAEEventHandlerUPP(AEHandleODoc
) ,
383 (long) wxTheApp
, FALSE
) ;
384 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
, NewAEEventHandlerUPP(AEHandleOApp
) ,
385 (long) wxTheApp
, FALSE
) ;
386 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
, NewAEEventHandlerUPP(AEHandlePDoc
) ,
387 (long) wxTheApp
, FALSE
) ;
388 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
, NewAEEventHandlerUPP(AEHandleQuit
) ,
389 (long) wxTheApp
, FALSE
) ;
391 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
, NewAEEventHandlerProc(AEHandleODoc
) ,
392 (long) wxTheApp
, FALSE
) ;
393 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
, NewAEEventHandlerProc(AEHandleOApp
) ,
394 (long) wxTheApp
, FALSE
) ;
395 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
, NewAEEventHandlerProc(AEHandlePDoc
) ,
396 (long) wxTheApp
, FALSE
) ;
397 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
, NewAEEventHandlerProc(AEHandleQuit
) ,
398 (long) wxTheApp
, FALSE
) ;
403 // test the minimal configuration necessary
409 if (Gestalt(gestaltMachineType
, &theMachine
) != noErr
)
411 error
= kMacSTRWrongMachine
;
413 else if (theMachine
< gestaltMacPlus
)
415 error
= kMacSTRWrongMachine
;
417 else if (Gestalt(gestaltSystemVersion
, &theSystem
) != noErr
)
419 error
= kMacSTROldSystem
;
421 else if ( theSystem
< 0x0860 )
423 error
= kMacSTROldSystem
;
425 else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap
)
427 error
= kMacSTRSmallSize
;
433 if ( !UMAHasAppearance() )
435 error = kMacSTRNoPre8Yet ;
441 // if we encountered any problems so far, give the error code and exit immediately
448 GetIndString(message
, 128, error
);
449 UMAShowArrowCursor() ;
450 ParamText("\pFatal Error", message
, (ConstStr255Param
)"\p", (ConstStr255Param
)"\p");
451 itemHit
= Alert(128, nil
);
456 #if __option(profile)
457 ProfilerInit( collectDetailed
, bestTimeBase
, 20000 , 40 ) ;
461 // now avoid exceptions thrown for new (bad_alloc)
464 std::__throws_bad_alloc
= FALSE
;
467 s_macCursorRgn
= ::NewRgn() ;
470 wxBuffer
= new char[1500];
472 wxBuffer
= new char[BUFSIZ
+ 512];
475 wxClassInfo::InitializeClasses();
478 // wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion);
482 wxPendingEventsLocker
= new wxCriticalSection
;
484 wxTheColourDatabase
= new wxColourDatabase(wxKEY_STRING
);
485 wxTheColourDatabase
->Initialize();
489 // flush the logged messages if any and install a 'safer' log target: the
490 // default one (wxLogGui) can't be used after the resources are freed just
491 // below and the user suppliedo ne might be even more unsafe (using any
492 // wxWindows GUI function is unsafe starting from now)
493 wxLog::DontCreateOnDemand();
495 // this will flush the old messages if any
496 delete wxLog::SetActiveTarget(new wxLogStderr
);
500 wxInitializeStockLists();
501 wxInitializeStockObjects();
503 #if wxUSE_WX_RESOURCES
504 wxInitializeResourceSystem();
507 wxBitmap::InitStandardHandlers();
509 wxModule::RegisterModules();
510 if (!wxModule::InitializeModules()) {
514 wxWinMacWindowList
= new wxList(wxKEY_INTEGER
);
515 wxWinMacControlList
= new wxList(wxKEY_INTEGER
);
517 wxMacCreateNotifierTable() ;
519 UMAShowArrowCursor() ;
524 void wxApp::CleanUp()
526 wxToolTip::RemoveToolTips() ;
528 // flush the logged messages if any and install a 'safer' log target: the
529 // default one (wxLogGui) can't be used after the resources are freed just
530 // below and the user suppliedo ne might be even more unsafe (using any
531 // wxWindows GUI function is unsafe starting from now)
532 wxLog::DontCreateOnDemand();
534 // this will flush the old messages if any
535 delete wxLog::SetActiveTarget(new wxLogStderr
);
538 // One last chance for pending objects to be cleaned up
539 wxTheApp
->DeletePendingObjects();
541 wxModule::CleanUpModules();
543 #if wxUSE_WX_RESOURCES
544 wxCleanUpResourceSystem();
547 wxDeleteStockObjects() ;
549 // Destroy all GDI lists, etc.
550 wxDeleteStockLists();
552 delete wxTheColourDatabase
;
553 wxTheColourDatabase
= NULL
;
555 wxBitmap::CleanUpHandlers();
560 wxMacDestroyNotifierTable() ;
561 if (wxWinMacWindowList
)
562 delete wxWinMacWindowList
;
564 if (wxWinMacControlList
)
565 delete wxWinMacControlList
;
567 delete wxPendingEvents
;
569 delete wxPendingEventsLocker
;
570 // If we don't do the following, we get an apparent memory leak.
571 ((wxEvtHandler
&) wxDefaultValidator
).ClearEventLocker();
574 wxClassInfo::CleanUpClasses();
577 #if __option(profile)
578 ProfilerDump( "\papp.prof" ) ;
586 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
587 // At this point we want to check if there are any memory
588 // blocks that aren't part of the wxDebugContext itself,
589 // as a special case. Then when dumping we need to ignore
590 // wxDebugContext, too.
591 if (wxDebugContext::CountObjectsLeft(TRUE
) > 0)
593 wxLogDebug(wxT("There were memory leaks."));
594 wxDebugContext::Dump();
595 wxDebugContext::PrintStatistics();
597 // wxDebugContext::SetStream(NULL, NULL);
601 // do it as the very last thing because everything else can log messages
602 delete wxLog::SetActiveTarget(NULL
);
605 UMACleanupToolbox() ;
607 ::DisposeRgn((RgnHandle
)s_macCursorRgn
);
614 //----------------------------------------------------------------------
616 //----------------------------------------------------------------------
618 int wxEntryStart( int argc
, char *argv
[] )
620 return wxApp::Initialize();
626 return wxTheApp
->OnInitGui();
630 void wxEntryCleanup()
636 int wxEntry( int argc
, char *argv
[] , bool enterLoop
)
639 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
640 // This seems to be necessary since there are 'rogue'
641 // objects present at this point (perhaps global objects?)
642 // Setting a checkpoint will ignore them as far as the
643 // memory checking facility is concerned.
644 // Of course you may argue that memory allocated in globals should be
645 // checked, but this is a reasonable compromise.
646 wxDebugContext::SetCheckpoint();
649 if (!wxEntryStart(argc
, argv
)) {
652 // create the application object or ensure that one already exists
655 // The app may have declared a global application object, but we recommend
656 // the IMPLEMENT_APP macro is used instead, which sets an initializer
657 // function for delayed, dynamic app object construction.
658 wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
659 wxT("No initializer - use IMPLEMENT_APP macro.") );
661 wxTheApp
= (wxApp
*) (*wxApp::GetInitializerFunction()) ();
664 wxCHECK_MSG( wxTheApp
, 0, wxT("You have to define an instance of wxApp!") );
667 argc
= 0 ; // currently we don't support files as parameters
669 // we could try to get the open apple events here to adjust argc and argv better
671 wxTheApp
->argc
= argc
;
672 wxTheApp
->argv
= argv
;
674 // GUI-specific initialization, such as creating an app context.
678 // Here frames insert themselves automatically
679 // into wxTopLevelWindows by getting created
684 if ( wxTheApp
->OnInit() )
688 retValue
= wxTheApp
->OnRun();
691 // We want to initialize, but not run or exit immediately.
694 //else: app initialization failed, so we skipped OnRun()
696 wxWindow
*topWindow
= wxTheApp
->GetTopWindow();
699 // Forcibly delete the window.
700 if ( topWindow
->IsKindOf(CLASSINFO(wxFrame
)) ||
701 topWindow
->IsKindOf(CLASSINFO(wxDialog
)) )
703 topWindow
->Close(TRUE
);
704 wxTheApp
->DeletePendingObjects();
709 wxTheApp
->SetTopWindow(NULL
);
720 // Static member initialization
721 wxAppInitializerFunction
wxAppBase::m_appInitFn
= (wxAppInitializerFunction
) NULL
;
728 m_wantDebugOutput
= TRUE
;
733 m_printMode
= wxPRINT_WINDOWS
;
734 m_exitOnFrameDelete
= TRUE
;
738 bool wxApp::Initialized()
746 int wxApp::MainLoop()
758 // Returns TRUE if more time is needed.
759 bool wxApp::ProcessIdle()
762 event
.SetEventObject(this);
765 return event
.MoreRequested();
768 void wxApp::ExitMainLoop()
773 // Is a message/event pending?
774 bool wxApp::Pending()
778 return EventAvail( everyEvent
, &event
) ;
781 // Dispatch a message.
782 void wxApp::Dispatch()
787 void wxApp::OnIdle(wxIdleEvent
& event
)
789 static bool s_inOnIdle
= FALSE
;
791 // Avoid recursion (via ProcessEvent default case)
798 // 'Garbage' collection of windows deleted with Close().
799 DeletePendingObjects();
801 // flush the logged messages if any
802 wxLog
*pLog
= wxLog::GetActiveTarget();
803 if ( pLog
!= NULL
&& pLog
->HasPendingMessages() )
806 // Send OnIdle events to all windows
807 bool needMore
= SendIdleEvents();
810 event
.RequestMore(TRUE
);
812 // If they are pending events, we must process them: pending events are
813 // either events to the threads other than main or events posted with
814 // wxPostEvent() functions
815 wxMacProcessNotifierAndPendingEvents();
825 // Send idle event to all top-level windows
826 bool wxApp::SendIdleEvents()
828 bool needMore
= FALSE
;
829 wxNode
* node
= wxTopLevelWindows
.First();
832 wxWindow
* win
= (wxWindow
*) node
->Data();
833 if (SendIdleEvents(win
))
841 // Send idle event to window and all subwindows
842 bool wxApp::SendIdleEvents(wxWindow
* win
)
844 bool needMore
= FALSE
;
847 event
.SetEventObject(win
);
848 win
->ProcessEvent(event
);
850 if (event
.MoreRequested())
853 wxNode
* node
= win
->GetChildren().First();
856 wxWindow
* win
= (wxWindow
*) node
->Data();
857 if (SendIdleEvents(win
))
865 void wxApp::DeletePendingObjects()
867 wxNode
*node
= wxPendingDelete
.First();
870 wxObject
*obj
= (wxObject
*)node
->Data();
874 if (wxPendingDelete
.Member(obj
))
877 // Deleting one object may have deleted other pending
878 // objects, so start from beginning of list again.
879 node
= wxPendingDelete
.First();
884 wxApp::GetStdIcon(int which
) const
888 case wxICON_INFORMATION
:
889 return wxIcon("wxICON_INFO");
891 case wxICON_QUESTION
:
892 return wxIcon("wxICON_QUESTION");
894 case wxICON_EXCLAMATION
:
895 return wxIcon("wxICON_WARNING");
898 wxFAIL_MSG(wxT("requested non existent standard icon"));
899 // still fall through
902 return wxIcon("wxICON_ERROR");
908 wxLogError(_("Fatal error: exiting"));
914 void wxApp::OnEndSession(wxCloseEvent
& WXUNUSED(event
))
917 GetTopWindow()->Close(TRUE
);
920 // Default behaviour: close the application with prompts. The
921 // user can veto the close, and therefore the end session.
922 void wxApp::OnQueryEndSession(wxCloseEvent
& event
)
926 if (!GetTopWindow()->Close(!event
.CanVeto()))
931 extern "C" void wxCYield() ;
937 // Yield to other processes
939 bool wxApp::Yield(bool onlyIfNeeded
)
941 static bool s_inYield
= FALSE
;
947 wxFAIL_MSG( wxT("wxYield called recursively" ) );
960 long sleepTime
= 1 ; //::GetCaretTime();
962 while ( !wxTheApp
->IsExiting() && WaitNextEvent(everyEvent
, &event
,sleepTime
, (RgnHandle
) wxApp::s_macCursorRgn
))
964 wxTheApp
->MacHandleOneEvent( &event
);
965 if ( event
.what
!= kHighLevelEvent
)
966 SetRectRgn( (RgnHandle
) wxApp::s_macCursorRgn
, event
.where
.h
, event
.where
.v
, event
.where
.h
+ 1 , event
.where
.v
+ 1 ) ;
969 wxMacProcessNotifierAndPendingEvents() ;
976 // platform specifics
978 void wxApp::MacSuspend( bool convertClipboard
)
980 // we have to deactive the top level windows manually
982 wxNode
* node
= wxTopLevelWindows
.First();
985 wxTopLevelWindow
* win
= (wxTopLevelWindow
*) node
->Data();
986 win
->MacActivate( MacGetCurrentEvent() , false ) ;
991 s_lastMouseDown
= 0 ;
992 if( convertClipboard
)
994 MacConvertPrivateToPublicScrap() ;
997 ::HideFloatingWindows() ;
1000 void wxApp::MacResume( bool convertClipboard
)
1002 s_lastMouseDown
= 0 ;
1003 if( convertClipboard
)
1005 MacConvertPublicToPrivateScrap() ;
1008 ::ShowFloatingWindows() ;
1011 void wxApp::MacConvertPrivateToPublicScrap()
1015 void wxApp::MacConvertPublicToPrivateScrap()
1019 void wxApp::MacDoOneEvent()
1023 long sleepTime
= 1; // GetCaretTime() / 4 ;
1025 if (WaitNextEvent(everyEvent
, &event
, sleepTime
, (RgnHandle
) s_macCursorRgn
))
1027 MacHandleOneEvent( &event
);
1032 WindowPtr window
= ::FrontWindow() ;
1034 ::IdleControls( window
) ;
1036 wxTheApp
->ProcessIdle() ;
1038 if ( event
.what
!= kHighLevelEvent
)
1039 SetRectRgn( (RgnHandle
) s_macCursorRgn
, event
.where
.h
, event
.where
.v
, event
.where
.h
+ 1 , event
.where
.v
+ 1 ) ;
1043 DeletePendingObjects() ;
1044 wxMacProcessNotifierAndPendingEvents() ;
1047 void wxApp::MacHandleOneEvent( WXEVENTREF evr
)
1049 EventRecord
* ev
= (EventRecord
*) evr
;
1050 m_macCurrentEvent
= ev
;
1052 wxApp::sm_lastMessageTime
= ev
->when
;
1057 MacHandleMouseDownEvent( ev
) ;
1058 if ( ev
->modifiers
& controlKey
)
1059 s_lastMouseDown
= 2;
1061 s_lastMouseDown
= 1;
1064 if ( s_lastMouseDown
== 2 )
1066 ev
->modifiers
|= controlKey
;
1070 ev
->modifiers
&= ~controlKey
;
1072 MacHandleMouseUpEvent( ev
) ;
1073 s_lastMouseDown
= 0;
1076 MacHandleActivateEvent( ev
) ;
1079 MacHandleUpdateEvent( ev
) ;
1083 MacHandleKeyDownEvent( ev
) ;
1086 MacHandleKeyUpEvent( ev
) ;
1089 MacHandleDiskEvent( ev
) ;
1092 MacHandleOSEvent( ev
) ;
1094 case kHighLevelEvent
:
1095 MacHandleHighLevelEvent( ev
) ;
1100 wxMacProcessNotifierAndPendingEvents() ;
1103 void wxApp::MacHandleHighLevelEvent( WXEVENTREF evr
)
1105 EventRecord
* ev
= (EventRecord
*) evr
;
1106 ::AEProcessAppleEvent( ev
) ;
1109 bool s_macIsInModalLoop
= false ;
1111 void wxApp::MacHandleMouseDownEvent( WXEVENTREF evr
)
1113 EventRecord
* ev
= (EventRecord
*) evr
;
1114 wxToolTip::RemoveToolTips() ;
1117 WindowRef frontWindow
= ::FrontNonFloatingWindow() ;
1118 WindowAttributes frontWindowAttributes
= NULL
;
1120 ::GetWindowAttributes( frontWindow
, &frontWindowAttributes
) ;
1122 short windowPart
= ::FindWindow(ev
->where
, &window
);
1123 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
1124 if ( wxPendingDelete
.Member(win
) )
1128 GetQDGlobalsScreenBits( &screenBits
);
1133 if ( s_macIsInModalLoop
)
1139 UInt32 menuresult
= MenuSelect(ev
->where
) ;
1140 MacHandleMenuSelect( HiWord( menuresult
) , LoWord( menuresult
) );
1141 s_lastMouseDown
= 0;
1146 SystemClick( ev
, window
) ;
1147 s_lastMouseDown
= 0;
1151 if ( window
!= frontWindow
&& s_macIsInModalLoop
&& !(ev
->modifiers
& cmdKey
) )
1157 DragWindow(window
, ev
->where
, &screenBits
.bounds
);
1162 Point pt
= { 0, 0 } ;
1163 SetPort( GetWindowPort(window
) ) ;
1164 LocalToGlobal( &pt
) ;
1166 win
->SetSize( pt
.h
, pt
.v
, -1 ,
1167 -1 , wxSIZE_USE_EXISTING
);
1169 s_lastMouseDown
= 0;
1173 if (TrackGoAway(window
, ev
->where
))
1178 s_lastMouseDown
= 0;
1182 int growResult
= GrowWindow(window
, ev
->where
, &screenBits
.bounds
);
1183 if (growResult
!= 0)
1185 int newWidth
= LoWord(growResult
);
1186 int newHeight
= HiWord(growResult
);
1187 int oldWidth
, oldHeight
;
1192 win
->GetSize(&oldWidth
, &oldHeight
);
1194 newWidth
= oldWidth
;
1196 newHeight
= oldHeight
;
1197 win
->SetSize( -1, -1, newWidth
, newHeight
, wxSIZE_USE_EXISTING
);
1200 s_lastMouseDown
= 0;
1205 if (TrackBox(window
, ev
->where
, windowPart
))
1207 // TODO setup size event
1208 ZoomWindow( window
, windowPart
, false ) ;
1213 GetWindowPortBounds(window
, &tempRect
) ;
1214 win
->SetSize( -1, -1, tempRect
.right
-tempRect
.left
,
1215 tempRect
.bottom
-tempRect
.top
, wxSIZE_USE_EXISTING
);
1218 s_lastMouseDown
= 0;
1220 case inCollapseBox
:
1221 // TODO setup size event
1222 s_lastMouseDown
= 0;
1229 SetPort( GetWindowPort(window
) ) ;
1232 if ( window
!= frontWindow
&& wxTheApp
->s_captureWindow
== NULL
)
1234 if ( s_macIsInModalLoop
)
1238 else if ( UMAIsWindowFloating( window
) )
1241 win
->MacMouseDown( ev
, windowPart
) ;
1246 win
->MacMouseDown( ev
, windowPart
) ;
1247 ::SelectWindow( window
) ;
1253 win
->MacMouseDown( ev
, windowPart
) ;
1262 void wxApp::MacHandleMouseUpEvent( WXEVENTREF evr
)
1264 EventRecord
* ev
= (EventRecord
*) evr
;
1267 short windowPart
= ::FindWindow(ev
->where
, &window
);
1277 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
1279 win
->MacMouseUp( ev
, windowPart
) ;
1285 long wxMacTranslateKey(unsigned char key
, unsigned char code
) ;
1286 long wxMacTranslateKey(unsigned char key
, unsigned char code
)
1295 retval
= WXK_RETURN
;
1310 retval
= WXK_PAGEUP
;
1313 retval
= WXK_PAGEDOWN
;
1316 retval
= WXK_RETURN
;
1371 retval
= WXK_ESCAPE
;
1377 retval
= WXK_RIGHT
;
1386 retval
= WXK_DELETE
;
1394 void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr
)
1396 EventRecord
* ev
= (EventRecord
*) evr
;
1397 wxToolTip::RemoveToolTips() ;
1399 UInt32 menuresult
= UMAMenuEvent(ev
) ;
1400 if ( HiWord( menuresult
) )
1402 if ( !s_macIsInModalLoop
)
1403 MacHandleMenuSelect( HiWord( menuresult
) , LoWord( menuresult
) ) ;
1409 keychar
= short(ev
->message
& charCodeMask
);
1410 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1411 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
1412 bool handled
= false ;
1413 wxWindow
* focus
= wxWindow::FindFocus() ;
1417 wxKeyEvent
event(wxEVT_KEY_DOWN
);
1418 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1419 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1420 event
.m_altDown
= ev
->modifiers
& optionKey
;
1421 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1422 event
.m_keyCode
= keyval
;
1423 event
.m_x
= ev
->where
.h
;
1424 event
.m_y
= ev
->where
.v
;
1425 event
.m_timeStamp
= ev
->when
;
1426 event
.SetEventObject(focus
);
1427 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1433 wxWindow
*ancestor
= focus
;
1437 int command = ancestor->GetAcceleratorTable()->GetCommand( event );
1440 wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
1441 handled = ancestor->GetEventHandler()->ProcessEvent( command_event );
1444 if (ancestor->m_isFrame)
1446 ancestor = ancestor->GetParent();
1450 #endif // wxUSE_ACCEL
1454 wxKeyEvent
event(wxEVT_CHAR
);
1455 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1456 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1457 event
.m_altDown
= ev
->modifiers
& optionKey
;
1458 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1459 event
.m_keyCode
= keyval
;
1460 event
.m_x
= ev
->where
.h
;
1461 event
.m_y
= ev
->where
.v
;
1462 event
.m_timeStamp
= ev
->when
;
1463 event
.SetEventObject(focus
);
1464 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1467 (keyval
== WXK_TAB
) &&
1468 (!focus
->HasFlag(wxTE_PROCESS_TAB
)) &&
1469 (focus
->GetParent()) &&
1470 (focus
->GetParent()->HasFlag( wxTAB_TRAVERSAL
)) )
1472 wxNavigationKeyEvent new_event
;
1473 new_event
.SetEventObject( focus
);
1474 new_event
.SetDirection( !event
.ShiftDown() );
1475 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
1476 new_event
.SetWindowChange( event
.ControlDown() );
1477 new_event
.SetCurrentFocus( focus
);
1478 handled
= focus
->GetEventHandler()->ProcessEvent( new_event
);
1483 // if window is not having a focus still testing for default enter or cancel
1484 // TODO add the UMA version for ActiveNonFloatingWindow
1485 focus
= wxFindWinFromMacWindow( FrontWindow() ) ;
1488 if ( keyval
== WXK_RETURN
)
1490 wxButton
*def
= wxDynamicCast(focus
->GetDefaultItem(),
1492 if ( def
&& def
->IsEnabled() )
1494 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1495 event
.SetEventObject(def
);
1496 def
->Command(event
);
1500 /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
1501 else if (keyval
== WXK_ESCAPE
|| (keyval
== '.' && ev
->modifiers
& cmdKey
) )
1503 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
1504 new_event
.SetEventObject( focus
);
1505 handled
= focus
->GetEventHandler()->ProcessEvent( new_event
);
1512 void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr
)
1514 EventRecord
* ev
= (EventRecord
*) evr
;
1515 wxToolTip::RemoveToolTips() ;
1517 UInt32 menuresult
= UMAMenuEvent(ev
) ;
1518 if ( HiWord( menuresult
) )
1525 keychar
= short(ev
->message
& charCodeMask
);
1526 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1528 wxWindow
* focus
= wxWindow::FindFocus() ;
1531 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
1533 wxKeyEvent
event(wxEVT_KEY_UP
);
1534 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1535 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1536 event
.m_altDown
= ev
->modifiers
& optionKey
;
1537 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1538 event
.m_keyCode
= keyval
;
1539 event
.m_x
= ev
->where
.h
;
1540 event
.m_y
= ev
->where
.v
;
1541 event
.m_timeStamp
= ev
->when
;
1542 event
.SetEventObject(focus
);
1543 bool handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1548 void wxApp::MacHandleActivateEvent( WXEVENTREF evr
)
1550 EventRecord
* ev
= (EventRecord
*) evr
;
1551 WindowRef window
= (WindowRef
) ev
->message
;
1554 bool activate
= (ev
->modifiers
& activeFlag
) ;
1555 WindowClass wclass
;
1556 ::GetWindowClass ( window
, &wclass
) ;
1557 if ( wclass
== kFloatingWindowClass
)
1559 // if it is a floater we activate/deactivate the front non-floating window instead
1560 window
= ::FrontNonFloatingWindow() ;
1562 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
1564 win
->MacActivate( ev
, activate
) ;
1568 void wxApp::MacHandleUpdateEvent( WXEVENTREF evr
)
1570 EventRecord
* ev
= (EventRecord
*) evr
;
1571 WindowRef window
= (WindowRef
) ev
->message
;
1572 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
1575 if ( !wxPendingDelete
.Member(win
) )
1576 win
->MacUpdate( ev
->when
) ;
1580 // since there is no way of telling this foreign window to update itself
1581 // we have to invalidate the update region otherwise we keep getting the same
1582 // event over and over again
1583 BeginUpdate( window
) ;
1584 EndUpdate( window
) ;
1588 void wxApp::MacHandleDiskEvent( WXEVENTREF evr
)
1590 EventRecord
* ev
= (EventRecord
*) evr
;
1591 if ( HiWord( ev
->message
) != noErr
)
1596 SetPt( &point
, 100 , 100 ) ;
1598 err
= DIBadMount( point
, ev
->message
) ;
1599 wxASSERT( err
== noErr
) ;
1604 void wxApp::MacHandleOSEvent( WXEVENTREF evr
)
1606 EventRecord
* ev
= (EventRecord
*) evr
;
1607 switch( ( ev
->message
& osEvtMessageMask
) >> 24 )
1609 case suspendResumeMessage
:
1611 bool isResuming
= ev
->message
& resumeFlag
;
1613 bool convertClipboard
= ev
->message
& convertClipboardFlag
;
1615 bool convertClipboard
= false;
1617 bool doesActivate
= UMAGetProcessModeDoesActivateOnFGSwitch() ;
1620 WindowRef oldFrontWindow
= NULL
;
1621 WindowRef newFrontWindow
= NULL
;
1623 // in case we don't take care of activating ourselves, we have to synchronize
1624 // our idea of the active window with the process manager's - which it already activated
1626 if ( !doesActivate
)
1627 oldFrontWindow
= ::FrontNonFloatingWindow() ;
1629 MacResume( convertClipboard
) ;
1631 newFrontWindow
= ::FrontNonFloatingWindow() ;
1633 if ( oldFrontWindow
)
1635 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( oldFrontWindow
) ;
1637 win
->MacActivate( ev
, false ) ;
1639 if ( newFrontWindow
)
1641 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( newFrontWindow
) ;
1643 win
->MacActivate( ev
, true ) ;
1648 MacSuspend( convertClipboard
) ;
1650 // in case this suspending did close an active window, another one might
1651 // have surfaced -> lets deactivate that one
1653 /* TODO : find out what to do on systems < 10 , perhaps FrontNonFloatingWindow
1654 WindowRef newActiveWindow = ::ActiveNonFloatingWindow() ;
1655 if ( newActiveWindow )
1657 wxWindow* win = wxFindWinFromMacWindow( newActiveWindow ) ;
1659 win->MacActivate( ev , false ) ;
1665 case mouseMovedMessage
:
1669 wxWindow
* currentMouseWindow
= NULL
;
1671 wxWindow::MacGetWindowFromPoint( wxPoint( ev
->where
.h
, ev
->where
.v
) ,
1672 ¤tMouseWindow
) ;
1674 if ( currentMouseWindow
!= wxWindow::s_lastMouseWindow
)
1676 wxMouseEvent event
;
1678 bool isDown
= !(ev
->modifiers
& btnState
) ; // 1 is for up
1679 bool controlDown
= ev
->modifiers
& controlKey
; // for simulating right mouse
1681 event
.m_leftDown
= isDown
&& !controlDown
;
1682 event
.m_middleDown
= FALSE
;
1683 event
.m_rightDown
= isDown
&& controlDown
;
1684 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1685 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1686 event
.m_altDown
= ev
->modifiers
& optionKey
;
1687 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1688 event
.m_x
= ev
->where
.h
;
1689 event
.m_y
= ev
->where
.v
;
1690 event
.m_timeStamp
= ev
->when
;
1691 event
.SetEventObject(this);
1693 if ( wxWindow::s_lastMouseWindow
)
1695 wxMouseEvent
eventleave(event
) ;
1696 eventleave
.SetEventType( wxEVT_LEAVE_WINDOW
) ;
1697 wxWindow::s_lastMouseWindow
->GetEventHandler()->ProcessEvent(eventleave
);
1699 if ( currentMouseWindow
)
1701 wxMouseEvent
evententer(event
) ;
1702 evententer
.SetEventType( wxEVT_ENTER_WINDOW
) ;
1703 currentMouseWindow
->GetEventHandler()->ProcessEvent(evententer
);
1705 wxWindow::s_lastMouseWindow
= currentMouseWindow
;
1708 short windowPart
= ::FindWindow(ev
->where
, &window
);
1712 // fixes for setting the cursor back from dominic mazzoni
1714 UMAShowArrowCursor();
1717 UMAShowArrowCursor();
1721 // if ( s_lastMouseDown == 0 )
1722 // ev->modifiers |= btnState ;
1724 // Calling GetNextEvent with a zero event mask will always
1725 // pass back a null event. However, it fills the EventRecord
1726 // with the state of the modifier keys. This is needed since
1727 // the modifier state returned by WaitForNextEvent often is
1728 // wrong mouse move events. The attempt above to correct this
1729 // didn't always work (under OS X at least).
1732 ::GetNextEvent(0, &tmp
);
1733 ev
->modifiers
= tmp
.modifiers
;
1735 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
1737 win
->MacMouseMoved( ev
, windowPart
) ;
1739 UMAShowArrowCursor();
1750 void wxApp::MacHandleMenuSelect( int macMenuId
, int macMenuItemNum
)
1753 return; // no menu item selected
1755 if (macMenuId
== kwxMacAppleMenuId
&& macMenuItemNum
> 1)
1758 Str255 deskAccessoryName
;
1761 GetMenuItemText(GetMenuHandle(kwxMacAppleMenuId
), macMenuItemNum
, deskAccessoryName
);
1762 GetPort(&savedPort
);
1763 OpenDeskAcc(deskAccessoryName
);
1769 wxWindow
* frontwindow
= wxFindWinFromMacWindow( ::FrontWindow() ) ;
1770 if ( frontwindow
&& wxMenuBar::MacGetInstalledMenuBar() )
1771 wxMenuBar::MacGetInstalledMenuBar()->MacMenuSelect( frontwindow
->GetEventHandler() , 0 , macMenuId
, macMenuItemNum
) ;
1777 long wxApp::MacTranslateKey(char key, int mods)
1781 void wxApp::MacAdjustCursor()
1788 wxApp::macAdjustCursor()
1790 if (ev->what != kHighLevelEvent)
1792 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow());
1795 if (!theMacWxFrame->MacAdjustCursor(ev->where))
1796 ::SetCursor(&(qd.arrow));