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