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