]> git.saurik.com Git - wxWidgets.git/blob - src/mac/classic/app.cpp
Add wx.ListBox.HitTest
[wxWidgets.git] / src / mac / classic / 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 #include "wx/defs.h"
13
14 #include "wx/window.h"
15 #include "wx/frame.h"
16 #include "wx/button.h"
17 #include "wx/app.h"
18 #include "wx/utils.h"
19 #include "wx/gdicmn.h"
20 #include "wx/pen.h"
21 #include "wx/brush.h"
22 #include "wx/cursor.h"
23 #include "wx/intl.h"
24 #include "wx/icon.h"
25 #include "wx/palette.h"
26 #include "wx/dc.h"
27 #include "wx/dialog.h"
28 #include "wx/msgdlg.h"
29 #include "wx/log.h"
30 #include "wx/module.h"
31 #include "wx/memory.h"
32 #include "wx/tooltip.h"
33 #include "wx/textctrl.h"
34 #include "wx/menu.h"
35 #include "wx/docview.h"
36 #include "wx/filename.h"
37
38 #include <string.h>
39
40 // mac
41
42 #ifndef __DARWIN__
43 #if __option(profile)
44 #include <profiler.h>
45 #endif
46 #endif
47
48 #include "apprsrc.h"
49
50 #include "wx/mac/uma.h"
51 #include "wx/mac/macnotfy.h"
52
53 #ifdef __DARWIN__
54 # include <CoreServices/CoreServices.h>
55 # if defined(WXMAKINGDLL_CORE)
56 # include <mach-o/dyld.h>
57 # endif
58 #else
59 # include <Sound.h>
60 # include <Threads.h>
61 # include <ToolUtils.h>
62 # include <DiskInit.h>
63 # include <Devices.h>
64 #endif
65
66 extern wxList wxPendingDelete;
67 extern wxList *wxWinMacWindowList;
68 extern wxList *wxWinMacControlList;
69 #if wxUSE_THREADS
70 extern size_t g_numberOfThreads;
71 #endif // wxUSE_THREADS
72
73 // statics for implementation
74
75 static bool s_inYield = FALSE;
76
77 #if TARGET_CARBON
78 static bool s_inReceiveEvent = FALSE ;
79 static EventTime sleepTime = kEventDurationNoWait ;
80 #else
81 static long sleepTime = 0 ;
82 #endif
83
84 IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
85 BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
86 EVT_IDLE(wxApp::OnIdle)
87 EVT_END_SESSION(wxApp::OnEndSession)
88 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
89 END_EVENT_TABLE()
90
91 const short kMacMinHeap = (29 * 1024) ;
92 // platform specific static variables
93
94 const short kwxMacMenuBarResource = 1 ;
95 const short kwxMacAppleMenuId = 1 ;
96
97 WXHRGN wxApp::s_macCursorRgn = NULL;
98 wxWindow* wxApp::s_captureWindow = NULL ;
99 int wxApp::s_lastMouseDown = 0 ;
100 long wxApp::sm_lastMessageTime = 0;
101 long wxApp::s_lastModifiers = 0 ;
102
103
104 bool wxApp::s_macSupportPCMenuShortcuts = true ;
105 long wxApp::s_macAboutMenuItemId = wxID_ABOUT ;
106 long wxApp::s_macPreferencesMenuItemId = wxID_PREFERENCES ;
107 long wxApp::s_macExitMenuItemId = wxID_EXIT ;
108 wxString wxApp::s_macHelpMenuTitleName = wxT("&Help") ;
109
110 // Normally we're not a plugin
111 bool wxApp::sm_isEmbedded = false;
112 //----------------------------------------------------------------------
113 // Core Apple Event Support
114 //----------------------------------------------------------------------
115
116 pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
117 pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
118 pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
119 pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
120 pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
121
122 pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
123 {
124 return wxTheApp->MacHandleAEODoc( (AppleEvent*) event , reply) ;
125 }
126
127 pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
128 {
129 return wxTheApp->MacHandleAEOApp( (AppleEvent*) event , reply ) ;
130 }
131
132 pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
133 {
134 return wxTheApp->MacHandleAEPDoc( (AppleEvent*) event , reply ) ;
135 }
136
137 pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
138 {
139 return wxTheApp->MacHandleAEQuit( (AppleEvent*) event , reply) ;
140 }
141
142 pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
143 {
144 return wxTheApp->MacHandleAERApp( (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 wxCommandEvent exitEvent(wxEVT_COMMAND_MENU_SELECTED, s_macExitMenuItemId);
231 if (!win->ProcessEvent(exitEvent))
232 win->Close(TRUE ) ;
233 }
234 else
235 {
236 ExitMainLoop() ;
237 }
238 return noErr ;
239 }
240
241 // AEROApp calls MacReopenApp
242
243 short wxApp::MacHandleAERApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
244 {
245 MacReopenApp() ;
246 return noErr ;
247 }
248
249
250 //----------------------------------------------------------------------
251 // Support Routines linking the Mac...File Calls to the Document Manager
252 //----------------------------------------------------------------------
253
254 void wxApp::MacOpenFile(const wxString & fileName )
255 {
256 wxDocManager* dm = wxDocManager::GetDocumentManager() ;
257 if ( dm )
258 dm->CreateDocument(fileName , wxDOC_SILENT ) ;
259 }
260
261 void wxApp::MacPrintFile(const wxString & fileName )
262 {
263 wxDocManager* dm = wxDocManager::GetDocumentManager() ;
264 if ( dm )
265 {
266 wxDocument *doc = dm->CreateDocument(fileName , wxDOC_SILENT ) ;
267 if ( doc )
268 {
269 wxView* view = doc->GetFirstView() ;
270 if( view )
271 {
272 wxPrintout *printout = view->OnCreatePrintout();
273 if (printout)
274 {
275 wxPrinter printer;
276 printer.Print(view->GetFrame(), printout, TRUE);
277 delete printout;
278 }
279 }
280 if (doc->Close())
281 {
282 doc->DeleteAllViews();
283 dm->RemoveDocument(doc) ;
284 }
285 }
286 }
287 }
288
289 void wxApp::MacNewFile()
290 {
291 }
292
293 void wxApp::MacReopenApp()
294 {
295 // eventually check for open docs, if none, call MacNewFile
296 }
297
298 //----------------------------------------------------------------------
299 // Carbon Event Handler
300 //----------------------------------------------------------------------
301
302 #if TARGET_CARBON
303
304 static const EventTypeSpec eventList[] =
305 {
306 { kEventClassCommand, kEventProcessCommand } ,
307 { kEventClassCommand, kEventCommandUpdateStatus } ,
308
309 { kEventClassMenu, kEventMenuOpening },
310 { kEventClassMenu, kEventMenuClosed },
311 { kEventClassMenu, kEventMenuTargetItem },
312
313 { kEventClassApplication , kEventAppActivated } ,
314 { kEventClassApplication , kEventAppDeactivated } ,
315 // handling the quit event is not recommended by apple
316 // rather using the quit apple event - which we do
317
318 { kEventClassAppleEvent , kEventAppleEvent } ,
319
320 { kEventClassMouse , kEventMouseDown } ,
321 { kEventClassMouse , kEventMouseMoved } ,
322 { kEventClassMouse , kEventMouseUp } ,
323 { kEventClassMouse , kEventMouseDragged } ,
324 { 'WXMC' , 'WXMC' }
325 } ;
326
327 static pascal OSStatus
328 MenuEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
329 {
330 wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar();
331
332 if ( mbar )
333 {
334 wxFrame* win = mbar->GetFrame();
335 if ( win )
336 {
337
338 // VZ: we could find the menu from its handle here by examining all
339 // the menus in the menu bar recursively but knowing that neither
340 // wxMSW nor wxGTK do it why bother...
341 #if 0
342 MenuRef menuRef;
343
344 GetEventParameter(event,
345 kEventParamDirectObject,
346 typeMenuRef, NULL,
347 sizeof(menuRef), NULL,
348 &menuRef);
349 #endif // 0
350
351 wxEventType type=0;
352 MenuCommand cmd=0;
353 switch (GetEventKind(event))
354 {
355 case kEventMenuOpening:
356 type = wxEVT_MENU_OPEN;
357 break;
358 case kEventMenuClosed:
359 type = wxEVT_MENU_CLOSE;
360 break;
361 case kEventMenuTargetItem:
362 type = wxEVT_MENU_HIGHLIGHT;
363 GetEventParameter(event, kEventParamMenuCommand,
364 typeMenuCommand, NULL,
365 sizeof(cmd), NULL, &cmd);
366 if (cmd == 0) return eventNotHandledErr;
367 break;
368 default:
369 wxFAIL_MSG(wxT("Unexpected menu event kind"));
370 break;
371 }
372
373 wxMenuEvent wxevent(type, cmd);
374 wxevent.SetEventObject(win);
375
376 (void)win->GetEventHandler()->ProcessEvent(wxevent);
377 }
378 }
379
380 return eventNotHandledErr;
381 }
382
383 // due to the rather low-level event API of wxWidgets, we cannot use RunApplicationEventLoop
384 // but have to use ReceiveNextEvent dealing with events manually, therefore we also have
385 // to deal with clicks in the menu bar explicitly
386
387 pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) ;
388
389 static pascal OSStatus MouseEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
390 {
391 OSStatus result = eventNotHandledErr ;
392
393 Point point ;
394 UInt32 modifiers = 0;
395 EventMouseButton button = 0 ;
396 UInt32 click = 0 ;
397
398 GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL,
399 sizeof( Point ), NULL, &point );
400 GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL,
401 sizeof( UInt32 ), NULL, &modifiers );
402 GetEventParameter( event, kEventParamMouseButton, typeMouseButton, NULL,
403 sizeof( EventMouseButton ), NULL, &button );
404 GetEventParameter( event, kEventParamClickCount, typeUInt32, NULL,
405 sizeof( UInt32 ), NULL, &click );
406
407 if ( button == 0 || GetEventKind( event ) == kEventMouseUp )
408 modifiers += btnState ;
409
410
411 switch( GetEventKind(event) )
412 {
413 case kEventMouseDown :
414 {
415 WindowRef window ;
416
417 short windowPart = ::FindWindow(point, &window);
418
419 if ( windowPart == inMenuBar )
420 {
421 MenuSelect( point ) ;
422 result = noErr ;
423 }
424 }
425 break ;
426 case kEventMouseDragged :
427 case kEventMouseUp :
428 {
429 if ( wxTheApp->s_captureWindow )
430 wxMacWindowEventHandler( handler , event , (void*) wxTheApp->s_captureWindow->MacGetTopLevelWindow() ) ;
431 }
432 break ;
433 case kEventMouseMoved :
434 {
435 wxTheApp->MacHandleMouseMovedEvent( point.h , point.v , modifiers , EventTimeToTicks( GetEventTime( event ) ) ) ;
436 result = noErr ;
437 break ;
438 }
439 break ;
440 }
441
442 return result ;
443 }
444
445 static pascal OSStatus CommandEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
446 {
447 OSStatus result = eventNotHandledErr ;
448
449 HICommand command ;
450
451 GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL,
452 sizeof( HICommand ), NULL, &command );
453
454 MenuCommand id = command.commandID ;
455 if ( id == kHICommandPreferences )
456 id = wxApp::s_macPreferencesMenuItemId ;
457
458 wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ;
459 wxMenu* menu = NULL ;
460 wxMenuItem* item = NULL ;
461
462 if ( mbar )
463 {
464 item = mbar->FindItem( id , &menu ) ;
465 // it is not 100 % sure that an menu of id 0 is really ours, safety check
466 if ( id == 0 && menu != NULL && menu->GetHMenu() != command.menu.menuRef )
467 {
468 item = NULL ;
469 menu = NULL ;
470 }
471 }
472
473 if ( item == NULL || menu == NULL || mbar == NULL )
474 return result ;
475
476 switch( GetEventKind( event ) )
477 {
478 case kEventProcessCommand :
479 {
480 if (item->IsCheckable())
481 {
482 item->Check( !item->IsChecked() ) ;
483 }
484
485 menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
486 result = noErr ;
487 }
488 break ;
489 case kEventCommandUpdateStatus:
490 // eventually trigger an updateui round
491 result = noErr ;
492 break ;
493 default :
494 break ;
495 }
496
497 return result ;
498 }
499
500 static pascal OSStatus ApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
501 {
502 OSStatus result = eventNotHandledErr ;
503 switch ( GetEventKind( event ) )
504 {
505 case kEventAppActivated :
506 {
507 if ( wxTheApp )
508 wxTheApp->MacResume( true ) ;
509 result = noErr ;
510 }
511 break ;
512 case kEventAppDeactivated :
513 {
514 if ( wxTheApp )
515 wxTheApp->MacSuspend( true ) ;
516 result = noErr ;
517 }
518 break ;
519 default :
520 break ;
521 }
522 return result ;
523 }
524
525 pascal OSStatus wxAppEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
526 {
527 OSStatus result = eventNotHandledErr ;
528 switch( GetEventClass( event ) )
529 {
530 case kEventClassCommand :
531 result = CommandEventHandler( handler , event , data ) ;
532 break ;
533 case kEventClassApplication :
534 result = ApplicationEventHandler( handler , event , data ) ;
535 break ;
536 case kEventClassMenu :
537 result = MenuEventHandler( handler , event , data ) ;
538 break ;
539 case kEventClassMouse :
540 result = MouseEventHandler( handler , event , data ) ;
541 break ;
542 case kEventClassAppleEvent :
543 {
544 EventRecord rec ;
545 wxMacConvertEventToRecord( event , &rec ) ;
546 result = AEProcessAppleEvent( &rec ) ;
547 }
548 break ;
549 default :
550 break ;
551 }
552
553 return result ;
554 }
555
556 DEFINE_ONE_SHOT_HANDLER_GETTER( wxAppEventHandler )
557
558 #endif
559
560 #if defined(WXMAKINGDLL_CORE) && !defined(__DARWIN__)
561 // we know it's there ;-)
562 WXIMPORT char std::__throws_bad_alloc ;
563 #endif
564
565 bool wxApp::Initialize(int& argc, wxChar **argv)
566 {
567 int error = 0 ;
568
569 // Mac-specific
570
571 UMAInitToolbox( 4, sm_isEmbedded ) ;
572 SetEventMask( everyEvent ) ;
573 UMAShowWatchCursor() ;
574
575 #if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
576 // open shared library resources from here since we don't have
577 // __wxinitialize in Mach-O shared libraries
578 wxStAppResource::OpenSharedLibraryResource(NULL);
579 #endif
580
581 #ifndef __DARWIN__
582 // test the minimal configuration necessary
583
584 # if !TARGET_CARBON
585 long theSystem ;
586 long theMachine;
587
588 if (Gestalt(gestaltMachineType, &theMachine) != noErr)
589 {
590 error = kMacSTRWrongMachine;
591 }
592 else if (theMachine < gestaltMacPlus)
593 {
594 error = kMacSTRWrongMachine;
595 }
596 else if (Gestalt(gestaltSystemVersion, &theSystem) != noErr )
597 {
598 error = kMacSTROldSystem ;
599 }
600 else if ( theSystem < 0x0860 )
601 {
602 error = kMacSTROldSystem ;
603 }
604 else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap)
605 {
606 error = kMacSTRSmallSize;
607 }
608 # endif
609 /*
610 else
611 {
612 if ( !UMAHasAppearance() )
613 {
614 error = kMacSTRNoPre8Yet ;
615 }
616 }
617 */
618 #endif
619
620 // if we encountered any problems so far, give the error code and exit immediately
621
622 if ( error )
623 {
624 wxStAppResource resload ;
625 short itemHit;
626 Str255 message;
627
628 GetIndString(message, 128, error);
629 UMAShowArrowCursor() ;
630 ParamText("\pFatal Error", message, (ConstStr255Param)"\p", (ConstStr255Param)"\p");
631 itemHit = Alert(128, nil);
632 return FALSE ;
633 }
634
635 #ifndef __DARWIN__
636 # if __option(profile)
637 ProfilerInit( collectDetailed, bestTimeBase , 40000 , 50 ) ;
638 # endif
639 #endif
640
641 #ifndef __DARWIN__
642 // now avoid exceptions thrown for new (bad_alloc)
643 // FIXME CS for some changes outside wxMac does not compile anymore
644 #if 0
645 std::__throws_bad_alloc = 0 ;
646 #endif
647
648 #endif
649
650 s_macCursorRgn = ::NewRgn() ;
651
652 // Mac OS X passes a process serial number command line argument when
653 // the application is launched from the Finder. This argument must be
654 // removed from the command line arguments before being handled by the
655 // application (otherwise applications would need to handle it)
656 if ( argc > 1 )
657 {
658 static const wxChar *ARG_PSN = _T("-psn_");
659 if ( wxStrncmp(argv[1], ARG_PSN, wxStrlen(ARG_PSN)) == 0 )
660 {
661 // remove this argument
662 --argc;
663 memmove(argv + 1, argv + 2, argc * sizeof(char *));
664 }
665 }
666
667 if ( !wxAppBase::Initialize(argc, argv) )
668 return false;
669
670 #if wxUSE_INTL
671 wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
672 #endif
673
674
675 wxWinMacWindowList = new wxList(wxKEY_INTEGER);
676 wxWinMacControlList = new wxList(wxKEY_INTEGER);
677
678 wxMacCreateNotifierTable() ;
679
680 UMAShowArrowCursor() ;
681
682 return true;
683 }
684
685 bool wxApp::OnInitGui()
686 {
687 if( !wxAppBase::OnInitGui() )
688 return false ;
689
690 #if TARGET_CARBON
691 InstallStandardEventHandler( GetApplicationEventTarget() ) ;
692
693 if (!sm_isEmbedded)
694 {
695 InstallApplicationEventHandler(
696 GetwxAppEventHandlerUPP(),
697 GetEventTypeCount(eventList), eventList, wxTheApp, (EventHandlerRef *)&(wxTheApp->m_macEventHandler));
698 }
699 #endif
700
701 if (!sm_isEmbedded)
702 {
703 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
704 AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
705 NewAEEventHandlerUPP(AEHandleODoc) ,
706 0 , FALSE ) ;
707 AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
708 NewAEEventHandlerUPP(AEHandleOApp) ,
709 0 , FALSE ) ;
710 AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
711 NewAEEventHandlerUPP(AEHandlePDoc) ,
712 0 , FALSE ) ;
713 AEInstallEventHandler( kCoreEventClass , kAEReopenApplication ,
714 NewAEEventHandlerUPP(AEHandleRApp) ,
715 0 , FALSE ) ;
716 AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
717 NewAEEventHandlerUPP(AEHandleQuit) ,
718 0 , FALSE ) ;
719 #else
720 AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
721 NewAEEventHandlerProc(AEHandleODoc) ,
722 0 , FALSE ) ;
723 AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
724 NewAEEventHandlerProc(AEHandleOApp) ,
725 0 , FALSE ) ;
726 AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
727 NewAEEventHandlerProc(AEHandlePDoc) ,
728 0 , FALSE ) ;
729 AEInstallEventHandler( kCoreEventClass , kAEReopenApplication ,
730 NewAEEventHandlerProc(AEHandleRApp) ,
731 0 , FALSE ) ;
732 AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
733 NewAEEventHandlerProc(AEHandleQuit) ,
734 0 , FALSE ) ;
735 #endif
736 }
737
738 return TRUE ;
739 }
740
741 void wxApp::CleanUp()
742 {
743 wxToolTip::RemoveToolTips() ;
744
745 // One last chance for pending objects to be cleaned up
746 wxTheApp->DeletePendingObjects();
747
748 wxMacDestroyNotifierTable() ;
749
750 delete wxWinMacWindowList ;
751 wxWinMacWindowList = NULL;
752
753 delete wxWinMacControlList ;
754 wxWinMacControlList = NULL;
755
756 #ifndef __DARWIN__
757 # if __option(profile)
758 ProfilerDump( (StringPtr)"\papp.prof" ) ;
759 ProfilerTerm() ;
760 # endif
761 #endif
762
763 #if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
764 // close shared library resources from here since we don't have
765 // __wxterminate in Mach-O shared libraries
766 wxStAppResource::CloseSharedLibraryResource();
767 #endif
768
769 UMACleanupToolbox() ;
770 if (s_macCursorRgn) {
771 ::DisposeRgn((RgnHandle)s_macCursorRgn);
772 }
773
774 #if 0
775 TerminateAE() ;
776 #endif
777
778 wxAppBase::CleanUp();
779 }
780
781 //----------------------------------------------------------------------
782 // misc initialization stuff
783 //----------------------------------------------------------------------
784
785 // extern variable for shared library resource id
786 // need to be able to find it with NSLookupAndBindSymbol
787 short gSharedLibraryResource = kResFileNotOpened ;
788
789 #if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
790 CFBundleRef gSharedLibraryBundle = NULL;
791 #endif /* WXMAKINGDLL_CORE && __DARWIN__ */
792
793 wxStAppResource::wxStAppResource()
794 {
795 m_currentRefNum = CurResFile() ;
796 if ( gSharedLibraryResource != kResFileNotOpened )
797 {
798 UseResFile( gSharedLibraryResource ) ;
799 }
800 }
801
802 wxStAppResource::~wxStAppResource()
803 {
804 if ( m_currentRefNum != kResFileNotOpened )
805 {
806 UseResFile( m_currentRefNum ) ;
807 }
808 }
809
810 void wxStAppResource::OpenSharedLibraryResource(const void *initBlock)
811 {
812 gSharedLibraryResource = kResFileNotOpened;
813
814 #ifdef WXMAKINGDLL_CORE
815 if ( initBlock != NULL ) {
816 const CFragInitBlock *theInitBlock = (const CFragInitBlock *)initBlock;
817 FSSpec *fileSpec = NULL;
818
819 if (theInitBlock->fragLocator.where == kDataForkCFragLocator) {
820 fileSpec = theInitBlock->fragLocator.u.onDisk.fileSpec;
821 }
822 else if (theInitBlock->fragLocator.where == kResourceCFragLocator) {
823 fileSpec = theInitBlock->fragLocator.u.inSegs.fileSpec;
824 }
825
826 if (fileSpec != NULL) {
827 gSharedLibraryResource = FSpOpenResFile(fileSpec, fsRdPerm);
828 }
829 }
830 else {
831 #ifdef __DARWIN__
832 // Open the shared library resource file if it is not yet open
833 NSSymbol theSymbol;
834 NSModule theModule;
835 const char *theLibPath;
836
837 gSharedLibraryBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWidgets"));
838 if (gSharedLibraryBundle != NULL) {
839 // wxWidgets has been bundled into a framework
840 // load the framework resources
841
842 gSharedLibraryResource = CFBundleOpenBundleResourceMap(gSharedLibraryBundle);
843 }
844 else {
845 // wxWidgets is a simple dynamic shared library
846 // load the resources from the data fork of a separate resource file
847 wxString theResPath;
848 wxString theName;
849 FSRef theResRef;
850 OSErr theErr = noErr;
851
852 // get the library path
853 theSymbol = NSLookupAndBindSymbol("_gSharedLibraryResource");
854 theModule = NSModuleForSymbol(theSymbol);
855 theLibPath = NSLibraryNameForModule(theModule);
856
857 // if we call wxLogDebug from here then, as wxTheApp hasn't been
858 // created yet when we're called from wxApp::Initialize(), wxLog
859 // is going to create a default stderr-based log target instead of
860 // the expected normal GUI one -- don't do it, if we really want
861 // to see this message just use fprintf() here
862 #if 0
863 wxLogDebug( wxT("wxMac library installation name is '%s'"),
864 theLibPath );
865 #endif
866
867 // allocate copy to replace .dylib.* extension with .rsrc
868 if (theLibPath != NULL) {
869 #if wxUSE_UNICODE
870 theResPath = wxString(theLibPath, wxConvLocal);
871 #else
872 theResPath = wxString(theLibPath);
873 #endif
874 // replace '_core' with '' in case of multi-lib build
875 theResPath.Replace(wxT("_core"), wxEmptyString);
876 // replace ".dylib" shared library extension with ".rsrc"
877 theResPath.Replace(wxT(".dylib"), wxT(".rsrc"));
878 // Find the begining of the filename
879 theName = theResPath.AfterLast('/');
880
881 #if 0
882 wxLogDebug( wxT("wxMac resources file name is '%s'"),
883 theResPath.mb_str() );
884 #endif
885
886 theErr = FSPathMakeRef((UInt8 *) theResPath.mb_str(), &theResRef, false);
887 if (theErr != noErr) {
888 // try in current directory (using name only)
889 theErr = FSPathMakeRef((UInt8 *) theName.mb_str(), &theResRef, false);
890 }
891
892 // open the resource file
893 if (theErr == noErr) {
894 theErr = FSOpenResourceFile( &theResRef, 0, NULL, fsRdPerm,
895 &gSharedLibraryResource);
896 }
897 if (theErr != noErr) {
898 #ifdef __WXDEBUG__
899 wxLogDebug( wxT("unable to open wxMac resource file '%s'\n"),
900 theResPath.mb_str() );
901 #endif // __WXDEBUG__
902 }
903
904 }
905 }
906 #endif /* __DARWIN__ */
907 }
908 #endif /* WXMAKINGDLL_CORE */
909 }
910
911 void wxStAppResource::CloseSharedLibraryResource()
912 {
913 #ifdef WXMAKINGDLL_CORE
914 // Close the shared library resource file
915 if (gSharedLibraryResource != kResFileNotOpened) {
916 #ifdef __DARWIN__
917 if (gSharedLibraryBundle != NULL) {
918 CFBundleCloseBundleResourceMap(gSharedLibraryBundle,
919 gSharedLibraryResource);
920 gSharedLibraryBundle = NULL;
921 }
922 else
923 #endif /* __DARWIN__ */
924 {
925 CloseResFile(gSharedLibraryResource);
926 }
927 gSharedLibraryResource = kResFileNotOpened;
928 }
929 #endif /* WXMAKINGDLL_CORE */
930 }
931
932 #if defined(WXMAKINGDLL_CORE) && !defined(__DARWIN__)
933
934 // for shared libraries we have to manually get the correct resource
935 // ref num upon initializing and releasing when terminating, therefore
936 // the __wxinitialize and __wxterminate must be used
937
938 extern "C" {
939 void __sinit(void); /* (generated by linker) */
940 pascal OSErr __initialize(const CFragInitBlock *theInitBlock);
941 pascal void __terminate(void);
942 }
943
944 pascal OSErr __wxinitialize(const CFragInitBlock *theInitBlock)
945 {
946 wxStAppResource::OpenSharedLibraryResource( theInitBlock ) ;
947 return __initialize( theInitBlock ) ;
948 }
949
950 pascal void __wxterminate(void)
951 {
952 wxStAppResource::CloseSharedLibraryResource() ;
953 __terminate() ;
954 }
955
956 #endif /* WXMAKINGDLL_CORE && !__DARWIN__ */
957
958 #if TARGET_CARBON
959
960 bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec)
961 {
962 bool converted = ConvertEventRefToEventRecord( event,rec) ;
963 OSStatus err = noErr ;
964 if ( !converted )
965 {
966 switch( GetEventClass( event ) )
967 {
968 case kEventClassKeyboard :
969 {
970 converted = true ;
971 switch( GetEventKind(event) )
972 {
973 case kEventRawKeyDown :
974 rec->what = keyDown ;
975 break ;
976 case kEventRawKeyRepeat :
977 rec->what = autoKey ;
978 break ;
979 case kEventRawKeyUp :
980 rec->what = keyUp ;
981 break ;
982 case kEventRawKeyModifiersChanged :
983 rec->what = nullEvent ;
984 break ;
985 default :
986 converted = false ;
987 break ;
988 }
989 if ( converted )
990 {
991 UInt32 keyCode ;
992 unsigned char charCode ;
993 UInt32 modifiers ;
994 GetMouse( &rec->where) ;
995
996 err = GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers);
997 err = GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode);
998 err = GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode);
999 rec->modifiers = modifiers ;
1000 rec->message = (keyCode << 8 ) + charCode ;
1001 }
1002 }
1003 break ;
1004 case kEventClassTextInput :
1005 {
1006 switch( GetEventKind( event ) )
1007 {
1008 case kEventTextInputUnicodeForKeyEvent :
1009 {
1010 EventRef rawEvent ;
1011 err = GetEventParameter( event , kEventParamTextInputSendKeyboardEvent ,typeEventRef,NULL,sizeof(rawEvent),NULL,&rawEvent ) ;
1012 converted = true ;
1013 {
1014 UInt32 keyCode ;
1015 unsigned char charCode ;
1016 UInt32 modifiers ;
1017 GetMouse( &rec->where) ;
1018 rec->what = keyDown ;
1019 err = GetEventParameter(rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers);
1020 err = GetEventParameter(rawEvent, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode);
1021 err = GetEventParameter(rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode);
1022 rec->modifiers = modifiers ;
1023 rec->message = (keyCode << 8 ) + charCode ;
1024 }
1025 }
1026 break ;
1027 default :
1028 break ;
1029 }
1030 }
1031 break ;
1032 }
1033 }
1034
1035 return converted ;
1036 }
1037
1038 /*
1039 pascal OSStatus wxMacApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
1040 {
1041 OSStatus result = eventNotHandledErr ;
1042
1043 EventRecord rec ;
1044 switch ( GetEventClass( event ) )
1045 {
1046 case kEventClassKeyboard :
1047 if ( wxMacConvertEventToRecord( event , &rec ) )
1048 {
1049 wxTheApp->MacHandleModifierEvents( &rec ) ;
1050 wxTheApp->MacHandleOneEvent( &rec ) ;
1051 result = noErr ;
1052 }
1053 break ;
1054 case kEventClassTextInput :
1055 if ( wxMacConvertEventToRecord( event , &rec ) )
1056 {
1057 wxTheApp->MacHandleModifierEvents( &rec ) ;
1058 wxTheApp->MacHandleOneEvent( &rec ) ;
1059 result = noErr ;
1060 }
1061 break ;
1062 default :
1063 break ;
1064 }
1065 return result ;
1066 }
1067 */
1068 #endif
1069
1070 wxApp::wxApp()
1071 {
1072 m_printMode = wxPRINT_WINDOWS;
1073 m_auto3D = TRUE;
1074
1075 m_macCurrentEvent = NULL ;
1076 #if TARGET_CARBON
1077 m_macCurrentEventHandlerCallRef = NULL ;
1078 #endif
1079 }
1080
1081 int wxApp::MainLoop()
1082 {
1083 m_keepGoing = TRUE;
1084
1085 while (m_keepGoing)
1086 {
1087 MacDoOneEvent() ;
1088 }
1089
1090 return 0;
1091 }
1092
1093 void wxApp::ExitMainLoop()
1094 {
1095 m_keepGoing = FALSE;
1096 }
1097
1098 // Is a message/event pending?
1099 bool wxApp::Pending()
1100 {
1101 #if TARGET_CARBON
1102 // without the receive event (with pull param = false ) nothing is ever reported
1103 EventRef theEvent;
1104 ReceiveNextEvent (0, NULL, kEventDurationNoWait, false, &theEvent);
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.SetTimestamp( 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( (WXWindow) 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( (WXWindow) 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 wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key !=
1850 WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons"));
1851
1852 KeyMap keymap;
1853 GetKeys(keymap);
1854 return !!(BitTst(keymap, (sizeof(KeyMap)*8) - key));
1855 }
1856
1857 #if !TARGET_CARBON
1858 void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr )
1859 {
1860 EventRecord* ev = (EventRecord*) evr ;
1861 wxToolTip::RemoveToolTips() ;
1862
1863 UInt32 menuresult = UMAMenuEvent(ev) ;
1864 if ( HiWord( menuresult ) )
1865 {
1866 if ( !s_macIsInModalLoop )
1867 MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ) ;
1868 }
1869 else
1870 {
1871 wxWindow* focus = wxWindow::FindFocus() ;
1872
1873 if ( MacSendKeyDownEvent( focus , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) == false )
1874 {
1875 #if 0
1876 // we must handle control keys the other way round, otherwise text content is updated too late
1877 // has not been handled -> perform default
1878 wxControl* control = wxDynamicCast( focus , wxControl ) ;
1879 if ( control && control->GetMacControl() != NULL )
1880 {
1881 short keycode ;
1882 short keychar ;
1883 keychar = short(ev->message & charCodeMask);
1884 keycode = short(ev->message & keyCodeMask) >> 8 ;
1885 ::HandleControlKey( (ControlHandle) control->GetMacControl() , keycode , keychar , ev->modifiers ) ;
1886 }
1887 #endif
1888 }
1889 }
1890 }
1891
1892 void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr )
1893 {
1894 EventRecord* ev = (EventRecord*) evr ;
1895 wxToolTip::RemoveToolTips() ;
1896
1897 UInt32 menuresult = UMAMenuEvent(ev) ;
1898 if ( HiWord( menuresult ) )
1899 {
1900 }
1901 else
1902 {
1903 MacSendKeyUpEvent( wxWindow::FindFocus() , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) ;
1904 }
1905 }
1906
1907 #endif
1908
1909 bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey )
1910 {
1911 if ( !focus )
1912 return false ;
1913
1914 short keycode ;
1915 short keychar ;
1916 keychar = short(keymessage & charCodeMask);
1917 keycode = short(keymessage & keyCodeMask) >> 8 ;
1918
1919 if ( modifiers & ( controlKey|shiftKey|optionKey ) )
1920 {
1921 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
1922 // and look at the character after
1923 UInt32 state = 0;
1924 UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state);
1925 keychar = short(keyInfo & charCodeMask);
1926 keycode = short(keyInfo & keyCodeMask) >> 8 ;
1927 }
1928 long keyval = wxMacTranslateKey(keychar, keycode) ;
1929 long realkeyval = keyval ;
1930 if ( keyval == keychar )
1931 {
1932 // 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)
1933 realkeyval = short(keymessage & charCodeMask) ;
1934 keyval = wxToupper( keyval ) ;
1935 }
1936
1937 wxKeyEvent event(wxEVT_KEY_DOWN);
1938 bool handled = false ;
1939 event.m_shiftDown = modifiers & shiftKey;
1940 event.m_controlDown = modifiers & controlKey;
1941 event.m_altDown = modifiers & optionKey;
1942 event.m_metaDown = modifiers & cmdKey;
1943 event.m_keyCode = keyval ;
1944
1945 event.m_x = wherex;
1946 event.m_y = wherey;
1947 event.SetTimestamp(when);
1948 event.SetEventObject(focus);
1949 handled = focus->GetEventHandler()->ProcessEvent( event ) ;
1950 if ( handled && event.GetSkipped() )
1951 handled = false ;
1952 if ( !handled )
1953 {
1954 #if wxUSE_ACCEL
1955 if (!handled)
1956 {
1957 wxWindow *ancestor = focus;
1958 while (ancestor)
1959 {
1960 int command = ancestor->GetAcceleratorTable()->GetCommand( event );
1961 if (command != -1)
1962 {
1963 wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
1964 handled = ancestor->GetEventHandler()->ProcessEvent( command_event );
1965 break;
1966 }
1967 if (ancestor->IsTopLevel())
1968 break;
1969 ancestor = ancestor->GetParent();
1970 }
1971 }
1972 #endif // wxUSE_ACCEL
1973 }
1974 if (!handled)
1975 {
1976 event.Skip( FALSE ) ;
1977 event.SetEventType( wxEVT_CHAR ) ;
1978 // raw value again
1979 event.m_keyCode = realkeyval ;
1980
1981 handled = focus->GetEventHandler()->ProcessEvent( event ) ;
1982 if ( handled && event.GetSkipped() )
1983 handled = false ;
1984 }
1985 if ( !handled &&
1986 (keyval == WXK_TAB) &&
1987 // CS: copied the change below from wxGTK
1988 // VZ: testing for wxTE_PROCESS_TAB shouldn't be done here the control may
1989 // have this style, yet choose not to process this particular TAB in which
1990 // case TAB must still work as a navigational character
1991 #if 0
1992 (!focus->HasFlag(wxTE_PROCESS_TAB)) &&
1993 #endif
1994 (focus->GetParent()) &&
1995 (focus->GetParent()->HasFlag( wxTAB_TRAVERSAL)) )
1996 {
1997 wxNavigationKeyEvent new_event;
1998 new_event.SetEventObject( focus );
1999 new_event.SetDirection( !event.ShiftDown() );
2000 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
2001 new_event.SetWindowChange( event.ControlDown() );
2002 new_event.SetCurrentFocus( focus );
2003 handled = focus->GetEventHandler()->ProcessEvent( new_event );
2004 if ( handled && new_event.GetSkipped() )
2005 handled = false ;
2006 }
2007 // backdoor handler for default return and command escape
2008 if ( !handled && (!focus->IsKindOf(CLASSINFO(wxControl) ) || !focus->MacCanFocus() ) )
2009 {
2010 // if window is not having a focus still testing for default enter or cancel
2011 // TODO add the UMA version for ActiveNonFloatingWindow
2012 wxWindow* focus = wxFindWinFromMacWindow( (WXWindow) FrontWindow() ) ;
2013 if ( focus )
2014 {
2015 if ( keyval == WXK_RETURN )
2016 {
2017 wxButton *def = wxDynamicCast(focus->GetDefaultItem(),
2018 wxButton);
2019 if ( def && def->IsEnabled() )
2020 {
2021 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
2022 event.SetEventObject(def);
2023 def->Command(event);
2024 return true ;
2025 }
2026 }
2027 /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
2028 else if (keyval == WXK_ESCAPE || (keyval == '.' && modifiers & cmdKey ) )
2029 {
2030 wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL);
2031 new_event.SetEventObject( focus );
2032 handled = focus->GetEventHandler()->ProcessEvent( new_event );
2033 }
2034 }
2035 }
2036 return handled ;
2037 }
2038
2039 bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey )
2040 {
2041 if ( !focus )
2042 return false ;
2043
2044 short keycode ;
2045 short keychar ;
2046 keychar = short(keymessage & charCodeMask);
2047 keycode = short(keymessage & keyCodeMask) >> 8 ;
2048 if ( modifiers & ( controlKey|shiftKey|optionKey ) )
2049 {
2050 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
2051 // and look at the character after
2052 UInt32 state = 0;
2053 UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state);
2054 keychar = short(keyInfo & charCodeMask);
2055 keycode = short(keyInfo & keyCodeMask) >> 8 ;
2056 }
2057 long keyval = wxMacTranslateKey(keychar, keycode) ;
2058
2059 if ( keyval == keychar )
2060 {
2061 keyval = wxToupper( keyval ) ;
2062 }
2063 bool handled = false ;
2064
2065 wxKeyEvent event(wxEVT_KEY_UP);
2066 event.m_shiftDown = modifiers & shiftKey;
2067 event.m_controlDown = modifiers & controlKey;
2068 event.m_altDown = modifiers & optionKey;
2069 event.m_metaDown = modifiers & cmdKey;
2070 event.m_keyCode = keyval ;
2071
2072 event.m_x = wherex;
2073 event.m_y = wherey;
2074 event.SetTimestamp(when);
2075 event.SetEventObject(focus);
2076 handled = focus->GetEventHandler()->ProcessEvent( event ) ;
2077
2078 return handled ;
2079 }
2080
2081 #if !TARGET_CARBON
2082 void wxApp::MacHandleActivateEvent( WXEVENTREF evr )
2083 {
2084 EventRecord* ev = (EventRecord*) evr ;
2085 WindowRef window = (WindowRef) ev->message ;
2086 if ( window )
2087 {
2088 bool activate = (ev->modifiers & activeFlag ) ;
2089 WindowClass wclass ;
2090 ::GetWindowClass ( window , &wclass ) ;
2091 if ( wclass == kFloatingWindowClass )
2092 {
2093 // if it is a floater we activate/deactivate the front non-floating window instead
2094 window = ::FrontNonFloatingWindow() ;
2095 }
2096 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( (WXWindow) window ) ;
2097 if ( win )
2098 win->MacActivate( ev->when , activate ) ;
2099 }
2100 }
2101
2102 void wxApp::MacHandleUpdateEvent( WXEVENTREF evr )
2103 {
2104 EventRecord* ev = (EventRecord*) evr ;
2105 WindowRef window = (WindowRef) ev->message ;
2106 wxTopLevelWindowMac * win = wxFindWinFromMacWindow( (WXWindow) window ) ;
2107 if ( win )
2108 {
2109 if ( !wxPendingDelete.Member(win) )
2110 win->MacUpdate( ev->when ) ;
2111 }
2112 else
2113 {
2114 // since there is no way of telling this foreign window to update itself
2115 // we have to invalidate the update region otherwise we keep getting the same
2116 // event over and over again
2117 BeginUpdate( window ) ;
2118 EndUpdate( window ) ;
2119 }
2120 }
2121
2122 void wxApp::MacHandleDiskEvent( WXEVENTREF evr )
2123 {
2124 EventRecord* ev = (EventRecord*) evr ;
2125 if ( HiWord( ev->message ) != noErr )
2126 {
2127 OSErr err ;
2128 Point point ;
2129 SetPt( &point , 100 , 100 ) ;
2130
2131 err = DIBadMount( point , ev->message ) ;
2132 wxASSERT( err == noErr ) ;
2133 }
2134 }
2135
2136 void wxApp::MacHandleOSEvent( WXEVENTREF evr )
2137 {
2138 EventRecord* ev = (EventRecord*) evr ;
2139 switch( ( ev->message & osEvtMessageMask ) >> 24 )
2140 {
2141 case suspendResumeMessage :
2142 {
2143 bool isResuming = ev->message & resumeFlag ;
2144 bool convertClipboard = ev->message & convertClipboardFlag ;
2145
2146 bool doesActivate = UMAGetProcessModeDoesActivateOnFGSwitch() ;
2147 if ( isResuming )
2148 {
2149 WindowRef oldFrontWindow = NULL ;
2150 WindowRef newFrontWindow = NULL ;
2151
2152 // in case we don't take care of activating ourselves, we have to synchronize
2153 // our idea of the active window with the process manager's - which it already activated
2154
2155 if ( !doesActivate )
2156 oldFrontWindow = ::FrontNonFloatingWindow() ;
2157
2158 MacResume( convertClipboard ) ;
2159
2160 newFrontWindow = ::FrontNonFloatingWindow() ;
2161
2162 if ( oldFrontWindow )
2163 {
2164 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( (WXWindow) oldFrontWindow ) ;
2165 if ( win )
2166 win->MacActivate( ev->when , false ) ;
2167 }
2168 if ( newFrontWindow )
2169 {
2170 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( (WXWindow) newFrontWindow ) ;
2171 if ( win )
2172 win->MacActivate( ev->when , true ) ;
2173 }
2174 }
2175 else
2176 {
2177 MacSuspend( convertClipboard ) ;
2178 }
2179 }
2180 break ;
2181 case mouseMovedMessage :
2182 {
2183 WindowRef window;
2184
2185 wxWindow* currentMouseWindow = NULL ;
2186
2187 if (s_captureWindow )
2188 {
2189 currentMouseWindow = s_captureWindow ;
2190 }
2191 else
2192 {
2193 wxWindow::MacGetWindowFromPoint( wxPoint( ev->where.h , ev->where.v ) ,
2194 &currentMouseWindow ) ;
2195 }
2196
2197 if ( currentMouseWindow != wxWindow::s_lastMouseWindow )
2198 {
2199 wxMouseEvent event ;
2200
2201 bool isDown = !(ev->modifiers & btnState) ; // 1 is for up
2202 bool controlDown = ev->modifiers & controlKey ; // for simulating right mouse
2203
2204 event.m_leftDown = isDown && !controlDown;
2205 event.m_middleDown = FALSE;
2206 event.m_rightDown = isDown && controlDown;
2207 event.m_shiftDown = ev->modifiers & shiftKey;
2208 event.m_controlDown = ev->modifiers & controlKey;
2209 event.m_altDown = ev->modifiers & optionKey;
2210 event.m_metaDown = ev->modifiers & cmdKey;
2211 event.m_x = ev->where.h;
2212 event.m_y = ev->where.v;
2213 event.SetTimestamp( ev->when );
2214 event.SetEventObject(this);
2215
2216 if ( wxWindow::s_lastMouseWindow )
2217 {
2218 wxMouseEvent eventleave(event);
2219 eventleave.SetEventType( wxEVT_LEAVE_WINDOW );
2220 wxWindow::s_lastMouseWindow->ScreenToClient( &eventleave.m_x, &eventleave.m_y );
2221 eventleave.SetEventObject( wxWindow::s_lastMouseWindow ) ;
2222
2223 wxWindow::s_lastMouseWindow->GetEventHandler()->ProcessEvent(eventleave);
2224 }
2225 if ( currentMouseWindow )
2226 {
2227 wxMouseEvent evententer(event);
2228 evententer.SetEventType( wxEVT_ENTER_WINDOW );
2229 currentMouseWindow->ScreenToClient( &evententer.m_x, &evententer.m_y );
2230 evententer.SetEventObject( currentMouseWindow ) ;
2231 currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
2232 }
2233 wxWindow::s_lastMouseWindow = currentMouseWindow ;
2234 }
2235
2236 short windowPart = inNoWindow ;
2237
2238 if ( s_captureWindow )
2239 {
2240 window = (WindowRef) s_captureWindow->MacGetRootWindow() ;
2241 windowPart = inContent ;
2242 }
2243 else
2244 {
2245 windowPart = ::FindWindow(ev->where, &window);
2246 }
2247
2248 switch (windowPart)
2249 {
2250 case inContent :
2251 {
2252 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( (WXWindow) window ) ;
2253 if ( win )
2254 win->MacMouseMoved( ev , windowPart ) ;
2255 else
2256 {
2257 if ( wxIsBusy() )
2258 {
2259 }
2260 else
2261 UMAShowArrowCursor();
2262 }
2263 }
2264 break;
2265 default :
2266 {
2267 if ( wxIsBusy() )
2268 {
2269 }
2270 else
2271 UMAShowArrowCursor();
2272 }
2273 break ;
2274 }
2275 }
2276 break ;
2277
2278 }
2279 }
2280 #else
2281
2282 void wxApp::MacHandleMouseMovedEvent(wxInt32 x , wxInt32 y ,wxUint32 modifiers , long timestamp)
2283 {
2284 WindowRef window;
2285
2286 wxWindow* currentMouseWindow = NULL ;
2287
2288 if (s_captureWindow )
2289 {
2290 currentMouseWindow = s_captureWindow ;
2291 }
2292 else
2293 {
2294 wxWindow::MacGetWindowFromPoint( wxPoint( x, y ) , &currentMouseWindow ) ;
2295 }
2296
2297 if ( currentMouseWindow != wxWindow::s_lastMouseWindow )
2298 {
2299 wxMouseEvent event ;
2300
2301 bool isDown = !(modifiers & btnState) ; // 1 is for up
2302 bool controlDown = modifiers & controlKey ; // for simulating right mouse
2303
2304 event.m_leftDown = isDown && !controlDown;
2305
2306 event.m_middleDown = FALSE;
2307 event.m_rightDown = isDown && controlDown;
2308
2309 event.m_shiftDown = modifiers & shiftKey;
2310 event.m_controlDown = modifiers & controlKey;
2311 event.m_altDown = modifiers & optionKey;
2312 event.m_metaDown = modifiers & cmdKey;
2313
2314 event.m_x = x;
2315 event.m_y = y;
2316 event.SetTimestamp(timestamp);
2317
2318 if ( wxWindow::s_lastMouseWindow )
2319 {
2320 wxMouseEvent eventleave(event);
2321 eventleave.SetEventType( wxEVT_LEAVE_WINDOW );
2322 wxWindow::s_lastMouseWindow->ScreenToClient( &eventleave.m_x, &eventleave.m_y );
2323 eventleave.SetEventObject( wxWindow::s_lastMouseWindow ) ;
2324
2325 #if wxUSE_TOOLTIPS
2326 wxToolTip::RelayEvent( wxWindow::s_lastMouseWindow , eventleave);
2327 #endif // wxUSE_TOOLTIPS
2328 wxWindow::s_lastMouseWindow->GetEventHandler()->ProcessEvent(eventleave);
2329 }
2330 if ( currentMouseWindow )
2331 {
2332 wxMouseEvent evententer(event);
2333 evententer.SetEventType( wxEVT_ENTER_WINDOW );
2334 currentMouseWindow->ScreenToClient( &evententer.m_x, &evententer.m_y );
2335 evententer.SetEventObject( currentMouseWindow ) ;
2336 #if wxUSE_TOOLTIPS
2337 wxToolTip::RelayEvent( currentMouseWindow , evententer);
2338 #endif // wxUSE_TOOLTIPS
2339 currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
2340 }
2341 wxWindow::s_lastMouseWindow = currentMouseWindow ;
2342 }
2343
2344 short windowPart = inNoWindow ;
2345
2346 if ( s_captureWindow )
2347 {
2348 window = (WindowRef) s_captureWindow->MacGetRootWindow() ;
2349 windowPart = inContent ;
2350 }
2351 else
2352 {
2353 Point pt= { y , x } ;
2354 windowPart = ::FindWindow(pt , &window);
2355 }
2356
2357 switch (windowPart)
2358 {
2359 case inContent :
2360 {
2361 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
2362 if ( win )
2363 win->MacFireMouseEvent( nullEvent , x , y , modifiers , timestamp ) ;
2364 else
2365 {
2366 if ( wxIsBusy() )
2367 {
2368 }
2369 else
2370 UMAShowArrowCursor();
2371 }
2372 }
2373 break;
2374 default :
2375 {
2376 if ( wxIsBusy() )
2377 {
2378 }
2379 else
2380 UMAShowArrowCursor();
2381 }
2382 break ;
2383 }
2384 }
2385 #endif
2386
2387 void wxApp::MacHandleMenuCommand( wxUint32 id )
2388 {
2389 wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ;
2390 wxFrame* frame = mbar->GetFrame();
2391 wxCHECK_RET( mbar != NULL && frame != NULL, wxT("error in menu item callback") );
2392 if ( frame )
2393 {
2394 frame->ProcessCommand(id);
2395 }
2396 }
2397
2398 #if !TARGET_CARBON
2399 void wxApp::MacHandleMenuSelect( int macMenuId , int macMenuItemNum )
2400 {
2401 if (macMenuId == 0)
2402 return; // no menu item selected
2403
2404 if (macMenuId == kwxMacAppleMenuId && macMenuItemNum > 1)
2405 {
2406 #if ! TARGET_CARBON
2407 Str255 deskAccessoryName ;
2408 GrafPtr savedPort ;
2409
2410 GetMenuItemText(GetMenuHandle(kwxMacAppleMenuId), macMenuItemNum, deskAccessoryName);
2411 GetPort(&savedPort);
2412 OpenDeskAcc(deskAccessoryName);
2413 SetPort(savedPort);
2414 #endif
2415 }
2416 else
2417 {
2418 MenuCommand id ;
2419 GetMenuItemCommandID( GetMenuHandle(macMenuId) , macMenuItemNum , &id ) ;
2420 MacHandleMenuCommand( id ) ;
2421 }
2422 HiliteMenu(0);
2423 }
2424 #endif