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