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