]> git.saurik.com Git - wxWidgets.git/blob - src/mac/app.cpp
corrected warnings when compiling with -Wall -W
[wxWidgets.git] / src / mac / app.cpp
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
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "app.h"
14 #endif
15
16 #include "wx/defs.h"
17
18 #include "wx/window.h"
19 #include "wx/frame.h"
20 #include "wx/button.h"
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"
27 #include "wx/intl.h"
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"
36 #include "wx/tooltip.h"
37 #include "wx/textctrl.h"
38 #include "wx/menu.h"
39 #if wxUSE_WX_RESOURCES
40 # include "wx/resource.h"
41 #endif
42
43 #include <string.h>
44
45 // mac
46
47 #ifndef __DARWIN__
48 #if __option(profile)
49 #include <profiler.h>
50 #endif
51 #endif
52
53 #include "apprsrc.h"
54
55 #include "wx/mac/uma.h"
56 #include "wx/mac/macnotfy.h"
57
58 #ifdef __DARWIN__
59 # include <CoreServices/CoreServices.h>
60 # if defined(WXMAKINGDLL)
61 # include <mach-o/dyld.h>
62 # endif
63 #else
64 # include <Sound.h>
65 # include <Threads.h>
66 # include <ToolUtils.h>
67 # include <DiskInit.h>
68 # include <Devices.h>
69 #endif
70
71 extern char *wxBuffer;
72 extern wxList wxPendingDelete;
73 extern wxList *wxWinMacWindowList;
74 extern wxList *wxWinMacControlList;
75
76 wxApp *wxTheApp = NULL;
77
78 #if !USE_SHARED_LIBRARY
79 IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
80 BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
81 EVT_IDLE(wxApp::OnIdle)
82 EVT_END_SESSION(wxApp::OnEndSession)
83 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
84 END_EVENT_TABLE()
85 #endif
86
87
88 const short kMacMinHeap = (29 * 1024) ;
89 // platform specific static variables
90
91 const short kwxMacMenuBarResource = 1 ;
92 const short kwxMacAppleMenuId = 1 ;
93
94 WXHRGN wxApp::s_macCursorRgn = NULL;
95 wxWindow* wxApp::s_captureWindow = NULL ;
96 int wxApp::s_lastMouseDown = 0 ;
97 long wxApp::sm_lastMessageTime = 0;
98
99 bool wxApp::s_macDefaultEncodingIsPC = true ;
100 bool wxApp::s_macSupportPCMenuShortcuts = true ;
101 long wxApp::s_macAboutMenuItemId = wxID_ABOUT ;
102 wxString wxApp::s_macHelpMenuTitleName = "&Help" ;
103
104 pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
105 pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
106 pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
107 pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
108
109
110 pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long refcon )
111 {
112 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
113 return wxTheApp->MacHandleAEODoc( (AppleEvent*) event , reply) ;
114 }
115
116 pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long refcon )
117 {
118 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
119 return wxTheApp->MacHandleAEOApp( (AppleEvent*) event , reply ) ;
120 }
121
122 pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long refcon )
123 {
124 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
125 return wxTheApp->MacHandleAEPDoc( (AppleEvent*) event , reply ) ;
126 }
127
128 pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long refcon )
129 {
130 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
131 return wxTheApp->MacHandleAEQuit( (AppleEvent*) event , reply) ;
132 }
133
134 short wxApp::MacHandleAEODoc(const WXEVENTREF event , WXEVENTREF reply)
135 {
136 SysBeep(40) ;
137 ProcessSerialNumber PSN ;
138 PSN.highLongOfPSN = 0 ;
139 PSN.lowLongOfPSN = kCurrentProcess ;
140 SetFrontProcess( &PSN ) ;
141 return noErr ;
142 }
143
144 short wxApp::MacHandleAEPDoc(const WXEVENTREF event , WXEVENTREF reply)
145 {
146 return noErr ;
147 }
148
149 short wxApp::MacHandleAEOApp(const WXEVENTREF event , WXEVENTREF reply)
150 {
151 return noErr ;
152 }
153
154 short wxApp::MacHandleAEQuit(const WXEVENTREF event , WXEVENTREF reply)
155 {
156 wxWindow* win = GetTopWindow() ;
157 if ( win )
158 {
159 win->Close(TRUE ) ;
160 }
161 else
162 {
163 ExitMainLoop() ;
164 }
165 return noErr ;
166 }
167
168 char StringMac[] = "\x0d\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
169 "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
170 "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf"
171 "\xb1\xb4\xb5\xb6\xbb\xbc\xbe\xbf"
172 "\xc0\xc1\xc2\xc4\xc7\xc8\xc9\xcb\xcc\xcd\xce\xcf"
173 "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xca\xdb" ;
174
175 char StringANSI[] = "\x0a\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8"
176 "\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC"
177 "\x86\xBA\xA2\xA3\xA7\x95\xB6\xDF\xAE\xA9\x99\xB4\xA8\xC6\xD8"
178 "\xB1\xA5\xB5\xF0\xAA\xBA\xE6\xF8"
179 "\xBF\xA1\xAC\x83\xAB\xBB\x85\xC0\xC3\xD5\x8C\x9C"
180 "\x96\x97\x93\x94\x91\x92\xF7\xFF\xA0\x80" ;
181
182 void wxMacConvertFromPC( const char *from , char *to , int len )
183 {
184 char *c ;
185 if ( from == to )
186 {
187 for( int i = 0 ; i < len ; ++ i )
188 {
189 c = strchr( StringANSI , *from ) ;
190 if ( c != NULL )
191 {
192 *to = StringMac[ c - StringANSI] ;
193 }
194 ++to ;
195 ++from ;
196 }
197 }
198 else
199 {
200 for( int i = 0 ; i < len ; ++ i )
201 {
202 c = strchr( StringANSI , *from ) ;
203 if ( c != NULL )
204 {
205 *to = StringMac[ c - StringANSI] ;
206 }
207 else
208 {
209 *to = *from ;
210 }
211 ++to ;
212 ++from ;
213 }
214 }
215 }
216
217 void wxMacConvertToPC( const char *from , char *to , int len )
218 {
219 char *c ;
220 if ( from == to )
221 {
222 for( int i = 0 ; i < len ; ++ i )
223 {
224 c = strchr( StringMac , *from ) ;
225 if ( c != NULL )
226 {
227 *to = StringANSI[ c - StringMac] ;
228 }
229 ++to ;
230 ++from ;
231 }
232 }
233 else
234 {
235 for( int i = 0 ; i < len ; ++ i )
236 {
237 c = strchr( StringMac , *from ) ;
238 if ( c != NULL )
239 {
240 *to = StringANSI[ c - StringMac] ;
241 }
242 else
243 {
244 *to = *from ;
245 }
246 ++to ;
247 ++from ;
248 }
249 }
250 }
251
252 void wxMacConvertFromPC( char * p )
253 {
254 char *ptr = p ;
255 int len = strlen ( p ) ;
256
257 wxMacConvertFromPC( ptr , ptr , len ) ;
258 }
259
260 void wxMacConvertFromPCForControls( char * p )
261 {
262 char *ptr = p ;
263 int len = strlen ( p ) ;
264
265 wxMacConvertFromPC( ptr , ptr , len ) ;
266 for ( unsigned int i = 0 ; i < strlen ( ptr ) ; i++ )
267 {
268 if ( ptr[i] == '&' && ptr[i]+1 != ' ' )
269 {
270 memmove( &ptr[i] , &ptr[i+1] , strlen( &ptr[i+1] ) + 1) ;
271 }
272 }
273 }
274
275 void wxMacConvertFromPC( unsigned char *p )
276 {
277 char *ptr = (char*) p + 1 ;
278 int len = p[0] ;
279
280 wxMacConvertFromPC( ptr , ptr , len ) ;
281 }
282
283 extern char *wxBuffer ;
284
285 wxString wxMacMakeMacStringFromPC( const char * p )
286 {
287 const char *ptr = p ;
288 int len = strlen ( p ) ;
289 char *buf = wxBuffer ;
290
291 if ( len >= BUFSIZ + 512 )
292 {
293 buf = new char [len+1] ;
294 }
295
296 wxMacConvertFromPC( ptr , buf , len ) ;
297 buf[len] = 0 ;
298 wxString result( buf ) ;
299 if ( buf != wxBuffer )
300 delete buf ;
301 return result ;
302 }
303
304
305 void wxMacConvertToPC( char * p )
306 {
307 char *ptr = p ;
308 int len = strlen ( p ) ;
309
310 wxMacConvertToPC( ptr , ptr , len ) ;
311 }
312
313 void wxMacConvertToPC( unsigned char *p )
314 {
315 char *ptr = (char*) p + 1 ;
316 int len = p[0] ;
317
318 wxMacConvertToPC( ptr , ptr , len ) ;
319 }
320
321 wxString wxMacMakePCStringFromMac( const char * p )
322 {
323 const char *ptr = p ;
324 int len = strlen ( p ) ;
325 char *buf = wxBuffer ;
326
327 if ( len >= BUFSIZ + 512 )
328 {
329 buf = new char [len+1] ;
330 }
331
332 wxMacConvertToPC( ptr , buf , len ) ;
333 buf[len] = 0 ;
334
335 wxString result( buf ) ;
336 if ( buf != wxBuffer )
337 delete buf ;
338 return result ;
339 }
340
341 wxString wxMacMakeStringFromMacString( const char* from , bool mac2pcEncoding )
342 {
343 if (mac2pcEncoding)
344 {
345 return wxMacMakePCStringFromMac( from ) ;
346 }
347 else
348 {
349 return wxString( from ) ;
350 }
351 }
352
353 wxString wxMacMakeStringFromPascal( StringPtr from , bool mac2pcEncoding )
354 {
355 // this is safe since a pascal string can never be larger than 256 bytes
356 char s[256] ;
357 CopyPascalStringToC( from , s ) ;
358 if (mac2pcEncoding)
359 {
360 return wxMacMakePCStringFromMac( s ) ;
361 }
362 else
363 {
364 return wxString( s ) ;
365 }
366 }
367
368 void wxMacStringToPascal( const char * from , StringPtr to , bool pc2macEncoding )
369 {
370 if (pc2macEncoding)
371 {
372 CopyCStringToPascal( wxMacMakeMacStringFromPC( from ) , to ) ;
373 }
374 else
375 {
376 CopyCStringToPascal( from , to ) ;
377 }
378 }
379
380 #if defined(WXMAKINGDLL) && !defined(__DARWIN__)
381 // we know it's there ;-)
382 WXIMPORT char std::__throws_bad_alloc ;
383 #endif
384
385 bool wxApp::Initialize()
386 {
387 int error = 0 ;
388
389 // Mac-specific
390
391 UMAInitToolbox( 4 ) ;
392 SetEventMask( everyEvent ) ;
393 UMAShowWatchCursor() ;
394
395 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
396 AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments , NewAEEventHandlerUPP(AEHandleODoc) ,
397 (long) wxTheApp , FALSE ) ;
398 AEInstallEventHandler( kCoreEventClass , kAEOpenApplication , NewAEEventHandlerUPP(AEHandleOApp) ,
399 (long) wxTheApp , FALSE ) ;
400 AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments , NewAEEventHandlerUPP(AEHandlePDoc) ,
401 (long) wxTheApp , FALSE ) ;
402 AEInstallEventHandler( kCoreEventClass , kAEQuitApplication , NewAEEventHandlerUPP(AEHandleQuit) ,
403 (long) wxTheApp , FALSE ) ;
404 #else
405 AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments , NewAEEventHandlerProc(AEHandleODoc) ,
406 (long) wxTheApp , FALSE ) ;
407 AEInstallEventHandler( kCoreEventClass , kAEOpenApplication , NewAEEventHandlerProc(AEHandleOApp) ,
408 (long) wxTheApp , FALSE ) ;
409 AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments , NewAEEventHandlerProc(AEHandlePDoc) ,
410 (long) wxTheApp , FALSE ) ;
411 AEInstallEventHandler( kCoreEventClass , kAEQuitApplication , NewAEEventHandlerProc(AEHandleQuit) ,
412 (long) wxTheApp , FALSE ) ;
413 #endif
414
415
416 #ifndef __DARWIN__
417 // test the minimal configuration necessary
418
419 #if !TARGET_CARBON
420 long theSystem ;
421 long theMachine;
422
423 if (Gestalt(gestaltMachineType, &theMachine) != noErr)
424 {
425 error = kMacSTRWrongMachine;
426 }
427 else if (theMachine < gestaltMacPlus)
428 {
429 error = kMacSTRWrongMachine;
430 }
431 else if (Gestalt(gestaltSystemVersion, &theSystem) != noErr )
432 {
433 error = kMacSTROldSystem ;
434 }
435 else if ( theSystem < 0x0860 )
436 {
437 error = kMacSTROldSystem ;
438 }
439 else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap)
440 {
441 error = kMacSTRSmallSize;
442 }
443 #endif
444 /*
445 else
446 {
447 if ( !UMAHasAppearance() )
448 {
449 error = kMacSTRNoPre8Yet ;
450 }
451 }
452 */
453 #endif
454
455 // if we encountered any problems so far, give the error code and exit immediately
456
457 if ( error )
458 {
459 wxStAppResource resload ;
460 short itemHit;
461 Str255 message;
462
463 GetIndString(message, 128, error);
464 UMAShowArrowCursor() ;
465 ParamText("\pFatal Error", message, (ConstStr255Param)"\p", (ConstStr255Param)"\p");
466 itemHit = Alert(128, nil);
467 return FALSE ;
468 }
469
470 #ifndef __DARWIN__
471 #if __option(profile)
472 ProfilerInit( collectDetailed, bestTimeBase , 20000 , 40 ) ;
473 #endif
474 #endif
475
476 #ifndef __DARWIN__
477 // now avoid exceptions thrown for new (bad_alloc)
478 std::__throws_bad_alloc = FALSE ;
479 #endif
480
481 s_macCursorRgn = ::NewRgn() ;
482
483 wxBuffer = new char[BUFSIZ + 512];
484
485 wxClassInfo::InitializeClasses();
486
487 #if wxUSE_RESOURCES
488 // wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion);
489 #endif
490
491 #if wxUSE_THREADS
492 wxPendingEventsLocker = new wxCriticalSection;
493 #endif
494
495 wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
496 wxTheColourDatabase->Initialize();
497
498 #ifdef __WXDEBUG__
499 #if wxUSE_LOG
500 // flush the logged messages if any and install a 'safer' log target: the
501 // default one (wxLogGui) can't be used after the resources are freed just
502 // below and the user suppliedo ne might be even more unsafe (using any
503 // wxWindows GUI function is unsafe starting from now)
504 wxLog::DontCreateOnDemand();
505
506 // this will flush the old messages if any
507 delete wxLog::SetActiveTarget(new wxLogStderr);
508 #endif // wxUSE_LOG
509 #endif
510
511 wxWinMacWindowList = new wxList(wxKEY_INTEGER);
512 wxWinMacControlList = new wxList(wxKEY_INTEGER);
513
514 wxInitializeStockLists();
515 wxInitializeStockObjects();
516
517 #if wxUSE_WX_RESOURCES
518 wxInitializeResourceSystem();
519 #endif
520
521 wxBitmap::InitStandardHandlers();
522
523 wxModule::RegisterModules();
524 if (!wxModule::InitializeModules()) {
525 return FALSE;
526 }
527
528 wxMacCreateNotifierTable() ;
529
530 UMAShowArrowCursor() ;
531
532 return TRUE;
533 }
534
535 void wxApp::CleanUp()
536 {
537 wxToolTip::RemoveToolTips() ;
538 #if wxUSE_LOG
539 // flush the logged messages if any and install a 'safer' log target: the
540 // default one (wxLogGui) can't be used after the resources are freed just
541 // below and the user suppliedo ne might be even more unsafe (using any
542 // wxWindows GUI function is unsafe starting from now)
543 wxLog::DontCreateOnDemand();
544
545 // this will flush the old messages if any
546 delete wxLog::SetActiveTarget(new wxLogStderr);
547 #endif // wxUSE_LOG
548
549 // One last chance for pending objects to be cleaned up
550 wxTheApp->DeletePendingObjects();
551
552 wxModule::CleanUpModules();
553
554 #if wxUSE_WX_RESOURCES
555 wxCleanUpResourceSystem();
556 #endif
557
558 wxDeleteStockObjects() ;
559
560 // Destroy all GDI lists, etc.
561 wxDeleteStockLists();
562
563 delete wxTheColourDatabase;
564 wxTheColourDatabase = NULL;
565
566 wxBitmap::CleanUpHandlers();
567
568 delete[] wxBuffer;
569 wxBuffer = NULL;
570
571 wxMacDestroyNotifierTable() ;
572 if (wxWinMacWindowList)
573 delete wxWinMacWindowList ;
574
575 if (wxWinMacControlList)
576 delete wxWinMacControlList ;
577
578 delete wxPendingEvents;
579 #if wxUSE_THREADS
580 delete wxPendingEventsLocker;
581 // If we don't do the following, we get an apparent memory leak.
582 ((wxEvtHandler&) wxDefaultValidator).ClearEventLocker();
583 #endif
584
585 wxClassInfo::CleanUpClasses();
586
587 #ifndef __DARWIN__
588 #if __option(profile)
589 ProfilerDump( "\papp.prof" ) ;
590 ProfilerTerm() ;
591 #endif
592 #endif
593
594 delete wxTheApp;
595 wxTheApp = NULL;
596
597 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
598 // At this point we want to check if there are any memory
599 // blocks that aren't part of the wxDebugContext itself,
600 // as a special case. Then when dumping we need to ignore
601 // wxDebugContext, too.
602 if (wxDebugContext::CountObjectsLeft(TRUE) > 0)
603 {
604 wxLogDebug(wxT("There were memory leaks."));
605 wxDebugContext::Dump();
606 wxDebugContext::PrintStatistics();
607 }
608 // wxDebugContext::SetStream(NULL, NULL);
609 #endif
610
611 #if wxUSE_LOG
612 // do it as the very last thing because everything else can log messages
613 delete wxLog::SetActiveTarget(NULL);
614 #endif // wxUSE_LOG
615
616 UMACleanupToolbox() ;
617 if (s_macCursorRgn)
618 ::DisposeRgn((RgnHandle)s_macCursorRgn);
619
620 #if 0
621 TerminateAE() ;
622 #endif
623 }
624
625 //----------------------------------------------------------------------
626 // wxEntry
627 //----------------------------------------------------------------------
628
629 short gCurrentResource = -1 ;
630 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
631 CFBundleRef gDylibBundle = NULL;
632 #endif /* WXMAKINGDLL && __DARWIN__ */
633
634 wxStAppResource::wxStAppResource()
635 {
636 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
637 // Open the shared library resource file if it is not yet open
638 if (gCurrentResource == -1) {
639 NSSymbol theSymbol;
640 NSModule theModule;
641 const char *theLibPath;
642
643 gDylibBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWindows"));
644 if (gDylibBundle != NULL) {
645 // wxWindows has been bundled into a framework
646 // load the framework resources
647
648 gCurrentResource = CFBundleOpenBundleResourceMap(gDylibBundle);
649 }
650 else {
651 // wxWindows is a simple dynamic shared library
652 // load the resources from the data fork of a separate resource file
653 char *theResPath;
654 char *theName;
655 char *theExt;
656 FSRef theResRef;
657 OSErr theErr = noErr;
658
659 // get the library path
660 theSymbol = NSLookupAndBindSymbol("_gCurrentResource");
661 theModule = NSModuleForSymbol(theSymbol);
662 theLibPath = NSLibraryNameForModule(theModule);
663
664 wxLogDebug( theLibPath );
665
666 // allocate copy to replace .dylib.* extension with .rsrc
667 theResPath = strdup(theLibPath);
668 if (theResPath != NULL) {
669 theName = strrchr(theResPath, '/');
670 if (theName == NULL) {
671 // no directory elements in path
672 theName = theResPath;
673 }
674 // find ".dylib" shared library extension
675 theExt = strstr(theName, ".dylib");
676 // overwrite extension with ".rsrc"
677 strcpy(theExt, ".rsrc");
678
679 wxLogDebug( theResPath );
680
681 theErr = FSPathMakeRef((UInt8 *) theResPath, &theResRef, false);
682 if (theErr != noErr) {
683 // try in current directory (using name only)
684 theErr = FSPathMakeRef((UInt8 *) theName, &theResRef, false);
685 }
686
687 // free duplicated resource file path
688 free(theResPath);
689
690 // open the resource file
691 if (theErr == noErr) {
692 theErr = FSOpenResourceFile( &theResRef, 0, NULL, fsRdPerm,
693 &gCurrentResource);
694 }
695 }
696 }
697
698 /*
699 char *path;
700 int i, len;
701
702 if( i++ > 0 ) {
703 len = i + strlen(rPath);
704 path = (char*) malloc(len+1);
705 }
706 else {
707 // try current directory
708 myerr = FSPathMakeRef((UInt8 *) rPath, &myref, false);
709 }
710 */
711 }
712 #endif /* WXMAKINGDLL && __DARWIN__ */
713
714 m_currentRefNum = CurResFile() ;
715 if ( gCurrentResource != -1 )
716 {
717 UseResFile( gCurrentResource ) ;
718 }
719 }
720
721 wxStAppResource::~wxStAppResource()
722 {
723 if ( m_currentRefNum != -1 )
724 {
725 UseResFile( m_currentRefNum ) ;
726 }
727
728 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
729 // Close the shared library resource file
730 if (gCurrentResource != -1) {
731 if (gDylibBundle != NULL) {
732 CFBundleCloseBundleResourceMap(gDylibBundle, gCurrentResource);
733 gDylibBundle = NULL;
734 }
735 else {
736 CloseResFile(gCurrentResource);
737 }
738 gCurrentResource = -1;
739 }
740 #endif /* WXMAKINGDLL && __DARWIN__ */
741 }
742
743 #if defined(WXMAKINGDLL) && !defined(__DARWIN__)
744
745 // for shared libraries we have to manually get the correct resource
746 // ref num upon initializing and releasing when terminating, therefore
747 // the __wxinitialize and __wxterminate must be used
748
749 #ifdef __cplusplus
750 extern "C" {
751 #endif
752
753 void __sinit(void); /* (generated by linker) */
754 pascal OSErr __initialize(const CFragInitBlock *theInitBlock);
755 pascal void __terminate(void);
756
757 #ifdef __cplusplus
758 }
759 #endif
760
761 pascal OSErr __wxinitialize(const CFragInitBlock *theInitBlock)
762 {
763 gCurrentResource = -1;
764
765 if (theInitBlock->fragLocator.where == kDataForkCFragLocator) {
766 gCurrentResource =
767 FSpOpenResFile(theInitBlock->fragLocator.u.onDisk.fileSpec,
768 fsRdPerm);
769 }
770 return __initialize( theInitBlock ) ;
771 }
772
773 pascal void __wxterminate(void)
774 {
775 if (gCurrentResource != -1)
776 CloseResFile(gCurrentResource);
777 __terminate() ;
778 }
779
780 #endif /* WXMAKINGDLL && !__DARWIN__ */
781
782 int WXDLLEXPORT wxEntryStart( int argc, char *argv[] )
783 {
784 return wxApp::Initialize();
785 }
786
787 int WXDLLEXPORT wxEntryInitGui()
788 {
789 return wxTheApp->OnInitGui();
790 }
791
792 void WXDLLEXPORT wxEntryCleanup()
793 {
794 wxApp::CleanUp();
795 }
796
797 int wxEntry( int argc, char *argv[] , bool enterLoop )
798 {
799 #if !(defined(WXMAKINGDLL) && defined(__DARWIN__))
800 gCurrentResource = CurResFile() ;
801 #endif
802
803 #ifdef __MWERKS__
804 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
805 // This seems to be necessary since there are 'rogue'
806 // objects present at this point (perhaps global objects?)
807 // Setting a checkpoint will ignore them as far as the
808 // memory checking facility is concerned.
809 // Of course you may argue that memory allocated in globals should be
810 // checked, but this is a reasonable compromise.
811 wxDebugContext::SetCheckpoint();
812 #endif
813 #endif
814 if (!wxEntryStart(argc, argv)) {
815 return 0;
816 }
817 // create the application object or ensure that one already exists
818 if (!wxTheApp)
819 {
820 // The app may have declared a global application object, but we recommend
821 // the IMPLEMENT_APP macro is used instead, which sets an initializer
822 // function for delayed, dynamic app object construction.
823 wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
824 wxT("No initializer - use IMPLEMENT_APP macro.") );
825
826 wxTheApp = (wxApp*) (*wxApp::GetInitializerFunction()) ();
827 }
828
829 wxCHECK_MSG( wxTheApp, 0, wxT("You have to define an instance of wxApp!") );
830
831 #ifdef __DARWIN__
832 // Mac OS X passes a process serial number command line argument when
833 // the application is launched from the Finder. This argument must be
834 // removed from the command line arguments before being handled by the
835 // application (otherwise applications would need to handle it)
836
837 if (argc > 1) {
838 char theArg[6] = "";
839 strncpy(theArg, argv[1], 5);
840
841 if (strcmp(theArg, "-psn_") == 0) {
842 // assume the argument is always the only one and remove it
843 --argc;
844 }
845 }
846 #else
847 argc = 0 ; // currently we don't support files as parameters
848 #endif
849 // we could try to get the open apple events here to adjust argc and argv better
850
851 wxTheApp->argc = argc;
852 wxTheApp->argv = argv;
853
854 // GUI-specific initialization, such as creating an app context.
855 wxEntryInitGui();
856
857 // Here frames insert themselves automatically
858 // into wxTopLevelWindows by getting created
859 // in OnInit().
860
861 int retValue = 0;
862
863 if ( wxTheApp->OnInit() )
864 {
865 if ( enterLoop )
866 {
867 retValue = wxTheApp->OnRun();
868 }
869 else
870 // We want to initialize, but not run or exit immediately.
871 return 1;
872 }
873 //else: app initialization failed, so we skipped OnRun()
874
875 wxWindow *topWindow = wxTheApp->GetTopWindow();
876 if ( topWindow )
877 {
878 // Forcibly delete the window.
879 if ( topWindow->IsKindOf(CLASSINFO(wxFrame)) ||
880 topWindow->IsKindOf(CLASSINFO(wxDialog)) )
881 {
882 topWindow->Close(TRUE);
883 wxTheApp->DeletePendingObjects();
884 }
885 else
886 {
887 delete topWindow;
888 wxTheApp->SetTopWindow(NULL);
889 }
890 }
891
892 wxTheApp->OnExit();
893
894 wxEntryCleanup();
895
896 return retValue;
897 }
898
899 // Static member initialization
900 wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
901
902 wxApp::wxApp()
903 {
904 m_topWindow = NULL;
905 wxTheApp = this;
906
907 #if WXWIN_COMPATIBILITY_2_2
908 m_wantDebugOutput = TRUE;
909 #endif
910
911 argc = 0;
912 argv = NULL;
913
914 m_printMode = wxPRINT_WINDOWS;
915 m_exitOnFrameDelete = TRUE;
916 m_auto3D = TRUE;
917 }
918
919 bool wxApp::Initialized()
920 {
921 if (GetTopWindow())
922 return TRUE;
923 else
924 return FALSE;
925 }
926
927 int wxApp::MainLoop()
928 {
929 m_keepGoing = TRUE;
930
931 while (m_keepGoing)
932 {
933 MacDoOneEvent() ;
934 }
935
936 return 0;
937 }
938
939 // Returns TRUE if more time is needed.
940 bool wxApp::ProcessIdle()
941 {
942 wxIdleEvent event;
943 event.SetEventObject(this);
944 ProcessEvent(event);
945
946 return event.MoreRequested();
947 }
948
949 void wxApp::ExitMainLoop()
950 {
951 m_keepGoing = FALSE;
952 }
953
954 // Is a message/event pending?
955 bool wxApp::Pending()
956 {
957 EventRecord event ;
958
959 return EventAvail( everyEvent , &event ) ;
960 }
961
962 // Dispatch a message.
963 void wxApp::Dispatch()
964 {
965 MacDoOneEvent() ;
966 }
967
968 void wxApp::OnIdle(wxIdleEvent& event)
969 {
970 static bool s_inOnIdle = FALSE;
971
972 // Avoid recursion (via ProcessEvent default case)
973 if ( s_inOnIdle )
974 return;
975
976
977 s_inOnIdle = TRUE;
978
979 // 'Garbage' collection of windows deleted with Close().
980 DeletePendingObjects();
981
982 // flush the logged messages if any
983 wxLog *pLog = wxLog::GetActiveTarget();
984 if ( pLog != NULL && pLog->HasPendingMessages() )
985 pLog->Flush();
986
987 // Send OnIdle events to all windows
988 bool needMore = SendIdleEvents();
989
990 if (needMore)
991 event.RequestMore(TRUE);
992
993 // If they are pending events, we must process them: pending events are
994 // either events to the threads other than main or events posted with
995 // wxPostEvent() functions
996 wxMacProcessNotifierAndPendingEvents();
997
998 s_inOnIdle = FALSE;
999 }
1000
1001 void wxWakeUpIdle()
1002 {
1003 wxMacWakeUp() ;
1004 }
1005
1006 // Send idle event to all top-level windows
1007 bool wxApp::SendIdleEvents()
1008 {
1009 bool needMore = FALSE;
1010 wxNode* node = wxTopLevelWindows.First();
1011 while (node)
1012 {
1013 wxWindow* win = (wxWindow*) node->Data();
1014 if (SendIdleEvents(win))
1015 needMore = TRUE;
1016
1017 node = node->Next();
1018 }
1019 return needMore;
1020 }
1021
1022 // Send idle event to window and all subwindows
1023 bool wxApp::SendIdleEvents(wxWindow* win)
1024 {
1025 bool needMore = FALSE;
1026
1027 wxIdleEvent event;
1028 event.SetEventObject(win);
1029 win->ProcessEvent(event);
1030
1031 if (event.MoreRequested())
1032 needMore = TRUE;
1033
1034 wxNode* node = win->GetChildren().First();
1035 while (node)
1036 {
1037 wxWindow* win = (wxWindow*) node->Data();
1038 if (SendIdleEvents(win))
1039 needMore = TRUE;
1040
1041 node = node->Next();
1042 }
1043 return needMore ;
1044 }
1045
1046 void wxApp::DeletePendingObjects()
1047 {
1048 wxNode *node = wxPendingDelete.First();
1049 while (node)
1050 {
1051 wxObject *obj = (wxObject *)node->Data();
1052
1053 delete obj;
1054
1055 if (wxPendingDelete.Member(obj))
1056 delete node;
1057
1058 // Deleting one object may have deleted other pending
1059 // objects, so start from beginning of list again.
1060 node = wxPendingDelete.First();
1061 }
1062 }
1063
1064 void wxExit()
1065 {
1066 wxLogError(_("Fatal error: exiting"));
1067
1068 wxApp::CleanUp();
1069 ::ExitToShell() ;
1070 }
1071
1072 void wxApp::OnEndSession(wxCloseEvent& WXUNUSED(event))
1073 {
1074 if (GetTopWindow())
1075 GetTopWindow()->Close(TRUE);
1076 }
1077
1078 // Default behaviour: close the application with prompts. The
1079 // user can veto the close, and therefore the end session.
1080 void wxApp::OnQueryEndSession(wxCloseEvent& event)
1081 {
1082 if (GetTopWindow())
1083 {
1084 if (!GetTopWindow()->Close(!event.CanVeto()))
1085 event.Veto(TRUE);
1086 }
1087 }
1088
1089 extern "C" void wxCYield() ;
1090 void wxCYield()
1091 {
1092 wxYield() ;
1093 }
1094
1095 // Yield to other processes
1096
1097 bool wxApp::Yield(bool onlyIfNeeded)
1098 {
1099 static bool s_inYield = FALSE;
1100
1101 if (s_inYield)
1102 {
1103 if ( !onlyIfNeeded )
1104 {
1105 wxFAIL_MSG( wxT("wxYield called recursively" ) );
1106 }
1107
1108 return FALSE;
1109 }
1110
1111 s_inYield = TRUE;
1112
1113 #if wxUSE_THREADS
1114 YieldToAnyThread() ;
1115 #endif
1116 EventRecord event ;
1117
1118 long sleepTime = 1 ; //::GetCaretTime();
1119
1120 while ( !wxTheApp->IsExiting() && WaitNextEvent(everyEvent, &event,sleepTime, (RgnHandle) wxApp::s_macCursorRgn))
1121 {
1122 wxTheApp->MacHandleOneEvent( &event );
1123 if ( event.what != kHighLevelEvent )
1124 SetRectRgn( (RgnHandle) wxApp::s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ;
1125 }
1126
1127 wxMacProcessNotifierAndPendingEvents() ;
1128
1129 s_inYield = FALSE;
1130
1131 return TRUE;
1132 }
1133
1134 // platform specifics
1135
1136 void wxApp::MacSuspend( bool convertClipboard )
1137 {
1138 // we have to deactive the top level windows manually
1139
1140 wxNode* node = wxTopLevelWindows.First();
1141 while (node)
1142 {
1143 wxTopLevelWindow* win = (wxTopLevelWindow*) node->Data();
1144 win->MacActivate( MacGetCurrentEvent() , false ) ;
1145
1146 node = node->Next();
1147 }
1148
1149 s_lastMouseDown = 0 ;
1150 if( convertClipboard )
1151 {
1152 MacConvertPrivateToPublicScrap() ;
1153 }
1154
1155 ::HideFloatingWindows() ;
1156 }
1157
1158 void wxApp::MacResume( bool convertClipboard )
1159 {
1160 s_lastMouseDown = 0 ;
1161 if( convertClipboard )
1162 {
1163 MacConvertPublicToPrivateScrap() ;
1164 }
1165
1166 ::ShowFloatingWindows() ;
1167 }
1168
1169 void wxApp::MacConvertPrivateToPublicScrap()
1170 {
1171 }
1172
1173 void wxApp::MacConvertPublicToPrivateScrap()
1174 {
1175 }
1176
1177 void wxApp::MacDoOneEvent()
1178 {
1179 EventRecord event ;
1180
1181 long sleepTime = 1; // GetCaretTime() / 4 ;
1182
1183 if (WaitNextEvent(everyEvent, &event, sleepTime, (RgnHandle) s_macCursorRgn))
1184 {
1185 MacHandleOneEvent( &event );
1186 }
1187 else
1188 {
1189 // idlers
1190 WindowPtr window = ::FrontWindow() ;
1191 if ( window )
1192 ::IdleControls( window ) ;
1193
1194 wxTheApp->ProcessIdle() ;
1195 }
1196 if ( event.what != kHighLevelEvent )
1197 SetRectRgn( (RgnHandle) s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ;
1198
1199 // repeaters
1200
1201 DeletePendingObjects() ;
1202 wxMacProcessNotifierAndPendingEvents() ;
1203 }
1204
1205 void wxApp::MacHandleOneEvent( WXEVENTREF evr )
1206 {
1207 EventRecord* ev = (EventRecord*) evr ;
1208 m_macCurrentEvent = ev ;
1209
1210 wxApp::sm_lastMessageTime = ev->when ;
1211
1212 switch (ev->what)
1213 {
1214 case mouseDown:
1215 MacHandleMouseDownEvent( ev ) ;
1216 if ( ev->modifiers & controlKey )
1217 s_lastMouseDown = 2;
1218 else
1219 s_lastMouseDown = 1;
1220 break;
1221 case mouseUp:
1222 if ( s_lastMouseDown == 2 )
1223 {
1224 ev->modifiers |= controlKey ;
1225 }
1226 else
1227 {
1228 ev->modifiers &= ~controlKey ;
1229 }
1230 MacHandleMouseUpEvent( ev ) ;
1231 s_lastMouseDown = 0;
1232 break;
1233 case activateEvt:
1234 MacHandleActivateEvent( ev ) ;
1235 break;
1236 case updateEvt:
1237 MacHandleUpdateEvent( ev ) ;
1238 break;
1239 case keyDown:
1240 case autoKey:
1241 MacHandleKeyDownEvent( ev ) ;
1242 break;
1243 case keyUp:
1244 MacHandleKeyUpEvent( ev ) ;
1245 break;
1246 case diskEvt:
1247 MacHandleDiskEvent( ev ) ;
1248 break;
1249 case osEvt:
1250 MacHandleOSEvent( ev ) ;
1251 break;
1252 case kHighLevelEvent:
1253 MacHandleHighLevelEvent( ev ) ;
1254 break;
1255 default:
1256 break;
1257 }
1258 wxMacProcessNotifierAndPendingEvents() ;
1259 }
1260
1261 void wxApp::MacHandleHighLevelEvent( WXEVENTREF evr )
1262 {
1263 EventRecord* ev = (EventRecord*) evr ;
1264 ::AEProcessAppleEvent( ev ) ;
1265 }
1266
1267 bool s_macIsInModalLoop = false ;
1268
1269 void wxApp::MacHandleMouseDownEvent( WXEVENTREF evr )
1270 {
1271 EventRecord* ev = (EventRecord*) evr ;
1272 wxToolTip::RemoveToolTips() ;
1273
1274 WindowRef window;
1275 WindowRef frontWindow = ::FrontNonFloatingWindow() ;
1276 WindowAttributes frontWindowAttributes = NULL ;
1277 if ( frontWindow )
1278 ::GetWindowAttributes( frontWindow , &frontWindowAttributes ) ;
1279
1280 short windowPart = ::FindWindow(ev->where, &window);
1281 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
1282 if ( wxPendingDelete.Member(win) )
1283 return ;
1284
1285 BitMap screenBits;
1286 GetQDGlobalsScreenBits( &screenBits );
1287
1288 switch (windowPart)
1289 {
1290 case inMenuBar :
1291 if ( s_macIsInModalLoop )
1292 {
1293 SysBeep ( 30 ) ;
1294 }
1295 else
1296 {
1297 UInt32 menuresult = MenuSelect(ev->where) ;
1298 MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) );
1299 s_lastMouseDown = 0;
1300 }
1301 break ;
1302 #if !TARGET_CARBON
1303 case inSysWindow :
1304 SystemClick( ev , window ) ;
1305 s_lastMouseDown = 0;
1306 break ;
1307 #endif
1308 case inDrag :
1309 if ( window != frontWindow && s_macIsInModalLoop && !(ev->modifiers & cmdKey ) )
1310 {
1311 SysBeep ( 30 ) ;
1312 }
1313 else
1314 {
1315 DragWindow(window, ev->where, &screenBits.bounds);
1316 if (win)
1317 {
1318 GrafPtr port ;
1319 GetPort( &port ) ;
1320 Point pt = { 0, 0 } ;
1321 SetPortWindowPort(window) ;
1322 LocalToGlobal( &pt ) ;
1323 SetPort( port ) ;
1324 win->SetSize( pt.h , pt.v , -1 ,
1325 -1 , wxSIZE_USE_EXISTING);
1326 }
1327 s_lastMouseDown = 0;
1328 }
1329 break ;
1330 case inGoAway:
1331 if (TrackGoAway(window, ev->where))
1332 {
1333 if ( win )
1334 win->Close() ;
1335 }
1336 s_lastMouseDown = 0;
1337 break;
1338 case inGrow:
1339 {
1340 int growResult = GrowWindow(window , ev->where, &screenBits.bounds);
1341 if (growResult != 0)
1342 {
1343 int newWidth = LoWord(growResult);
1344 int newHeight = HiWord(growResult);
1345 int oldWidth, oldHeight;
1346
1347
1348 if (win)
1349 {
1350 win->GetSize(&oldWidth, &oldHeight);
1351 if (newWidth == 0)
1352 newWidth = oldWidth;
1353 if (newHeight == 0)
1354 newHeight = oldHeight;
1355 win->SetSize( -1, -1, newWidth, newHeight, wxSIZE_USE_EXISTING);
1356 }
1357 }
1358 s_lastMouseDown = 0;
1359 }
1360 break;
1361 case inZoomIn:
1362 case inZoomOut:
1363 if (TrackBox(window, ev->where, windowPart))
1364 {
1365 // TODO setup size event
1366 ZoomWindow( window , windowPart , false ) ;
1367 if (win)
1368 {
1369 Rect tempRect ;
1370
1371 GetWindowPortBounds(window, &tempRect ) ;
1372 win->SetSize( -1, -1, tempRect.right-tempRect.left ,
1373 tempRect.bottom-tempRect.top, wxSIZE_USE_EXISTING);
1374 }
1375 }
1376 s_lastMouseDown = 0;
1377 break;
1378 case inCollapseBox :
1379 // TODO setup size event
1380 s_lastMouseDown = 0;
1381 break ;
1382
1383 case inContent :
1384 {
1385 GrafPtr port ;
1386 GetPort( &port ) ;
1387 SetPortWindowPort(window) ;
1388 SetPort( port ) ;
1389 }
1390 if ( window != frontWindow && wxTheApp->s_captureWindow == NULL )
1391 {
1392 if ( s_macIsInModalLoop )
1393 {
1394 SysBeep ( 30 ) ;
1395 }
1396 else if ( UMAIsWindowFloating( window ) )
1397 {
1398 if ( win )
1399 win->MacMouseDown( ev , windowPart ) ;
1400 }
1401 else
1402 {
1403 if ( win )
1404 win->MacMouseDown( ev , windowPart ) ;
1405 ::SelectWindow( window ) ;
1406 }
1407 }
1408 else
1409 {
1410 if ( win )
1411 win->MacMouseDown( ev , windowPart ) ;
1412 }
1413 break ;
1414
1415 default:
1416 break;
1417 }
1418 }
1419
1420 void wxApp::MacHandleMouseUpEvent( WXEVENTREF evr )
1421 {
1422 EventRecord* ev = (EventRecord*) evr ;
1423 WindowRef window;
1424
1425 short windowPart = inNoWindow ;
1426 if ( wxTheApp->s_captureWindow )
1427 {
1428 window = (WindowRef) s_captureWindow->MacGetRootWindow() ;
1429 windowPart = inContent ;
1430 }
1431 else
1432 {
1433 windowPart = ::FindWindow(ev->where, &window) ;
1434 }
1435
1436 switch (windowPart)
1437 {
1438 case inMenuBar :
1439 break ;
1440 case inSysWindow :
1441 break ;
1442 default:
1443 {
1444 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
1445 if ( win )
1446 win->MacMouseUp( ev , windowPart ) ;
1447 }
1448 break;
1449 }
1450 }
1451
1452 long wxMacTranslateKey(unsigned char key, unsigned char code) ;
1453 long wxMacTranslateKey(unsigned char key, unsigned char code)
1454 {
1455 long retval = key ;
1456 switch (key)
1457 {
1458 case 0x01 :
1459 retval = WXK_HOME;
1460 break;
1461 case 0x03 :
1462 retval = WXK_RETURN;
1463 break;
1464 case 0x04 :
1465 retval = WXK_END;
1466 break;
1467 case 0x05 :
1468 retval = WXK_HELP;
1469 break;
1470 case 0x08 :
1471 retval = WXK_BACK;
1472 break;
1473 case 0x09 :
1474 retval = WXK_TAB;
1475 break;
1476 case 0x0b :
1477 retval = WXK_PAGEUP;
1478 break;
1479 case 0x0c :
1480 retval = WXK_PAGEDOWN;
1481 break;
1482 case 0x0d :
1483 retval = WXK_RETURN;
1484 break;
1485 case 0x10 :
1486 {
1487 switch( code )
1488 {
1489 case 0x7a :
1490 retval = WXK_F1 ;
1491 break;
1492 case 0x78 :
1493 retval = WXK_F2 ;
1494 break;
1495 case 0x63 :
1496 retval = WXK_F3 ;
1497 break;
1498 case 0x76 :
1499 retval = WXK_F4 ;
1500 break;
1501 case 0x60 :
1502 retval = WXK_F5 ;
1503 break;
1504 case 0x61 :
1505 retval = WXK_F6 ;
1506 break;
1507 case 0x62:
1508 retval = WXK_F7 ;
1509 break;
1510 case 0x64 :
1511 retval = WXK_F8 ;
1512 break;
1513 case 0x65 :
1514 retval = WXK_F9 ;
1515 break;
1516 case 0x6D :
1517 retval = WXK_F10 ;
1518 break;
1519 case 0x67 :
1520 retval = WXK_F11 ;
1521 break;
1522 case 0x6F :
1523 retval = WXK_F12 ;
1524 break;
1525 case 0x69 :
1526 retval = WXK_F13 ;
1527 break;
1528 case 0x6B :
1529 retval = WXK_F14 ;
1530 break;
1531 case 0x71 :
1532 retval = WXK_F15 ;
1533 break;
1534 }
1535 }
1536 break ;
1537 case 0x1b :
1538 retval = WXK_ESCAPE ;
1539 break ;
1540 case 0x1c :
1541 retval = WXK_LEFT ;
1542 break ;
1543 case 0x1d :
1544 retval = WXK_RIGHT ;
1545 break ;
1546 case 0x1e :
1547 retval = WXK_UP ;
1548 break ;
1549 case 0x1f :
1550 retval = WXK_DOWN ;
1551 break ;
1552 case 0x7F :
1553 retval = WXK_DELETE ;
1554 default:
1555 break ;
1556 } // end switch
1557
1558 return retval;
1559 }
1560
1561 void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr )
1562 {
1563 EventRecord* ev = (EventRecord*) evr ;
1564 wxToolTip::RemoveToolTips() ;
1565
1566 UInt32 menuresult = UMAMenuEvent(ev) ;
1567 if ( HiWord( menuresult ) )
1568 {
1569 if ( !s_macIsInModalLoop )
1570 MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ) ;
1571 }
1572 else
1573 {
1574 short keycode ;
1575 short keychar ;
1576 keychar = short(ev->message & charCodeMask);
1577 keycode = short(ev->message & keyCodeMask) >> 8 ;
1578 long keyval = wxMacTranslateKey(keychar, keycode) ;
1579 bool handled = false ;
1580 wxWindow* focus = wxWindow::FindFocus() ;
1581 if ( focus )
1582 {
1583
1584 wxKeyEvent event(wxEVT_KEY_DOWN);
1585 event.m_shiftDown = ev->modifiers & shiftKey;
1586 event.m_controlDown = ev->modifiers & controlKey;
1587 event.m_altDown = ev->modifiers & optionKey;
1588 event.m_metaDown = ev->modifiers & cmdKey;
1589 event.m_keyCode = keyval;
1590 event.m_x = ev->where.h;
1591 event.m_y = ev->where.v;
1592 event.m_timeStamp = ev->when;
1593 event.SetEventObject(focus);
1594 handled = focus->GetEventHandler()->ProcessEvent( event ) ;
1595 if ( !handled )
1596 {
1597 #if wxUSE_ACCEL
1598 if (!handled)
1599 {
1600 /*
1601 wxWindow *ancestor = focus;
1602 while (ancestor)
1603 {
1604 int command = ancestor->GetAcceleratorTable()->GetCommand( event );
1605 if (command != -1)
1606 {
1607 wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
1608 handled = ancestor->GetEventHandler()->ProcessEvent( command_event );
1609 break;
1610 }
1611 if (ancestor->m_isFrame)
1612 break;
1613 ancestor = ancestor->GetParent();
1614 }
1615 */
1616 }
1617 #endif // wxUSE_ACCEL
1618 }
1619 if (!handled)
1620 {
1621 wxKeyEvent event(wxEVT_CHAR);
1622 event.m_shiftDown = ev->modifiers & shiftKey;
1623 event.m_controlDown = ev->modifiers & controlKey;
1624 event.m_altDown = ev->modifiers & optionKey;
1625 event.m_metaDown = ev->modifiers & cmdKey;
1626 event.m_keyCode = keyval;
1627 event.m_x = ev->where.h;
1628 event.m_y = ev->where.v;
1629 event.m_timeStamp = ev->when;
1630 event.SetEventObject(focus);
1631 handled = focus->GetEventHandler()->ProcessEvent( event ) ;
1632 }
1633 if ( !handled &&
1634 (keyval == WXK_TAB) &&
1635 (!focus->HasFlag(wxTE_PROCESS_TAB)) &&
1636 (focus->GetParent()) &&
1637 (focus->GetParent()->HasFlag( wxTAB_TRAVERSAL)) )
1638 {
1639 wxNavigationKeyEvent new_event;
1640 new_event.SetEventObject( focus );
1641 new_event.SetDirection( !event.ShiftDown() );
1642 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
1643 new_event.SetWindowChange( event.ControlDown() );
1644 new_event.SetCurrentFocus( focus );
1645 handled = focus->GetEventHandler()->ProcessEvent( new_event );
1646 }
1647 }
1648 if ( !handled )
1649 {
1650 // if window is not having a focus still testing for default enter or cancel
1651 // TODO add the UMA version for ActiveNonFloatingWindow
1652 focus = wxFindWinFromMacWindow( FrontWindow() ) ;
1653 if ( focus )
1654 {
1655 if ( keyval == WXK_RETURN )
1656 {
1657 wxButton *def = wxDynamicCast(focus->GetDefaultItem(),
1658 wxButton);
1659 if ( def && def->IsEnabled() )
1660 {
1661 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
1662 event.SetEventObject(def);
1663 def->Command(event);
1664 return ;
1665 }
1666 }
1667 /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
1668 else if (keyval == WXK_ESCAPE || (keyval == '.' && ev->modifiers & cmdKey ) )
1669 {
1670 wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL);
1671 new_event.SetEventObject( focus );
1672 handled = focus->GetEventHandler()->ProcessEvent( new_event );
1673 }
1674 }
1675 }
1676 }
1677 }
1678
1679 void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr )
1680 {
1681 EventRecord* ev = (EventRecord*) evr ;
1682 wxToolTip::RemoveToolTips() ;
1683
1684 UInt32 menuresult = UMAMenuEvent(ev) ;
1685 if ( HiWord( menuresult ) )
1686 {
1687 }
1688 else
1689 {
1690 short keycode ;
1691 short keychar ;
1692 keychar = short(ev->message & charCodeMask);
1693 keycode = short(ev->message & keyCodeMask) >> 8 ;
1694
1695 wxWindow* focus = wxWindow::FindFocus() ;
1696 if ( focus )
1697 {
1698 long keyval = wxMacTranslateKey(keychar, keycode) ;
1699
1700 wxKeyEvent event(wxEVT_KEY_UP);
1701 event.m_shiftDown = ev->modifiers & shiftKey;
1702 event.m_controlDown = ev->modifiers & controlKey;
1703 event.m_altDown = ev->modifiers & optionKey;
1704 event.m_metaDown = ev->modifiers & cmdKey;
1705 event.m_keyCode = keyval;
1706 event.m_x = ev->where.h;
1707 event.m_y = ev->where.v;
1708 event.m_timeStamp = ev->when;
1709 event.SetEventObject(focus);
1710 bool handled = focus->GetEventHandler()->ProcessEvent( event ) ;
1711 }
1712 }
1713 }
1714
1715 void wxApp::MacHandleActivateEvent( WXEVENTREF evr )
1716 {
1717 EventRecord* ev = (EventRecord*) evr ;
1718 WindowRef window = (WindowRef) ev->message ;
1719 if ( window )
1720 {
1721 bool activate = (ev->modifiers & activeFlag ) ;
1722 WindowClass wclass ;
1723 ::GetWindowClass ( window , &wclass ) ;
1724 if ( wclass == kFloatingWindowClass )
1725 {
1726 // if it is a floater we activate/deactivate the front non-floating window instead
1727 window = ::FrontNonFloatingWindow() ;
1728 }
1729 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
1730 if ( win )
1731 win->MacActivate( ev , activate ) ;
1732 }
1733 }
1734
1735 void wxApp::MacHandleUpdateEvent( WXEVENTREF evr )
1736 {
1737 EventRecord* ev = (EventRecord*) evr ;
1738 WindowRef window = (WindowRef) ev->message ;
1739 wxTopLevelWindowMac * win = wxFindWinFromMacWindow( window ) ;
1740 if ( win )
1741 {
1742 if ( !wxPendingDelete.Member(win) )
1743 win->MacUpdate( ev->when ) ;
1744 }
1745 else
1746 {
1747 // since there is no way of telling this foreign window to update itself
1748 // we have to invalidate the update region otherwise we keep getting the same
1749 // event over and over again
1750 BeginUpdate( window ) ;
1751 EndUpdate( window ) ;
1752 }
1753 }
1754
1755 void wxApp::MacHandleDiskEvent( WXEVENTREF evr )
1756 {
1757 EventRecord* ev = (EventRecord*) evr ;
1758 if ( HiWord( ev->message ) != noErr )
1759 {
1760 #if !TARGET_CARBON
1761 OSErr err ;
1762 Point point ;
1763 SetPt( &point , 100 , 100 ) ;
1764
1765 err = DIBadMount( point , ev->message ) ;
1766 wxASSERT( err == noErr ) ;
1767 #endif
1768 }
1769 }
1770
1771 void wxApp::MacHandleOSEvent( WXEVENTREF evr )
1772 {
1773 EventRecord* ev = (EventRecord*) evr ;
1774 switch( ( ev->message & osEvtMessageMask ) >> 24 )
1775 {
1776 case suspendResumeMessage :
1777 {
1778 bool isResuming = ev->message & resumeFlag ;
1779 #if !TARGET_CARBON
1780 bool convertClipboard = ev->message & convertClipboardFlag ;
1781 #else
1782 bool convertClipboard = false;
1783 #endif
1784 bool doesActivate = UMAGetProcessModeDoesActivateOnFGSwitch() ;
1785 if ( isResuming )
1786 {
1787 WindowRef oldFrontWindow = NULL ;
1788 WindowRef newFrontWindow = NULL ;
1789
1790 // in case we don't take care of activating ourselves, we have to synchronize
1791 // our idea of the active window with the process manager's - which it already activated
1792
1793 if ( !doesActivate )
1794 oldFrontWindow = ::FrontNonFloatingWindow() ;
1795
1796 MacResume( convertClipboard ) ;
1797
1798 newFrontWindow = ::FrontNonFloatingWindow() ;
1799
1800 if ( oldFrontWindow )
1801 {
1802 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( oldFrontWindow ) ;
1803 if ( win )
1804 win->MacActivate( ev , false ) ;
1805 }
1806 if ( newFrontWindow )
1807 {
1808 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( newFrontWindow ) ;
1809 if ( win )
1810 win->MacActivate( ev , true ) ;
1811 }
1812 }
1813 else
1814 {
1815 MacSuspend( convertClipboard ) ;
1816
1817 // in case this suspending did close an active window, another one might
1818 // have surfaced -> lets deactivate that one
1819
1820 /* TODO : find out what to do on systems < 10 , perhaps FrontNonFloatingWindow
1821 WindowRef newActiveWindow = ::ActiveNonFloatingWindow() ;
1822 if ( newActiveWindow )
1823 {
1824 wxWindow* win = wxFindWinFromMacWindow( newActiveWindow ) ;
1825 if ( win )
1826 win->MacActivate( ev , false ) ;
1827 }
1828 */
1829 }
1830 }
1831 break ;
1832 case mouseMovedMessage :
1833 {
1834 WindowRef window;
1835
1836 wxWindow* currentMouseWindow = NULL ;
1837
1838 wxWindow::MacGetWindowFromPoint( wxPoint( ev->where.h , ev->where.v ) ,
1839 &currentMouseWindow ) ;
1840 if ( currentMouseWindow != wxWindow::s_lastMouseWindow )
1841 {
1842 wxMouseEvent event ;
1843
1844 bool isDown = !(ev->modifiers & btnState) ; // 1 is for up
1845 bool controlDown = ev->modifiers & controlKey ; // for simulating right mouse
1846
1847 event.m_leftDown = isDown && !controlDown;
1848 event.m_middleDown = FALSE;
1849 event.m_rightDown = isDown && controlDown;
1850 event.m_shiftDown = ev->modifiers & shiftKey;
1851 event.m_controlDown = ev->modifiers & controlKey;
1852 event.m_altDown = ev->modifiers & optionKey;
1853 event.m_metaDown = ev->modifiers & cmdKey;
1854 event.m_x = ev->where.h;
1855 event.m_y = ev->where.v;
1856 event.m_timeStamp = ev->when;
1857 event.SetEventObject(this);
1858
1859 if ( wxWindow::s_lastMouseWindow )
1860 {
1861 wxMouseEvent eventleave(event);
1862 eventleave.SetEventType( wxEVT_LEAVE_WINDOW );
1863 wxWindow::s_lastMouseWindow->ScreenToClient( &eventleave.m_x, &eventleave.m_y );
1864 eventleave.SetEventObject( wxWindow::s_lastMouseWindow ) ;
1865
1866 wxWindow::s_lastMouseWindow->GetEventHandler()->ProcessEvent(eventleave);
1867 }
1868 if ( currentMouseWindow )
1869 {
1870 wxMouseEvent evententer(event);
1871 evententer.SetEventType( wxEVT_ENTER_WINDOW );
1872 currentMouseWindow->ScreenToClient( &evententer.m_x, &evententer.m_y );
1873 evententer.SetEventObject( currentMouseWindow ) ;
1874 currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
1875 }
1876 wxWindow::s_lastMouseWindow = currentMouseWindow ;
1877 }
1878
1879 short windowPart = ::FindWindow(ev->where, &window);
1880
1881 switch (windowPart)
1882 {
1883 // fixes for setting the cursor back from dominic mazzoni
1884 case inMenuBar :
1885 UMAShowArrowCursor();
1886 break ;
1887 case inSysWindow :
1888 UMAShowArrowCursor();
1889 break ;
1890 default:
1891 {
1892 // if ( s_lastMouseDown == 0 )
1893 // ev->modifiers |= btnState ;
1894
1895 // Calling GetNextEvent with a zero event mask will always
1896 // pass back a null event. However, it fills the EventRecord
1897 // with the state of the modifier keys. This is needed since
1898 // the modifier state returned by WaitForNextEvent often is
1899 // wrong mouse move events. The attempt above to correct this
1900 // didn't always work (under OS X at least).
1901
1902 EventRecord tmp;
1903 ::GetNextEvent(0, &tmp);
1904 ev->modifiers = tmp.modifiers;
1905
1906 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
1907 if ( win )
1908 win->MacMouseMoved( ev , windowPart ) ;
1909 else
1910 UMAShowArrowCursor();
1911
1912 }
1913 break;
1914 }
1915 }
1916 break ;
1917
1918 }
1919 }
1920
1921 void wxApp::MacHandleMenuSelect( int macMenuId , int macMenuItemNum )
1922 {
1923 if (macMenuId == 0)
1924 return; // no menu item selected
1925
1926 if (macMenuId == kwxMacAppleMenuId && macMenuItemNum > 1)
1927 {
1928 #if ! TARGET_CARBON
1929 Str255 deskAccessoryName ;
1930 GrafPtr savedPort ;
1931
1932 GetMenuItemText(GetMenuHandle(kwxMacAppleMenuId), macMenuItemNum, deskAccessoryName);
1933 GetPort(&savedPort);
1934 OpenDeskAcc(deskAccessoryName);
1935 SetPort(savedPort);
1936 #endif
1937 }
1938 else
1939 {
1940 wxWindow* frontwindow = wxFindWinFromMacWindow( ::FrontWindow() ) ;
1941 if ( frontwindow && wxMenuBar::MacGetInstalledMenuBar() )
1942 wxMenuBar::MacGetInstalledMenuBar()->MacMenuSelect( frontwindow->GetEventHandler() , 0 , macMenuId , macMenuItemNum ) ;
1943 }
1944 HiliteMenu(0);
1945 }
1946
1947 /*
1948 long wxApp::MacTranslateKey(char key, int mods)
1949 {
1950 }
1951
1952 void wxApp::MacAdjustCursor()
1953 {
1954 }
1955
1956 */
1957 /*
1958 void
1959 wxApp::macAdjustCursor()
1960 {
1961 if (ev->what != kHighLevelEvent)
1962 {
1963 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow());
1964 if (theMacWxFrame)
1965 {
1966 if (!theMacWxFrame->MacAdjustCursor(ev->where))
1967 ::SetCursor(&(qd.arrow));
1968 }
1969 }
1970 }
1971 */