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"
34 #include "wx/textctrl.h"
36 #if wxUSE_WX_RESOURCES
37 #include "wx/resource.h"
52 #include "wx/mac/uma.h"
53 #include "wx/mac/macnotfy.h"
57 #include <CoreServices/CoreServices.h>
59 #include <OpenTransport.h>
60 #include <OpenTptInternet.h>
64 extern char *wxBuffer
;
65 extern wxList wxPendingDelete
;
66 extern wxList
*wxWinMacWindowList
;
67 extern wxList
*wxWinMacControlList
;
69 wxApp
*wxTheApp
= NULL
;
71 #if !USE_SHARED_LIBRARY
72 IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
)
73 BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
)
74 EVT_IDLE(wxApp::OnIdle
)
75 EVT_END_SESSION(wxApp::OnEndSession
)
76 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession
)
81 const short kMacMinHeap
= (29 * 1024) ;
82 // platform specific static variables
84 const short kwxMacMenuBarResource
= 1 ;
85 const short kwxMacAppleMenuId
= 1 ;
87 RgnHandle
wxApp::s_macCursorRgn
= NULL
;
88 wxWindow
* wxApp::s_captureWindow
= NULL
;
89 int wxApp::s_lastMouseDown
= 0 ;
90 long wxApp::sm_lastMessageTime
= 0;
92 bool wxApp::s_macDefaultEncodingIsPC
= true ;
93 bool wxApp::s_macSupportPCMenuShortcuts
= true ;
94 long wxApp::s_macAboutMenuItemId
= wxID_ABOUT
;
95 wxString
wxApp::s_macHelpMenuTitleName
= "&Help" ;
97 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
98 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
99 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
100 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
103 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
)
105 wxApp
* app
= (wxApp
*) refcon
;
106 return wxTheApp
->MacHandleAEODoc( (AppleEvent
*) event
, reply
) ;
109 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
)
111 wxApp
* app
= (wxApp
*) refcon
;
112 return wxTheApp
->MacHandleAEOApp( (AppleEvent
*) event
, reply
) ;
115 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
)
117 wxApp
* app
= (wxApp
*) refcon
;
118 return wxTheApp
->MacHandleAEPDoc( (AppleEvent
*) event
, reply
) ;
121 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
)
123 wxApp
* app
= (wxApp
*) refcon
;
124 return wxTheApp
->MacHandleAEQuit( (AppleEvent
*) event
, reply
) ;
127 OSErr
wxApp::MacHandleAEODoc(const AppleEvent
*event
, AppleEvent
*reply
)
130 ProcessSerialNumber PSN
;
131 PSN
.highLongOfPSN
= 0 ;
132 PSN
.lowLongOfPSN
= kCurrentProcess
;
133 SetFrontProcess( &PSN
) ;
137 OSErr
wxApp::MacHandleAEPDoc(const AppleEvent
*event
, AppleEvent
*reply
)
142 OSErr
wxApp::MacHandleAEOApp(const AppleEvent
*event
, AppleEvent
*reply
)
147 OSErr
wxApp::MacHandleAEQuit(const AppleEvent
*event
, AppleEvent
*reply
)
149 wxWindow
* win
= GetTopWindow() ;
161 char StringMac
[] = "\x0d\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
162 "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
163 "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf"
164 "\xb1\xb4\xb5\xb6\xbb\xbc\xbe\xbf"
165 "\xc0\xc1\xc2\xc4\xc7\xc8\xc9\xcb\xcc\xcd\xce\xcf"
166 "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xca\xdb" ;
168 char StringANSI
[] = "\x0a\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8"
169 "\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC"
170 "\x86\xBA\xA2\xA3\xA7\x95\xB6\xDF\xAE\xA9\x99\xB4\xA8\xC6\xD8"
171 "\xB1\xA5\xB5\xF0\xAA\xBA\xE6\xF8"
172 "\xBF\xA1\xAC\x83\xAB\xBB\x85\xC0\xC3\xD5\x8C\x9C"
173 "\x96\x97\x93\x94\x91\x92\xF7\xFF\xA0\x80" ;
175 void wxMacConvertFromPC( const char *from
, char *to
, int len
)
180 for( int i
= 0 ; i
< len
; ++ i
)
182 c
= strchr( StringANSI
, *from
) ;
185 *to
= StringMac
[ c
- StringANSI
] ;
193 for( int i
= 0 ; i
< len
; ++ i
)
195 c
= strchr( StringANSI
, *from
) ;
198 *to
= StringMac
[ c
- StringANSI
] ;
210 void wxMacConvertToPC( const char *from
, char *to
, int len
)
215 for( int i
= 0 ; i
< len
; ++ i
)
217 c
= strchr( StringMac
, *from
) ;
220 *to
= StringANSI
[ c
- StringMac
] ;
228 for( int i
= 0 ; i
< len
; ++ i
)
230 c
= strchr( StringMac
, *from
) ;
233 *to
= StringANSI
[ c
- StringMac
] ;
245 void wxMacConvertFromPC( char * p
)
248 int len
= strlen ( p
) ;
250 wxMacConvertFromPC( ptr
, ptr
, len
) ;
253 void wxMacConvertFromPCForControls( char * p
)
256 int len
= strlen ( p
) ;
258 wxMacConvertFromPC( ptr
, ptr
, len
) ;
259 for ( int i
= 0 ; i
< strlen ( ptr
) ; i
++ )
261 if ( ptr
[i
] == '&' && ptr
[i
]+1 != ' ' )
263 memmove( &ptr
[i
] , &ptr
[i
+1] , strlen( &ptr
[i
+1] ) + 1) ;
268 void wxMacConvertFromPC( unsigned char *p
)
270 char *ptr
= (char*) p
+ 1 ;
273 wxMacConvertFromPC( ptr
, ptr
, len
) ;
276 extern char *wxBuffer
;
278 wxString
wxMacMakeMacStringFromPC( const char * p
)
280 const char *ptr
= p
;
281 int len
= strlen ( p
) ;
282 char *buf
= wxBuffer
;
284 if ( len
>= BUFSIZ
+ 512 )
286 buf
= new char [len
+1] ;
289 wxMacConvertFromPC( ptr
, buf
, len
) ;
291 wxString
result( buf
) ;
292 if ( buf
!= wxBuffer
)
298 void wxMacConvertToPC( char * p
)
301 int len
= strlen ( p
) ;
303 wxMacConvertToPC( ptr
, ptr
, len
) ;
306 void wxMacConvertToPC( unsigned char *p
)
308 char *ptr
= (char*) p
+ 1 ;
311 wxMacConvertToPC( ptr
, ptr
, len
) ;
314 wxString
wxMacMakePCStringFromMac( const char * p
)
316 const char *ptr
= p
;
317 int len
= strlen ( p
) ;
318 char *buf
= wxBuffer
;
320 if ( len
>= BUFSIZ
+ 512 )
322 buf
= new char [len
+1] ;
325 wxMacConvertToPC( ptr
, buf
, len
) ;
328 wxString
result( buf
) ;
329 if ( buf
!= wxBuffer
)
334 wxString
wxMacMakeStringFromMacString( const char* from
, bool mac2pcEncoding
)
338 return wxMacMakePCStringFromMac( from
) ;
342 return wxString( from
) ;
346 wxString
wxMacMakeStringFromPascal( StringPtr from
, bool mac2pcEncoding
)
348 // this is safe since a pascal string can never be larger than 256 bytes
350 CopyPascalStringToC( from
, s
) ;
353 return wxMacMakePCStringFromMac( s
) ;
357 return wxString( s
) ;
361 void wxMacStringToPascal( const char * from
, StringPtr to
, bool pc2macEncoding
)
365 CopyCStringToPascal( wxMacMakeMacStringFromPC( from
) , to
) ;
369 CopyCStringToPascal( from
, to
) ;
373 bool wxApp::Initialize()
379 UMAInitToolbox( 4 ) ;
380 SetEventMask( everyEvent
) ;
381 UMAShowWatchCursor() ;
383 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
384 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
, NewAEEventHandlerUPP(AEHandleODoc
) ,
385 (long) wxTheApp
, FALSE
) ;
386 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
, NewAEEventHandlerUPP(AEHandleOApp
) ,
387 (long) wxTheApp
, FALSE
) ;
388 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
, NewAEEventHandlerUPP(AEHandlePDoc
) ,
389 (long) wxTheApp
, FALSE
) ;
390 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
, NewAEEventHandlerUPP(AEHandleQuit
) ,
391 (long) wxTheApp
, FALSE
) ;
393 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
, NewAEEventHandlerProc(AEHandleODoc
) ,
394 (long) wxTheApp
, FALSE
) ;
395 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
, NewAEEventHandlerProc(AEHandleOApp
) ,
396 (long) wxTheApp
, FALSE
) ;
397 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
, NewAEEventHandlerProc(AEHandlePDoc
) ,
398 (long) wxTheApp
, FALSE
) ;
399 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
, NewAEEventHandlerProc(AEHandleQuit
) ,
400 (long) wxTheApp
, FALSE
) ;
405 // test the minimal configuration necessary
411 if (Gestalt(gestaltMachineType
, &theMachine
) != noErr
)
413 error
= kMacSTRWrongMachine
;
415 else if (theMachine
< gestaltMacPlus
)
417 error
= kMacSTRWrongMachine
;
419 else if (Gestalt(gestaltSystemVersion
, &theSystem
) != noErr
)
421 error
= kMacSTROldSystem
;
423 else if ( theSystem
< 0x0860 )
425 error
= kMacSTROldSystem
;
427 else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap
)
429 error
= kMacSTRSmallSize
;
435 if ( !UMAHasAppearance() )
437 error = kMacSTRNoPre8Yet ;
443 // if we encountered any problems so far, give the error code and exit immediately
450 GetIndString(message
, 128, error
);
451 UMAShowArrowCursor() ;
452 ParamText("\pFatal Error", message
, (ConstStr255Param
)"\p", (ConstStr255Param
)"\p");
453 itemHit
= Alert(128, nil
);
458 #if __option(profile)
459 ProfilerInit( collectDetailed
, bestTimeBase
, 20000 , 40 ) ;
463 // now avoid exceptions thrown for new (bad_alloc)
466 std::__throws_bad_alloc
= FALSE
;
469 s_macCursorRgn
= ::NewRgn() ;
472 wxBuffer
= new char[1500];
474 wxBuffer
= new char[BUFSIZ
+ 512];
477 wxClassInfo::InitializeClasses();
480 // wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion);
484 wxPendingEventsLocker
= new wxCriticalSection
;
486 wxTheColourDatabase
= new wxColourDatabase(wxKEY_STRING
);
487 wxTheColourDatabase
->Initialize();
491 // flush the logged messages if any and install a 'safer' log target: the
492 // default one (wxLogGui) can't be used after the resources are freed just
493 // below and the user suppliedo ne might be even more unsafe (using any
494 // wxWindows GUI function is unsafe starting from now)
495 wxLog::DontCreateOnDemand();
497 // this will flush the old messages if any
498 delete wxLog::SetActiveTarget(new wxLogStderr
);
502 wxInitializeStockLists();
503 wxInitializeStockObjects();
505 #if wxUSE_WX_RESOURCES
506 wxInitializeResourceSystem();
509 wxBitmap::InitStandardHandlers();
511 wxModule::RegisterModules();
512 if (!wxModule::InitializeModules()) {
516 wxWinMacWindowList
= new wxList(wxKEY_INTEGER
);
517 wxWinMacControlList
= new wxList(wxKEY_INTEGER
);
519 wxMacCreateNotifierTable() ;
521 UMAShowArrowCursor() ;
526 void wxApp::CleanUp()
529 // flush the logged messages if any and install a 'safer' log target: the
530 // default one (wxLogGui) can't be used after the resources are freed just
531 // below and the user suppliedo ne might be even more unsafe (using any
532 // wxWindows GUI function is unsafe starting from now)
533 wxLog::DontCreateOnDemand();
535 // this will flush the old messages if any
536 delete wxLog::SetActiveTarget(new wxLogStderr
);
539 // One last chance for pending objects to be cleaned up
540 wxTheApp
->DeletePendingObjects();
542 wxModule::CleanUpModules();
544 #if wxUSE_WX_RESOURCES
545 wxCleanUpResourceSystem();
548 wxDeleteStockObjects() ;
550 // Destroy all GDI lists, etc.
551 wxDeleteStockLists();
553 delete wxTheColourDatabase
;
554 wxTheColourDatabase
= NULL
;
556 wxBitmap::CleanUpHandlers();
561 wxMacDestroyNotifierTable() ;
562 if (wxWinMacWindowList
)
563 delete wxWinMacWindowList
;
565 delete wxPendingEvents
;
567 delete wxPendingEventsLocker
;
568 // If we don't do the following, we get an apparent memory leak.
569 ((wxEvtHandler
&) wxDefaultValidator
).ClearEventLocker();
572 wxClassInfo::CleanUpClasses();
575 #if __option(profile)
576 ProfilerDump( "\papp.prof" ) ;
584 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
585 // At this point we want to check if there are any memory
586 // blocks that aren't part of the wxDebugContext itself,
587 // as a special case. Then when dumping we need to ignore
588 // wxDebugContext, too.
589 if (wxDebugContext::CountObjectsLeft(TRUE
) > 0)
591 wxLogDebug(wxT("There were memory leaks."));
592 wxDebugContext::Dump();
593 wxDebugContext::PrintStatistics();
595 // wxDebugContext::SetStream(NULL, NULL);
599 // do it as the very last thing because everything else can log messages
600 delete wxLog::SetActiveTarget(NULL
);
603 UMACleanupToolbox() ;
605 ::DisposeRgn(s_macCursorRgn
);
612 int wxEntry( int argc
, char *argv
[] , bool enterLoop
)
615 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
616 // This seems to be necessary since there are 'rogue'
617 // objects present at this point (perhaps global objects?)
618 // Setting a checkpoint will ignore them as far as the
619 // memory checking facility is concerned.
620 // Of course you may argue that memory allocated in globals should be
621 // checked, but this is a reasonable compromise.
622 wxDebugContext::SetCheckpoint();
625 if (!wxApp::Initialize()) {
628 // create the application object or ensure that one already exists
631 // The app may have declared a global application object, but we recommend
632 // the IMPLEMENT_APP macro is used instead, which sets an initializer
633 // function for delayed, dynamic app object construction.
634 wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
635 wxT("No initializer - use IMPLEMENT_APP macro.") );
637 wxTheApp
= (wxApp
*) (*wxApp::GetInitializerFunction()) ();
640 wxCHECK_MSG( wxTheApp
, 0, wxT("You have to define an instance of wxApp!") );
643 argc
= 0 ; // currently we don't support files as parameters
646 wxTheApp
->argc
= argc
;
647 wxTheApp
->argv
= argv
;
649 // GUI-specific initialization, such as creating an app context.
650 wxTheApp
->OnInitGui();
652 // we could try to get the open apple events here to adjust argc and argv better
655 // Here frames insert themselves automatically
656 // into wxTopLevelWindows by getting created
661 if ( wxTheApp
->OnInit() )
665 retValue
= wxTheApp
->OnRun();
668 // We want to initialize, but not run or exit immediately.
671 //else: app initialization failed, so we skipped OnRun()
673 wxWindow
*topWindow
= wxTheApp
->GetTopWindow();
676 // Forcibly delete the window.
677 if ( topWindow
->IsKindOf(CLASSINFO(wxFrame
)) ||
678 topWindow
->IsKindOf(CLASSINFO(wxDialog
)) )
680 topWindow
->Close(TRUE
);
681 wxTheApp
->DeletePendingObjects();
686 wxTheApp
->SetTopWindow(NULL
);
697 // Static member initialization
698 wxAppInitializerFunction
wxAppBase::m_appInitFn
= (wxAppInitializerFunction
) NULL
;
705 m_wantDebugOutput
= TRUE
;
710 m_printMode
= wxPRINT_WINDOWS
;
711 m_exitOnFrameDelete
= TRUE
;
715 bool wxApp::Initialized()
723 int wxApp::MainLoop()
735 // Returns TRUE if more time is needed.
736 bool wxApp::ProcessIdle()
739 event
.SetEventObject(this);
742 return event
.MoreRequested();
745 void wxApp::ExitMainLoop()
750 // Is a message/event pending?
751 bool wxApp::Pending()
755 return EventAvail( everyEvent
, &event
) ;
758 // Dispatch a message.
759 void wxApp::Dispatch()
764 void wxApp::OnIdle(wxIdleEvent
& event
)
766 static bool s_inOnIdle
= FALSE
;
768 // Avoid recursion (via ProcessEvent default case)
775 // 'Garbage' collection of windows deleted with Close().
776 DeletePendingObjects();
778 // flush the logged messages if any
779 wxLog
*pLog
= wxLog::GetActiveTarget();
780 if ( pLog
!= NULL
&& pLog
->HasPendingMessages() )
783 // Send OnIdle events to all windows
784 bool needMore
= SendIdleEvents();
787 event
.RequestMore(TRUE
);
789 // If they are pending events, we must process them: pending events are
790 // either events to the threads other than main or events posted with
791 // wxPostEvent() functions
792 wxMacProcessNotifierAndPendingEvents();
802 // Send idle event to all top-level windows
803 bool wxApp::SendIdleEvents()
805 bool needMore
= FALSE
;
806 wxNode
* node
= wxTopLevelWindows
.First();
809 wxWindow
* win
= (wxWindow
*) node
->Data();
810 if (SendIdleEvents(win
))
818 // Send idle event to window and all subwindows
819 bool wxApp::SendIdleEvents(wxWindow
* win
)
821 bool needMore
= FALSE
;
824 event
.SetEventObject(win
);
825 win
->ProcessEvent(event
);
827 if (event
.MoreRequested())
830 wxNode
* node
= win
->GetChildren().First();
833 wxWindow
* win
= (wxWindow
*) node
->Data();
834 if (SendIdleEvents(win
))
842 void wxApp::DeletePendingObjects()
844 wxNode
*node
= wxPendingDelete
.First();
847 wxObject
*obj
= (wxObject
*)node
->Data();
851 if (wxPendingDelete
.Member(obj
))
854 // Deleting one object may have deleted other pending
855 // objects, so start from beginning of list again.
856 node
= wxPendingDelete
.First();
861 wxApp::GetStdIcon(int which
) const
865 case wxICON_INFORMATION
:
866 return wxIcon("wxICON_INFO");
868 case wxICON_QUESTION
:
869 return wxIcon("wxICON_QUESTION");
871 case wxICON_EXCLAMATION
:
872 return wxIcon("wxICON_WARNING");
875 wxFAIL_MSG(wxT("requested non existent standard icon"));
876 // still fall through
879 return wxIcon("wxICON_ERROR");
885 wxLogError(_("Fatal error: exiting"));
891 void wxApp::OnEndSession(wxCloseEvent
& WXUNUSED(event
))
894 GetTopWindow()->Close(TRUE
);
897 // Default behaviour: close the application with prompts. The
898 // user can veto the close, and therefore the end session.
899 void wxApp::OnQueryEndSession(wxCloseEvent
& event
)
903 if (!GetTopWindow()->Close(!event
.CanVeto()))
908 extern "C" void wxCYield() ;
914 // Yield to other processes
916 bool wxApp::Yield(bool onlyIfNeeded
)
918 static bool s_inYield
= FALSE
;
924 wxFAIL_MSG( wxT("wxYield called recursively" ) );
937 long sleepTime
= 1 ; //::GetCaretTime();
939 while ( !wxTheApp
->IsExiting() && WaitNextEvent(everyEvent
, &event
,sleepTime
, wxApp::s_macCursorRgn
))
941 wxTheApp
->MacHandleOneEvent( &event
);
942 if ( event
.what
!= kHighLevelEvent
)
943 SetRectRgn( wxApp::s_macCursorRgn
, event
.where
.h
, event
.where
.v
, event
.where
.h
+ 1 , event
.where
.v
+ 1 ) ;
946 wxMacProcessNotifierAndPendingEvents() ;
953 // platform specifics
955 void wxApp::MacSuspend( bool convertClipboard
)
957 // we have to deactive the window manually
959 wxWindow
* window
= GetTopWindow() ;
961 window
->MacActivate( MacGetCurrentEvent() , false ) ;
963 s_lastMouseDown
= 0 ;
964 if( convertClipboard
)
966 MacConvertPrivateToPublicScrap() ;
969 ::HideFloatingWindows() ;
972 void wxApp::MacResume( bool convertClipboard
)
974 s_lastMouseDown
= 0 ;
975 if( convertClipboard
)
977 MacConvertPublicToPrivateScrap() ;
980 ::ShowFloatingWindows() ;
983 void wxApp::MacConvertPrivateToPublicScrap()
987 void wxApp::MacConvertPublicToPrivateScrap()
991 void wxApp::MacDoOneEvent()
995 long sleepTime
= 1 ; // GetCaretTime() / 4 ;
997 if (WaitNextEvent(everyEvent
, &event
,sleepTime
, s_macCursorRgn
))
999 MacHandleOneEvent( &event
);
1004 WindowPtr window
= ::FrontWindow() ;
1006 ::IdleControls( window
) ;
1008 wxTheApp
->ProcessIdle() ;
1010 if ( event
.what
!= kHighLevelEvent
)
1011 SetRectRgn( s_macCursorRgn
, event
.where
.h
, event
.where
.v
, event
.where
.h
+ 1 , event
.where
.v
+ 1 ) ;
1015 DeletePendingObjects() ;
1016 wxMacProcessNotifierAndPendingEvents() ;
1019 void wxApp::MacHandleOneEvent( EventRecord
*ev
)
1021 m_macCurrentEvent
= ev
;
1023 wxApp::sm_lastMessageTime
= ev
->when
;
1028 MacHandleMouseDownEvent( ev
) ;
1029 if ( ev
->modifiers
& controlKey
)
1030 s_lastMouseDown
= 2;
1032 s_lastMouseDown
= 1;
1035 if ( s_lastMouseDown
== 2 )
1037 ev
->modifiers
|= controlKey
;
1041 ev
->modifiers
&= ~controlKey
;
1043 MacHandleMouseUpEvent( ev
) ;
1044 s_lastMouseDown
= 0;
1047 MacHandleActivateEvent( ev
) ;
1050 MacHandleUpdateEvent( ev
) ;
1054 MacHandleKeyDownEvent( ev
) ;
1057 MacHandleKeyUpEvent( ev
) ;
1060 MacHandleDiskEvent( ev
) ;
1063 MacHandleOSEvent( ev
) ;
1065 case kHighLevelEvent
:
1066 MacHandleHighLevelEvent( ev
) ;
1071 wxMacProcessNotifierAndPendingEvents() ;
1074 void wxApp::MacHandleHighLevelEvent( EventRecord
*ev
)
1076 ::AEProcessAppleEvent( ev
) ;
1079 bool s_macIsInModalLoop
= false ;
1081 void wxApp::MacHandleMouseDownEvent( EventRecord
*ev
)
1083 wxToolTip::RemoveToolTips() ;
1086 WindowRef frontWindow
= ::FrontNonFloatingWindow() ;
1087 WindowAttributes frontWindowAttributes
= NULL
;
1089 ::GetWindowAttributes( frontWindow
, &frontWindowAttributes
) ;
1091 short windowPart
= ::FindWindow(ev
->where
, &window
);
1092 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
1093 if ( wxPendingDelete
.Member(win
) )
1097 GetQDGlobalsScreenBits( &screenBits
);
1102 if ( s_macIsInModalLoop
)
1108 UInt32 menuresult
= MenuSelect(ev
->where
) ;
1109 MacHandleMenuSelect( HiWord( menuresult
) , LoWord( menuresult
) );
1110 s_lastMouseDown
= 0;
1115 SystemClick( ev
, window
) ;
1116 s_lastMouseDown
= 0;
1120 if ( window
!= frontWindow
&& s_macIsInModalLoop
&& !(ev
->modifiers
& cmdKey
) )
1126 DragWindow(window
, ev
->where
, &screenBits
.bounds
);
1131 Point pt
= { 0, 0 } ;
1133 SetPort( GetWindowPort(window
) ) ;
1135 SetPort( (window
) ) ;
1137 SetOrigin( 0 , 0 ) ;
1138 LocalToGlobal( &pt
) ;
1140 win
->SetSize( pt
.h
, pt
.v
, -1 ,
1141 -1 , wxSIZE_USE_EXISTING
);
1143 s_lastMouseDown
= 0;
1147 if (TrackGoAway(window
, ev
->where
))
1152 s_lastMouseDown
= 0;
1156 int growResult
= GrowWindow(window
, ev
->where
, &screenBits
.bounds
);
1157 if (growResult
!= 0)
1159 int newWidth
= LoWord(growResult
);
1160 int newHeight
= HiWord(growResult
);
1161 int oldWidth
, oldHeight
;
1166 win
->GetSize(&oldWidth
, &oldHeight
);
1168 newWidth
= oldWidth
;
1170 newHeight
= oldHeight
;
1171 win
->SetSize( -1, -1, newWidth
, newHeight
, wxSIZE_USE_EXISTING
);
1174 s_lastMouseDown
= 0;
1179 if (TrackBox(window
, ev
->where
, windowPart
))
1181 // TODO setup size event
1182 ZoomWindow( window
, windowPart
, false ) ;
1187 GetWindowPortBounds(window
, &tempRect
) ;
1188 win
->SetSize( -1, -1, tempRect
.right
-tempRect
.left
,
1189 tempRect
.bottom
-tempRect
.top
, wxSIZE_USE_EXISTING
);
1192 s_lastMouseDown
= 0;
1194 case inCollapseBox
:
1195 // TODO setup size event
1196 s_lastMouseDown
= 0;
1204 SetPort( GetWindowPort(window
) ) ;
1206 SetPort( (window
) ) ;
1208 SetOrigin( 0 , 0 ) ;
1211 if ( window
!= frontWindow
&& wxTheApp
->s_captureWindow
== NULL
)
1213 if ( s_macIsInModalLoop
)
1217 else if ( UMAIsWindowFloating( window
) )
1220 win
->MacMouseDown( ev
, windowPart
) ;
1225 win
->MacMouseDown( ev
, windowPart
) ;
1226 ::SelectWindow( window
) ;
1232 win
->MacMouseDown( ev
, windowPart
) ;
1241 void wxApp::MacHandleMouseUpEvent( EventRecord
*ev
)
1245 short windowPart
= ::FindWindow(ev
->where
, &window
);
1255 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
1257 win
->MacMouseUp( ev
, windowPart
) ;
1263 long wxMacTranslateKey(unsigned char key
, unsigned char code
) ;
1264 long wxMacTranslateKey(unsigned char key
, unsigned char code
)
1273 retval
= WXK_RETURN
;
1288 retval
= WXK_PAGEUP
;
1291 retval
= WXK_PAGEDOWN
;
1294 retval
= WXK_RETURN
;
1349 retval
= WXK_ESCAPE
;
1355 retval
= WXK_RIGHT
;
1364 retval
= WXK_DELETE
;
1372 void wxApp::MacHandleKeyDownEvent( EventRecord
*ev
)
1374 wxToolTip::RemoveToolTips() ;
1376 UInt32 menuresult
= UMAMenuEvent(ev
) ;
1377 if ( HiWord( menuresult
) )
1379 if ( !s_macIsInModalLoop
)
1380 MacHandleMenuSelect( HiWord( menuresult
) , LoWord( menuresult
) ) ;
1386 keychar
= short(ev
->message
& charCodeMask
);
1387 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1389 wxWindow
* focus
= wxWindow::FindFocus() ;
1392 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
1394 wxKeyEvent
event(wxEVT_KEY_DOWN
);
1395 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1396 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1397 event
.m_altDown
= ev
->modifiers
& optionKey
;
1398 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1399 event
.m_keyCode
= keyval
;
1400 event
.m_x
= ev
->where
.h
;
1401 event
.m_y
= ev
->where
.v
;
1402 event
.m_timeStamp
= ev
->when
;
1403 event
.SetEventObject(focus
);
1404 bool handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1410 wxWindow
*ancestor
= focus
;
1414 int command = ancestor->GetAcceleratorTable()->GetCommand( event );
1417 wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
1418 handled = ancestor->GetEventHandler()->ProcessEvent( command_event );
1421 if (ancestor->m_isFrame)
1423 ancestor = ancestor->GetParent();
1427 #endif // wxUSE_ACCEL
1431 wxKeyEvent
event(wxEVT_CHAR
);
1432 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1433 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1434 event
.m_altDown
= ev
->modifiers
& optionKey
;
1435 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1436 event
.m_keyCode
= keyval
;
1437 event
.m_x
= ev
->where
.h
;
1438 event
.m_y
= ev
->where
.v
;
1439 event
.m_timeStamp
= ev
->when
;
1440 event
.SetEventObject(focus
);
1441 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1444 (keyval
== WXK_TAB
) &&
1445 (!focus
->HasFlag(wxTE_PROCESS_TAB
)) &&
1446 (focus
->GetParent()) &&
1447 (focus
->GetParent()->HasFlag( wxTAB_TRAVERSAL
)) )
1449 wxNavigationKeyEvent new_event
;
1450 new_event
.SetEventObject( focus
);
1451 new_event
.SetDirection( !event
.ShiftDown() );
1452 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
1453 new_event
.SetWindowChange( event
.ControlDown() );
1454 new_event
.SetCurrentFocus( focus
);
1455 handled
= focus
->GetEventHandler()->ProcessEvent( new_event
);
1457 /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
1459 (keyval
== '.' && event
.ControlDown() ) )
1461 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
1462 new_event
.SetEventObject( focus
);
1463 handled
= focus
->GetEventHandler()->ProcessEvent( new_event
);
1469 void wxApp::MacHandleKeyUpEvent( EventRecord
*ev
)
1471 wxToolTip::RemoveToolTips() ;
1473 UInt32 menuresult
= UMAMenuEvent(ev
) ;
1474 if ( HiWord( menuresult
) )
1481 keychar
= short(ev
->message
& charCodeMask
);
1482 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1484 wxWindow
* focus
= wxWindow::FindFocus() ;
1487 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
1489 wxKeyEvent
event(wxEVT_KEY_UP
);
1490 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1491 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1492 event
.m_altDown
= ev
->modifiers
& optionKey
;
1493 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1494 event
.m_keyCode
= keyval
;
1495 event
.m_x
= ev
->where
.h
;
1496 event
.m_y
= ev
->where
.v
;
1497 event
.m_timeStamp
= ev
->when
;
1498 event
.SetEventObject(focus
);
1499 bool handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1504 void wxApp::MacHandleActivateEvent( EventRecord
*ev
)
1506 WindowRef window
= (WindowRef
) ev
->message
;
1509 bool activate
= (ev
->modifiers
& activeFlag
) ;
1510 WindowClass wclass
;
1511 ::GetWindowClass ( window
, &wclass
) ;
1512 if ( wclass
== kFloatingWindowClass
)
1514 // if it is a floater we activate/deactivate the front non-floating window instead
1515 window
= ::FrontNonFloatingWindow() ;
1517 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
1519 win
->MacActivate( ev
, activate
) ;
1523 void wxApp::MacHandleUpdateEvent( EventRecord
*ev
)
1525 WindowRef window
= (WindowRef
) ev
->message
;
1526 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
1529 if ( !wxPendingDelete
.Member(win
) )
1530 win
->MacUpdate( ev
) ;
1534 // since there is no way of telling this foreign window to update itself
1535 // we have to invalidate the update region otherwise we keep getting the same
1536 // event over and over again
1537 BeginUpdate( window
) ;
1538 EndUpdate( window
) ;
1542 void wxApp::MacHandleDiskEvent( EventRecord
*ev
)
1544 if ( HiWord( ev
->message
) != noErr
)
1549 SetPt( &point
, 100 , 100 ) ;
1551 err
= DIBadMount( point
, ev
->message
) ;
1552 wxASSERT( err
== noErr
) ;
1557 void wxApp::MacHandleOSEvent( EventRecord
*ev
)
1559 switch( ( ev
->message
& osEvtMessageMask
) >> 24 )
1561 case suspendResumeMessage
:
1563 bool isResuming
= ev
->message
& resumeFlag
;
1565 bool convertClipboard
= ev
->message
& convertClipboardFlag
;
1567 bool convertClipboard
= false;
1569 bool doesActivate
= UMAGetProcessModeDoesActivateOnFGSwitch() ;
1572 WindowRef oldFrontWindow
= NULL
;
1573 WindowRef newFrontWindow
= NULL
;
1575 // in case we don't take care of activating ourselves, we have to synchronize
1576 // our idea of the active window with the process manager's - which it already activated
1578 if ( !doesActivate
)
1579 oldFrontWindow
= ::FrontNonFloatingWindow() ;
1581 MacResume( convertClipboard
) ;
1583 newFrontWindow
= ::FrontNonFloatingWindow() ;
1585 if ( oldFrontWindow
)
1587 wxWindow
* win
= wxFindWinFromMacWindow( oldFrontWindow
) ;
1589 win
->MacActivate( ev
, false ) ;
1591 if ( newFrontWindow
)
1593 wxWindow
* win
= wxFindWinFromMacWindow( newFrontWindow
) ;
1595 win
->MacActivate( ev
, true ) ;
1600 MacSuspend( convertClipboard
) ;
1602 // in case this suspending did close an active window, another one might
1603 // have surfaced -> lets deactivate that one
1605 /* TODO : find out what to do on systems < 10 , perhaps FrontNonFloatingWindow
1606 WindowRef newActiveWindow = ::ActiveNonFloatingWindow() ;
1607 if ( newActiveWindow )
1609 wxWindow* win = wxFindWinFromMacWindow( newActiveWindow ) ;
1611 win->MacActivate( ev , false ) ;
1617 case mouseMovedMessage
:
1621 wxWindow
* currentMouseWindow
= NULL
;
1623 wxWindow::MacGetWindowFromPoint( wxPoint( ev
->where
.h
, ev
->where
.v
) ,
1624 ¤tMouseWindow
) ;
1626 if ( currentMouseWindow
!= wxWindow::s_lastMouseWindow
)
1628 wxMouseEvent event
;
1630 bool isDown
= !(ev
->modifiers
& btnState
) ; // 1 is for up
1631 bool controlDown
= ev
->modifiers
& controlKey
; // for simulating right mouse
1633 event
.m_leftDown
= isDown
&& !controlDown
;
1634 event
.m_middleDown
= FALSE
;
1635 event
.m_rightDown
= isDown
&& controlDown
;
1636 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1637 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1638 event
.m_altDown
= ev
->modifiers
& optionKey
;
1639 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1640 event
.m_x
= ev
->where
.h
;
1641 event
.m_y
= ev
->where
.v
;
1642 event
.m_timeStamp
= ev
->when
;
1643 event
.SetEventObject(this);
1645 if ( wxWindow::s_lastMouseWindow
)
1647 wxMouseEvent
eventleave(event
) ;
1648 eventleave
.SetEventType( wxEVT_LEAVE_WINDOW
) ;
1649 wxWindow::s_lastMouseWindow
->GetEventHandler()->ProcessEvent(eventleave
);
1651 if ( currentMouseWindow
)
1653 wxMouseEvent
evententer(event
) ;
1654 evententer
.SetEventType( wxEVT_ENTER_WINDOW
) ;
1655 currentMouseWindow
->GetEventHandler()->ProcessEvent(evententer
);
1657 wxWindow::s_lastMouseWindow
= currentMouseWindow
;
1660 short windowPart
= ::FindWindow(ev
->where
, &window
);
1664 // fixes for setting the cursor back from dominic mazzoni
1666 UMAShowArrowCursor();
1669 UMAShowArrowCursor();
1673 if ( s_lastMouseDown
== 0 )
1674 ev
->modifiers
|= btnState
;
1676 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
1678 win
->MacMouseMoved( ev
, windowPart
) ;
1680 UMAShowArrowCursor();
1691 void wxApp::MacHandleMenuSelect( int macMenuId
, int macMenuItemNum
)
1694 return; // no menu item selected
1696 if (macMenuId
== kwxMacAppleMenuId
&& macMenuItemNum
> 1)
1699 Str255 deskAccessoryName
;
1702 GetMenuItemText(GetMenuHandle(kwxMacAppleMenuId
), macMenuItemNum
, deskAccessoryName
);
1703 GetPort(&savedPort
);
1704 OpenDeskAcc(deskAccessoryName
);
1710 wxWindow
* frontwindow
= wxFindWinFromMacWindow( ::FrontWindow() ) ;
1711 if ( frontwindow
&& wxMenuBar::MacGetInstalledMenuBar() )
1712 wxMenuBar::MacGetInstalledMenuBar()->MacMenuSelect( frontwindow
->GetEventHandler() , 0 , macMenuId
, macMenuItemNum
) ;
1718 long wxApp::MacTranslateKey(char key, int mods)
1722 void wxApp::MacAdjustCursor()
1729 wxApp::macAdjustCursor()
1731 if (ev->what != kHighLevelEvent)
1733 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow());
1736 if (!theMacWxFrame->MacAdjustCursor(ev->where))
1737 ::SetCursor(&(qd.arrow));