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