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