1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
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"
40 #include "wx/filename.h"
54 #include "wx/mac/uma.h"
55 #include "wx/mac/macnotfy.h"
58 # include <CoreServices/CoreServices.h>
59 # if defined(WXMAKINGDLL_CORE)
60 # include <mach-o/dyld.h>
65 # include <ToolUtils.h>
66 # include <DiskInit.h>
70 extern wxList wxPendingDelete
;
73 extern size_t g_numberOfThreads
;
74 #endif // wxUSE_THREADS
76 // statics for implementation
78 static bool s_inYield
= FALSE
;
80 static bool s_inReceiveEvent
= FALSE
;
81 static EventTime sleepTime
= kEventDurationNoWait
;
83 #if !USE_SHARED_LIBRARY
84 IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
)
85 BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
)
86 EVT_IDLE(wxApp::OnIdle
)
87 EVT_END_SESSION(wxApp::OnEndSession
)
88 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession
)
93 const short kMacMinHeap
= (29 * 1024) ;
94 // platform specific static variables
96 const short kwxMacMenuBarResource
= 1 ;
97 const short kwxMacAppleMenuId
= 1 ;
99 WXHRGN
wxApp::s_macCursorRgn
= NULL
;
100 wxWindow
* wxApp::s_captureWindow
= NULL
;
101 int wxApp::s_lastMouseDown
= 0 ;
102 long wxApp::sm_lastMessageTime
= 0;
103 long wxApp::s_lastModifiers
= 0 ;
106 bool wxApp::s_macSupportPCMenuShortcuts
= true ;
107 long wxApp::s_macAboutMenuItemId
= wxID_ABOUT
;
108 long wxApp::s_macPreferencesMenuItemId
= wxID_PREFERENCES
;
109 long wxApp::s_macExitMenuItemId
= wxID_EXIT
;
110 wxString
wxApp::s_macHelpMenuTitleName
= wxT("&Help") ;
112 // Normally we're not a plugin
113 bool wxApp::sm_isEmbedded
= false;
114 //----------------------------------------------------------------------
115 // Core Apple Event Support
116 //----------------------------------------------------------------------
118 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
119 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
120 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
121 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
122 pascal OSErr
AEHandleRApp( const AppleEvent
*event
, AppleEvent
*reply
, long refcon
) ;
124 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
126 return wxTheApp
->MacHandleAEODoc( (AppleEvent
*) event
, reply
) ;
129 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
131 return wxTheApp
->MacHandleAEOApp( (AppleEvent
*) event
, reply
) ;
134 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
136 return wxTheApp
->MacHandleAEPDoc( (AppleEvent
*) event
, reply
) ;
139 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
141 return wxTheApp
->MacHandleAEQuit( (AppleEvent
*) event
, reply
) ;
144 pascal OSErr
AEHandleRApp( const AppleEvent
*event
, AppleEvent
*reply
, long WXUNUSED(refcon
) )
146 return wxTheApp
->MacHandleAERApp( (AppleEvent
*) event
, reply
) ;
149 // AEODoc Calls MacOpenFile on each of the files passed
151 short wxApp::MacHandleAEODoc(const WXEVENTREF event
, WXEVENTREF
WXUNUSED(reply
))
155 DescType returnedType
;
161 err
= AEGetParamDesc((AppleEvent
*)event
, keyDirectObject
, typeAEList
,&docList
);
165 err
= AECountItems(&docList
, &itemsInList
);
169 ProcessSerialNumber PSN
;
170 PSN
.highLongOfPSN
= 0 ;
171 PSN
.lowLongOfPSN
= kCurrentProcess
;
172 SetFrontProcess( &PSN
) ;
174 for (i
= 1; i
<= itemsInList
; i
++) {
175 AEGetNthPtr(&docList
, i
, typeFSS
, &keywd
, &returnedType
,
176 (Ptr
) & theSpec
, sizeof(theSpec
), &actualSize
);
177 wxString fName
= wxMacFSSpec2MacFilename(&theSpec
);
183 // AEPDoc Calls MacPrintFile on each of the files passed
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 // AEOApp calls MacNewFile
219 short wxApp::MacHandleAEOApp(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
225 // AEQuit attempts to quit the application
227 short wxApp::MacHandleAEQuit(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
229 wxWindow
* win
= GetTopWindow() ;
232 wxCommandEvent
exitEvent(wxEVT_COMMAND_MENU_SELECTED
, s_macExitMenuItemId
);
233 if (!win
->ProcessEvent(exitEvent
))
243 // AEROApp calls MacReopenApp
245 short wxApp::MacHandleAERApp(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
252 //----------------------------------------------------------------------
253 // Support Routines linking the Mac...File Calls to the Document Manager
254 //----------------------------------------------------------------------
256 void wxApp::MacOpenFile(const wxString
& fileName
)
258 wxDocManager
* dm
= wxDocManager::GetDocumentManager() ;
260 dm
->CreateDocument(fileName
, wxDOC_SILENT
) ;
263 void wxApp::MacPrintFile(const wxString
& fileName
)
265 wxDocManager
* dm
= wxDocManager::GetDocumentManager() ;
268 wxDocument
*doc
= dm
->CreateDocument(fileName
, wxDOC_SILENT
) ;
271 wxView
* view
= doc
->GetFirstView() ;
274 wxPrintout
*printout
= view
->OnCreatePrintout();
278 printer
.Print(view
->GetFrame(), printout
, TRUE
);
284 doc
->DeleteAllViews();
285 dm
->RemoveDocument(doc
) ;
291 void wxApp::MacNewFile()
295 void wxApp::MacReopenApp()
297 // eventually check for open docs, if none, call MacNewFile
300 //----------------------------------------------------------------------
301 // Carbon Event Handler
302 //----------------------------------------------------------------------
304 static const EventTypeSpec eventList
[] =
306 { kEventClassCommand
, kEventProcessCommand
} ,
307 { kEventClassCommand
, kEventCommandUpdateStatus
} ,
309 { kEventClassMenu
, kEventMenuOpening
},
310 { kEventClassMenu
, kEventMenuClosed
},
311 { kEventClassMenu
, kEventMenuTargetItem
},
313 { kEventClassApplication
, kEventAppActivated
} ,
314 { kEventClassApplication
, kEventAppDeactivated
} ,
315 // handling the quit event is not recommended by apple
316 // rather using the quit apple event - which we do
318 { kEventClassAppleEvent
, kEventAppleEvent
} ,
320 { kEventClassMouse
, kEventMouseDown
} ,
321 { kEventClassMouse
, kEventMouseMoved
} ,
322 { kEventClassMouse
, kEventMouseUp
} ,
323 { kEventClassMouse
, kEventMouseDragged
} ,
327 static pascal OSStatus
328 wxMacAppMenuEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
330 wxMenuBar
* mbar
= wxMenuBar::MacGetInstalledMenuBar();
334 wxFrame
* win
= mbar
->GetFrame();
338 // VZ: we could find the menu from its handle here by examining all
339 // the menus in the menu bar recursively but knowing that neither
340 // wxMSW nor wxGTK do it why bother...
344 GetEventParameter(event
,
345 kEventParamDirectObject
,
347 sizeof(menuRef
), NULL
,
353 switch (GetEventKind(event
))
355 case kEventMenuOpening
:
356 type
= wxEVT_MENU_OPEN
;
358 case kEventMenuClosed
:
359 type
= wxEVT_MENU_CLOSE
;
361 case kEventMenuTargetItem
:
362 type
= wxEVT_MENU_HIGHLIGHT
;
363 GetEventParameter(event
, kEventParamMenuCommand
,
364 typeMenuCommand
, NULL
,
365 sizeof(cmd
), NULL
, &cmd
);
366 if (cmd
== 0) return eventNotHandledErr
;
369 wxFAIL_MSG(wxT("Unexpected menu event kind"));
373 wxMenuEvent
wxevent(type
, cmd
);
374 wxevent
.SetEventObject(win
);
376 (void)win
->GetEventHandler()->ProcessEvent(wxevent
);
380 return eventNotHandledErr
;
383 static pascal OSStatus
wxMacAppCommandEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
385 OSStatus result
= eventNotHandledErr
;
389 GetEventParameter( event
, kEventParamDirectObject
, typeHICommand
, NULL
,
390 sizeof( HICommand
), NULL
, &command
);
392 MenuCommand id
= command
.commandID
;
393 if ( id
== kHICommandPreferences
)
394 id
= wxApp::s_macPreferencesMenuItemId
;
396 wxMenuBar
* mbar
= wxMenuBar::MacGetInstalledMenuBar() ;
397 wxMenu
* menu
= NULL
;
398 wxMenuItem
* item
= NULL
;
402 item
= mbar
->FindItem( id
, &menu
) ;
403 // it is not 100 % sure that an menu of id 0 is really ours, safety check
404 if ( id
== 0 && menu
!= NULL
&& menu
->GetHMenu() != command
.menu
.menuRef
)
411 if ( item
== NULL
|| menu
== NULL
|| mbar
== NULL
)
414 switch( GetEventKind( event
) )
416 case kEventProcessCommand
:
418 if (item
->IsCheckable())
420 item
->Check( !item
->IsChecked() ) ;
423 menu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) ;
427 case kEventCommandUpdateStatus
:
428 // eventually trigger an updateui round
438 static pascal OSStatus
wxMacAppApplicationEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
440 OSStatus result
= eventNotHandledErr
;
441 switch ( GetEventKind( event
) )
443 case kEventAppActivated
:
446 wxTheApp
->SetActive( true , NULL
) ;
450 case kEventAppDeactivated
:
453 wxTheApp
->SetActive( false , NULL
) ;
463 pascal OSStatus
wxMacAppEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
465 OSStatus result
= eventNotHandledErr
;
466 switch( GetEventClass( event
) )
468 case kEventClassCommand
:
469 result
= wxMacAppCommandEventHandler( handler
, event
, data
) ;
471 case kEventClassApplication
:
472 result
= wxMacAppApplicationEventHandler( handler
, event
, data
) ;
474 case kEventClassMenu
:
475 result
= wxMacAppMenuEventHandler( handler
, event
, data
) ;
477 case kEventClassMouse
:
478 result
= wxMacTopLevelMouseEventHandler( handler
, event
, NULL
) ;
480 case kEventClassAppleEvent
:
483 wxMacConvertEventToRecord( event
, &rec
) ;
484 result
= AEProcessAppleEvent( &rec
) ;
494 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacAppEventHandler
)
496 #if defined(WXMAKINGDLL_CORE) && !defined(__DARWIN__)
497 // we know it's there ;-)
498 WXIMPORT
char std::__throws_bad_alloc
;
501 pascal static void wxMacAssertOutputHandler(OSType componentSignature
, UInt32 options
,
502 const char *assertionString
, const char *exceptionLabelString
,
503 const char *errorString
, const char *fileName
, long lineNumber
, void *value
, ConstStr255Param outputMsg
)
505 // flow into assert handling
506 wxString fileNameStr
;
507 wxString assertionStr
;
508 wxString exceptionStr
;
511 fileNameStr
= wxString(fileName
, wxConvLocal
);
512 assertionStr
= wxString(assertionString
, wxConvLocal
);
513 exceptionStr
= wxString((exceptionLabelString
!=0) ? exceptionLabelString
: "", wxConvLocal
) ;
514 errorStr
= wxString((errorString
!=0) ? errorString
: "", wxConvLocal
) ;
516 fileNameStr
= fileName
;
517 assertionStr
= assertionString
;
518 exceptionStr
= (exceptionLabelString
!=0) ? exceptionLabelString
: "" ;
519 errorStr
= (errorString
!=0) ? errorString
: "" ;
524 wxLogDebug( wxT("AssertMacros: %s %s %s file: %s, line: %ld (value %p)\n"),
525 assertionStr
.c_str() ,
526 exceptionStr
.c_str() ,
528 fileNameStr
.c_str(), lineNumber
,
532 wxOnAssert(fileNameStr
, lineNumber
, assertionStr
,
533 wxString::Format( wxT("%s %s value (%p)") ,exceptionStr
, errorStr
, value
) ) ;
537 bool wxApp::Initialize(int& argc
, wxChar
**argv
)
542 InstallDebugAssertOutputHandler ( NewDebugAssertOutputHandlerUPP( wxMacAssertOutputHandler
) );
544 UMAInitToolbox( 4, sm_isEmbedded
) ;
545 SetEventMask( everyEvent
) ;
546 UMAShowWatchCursor() ;
548 #if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
549 // open shared library resources from here since we don't have
550 // __wxinitialize in Mach-O shared libraries
551 wxStAppResource::OpenSharedLibraryResource(NULL
);
555 # if __option(profile)
556 ProfilerInit( collectDetailed
, bestTimeBase
, 40000 , 50 ) ;
561 // now avoid exceptions thrown for new (bad_alloc)
562 // FIXME CS for some changes outside wxMac does not compile anymore
564 std::__throws_bad_alloc
= 0 ;
569 s_macCursorRgn
= ::NewRgn() ;
571 // Mac OS X passes a process serial number command line argument when
572 // the application is launched from the Finder. This argument must be
573 // removed from the command line arguments before being handled by the
574 // application (otherwise applications would need to handle it)
577 static const wxChar
*ARG_PSN
= _T("-psn_");
578 if ( wxStrncmp(argv
[1], ARG_PSN
, wxStrlen(ARG_PSN
)) == 0 )
580 // remove this argument
582 memmove(argv
+ 1, argv
+ 2, argc
* sizeof(char *));
586 if ( !wxAppBase::Initialize(argc
, argv
) )
590 wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
594 wxMacCreateNotifierTable() ;
596 UMAShowArrowCursor() ;
601 bool wxApp::OnInitGui()
603 if( !wxAppBase::OnInitGui() )
606 InstallStandardEventHandler( GetApplicationEventTarget() ) ;
610 InstallApplicationEventHandler(
611 GetwxMacAppEventHandlerUPP(),
612 GetEventTypeCount(eventList
), eventList
, wxTheApp
, (EventHandlerRef
*)&(wxTheApp
->m_macEventHandler
));
617 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
,
618 NewAEEventHandlerUPP(AEHandleODoc
) ,
620 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
,
621 NewAEEventHandlerUPP(AEHandleOApp
) ,
623 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
,
624 NewAEEventHandlerUPP(AEHandlePDoc
) ,
626 AEInstallEventHandler( kCoreEventClass
, kAEReopenApplication
,
627 NewAEEventHandlerUPP(AEHandleRApp
) ,
629 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
,
630 NewAEEventHandlerUPP(AEHandleQuit
) ,
637 void wxApp::CleanUp()
639 wxToolTip::RemoveToolTips() ;
641 // One last chance for pending objects to be cleaned up
642 wxTheApp
->DeletePendingObjects();
644 wxMacDestroyNotifierTable() ;
647 # if __option(profile)
648 ProfilerDump( (StringPtr
)"\papp.prof" ) ;
653 #if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
654 // close shared library resources from here since we don't have
655 // __wxterminate in Mach-O shared libraries
656 wxStAppResource::CloseSharedLibraryResource();
659 UMACleanupToolbox() ;
660 if (s_macCursorRgn
) {
661 ::DisposeRgn((RgnHandle
)s_macCursorRgn
);
668 wxAppBase::CleanUp();
671 //----------------------------------------------------------------------
672 // misc initialization stuff
673 //----------------------------------------------------------------------
675 // extern variable for shared library resource id
676 // need to be able to find it with NSLookupAndBindSymbol
677 short gSharedLibraryResource
= kResFileNotOpened
;
679 #if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
680 CFBundleRef gSharedLibraryBundle
= NULL
;
681 #endif /* WXMAKINGDLL_CORE && __DARWIN__ */
683 wxStAppResource::wxStAppResource()
685 m_currentRefNum
= CurResFile() ;
686 if ( gSharedLibraryResource
!= kResFileNotOpened
)
688 UseResFile( gSharedLibraryResource
) ;
692 wxStAppResource::~wxStAppResource()
694 if ( m_currentRefNum
!= kResFileNotOpened
)
696 UseResFile( m_currentRefNum
) ;
700 void wxStAppResource::OpenSharedLibraryResource(const void *initBlock
)
702 gSharedLibraryResource
= kResFileNotOpened
;
704 #ifdef WXMAKINGDLL_CORE
705 if ( initBlock
!= NULL
) {
706 const CFragInitBlock
*theInitBlock
= (const CFragInitBlock
*)initBlock
;
707 FSSpec
*fileSpec
= NULL
;
709 if (theInitBlock
->fragLocator
.where
== kDataForkCFragLocator
) {
710 fileSpec
= theInitBlock
->fragLocator
.u
.onDisk
.fileSpec
;
712 else if (theInitBlock
->fragLocator
.where
== kResourceCFragLocator
) {
713 fileSpec
= theInitBlock
->fragLocator
.u
.inSegs
.fileSpec
;
716 if (fileSpec
!= NULL
) {
717 gSharedLibraryResource
= FSpOpenResFile(fileSpec
, fsRdPerm
);
722 // Open the shared library resource file if it is not yet open
725 const char *theLibPath
;
727 gSharedLibraryBundle
= CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWindows"));
728 if (gSharedLibraryBundle
!= NULL
) {
729 // wxWindows has been bundled into a framework
730 // load the framework resources
732 gSharedLibraryResource
= CFBundleOpenBundleResourceMap(gSharedLibraryBundle
);
735 // wxWindows is a simple dynamic shared library
736 // load the resources from the data fork of a separate resource file
740 OSErr theErr
= noErr
;
742 // get the library path
743 theSymbol
= NSLookupAndBindSymbol("_gSharedLibraryResource");
744 theModule
= NSModuleForSymbol(theSymbol
);
745 theLibPath
= NSLibraryNameForModule(theModule
);
747 // if we call wxLogDebug from here then, as wxTheApp hasn't been
748 // created yet when we're called from wxApp::Initialize(), wxLog
749 // is going to create a default stderr-based log target instead of
750 // the expected normal GUI one -- don't do it, if we really want
751 // to see this message just use fprintf() here
753 wxLogDebug( wxT("wxMac library installation name is '%s'"),
757 // allocate copy to replace .dylib.* extension with .rsrc
758 if (theLibPath
!= NULL
) {
760 theResPath
= wxString(theLibPath
, wxConvLocal
);
762 theResPath
= wxString(theLibPath
);
764 // replace '_core' with '' in case of multi-lib build
765 theResPath
.Replace(wxT("_core"), wxEmptyString
);
766 // replace ".dylib" shared library extension with ".rsrc"
767 theResPath
.Replace(wxT(".dylib"), wxT(".rsrc"));
768 // Find the begining of the filename
769 theName
= theResPath
.AfterLast('/');
772 wxLogDebug( wxT("wxMac resources file name is '%s'"),
773 theResPath
.mb_str() );
776 theErr
= FSPathMakeRef((UInt8
*) theResPath
.mb_str(), &theResRef
, false);
777 if (theErr
!= noErr
) {
778 // try in current directory (using name only)
779 theErr
= FSPathMakeRef((UInt8
*) theName
.mb_str(), &theResRef
, false);
782 // open the resource file
783 if (theErr
== noErr
) {
784 theErr
= FSOpenResourceFile( &theResRef
, 0, NULL
, fsRdPerm
,
785 &gSharedLibraryResource
);
787 if (theErr
!= noErr
) {
789 wxLogDebug( wxT("unable to open wxMac resource file '%s'\n"),
790 theResPath
.mb_str() );
791 #endif // __WXDEBUG__
796 #endif /* __DARWIN__ */
798 #endif /* WXMAKINGDLL_CORE */
801 void wxStAppResource::CloseSharedLibraryResource()
803 #ifdef WXMAKINGDLL_CORE
804 // Close the shared library resource file
805 if (gSharedLibraryResource
!= kResFileNotOpened
) {
807 if (gSharedLibraryBundle
!= NULL
) {
808 CFBundleCloseBundleResourceMap(gSharedLibraryBundle
,
809 gSharedLibraryResource
);
810 gSharedLibraryBundle
= NULL
;
813 #endif /* __DARWIN__ */
815 CloseResFile(gSharedLibraryResource
);
817 gSharedLibraryResource
= kResFileNotOpened
;
819 #endif /* WXMAKINGDLL_CORE */
822 #if defined(WXMAKINGDLL_CORE) && !defined(__DARWIN__)
824 // for shared libraries we have to manually get the correct resource
825 // ref num upon initializing and releasing when terminating, therefore
826 // the __wxinitialize and __wxterminate must be used
829 void __sinit(void); /* (generated by linker) */
830 pascal OSErr
__initialize(const CFragInitBlock
*theInitBlock
);
831 pascal void __terminate(void);
834 pascal OSErr
__wxinitialize(const CFragInitBlock
*theInitBlock
)
836 wxStAppResource::OpenSharedLibraryResource( theInitBlock
) ;
837 return __initialize( theInitBlock
) ;
840 pascal void __wxterminate(void)
842 wxStAppResource::CloseSharedLibraryResource() ;
846 #endif /* WXMAKINGDLL_CORE && !__DARWIN__ */
848 bool wxMacConvertEventToRecord( EventRef event
, EventRecord
*rec
)
850 bool converted
= ConvertEventRefToEventRecord( event
,rec
) ;
851 OSStatus err
= noErr
;
854 switch( GetEventClass( event
) )
856 case kEventClassKeyboard
:
859 switch( GetEventKind(event
) )
861 case kEventRawKeyDown
:
862 rec
->what
= keyDown
;
864 case kEventRawKeyRepeat
:
865 rec
->what
= autoKey
;
867 case kEventRawKeyUp
:
870 case kEventRawKeyModifiersChanged
:
871 rec
->what
= nullEvent
;
880 unsigned char charCode
;
882 GetMouse( &rec
->where
) ;
884 err
= GetEventParameter(event
, kEventParamKeyModifiers
, typeUInt32
, NULL
, 4, NULL
, &modifiers
);
885 err
= GetEventParameter(event
, kEventParamKeyCode
, typeUInt32
, NULL
, 4, NULL
, &keyCode
);
886 err
= GetEventParameter(event
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, 1, NULL
, &charCode
);
887 rec
->modifiers
= modifiers
;
888 rec
->message
= (keyCode
<< 8 ) + charCode
;
892 case kEventClassTextInput
:
894 switch( GetEventKind( event
) )
896 case kEventTextInputUnicodeForKeyEvent
:
899 err
= GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
,typeEventRef
,NULL
,sizeof(rawEvent
),NULL
,&rawEvent
) ;
903 unsigned char charCode
;
905 GetMouse( &rec
->where
) ;
906 rec
->what
= keyDown
;
907 err
= GetEventParameter(rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, 4, NULL
, &modifiers
);
908 err
= GetEventParameter(rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, 4, NULL
, &keyCode
);
909 err
= GetEventParameter(rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, 1, NULL
, &charCode
);
910 rec
->modifiers
= modifiers
;
911 rec
->message
= (keyCode
<< 8 ) + charCode
;
928 m_printMode
= wxPRINT_WINDOWS
;
930 m_macCurrentEvent
= NULL
;
931 m_macCurrentEventHandlerCallRef
= NULL
;
934 int wxApp::MainLoop()
946 void wxApp::ExitMainLoop()
951 // Is a message/event pending?
952 bool wxApp::Pending()
954 // without the receive event (with pull param = false ) nothing is ever reported
956 ReceiveNextEvent (0, NULL
, kEventDurationNoWait
, false, &theEvent
);
957 return GetNumEventsInQueue( GetMainEventQueue() ) > 0 ;
960 // Dispatch a message.
961 bool wxApp::Dispatch()
968 void wxApp::OnIdle(wxIdleEvent
& event
)
970 wxAppBase::OnIdle(event
);
972 // If they are pending events, we must process them: pending events are
973 // either events to the threads other than main or events posted with
974 // wxPostEvent() functions
975 wxMacProcessNotifierAndPendingEvents();
977 if(!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar())
978 wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar();
981 void wxApp::WakeUpIdle()
992 void wxApp::OnEndSession(wxCloseEvent
& WXUNUSED(event
))
995 GetTopWindow()->Close(TRUE
);
998 // Default behaviour: close the application with prompts. The
999 // user can veto the close, and therefore the end session.
1000 void wxApp::OnQueryEndSession(wxCloseEvent
& event
)
1004 if (!GetTopWindow()->Close(!event
.CanVeto()))
1009 extern "C" void wxCYield() ;
1015 // Yield to other processes
1017 bool wxApp::Yield(bool onlyIfNeeded
)
1021 if ( !onlyIfNeeded
)
1023 wxFAIL_MSG( wxT("wxYield called recursively" ) );
1032 YieldToAnyThread() ;
1034 // by definition yield should handle all non-processed events
1038 OSStatus status
= noErr
;
1041 s_inReceiveEvent
= true ;
1042 status
= ReceiveNextEvent(0, NULL
,kEventDurationNoWait
,true,&theEvent
) ;
1043 s_inReceiveEvent
= false ;
1045 if ( status
== eventLoopTimedOutErr
)
1047 // make sure next time the event loop will trigger idle events
1048 sleepTime
= kEventDurationNoWait
;
1050 else if ( status
== eventLoopQuitErr
)
1052 // according to QA1061 this may also occur when a WakeUp Process
1057 MacHandleOneEvent( theEvent
) ;
1058 ReleaseEvent(theEvent
);
1060 } while( status
== noErr
) ;
1062 wxMacProcessNotifierAndPendingEvents() ;
1068 void wxApp::MacDoOneEvent()
1072 s_inReceiveEvent
= true ;
1073 OSStatus status
= ReceiveNextEvent(0, NULL
,sleepTime
,true,&theEvent
) ;
1074 s_inReceiveEvent
= false ;
1075 if ( status
== eventLoopTimedOutErr
)
1077 if ( wxTheApp
->ProcessIdle() )
1078 sleepTime
= kEventDurationNoWait
;
1082 if (g_numberOfThreads
)
1084 YieldToAnyThread() ;
1085 sleepTime
= kEventDurationNoWait
;
1088 #endif // wxUSE_THREADS
1090 sleepTime
= kEventDurationSecond
;
1094 else if ( status
== eventLoopQuitErr
)
1096 // according to QA1061 this may also occur when a WakeUp Process
1101 MacHandleOneEvent( theEvent
) ;
1102 ReleaseEvent(theEvent
);
1103 sleepTime
= kEventDurationNoWait
;
1107 DeletePendingObjects() ;
1108 wxMacProcessNotifierAndPendingEvents() ;
1111 /*virtual*/ void wxApp::MacHandleUnhandledEvent( WXEVENTREF evr
)
1113 // Override to process unhandled events as you please
1116 void wxApp::MacHandleOneEvent( WXEVENTREF evr
)
1118 EventTargetRef theTarget
;
1119 theTarget
= GetEventDispatcherTarget();
1120 m_macCurrentEvent
= evr
;
1121 OSStatus status
= SendEventToEventTarget ((EventRef
) evr
, theTarget
);
1122 if(status
== eventNotHandledErr
)
1124 MacHandleUnhandledEvent(evr
);
1126 wxMacProcessNotifierAndPendingEvents() ;
1128 wxMutexGuiLeaveOrEnter();
1129 #endif // wxUSE_THREADS
1132 long wxMacTranslateKey(unsigned char key
, unsigned char code
) ;
1133 long wxMacTranslateKey(unsigned char key
, unsigned char code
)
1138 case kHomeCharCode
:
1141 case kEnterCharCode
:
1142 retval
= WXK_RETURN
;
1147 case kHelpCharCode
:
1150 case kBackspaceCharCode
:
1156 case kPageUpCharCode
:
1157 retval
= WXK_PAGEUP
;
1159 case kPageDownCharCode
:
1160 retval
= WXK_PAGEDOWN
;
1162 case kReturnCharCode
:
1163 retval
= WXK_RETURN
;
1165 case kFunctionKeyCharCode
:
1217 case kEscapeCharCode
:
1218 retval
= WXK_ESCAPE
;
1220 case kLeftArrowCharCode
:
1223 case kRightArrowCharCode
:
1224 retval
= WXK_RIGHT
;
1226 case kUpArrowCharCode
:
1229 case kDownArrowCharCode
:
1232 case kDeleteCharCode
:
1233 retval
= WXK_DELETE
;
1241 int wxMacKeyCodeToModifier(wxKeyCode key
)
1266 bool wxGetKeyState(wxKeyCode key
) //virtual key code if < 10.2.x, else see below
1269 // wxHIDKeyboard keyboard;
1270 // return keyboard.IsActive(key);
1272 // TODO: Have it use HID Manager on OSX...
1273 //if OS X > 10.2 (i.e. 10.2.x)
1274 //a known apple bug prevents the system from determining led
1275 //states with GetKeys... can only determine caps lock led
1276 return !!(GetCurrentKeyModifiers() & wxMacKeyCodeToModifier(key
));
1278 // KeyMapByteArray keymap;
1279 // GetKeys((BigEndianLong*)keymap);
1280 // return !!(BitTst(keymap, (sizeof(KeyMapByteArray)*8) - iKey));
1285 bool wxApp::MacSendKeyDownEvent( wxWindow
* focus
, long keymessage
, long modifiers
, long when
, short wherex
, short wherey
)
1292 keychar
= short(keymessage
& charCodeMask
);
1293 keycode
= short(keymessage
& keyCodeMask
) >> 8 ;
1295 if ( modifiers
& ( controlKey
|shiftKey
|optionKey
) )
1297 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
1298 // and look at the character after
1300 UInt32 keyInfo
= KeyTranslate((Ptr
)GetScriptManagerVariable(smKCHRCache
), ( modifiers
& (~(controlKey
|shiftKey
|optionKey
))) | keycode
, &state
);
1301 keychar
= short(keyInfo
& charCodeMask
);
1302 keycode
= short(keyInfo
& keyCodeMask
) >> 8 ;
1304 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
1305 long realkeyval
= keyval
;
1306 if ( keyval
== keychar
)
1308 // 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)
1309 realkeyval
= short(keymessage
& charCodeMask
) ;
1310 keyval
= wxToupper( keyval
) ;
1313 wxKeyEvent
event(wxEVT_KEY_DOWN
);
1314 bool handled
= false ;
1315 event
.m_shiftDown
= modifiers
& shiftKey
;
1316 event
.m_controlDown
= modifiers
& controlKey
;
1317 event
.m_altDown
= modifiers
& optionKey
;
1318 event
.m_metaDown
= modifiers
& cmdKey
;
1319 event
.m_keyCode
= keyval
;
1323 event
.m_timeStamp
= when
;
1324 event
.SetEventObject(focus
);
1325 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1326 if ( handled
&& event
.GetSkipped() )
1333 wxWindow
*ancestor
= focus
;
1336 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
1339 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
1340 handled
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
1343 if (ancestor
->IsTopLevel())
1345 ancestor
= ancestor
->GetParent();
1348 #endif // wxUSE_ACCEL
1352 event
.Skip( FALSE
) ;
1353 event
.SetEventType( wxEVT_CHAR
) ;
1355 event
.m_keyCode
= realkeyval
;
1357 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;
1358 if ( handled
&& event
.GetSkipped() )
1361 if ( !handled
&& (keyval
== WXK_TAB
) )
1363 wxWindow
* iter
= focus
->GetParent() ;
1364 while( iter
&& !handled
)
1366 if ( iter
->HasFlag( wxTAB_TRAVERSAL
) )
1368 wxNavigationKeyEvent new_event
;
1369 new_event
.SetEventObject( focus
);
1370 new_event
.SetDirection( !event
.ShiftDown() );
1371 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
1372 new_event
.SetWindowChange( event
.ControlDown() );
1373 new_event
.SetCurrentFocus( focus
);
1374 handled
= focus
->GetParent()->GetEventHandler()->ProcessEvent( new_event
);
1375 if ( handled
&& new_event
.GetSkipped() )
1378 iter
= iter
->GetParent() ;
1381 // backdoor handler for default return and command escape
1382 if ( !handled
&& (!focus
->IsKindOf(CLASSINFO(wxControl
) ) || !focus
->MacCanFocus() ) )
1384 // if window is not having a focus still testing for default enter or cancel
1385 // TODO add the UMA version for ActiveNonFloatingWindow
1386 wxWindow
* focus
= wxFindWinFromMacWindow( FrontWindow() ) ;
1389 if ( keyval
== WXK_RETURN
)
1391 wxButton
*def
= wxDynamicCast(focus
->GetDefaultItem(),
1393 if ( def
&& def
->IsEnabled() )
1395 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1396 event
.SetEventObject(def
);
1397 def
->Command(event
);
1401 /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
1402 else if (keyval
== WXK_ESCAPE
|| (keyval
== '.' && modifiers
& cmdKey
) )
1404 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
1405 new_event
.SetEventObject( focus
);
1406 handled
= focus
->GetEventHandler()->ProcessEvent( new_event
);
1413 bool wxApp::MacSendKeyUpEvent( wxWindow
* focus
, long keymessage
, long modifiers
, long when
, short wherex
, short wherey
)
1420 keychar
= short(keymessage
& charCodeMask
);
1421 keycode
= short(keymessage
& keyCodeMask
) >> 8 ;
1422 if ( modifiers
& ( controlKey
|shiftKey
|optionKey
) )
1424 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
1425 // and look at the character after
1427 UInt32 keyInfo
= KeyTranslate((Ptr
)GetScriptManagerVariable(smKCHRCache
), ( modifiers
& (~(controlKey
|shiftKey
|optionKey
))) | keycode
, &state
);
1428 keychar
= short(keyInfo
& charCodeMask
);
1429 keycode
= short(keyInfo
& keyCodeMask
) >> 8 ;
1431 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
1433 if ( keyval
== keychar
)
1435 keyval
= wxToupper( keyval
) ;
1437 bool handled
= false ;
1439 wxKeyEvent
event(wxEVT_KEY_UP
);
1440 event
.m_shiftDown
= modifiers
& shiftKey
;
1441 event
.m_controlDown
= modifiers
& controlKey
;
1442 event
.m_altDown
= modifiers
& optionKey
;
1443 event
.m_metaDown
= modifiers
& cmdKey
;
1444 event
.m_keyCode
= keyval
;
1448 event
.m_timeStamp
= when
;
1449 event
.SetEventObject(focus
);
1450 handled
= focus
->GetEventHandler()->ProcessEvent( event
) ;