]> git.saurik.com Git - wxWidgets.git/blob - src/osx/carbon/app.cpp
Show full screen windows with WS_POPUP style in wxMSW.
[wxWidgets.git] / src / osx / carbon / app.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/app.cpp
3 // Purpose: wxApp
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // Copyright: (c) Stefan Csomor
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 #include "wx/wxprec.h"
12
13 #include "wx/app.h"
14
15 #ifndef WX_PRECOMP
16 #include "wx/intl.h"
17 #include "wx/log.h"
18 #include "wx/utils.h"
19 #include "wx/window.h"
20 #include "wx/frame.h"
21 #include "wx/dc.h"
22 #include "wx/button.h"
23 #include "wx/menu.h"
24 #include "wx/pen.h"
25 #include "wx/brush.h"
26 #include "wx/palette.h"
27 #include "wx/icon.h"
28 #include "wx/cursor.h"
29 #include "wx/dialog.h"
30 #include "wx/msgdlg.h"
31 #include "wx/textctrl.h"
32 #include "wx/memory.h"
33 #include "wx/gdicmn.h"
34 #include "wx/module.h"
35 #endif
36
37 #include "wx/tooltip.h"
38 #include "wx/docview.h"
39 #include "wx/filename.h"
40 #include "wx/link.h"
41 #include "wx/thread.h"
42 #include "wx/evtloop.h"
43
44 #include <string.h>
45
46 // mac
47 #if wxOSX_USE_CARBON
48 #include "wx/osx/uma.h"
49 #else
50 #include "wx/osx/private.h"
51 #endif
52
53 #if defined(WXMAKINGDLL_CORE)
54 # include <mach-o/dyld.h>
55 #endif
56
57 // Keep linker from discarding wxStockGDIMac
58 wxFORCE_LINK_MODULE(gdiobj)
59
60 IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
61 BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
62 EVT_IDLE(wxApp::OnIdle)
63 EVT_END_SESSION(wxApp::OnEndSession)
64 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
65 END_EVENT_TABLE()
66
67
68 // platform specific static variables
69 static const short kwxMacAppleMenuId = 1 ;
70
71 wxWindow* wxApp::s_captureWindow = NULL ;
72 long wxApp::s_lastModifiers = 0 ;
73
74 long wxApp::s_macAboutMenuItemId = wxID_ABOUT ;
75 long wxApp::s_macPreferencesMenuItemId = wxID_PREFERENCES ;
76 long wxApp::s_macExitMenuItemId = wxID_EXIT ;
77 wxString wxApp::s_macHelpMenuTitleName = wxT("&Help") ;
78
79 bool wxApp::sm_isEmbedded = false; // Normally we're not a plugin
80
81 #if wxOSX_USE_CARBON
82
83 //----------------------------------------------------------------------
84 // Core Apple Event Support
85 //----------------------------------------------------------------------
86
87 AEEventHandlerUPP sODocHandler = NULL ;
88 AEEventHandlerUPP sGURLHandler = NULL ;
89 AEEventHandlerUPP sOAppHandler = NULL ;
90 AEEventHandlerUPP sPDocHandler = NULL ;
91 AEEventHandlerUPP sRAppHandler = NULL ;
92 AEEventHandlerUPP sQuitHandler = NULL ;
93
94 pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ;
95 pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ;
96 pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ;
97 pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ;
98 pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ;
99 pascal OSErr AEHandleGURL( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ;
100
101 pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , SRefCon WXUNUSED(refcon) )
102 {
103 return wxTheApp->MacHandleAEODoc( (AppleEvent*) event , reply) ;
104 }
105
106 pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , SRefCon WXUNUSED(refcon) )
107 {
108 return wxTheApp->MacHandleAEOApp( (AppleEvent*) event , reply ) ;
109 }
110
111 pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , SRefCon WXUNUSED(refcon) )
112 {
113 return wxTheApp->MacHandleAEPDoc( (AppleEvent*) event , reply ) ;
114 }
115
116 pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , SRefCon WXUNUSED(refcon) )
117 {
118 return wxTheApp->MacHandleAEQuit( (AppleEvent*) event , reply) ;
119 }
120
121 pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , SRefCon WXUNUSED(refcon) )
122 {
123 return wxTheApp->MacHandleAERApp( (AppleEvent*) event , reply) ;
124 }
125
126 pascal OSErr AEHandleGURL( const AppleEvent *event , AppleEvent *reply , SRefCon WXUNUSED(refcon) )
127 {
128 return wxTheApp->MacHandleAEGURL((WXEVENTREF *)event , reply) ;
129 }
130
131
132 // AEODoc Calls MacOpenFiles with all of the files passed
133
134 short wxApp::MacHandleAEODoc(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply))
135 {
136 AEDescList docList;
137 AEKeyword keywd;
138 DescType returnedType;
139 Size actualSize;
140 long itemsInList;
141 OSErr err;
142 short i;
143
144 err = AEGetParamDesc((AppleEvent *)event, keyDirectObject, typeAEList,&docList);
145 if (err != noErr)
146 return err;
147
148 err = AECountItems(&docList, &itemsInList);
149 if (err != noErr)
150 return err;
151
152 ProcessSerialNumber PSN ;
153 PSN.highLongOfPSN = 0 ;
154 PSN.lowLongOfPSN = kCurrentProcess ;
155 SetFrontProcess( &PSN ) ;
156
157 wxString fName ;
158 FSRef theRef ;
159
160 wxArrayString fileNames;
161 for (i = 1; i <= itemsInList; i++)
162 {
163 err = AEGetNthPtr(
164 &docList, i, typeFSRef, &keywd, &returnedType,
165 (Ptr)&theRef, sizeof(theRef), &actualSize);
166
167 if ( err != noErr)
168 return err;
169
170 fName = wxMacFSRefToPath( &theRef ) ;
171
172 fileNames.Add(fName);
173 }
174
175 MacOpenFiles(fileNames);
176
177 return noErr;
178 }
179
180 // AEODoc Calls MacOpenURL on the url passed
181
182 short wxApp::MacHandleAEGURL(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply))
183 {
184 DescType returnedType;
185 Size actualSize;
186 char url[255];
187 OSErr err = AEGetParamPtr((AppleEvent *)event, keyDirectObject, typeChar,
188 &returnedType, url, sizeof(url)-1,
189 &actualSize);
190 if (err != noErr)
191 return err;
192
193 url[actualSize] = '\0'; // Terminate the C string
194
195 ProcessSerialNumber PSN ;
196 PSN.highLongOfPSN = 0 ;
197 PSN.lowLongOfPSN = kCurrentProcess ;
198 SetFrontProcess( &PSN ) ;
199
200 MacOpenURL(wxString(url, wxConvUTF8));
201
202 return noErr;
203 }
204
205 // AEPDoc Calls MacPrintFile on each of the files passed
206
207 short wxApp::MacHandleAEPDoc(const WXEVENTREF event , WXEVENTREF WXUNUSED(reply))
208 {
209 AEDescList docList;
210 AEKeyword keywd;
211 DescType returnedType;
212 Size actualSize;
213 long itemsInList;
214 OSErr err;
215 short i;
216
217 err = AEGetParamDesc((AppleEvent *)event, keyDirectObject, typeAEList,&docList);
218 if (err != noErr)
219 return err;
220
221 err = AECountItems(&docList, &itemsInList);
222 if (err != noErr)
223 return err;
224
225 ProcessSerialNumber PSN ;
226 PSN.highLongOfPSN = 0 ;
227 PSN.lowLongOfPSN = kCurrentProcess ;
228 SetFrontProcess( &PSN ) ;
229
230 wxString fName ;
231 FSRef theRef ;
232
233 for (i = 1; i <= itemsInList; i++)
234 {
235 err = AEGetNthPtr(
236 &docList, i, typeFSRef, &keywd, &returnedType,
237 (Ptr)&theRef, sizeof(theRef), &actualSize);
238
239 if ( err != noErr)
240 return err;
241
242 fName = wxMacFSRefToPath( &theRef ) ;
243
244 MacPrintFile(fName);
245 }
246
247 return noErr;
248 }
249
250 // AEOApp calls MacNewFile
251
252 short wxApp::MacHandleAEOApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
253 {
254 MacNewFile() ;
255 return noErr ;
256 }
257
258 // AEQuit attempts to quit the application
259
260 short wxApp::MacHandleAEQuit(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
261 {
262 wxCloseEvent event;
263 wxTheApp->OnQueryEndSession(event);
264 if ( !event.GetVeto() )
265 {
266 wxCloseEvent event;
267 wxTheApp->OnEndSession(event);
268 }
269 return noErr ;
270 }
271
272 // AEROApp calls MacReopenApp
273
274 short wxApp::MacHandleAERApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
275 {
276 MacReopenApp() ;
277
278 return noErr ;
279 }
280
281 #endif
282
283 //----------------------------------------------------------------------
284 // Support Routines linking the Mac...File Calls to the Document Manager
285 //----------------------------------------------------------------------
286
287 void wxApp::MacOpenFiles(const wxArrayString & fileNames )
288 {
289 size_t i;
290 const size_t fileCount = fileNames.GetCount();
291 for (i = 0; i < fileCount; i++)
292 {
293 MacOpenFile(fileNames[i]);
294 }
295 }
296
297 void wxApp::MacOpenFile(const wxString & fileName )
298 {
299 #if wxUSE_DOC_VIEW_ARCHITECTURE
300 wxDocManager* dm = wxDocManager::GetDocumentManager() ;
301 if ( dm )
302 dm->CreateDocument(fileName , wxDOC_SILENT ) ;
303 #endif
304 }
305
306 void wxApp::MacOpenURL(const wxString & WXUNUSED(url) )
307 {
308 }
309
310 void wxApp::MacPrintFile(const wxString & fileName )
311 {
312 #if wxUSE_DOC_VIEW_ARCHITECTURE
313
314 #if wxUSE_PRINTING_ARCHITECTURE
315 wxDocManager* dm = wxDocManager::GetDocumentManager() ;
316 if ( dm )
317 {
318 wxDocument *doc = dm->CreateDocument(fileName , wxDOC_SILENT ) ;
319 if ( doc )
320 {
321 wxView* view = doc->GetFirstView() ;
322 if ( view )
323 {
324 wxPrintout *printout = view->OnCreatePrintout();
325 if (printout)
326 {
327 wxPrinter printer;
328 printer.Print(view->GetFrame(), printout, true);
329 delete printout;
330 }
331 }
332
333 if (doc->Close())
334 {
335 doc->DeleteAllViews();
336 dm->RemoveDocument(doc) ;
337 }
338 }
339 }
340 #endif //print
341
342 #endif //docview
343 }
344
345
346
347 void wxApp::MacNewFile()
348 {
349 }
350
351 void wxApp::MacReopenApp()
352 {
353 // HIG says :
354 // if there is no open window -> create a new one
355 // if all windows are hidden -> show the first
356 // if some windows are not hidden -> do nothing
357
358 wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst();
359 if ( !node )
360 {
361 MacNewFile() ;
362 }
363 else
364 {
365 wxTopLevelWindow* firstIconized = NULL ;
366 wxTopLevelWindow* firstHidden = NULL ;
367 while (node)
368 {
369 wxTopLevelWindow* win = (wxTopLevelWindow*) node->GetData();
370 if ( !win->IsShown() )
371 {
372 // make sure we don't show 'virtual toplevel windows' like wxTaskBarIconWindow
373 if ( firstHidden == NULL && ( wxDynamicCast( win, wxFrame ) || wxDynamicCast( win, wxDialog ) ) )
374 firstHidden = win ;
375 }
376 else if ( win->IsIconized() )
377 {
378 if ( firstIconized == NULL )
379 firstIconized = win ;
380 }
381 else
382 {
383 // we do have a visible, non-iconized toplevelwindow -> do nothing
384 return;
385 }
386
387 node = node->GetNext();
388 }
389
390 if ( firstIconized )
391 firstIconized->Iconize( false ) ;
392
393 // showing hidden windows is not really always a good solution, also non-modal dialogs when closed end up
394 // as hidden tlws, we don't want to reshow those, so let's just reopen the minimized a.k.a. iconized tlws
395 // unless we find a regression ...
396 #if 0
397 else if ( firstHidden )
398 firstHidden->Show( true );
399 #endif
400 }
401 }
402
403 #if wxOSX_USE_COCOA_OR_IPHONE
404 void wxApp::OSXOnWillFinishLaunching()
405 {
406 #if wxOSX_USE_IPHONE
407 m_onInitResult = OnInit();
408 #endif
409 }
410
411 void wxApp::OSXOnDidFinishLaunching()
412 {
413 }
414
415 void wxApp::OSXOnWillTerminate()
416 {
417 wxCloseEvent event;
418 event.SetCanVeto(false);
419 wxTheApp->OnEndSession(event);
420 }
421
422 bool wxApp::OSXOnShouldTerminate()
423 {
424 wxCloseEvent event;
425 wxTheApp->OnQueryEndSession(event);
426 return !event.GetVeto();
427 }
428 #endif
429
430 //----------------------------------------------------------------------
431 // Macintosh CommandID support - converting between native and wx IDs
432 //----------------------------------------------------------------------
433
434 // if no native match they just return the passed-in id
435
436 #if wxOSX_USE_CARBON
437
438 struct IdPair
439 {
440 UInt32 macId ;
441 int wxId ;
442 } ;
443
444 IdPair gCommandIds [] =
445 {
446 { kHICommandCut , wxID_CUT } ,
447 { kHICommandCopy , wxID_COPY } ,
448 { kHICommandPaste , wxID_PASTE } ,
449 { kHICommandSelectAll , wxID_SELECTALL } ,
450 { kHICommandClear , wxID_CLEAR } ,
451 { kHICommandUndo , wxID_UNDO } ,
452 { kHICommandRedo , wxID_REDO } ,
453 } ;
454
455 int wxMacCommandToId( UInt32 macCommandId )
456 {
457 int wxid = 0 ;
458
459 switch ( macCommandId )
460 {
461 case kHICommandPreferences :
462 wxid = wxApp::s_macPreferencesMenuItemId ;
463 break ;
464
465 case kHICommandQuit :
466 wxid = wxApp::s_macExitMenuItemId ;
467 break ;
468
469 case kHICommandAbout :
470 wxid = wxApp::s_macAboutMenuItemId ;
471 break ;
472
473 default :
474 {
475 for ( size_t i = 0 ; i < WXSIZEOF(gCommandIds) ; ++i )
476 {
477 if ( gCommandIds[i].macId == macCommandId )
478 {
479 wxid = gCommandIds[i].wxId ;
480 break ;
481 }
482 }
483 }
484 break ;
485 }
486
487 if ( wxid == 0 )
488 wxid = (int) macCommandId ;
489
490 return wxid ;
491 }
492
493 UInt32 wxIdToMacCommand( int wxId )
494 {
495 UInt32 macId = 0 ;
496
497 if ( wxId == wxApp::s_macPreferencesMenuItemId )
498 macId = kHICommandPreferences ;
499 else if (wxId == wxApp::s_macExitMenuItemId)
500 macId = kHICommandQuit ;
501 else if (wxId == wxApp::s_macAboutMenuItemId)
502 macId = kHICommandAbout ;
503 else
504 {
505 for ( size_t i = 0 ; i < WXSIZEOF(gCommandIds) ; ++i )
506 {
507 if ( gCommandIds[i].wxId == wxId )
508 {
509 macId = gCommandIds[i].macId ;
510 break ;
511 }
512 }
513 }
514
515 if ( macId == 0 )
516 macId = (int) wxId ;
517
518 return macId ;
519 }
520
521 wxMenu* wxFindMenuFromMacCommand( const HICommand &command , wxMenuItem* &item )
522 {
523 wxMenu* itemMenu = NULL ;
524 #ifndef __WXUNIVERSAL__
525 int id = 0 ;
526
527 // for 'standard' commands which don't have a wx-menu
528 if ( command.commandID == kHICommandPreferences || command.commandID == kHICommandQuit || command.commandID == kHICommandAbout )
529 {
530 id = wxMacCommandToId( command.commandID ) ;
531
532 wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ;
533 if ( mbar )
534 item = mbar->FindItem( id , &itemMenu ) ;
535 }
536 else if ( command.commandID != 0 && command.menu.menuRef != 0 && command.menu.menuItemIndex != 0 )
537 {
538 id = wxMacCommandToId( command.commandID ) ;
539 // make sure it is one of our own menus, or of the 'synthetic' apple and help menus , otherwise don't touch
540 MenuItemIndex firstUserHelpMenuItem ;
541 static MenuHandle helpMenuHandle = NULL ;
542 if ( helpMenuHandle == NULL )
543 {
544 if ( UMAGetHelpMenuDontCreate( &helpMenuHandle , &firstUserHelpMenuItem) != noErr )
545 helpMenuHandle = NULL ;
546 }
547
548 // is it part of the application or the Help menu, then look for the id directly
549 if ( ( GetMenuHandle( kwxMacAppleMenuId ) != NULL && command.menu.menuRef == GetMenuHandle( kwxMacAppleMenuId ) ) ||
550 ( helpMenuHandle != NULL && command.menu.menuRef == helpMenuHandle ) ||
551 wxMenuBar::MacGetWindowMenuHMenu() != NULL && command.menu.menuRef == wxMenuBar::MacGetWindowMenuHMenu() )
552 {
553 wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ;
554 if ( mbar )
555 item = mbar->FindItem( id , &itemMenu ) ;
556 }
557 else
558 {
559 URefCon refCon = 0 ;
560
561 GetMenuItemRefCon( command.menu.menuRef , command.menu.menuItemIndex , &refCon ) ;
562 itemMenu = wxFindMenuFromMacMenu( command.menu.menuRef ) ;
563 if ( itemMenu != NULL && refCon != 0)
564 item = (wxMenuItem*) refCon;
565 }
566 }
567 #endif
568 return itemMenu ;
569 }
570
571 #endif
572
573 //----------------------------------------------------------------------
574 // Carbon Event Handler
575 //----------------------------------------------------------------------
576
577 #if wxOSX_USE_CARBON
578
579 static const EventTypeSpec eventList[] =
580 {
581 { kEventClassCommand, kEventProcessCommand } ,
582 { kEventClassCommand, kEventCommandUpdateStatus } ,
583
584 { kEventClassMenu, kEventMenuOpening },
585 { kEventClassMenu, kEventMenuClosed },
586 { kEventClassMenu, kEventMenuTargetItem },
587
588 { kEventClassApplication , kEventAppActivated } ,
589 { kEventClassApplication , kEventAppDeactivated } ,
590 // handling the quit event is not recommended by apple
591 // rather using the quit apple event - which we do
592
593 { kEventClassAppleEvent , kEventAppleEvent } ,
594
595 { kEventClassMouse , kEventMouseDown } ,
596 { kEventClassMouse , kEventMouseMoved } ,
597 { kEventClassMouse , kEventMouseUp } ,
598 { kEventClassMouse , kEventMouseDragged } ,
599 { 'WXMC' , 'WXMC' }
600 } ;
601
602 static pascal OSStatus
603 wxMacAppMenuEventHandler( EventHandlerCallRef WXUNUSED(handler),
604 EventRef event,
605 void *WXUNUSED(data) )
606 {
607 wxMacCarbonEvent cEvent( event ) ;
608 MenuRef menuRef = cEvent.GetParameter<MenuRef>(kEventParamDirectObject) ;
609 #ifndef __WXUNIVERSAL__
610 wxMenu* menu = wxFindMenuFromMacMenu( menuRef ) ;
611
612 if ( menu )
613 {
614 switch (GetEventKind(event))
615 {
616 case kEventMenuOpening:
617 menu->HandleMenuOpened();
618 break;
619
620 case kEventMenuClosed:
621 menu->HandleMenuClosed();
622 break;
623
624 case kEventMenuTargetItem:
625 {
626 HICommand command ;
627
628 command.menu.menuRef = menuRef;
629 command.menu.menuItemIndex = cEvent.GetParameter<MenuItemIndex>(kEventParamMenuItemIndex,typeMenuItemIndex) ;
630 command.commandID = cEvent.GetParameter<MenuCommand>(kEventParamMenuCommand,typeMenuCommand) ;
631 if (command.commandID != 0)
632 {
633 wxMenuItem* item = NULL ;
634 wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ;
635 if ( itemMenu && item )
636 itemMenu->HandleMenuItemHighlighted( item );
637 }
638 }
639 break;
640
641 default:
642 wxFAIL_MSG(wxT("Unexpected menu event kind"));
643 break;
644 }
645
646 }
647 #endif
648 return eventNotHandledErr;
649 }
650
651 static pascal OSStatus
652 wxMacAppCommandEventHandler( EventHandlerCallRef WXUNUSED(handler) ,
653 EventRef event ,
654 void *WXUNUSED(data) )
655 {
656 OSStatus result = eventNotHandledErr ;
657
658 HICommand command ;
659
660 wxMacCarbonEvent cEvent( event ) ;
661 cEvent.GetParameter<HICommand>(kEventParamDirectObject,typeHICommand,&command) ;
662
663 wxMenuItem* item = NULL ;
664 wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ;
665
666 if ( item )
667 {
668 wxASSERT( itemMenu != NULL ) ;
669
670 switch ( cEvent.GetKind() )
671 {
672 case kEventProcessCommand :
673 if ( itemMenu->HandleCommandProcess( item ) )
674 result = noErr;
675 break ;
676
677 case kEventCommandUpdateStatus:
678 if ( itemMenu->HandleCommandUpdateStatus( item ) )
679 result = noErr;
680 break ;
681
682 default :
683 break ;
684 }
685 }
686 return result ;
687 }
688
689 static pascal OSStatus
690 wxMacAppApplicationEventHandler( EventHandlerCallRef WXUNUSED(handler) ,
691 EventRef event ,
692 void *WXUNUSED(data) )
693 {
694 OSStatus result = eventNotHandledErr ;
695 switch ( GetEventKind( event ) )
696 {
697 case kEventAppActivated :
698 if ( wxTheApp )
699 wxTheApp->SetActive( true , NULL ) ;
700 result = noErr ;
701 break ;
702
703 case kEventAppDeactivated :
704 if ( wxTheApp )
705 wxTheApp->SetActive( false , NULL ) ;
706 result = noErr ;
707 break ;
708
709 default :
710 break ;
711 }
712
713 return result ;
714 }
715
716 pascal OSStatus wxMacAppEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
717 {
718 EventRef formerEvent = (EventRef) wxTheApp->MacGetCurrentEvent() ;
719 EventHandlerCallRef formerEventHandlerCallRef = (EventHandlerCallRef) wxTheApp->MacGetCurrentEventHandlerCallRef() ;
720 wxTheApp->MacSetCurrentEvent( event , handler ) ;
721
722 OSStatus result = eventNotHandledErr ;
723 switch ( GetEventClass( event ) )
724 {
725 #ifndef __LP64__
726 case kEventClassCommand :
727 result = wxMacAppCommandEventHandler( handler , event , data ) ;
728 break ;
729 #endif
730 case kEventClassApplication :
731 result = wxMacAppApplicationEventHandler( handler , event , data ) ;
732 break ;
733 #ifndef __LP64__
734 case kEventClassMenu :
735 result = wxMacAppMenuEventHandler( handler , event , data ) ;
736 break ;
737
738 case kEventClassMouse :
739 {
740 wxMacCarbonEvent cEvent( event ) ;
741
742 WindowRef window ;
743 Point screenMouseLocation = cEvent.GetParameter<Point>(kEventParamMouseLocation) ;
744 ::FindWindow(screenMouseLocation, &window);
745 // only send this event in case it had not already been sent to a tlw, as we get
746 // double events otherwise (in case event.skip) was called
747 if ( window == NULL )
748 result = wxMacTopLevelMouseEventHandler( handler , event , NULL ) ;
749 }
750 break ;
751 #endif
752 case kEventClassAppleEvent :
753 result = AEProcessEvent(event);
754 break ;
755
756 default :
757 break ;
758 }
759
760 wxTheApp->MacSetCurrentEvent( formerEvent, formerEventHandlerCallRef ) ;
761
762 return result ;
763 }
764
765 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacAppEventHandler )
766 #endif
767
768 #if wxDEBUG_LEVEL && wxOSX_USE_COCOA_OR_CARBON
769
770 pascal static void
771 wxMacAssertOutputHandler(OSType WXUNUSED(componentSignature),
772 UInt32 WXUNUSED(options),
773 const char *assertionString,
774 const char *exceptionLabelString,
775 const char *errorString,
776 const char *fileName,
777 long lineNumber,
778 void *value,
779 ConstStr255Param WXUNUSED(outputMsg))
780 {
781 // flow into assert handling
782 wxString fileNameStr ;
783 wxString assertionStr ;
784 wxString exceptionStr ;
785 wxString errorStr ;
786
787 #if wxUSE_UNICODE
788 fileNameStr = wxString(fileName, wxConvLocal);
789 assertionStr = wxString(assertionString, wxConvLocal);
790 exceptionStr = wxString((exceptionLabelString!=0) ? exceptionLabelString : "", wxConvLocal) ;
791 errorStr = wxString((errorString!=0) ? errorString : "", wxConvLocal) ;
792 #else
793 fileNameStr = fileName;
794 assertionStr = assertionString;
795 exceptionStr = (exceptionLabelString!=0) ? exceptionLabelString : "" ;
796 errorStr = (errorString!=0) ? errorString : "" ;
797 #endif
798
799 #if 1
800 // flow into log
801 wxLogDebug( wxT("AssertMacros: %s %s %s file: %s, line: %ld (value %p)\n"),
802 assertionStr.c_str() ,
803 exceptionStr.c_str() ,
804 errorStr.c_str(),
805 fileNameStr.c_str(), lineNumber ,
806 value ) ;
807 #else
808
809 wxOnAssert(fileNameStr, lineNumber , assertionStr ,
810 wxString::Format( wxT("%s %s value (%p)") , exceptionStr, errorStr , value ) ) ;
811 #endif
812 }
813
814 #endif // wxDEBUG_LEVEL
815
816 bool wxApp::Initialize(int& argc, wxChar **argv)
817 {
818 // Mac-specific
819
820 #if wxDEBUG_LEVEL && wxOSX_USE_COCOA_OR_CARBON
821 InstallDebugAssertOutputHandler( NewDebugAssertOutputHandlerUPP( wxMacAssertOutputHandler ) );
822 #endif
823
824 /*
825 Cocoa supports -Key value options which set the user defaults key "Key"
826 to the value "value" Some of them are very handy for debugging like
827 -NSShowAllViews YES. Cocoa picks these up from the real argv so
828 our removal of them from the wx copy of it does not affect Cocoa's
829 ability to see them.
830
831 We basically just assume that any "-NS" option and its following
832 argument needs to be removed from argv. We hope that user code does
833 not expect to see -NS options and indeed it's probably a safe bet
834 since most user code accepting options is probably using the
835 double-dash GNU-style syntax.
836 */
837 for(int i=1; i < argc; ++i)
838 {
839 static const wxChar *ARG_NS = wxT("-NS");
840 if( wxStrncmp(argv[i], ARG_NS, wxStrlen(ARG_NS)) == 0 )
841 {
842 // Only eat this option if it has an argument
843 if( (i + 1) < argc )
844 {
845 memmove(argv + i, argv + i + 2, (argc-i-1)*sizeof(wxChar*));
846 argc -= 2;
847 // drop back one position so the next run through the loop
848 // reprocesses the argument at our current index.
849 --i;
850 }
851 }
852 }
853
854 if ( !wxAppBase::Initialize(argc, argv) )
855 return false;
856
857 #if wxUSE_INTL
858 wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
859 #endif
860
861 // these might be the startup dirs, set them to the 'usual' dir containing the app bundle
862 wxString startupCwd = wxGetCwd() ;
863 if ( startupCwd == wxT("/") || startupCwd.Right(15) == wxT("/Contents/MacOS") )
864 {
865 CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle() ) ;
866 CFURLRef urlParent = CFURLCreateCopyDeletingLastPathComponent( kCFAllocatorDefault , url ) ;
867 CFRelease( url ) ;
868 CFStringRef path = CFURLCopyFileSystemPath ( urlParent , kCFURLPOSIXPathStyle ) ;
869 CFRelease( urlParent ) ;
870 wxString cwd = wxCFStringRef(path).AsString(wxLocale::GetSystemEncoding());
871 wxSetWorkingDirectory( cwd ) ;
872 }
873
874 return true;
875 }
876
877 #if wxOSX_USE_CARBON
878 bool wxApp::CallOnInit()
879 {
880 wxMacAutoreleasePool autoreleasepool;
881 return OnInit();
882 }
883 #endif
884
885 bool wxApp::OnInitGui()
886 {
887 if ( !wxAppBase::OnInitGui() )
888 return false ;
889
890 if ( !DoInitGui() )
891 return false;
892
893 return true ;
894 }
895
896 bool wxApp::ProcessIdle()
897 {
898 wxMacAutoreleasePool autoreleasepool;
899 return wxAppBase::ProcessIdle();
900 }
901
902 int wxApp::OnRun()
903 {
904 wxMacAutoreleasePool pool;
905 return wxAppBase::OnRun();
906 }
907
908 #if wxOSX_USE_CARBON
909 bool wxApp::DoInitGui()
910 {
911 InstallStandardEventHandler( GetApplicationEventTarget() ) ;
912 if (!sm_isEmbedded)
913 {
914 InstallApplicationEventHandler(
915 GetwxMacAppEventHandlerUPP(),
916 GetEventTypeCount(eventList), eventList, wxTheApp, (EventHandlerRef *)&(wxTheApp->m_macEventHandler));
917 }
918
919 if (!sm_isEmbedded)
920 {
921 sODocHandler = NewAEEventHandlerUPP(AEHandleODoc) ;
922 sGURLHandler = NewAEEventHandlerUPP(AEHandleGURL) ;
923 sOAppHandler = NewAEEventHandlerUPP(AEHandleOApp) ;
924 sPDocHandler = NewAEEventHandlerUPP(AEHandlePDoc) ;
925 sRAppHandler = NewAEEventHandlerUPP(AEHandleRApp) ;
926 sQuitHandler = NewAEEventHandlerUPP(AEHandleQuit) ;
927
928 AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
929 sODocHandler , 0 , FALSE ) ;
930 AEInstallEventHandler( kInternetEventClass, kAEGetURL,
931 sGURLHandler , 0 , FALSE ) ;
932 AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
933 sOAppHandler , 0 , FALSE ) ;
934 AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
935 sPDocHandler , 0 , FALSE ) ;
936 AEInstallEventHandler( kCoreEventClass , kAEReopenApplication ,
937 sRAppHandler , 0 , FALSE ) ;
938 AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
939 sQuitHandler , 0 , FALSE ) ;
940 }
941
942 if ( !wxMacInitCocoa() )
943 return false;
944
945 return true;
946 }
947
948 void wxApp::DoCleanUp()
949 {
950 if (!sm_isEmbedded)
951 RemoveEventHandler( (EventHandlerRef)(wxTheApp->m_macEventHandler) );
952
953 if (!sm_isEmbedded)
954 {
955 AERemoveEventHandler( kCoreEventClass , kAEOpenDocuments ,
956 sODocHandler , FALSE ) ;
957 AERemoveEventHandler( kInternetEventClass, kAEGetURL,
958 sGURLHandler , FALSE ) ;
959 AERemoveEventHandler( kCoreEventClass , kAEOpenApplication ,
960 sOAppHandler , FALSE ) ;
961 AERemoveEventHandler( kCoreEventClass , kAEPrintDocuments ,
962 sPDocHandler , FALSE ) ;
963 AERemoveEventHandler( kCoreEventClass , kAEReopenApplication ,
964 sRAppHandler , FALSE ) ;
965 AERemoveEventHandler( kCoreEventClass , kAEQuitApplication ,
966 sQuitHandler , FALSE ) ;
967
968 DisposeAEEventHandlerUPP( sODocHandler ) ;
969 DisposeAEEventHandlerUPP( sGURLHandler ) ;
970 DisposeAEEventHandlerUPP( sOAppHandler ) ;
971 DisposeAEEventHandlerUPP( sPDocHandler ) ;
972 DisposeAEEventHandlerUPP( sRAppHandler ) ;
973 DisposeAEEventHandlerUPP( sQuitHandler ) ;
974 }
975 }
976
977 #endif
978
979 void wxApp::CleanUp()
980 {
981 wxMacAutoreleasePool autoreleasepool;
982 #if wxUSE_TOOLTIPS
983 wxToolTip::RemoveToolTips() ;
984 #endif
985
986 DoCleanUp();
987
988 wxAppBase::CleanUp();
989 }
990
991 //----------------------------------------------------------------------
992 // misc initialization stuff
993 //----------------------------------------------------------------------
994
995 wxApp::wxApp()
996 {
997 m_printMode = wxPRINT_WINDOWS;
998
999 m_macCurrentEvent = NULL ;
1000 m_macCurrentEventHandlerCallRef = NULL ;
1001 m_macPool = new wxMacAutoreleasePool();
1002 }
1003
1004 wxApp::~wxApp()
1005 {
1006 if (m_macPool)
1007 delete m_macPool;
1008 }
1009
1010 CFMutableArrayRef GetAutoReleaseArray()
1011 {
1012 static CFMutableArrayRef array = 0;
1013 if ( array == 0)
1014 array= CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks);
1015 return array;
1016 }
1017
1018 void wxApp::MacAddToAutorelease( void* cfrefobj )
1019 {
1020 CFArrayAppendValue( GetAutoReleaseArray(), cfrefobj );
1021 }
1022
1023 void wxApp::MacReleaseAutoreleasePool()
1024 {
1025 if (m_macPool)
1026 delete m_macPool;
1027 m_macPool = new wxMacAutoreleasePool();
1028 }
1029
1030 void wxApp::OnIdle(wxIdleEvent& WXUNUSED(event))
1031 {
1032 // If they are pending events, we must process them: pending events are
1033 // either events to the threads other than main or events posted with
1034 // wxPostEvent() functions
1035 #ifndef __WXUNIVERSAL__
1036 #if wxUSE_MENUS
1037 if (!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar())
1038 wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar();
1039 #endif
1040 #endif
1041 CFArrayRemoveAllValues( GetAutoReleaseArray() );
1042 }
1043
1044 void wxApp::WakeUpIdle()
1045 {
1046 wxEventLoopBase * const loop = wxEventLoopBase::GetActive();
1047
1048 if ( loop )
1049 loop->WakeUp();
1050 }
1051
1052 void wxApp::OnEndSession(wxCloseEvent& WXUNUSED(event))
1053 {
1054 if (GetTopWindow())
1055 GetTopWindow()->Close(true);
1056 }
1057
1058 // Default behaviour: close the application with prompts. The
1059 // user can veto the close, and therefore the end session.
1060 void wxApp::OnQueryEndSession(wxCloseEvent& event)
1061 {
1062 if ( !wxDialog::OSXHasModalDialogsOpen() )
1063 {
1064 if (GetTopWindow())
1065 {
1066 if (!GetTopWindow()->Close(!event.CanVeto()))
1067 event.Veto(true);
1068 }
1069 }
1070 else
1071 {
1072 event.Veto(true);
1073 }
1074 }
1075
1076 extern "C" void wxCYield() ;
1077 void wxCYield()
1078 {
1079 wxYield() ;
1080 }
1081
1082 // virtual
1083 void wxApp::MacHandleUnhandledEvent( WXEVENTREF WXUNUSED(evr) )
1084 {
1085 // Override to process unhandled events as you please
1086 }
1087
1088 #if wxOSX_USE_COCOA_OR_CARBON
1089
1090 CGKeyCode wxCharCodeWXToOSX(wxKeyCode code)
1091 {
1092 CGKeyCode keycode;
1093
1094 switch (code)
1095 {
1096 // Clang warns about switch values not of the same type as (enumerated)
1097 // switch controlling expression. This is generally useful but here we
1098 // really want to be able to use letters and digits without making them
1099 // part of wxKeyCode enum.
1100 #ifdef __clang__
1101 #pragma clang diagnostic push
1102 #pragma clang diagnostic ignored "-Wswitch"
1103 #endif // __clang__
1104
1105 case 'a': case 'A': keycode = kVK_ANSI_A; break;
1106 case 'b': case 'B': keycode = kVK_ANSI_B; break;
1107 case 'c': case 'C': keycode = kVK_ANSI_C; break;
1108 case 'd': case 'D': keycode = kVK_ANSI_D; break;
1109 case 'e': case 'E': keycode = kVK_ANSI_E; break;
1110 case 'f': case 'F': keycode = kVK_ANSI_F; break;
1111 case 'g': case 'G': keycode = kVK_ANSI_G; break;
1112 case 'h': case 'H': keycode = kVK_ANSI_H; break;
1113 case 'i': case 'I': keycode = kVK_ANSI_I; break;
1114 case 'j': case 'J': keycode = kVK_ANSI_J; break;
1115 case 'k': case 'K': keycode = kVK_ANSI_K; break;
1116 case 'l': case 'L': keycode = kVK_ANSI_L; break;
1117 case 'm': case 'M': keycode = kVK_ANSI_M; break;
1118 case 'n': case 'N': keycode = kVK_ANSI_N; break;
1119 case 'o': case 'O': keycode = kVK_ANSI_O; break;
1120 case 'p': case 'P': keycode = kVK_ANSI_P; break;
1121 case 'q': case 'Q': keycode = kVK_ANSI_Q; break;
1122 case 'r': case 'R': keycode = kVK_ANSI_R; break;
1123 case 's': case 'S': keycode = kVK_ANSI_S; break;
1124 case 't': case 'T': keycode = kVK_ANSI_T; break;
1125 case 'u': case 'U': keycode = kVK_ANSI_U; break;
1126 case 'v': case 'V': keycode = kVK_ANSI_V; break;
1127 case 'w': case 'W': keycode = kVK_ANSI_W; break;
1128 case 'x': case 'X': keycode = kVK_ANSI_X; break;
1129 case 'y': case 'Y': keycode = kVK_ANSI_Y; break;
1130 case 'z': case 'Z': keycode = kVK_ANSI_Z; break;
1131
1132 case '0': keycode = kVK_ANSI_0; break;
1133 case '1': keycode = kVK_ANSI_1; break;
1134 case '2': keycode = kVK_ANSI_2; break;
1135 case '3': keycode = kVK_ANSI_3; break;
1136 case '4': keycode = kVK_ANSI_4; break;
1137 case '5': keycode = kVK_ANSI_5; break;
1138 case '6': keycode = kVK_ANSI_6; break;
1139 case '7': keycode = kVK_ANSI_7; break;
1140 case '8': keycode = kVK_ANSI_8; break;
1141 case '9': keycode = kVK_ANSI_9; break;
1142
1143 #ifdef __clang__
1144 #pragma clang diagnostic pop
1145 #endif // __clang__
1146
1147 case WXK_BACK: keycode = kVK_Delete; break;
1148 case WXK_TAB: keycode = kVK_Tab; break;
1149 case WXK_RETURN: keycode = kVK_Return; break;
1150 case WXK_ESCAPE: keycode = kVK_Escape; break;
1151 case WXK_SPACE: keycode = kVK_Space; break;
1152 case WXK_DELETE: keycode = kVK_ForwardDelete; break;
1153
1154 case WXK_SHIFT: keycode = kVK_Shift; break;
1155 case WXK_ALT: keycode = kVK_Option; break;
1156 case WXK_RAW_CONTROL: keycode = kVK_Control; break;
1157 case WXK_CONTROL: keycode = kVK_Command; break;
1158
1159 case WXK_CAPITAL: keycode = kVK_CapsLock; break;
1160 case WXK_END: keycode = kVK_End; break;
1161 case WXK_HOME: keycode = kVK_Home; break;
1162 case WXK_LEFT: keycode = kVK_LeftArrow; break;
1163 case WXK_UP: keycode = kVK_UpArrow; break;
1164 case WXK_RIGHT: keycode = kVK_RightArrow; break;
1165 case WXK_DOWN: keycode = kVK_DownArrow; break;
1166
1167 case WXK_HELP: keycode = kVK_Help; break;
1168
1169
1170 case WXK_NUMPAD0: keycode = kVK_ANSI_Keypad0; break;
1171 case WXK_NUMPAD1: keycode = kVK_ANSI_Keypad1; break;
1172 case WXK_NUMPAD2: keycode = kVK_ANSI_Keypad2; break;
1173 case WXK_NUMPAD3: keycode = kVK_ANSI_Keypad3; break;
1174 case WXK_NUMPAD4: keycode = kVK_ANSI_Keypad4; break;
1175 case WXK_NUMPAD5: keycode = kVK_ANSI_Keypad5; break;
1176 case WXK_NUMPAD6: keycode = kVK_ANSI_Keypad6; break;
1177 case WXK_NUMPAD7: keycode = kVK_ANSI_Keypad7; break;
1178 case WXK_NUMPAD8: keycode = kVK_ANSI_Keypad8; break;
1179 case WXK_NUMPAD9: keycode = kVK_ANSI_Keypad9; break;
1180 case WXK_F1: keycode = kVK_F1; break;
1181 case WXK_F2: keycode = kVK_F2; break;
1182 case WXK_F3: keycode = kVK_F3; break;
1183 case WXK_F4: keycode = kVK_F4; break;
1184 case WXK_F5: keycode = kVK_F5; break;
1185 case WXK_F6: keycode = kVK_F6; break;
1186 case WXK_F7: keycode = kVK_F7; break;
1187 case WXK_F8: keycode = kVK_F8; break;
1188 case WXK_F9: keycode = kVK_F9; break;
1189 case WXK_F10: keycode = kVK_F10; break;
1190 case WXK_F11: keycode = kVK_F11; break;
1191 case WXK_F12: keycode = kVK_F12; break;
1192 case WXK_F13: keycode = kVK_F13; break;
1193 case WXK_F14: keycode = kVK_F14; break;
1194 case WXK_F15: keycode = kVK_F15; break;
1195 case WXK_F16: keycode = kVK_F16; break;
1196 case WXK_F17: keycode = kVK_F17; break;
1197 case WXK_F18: keycode = kVK_F18; break;
1198 case WXK_F19: keycode = kVK_F19; break;
1199 case WXK_F20: keycode = kVK_F20; break;
1200
1201 case WXK_PAGEUP: keycode = kVK_PageUp; break;
1202 case WXK_PAGEDOWN: keycode = kVK_PageDown; break;
1203
1204 case WXK_NUMPAD_DELETE: keycode = kVK_ANSI_KeypadClear; break;
1205 case WXK_NUMPAD_EQUAL: keycode = kVK_ANSI_KeypadEquals; break;
1206 case WXK_NUMPAD_MULTIPLY: keycode = kVK_ANSI_KeypadMultiply; break;
1207 case WXK_NUMPAD_ADD: keycode = kVK_ANSI_KeypadPlus; break;
1208 case WXK_NUMPAD_SUBTRACT: keycode = kVK_ANSI_KeypadMinus; break;
1209 case WXK_NUMPAD_DECIMAL: keycode = kVK_ANSI_KeypadDecimal; break;
1210 case WXK_NUMPAD_DIVIDE: keycode = kVK_ANSI_KeypadDivide; break;
1211
1212 default:
1213 wxLogDebug( "Unrecognised keycode %d", code );
1214 keycode = static_cast<CGKeyCode>(-1);
1215 }
1216
1217 return keycode;
1218 }
1219
1220 long wxMacTranslateKey(unsigned char key, unsigned char code)
1221 {
1222 long retval = key ;
1223 switch (key)
1224 {
1225 case kHomeCharCode :
1226 retval = WXK_HOME;
1227 break;
1228
1229 case kEnterCharCode :
1230 retval = WXK_RETURN;
1231 break;
1232 case kEndCharCode :
1233 retval = WXK_END;
1234 break;
1235
1236 case kHelpCharCode :
1237 retval = WXK_HELP;
1238 break;
1239
1240 case kBackspaceCharCode :
1241 retval = WXK_BACK;
1242 break;
1243
1244 case kTabCharCode :
1245 retval = WXK_TAB;
1246 break;
1247
1248 case kPageUpCharCode :
1249 retval = WXK_PAGEUP;
1250 break;
1251
1252 case kPageDownCharCode :
1253 retval = WXK_PAGEDOWN;
1254 break;
1255
1256 case kReturnCharCode :
1257 retval = WXK_RETURN;
1258 break;
1259
1260 case kFunctionKeyCharCode :
1261 {
1262 switch ( code )
1263 {
1264 case 0x7a :
1265 retval = WXK_F1 ;
1266 break;
1267
1268 case 0x78 :
1269 retval = WXK_F2 ;
1270 break;
1271
1272 case 0x63 :
1273 retval = WXK_F3 ;
1274 break;
1275
1276 case 0x76 :
1277 retval = WXK_F4 ;
1278 break;
1279
1280 case 0x60 :
1281 retval = WXK_F5 ;
1282 break;
1283
1284 case 0x61 :
1285 retval = WXK_F6 ;
1286 break;
1287
1288 case 0x62:
1289 retval = WXK_F7 ;
1290 break;
1291
1292 case 0x64 :
1293 retval = WXK_F8 ;
1294 break;
1295
1296 case 0x65 :
1297 retval = WXK_F9 ;
1298 break;
1299
1300 case 0x6D :
1301 retval = WXK_F10 ;
1302 break;
1303
1304 case 0x67 :
1305 retval = WXK_F11 ;
1306 break;
1307
1308 case 0x6F :
1309 retval = WXK_F12 ;
1310 break;
1311
1312 case 0x69 :
1313 retval = WXK_F13 ;
1314 break;
1315
1316 case 0x6B :
1317 retval = WXK_F14 ;
1318 break;
1319
1320 case 0x71 :
1321 retval = WXK_F15 ;
1322 break;
1323
1324 default:
1325 break;
1326 }
1327 }
1328 break ;
1329
1330 case kEscapeCharCode :
1331 retval = WXK_ESCAPE ;
1332 break ;
1333
1334 case kLeftArrowCharCode :
1335 retval = WXK_LEFT ;
1336 break ;
1337
1338 case kRightArrowCharCode :
1339 retval = WXK_RIGHT ;
1340 break ;
1341
1342 case kUpArrowCharCode :
1343 retval = WXK_UP ;
1344 break ;
1345
1346 case kDownArrowCharCode :
1347 retval = WXK_DOWN ;
1348 break ;
1349
1350 case kDeleteCharCode :
1351 retval = WXK_DELETE ;
1352 break ;
1353
1354 default:
1355 break ;
1356 } // end switch
1357
1358 return retval;
1359 }
1360
1361 int wxMacKeyCodeToModifier(wxKeyCode key)
1362 {
1363 switch (key)
1364 {
1365 case WXK_START:
1366 case WXK_MENU:
1367 case WXK_COMMAND:
1368 return cmdKey;
1369
1370 case WXK_SHIFT:
1371 return shiftKey;
1372
1373 case WXK_CAPITAL:
1374 return alphaLock;
1375
1376 case WXK_ALT:
1377 return optionKey;
1378
1379 case WXK_RAW_CONTROL:
1380 return controlKey;
1381
1382 default:
1383 return 0;
1384 }
1385 }
1386 #endif
1387
1388 #if wxOSX_USE_COCOA && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
1389
1390 // defined in utils.mm
1391
1392 #elif wxOSX_USE_COCOA_OR_CARBON
1393
1394 wxMouseState wxGetMouseState()
1395 {
1396 wxMouseState ms;
1397
1398 wxPoint pt = wxGetMousePosition();
1399 ms.SetX(pt.x);
1400 ms.SetY(pt.y);
1401
1402 UInt32 buttons = GetCurrentButtonState();
1403 ms.SetLeftDown( (buttons & 0x01) != 0 );
1404 ms.SetMiddleDown( (buttons & 0x04) != 0 );
1405 ms.SetRightDown( (buttons & 0x02) != 0 );
1406
1407 UInt32 modifiers = GetCurrentKeyModifiers();
1408 ms.SetRawControlDown(modifiers & controlKey);
1409 ms.SetShiftDown(modifiers & shiftKey);
1410 ms.SetAltDown(modifiers & optionKey);
1411 ms.SetControlDown(modifiers & cmdKey);
1412
1413 return ms;
1414 }
1415
1416 #endif
1417
1418 // TODO : once the new key/char handling is tested, move all the code to wxWindow
1419
1420 bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , wxChar uniChar )
1421 {
1422 if ( !focus )
1423 return false ;
1424
1425 wxKeyEvent event(wxEVT_KEY_DOWN) ;
1426 MacCreateKeyEvent( event, focus , keymessage , modifiers , when , uniChar ) ;
1427
1428 return focus->OSXHandleKeyEvent(event);
1429 }
1430
1431 bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , wxChar uniChar )
1432 {
1433 if ( !focus )
1434 return false ;
1435
1436 wxKeyEvent event( wxEVT_KEY_UP ) ;
1437 MacCreateKeyEvent( event, focus , keymessage , modifiers , when , uniChar ) ;
1438
1439 return focus->OSXHandleKeyEvent(event) ;
1440 }
1441
1442 bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers , long when , wxChar uniChar )
1443 {
1444 if ( !focus )
1445 return false ;
1446 wxKeyEvent event(wxEVT_CHAR) ;
1447 MacCreateKeyEvent( event, focus , keymessage , modifiers , when , uniChar ) ;
1448
1449 bool handled = false ;
1450
1451 #if wxOSX_USE_CARBON
1452 long keyval = event.m_keyCode ;
1453
1454 {
1455 wxKeyEvent eventCharHook(wxEVT_CHAR_HOOK, event);
1456 handled = focus->HandleWindowEvent( eventCharHook );
1457 if ( handled && eventCharHook.IsNextEventAllowed() )
1458 handled = false ;
1459 }
1460
1461 if ( !handled )
1462 {
1463 handled = focus->HandleWindowEvent( event ) ;
1464 }
1465
1466 if ( !handled && (keyval == WXK_TAB) )
1467 {
1468 wxWindow* iter = focus->GetParent() ;
1469 while ( iter && !handled )
1470 {
1471 if ( iter->HasFlag( wxTAB_TRAVERSAL ) )
1472 {
1473 wxNavigationKeyEvent new_event;
1474 new_event.SetEventObject( focus );
1475 new_event.SetDirection( !event.ShiftDown() );
1476 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
1477 new_event.SetWindowChange( event.ControlDown() );
1478 new_event.SetCurrentFocus( focus );
1479 handled = focus->GetParent()->HandleWindowEvent( new_event );
1480 if ( handled && new_event.GetSkipped() )
1481 handled = false ;
1482 }
1483
1484 iter = iter->GetParent() ;
1485 }
1486 }
1487
1488 // backdoor handler for default return and command escape
1489 if ( !handled && (!focus->IsKindOf(CLASSINFO(wxControl) ) || !focus->AcceptsFocus() ) )
1490 {
1491 // if window is not having a focus still testing for default enter or cancel
1492 // TODO: add the UMA version for ActiveNonFloatingWindow
1493 #ifndef __LP64__
1494 wxWindow* focus = wxNonOwnedWindow::GetFromWXWindow( (WXWindow) FrontWindow() ) ;
1495 if ( focus )
1496 {
1497 if ( keyval == WXK_RETURN || keyval == WXK_NUMPAD_ENTER )
1498 {
1499 wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(focus), wxTopLevelWindow);
1500 if ( tlw && tlw->GetDefaultItem() )
1501 {
1502 wxButton *def = wxDynamicCast(tlw->GetDefaultItem(), wxButton);
1503 if ( def && def->IsEnabled() )
1504 {
1505 wxCommandEvent event(wxEVT_BUTTON, def->GetId() );
1506 event.SetEventObject(def);
1507 def->Command(event);
1508
1509 return true ;
1510 }
1511 }
1512 }
1513 else if (keyval == WXK_ESCAPE || (keyval == '.' && modifiers & cmdKey ) )
1514 {
1515 // generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs)
1516 wxCommandEvent new_event(wxEVT_BUTTON,wxID_CANCEL);
1517 new_event.SetEventObject( focus );
1518 handled = focus->HandleWindowEvent( new_event );
1519 }
1520 }
1521 #endif
1522 }
1523 #endif
1524 return handled ;
1525 }
1526
1527 // This method handles common code for SendKeyDown, SendKeyUp, and SendChar events.
1528 void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymessage , long modifiers , long when , wxChar uniChar )
1529 {
1530 #if wxOSX_USE_COCOA_OR_CARBON
1531
1532 short keycode, keychar ;
1533
1534 keychar = short(keymessage & charCodeMask);
1535 keycode = short(keymessage & keyCodeMask) >> 8 ;
1536 if ( !(event.GetEventType() == wxEVT_CHAR) && (modifiers & (controlKey | shiftKey | optionKey) ) )
1537 {
1538 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
1539 // and look at the character after
1540 #ifdef __LP64__
1541 // TODO new implementation using TextInputSources
1542 #else
1543 UInt32 state = 0;
1544 UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey | shiftKey | optionKey))) | keycode, &state);
1545 keychar = short(keyInfo & charCodeMask);
1546 #endif
1547 }
1548
1549 long keyval = wxMacTranslateKey(keychar, keycode) ;
1550 if ( keyval == keychar && ( event.GetEventType() == wxEVT_KEY_UP || event.GetEventType() == wxEVT_KEY_DOWN ) )
1551 keyval = wxToupper( keyval ) ;
1552
1553 // Check for NUMPAD keys. For KEY_UP/DOWN events we need to use the
1554 // WXK_NUMPAD constants, but for the CHAR event we want to use the
1555 // standard ascii values
1556 if ( event.GetEventType() != wxEVT_CHAR )
1557 {
1558 if (keyval >= '0' && keyval <= '9' && keycode >= 82 && keycode <= 92)
1559 {
1560 keyval = (keyval - '0') + WXK_NUMPAD0;
1561 }
1562 else if (keycode >= 65 && keycode <= 81)
1563 {
1564 switch (keycode)
1565 {
1566 case 76 :
1567 keyval = WXK_NUMPAD_ENTER;
1568 break;
1569
1570 case 81:
1571 keyval = WXK_NUMPAD_EQUAL;
1572 break;
1573
1574 case 67:
1575 keyval = WXK_NUMPAD_MULTIPLY;
1576 break;
1577
1578 case 75:
1579 keyval = WXK_NUMPAD_DIVIDE;
1580 break;
1581
1582 case 78:
1583 keyval = WXK_NUMPAD_SUBTRACT;
1584 break;
1585
1586 case 69:
1587 keyval = WXK_NUMPAD_ADD;
1588 break;
1589
1590 case 65:
1591 keyval = WXK_NUMPAD_DECIMAL;
1592 break;
1593 default:
1594 break;
1595 }
1596 }
1597 }
1598
1599 event.m_shiftDown = modifiers & shiftKey;
1600 event.m_rawControlDown = modifiers & controlKey;
1601 event.m_altDown = modifiers & optionKey;
1602 event.m_controlDown = modifiers & cmdKey;
1603 event.m_keyCode = keyval ;
1604 #if wxUSE_UNICODE
1605 event.m_uniChar = uniChar ;
1606 #endif
1607
1608 event.m_rawCode = keymessage;
1609 event.m_rawFlags = modifiers;
1610 event.SetTimestamp(when);
1611 event.SetEventObject(focus);
1612 #else
1613 wxUnusedVar(event);
1614 wxUnusedVar(focus);
1615 wxUnusedVar(keymessage);
1616 wxUnusedVar(modifiers);
1617 wxUnusedVar(when);
1618 wxUnusedVar(uniChar);
1619 #endif
1620 }
1621
1622
1623 void wxApp::MacHideApp()
1624 {
1625 #if wxOSX_USE_CARBON
1626 wxMacCarbonEvent event( kEventClassCommand , kEventCommandProcess );
1627 HICommand command;
1628 memset( &command, 0 , sizeof(command) );
1629 command.commandID = kHICommandHide ;
1630 event.SetParameter<HICommand>(kEventParamDirectObject, command );
1631 SendEventToApplication( event );
1632 #endif
1633 }