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