1 /////////////////////////////////////////////////////////////////////////////
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "app.h"
18 #include "wx/window.h"
20 #include "wx/button.h"
23 #include "wx/gdicmn.h"
26 #include "wx/cursor.h"
29 #include "wx/palette.h"
31 #include "wx/dialog.h"
32 #include "wx/msgdlg.h"
34 #include "wx/module.h"
35 #include "wx/memory.h"
36 #include "wx/tooltip.h"
37 #include "wx/textctrl.h"
39 #if wxUSE_WX_RESOURCES
40 # include "wx/resource.h"
55 #include "wx/mac/uma.h"
56 #include "wx/mac/macnotfy.h"
59 # include <CoreServices/CoreServices.h>
60 # if defined(WXMAKINGDLL)
61 # include <mach-o/dyld.h>
66 # include <ToolUtils.h>
67 # include <DiskInit.h>
71 extern char *wxBuffer
;
72 extern wxList wxPendingDelete
;
73 extern wxList
*wxWinMacWindowList
;
74 extern wxList
*wxWinMacControlList
;
76 wxApp
*wxTheApp
= NULL
;
78 #if !USE_SHARED_LIBRARY
79 IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
)
80 BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
)
81 EVT_IDLE(wxApp::OnIdle
)
82 EVT_END_SESSION(wxApp::OnEndSession
)
83 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession
)
88 const short kMacMinHeap
= (29 * 1024) ;
89 // platform specific static variables
91 const short kwxMacMenuBarResource
= 1 ;
92 const short kwxMacAppleMenuId
= 1 ;
94 WXHRGN
wxApp::s_macCursorRgn
= NULL
;
95 wxWindow
* wxApp::s_captureWindow
= NULL
;
96 int wxApp::s_lastMouseDown
= 0 ;
97 long wxApp::sm_lastMessageTime
= 0;
98 long wxApp::s_lastModifiers
= 0 ;
101 bool wxApp::s_macDefaultEncodingIsPC
= true ;
102 bool wxApp::s_macSupportPCMenuShortcuts
= true ;
103 long wxApp::s_macAboutMenuItemId
= wxID_ABOUT
;
104 wxString
wxApp::s_macHelpMenuTitleName
= "&Help" ;
106 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
107 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
108 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
109 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
112 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
114 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
115 return wxTheApp
->MacHandleAEODoc( (AppleEvent
*) event
, reply
) ;
118 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
120 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
121 return wxTheApp
->MacHandleAEOApp( (AppleEvent
*) event
, reply
) ;
124 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
126 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
127 return wxTheApp
->MacHandleAEPDoc( (AppleEvent
*) event
, reply
) ;
130 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
132 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
133 return wxTheApp
->MacHandleAEQuit( (AppleEvent
*) event
, reply
) ;
136 short wxApp::MacHandleAEODoc(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
139 ProcessSerialNumber PSN
;
140 PSN
.highLongOfPSN
= 0 ;
141 PSN
.lowLongOfPSN
= kCurrentProcess
;
142 SetFrontProcess( &PSN
) ;
146 short wxApp::MacHandleAEPDoc(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
151 short wxApp::MacHandleAEOApp(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
156 short wxApp::MacHandleAEQuit(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
158 wxWindow
* win
= GetTopWindow() ;
170 char StringMac
[] = "\x0d\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
171 "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
172 "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf"
173 "\xb1\xb4\xb5\xb6\xbb\xbc\xbe\xbf"
174 "\xc0\xc1\xc2\xc4\xc7\xc8\xc9\xcb\xcc\xcd\xce\xcf"
175 "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xca\xdb" ;
177 char StringANSI
[] = "\x0a\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8"
178 "\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC"
179 "\x86\xBA\xA2\xA3\xA7\x95\xB6\xDF\xAE\xA9\x99\xB4\xA8\xC6\xD8"
180 "\xB1\xA5\xB5\xF0\xAA\xBA\xE6\xF8"
181 "\xBF\xA1\xAC\x83\xAB\xBB\x85\xC0\xC3\xD5\x8C\x9C"
182 "\x96\x97\x93\x94\x91\x92\xF7\xFF\xA0\x80" ;
184 void wxMacConvertFromPC( const char *from
, char *to
, int len
)
189 for( int i
= 0 ; i
< len
; ++ i
)
191 c
= strchr( StringANSI
, *from
) ;
194 *to
= StringMac
[ c
- StringANSI
] ;
202 for( int i
= 0 ; i
< len
; ++ i
)
204 c
= strchr( StringANSI
, *from
) ;
207 *to
= StringMac
[ c
- StringANSI
] ;
219 void wxMacConvertToPC( const char *from
, char *to
, int len
)
224 for( int i
= 0 ; i
< len
; ++ i
)
226 c
= strchr( StringMac
, *from
) ;
229 *to
= StringANSI
[ c
- StringMac
] ;
237 for( int i
= 0 ; i
< len
; ++ i
)
239 c
= strchr( StringMac
, *from
) ;
242 *to
= StringANSI
[ c
- StringMac
] ;
254 void wxMacConvertFromPC( char * p
)
257 int len
= strlen ( p
) ;
259 wxMacConvertFromPC( ptr
, ptr
, len
) ;
262 void wxMacConvertFromPCForControls( char * p
)
265 int len
= strlen ( p
) ;
267 wxMacConvertFromPC( ptr
, ptr
, len
) ;
268 for ( unsigned int i
= 0 ; i
< strlen ( ptr
) ; i
++ )
270 if ( ptr
[i
] == '&' && ptr
[i
]+1 != ' ' )
272 memmove( &ptr
[i
] , &ptr
[i
+1] , strlen( &ptr
[i
+1] ) + 1) ;
277 void wxMacConvertFromPC( unsigned char *p
)
279 char *ptr
= (char*) p
+ 1 ;
282 wxMacConvertFromPC( ptr
, ptr
, len
) ;
285 extern char *wxBuffer
;
287 wxString
wxMacMakeMacStringFromPC( const char * p
)
289 const char *ptr
= p
;
290 int len
= strlen ( p
) ;
291 char *buf
= wxBuffer
;
293 if ( len
>= BUFSIZ
+ 512 )
295 buf
= new char [len
+1] ;
298 wxMacConvertFromPC( ptr
, buf
, len
) ;
300 wxString
result( buf
) ;
301 if ( buf
!= wxBuffer
)
307 void wxMacConvertToPC( char * p
)
310 int len
= strlen ( p
) ;
312 wxMacConvertToPC( ptr
, ptr
, len
) ;
315 void wxMacConvertToPC( unsigned char *p
)
317 char *ptr
= (char*) p
+ 1 ;
320 wxMacConvertToPC( ptr
, ptr
, len
) ;
323 wxString
wxMacMakePCStringFromMac( const char * p
)
325 const char *ptr
= p
;
326 int len
= strlen ( p
) ;
327 char *buf
= wxBuffer
;
329 if ( len
>= BUFSIZ
+ 512 )
331 buf
= new char [len
+1] ;
334 wxMacConvertToPC( ptr
, buf
, len
) ;
337 wxString
result( buf
) ;
338 if ( buf
!= wxBuffer
)
343 wxString
wxMacMakeStringFromMacString( const char* from
, bool mac2pcEncoding
)
347 return wxMacMakePCStringFromMac( from
) ;
351 return wxString( from
) ;
355 wxString
wxMacMakeStringFromPascal( StringPtr from
, bool mac2pcEncoding
)
357 // this is safe since a pascal string can never be larger than 256 bytes
359 CopyPascalStringToC( from
, s
) ;
362 return wxMacMakePCStringFromMac( s
) ;
366 return wxString( s
) ;
370 void wxMacStringToPascal( const char * from
, StringPtr to
, bool pc2macEncoding
)
374 CopyCStringToPascal( wxMacMakeMacStringFromPC( from
) , to
) ;
378 CopyCStringToPascal( from
, to
) ;
382 #if defined(WXMAKINGDLL) && !defined(__DARWIN__)
383 // we know it's there ;-)
384 WXIMPORT
char std::__throws_bad_alloc
;
387 bool wxApp::Initialize()
393 UMAInitToolbox( 4 ) ;
394 SetEventMask( everyEvent
) ;
395 UMAShowWatchCursor() ;
397 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
398 // open shared library resources from here since we don't have
399 // __wxinitialize in Mach-O shared libraries
400 wxStAppResource::OpenSharedLibraryResource(NULL
);
403 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
404 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
,
405 NewAEEventHandlerUPP(AEHandleODoc
) ,
406 (long) wxTheApp
, FALSE
) ;
407 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
,
408 NewAEEventHandlerUPP(AEHandleOApp
) ,
409 (long) wxTheApp
, FALSE
) ;
410 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
,
411 NewAEEventHandlerUPP(AEHandlePDoc
) ,
412 (long) wxTheApp
, FALSE
) ;
413 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
,
414 NewAEEventHandlerUPP(AEHandleQuit
) ,
415 (long) wxTheApp
, FALSE
) ;
417 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
,
418 NewAEEventHandlerProc(AEHandleODoc
) ,
419 (long) wxTheApp
, FALSE
) ;
420 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
,
421 NewAEEventHandlerProc(AEHandleOApp
) ,
422 (long) wxTheApp
, FALSE
) ;
423 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
,
424 NewAEEventHandlerProc(AEHandlePDoc
) ,
425 (long) wxTheApp
, FALSE
) ;
426 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
,
427 NewAEEventHandlerProc(AEHandleQuit
) ,
428 (long) wxTheApp
, FALSE
) ;
432 // test the minimal configuration necessary
438 if (Gestalt(gestaltMachineType
, &theMachine
) != noErr
)
440 error
= kMacSTRWrongMachine
;
442 else if (theMachine
< gestaltMacPlus
)
444 error
= kMacSTRWrongMachine
;
446 else if (Gestalt(gestaltSystemVersion
, &theSystem
) != noErr
)
448 error
= kMacSTROldSystem
;
450 else if ( theSystem
< 0x0860 )
452 error
= kMacSTROldSystem
;
454 else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap
)
456 error
= kMacSTRSmallSize
;
462 if ( !UMAHasAppearance() )
464 error = kMacSTRNoPre8Yet ;
470 // if we encountered any problems so far, give the error code and exit immediately
474 wxStAppResource resload
;
478 GetIndString(message
, 128, error
);
479 UMAShowArrowCursor() ;
480 ParamText("\pFatal Error", message
, (ConstStr255Param
)"\p", (ConstStr255Param
)"\p");
481 itemHit
= Alert(128, nil
);
486 # if __option(profile)
487 ProfilerInit( collectDetailed
, bestTimeBase
, 20000 , 40 ) ;
492 // now avoid exceptions thrown for new (bad_alloc)
493 std::__throws_bad_alloc
= FALSE
;
496 s_macCursorRgn
= ::NewRgn() ;
498 wxBuffer
= new char[BUFSIZ
+ 512];
500 wxClassInfo::InitializeClasses();
503 // wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion);
507 wxPendingEventsLocker
= new wxCriticalSection
;
510 wxTheColourDatabase
= new wxColourDatabase(wxKEY_STRING
);
511 wxTheColourDatabase
->Initialize();
515 // flush the logged messages if any and install a 'safer' log target: the
516 // default one (wxLogGui) can't be used after the resources are freed just
517 // below and the user suppliedo ne might be even more unsafe (using any
518 // wxWindows GUI function is unsafe starting from now)
519 wxLog::DontCreateOnDemand();
521 // this will flush the old messages if any
522 delete wxLog::SetActiveTarget(new wxLogStderr
);
526 wxWinMacWindowList
= new wxList(wxKEY_INTEGER
);
527 wxWinMacControlList
= new wxList(wxKEY_INTEGER
);
529 wxInitializeStockLists();
530 wxInitializeStockObjects();
532 #if wxUSE_WX_RESOURCES
533 wxInitializeResourceSystem();
536 wxBitmap::InitStandardHandlers();
538 wxModule::RegisterModules();
539 if (!wxModule::InitializeModules()) {
543 wxMacCreateNotifierTable() ;
546 UMAShowArrowCursor() ;
551 void wxApp::CleanUp()
553 wxToolTip::RemoveToolTips() ;
555 // flush the logged messages if any and install a 'safer' log target: the
556 // default one (wxLogGui) can't be used after the resources are freed just
557 // below and the user suppliedo ne might be even more unsafe (using any
558 // wxWindows GUI function is unsafe starting from now)
559 wxLog::DontCreateOnDemand();
561 // this will flush the old messages if any
562 delete wxLog::SetActiveTarget(new wxLogStderr
);
565 // One last chance for pending objects to be cleaned up
566 wxTheApp
->DeletePendingObjects();
568 wxModule::CleanUpModules();
570 #if wxUSE_WX_RESOURCES
571 wxCleanUpResourceSystem();
574 wxDeleteStockObjects() ;
576 // Destroy all GDI lists, etc.
577 wxDeleteStockLists();
579 delete wxTheColourDatabase
;
580 wxTheColourDatabase
= NULL
;
582 wxBitmap::CleanUpHandlers();
587 wxMacDestroyNotifierTable() ;
588 if (wxWinMacWindowList
) {
589 delete wxWinMacWindowList
;
591 if (wxWinMacControlList
) {
592 delete wxWinMacControlList
;
594 delete wxPendingEvents
;
597 delete wxPendingEventsLocker
;
598 // If we don't do the following, we get an apparent memory leak.
599 ((wxEvtHandler
&) wxDefaultValidator
).ClearEventLocker();
602 wxClassInfo::CleanUpClasses();
605 # if __option(profile)
606 ProfilerDump( "\papp.prof" ) ;
614 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
615 // At this point we want to check if there are any memory
616 // blocks that aren't part of the wxDebugContext itself,
617 // as a special case. Then when dumping we need to ignore
618 // wxDebugContext, too.
619 if (wxDebugContext::CountObjectsLeft(TRUE
) > 0)
621 wxLogDebug(wxT("There were memory leaks."));
622 wxDebugContext::Dump();
623 wxDebugContext::PrintStatistics();
625 // wxDebugContext::SetStream(NULL, NULL);
629 // do it as the very last thing because everything else can log messages
630 delete wxLog::SetActiveTarget(NULL
);
633 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
634 // close shared library resources from here since we don't have
635 // __wxterminate in Mach-O shared libraries
636 wxStAppResource::CloseSharedLibraryResource();
639 UMACleanupToolbox() ;
640 if (s_macCursorRgn
) {
641 ::DisposeRgn((RgnHandle
)s_macCursorRgn
);
649 //----------------------------------------------------------------------
651 //----------------------------------------------------------------------
653 // extern variable for shared library resource id
654 // need to be able to find it with NSLookupAndBindSymbol
655 short gSharedLibraryResource
= kResFileNotOpened
;
657 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
658 CFBundleRef gSharedLibraryBundle
= NULL
;
659 #endif /* WXMAKINGDLL && __DARWIN__ */
661 wxStAppResource::wxStAppResource()
663 m_currentRefNum
= CurResFile() ;
664 if ( gSharedLibraryResource
!= kResFileNotOpened
)
666 UseResFile( gSharedLibraryResource
) ;
670 wxStAppResource::~wxStAppResource()
672 if ( m_currentRefNum
!= kResFileNotOpened
)
674 UseResFile( m_currentRefNum
) ;
678 void wxStAppResource::OpenSharedLibraryResource(const void *initBlock
)
680 gSharedLibraryResource
= kResFileNotOpened
;
683 if ( initBlock
!= NULL
) {
684 const CFragInitBlock
*theInitBlock
= (const CFragInitBlock
*)initBlock
;
685 FSSpec
*fileSpec
= NULL
;
687 if (theInitBlock
->fragLocator
.where
== kDataForkCFragLocator
) {
688 fileSpec
= theInitBlock
->fragLocator
.u
.onDisk
.fileSpec
;
690 else if (theInitBlock
->fragLocator
.where
== kResourceCFragLocator
) {
691 fileSpec
= theInitBlock
->fragLocator
.u
.inSegs
.fileSpec
;
694 if (fileSpec
!= NULL
) {
695 gSharedLibraryResource
= FSpOpenResFile(fileSpec
, fsRdPerm
);
700 // Open the shared library resource file if it is not yet open
703 const char *theLibPath
;
705 gSharedLibraryBundle
= CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWindows"));
706 if (gSharedLibraryBundle
!= NULL
) {
707 // wxWindows has been bundled into a framework
708 // load the framework resources
710 gSharedLibraryResource
= CFBundleOpenBundleResourceMap(gSharedLibraryBundle
);
713 // wxWindows is a simple dynamic shared library
714 // load the resources from the data fork of a separate resource file
719 OSErr theErr
= noErr
;
721 // get the library path
722 theSymbol
= NSLookupAndBindSymbol("_gSharedLibraryResource");
723 theModule
= NSModuleForSymbol(theSymbol
);
724 theLibPath
= NSLibraryNameForModule(theModule
);
726 // allocate copy to replace .dylib.* extension with .rsrc
727 theResPath
= strdup(theLibPath
);
728 if (theResPath
!= NULL
) {
729 theName
= strrchr(theResPath
, '/');
730 if (theName
== NULL
) {
731 // no directory elements in path
732 theName
= theResPath
;
734 // find ".dylib" shared library extension
735 theExt
= strstr(theName
, ".dylib");
736 // overwrite extension with ".rsrc"
737 strcpy(theExt
, ".rsrc");
739 wxLogDebug( theResPath
);
741 theErr
= FSPathMakeRef((UInt8
*) theResPath
, &theResRef
, false);
742 if (theErr
!= noErr
) {
743 // try in current directory (using name only)
744 theErr
= FSPathMakeRef((UInt8
*) theName
, &theResRef
, false);
747 // free duplicated resource file path
750 // open the resource file
751 if (theErr
== noErr
) {
752 theErr
= FSOpenResourceFile( &theResRef
, 0, NULL
, fsRdPerm
,
753 &gSharedLibraryResource
);
757 #endif /* __DARWIN__ */
759 #endif /* WXMAKINGDLL */
762 void wxStAppResource::CloseSharedLibraryResource()
765 // Close the shared library resource file
766 if (gSharedLibraryResource
!= kResFileNotOpened
) {
768 if (gSharedLibraryBundle
!= NULL
) {
769 CFBundleCloseBundleResourceMap(gSharedLibraryBundle
,
770 gSharedLibraryResource
);
771 gSharedLibraryBundle
= NULL
;
774 #endif /* __DARWIN__ */
776 CloseResFile(gSharedLibraryResource
);
778 gSharedLibraryResource
= kResFileNotOpened
;
780 #endif /* WXMAKINGDLL */
783 #if defined(WXMAKINGDLL) && !defined(__DARWIN__)
785 // for shared libraries we have to manually get the correct resource
786 // ref num upon initializing and releasing when terminating, therefore
787 // the __wxinitialize and __wxterminate must be used
790 void __sinit(void); /* (generated by linker) */
791 pascal OSErr
__initialize(const CFragInitBlock
*theInitBlock
);
792 pascal void __terminate(void);
795 pascal OSErr
__wxinitialize(const CFragInitBlock
*theInitBlock
)
797 wxStAppResource::OpenSharedLibraryResource( theInitBlock
) ;
798 return __initialize( theInitBlock
) ;
801 pascal void __wxterminate(void)
803 wxStAppResource::CloseSharedLibraryResource() ;
807 #endif /* WXMAKINGDLL && !__DARWIN__ */
809 int WXDLLEXPORT
wxEntryStart( int WXUNUSED(argc
), char *WXUNUSED(argv
)[] )
811 return wxApp::Initialize();
814 int WXDLLEXPORT
wxEntryInitGui()
816 return wxTheApp
->OnInitGui();
819 void WXDLLEXPORT
wxEntryCleanup()
824 int wxEntry( int argc
, char *argv
[] , bool enterLoop
)
827 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
828 // This seems to be necessary since there are 'rogue'
829 // objects present at this point (perhaps global objects?)
830 // Setting a checkpoint will ignore them as far as the
831 // memory checking facility is concerned.
832 // Of course you may argue that memory allocated in globals should be
833 // checked, but this is a reasonable compromise.
834 wxDebugContext::SetCheckpoint();
837 if (!wxEntryStart(argc
, argv
)) {
840 // create the application object or ensure that one already exists
843 // The app may have declared a global application object, but we recommend
844 // the IMPLEMENT_APP macro is used instead, which sets an initializer
845 // function for delayed, dynamic app object construction.
846 wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
847 wxT("No initializer - use IMPLEMENT_APP macro.") );
849 wxTheApp
= (wxApp
*) (*wxApp::GetInitializerFunction()) ();
852 wxCHECK_MSG( wxTheApp
, 0, wxT("You have to define an instance of wxApp!") );
855 // Mac OS X passes a process serial number command line argument when
856 // the application is launched from the Finder. This argument must be
857 // removed from the command line arguments before being handled by the
858 // application (otherwise applications would need to handle it)
862 strncpy(theArg
, argv
[1], 5);
864 if (strcmp(theArg
, "-psn_") == 0) {
865 // assume the argument is always the only one and remove it
870 argc
= 0 ; // currently we don't support files as parameters
872 // we could try to get the open apple events here to adjust argc and argv better
874 wxTheApp
->argc
= argc
;
875 wxTheApp
->argv
= argv
;
877 // GUI-specific initialization, such as creating an app context.
880 // Here frames insert themselves automatically
881 // into wxTopLevelWindows by getting created
886 if ( wxTheApp
->OnInit() )
890 retValue
= wxTheApp
->OnRun();
893 // We want to initialize, but not run or exit immediately.
896 //else: app initialization failed, so we skipped OnRun()
898 wxWindow
*topWindow
= wxTheApp
->GetTopWindow();
901 // Forcibly delete the window.
902 if ( topWindow
->IsKindOf(CLASSINFO(wxFrame
)) ||
903 topWindow
->IsKindOf(CLASSINFO(wxDialog
)) )
905 topWindow
->Close(TRUE
);
906 wxTheApp
->DeletePendingObjects();
911 wxTheApp
->SetTopWindow(NULL
);
924 bool wxMacConvertEventToRecord( EventRef event
, EventRecord
*rec
)
926 bool converted
= ConvertEventRefToEventRecord( event
,rec
) ;
927 OSStatus err
= noErr
;
930 switch( GetEventClass( event
) )
932 case kEventClassKeyboard
:
935 switch( GetEventKind(event
) )
937 case kEventRawKeyDown
:
938 rec
->what
= keyDown
;
940 case kEventRawKeyRepeat
:
941 rec
->what
= autoKey
;
943 case kEventRawKeyUp
:
946 case kEventRawKeyModifiersChanged
:
947 rec
->what
= nullEvent
;
956 unsigned char charCode
;
958 GetMouse( &rec
->where
) ;
960 err
= GetEventParameter(event
, kEventParamKeyModifiers
, typeUInt32
, NULL
, 4, NULL
, &modifiers
);
961 err
= GetEventParameter(event
, kEventParamKeyCode
, typeUInt32
, NULL
, 4, NULL
, &keyCode
);
962 err
= GetEventParameter(event
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, 1, NULL
, &charCode
);
963 rec
->modifiers
= modifiers
;
964 rec
->message
= (keyCode
<< 8 ) + charCode
;
968 case kEventClassTextInput
:
970 switch( GetEventKind( event
) )
972 case kEventTextInputUnicodeForKeyEvent
:
975 err
= GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
,typeEventRef
,NULL
,sizeof(rawEvent
),NULL
,&rawEvent
) ;
979 unsigned char charCode
;
981 GetMouse( &rec
->where
) ;
982 rec
->what
= keyDown
;
983 err
= GetEventParameter(rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, 4, NULL
, &modifiers
);
984 err
= GetEventParameter(rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, 4, NULL
, &keyCode
);
985 err
= GetEventParameter(rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, 1, NULL
, &charCode
);
986 rec
->modifiers
= modifiers
;
987 rec
->message
= (keyCode
<< 8 ) + charCode
;
1002 pascal OSStatus
wxMacApplicationEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
1004 OSStatus result
= eventNotHandledErr
;
1007 switch ( GetEventClass( event
) )
1009 case kEventClassKeyboard
:
1010 if ( wxMacConvertEventToRecord( event
, &rec
) )
1012 wxTheApp
->MacHandleModifierEvents( &rec
) ;
1013 wxTheApp
->MacHandleOneEvent( &rec
) ;
1017 case kEventClassTextInput
:
1018 if ( wxMacConvertEventToRecord( event
, &rec
) )
1020 wxTheApp
->MacHandleModifierEvents( &rec
) ;
1021 wxTheApp
->MacHandleOneEvent( &rec
) ;
1033 bool wxApp::OnInit()
1035 if ( ! wxAppBase::OnInit() )
1038 #if 0 // TARGET_CARBON
1039 static const EventTypeSpec eventList
[] =
1041 { kEventClassKeyboard
, kEventRawKeyDown
} ,
1042 { kEventClassKeyboard
, kEventRawKeyRepeat
} ,
1043 { kEventClassKeyboard
, kEventRawKeyUp
} ,
1044 { kEventClassKeyboard
, kEventRawKeyModifiersChanged
} ,
1046 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} ,
1049 InstallApplicationEventHandler(NewEventHandlerUPP(wxMacApplicationEventHandler
)
1050 , WXSIZEOF(eventList
), eventList
, this, NULL
);
1054 // Static member initialization
1055 wxAppInitializerFunction
wxAppBase::m_appInitFn
= (wxAppInitializerFunction
) NULL
;
1062 #if WXWIN_COMPATIBILITY_2_2
1063 m_wantDebugOutput
= TRUE
;
1069 m_printMode
= wxPRINT_WINDOWS
;
1073 bool wxApp::Initialized()
1081 int wxApp::MainLoop()
1093 // Returns TRUE if more time is needed.
1094 bool wxApp::ProcessIdle()
1097 event
.SetEventObject(this);
1098 ProcessEvent(event
);
1100 return event
.MoreRequested();
1103 void wxApp::ExitMainLoop()
1105 m_keepGoing
= FALSE
;
1108 // Is a message/event pending?
1109 bool wxApp::Pending()
1113 return EventAvail( everyEvent
, &event
) ;
1116 // Dispatch a message.
1117 void wxApp::Dispatch()
1122 void wxApp::OnIdle(wxIdleEvent
& event
)
1124 static bool s_inOnIdle
= FALSE
;
1126 // Avoid recursion (via ProcessEvent default case)
1133 // 'Garbage' collection of windows deleted with Close().
1134 DeletePendingObjects();
1136 // flush the logged messages if any
1137 wxLog
*pLog
= wxLog::GetActiveTarget();
1138 if ( pLog
!= NULL
&& pLog
->HasPendingMessages() )
1141 // Send OnIdle events to all windows
1142 bool needMore
= SendIdleEvents();
1145 event
.RequestMore(TRUE
);
1147 // If they are pending events, we must process them: pending events are
1148 // either events to the threads other than main or events posted with
1149 // wxPostEvent() functions
1150 wxMacProcessNotifierAndPendingEvents();
1160 // Send idle event to all top-level windows
1161 bool wxApp::SendIdleEvents()
1163 bool needMore
= FALSE
;
1164 wxNode
* node
= wxTopLevelWindows
.First();
1167 wxWindow
* win
= (wxWindow
*) node
->Data();
1168 if (SendIdleEvents(win
))
1171 node
= node
->Next();
1176 // Send idle event to window and all subwindows
1177 bool wxApp::SendIdleEvents(wxWindow
* win
)
1179 bool needMore
= FALSE
;
1182 event
.SetEventObject(win
);
1183 win
->ProcessEvent(event
);
1185 if (event
.MoreRequested())
1188 wxNode
* node
= win
->GetChildren().First();
1191 wxWindow
* win
= (wxWindow
*) node
->Data();
1192 if (SendIdleEvents(win
))
1195 node
= node
->Next();
1200 void wxApp::DeletePendingObjects()
1202 wxNode
*node
= wxPendingDelete
.First();
1205 wxObject
*obj
= (wxObject
*)node
->Data();
1209 if (wxPendingDelete
.Member(obj
))
1212 // Deleting one object may have deleted other pending
1213 // objects, so start from beginning of list again.
1214 node
= wxPendingDelete
.First();
1220 wxLogError(_("Fatal error: exiting"));
1226 void wxApp::OnEndSession(wxCloseEvent
& WXUNUSED(event
))
1229 GetTopWindow()->Close(TRUE
);
1232 // Default behaviour: close the application with prompts. The
1233 // user can veto the close, and therefore the end session.
1234 void wxApp::OnQueryEndSession(wxCloseEvent
& event
)
1238 if (!GetTopWindow()->Close(!event
.CanVeto()))
1243 extern "C" void wxCYield() ;
1249 // Yield to other processes
1251 bool wxApp::Yield(bool onlyIfNeeded
)
1253 static bool s_inYield
= FALSE
;
1257 if ( !onlyIfNeeded
)
1259 wxFAIL_MSG( wxT("wxYield called recursively" ) );
1268 YieldToAnyThread() ;
1272 long sleepTime
= 1 ; //::GetCaretTime();
1274 while ( !wxTheApp
->IsExiting() && WaitNextEvent(everyEvent
, &event
,sleepTime
, (RgnHandle
) wxApp::s_macCursorRgn
))
1276 wxTheApp
->MacHandleModifierEvents( &event
) ;
1277 wxTheApp
->MacHandleOneEvent( &event
);
1278 if ( event
.what
!= kHighLevelEvent
)
1279 SetRectRgn( (RgnHandle
) wxApp::s_macCursorRgn
, event
.where
.h
, event
.where
.v
, event
.where
.h
+ 1 , event
.where
.v
+ 1 ) ;
1281 wxTheApp
->MacHandleModifierEvents( &event
) ;
1283 wxMacProcessNotifierAndPendingEvents() ;
1290 // platform specifics
1292 void wxApp::MacSuspend( bool convertClipboard
)
1294 // we have to deactive the top level windows manually
1296 wxNode
* node
= wxTopLevelWindows
.First();
1299 wxTopLevelWindow
* win
= (wxTopLevelWindow
*) node
->Data();
1300 win
->MacActivate( MacGetCurrentEvent() , false ) ;
1302 node
= node
->Next();
1305 s_lastMouseDown
= 0 ;
1306 if( convertClipboard
)
1308 MacConvertPrivateToPublicScrap() ;
1311 ::HideFloatingWindows() ;
1314 extern wxList wxModalDialogs
;
1316 void wxApp::MacResume( bool convertClipboard
)
1318 s_lastMouseDown
= 0 ;
1319 if( convertClipboard
)
1321 MacConvertPublicToPrivateScrap() ;
1324 ::ShowFloatingWindows() ;
1326 // raise modal dialogs in case a non modal window was selected to activate the app
1328 wxNode
* node
= wxModalDialogs
.First();
1331 wxDialog
* dialog
= (wxDialog
*) node
->Data();
1334 node
= node
->Next();
1338 void wxApp::MacConvertPrivateToPublicScrap()
1342 void wxApp::MacConvertPublicToPrivateScrap()
1346 void wxApp::MacDoOneEvent()
1350 long sleepTime
= 1; // GetCaretTime() / 4 ;
1352 if (WaitNextEvent(everyEvent
, &event
, sleepTime
, (RgnHandle
) s_macCursorRgn
))
1354 MacHandleModifierEvents( &event
) ;
1355 MacHandleOneEvent( &event
);
1359 MacHandleModifierEvents( &event
) ;
1361 WindowPtr window
= ::FrontWindow() ;
1363 ::IdleControls( window
) ;
1365 wxTheApp
->ProcessIdle() ;
1367 if ( event
.what
!= kHighLevelEvent
)
1368 SetRectRgn( (RgnHandle
) s_macCursorRgn
, event
.where
.h
, event
.where
.v
, event
.where
.h
+ 1 , event
.where
.v
+ 1 ) ;
1372 DeletePendingObjects() ;
1373 wxMacProcessNotifierAndPendingEvents() ;
1376 void wxApp::MacHandleModifierEvents( WXEVENTREF evr
)
1378 EventRecord
* ev
= (EventRecord
*) evr
;
1380 if ( ev
->what
== mouseDown
|| ev
->what
== mouseUp
|| ev
->what
== activateEvt
||
1381 ev
->what
== keyDown
|| ev
->what
== autoKey
|| ev
->what
== keyUp
|| ev
->what
== nullEvent
)
1383 // in these cases the modifiers are already correctly setup by carbon
1388 WaitNextEvent( 0 , &nev
, 0 , NULL
) ;
1389 ev
->modifiers
= nev
.modifiers
;
1390 // KeyModifiers unfortunately don't include btnState...
1391 // ev->modifiers = GetCurrentKeyModifiers() ;
1394 if ( ev
->modifiers
!= s_lastModifiers
&& wxWindow::FindFocus() != NULL
)
1396 wxKeyEvent
event(wxEVT_KEY_DOWN
);
1398 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1399 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1400 event
.m_altDown
= ev
->modifiers
& optionKey
;
1401 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1403 event
.m_x
= ev
->where
.h
;
1404 event
.m_y
= ev
->where
.v
;
1405 event
.m_timeStamp
= ev
->when
;
1406 wxWindow
* focus
= wxWindow::FindFocus() ;
1407 event
.SetEventObject(focus
);
1409 if ( (ev
->modifiers
^ s_lastModifiers
) & controlKey
)
1411 event
.m_keyCode
= WXK_CONTROL
;
1412 event
.SetEventType( ( ev
->modifiers
& controlKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
1413 focus
->GetEventHandler()->ProcessEvent( event
) ;
1415 if ( (ev
->modifiers
^ s_lastModifiers
) & shiftKey
)
1417 event
.m_keyCode
= WXK_SHIFT
;
1418 event
.SetEventType( ( ev
->modifiers
& shiftKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
1419 focus
->GetEventHandler()->ProcessEvent( event
) ;
1421 if ( (ev
->modifiers
^ s_lastModifiers
) & optionKey
)
1423 event
.m_keyCode
= WXK_ALT
;
1424 event
.SetEventType( ( ev
->modifiers
& optionKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
1425 focus
->GetEventHandler()->ProcessEvent( event
) ;
1427 s_lastModifiers
= ev
->modifiers
;
1431 void wxApp::MacHandleOneEvent( WXEVENTREF evr
)
1433 EventRecord
* ev
= (EventRecord
*) evr
;
1434 m_macCurrentEvent
= ev
;
1436 wxApp::sm_lastMessageTime
= ev
->when
;
1441 MacHandleMouseDownEvent( ev
) ;
1442 if ( ev
->modifiers
& controlKey
)
1443 s_lastMouseDown
= 2;
1445 s_lastMouseDown
= 1;
1448 if ( s_lastMouseDown
== 2 )
1450 ev
->modifiers
|= controlKey
;
1454 ev
->modifiers
&= ~controlKey
;
1456 MacHandleMouseUpEvent( ev
) ;
1457 s_lastMouseDown
= 0;
1460 MacHandleActivateEvent( ev
) ;
1463 MacHandleUpdateEvent( ev
) ;
1467 MacHandleKeyDownEvent( ev
) ;
1470 MacHandleKeyUpEvent( ev
) ;
1473 MacHandleDiskEvent( ev
) ;
1476 MacHandleOSEvent( ev
) ;
1478 case kHighLevelEvent
:
1479 MacHandleHighLevelEvent( ev
) ;
1484 wxMacProcessNotifierAndPendingEvents() ;
1487 void wxApp::MacHandleHighLevelEvent( WXEVENTREF evr
)
1489 EventRecord
* ev
= (EventRecord
*) evr
;
1490 ::AEProcessAppleEvent( ev
) ;
1493 bool s_macIsInModalLoop
= false ;
1495 void wxApp::MacHandleMouseDownEvent( WXEVENTREF evr
)
1497 EventRecord
* ev
= (EventRecord
*) evr
;
1498 wxToolTip::RemoveToolTips() ;
1501 WindowRef frontWindow
= ::FrontNonFloatingWindow() ;
1502 WindowAttributes frontWindowAttributes
= NULL
;
1504 ::GetWindowAttributes( frontWindow
, &frontWindowAttributes
) ;
1506 short windowPart
= ::FindWindow(ev
->where
, &window
);
1507 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
1508 if ( wxPendingDelete
.Member(win
) )
1512 GetQDGlobalsScreenBits( &screenBits
);
1517 if ( s_macIsInModalLoop
)
1523 UInt32 menuresult
= MenuSelect(ev
->where
) ;
1524 MacHandleMenuSelect( HiWord( menuresult
) , LoWord( menuresult
) );
1525 s_lastMouseDown
= 0;
1530 SystemClick( ev
, window
) ;
1531 s_lastMouseDown
= 0;
1535 if ( window
!= frontWindow
&& s_macIsInModalLoop
&& !(ev
->modifiers
& cmdKey
) )
1541 DragWindow(window
, ev
->where
, &screenBits
.bounds
);
1546 Point pt
= { 0, 0 } ;
1547 SetPortWindowPort(window
) ;
1548 LocalToGlobal( &pt
) ;
1550 win
->SetSize( pt
.h
, pt
.v
, -1 ,
1551 -1 , wxSIZE_USE_EXISTING
);
1553 s_lastMouseDown
= 0;
1557 if (TrackGoAway(window
, ev
->where
))
1562 s_lastMouseDown
= 0;
1566 int growResult
= GrowWindow(window
, ev
->where
, &screenBits
.bounds
);
1567 if (growResult
!= 0)
1569 int newWidth
= LoWord(growResult
);
1570 int newHeight
= HiWord(growResult
);
1571 int oldWidth
, oldHeight
;
1576 win
->GetSize(&oldWidth
, &oldHeight
);
1578 newWidth
= oldWidth
;
1580 newHeight
= oldHeight
;
1581 win
->SetSize( -1, -1 , newWidth
, newHeight
, wxSIZE_USE_EXISTING
);
1584 s_lastMouseDown
= 0;
1589 if (TrackBox(window
, ev
->where
, windowPart
))
1591 // TODO setup size event
1592 ZoomWindow( window
, windowPart
, false ) ;
1598 Point pt
= { 0, 0 } ;
1599 SetPortWindowPort(window
) ;
1600 LocalToGlobal( &pt
) ;
1603 GetWindowPortBounds(window
, &tempRect
) ;
1604 win
->SetSize( pt
.h
, pt
.v
, tempRect
.right
-tempRect
.left
,
1605 tempRect
.bottom
-tempRect
.top
, wxSIZE_USE_EXISTING
);
1608 s_lastMouseDown
= 0;
1610 case inCollapseBox
:
1611 // TODO setup size event
1612 s_lastMouseDown
= 0;
1619 SetPortWindowPort(window
) ;
1622 if ( window
!= frontWindow
&& wxTheApp
->s_captureWindow
== NULL
)
1624 if ( s_macIsInModalLoop
)
1628 else if ( UMAIsWindowFloating( window
) )
1631 win
->MacMouseDown( ev
, windowPart
) ;
1636 win
->MacMouseDown( ev
, windowPart
) ;
1637 ::SelectWindow( window
) ;
1643 win
->MacMouseDown( ev
, windowPart
) ;
1652 void wxApp::MacHandleMouseUpEvent( WXEVENTREF evr
)
1654 EventRecord
* ev
= (EventRecord
*) evr
;
1657 short windowPart
= inNoWindow
;
1658 if ( wxTheApp
->s_captureWindow
)
1660 window
= (WindowRef
) s_captureWindow
->MacGetRootWindow() ;
1661 windowPart
= inContent
;
1665 windowPart
= ::FindWindow(ev
->where
, &window
) ;
1676 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
1678 win
->MacMouseUp( ev
, windowPart
) ;
1684 long wxMacTranslateKey(unsigned char key
, unsigned char code
) ;
1685 long wxMacTranslateKey(unsigned char key
, unsigned char code
)
1690 case kHomeCharCode
:
1693 case kEnterCharCode
:
1694 retval
= WXK_RETURN
;
1699 case kHelpCharCode
:
1702 case kBackspaceCharCode
:
1708 case kPageUpCharCode
:
1709 retval
= WXK_PAGEUP
;
1711 case kPageDownCharCode
:
1712 retval
= WXK_PAGEDOWN
;
1714 case kReturnCharCode
:
1715 retval
= WXK_RETURN
;
1717 case kFunctionKeyCharCode
:
1769 case kEscapeCharCode
:
1770 retval
= WXK_ESCAPE
;
1772 case kLeftArrowCharCode
:
1775 case kRightArrowCharCode
:
1776 retval
= WXK_RIGHT
;
1778 case kUpArrowCharCode
:
1781 case kDownArrowCharCode
:
1784 case kDeleteCharCode
:
1785 retval
= WXK_DELETE
;
1793 void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr
)
1795 EventRecord
* ev
= (EventRecord
*) evr
;
1796 wxToolTip::RemoveToolTips() ;
1798 UInt32 menuresult
= UMAMenuEvent(ev
) ;
1799 if ( HiWord( menuresult
) )
1801 if ( !s_macIsInModalLoop
)
1802 MacHandleMenuSelect( HiWord( menuresult
) , LoWord( menuresult
) ) ;
1806 wxWindow
* focus
= wxWindow::FindFocus() ;
1808 if ( MacSendKeyDownEvent( focus
, ev
->message
, ev
->modifiers
, ev
->when
, ev
->where
.h
, ev
->where
.v
) == false )
1810 // has not been handled -> perform default
1811 wxControl
* control
= wxDynamicCast( focus
, wxControl
) ;
1812 if ( control
&& control
->GetMacControl() != NULL
)
1816 keychar
= short(ev
->message
& charCodeMask
);
1817 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1818 ::HandleControlKey( (ControlHandle
) control
->GetMacControl() , keycode
, keychar
, ev
->modifiers
) ;
1824 bool wxApp::MacSendKeyDownEvent( wxWindow
* focus
, long keymessage
, long modifiers
, long when
, short wherex
, short wherey
)
1831 keychar
= short(keymessage
& charCodeMask
);
1832 keycode
= short(keymessage
& keyCodeMask
) >> 8 ;
1834 if ( modifiers
& ( controlKey
|shiftKey
|optionKey
) )
1836 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
1837 // and look at the character after
1839 UInt32 keyInfo
= KeyTranslate((Ptr
)GetScriptManagerVariable(smKCHRCache
), ( modifiers
& (~(controlKey
|shiftKey
|optionKey
))) | keycode
, &state
);
1840 keychar
= short(keyInfo
& charCodeMask
);
1841 keycode
= short(keyInfo
& keyCodeMask
) >> 8 ;
1843 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
1844 long realkeyval
= keyval
;
1845 if ( keyval
== keychar
)
1847 // we are not on a special character combo -> pass the real os event-value to EVT_CHAR, but not to EVT_KEY (make upper first)
1848 realkeyval
= short(keymessage
& charCodeMask
) ;
1849 keyval
= wxToupper( keyval
) ;
1852 wxKeyEvent
event(wxEVT_KEY_DOWN
);
1853 bool handled
= false ;
1854 event
.m_shiftDown
= modifiers
& shiftKey
;
1855 event
.m_controlDown
= modifiers
& controlKey
;
1856 event
.m_altDown
= modifiers
& optionKey
;
1857 event
.m_metaDown
= modifiers
& cmdKey
;
1858 event
.m_keyCode
= keyval
;
1862 event
.m_timeStamp
= when
;
1863 event
.SetEventObject(focus
);
1864 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1865 if ( handled
&& event
.GetSkipped() )
1872 wxWindow
*ancestor
= focus
;
1875 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
1878 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
1879 handled
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
1882 if (ancestor
->IsTopLevel())
1884 ancestor
= ancestor
->GetParent();
1887 #endif // wxUSE_ACCEL
1891 event
.Skip( FALSE
) ;
1892 event
.SetEventType( wxEVT_CHAR
) ;
1894 event
.m_keyCode
= realkeyval
;
1896 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1897 if ( handled
&& event
.GetSkipped() )
1901 (keyval
== WXK_TAB
) &&
1902 // CS: copied the change below from wxGTK
1903 // VZ: testing for wxTE_PROCESS_TAB shouldn't be done here the control may
1904 // have this style, yet choose not to process this particular TAB in which
1905 // case TAB must still work as a navigational character
1907 (!focus
->HasFlag(wxTE_PROCESS_TAB
)) &&
1909 (focus
->GetParent()) &&
1910 (focus
->GetParent()->HasFlag( wxTAB_TRAVERSAL
)) )
1912 wxNavigationKeyEvent new_event
;
1913 new_event
.SetEventObject( focus
);
1914 new_event
.SetDirection( !event
.ShiftDown() );
1915 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
1916 new_event
.SetWindowChange( event
.ControlDown() );
1917 new_event
.SetCurrentFocus( focus
);
1918 handled
= focus
->GetEventHandler()->ProcessEvent( new_event
);
1919 if ( handled
&& new_event
.GetSkipped() )
1922 // backdoor handler for default return and command escape
1923 if ( !handled
&& (!focus
->IsKindOf(CLASSINFO(wxControl
) ) || !focus
->MacCanFocus() ) )
1925 // if window is not having a focus still testing for default enter or cancel
1926 // TODO add the UMA version for ActiveNonFloatingWindow
1927 wxWindow
* focus
= wxFindWinFromMacWindow( FrontWindow() ) ;
1930 if ( keyval
== WXK_RETURN
)
1932 wxButton
*def
= wxDynamicCast(focus
->GetDefaultItem(),
1934 if ( def
&& def
->IsEnabled() )
1936 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1937 event
.SetEventObject(def
);
1938 def
->Command(event
);
1942 /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
1943 else if (keyval
== WXK_ESCAPE
|| (keyval
== '.' && modifiers
& cmdKey
) )
1945 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
1946 new_event
.SetEventObject( focus
);
1947 handled
= focus
->GetEventHandler()->ProcessEvent( new_event
);
1955 void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr
)
1957 EventRecord
* ev
= (EventRecord
*) evr
;
1958 wxToolTip::RemoveToolTips() ;
1960 UInt32 menuresult
= UMAMenuEvent(ev
) ;
1961 if ( HiWord( menuresult
) )
1966 MacSendKeyUpEvent( wxWindow::FindFocus() , ev
->message
, ev
->modifiers
, ev
->when
, ev
->where
.h
, ev
->where
.v
) ;
1970 bool wxApp::MacSendKeyUpEvent( wxWindow
* focus
, long keymessage
, long modifiers
, long when
, short wherex
, short wherey
)
1977 keychar
= short(keymessage
& charCodeMask
);
1978 keycode
= short(keymessage
& keyCodeMask
) >> 8 ;
1979 if ( modifiers
& ( controlKey
|shiftKey
|optionKey
) )
1981 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
1982 // and look at the character after
1984 UInt32 keyInfo
= KeyTranslate((Ptr
)GetScriptManagerVariable(smKCHRCache
), ( modifiers
& (~(controlKey
|shiftKey
|optionKey
))) | keycode
, &state
);
1985 keychar
= short(keyInfo
& charCodeMask
);
1986 keycode
= short(keyInfo
& keyCodeMask
) >> 8 ;
1988 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
1990 if ( keyval
== keychar
)
1992 keyval
= wxToupper( keyval
) ;
1994 bool handled
= false ;
1996 wxKeyEvent
event(wxEVT_KEY_UP
);
1997 event
.m_shiftDown
= modifiers
& shiftKey
;
1998 event
.m_controlDown
= modifiers
& controlKey
;
1999 event
.m_altDown
= modifiers
& optionKey
;
2000 event
.m_metaDown
= modifiers
& cmdKey
;
2001 event
.m_keyCode
= keyval
;
2005 event
.m_timeStamp
= when
;
2006 event
.SetEventObject(focus
);
2007 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
2011 void wxApp::MacHandleActivateEvent( WXEVENTREF evr
)
2013 EventRecord
* ev
= (EventRecord
*) evr
;
2014 WindowRef window
= (WindowRef
) ev
->message
;
2017 bool activate
= (ev
->modifiers
& activeFlag
) ;
2018 WindowClass wclass
;
2019 ::GetWindowClass ( window
, &wclass
) ;
2020 if ( wclass
== kFloatingWindowClass
)
2022 // if it is a floater we activate/deactivate the front non-floating window instead
2023 window
= ::FrontNonFloatingWindow() ;
2025 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
2027 win
->MacActivate( ev
, activate
) ;
2031 void wxApp::MacHandleUpdateEvent( WXEVENTREF evr
)
2033 EventRecord
* ev
= (EventRecord
*) evr
;
2034 WindowRef window
= (WindowRef
) ev
->message
;
2035 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
2038 if ( !wxPendingDelete
.Member(win
) )
2039 win
->MacUpdate( ev
->when
) ;
2043 // since there is no way of telling this foreign window to update itself
2044 // we have to invalidate the update region otherwise we keep getting the same
2045 // event over and over again
2046 BeginUpdate( window
) ;
2047 EndUpdate( window
) ;
2051 void wxApp::MacHandleDiskEvent( WXEVENTREF evr
)
2053 EventRecord
* ev
= (EventRecord
*) evr
;
2054 if ( HiWord( ev
->message
) != noErr
)
2059 SetPt( &point
, 100 , 100 ) ;
2061 err
= DIBadMount( point
, ev
->message
) ;
2062 wxASSERT( err
== noErr
) ;
2067 void wxApp::MacHandleOSEvent( WXEVENTREF evr
)
2069 EventRecord
* ev
= (EventRecord
*) evr
;
2070 switch( ( ev
->message
& osEvtMessageMask
) >> 24 )
2072 case suspendResumeMessage
:
2074 bool isResuming
= ev
->message
& resumeFlag
;
2076 bool convertClipboard
= ev
->message
& convertClipboardFlag
;
2078 bool convertClipboard
= false;
2080 bool doesActivate
= UMAGetProcessModeDoesActivateOnFGSwitch() ;
2083 WindowRef oldFrontWindow
= NULL
;
2084 WindowRef newFrontWindow
= NULL
;
2086 // in case we don't take care of activating ourselves, we have to synchronize
2087 // our idea of the active window with the process manager's - which it already activated
2089 if ( !doesActivate
)
2090 oldFrontWindow
= ::FrontNonFloatingWindow() ;
2092 MacResume( convertClipboard
) ;
2094 newFrontWindow
= ::FrontNonFloatingWindow() ;
2096 if ( oldFrontWindow
)
2098 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( oldFrontWindow
) ;
2100 win
->MacActivate( ev
, false ) ;
2102 if ( newFrontWindow
)
2104 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( newFrontWindow
) ;
2106 win
->MacActivate( ev
, true ) ;
2111 MacSuspend( convertClipboard
) ;
2113 // in case this suspending did close an active window, another one might
2114 // have surfaced -> lets deactivate that one
2116 /* TODO : find out what to do on systems < 10 , perhaps FrontNonFloatingWindow
2117 WindowRef newActiveWindow = ::ActiveNonFloatingWindow() ;
2118 if ( newActiveWindow )
2120 wxWindow* win = wxFindWinFromMacWindow( newActiveWindow ) ;
2122 win->MacActivate( ev , false ) ;
2128 case mouseMovedMessage
:
2132 wxWindow
* currentMouseWindow
= NULL
;
2134 if (s_captureWindow
)
2136 currentMouseWindow
= s_captureWindow
;
2140 wxWindow::MacGetWindowFromPoint( wxPoint( ev
->where
.h
, ev
->where
.v
) ,
2141 ¤tMouseWindow
) ;
2144 if ( currentMouseWindow
!= wxWindow::s_lastMouseWindow
)
2146 wxMouseEvent event
;
2148 bool isDown
= !(ev
->modifiers
& btnState
) ; // 1 is for up
2149 bool controlDown
= ev
->modifiers
& controlKey
; // for simulating right mouse
2151 event
.m_leftDown
= isDown
&& !controlDown
;
2152 event
.m_middleDown
= FALSE
;
2153 event
.m_rightDown
= isDown
&& controlDown
;
2154 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
2155 event
.m_controlDown
= ev
->modifiers
& controlKey
;
2156 event
.m_altDown
= ev
->modifiers
& optionKey
;
2157 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
2158 event
.m_x
= ev
->where
.h
;
2159 event
.m_y
= ev
->where
.v
;
2160 event
.m_timeStamp
= ev
->when
;
2161 event
.SetEventObject(this);
2163 if ( wxWindow::s_lastMouseWindow
)
2165 wxMouseEvent
eventleave(event
);
2166 eventleave
.SetEventType( wxEVT_LEAVE_WINDOW
);
2167 wxWindow::s_lastMouseWindow
->ScreenToClient( &eventleave
.m_x
, &eventleave
.m_y
);
2168 eventleave
.SetEventObject( wxWindow::s_lastMouseWindow
) ;
2170 wxWindow::s_lastMouseWindow
->GetEventHandler()->ProcessEvent(eventleave
);
2172 if ( currentMouseWindow
)
2174 wxMouseEvent
evententer(event
);
2175 evententer
.SetEventType( wxEVT_ENTER_WINDOW
);
2176 currentMouseWindow
->ScreenToClient( &evententer
.m_x
, &evententer
.m_y
);
2177 evententer
.SetEventObject( currentMouseWindow
) ;
2178 currentMouseWindow
->GetEventHandler()->ProcessEvent(evententer
);
2180 wxWindow::s_lastMouseWindow
= currentMouseWindow
;
2183 short windowPart
= inNoWindow
;
2185 if ( s_captureWindow
)
2187 window
= (WindowRef
) s_captureWindow
->MacGetRootWindow() ;
2188 windowPart
= inContent
;
2192 windowPart
= ::FindWindow(ev
->where
, &window
);
2199 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
2201 win
->MacMouseMoved( ev
, windowPart
) ;
2208 UMAShowArrowCursor();
2218 UMAShowArrowCursor();
2228 void wxApp::MacHandleMenuSelect( int macMenuId
, int macMenuItemNum
)
2231 return; // no menu item selected
2233 if (macMenuId
== kwxMacAppleMenuId
&& macMenuItemNum
> 1)
2236 Str255 deskAccessoryName
;
2239 GetMenuItemText(GetMenuHandle(kwxMacAppleMenuId
), macMenuItemNum
, deskAccessoryName
);
2240 GetPort(&savedPort
);
2241 OpenDeskAcc(deskAccessoryName
);
2247 wxWindow
* frontwindow
= wxFindWinFromMacWindow( ::FrontWindow() ) ;
2248 if ( frontwindow
&& wxMenuBar::MacGetInstalledMenuBar() )
2249 wxMenuBar::MacGetInstalledMenuBar()->MacMenuSelect( frontwindow
->GetEventHandler() , 0 , macMenuId
, macMenuItemNum
) ;
2255 long wxApp::MacTranslateKey(char key, int mods)
2259 void wxApp::MacAdjustCursor()
2266 wxApp::macAdjustCursor()
2268 if (ev->what != kHighLevelEvent)
2270 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow());
2273 if (!theMacWxFrame->MacAdjustCursor(ev->where))
2274 ::SetCursor(&(qd.arrow));