1 /////////////////////////////////////////////////////////////////////////////
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "app.h"
16 #include "wx/window.h"
20 #include "wx/gdicmn.h"
23 #include "wx/cursor.h"
26 #include "wx/palette.h"
28 #include "wx/dialog.h"
29 #include "wx/msgdlg.h"
31 #include "wx/module.h"
32 #include "wx/memory.h"
33 #include "wx/tooltip.h"
35 #if wxUSE_WX_RESOURCES
36 #include "wx/resource.h"
51 #include "wx/mac/uma.h"
52 #include "wx/mac/macnotfy.h"
56 #include <CoreServices/CoreServices.h>
58 #include <OpenTransport.h>
59 #include <OpenTptInternet.h>
63 extern char *wxBuffer
;
64 extern wxList wxPendingDelete
;
65 extern wxList
*wxWinMacWindowList
;
66 extern wxList
*wxWinMacControlList
;
68 wxApp
*wxTheApp
= NULL
;
70 #if !USE_SHARED_LIBRARY
71 IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
)
72 BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
)
73 EVT_IDLE(wxApp::OnIdle
)
74 EVT_END_SESSION(wxApp::OnEndSession
)
75 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession
)
80 const short kMacMinHeap
= (29 * 1024) ;
81 // platform specific static variables
83 const short kwxMacMenuBarResource
= 1 ;
84 const short kwxMacAppleMenuId
= 1 ;
86 RgnHandle
wxApp::s_macCursorRgn
= NULL
;
87 wxWindow
* wxApp::s_captureWindow
= NULL
;
88 int wxApp::s_lastMouseDown
= 0 ;
89 long wxApp::sm_lastMessageTime
= 0;
93 bool wxApp::s_macDefaultEncodingIsPC
= true ;
94 bool wxApp::s_macSupportPCMenuShortcuts
= true ;
95 long wxApp::s_macAboutMenuItemId
= wxID_ABOUT
;
96 wxString
wxApp::s_macHelpMenuTitleName
= "&Help" ;
98 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
99 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
)
101 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, unsigned long refcon
)
104 wxApp
* app
= (wxApp
*) refcon
;
105 return wxTheApp
->MacHandleAEODoc( (AppleEvent
*) event
, reply
) ;
108 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
109 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
)
111 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, unsigned long refcon
)
114 wxApp
* app
= (wxApp
*) refcon
;
115 return wxTheApp
->MacHandleAEOApp( (AppleEvent
*) event
, reply
) ;
118 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
119 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
)
121 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, unsigned long refcon
)
124 wxApp
* app
= (wxApp
*) refcon
;
125 return wxTheApp
->MacHandleAEPDoc( (AppleEvent
*) event
, reply
) ;
128 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
129 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
)
131 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, unsigned long refcon
)
134 wxApp
* app
= (wxApp
*) refcon
;
135 return wxTheApp
->MacHandleAEQuit( (AppleEvent
*) event
, reply
) ;
138 OSErr
wxApp::MacHandleAEODoc(const AppleEvent
*event
, AppleEvent
*reply
)
140 ProcessSerialNumber PSN
;
141 PSN
.highLongOfPSN
= 0 ;
142 PSN
.lowLongOfPSN
= kCurrentProcess
;
143 SetFrontProcess( &PSN
) ;
147 OSErr
wxApp::MacHandleAEPDoc(const AppleEvent
*event
, AppleEvent
*reply
)
152 OSErr
wxApp::MacHandleAEOApp(const AppleEvent
*event
, AppleEvent
*reply
)
157 OSErr
wxApp::MacHandleAEQuit(const AppleEvent
*event
, AppleEvent
*reply
)
159 wxWindow
* win
= GetTopWindow() ;
171 char StringMac
[] = "\x0d\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
172 "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
173 "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf"
174 "\xb1\xb4\xb5\xb6\xbb\xbc\xbe\xbf"
175 "\xc0\xc1\xc2\xc4\xc7\xc8\xc9\xcb\xcc\xcd\xce\xcf"
176 "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xca\xdb" ;
178 char StringANSI
[] = "\x0a\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8"
179 "\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC"
180 "\x86\xBA\xA2\xA3\xA7\x95\xB6\xDF\xAE\xA9\x99\xB4\xA8\xC6\xD8"
181 "\xB1\xA5\xB5\xF0\xAA\xBA\xE6\xF8"
182 "\xBF\xA1\xAC\x83\xAB\xBB\x85\xC0\xC3\xD5\x8C\x9C"
183 "\x96\x97\x93\x94\x91\x92\xF7\xFF\xA0\x80" ;
185 void wxMacConvertFromPC( const char *from
, char *to
, int len
)
190 for( int i
= 0 ; i
< len
; ++ i
)
192 c
= strchr( StringANSI
, *from
) ;
195 *to
= StringMac
[ c
- StringANSI
] ;
203 for( int i
= 0 ; i
< len
; ++ i
)
205 c
= strchr( StringANSI
, *from
) ;
208 *to
= StringMac
[ c
- StringANSI
] ;
220 void wxMacConvertToPC( const char *from
, char *to
, int len
)
225 for( int i
= 0 ; i
< len
; ++ i
)
227 c
= strchr( StringMac
, *from
) ;
230 *to
= StringANSI
[ c
- StringMac
] ;
238 for( int i
= 0 ; i
< len
; ++ i
)
240 c
= strchr( StringMac
, *from
) ;
243 *to
= StringANSI
[ c
- StringMac
] ;
255 void wxMacConvertFromPC( char * p
)
258 int len
= strlen ( p
) ;
260 wxMacConvertFromPC( ptr
, ptr
, len
) ;
263 void wxMacConvertFromPCForControls( char * p
)
266 int len
= strlen ( p
) ;
268 wxMacConvertFromPC( ptr
, ptr
, len
) ;
269 for ( int i
= 0 ; i
< strlen ( ptr
) ; i
++ )
271 if ( ptr
[i
] == '&' && ptr
[i
]+1 != ' ' )
273 memmove( &ptr
[i
] , &ptr
[i
+1] , strlen( &ptr
[i
+1] ) + 1) ;
278 void wxMacConvertFromPC( unsigned char *p
)
280 char *ptr
= (char*) p
+ 1 ;
283 wxMacConvertFromPC( ptr
, ptr
, len
) ;
286 extern char *wxBuffer
;
288 wxString
wxMacMakeMacStringFromPC( const char * p
)
290 const char *ptr
= p
;
291 int len
= strlen ( p
) ;
292 char *buf
= wxBuffer
;
294 if ( len
>= BUFSIZ
+ 512 )
296 buf
= new char [len
+1] ;
299 wxMacConvertFromPC( ptr
, buf
, len
) ;
301 wxString
result( buf
) ;
302 if ( buf
!= wxBuffer
)
308 void wxMacConvertToPC( char * p
)
311 int len
= strlen ( p
) ;
313 wxMacConvertToPC( ptr
, ptr
, len
) ;
316 void wxMacConvertToPC( unsigned char *p
)
318 char *ptr
= (char*) p
+ 1 ;
321 wxMacConvertToPC( ptr
, ptr
, len
) ;
324 wxString
wxMacMakePCStringFromMac( const char * p
)
326 const char *ptr
= p
;
327 int len
= strlen ( p
) ;
328 char *buf
= wxBuffer
;
330 if ( len
>= BUFSIZ
+ 512 )
332 buf
= new char [len
+1] ;
335 wxMacConvertToPC( ptr
, buf
, len
) ;
338 wxString
result( buf
) ;
339 if ( buf
!= wxBuffer
)
346 bool wxApp::Initialize()
352 UMAInitToolbox( 4 ) ;
353 SetEventMask( everyEvent
) ;
354 UMAShowWatchCursor() ;
356 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
357 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
, NewAEEventHandlerUPP(AEHandleODoc
) ,
358 (long) wxTheApp
, FALSE
) ;
359 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
, NewAEEventHandlerUPP(AEHandleOApp
) ,
360 (long) wxTheApp
, FALSE
) ;
361 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
, NewAEEventHandlerUPP(AEHandlePDoc
) ,
362 (long) wxTheApp
, FALSE
) ;
363 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
, NewAEEventHandlerUPP(AEHandleQuit
) ,
364 (long) wxTheApp
, FALSE
) ;
366 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
, NewAEEventHandlerProc(AEHandleODoc
) ,
367 (long) wxTheApp
, FALSE
) ;
368 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
, NewAEEventHandlerProc(AEHandleOApp
) ,
369 (long) wxTheApp
, FALSE
) ;
370 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
, NewAEEventHandlerProc(AEHandlePDoc
) ,
371 (long) wxTheApp
, FALSE
) ;
372 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
, NewAEEventHandlerProc(AEHandleQuit
) ,
373 (long) wxTheApp
, FALSE
) ;
378 // test the minimal configuration necessary
384 if (Gestalt(gestaltMachineType
, &theMachine
) != noErr
)
386 error
= kMacSTRWrongMachine
;
388 else if (theMachine
< gestaltMacPlus
)
390 error
= kMacSTRWrongMachine
;
392 else if (Gestalt(gestaltSystemVersion
, &theSystem
) != noErr
)
394 error
= kMacSTROldSystem
;
396 else if ( theSystem
< 0x0750 )
398 error
= kMacSTROldSystem
;
400 else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap
)
402 error
= kMacSTRSmallSize
;
408 if ( !UMAHasAppearance() )
410 error = kMacSTRNoPre8Yet ;
416 // if we encountered any problems so far, give the error code and exit immediately
423 GetIndString(message
, 128, error
);
424 UMAShowArrowCursor() ;
425 ParamText("\pFatal Error", message
, (ConstStr255Param
)"\p", (ConstStr255Param
)"\p");
426 itemHit
= Alert(128, nil
);
431 #if __option(profile)
432 ProfilerInit( collectDetailed
, bestTimeBase
, 20000 , 40 ) ;
436 // now avoid exceptions thrown for new (bad_alloc)
439 std::__throws_bad_alloc
= FALSE
;
442 s_macCursorRgn
= ::NewRgn() ;
445 wxBuffer
= new char[1500];
447 wxBuffer
= new char[BUFSIZ
+ 512];
450 wxClassInfo::InitializeClasses();
453 // wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion);
457 wxPendingEventsLocker
= new wxCriticalSection
;
459 wxTheColourDatabase
= new wxColourDatabase(wxKEY_STRING
);
460 wxTheColourDatabase
->Initialize();
464 // flush the logged messages if any and install a 'safer' log target: the
465 // default one (wxLogGui) can't be used after the resources are freed just
466 // below and the user suppliedo ne might be even more unsafe (using any
467 // wxWindows GUI function is unsafe starting from now)
468 wxLog::DontCreateOnDemand();
470 // this will flush the old messages if any
471 delete wxLog::SetActiveTarget(new wxLogStderr
);
475 wxInitializeStockLists();
476 wxInitializeStockObjects();
478 #if wxUSE_WX_RESOURCES
479 wxInitializeResourceSystem();
482 wxBitmap::InitStandardHandlers();
484 wxModule::RegisterModules();
485 if (!wxModule::InitializeModules()) {
489 wxWinMacWindowList
= new wxList(wxKEY_INTEGER
);
490 wxWinMacControlList
= new wxList(wxKEY_INTEGER
);
492 wxMacCreateNotifierTable() ;
494 UMAShowArrowCursor() ;
499 void wxApp::CleanUp()
502 // flush the logged messages if any and install a 'safer' log target: the
503 // default one (wxLogGui) can't be used after the resources are freed just
504 // below and the user suppliedo ne might be even more unsafe (using any
505 // wxWindows GUI function is unsafe starting from now)
506 wxLog::DontCreateOnDemand();
508 // this will flush the old messages if any
509 delete wxLog::SetActiveTarget(new wxLogStderr
);
512 // One last chance for pending objects to be cleaned up
513 wxTheApp
->DeletePendingObjects();
515 wxModule::CleanUpModules();
517 #if wxUSE_WX_RESOURCES
518 wxCleanUpResourceSystem();
521 wxDeleteStockObjects() ;
523 // Destroy all GDI lists, etc.
524 wxDeleteStockLists();
526 delete wxTheColourDatabase
;
527 wxTheColourDatabase
= NULL
;
529 wxBitmap::CleanUpHandlers();
534 wxMacDestroyNotifierTable() ;
535 if (wxWinMacWindowList
)
536 delete wxWinMacWindowList
;
538 delete wxPendingEvents
;
540 delete wxPendingEventsLocker
;
541 // If we don't do the following, we get an apparent memory leak.
542 ((wxEvtHandler
&) wxDefaultValidator
).ClearEventLocker();
545 wxClassInfo::CleanUpClasses();
548 #if __option(profile)
549 ProfilerDump( "\papp.prof" ) ;
557 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
558 // At this point we want to check if there are any memory
559 // blocks that aren't part of the wxDebugContext itself,
560 // as a special case. Then when dumping we need to ignore
561 // wxDebugContext, too.
562 if (wxDebugContext::CountObjectsLeft(TRUE
) > 0)
564 wxLogDebug(wxT("There were memory leaks."));
565 wxDebugContext::Dump();
566 wxDebugContext::PrintStatistics();
568 // wxDebugContext::SetStream(NULL, NULL);
572 // do it as the very last thing because everything else can log messages
573 delete wxLog::SetActiveTarget(NULL
);
576 UMACleanupToolbox() ;
578 ::DisposeRgn(s_macCursorRgn
);
585 int wxEntry( int argc
, char *argv
[] , bool enterLoop
)
588 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
589 // This seems to be necessary since there are 'rogue'
590 // objects present at this point (perhaps global objects?)
591 // Setting a checkpoint will ignore them as far as the
592 // memory checking facility is concerned.
593 // Of course you may argue that memory allocated in globals should be
594 // checked, but this is a reasonable compromise.
595 wxDebugContext::SetCheckpoint();
598 if (!wxApp::Initialize()) {
601 // create the application object or ensure that one already exists
604 // The app may have declared a global application object, but we recommend
605 // the IMPLEMENT_APP macro is used instead, which sets an initializer
606 // function for delayed, dynamic app object construction.
607 wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
608 wxT("No initializer - use IMPLEMENT_APP macro.") );
610 wxTheApp
= (wxApp
*) (*wxApp::GetInitializerFunction()) ();
613 wxCHECK_MSG( wxTheApp
, 0, wxT("You have to define an instance of wxApp!") );
616 argc
= 0 ; // currently we don't support files as parameters
619 wxTheApp
->argc
= argc
;
620 wxTheApp
->argv
= argv
;
622 // GUI-specific initialization, such as creating an app context.
623 wxTheApp
->OnInitGui();
625 // we could try to get the open apple events here to adjust argc and argv better
628 // Here frames insert themselves automatically
629 // into wxTopLevelWindows by getting created
634 if ( wxTheApp
->OnInit() )
638 retValue
= wxTheApp
->OnRun();
641 // We want to initialize, but not run or exit immediately.
644 //else: app initialization failed, so we skipped OnRun()
646 wxWindow
*topWindow
= wxTheApp
->GetTopWindow();
649 // Forcibly delete the window.
650 if ( topWindow
->IsKindOf(CLASSINFO(wxFrame
)) ||
651 topWindow
->IsKindOf(CLASSINFO(wxDialog
)) )
653 topWindow
->Close(TRUE
);
654 wxTheApp
->DeletePendingObjects();
659 wxTheApp
->SetTopWindow(NULL
);
670 // Static member initialization
671 wxAppInitializerFunction
wxAppBase::m_appInitFn
= (wxAppInitializerFunction
) NULL
;
678 m_wantDebugOutput
= TRUE
;
683 m_printMode
= wxPRINT_WINDOWS
;
684 m_exitOnFrameDelete
= TRUE
;
688 bool wxApp::Initialized()
696 int wxApp::MainLoop()
708 // Returns TRUE if more time is needed.
709 bool wxApp::ProcessIdle()
712 event
.SetEventObject(this);
715 return event
.MoreRequested();
718 void wxApp::ExitMainLoop()
723 // Is a message/event pending?
724 bool wxApp::Pending()
728 return EventAvail( everyEvent
, &event
) ;
731 // Dispatch a message.
732 void wxApp::Dispatch()
737 void wxApp::OnIdle(wxIdleEvent
& event
)
739 static bool s_inOnIdle
= FALSE
;
741 // Avoid recursion (via ProcessEvent default case)
748 // 'Garbage' collection of windows deleted with Close().
749 DeletePendingObjects();
751 // flush the logged messages if any
752 wxLog
*pLog
= wxLog::GetActiveTarget();
753 if ( pLog
!= NULL
&& pLog
->HasPendingMessages() )
756 // Send OnIdle events to all windows
757 bool needMore
= SendIdleEvents();
760 event
.RequestMore(TRUE
);
762 // If they are pending events, we must process them: pending events are
763 // either events to the threads other than main or events posted with
764 // wxPostEvent() functions
765 wxMacProcessNotifierAndPendingEvents();
775 // Send idle event to all top-level windows
776 bool wxApp::SendIdleEvents()
778 bool needMore
= FALSE
;
779 wxNode
* node
= wxTopLevelWindows
.First();
782 wxWindow
* win
= (wxWindow
*) node
->Data();
783 if (SendIdleEvents(win
))
791 // Send idle event to window and all subwindows
792 bool wxApp::SendIdleEvents(wxWindow
* win
)
794 bool needMore
= FALSE
;
797 event
.SetEventObject(win
);
798 win
->ProcessEvent(event
);
800 if (event
.MoreRequested())
803 wxNode
* node
= win
->GetChildren().First();
806 wxWindow
* win
= (wxWindow
*) node
->Data();
807 if (SendIdleEvents(win
))
815 void wxApp::DeletePendingObjects()
817 wxNode
*node
= wxPendingDelete
.First();
820 wxObject
*obj
= (wxObject
*)node
->Data();
824 if (wxPendingDelete
.Member(obj
))
827 // Deleting one object may have deleted other pending
828 // objects, so start from beginning of list again.
829 node
= wxPendingDelete
.First();
834 wxApp::GetStdIcon(int which
) const
838 case wxICON_INFORMATION
:
839 return wxIcon("wxICON_INFO");
841 case wxICON_QUESTION
:
842 return wxIcon("wxICON_QUESTION");
844 case wxICON_EXCLAMATION
:
845 return wxIcon("wxICON_WARNING");
848 wxFAIL_MSG(wxT("requested non existent standard icon"));
849 // still fall through
852 return wxIcon("wxICON_ERROR");
858 wxLogError(_("Fatal error: exiting"));
864 void wxApp::OnEndSession(wxCloseEvent
& WXUNUSED(event
))
867 GetTopWindow()->Close(TRUE
);
870 // Default behaviour: close the application with prompts. The
871 // user can veto the close, and therefore the end session.
872 void wxApp::OnQueryEndSession(wxCloseEvent
& event
)
876 if (!GetTopWindow()->Close(!event
.CanVeto()))
881 extern "C" void wxCYield() ;
887 // Yield to other processes
889 static bool gs_inYield
= FALSE
;
895 wxFAIL_MSG( wxT("wxYield called recursively" ) );
905 long sleepTime
= 1 ; //::GetCaretTime();
907 while ( !wxTheApp
->IsExiting() && WaitNextEvent(everyEvent
, &event
,sleepTime
, wxApp::s_macCursorRgn
))
909 wxTheApp
->MacHandleOneEvent( &event
);
910 if ( event
.what
!= kHighLevelEvent
)
911 SetRectRgn( wxApp::s_macCursorRgn
, event
.where
.h
, event
.where
.v
, event
.where
.h
+ 1 , event
.where
.v
+ 1 ) ;
914 wxMacProcessNotifierAndPendingEvents() ;
921 // Yield to incoming messages; but fail silently if recursion is detected.
922 bool wxYieldIfNeeded()
930 // platform specifics
932 void wxApp::MacSuspend( bool convertClipboard
)
934 // we have to deactive the window manually
936 wxWindow
* window
= GetTopWindow() ;
938 window
->MacActivate( MacGetCurrentEvent() , false ) ;
940 s_lastMouseDown
= 0 ;
941 if( convertClipboard
)
943 MacConvertPrivateToPublicScrap() ;
946 UMAHideFloatingWindows() ;
949 void wxApp::MacResume( bool convertClipboard
)
951 s_lastMouseDown
= 0 ;
952 if( convertClipboard
)
954 MacConvertPublicToPrivateScrap() ;
957 UMAShowFloatingWindows() ;
960 void wxApp::MacConvertPrivateToPublicScrap()
964 void wxApp::MacConvertPublicToPrivateScrap()
968 void wxApp::MacDoOneEvent()
972 long sleepTime
= 1 ; // GetCaretTime() / 4 ;
974 if (WaitNextEvent(everyEvent
, &event
,sleepTime
, s_macCursorRgn
))
976 MacHandleOneEvent( &event
);
981 WindowPtr window
= UMAFrontWindow() ;
983 UMAIdleControls( window
) ;
985 wxTheApp
->ProcessIdle() ;
987 if ( event
.what
!= kHighLevelEvent
)
988 SetRectRgn( s_macCursorRgn
, event
.where
.h
, event
.where
.v
, event
.where
.h
+ 1 , event
.where
.v
+ 1 ) ;
992 DeletePendingObjects() ;
993 wxMacProcessNotifierAndPendingEvents() ;
996 void wxApp::MacHandleOneEvent( EventRecord
*ev
)
998 m_macCurrentEvent
= ev
;
1000 wxApp::sm_lastMessageTime
= ev
->when
;
1005 MacHandleMouseDownEvent( ev
) ;
1006 if ( ev
->modifiers
& controlKey
)
1007 s_lastMouseDown
= 2;
1009 s_lastMouseDown
= 1;
1012 if ( s_lastMouseDown
== 2 )
1014 ev
->modifiers
|= controlKey
;
1018 ev
->modifiers
&= ~controlKey
;
1020 MacHandleMouseUpEvent( ev
) ;
1021 s_lastMouseDown
= 0;
1024 MacHandleActivateEvent( ev
) ;
1027 MacHandleUpdateEvent( ev
) ;
1031 MacHandleKeyDownEvent( ev
) ;
1034 MacHandleKeyUpEvent( ev
) ;
1037 MacHandleDiskEvent( ev
) ;
1040 MacHandleOSEvent( ev
) ;
1042 case kHighLevelEvent
:
1043 MacHandleHighLevelEvent( ev
) ;
1048 wxMacProcessNotifierAndPendingEvents() ;
1051 void wxApp::MacHandleHighLevelEvent( EventRecord
*ev
)
1053 ::AEProcessAppleEvent( ev
) ;
1056 bool s_macIsInModalLoop
= false ;
1058 void wxApp::MacHandleMouseDownEvent( EventRecord
*ev
)
1060 wxToolTip::RemoveToolTips() ;
1063 WindowRef frontWindow
= UMAFrontNonFloatingWindow() ;
1064 WindowAttributes frontWindowAttributes
= NULL
;
1066 UMAGetWindowAttributes( frontWindow
, &frontWindowAttributes
) ;
1068 short windowPart
= ::FindWindow(ev
->where
, &window
);
1069 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
1070 if ( wxPendingDelete
.Member(win
) )
1074 GetQDGlobalsScreenBits( &screenBits
);
1079 if ( s_macIsInModalLoop
)
1085 UInt32 menuresult
= MenuSelect(ev
->where
) ;
1086 MacHandleMenuSelect( HiWord( menuresult
) , LoWord( menuresult
) );
1087 s_lastMouseDown
= 0;
1092 SystemClick( ev
, window
) ;
1093 s_lastMouseDown
= 0;
1097 if ( window
!= frontWindow
&& s_macIsInModalLoop
&& !(ev
->modifiers
& cmdKey
) )
1103 DragWindow(window
, ev
->where
, &screenBits
.bounds
);
1108 Point pt
= { 0, 0 } ;
1110 SetPort( GetWindowPort(window
) ) ;
1112 SetPort( (window
) ) ;
1114 SetOrigin( 0 , 0 ) ;
1115 LocalToGlobal( &pt
) ;
1117 win
->SetSize( pt
.h
, pt
.v
, -1 ,
1118 -1 , wxSIZE_USE_EXISTING
);
1120 s_lastMouseDown
= 0;
1124 if (TrackGoAway(window
, ev
->where
))
1129 s_lastMouseDown
= 0;
1133 int growResult
= GrowWindow(window
, ev
->where
, &screenBits
.bounds
);
1134 if (growResult
!= 0)
1136 int newWidth
= LoWord(growResult
);
1137 int newHeight
= HiWord(growResult
);
1138 int oldWidth
, oldHeight
;
1143 win
->GetSize(&oldWidth
, &oldHeight
);
1145 newWidth
= oldWidth
;
1147 newHeight
= oldHeight
;
1148 win
->SetSize( -1, -1, newWidth
, newHeight
, wxSIZE_USE_EXISTING
);
1151 s_lastMouseDown
= 0;
1156 if (TrackBox(window
, ev
->where
, windowPart
))
1158 // TODO setup size event
1159 ZoomWindow( window
, windowPart
, false ) ;
1164 GetWindowPortBounds(window
, &tempRect
) ;
1165 win
->SetSize( -1, -1, tempRect
.right
-tempRect
.left
,
1166 tempRect
.bottom
-tempRect
.top
, wxSIZE_USE_EXISTING
);
1169 s_lastMouseDown
= 0;
1171 case inCollapseBox
:
1172 // TODO setup size event
1173 s_lastMouseDown
= 0;
1181 SetPort( GetWindowPort(window
) ) ;
1183 SetPort( (window
) ) ;
1185 SetOrigin( 0 , 0 ) ;
1188 if ( window
!= frontWindow
&& wxTheApp
->s_captureWindow
== NULL
)
1190 if ( s_macIsInModalLoop
)
1194 else if ( UMAIsWindowFloating( window
) )
1197 win
->MacMouseDown( ev
, windowPart
) ;
1202 win
->MacMouseDown( ev
, windowPart
) ;
1203 UMASelectWindow( window
) ;
1209 win
->MacMouseDown( ev
, windowPart
) ;
1218 void wxApp::MacHandleMouseUpEvent( EventRecord
*ev
)
1222 short windowPart
= ::FindWindow(ev
->where
, &window
);
1232 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
1234 win
->MacMouseUp( ev
, windowPart
) ;
1240 long wxMacTranslateKey(unsigned char key
, unsigned char code
)
1249 retval
= WXK_RETURN
;
1264 retval
= WXK_PAGEUP
;
1267 retval
= WXK_PAGEDOWN
;
1270 retval
= WXK_RETURN
;
1325 retval
= WXK_ESCAPE
;
1331 retval
= WXK_RIGHT
;
1340 retval
= WXK_DELETE
;
1348 void wxApp::MacHandleKeyDownEvent( EventRecord
*ev
)
1350 wxToolTip::RemoveToolTips() ;
1352 UInt32 menuresult
= UMAMenuEvent(ev
) ;
1353 if ( HiWord( menuresult
) )
1355 if ( !s_macIsInModalLoop
)
1356 MacHandleMenuSelect( HiWord( menuresult
) , LoWord( menuresult
) ) ;
1362 keychar
= short(ev
->message
& charCodeMask
);
1363 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1365 wxWindow
* focus
= wxWindow::FindFocus() ;
1368 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
1370 wxKeyEvent
event(wxEVT_KEY_DOWN
);
1371 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1372 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1373 event
.m_altDown
= ev
->modifiers
& optionKey
;
1374 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1375 event
.m_keyCode
= keyval
;
1376 event
.m_x
= ev
->where
.h
;
1377 event
.m_y
= ev
->where
.v
;
1378 event
.m_timeStamp
= ev
->when
;
1379 event
.SetEventObject(focus
);
1380 bool handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1386 wxWindow
*ancestor
= focus
;
1390 int command = ancestor->GetAcceleratorTable()->GetCommand( event );
1393 wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
1394 handled = ancestor->GetEventHandler()->ProcessEvent( command_event );
1397 if (ancestor->m_isFrame)
1399 ancestor = ancestor->GetParent();
1403 #endif // wxUSE_ACCEL
1407 wxKeyEvent
event(wxEVT_CHAR
);
1408 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1409 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1410 event
.m_altDown
= ev
->modifiers
& optionKey
;
1411 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1412 event
.m_keyCode
= keyval
;
1413 event
.m_x
= ev
->where
.h
;
1414 event
.m_y
= ev
->where
.v
;
1415 event
.m_timeStamp
= ev
->when
;
1416 event
.SetEventObject(focus
);
1417 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1420 (keyval
== WXK_TAB
) &&
1421 (!focus
->HasFlag(wxTE_PROCESS_TAB
)) &&
1422 (focus
->GetParent()) &&
1423 (focus
->GetParent()->HasFlag( wxTAB_TRAVERSAL
)) )
1425 wxNavigationKeyEvent new_event
;
1426 new_event
.SetEventObject( focus
);
1427 new_event
.SetDirection( !event
.ShiftDown() );
1428 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
1429 new_event
.SetWindowChange( event
.ControlDown() );
1430 new_event
.SetCurrentFocus( focus
);
1431 handled
= focus
->GetEventHandler()->ProcessEvent( new_event
);
1433 /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
1435 (keyval
== '.' && event
.ControlDown() ) )
1437 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
1438 new_event
.SetEventObject( focus
);
1439 handled
= focus
->GetEventHandler()->ProcessEvent( new_event
);
1445 void wxApp::MacHandleKeyUpEvent( EventRecord
*ev
)
1447 wxToolTip::RemoveToolTips() ;
1449 UInt32 menuresult
= UMAMenuEvent(ev
) ;
1450 if ( HiWord( menuresult
) )
1457 keychar
= short(ev
->message
& charCodeMask
);
1458 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1460 wxWindow
* focus
= wxWindow::FindFocus() ;
1463 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
1465 wxKeyEvent
event(wxEVT_KEY_UP
);
1466 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1467 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1468 event
.m_altDown
= ev
->modifiers
& optionKey
;
1469 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1470 event
.m_keyCode
= keyval
;
1471 event
.m_x
= ev
->where
.h
;
1472 event
.m_y
= ev
->where
.v
;
1473 event
.m_timeStamp
= ev
->when
;
1474 event
.SetEventObject(focus
);
1475 bool handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1480 void wxApp::MacHandleActivateEvent( EventRecord
*ev
)
1482 WindowRef window
= (WindowRef
) ev
->message
;
1485 bool activate
= (ev
->modifiers
& activeFlag
) ;
1486 WindowClass wclass
;
1487 UMAGetWindowClass ( window
, &wclass
) ;
1488 if ( wclass
== kFloatingWindowClass
)
1490 // if it is a floater we activate/deactivate the front non-floating window instead
1491 window
= UMAFrontNonFloatingWindow() ;
1493 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
1495 win
->MacActivate( ev
, activate
) ;
1499 void wxApp::MacHandleUpdateEvent( EventRecord
*ev
)
1501 WindowRef window
= (WindowRef
) ev
->message
;
1502 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
1505 if ( !wxPendingDelete
.Member(win
) )
1506 win
->MacUpdate( ev
) ;
1510 // since there is no way of telling this foreign window to update itself
1511 // we have to invalidate the update region otherwise we keep getting the same
1512 // event over and over again
1513 BeginUpdate( window
) ;
1514 EndUpdate( window
) ;
1518 void wxApp::MacHandleDiskEvent( EventRecord
*ev
)
1520 if ( HiWord( ev
->message
) != noErr
)
1525 SetPt( &point
, 100 , 100 ) ;
1527 err
= DIBadMount( point
, ev
->message
) ;
1528 wxASSERT( err
== noErr
) ;
1533 void wxApp::MacHandleOSEvent( EventRecord
*ev
)
1535 switch( ( ev
->message
& osEvtMessageMask
) >> 24 )
1537 case suspendResumeMessage
:
1539 bool isResuming
= ev
->message
& resumeFlag
;
1541 bool convertClipboard
= ev
->message
& convertClipboardFlag
;
1543 bool convertClipboard
= false;
1545 bool doesActivate
= UMAGetProcessModeDoesActivateOnFGSwitch() ;
1548 WindowRef oldFrontWindow
= NULL
;
1549 WindowRef newFrontWindow
= NULL
;
1551 // in case we don't take care of activating ourselves, we have to synchronize
1552 // our idea of the active window with the process manager's - which it already activated
1554 if ( !doesActivate
)
1555 oldFrontWindow
= UMAFrontNonFloatingWindow() ;
1557 MacResume( convertClipboard
) ;
1559 newFrontWindow
= UMAFrontNonFloatingWindow() ;
1561 if ( oldFrontWindow
)
1563 wxWindow
* win
= wxFindWinFromMacWindow( oldFrontWindow
) ;
1565 win
->MacActivate( ev
, false ) ;
1567 if ( newFrontWindow
)
1569 wxWindow
* win
= wxFindWinFromMacWindow( newFrontWindow
) ;
1571 win
->MacActivate( ev
, true ) ;
1576 MacSuspend( convertClipboard
) ;
1578 // in case this suspending did close an active window, another one might
1579 // have surfaced -> lets deactivate that one
1581 WindowRef newActiveWindow
= UMAGetActiveNonFloatingWindow() ;
1582 if ( newActiveWindow
)
1584 wxWindow
* win
= wxFindWinFromMacWindow( newActiveWindow
) ;
1586 win
->MacActivate( ev
, false ) ;
1591 case mouseMovedMessage
:
1595 wxWindow
* currentMouseWindow
= NULL
;
1597 wxWindow::MacGetWindowFromPoint( wxPoint( ev
->where
.h
, ev
->where
.v
) ,
1598 ¤tMouseWindow
) ;
1600 if ( currentMouseWindow
!= wxWindow::s_lastMouseWindow
)
1602 wxMouseEvent event
;
1604 bool isDown
= !(ev
->modifiers
& btnState
) ; // 1 is for up
1605 bool controlDown
= ev
->modifiers
& controlKey
; // for simulating right mouse
1607 event
.m_leftDown
= isDown
&& !controlDown
;
1608 event
.m_middleDown
= FALSE
;
1609 event
.m_rightDown
= isDown
&& controlDown
;
1610 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1611 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1612 event
.m_altDown
= ev
->modifiers
& optionKey
;
1613 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1614 event
.m_x
= ev
->where
.h
;
1615 event
.m_y
= ev
->where
.v
;
1616 event
.m_timeStamp
= ev
->when
;
1617 event
.SetEventObject(this);
1619 if ( wxWindow::s_lastMouseWindow
)
1621 wxMouseEvent
eventleave(event
) ;
1622 eventleave
.SetEventType( wxEVT_LEAVE_WINDOW
) ;
1623 wxWindow::s_lastMouseWindow
->GetEventHandler()->ProcessEvent(eventleave
);
1625 if ( currentMouseWindow
)
1627 wxMouseEvent
evententer(event
) ;
1628 evententer
.SetEventType( wxEVT_ENTER_WINDOW
) ;
1629 currentMouseWindow
->GetEventHandler()->ProcessEvent(evententer
);
1631 wxWindow::s_lastMouseWindow
= currentMouseWindow
;
1634 short windowPart
= ::FindWindow(ev
->where
, &window
);
1638 // fixes for setting the cursor back from dominic mazzoni
1640 UMAShowArrowCursor();
1643 UMAShowArrowCursor();
1647 if ( s_lastMouseDown
== 0 )
1648 ev
->modifiers
|= btnState
;
1650 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
1652 win
->MacMouseMoved( ev
, windowPart
) ;
1654 UMAShowArrowCursor();
1665 void wxApp::MacHandleMenuSelect( int macMenuId
, int macMenuItemNum
)
1668 return; // no menu item selected
1670 if (macMenuId
== kwxMacAppleMenuId
&& macMenuItemNum
> 1)
1673 Str255 deskAccessoryName
;
1676 GetMenuItemText(GetMenuHandle(kwxMacAppleMenuId
), macMenuItemNum
, deskAccessoryName
);
1677 GetPort(&savedPort
);
1678 OpenDeskAcc(deskAccessoryName
);
1684 wxWindow
* frontwindow
= wxFindWinFromMacWindow( ::FrontWindow() ) ;
1685 if ( frontwindow
&& wxMenuBar::MacGetInstalledMenuBar() )
1686 wxMenuBar::MacGetInstalledMenuBar()->MacMenuSelect( frontwindow
->GetEventHandler() , 0 , macMenuId
, macMenuItemNum
) ;
1692 long wxApp::MacTranslateKey(char key, int mods)
1696 void wxApp::MacAdjustCursor()
1703 wxApp::macAdjustCursor()
1705 if (ev->what != kHighLevelEvent)
1707 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow());
1710 if (!theMacWxFrame->MacAdjustCursor(ev->where))
1711 ::SetCursor(&(qd.arrow));