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