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>
60 #include <OpenTransport.h>
61 #include <OpenTptInternet.h>
65 extern char *wxBuffer
;
66 extern wxList wxPendingDelete
;
67 extern wxList
*wxWinMacWindowList
;
68 extern wxList
*wxWinMacControlList
;
70 wxApp
*wxTheApp
= NULL
;
72 #if !USE_SHARED_LIBRARY
73 IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
)
74 BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
)
75 EVT_IDLE(wxApp::OnIdle
)
76 EVT_END_SESSION(wxApp::OnEndSession
)
77 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession
)
82 const short kMacMinHeap
= (29 * 1024) ;
83 // platform specific static variables
85 const short kwxMacMenuBarResource
= 1 ;
86 const short kwxMacAppleMenuId
= 1 ;
88 RgnHandle
wxApp::s_macCursorRgn
= NULL
;
89 wxWindow
* wxApp::s_captureWindow
= NULL
;
90 int wxApp::s_lastMouseDown
= 0 ;
91 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 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
99 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
100 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
101 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
104 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
)
106 wxApp
* app
= (wxApp
*) refcon
;
107 return wxTheApp
->MacHandleAEODoc( (AppleEvent
*) event
, reply
) ;
110 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
)
112 wxApp
* app
= (wxApp
*) refcon
;
113 return wxTheApp
->MacHandleAEOApp( (AppleEvent
*) event
, reply
) ;
116 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
)
118 wxApp
* app
= (wxApp
*) refcon
;
119 return wxTheApp
->MacHandleAEPDoc( (AppleEvent
*) event
, reply
) ;
122 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
)
124 wxApp
* app
= (wxApp
*) refcon
;
125 return wxTheApp
->MacHandleAEQuit( (AppleEvent
*) event
, reply
) ;
128 OSErr
wxApp::MacHandleAEODoc(const AppleEvent
*event
, AppleEvent
*reply
)
131 ProcessSerialNumber PSN
;
132 PSN
.highLongOfPSN
= 0 ;
133 PSN
.lowLongOfPSN
= kCurrentProcess
;
134 SetFrontProcess( &PSN
) ;
138 OSErr
wxApp::MacHandleAEPDoc(const AppleEvent
*event
, AppleEvent
*reply
)
143 OSErr
wxApp::MacHandleAEOApp(const AppleEvent
*event
, AppleEvent
*reply
)
148 OSErr
wxApp::MacHandleAEQuit(const AppleEvent
*event
, AppleEvent
*reply
)
150 wxWindow
* win
= GetTopWindow() ;
162 char StringMac
[] = "\x0d\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
163 "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
164 "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf"
165 "\xb1\xb4\xb5\xb6\xbb\xbc\xbe\xbf"
166 "\xc0\xc1\xc2\xc4\xc7\xc8\xc9\xcb\xcc\xcd\xce\xcf"
167 "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xca\xdb" ;
169 char StringANSI
[] = "\x0a\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8"
170 "\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC"
171 "\x86\xBA\xA2\xA3\xA7\x95\xB6\xDF\xAE\xA9\x99\xB4\xA8\xC6\xD8"
172 "\xB1\xA5\xB5\xF0\xAA\xBA\xE6\xF8"
173 "\xBF\xA1\xAC\x83\xAB\xBB\x85\xC0\xC3\xD5\x8C\x9C"
174 "\x96\x97\x93\x94\x91\x92\xF7\xFF\xA0\x80" ;
176 void wxMacConvertFromPC( const char *from
, char *to
, int len
)
181 for( int i
= 0 ; i
< len
; ++ i
)
183 c
= strchr( StringANSI
, *from
) ;
186 *to
= StringMac
[ c
- StringANSI
] ;
194 for( int i
= 0 ; i
< len
; ++ i
)
196 c
= strchr( StringANSI
, *from
) ;
199 *to
= StringMac
[ c
- StringANSI
] ;
211 void wxMacConvertToPC( const char *from
, char *to
, int len
)
216 for( int i
= 0 ; i
< len
; ++ i
)
218 c
= strchr( StringMac
, *from
) ;
221 *to
= StringANSI
[ c
- StringMac
] ;
229 for( int i
= 0 ; i
< len
; ++ i
)
231 c
= strchr( StringMac
, *from
) ;
234 *to
= StringANSI
[ c
- StringMac
] ;
246 void wxMacConvertFromPC( char * p
)
249 int len
= strlen ( p
) ;
251 wxMacConvertFromPC( ptr
, ptr
, len
) ;
254 void wxMacConvertFromPCForControls( char * p
)
257 int len
= strlen ( p
) ;
259 wxMacConvertFromPC( ptr
, ptr
, len
) ;
260 for ( int i
= 0 ; i
< strlen ( ptr
) ; i
++ )
262 if ( ptr
[i
] == '&' && ptr
[i
]+1 != ' ' )
264 memmove( &ptr
[i
] , &ptr
[i
+1] , strlen( &ptr
[i
+1] ) + 1) ;
269 void wxMacConvertFromPC( unsigned char *p
)
271 char *ptr
= (char*) p
+ 1 ;
274 wxMacConvertFromPC( ptr
, ptr
, len
) ;
277 extern char *wxBuffer
;
279 wxString
wxMacMakeMacStringFromPC( const char * p
)
281 const char *ptr
= p
;
282 int len
= strlen ( p
) ;
283 char *buf
= wxBuffer
;
285 if ( len
>= BUFSIZ
+ 512 )
287 buf
= new char [len
+1] ;
290 wxMacConvertFromPC( ptr
, buf
, len
) ;
292 wxString
result( buf
) ;
293 if ( buf
!= wxBuffer
)
299 void wxMacConvertToPC( char * p
)
302 int len
= strlen ( p
) ;
304 wxMacConvertToPC( ptr
, ptr
, len
) ;
307 void wxMacConvertToPC( unsigned char *p
)
309 char *ptr
= (char*) p
+ 1 ;
312 wxMacConvertToPC( ptr
, ptr
, len
) ;
315 wxString
wxMacMakePCStringFromMac( const char * p
)
317 const char *ptr
= p
;
318 int len
= strlen ( p
) ;
319 char *buf
= wxBuffer
;
321 if ( len
>= BUFSIZ
+ 512 )
323 buf
= new char [len
+1] ;
326 wxMacConvertToPC( ptr
, buf
, len
) ;
329 wxString
result( buf
) ;
330 if ( buf
!= wxBuffer
)
335 wxString
wxMacMakeStringFromMacString( const char* from
, bool mac2pcEncoding
)
339 return wxMacMakePCStringFromMac( from
) ;
343 return wxString( from
) ;
347 wxString
wxMacMakeStringFromPascal( StringPtr from
, bool mac2pcEncoding
)
349 // this is safe since a pascal string can never be larger than 256 bytes
351 CopyPascalStringToC( from
, s
) ;
354 return wxMacMakePCStringFromMac( s
) ;
358 return wxString( s
) ;
362 void wxMacStringToPascal( const char * from
, StringPtr to
, bool pc2macEncoding
)
366 CopyCStringToPascal( wxMacMakeMacStringFromPC( from
) , to
) ;
370 CopyCStringToPascal( from
, to
) ;
374 bool wxApp::Initialize()
380 UMAInitToolbox( 4 ) ;
381 SetEventMask( everyEvent
) ;
382 UMAShowWatchCursor() ;
384 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
385 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
, NewAEEventHandlerUPP(AEHandleODoc
) ,
386 (long) wxTheApp
, FALSE
) ;
387 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
, NewAEEventHandlerUPP(AEHandleOApp
) ,
388 (long) wxTheApp
, FALSE
) ;
389 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
, NewAEEventHandlerUPP(AEHandlePDoc
) ,
390 (long) wxTheApp
, FALSE
) ;
391 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
, NewAEEventHandlerUPP(AEHandleQuit
) ,
392 (long) wxTheApp
, FALSE
) ;
394 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
, NewAEEventHandlerProc(AEHandleODoc
) ,
395 (long) wxTheApp
, FALSE
) ;
396 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
, NewAEEventHandlerProc(AEHandleOApp
) ,
397 (long) wxTheApp
, FALSE
) ;
398 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
, NewAEEventHandlerProc(AEHandlePDoc
) ,
399 (long) wxTheApp
, FALSE
) ;
400 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
, NewAEEventHandlerProc(AEHandleQuit
) ,
401 (long) wxTheApp
, FALSE
) ;
406 // test the minimal configuration necessary
412 if (Gestalt(gestaltMachineType
, &theMachine
) != noErr
)
414 error
= kMacSTRWrongMachine
;
416 else if (theMachine
< gestaltMacPlus
)
418 error
= kMacSTRWrongMachine
;
420 else if (Gestalt(gestaltSystemVersion
, &theSystem
) != noErr
)
422 error
= kMacSTROldSystem
;
424 else if ( theSystem
< 0x0860 )
426 error
= kMacSTROldSystem
;
428 else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap
)
430 error
= kMacSTRSmallSize
;
436 if ( !UMAHasAppearance() )
438 error = kMacSTRNoPre8Yet ;
444 // if we encountered any problems so far, give the error code and exit immediately
451 GetIndString(message
, 128, error
);
452 UMAShowArrowCursor() ;
453 ParamText("\pFatal Error", message
, (ConstStr255Param
)"\p", (ConstStr255Param
)"\p");
454 itemHit
= Alert(128, nil
);
459 #if __option(profile)
460 ProfilerInit( collectDetailed
, bestTimeBase
, 20000 , 40 ) ;
464 // now avoid exceptions thrown for new (bad_alloc)
467 std::__throws_bad_alloc
= FALSE
;
470 s_macCursorRgn
= ::NewRgn() ;
473 wxBuffer
= new char[1500];
475 wxBuffer
= new char[BUFSIZ
+ 512];
478 wxClassInfo::InitializeClasses();
481 // wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion);
485 wxPendingEventsLocker
= new wxCriticalSection
;
487 wxTheColourDatabase
= new wxColourDatabase(wxKEY_STRING
);
488 wxTheColourDatabase
->Initialize();
492 // flush the logged messages if any and install a 'safer' log target: the
493 // default one (wxLogGui) can't be used after the resources are freed just
494 // below and the user suppliedo ne might be even more unsafe (using any
495 // wxWindows GUI function is unsafe starting from now)
496 wxLog::DontCreateOnDemand();
498 // this will flush the old messages if any
499 delete wxLog::SetActiveTarget(new wxLogStderr
);
503 wxInitializeStockLists();
504 wxInitializeStockObjects();
506 #if wxUSE_WX_RESOURCES
507 wxInitializeResourceSystem();
510 wxBitmap::InitStandardHandlers();
512 wxModule::RegisterModules();
513 if (!wxModule::InitializeModules()) {
517 wxWinMacWindowList
= new wxList(wxKEY_INTEGER
);
518 wxWinMacControlList
= new wxList(wxKEY_INTEGER
);
520 wxMacCreateNotifierTable() ;
522 UMAShowArrowCursor() ;
527 void wxApp::CleanUp()
530 // flush the logged messages if any and install a 'safer' log target: the
531 // default one (wxLogGui) can't be used after the resources are freed just
532 // below and the user suppliedo ne might be even more unsafe (using any
533 // wxWindows GUI function is unsafe starting from now)
534 wxLog::DontCreateOnDemand();
536 // this will flush the old messages if any
537 delete wxLog::SetActiveTarget(new wxLogStderr
);
540 // One last chance for pending objects to be cleaned up
541 wxTheApp
->DeletePendingObjects();
543 wxModule::CleanUpModules();
545 #if wxUSE_WX_RESOURCES
546 wxCleanUpResourceSystem();
549 wxDeleteStockObjects() ;
551 // Destroy all GDI lists, etc.
552 wxDeleteStockLists();
554 delete wxTheColourDatabase
;
555 wxTheColourDatabase
= NULL
;
557 wxBitmap::CleanUpHandlers();
562 wxMacDestroyNotifierTable() ;
563 if (wxWinMacWindowList
)
564 delete wxWinMacWindowList
;
566 delete wxPendingEvents
;
568 delete wxPendingEventsLocker
;
569 // If we don't do the following, we get an apparent memory leak.
570 ((wxEvtHandler
&) wxDefaultValidator
).ClearEventLocker();
573 wxClassInfo::CleanUpClasses();
576 #if __option(profile)
577 ProfilerDump( "\papp.prof" ) ;
585 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
586 // At this point we want to check if there are any memory
587 // blocks that aren't part of the wxDebugContext itself,
588 // as a special case. Then when dumping we need to ignore
589 // wxDebugContext, too.
590 if (wxDebugContext::CountObjectsLeft(TRUE
) > 0)
592 wxLogDebug(wxT("There were memory leaks."));
593 wxDebugContext::Dump();
594 wxDebugContext::PrintStatistics();
596 // wxDebugContext::SetStream(NULL, NULL);
600 // do it as the very last thing because everything else can log messages
601 delete wxLog::SetActiveTarget(NULL
);
604 UMACleanupToolbox() ;
606 ::DisposeRgn(s_macCursorRgn
);
613 //----------------------------------------------------------------------
615 //----------------------------------------------------------------------
617 int wxEntryStart( int argc
, char *argv
[] )
619 return wxApp::Initialize();
625 return wxTheApp
->OnInitGui();
629 void wxEntryCleanup()
635 int wxEntry( int argc
, char *argv
[] , bool enterLoop
)
638 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
639 // This seems to be necessary since there are 'rogue'
640 // objects present at this point (perhaps global objects?)
641 // Setting a checkpoint will ignore them as far as the
642 // memory checking facility is concerned.
643 // Of course you may argue that memory allocated in globals should be
644 // checked, but this is a reasonable compromise.
645 wxDebugContext::SetCheckpoint();
648 if (!wxEntryStart(argc
, argv
)) {
651 // create the application object or ensure that one already exists
654 // The app may have declared a global application object, but we recommend
655 // the IMPLEMENT_APP macro is used instead, which sets an initializer
656 // function for delayed, dynamic app object construction.
657 wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
658 wxT("No initializer - use IMPLEMENT_APP macro.") );
660 wxTheApp
= (wxApp
*) (*wxApp::GetInitializerFunction()) ();
663 wxCHECK_MSG( wxTheApp
, 0, wxT("You have to define an instance of wxApp!") );
666 argc
= 0 ; // currently we don't support files as parameters
668 // we could try to get the open apple events here to adjust argc and argv better
670 wxTheApp
->argc
= argc
;
671 wxTheApp
->argv
= argv
;
673 // GUI-specific initialization, such as creating an app context.
677 // Here frames insert themselves automatically
678 // into wxTopLevelWindows by getting created
683 if ( wxTheApp
->OnInit() )
687 retValue
= wxTheApp
->OnRun();
690 // We want to initialize, but not run or exit immediately.
693 //else: app initialization failed, so we skipped OnRun()
695 wxWindow
*topWindow
= wxTheApp
->GetTopWindow();
698 // Forcibly delete the window.
699 if ( topWindow
->IsKindOf(CLASSINFO(wxFrame
)) ||
700 topWindow
->IsKindOf(CLASSINFO(wxDialog
)) )
702 topWindow
->Close(TRUE
);
703 wxTheApp
->DeletePendingObjects();
708 wxTheApp
->SetTopWindow(NULL
);
719 // Static member initialization
720 wxAppInitializerFunction
wxAppBase::m_appInitFn
= (wxAppInitializerFunction
) NULL
;
727 m_wantDebugOutput
= TRUE
;
732 m_printMode
= wxPRINT_WINDOWS
;
733 m_exitOnFrameDelete
= TRUE
;
737 bool wxApp::Initialized()
745 int wxApp::MainLoop()
757 // Returns TRUE if more time is needed.
758 bool wxApp::ProcessIdle()
761 event
.SetEventObject(this);
764 return event
.MoreRequested();
767 void wxApp::ExitMainLoop()
772 // Is a message/event pending?
773 bool wxApp::Pending()
777 return EventAvail( everyEvent
, &event
) ;
780 // Dispatch a message.
781 void wxApp::Dispatch()
786 void wxApp::OnIdle(wxIdleEvent
& event
)
788 static bool s_inOnIdle
= FALSE
;
790 // Avoid recursion (via ProcessEvent default case)
797 // 'Garbage' collection of windows deleted with Close().
798 DeletePendingObjects();
800 // flush the logged messages if any
801 wxLog
*pLog
= wxLog::GetActiveTarget();
802 if ( pLog
!= NULL
&& pLog
->HasPendingMessages() )
805 // Send OnIdle events to all windows
806 bool needMore
= SendIdleEvents();
809 event
.RequestMore(TRUE
);
811 // If they are pending events, we must process them: pending events are
812 // either events to the threads other than main or events posted with
813 // wxPostEvent() functions
814 wxMacProcessNotifierAndPendingEvents();
824 // Send idle event to all top-level windows
825 bool wxApp::SendIdleEvents()
827 bool needMore
= FALSE
;
828 wxNode
* node
= wxTopLevelWindows
.First();
831 wxWindow
* win
= (wxWindow
*) node
->Data();
832 if (SendIdleEvents(win
))
840 // Send idle event to window and all subwindows
841 bool wxApp::SendIdleEvents(wxWindow
* win
)
843 bool needMore
= FALSE
;
846 event
.SetEventObject(win
);
847 win
->ProcessEvent(event
);
849 if (event
.MoreRequested())
852 wxNode
* node
= win
->GetChildren().First();
855 wxWindow
* win
= (wxWindow
*) node
->Data();
856 if (SendIdleEvents(win
))
864 void wxApp::DeletePendingObjects()
866 wxNode
*node
= wxPendingDelete
.First();
869 wxObject
*obj
= (wxObject
*)node
->Data();
873 if (wxPendingDelete
.Member(obj
))
876 // Deleting one object may have deleted other pending
877 // objects, so start from beginning of list again.
878 node
= wxPendingDelete
.First();
883 wxApp::GetStdIcon(int which
) const
887 case wxICON_INFORMATION
:
888 return wxIcon("wxICON_INFO");
890 case wxICON_QUESTION
:
891 return wxIcon("wxICON_QUESTION");
893 case wxICON_EXCLAMATION
:
894 return wxIcon("wxICON_WARNING");
897 wxFAIL_MSG(wxT("requested non existent standard icon"));
898 // still fall through
901 return wxIcon("wxICON_ERROR");
907 wxLogError(_("Fatal error: exiting"));
913 void wxApp::OnEndSession(wxCloseEvent
& WXUNUSED(event
))
916 GetTopWindow()->Close(TRUE
);
919 // Default behaviour: close the application with prompts. The
920 // user can veto the close, and therefore the end session.
921 void wxApp::OnQueryEndSession(wxCloseEvent
& event
)
925 if (!GetTopWindow()->Close(!event
.CanVeto()))
930 extern "C" void wxCYield() ;
936 // Yield to other processes
938 bool wxApp::Yield(bool onlyIfNeeded
)
940 static bool s_inYield
= FALSE
;
946 wxFAIL_MSG( wxT("wxYield called recursively" ) );
959 long sleepTime
= 1 ; //::GetCaretTime();
961 while ( !wxTheApp
->IsExiting() && WaitNextEvent(everyEvent
, &event
,sleepTime
, wxApp::s_macCursorRgn
))
963 wxTheApp
->MacHandleOneEvent( &event
);
964 if ( event
.what
!= kHighLevelEvent
)
965 SetRectRgn( wxApp::s_macCursorRgn
, event
.where
.h
, event
.where
.v
, event
.where
.h
+ 1 , event
.where
.v
+ 1 ) ;
968 wxMacProcessNotifierAndPendingEvents() ;
975 // platform specifics
977 void wxApp::MacSuspend( bool convertClipboard
)
979 // we have to deactive the top level windows manually
981 wxNode
* node
= wxTopLevelWindows
.First();
984 wxTopLevelWindow
* win
= (wxTopLevelWindow
*) node
->Data();
985 win
->MacActivate( MacGetCurrentEvent() , false ) ;
990 s_lastMouseDown
= 0 ;
991 if( convertClipboard
)
993 MacConvertPrivateToPublicScrap() ;
996 ::HideFloatingWindows() ;
999 void wxApp::MacResume( bool convertClipboard
)
1001 s_lastMouseDown
= 0 ;
1002 if( convertClipboard
)
1004 MacConvertPublicToPrivateScrap() ;
1007 ::ShowFloatingWindows() ;
1010 void wxApp::MacConvertPrivateToPublicScrap()
1014 void wxApp::MacConvertPublicToPrivateScrap()
1018 void wxApp::MacDoOneEvent()
1022 long sleepTime
= 1; // GetCaretTime() / 4 ;
1024 if (WaitNextEvent(everyEvent
, &event
, sleepTime
, s_macCursorRgn
))
1026 MacHandleOneEvent( &event
);
1031 WindowPtr window
= ::FrontWindow() ;
1033 ::IdleControls( window
) ;
1035 wxTheApp
->ProcessIdle() ;
1037 if ( event
.what
!= kHighLevelEvent
)
1038 SetRectRgn( s_macCursorRgn
, event
.where
.h
, event
.where
.v
, event
.where
.h
+ 1 , event
.where
.v
+ 1 ) ;
1042 DeletePendingObjects() ;
1043 wxMacProcessNotifierAndPendingEvents() ;
1046 void wxApp::MacHandleOneEvent( EventRecord
*ev
)
1048 m_macCurrentEvent
= ev
;
1050 wxApp::sm_lastMessageTime
= ev
->when
;
1055 MacHandleMouseDownEvent( ev
) ;
1056 if ( ev
->modifiers
& controlKey
)
1057 s_lastMouseDown
= 2;
1059 s_lastMouseDown
= 1;
1062 if ( s_lastMouseDown
== 2 )
1064 ev
->modifiers
|= controlKey
;
1068 ev
->modifiers
&= ~controlKey
;
1070 MacHandleMouseUpEvent( ev
) ;
1071 s_lastMouseDown
= 0;
1074 MacHandleActivateEvent( ev
) ;
1077 MacHandleUpdateEvent( ev
) ;
1081 MacHandleKeyDownEvent( ev
) ;
1084 MacHandleKeyUpEvent( ev
) ;
1087 MacHandleDiskEvent( ev
) ;
1090 MacHandleOSEvent( ev
) ;
1092 case kHighLevelEvent
:
1093 MacHandleHighLevelEvent( ev
) ;
1098 wxMacProcessNotifierAndPendingEvents() ;
1101 void wxApp::MacHandleHighLevelEvent( EventRecord
*ev
)
1103 ::AEProcessAppleEvent( ev
) ;
1106 bool s_macIsInModalLoop
= false ;
1108 void wxApp::MacHandleMouseDownEvent( EventRecord
*ev
)
1110 wxToolTip::RemoveToolTips() ;
1113 WindowRef frontWindow
= ::FrontNonFloatingWindow() ;
1114 WindowAttributes frontWindowAttributes
= NULL
;
1116 ::GetWindowAttributes( frontWindow
, &frontWindowAttributes
) ;
1118 short windowPart
= ::FindWindow(ev
->where
, &window
);
1119 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
1120 if ( wxPendingDelete
.Member(win
) )
1124 GetQDGlobalsScreenBits( &screenBits
);
1129 if ( s_macIsInModalLoop
)
1135 UInt32 menuresult
= MenuSelect(ev
->where
) ;
1136 MacHandleMenuSelect( HiWord( menuresult
) , LoWord( menuresult
) );
1137 s_lastMouseDown
= 0;
1142 SystemClick( ev
, window
) ;
1143 s_lastMouseDown
= 0;
1147 if ( window
!= frontWindow
&& s_macIsInModalLoop
&& !(ev
->modifiers
& cmdKey
) )
1153 DragWindow(window
, ev
->where
, &screenBits
.bounds
);
1158 Point pt
= { 0, 0 } ;
1160 SetPort( GetWindowPort(window
) ) ;
1162 SetPort( (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;
1230 SetPort( GetWindowPort(window
) ) ;
1232 SetPort( (window
) ) ;
1236 if ( window
!= frontWindow
&& wxTheApp
->s_captureWindow
== NULL
)
1238 if ( s_macIsInModalLoop
)
1242 else if ( UMAIsWindowFloating( window
) )
1245 win
->MacMouseDown( ev
, windowPart
) ;
1250 win
->MacMouseDown( ev
, windowPart
) ;
1251 ::SelectWindow( window
) ;
1257 win
->MacMouseDown( ev
, windowPart
) ;
1266 void wxApp::MacHandleMouseUpEvent( EventRecord
*ev
)
1270 short windowPart
= ::FindWindow(ev
->where
, &window
);
1280 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
1282 win
->MacMouseUp( ev
, windowPart
) ;
1288 long wxMacTranslateKey(unsigned char key
, unsigned char code
) ;
1289 long wxMacTranslateKey(unsigned char key
, unsigned char code
)
1298 retval
= WXK_RETURN
;
1313 retval
= WXK_PAGEUP
;
1316 retval
= WXK_PAGEDOWN
;
1319 retval
= WXK_RETURN
;
1374 retval
= WXK_ESCAPE
;
1380 retval
= WXK_RIGHT
;
1389 retval
= WXK_DELETE
;
1397 void wxApp::MacHandleKeyDownEvent( EventRecord
*ev
)
1399 wxToolTip::RemoveToolTips() ;
1401 UInt32 menuresult
= UMAMenuEvent(ev
) ;
1402 if ( HiWord( menuresult
) )
1404 if ( !s_macIsInModalLoop
)
1405 MacHandleMenuSelect( HiWord( menuresult
) , LoWord( menuresult
) ) ;
1411 keychar
= short(ev
->message
& charCodeMask
);
1412 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1413 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
1414 bool handled
= false ;
1415 wxWindow
* focus
= wxWindow::FindFocus() ;
1419 wxKeyEvent
event(wxEVT_KEY_DOWN
);
1420 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1421 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1422 event
.m_altDown
= ev
->modifiers
& optionKey
;
1423 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1424 event
.m_keyCode
= keyval
;
1425 event
.m_x
= ev
->where
.h
;
1426 event
.m_y
= ev
->where
.v
;
1427 event
.m_timeStamp
= ev
->when
;
1428 event
.SetEventObject(focus
);
1429 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1435 wxWindow
*ancestor
= focus
;
1439 int command = ancestor->GetAcceleratorTable()->GetCommand( event );
1442 wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
1443 handled = ancestor->GetEventHandler()->ProcessEvent( command_event );
1446 if (ancestor->m_isFrame)
1448 ancestor = ancestor->GetParent();
1452 #endif // wxUSE_ACCEL
1456 wxKeyEvent
event(wxEVT_CHAR
);
1457 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1458 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1459 event
.m_altDown
= ev
->modifiers
& optionKey
;
1460 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1461 event
.m_keyCode
= keyval
;
1462 event
.m_x
= ev
->where
.h
;
1463 event
.m_y
= ev
->where
.v
;
1464 event
.m_timeStamp
= ev
->when
;
1465 event
.SetEventObject(focus
);
1466 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1469 (keyval
== WXK_TAB
) &&
1470 (!focus
->HasFlag(wxTE_PROCESS_TAB
)) &&
1471 (focus
->GetParent()) &&
1472 (focus
->GetParent()->HasFlag( wxTAB_TRAVERSAL
)) )
1474 wxNavigationKeyEvent new_event
;
1475 new_event
.SetEventObject( focus
);
1476 new_event
.SetDirection( !event
.ShiftDown() );
1477 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
1478 new_event
.SetWindowChange( event
.ControlDown() );
1479 new_event
.SetCurrentFocus( focus
);
1480 handled
= focus
->GetEventHandler()->ProcessEvent( new_event
);
1485 // if window is not having a focus still testing for default enter or cancel
1486 // TODO add the UMA version for ActiveNonFloatingWindow
1487 focus
= wxFindWinFromMacWindow( FrontWindow() ) ;
1490 if ( keyval
== WXK_RETURN
)
1492 wxButton
*def
= wxDynamicCast(focus
->GetDefaultItem(),
1494 if ( def
&& def
->IsEnabled() )
1496 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1497 event
.SetEventObject(def
);
1498 def
->Command(event
);
1502 /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
1503 else if (keyval
== WXK_ESCAPE
|| (keyval
== '.' && ev
->modifiers
& cmdKey
) )
1505 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
1506 new_event
.SetEventObject( focus
);
1507 handled
= focus
->GetEventHandler()->ProcessEvent( new_event
);
1514 void wxApp::MacHandleKeyUpEvent( EventRecord
*ev
)
1516 wxToolTip::RemoveToolTips() ;
1518 UInt32 menuresult
= UMAMenuEvent(ev
) ;
1519 if ( HiWord( menuresult
) )
1526 keychar
= short(ev
->message
& charCodeMask
);
1527 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1529 wxWindow
* focus
= wxWindow::FindFocus() ;
1532 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
1534 wxKeyEvent
event(wxEVT_KEY_UP
);
1535 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1536 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1537 event
.m_altDown
= ev
->modifiers
& optionKey
;
1538 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1539 event
.m_keyCode
= keyval
;
1540 event
.m_x
= ev
->where
.h
;
1541 event
.m_y
= ev
->where
.v
;
1542 event
.m_timeStamp
= ev
->when
;
1543 event
.SetEventObject(focus
);
1544 bool handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1549 void wxApp::MacHandleActivateEvent( EventRecord
*ev
)
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( EventRecord
*ev
)
1570 WindowRef window
= (WindowRef
) ev
->message
;
1571 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
1574 if ( !wxPendingDelete
.Member(win
) )
1575 win
->MacUpdate( ev
->when
) ;
1579 // since there is no way of telling this foreign window to update itself
1580 // we have to invalidate the update region otherwise we keep getting the same
1581 // event over and over again
1582 BeginUpdate( window
) ;
1583 EndUpdate( window
) ;
1587 void wxApp::MacHandleDiskEvent( EventRecord
*ev
)
1589 if ( HiWord( ev
->message
) != noErr
)
1594 SetPt( &point
, 100 , 100 ) ;
1596 err
= DIBadMount( point
, ev
->message
) ;
1597 wxASSERT( err
== noErr
) ;
1602 void wxApp::MacHandleOSEvent( EventRecord
*ev
)
1604 switch( ( ev
->message
& osEvtMessageMask
) >> 24 )
1606 case suspendResumeMessage
:
1608 bool isResuming
= ev
->message
& resumeFlag
;
1610 bool convertClipboard
= ev
->message
& convertClipboardFlag
;
1612 bool convertClipboard
= false;
1614 bool doesActivate
= UMAGetProcessModeDoesActivateOnFGSwitch() ;
1617 WindowRef oldFrontWindow
= NULL
;
1618 WindowRef newFrontWindow
= NULL
;
1620 // in case we don't take care of activating ourselves, we have to synchronize
1621 // our idea of the active window with the process manager's - which it already activated
1623 if ( !doesActivate
)
1624 oldFrontWindow
= ::FrontNonFloatingWindow() ;
1626 MacResume( convertClipboard
) ;
1628 newFrontWindow
= ::FrontNonFloatingWindow() ;
1630 if ( oldFrontWindow
)
1632 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( oldFrontWindow
) ;
1634 win
->MacActivate( ev
, false ) ;
1636 if ( newFrontWindow
)
1638 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( newFrontWindow
) ;
1640 win
->MacActivate( ev
, true ) ;
1645 MacSuspend( convertClipboard
) ;
1647 // in case this suspending did close an active window, another one might
1648 // have surfaced -> lets deactivate that one
1650 /* TODO : find out what to do on systems < 10 , perhaps FrontNonFloatingWindow
1651 WindowRef newActiveWindow = ::ActiveNonFloatingWindow() ;
1652 if ( newActiveWindow )
1654 wxWindow* win = wxFindWinFromMacWindow( newActiveWindow ) ;
1656 win->MacActivate( ev , false ) ;
1662 case mouseMovedMessage
:
1666 wxWindow
* currentMouseWindow
= NULL
;
1668 wxWindow::MacGetWindowFromPoint( wxPoint( ev
->where
.h
, ev
->where
.v
) ,
1669 ¤tMouseWindow
) ;
1671 if ( currentMouseWindow
!= wxWindow::s_lastMouseWindow
)
1673 wxMouseEvent event
;
1675 bool isDown
= !(ev
->modifiers
& btnState
) ; // 1 is for up
1676 bool controlDown
= ev
->modifiers
& controlKey
; // for simulating right mouse
1678 event
.m_leftDown
= isDown
&& !controlDown
;
1679 event
.m_middleDown
= FALSE
;
1680 event
.m_rightDown
= isDown
&& controlDown
;
1681 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1682 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1683 event
.m_altDown
= ev
->modifiers
& optionKey
;
1684 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1685 event
.m_x
= ev
->where
.h
;
1686 event
.m_y
= ev
->where
.v
;
1687 event
.m_timeStamp
= ev
->when
;
1688 event
.SetEventObject(this);
1690 if ( wxWindow::s_lastMouseWindow
)
1692 wxMouseEvent
eventleave(event
) ;
1693 eventleave
.SetEventType( wxEVT_LEAVE_WINDOW
) ;
1694 wxWindow::s_lastMouseWindow
->GetEventHandler()->ProcessEvent(eventleave
);
1696 if ( currentMouseWindow
)
1698 wxMouseEvent
evententer(event
) ;
1699 evententer
.SetEventType( wxEVT_ENTER_WINDOW
) ;
1700 currentMouseWindow
->GetEventHandler()->ProcessEvent(evententer
);
1702 wxWindow::s_lastMouseWindow
= currentMouseWindow
;
1705 short windowPart
= ::FindWindow(ev
->where
, &window
);
1709 // fixes for setting the cursor back from dominic mazzoni
1711 UMAShowArrowCursor();
1714 UMAShowArrowCursor();
1718 // if ( s_lastMouseDown == 0 )
1719 // ev->modifiers |= btnState ;
1721 // Calling GetNextEvent with a zero event mask will always
1722 // pass back a null event. However, it fills the EventRecord
1723 // with the state of the modifier keys. This is needed since
1724 // the modifier state returned by WaitForNextEvent often is
1725 // wrong mouse move events. The attempt above to correct this
1726 // didn't always work (under OS X at least).
1729 ::GetNextEvent(0, &tmp
);
1730 ev
->modifiers
= tmp
.modifiers
;
1732 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
1734 win
->MacMouseMoved( ev
, windowPart
) ;
1736 UMAShowArrowCursor();
1747 void wxApp::MacHandleMenuSelect( int macMenuId
, int macMenuItemNum
)
1750 return; // no menu item selected
1752 if (macMenuId
== kwxMacAppleMenuId
&& macMenuItemNum
> 1)
1755 Str255 deskAccessoryName
;
1758 GetMenuItemText(GetMenuHandle(kwxMacAppleMenuId
), macMenuItemNum
, deskAccessoryName
);
1759 GetPort(&savedPort
);
1760 OpenDeskAcc(deskAccessoryName
);
1766 wxWindow
* frontwindow
= wxFindWinFromMacWindow( ::FrontWindow() ) ;
1767 if ( frontwindow
&& wxMenuBar::MacGetInstalledMenuBar() )
1768 wxMenuBar::MacGetInstalledMenuBar()->MacMenuSelect( frontwindow
->GetEventHandler() , 0 , macMenuId
, macMenuItemNum
) ;
1774 long wxApp::MacTranslateKey(char key, int mods)
1778 void wxApp::MacAdjustCursor()
1785 wxApp::macAdjustCursor()
1787 if (ev->what != kHighLevelEvent)
1789 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow());
1792 if (!theMacWxFrame->MacAdjustCursor(ev->where))
1793 ::SetCursor(&(qd.arrow));