]> git.saurik.com Git - wxWidgets.git/blob - src/mac/app.cpp
71ea9d67d1786234d6a3b2e287a41b5f879bd14c
[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 wxApp *wxTheApp = NULL;
86
87 #if !USE_SHARED_LIBRARY
88 IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
89 BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
90 EVT_IDLE(wxApp::OnIdle)
91 EVT_END_SESSION(wxApp::OnEndSession)
92 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
93 END_EVENT_TABLE()
94 #endif
95
96
97 const short kMacMinHeap = (29 * 1024) ;
98 // platform specific static variables
99
100 const short kwxMacMenuBarResource = 1 ;
101 const short kwxMacAppleMenuId = 1 ;
102
103 WXHRGN wxApp::s_macCursorRgn = NULL;
104 wxWindow* wxApp::s_captureWindow = NULL ;
105 int wxApp::s_lastMouseDown = 0 ;
106 long wxApp::sm_lastMessageTime = 0;
107 long wxApp::s_lastModifiers = 0 ;
108
109
110 bool wxApp::s_macDefaultEncodingIsPC = true ;
111 bool wxApp::s_macSupportPCMenuShortcuts = true ;
112 long wxApp::s_macAboutMenuItemId = wxID_ABOUT ;
113 long wxApp::s_macPreferencesMenuItemId = 0 ;
114 long wxApp::s_macExitMenuItemId = wxID_EXIT ;
115 wxString wxApp::s_macHelpMenuTitleName = wxT("&Help") ;
116
117 //----------------------------------------------------------------------
118 // Core Apple Event Support
119 //----------------------------------------------------------------------
120
121 pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
122 pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
123 pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
124 pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
125
126 pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
127 {
128 return wxTheApp->MacHandleAEODoc( (AppleEvent*) event , reply) ;
129 }
130
131 pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
132 {
133 return wxTheApp->MacHandleAEOApp( (AppleEvent*) event , reply ) ;
134 }
135
136 pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
137 {
138 return wxTheApp->MacHandleAEPDoc( (AppleEvent*) event , reply ) ;
139 }
140
141 pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
142 {
143 return wxTheApp->MacHandleAEQuit( (AppleEvent*) event , reply) ;
144 }
145
146 // AEODoc Calls MacOpenFile on each of the files passed
147
148 short wxApp::MacHandleAEODoc(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply))
149 {
150 AEDescList docList;
151 AEKeyword keywd;
152 DescType returnedType;
153 Size actualSize;
154 long itemsInList;
155 FSSpec theSpec;
156 OSErr err;
157 short i;
158 err = AEGetParamDesc((AppleEvent *)event, keyDirectObject, typeAEList,&docList);
159 if (err != noErr)
160 return err;
161
162 err = AECountItems(&docList, &itemsInList);
163 if (err != noErr)
164 return err;
165
166 ProcessSerialNumber PSN ;
167 PSN.highLongOfPSN = 0 ;
168 PSN.lowLongOfPSN = kCurrentProcess ;
169 SetFrontProcess( &PSN ) ;
170
171 for (i = 1; i <= itemsInList; i++) {
172 AEGetNthPtr(&docList, i, typeFSS, &keywd, &returnedType,
173 (Ptr) & theSpec, sizeof(theSpec), &actualSize);
174 wxString fName = wxMacFSSpec2MacFilename(&theSpec);
175 MacOpenFile(fName);
176 }
177 return noErr;
178 }
179
180 // AEPDoc Calls MacPrintFile on each of the files passed
181
182 short wxApp::MacHandleAEPDoc(const WXEVENTREF event , WXEVENTREF WXUNUSED(reply))
183 {
184 AEDescList docList;
185 AEKeyword keywd;
186 DescType returnedType;
187 Size actualSize;
188 long itemsInList;
189 FSSpec theSpec;
190 OSErr err;
191 short i;
192 err = AEGetParamDesc((AppleEvent *)event, keyDirectObject, typeAEList,&docList);
193 if (err != noErr)
194 return err;
195
196 err = AECountItems(&docList, &itemsInList);
197 if (err != noErr)
198 return err;
199
200 ProcessSerialNumber PSN ;
201 PSN.highLongOfPSN = 0 ;
202 PSN.lowLongOfPSN = kCurrentProcess ;
203 SetFrontProcess( &PSN ) ;
204
205 for (i = 1; i <= itemsInList; i++) {
206 AEGetNthPtr(&docList, i, typeFSS, &keywd, &returnedType,
207 (Ptr) & theSpec, sizeof(theSpec), &actualSize);
208 wxString fName = wxMacFSSpec2MacFilename(&theSpec);
209 MacPrintFile(fName);
210 }
211 return noErr;
212 }
213
214 // AEOApp calls MacNewFile
215
216 short wxApp::MacHandleAEOApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
217 {
218 MacNewFile() ;
219 return noErr ;
220 }
221
222 // AEQuit attempts to quite the application
223
224 short wxApp::MacHandleAEQuit(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
225 {
226 /* wxWindow* win = GetTopWindow() ;
227 if ( win )
228 {
229 win->Close(TRUE ) ;
230 }
231 else
232 */
233 {
234 ExitMainLoop() ;
235 }
236 return noErr ;
237 }
238
239 //----------------------------------------------------------------------
240 // Support Routines linking the Mac...File Calls to the Document Manager
241 //----------------------------------------------------------------------
242
243 void wxApp::MacOpenFile(const wxString & fileName )
244 {
245 wxDocManager* dm = wxDocManager::GetDocumentManager() ;
246 if ( dm )
247 dm->CreateDocument(fileName , wxDOC_SILENT ) ;
248 }
249
250 void wxApp::MacPrintFile(const wxString & fileName )
251 {
252 wxDocManager* dm = wxDocManager::GetDocumentManager() ;
253 if ( dm )
254 {
255 wxDocument *doc = dm->CreateDocument(fileName , wxDOC_SILENT ) ;
256 if ( doc )
257 {
258 wxView* view = doc->GetFirstView() ;
259 if( view )
260 {
261 wxPrintout *printout = view->OnCreatePrintout();
262 if (printout)
263 {
264 wxPrinter printer;
265 printer.Print(view->GetFrame(), printout, TRUE);
266 delete printout;
267 }
268 }
269 if (doc->Close())
270 {
271 doc->DeleteAllViews();
272 dm->RemoveDocument(doc) ;
273 }
274 }
275 }
276 }
277
278 void wxApp::MacNewFile()
279 {
280 }
281
282 //----------------------------------------------------------------------
283 // Carbon Event Handler
284 //----------------------------------------------------------------------
285
286 #if TARGET_CARBON
287
288 static const EventTypeSpec eventList[] =
289 {
290 { kEventClassCommand, kEventProcessCommand } ,
291 { kEventClassCommand, kEventCommandUpdateStatus } ,
292
293 { kEventClassApplication , kEventAppActivated } ,
294 { kEventClassApplication , kEventAppDeactivated } ,
295 // handling the quit event is not recommended by apple
296 // rather using the quit apple event - which we do
297
298 { kEventClassAppleEvent , kEventAppleEvent } ,
299
300 { kEventClassMouse , kEventMouseDown } ,
301 { 'WXMC' , 'WXMC' }
302 } ;
303
304 static pascal OSStatus MenuEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
305 {
306 OSStatus result = eventNotHandledErr ;
307 UInt32 kind = GetEventKind( event ) ;
308
309 return result ;
310 }
311
312 // due to the rather low-level event API of wxWindows, we cannot use RunApplicationEventLoop
313 // but have to use ReceiveNextEvent dealing with events manually, therefore we also have
314 // deal with clicks in the menu bar explicitely
315
316 static pascal OSStatus MouseEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
317 {
318 OSStatus result = eventNotHandledErr ;
319
320 switch( GetEventKind(event) )
321 {
322 case kEventMouseDown :
323 {
324 Point point ;
325 WindowRef window ;
326
327 GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL,
328 sizeof( Point ), NULL, &point );
329 short windowPart = ::FindWindow(point, &window);
330
331 if ( windowPart == inMenuBar )
332 {
333 MenuSelect( point ) ;
334 result = noErr ;
335 }
336 }
337 break ;
338 }
339
340 return result ;
341 }
342
343 static pascal OSStatus CommandEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
344 {
345 OSStatus result = eventNotHandledErr ;
346
347 HICommand command ;
348
349 GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL,
350 sizeof( HICommand ), NULL, &command );
351
352 MenuCommand id = command.commandID ;
353 if ( id == kHICommandPreferences )
354 id = wxApp::s_macPreferencesMenuItemId ;
355
356 wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ;
357 wxMenu* menu = NULL ;
358 wxMenuItem* item = NULL ;
359
360 if ( mbar )
361 item = mbar->FindItem( id , &menu ) ;
362
363 if ( item == NULL || menu == NULL || mbar == NULL )
364 return result ;
365
366 switch( GetEventKind( event ) )
367 {
368 case kEventProcessCommand :
369 {
370 if (item->IsCheckable())
371 {
372 item->Check( !item->IsChecked() ) ;
373 }
374
375 menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
376 result = noErr ;
377 }
378 break ;
379 case kEventCommandUpdateStatus:
380 // eventually trigger an updateui round
381 result = noErr ;
382 break ;
383 default :
384 break ;
385 }
386
387 return result ;
388 }
389
390 static pascal OSStatus ApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
391 {
392 OSStatus result = eventNotHandledErr ;
393 switch ( GetEventKind( event ) )
394 {
395 case kEventAppActivated :
396 {
397 if ( wxTheApp )
398 wxTheApp->MacResume( true ) ;
399 result = noErr ;
400 }
401 break ;
402 case kEventAppDeactivated :
403 {
404 if ( wxTheApp )
405 wxTheApp->MacSuspend( true ) ;
406 result = noErr ;
407 }
408 break ;
409 default :
410 break ;
411 }
412 return result ;
413 }
414
415 pascal OSStatus wxAppEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
416 {
417 OSStatus result = eventNotHandledErr ;
418 switch( GetEventClass( event ) )
419 {
420 case kEventClassCommand :
421 result = CommandEventHandler( handler , event , data ) ;
422 break ;
423 case kEventClassApplication :
424 result = ApplicationEventHandler( handler , event , data ) ;
425 break ;
426 case kEventClassMenu :
427 result = MenuEventHandler( handler , event , data ) ;
428 break ;
429 case kEventClassMouse :
430 result = MouseEventHandler( handler , event , data ) ;
431 break ;
432 case kEventClassAppleEvent :
433 {
434 EventRecord rec ;
435 wxMacConvertEventToRecord( event , &rec ) ;
436 result = AEProcessAppleEvent( &rec ) ;
437 }
438 break ;
439 default :
440 break ;
441 }
442
443 return result ;
444 }
445
446 DEFINE_ONE_SHOT_HANDLER_GETTER( wxAppEventHandler )
447
448 #endif
449
450 #if defined(WXMAKINGDLL) && !defined(__DARWIN__)
451 // we know it's there ;-)
452 WXIMPORT char std::__throws_bad_alloc ;
453 #endif
454
455 bool wxApp::Initialize()
456 {
457 int error = 0 ;
458
459 // Mac-specific
460
461 UMAInitToolbox( 4 ) ;
462 SetEventMask( everyEvent ) ;
463 UMAShowWatchCursor() ;
464
465 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
466 // open shared library resources from here since we don't have
467 // __wxinitialize in Mach-O shared libraries
468 wxStAppResource::OpenSharedLibraryResource(NULL);
469 #endif
470
471 #ifndef __DARWIN__
472 // test the minimal configuration necessary
473
474 # if !TARGET_CARBON
475 long theSystem ;
476 long theMachine;
477
478 if (Gestalt(gestaltMachineType, &theMachine) != noErr)
479 {
480 error = kMacSTRWrongMachine;
481 }
482 else if (theMachine < gestaltMacPlus)
483 {
484 error = kMacSTRWrongMachine;
485 }
486 else if (Gestalt(gestaltSystemVersion, &theSystem) != noErr )
487 {
488 error = kMacSTROldSystem ;
489 }
490 else if ( theSystem < 0x0860 )
491 {
492 error = kMacSTROldSystem ;
493 }
494 else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap)
495 {
496 error = kMacSTRSmallSize;
497 }
498 # endif
499 /*
500 else
501 {
502 if ( !UMAHasAppearance() )
503 {
504 error = kMacSTRNoPre8Yet ;
505 }
506 }
507 */
508 #endif
509
510 // if we encountered any problems so far, give the error code and exit immediately
511
512 if ( error )
513 {
514 wxStAppResource resload ;
515 short itemHit;
516 Str255 message;
517
518 GetIndString(message, 128, error);
519 UMAShowArrowCursor() ;
520 ParamText("\pFatal Error", message, (ConstStr255Param)"\p", (ConstStr255Param)"\p");
521 itemHit = Alert(128, nil);
522 return FALSE ;
523 }
524
525 #ifndef __DARWIN__
526 # if __option(profile)
527 ProfilerInit( collectDetailed, bestTimeBase , 20000 , 40 ) ;
528 # endif
529 #endif
530
531 #ifndef __DARWIN__
532 // now avoid exceptions thrown for new (bad_alloc)
533 // FIXME CS for some changes outside wxMac does not compile anymore
534 #if 0
535 std::__throws_bad_alloc = 0 ;
536 #endif
537
538 #endif
539 wxMacSetupConverters() ;
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 wxWinMacWindowList = new wxList(wxKEY_INTEGER);
557 wxWinMacControlList = new wxList(wxKEY_INTEGER);
558
559 wxInitializeStockLists();
560 wxInitializeStockObjects();
561
562 wxBitmap::InitStandardHandlers();
563
564 wxModule::RegisterModules();
565 if (!wxModule::InitializeModules()) {
566 return FALSE;
567 }
568
569 wxMacCreateNotifierTable() ;
570
571 UMAShowArrowCursor() ;
572
573 return TRUE;
574 }
575
576 bool wxApp::OnInitGui()
577 {
578 if( !wxAppBase::OnInitGui() )
579 return false ;
580
581 #if TARGET_CARBON
582 InstallStandardEventHandler( GetApplicationEventTarget() ) ;
583
584 InstallApplicationEventHandler(
585 GetwxAppEventHandlerUPP(),
586 GetEventTypeCount(eventList), eventList, wxTheApp, &((EventHandlerRef)wxTheApp->m_macEventHandler));
587 #endif
588
589 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
590 AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
591 NewAEEventHandlerUPP(AEHandleODoc) ,
592 0 , FALSE ) ;
593 AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
594 NewAEEventHandlerUPP(AEHandleOApp) ,
595 0 , FALSE ) ;
596 AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
597 NewAEEventHandlerUPP(AEHandlePDoc) ,
598 0 , FALSE ) ;
599 AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
600 NewAEEventHandlerUPP(AEHandleQuit) ,
601 0 , FALSE ) ;
602 #else
603 AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
604 NewAEEventHandlerProc(AEHandleODoc) ,
605 0 , FALSE ) ;
606 AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
607 NewAEEventHandlerProc(AEHandleOApp) ,
608 0 , FALSE ) ;
609 AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
610 NewAEEventHandlerProc(AEHandlePDoc) ,
611 0 , FALSE ) ;
612 AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
613 NewAEEventHandlerProc(AEHandleQuit) ,
614 0 , FALSE ) ;
615 #endif
616
617 return TRUE ;
618 }
619
620 void wxApp::CleanUp()
621 {
622 wxToolTip::RemoveToolTips() ;
623 #if wxUSE_LOG
624 // flush the logged messages if any and install a 'safer' log target: the
625 // default one (wxLogGui) can't be used after the resources are freed just
626 // below and the user suppliedo ne might be even more unsafe (using any
627 // wxWindows GUI function is unsafe starting from now)
628 wxLog::DontCreateOnDemand();
629
630 // this will flush the old messages if any
631 delete wxLog::SetActiveTarget(new wxLogStderr);
632 #endif // wxUSE_LOG
633
634 // One last chance for pending objects to be cleaned up
635 wxTheApp->DeletePendingObjects();
636
637 wxModule::CleanUpModules();
638
639 wxDeleteStockObjects() ;
640
641 // Destroy all GDI lists, etc.
642 wxDeleteStockLists();
643
644 delete wxTheColourDatabase;
645 wxTheColourDatabase = NULL;
646
647 wxBitmap::CleanUpHandlers();
648
649 wxMacDestroyNotifierTable() ;
650 if (wxWinMacWindowList) {
651 delete wxWinMacWindowList ;
652 }
653 if (wxWinMacControlList) {
654 delete wxWinMacControlList ;
655 }
656 delete wxPendingEvents;
657
658 #if wxUSE_THREADS
659 delete wxPendingEventsLocker;
660 // There is still more cleanup code that will try to use this if not NULL.
661 wxPendingEventsLocker = NULL;
662 // If we don't do the following, we get an apparent memory leak.
663 ((wxEvtHandler&) wxDefaultValidator).ClearEventLocker();
664 #endif
665
666 wxClassInfo::CleanUpClasses();
667
668 #ifndef __DARWIN__
669 # if __option(profile)
670 ProfilerDump( "\papp.prof" ) ;
671 ProfilerTerm() ;
672 # endif
673 #endif
674
675 delete wxTheApp;
676 wxTheApp = NULL;
677
678 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
679 // At this point we want to check if there are any memory
680 // blocks that aren't part of the wxDebugContext itself,
681 // as a special case. Then when dumping we need to ignore
682 // wxDebugContext, too.
683 if (wxDebugContext::CountObjectsLeft(TRUE) > 0)
684 {
685 wxLogDebug(wxT("There were memory leaks."));
686 wxDebugContext::Dump();
687 wxDebugContext::PrintStatistics();
688 }
689 // wxDebugContext::SetStream(NULL, NULL);
690 #endif
691
692 #if wxUSE_LOG
693 // do it as the very last thing because everything else can log messages
694 delete wxLog::SetActiveTarget(NULL);
695 #endif // wxUSE_LOG
696
697 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
698 // close shared library resources from here since we don't have
699 // __wxterminate in Mach-O shared libraries
700 wxStAppResource::CloseSharedLibraryResource();
701 #endif
702 wxMacCleanupConverters() ;
703
704 UMACleanupToolbox() ;
705 if (s_macCursorRgn) {
706 ::DisposeRgn((RgnHandle)s_macCursorRgn);
707 }
708
709 #if 0
710 TerminateAE() ;
711 #endif
712 }
713
714 //----------------------------------------------------------------------
715 // wxEntry
716 //----------------------------------------------------------------------
717
718 // extern variable for shared library resource id
719 // need to be able to find it with NSLookupAndBindSymbol
720 short gSharedLibraryResource = kResFileNotOpened ;
721
722 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
723 CFBundleRef gSharedLibraryBundle = NULL;
724 #endif /* WXMAKINGDLL && __DARWIN__ */
725
726 wxStAppResource::wxStAppResource()
727 {
728 m_currentRefNum = CurResFile() ;
729 if ( gSharedLibraryResource != kResFileNotOpened )
730 {
731 UseResFile( gSharedLibraryResource ) ;
732 }
733 }
734
735 wxStAppResource::~wxStAppResource()
736 {
737 if ( m_currentRefNum != kResFileNotOpened )
738 {
739 UseResFile( m_currentRefNum ) ;
740 }
741 }
742
743 void wxStAppResource::OpenSharedLibraryResource(const void *initBlock)
744 {
745 gSharedLibraryResource = kResFileNotOpened;
746
747 #ifdef WXMAKINGDLL
748 if ( initBlock != NULL ) {
749 const CFragInitBlock *theInitBlock = (const CFragInitBlock *)initBlock;
750 FSSpec *fileSpec = NULL;
751
752 if (theInitBlock->fragLocator.where == kDataForkCFragLocator) {
753 fileSpec = theInitBlock->fragLocator.u.onDisk.fileSpec;
754 }
755 else if (theInitBlock->fragLocator.where == kResourceCFragLocator) {
756 fileSpec = theInitBlock->fragLocator.u.inSegs.fileSpec;
757 }
758
759 if (fileSpec != NULL) {
760 gSharedLibraryResource = FSpOpenResFile(fileSpec, fsRdPerm);
761 }
762 }
763 else {
764 #ifdef __DARWIN__
765 // Open the shared library resource file if it is not yet open
766 NSSymbol theSymbol;
767 NSModule theModule;
768 const char *theLibPath;
769
770 gSharedLibraryBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWindows"));
771 if (gSharedLibraryBundle != NULL) {
772 // wxWindows has been bundled into a framework
773 // load the framework resources
774
775 gSharedLibraryResource = CFBundleOpenBundleResourceMap(gSharedLibraryBundle);
776 }
777 else {
778 // wxWindows is a simple dynamic shared library
779 // load the resources from the data fork of a separate resource file
780 char *theResPath;
781 char *theName;
782 char *theExt;
783 FSRef theResRef;
784 OSErr theErr = noErr;
785
786 // get the library path
787 theSymbol = NSLookupAndBindSymbol("_gSharedLibraryResource");
788 theModule = NSModuleForSymbol(theSymbol);
789 theLibPath = NSLibraryNameForModule(theModule);
790
791 // if we call wxLogDebug from here then, as wxTheApp hasn't been
792 // created yet when we're called from wxApp::Initialize(), wxLog
793 // is going to create a default stderr-based log target instead of
794 // the expected normal GUI one -- don't do it, if we really want
795 // to see this message just use fprintf() here
796 #if 0
797 wxLogDebug( wxT("wxMac library installation name is '%s'"),
798 theLibPath );
799 #endif
800
801 // allocate copy to replace .dylib.* extension with .rsrc
802 theResPath = strdup(theLibPath);
803 if (theResPath != NULL) {
804 theName = strrchr(theResPath, '/');
805 if (theName == NULL) {
806 // no directory elements in path
807 theName = theResPath;
808 }
809 // find ".dylib" shared library extension
810 theExt = strstr(theName, ".dylib");
811 // overwrite extension with ".rsrc"
812 strcpy(theExt, ".rsrc");
813
814 #if 0
815 wxLogDebug( wxT("wxMac resources file name is '%s'"),
816 theResPath );
817 #endif
818
819 theErr = FSPathMakeRef((UInt8 *) theResPath, &theResRef, false);
820 if (theErr != noErr) {
821 // try in current directory (using name only)
822 theErr = FSPathMakeRef((UInt8 *) theName, &theResRef, false);
823 }
824
825 // open the resource file
826 if (theErr == noErr) {
827 theErr = FSOpenResourceFile( &theResRef, 0, NULL, fsRdPerm,
828 &gSharedLibraryResource);
829 }
830 if (theErr != noErr) {
831 #ifdef __WXDEBUG__
832 fprintf(stderr,
833 wxT("unable to open wxMac resource file '%s'\n"),
834 theResPath );
835 #endif // __WXDEBUG__
836 }
837
838 // free duplicated resource file path
839 free(theResPath);
840 }
841 }
842 #endif /* __DARWIN__ */
843 }
844 #endif /* WXMAKINGDLL */
845 }
846
847 void wxStAppResource::CloseSharedLibraryResource()
848 {
849 #ifdef WXMAKINGDLL
850 // Close the shared library resource file
851 if (gSharedLibraryResource != kResFileNotOpened) {
852 #ifdef __DARWIN__
853 if (gSharedLibraryBundle != NULL) {
854 CFBundleCloseBundleResourceMap(gSharedLibraryBundle,
855 gSharedLibraryResource);
856 gSharedLibraryBundle = NULL;
857 }
858 else
859 #endif /* __DARWIN__ */
860 {
861 CloseResFile(gSharedLibraryResource);
862 }
863 gSharedLibraryResource = kResFileNotOpened;
864 }
865 #endif /* WXMAKINGDLL */
866 }
867
868 #if defined(WXMAKINGDLL) && !defined(__DARWIN__)
869
870 // for shared libraries we have to manually get the correct resource
871 // ref num upon initializing and releasing when terminating, therefore
872 // the __wxinitialize and __wxterminate must be used
873
874 extern "C" {
875 void __sinit(void); /* (generated by linker) */
876 pascal OSErr __initialize(const CFragInitBlock *theInitBlock);
877 pascal void __terminate(void);
878 }
879
880 pascal OSErr __wxinitialize(const CFragInitBlock *theInitBlock)
881 {
882 wxStAppResource::OpenSharedLibraryResource( theInitBlock ) ;
883 return __initialize( theInitBlock ) ;
884 }
885
886 pascal void __wxterminate(void)
887 {
888 wxStAppResource::CloseSharedLibraryResource() ;
889 __terminate() ;
890 }
891
892 #endif /* WXMAKINGDLL && !__DARWIN__ */
893
894 int WXDLLEXPORT wxEntryStart( int WXUNUSED(argc), char *WXUNUSED(argv)[] )
895 {
896 return wxApp::Initialize();
897 }
898
899 int WXDLLEXPORT wxEntryInitGui()
900 {
901 return wxTheApp->OnInitGui();
902 }
903
904 void WXDLLEXPORT wxEntryCleanup()
905 {
906 wxApp::CleanUp();
907 }
908
909 int wxEntry( int argc, char *argv[] , bool enterLoop )
910 {
911 #ifdef __MWERKS__
912 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
913 // This seems to be necessary since there are 'rogue'
914 // objects present at this point (perhaps global objects?)
915 // Setting a checkpoint will ignore them as far as the
916 // memory checking facility is concerned.
917 // Of course you may argue that memory allocated in globals should be
918 // checked, but this is a reasonable compromise.
919 wxDebugContext::SetCheckpoint();
920 #endif
921 #endif
922 if (!wxEntryStart(argc, argv)) {
923 return 0;
924 }
925 // create the application object or ensure that one already exists
926 if (!wxTheApp)
927 {
928 // The app may have declared a global application object, but we recommend
929 // the IMPLEMENT_APP macro is used instead, which sets an initializer
930 // function for delayed, dynamic app object construction.
931 wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
932 wxT("No initializer - use IMPLEMENT_APP macro.") );
933
934 wxTheApp = (wxApp*) (*wxApp::GetInitializerFunction()) ();
935 }
936
937 wxCHECK_MSG( wxTheApp, 0, wxT("You have to define an instance of wxApp!") );
938
939 #ifdef __DARWIN__
940 // Mac OS X passes a process serial number command line argument when
941 // the application is launched from the Finder. This argument must be
942 // removed from the command line arguments before being handled by the
943 // application (otherwise applications would need to handle it)
944
945 if (argc > 1) {
946 if (strncmp(argv[1], "-psn_", 5) == 0) {
947 // assume the argument is always the only one and remove it
948 --argc;
949 }
950 }
951 #else
952 argc = 0 ; // currently we don't support files as parameters
953 #endif
954 // we could try to get the open apple events here to adjust argc and argv better
955
956 wxTheApp->argc = argc;
957 #if wxUSE_UNICODE
958 wxTheApp->argv = new wxChar*[argc+1];
959 int mb_argc ;
960 for ( mb_argc = 0; mb_argc < argc; mb_argc++ )
961 {
962 wxTheApp->argv[mb_argc] = wxStrdup(wxConvLocal.cMB2WX(argv[mb_argc]));
963 }
964 wxTheApp->argv[mb_argc] = (wxChar *)NULL;
965 #else
966 wxTheApp->argv = argv;
967 #endif
968
969 // GUI-specific initialization, such as creating an app context.
970 wxEntryInitGui();
971
972 // Here frames insert themselves automatically
973 // into wxTopLevelWindows by getting created
974 // in OnInit().
975
976 int retValue = 0;
977
978 if ( wxTheApp->OnInit() )
979 {
980 if ( enterLoop )
981 {
982 retValue = wxTheApp->OnRun();
983 }
984 else
985 // We want to initialize, but not run or exit immediately.
986 return 1;
987 }
988 //else: app initialization failed, so we skipped OnRun()
989
990 wxWindow *topWindow = wxTheApp->GetTopWindow();
991 if ( topWindow )
992 {
993 // Forcibly delete the window.
994 if ( topWindow->IsKindOf(CLASSINFO(wxFrame)) ||
995 topWindow->IsKindOf(CLASSINFO(wxDialog)) )
996 {
997 topWindow->Close(TRUE);
998 wxTheApp->DeletePendingObjects();
999 }
1000 else
1001 {
1002 delete topWindow;
1003 wxTheApp->SetTopWindow(NULL);
1004 }
1005 }
1006
1007 wxTheApp->OnExit();
1008
1009 wxEntryCleanup();
1010
1011 return retValue;
1012 }
1013
1014 #if TARGET_CARBON
1015
1016 bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec)
1017 {
1018 bool converted = ConvertEventRefToEventRecord( event,rec) ;
1019 OSStatus err = noErr ;
1020 if ( !converted )
1021 {
1022 switch( GetEventClass( event ) )
1023 {
1024 case kEventClassKeyboard :
1025 {
1026 converted = true ;
1027 switch( GetEventKind(event) )
1028 {
1029 case kEventRawKeyDown :
1030 rec->what = keyDown ;
1031 break ;
1032 case kEventRawKeyRepeat :
1033 rec->what = autoKey ;
1034 break ;
1035 case kEventRawKeyUp :
1036 rec->what = keyUp ;
1037 break ;
1038 case kEventRawKeyModifiersChanged :
1039 rec->what = nullEvent ;
1040 break ;
1041 default :
1042 converted = false ;
1043 break ;
1044 }
1045 if ( converted )
1046 {
1047 UInt32 keyCode ;
1048 unsigned char charCode ;
1049 UInt32 modifiers ;
1050 GetMouse( &rec->where) ;
1051
1052 err = GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers);
1053 err = GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode);
1054 err = GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode);
1055 rec->modifiers = modifiers ;
1056 rec->message = (keyCode << 8 ) + charCode ;
1057 }
1058 }
1059 break ;
1060 case kEventClassTextInput :
1061 {
1062 switch( GetEventKind( event ) )
1063 {
1064 case kEventTextInputUnicodeForKeyEvent :
1065 {
1066 EventRef rawEvent ;
1067 err = GetEventParameter( event , kEventParamTextInputSendKeyboardEvent ,typeEventRef,NULL,sizeof(rawEvent),NULL,&rawEvent ) ;
1068 converted = true ;
1069 {
1070 UInt32 keyCode ;
1071 unsigned char charCode ;
1072 UInt32 modifiers ;
1073 GetMouse( &rec->where) ;
1074 rec->what = keyDown ;
1075 err = GetEventParameter(rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers);
1076 err = GetEventParameter(rawEvent, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode);
1077 err = GetEventParameter(rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode);
1078 rec->modifiers = modifiers ;
1079 rec->message = (keyCode << 8 ) + charCode ;
1080 }
1081 }
1082 break ;
1083 default :
1084 break ;
1085 }
1086 }
1087 break ;
1088 }
1089 }
1090
1091 return converted ;
1092 }
1093
1094 /*
1095 pascal OSStatus wxMacApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
1096 {
1097 OSStatus result = eventNotHandledErr ;
1098
1099 EventRecord rec ;
1100 switch ( GetEventClass( event ) )
1101 {
1102 case kEventClassKeyboard :
1103 if ( wxMacConvertEventToRecord( event , &rec ) )
1104 {
1105 wxTheApp->MacHandleModifierEvents( &rec ) ;
1106 wxTheApp->MacHandleOneEvent( &rec ) ;
1107 result = noErr ;
1108 }
1109 break ;
1110 case kEventClassTextInput :
1111 if ( wxMacConvertEventToRecord( event , &rec ) )
1112 {
1113 wxTheApp->MacHandleModifierEvents( &rec ) ;
1114 wxTheApp->MacHandleOneEvent( &rec ) ;
1115 result = noErr ;
1116 }
1117 break ;
1118 default :
1119 break ;
1120 }
1121 return result ;
1122 }
1123 */
1124 #endif
1125
1126 // Static member initialization
1127 wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
1128
1129 wxApp::wxApp()
1130 {
1131 m_topWindow = NULL;
1132 wxTheApp = this;
1133
1134 #if WXWIN_COMPATIBILITY_2_2
1135 m_wantDebugOutput = TRUE;
1136 #endif
1137
1138 argc = 0;
1139 argv = NULL;
1140
1141 m_printMode = wxPRINT_WINDOWS;
1142 m_auto3D = TRUE;
1143 }
1144
1145 bool wxApp::Initialized()
1146 {
1147 if (GetTopWindow())
1148 return TRUE;
1149 else
1150 return FALSE;
1151 }
1152
1153 int wxApp::MainLoop()
1154 {
1155 m_keepGoing = TRUE;
1156
1157 while (m_keepGoing)
1158 {
1159 MacDoOneEvent() ;
1160 }
1161
1162 return 0;
1163 }
1164
1165 // Returns TRUE if more time is needed.
1166 bool wxApp::ProcessIdle()
1167 {
1168 wxIdleEvent event;
1169 event.SetEventObject(this);
1170 ProcessEvent(event);
1171
1172 return event.MoreRequested();
1173 }
1174
1175 void wxApp::ExitMainLoop()
1176 {
1177 m_keepGoing = FALSE;
1178 }
1179
1180 // Is a message/event pending?
1181 bool wxApp::Pending()
1182 {
1183 #if TARGET_CARBON
1184 return GetNumEventsInQueue( GetMainEventQueue() ) > 0 ;
1185 #else
1186 EventRecord event ;
1187
1188 return EventAvail( everyEvent , &event ) ;
1189 #endif
1190 }
1191
1192 // Dispatch a message.
1193 void wxApp::Dispatch()
1194 {
1195 MacDoOneEvent() ;
1196 }
1197
1198 void wxApp::OnIdle(wxIdleEvent& event)
1199 {
1200 // Avoid recursion (via ProcessEvent default case)
1201 if ( s_inOnIdle )
1202 return;
1203
1204
1205 s_inOnIdle = TRUE;
1206
1207 // 'Garbage' collection of windows deleted with Close().
1208 DeletePendingObjects();
1209
1210 // flush the logged messages if any
1211 wxLog *pLog = wxLog::GetActiveTarget();
1212 if ( pLog != NULL && pLog->HasPendingMessages() )
1213 pLog->Flush();
1214
1215 // Send OnIdle events to all windows
1216 bool needMore = SendIdleEvents();
1217
1218 if (needMore)
1219 event.RequestMore(TRUE);
1220
1221 // If they are pending events, we must process them: pending events are
1222 // either events to the threads other than main or events posted with
1223 // wxPostEvent() functions
1224 wxMacProcessNotifierAndPendingEvents();
1225
1226 s_inOnIdle = FALSE;
1227 }
1228
1229 void wxWakeUpIdle()
1230 {
1231 wxMacWakeUp() ;
1232 }
1233
1234 // Send idle event to all top-level windows
1235 bool wxApp::SendIdleEvents()
1236 {
1237 bool needMore = FALSE;
1238 wxWindowListNode* node = wxTopLevelWindows.GetFirst();
1239 while (node)
1240 {
1241 wxWindow* win = node->GetData();
1242 if (SendIdleEvents(win))
1243 needMore = TRUE;
1244
1245 node = node->GetNext();
1246 }
1247 return needMore;
1248 }
1249
1250 // Send idle event to window and all subwindows
1251 bool wxApp::SendIdleEvents(wxWindow* win)
1252 {
1253 bool needMore = FALSE;
1254
1255 wxIdleEvent event;
1256 event.SetEventObject(win);
1257 win->ProcessEvent(event);
1258
1259 if (event.MoreRequested())
1260 needMore = TRUE;
1261
1262 wxWindowListNode* node = win->GetChildren().GetFirst();
1263 while (node)
1264 {
1265 wxWindow* win = node->GetData();
1266 if (SendIdleEvents(win))
1267 needMore = TRUE;
1268
1269 node = node->GetNext();
1270 }
1271 return needMore ;
1272 }
1273
1274 void wxApp::DeletePendingObjects()
1275 {
1276 wxNode *node = wxPendingDelete.GetFirst();
1277 while (node)
1278 {
1279 wxObject *obj = (wxObject *)node->GetData();
1280
1281 delete obj;
1282
1283 if (wxPendingDelete.Member(obj))
1284 delete node;
1285
1286 // Deleting one object may have deleted other pending
1287 // objects, so start from beginning of list again.
1288 node = wxPendingDelete.GetFirst();
1289 }
1290 }
1291
1292 void wxExit()
1293 {
1294 wxLogError(_("Fatal error: exiting"));
1295
1296 wxApp::CleanUp();
1297 ::ExitToShell() ;
1298 }
1299
1300 void wxApp::OnEndSession(wxCloseEvent& WXUNUSED(event))
1301 {
1302 if (GetTopWindow())
1303 GetTopWindow()->Close(TRUE);
1304 }
1305
1306 // Default behaviour: close the application with prompts. The
1307 // user can veto the close, and therefore the end session.
1308 void wxApp::OnQueryEndSession(wxCloseEvent& event)
1309 {
1310 if (GetTopWindow())
1311 {
1312 if (!GetTopWindow()->Close(!event.CanVeto()))
1313 event.Veto(TRUE);
1314 }
1315 }
1316
1317 extern "C" void wxCYield() ;
1318 void wxCYield()
1319 {
1320 wxYield() ;
1321 }
1322
1323 // Yield to other processes
1324
1325 bool wxApp::Yield(bool onlyIfNeeded)
1326 {
1327 if (s_inYield)
1328 {
1329 if ( !onlyIfNeeded )
1330 {
1331 wxFAIL_MSG( wxT("wxYield called recursively" ) );
1332 }
1333
1334 return FALSE;
1335 }
1336
1337 s_inYield = TRUE;
1338
1339 #if wxUSE_THREADS
1340 YieldToAnyThread() ;
1341 #endif
1342 // by definition yield should handle all non-processed events
1343 #if TARGET_CARBON
1344 EventRef theEvent;
1345
1346 OSStatus status = noErr ;
1347 do
1348 {
1349 s_inReceiveEvent = true ;
1350 status = ReceiveNextEvent(0, NULL,kEventDurationNoWait,true,&theEvent) ;
1351 s_inReceiveEvent = false ;
1352
1353 if ( status == eventLoopTimedOutErr )
1354 {
1355 // make sure next time the event loop will trigger idle events
1356 sleepTime = kEventDurationNoWait ;
1357 }
1358 else if ( status == eventLoopQuitErr )
1359 {
1360 // according to QA1061 this may also occur when a WakeUp Process
1361 // is executed
1362 }
1363 else
1364 {
1365 MacHandleOneEvent( theEvent ) ;
1366 ReleaseEvent(theEvent);
1367 }
1368 } while( status == noErr ) ;
1369 #else
1370 EventRecord event ;
1371
1372 // having a larger value here leads to large performance slowdowns
1373 // so we cannot give background apps more processor time here
1374 // we do so however having a large sleep value in the main event loop
1375 sleepTime = 0 ;
1376
1377 while ( !IsExiting() && WaitNextEvent(everyEvent, &event,sleepTime, (RgnHandle) wxApp::s_macCursorRgn))
1378 {
1379 MacHandleModifierEvents( &event ) ;
1380 MacHandleOneEvent( &event );
1381 if ( event.what != kHighLevelEvent )
1382 SetRectRgn( (RgnHandle) wxApp::s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ;
1383 }
1384 MacHandleModifierEvents( &event ) ;
1385 #endif
1386
1387 wxMacProcessNotifierAndPendingEvents() ;
1388 s_inYield = FALSE;
1389
1390 return TRUE;
1391 }
1392
1393 // platform specifics
1394
1395 void wxApp::MacSuspend( bool convertClipboard )
1396 {
1397 #if !TARGET_CARBON
1398 // we have to deactive the top level windows manually
1399
1400 wxWindowListNode* node = wxTopLevelWindows.GetFirst();
1401 while (node)
1402 {
1403 wxTopLevelWindow* win = (wxTopLevelWindow*) node->Data();
1404 win->MacActivate( ((EventRecord*) MacGetCurrentEvent())->when , false ) ;
1405
1406 node = node->GetNext();
1407 }
1408
1409 ::HideFloatingWindows() ;
1410 #endif
1411 s_lastMouseDown = 0 ;
1412
1413 if( convertClipboard )
1414 {
1415 MacConvertPrivateToPublicScrap() ;
1416 }
1417 }
1418
1419 extern wxList wxModalDialogs;
1420
1421 void wxApp::MacResume( bool convertClipboard )
1422 {
1423 s_lastMouseDown = 0 ;
1424 if( convertClipboard )
1425 {
1426 MacConvertPublicToPrivateScrap() ;
1427 }
1428
1429 #if !TARGET_CARBON
1430 ::ShowFloatingWindows() ;
1431 // raise modal dialogs in case a non modal window was selected to activate the app
1432
1433 wxNode* node = wxModalDialogs.GetFirst();
1434 while (node)
1435 {
1436 wxDialog* dialog = (wxDialog *) node->GetData();
1437 dialog->Raise();
1438
1439 node = node->GetNext();
1440 }
1441 #endif
1442 }
1443
1444 void wxApp::MacConvertPrivateToPublicScrap()
1445 {
1446 }
1447
1448 void wxApp::MacConvertPublicToPrivateScrap()
1449 {
1450 }
1451
1452 void wxApp::MacDoOneEvent()
1453 {
1454 #if TARGET_CARBON
1455 EventRef theEvent;
1456
1457 s_inReceiveEvent = true ;
1458 OSStatus status = ReceiveNextEvent(0, NULL,sleepTime,true,&theEvent) ;
1459 s_inReceiveEvent = false ;
1460 if ( status == eventLoopTimedOutErr )
1461 {
1462 if ( wxTheApp->ProcessIdle() )
1463 sleepTime = kEventDurationNoWait ;
1464 else
1465 sleepTime = kEventDurationForever ;
1466 }
1467 else if ( status == eventLoopQuitErr )
1468 {
1469 // according to QA1061 this may also occur when a WakeUp Process
1470 // is executed
1471 }
1472 else
1473 {
1474 MacHandleOneEvent( theEvent ) ;
1475 ReleaseEvent(theEvent);
1476 sleepTime = kEventDurationNoWait ;
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 wxFrame* frame = mbar->GetFrame();
2354 wxCHECK_RET( mbar != NULL && frame != NULL, wxT("error in menu item callback") );
2355 if ( frame )
2356 {
2357 frame->ProcessCommand(id);
2358 }
2359 }
2360
2361 #if !TARGET_CARBON
2362 void wxApp::MacHandleMenuSelect( int macMenuId , int macMenuItemNum )
2363 {
2364 if (macMenuId == 0)
2365 return; // no menu item selected
2366
2367 if (macMenuId == kwxMacAppleMenuId && macMenuItemNum > 1)
2368 {
2369 #if ! TARGET_CARBON
2370 Str255 deskAccessoryName ;
2371 GrafPtr savedPort ;
2372
2373 GetMenuItemText(GetMenuHandle(kwxMacAppleMenuId), macMenuItemNum, deskAccessoryName);
2374 GetPort(&savedPort);
2375 OpenDeskAcc(deskAccessoryName);
2376 SetPort(savedPort);
2377 #endif
2378 }
2379 else
2380 {
2381 MenuCommand id ;
2382 GetMenuItemCommandID( GetMenuHandle(macMenuId) , macMenuItemNum , &id ) ;
2383 MacHandleMenuCommand( id ) ;
2384 }
2385 HiliteMenu(0);
2386 }
2387 #endif