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 #include "wx/docview.h"
41 #if wxUSE_WX_RESOURCES
42 # include "wx/resource.h"
57 #include "wx/mac/uma.h"
58 #include "wx/mac/macnotfy.h"
61 # include <CoreServices/CoreServices.h>
62 # if defined(WXMAKINGDLL)
63 # include <mach-o/dyld.h>
68 # include <ToolUtils.h>
69 # include <DiskInit.h>
73 extern char *wxBuffer
;
74 extern wxList wxPendingDelete
;
75 extern wxList
*wxWinMacWindowList
;
76 extern wxList
*wxWinMacControlList
;
78 static bool s_inYield
= FALSE
;
80 wxApp
*wxTheApp
= NULL
;
82 #if !USE_SHARED_LIBRARY
83 IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
)
84 BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
)
85 EVT_IDLE(wxApp::OnIdle
)
86 EVT_END_SESSION(wxApp::OnEndSession
)
87 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession
)
92 const short kMacMinHeap
= (29 * 1024) ;
93 // platform specific static variables
95 const short kwxMacMenuBarResource
= 1 ;
96 const short kwxMacAppleMenuId
= 1 ;
98 WXHRGN
wxApp::s_macCursorRgn
= NULL
;
99 wxWindow
* wxApp::s_captureWindow
= NULL
;
100 int wxApp::s_lastMouseDown
= 0 ;
101 long wxApp::sm_lastMessageTime
= 0;
102 long wxApp::s_lastModifiers
= 0 ;
105 bool wxApp::s_macDefaultEncodingIsPC
= true ;
106 bool wxApp::s_macSupportPCMenuShortcuts
= true ;
107 long wxApp::s_macAboutMenuItemId
= wxID_ABOUT
;
108 long wxApp::s_macPreferencesMenuItemId
= 0 ;
109 long wxApp::s_macExitMenuItemId
= wxID_EXIT
;
110 wxString
wxApp::s_macHelpMenuTitleName
= "&Help" ;
112 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
113 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
114 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
115 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
116 pascal OSErr
AEHandlePreferences( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
119 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
121 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
122 return wxTheApp
->MacHandleAEODoc( (AppleEvent
*) event
, reply
) ;
125 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
127 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
128 return wxTheApp
->MacHandleAEOApp( (AppleEvent
*) event
, reply
) ;
131 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
133 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
134 return wxTheApp
->MacHandleAEPDoc( (AppleEvent
*) event
, reply
) ;
137 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
139 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
140 return wxTheApp
->MacHandleAEQuit( (AppleEvent
*) event
, reply
) ;
143 pascal OSErr
AEHandlePreferences( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
145 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
147 wxMenuBar
* mbar
= wxMenuBar::MacGetInstalledMenuBar() ;
148 wxMenu
* menu
= NULL
;
149 wxMenuItem
* item
= NULL
;
152 item
= mbar
->FindItem( wxApp::s_macPreferencesMenuItemId
, &menu
) ;
154 if ( item
!= NULL
&& menu
!= NULL
&& mbar
!= NULL
)
155 menu
->SendEvent( wxApp::s_macPreferencesMenuItemId
, -1 ) ;
159 // new virtual public method in wxApp
160 void wxApp::MacOpenFile(const wxString
& fileName
)
162 wxDocManager
* dm
= wxDocManager::GetDocumentManager() ;
164 dm
->CreateDocument(fileName
, wxDOC_SILENT
) ;
167 void wxApp::MacPrintFile(const wxString
& fileName
)
169 wxDocManager
* dm
= wxDocManager::GetDocumentManager() ;
172 wxDocument
*doc
= dm
->CreateDocument(fileName
, wxDOC_SILENT
) ;
175 wxView
* view
= doc
->GetFirstView() ;
178 wxPrintout
*printout
= view
->OnCreatePrintout();
182 printer
.Print(view
->GetFrame(), printout
, TRUE
);
188 doc
->DeleteAllViews();
189 dm
->RemoveDocument(doc
) ;
195 void wxApp::MacNewFile()
199 // new implementation, which parses the event and calls
200 // MacOpenFile on each of the files it's passed
201 short wxApp::MacHandleAEODoc(const WXEVENTREF event
, WXEVENTREF
WXUNUSED(reply
))
205 DescType returnedType
;
211 err
= AEGetParamDesc((AppleEvent
*)event
, keyDirectObject
, typeAEList
,&docList
);
215 err
= AECountItems(&docList
, &itemsInList
);
219 ProcessSerialNumber PSN
;
220 PSN
.highLongOfPSN
= 0 ;
221 PSN
.lowLongOfPSN
= kCurrentProcess
;
222 SetFrontProcess( &PSN
) ;
224 for (i
= 1; i
<= itemsInList
; i
++) {
225 AEGetNthPtr(&docList
, i
, typeFSS
, &keywd
, &returnedType
,
226 (Ptr
) & theSpec
, sizeof(theSpec
), &actualSize
);
227 wxString fName
= wxMacFSSpec2MacFilename(&theSpec
);
233 short wxApp::MacHandleAEPDoc(const WXEVENTREF event
, WXEVENTREF
WXUNUSED(reply
))
237 DescType returnedType
;
243 err
= AEGetParamDesc((AppleEvent
*)event
, keyDirectObject
, typeAEList
,&docList
);
247 err
= AECountItems(&docList
, &itemsInList
);
251 ProcessSerialNumber PSN
;
252 PSN
.highLongOfPSN
= 0 ;
253 PSN
.lowLongOfPSN
= kCurrentProcess
;
254 SetFrontProcess( &PSN
) ;
256 for (i
= 1; i
<= itemsInList
; i
++) {
257 AEGetNthPtr(&docList
, i
, typeFSS
, &keywd
, &returnedType
,
258 (Ptr
) & theSpec
, sizeof(theSpec
), &actualSize
);
259 wxString fName
= wxMacFSSpec2MacFilename(&theSpec
);
265 short wxApp::MacHandleAEOApp(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
271 short wxApp::MacHandleAEQuit(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
273 wxWindow
* win
= GetTopWindow() ;
285 char StringMac
[] = "\x0d\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
286 "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
287 "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf"
288 "\xb1\xb4\xb5\xb6\xbb\xbc\xbe\xbf"
289 "\xc0\xc1\xc2\xc4\xc7\xc8\xc9\xcb\xcc\xcd\xce\xcf"
290 "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xca\xdb" ;
292 char StringANSI
[] = "\x0a\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8"
293 "\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC"
294 "\x86\xBA\xA2\xA3\xA7\x95\xB6\xDF\xAE\xA9\x99\xB4\xA8\xC6\xD8"
295 "\xB1\xA5\xB5\xF0\xAA\xBA\xE6\xF8"
296 "\xBF\xA1\xAC\x83\xAB\xBB\x85\xC0\xC3\xD5\x8C\x9C"
297 "\x96\x97\x93\x94\x91\x92\xF7\xFF\xA0\x80" ;
299 void wxMacConvertFromPC( const char *from
, char *to
, int len
)
304 for( int i
= 0 ; i
< len
; ++ i
)
306 c
= strchr( StringANSI
, *from
) ;
309 *to
= StringMac
[ c
- StringANSI
] ;
317 for( int i
= 0 ; i
< len
; ++ i
)
319 c
= strchr( StringANSI
, *from
) ;
322 *to
= StringMac
[ c
- StringANSI
] ;
334 void wxMacConvertToPC( const char *from
, char *to
, int len
)
339 for( int i
= 0 ; i
< len
; ++ i
)
341 c
= strchr( StringMac
, *from
) ;
344 *to
= StringANSI
[ c
- StringMac
] ;
352 for( int i
= 0 ; i
< len
; ++ i
)
354 c
= strchr( StringMac
, *from
) ;
357 *to
= StringANSI
[ c
- StringMac
] ;
369 void wxMacConvertFromPC( char * p
)
372 int len
= strlen ( p
) ;
374 wxMacConvertFromPC( ptr
, ptr
, len
) ;
377 void wxMacConvertFromPCForControls( char * p
)
380 int len
= strlen ( p
) ;
382 wxMacConvertFromPC( ptr
, ptr
, len
) ;
383 for ( unsigned int i
= 0 ; i
< strlen ( ptr
) ; i
++ )
385 if ( ptr
[i
] == '&' && ptr
[i
]+1 != ' ' )
387 memmove( &ptr
[i
] , &ptr
[i
+1] , strlen( &ptr
[i
+1] ) + 1) ;
392 void wxMacConvertFromPC( unsigned char *p
)
394 char *ptr
= (char*) p
+ 1 ;
397 wxMacConvertFromPC( ptr
, ptr
, len
) ;
400 extern char *wxBuffer
;
402 wxString
wxMacMakeMacStringFromPC( const char * p
)
404 const char *ptr
= p
;
405 int len
= strlen ( p
) ;
406 char *buf
= wxBuffer
;
408 if ( len
>= BUFSIZ
+ 512 )
410 buf
= new char [len
+1] ;
413 wxMacConvertFromPC( ptr
, buf
, len
) ;
415 wxString
result( buf
) ;
416 if ( buf
!= wxBuffer
)
422 void wxMacConvertToPC( char * p
)
425 int len
= strlen ( p
) ;
427 wxMacConvertToPC( ptr
, ptr
, len
) ;
430 void wxMacConvertToPC( unsigned char *p
)
432 char *ptr
= (char*) p
+ 1 ;
435 wxMacConvertToPC( ptr
, ptr
, len
) ;
438 wxString
wxMacMakePCStringFromMac( const char * p
)
440 const char *ptr
= p
;
441 int len
= strlen ( p
) ;
442 char *buf
= wxBuffer
;
444 if ( len
>= BUFSIZ
+ 512 )
446 buf
= new char [len
+1] ;
449 wxMacConvertToPC( ptr
, buf
, len
) ;
452 wxString
result( buf
) ;
453 if ( buf
!= wxBuffer
)
458 wxString
wxMacMakeStringFromMacString( const char* from
, bool mac2pcEncoding
)
462 return wxMacMakePCStringFromMac( from
) ;
466 return wxString( from
) ;
470 wxString
wxMacMakeStringFromPascal( StringPtr from
, bool mac2pcEncoding
)
472 // this is safe since a pascal string can never be larger than 256 bytes
474 CopyPascalStringToC( from
, s
) ;
477 return wxMacMakePCStringFromMac( s
) ;
481 return wxString( s
) ;
485 void wxMacStringToPascal( const char * from
, StringPtr to
, bool pc2macEncoding
)
489 CopyCStringToPascal( wxMacMakeMacStringFromPC( from
) , to
) ;
493 CopyCStringToPascal( from
, to
) ;
497 #if defined(WXMAKINGDLL) && !defined(__DARWIN__)
498 // we know it's there ;-)
499 WXIMPORT
char std::__throws_bad_alloc
;
502 bool wxApp::Initialize()
508 UMAInitToolbox( 4 ) ;
509 SetEventMask( everyEvent
) ;
510 UMAShowWatchCursor() ;
512 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
513 // open shared library resources from here since we don't have
514 // __wxinitialize in Mach-O shared libraries
515 wxStAppResource::OpenSharedLibraryResource(NULL
);
518 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
519 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
,
520 NewAEEventHandlerUPP(AEHandleODoc
) ,
521 (long) wxTheApp
, FALSE
) ;
522 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
,
523 NewAEEventHandlerUPP(AEHandleOApp
) ,
524 (long) wxTheApp
, FALSE
) ;
525 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
,
526 NewAEEventHandlerUPP(AEHandlePDoc
) ,
527 (long) wxTheApp
, FALSE
) ;
528 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
,
529 NewAEEventHandlerUPP(AEHandleQuit
) ,
530 (long) wxTheApp
, FALSE
) ;
532 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
,
533 NewAEEventHandlerProc(AEHandleODoc
) ,
534 (long) wxTheApp
, FALSE
) ;
535 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
,
536 NewAEEventHandlerProc(AEHandleOApp
) ,
537 (long) wxTheApp
, FALSE
) ;
538 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
,
539 NewAEEventHandlerProc(AEHandlePDoc
) ,
540 (long) wxTheApp
, FALSE
) ;
541 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
,
542 NewAEEventHandlerProc(AEHandleQuit
) ,
543 (long) wxTheApp
, FALSE
) ;
547 // test the minimal configuration necessary
553 if (Gestalt(gestaltMachineType
, &theMachine
) != noErr
)
555 error
= kMacSTRWrongMachine
;
557 else if (theMachine
< gestaltMacPlus
)
559 error
= kMacSTRWrongMachine
;
561 else if (Gestalt(gestaltSystemVersion
, &theSystem
) != noErr
)
563 error
= kMacSTROldSystem
;
565 else if ( theSystem
< 0x0860 )
567 error
= kMacSTROldSystem
;
569 else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap
)
571 error
= kMacSTRSmallSize
;
577 if ( !UMAHasAppearance() )
579 error = kMacSTRNoPre8Yet ;
585 // if we encountered any problems so far, give the error code and exit immediately
589 wxStAppResource resload
;
593 GetIndString(message
, 128, error
);
594 UMAShowArrowCursor() ;
595 ParamText("\pFatal Error", message
, (ConstStr255Param
)"\p", (ConstStr255Param
)"\p");
596 itemHit
= Alert(128, nil
);
601 # if __option(profile)
602 ProfilerInit( collectDetailed
, bestTimeBase
, 20000 , 40 ) ;
607 // now avoid exceptions thrown for new (bad_alloc)
608 std::__throws_bad_alloc
= FALSE
;
611 s_macCursorRgn
= ::NewRgn() ;
613 wxBuffer
= new char[BUFSIZ
+ 512];
615 wxClassInfo::InitializeClasses();
618 // wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion);
622 wxPendingEventsLocker
= new wxCriticalSection
;
625 wxTheColourDatabase
= new wxColourDatabase(wxKEY_STRING
);
626 wxTheColourDatabase
->Initialize();
630 // flush the logged messages if any and install a 'safer' log target: the
631 // default one (wxLogGui) can't be used after the resources are freed just
632 // below and the user suppliedo ne might be even more unsafe (using any
633 // wxWindows GUI function is unsafe starting from now)
634 wxLog::DontCreateOnDemand();
636 // this will flush the old messages if any
637 delete wxLog::SetActiveTarget(new wxLogStderr
);
641 wxWinMacWindowList
= new wxList(wxKEY_INTEGER
);
642 wxWinMacControlList
= new wxList(wxKEY_INTEGER
);
644 wxInitializeStockLists();
645 wxInitializeStockObjects();
647 #if wxUSE_WX_RESOURCES
648 wxInitializeResourceSystem();
651 wxBitmap::InitStandardHandlers();
653 wxModule::RegisterModules();
654 if (!wxModule::InitializeModules()) {
658 wxMacCreateNotifierTable() ;
661 UMAShowArrowCursor() ;
666 void wxApp::CleanUp()
668 wxToolTip::RemoveToolTips() ;
670 // flush the logged messages if any and install a 'safer' log target: the
671 // default one (wxLogGui) can't be used after the resources are freed just
672 // below and the user suppliedo ne might be even more unsafe (using any
673 // wxWindows GUI function is unsafe starting from now)
674 wxLog::DontCreateOnDemand();
676 // this will flush the old messages if any
677 delete wxLog::SetActiveTarget(new wxLogStderr
);
680 // One last chance for pending objects to be cleaned up
681 wxTheApp
->DeletePendingObjects();
683 wxModule::CleanUpModules();
685 #if wxUSE_WX_RESOURCES
686 wxCleanUpResourceSystem();
689 wxDeleteStockObjects() ;
691 // Destroy all GDI lists, etc.
692 wxDeleteStockLists();
694 delete wxTheColourDatabase
;
695 wxTheColourDatabase
= NULL
;
697 wxBitmap::CleanUpHandlers();
702 wxMacDestroyNotifierTable() ;
703 if (wxWinMacWindowList
) {
704 delete wxWinMacWindowList
;
706 if (wxWinMacControlList
) {
707 delete wxWinMacControlList
;
709 delete wxPendingEvents
;
712 delete wxPendingEventsLocker
;
713 // If we don't do the following, we get an apparent memory leak.
714 ((wxEvtHandler
&) wxDefaultValidator
).ClearEventLocker();
717 wxClassInfo::CleanUpClasses();
720 # if __option(profile)
721 ProfilerDump( "\papp.prof" ) ;
729 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
730 // At this point we want to check if there are any memory
731 // blocks that aren't part of the wxDebugContext itself,
732 // as a special case. Then when dumping we need to ignore
733 // wxDebugContext, too.
734 if (wxDebugContext::CountObjectsLeft(TRUE
) > 0)
736 wxLogDebug(wxT("There were memory leaks."));
737 wxDebugContext::Dump();
738 wxDebugContext::PrintStatistics();
740 // wxDebugContext::SetStream(NULL, NULL);
744 // do it as the very last thing because everything else can log messages
745 delete wxLog::SetActiveTarget(NULL
);
748 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
749 // close shared library resources from here since we don't have
750 // __wxterminate in Mach-O shared libraries
751 wxStAppResource::CloseSharedLibraryResource();
754 UMACleanupToolbox() ;
755 if (s_macCursorRgn
) {
756 ::DisposeRgn((RgnHandle
)s_macCursorRgn
);
764 //----------------------------------------------------------------------
766 //----------------------------------------------------------------------
768 // extern variable for shared library resource id
769 // need to be able to find it with NSLookupAndBindSymbol
770 short gSharedLibraryResource
= kResFileNotOpened
;
772 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
773 CFBundleRef gSharedLibraryBundle
= NULL
;
774 #endif /* WXMAKINGDLL && __DARWIN__ */
776 wxStAppResource::wxStAppResource()
778 m_currentRefNum
= CurResFile() ;
779 if ( gSharedLibraryResource
!= kResFileNotOpened
)
781 UseResFile( gSharedLibraryResource
) ;
785 wxStAppResource::~wxStAppResource()
787 if ( m_currentRefNum
!= kResFileNotOpened
)
789 UseResFile( m_currentRefNum
) ;
793 void wxStAppResource::OpenSharedLibraryResource(const void *initBlock
)
795 gSharedLibraryResource
= kResFileNotOpened
;
798 if ( initBlock
!= NULL
) {
799 const CFragInitBlock
*theInitBlock
= (const CFragInitBlock
*)initBlock
;
800 FSSpec
*fileSpec
= NULL
;
802 if (theInitBlock
->fragLocator
.where
== kDataForkCFragLocator
) {
803 fileSpec
= theInitBlock
->fragLocator
.u
.onDisk
.fileSpec
;
805 else if (theInitBlock
->fragLocator
.where
== kResourceCFragLocator
) {
806 fileSpec
= theInitBlock
->fragLocator
.u
.inSegs
.fileSpec
;
809 if (fileSpec
!= NULL
) {
810 gSharedLibraryResource
= FSpOpenResFile(fileSpec
, fsRdPerm
);
815 // Open the shared library resource file if it is not yet open
818 const char *theLibPath
;
820 gSharedLibraryBundle
= CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWindows"));
821 if (gSharedLibraryBundle
!= NULL
) {
822 // wxWindows has been bundled into a framework
823 // load the framework resources
825 gSharedLibraryResource
= CFBundleOpenBundleResourceMap(gSharedLibraryBundle
);
828 // wxWindows is a simple dynamic shared library
829 // load the resources from the data fork of a separate resource file
834 OSErr theErr
= noErr
;
836 // get the library path
837 theSymbol
= NSLookupAndBindSymbol("_gSharedLibraryResource");
838 theModule
= NSModuleForSymbol(theSymbol
);
839 theLibPath
= NSLibraryNameForModule(theModule
);
841 wxLogDebug( wxT("wxMac library installation name is '%s'"),
844 // allocate copy to replace .dylib.* extension with .rsrc
845 theResPath
= strdup(theLibPath
);
846 if (theResPath
!= NULL
) {
847 theName
= strrchr(theResPath
, '/');
848 if (theName
== NULL
) {
849 // no directory elements in path
850 theName
= theResPath
;
852 // find ".dylib" shared library extension
853 theExt
= strstr(theName
, ".dylib");
854 // overwrite extension with ".rsrc"
855 strcpy(theExt
, ".rsrc");
857 wxLogDebug( wxT("wxMac resources file name is '%s'"),
860 theErr
= FSPathMakeRef((UInt8
*) theResPath
, &theResRef
, false);
861 if (theErr
!= noErr
) {
862 // try in current directory (using name only)
863 theErr
= FSPathMakeRef((UInt8
*) theName
, &theResRef
, false);
866 // open the resource file
867 if (theErr
== noErr
) {
868 theErr
= FSOpenResourceFile( &theResRef
, 0, NULL
, fsRdPerm
,
869 &gSharedLibraryResource
);
871 if (theErr
!= noErr
) {
872 wxLogDebug( wxT("unable to open wxMac resource file '%s'"),
876 // free duplicated resource file path
880 #endif /* __DARWIN__ */
882 #endif /* WXMAKINGDLL */
885 void wxStAppResource::CloseSharedLibraryResource()
888 // Close the shared library resource file
889 if (gSharedLibraryResource
!= kResFileNotOpened
) {
891 if (gSharedLibraryBundle
!= NULL
) {
892 CFBundleCloseBundleResourceMap(gSharedLibraryBundle
,
893 gSharedLibraryResource
);
894 gSharedLibraryBundle
= NULL
;
897 #endif /* __DARWIN__ */
899 CloseResFile(gSharedLibraryResource
);
901 gSharedLibraryResource
= kResFileNotOpened
;
903 #endif /* WXMAKINGDLL */
906 #if defined(WXMAKINGDLL) && !defined(__DARWIN__)
908 // for shared libraries we have to manually get the correct resource
909 // ref num upon initializing and releasing when terminating, therefore
910 // the __wxinitialize and __wxterminate must be used
913 void __sinit(void); /* (generated by linker) */
914 pascal OSErr
__initialize(const CFragInitBlock
*theInitBlock
);
915 pascal void __terminate(void);
918 pascal OSErr
__wxinitialize(const CFragInitBlock
*theInitBlock
)
920 wxStAppResource::OpenSharedLibraryResource( theInitBlock
) ;
921 return __initialize( theInitBlock
) ;
924 pascal void __wxterminate(void)
926 wxStAppResource::CloseSharedLibraryResource() ;
930 #endif /* WXMAKINGDLL && !__DARWIN__ */
932 int WXDLLEXPORT
wxEntryStart( int WXUNUSED(argc
), char *WXUNUSED(argv
)[] )
934 return wxApp::Initialize();
937 int WXDLLEXPORT
wxEntryInitGui()
939 return wxTheApp
->OnInitGui();
942 void WXDLLEXPORT
wxEntryCleanup()
947 int wxEntry( int argc
, char *argv
[] , bool enterLoop
)
950 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
951 // This seems to be necessary since there are 'rogue'
952 // objects present at this point (perhaps global objects?)
953 // Setting a checkpoint will ignore them as far as the
954 // memory checking facility is concerned.
955 // Of course you may argue that memory allocated in globals should be
956 // checked, but this is a reasonable compromise.
957 wxDebugContext::SetCheckpoint();
960 if (!wxEntryStart(argc
, argv
)) {
963 // create the application object or ensure that one already exists
966 // The app may have declared a global application object, but we recommend
967 // the IMPLEMENT_APP macro is used instead, which sets an initializer
968 // function for delayed, dynamic app object construction.
969 wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
970 wxT("No initializer - use IMPLEMENT_APP macro.") );
972 wxTheApp
= (wxApp
*) (*wxApp::GetInitializerFunction()) ();
975 wxCHECK_MSG( wxTheApp
, 0, wxT("You have to define an instance of wxApp!") );
978 // Mac OS X passes a process serial number command line argument when
979 // the application is launched from the Finder. This argument must be
980 // removed from the command line arguments before being handled by the
981 // application (otherwise applications would need to handle it)
984 if (strncmp(argv
[1], "-psn_", 5) == 0) {
985 // assume the argument is always the only one and remove it
990 argc
= 0 ; // currently we don't support files as parameters
992 // we could try to get the open apple events here to adjust argc and argv better
994 wxTheApp
->argc
= argc
;
995 wxTheApp
->argv
= argv
;
997 // GUI-specific initialization, such as creating an app context.
1000 // Here frames insert themselves automatically
1001 // into wxTopLevelWindows by getting created
1006 if ( wxTheApp
->OnInit() )
1010 retValue
= wxTheApp
->OnRun();
1013 // We want to initialize, but not run or exit immediately.
1016 //else: app initialization failed, so we skipped OnRun()
1018 wxWindow
*topWindow
= wxTheApp
->GetTopWindow();
1021 // Forcibly delete the window.
1022 if ( topWindow
->IsKindOf(CLASSINFO(wxFrame
)) ||
1023 topWindow
->IsKindOf(CLASSINFO(wxDialog
)) )
1025 topWindow
->Close(TRUE
);
1026 wxTheApp
->DeletePendingObjects();
1031 wxTheApp
->SetTopWindow(NULL
);
1044 bool wxMacConvertEventToRecord( EventRef event
, EventRecord
*rec
)
1046 bool converted
= ConvertEventRefToEventRecord( event
,rec
) ;
1047 OSStatus err
= noErr
;
1050 switch( GetEventClass( event
) )
1052 case kEventClassKeyboard
:
1055 switch( GetEventKind(event
) )
1057 case kEventRawKeyDown
:
1058 rec
->what
= keyDown
;
1060 case kEventRawKeyRepeat
:
1061 rec
->what
= autoKey
;
1063 case kEventRawKeyUp
:
1066 case kEventRawKeyModifiersChanged
:
1067 rec
->what
= nullEvent
;
1076 unsigned char charCode
;
1078 GetMouse( &rec
->where
) ;
1080 err
= GetEventParameter(event
, kEventParamKeyModifiers
, typeUInt32
, NULL
, 4, NULL
, &modifiers
);
1081 err
= GetEventParameter(event
, kEventParamKeyCode
, typeUInt32
, NULL
, 4, NULL
, &keyCode
);
1082 err
= GetEventParameter(event
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, 1, NULL
, &charCode
);
1083 rec
->modifiers
= modifiers
;
1084 rec
->message
= (keyCode
<< 8 ) + charCode
;
1088 case kEventClassTextInput
:
1090 switch( GetEventKind( event
) )
1092 case kEventTextInputUnicodeForKeyEvent
:
1095 err
= GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
,typeEventRef
,NULL
,sizeof(rawEvent
),NULL
,&rawEvent
) ;
1099 unsigned char charCode
;
1101 GetMouse( &rec
->where
) ;
1102 rec
->what
= keyDown
;
1103 err
= GetEventParameter(rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, 4, NULL
, &modifiers
);
1104 err
= GetEventParameter(rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, 4, NULL
, &keyCode
);
1105 err
= GetEventParameter(rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, 1, NULL
, &charCode
);
1106 rec
->modifiers
= modifiers
;
1107 rec
->message
= (keyCode
<< 8 ) + charCode
;
1122 pascal OSStatus
wxMacApplicationEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
1124 OSStatus result
= eventNotHandledErr
;
1127 switch ( GetEventClass( event
) )
1129 case kEventClassKeyboard
:
1130 if ( wxMacConvertEventToRecord( event
, &rec
) )
1132 wxTheApp
->MacHandleModifierEvents( &rec
) ;
1133 wxTheApp
->MacHandleOneEvent( &rec
) ;
1137 case kEventClassTextInput
:
1138 if ( wxMacConvertEventToRecord( event
, &rec
) )
1140 wxTheApp
->MacHandleModifierEvents( &rec
) ;
1141 wxTheApp
->MacHandleOneEvent( &rec
) ;
1153 bool wxApp::OnInit()
1155 if ( ! wxAppBase::OnInit() )
1158 #if 0 // TARGET_CARBON
1159 static const EventTypeSpec eventList
[] =
1161 { kEventClassKeyboard
, kEventRawKeyDown
} ,
1162 { kEventClassKeyboard
, kEventRawKeyRepeat
} ,
1163 { kEventClassKeyboard
, kEventRawKeyUp
} ,
1164 { kEventClassKeyboard
, kEventRawKeyModifiersChanged
} ,
1166 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} ,
1169 InstallApplicationEventHandler(NewEventHandlerUPP(wxMacApplicationEventHandler
)
1170 , WXSIZEOF(eventList
), eventList
, this, NULL
);
1174 // Static member initialization
1175 wxAppInitializerFunction
wxAppBase::m_appInitFn
= (wxAppInitializerFunction
) NULL
;
1182 #if WXWIN_COMPATIBILITY_2_2
1183 m_wantDebugOutput
= TRUE
;
1189 m_printMode
= wxPRINT_WINDOWS
;
1193 bool wxApp::Initialized()
1201 int wxApp::MainLoop()
1206 if ( UMAGetSystemVersion() >= 0x1000 )
1208 if ( s_macPreferencesMenuItemId
)
1210 EnableMenuCommand( NULL
, kHICommandPreferences
) ;
1211 AEInstallEventHandler( kCoreEventClass
, kAEShowPreferences
,
1212 NewAEEventHandlerUPP(AEHandlePreferences
) ,
1213 (long) wxTheApp
, FALSE
) ;
1225 // Returns TRUE if more time is needed.
1226 bool wxApp::ProcessIdle()
1229 event
.SetEventObject(this);
1230 ProcessEvent(event
);
1232 return event
.MoreRequested();
1235 void wxApp::ExitMainLoop()
1237 m_keepGoing
= FALSE
;
1240 // Is a message/event pending?
1241 bool wxApp::Pending()
1245 return EventAvail( everyEvent
, &event
) ;
1248 // Dispatch a message.
1249 void wxApp::Dispatch()
1254 void wxApp::OnIdle(wxIdleEvent
& event
)
1256 static bool s_inOnIdle
= FALSE
;
1258 // Avoid recursion (via ProcessEvent default case)
1265 // 'Garbage' collection of windows deleted with Close().
1266 DeletePendingObjects();
1268 // flush the logged messages if any
1269 wxLog
*pLog
= wxLog::GetActiveTarget();
1270 if ( pLog
!= NULL
&& pLog
->HasPendingMessages() )
1273 // Send OnIdle events to all windows
1274 bool needMore
= SendIdleEvents();
1277 event
.RequestMore(TRUE
);
1279 // If they are pending events, we must process them: pending events are
1280 // either events to the threads other than main or events posted with
1281 // wxPostEvent() functions
1282 wxMacProcessNotifierAndPendingEvents();
1292 // Send idle event to all top-level windows
1293 bool wxApp::SendIdleEvents()
1295 bool needMore
= FALSE
;
1296 wxNode
* node
= wxTopLevelWindows
.First();
1299 wxWindow
* win
= (wxWindow
*) node
->Data();
1300 if (SendIdleEvents(win
))
1303 node
= node
->Next();
1308 // Send idle event to window and all subwindows
1309 bool wxApp::SendIdleEvents(wxWindow
* win
)
1311 bool needMore
= FALSE
;
1314 event
.SetEventObject(win
);
1315 win
->ProcessEvent(event
);
1317 if (event
.MoreRequested())
1320 wxNode
* node
= win
->GetChildren().First();
1323 wxWindow
* win
= (wxWindow
*) node
->Data();
1324 if (SendIdleEvents(win
))
1327 node
= node
->Next();
1332 void wxApp::DeletePendingObjects()
1334 wxNode
*node
= wxPendingDelete
.First();
1337 wxObject
*obj
= (wxObject
*)node
->Data();
1341 if (wxPendingDelete
.Member(obj
))
1344 // Deleting one object may have deleted other pending
1345 // objects, so start from beginning of list again.
1346 node
= wxPendingDelete
.First();
1352 wxLogError(_("Fatal error: exiting"));
1358 void wxApp::OnEndSession(wxCloseEvent
& WXUNUSED(event
))
1361 GetTopWindow()->Close(TRUE
);
1364 // Default behaviour: close the application with prompts. The
1365 // user can veto the close, and therefore the end session.
1366 void wxApp::OnQueryEndSession(wxCloseEvent
& event
)
1370 if (!GetTopWindow()->Close(!event
.CanVeto()))
1375 extern "C" void wxCYield() ;
1381 // Yield to other processes
1383 bool wxApp::Yield(bool onlyIfNeeded
)
1387 if ( !onlyIfNeeded
)
1389 wxFAIL_MSG( wxT("wxYield called recursively" ) );
1398 YieldToAnyThread() ;
1402 long sleepTime
= 1 ; //::GetCaretTime();
1404 while ( !wxTheApp
->IsExiting() && WaitNextEvent(everyEvent
, &event
,sleepTime
, (RgnHandle
) wxApp::s_macCursorRgn
))
1406 wxTheApp
->MacHandleModifierEvents( &event
) ;
1407 wxTheApp
->MacHandleOneEvent( &event
);
1408 if ( event
.what
!= kHighLevelEvent
)
1409 SetRectRgn( (RgnHandle
) wxApp::s_macCursorRgn
, event
.where
.h
, event
.where
.v
, event
.where
.h
+ 1 , event
.where
.v
+ 1 ) ;
1411 wxTheApp
->MacHandleModifierEvents( &event
) ;
1413 wxMacProcessNotifierAndPendingEvents() ;
1420 // platform specifics
1422 void wxApp::MacSuspend( bool convertClipboard
)
1424 // we have to deactive the top level windows manually
1426 wxNode
* node
= wxTopLevelWindows
.First();
1429 wxTopLevelWindow
* win
= (wxTopLevelWindow
*) node
->Data();
1430 win
->MacActivate( MacGetCurrentEvent() , false ) ;
1432 node
= node
->Next();
1435 s_lastMouseDown
= 0 ;
1436 if( convertClipboard
)
1438 MacConvertPrivateToPublicScrap() ;
1441 ::HideFloatingWindows() ;
1444 extern wxList wxModalDialogs
;
1446 void wxApp::MacResume( bool convertClipboard
)
1448 s_lastMouseDown
= 0 ;
1449 if( convertClipboard
)
1451 MacConvertPublicToPrivateScrap() ;
1454 ::ShowFloatingWindows() ;
1456 // raise modal dialogs in case a non modal window was selected to activate the app
1458 wxNode
* node
= wxModalDialogs
.First();
1461 wxDialog
* dialog
= (wxDialog
*) node
->Data();
1464 node
= node
->Next();
1468 void wxApp::MacConvertPrivateToPublicScrap()
1472 void wxApp::MacConvertPublicToPrivateScrap()
1476 void wxApp::MacDoOneEvent()
1480 long sleepTime
= 1; // GetCaretTime() / 4 ;
1482 if (WaitNextEvent(everyEvent
, &event
, sleepTime
, (RgnHandle
) s_macCursorRgn
))
1484 MacHandleModifierEvents( &event
) ;
1485 MacHandleOneEvent( &event
);
1489 MacHandleModifierEvents( &event
) ;
1491 WindowPtr window
= ::FrontWindow() ;
1493 ::IdleControls( window
) ;
1495 wxTheApp
->ProcessIdle() ;
1497 if ( event
.what
!= kHighLevelEvent
)
1498 SetRectRgn( (RgnHandle
) s_macCursorRgn
, event
.where
.h
, event
.where
.v
, event
.where
.h
+ 1 , event
.where
.v
+ 1 ) ;
1502 DeletePendingObjects() ;
1503 wxMacProcessNotifierAndPendingEvents() ;
1506 void wxApp::MacHandleModifierEvents( WXEVENTREF evr
)
1508 EventRecord
* ev
= (EventRecord
*) evr
;
1510 if ( ev
->what
== mouseDown
|| ev
->what
== mouseUp
|| ev
->what
== activateEvt
||
1511 ev
->what
== keyDown
|| ev
->what
== autoKey
|| ev
->what
== keyUp
|| ev
->what
== kHighLevelEvent
||
1512 ev
->what
== nullEvent
1515 // in these cases the modifiers are already correctly setup by carbon
1520 WaitNextEvent( 0 , &nev
, 0 , NULL
) ;
1521 ev
->modifiers
= nev
.modifiers
;
1522 // KeyModifiers unfortunately don't include btnState...
1523 // ev->modifiers = GetCurrentKeyModifiers() ;
1526 if ( ev
->modifiers
!= s_lastModifiers
&& wxWindow::FindFocus() != NULL
)
1528 wxKeyEvent
event(wxEVT_KEY_DOWN
);
1530 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
1531 event
.m_controlDown
= ev
->modifiers
& controlKey
;
1532 event
.m_altDown
= ev
->modifiers
& optionKey
;
1533 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
1535 event
.m_x
= ev
->where
.h
;
1536 event
.m_y
= ev
->where
.v
;
1537 event
.m_timeStamp
= ev
->when
;
1538 wxWindow
* focus
= wxWindow::FindFocus() ;
1539 event
.SetEventObject(focus
);
1541 if ( (ev
->modifiers
^ s_lastModifiers
) & controlKey
)
1543 event
.m_keyCode
= WXK_CONTROL
;
1544 event
.SetEventType( ( ev
->modifiers
& controlKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
1545 focus
->GetEventHandler()->ProcessEvent( event
) ;
1547 if ( (ev
->modifiers
^ s_lastModifiers
) & shiftKey
)
1549 event
.m_keyCode
= WXK_SHIFT
;
1550 event
.SetEventType( ( ev
->modifiers
& shiftKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
1551 focus
->GetEventHandler()->ProcessEvent( event
) ;
1553 if ( (ev
->modifiers
^ s_lastModifiers
) & optionKey
)
1555 event
.m_keyCode
= WXK_ALT
;
1556 event
.SetEventType( ( ev
->modifiers
& optionKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
1557 focus
->GetEventHandler()->ProcessEvent( event
) ;
1559 s_lastModifiers
= ev
->modifiers
;
1563 void wxApp::MacHandleOneEvent( WXEVENTREF evr
)
1565 EventRecord
* ev
= (EventRecord
*) evr
;
1566 m_macCurrentEvent
= ev
;
1568 wxApp::sm_lastMessageTime
= ev
->when
;
1573 MacHandleMouseDownEvent( ev
) ;
1574 if ( ev
->modifiers
& controlKey
)
1575 s_lastMouseDown
= 2;
1577 s_lastMouseDown
= 1;
1580 if ( s_lastMouseDown
== 2 )
1582 ev
->modifiers
|= controlKey
;
1586 ev
->modifiers
&= ~controlKey
;
1588 MacHandleMouseUpEvent( ev
) ;
1589 s_lastMouseDown
= 0;
1592 MacHandleActivateEvent( ev
) ;
1595 MacHandleUpdateEvent( ev
) ;
1599 MacHandleKeyDownEvent( ev
) ;
1602 MacHandleKeyUpEvent( ev
) ;
1605 MacHandleDiskEvent( ev
) ;
1608 MacHandleOSEvent( ev
) ;
1610 case kHighLevelEvent
:
1611 MacHandleHighLevelEvent( ev
) ;
1616 wxMacProcessNotifierAndPendingEvents() ;
1619 void wxApp::MacHandleHighLevelEvent( WXEVENTREF evr
)
1621 // we must avoid reentrancy problems when processing high level events eg printing
1622 bool former
= s_inYield
;
1624 EventRecord
* ev
= (EventRecord
*) evr
;
1625 ::AEProcessAppleEvent( ev
) ;
1626 s_inYield
= former
;
1629 bool s_macIsInModalLoop
= false ;
1631 void wxApp::MacHandleMouseDownEvent( WXEVENTREF evr
)
1633 EventRecord
* ev
= (EventRecord
*) evr
;
1634 wxToolTip::RemoveToolTips() ;
1637 WindowRef frontWindow
= ::FrontNonFloatingWindow() ;
1638 WindowAttributes frontWindowAttributes
= NULL
;
1640 ::GetWindowAttributes( frontWindow
, &frontWindowAttributes
) ;
1642 short windowPart
= ::FindWindow(ev
->where
, &window
);
1643 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
1644 if ( wxPendingDelete
.Member(win
) )
1648 GetQDGlobalsScreenBits( &screenBits
);
1653 if ( s_macIsInModalLoop
)
1659 UInt32 menuresult
= MenuSelect(ev
->where
) ;
1660 MacHandleMenuSelect( HiWord( menuresult
) , LoWord( menuresult
) );
1661 s_lastMouseDown
= 0;
1666 SystemClick( ev
, window
) ;
1667 s_lastMouseDown
= 0;
1671 if ( window
!= frontWindow
&& s_macIsInModalLoop
&& !(ev
->modifiers
& cmdKey
) )
1677 DragWindow(window
, ev
->where
, &screenBits
.bounds
);
1682 Point pt
= { 0, 0 } ;
1683 SetPortWindowPort(window
) ;
1684 LocalToGlobal( &pt
) ;
1686 win
->SetSize( pt
.h
, pt
.v
, -1 ,
1687 -1 , wxSIZE_USE_EXISTING
);
1689 s_lastMouseDown
= 0;
1693 if (TrackGoAway(window
, ev
->where
))
1698 s_lastMouseDown
= 0;
1702 Rect newContentRect
;
1703 Rect constraintRect
;
1704 constraintRect
.top
= win
->GetMinHeight() ;
1705 if ( constraintRect
.top
== -1 )
1706 constraintRect
.top
= 0 ;
1707 constraintRect
.left
= win
->GetMinWidth() ;
1708 if ( constraintRect
.left
== -1 )
1709 constraintRect
.left
= 0 ;
1710 constraintRect
.right
= win
->GetMaxWidth() ;
1711 if ( constraintRect
.right
== -1 )
1712 constraintRect
.right
= 32000 ;
1713 constraintRect
.bottom
= win
->GetMaxHeight() ;
1714 if ( constraintRect
.bottom
== -1 )
1715 constraintRect
.bottom
= 32000 ;
1717 Boolean growResult
= ResizeWindow( window
, ev
->where
,
1718 &constraintRect
, &newContentRect
) ;
1721 win
->SetSize( newContentRect
.left
, newContentRect
.top
,
1722 newContentRect
.right
- newContentRect
.left
,
1723 newContentRect
.bottom
- newContentRect
.top
, wxSIZE_USE_EXISTING
);
1725 s_lastMouseDown
= 0;
1730 if (TrackBox(window
, ev
->where
, windowPart
))
1732 // TODO setup size event
1733 ZoomWindow( window
, windowPart
, false ) ;
1739 Point pt
= { 0, 0 } ;
1740 SetPortWindowPort(window
) ;
1741 LocalToGlobal( &pt
) ;
1744 GetWindowPortBounds(window
, &tempRect
) ;
1745 win
->SetSize( pt
.h
, pt
.v
, tempRect
.right
-tempRect
.left
,
1746 tempRect
.bottom
-tempRect
.top
, wxSIZE_USE_EXISTING
);
1749 s_lastMouseDown
= 0;
1751 case inCollapseBox
:
1752 // TODO setup size event
1753 s_lastMouseDown
= 0;
1760 SetPortWindowPort(window
) ;
1763 if ( window
!= frontWindow
&& wxTheApp
->s_captureWindow
== NULL
)
1765 if ( s_macIsInModalLoop
)
1769 else if ( UMAIsWindowFloating( window
) )
1772 win
->MacMouseDown( ev
, windowPart
) ;
1777 win
->MacMouseDown( ev
, windowPart
) ;
1778 ::SelectWindow( window
) ;
1784 win
->MacMouseDown( ev
, windowPart
) ;
1793 void wxApp::MacHandleMouseUpEvent( WXEVENTREF evr
)
1795 EventRecord
* ev
= (EventRecord
*) evr
;
1798 short windowPart
= inNoWindow
;
1799 if ( wxTheApp
->s_captureWindow
)
1801 window
= (WindowRef
) s_captureWindow
->MacGetRootWindow() ;
1802 windowPart
= inContent
;
1806 windowPart
= ::FindWindow(ev
->where
, &window
) ;
1817 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
1819 win
->MacMouseUp( ev
, windowPart
) ;
1825 long wxMacTranslateKey(unsigned char key
, unsigned char code
) ;
1826 long wxMacTranslateKey(unsigned char key
, unsigned char code
)
1831 case kHomeCharCode
:
1834 case kEnterCharCode
:
1835 retval
= WXK_RETURN
;
1840 case kHelpCharCode
:
1843 case kBackspaceCharCode
:
1849 case kPageUpCharCode
:
1850 retval
= WXK_PAGEUP
;
1852 case kPageDownCharCode
:
1853 retval
= WXK_PAGEDOWN
;
1855 case kReturnCharCode
:
1856 retval
= WXK_RETURN
;
1858 case kFunctionKeyCharCode
:
1910 case kEscapeCharCode
:
1911 retval
= WXK_ESCAPE
;
1913 case kLeftArrowCharCode
:
1916 case kRightArrowCharCode
:
1917 retval
= WXK_RIGHT
;
1919 case kUpArrowCharCode
:
1922 case kDownArrowCharCode
:
1925 case kDeleteCharCode
:
1926 retval
= WXK_DELETE
;
1934 void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr
)
1936 EventRecord
* ev
= (EventRecord
*) evr
;
1937 wxToolTip::RemoveToolTips() ;
1939 UInt32 menuresult
= UMAMenuEvent(ev
) ;
1940 if ( HiWord( menuresult
) )
1942 if ( !s_macIsInModalLoop
)
1943 MacHandleMenuSelect( HiWord( menuresult
) , LoWord( menuresult
) ) ;
1947 wxWindow
* focus
= wxWindow::FindFocus() ;
1949 if ( MacSendKeyDownEvent( focus
, ev
->message
, ev
->modifiers
, ev
->when
, ev
->where
.h
, ev
->where
.v
) == false )
1951 // has not been handled -> perform default
1952 wxControl
* control
= wxDynamicCast( focus
, wxControl
) ;
1953 if ( control
&& control
->GetMacControl() != NULL
)
1957 keychar
= short(ev
->message
& charCodeMask
);
1958 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1959 ::HandleControlKey( (ControlHandle
) control
->GetMacControl() , keycode
, keychar
, ev
->modifiers
) ;
1965 bool wxApp::MacSendKeyDownEvent( wxWindow
* focus
, long keymessage
, long modifiers
, long when
, short wherex
, short wherey
)
1972 keychar
= short(keymessage
& charCodeMask
);
1973 keycode
= short(keymessage
& keyCodeMask
) >> 8 ;
1975 if ( modifiers
& ( controlKey
|shiftKey
|optionKey
) )
1977 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
1978 // and look at the character after
1980 UInt32 keyInfo
= KeyTranslate((Ptr
)GetScriptManagerVariable(smKCHRCache
), ( modifiers
& (~(controlKey
|shiftKey
|optionKey
))) | keycode
, &state
);
1981 keychar
= short(keyInfo
& charCodeMask
);
1982 keycode
= short(keyInfo
& keyCodeMask
) >> 8 ;
1984 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
1985 long realkeyval
= keyval
;
1986 if ( keyval
== keychar
)
1988 // 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)
1989 realkeyval
= short(keymessage
& charCodeMask
) ;
1990 keyval
= wxToupper( keyval
) ;
1993 wxKeyEvent
event(wxEVT_KEY_DOWN
);
1994 bool handled
= false ;
1995 event
.m_shiftDown
= modifiers
& shiftKey
;
1996 event
.m_controlDown
= modifiers
& controlKey
;
1997 event
.m_altDown
= modifiers
& optionKey
;
1998 event
.m_metaDown
= modifiers
& cmdKey
;
1999 event
.m_keyCode
= keyval
;
2003 event
.m_timeStamp
= when
;
2004 event
.SetEventObject(focus
);
2005 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
2006 if ( handled
&& event
.GetSkipped() )
2013 wxWindow
*ancestor
= focus
;
2016 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
2019 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
2020 handled
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
2023 if (ancestor
->IsTopLevel())
2025 ancestor
= ancestor
->GetParent();
2028 #endif // wxUSE_ACCEL
2032 event
.Skip( FALSE
) ;
2033 event
.SetEventType( wxEVT_CHAR
) ;
2035 event
.m_keyCode
= realkeyval
;
2037 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
2038 if ( handled
&& event
.GetSkipped() )
2042 (keyval
== WXK_TAB
) &&
2043 // CS: copied the change below from wxGTK
2044 // VZ: testing for wxTE_PROCESS_TAB shouldn't be done here the control may
2045 // have this style, yet choose not to process this particular TAB in which
2046 // case TAB must still work as a navigational character
2048 (!focus
->HasFlag(wxTE_PROCESS_TAB
)) &&
2050 (focus
->GetParent()) &&
2051 (focus
->GetParent()->HasFlag( wxTAB_TRAVERSAL
)) )
2053 wxNavigationKeyEvent new_event
;
2054 new_event
.SetEventObject( focus
);
2055 new_event
.SetDirection( !event
.ShiftDown() );
2056 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
2057 new_event
.SetWindowChange( event
.ControlDown() );
2058 new_event
.SetCurrentFocus( focus
);
2059 handled
= focus
->GetEventHandler()->ProcessEvent( new_event
);
2060 if ( handled
&& new_event
.GetSkipped() )
2063 // backdoor handler for default return and command escape
2064 if ( !handled
&& (!focus
->IsKindOf(CLASSINFO(wxControl
) ) || !focus
->MacCanFocus() ) )
2066 // if window is not having a focus still testing for default enter or cancel
2067 // TODO add the UMA version for ActiveNonFloatingWindow
2068 wxWindow
* focus
= wxFindWinFromMacWindow( FrontWindow() ) ;
2071 if ( keyval
== WXK_RETURN
)
2073 wxButton
*def
= wxDynamicCast(focus
->GetDefaultItem(),
2075 if ( def
&& def
->IsEnabled() )
2077 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
2078 event
.SetEventObject(def
);
2079 def
->Command(event
);
2083 /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
2084 else if (keyval
== WXK_ESCAPE
|| (keyval
== '.' && modifiers
& cmdKey
) )
2086 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
2087 new_event
.SetEventObject( focus
);
2088 handled
= focus
->GetEventHandler()->ProcessEvent( new_event
);
2096 void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr
)
2098 EventRecord
* ev
= (EventRecord
*) evr
;
2099 wxToolTip::RemoveToolTips() ;
2101 UInt32 menuresult
= UMAMenuEvent(ev
) ;
2102 if ( HiWord( menuresult
) )
2107 MacSendKeyUpEvent( wxWindow::FindFocus() , ev
->message
, ev
->modifiers
, ev
->when
, ev
->where
.h
, ev
->where
.v
) ;
2111 bool wxApp::MacSendKeyUpEvent( wxWindow
* focus
, long keymessage
, long modifiers
, long when
, short wherex
, short wherey
)
2118 keychar
= short(keymessage
& charCodeMask
);
2119 keycode
= short(keymessage
& keyCodeMask
) >> 8 ;
2120 if ( modifiers
& ( controlKey
|shiftKey
|optionKey
) )
2122 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
2123 // and look at the character after
2125 UInt32 keyInfo
= KeyTranslate((Ptr
)GetScriptManagerVariable(smKCHRCache
), ( modifiers
& (~(controlKey
|shiftKey
|optionKey
))) | keycode
, &state
);
2126 keychar
= short(keyInfo
& charCodeMask
);
2127 keycode
= short(keyInfo
& keyCodeMask
) >> 8 ;
2129 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
2131 if ( keyval
== keychar
)
2133 keyval
= wxToupper( keyval
) ;
2135 bool handled
= false ;
2137 wxKeyEvent
event(wxEVT_KEY_UP
);
2138 event
.m_shiftDown
= modifiers
& shiftKey
;
2139 event
.m_controlDown
= modifiers
& controlKey
;
2140 event
.m_altDown
= modifiers
& optionKey
;
2141 event
.m_metaDown
= modifiers
& cmdKey
;
2142 event
.m_keyCode
= keyval
;
2146 event
.m_timeStamp
= when
;
2147 event
.SetEventObject(focus
);
2148 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
2152 void wxApp::MacHandleActivateEvent( WXEVENTREF evr
)
2154 EventRecord
* ev
= (EventRecord
*) evr
;
2155 WindowRef window
= (WindowRef
) ev
->message
;
2158 bool activate
= (ev
->modifiers
& activeFlag
) ;
2159 WindowClass wclass
;
2160 ::GetWindowClass ( window
, &wclass
) ;
2161 if ( wclass
== kFloatingWindowClass
)
2163 // if it is a floater we activate/deactivate the front non-floating window instead
2164 window
= ::FrontNonFloatingWindow() ;
2166 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
2168 win
->MacActivate( ev
, activate
) ;
2172 void wxApp::MacHandleUpdateEvent( WXEVENTREF evr
)
2174 EventRecord
* ev
= (EventRecord
*) evr
;
2175 WindowRef window
= (WindowRef
) ev
->message
;
2176 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
2179 if ( !wxPendingDelete
.Member(win
) )
2180 win
->MacUpdate( ev
->when
) ;
2184 // since there is no way of telling this foreign window to update itself
2185 // we have to invalidate the update region otherwise we keep getting the same
2186 // event over and over again
2187 BeginUpdate( window
) ;
2188 EndUpdate( window
) ;
2192 void wxApp::MacHandleDiskEvent( WXEVENTREF evr
)
2194 EventRecord
* ev
= (EventRecord
*) evr
;
2195 if ( HiWord( ev
->message
) != noErr
)
2200 SetPt( &point
, 100 , 100 ) ;
2202 err
= DIBadMount( point
, ev
->message
) ;
2203 wxASSERT( err
== noErr
) ;
2208 void wxApp::MacHandleOSEvent( WXEVENTREF evr
)
2210 EventRecord
* ev
= (EventRecord
*) evr
;
2211 switch( ( ev
->message
& osEvtMessageMask
) >> 24 )
2213 case suspendResumeMessage
:
2215 bool isResuming
= ev
->message
& resumeFlag
;
2217 bool convertClipboard
= ev
->message
& convertClipboardFlag
;
2219 bool convertClipboard
= false;
2221 bool doesActivate
= UMAGetProcessModeDoesActivateOnFGSwitch() ;
2224 WindowRef oldFrontWindow
= NULL
;
2225 WindowRef newFrontWindow
= NULL
;
2227 // in case we don't take care of activating ourselves, we have to synchronize
2228 // our idea of the active window with the process manager's - which it already activated
2230 if ( !doesActivate
)
2231 oldFrontWindow
= ::FrontNonFloatingWindow() ;
2233 MacResume( convertClipboard
) ;
2235 newFrontWindow
= ::FrontNonFloatingWindow() ;
2237 if ( oldFrontWindow
)
2239 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( oldFrontWindow
) ;
2241 win
->MacActivate( ev
, false ) ;
2243 if ( newFrontWindow
)
2245 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( newFrontWindow
) ;
2247 win
->MacActivate( ev
, true ) ;
2252 MacSuspend( convertClipboard
) ;
2254 // in case this suspending did close an active window, another one might
2255 // have surfaced -> lets deactivate that one
2257 /* TODO : find out what to do on systems < 10 , perhaps FrontNonFloatingWindow
2258 WindowRef newActiveWindow = ::ActiveNonFloatingWindow() ;
2259 if ( newActiveWindow )
2261 wxWindow* win = wxFindWinFromMacWindow( newActiveWindow ) ;
2263 win->MacActivate( ev , false ) ;
2269 case mouseMovedMessage
:
2273 wxWindow
* currentMouseWindow
= NULL
;
2275 if (s_captureWindow
)
2277 currentMouseWindow
= s_captureWindow
;
2281 wxWindow::MacGetWindowFromPoint( wxPoint( ev
->where
.h
, ev
->where
.v
) ,
2282 ¤tMouseWindow
) ;
2285 if ( currentMouseWindow
!= wxWindow::s_lastMouseWindow
)
2287 wxMouseEvent event
;
2289 bool isDown
= !(ev
->modifiers
& btnState
) ; // 1 is for up
2290 bool controlDown
= ev
->modifiers
& controlKey
; // for simulating right mouse
2292 event
.m_leftDown
= isDown
&& !controlDown
;
2293 event
.m_middleDown
= FALSE
;
2294 event
.m_rightDown
= isDown
&& controlDown
;
2295 event
.m_shiftDown
= ev
->modifiers
& shiftKey
;
2296 event
.m_controlDown
= ev
->modifiers
& controlKey
;
2297 event
.m_altDown
= ev
->modifiers
& optionKey
;
2298 event
.m_metaDown
= ev
->modifiers
& cmdKey
;
2299 event
.m_x
= ev
->where
.h
;
2300 event
.m_y
= ev
->where
.v
;
2301 event
.m_timeStamp
= ev
->when
;
2302 event
.SetEventObject(this);
2304 if ( wxWindow::s_lastMouseWindow
)
2306 wxMouseEvent
eventleave(event
);
2307 eventleave
.SetEventType( wxEVT_LEAVE_WINDOW
);
2308 wxWindow::s_lastMouseWindow
->ScreenToClient( &eventleave
.m_x
, &eventleave
.m_y
);
2309 eventleave
.SetEventObject( wxWindow::s_lastMouseWindow
) ;
2311 wxWindow::s_lastMouseWindow
->GetEventHandler()->ProcessEvent(eventleave
);
2313 if ( currentMouseWindow
)
2315 wxMouseEvent
evententer(event
);
2316 evententer
.SetEventType( wxEVT_ENTER_WINDOW
);
2317 currentMouseWindow
->ScreenToClient( &evententer
.m_x
, &evententer
.m_y
);
2318 evententer
.SetEventObject( currentMouseWindow
) ;
2319 currentMouseWindow
->GetEventHandler()->ProcessEvent(evententer
);
2321 wxWindow::s_lastMouseWindow
= currentMouseWindow
;
2324 short windowPart
= inNoWindow
;
2326 if ( s_captureWindow
)
2328 window
= (WindowRef
) s_captureWindow
->MacGetRootWindow() ;
2329 windowPart
= inContent
;
2333 windowPart
= ::FindWindow(ev
->where
, &window
);
2340 wxTopLevelWindowMac
* win
= wxFindWinFromMacWindow( window
) ;
2342 win
->MacMouseMoved( ev
, windowPart
) ;
2349 UMAShowArrowCursor();
2359 UMAShowArrowCursor();
2369 void wxApp::MacHandleMenuSelect( int macMenuId
, int macMenuItemNum
)
2372 return; // no menu item selected
2374 if (macMenuId
== kwxMacAppleMenuId
&& macMenuItemNum
> 1)
2377 Str255 deskAccessoryName
;
2380 GetMenuItemText(GetMenuHandle(kwxMacAppleMenuId
), macMenuItemNum
, deskAccessoryName
);
2381 GetPort(&savedPort
);
2382 OpenDeskAcc(deskAccessoryName
);
2389 GetMenuItemCommandID( GetMenuHandle(macMenuId
) , macMenuItemNum
, &id
) ;
2390 wxMenuBar
* mbar
= wxMenuBar::MacGetInstalledMenuBar() ;
2391 wxMenu
* menu
= NULL
;
2392 wxMenuItem
* item
= NULL
;
2395 item
= mbar
->FindItem( id
, &menu
) ;
2397 wxCHECK_RET( item
!= NULL
&& menu
!= NULL
&& mbar
!= NULL
, wxT("error in menu item callback") );
2399 if (item
->IsCheckable())
2401 item
->Check( !item
->IsChecked() ) ;
2404 menu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) ;
2406 wxWindow* frontwindow = wxFindWinFromMacWindow( ::FrontWindow() ) ;
2407 wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, id );
2408 event.m_timeStamp = ((EventRecord*) MacGetCurrentEvent())->when ;
2409 event.SetEventObject(menu);
2410 event.SetInt(item->IsCheckable() ? item->IsChecked() : -1);
2411 frontwindow->GetEventHandler()->ProcessEvent(event);