]> git.saurik.com Git - wxWidgets.git/blob - src/mac/app.cpp
moved system-fontencoding conversions to fontutil.cpp
[wxWidgets.git] / src / mac / app.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: app.cpp
3 // Purpose: wxApp
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "app.h"
14 #endif
15
16 #include "wx/defs.h"
17
18 #include "wx/window.h"
19 #include "wx/frame.h"
20 #include "wx/button.h"
21 #include "wx/app.h"
22 #include "wx/utils.h"
23 #include "wx/gdicmn.h"
24 #include "wx/pen.h"
25 #include "wx/brush.h"
26 #include "wx/cursor.h"
27 #include "wx/intl.h"
28 #include "wx/icon.h"
29 #include "wx/palette.h"
30 #include "wx/dc.h"
31 #include "wx/dialog.h"
32 #include "wx/msgdlg.h"
33 #include "wx/log.h"
34 #include "wx/module.h"
35 #include "wx/memory.h"
36 #include "wx/tooltip.h"
37 #include "wx/textctrl.h"
38 #include "wx/menu.h"
39 #include "wx/docview.h"
40
41 #include <string.h>
42
43 // mac
44
45 #ifndef __DARWIN__
46 #if __option(profile)
47 #include <profiler.h>
48 #endif
49 #endif
50
51 #include "apprsrc.h"
52
53 #include "wx/mac/uma.h"
54 #include "wx/mac/macnotfy.h"
55
56 #ifdef __DARWIN__
57 # include <CoreServices/CoreServices.h>
58 # if defined(WXMAKINGDLL_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 wxWinMacWindowList = new wxList(wxKEY_INTEGER);
651 wxWinMacControlList = new wxList(wxKEY_INTEGER);
652
653 wxMacCreateNotifierTable() ;
654
655 UMAShowArrowCursor() ;
656
657 return true;
658 }
659
660 bool wxApp::OnInitGui()
661 {
662 if( !wxAppBase::OnInitGui() )
663 return false ;
664
665 #if TARGET_CARBON
666 InstallStandardEventHandler( GetApplicationEventTarget() ) ;
667
668 if (!sm_isEmbedded)
669 {
670 InstallApplicationEventHandler(
671 GetwxAppEventHandlerUPP(),
672 GetEventTypeCount(eventList), eventList, wxTheApp, (EventHandlerRef *)&(wxTheApp->m_macEventHandler));
673 }
674 #endif
675
676 if (!sm_isEmbedded)
677 {
678 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
679 AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
680 NewAEEventHandlerUPP(AEHandleODoc) ,
681 0 , FALSE ) ;
682 AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
683 NewAEEventHandlerUPP(AEHandleOApp) ,
684 0 , FALSE ) ;
685 AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
686 NewAEEventHandlerUPP(AEHandlePDoc) ,
687 0 , FALSE ) ;
688 AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
689 NewAEEventHandlerUPP(AEHandleQuit) ,
690 0 , FALSE ) ;
691 #else
692 AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
693 NewAEEventHandlerProc(AEHandleODoc) ,
694 0 , FALSE ) ;
695 AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
696 NewAEEventHandlerProc(AEHandleOApp) ,
697 0 , FALSE ) ;
698 AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
699 NewAEEventHandlerProc(AEHandlePDoc) ,
700 0 , FALSE ) ;
701 AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
702 NewAEEventHandlerProc(AEHandleQuit) ,
703 0 , FALSE ) ;
704 #endif
705 }
706
707 return TRUE ;
708 }
709
710 void wxApp::CleanUp()
711 {
712 wxToolTip::RemoveToolTips() ;
713
714 // One last chance for pending objects to be cleaned up
715 wxTheApp->DeletePendingObjects();
716
717 wxMacDestroyNotifierTable() ;
718
719 delete wxWinMacWindowList ;
720 wxWinMacWindowList = NULL;
721
722 delete wxWinMacControlList ;
723 wxWinMacControlList = NULL;
724
725 #ifndef __DARWIN__
726 # if __option(profile)
727 ProfilerDump( (StringPtr)"\papp.prof" ) ;
728 ProfilerTerm() ;
729 # endif
730 #endif
731
732 #if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
733 // close shared library resources from here since we don't have
734 // __wxterminate in Mach-O shared libraries
735 wxStAppResource::CloseSharedLibraryResource();
736 #endif
737
738 UMACleanupToolbox() ;
739 if (s_macCursorRgn) {
740 ::DisposeRgn((RgnHandle)s_macCursorRgn);
741 }
742
743 #if 0
744 TerminateAE() ;
745 #endif
746
747 wxAppBase::CleanUp();
748 }
749
750 //----------------------------------------------------------------------
751 // misc initialization stuff
752 //----------------------------------------------------------------------
753
754 // extern variable for shared library resource id
755 // need to be able to find it with NSLookupAndBindSymbol
756 short gSharedLibraryResource = kResFileNotOpened ;
757
758 #if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
759 CFBundleRef gSharedLibraryBundle = NULL;
760 #endif /* WXMAKINGDLL_CORE && __DARWIN__ */
761
762 wxStAppResource::wxStAppResource()
763 {
764 m_currentRefNum = CurResFile() ;
765 if ( gSharedLibraryResource != kResFileNotOpened )
766 {
767 UseResFile( gSharedLibraryResource ) ;
768 }
769 }
770
771 wxStAppResource::~wxStAppResource()
772 {
773 if ( m_currentRefNum != kResFileNotOpened )
774 {
775 UseResFile( m_currentRefNum ) ;
776 }
777 }
778
779 void wxStAppResource::OpenSharedLibraryResource(const void *initBlock)
780 {
781 gSharedLibraryResource = kResFileNotOpened;
782
783 #ifdef WXMAKINGDLL_CORE
784 if ( initBlock != NULL ) {
785 const CFragInitBlock *theInitBlock = (const CFragInitBlock *)initBlock;
786 FSSpec *fileSpec = NULL;
787
788 if (theInitBlock->fragLocator.where == kDataForkCFragLocator) {
789 fileSpec = theInitBlock->fragLocator.u.onDisk.fileSpec;
790 }
791 else if (theInitBlock->fragLocator.where == kResourceCFragLocator) {
792 fileSpec = theInitBlock->fragLocator.u.inSegs.fileSpec;
793 }
794
795 if (fileSpec != NULL) {
796 gSharedLibraryResource = FSpOpenResFile(fileSpec, fsRdPerm);
797 }
798 }
799 else {
800 #ifdef __DARWIN__
801 // Open the shared library resource file if it is not yet open
802 NSSymbol theSymbol;
803 NSModule theModule;
804 const char *theLibPath;
805
806 gSharedLibraryBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWindows"));
807 if (gSharedLibraryBundle != NULL) {
808 // wxWindows has been bundled into a framework
809 // load the framework resources
810
811 gSharedLibraryResource = CFBundleOpenBundleResourceMap(gSharedLibraryBundle);
812 }
813 else {
814 // wxWindows is a simple dynamic shared library
815 // load the resources from the data fork of a separate resource file
816 wxString theResPath;
817 wxString theName;
818 FSRef theResRef;
819 OSErr theErr = noErr;
820
821 // get the library path
822 theSymbol = NSLookupAndBindSymbol("_gSharedLibraryResource");
823 theModule = NSModuleForSymbol(theSymbol);
824 theLibPath = NSLibraryNameForModule(theModule);
825
826 // if we call wxLogDebug from here then, as wxTheApp hasn't been
827 // created yet when we're called from wxApp::Initialize(), wxLog
828 // is going to create a default stderr-based log target instead of
829 // the expected normal GUI one -- don't do it, if we really want
830 // to see this message just use fprintf() here
831 #if 0
832 wxLogDebug( wxT("wxMac library installation name is '%s'"),
833 theLibPath );
834 #endif
835
836 // allocate copy to replace .dylib.* extension with .rsrc
837 if (theLibPath != NULL) {
838 #if wxUSE_UNICODE
839 theResPath = wxString(theLibPath, wxConvLocal);
840 #else
841 theResPath = wxString(theLibPath);
842 #endif
843 // replace '_core' with '' in case of multi-lib build
844 theResPath.Replace(wxT("_core"), wxEmptyString);
845 // replace ".dylib" shared library extension with ".rsrc"
846 theResPath.Replace(wxT(".dylib"), wxT(".rsrc"));
847 // Find the begining of the filename
848 theName = theResPath.AfterLast('/');
849
850 #if 0
851 wxLogDebug( wxT("wxMac resources file name is '%s'"),
852 theResPath.mb_str() );
853 #endif
854
855 theErr = FSPathMakeRef((UInt8 *) theResPath.mb_str(), &theResRef, false);
856 if (theErr != noErr) {
857 // try in current directory (using name only)
858 theErr = FSPathMakeRef((UInt8 *) theName.mb_str(), &theResRef, false);
859 }
860
861 // open the resource file
862 if (theErr == noErr) {
863 theErr = FSOpenResourceFile( &theResRef, 0, NULL, fsRdPerm,
864 &gSharedLibraryResource);
865 }
866 if (theErr != noErr) {
867 #ifdef __WXDEBUG__
868 wxLogDebug( wxT("unable to open wxMac resource file '%s'\n"),
869 theResPath.mb_str() );
870 #endif // __WXDEBUG__
871 }
872
873 }
874 }
875 #endif /* __DARWIN__ */
876 }
877 #endif /* WXMAKINGDLL_CORE */
878 }
879
880 void wxStAppResource::CloseSharedLibraryResource()
881 {
882 #ifdef WXMAKINGDLL_CORE
883 // Close the shared library resource file
884 if (gSharedLibraryResource != kResFileNotOpened) {
885 #ifdef __DARWIN__
886 if (gSharedLibraryBundle != NULL) {
887 CFBundleCloseBundleResourceMap(gSharedLibraryBundle,
888 gSharedLibraryResource);
889 gSharedLibraryBundle = NULL;
890 }
891 else
892 #endif /* __DARWIN__ */
893 {
894 CloseResFile(gSharedLibraryResource);
895 }
896 gSharedLibraryResource = kResFileNotOpened;
897 }
898 #endif /* WXMAKINGDLL_CORE */
899 }
900
901 #if defined(WXMAKINGDLL_CORE) && !defined(__DARWIN__)
902
903 // for shared libraries we have to manually get the correct resource
904 // ref num upon initializing and releasing when terminating, therefore
905 // the __wxinitialize and __wxterminate must be used
906
907 extern "C" {
908 void __sinit(void); /* (generated by linker) */
909 pascal OSErr __initialize(const CFragInitBlock *theInitBlock);
910 pascal void __terminate(void);
911 }
912
913 pascal OSErr __wxinitialize(const CFragInitBlock *theInitBlock)
914 {
915 wxStAppResource::OpenSharedLibraryResource( theInitBlock ) ;
916 return __initialize( theInitBlock ) ;
917 }
918
919 pascal void __wxterminate(void)
920 {
921 wxStAppResource::CloseSharedLibraryResource() ;
922 __terminate() ;
923 }
924
925 #endif /* WXMAKINGDLL_CORE && !__DARWIN__ */
926
927 #if TARGET_CARBON
928
929 bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec)
930 {
931 bool converted = ConvertEventRefToEventRecord( event,rec) ;
932 OSStatus err = noErr ;
933 if ( !converted )
934 {
935 switch( GetEventClass( event ) )
936 {
937 case kEventClassKeyboard :
938 {
939 converted = true ;
940 switch( GetEventKind(event) )
941 {
942 case kEventRawKeyDown :
943 rec->what = keyDown ;
944 break ;
945 case kEventRawKeyRepeat :
946 rec->what = autoKey ;
947 break ;
948 case kEventRawKeyUp :
949 rec->what = keyUp ;
950 break ;
951 case kEventRawKeyModifiersChanged :
952 rec->what = nullEvent ;
953 break ;
954 default :
955 converted = false ;
956 break ;
957 }
958 if ( converted )
959 {
960 UInt32 keyCode ;
961 unsigned char charCode ;
962 UInt32 modifiers ;
963 GetMouse( &rec->where) ;
964
965 err = GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers);
966 err = GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode);
967 err = GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode);
968 rec->modifiers = modifiers ;
969 rec->message = (keyCode << 8 ) + charCode ;
970 }
971 }
972 break ;
973 case kEventClassTextInput :
974 {
975 switch( GetEventKind( event ) )
976 {
977 case kEventTextInputUnicodeForKeyEvent :
978 {
979 EventRef rawEvent ;
980 err = GetEventParameter( event , kEventParamTextInputSendKeyboardEvent ,typeEventRef,NULL,sizeof(rawEvent),NULL,&rawEvent ) ;
981 converted = true ;
982 {
983 UInt32 keyCode ;
984 unsigned char charCode ;
985 UInt32 modifiers ;
986 GetMouse( &rec->where) ;
987 rec->what = keyDown ;
988 err = GetEventParameter(rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers);
989 err = GetEventParameter(rawEvent, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode);
990 err = GetEventParameter(rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode);
991 rec->modifiers = modifiers ;
992 rec->message = (keyCode << 8 ) + charCode ;
993 }
994 }
995 break ;
996 default :
997 break ;
998 }
999 }
1000 break ;
1001 }
1002 }
1003
1004 return converted ;
1005 }
1006
1007 /*
1008 pascal OSStatus wxMacApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
1009 {
1010 OSStatus result = eventNotHandledErr ;
1011
1012 EventRecord rec ;
1013 switch ( GetEventClass( event ) )
1014 {
1015 case kEventClassKeyboard :
1016 if ( wxMacConvertEventToRecord( event , &rec ) )
1017 {
1018 wxTheApp->MacHandleModifierEvents( &rec ) ;
1019 wxTheApp->MacHandleOneEvent( &rec ) ;
1020 result = noErr ;
1021 }
1022 break ;
1023 case kEventClassTextInput :
1024 if ( wxMacConvertEventToRecord( event , &rec ) )
1025 {
1026 wxTheApp->MacHandleModifierEvents( &rec ) ;
1027 wxTheApp->MacHandleOneEvent( &rec ) ;
1028 result = noErr ;
1029 }
1030 break ;
1031 default :
1032 break ;
1033 }
1034 return result ;
1035 }
1036 */
1037 #endif
1038
1039 wxApp::wxApp()
1040 {
1041 m_printMode = wxPRINT_WINDOWS;
1042 m_auto3D = TRUE;
1043
1044 m_macCurrentEvent = NULL ;
1045 #if TARGET_CARBON
1046 m_macCurrentEventHandlerCallRef = NULL ;
1047 #endif
1048 }
1049
1050 int wxApp::MainLoop()
1051 {
1052 m_keepGoing = TRUE;
1053
1054 while (m_keepGoing)
1055 {
1056 MacDoOneEvent() ;
1057 }
1058
1059 return 0;
1060 }
1061
1062 void wxApp::ExitMainLoop()
1063 {
1064 m_keepGoing = FALSE;
1065 }
1066
1067 // Is a message/event pending?
1068 bool wxApp::Pending()
1069 {
1070 #if TARGET_CARBON
1071 return GetNumEventsInQueue( GetMainEventQueue() ) > 0 ;
1072 #else
1073 EventRecord event ;
1074
1075 return EventAvail( everyEvent , &event ) ;
1076 #endif
1077 }
1078
1079 // Dispatch a message.
1080 bool wxApp::Dispatch()
1081 {
1082 MacDoOneEvent() ;
1083
1084 return true;
1085 }
1086
1087 void wxApp::OnIdle(wxIdleEvent& event)
1088 {
1089 wxAppBase::OnIdle(event);
1090
1091 // If they are pending events, we must process them: pending events are
1092 // either events to the threads other than main or events posted with
1093 // wxPostEvent() functions
1094 wxMacProcessNotifierAndPendingEvents();
1095
1096 if(!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar())
1097 wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar();
1098 }
1099
1100 void wxApp::WakeUpIdle()
1101 {
1102 wxMacWakeUp() ;
1103 }
1104
1105 void wxApp::Exit()
1106 {
1107 wxApp::CleanUp();
1108 ::ExitToShell() ;
1109 }
1110
1111 void wxApp::OnEndSession(wxCloseEvent& WXUNUSED(event))
1112 {
1113 if (GetTopWindow())
1114 GetTopWindow()->Close(TRUE);
1115 }
1116
1117 // Default behaviour: close the application with prompts. The
1118 // user can veto the close, and therefore the end session.
1119 void wxApp::OnQueryEndSession(wxCloseEvent& event)
1120 {
1121 if (GetTopWindow())
1122 {
1123 if (!GetTopWindow()->Close(!event.CanVeto()))
1124 event.Veto(TRUE);
1125 }
1126 }
1127
1128 extern "C" void wxCYield() ;
1129 void wxCYield()
1130 {
1131 wxYield() ;
1132 }
1133
1134 // Yield to other processes
1135
1136 bool wxApp::Yield(bool onlyIfNeeded)
1137 {
1138 if (s_inYield)
1139 {
1140 if ( !onlyIfNeeded )
1141 {
1142 wxFAIL_MSG( wxT("wxYield called recursively" ) );
1143 }
1144
1145 return FALSE;
1146 }
1147
1148 s_inYield = TRUE;
1149
1150 #if wxUSE_THREADS
1151 YieldToAnyThread() ;
1152 #endif
1153 // by definition yield should handle all non-processed events
1154 #if TARGET_CARBON
1155 EventRef theEvent;
1156
1157 OSStatus status = noErr ;
1158 do
1159 {
1160 s_inReceiveEvent = true ;
1161 status = ReceiveNextEvent(0, NULL,kEventDurationNoWait,true,&theEvent) ;
1162 s_inReceiveEvent = false ;
1163
1164 if ( status == eventLoopTimedOutErr )
1165 {
1166 // make sure next time the event loop will trigger idle events
1167 sleepTime = kEventDurationNoWait ;
1168 }
1169 else if ( status == eventLoopQuitErr )
1170 {
1171 // according to QA1061 this may also occur when a WakeUp Process
1172 // is executed
1173 }
1174 else
1175 {
1176 MacHandleOneEvent( theEvent ) ;
1177 ReleaseEvent(theEvent);
1178 }
1179 } while( status == noErr ) ;
1180 #else
1181 EventRecord event ;
1182
1183 // having a larger value here leads to large performance slowdowns
1184 // so we cannot give background apps more processor time here
1185 // we do so however having a large sleep value in the main event loop
1186 sleepTime = 0 ;
1187
1188 while ( !IsExiting() && WaitNextEvent(everyEvent, &event,sleepTime, (RgnHandle) wxApp::s_macCursorRgn))
1189 {
1190 MacHandleModifierEvents( &event ) ;
1191 MacHandleOneEvent( &event );
1192 if ( event.what != kHighLevelEvent )
1193 SetRectRgn( (RgnHandle) wxApp::s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ;
1194 }
1195 MacHandleModifierEvents( &event ) ;
1196 #endif
1197
1198 wxMacProcessNotifierAndPendingEvents() ;
1199 s_inYield = FALSE;
1200
1201 return TRUE;
1202 }
1203
1204 // platform specifics
1205
1206 void wxApp::MacSuspend( bool convertClipboard )
1207 {
1208 #if !TARGET_CARBON
1209 // we have to deactive the top level windows manually
1210
1211 wxWindowListNode* node = wxTopLevelWindows.GetFirst();
1212 while (node)
1213 {
1214 wxTopLevelWindow* win = (wxTopLevelWindow*) node->Data();
1215 #if TARGET_CARBON
1216 #if 0 // having problems right now with that
1217 if (!win->HasFlag(wxSTAY_ON_TOP))
1218 #endif
1219 #endif
1220 win->MacActivate( ((EventRecord*) MacGetCurrentEvent())->when , false ) ;
1221
1222 node = node->GetNext();
1223 }
1224
1225 ::HideFloatingWindows() ;
1226 #endif
1227 s_lastMouseDown = 0 ;
1228
1229 if( convertClipboard )
1230 {
1231 MacConvertPrivateToPublicScrap() ;
1232 }
1233 }
1234
1235 extern wxList wxModalDialogs;
1236
1237 void wxApp::MacResume( bool convertClipboard )
1238 {
1239 s_lastMouseDown = 0 ;
1240 if( convertClipboard )
1241 {
1242 MacConvertPublicToPrivateScrap() ;
1243 }
1244
1245 #if !TARGET_CARBON
1246 ::ShowFloatingWindows() ;
1247 // raise modal dialogs in case a non modal window was selected to activate the app
1248
1249 wxNode* node = wxModalDialogs.GetFirst();
1250 while (node)
1251 {
1252 wxDialog* dialog = (wxDialog *) node->GetData();
1253 dialog->Raise();
1254
1255 node = node->GetNext();
1256 }
1257 #endif
1258 }
1259
1260 void wxApp::MacConvertPrivateToPublicScrap()
1261 {
1262 }
1263
1264 void wxApp::MacConvertPublicToPrivateScrap()
1265 {
1266 }
1267
1268 void wxApp::MacDoOneEvent()
1269 {
1270 #if TARGET_CARBON
1271 EventRef theEvent;
1272
1273 s_inReceiveEvent = true ;
1274 OSStatus status = ReceiveNextEvent(0, NULL,sleepTime,true,&theEvent) ;
1275 s_inReceiveEvent = false ;
1276 if ( status == eventLoopTimedOutErr )
1277 {
1278 if ( wxTheApp->ProcessIdle() )
1279 sleepTime = kEventDurationNoWait ;
1280 else
1281 {
1282 #if wxUSE_THREADS
1283 if (g_numberOfThreads)
1284 {
1285 sleepTime = kEventDurationNoWait;
1286 }
1287 else
1288 #endif // wxUSE_THREADS
1289 {
1290 sleepTime = kEventDurationSecond;
1291 }
1292 }
1293 }
1294 else if ( status == eventLoopQuitErr )
1295 {
1296 // according to QA1061 this may also occur when a WakeUp Process
1297 // is executed
1298 }
1299 else
1300 {
1301 MacHandleOneEvent( theEvent ) ;
1302 ReleaseEvent(theEvent);
1303 sleepTime = kEventDurationNoWait ;
1304 }
1305 #else
1306 EventRecord event ;
1307
1308 EventMask eventMask = everyEvent ;
1309
1310 if (WaitNextEvent(eventMask, &event, sleepTime, (RgnHandle) s_macCursorRgn))
1311 {
1312 MacHandleModifierEvents( &event ) ;
1313 MacHandleOneEvent( &event );
1314 }
1315 else
1316 {
1317 MacHandleModifierEvents( &event ) ;
1318 // idlers
1319 WindowPtr window = ::FrontWindow() ;
1320 if ( window )
1321 ::IdleControls( window ) ;
1322
1323 if ( wxTheApp->ProcessIdle() )
1324 sleepTime = kEventDurationNoWait;
1325 else
1326 {
1327 #if wxUSE_THREADS
1328 if (g_numberOfThreads)
1329 {
1330 sleepTime = kEventDurationNoWait;
1331 }
1332 else
1333 #endif // wxUSE_THREADS
1334 {
1335 sleepTime = kEventDurationSecond;
1336 }
1337 }
1338 }
1339 if ( event.what != kHighLevelEvent )
1340 SetRectRgn( (RgnHandle) s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ;
1341 #endif
1342 // repeaters
1343
1344 DeletePendingObjects() ;
1345 wxMacProcessNotifierAndPendingEvents() ;
1346 }
1347
1348 /*virtual*/ void wxApp::MacHandleUnhandledEvent( WXEVENTREF evr )
1349 {
1350 // Override to process unhandled events as you please
1351 }
1352
1353 void wxApp::MacHandleOneEvent( WXEVENTREF evr )
1354 {
1355 #if TARGET_CARBON
1356 EventTargetRef theTarget;
1357 theTarget = GetEventDispatcherTarget();
1358 m_macCurrentEvent = evr ;
1359 OSStatus status = SendEventToEventTarget ((EventRef) evr , theTarget);
1360 if(status == eventNotHandledErr)
1361 {
1362 MacHandleUnhandledEvent(evr);
1363 }
1364 #else
1365 EventRecord* ev = (EventRecord*) evr ;
1366 m_macCurrentEvent = ev ;
1367
1368 wxApp::sm_lastMessageTime = ev->when ;
1369
1370 switch (ev->what)
1371 {
1372 case mouseDown:
1373 MacHandleMouseDownEvent( ev ) ;
1374 if ( ev->modifiers & controlKey )
1375 s_lastMouseDown = 2;
1376 else
1377 s_lastMouseDown = 1;
1378 break;
1379 case mouseUp:
1380 if ( s_lastMouseDown == 2 )
1381 {
1382 ev->modifiers |= controlKey ;
1383 }
1384 else
1385 {
1386 ev->modifiers &= ~controlKey ;
1387 }
1388 MacHandleMouseUpEvent( ev ) ;
1389 s_lastMouseDown = 0;
1390 break;
1391 case activateEvt:
1392 MacHandleActivateEvent( ev ) ;
1393 break;
1394 case updateEvt:
1395 // In embedded mode we first let the UnhandledEvent function
1396 // try to handle the update event. If we handle it ourselves
1397 // first and then pass it on, the host's windows won't update.
1398 MacHandleUnhandledEvent(ev);
1399 MacHandleUpdateEvent( ev ) ;
1400 break;
1401 case keyDown:
1402 case autoKey:
1403 MacHandleKeyDownEvent( ev ) ;
1404 break;
1405 case keyUp:
1406 MacHandleKeyUpEvent( ev ) ;
1407 break;
1408 case diskEvt:
1409 MacHandleDiskEvent( ev ) ;
1410 break;
1411 case osEvt:
1412 MacHandleOSEvent( ev ) ;
1413 break;
1414 case kHighLevelEvent:
1415 MacHandleHighLevelEvent( ev ) ;
1416 break;
1417 default:
1418 break;
1419 }
1420 #endif
1421 wxMacProcessNotifierAndPendingEvents() ;
1422 }
1423
1424 #if !TARGET_CARBON
1425 bool s_macIsInModalLoop = false ;
1426
1427 void wxApp::MacHandleModifierEvents( WXEVENTREF evr )
1428 {
1429 EventRecord* ev = (EventRecord*) evr ;
1430 if ( ev->modifiers != s_lastModifiers && wxWindow::FindFocus() != NULL )
1431 {
1432 wxKeyEvent event(wxEVT_KEY_DOWN);
1433
1434 event.m_shiftDown = ev->modifiers & shiftKey;
1435 event.m_controlDown = ev->modifiers & controlKey;
1436 event.m_altDown = ev->modifiers & optionKey;
1437 event.m_metaDown = ev->modifiers & cmdKey;
1438
1439 event.m_x = ev->where.h;
1440 event.m_y = ev->where.v;
1441 event.m_timeStamp = ev->when;
1442 wxWindow* focus = wxWindow::FindFocus() ;
1443 event.SetEventObject(focus);
1444
1445 if ( (ev->modifiers ^ s_lastModifiers ) & controlKey )
1446 {
1447 event.m_keyCode = WXK_CONTROL ;
1448 event.SetEventType( ( ev->modifiers & controlKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
1449 focus->GetEventHandler()->ProcessEvent( event ) ;
1450 }
1451 if ( (ev->modifiers ^ s_lastModifiers ) & shiftKey )
1452 {
1453 event.m_keyCode = WXK_SHIFT ;
1454 event.SetEventType( ( ev->modifiers & shiftKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
1455 focus->GetEventHandler()->ProcessEvent( event ) ;
1456 }
1457 if ( (ev->modifiers ^ s_lastModifiers ) & optionKey )
1458 {
1459 event.m_keyCode = WXK_ALT ;
1460 event.SetEventType( ( ev->modifiers & optionKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
1461 focus->GetEventHandler()->ProcessEvent( event ) ;
1462 }
1463 if ( ( ev->modifiers ^ s_lastModifiers ) & cmdKey )
1464 {
1465 event.m_keyCode = WXK_COMMAND ;
1466 event.SetEventType( ( ev->modifiers & cmdKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
1467 focus->GetEventHandler()->ProcessEvent( event ) ;
1468 }
1469 s_lastModifiers = ev->modifiers ;
1470 }
1471 }
1472
1473 void wxApp::MacHandleHighLevelEvent( WXEVENTREF evr )
1474 {
1475 // we must avoid reentrancy problems when processing high level events eg printing
1476 bool former = s_inYield ;
1477 s_inYield = TRUE ;
1478 EventRecord* ev = (EventRecord*) evr ;
1479 ::AEProcessAppleEvent( ev ) ;
1480 s_inYield = former ;
1481 }
1482
1483 void wxApp::MacHandleMouseDownEvent( WXEVENTREF evr )
1484 {
1485 EventRecord* ev = (EventRecord*) evr ;
1486 wxToolTip::RemoveToolTips() ;
1487
1488 WindowRef window;
1489 WindowRef frontWindow = ::FrontNonFloatingWindow() ;
1490 WindowAttributes frontWindowAttributes = NULL ;
1491 if ( frontWindow )
1492 ::GetWindowAttributes( frontWindow , &frontWindowAttributes ) ;
1493
1494 short windowPart = ::FindWindow(ev->where, &window);
1495 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
1496 if ( wxPendingDelete.Member(win) )
1497 return ;
1498
1499 BitMap screenBits;
1500 GetQDGlobalsScreenBits( &screenBits );
1501
1502 switch (windowPart)
1503 {
1504 case inMenuBar :
1505 if ( s_macIsInModalLoop )
1506 {
1507 SysBeep ( 30 ) ;
1508 }
1509 else
1510 {
1511 UInt32 menuresult = MenuSelect(ev->where) ;
1512 MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) );
1513 s_lastMouseDown = 0;
1514 }
1515 break ;
1516 case inSysWindow :
1517 SystemClick( ev , window ) ;
1518 s_lastMouseDown = 0;
1519 break ;
1520 case inDrag :
1521 if ( window != frontWindow && s_macIsInModalLoop && !(ev->modifiers & cmdKey ) )
1522 {
1523 SysBeep ( 30 ) ;
1524 }
1525 else
1526 {
1527 DragWindow(window, ev->where, &screenBits.bounds);
1528 if (win)
1529 {
1530 GrafPtr port ;
1531 GetPort( &port ) ;
1532 Point pt = { 0, 0 } ;
1533 SetPortWindowPort(window) ;
1534 LocalToGlobal( &pt ) ;
1535 SetPort( port ) ;
1536 win->SetSize( pt.h , pt.v , -1 ,
1537 -1 , wxSIZE_USE_EXISTING);
1538 }
1539 s_lastMouseDown = 0;
1540 }
1541 break ;
1542 case inGoAway:
1543 if (TrackGoAway(window, ev->where))
1544 {
1545 if ( win )
1546 win->Close() ;
1547 }
1548 s_lastMouseDown = 0;
1549 break;
1550 case inGrow:
1551 {
1552 Rect newContentRect ;
1553 Rect constraintRect ;
1554 constraintRect.top = win->GetMinHeight() ;
1555 if ( constraintRect.top == -1 )
1556 constraintRect.top = 0 ;
1557 constraintRect.left = win->GetMinWidth() ;
1558 if ( constraintRect.left == -1 )
1559 constraintRect.left = 0 ;
1560 constraintRect.right = win->GetMaxWidth() ;
1561 if ( constraintRect.right == -1 )
1562 constraintRect.right = 32000 ;
1563 constraintRect.bottom = win->GetMaxHeight() ;
1564 if ( constraintRect.bottom == -1 )
1565 constraintRect.bottom = 32000 ;
1566
1567 Boolean growResult = ResizeWindow( window , ev->where ,
1568 &constraintRect , &newContentRect ) ;
1569 if ( growResult )
1570 {
1571 win->SetSize( newContentRect.left , newContentRect.top ,
1572 newContentRect.right - newContentRect.left ,
1573 newContentRect.bottom - newContentRect.top, wxSIZE_USE_EXISTING);
1574 }
1575 s_lastMouseDown = 0;
1576 }
1577 break;
1578 case inZoomIn:
1579 case inZoomOut:
1580 if (TrackBox(window, ev->where, windowPart))
1581 {
1582 // TODO setup size event
1583 ZoomWindow( window , windowPart , false ) ;
1584 if (win)
1585 {
1586 Rect tempRect ;
1587 GrafPtr port ;
1588 GetPort( &port ) ;
1589 Point pt = { 0, 0 } ;
1590 SetPortWindowPort(window) ;
1591 LocalToGlobal( &pt ) ;
1592 SetPort( port ) ;
1593
1594 GetWindowPortBounds(window, &tempRect ) ;
1595 win->SetSize( pt.h , pt.v , tempRect.right-tempRect.left ,
1596 tempRect.bottom-tempRect.top, wxSIZE_USE_EXISTING);
1597 }
1598 }
1599 s_lastMouseDown = 0;
1600 break;
1601 case inCollapseBox :
1602 // TODO setup size event
1603 s_lastMouseDown = 0;
1604 break ;
1605
1606 case inContent :
1607 {
1608 GrafPtr port ;
1609 GetPort( &port ) ;
1610 SetPortWindowPort(window) ;
1611 SetPort( port ) ;
1612 }
1613 if ( window != frontWindow && wxTheApp->s_captureWindow == NULL )
1614 {
1615 if ( s_macIsInModalLoop )
1616 {
1617 SysBeep ( 30 ) ;
1618 }
1619 else if ( UMAIsWindowFloating( window ) )
1620 {
1621 if ( win )
1622 win->MacMouseDown( ev , windowPart ) ;
1623 }
1624 else
1625 {
1626 // Activate window first
1627 ::SelectWindow( window ) ;
1628
1629 // Send event later
1630 if ( win )
1631 win->MacMouseDown( ev , windowPart ) ;
1632 }
1633 }
1634 else
1635 {
1636 if ( win )
1637 win->MacMouseDown( ev , windowPart ) ;
1638 }
1639 break ;
1640 default:
1641 break;
1642 }
1643 }
1644
1645 void wxApp::MacHandleMouseUpEvent( WXEVENTREF evr )
1646 {
1647 EventRecord* ev = (EventRecord*) evr ;
1648 WindowRef window;
1649
1650 short windowPart = inNoWindow ;
1651 if ( wxTheApp->s_captureWindow )
1652 {
1653 window = (WindowRef) s_captureWindow->MacGetRootWindow() ;
1654 windowPart = inContent ;
1655 }
1656 else
1657 {
1658 windowPart = ::FindWindow(ev->where, &window) ;
1659 }
1660
1661 switch (windowPart)
1662 {
1663 case inMenuBar :
1664 break ;
1665 case inSysWindow :
1666 break ;
1667 default:
1668 {
1669 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
1670 if ( win )
1671 win->MacMouseUp( ev , windowPart ) ;
1672 }
1673 break;
1674 }
1675 }
1676
1677 #endif
1678
1679 long wxMacTranslateKey(unsigned char key, unsigned char code) ;
1680 long wxMacTranslateKey(unsigned char key, unsigned char code)
1681 {
1682 long retval = key ;
1683 switch (key)
1684 {
1685 case kHomeCharCode :
1686 retval = WXK_HOME;
1687 break;
1688 case kEnterCharCode :
1689 retval = WXK_RETURN;
1690 break;
1691 case kEndCharCode :
1692 retval = WXK_END;
1693 break;
1694 case kHelpCharCode :
1695 retval = WXK_HELP;
1696 break;
1697 case kBackspaceCharCode :
1698 retval = WXK_BACK;
1699 break;
1700 case kTabCharCode :
1701 retval = WXK_TAB;
1702 break;
1703 case kPageUpCharCode :
1704 retval = WXK_PAGEUP;
1705 break;
1706 case kPageDownCharCode :
1707 retval = WXK_PAGEDOWN;
1708 break;
1709 case kReturnCharCode :
1710 retval = WXK_RETURN;
1711 break;
1712 case kFunctionKeyCharCode :
1713 {
1714 switch( code )
1715 {
1716 case 0x7a :
1717 retval = WXK_F1 ;
1718 break;
1719 case 0x78 :
1720 retval = WXK_F2 ;
1721 break;
1722 case 0x63 :
1723 retval = WXK_F3 ;
1724 break;
1725 case 0x76 :
1726 retval = WXK_F4 ;
1727 break;
1728 case 0x60 :
1729 retval = WXK_F5 ;
1730 break;
1731 case 0x61 :
1732 retval = WXK_F6 ;
1733 break;
1734 case 0x62:
1735 retval = WXK_F7 ;
1736 break;
1737 case 0x64 :
1738 retval = WXK_F8 ;
1739 break;
1740 case 0x65 :
1741 retval = WXK_F9 ;
1742 break;
1743 case 0x6D :
1744 retval = WXK_F10 ;
1745 break;
1746 case 0x67 :
1747 retval = WXK_F11 ;
1748 break;
1749 case 0x6F :
1750 retval = WXK_F12 ;
1751 break;
1752 case 0x69 :
1753 retval = WXK_F13 ;
1754 break;
1755 case 0x6B :
1756 retval = WXK_F14 ;
1757 break;
1758 case 0x71 :
1759 retval = WXK_F15 ;
1760 break;
1761 }
1762 }
1763 break ;
1764 case kEscapeCharCode :
1765 retval = WXK_ESCAPE ;
1766 break ;
1767 case kLeftArrowCharCode :
1768 retval = WXK_LEFT ;
1769 break ;
1770 case kRightArrowCharCode :
1771 retval = WXK_RIGHT ;
1772 break ;
1773 case kUpArrowCharCode :
1774 retval = WXK_UP ;
1775 break ;
1776 case kDownArrowCharCode :
1777 retval = WXK_DOWN ;
1778 break ;
1779 case kDeleteCharCode :
1780 retval = WXK_DELETE ;
1781 default:
1782 break ;
1783 } // end switch
1784
1785 return retval;
1786 }
1787
1788 int wxKeyCodeToMacModifier(wxKeyCode key)
1789 {
1790 switch (key)
1791 {
1792 case WXK_START:
1793 case WXK_MENU:
1794 return cmdKey;
1795
1796 case WXK_SHIFT:
1797 return shiftKey;
1798
1799 case WXK_CAPITAL:
1800 return alphaLock;
1801
1802 case WXK_ALT:
1803 return optionKey;
1804
1805 case WXK_CONTROL:
1806 return controlKey;
1807
1808 default:
1809 return 0;
1810 }
1811 }
1812
1813 bool wxGetKeyState(wxKeyCode key) //virtual key code if < 10.2.x, else see below
1814 {
1815 // TODO: Have it use HID Manager on OSX...
1816 //if OS X > 10.2 (i.e. 10.2.x)
1817 //a known apple bug prevents the system from determining led
1818 //states with GetKeys... can only determine caps lock led
1819 return !!(GetCurrentKeyModifiers() & wxKeyCodeToMacModifier(key));
1820 //else
1821 // KeyMapByteArray keymap;
1822 // GetKeys((BigEndianLong*)keymap);
1823 // return !!(BitTst(keymap, (sizeof(KeyMapByteArray)*8) - iKey));
1824 }
1825
1826 #if !TARGET_CARBON
1827 void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr )
1828 {
1829 EventRecord* ev = (EventRecord*) evr ;
1830 wxToolTip::RemoveToolTips() ;
1831
1832 UInt32 menuresult = UMAMenuEvent(ev) ;
1833 if ( HiWord( menuresult ) )
1834 {
1835 if ( !s_macIsInModalLoop )
1836 MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ) ;
1837 }
1838 else
1839 {
1840 wxWindow* focus = wxWindow::FindFocus() ;
1841
1842 if ( MacSendKeyDownEvent( focus , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) == false )
1843 {
1844 #if 0
1845 // we must handle control keys the other way round, otherwise text content is updated too late
1846 // has not been handled -> perform default
1847 wxControl* control = wxDynamicCast( focus , wxControl ) ;
1848 if ( control && control->GetMacControl() != NULL )
1849 {
1850 short keycode ;
1851 short keychar ;
1852 keychar = short(ev->message & charCodeMask);
1853 keycode = short(ev->message & keyCodeMask) >> 8 ;
1854 ::HandleControlKey( (ControlHandle) control->GetMacControl() , keycode , keychar , ev->modifiers ) ;
1855 }
1856 #endif
1857 }
1858 }
1859 }
1860
1861 void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr )
1862 {
1863 EventRecord* ev = (EventRecord*) evr ;
1864 wxToolTip::RemoveToolTips() ;
1865
1866 UInt32 menuresult = UMAMenuEvent(ev) ;
1867 if ( HiWord( menuresult ) )
1868 {
1869 }
1870 else
1871 {
1872 MacSendKeyUpEvent( wxWindow::FindFocus() , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) ;
1873 }
1874 }
1875
1876 #endif
1877
1878 bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey )
1879 {
1880 if ( !focus )
1881 return false ;
1882
1883 short keycode ;
1884 short keychar ;
1885 keychar = short(keymessage & charCodeMask);
1886 keycode = short(keymessage & keyCodeMask) >> 8 ;
1887
1888 if ( modifiers & ( controlKey|shiftKey|optionKey ) )
1889 {
1890 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
1891 // and look at the character after
1892 UInt32 state = 0;
1893 UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state);
1894 keychar = short(keyInfo & charCodeMask);
1895 keycode = short(keyInfo & keyCodeMask) >> 8 ;
1896 }
1897 long keyval = wxMacTranslateKey(keychar, keycode) ;
1898 long realkeyval = keyval ;
1899 if ( keyval == keychar )
1900 {
1901 // 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)
1902 realkeyval = short(keymessage & charCodeMask) ;
1903 keyval = wxToupper( keyval ) ;
1904 }
1905
1906 wxKeyEvent event(wxEVT_KEY_DOWN);
1907 bool handled = false ;
1908 event.m_shiftDown = modifiers & shiftKey;
1909 event.m_controlDown = modifiers & controlKey;
1910 event.m_altDown = modifiers & optionKey;
1911 event.m_metaDown = modifiers & cmdKey;
1912 event.m_keyCode = keyval ;
1913
1914 event.m_x = wherex;
1915 event.m_y = wherey;
1916 event.m_timeStamp = when;
1917 event.SetEventObject(focus);
1918 handled = focus->GetEventHandler()->ProcessEvent( event ) ;
1919 if ( handled && event.GetSkipped() )
1920 handled = false ;
1921 if ( !handled )
1922 {
1923 #if wxUSE_ACCEL
1924 if (!handled)
1925 {
1926 wxWindow *ancestor = focus;
1927 while (ancestor)
1928 {
1929 int command = ancestor->GetAcceleratorTable()->GetCommand( event );
1930 if (command != -1)
1931 {
1932 wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
1933 handled = ancestor->GetEventHandler()->ProcessEvent( command_event );
1934 break;
1935 }
1936 if (ancestor->IsTopLevel())
1937 break;
1938 ancestor = ancestor->GetParent();
1939 }
1940 }
1941 #endif // wxUSE_ACCEL
1942 }
1943 if (!handled)
1944 {
1945 event.Skip( FALSE ) ;
1946 event.SetEventType( wxEVT_CHAR ) ;
1947 // raw value again
1948 event.m_keyCode = realkeyval ;
1949
1950 handled = focus->GetEventHandler()->ProcessEvent( event ) ;
1951 if ( handled && event.GetSkipped() )
1952 handled = false ;
1953 }
1954 if ( !handled &&
1955 (keyval == WXK_TAB) &&
1956 // CS: copied the change below from wxGTK
1957 // VZ: testing for wxTE_PROCESS_TAB shouldn't be done here the control may
1958 // have this style, yet choose not to process this particular TAB in which
1959 // case TAB must still work as a navigational character
1960 #if 0
1961 (!focus->HasFlag(wxTE_PROCESS_TAB)) &&
1962 #endif
1963 (focus->GetParent()) &&
1964 (focus->GetParent()->HasFlag( wxTAB_TRAVERSAL)) )
1965 {
1966 wxNavigationKeyEvent new_event;
1967 new_event.SetEventObject( focus );
1968 new_event.SetDirection( !event.ShiftDown() );
1969 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
1970 new_event.SetWindowChange( event.ControlDown() );
1971 new_event.SetCurrentFocus( focus );
1972 handled = focus->GetEventHandler()->ProcessEvent( new_event );
1973 if ( handled && new_event.GetSkipped() )
1974 handled = false ;
1975 }
1976 // backdoor handler for default return and command escape
1977 if ( !handled && (!focus->IsKindOf(CLASSINFO(wxControl) ) || !focus->MacCanFocus() ) )
1978 {
1979 // if window is not having a focus still testing for default enter or cancel
1980 // TODO add the UMA version for ActiveNonFloatingWindow
1981 wxWindow* focus = wxFindWinFromMacWindow( FrontWindow() ) ;
1982 if ( focus )
1983 {
1984 if ( keyval == WXK_RETURN )
1985 {
1986 wxButton *def = wxDynamicCast(focus->GetDefaultItem(),
1987 wxButton);
1988 if ( def && def->IsEnabled() )
1989 {
1990 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
1991 event.SetEventObject(def);
1992 def->Command(event);
1993 return true ;
1994 }
1995 }
1996 /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
1997 else if (keyval == WXK_ESCAPE || (keyval == '.' && modifiers & cmdKey ) )
1998 {
1999 wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL);
2000 new_event.SetEventObject( focus );
2001 handled = focus->GetEventHandler()->ProcessEvent( new_event );
2002 }
2003 }
2004 }
2005 return handled ;
2006 }
2007
2008 bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey )
2009 {
2010 if ( !focus )
2011 return false ;
2012
2013 short keycode ;
2014 short keychar ;
2015 keychar = short(keymessage & charCodeMask);
2016 keycode = short(keymessage & keyCodeMask) >> 8 ;
2017 if ( modifiers & ( controlKey|shiftKey|optionKey ) )
2018 {
2019 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
2020 // and look at the character after
2021 UInt32 state = 0;
2022 UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state);
2023 keychar = short(keyInfo & charCodeMask);
2024 keycode = short(keyInfo & keyCodeMask) >> 8 ;
2025 }
2026 long keyval = wxMacTranslateKey(keychar, keycode) ;
2027
2028 if ( keyval == keychar )
2029 {
2030 keyval = wxToupper( keyval ) ;
2031 }
2032 bool handled = false ;
2033
2034 wxKeyEvent event(wxEVT_KEY_UP);
2035 event.m_shiftDown = modifiers & shiftKey;
2036 event.m_controlDown = modifiers & controlKey;
2037 event.m_altDown = modifiers & optionKey;
2038 event.m_metaDown = modifiers & cmdKey;
2039 event.m_keyCode = keyval ;
2040
2041 event.m_x = wherex;
2042 event.m_y = wherey;
2043 event.m_timeStamp = when;
2044 event.SetEventObject(focus);
2045 handled = focus->GetEventHandler()->ProcessEvent( event ) ;
2046
2047 return handled ;
2048 }
2049
2050 #if !TARGET_CARBON
2051 void wxApp::MacHandleActivateEvent( WXEVENTREF evr )
2052 {
2053 EventRecord* ev = (EventRecord*) evr ;
2054 WindowRef window = (WindowRef) ev->message ;
2055 if ( window )
2056 {
2057 bool activate = (ev->modifiers & activeFlag ) ;
2058 WindowClass wclass ;
2059 ::GetWindowClass ( window , &wclass ) ;
2060 if ( wclass == kFloatingWindowClass )
2061 {
2062 // if it is a floater we activate/deactivate the front non-floating window instead
2063 window = ::FrontNonFloatingWindow() ;
2064 }
2065 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
2066 if ( win )
2067 win->MacActivate( ev->when , activate ) ;
2068 }
2069 }
2070
2071 void wxApp::MacHandleUpdateEvent( WXEVENTREF evr )
2072 {
2073 EventRecord* ev = (EventRecord*) evr ;
2074 WindowRef window = (WindowRef) ev->message ;
2075 wxTopLevelWindowMac * win = wxFindWinFromMacWindow( window ) ;
2076 if ( win )
2077 {
2078 if ( !wxPendingDelete.Member(win) )
2079 win->MacUpdate( ev->when ) ;
2080 }
2081 else
2082 {
2083 // since there is no way of telling this foreign window to update itself
2084 // we have to invalidate the update region otherwise we keep getting the same
2085 // event over and over again
2086 BeginUpdate( window ) ;
2087 EndUpdate( window ) ;
2088 }
2089 }
2090
2091 void wxApp::MacHandleDiskEvent( WXEVENTREF evr )
2092 {
2093 EventRecord* ev = (EventRecord*) evr ;
2094 if ( HiWord( ev->message ) != noErr )
2095 {
2096 OSErr err ;
2097 Point point ;
2098 SetPt( &point , 100 , 100 ) ;
2099
2100 err = DIBadMount( point , ev->message ) ;
2101 wxASSERT( err == noErr ) ;
2102 }
2103 }
2104
2105 void wxApp::MacHandleOSEvent( WXEVENTREF evr )
2106 {
2107 EventRecord* ev = (EventRecord*) evr ;
2108 switch( ( ev->message & osEvtMessageMask ) >> 24 )
2109 {
2110 case suspendResumeMessage :
2111 {
2112 bool isResuming = ev->message & resumeFlag ;
2113 bool convertClipboard = ev->message & convertClipboardFlag ;
2114
2115 bool doesActivate = UMAGetProcessModeDoesActivateOnFGSwitch() ;
2116 if ( isResuming )
2117 {
2118 WindowRef oldFrontWindow = NULL ;
2119 WindowRef newFrontWindow = NULL ;
2120
2121 // in case we don't take care of activating ourselves, we have to synchronize
2122 // our idea of the active window with the process manager's - which it already activated
2123
2124 if ( !doesActivate )
2125 oldFrontWindow = ::FrontNonFloatingWindow() ;
2126
2127 MacResume( convertClipboard ) ;
2128
2129 newFrontWindow = ::FrontNonFloatingWindow() ;
2130
2131 if ( oldFrontWindow )
2132 {
2133 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( oldFrontWindow ) ;
2134 if ( win )
2135 win->MacActivate( ev->when , false ) ;
2136 }
2137 if ( newFrontWindow )
2138 {
2139 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( newFrontWindow ) ;
2140 if ( win )
2141 win->MacActivate( ev->when , true ) ;
2142 }
2143 }
2144 else
2145 {
2146 MacSuspend( convertClipboard ) ;
2147 }
2148 }
2149 break ;
2150 case mouseMovedMessage :
2151 {
2152 WindowRef window;
2153
2154 wxWindow* currentMouseWindow = NULL ;
2155
2156 if (s_captureWindow )
2157 {
2158 currentMouseWindow = s_captureWindow ;
2159 }
2160 else
2161 {
2162 wxWindow::MacGetWindowFromPoint( wxPoint( ev->where.h , ev->where.v ) ,
2163 &currentMouseWindow ) ;
2164 }
2165
2166 if ( currentMouseWindow != wxWindow::s_lastMouseWindow )
2167 {
2168 wxMouseEvent event ;
2169
2170 bool isDown = !(ev->modifiers & btnState) ; // 1 is for up
2171 bool controlDown = ev->modifiers & controlKey ; // for simulating right mouse
2172
2173 event.m_leftDown = isDown && !controlDown;
2174 event.m_middleDown = FALSE;
2175 event.m_rightDown = isDown && controlDown;
2176 event.m_shiftDown = ev->modifiers & shiftKey;
2177 event.m_controlDown = ev->modifiers & controlKey;
2178 event.m_altDown = ev->modifiers & optionKey;
2179 event.m_metaDown = ev->modifiers & cmdKey;
2180 event.m_x = ev->where.h;
2181 event.m_y = ev->where.v;
2182 event.m_timeStamp = ev->when;
2183 event.SetEventObject(this);
2184
2185 if ( wxWindow::s_lastMouseWindow )
2186 {
2187 wxMouseEvent eventleave(event);
2188 eventleave.SetEventType( wxEVT_LEAVE_WINDOW );
2189 wxWindow::s_lastMouseWindow->ScreenToClient( &eventleave.m_x, &eventleave.m_y );
2190 eventleave.SetEventObject( wxWindow::s_lastMouseWindow ) ;
2191
2192 wxWindow::s_lastMouseWindow->GetEventHandler()->ProcessEvent(eventleave);
2193 }
2194 if ( currentMouseWindow )
2195 {
2196 wxMouseEvent evententer(event);
2197 evententer.SetEventType( wxEVT_ENTER_WINDOW );
2198 currentMouseWindow->ScreenToClient( &evententer.m_x, &evententer.m_y );
2199 evententer.SetEventObject( currentMouseWindow ) ;
2200 currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
2201 }
2202 wxWindow::s_lastMouseWindow = currentMouseWindow ;
2203 }
2204
2205 short windowPart = inNoWindow ;
2206
2207 if ( s_captureWindow )
2208 {
2209 window = (WindowRef) s_captureWindow->MacGetRootWindow() ;
2210 windowPart = inContent ;
2211 }
2212 else
2213 {
2214 windowPart = ::FindWindow(ev->where, &window);
2215 }
2216
2217 switch (windowPart)
2218 {
2219 case inContent :
2220 {
2221 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
2222 if ( win )
2223 win->MacMouseMoved( ev , windowPart ) ;
2224 else
2225 {
2226 if ( wxIsBusy() )
2227 {
2228 }
2229 else
2230 UMAShowArrowCursor();
2231 }
2232 }
2233 break;
2234 default :
2235 {
2236 if ( wxIsBusy() )
2237 {
2238 }
2239 else
2240 UMAShowArrowCursor();
2241 }
2242 break ;
2243 }
2244 }
2245 break ;
2246
2247 }
2248 }
2249 #else
2250
2251 void wxApp::MacHandleMouseMovedEvent(wxInt32 x , wxInt32 y ,wxUint32 modifiers , long timestamp)
2252 {
2253 WindowRef window;
2254
2255 wxWindow* currentMouseWindow = NULL ;
2256
2257 if (s_captureWindow )
2258 {
2259 currentMouseWindow = s_captureWindow ;
2260 }
2261 else
2262 {
2263 wxWindow::MacGetWindowFromPoint( wxPoint( x, y ) , &currentMouseWindow ) ;
2264 }
2265
2266 if ( currentMouseWindow != wxWindow::s_lastMouseWindow )
2267 {
2268 wxMouseEvent event ;
2269
2270 bool isDown = !(modifiers & btnState) ; // 1 is for up
2271 bool controlDown = modifiers & controlKey ; // for simulating right mouse
2272
2273 event.m_leftDown = isDown && !controlDown;
2274
2275 event.m_middleDown = FALSE;
2276 event.m_rightDown = isDown && controlDown;
2277
2278 event.m_shiftDown = modifiers & shiftKey;
2279 event.m_controlDown = modifiers & controlKey;
2280 event.m_altDown = modifiers & optionKey;
2281 event.m_metaDown = modifiers & cmdKey;
2282
2283 event.m_x = x;
2284 event.m_y = y;
2285 event.m_timeStamp = timestamp;
2286
2287 if ( wxWindow::s_lastMouseWindow )
2288 {
2289 wxMouseEvent eventleave(event);
2290 eventleave.SetEventType( wxEVT_LEAVE_WINDOW );
2291 wxWindow::s_lastMouseWindow->ScreenToClient( &eventleave.m_x, &eventleave.m_y );
2292 eventleave.SetEventObject( wxWindow::s_lastMouseWindow ) ;
2293
2294 #if wxUSE_TOOLTIPS
2295 wxToolTip::RelayEvent( wxWindow::s_lastMouseWindow , eventleave);
2296 #endif // wxUSE_TOOLTIPS
2297 wxWindow::s_lastMouseWindow->GetEventHandler()->ProcessEvent(eventleave);
2298 }
2299 if ( currentMouseWindow )
2300 {
2301 wxMouseEvent evententer(event);
2302 evententer.SetEventType( wxEVT_ENTER_WINDOW );
2303 currentMouseWindow->ScreenToClient( &evententer.m_x, &evententer.m_y );
2304 evententer.SetEventObject( currentMouseWindow ) ;
2305 #if wxUSE_TOOLTIPS
2306 wxToolTip::RelayEvent( currentMouseWindow , evententer);
2307 #endif // wxUSE_TOOLTIPS
2308 currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
2309 }
2310 wxWindow::s_lastMouseWindow = currentMouseWindow ;
2311 }
2312
2313 short windowPart = inNoWindow ;
2314
2315 if ( s_captureWindow )
2316 {
2317 window = (WindowRef) s_captureWindow->MacGetRootWindow() ;
2318 windowPart = inContent ;
2319 }
2320 else
2321 {
2322 Point pt= { y , x } ;
2323 windowPart = ::FindWindow(pt , &window);
2324 }
2325
2326 switch (windowPart)
2327 {
2328 case inContent :
2329 {
2330 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
2331 if ( win )
2332 win->MacFireMouseEvent( nullEvent , x , y , modifiers , timestamp ) ;
2333 else
2334 {
2335 if ( wxIsBusy() )
2336 {
2337 }
2338 else
2339 UMAShowArrowCursor();
2340 }
2341 }
2342 break;
2343 default :
2344 {
2345 if ( wxIsBusy() )
2346 {
2347 }
2348 else
2349 UMAShowArrowCursor();
2350 }
2351 break ;
2352 }
2353 }
2354 #endif
2355
2356 void wxApp::MacHandleMenuCommand( wxUint32 id )
2357 {
2358 wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ;
2359 wxFrame* frame = mbar->GetFrame();
2360 wxCHECK_RET( mbar != NULL && frame != NULL, wxT("error in menu item callback") );
2361 if ( frame )
2362 {
2363 frame->ProcessCommand(id);
2364 }
2365 }
2366
2367 #if !TARGET_CARBON
2368 void wxApp::MacHandleMenuSelect( int macMenuId , int macMenuItemNum )
2369 {
2370 if (macMenuId == 0)
2371 return; // no menu item selected
2372
2373 if (macMenuId == kwxMacAppleMenuId && macMenuItemNum > 1)
2374 {
2375 #if ! TARGET_CARBON
2376 Str255 deskAccessoryName ;
2377 GrafPtr savedPort ;
2378
2379 GetMenuItemText(GetMenuHandle(kwxMacAppleMenuId), macMenuItemNum, deskAccessoryName);
2380 GetPort(&savedPort);
2381 OpenDeskAcc(deskAccessoryName);
2382 SetPort(savedPort);
2383 #endif
2384 }
2385 else
2386 {
2387 MenuCommand id ;
2388 GetMenuItemCommandID( GetMenuHandle(macMenuId) , macMenuItemNum , &id ) ;
2389 MacHandleMenuCommand( id ) ;
2390 }
2391 HiliteMenu(0);
2392 }
2393 #endif