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 long wxApp::s_macPreferencesMenuItemId
= 0 ;
105 long wxApp::s_macExitMenuItemId
= wxID_EXIT
;
106 wxString
wxApp::s_macHelpMenuTitleName
= "&Help" ;
108 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
109 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
110 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
111 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
114 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
116 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
117 return wxTheApp
->MacHandleAEODoc( (AppleEvent
*) event
, reply
) ;
120 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
122 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
123 return wxTheApp
->MacHandleAEOApp( (AppleEvent
*) event
, reply
) ;
126 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
128 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
129 return wxTheApp
->MacHandleAEPDoc( (AppleEvent
*) event
, reply
) ;
132 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
134 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
135 return wxTheApp
->MacHandleAEQuit( (AppleEvent
*) event
, reply
) ;
138 // new virtual public method in wxApp
139 void wxApp::MacOpenFile(const wxString
& WXUNUSED(fileName
) )
143 void wxApp::MacPrintFile(const wxString
& WXUNUSED(fileName
) )
147 void wxApp::MacNewFile()
151 // new implementation, which parses the event and calls
152 // MacOpenFile on each of the files it's passed
153 short wxApp::MacHandleAEODoc(const WXEVENTREF event
, WXEVENTREF
WXUNUSED(reply
))
157 DescType returnedType
;
163 err
= AEGetParamDesc((AppleEvent
*)event
, keyDirectObject
, typeAEList
,&docList
);
167 err
= AECountItems(&docList
, &itemsInList
);
171 ProcessSerialNumber PSN
;
172 PSN
.highLongOfPSN
= 0 ;
173 PSN
.lowLongOfPSN
= kCurrentProcess
;
174 SetFrontProcess( &PSN
) ;
176 for (i
= 1; i
<= itemsInList
; i
++) {
177 AEGetNthPtr(&docList
, i
, typeFSS
, &keywd
, &returnedType
,
178 (Ptr
) & theSpec
, sizeof(theSpec
), &actualSize
);
179 wxString fName
= wxMacFSSpec2MacFilename(&theSpec
);
185 short wxApp::MacHandleAEPDoc(const WXEVENTREF event
, WXEVENTREF
WXUNUSED(reply
))
189 DescType returnedType
;
195 err
= AEGetParamDesc((AppleEvent
*)event
, keyDirectObject
, typeAEList
,&docList
);
199 err
= AECountItems(&docList
, &itemsInList
);
203 ProcessSerialNumber PSN
;
204 PSN
.highLongOfPSN
= 0 ;
205 PSN
.lowLongOfPSN
= kCurrentProcess
;
206 SetFrontProcess( &PSN
) ;
208 for (i
= 1; i
<= itemsInList
; i
++) {
209 AEGetNthPtr(&docList
, i
, typeFSS
, &keywd
, &returnedType
,
210 (Ptr
) & theSpec
, sizeof(theSpec
), &actualSize
);
211 wxString fName
= wxMacFSSpec2MacFilename(&theSpec
);
217 short wxApp::MacHandleAEOApp(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
223 short wxApp::MacHandleAEQuit(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
225 wxWindow
* win
= GetTopWindow() ;
237 char StringMac
[] = "\x0d\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
238 "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
239 "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf"
240 "\xb1\xb4\xb5\xb6\xbb\xbc\xbe\xbf"
241 "\xc0\xc1\xc2\xc4\xc7\xc8\xc9\xcb\xcc\xcd\xce\xcf"
242 "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xca\xdb" ;
244 char StringANSI
[] = "\x0a\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8"
245 "\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC"
246 "\x86\xBA\xA2\xA3\xA7\x95\xB6\xDF\xAE\xA9\x99\xB4\xA8\xC6\xD8"
247 "\xB1\xA5\xB5\xF0\xAA\xBA\xE6\xF8"
248 "\xBF\xA1\xAC\x83\xAB\xBB\x85\xC0\xC3\xD5\x8C\x9C"
249 "\x96\x97\x93\x94\x91\x92\xF7\xFF\xA0\x80" ;
251 void wxMacConvertFromPC( const char *from
, char *to
, int len
)
256 for( int i
= 0 ; i
< len
; ++ i
)
258 c
= strchr( StringANSI
, *from
) ;
261 *to
= StringMac
[ c
- StringANSI
] ;
269 for( int i
= 0 ; i
< len
; ++ i
)
271 c
= strchr( StringANSI
, *from
) ;
274 *to
= StringMac
[ c
- StringANSI
] ;
286 void wxMacConvertToPC( const char *from
, char *to
, int len
)
291 for( int i
= 0 ; i
< len
; ++ i
)
293 c
= strchr( StringMac
, *from
) ;
296 *to
= StringANSI
[ c
- StringMac
] ;
304 for( int i
= 0 ; i
< len
; ++ i
)
306 c
= strchr( StringMac
, *from
) ;
309 *to
= StringANSI
[ c
- StringMac
] ;
321 void wxMacConvertFromPC( char * p
)
324 int len
= strlen ( p
) ;
326 wxMacConvertFromPC( ptr
, ptr
, len
) ;
329 void wxMacConvertFromPCForControls( char * p
)
332 int len
= strlen ( p
) ;
334 wxMacConvertFromPC( ptr
, ptr
, len
) ;
335 for ( unsigned int i
= 0 ; i
< strlen ( ptr
) ; i
++ )
337 if ( ptr
[i
] == '&' && ptr
[i
]+1 != ' ' )
339 memmove( &ptr
[i
] , &ptr
[i
+1] , strlen( &ptr
[i
+1] ) + 1) ;
344 void wxMacConvertFromPC( unsigned char *p
)
346 char *ptr
= (char*) p
+ 1 ;
349 wxMacConvertFromPC( ptr
, ptr
, len
) ;
352 extern char *wxBuffer
;
354 wxString
wxMacMakeMacStringFromPC( const char * p
)
356 const char *ptr
= p
;
357 int len
= strlen ( p
) ;
358 char *buf
= wxBuffer
;
360 if ( len
>= BUFSIZ
+ 512 )
362 buf
= new char [len
+1] ;
365 wxMacConvertFromPC( ptr
, buf
, len
) ;
367 wxString
result( buf
) ;
368 if ( buf
!= wxBuffer
)
374 void wxMacConvertToPC( char * p
)
377 int len
= strlen ( p
) ;
379 wxMacConvertToPC( ptr
, ptr
, len
) ;
382 void wxMacConvertToPC( unsigned char *p
)
384 char *ptr
= (char*) p
+ 1 ;
387 wxMacConvertToPC( ptr
, ptr
, len
) ;
390 wxString
wxMacMakePCStringFromMac( const char * p
)
392 const char *ptr
= p
;
393 int len
= strlen ( p
) ;
394 char *buf
= wxBuffer
;
396 if ( len
>= BUFSIZ
+ 512 )
398 buf
= new char [len
+1] ;
401 wxMacConvertToPC( ptr
, buf
, len
) ;
404 wxString
result( buf
) ;
405 if ( buf
!= wxBuffer
)
410 wxString
wxMacMakeStringFromMacString( const char* from
, bool mac2pcEncoding
)
414 return wxMacMakePCStringFromMac( from
) ;
418 return wxString( from
) ;
422 wxString
wxMacMakeStringFromPascal( StringPtr from
, bool mac2pcEncoding
)
424 // this is safe since a pascal string can never be larger than 256 bytes
426 CopyPascalStringToC( from
, s
) ;
429 return wxMacMakePCStringFromMac( s
) ;
433 return wxString( s
) ;
437 void wxMacStringToPascal( const char * from
, StringPtr to
, bool pc2macEncoding
)
441 CopyCStringToPascal( wxMacMakeMacStringFromPC( from
) , to
) ;
445 CopyCStringToPascal( from
, to
) ;
449 #if defined(WXMAKINGDLL) && !defined(__DARWIN__)
450 // we know it's there ;-)
451 WXIMPORT
char std::__throws_bad_alloc
;
454 bool wxApp::Initialize()
460 UMAInitToolbox( 4 ) ;
461 SetEventMask( everyEvent
) ;
462 UMAShowWatchCursor() ;
464 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
465 // open shared library resources from here since we don't have
466 // __wxinitialize in Mach-O shared libraries
467 wxStAppResource::OpenSharedLibraryResource(NULL
);
470 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
471 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
,
472 NewAEEventHandlerUPP(AEHandleODoc
) ,
473 (long) wxTheApp
, FALSE
) ;
474 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
,
475 NewAEEventHandlerUPP(AEHandleOApp
) ,
476 (long) wxTheApp
, FALSE
) ;
477 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
,
478 NewAEEventHandlerUPP(AEHandlePDoc
) ,
479 (long) wxTheApp
, FALSE
) ;
480 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
,
481 NewAEEventHandlerUPP(AEHandleQuit
) ,
482 (long) wxTheApp
, FALSE
) ;
484 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
,
485 NewAEEventHandlerProc(AEHandleODoc
) ,
486 (long) wxTheApp
, FALSE
) ;
487 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
,
488 NewAEEventHandlerProc(AEHandleOApp
) ,
489 (long) wxTheApp
, FALSE
) ;
490 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
,
491 NewAEEventHandlerProc(AEHandlePDoc
) ,
492 (long) wxTheApp
, FALSE
) ;
493 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
,
494 NewAEEventHandlerProc(AEHandleQuit
) ,
495 (long) wxTheApp
, FALSE
) ;
499 // test the minimal configuration necessary
505 if (Gestalt(gestaltMachineType
, &theMachine
) != noErr
)
507 error
= kMacSTRWrongMachine
;
509 else if (theMachine
< gestaltMacPlus
)
511 error
= kMacSTRWrongMachine
;
513 else if (Gestalt(gestaltSystemVersion
, &theSystem
) != noErr
)
515 error
= kMacSTROldSystem
;
517 else if ( theSystem
< 0x0860 )
519 error
= kMacSTROldSystem
;
521 else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap
)
523 error
= kMacSTRSmallSize
;
529 if ( !UMAHasAppearance() )
531 error = kMacSTRNoPre8Yet ;
537 // if we encountered any problems so far, give the error code and exit immediately
541 wxStAppResource resload
;
545 GetIndString(message
, 128, error
);
546 UMAShowArrowCursor() ;
547 ParamText("\pFatal Error", message
, (ConstStr255Param
)"\p", (ConstStr255Param
)"\p");
548 itemHit
= Alert(128, nil
);
553 # if __option(profile)
554 ProfilerInit( collectDetailed
, bestTimeBase
, 20000 , 40 ) ;
559 // now avoid exceptions thrown for new (bad_alloc)
560 std::__throws_bad_alloc
= FALSE
;
563 s_macCursorRgn
= ::NewRgn() ;
565 wxBuffer
= new char[BUFSIZ
+ 512];
567 wxClassInfo::InitializeClasses();
570 // wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion);
574 wxPendingEventsLocker
= new wxCriticalSection
;
577 wxTheColourDatabase
= new wxColourDatabase(wxKEY_STRING
);
578 wxTheColourDatabase
->Initialize();
582 // flush the logged messages if any and install a 'safer' log target: the
583 // default one (wxLogGui) can't be used after the resources are freed just
584 // below and the user suppliedo ne might be even more unsafe (using any
585 // wxWindows GUI function is unsafe starting from now)
586 wxLog::DontCreateOnDemand();
588 // this will flush the old messages if any
589 delete wxLog::SetActiveTarget(new wxLogStderr
);
593 wxWinMacWindowList
= new wxList(wxKEY_INTEGER
);
594 wxWinMacControlList
= new wxList(wxKEY_INTEGER
);
596 wxInitializeStockLists();
597 wxInitializeStockObjects();
599 #if wxUSE_WX_RESOURCES
600 wxInitializeResourceSystem();
603 wxBitmap::InitStandardHandlers();
605 wxModule::RegisterModules();
606 if (!wxModule::InitializeModules()) {
610 wxMacCreateNotifierTable() ;
613 UMAShowArrowCursor() ;
618 void wxApp::CleanUp()
620 wxToolTip::RemoveToolTips() ;
622 // flush the logged messages if any and install a 'safer' log target: the
623 // default one (wxLogGui) can't be used after the resources are freed just
624 // below and the user suppliedo ne might be even more unsafe (using any
625 // wxWindows GUI function is unsafe starting from now)
626 wxLog::DontCreateOnDemand();
628 // this will flush the old messages if any
629 delete wxLog::SetActiveTarget(new wxLogStderr
);
632 // One last chance for pending objects to be cleaned up
633 wxTheApp
->DeletePendingObjects();
635 wxModule::CleanUpModules();
637 #if wxUSE_WX_RESOURCES
638 wxCleanUpResourceSystem();
641 wxDeleteStockObjects() ;
643 // Destroy all GDI lists, etc.
644 wxDeleteStockLists();
646 delete wxTheColourDatabase
;
647 wxTheColourDatabase
= NULL
;
649 wxBitmap::CleanUpHandlers();
654 wxMacDestroyNotifierTable() ;
655 if (wxWinMacWindowList
) {
656 delete wxWinMacWindowList
;
658 if (wxWinMacControlList
) {
659 delete wxWinMacControlList
;
661 delete wxPendingEvents
;
664 delete wxPendingEventsLocker
;
665 // If we don't do the following, we get an apparent memory leak.
666 ((wxEvtHandler
&) wxDefaultValidator
).ClearEventLocker();
669 wxClassInfo::CleanUpClasses();
672 # if __option(profile)
673 ProfilerDump( "\papp.prof" ) ;
681 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
682 // At this point we want to check if there are any memory
683 // blocks that aren't part of the wxDebugContext itself,
684 // as a special case. Then when dumping we need to ignore
685 // wxDebugContext, too.
686 if (wxDebugContext::CountObjectsLeft(TRUE
) > 0)
688 wxLogDebug(wxT("There were memory leaks."));
689 wxDebugContext::Dump();
690 wxDebugContext::PrintStatistics();
692 // wxDebugContext::SetStream(NULL, NULL);
696 // do it as the very last thing because everything else can log messages
697 delete wxLog::SetActiveTarget(NULL
);
700 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
701 // close shared library resources from here since we don't have
702 // __wxterminate in Mach-O shared libraries
703 wxStAppResource::CloseSharedLibraryResource();
706 UMACleanupToolbox() ;
707 if (s_macCursorRgn
) {
708 ::DisposeRgn((RgnHandle
)s_macCursorRgn
);
716 //----------------------------------------------------------------------
718 //----------------------------------------------------------------------
720 // extern variable for shared library resource id
721 // need to be able to find it with NSLookupAndBindSymbol
722 short gSharedLibraryResource
= kResFileNotOpened
;
724 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
725 CFBundleRef gSharedLibraryBundle
= NULL
;
726 #endif /* WXMAKINGDLL && __DARWIN__ */
728 wxStAppResource::wxStAppResource()
730 m_currentRefNum
= CurResFile() ;
731 if ( gSharedLibraryResource
!= kResFileNotOpened
)
733 UseResFile( gSharedLibraryResource
) ;
737 wxStAppResource::~wxStAppResource()
739 if ( m_currentRefNum
!= kResFileNotOpened
)
741 UseResFile( m_currentRefNum
) ;
745 void wxStAppResource::OpenSharedLibraryResource(const void *initBlock
)
747 gSharedLibraryResource
= kResFileNotOpened
;
750 if ( initBlock
!= NULL
) {
751 const CFragInitBlock
*theInitBlock
= (const CFragInitBlock
*)initBlock
;
752 FSSpec
*fileSpec
= NULL
;
754 if (theInitBlock
->fragLocator
.where
== kDataForkCFragLocator
) {
755 fileSpec
= theInitBlock
->fragLocator
.u
.onDisk
.fileSpec
;
757 else if (theInitBlock
->fragLocator
.where
== kResourceCFragLocator
) {
758 fileSpec
= theInitBlock
->fragLocator
.u
.inSegs
.fileSpec
;
761 if (fileSpec
!= NULL
) {
762 gSharedLibraryResource
= FSpOpenResFile(fileSpec
, fsRdPerm
);
767 // Open the shared library resource file if it is not yet open
770 const char *theLibPath
;
772 gSharedLibraryBundle
= CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWindows"));
773 if (gSharedLibraryBundle
!= NULL
) {
774 // wxWindows has been bundled into a framework
775 // load the framework resources
777 gSharedLibraryResource
= CFBundleOpenBundleResourceMap(gSharedLibraryBundle
);
780 // wxWindows is a simple dynamic shared library
781 // load the resources from the data fork of a separate resource file
786 OSErr theErr
= noErr
;
788 // get the library path
789 theSymbol
= NSLookupAndBindSymbol("_gSharedLibraryResource");
790 theModule
= NSModuleForSymbol(theSymbol
);
791 theLibPath
= NSLibraryNameForModule(theModule
);
793 // allocate copy to replace .dylib.* extension with .rsrc
794 theResPath
= strdup(theLibPath
);
795 if (theResPath
!= NULL
) {
796 theName
= strrchr(theResPath
, '/');
797 if (theName
== NULL
) {
798 // no directory elements in path
799 theName
= theResPath
;
801 // find ".dylib" shared library extension
802 theExt
= strstr(theName
, ".dylib");
803 // overwrite extension with ".rsrc"
804 strcpy(theExt
, ".rsrc");
806 wxLogDebug( theResPath
);
808 theErr
= FSPathMakeRef((UInt8
*) theResPath
, &theResRef
, false);
809 if (theErr
!= noErr
) {
810 // try in current directory (using name only)
811 theErr
= FSPathMakeRef((UInt8
*) theName
, &theResRef
, false);
814 // free duplicated resource file path
817 // open the resource file
818 if (theErr
== noErr
) {
819 theErr
= FSOpenResourceFile( &theResRef
, 0, NULL
, fsRdPerm
,
820 &gSharedLibraryResource
);
824 #endif /* __DARWIN__ */
826 #endif /* WXMAKINGDLL */
829 void wxStAppResource::CloseSharedLibraryResource()
832 // Close the shared library resource file
833 if (gSharedLibraryResource
!= kResFileNotOpened
) {
835 if (gSharedLibraryBundle
!= NULL
) {
836 CFBundleCloseBundleResourceMap(gSharedLibraryBundle
,
837 gSharedLibraryResource
);
838 gSharedLibraryBundle
= NULL
;
841 #endif /* __DARWIN__ */
843 CloseResFile(gSharedLibraryResource
);
845 gSharedLibraryResource
= kResFileNotOpened
;
847 #endif /* WXMAKINGDLL */
850 #if defined(WXMAKINGDLL) && !defined(__DARWIN__)
852 // for shared libraries we have to manually get the correct resource
853 // ref num upon initializing and releasing when terminating, therefore
854 // the __wxinitialize and __wxterminate must be used
857 void __sinit(void); /* (generated by linker) */
858 pascal OSErr
__initialize(const CFragInitBlock
*theInitBlock
);
859 pascal void __terminate(void);
862 pascal OSErr
__wxinitialize(const CFragInitBlock
*theInitBlock
)
864 wxStAppResource::OpenSharedLibraryResource( theInitBlock
) ;
865 return __initialize( theInitBlock
) ;
868 pascal void __wxterminate(void)
870 wxStAppResource::CloseSharedLibraryResource() ;
874 #endif /* WXMAKINGDLL && !__DARWIN__ */
876 int WXDLLEXPORT
wxEntryStart( int WXUNUSED(argc
), char *WXUNUSED(argv
)[] )
878 return wxApp::Initialize();
881 int WXDLLEXPORT
wxEntryInitGui()
883 return wxTheApp
->OnInitGui();
886 void WXDLLEXPORT
wxEntryCleanup()
891 int wxEntry( int argc
, char *argv
[] , bool enterLoop
)
894 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
895 // This seems to be necessary since there are 'rogue'
896 // objects present at this point (perhaps global objects?)
897 // Setting a checkpoint will ignore them as far as the
898 // memory checking facility is concerned.
899 // Of course you may argue that memory allocated in globals should be
900 // checked, but this is a reasonable compromise.
901 wxDebugContext::SetCheckpoint();
904 if (!wxEntryStart(argc
, argv
)) {
907 // create the application object or ensure that one already exists
910 // The app may have declared a global application object, but we recommend
911 // the IMPLEMENT_APP macro is used instead, which sets an initializer
912 // function for delayed, dynamic app object construction.
913 wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
914 wxT("No initializer - use IMPLEMENT_APP macro.") );
916 wxTheApp
= (wxApp
*) (*wxApp::GetInitializerFunction()) ();
919 wxCHECK_MSG( wxTheApp
, 0, wxT("You have to define an instance of wxApp!") );
922 // Mac OS X passes a process serial number command line argument when
923 // the application is launched from the Finder. This argument must be
924 // removed from the command line arguments before being handled by the
925 // application (otherwise applications would need to handle it)
928 if (strncmp(argv
[1], "-psn_", 5) == 0) {
929 // assume the argument is always the only one and remove it
934 argc
= 0 ; // currently we don't support files as parameters
936 // we could try to get the open apple events here to adjust argc and argv better
938 wxTheApp
->argc
= argc
;
939 wxTheApp
->argv
= argv
;
941 // GUI-specific initialization, such as creating an app context.
944 // Here frames insert themselves automatically
945 // into wxTopLevelWindows by getting created
950 if ( wxTheApp
->OnInit() )
954 retValue
= wxTheApp
->OnRun();
957 // We want to initialize, but not run or exit immediately.
960 //else: app initialization failed, so we skipped OnRun()
962 wxWindow
*topWindow
= wxTheApp
->GetTopWindow();
965 // Forcibly delete the window.
966 if ( topWindow
->IsKindOf(CLASSINFO(wxFrame
)) ||
967 topWindow
->IsKindOf(CLASSINFO(wxDialog
)) )
969 topWindow
->Close(TRUE
);
970 wxTheApp
->DeletePendingObjects();
975 wxTheApp
->SetTopWindow(NULL
);
988 bool wxMacConvertEventToRecord( EventRef event
, EventRecord
*rec
)
990 bool converted
= ConvertEventRefToEventRecord( event
,rec
) ;
991 OSStatus err
= noErr
;
994 switch( GetEventClass( event
) )
996 case kEventClassKeyboard
:
999 switch( GetEventKind(event
) )
1001 case kEventRawKeyDown
:
1002 rec
->what
= keyDown
;
1004 case kEventRawKeyRepeat
:
1005 rec
->what
= autoKey
;
1007 case kEventRawKeyUp
:
1010 case kEventRawKeyModifiersChanged
:
1011 rec
->what
= nullEvent
;
1020 unsigned char charCode
;
1022 GetMouse( &rec
->where
) ;
1024 err
= GetEventParameter(event
, kEventParamKeyModifiers
, typeUInt32
, NULL
, 4, NULL
, &modifiers
);
1025 err
= GetEventParameter(event
, kEventParamKeyCode
, typeUInt32
, NULL
, 4, NULL
, &keyCode
);
1026 err
= GetEventParameter(event
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, 1, NULL
, &charCode
);
1027 rec
->modifiers
= modifiers
;
1028 rec
->message
= (keyCode
<< 8 ) + charCode
;
1032 case kEventClassTextInput
:
1034 switch( GetEventKind( event
) )
1036 case kEventTextInputUnicodeForKeyEvent
:
1039 err
= GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
,typeEventRef
,NULL
,sizeof(rawEvent
),NULL
,&rawEvent
) ;
1043 unsigned char charCode
;
1045 GetMouse( &rec
->where
) ;
1046 rec
->what
= keyDown
;
1047 err
= GetEventParameter(rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, 4, NULL
, &modifiers
);
1048 err
= GetEventParameter(rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, 4, NULL
, &keyCode
);
1049 err
= GetEventParameter(rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, 1, NULL
, &charCode
);
1050 rec
->modifiers
= modifiers
;
1051 rec
->message
= (keyCode
<< 8 ) + charCode
;
1066 pascal OSStatus
wxMacApplicationEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
1068 OSStatus result
= eventNotHandledErr
;
1071 switch ( GetEventClass( event
) )
1073 case kEventClassKeyboard
:
1074 if ( wxMacConvertEventToRecord( event
, &rec
) )
1076 wxTheApp
->MacHandleModifierEvents( &rec
) ;
1077 wxTheApp
->MacHandleOneEvent( &rec
) ;
1081 case kEventClassTextInput
:
1082 if ( wxMacConvertEventToRecord( event
, &rec
) )
1084 wxTheApp
->MacHandleModifierEvents( &rec
) ;
1085 wxTheApp
->MacHandleOneEvent( &rec
) ;
1097 bool wxApp::OnInit()
1099 if ( ! wxAppBase::OnInit() )
1102 #if 0 // TARGET_CARBON
1103 static const EventTypeSpec eventList
[] =
1105 { kEventClassKeyboard
, kEventRawKeyDown
} ,
1106 { kEventClassKeyboard
, kEventRawKeyRepeat
} ,
1107 { kEventClassKeyboard
, kEventRawKeyUp
} ,
1108 { kEventClassKeyboard
, kEventRawKeyModifiersChanged
} ,
1110 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} ,
1113 InstallApplicationEventHandler(NewEventHandlerUPP(wxMacApplicationEventHandler
)
1114 , WXSIZEOF(eventList
), eventList
, this, NULL
);
1118 // Static member initialization
1119 wxAppInitializerFunction
wxAppBase::m_appInitFn
= (wxAppInitializerFunction
) NULL
;
1126 #if WXWIN_COMPATIBILITY_2_2
1127 m_wantDebugOutput
= TRUE
;
1133 m_printMode
= wxPRINT_WINDOWS
;
1137 bool wxApp::Initialized()
1145 int wxApp::MainLoop()
1157 // Returns TRUE if more time is needed.
1158 bool wxApp::ProcessIdle()
1161 event
.SetEventObject(this);
1162 ProcessEvent(event
);
1164 return event
.MoreRequested();
1167 void wxApp::ExitMainLoop()
1169 m_keepGoing
= FALSE
;
1172 // Is a message/event pending?
1173 bool wxApp::Pending()
1177 return EventAvail( everyEvent
, &event
) ;
1180 // Dispatch a message.
1181 void wxApp::Dispatch()
1186 void wxApp::OnIdle(wxIdleEvent
& event
)
1188 static bool s_inOnIdle
= FALSE
;
1190 // Avoid recursion (via ProcessEvent default case)
1197 // 'Garbage' collection of windows deleted with Close().
1198 DeletePendingObjects();
1200 // flush the logged messages if any
1201 wxLog
*pLog
= wxLog::GetActiveTarget();
1202 if ( pLog
!= NULL
&& pLog
->HasPendingMessages() )
1205 // Send OnIdle events to all windows
1206 bool needMore
= SendIdleEvents();
1209 event
.RequestMore(TRUE
);
1211 // If they are pending events, we must process them: pending events are
1212 // either events to the threads other than main or events posted with
1213 // wxPostEvent() functions
1214 wxMacProcessNotifierAndPendingEvents();
1224 // Send idle event to all top-level windows
1225 bool wxApp::SendIdleEvents()
1227 bool needMore
= FALSE
;
1228 wxNode
* node
= wxTopLevelWindows
.First();
1231 wxWindow
* win
= (wxWindow
*) node
->Data();
1232 if (SendIdleEvents(win
))
1235 node
= node
->Next();
1240 // Send idle event to window and all subwindows
1241 bool wxApp::SendIdleEvents(wxWindow
* win
)
1243 bool needMore
= FALSE
;
1246 event
.SetEventObject(win
);
1247 win
->ProcessEvent(event
);
1249 if (event
.MoreRequested())
1252 wxNode
* node
= win
->GetChildren().First();
1255 wxWindow
* win
= (wxWindow
*) node
->Data();
1256 if (SendIdleEvents(win
))
1259 node
= node
->Next();
1264 void wxApp::DeletePendingObjects()
1266 wxNode
*node
= wxPendingDelete
.First();
1269 wxObject
*obj
= (wxObject
*)node
->Data();
1273 if (wxPendingDelete
.Member(obj
))
1276 // Deleting one object may have deleted other pending
1277 // objects, so start from beginning of list again.
1278 node
= wxPendingDelete
.First();
1284 wxLogError(_("Fatal error: exiting"));
1290 void wxApp::OnEndSession(wxCloseEvent
& WXUNUSED(event
))
1293 GetTopWindow()->Close(TRUE
);
1296 // Default behaviour: close the application with prompts. The
1297 // user can veto the close, and therefore the end session.
1298 void wxApp::OnQueryEndSession(wxCloseEvent
& event
)
1302 if (!GetTopWindow()->Close(!event
.CanVeto()))
1307 extern "C" void wxCYield() ;
1313 // Yield to other processes
1315 bool wxApp::Yield(bool onlyIfNeeded
)
1317 static bool s_inYield
= FALSE
;
1321 if ( !onlyIfNeeded
)
1323 wxFAIL_MSG( wxT("wxYield called recursively" ) );
1332 YieldToAnyThread() ;
1336 long sleepTime
= 1 ; //::GetCaretTime();
1338 while ( !wxTheApp
->IsExiting() && WaitNextEvent(everyEvent
, &event
,sleepTime
, (RgnHandle
) wxApp::s_macCursorRgn
))
1340 wxTheApp
->MacHandleModifierEvents( &event
) ;
1341 wxTheApp
->MacHandleOneEvent( &event
);
1342 if ( event
.what
!= kHighLevelEvent
)
1343 SetRectRgn( (RgnHandle
) wxApp::s_macCursorRgn
, event
.where
.h
, event
.where
.v
, event
.where
.h
+ 1 , event
.where
.v
+ 1 ) ;
1345 wxTheApp
->MacHandleModifierEvents( &event
) ;
1347 wxMacProcessNotifierAndPendingEvents() ;
1354 // platform specifics
1356 void wxApp::MacSuspend( bool convertClipboard
)
1358 // we have to deactive the top level windows manually
1360 wxNode
* node
= wxTopLevelWindows
.First();
1363 wxTopLevelWindow
* win
= (wxTopLevelWindow
*) node
->Data();
1364 win
->MacActivate( MacGetCurrentEvent() , false ) ;
1366 node
= node
->Next();
1369 s_lastMouseDown
= 0 ;
1370 if( convertClipboard
)
1372 MacConvertPrivateToPublicScrap() ;
1375 ::HideFloatingWindows() ;
1378 extern wxList wxModalDialogs
;
1380 void wxApp::MacResume( bool convertClipboard
)
1382 s_lastMouseDown
= 0 ;
1383 if( convertClipboard
)
1385 MacConvertPublicToPrivateScrap() ;
1388 ::ShowFloatingWindows() ;
1390 // raise modal dialogs in case a non modal window was selected to activate the app
1392 wxNode
* node
= wxModalDialogs
.First();
1395 wxDialog
* dialog
= (wxDialog
*) node
->Data();
1398 node
= node
->Next();
1402 void wxApp::MacConvertPrivateToPublicScrap()
1406 void wxApp::MacConvertPublicToPrivateScrap()
1410 void wxApp::MacDoOneEvent()
1414 long sleepTime
= 1; // GetCaretTime() / 4 ;
1416 if (WaitNextEvent(everyEvent
, &event
, sleepTime
, (RgnHandle
) s_macCursorRgn
))
1418 MacHandleModifierEvents( &event
) ;
1419 MacHandleOneEvent( &event
);
1423 MacHandleModifierEvents( &event
) ;
1425 WindowPtr window
= ::FrontWindow() ;
1427 ::IdleControls( window
) ;
1429 wxTheApp
->ProcessIdle() ;
1431 if ( event
.what
!= kHighLevelEvent
)
1432 SetRectRgn( (RgnHandle
) s_macCursorRgn
, event
.where
.h
, event
.where
.v
, event
.where
.h
+ 1 , event
.where
.v
+ 1 ) ;
1436 DeletePendingObjects() ;
1437 wxMacProcessNotifierAndPendingEvents() ;
1440 void wxApp::MacHandleModifierEvents( WXEVENTREF evr
)
1442 EventRecord
* ev
= (EventRecord
*) evr
;
1444 if ( ev
->what
== mouseDown
|| ev
->what
== mouseUp
|| ev
->what
== activateEvt
||
1445 ev
->what
== keyDown
|| ev
->what
== autoKey
|| ev
->what
== keyUp
|| ev
->what
== kHighLevelEvent
||
1446 ev
->what
== nullEvent
1449 // in these cases the modifiers are already correctly setup by carbon
1454 WaitNextEvent( 0 , &nev
, 0 , NULL
) ;
1455 ev
->modifiers
= nev
.modifiers
;
1456 // KeyModifiers unfortunately don't include btnState...
1457 // ev->modifiers = GetCurrentKeyModifiers() ;
1460 if ( ev
->modifiers
!= s_lastModifiers
&& wxWindow::FindFocus() != NULL
)
1462 wxKeyEvent
event(wxEVT_KEY_DOWN
);
1464 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1465 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1466 event
.m_altDown
= ev
->modifiers
& optionKey
;
1467 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1469 event
.m_x
= ev
->where
.h
;
1470 event
.m_y
= ev
->where
.v
;
1471 event
.m_timeStamp
= ev
->when
;
1472 wxWindow
* focus
= wxWindow::FindFocus() ;
1473 event
.SetEventObject(focus
);
1475 if ( (ev
->modifiers
^ s_lastModifiers
) & controlKey
)
1477 event
.m_keyCode
= WXK_CONTROL
;
1478 event
.SetEventType( ( ev
->modifiers
& controlKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
1479 focus
->GetEventHandler()->ProcessEvent( event
) ;
1481 if ( (ev
->modifiers
^ s_lastModifiers
) & shiftKey
)
1483 event
.m_keyCode
= WXK_SHIFT
;
1484 event
.SetEventType( ( ev
->modifiers
& shiftKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
1485 focus
->GetEventHandler()->ProcessEvent( event
) ;
1487 if ( (ev
->modifiers
^ s_lastModifiers
) & optionKey
)
1489 event
.m_keyCode
= WXK_ALT
;
1490 event
.SetEventType( ( ev
->modifiers
& optionKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
1491 focus
->GetEventHandler()->ProcessEvent( event
) ;
1493 s_lastModifiers
= ev
->modifiers
;
1497 void wxApp::MacHandleOneEvent( WXEVENTREF evr
)
1499 EventRecord
* ev
= (EventRecord
*) evr
;
1500 m_macCurrentEvent
= ev
;
1502 wxApp::sm_lastMessageTime
= ev
->when
;
1507 MacHandleMouseDownEvent( ev
) ;
1508 if ( ev
->modifiers
& controlKey
)
1509 s_lastMouseDown
= 2;
1511 s_lastMouseDown
= 1;
1514 if ( s_lastMouseDown
== 2 )
1516 ev
->modifiers
|= controlKey
;
1520 ev
->modifiers
&= ~controlKey
;
1522 MacHandleMouseUpEvent( ev
) ;
1523 s_lastMouseDown
= 0;
1526 MacHandleActivateEvent( ev
) ;
1529 MacHandleUpdateEvent( ev
) ;
1533 MacHandleKeyDownEvent( ev
) ;
1536 MacHandleKeyUpEvent( ev
) ;
1539 MacHandleDiskEvent( ev
) ;
1542 MacHandleOSEvent( ev
) ;
1544 case kHighLevelEvent
:
1545 MacHandleHighLevelEvent( ev
) ;
1550 wxMacProcessNotifierAndPendingEvents() ;
1553 void wxApp::MacHandleHighLevelEvent( WXEVENTREF evr
)
1555 EventRecord
* ev
= (EventRecord
*) evr
;
1556 ::AEProcessAppleEvent( ev
) ;
1559 bool s_macIsInModalLoop
= false ;
1561 void wxApp::MacHandleMouseDownEvent( WXEVENTREF evr
)
1563 EventRecord
* ev
= (EventRecord
*) evr
;
1564 wxToolTip::RemoveToolTips() ;
1567 WindowRef frontWindow
= ::FrontNonFloatingWindow() ;
1568 WindowAttributes frontWindowAttributes
= NULL
;
1570 ::GetWindowAttributes( frontWindow
, &frontWindowAttributes
) ;
1572 short windowPart
= ::FindWindow(ev
->where
, &window
);
1573 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
1574 if ( wxPendingDelete
.Member(win
) )
1578 GetQDGlobalsScreenBits( &screenBits
);
1583 if ( s_macIsInModalLoop
)
1589 UInt32 menuresult
= MenuSelect(ev
->where
) ;
1590 MacHandleMenuSelect( HiWord( menuresult
) , LoWord( menuresult
) );
1591 s_lastMouseDown
= 0;
1596 SystemClick( ev
, window
) ;
1597 s_lastMouseDown
= 0;
1601 if ( window
!= frontWindow
&& s_macIsInModalLoop
&& !(ev
->modifiers
& cmdKey
) )
1607 DragWindow(window
, ev
->where
, &screenBits
.bounds
);
1612 Point pt
= { 0, 0 } ;
1613 SetPortWindowPort(window
) ;
1614 LocalToGlobal( &pt
) ;
1616 win
->SetSize( pt
.h
, pt
.v
, -1 ,
1617 -1 , wxSIZE_USE_EXISTING
);
1619 s_lastMouseDown
= 0;
1623 if (TrackGoAway(window
, ev
->where
))
1628 s_lastMouseDown
= 0;
1632 Rect newContentRect
;
1633 Rect constraintRect
;
1634 constraintRect
.top
= win
->GetMinHeight() ;
1635 if ( constraintRect
.top
== -1 )
1636 constraintRect
.top
= 0 ;
1637 constraintRect
.left
= win
->GetMinWidth() ;
1638 if ( constraintRect
.left
== -1 )
1639 constraintRect
.left
= 0 ;
1640 constraintRect
.right
= win
->GetMaxWidth() ;
1641 if ( constraintRect
.right
== -1 )
1642 constraintRect
.right
= 32000 ;
1643 constraintRect
.bottom
= win
->GetMaxHeight() ;
1644 if ( constraintRect
.bottom
== -1 )
1645 constraintRect
.bottom
= 32000 ;
1647 Boolean growResult
= ResizeWindow( window
, ev
->where
,
1648 &constraintRect
, &newContentRect
) ;
1651 win
->SetSize( newContentRect
.left
, newContentRect
.top
,
1652 newContentRect
.right
- newContentRect
.left
,
1653 newContentRect
.bottom
- newContentRect
.top
, wxSIZE_USE_EXISTING
);
1655 s_lastMouseDown
= 0;
1660 if (TrackBox(window
, ev
->where
, windowPart
))
1662 // TODO setup size event
1663 ZoomWindow( window
, windowPart
, false ) ;
1669 Point pt
= { 0, 0 } ;
1670 SetPortWindowPort(window
) ;
1671 LocalToGlobal( &pt
) ;
1674 GetWindowPortBounds(window
, &tempRect
) ;
1675 win
->SetSize( pt
.h
, pt
.v
, tempRect
.right
-tempRect
.left
,
1676 tempRect
.bottom
-tempRect
.top
, wxSIZE_USE_EXISTING
);
1679 s_lastMouseDown
= 0;
1681 case inCollapseBox
:
1682 // TODO setup size event
1683 s_lastMouseDown
= 0;
1690 SetPortWindowPort(window
) ;
1693 if ( window
!= frontWindow
&& wxTheApp
->s_captureWindow
== NULL
)
1695 if ( s_macIsInModalLoop
)
1699 else if ( UMAIsWindowFloating( window
) )
1702 win
->MacMouseDown( ev
, windowPart
) ;
1707 win
->MacMouseDown( ev
, windowPart
) ;
1708 ::SelectWindow( window
) ;
1714 win
->MacMouseDown( ev
, windowPart
) ;
1723 void wxApp::MacHandleMouseUpEvent( WXEVENTREF evr
)
1725 EventRecord
* ev
= (EventRecord
*) evr
;
1728 short windowPart
= inNoWindow
;
1729 if ( wxTheApp
->s_captureWindow
)
1731 window
= (WindowRef
) s_captureWindow
->MacGetRootWindow() ;
1732 windowPart
= inContent
;
1736 windowPart
= ::FindWindow(ev
->where
, &window
) ;
1747 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
1749 win
->MacMouseUp( ev
, windowPart
) ;
1755 long wxMacTranslateKey(unsigned char key
, unsigned char code
) ;
1756 long wxMacTranslateKey(unsigned char key
, unsigned char code
)
1761 case kHomeCharCode
:
1764 case kEnterCharCode
:
1765 retval
= WXK_RETURN
;
1770 case kHelpCharCode
:
1773 case kBackspaceCharCode
:
1779 case kPageUpCharCode
:
1780 retval
= WXK_PAGEUP
;
1782 case kPageDownCharCode
:
1783 retval
= WXK_PAGEDOWN
;
1785 case kReturnCharCode
:
1786 retval
= WXK_RETURN
;
1788 case kFunctionKeyCharCode
:
1840 case kEscapeCharCode
:
1841 retval
= WXK_ESCAPE
;
1843 case kLeftArrowCharCode
:
1846 case kRightArrowCharCode
:
1847 retval
= WXK_RIGHT
;
1849 case kUpArrowCharCode
:
1852 case kDownArrowCharCode
:
1855 case kDeleteCharCode
:
1856 retval
= WXK_DELETE
;
1864 void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr
)
1866 EventRecord
* ev
= (EventRecord
*) evr
;
1867 wxToolTip::RemoveToolTips() ;
1869 UInt32 menuresult
= UMAMenuEvent(ev
) ;
1870 if ( HiWord( menuresult
) )
1872 if ( !s_macIsInModalLoop
)
1873 MacHandleMenuSelect( HiWord( menuresult
) , LoWord( menuresult
) ) ;
1877 wxWindow
* focus
= wxWindow::FindFocus() ;
1879 if ( MacSendKeyDownEvent( focus
, ev
->message
, ev
->modifiers
, ev
->when
, ev
->where
.h
, ev
->where
.v
) == false )
1881 // has not been handled -> perform default
1882 wxControl
* control
= wxDynamicCast( focus
, wxControl
) ;
1883 if ( control
&& control
->GetMacControl() != NULL
)
1887 keychar
= short(ev
->message
& charCodeMask
);
1888 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1889 ::HandleControlKey( (ControlHandle
) control
->GetMacControl() , keycode
, keychar
, ev
->modifiers
) ;
1895 bool wxApp::MacSendKeyDownEvent( wxWindow
* focus
, long keymessage
, long modifiers
, long when
, short wherex
, short wherey
)
1902 keychar
= short(keymessage
& charCodeMask
);
1903 keycode
= short(keymessage
& keyCodeMask
) >> 8 ;
1905 if ( modifiers
& ( controlKey
|shiftKey
|optionKey
) )
1907 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
1908 // and look at the character after
1910 UInt32 keyInfo
= KeyTranslate((Ptr
)GetScriptManagerVariable(smKCHRCache
), ( modifiers
& (~(controlKey
|shiftKey
|optionKey
))) | keycode
, &state
);
1911 keychar
= short(keyInfo
& charCodeMask
);
1912 keycode
= short(keyInfo
& keyCodeMask
) >> 8 ;
1914 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
1915 long realkeyval
= keyval
;
1916 if ( keyval
== keychar
)
1918 // 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)
1919 realkeyval
= short(keymessage
& charCodeMask
) ;
1920 keyval
= wxToupper( keyval
) ;
1923 wxKeyEvent
event(wxEVT_KEY_DOWN
);
1924 bool handled
= false ;
1925 event
.m_shiftDown
= modifiers
& shiftKey
;
1926 event
.m_controlDown
= modifiers
& controlKey
;
1927 event
.m_altDown
= modifiers
& optionKey
;
1928 event
.m_metaDown
= modifiers
& cmdKey
;
1929 event
.m_keyCode
= keyval
;
1933 event
.m_timeStamp
= when
;
1934 event
.SetEventObject(focus
);
1935 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1936 if ( handled
&& event
.GetSkipped() )
1943 wxWindow
*ancestor
= focus
;
1946 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
1949 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
1950 handled
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
1953 if (ancestor
->IsTopLevel())
1955 ancestor
= ancestor
->GetParent();
1958 #endif // wxUSE_ACCEL
1962 event
.Skip( FALSE
) ;
1963 event
.SetEventType( wxEVT_CHAR
) ;
1965 event
.m_keyCode
= realkeyval
;
1967 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1968 if ( handled
&& event
.GetSkipped() )
1972 (keyval
== WXK_TAB
) &&
1973 // CS: copied the change below from wxGTK
1974 // VZ: testing for wxTE_PROCESS_TAB shouldn't be done here the control may
1975 // have this style, yet choose not to process this particular TAB in which
1976 // case TAB must still work as a navigational character
1978 (!focus
->HasFlag(wxTE_PROCESS_TAB
)) &&
1980 (focus
->GetParent()) &&
1981 (focus
->GetParent()->HasFlag( wxTAB_TRAVERSAL
)) )
1983 wxNavigationKeyEvent new_event
;
1984 new_event
.SetEventObject( focus
);
1985 new_event
.SetDirection( !event
.ShiftDown() );
1986 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
1987 new_event
.SetWindowChange( event
.ControlDown() );
1988 new_event
.SetCurrentFocus( focus
);
1989 handled
= focus
->GetEventHandler()->ProcessEvent( new_event
);
1990 if ( handled
&& new_event
.GetSkipped() )
1993 // backdoor handler for default return and command escape
1994 if ( !handled
&& (!focus
->IsKindOf(CLASSINFO(wxControl
) ) || !focus
->MacCanFocus() ) )
1996 // if window is not having a focus still testing for default enter or cancel
1997 // TODO add the UMA version for ActiveNonFloatingWindow
1998 wxWindow
* focus
= wxFindWinFromMacWindow( FrontWindow() ) ;
2001 if ( keyval
== WXK_RETURN
)
2003 wxButton
*def
= wxDynamicCast(focus
->GetDefaultItem(),
2005 if ( def
&& def
->IsEnabled() )
2007 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
2008 event
.SetEventObject(def
);
2009 def
->Command(event
);
2013 /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
2014 else if (keyval
== WXK_ESCAPE
|| (keyval
== '.' && modifiers
& cmdKey
) )
2016 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
2017 new_event
.SetEventObject( focus
);
2018 handled
= focus
->GetEventHandler()->ProcessEvent( new_event
);
2026 void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr
)
2028 EventRecord
* ev
= (EventRecord
*) evr
;
2029 wxToolTip::RemoveToolTips() ;
2031 UInt32 menuresult
= UMAMenuEvent(ev
) ;
2032 if ( HiWord( menuresult
) )
2037 MacSendKeyUpEvent( wxWindow::FindFocus() , ev
->message
, ev
->modifiers
, ev
->when
, ev
->where
.h
, ev
->where
.v
) ;
2041 bool wxApp::MacSendKeyUpEvent( wxWindow
* focus
, long keymessage
, long modifiers
, long when
, short wherex
, short wherey
)
2048 keychar
= short(keymessage
& charCodeMask
);
2049 keycode
= short(keymessage
& keyCodeMask
) >> 8 ;
2050 if ( modifiers
& ( controlKey
|shiftKey
|optionKey
) )
2052 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
2053 // and look at the character after
2055 UInt32 keyInfo
= KeyTranslate((Ptr
)GetScriptManagerVariable(smKCHRCache
), ( modifiers
& (~(controlKey
|shiftKey
|optionKey
))) | keycode
, &state
);
2056 keychar
= short(keyInfo
& charCodeMask
);
2057 keycode
= short(keyInfo
& keyCodeMask
) >> 8 ;
2059 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
2061 if ( keyval
== keychar
)
2063 keyval
= wxToupper( keyval
) ;
2065 bool handled
= false ;
2067 wxKeyEvent
event(wxEVT_KEY_UP
);
2068 event
.m_shiftDown
= modifiers
& shiftKey
;
2069 event
.m_controlDown
= modifiers
& controlKey
;
2070 event
.m_altDown
= modifiers
& optionKey
;
2071 event
.m_metaDown
= modifiers
& cmdKey
;
2072 event
.m_keyCode
= keyval
;
2076 event
.m_timeStamp
= when
;
2077 event
.SetEventObject(focus
);
2078 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
2082 void wxApp::MacHandleActivateEvent( WXEVENTREF evr
)
2084 EventRecord
* ev
= (EventRecord
*) evr
;
2085 WindowRef window
= (WindowRef
) ev
->message
;
2088 bool activate
= (ev
->modifiers
& activeFlag
) ;
2089 WindowClass wclass
;
2090 ::GetWindowClass ( window
, &wclass
) ;
2091 if ( wclass
== kFloatingWindowClass
)
2093 // if it is a floater we activate/deactivate the front non-floating window instead
2094 window
= ::FrontNonFloatingWindow() ;
2096 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
2098 win
->MacActivate( ev
, activate
) ;
2102 void wxApp::MacHandleUpdateEvent( WXEVENTREF evr
)
2104 EventRecord
* ev
= (EventRecord
*) evr
;
2105 WindowRef window
= (WindowRef
) ev
->message
;
2106 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
2109 if ( !wxPendingDelete
.Member(win
) )
2110 win
->MacUpdate( ev
->when
) ;
2114 // since there is no way of telling this foreign window to update itself
2115 // we have to invalidate the update region otherwise we keep getting the same
2116 // event over and over again
2117 BeginUpdate( window
) ;
2118 EndUpdate( window
) ;
2122 void wxApp::MacHandleDiskEvent( WXEVENTREF evr
)
2124 EventRecord
* ev
= (EventRecord
*) evr
;
2125 if ( HiWord( ev
->message
) != noErr
)
2130 SetPt( &point
, 100 , 100 ) ;
2132 err
= DIBadMount( point
, ev
->message
) ;
2133 wxASSERT( err
== noErr
) ;
2138 void wxApp::MacHandleOSEvent( WXEVENTREF evr
)
2140 EventRecord
* ev
= (EventRecord
*) evr
;
2141 switch( ( ev
->message
& osEvtMessageMask
) >> 24 )
2143 case suspendResumeMessage
:
2145 bool isResuming
= ev
->message
& resumeFlag
;
2147 bool convertClipboard
= ev
->message
& convertClipboardFlag
;
2149 bool convertClipboard
= false;
2151 bool doesActivate
= UMAGetProcessModeDoesActivateOnFGSwitch() ;
2154 WindowRef oldFrontWindow
= NULL
;
2155 WindowRef newFrontWindow
= NULL
;
2157 // in case we don't take care of activating ourselves, we have to synchronize
2158 // our idea of the active window with the process manager's - which it already activated
2160 if ( !doesActivate
)
2161 oldFrontWindow
= ::FrontNonFloatingWindow() ;
2163 MacResume( convertClipboard
) ;
2165 newFrontWindow
= ::FrontNonFloatingWindow() ;
2167 if ( oldFrontWindow
)
2169 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( oldFrontWindow
) ;
2171 win
->MacActivate( ev
, false ) ;
2173 if ( newFrontWindow
)
2175 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( newFrontWindow
) ;
2177 win
->MacActivate( ev
, true ) ;
2182 MacSuspend( convertClipboard
) ;
2184 // in case this suspending did close an active window, another one might
2185 // have surfaced -> lets deactivate that one
2187 /* TODO : find out what to do on systems < 10 , perhaps FrontNonFloatingWindow
2188 WindowRef newActiveWindow = ::ActiveNonFloatingWindow() ;
2189 if ( newActiveWindow )
2191 wxWindow* win = wxFindWinFromMacWindow( newActiveWindow ) ;
2193 win->MacActivate( ev , false ) ;
2199 case mouseMovedMessage
:
2203 wxWindow
* currentMouseWindow
= NULL
;
2205 if (s_captureWindow
)
2207 currentMouseWindow
= s_captureWindow
;
2211 wxWindow::MacGetWindowFromPoint( wxPoint( ev
->where
.h
, ev
->where
.v
) ,
2212 ¤tMouseWindow
) ;
2215 if ( currentMouseWindow
!= wxWindow::s_lastMouseWindow
)
2217 wxMouseEvent event
;
2219 bool isDown
= !(ev
->modifiers
& btnState
) ; // 1 is for up
2220 bool controlDown
= ev
->modifiers
& controlKey
; // for simulating right mouse
2222 event
.m_leftDown
= isDown
&& !controlDown
;
2223 event
.m_middleDown
= FALSE
;
2224 event
.m_rightDown
= isDown
&& controlDown
;
2225 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
2226 event
.m_controlDown
= ev
->modifiers
& controlKey
;
2227 event
.m_altDown
= ev
->modifiers
& optionKey
;
2228 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
2229 event
.m_x
= ev
->where
.h
;
2230 event
.m_y
= ev
->where
.v
;
2231 event
.m_timeStamp
= ev
->when
;
2232 event
.SetEventObject(this);
2234 if ( wxWindow::s_lastMouseWindow
)
2236 wxMouseEvent
eventleave(event
);
2237 eventleave
.SetEventType( wxEVT_LEAVE_WINDOW
);
2238 wxWindow::s_lastMouseWindow
->ScreenToClient( &eventleave
.m_x
, &eventleave
.m_y
);
2239 eventleave
.SetEventObject( wxWindow::s_lastMouseWindow
) ;
2241 wxWindow::s_lastMouseWindow
->GetEventHandler()->ProcessEvent(eventleave
);
2243 if ( currentMouseWindow
)
2245 wxMouseEvent
evententer(event
);
2246 evententer
.SetEventType( wxEVT_ENTER_WINDOW
);
2247 currentMouseWindow
->ScreenToClient( &evententer
.m_x
, &evententer
.m_y
);
2248 evententer
.SetEventObject( currentMouseWindow
) ;
2249 currentMouseWindow
->GetEventHandler()->ProcessEvent(evententer
);
2251 wxWindow::s_lastMouseWindow
= currentMouseWindow
;
2254 short windowPart
= inNoWindow
;
2256 if ( s_captureWindow
)
2258 window
= (WindowRef
) s_captureWindow
->MacGetRootWindow() ;
2259 windowPart
= inContent
;
2263 windowPart
= ::FindWindow(ev
->where
, &window
);
2270 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
2272 win
->MacMouseMoved( ev
, windowPart
) ;
2279 UMAShowArrowCursor();
2289 UMAShowArrowCursor();
2299 void wxApp::MacHandleMenuSelect( int macMenuId
, int macMenuItemNum
)
2302 return; // no menu item selected
2304 if (macMenuId
== kwxMacAppleMenuId
&& macMenuItemNum
> 1)
2307 Str255 deskAccessoryName
;
2310 GetMenuItemText(GetMenuHandle(kwxMacAppleMenuId
), macMenuItemNum
, deskAccessoryName
);
2311 GetPort(&savedPort
);
2312 OpenDeskAcc(deskAccessoryName
);
2319 GetMenuItemCommandID( GetMenuHandle(macMenuId
) , macMenuItemNum
, &id
) ;
2320 wxMenuBar
* mbar
= wxMenuBar::MacGetInstalledMenuBar() ;
2321 wxMenu
* menu
= NULL
;
2322 wxMenuItem
* item
= NULL
;
2325 item
= mbar
->FindItem( id
, &menu
) ;
2327 wxCHECK_RET( item
!= NULL
&& menu
!= NULL
&& mbar
!= NULL
, wxT("error in menu item callback") );
2329 if (item
->IsCheckable())
2331 item
->Check( !item
->IsChecked() ) ;
2334 menu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) ;
2336 wxWindow* frontwindow = wxFindWinFromMacWindow( ::FrontWindow() ) ;
2337 wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, id );
2338 event.m_timeStamp = ((EventRecord*) MacGetCurrentEvent())->when ;
2339 event.SetEventObject(menu);
2340 event.SetInt(item->IsCheckable() ? item->IsChecked() : -1);
2341 frontwindow->GetEventHandler()->ProcessEvent(event);