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