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