]> git.saurik.com Git - wxWidgets.git/blob - src/mac/app.cpp
extracted common initialization/cleanup functions in common/init.cpp; standardized...
[wxWidgets.git] / src / mac / app.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: app.cpp
3 // Purpose: wxApp
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "app.h"
14 #endif
15
16 #include "wx/defs.h"
17
18 #include "wx/window.h"
19 #include "wx/frame.h"
20 #include "wx/button.h"
21 #include "wx/app.h"
22 #include "wx/utils.h"
23 #include "wx/gdicmn.h"
24 #include "wx/pen.h"
25 #include "wx/brush.h"
26 #include "wx/cursor.h"
27 #include "wx/intl.h"
28 #include "wx/icon.h"
29 #include "wx/palette.h"
30 #include "wx/dc.h"
31 #include "wx/dialog.h"
32 #include "wx/msgdlg.h"
33 #include "wx/log.h"
34 #include "wx/module.h"
35 #include "wx/memory.h"
36 #include "wx/tooltip.h"
37 #include "wx/textctrl.h"
38 #include "wx/menu.h"
39 #include "wx/docview.h"
40
41 #include <string.h>
42
43 // mac
44
45 #ifndef __DARWIN__
46 #if __option(profile)
47 #include <profiler.h>
48 #endif
49 #endif
50
51 #include "apprsrc.h"
52
53 #include "wx/mac/uma.h"
54 #include "wx/mac/macnotfy.h"
55
56 #ifdef __DARWIN__
57 # include <CoreServices/CoreServices.h>
58 # if defined(WXMAKINGDLL)
59 # include <mach-o/dyld.h>
60 # endif
61 #else
62 # include <Sound.h>
63 # include <Threads.h>
64 # include <ToolUtils.h>
65 # include <DiskInit.h>
66 # include <Devices.h>
67 #endif
68
69 extern wxList wxPendingDelete;
70 extern wxList *wxWinMacWindowList;
71 extern wxList *wxWinMacControlList;
72
73 // statics for implementation
74
75 static bool s_inYield = FALSE;
76 static bool s_inOnIdle = FALSE;
77
78 #if TARGET_CARBON
79 static bool s_inReceiveEvent = FALSE ;
80 static EventTime sleepTime = kEventDurationNoWait ;
81 #else
82 static long sleepTime = 0 ;
83 #endif
84
85 #if !USE_SHARED_LIBRARY
86 IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
87 BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
88 EVT_IDLE(wxApp::OnIdle)
89 EVT_END_SESSION(wxApp::OnEndSession)
90 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
91 END_EVENT_TABLE()
92 #endif
93
94
95 const short kMacMinHeap = (29 * 1024) ;
96 // platform specific static variables
97
98 const short kwxMacMenuBarResource = 1 ;
99 const short kwxMacAppleMenuId = 1 ;
100
101 WXHRGN wxApp::s_macCursorRgn = NULL;
102 wxWindow* wxApp::s_captureWindow = NULL ;
103 int wxApp::s_lastMouseDown = 0 ;
104 long wxApp::sm_lastMessageTime = 0;
105 long wxApp::s_lastModifiers = 0 ;
106
107
108 bool wxApp::s_macDefaultEncodingIsPC = true ;
109 bool wxApp::s_macSupportPCMenuShortcuts = true ;
110 long wxApp::s_macAboutMenuItemId = wxID_ABOUT ;
111 long wxApp::s_macPreferencesMenuItemId = 0 ;
112 long wxApp::s_macExitMenuItemId = wxID_EXIT ;
113 wxString wxApp::s_macHelpMenuTitleName = wxT("&Help") ;
114
115 //----------------------------------------------------------------------
116 // Core Apple Event Support
117 //----------------------------------------------------------------------
118
119 pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
120 pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
121 pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
122 pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
123
124 pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
125 {
126 return wxTheApp->MacHandleAEODoc( (AppleEvent*) event , reply) ;
127 }
128
129 pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
130 {
131 return wxTheApp->MacHandleAEOApp( (AppleEvent*) event , reply ) ;
132 }
133
134 pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
135 {
136 return wxTheApp->MacHandleAEPDoc( (AppleEvent*) event , reply ) ;
137 }
138
139 pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
140 {
141 return wxTheApp->MacHandleAEQuit( (AppleEvent*) event , reply) ;
142 }
143
144 // AEODoc Calls MacOpenFile on each of the files passed
145
146 short wxApp::MacHandleAEODoc(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply))
147 {
148 AEDescList docList;
149 AEKeyword keywd;
150 DescType returnedType;
151 Size actualSize;
152 long itemsInList;
153 FSSpec theSpec;
154 OSErr err;
155 short i;
156 err = AEGetParamDesc((AppleEvent *)event, keyDirectObject, typeAEList,&docList);
157 if (err != noErr)
158 return err;
159
160 err = AECountItems(&docList, &itemsInList);
161 if (err != noErr)
162 return err;
163
164 ProcessSerialNumber PSN ;
165 PSN.highLongOfPSN = 0 ;
166 PSN.lowLongOfPSN = kCurrentProcess ;
167 SetFrontProcess( &PSN ) ;
168
169 for (i = 1; i <= itemsInList; i++) {
170 AEGetNthPtr(&docList, i, typeFSS, &keywd, &returnedType,
171 (Ptr) & theSpec, sizeof(theSpec), &actualSize);
172 wxString fName = wxMacFSSpec2MacFilename(&theSpec);
173 MacOpenFile(fName);
174 }
175 return noErr;
176 }
177
178 // AEPDoc Calls MacPrintFile on each of the files passed
179
180 short wxApp::MacHandleAEPDoc(const WXEVENTREF event , WXEVENTREF WXUNUSED(reply))
181 {
182 AEDescList docList;
183 AEKeyword keywd;
184 DescType returnedType;
185 Size actualSize;
186 long itemsInList;
187 FSSpec theSpec;
188 OSErr err;
189 short i;
190 err = AEGetParamDesc((AppleEvent *)event, keyDirectObject, typeAEList,&docList);
191 if (err != noErr)
192 return err;
193
194 err = AECountItems(&docList, &itemsInList);
195 if (err != noErr)
196 return err;
197
198 ProcessSerialNumber PSN ;
199 PSN.highLongOfPSN = 0 ;
200 PSN.lowLongOfPSN = kCurrentProcess ;
201 SetFrontProcess( &PSN ) ;
202
203 for (i = 1; i <= itemsInList; i++) {
204 AEGetNthPtr(&docList, i, typeFSS, &keywd, &returnedType,
205 (Ptr) & theSpec, sizeof(theSpec), &actualSize);
206 wxString fName = wxMacFSSpec2MacFilename(&theSpec);
207 MacPrintFile(fName);
208 }
209 return noErr;
210 }
211
212 // AEOApp calls MacNewFile
213
214 short wxApp::MacHandleAEOApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
215 {
216 MacNewFile() ;
217 return noErr ;
218 }
219
220 // AEQuit attempts to quit the application
221
222 short wxApp::MacHandleAEQuit(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
223 {
224 /* wxWindow* win = GetTopWindow() ;
225 if ( win )
226 {
227 win->Close(TRUE ) ;
228 }
229 else
230 */
231 {
232 ExitMainLoop() ;
233 }
234 return noErr ;
235 }
236
237 //----------------------------------------------------------------------
238 // Support Routines linking the Mac...File Calls to the Document Manager
239 //----------------------------------------------------------------------
240
241 void wxApp::MacOpenFile(const wxString & fileName )
242 {
243 wxDocManager* dm = wxDocManager::GetDocumentManager() ;
244 if ( dm )
245 dm->CreateDocument(fileName , wxDOC_SILENT ) ;
246 }
247
248 void wxApp::MacPrintFile(const wxString & fileName )
249 {
250 wxDocManager* dm = wxDocManager::GetDocumentManager() ;
251 if ( dm )
252 {
253 wxDocument *doc = dm->CreateDocument(fileName , wxDOC_SILENT ) ;
254 if ( doc )
255 {
256 wxView* view = doc->GetFirstView() ;
257 if( view )
258 {
259 wxPrintout *printout = view->OnCreatePrintout();
260 if (printout)
261 {
262 wxPrinter printer;
263 printer.Print(view->GetFrame(), printout, TRUE);
264 delete printout;
265 }
266 }
267 if (doc->Close())
268 {
269 doc->DeleteAllViews();
270 dm->RemoveDocument(doc) ;
271 }
272 }
273 }
274 }
275
276 void wxApp::MacNewFile()
277 {
278 }
279
280 //----------------------------------------------------------------------
281 // Carbon Event Handler
282 //----------------------------------------------------------------------
283
284 #if TARGET_CARBON
285
286 static const EventTypeSpec eventList[] =
287 {
288 { kEventClassCommand, kEventProcessCommand } ,
289 { kEventClassCommand, kEventCommandUpdateStatus } ,
290
291 { kEventClassApplication , kEventAppActivated } ,
292 { kEventClassApplication , kEventAppDeactivated } ,
293 // handling the quit event is not recommended by apple
294 // rather using the quit apple event - which we do
295
296 { kEventClassAppleEvent , kEventAppleEvent } ,
297
298 { kEventClassMouse , kEventMouseDown } ,
299 { 'WXMC' , 'WXMC' }
300 } ;
301
302 static pascal OSStatus MenuEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
303 {
304 return eventNotHandledErr ;
305 }
306
307 // due to the rather low-level event API of wxWindows, we cannot use RunApplicationEventLoop
308 // but have to use ReceiveNextEvent dealing with events manually, therefore we also have
309 // deal with clicks in the menu bar explicitely
310
311 static pascal OSStatus MouseEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
312 {
313 OSStatus result = eventNotHandledErr ;
314
315 switch( GetEventKind(event) )
316 {
317 case kEventMouseDown :
318 {
319 Point point ;
320 WindowRef window ;
321
322 GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL,
323 sizeof( Point ), NULL, &point );
324 short windowPart = ::FindWindow(point, &window);
325
326 if ( windowPart == inMenuBar )
327 {
328 MenuSelect( point ) ;
329 result = noErr ;
330 }
331 }
332 break ;
333 }
334
335 return result ;
336 }
337
338 static pascal OSStatus CommandEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
339 {
340 OSStatus result = eventNotHandledErr ;
341
342 HICommand command ;
343
344 GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL,
345 sizeof( HICommand ), NULL, &command );
346
347 MenuCommand id = command.commandID ;
348 if ( id == kHICommandPreferences )
349 id = wxApp::s_macPreferencesMenuItemId ;
350
351 wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ;
352 wxMenu* menu = NULL ;
353 wxMenuItem* item = NULL ;
354
355 if ( mbar )
356 item = mbar->FindItem( id , &menu ) ;
357
358 if ( item == NULL || menu == NULL || mbar == NULL )
359 return result ;
360
361 switch( GetEventKind( event ) )
362 {
363 case kEventProcessCommand :
364 {
365 if (item->IsCheckable())
366 {
367 item->Check( !item->IsChecked() ) ;
368 }
369
370 menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
371 result = noErr ;
372 }
373 break ;
374 case kEventCommandUpdateStatus:
375 // eventually trigger an updateui round
376 result = noErr ;
377 break ;
378 default :
379 break ;
380 }
381
382 return result ;
383 }
384
385 static pascal OSStatus ApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
386 {
387 OSStatus result = eventNotHandledErr ;
388 switch ( GetEventKind( event ) )
389 {
390 case kEventAppActivated :
391 {
392 if ( wxTheApp )
393 wxTheApp->MacResume( true ) ;
394 result = noErr ;
395 }
396 break ;
397 case kEventAppDeactivated :
398 {
399 if ( wxTheApp )
400 wxTheApp->MacSuspend( true ) ;
401 result = noErr ;
402 }
403 break ;
404 default :
405 break ;
406 }
407 return result ;
408 }
409
410 pascal OSStatus wxAppEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
411 {
412 OSStatus result = eventNotHandledErr ;
413 switch( GetEventClass( event ) )
414 {
415 case kEventClassCommand :
416 result = CommandEventHandler( handler , event , data ) ;
417 break ;
418 case kEventClassApplication :
419 result = ApplicationEventHandler( handler , event , data ) ;
420 break ;
421 case kEventClassMenu :
422 result = MenuEventHandler( handler , event , data ) ;
423 break ;
424 case kEventClassMouse :
425 result = MouseEventHandler( handler , event , data ) ;
426 break ;
427 case kEventClassAppleEvent :
428 {
429 EventRecord rec ;
430 wxMacConvertEventToRecord( event , &rec ) ;
431 result = AEProcessAppleEvent( &rec ) ;
432 }
433 break ;
434 default :
435 break ;
436 }
437
438 return result ;
439 }
440
441 DEFINE_ONE_SHOT_HANDLER_GETTER( wxAppEventHandler )
442
443 #endif
444
445 #if defined(WXMAKINGDLL) && !defined(__DARWIN__)
446 // we know it's there ;-)
447 WXIMPORT char std::__throws_bad_alloc ;
448 #endif
449
450 bool wxApp::Initialize(int argc, wxChar **argv)
451 {
452 int error = 0 ;
453
454 // Mac-specific
455
456 UMAInitToolbox( 4 ) ;
457 SetEventMask( everyEvent ) ;
458 UMAShowWatchCursor() ;
459
460 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
461 // open shared library resources from here since we don't have
462 // __wxinitialize in Mach-O shared libraries
463 wxStAppResource::OpenSharedLibraryResource(NULL);
464 #endif
465
466 #ifndef __DARWIN__
467 // test the minimal configuration necessary
468
469 # if !TARGET_CARBON
470 long theSystem ;
471 long theMachine;
472
473 if (Gestalt(gestaltMachineType, &theMachine) != noErr)
474 {
475 error = kMacSTRWrongMachine;
476 }
477 else if (theMachine < gestaltMacPlus)
478 {
479 error = kMacSTRWrongMachine;
480 }
481 else if (Gestalt(gestaltSystemVersion, &theSystem) != noErr )
482 {
483 error = kMacSTROldSystem ;
484 }
485 else if ( theSystem < 0x0860 )
486 {
487 error = kMacSTROldSystem ;
488 }
489 else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap)
490 {
491 error = kMacSTRSmallSize;
492 }
493 # endif
494 /*
495 else
496 {
497 if ( !UMAHasAppearance() )
498 {
499 error = kMacSTRNoPre8Yet ;
500 }
501 }
502 */
503 #endif
504
505 // if we encountered any problems so far, give the error code and exit immediately
506
507 if ( error )
508 {
509 wxStAppResource resload ;
510 short itemHit;
511 Str255 message;
512
513 GetIndString(message, 128, error);
514 UMAShowArrowCursor() ;
515 ParamText("\pFatal Error", message, (ConstStr255Param)"\p", (ConstStr255Param)"\p");
516 itemHit = Alert(128, nil);
517 return FALSE ;
518 }
519
520 #ifndef __DARWIN__
521 # if __option(profile)
522 ProfilerInit( collectDetailed, bestTimeBase , 20000 , 40 ) ;
523 # endif
524 #endif
525
526 #ifndef __DARWIN__
527 // now avoid exceptions thrown for new (bad_alloc)
528 // FIXME CS for some changes outside wxMac does not compile anymore
529 #if 0
530 std::__throws_bad_alloc = 0 ;
531 #endif
532
533 #endif
534 wxMacSetupConverters() ;
535
536 s_macCursorRgn = ::NewRgn() ;
537
538 if ( !wxAppBase::Initialize(argc, argv) )
539 return false;
540
541 wxWinMacWindowList = new wxList(wxKEY_INTEGER);
542 wxWinMacControlList = new wxList(wxKEY_INTEGER);
543
544 wxMacCreateNotifierTable() ;
545
546 UMAShowArrowCursor() ;
547
548 return true;
549 }
550
551 bool wxApp::OnInitGui()
552 {
553 if( !wxAppBase::OnInitGui() )
554 return false ;
555
556 #if TARGET_CARBON
557 InstallStandardEventHandler( GetApplicationEventTarget() ) ;
558
559 InstallApplicationEventHandler(
560 GetwxAppEventHandlerUPP(),
561 GetEventTypeCount(eventList), eventList, wxTheApp, (EventHandlerRef *)&(wxTheApp->m_macEventHandler));
562 #endif
563
564 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
565 AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
566 NewAEEventHandlerUPP(AEHandleODoc) ,
567 0 , FALSE ) ;
568 AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
569 NewAEEventHandlerUPP(AEHandleOApp) ,
570 0 , FALSE ) ;
571 AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
572 NewAEEventHandlerUPP(AEHandlePDoc) ,
573 0 , FALSE ) ;
574 AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
575 NewAEEventHandlerUPP(AEHandleQuit) ,
576 0 , FALSE ) ;
577 #else
578 AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
579 NewAEEventHandlerProc(AEHandleODoc) ,
580 0 , FALSE ) ;
581 AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
582 NewAEEventHandlerProc(AEHandleOApp) ,
583 0 , FALSE ) ;
584 AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
585 NewAEEventHandlerProc(AEHandlePDoc) ,
586 0 , FALSE ) ;
587 AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
588 NewAEEventHandlerProc(AEHandleQuit) ,
589 0 , FALSE ) ;
590 #endif
591
592 return TRUE ;
593 }
594
595 void wxApp::CleanUp()
596 {
597 wxToolTip::RemoveToolTips() ;
598
599 // One last chance for pending objects to be cleaned up
600 wxTheApp->DeletePendingObjects();
601
602 wxMacDestroyNotifierTable() ;
603
604 delete wxWinMacWindowList ;
605 wxWinMacWindowList = NULL;
606
607 delete wxWinMacControlList ;
608 wxWinMacControlList = NULL;
609
610 #ifndef __DARWIN__
611 # if __option(profile)
612 ProfilerDump( (StringPtr)"\papp.prof" ) ;
613 ProfilerTerm() ;
614 # endif
615 #endif
616
617 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
618 // close shared library resources from here since we don't have
619 // __wxterminate in Mach-O shared libraries
620 wxStAppResource::CloseSharedLibraryResource();
621 #endif
622 wxMacCleanupConverters() ;
623
624 UMACleanupToolbox() ;
625 if (s_macCursorRgn) {
626 ::DisposeRgn((RgnHandle)s_macCursorRgn);
627 }
628
629 #if 0
630 TerminateAE() ;
631 #endif
632
633 wxAppBase::CleanUp();
634 }
635
636 //----------------------------------------------------------------------
637 // wxEntry
638 //----------------------------------------------------------------------
639
640 // extern variable for shared library resource id
641 // need to be able to find it with NSLookupAndBindSymbol
642 short gSharedLibraryResource = kResFileNotOpened ;
643
644 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
645 CFBundleRef gSharedLibraryBundle = NULL;
646 #endif /* WXMAKINGDLL && __DARWIN__ */
647
648 wxStAppResource::wxStAppResource()
649 {
650 m_currentRefNum = CurResFile() ;
651 if ( gSharedLibraryResource != kResFileNotOpened )
652 {
653 UseResFile( gSharedLibraryResource ) ;
654 }
655 }
656
657 wxStAppResource::~wxStAppResource()
658 {
659 if ( m_currentRefNum != kResFileNotOpened )
660 {
661 UseResFile( m_currentRefNum ) ;
662 }
663 }
664
665 void wxStAppResource::OpenSharedLibraryResource(const void *initBlock)
666 {
667 gSharedLibraryResource = kResFileNotOpened;
668
669 #ifdef WXMAKINGDLL
670 if ( initBlock != NULL ) {
671 const CFragInitBlock *theInitBlock = (const CFragInitBlock *)initBlock;
672 FSSpec *fileSpec = NULL;
673
674 if (theInitBlock->fragLocator.where == kDataForkCFragLocator) {
675 fileSpec = theInitBlock->fragLocator.u.onDisk.fileSpec;
676 }
677 else if (theInitBlock->fragLocator.where == kResourceCFragLocator) {
678 fileSpec = theInitBlock->fragLocator.u.inSegs.fileSpec;
679 }
680
681 if (fileSpec != NULL) {
682 gSharedLibraryResource = FSpOpenResFile(fileSpec, fsRdPerm);
683 }
684 }
685 else {
686 #ifdef __DARWIN__
687 // Open the shared library resource file if it is not yet open
688 NSSymbol theSymbol;
689 NSModule theModule;
690 const char *theLibPath;
691
692 gSharedLibraryBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWindows"));
693 if (gSharedLibraryBundle != NULL) {
694 // wxWindows has been bundled into a framework
695 // load the framework resources
696
697 gSharedLibraryResource = CFBundleOpenBundleResourceMap(gSharedLibraryBundle);
698 }
699 else {
700 // wxWindows is a simple dynamic shared library
701 // load the resources from the data fork of a separate resource file
702 char *theResPath;
703 char *theName;
704 char *theExt;
705 FSRef theResRef;
706 OSErr theErr = noErr;
707
708 // get the library path
709 theSymbol = NSLookupAndBindSymbol("_gSharedLibraryResource");
710 theModule = NSModuleForSymbol(theSymbol);
711 theLibPath = NSLibraryNameForModule(theModule);
712
713 // if we call wxLogDebug from here then, as wxTheApp hasn't been
714 // created yet when we're called from wxApp::Initialize(), wxLog
715 // is going to create a default stderr-based log target instead of
716 // the expected normal GUI one -- don't do it, if we really want
717 // to see this message just use fprintf() here
718 #if 0
719 wxLogDebug( wxT("wxMac library installation name is '%s'"),
720 theLibPath );
721 #endif
722
723 // allocate copy to replace .dylib.* extension with .rsrc
724 theResPath = strdup(theLibPath);
725 if (theResPath != NULL) {
726 theName = strrchr(theResPath, '/');
727 if (theName == NULL) {
728 // no directory elements in path
729 theName = theResPath;
730 }
731 // find ".dylib" shared library extension
732 theExt = strstr(theName, ".dylib");
733 // overwrite extension with ".rsrc"
734 strcpy(theExt, ".rsrc");
735
736 #if 0
737 wxLogDebug( wxT("wxMac resources file name is '%s'"),
738 theResPath );
739 #endif
740
741 theErr = FSPathMakeRef((UInt8 *) theResPath, &theResRef, false);
742 if (theErr != noErr) {
743 // try in current directory (using name only)
744 theErr = FSPathMakeRef((UInt8 *) theName, &theResRef, false);
745 }
746
747 // open the resource file
748 if (theErr == noErr) {
749 theErr = FSOpenResourceFile( &theResRef, 0, NULL, fsRdPerm,
750 &gSharedLibraryResource);
751 }
752 if (theErr != noErr) {
753 #ifdef __WXDEBUG__
754 fprintf(stderr,
755 wxT("unable to open wxMac resource file '%s'\n"),
756 theResPath );
757 #endif // __WXDEBUG__
758 }
759
760 // free duplicated resource file path
761 free(theResPath);
762 }
763 }
764 #endif /* __DARWIN__ */
765 }
766 #endif /* WXMAKINGDLL */
767 }
768
769 void wxStAppResource::CloseSharedLibraryResource()
770 {
771 #ifdef WXMAKINGDLL
772 // Close the shared library resource file
773 if (gSharedLibraryResource != kResFileNotOpened) {
774 #ifdef __DARWIN__
775 if (gSharedLibraryBundle != NULL) {
776 CFBundleCloseBundleResourceMap(gSharedLibraryBundle,
777 gSharedLibraryResource);
778 gSharedLibraryBundle = NULL;
779 }
780 else
781 #endif /* __DARWIN__ */
782 {
783 CloseResFile(gSharedLibraryResource);
784 }
785 gSharedLibraryResource = kResFileNotOpened;
786 }
787 #endif /* WXMAKINGDLL */
788 }
789
790 #if defined(WXMAKINGDLL) && !defined(__DARWIN__)
791
792 // for shared libraries we have to manually get the correct resource
793 // ref num upon initializing and releasing when terminating, therefore
794 // the __wxinitialize and __wxterminate must be used
795
796 extern "C" {
797 void __sinit(void); /* (generated by linker) */
798 pascal OSErr __initialize(const CFragInitBlock *theInitBlock);
799 pascal void __terminate(void);
800 }
801
802 pascal OSErr __wxinitialize(const CFragInitBlock *theInitBlock)
803 {
804 wxStAppResource::OpenSharedLibraryResource( theInitBlock ) ;
805 return __initialize( theInitBlock ) ;
806 }
807
808 pascal void __wxterminate(void)
809 {
810 wxStAppResource::CloseSharedLibraryResource() ;
811 __terminate() ;
812 }
813
814 #endif /* WXMAKINGDLL && !__DARWIN__ */
815
816 int WXDLLEXPORT wxEntryStart( int WXUNUSED(argc), char *WXUNUSED(argv)[] )
817 {
818 return wxApp::Initialize();
819 }
820
821 int WXDLLEXPORT wxEntryInitGui()
822 {
823 return wxTheApp->OnInitGui();
824 }
825
826 void WXDLLEXPORT wxEntryCleanup()
827 {
828 wxApp::CleanUp();
829 }
830
831 int wxEntry( int argc, char *argv[] , bool enterLoop )
832 {
833 #ifdef __MWERKS__
834 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
835 // This seems to be necessary since there are 'rogue'
836 // objects present at this point (perhaps global objects?)
837 // Setting a checkpoint will ignore them as far as the
838 // memory checking facility is concerned.
839 // Of course you may argue that memory allocated in globals should be
840 // checked, but this is a reasonable compromise.
841 wxDebugContext::SetCheckpoint();
842 #endif
843 #endif
844 if (!wxEntryStart(argc, argv)) {
845 return 0;
846 }
847 // create the application object or ensure that one already exists
848 if (!wxTheApp)
849 {
850 // The app may have declared a global application object, but we recommend
851 // the IMPLEMENT_APP macro is used instead, which sets an initializer
852 // function for delayed, dynamic app object construction.
853 wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
854 wxT("No initializer - use IMPLEMENT_APP macro.") );
855
856 wxTheApp = (wxApp*) (*wxApp::GetInitializerFunction()) ();
857 }
858
859 wxCHECK_MSG( wxTheApp, 0, wxT("You have to define an instance of wxApp!") );
860
861 #ifdef __DARWIN__
862 // Mac OS X passes a process serial number command line argument when
863 // the application is launched from the Finder. This argument must be
864 // removed from the command line arguments before being handled by the
865 // application (otherwise applications would need to handle it)
866
867 if (argc > 1) {
868 if (strncmp(argv[1], "-psn_", 5) == 0) {
869 // assume the argument is always the only one and remove it
870 --argc;
871 }
872 }
873 #else
874 argc = 0 ; // currently we don't support files as parameters
875 #endif
876 // we could try to get the open apple events here to adjust argc and argv better
877
878 wxTheApp->argc = argc;
879 #if wxUSE_UNICODE
880 wxTheApp->argv = new wxChar*[argc+1];
881 int mb_argc ;
882 for ( mb_argc = 0; mb_argc < argc; mb_argc++ )
883 {
884 wxTheApp->argv[mb_argc] = wxStrdup(wxConvLocal.cMB2WX(argv[mb_argc]));
885 }
886 wxTheApp->argv[mb_argc] = (wxChar *)NULL;
887 #else
888 wxTheApp->argv = argv;
889 #endif
890
891 // GUI-specific initialization, such as creating an app context.
892 wxEntryInitGui();
893
894 // Here frames insert themselves automatically
895 // into wxTopLevelWindows by getting created
896 // in OnInit().
897
898 int retValue = 0;
899
900 if ( wxTheApp->OnInit() )
901 {
902 if ( enterLoop )
903 {
904 retValue = wxTheApp->OnRun();
905 }
906 else
907 // We want to initialize, but not run or exit immediately.
908 return 1;
909 }
910 //else: app initialization failed, so we skipped OnRun()
911
912 wxWindow *topWindow = wxTheApp->GetTopWindow();
913 if ( topWindow )
914 {
915 // Forcibly delete the window.
916 if ( topWindow->IsKindOf(CLASSINFO(wxFrame)) ||
917 topWindow->IsKindOf(CLASSINFO(wxDialog)) )
918 {
919 topWindow->Close(TRUE);
920 wxTheApp->DeletePendingObjects();
921 }
922 else
923 {
924 delete topWindow;
925 wxTheApp->SetTopWindow(NULL);
926 }
927 }
928
929 wxTheApp->OnExit();
930
931 wxEntryCleanup();
932
933 return retValue;
934 }
935
936 #if TARGET_CARBON
937
938 bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec)
939 {
940 bool converted = ConvertEventRefToEventRecord( event,rec) ;
941 OSStatus err = noErr ;
942 if ( !converted )
943 {
944 switch( GetEventClass( event ) )
945 {
946 case kEventClassKeyboard :
947 {
948 converted = true ;
949 switch( GetEventKind(event) )
950 {
951 case kEventRawKeyDown :
952 rec->what = keyDown ;
953 break ;
954 case kEventRawKeyRepeat :
955 rec->what = autoKey ;
956 break ;
957 case kEventRawKeyUp :
958 rec->what = keyUp ;
959 break ;
960 case kEventRawKeyModifiersChanged :
961 rec->what = nullEvent ;
962 break ;
963 default :
964 converted = false ;
965 break ;
966 }
967 if ( converted )
968 {
969 UInt32 keyCode ;
970 unsigned char charCode ;
971 UInt32 modifiers ;
972 GetMouse( &rec->where) ;
973
974 err = GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers);
975 err = GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode);
976 err = GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode);
977 rec->modifiers = modifiers ;
978 rec->message = (keyCode << 8 ) + charCode ;
979 }
980 }
981 break ;
982 case kEventClassTextInput :
983 {
984 switch( GetEventKind( event ) )
985 {
986 case kEventTextInputUnicodeForKeyEvent :
987 {
988 EventRef rawEvent ;
989 err = GetEventParameter( event , kEventParamTextInputSendKeyboardEvent ,typeEventRef,NULL,sizeof(rawEvent),NULL,&rawEvent ) ;
990 converted = true ;
991 {
992 UInt32 keyCode ;
993 unsigned char charCode ;
994 UInt32 modifiers ;
995 GetMouse( &rec->where) ;
996 rec->what = keyDown ;
997 err = GetEventParameter(rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers);
998 err = GetEventParameter(rawEvent, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode);
999 err = GetEventParameter(rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode);
1000 rec->modifiers = modifiers ;
1001 rec->message = (keyCode << 8 ) + charCode ;
1002 }
1003 }
1004 break ;
1005 default :
1006 break ;
1007 }
1008 }
1009 break ;
1010 }
1011 }
1012
1013 return converted ;
1014 }
1015
1016 /*
1017 pascal OSStatus wxMacApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
1018 {
1019 OSStatus result = eventNotHandledErr ;
1020
1021 EventRecord rec ;
1022 switch ( GetEventClass( event ) )
1023 {
1024 case kEventClassKeyboard :
1025 if ( wxMacConvertEventToRecord( event , &rec ) )
1026 {
1027 wxTheApp->MacHandleModifierEvents( &rec ) ;
1028 wxTheApp->MacHandleOneEvent( &rec ) ;
1029 result = noErr ;
1030 }
1031 break ;
1032 case kEventClassTextInput :
1033 if ( wxMacConvertEventToRecord( event , &rec ) )
1034 {
1035 wxTheApp->MacHandleModifierEvents( &rec ) ;
1036 wxTheApp->MacHandleOneEvent( &rec ) ;
1037 result = noErr ;
1038 }
1039 break ;
1040 default :
1041 break ;
1042 }
1043 return result ;
1044 }
1045 */
1046 #endif
1047
1048 wxApp::wxApp()
1049 {
1050 m_topWindow = NULL;
1051 wxTheApp = this;
1052
1053 #if WXWIN_COMPATIBILITY_2_2
1054 m_wantDebugOutput = TRUE;
1055 #endif
1056
1057 argc = 0;
1058 argv = NULL;
1059
1060 m_printMode = wxPRINT_WINDOWS;
1061 m_auto3D = TRUE;
1062 }
1063
1064 bool wxApp::Initialized()
1065 {
1066 if (GetTopWindow())
1067 return TRUE;
1068 else
1069 return FALSE;
1070 }
1071
1072 int wxApp::MainLoop()
1073 {
1074 m_keepGoing = TRUE;
1075
1076 while (m_keepGoing)
1077 {
1078 MacDoOneEvent() ;
1079 }
1080
1081 return 0;
1082 }
1083
1084 // Returns TRUE if more time is needed.
1085 bool wxApp::ProcessIdle()
1086 {
1087 wxIdleEvent event;
1088 event.SetEventObject(this);
1089 ProcessEvent(event);
1090
1091 return event.MoreRequested();
1092 }
1093
1094 void wxApp::ExitMainLoop()
1095 {
1096 m_keepGoing = FALSE;
1097 }
1098
1099 // Is a message/event pending?
1100 bool wxApp::Pending()
1101 {
1102 #if TARGET_CARBON
1103 return GetNumEventsInQueue( GetMainEventQueue() ) > 0 ;
1104 #else
1105 EventRecord event ;
1106
1107 return EventAvail( everyEvent , &event ) ;
1108 #endif
1109 }
1110
1111 // Dispatch a message.
1112 void wxApp::Dispatch()
1113 {
1114 MacDoOneEvent() ;
1115 }
1116
1117 void wxApp::OnIdle(wxIdleEvent& event)
1118 {
1119 // Avoid recursion (via ProcessEvent default case)
1120 if ( s_inOnIdle )
1121 return;
1122
1123
1124 s_inOnIdle = TRUE;
1125
1126 // 'Garbage' collection of windows deleted with Close().
1127 DeletePendingObjects();
1128
1129 // flush the logged messages if any
1130 wxLog *pLog = wxLog::GetActiveTarget();
1131 if ( pLog != NULL && pLog->HasPendingMessages() )
1132 pLog->Flush();
1133
1134 // Send OnIdle events to all windows
1135 bool needMore = SendIdleEvents();
1136
1137 if (needMore)
1138 event.RequestMore(TRUE);
1139
1140 // If they are pending events, we must process them: pending events are
1141 // either events to the threads other than main or events posted with
1142 // wxPostEvent() functions
1143 wxMacProcessNotifierAndPendingEvents();
1144
1145 s_inOnIdle = FALSE;
1146 if(!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar())
1147 wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar();
1148 }
1149
1150 void wxApp::WakeUpIdle()
1151 {
1152 wxMacWakeUp() ;
1153 }
1154
1155 // Send idle event to all top-level windows
1156 bool wxApp::SendIdleEvents()
1157 {
1158 bool needMore = FALSE;
1159 wxWindowListNode* node = wxTopLevelWindows.GetFirst();
1160 while (node)
1161 {
1162 wxWindow* win = node->GetData();
1163 if (SendIdleEvents(win))
1164 needMore = TRUE;
1165
1166 node = node->GetNext();
1167 }
1168 return needMore;
1169 }
1170
1171 // Send idle event to window and all subwindows
1172 bool wxApp::SendIdleEvents(wxWindow* win)
1173 {
1174 bool needMore = FALSE;
1175
1176 wxIdleEvent event;
1177 event.SetEventObject(win);
1178 win->ProcessEvent(event);
1179
1180 if (event.MoreRequested())
1181 needMore = TRUE;
1182
1183 wxWindowListNode* node = win->GetChildren().GetFirst();
1184 while (node)
1185 {
1186 wxWindow* win = node->GetData();
1187 if (SendIdleEvents(win))
1188 needMore = TRUE;
1189
1190 node = node->GetNext();
1191 }
1192 return needMore ;
1193 }
1194
1195 void wxApp::Exit()
1196 {
1197 wxApp::CleanUp();
1198 ::ExitToShell() ;
1199 }
1200
1201 void wxApp::OnEndSession(wxCloseEvent& WXUNUSED(event))
1202 {
1203 if (GetTopWindow())
1204 GetTopWindow()->Close(TRUE);
1205 }
1206
1207 // Default behaviour: close the application with prompts. The
1208 // user can veto the close, and therefore the end session.
1209 void wxApp::OnQueryEndSession(wxCloseEvent& event)
1210 {
1211 if (GetTopWindow())
1212 {
1213 if (!GetTopWindow()->Close(!event.CanVeto()))
1214 event.Veto(TRUE);
1215 }
1216 }
1217
1218 extern "C" void wxCYield() ;
1219 void wxCYield()
1220 {
1221 wxYield() ;
1222 }
1223
1224 // Yield to other processes
1225
1226 bool wxApp::Yield(bool onlyIfNeeded)
1227 {
1228 if (s_inYield)
1229 {
1230 if ( !onlyIfNeeded )
1231 {
1232 wxFAIL_MSG( wxT("wxYield called recursively" ) );
1233 }
1234
1235 return FALSE;
1236 }
1237
1238 s_inYield = TRUE;
1239
1240 #if wxUSE_THREADS
1241 YieldToAnyThread() ;
1242 #endif
1243 // by definition yield should handle all non-processed events
1244 #if TARGET_CARBON
1245 EventRef theEvent;
1246
1247 OSStatus status = noErr ;
1248 do
1249 {
1250 s_inReceiveEvent = true ;
1251 status = ReceiveNextEvent(0, NULL,kEventDurationNoWait,true,&theEvent) ;
1252 s_inReceiveEvent = false ;
1253
1254 if ( status == eventLoopTimedOutErr )
1255 {
1256 // make sure next time the event loop will trigger idle events
1257 sleepTime = kEventDurationNoWait ;
1258 }
1259 else if ( status == eventLoopQuitErr )
1260 {
1261 // according to QA1061 this may also occur when a WakeUp Process
1262 // is executed
1263 }
1264 else
1265 {
1266 MacHandleOneEvent( theEvent ) ;
1267 ReleaseEvent(theEvent);
1268 }
1269 } while( status == noErr ) ;
1270 #else
1271 EventRecord event ;
1272
1273 // having a larger value here leads to large performance slowdowns
1274 // so we cannot give background apps more processor time here
1275 // we do so however having a large sleep value in the main event loop
1276 sleepTime = 0 ;
1277
1278 while ( !IsExiting() && WaitNextEvent(everyEvent, &event,sleepTime, (RgnHandle) wxApp::s_macCursorRgn))
1279 {
1280 MacHandleModifierEvents( &event ) ;
1281 MacHandleOneEvent( &event );
1282 if ( event.what != kHighLevelEvent )
1283 SetRectRgn( (RgnHandle) wxApp::s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ;
1284 }
1285 MacHandleModifierEvents( &event ) ;
1286 #endif
1287
1288 wxMacProcessNotifierAndPendingEvents() ;
1289 s_inYield = FALSE;
1290
1291 return TRUE;
1292 }
1293
1294 // platform specifics
1295
1296 void wxApp::MacSuspend( bool convertClipboard )
1297 {
1298 #if !TARGET_CARBON
1299 // we have to deactive the top level windows manually
1300
1301 wxWindowListNode* node = wxTopLevelWindows.GetFirst();
1302 while (node)
1303 {
1304 wxTopLevelWindow* win = (wxTopLevelWindow*) node->Data();
1305 #if TARGET_CARBON
1306 #if 0 // having problems right now with that
1307 if (!win->HasFlag(wxSTAY_ON_TOP))
1308 #endif
1309 #endif
1310 win->MacActivate( ((EventRecord*) MacGetCurrentEvent())->when , false ) ;
1311
1312 node = node->GetNext();
1313 }
1314
1315 ::HideFloatingWindows() ;
1316 #endif
1317 s_lastMouseDown = 0 ;
1318
1319 if( convertClipboard )
1320 {
1321 MacConvertPrivateToPublicScrap() ;
1322 }
1323 }
1324
1325 extern wxList wxModalDialogs;
1326
1327 void wxApp::MacResume( bool convertClipboard )
1328 {
1329 s_lastMouseDown = 0 ;
1330 if( convertClipboard )
1331 {
1332 MacConvertPublicToPrivateScrap() ;
1333 }
1334
1335 #if !TARGET_CARBON
1336 ::ShowFloatingWindows() ;
1337 // raise modal dialogs in case a non modal window was selected to activate the app
1338
1339 wxNode* node = wxModalDialogs.GetFirst();
1340 while (node)
1341 {
1342 wxDialog* dialog = (wxDialog *) node->GetData();
1343 dialog->Raise();
1344
1345 node = node->GetNext();
1346 }
1347 #endif
1348 }
1349
1350 void wxApp::MacConvertPrivateToPublicScrap()
1351 {
1352 }
1353
1354 void wxApp::MacConvertPublicToPrivateScrap()
1355 {
1356 }
1357
1358 void wxApp::MacDoOneEvent()
1359 {
1360 #if TARGET_CARBON
1361 EventRef theEvent;
1362
1363 s_inReceiveEvent = true ;
1364 OSStatus status = ReceiveNextEvent(0, NULL,sleepTime,true,&theEvent) ;
1365 s_inReceiveEvent = false ;
1366 if ( status == eventLoopTimedOutErr )
1367 {
1368 if ( wxTheApp->ProcessIdle() )
1369 sleepTime = kEventDurationNoWait ;
1370 else
1371 sleepTime = kEventDurationForever ;
1372 }
1373 else if ( status == eventLoopQuitErr )
1374 {
1375 // according to QA1061 this may also occur when a WakeUp Process
1376 // is executed
1377 }
1378 else
1379 {
1380 MacHandleOneEvent( theEvent ) ;
1381 ReleaseEvent(theEvent);
1382 sleepTime = kEventDurationNoWait ;
1383 }
1384 #else
1385 EventRecord event ;
1386
1387 EventMask eventMask = everyEvent ;
1388
1389 if (WaitNextEvent(eventMask, &event, sleepTime, (RgnHandle) s_macCursorRgn))
1390 {
1391 MacHandleModifierEvents( &event ) ;
1392 MacHandleOneEvent( &event );
1393 }
1394 else
1395 {
1396 MacHandleModifierEvents( &event ) ;
1397 // idlers
1398 WindowPtr window = ::FrontWindow() ;
1399 if ( window )
1400 ::IdleControls( window ) ;
1401
1402 if ( wxTheApp->ProcessIdle() )
1403 sleepTime = 0 ;
1404 else
1405 sleepTime = GetCaretTime() / 2 ;
1406 }
1407 if ( event.what != kHighLevelEvent )
1408 SetRectRgn( (RgnHandle) s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ;
1409 #endif
1410 // repeaters
1411
1412 DeletePendingObjects() ;
1413 wxMacProcessNotifierAndPendingEvents() ;
1414 }
1415
1416 void wxApp::MacHandleOneEvent( WXEVENTREF evr )
1417 {
1418 #if TARGET_CARBON
1419 EventTargetRef theTarget;
1420 theTarget = GetEventDispatcherTarget();
1421 m_macCurrentEvent = evr ;
1422 SendEventToEventTarget ((EventRef) evr , theTarget);
1423 #else
1424 EventRecord* ev = (EventRecord*) evr ;
1425 m_macCurrentEvent = ev ;
1426
1427 wxApp::sm_lastMessageTime = ev->when ;
1428
1429 switch (ev->what)
1430 {
1431 case mouseDown:
1432 MacHandleMouseDownEvent( ev ) ;
1433 if ( ev->modifiers & controlKey )
1434 s_lastMouseDown = 2;
1435 else
1436 s_lastMouseDown = 1;
1437 break;
1438 case mouseUp:
1439 if ( s_lastMouseDown == 2 )
1440 {
1441 ev->modifiers |= controlKey ;
1442 }
1443 else
1444 {
1445 ev->modifiers &= ~controlKey ;
1446 }
1447 MacHandleMouseUpEvent( ev ) ;
1448 s_lastMouseDown = 0;
1449 break;
1450 case activateEvt:
1451 MacHandleActivateEvent( ev ) ;
1452 break;
1453 case updateEvt:
1454 MacHandleUpdateEvent( ev ) ;
1455 break;
1456 case keyDown:
1457 case autoKey:
1458 MacHandleKeyDownEvent( ev ) ;
1459 break;
1460 case keyUp:
1461 MacHandleKeyUpEvent( ev ) ;
1462 break;
1463 case diskEvt:
1464 MacHandleDiskEvent( ev ) ;
1465 break;
1466 case osEvt:
1467 MacHandleOSEvent( ev ) ;
1468 break;
1469 case kHighLevelEvent:
1470 MacHandleHighLevelEvent( ev ) ;
1471 break;
1472 default:
1473 break;
1474 }
1475 #endif
1476 wxMacProcessNotifierAndPendingEvents() ;
1477 }
1478
1479 #if !TARGET_CARBON
1480 bool s_macIsInModalLoop = false ;
1481
1482 void wxApp::MacHandleModifierEvents( WXEVENTREF evr )
1483 {
1484 EventRecord* ev = (EventRecord*) evr ;
1485 if ( ev->modifiers != s_lastModifiers && wxWindow::FindFocus() != NULL )
1486 {
1487 wxKeyEvent event(wxEVT_KEY_DOWN);
1488
1489 event.m_shiftDown = ev->modifiers & shiftKey;
1490 event.m_controlDown = ev->modifiers & controlKey;
1491 event.m_altDown = ev->modifiers & optionKey;
1492 event.m_metaDown = ev->modifiers & cmdKey;
1493
1494 event.m_x = ev->where.h;
1495 event.m_y = ev->where.v;
1496 event.m_timeStamp = ev->when;
1497 wxWindow* focus = wxWindow::FindFocus() ;
1498 event.SetEventObject(focus);
1499
1500 if ( (ev->modifiers ^ s_lastModifiers ) & controlKey )
1501 {
1502 event.m_keyCode = WXK_CONTROL ;
1503 event.SetEventType( ( ev->modifiers & controlKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
1504 focus->GetEventHandler()->ProcessEvent( event ) ;
1505 }
1506 if ( (ev->modifiers ^ s_lastModifiers ) & shiftKey )
1507 {
1508 event.m_keyCode = WXK_SHIFT ;
1509 event.SetEventType( ( ev->modifiers & shiftKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
1510 focus->GetEventHandler()->ProcessEvent( event ) ;
1511 }
1512 if ( (ev->modifiers ^ s_lastModifiers ) & optionKey )
1513 {
1514 event.m_keyCode = WXK_ALT ;
1515 event.SetEventType( ( ev->modifiers & optionKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
1516 focus->GetEventHandler()->ProcessEvent( event ) ;
1517 }
1518 s_lastModifiers = ev->modifiers ;
1519 }
1520 }
1521
1522 void wxApp::MacHandleHighLevelEvent( WXEVENTREF evr )
1523 {
1524 // we must avoid reentrancy problems when processing high level events eg printing
1525 bool former = s_inYield ;
1526 s_inYield = TRUE ;
1527 EventRecord* ev = (EventRecord*) evr ;
1528 ::AEProcessAppleEvent( ev ) ;
1529 s_inYield = former ;
1530 }
1531
1532 void wxApp::MacHandleMouseDownEvent( WXEVENTREF evr )
1533 {
1534 EventRecord* ev = (EventRecord*) evr ;
1535 wxToolTip::RemoveToolTips() ;
1536
1537 WindowRef window;
1538 WindowRef frontWindow = ::FrontNonFloatingWindow() ;
1539 WindowAttributes frontWindowAttributes = NULL ;
1540 if ( frontWindow )
1541 ::GetWindowAttributes( frontWindow , &frontWindowAttributes ) ;
1542
1543 short windowPart = ::FindWindow(ev->where, &window);
1544 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
1545 if ( wxPendingDelete.Member(win) )
1546 return ;
1547
1548 BitMap screenBits;
1549 GetQDGlobalsScreenBits( &screenBits );
1550
1551 switch (windowPart)
1552 {
1553 case inMenuBar :
1554 if ( s_macIsInModalLoop )
1555 {
1556 SysBeep ( 30 ) ;
1557 }
1558 else
1559 {
1560 UInt32 menuresult = MenuSelect(ev->where) ;
1561 MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) );
1562 s_lastMouseDown = 0;
1563 }
1564 break ;
1565 case inSysWindow :
1566 SystemClick( ev , window ) ;
1567 s_lastMouseDown = 0;
1568 break ;
1569 case inDrag :
1570 if ( window != frontWindow && s_macIsInModalLoop && !(ev->modifiers & cmdKey ) )
1571 {
1572 SysBeep ( 30 ) ;
1573 }
1574 else
1575 {
1576 DragWindow(window, ev->where, &screenBits.bounds);
1577 if (win)
1578 {
1579 GrafPtr port ;
1580 GetPort( &port ) ;
1581 Point pt = { 0, 0 } ;
1582 SetPortWindowPort(window) ;
1583 LocalToGlobal( &pt ) ;
1584 SetPort( port ) ;
1585 win->SetSize( pt.h , pt.v , -1 ,
1586 -1 , wxSIZE_USE_EXISTING);
1587 }
1588 s_lastMouseDown = 0;
1589 }
1590 break ;
1591 case inGoAway:
1592 if (TrackGoAway(window, ev->where))
1593 {
1594 if ( win )
1595 win->Close() ;
1596 }
1597 s_lastMouseDown = 0;
1598 break;
1599 case inGrow:
1600 {
1601 Rect newContentRect ;
1602 Rect constraintRect ;
1603 constraintRect.top = win->GetMinHeight() ;
1604 if ( constraintRect.top == -1 )
1605 constraintRect.top = 0 ;
1606 constraintRect.left = win->GetMinWidth() ;
1607 if ( constraintRect.left == -1 )
1608 constraintRect.left = 0 ;
1609 constraintRect.right = win->GetMaxWidth() ;
1610 if ( constraintRect.right == -1 )
1611 constraintRect.right = 32000 ;
1612 constraintRect.bottom = win->GetMaxHeight() ;
1613 if ( constraintRect.bottom == -1 )
1614 constraintRect.bottom = 32000 ;
1615
1616 Boolean growResult = ResizeWindow( window , ev->where ,
1617 &constraintRect , &newContentRect ) ;
1618 if ( growResult )
1619 {
1620 win->SetSize( newContentRect.left , newContentRect.top ,
1621 newContentRect.right - newContentRect.left ,
1622 newContentRect.bottom - newContentRect.top, wxSIZE_USE_EXISTING);
1623 }
1624 s_lastMouseDown = 0;
1625 }
1626 break;
1627 case inZoomIn:
1628 case inZoomOut:
1629 if (TrackBox(window, ev->where, windowPart))
1630 {
1631 // TODO setup size event
1632 ZoomWindow( window , windowPart , false ) ;
1633 if (win)
1634 {
1635 Rect tempRect ;
1636 GrafPtr port ;
1637 GetPort( &port ) ;
1638 Point pt = { 0, 0 } ;
1639 SetPortWindowPort(window) ;
1640 LocalToGlobal( &pt ) ;
1641 SetPort( port ) ;
1642
1643 GetWindowPortBounds(window, &tempRect ) ;
1644 win->SetSize( pt.h , pt.v , tempRect.right-tempRect.left ,
1645 tempRect.bottom-tempRect.top, wxSIZE_USE_EXISTING);
1646 }
1647 }
1648 s_lastMouseDown = 0;
1649 break;
1650 case inCollapseBox :
1651 // TODO setup size event
1652 s_lastMouseDown = 0;
1653 break ;
1654
1655 case inContent :
1656 {
1657 GrafPtr port ;
1658 GetPort( &port ) ;
1659 SetPortWindowPort(window) ;
1660 SetPort( port ) ;
1661 }
1662 if ( window != frontWindow && wxTheApp->s_captureWindow == NULL )
1663 {
1664 if ( s_macIsInModalLoop )
1665 {
1666 SysBeep ( 30 ) ;
1667 }
1668 else if ( UMAIsWindowFloating( window ) )
1669 {
1670 if ( win )
1671 win->MacMouseDown( ev , windowPart ) ;
1672 }
1673 else
1674 {
1675 if ( win )
1676 win->MacMouseDown( ev , windowPart ) ;
1677 ::SelectWindow( window ) ;
1678 }
1679 }
1680 else
1681 {
1682 if ( win )
1683 win->MacMouseDown( ev , windowPart ) ;
1684 }
1685 break ;
1686 default:
1687 break;
1688 }
1689 }
1690
1691 void wxApp::MacHandleMouseUpEvent( WXEVENTREF evr )
1692 {
1693 EventRecord* ev = (EventRecord*) evr ;
1694 WindowRef window;
1695
1696 short windowPart = inNoWindow ;
1697 if ( wxTheApp->s_captureWindow )
1698 {
1699 window = (WindowRef) s_captureWindow->MacGetRootWindow() ;
1700 windowPart = inContent ;
1701 }
1702 else
1703 {
1704 windowPart = ::FindWindow(ev->where, &window) ;
1705 }
1706
1707 switch (windowPart)
1708 {
1709 case inMenuBar :
1710 break ;
1711 case inSysWindow :
1712 break ;
1713 default:
1714 {
1715 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
1716 if ( win )
1717 win->MacMouseUp( ev , windowPart ) ;
1718 }
1719 break;
1720 }
1721 }
1722
1723 #endif
1724
1725 long wxMacTranslateKey(unsigned char key, unsigned char code) ;
1726 long wxMacTranslateKey(unsigned char key, unsigned char code)
1727 {
1728 long retval = key ;
1729 switch (key)
1730 {
1731 case kHomeCharCode :
1732 retval = WXK_HOME;
1733 break;
1734 case kEnterCharCode :
1735 retval = WXK_RETURN;
1736 break;
1737 case kEndCharCode :
1738 retval = WXK_END;
1739 break;
1740 case kHelpCharCode :
1741 retval = WXK_HELP;
1742 break;
1743 case kBackspaceCharCode :
1744 retval = WXK_BACK;
1745 break;
1746 case kTabCharCode :
1747 retval = WXK_TAB;
1748 break;
1749 case kPageUpCharCode :
1750 retval = WXK_PAGEUP;
1751 break;
1752 case kPageDownCharCode :
1753 retval = WXK_PAGEDOWN;
1754 break;
1755 case kReturnCharCode :
1756 retval = WXK_RETURN;
1757 break;
1758 case kFunctionKeyCharCode :
1759 {
1760 switch( code )
1761 {
1762 case 0x7a :
1763 retval = WXK_F1 ;
1764 break;
1765 case 0x78 :
1766 retval = WXK_F2 ;
1767 break;
1768 case 0x63 :
1769 retval = WXK_F3 ;
1770 break;
1771 case 0x76 :
1772 retval = WXK_F4 ;
1773 break;
1774 case 0x60 :
1775 retval = WXK_F5 ;
1776 break;
1777 case 0x61 :
1778 retval = WXK_F6 ;
1779 break;
1780 case 0x62:
1781 retval = WXK_F7 ;
1782 break;
1783 case 0x64 :
1784 retval = WXK_F8 ;
1785 break;
1786 case 0x65 :
1787 retval = WXK_F9 ;
1788 break;
1789 case 0x6D :
1790 retval = WXK_F10 ;
1791 break;
1792 case 0x67 :
1793 retval = WXK_F11 ;
1794 break;
1795 case 0x6F :
1796 retval = WXK_F12 ;
1797 break;
1798 case 0x69 :
1799 retval = WXK_F13 ;
1800 break;
1801 case 0x6B :
1802 retval = WXK_F14 ;
1803 break;
1804 case 0x71 :
1805 retval = WXK_F15 ;
1806 break;
1807 }
1808 }
1809 break ;
1810 case kEscapeCharCode :
1811 retval = WXK_ESCAPE ;
1812 break ;
1813 case kLeftArrowCharCode :
1814 retval = WXK_LEFT ;
1815 break ;
1816 case kRightArrowCharCode :
1817 retval = WXK_RIGHT ;
1818 break ;
1819 case kUpArrowCharCode :
1820 retval = WXK_UP ;
1821 break ;
1822 case kDownArrowCharCode :
1823 retval = WXK_DOWN ;
1824 break ;
1825 case kDeleteCharCode :
1826 retval = WXK_DELETE ;
1827 default:
1828 break ;
1829 } // end switch
1830
1831 return retval;
1832 }
1833
1834 #if !TARGET_CARBON
1835 void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr )
1836 {
1837 EventRecord* ev = (EventRecord*) evr ;
1838 wxToolTip::RemoveToolTips() ;
1839
1840 UInt32 menuresult = UMAMenuEvent(ev) ;
1841 if ( HiWord( menuresult ) )
1842 {
1843 if ( !s_macIsInModalLoop )
1844 MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ) ;
1845 }
1846 else
1847 {
1848 wxWindow* focus = wxWindow::FindFocus() ;
1849
1850 if ( MacSendKeyDownEvent( focus , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) == false )
1851 {
1852 // has not been handled -> perform default
1853 wxControl* control = wxDynamicCast( focus , wxControl ) ;
1854 if ( control && control->GetMacControl() != NULL )
1855 {
1856 short keycode ;
1857 short keychar ;
1858 keychar = short(ev->message & charCodeMask);
1859 keycode = short(ev->message & keyCodeMask) >> 8 ;
1860 ::HandleControlKey( (ControlHandle) control->GetMacControl() , keycode , keychar , ev->modifiers ) ;
1861 }
1862 }
1863 }
1864 }
1865
1866 void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr )
1867 {
1868 EventRecord* ev = (EventRecord*) evr ;
1869 wxToolTip::RemoveToolTips() ;
1870
1871 UInt32 menuresult = UMAMenuEvent(ev) ;
1872 if ( HiWord( menuresult ) )
1873 {
1874 }
1875 else
1876 {
1877 MacSendKeyUpEvent( wxWindow::FindFocus() , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) ;
1878 }
1879 }
1880
1881 #endif
1882
1883 bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey )
1884 {
1885 if ( !focus )
1886 return false ;
1887
1888 short keycode ;
1889 short keychar ;
1890 keychar = short(keymessage & charCodeMask);
1891 keycode = short(keymessage & keyCodeMask) >> 8 ;
1892
1893 if ( modifiers & ( controlKey|shiftKey|optionKey ) )
1894 {
1895 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
1896 // and look at the character after
1897 UInt32 state = 0;
1898 UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state);
1899 keychar = short(keyInfo & charCodeMask);
1900 keycode = short(keyInfo & keyCodeMask) >> 8 ;
1901 }
1902 long keyval = wxMacTranslateKey(keychar, keycode) ;
1903 long realkeyval = keyval ;
1904 if ( keyval == keychar )
1905 {
1906 // 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)
1907 realkeyval = short(keymessage & charCodeMask) ;
1908 keyval = wxToupper( keyval ) ;
1909 }
1910
1911 wxKeyEvent event(wxEVT_KEY_DOWN);
1912 bool handled = false ;
1913 event.m_shiftDown = modifiers & shiftKey;
1914 event.m_controlDown = modifiers & controlKey;
1915 event.m_altDown = modifiers & optionKey;
1916 event.m_metaDown = modifiers & cmdKey;
1917 event.m_keyCode = keyval ;
1918
1919 event.m_x = wherex;
1920 event.m_y = wherey;
1921 event.m_timeStamp = when;
1922 event.SetEventObject(focus);
1923 handled = focus->GetEventHandler()->ProcessEvent( event ) ;
1924 if ( handled && event.GetSkipped() )
1925 handled = false ;
1926 if ( !handled )
1927 {
1928 #if wxUSE_ACCEL
1929 if (!handled)
1930 {
1931 wxWindow *ancestor = focus;
1932 while (ancestor)
1933 {
1934 int command = ancestor->GetAcceleratorTable()->GetCommand( event );
1935 if (command != -1)
1936 {
1937 wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
1938 handled = ancestor->GetEventHandler()->ProcessEvent( command_event );
1939 break;
1940 }
1941 if (ancestor->IsTopLevel())
1942 break;
1943 ancestor = ancestor->GetParent();
1944 }
1945 }
1946 #endif // wxUSE_ACCEL
1947 }
1948 if (!handled)
1949 {
1950 event.Skip( FALSE ) ;
1951 event.SetEventType( wxEVT_CHAR ) ;
1952 // raw value again
1953 event.m_keyCode = realkeyval ;
1954
1955 handled = focus->GetEventHandler()->ProcessEvent( event ) ;
1956 if ( handled && event.GetSkipped() )
1957 handled = false ;
1958 }
1959 if ( !handled &&
1960 (keyval == WXK_TAB) &&
1961 // CS: copied the change below from wxGTK
1962 // VZ: testing for wxTE_PROCESS_TAB shouldn't be done here the control may
1963 // have this style, yet choose not to process this particular TAB in which
1964 // case TAB must still work as a navigational character
1965 #if 0
1966 (!focus->HasFlag(wxTE_PROCESS_TAB)) &&
1967 #endif
1968 (focus->GetParent()) &&
1969 (focus->GetParent()->HasFlag( wxTAB_TRAVERSAL)) )
1970 {
1971 wxNavigationKeyEvent new_event;
1972 new_event.SetEventObject( focus );
1973 new_event.SetDirection( !event.ShiftDown() );
1974 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
1975 new_event.SetWindowChange( event.ControlDown() );
1976 new_event.SetCurrentFocus( focus );
1977 handled = focus->GetEventHandler()->ProcessEvent( new_event );
1978 if ( handled && new_event.GetSkipped() )
1979 handled = false ;
1980 }
1981 // backdoor handler for default return and command escape
1982 if ( !handled && (!focus->IsKindOf(CLASSINFO(wxControl) ) || !focus->MacCanFocus() ) )
1983 {
1984 // if window is not having a focus still testing for default enter or cancel
1985 // TODO add the UMA version for ActiveNonFloatingWindow
1986 wxWindow* focus = wxFindWinFromMacWindow( FrontWindow() ) ;
1987 if ( focus )
1988 {
1989 if ( keyval == WXK_RETURN )
1990 {
1991 wxButton *def = wxDynamicCast(focus->GetDefaultItem(),
1992 wxButton);
1993 if ( def && def->IsEnabled() )
1994 {
1995 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
1996 event.SetEventObject(def);
1997 def->Command(event);
1998 return true ;
1999 }
2000 }
2001 /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
2002 else if (keyval == WXK_ESCAPE || (keyval == '.' && modifiers & cmdKey ) )
2003 {
2004 wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL);
2005 new_event.SetEventObject( focus );
2006 handled = focus->GetEventHandler()->ProcessEvent( new_event );
2007 }
2008 }
2009 }
2010 return handled ;
2011 }
2012
2013 bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey )
2014 {
2015 if ( !focus )
2016 return false ;
2017
2018 short keycode ;
2019 short keychar ;
2020 keychar = short(keymessage & charCodeMask);
2021 keycode = short(keymessage & keyCodeMask) >> 8 ;
2022 if ( modifiers & ( controlKey|shiftKey|optionKey ) )
2023 {
2024 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
2025 // and look at the character after
2026 UInt32 state = 0;
2027 UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state);
2028 keychar = short(keyInfo & charCodeMask);
2029 keycode = short(keyInfo & keyCodeMask) >> 8 ;
2030 }
2031 long keyval = wxMacTranslateKey(keychar, keycode) ;
2032
2033 if ( keyval == keychar )
2034 {
2035 keyval = wxToupper( keyval ) ;
2036 }
2037 bool handled = false ;
2038
2039 wxKeyEvent event(wxEVT_KEY_UP);
2040 event.m_shiftDown = modifiers & shiftKey;
2041 event.m_controlDown = modifiers & controlKey;
2042 event.m_altDown = modifiers & optionKey;
2043 event.m_metaDown = modifiers & cmdKey;
2044 event.m_keyCode = keyval ;
2045
2046 event.m_x = wherex;
2047 event.m_y = wherey;
2048 event.m_timeStamp = when;
2049 event.SetEventObject(focus);
2050 handled = focus->GetEventHandler()->ProcessEvent( event ) ;
2051
2052 return handled ;
2053 }
2054
2055 #if !TARGET_CARBON
2056 void wxApp::MacHandleActivateEvent( WXEVENTREF evr )
2057 {
2058 EventRecord* ev = (EventRecord*) evr ;
2059 WindowRef window = (WindowRef) ev->message ;
2060 if ( window )
2061 {
2062 bool activate = (ev->modifiers & activeFlag ) ;
2063 WindowClass wclass ;
2064 ::GetWindowClass ( window , &wclass ) ;
2065 if ( wclass == kFloatingWindowClass )
2066 {
2067 // if it is a floater we activate/deactivate the front non-floating window instead
2068 window = ::FrontNonFloatingWindow() ;
2069 }
2070 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
2071 if ( win )
2072 win->MacActivate( ev->when , activate ) ;
2073 }
2074 }
2075
2076 void wxApp::MacHandleUpdateEvent( WXEVENTREF evr )
2077 {
2078 EventRecord* ev = (EventRecord*) evr ;
2079 WindowRef window = (WindowRef) ev->message ;
2080 wxTopLevelWindowMac * win = wxFindWinFromMacWindow( window ) ;
2081 if ( win )
2082 {
2083 if ( !wxPendingDelete.Member(win) )
2084 win->MacUpdate( ev->when ) ;
2085 }
2086 else
2087 {
2088 // since there is no way of telling this foreign window to update itself
2089 // we have to invalidate the update region otherwise we keep getting the same
2090 // event over and over again
2091 BeginUpdate( window ) ;
2092 EndUpdate( window ) ;
2093 }
2094 }
2095
2096 void wxApp::MacHandleDiskEvent( WXEVENTREF evr )
2097 {
2098 EventRecord* ev = (EventRecord*) evr ;
2099 if ( HiWord( ev->message ) != noErr )
2100 {
2101 OSErr err ;
2102 Point point ;
2103 SetPt( &point , 100 , 100 ) ;
2104
2105 err = DIBadMount( point , ev->message ) ;
2106 wxASSERT( err == noErr ) ;
2107 }
2108 }
2109
2110 void wxApp::MacHandleOSEvent( WXEVENTREF evr )
2111 {
2112 EventRecord* ev = (EventRecord*) evr ;
2113 switch( ( ev->message & osEvtMessageMask ) >> 24 )
2114 {
2115 case suspendResumeMessage :
2116 {
2117 bool isResuming = ev->message & resumeFlag ;
2118 bool convertClipboard = ev->message & convertClipboardFlag ;
2119
2120 bool doesActivate = UMAGetProcessModeDoesActivateOnFGSwitch() ;
2121 if ( isResuming )
2122 {
2123 WindowRef oldFrontWindow = NULL ;
2124 WindowRef newFrontWindow = NULL ;
2125
2126 // in case we don't take care of activating ourselves, we have to synchronize
2127 // our idea of the active window with the process manager's - which it already activated
2128
2129 if ( !doesActivate )
2130 oldFrontWindow = ::FrontNonFloatingWindow() ;
2131
2132 MacResume( convertClipboard ) ;
2133
2134 newFrontWindow = ::FrontNonFloatingWindow() ;
2135
2136 if ( oldFrontWindow )
2137 {
2138 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( oldFrontWindow ) ;
2139 if ( win )
2140 win->MacActivate( ev->when , false ) ;
2141 }
2142 if ( newFrontWindow )
2143 {
2144 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( newFrontWindow ) ;
2145 if ( win )
2146 win->MacActivate( ev->when , true ) ;
2147 }
2148 }
2149 else
2150 {
2151 MacSuspend( convertClipboard ) ;
2152 }
2153 }
2154 break ;
2155 case mouseMovedMessage :
2156 {
2157 WindowRef window;
2158
2159 wxWindow* currentMouseWindow = NULL ;
2160
2161 if (s_captureWindow )
2162 {
2163 currentMouseWindow = s_captureWindow ;
2164 }
2165 else
2166 {
2167 wxWindow::MacGetWindowFromPoint( wxPoint( ev->where.h , ev->where.v ) ,
2168 &currentMouseWindow ) ;
2169 }
2170
2171 if ( currentMouseWindow != wxWindow::s_lastMouseWindow )
2172 {
2173 wxMouseEvent event ;
2174
2175 bool isDown = !(ev->modifiers & btnState) ; // 1 is for up
2176 bool controlDown = ev->modifiers & controlKey ; // for simulating right mouse
2177
2178 event.m_leftDown = isDown && !controlDown;
2179 event.m_middleDown = FALSE;
2180 event.m_rightDown = isDown && controlDown;
2181 event.m_shiftDown = ev->modifiers & shiftKey;
2182 event.m_controlDown = ev->modifiers & controlKey;
2183 event.m_altDown = ev->modifiers & optionKey;
2184 event.m_metaDown = ev->modifiers & cmdKey;
2185 event.m_x = ev->where.h;
2186 event.m_y = ev->where.v;
2187 event.m_timeStamp = ev->when;
2188 event.SetEventObject(this);
2189
2190 if ( wxWindow::s_lastMouseWindow )
2191 {
2192 wxMouseEvent eventleave(event);
2193 eventleave.SetEventType( wxEVT_LEAVE_WINDOW );
2194 wxWindow::s_lastMouseWindow->ScreenToClient( &eventleave.m_x, &eventleave.m_y );
2195 eventleave.SetEventObject( wxWindow::s_lastMouseWindow ) ;
2196
2197 wxWindow::s_lastMouseWindow->GetEventHandler()->ProcessEvent(eventleave);
2198 }
2199 if ( currentMouseWindow )
2200 {
2201 wxMouseEvent evententer(event);
2202 evententer.SetEventType( wxEVT_ENTER_WINDOW );
2203 currentMouseWindow->ScreenToClient( &evententer.m_x, &evententer.m_y );
2204 evententer.SetEventObject( currentMouseWindow ) ;
2205 currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
2206 }
2207 wxWindow::s_lastMouseWindow = currentMouseWindow ;
2208 }
2209
2210 short windowPart = inNoWindow ;
2211
2212 if ( s_captureWindow )
2213 {
2214 window = (WindowRef) s_captureWindow->MacGetRootWindow() ;
2215 windowPart = inContent ;
2216 }
2217 else
2218 {
2219 windowPart = ::FindWindow(ev->where, &window);
2220 }
2221
2222 switch (windowPart)
2223 {
2224 case inContent :
2225 {
2226 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
2227 if ( win )
2228 win->MacMouseMoved( ev , windowPart ) ;
2229 else
2230 {
2231 if ( wxIsBusy() )
2232 {
2233 }
2234 else
2235 UMAShowArrowCursor();
2236 }
2237 }
2238 break;
2239 default :
2240 {
2241 if ( wxIsBusy() )
2242 {
2243 }
2244 else
2245 UMAShowArrowCursor();
2246 }
2247 break ;
2248 }
2249 }
2250 break ;
2251
2252 }
2253 }
2254 #endif
2255
2256 void wxApp::MacHandleMenuCommand( wxUint32 id )
2257 {
2258 wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ;
2259 wxFrame* frame = mbar->GetFrame();
2260 wxCHECK_RET( mbar != NULL && frame != NULL, wxT("error in menu item callback") );
2261 if ( frame )
2262 {
2263 frame->ProcessCommand(id);
2264 }
2265 }
2266
2267 #if !TARGET_CARBON
2268 void wxApp::MacHandleMenuSelect( int macMenuId , int macMenuItemNum )
2269 {
2270 if (macMenuId == 0)
2271 return; // no menu item selected
2272
2273 if (macMenuId == kwxMacAppleMenuId && macMenuItemNum > 1)
2274 {
2275 #if ! TARGET_CARBON
2276 Str255 deskAccessoryName ;
2277 GrafPtr savedPort ;
2278
2279 GetMenuItemText(GetMenuHandle(kwxMacAppleMenuId), macMenuItemNum, deskAccessoryName);
2280 GetPort(&savedPort);
2281 OpenDeskAcc(deskAccessoryName);
2282 SetPort(savedPort);
2283 #endif
2284 }
2285 else
2286 {
2287 MenuCommand id ;
2288 GetMenuItemCommandID( GetMenuHandle(macMenuId) , macMenuItemNum , &id ) ;
2289 MacHandleMenuCommand( id ) ;
2290 }
2291 HiliteMenu(0);
2292 }
2293 #endif