]> git.saurik.com Git - wxWidgets.git/blob - src/mac/app.cpp
added wxArray::SetCount()
[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 #include "wx/docview.h"
40
41 #if wxUSE_WX_RESOURCES
42 # include "wx/resource.h"
43 #endif
44
45 #include <string.h>
46
47 // mac
48
49 #ifndef __DARWIN__
50 #if __option(profile)
51 #include <profiler.h>
52 #endif
53 #endif
54
55 #include "apprsrc.h"
56
57 #include "wx/mac/uma.h"
58 #include "wx/mac/macnotfy.h"
59
60 #ifdef __DARWIN__
61 # include <CoreServices/CoreServices.h>
62 # if defined(WXMAKINGDLL)
63 # include <mach-o/dyld.h>
64 # endif
65 #else
66 # include <Sound.h>
67 # include <Threads.h>
68 # include <ToolUtils.h>
69 # include <DiskInit.h>
70 # include <Devices.h>
71 #endif
72
73 extern char *wxBuffer;
74 extern wxList wxPendingDelete;
75 extern wxList *wxWinMacWindowList;
76 extern wxList *wxWinMacControlList;
77
78 static bool s_inYield = FALSE;
79
80 wxApp *wxTheApp = NULL;
81
82 #if !USE_SHARED_LIBRARY
83 IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
84 BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
85 EVT_IDLE(wxApp::OnIdle)
86 EVT_END_SESSION(wxApp::OnEndSession)
87 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
88 END_EVENT_TABLE()
89 #endif
90
91
92 const short kMacMinHeap = (29 * 1024) ;
93 // platform specific static variables
94
95 const short kwxMacMenuBarResource = 1 ;
96 const short kwxMacAppleMenuId = 1 ;
97
98 WXHRGN wxApp::s_macCursorRgn = NULL;
99 wxWindow* wxApp::s_captureWindow = NULL ;
100 int wxApp::s_lastMouseDown = 0 ;
101 long wxApp::sm_lastMessageTime = 0;
102 long wxApp::s_lastModifiers = 0 ;
103
104
105 bool wxApp::s_macDefaultEncodingIsPC = true ;
106 bool wxApp::s_macSupportPCMenuShortcuts = true ;
107 long wxApp::s_macAboutMenuItemId = wxID_ABOUT ;
108 long wxApp::s_macPreferencesMenuItemId = 0 ;
109 long wxApp::s_macExitMenuItemId = wxID_EXIT ;
110 wxString wxApp::s_macHelpMenuTitleName = "&Help" ;
111
112 pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
113 pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
114 pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
115 pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
116 pascal OSErr AEHandlePreferences( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
117
118
119 pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
120 {
121 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
122 return wxTheApp->MacHandleAEODoc( (AppleEvent*) event , reply) ;
123 }
124
125 pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
126 {
127 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
128 return wxTheApp->MacHandleAEOApp( (AppleEvent*) event , reply ) ;
129 }
130
131 pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
132 {
133 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
134 return wxTheApp->MacHandleAEPDoc( (AppleEvent*) event , reply ) ;
135 }
136
137 pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
138 {
139 // GD: UNUSED wxApp* app = (wxApp*) refcon ;
140 return wxTheApp->MacHandleAEQuit( (AppleEvent*) event , reply) ;
141 }
142
143 pascal 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
159 // new virtual public method in wxApp
160 void wxApp::MacOpenFile(const wxString & fileName )
161 {
162 wxDocManager* dm = wxDocManager::GetDocumentManager() ;
163 if ( dm )
164 dm->CreateDocument(fileName , wxDOC_SILENT ) ;
165 }
166
167 void wxApp::MacPrintFile(const wxString & fileName )
168 {
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 }
193 }
194
195 void wxApp::MacNewFile()
196 {
197 }
198
199 // new implementation, which parses the event and calls
200 // MacOpenFile on each of the files it's passed
201 short 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
219 ProcessSerialNumber PSN ;
220 PSN.highLongOfPSN = 0 ;
221 PSN.lowLongOfPSN = kCurrentProcess ;
222 SetFrontProcess( &PSN ) ;
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;
231 }
232
233 short wxApp::MacHandleAEPDoc(const WXEVENTREF event , WXEVENTREF WXUNUSED(reply))
234 {
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;
263 }
264
265 short wxApp::MacHandleAEOApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
266 {
267 MacNewFile() ;
268 return noErr ;
269 }
270
271 short wxApp::MacHandleAEQuit(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
272 {
273 wxWindow* win = GetTopWindow() ;
274 if ( win )
275 {
276 win->Close(TRUE ) ;
277 }
278 else
279 {
280 ExitMainLoop() ;
281 }
282 return noErr ;
283 }
284
285 char StringMac[] = "\x0d\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
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" ;
291
292 char StringANSI[] = "\x0a\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8"
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" ;
298
299 void wxMacConvertFromPC( const char *from , char *to , int len )
300 {
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 }
332 }
333
334 void wxMacConvertToPC( const char *from , char *to , int len )
335 {
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 }
367 }
368
369 void wxMacConvertFromPC( char * p )
370 {
371 char *ptr = p ;
372 int len = strlen ( p ) ;
373
374 wxMacConvertFromPC( ptr , ptr , len ) ;
375 }
376
377 void wxMacConvertFromPCForControls( char * p )
378 {
379 char *ptr = p ;
380 int len = strlen ( p ) ;
381
382 wxMacConvertFromPC( ptr , ptr , len ) ;
383 for ( unsigned int i = 0 ; i < strlen ( ptr ) ; i++ )
384 {
385 if ( ptr[i] == '&' && ptr[i]+1 != ' ' )
386 {
387 memmove( &ptr[i] , &ptr[i+1] , strlen( &ptr[i+1] ) + 1) ;
388 }
389 }
390 }
391
392 void wxMacConvertFromPC( unsigned char *p )
393 {
394 char *ptr = (char*) p + 1 ;
395 int len = p[0] ;
396
397 wxMacConvertFromPC( ptr , ptr , len ) ;
398 }
399
400 extern char *wxBuffer ;
401
402 wxString wxMacMakeMacStringFromPC( const char * p )
403 {
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 ;
419 }
420
421
422 void wxMacConvertToPC( char * p )
423 {
424 char *ptr = p ;
425 int len = strlen ( p ) ;
426
427 wxMacConvertToPC( ptr , ptr , len ) ;
428 }
429
430 void wxMacConvertToPC( unsigned char *p )
431 {
432 char *ptr = (char*) p + 1 ;
433 int len = p[0] ;
434
435 wxMacConvertToPC( ptr , ptr , len ) ;
436 }
437
438 wxString wxMacMakePCStringFromMac( const char * p )
439 {
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 ;
456 }
457
458 wxString wxMacMakeStringFromMacString( const char* from , bool mac2pcEncoding )
459 {
460 if (mac2pcEncoding)
461 {
462 return wxMacMakePCStringFromMac( from ) ;
463 }
464 else
465 {
466 return wxString( from ) ;
467 }
468 }
469
470 wxString wxMacMakeStringFromPascal( StringPtr from , bool mac2pcEncoding )
471 {
472 // this is safe since a pascal string can never be larger than 256 bytes
473 char s[256] ;
474 CopyPascalStringToC( from , s ) ;
475 if (mac2pcEncoding)
476 {
477 return wxMacMakePCStringFromMac( s ) ;
478 }
479 else
480 {
481 return wxString( s ) ;
482 }
483 }
484
485 void wxMacStringToPascal( const char * from , StringPtr to , bool pc2macEncoding )
486 {
487 if (pc2macEncoding)
488 {
489 CopyCStringToPascal( wxMacMakeMacStringFromPC( from ) , to ) ;
490 }
491 else
492 {
493 CopyCStringToPascal( from , to ) ;
494 }
495 }
496
497 #if defined(WXMAKINGDLL) && !defined(__DARWIN__)
498 // we know it's there ;-)
499 WXIMPORT char std::__throws_bad_alloc ;
500 #endif
501
502 bool wxApp::Initialize()
503 {
504 int error = 0 ;
505
506 // Mac-specific
507
508 UMAInitToolbox( 4 ) ;
509 SetEventMask( everyEvent ) ;
510 UMAShowWatchCursor() ;
511
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
517
518 #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
519 AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
520 NewAEEventHandlerUPP(AEHandleODoc) ,
521 (long) wxTheApp , FALSE ) ;
522 AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
523 NewAEEventHandlerUPP(AEHandleOApp) ,
524 (long) wxTheApp , FALSE ) ;
525 AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
526 NewAEEventHandlerUPP(AEHandlePDoc) ,
527 (long) wxTheApp , FALSE ) ;
528 AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
529 NewAEEventHandlerUPP(AEHandleQuit) ,
530 (long) wxTheApp , FALSE ) ;
531 #else
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 ) ;
544 #endif
545
546 #ifndef __DARWIN__
547 // test the minimal configuration necessary
548
549 # if !TARGET_CARBON
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 }
565 else if ( theSystem < 0x0860 )
566 {
567 error = kMacSTROldSystem ;
568 }
569 else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap)
570 {
571 error = kMacSTRSmallSize;
572 }
573 # endif
574 /*
575 else
576 {
577 if ( !UMAHasAppearance() )
578 {
579 error = kMacSTRNoPre8Yet ;
580 }
581 }
582 */
583 #endif
584
585 // if we encountered any problems so far, give the error code and exit immediately
586
587 if ( error )
588 {
589 wxStAppResource resload ;
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 ;
598 }
599
600 #ifndef __DARWIN__
601 # if __option(profile)
602 ProfilerInit( collectDetailed, bestTimeBase , 20000 , 40 ) ;
603 # endif
604 #endif
605
606 #ifndef __DARWIN__
607 // now avoid exceptions thrown for new (bad_alloc)
608 std::__throws_bad_alloc = FALSE ;
609 #endif
610
611 s_macCursorRgn = ::NewRgn() ;
612
613 wxBuffer = new char[BUFSIZ + 512];
614
615 wxClassInfo::InitializeClasses();
616
617 #if wxUSE_RESOURCES
618 // wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion);
619 #endif
620
621 #if wxUSE_THREADS
622 wxPendingEventsLocker = new wxCriticalSection;
623 #endif
624
625 wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
626 wxTheColourDatabase->Initialize();
627
628 #ifdef __WXDEBUG__
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
639 #endif
640
641 wxWinMacWindowList = new wxList(wxKEY_INTEGER);
642 wxWinMacControlList = new wxList(wxKEY_INTEGER);
643
644 wxInitializeStockLists();
645 wxInitializeStockObjects();
646
647 #if wxUSE_WX_RESOURCES
648 wxInitializeResourceSystem();
649 #endif
650
651 wxBitmap::InitStandardHandlers();
652
653 wxModule::RegisterModules();
654 if (!wxModule::InitializeModules()) {
655 return FALSE;
656 }
657
658 wxMacCreateNotifierTable() ;
659
660
661 UMAShowArrowCursor() ;
662
663 return TRUE;
664 }
665
666 void wxApp::CleanUp()
667 {
668 wxToolTip::RemoveToolTips() ;
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
683 wxModule::CleanUpModules();
684
685 #if wxUSE_WX_RESOURCES
686 wxCleanUpResourceSystem();
687 #endif
688
689 wxDeleteStockObjects() ;
690
691 // Destroy all GDI lists, etc.
692 wxDeleteStockLists();
693
694 delete wxTheColourDatabase;
695 wxTheColourDatabase = NULL;
696
697 wxBitmap::CleanUpHandlers();
698
699 delete[] wxBuffer;
700 wxBuffer = NULL;
701
702 wxMacDestroyNotifierTable() ;
703 if (wxWinMacWindowList) {
704 delete wxWinMacWindowList ;
705 }
706 if (wxWinMacControlList) {
707 delete wxWinMacControlList ;
708 }
709 delete wxPendingEvents;
710
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
717 wxClassInfo::CleanUpClasses();
718
719 #ifndef __DARWIN__
720 # if __option(profile)
721 ProfilerDump( "\papp.prof" ) ;
722 ProfilerTerm() ;
723 # endif
724 #endif
725
726 delete wxTheApp;
727 wxTheApp = NULL;
728
729 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
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);
741 #endif
742
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
747
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
753
754 UMACleanupToolbox() ;
755 if (s_macCursorRgn) {
756 ::DisposeRgn((RgnHandle)s_macCursorRgn);
757 }
758
759 #if 0
760 TerminateAE() ;
761 #endif
762 }
763
764 //----------------------------------------------------------------------
765 // wxEntry
766 //----------------------------------------------------------------------
767
768 // extern variable for shared library resource id
769 // need to be able to find it with NSLookupAndBindSymbol
770 short gSharedLibraryResource = kResFileNotOpened ;
771
772 #if defined(WXMAKINGDLL) && defined(__DARWIN__)
773 CFBundleRef gSharedLibraryBundle = NULL;
774 #endif /* WXMAKINGDLL && __DARWIN__ */
775
776 wxStAppResource::wxStAppResource()
777 {
778 m_currentRefNum = CurResFile() ;
779 if ( gSharedLibraryResource != kResFileNotOpened )
780 {
781 UseResFile( gSharedLibraryResource ) ;
782 }
783 }
784
785 wxStAppResource::~wxStAppResource()
786 {
787 if ( m_currentRefNum != kResFileNotOpened )
788 {
789 UseResFile( m_currentRefNum ) ;
790 }
791 }
792
793 void 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;
801
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 }
808
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
816 NSSymbol theSymbol;
817 NSModule theModule;
818 const char *theLibPath;
819
820 gSharedLibraryBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWindows"));
821 if (gSharedLibraryBundle != NULL) {
822 // wxWindows has been bundled into a framework
823 // load the framework resources
824
825 gSharedLibraryResource = CFBundleOpenBundleResourceMap(gSharedLibraryBundle);
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;
835
836 // get the library path
837 theSymbol = NSLookupAndBindSymbol("_gSharedLibraryResource");
838 theModule = NSModuleForSymbol(theSymbol);
839 theLibPath = NSLibraryNameForModule(theModule);
840
841 wxLogDebug( wxT("wxMac library installation name is '%s'"),
842 theLibPath );
843
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");
856
857 wxLogDebug( wxT("wxMac resources file name is '%s'"),
858 theResPath );
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 }
865
866 // open the resource file
867 if (theErr == noErr) {
868 theErr = FSOpenResourceFile( &theResRef, 0, NULL, fsRdPerm,
869 &gSharedLibraryResource);
870 }
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);
878 }
879 }
880 #endif /* __DARWIN__ */
881 }
882 #endif /* WXMAKINGDLL */
883 }
884
885 void wxStAppResource::CloseSharedLibraryResource()
886 {
887 #ifdef WXMAKINGDLL
888 // Close the shared library resource file
889 if (gSharedLibraryResource != kResFileNotOpened) {
890 #ifdef __DARWIN__
891 if (gSharedLibraryBundle != NULL) {
892 CFBundleCloseBundleResourceMap(gSharedLibraryBundle,
893 gSharedLibraryResource);
894 gSharedLibraryBundle = NULL;
895 }
896 else
897 #endif /* __DARWIN__ */
898 {
899 CloseResFile(gSharedLibraryResource);
900 }
901 gSharedLibraryResource = kResFileNotOpened;
902 }
903 #endif /* WXMAKINGDLL */
904 }
905
906 #if defined(WXMAKINGDLL) && !defined(__DARWIN__)
907
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
911
912 extern "C" {
913 void __sinit(void); /* (generated by linker) */
914 pascal OSErr __initialize(const CFragInitBlock *theInitBlock);
915 pascal void __terminate(void);
916 }
917
918 pascal OSErr __wxinitialize(const CFragInitBlock *theInitBlock)
919 {
920 wxStAppResource::OpenSharedLibraryResource( theInitBlock ) ;
921 return __initialize( theInitBlock ) ;
922 }
923
924 pascal void __wxterminate(void)
925 {
926 wxStAppResource::CloseSharedLibraryResource() ;
927 __terminate() ;
928 }
929
930 #endif /* WXMAKINGDLL && !__DARWIN__ */
931
932 int WXDLLEXPORT wxEntryStart( int WXUNUSED(argc), char *WXUNUSED(argv)[] )
933 {
934 return wxApp::Initialize();
935 }
936
937 int WXDLLEXPORT wxEntryInitGui()
938 {
939 return wxTheApp->OnInitGui();
940 }
941
942 void WXDLLEXPORT wxEntryCleanup()
943 {
944 wxApp::CleanUp();
945 }
946
947 int wxEntry( int argc, char *argv[] , bool enterLoop )
948 {
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
960 if (!wxEntryStart(argc, argv)) {
961 return 0;
962 }
963 // create the application object or ensure that one already exists
964 if (!wxTheApp)
965 {
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.") );
971
972 wxTheApp = (wxApp*) (*wxApp::GetInitializerFunction()) ();
973 }
974
975 wxCHECK_MSG( wxTheApp, 0, wxT("You have to define an instance of wxApp!") );
976
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) {
984 if (strncmp(argv[1], "-psn_", 5) == 0) {
985 // assume the argument is always the only one and remove it
986 --argc;
987 }
988 }
989 #else
990 argc = 0 ; // currently we don't support files as parameters
991 #endif
992 // we could try to get the open apple events here to adjust argc and argv better
993
994 wxTheApp->argc = argc;
995 wxTheApp->argv = argv;
996
997 // GUI-specific initialization, such as creating an app context.
998 wxEntryInitGui();
999
1000 // Here frames insert themselves automatically
1001 // into wxTopLevelWindows by getting created
1002 // in OnInit().
1003
1004 int retValue = 0;
1005
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
1037 wxEntryCleanup();
1038
1039 return retValue;
1040 }
1041
1042 #if TARGET_CARBON
1043
1044 bool 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 ;
1055 switch( GetEventKind(event) )
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 }
1118
1119 return converted ;
1120 }
1121
1122 pascal OSStatus wxMacApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
1123 {
1124 OSStatus result = eventNotHandledErr ;
1125
1126 EventRecord rec ;
1127 switch ( GetEventClass( event ) )
1128 {
1129 case kEventClassKeyboard :
1130 if ( wxMacConvertEventToRecord( event , &rec ) )
1131 {
1132 wxTheApp->MacHandleModifierEvents( &rec ) ;
1133 wxTheApp->MacHandleOneEvent( &rec ) ;
1134 result = noErr ;
1135 }
1136 break ;
1137 case kEventClassTextInput :
1138 if ( wxMacConvertEventToRecord( event , &rec ) )
1139 {
1140 wxTheApp->MacHandleModifierEvents( &rec ) ;
1141 wxTheApp->MacHandleOneEvent( &rec ) ;
1142 result = noErr ;
1143 }
1144 break ;
1145 default :
1146 break ;
1147 }
1148 return result ;
1149 }
1150
1151 #endif
1152
1153 bool wxApp::OnInit()
1154 {
1155 if ( ! wxAppBase::OnInit() )
1156 return FALSE ;
1157
1158 #if 0 // TARGET_CARBON
1159 static const EventTypeSpec eventList[] =
1160 {
1161 { kEventClassKeyboard, kEventRawKeyDown } ,
1162 { kEventClassKeyboard, kEventRawKeyRepeat } ,
1163 { kEventClassKeyboard, kEventRawKeyUp } ,
1164 { kEventClassKeyboard, kEventRawKeyModifiersChanged } ,
1165
1166 { kEventClassTextInput , kEventTextInputUnicodeForKeyEvent } ,
1167 } ;
1168
1169 InstallApplicationEventHandler(NewEventHandlerUPP(wxMacApplicationEventHandler)
1170 , WXSIZEOF(eventList), eventList, this, NULL);
1171 #endif
1172 return TRUE ;
1173 }
1174 // Static member initialization
1175 wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
1176
1177 wxApp::wxApp()
1178 {
1179 m_topWindow = NULL;
1180 wxTheApp = this;
1181
1182 #if WXWIN_COMPATIBILITY_2_2
1183 m_wantDebugOutput = TRUE;
1184 #endif
1185
1186 argc = 0;
1187 argv = NULL;
1188
1189 m_printMode = wxPRINT_WINDOWS;
1190 m_auto3D = TRUE;
1191 }
1192
1193 bool wxApp::Initialized()
1194 {
1195 if (GetTopWindow())
1196 return TRUE;
1197 else
1198 return FALSE;
1199 }
1200
1201 int wxApp::MainLoop()
1202 {
1203 m_keepGoing = TRUE;
1204
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 }
1221
1222 return 0;
1223 }
1224
1225 // Returns TRUE if more time is needed.
1226 bool wxApp::ProcessIdle()
1227 {
1228 wxIdleEvent event;
1229 event.SetEventObject(this);
1230 ProcessEvent(event);
1231
1232 return event.MoreRequested();
1233 }
1234
1235 void wxApp::ExitMainLoop()
1236 {
1237 m_keepGoing = FALSE;
1238 }
1239
1240 // Is a message/event pending?
1241 bool wxApp::Pending()
1242 {
1243 EventRecord event ;
1244
1245 return EventAvail( everyEvent , &event ) ;
1246 }
1247
1248 // Dispatch a message.
1249 void wxApp::Dispatch()
1250 {
1251 MacDoOneEvent() ;
1252 }
1253
1254 void wxApp::OnIdle(wxIdleEvent& event)
1255 {
1256 static bool s_inOnIdle = FALSE;
1257
1258 // Avoid recursion (via ProcessEvent default case)
1259 if ( s_inOnIdle )
1260 return;
1261
1262
1263 s_inOnIdle = TRUE;
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
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;
1285 }
1286
1287 void wxWakeUpIdle()
1288 {
1289 wxMacWakeUp() ;
1290 }
1291
1292 // Send idle event to all top-level windows
1293 bool wxApp::SendIdleEvents()
1294 {
1295 bool needMore = FALSE;
1296 wxNode* node = wxTopLevelWindows.First();
1297 while (node)
1298 {
1299 wxWindow* win = (wxWindow*) node->Data();
1300 if (SendIdleEvents(win))
1301 needMore = TRUE;
1302
1303 node = node->Next();
1304 }
1305 return needMore;
1306 }
1307
1308 // Send idle event to window and all subwindows
1309 bool wxApp::SendIdleEvents(wxWindow* win)
1310 {
1311 bool needMore = FALSE;
1312
1313 wxIdleEvent event;
1314 event.SetEventObject(win);
1315 win->ProcessEvent(event);
1316
1317 if (event.MoreRequested())
1318 needMore = TRUE;
1319
1320 wxNode* node = win->GetChildren().First();
1321 while (node)
1322 {
1323 wxWindow* win = (wxWindow*) node->Data();
1324 if (SendIdleEvents(win))
1325 needMore = TRUE;
1326
1327 node = node->Next();
1328 }
1329 return needMore ;
1330 }
1331
1332 void wxApp::DeletePendingObjects()
1333 {
1334 wxNode *node = wxPendingDelete.First();
1335 while (node)
1336 {
1337 wxObject *obj = (wxObject *)node->Data();
1338
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
1350 void wxExit()
1351 {
1352 wxLogError(_("Fatal error: exiting"));
1353
1354 wxApp::CleanUp();
1355 ::ExitToShell() ;
1356 }
1357
1358 void 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.
1366 void wxApp::OnQueryEndSession(wxCloseEvent& event)
1367 {
1368 if (GetTopWindow())
1369 {
1370 if (!GetTopWindow()->Close(!event.CanVeto()))
1371 event.Veto(TRUE);
1372 }
1373 }
1374
1375 extern "C" void wxCYield() ;
1376 void wxCYield()
1377 {
1378 wxYield() ;
1379 }
1380
1381 // Yield to other processes
1382
1383 bool wxApp::Yield(bool onlyIfNeeded)
1384 {
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;
1396
1397 #if wxUSE_THREADS
1398 YieldToAnyThread() ;
1399 #endif
1400 EventRecord event ;
1401
1402 long sleepTime = 1 ; //::GetCaretTime();
1403
1404 while ( !wxTheApp->IsExiting() && WaitNextEvent(everyEvent, &event,sleepTime, (RgnHandle) wxApp::s_macCursorRgn))
1405 {
1406 wxTheApp->MacHandleModifierEvents( &event ) ;
1407 wxTheApp->MacHandleOneEvent( &event );
1408 if ( event.what != kHighLevelEvent )
1409 SetRectRgn( (RgnHandle) wxApp::s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ;
1410 }
1411 wxTheApp->MacHandleModifierEvents( &event ) ;
1412
1413 wxMacProcessNotifierAndPendingEvents() ;
1414
1415 s_inYield = FALSE;
1416
1417 return TRUE;
1418 }
1419
1420 // platform specifics
1421
1422 void wxApp::MacSuspend( bool convertClipboard )
1423 {
1424 // we have to deactive the top level windows manually
1425
1426 wxNode* node = wxTopLevelWindows.First();
1427 while (node)
1428 {
1429 wxTopLevelWindow* win = (wxTopLevelWindow*) node->Data();
1430 win->MacActivate( MacGetCurrentEvent() , false ) ;
1431
1432 node = node->Next();
1433 }
1434
1435 s_lastMouseDown = 0 ;
1436 if( convertClipboard )
1437 {
1438 MacConvertPrivateToPublicScrap() ;
1439 }
1440
1441 ::HideFloatingWindows() ;
1442 }
1443
1444 extern wxList wxModalDialogs;
1445
1446 void wxApp::MacResume( bool convertClipboard )
1447 {
1448 s_lastMouseDown = 0 ;
1449 if( convertClipboard )
1450 {
1451 MacConvertPublicToPrivateScrap() ;
1452 }
1453
1454 ::ShowFloatingWindows() ;
1455
1456 // raise modal dialogs in case a non modal window was selected to activate the app
1457
1458 wxNode* node = wxModalDialogs.First();
1459 while (node)
1460 {
1461 wxDialog* dialog = (wxDialog *) node->Data();
1462 dialog->Raise();
1463
1464 node = node->Next();
1465 }
1466 }
1467
1468 void wxApp::MacConvertPrivateToPublicScrap()
1469 {
1470 }
1471
1472 void wxApp::MacConvertPublicToPrivateScrap()
1473 {
1474 }
1475
1476 void wxApp::MacDoOneEvent()
1477 {
1478 EventRecord event ;
1479
1480 long sleepTime = 1; // GetCaretTime() / 4 ;
1481
1482 if (WaitNextEvent(everyEvent, &event, sleepTime, (RgnHandle) s_macCursorRgn))
1483 {
1484 MacHandleModifierEvents( &event ) ;
1485 MacHandleOneEvent( &event );
1486 }
1487 else
1488 {
1489 MacHandleModifierEvents( &event ) ;
1490 // idlers
1491 WindowPtr window = ::FrontWindow() ;
1492 if ( window )
1493 ::IdleControls( window ) ;
1494
1495 wxTheApp->ProcessIdle() ;
1496 }
1497 if ( event.what != kHighLevelEvent )
1498 SetRectRgn( (RgnHandle) s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ;
1499
1500 // repeaters
1501
1502 DeletePendingObjects() ;
1503 wxMacProcessNotifierAndPendingEvents() ;
1504 }
1505
1506 void wxApp::MacHandleModifierEvents( WXEVENTREF evr )
1507 {
1508 EventRecord* ev = (EventRecord*) evr ;
1509 #if TARGET_CARBON
1510 if ( ev->what == mouseDown || ev->what == mouseUp || ev->what == activateEvt ||
1511 ev->what == keyDown || ev->what == autoKey || ev->what == keyUp || ev->what == kHighLevelEvent ||
1512 ev->what == nullEvent
1513 )
1514 {
1515 // in these cases the modifiers are already correctly setup by carbon
1516 }
1517 else
1518 {
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() ;
1524 }
1525 #endif
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);
1540
1541 if ( (ev->modifiers ^ s_lastModifiers ) & controlKey )
1542 {
1543 event.m_keyCode = WXK_CONTROL ;
1544 event.SetEventType( ( ev->modifiers & controlKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
1545 focus->GetEventHandler()->ProcessEvent( event ) ;
1546 }
1547 if ( (ev->modifiers ^ s_lastModifiers ) & shiftKey )
1548 {
1549 event.m_keyCode = WXK_SHIFT ;
1550 event.SetEventType( ( ev->modifiers & shiftKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
1551 focus->GetEventHandler()->ProcessEvent( event ) ;
1552 }
1553 if ( (ev->modifiers ^ s_lastModifiers ) & optionKey )
1554 {
1555 event.m_keyCode = WXK_ALT ;
1556 event.SetEventType( ( ev->modifiers & optionKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
1557 focus->GetEventHandler()->ProcessEvent( event ) ;
1558 }
1559 s_lastModifiers = ev->modifiers ;
1560 }
1561 }
1562
1563 void wxApp::MacHandleOneEvent( WXEVENTREF evr )
1564 {
1565 EventRecord* ev = (EventRecord*) evr ;
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() ;
1617 }
1618
1619 void wxApp::MacHandleHighLevelEvent( WXEVENTREF evr )
1620 {
1621 // we must avoid reentrancy problems when processing high level events eg printing
1622 bool former = s_inYield ;
1623 s_inYield = TRUE ;
1624 EventRecord* ev = (EventRecord*) evr ;
1625 ::AEProcessAppleEvent( ev ) ;
1626 s_inYield = former ;
1627 }
1628
1629 bool s_macIsInModalLoop = false ;
1630
1631 void wxApp::MacHandleMouseDownEvent( WXEVENTREF evr )
1632 {
1633 EventRecord* ev = (EventRecord*) evr ;
1634 wxToolTip::RemoveToolTips() ;
1635
1636 WindowRef window;
1637 WindowRef frontWindow = ::FrontNonFloatingWindow() ;
1638 WindowAttributes frontWindowAttributes = NULL ;
1639 if ( frontWindow )
1640 ::GetWindowAttributes( frontWindow , &frontWindowAttributes ) ;
1641
1642 short windowPart = ::FindWindow(ev->where, &window);
1643 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
1644 if ( wxPendingDelete.Member(win) )
1645 return ;
1646
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 ;
1664 #if !TARGET_CARBON
1665 case inSysWindow :
1666 SystemClick( ev , window ) ;
1667 s_lastMouseDown = 0;
1668 break ;
1669 #endif
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 } ;
1683 SetPortWindowPort(window) ;
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 {
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 )
1720 {
1721 win->SetSize( newContentRect.left , newContentRect.top ,
1722 newContentRect.right - newContentRect.left ,
1723 newContentRect.bottom - newContentRect.top, wxSIZE_USE_EXISTING);
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 ;
1737 GrafPtr port ;
1738 GetPort( &port ) ;
1739 Point pt = { 0, 0 } ;
1740 SetPortWindowPort(window) ;
1741 LocalToGlobal( &pt ) ;
1742 SetPort( port ) ;
1743
1744 GetWindowPortBounds(window, &tempRect ) ;
1745 win->SetSize( pt.h , pt.v , tempRect.right-tempRect.left ,
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 ) ;
1760 SetPortWindowPort(window) ;
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 ) ;
1778 ::SelectWindow( window ) ;
1779 }
1780 }
1781 else
1782 {
1783 if ( win )
1784 win->MacMouseDown( ev , windowPart ) ;
1785 }
1786 break ;
1787
1788 default:
1789 break;
1790 }
1791 }
1792
1793 void wxApp::MacHandleMouseUpEvent( WXEVENTREF evr )
1794 {
1795 EventRecord* ev = (EventRecord*) evr ;
1796 WindowRef window;
1797
1798 short windowPart = inNoWindow ;
1799 if ( wxTheApp->s_captureWindow )
1800 {
1801 window = (WindowRef) s_captureWindow->MacGetRootWindow() ;
1802 windowPart = inContent ;
1803 }
1804 else
1805 {
1806 windowPart = ::FindWindow(ev->where, &window) ;
1807 }
1808
1809 switch (windowPart)
1810 {
1811 case inMenuBar :
1812 break ;
1813 case inSysWindow :
1814 break ;
1815 default:
1816 {
1817 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
1818 if ( win )
1819 win->MacMouseUp( ev , windowPart ) ;
1820 }
1821 break;
1822 }
1823 }
1824
1825 long wxMacTranslateKey(unsigned char key, unsigned char code) ;
1826 long wxMacTranslateKey(unsigned char key, unsigned char code)
1827 {
1828 long retval = key ;
1829 switch (key)
1830 {
1831 case kHomeCharCode :
1832 retval = WXK_HOME;
1833 break;
1834 case kEnterCharCode :
1835 retval = WXK_RETURN;
1836 break;
1837 case kEndCharCode :
1838 retval = WXK_END;
1839 break;
1840 case kHelpCharCode :
1841 retval = WXK_HELP;
1842 break;
1843 case kBackspaceCharCode :
1844 retval = WXK_BACK;
1845 break;
1846 case kTabCharCode :
1847 retval = WXK_TAB;
1848 break;
1849 case kPageUpCharCode :
1850 retval = WXK_PAGEUP;
1851 break;
1852 case kPageDownCharCode :
1853 retval = WXK_PAGEDOWN;
1854 break;
1855 case kReturnCharCode :
1856 retval = WXK_RETURN;
1857 break;
1858 case kFunctionKeyCharCode :
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 ;
1910 case kEscapeCharCode :
1911 retval = WXK_ESCAPE ;
1912 break ;
1913 case kLeftArrowCharCode :
1914 retval = WXK_LEFT ;
1915 break ;
1916 case kRightArrowCharCode :
1917 retval = WXK_RIGHT ;
1918 break ;
1919 case kUpArrowCharCode :
1920 retval = WXK_UP ;
1921 break ;
1922 case kDownArrowCharCode :
1923 retval = WXK_DOWN ;
1924 break ;
1925 case kDeleteCharCode :
1926 retval = WXK_DELETE ;
1927 default:
1928 break ;
1929 } // end switch
1930
1931 return retval;
1932 }
1933
1934 void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr )
1935 {
1936 EventRecord* ev = (EventRecord*) evr ;
1937 wxToolTip::RemoveToolTips() ;
1938
1939 UInt32 menuresult = UMAMenuEvent(ev) ;
1940 if ( HiWord( menuresult ) )
1941 {
1942 if ( !s_macIsInModalLoop )
1943 MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ) ;
1944 }
1945 else
1946 {
1947 wxWindow* focus = wxWindow::FindFocus() ;
1948
1949 if ( MacSendKeyDownEvent( focus , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) == false )
1950 {
1951 // has not been handled -> perform default
1952 wxControl* control = wxDynamicCast( focus , wxControl ) ;
1953 if ( control && control->GetMacControl() != NULL )
1954 {
1955 short keycode ;
1956 short keychar ;
1957 keychar = short(ev->message & charCodeMask);
1958 keycode = short(ev->message & keyCodeMask) >> 8 ;
1959 ::HandleControlKey( (ControlHandle) control->GetMacControl() , keycode , keychar , ev->modifiers ) ;
1960 }
1961 }
1962 }
1963 }
1964
1965 bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey )
1966 {
1967 if ( !focus )
1968 return false ;
1969
1970 short keycode ;
1971 short keychar ;
1972 keychar = short(keymessage & charCodeMask);
1973 keycode = short(keymessage & keyCodeMask) >> 8 ;
1974
1975 if ( modifiers & ( controlKey|shiftKey|optionKey ) )
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;
1980 UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state);
1981 keychar = short(keyInfo & charCodeMask);
1982 keycode = short(keyInfo & keyCodeMask) >> 8 ;
1983 }
1984 long keyval = wxMacTranslateKey(keychar, keycode) ;
1985 long realkeyval = keyval ;
1986 if ( keyval == keychar )
1987 {
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)
1989 realkeyval = short(keymessage & charCodeMask) ;
1990 keyval = wxToupper( keyval ) ;
1991 }
1992
1993 wxKeyEvent event(wxEVT_KEY_DOWN);
1994 bool handled = false ;
1995 event.m_shiftDown = modifiers & shiftKey;
1996 event.m_controlDown = modifiers & controlKey;
1997 event.m_altDown = modifiers & optionKey;
1998 event.m_metaDown = modifiers & cmdKey;
1999 event.m_keyCode = keyval ;
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 {
2010 #if wxUSE_ACCEL
2011 if (!handled)
2012 {
2013 wxWindow *ancestor = focus;
2014 while (ancestor)
2015 {
2016 int command = ancestor->GetAcceleratorTable()->GetCommand( event );
2017 if (command != -1)
2018 {
2019 wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
2020 handled = ancestor->GetEventHandler()->ProcessEvent( command_event );
2021 break;
2022 }
2023 if (ancestor->IsTopLevel())
2024 break;
2025 ancestor = ancestor->GetParent();
2026 }
2027 }
2028 #endif // wxUSE_ACCEL
2029 }
2030 if (!handled)
2031 {
2032 event.Skip( FALSE ) ;
2033 event.SetEventType( wxEVT_CHAR ) ;
2034 // raw value again
2035 event.m_keyCode = realkeyval ;
2036
2037 handled = focus->GetEventHandler()->ProcessEvent( event ) ;
2038 if ( handled && event.GetSkipped() )
2039 handled = false ;
2040 }
2041 if ( !handled &&
2042 (keyval == WXK_TAB) &&
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
2048 (!focus->HasFlag(wxTE_PROCESS_TAB)) &&
2049 #endif
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() ) ;
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);
2080 return true ;
2081 }
2082 }
2083 /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
2084 else if (keyval == WXK_ESCAPE || (keyval == '.' && modifiers & cmdKey ) )
2085 {
2086 wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL);
2087 new_event.SetEventObject( focus );
2088 handled = focus->GetEventHandler()->ProcessEvent( new_event );
2089 }
2090 }
2091 }
2092 return handled ;
2093 }
2094
2095
2096 void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr )
2097 {
2098 EventRecord* ev = (EventRecord*) evr ;
2099 wxToolTip::RemoveToolTips() ;
2100
2101 UInt32 menuresult = UMAMenuEvent(ev) ;
2102 if ( HiWord( menuresult ) )
2103 {
2104 }
2105 else
2106 {
2107 MacSendKeyUpEvent( wxWindow::FindFocus() , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) ;
2108 }
2109 }
2110
2111 bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey )
2112 {
2113 if ( !focus )
2114 return false ;
2115
2116 short keycode ;
2117 short keychar ;
2118 keychar = short(keymessage & charCodeMask);
2119 keycode = short(keymessage & keyCodeMask) >> 8 ;
2120 if ( modifiers & ( controlKey|shiftKey|optionKey ) )
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;
2125 UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state);
2126 keychar = short(keyInfo & charCodeMask);
2127 keycode = short(keyInfo & keyCodeMask) >> 8 ;
2128 }
2129 long keyval = wxMacTranslateKey(keychar, keycode) ;
2130
2131 if ( keyval == keychar )
2132 {
2133 keyval = wxToupper( keyval ) ;
2134 }
2135 bool handled = false ;
2136
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;
2142 event.m_keyCode = keyval ;
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
2150 return handled ;
2151 }
2152 void wxApp::MacHandleActivateEvent( WXEVENTREF evr )
2153 {
2154 EventRecord* ev = (EventRecord*) evr ;
2155 WindowRef window = (WindowRef) ev->message ;
2156 if ( window )
2157 {
2158 bool activate = (ev->modifiers & activeFlag ) ;
2159 WindowClass wclass ;
2160 ::GetWindowClass ( window , &wclass ) ;
2161 if ( wclass == kFloatingWindowClass )
2162 {
2163 // if it is a floater we activate/deactivate the front non-floating window instead
2164 window = ::FrontNonFloatingWindow() ;
2165 }
2166 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
2167 if ( win )
2168 win->MacActivate( ev , activate ) ;
2169 }
2170 }
2171
2172 void wxApp::MacHandleUpdateEvent( WXEVENTREF evr )
2173 {
2174 EventRecord* ev = (EventRecord*) evr ;
2175 WindowRef window = (WindowRef) ev->message ;
2176 wxTopLevelWindowMac * win = wxFindWinFromMacWindow( window ) ;
2177 if ( win )
2178 {
2179 if ( !wxPendingDelete.Member(win) )
2180 win->MacUpdate( ev->when ) ;
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 }
2190 }
2191
2192 void wxApp::MacHandleDiskEvent( WXEVENTREF evr )
2193 {
2194 EventRecord* ev = (EventRecord*) evr ;
2195 if ( HiWord( ev->message ) != noErr )
2196 {
2197 #if !TARGET_CARBON
2198 OSErr err ;
2199 Point point ;
2200 SetPt( &point , 100 , 100 ) ;
2201
2202 err = DIBadMount( point , ev->message ) ;
2203 wxASSERT( err == noErr ) ;
2204 #endif
2205 }
2206 }
2207
2208 void wxApp::MacHandleOSEvent( WXEVENTREF evr )
2209 {
2210 EventRecord* ev = (EventRecord*) evr ;
2211 switch( ( ev->message & osEvtMessageMask ) >> 24 )
2212 {
2213 case suspendResumeMessage :
2214 {
2215 bool isResuming = ev->message & resumeFlag ;
2216 #if !TARGET_CARBON
2217 bool convertClipboard = ev->message & convertClipboardFlag ;
2218 #else
2219 bool convertClipboard = false;
2220 #endif
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 )
2231 oldFrontWindow = ::FrontNonFloatingWindow() ;
2232
2233 MacResume( convertClipboard ) ;
2234
2235 newFrontWindow = ::FrontNonFloatingWindow() ;
2236
2237 if ( oldFrontWindow )
2238 {
2239 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( oldFrontWindow ) ;
2240 if ( win )
2241 win->MacActivate( ev , false ) ;
2242 }
2243 if ( newFrontWindow )
2244 {
2245 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( newFrontWindow ) ;
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
2257 /* TODO : find out what to do on systems < 10 , perhaps FrontNonFloatingWindow
2258 WindowRef newActiveWindow = ::ActiveNonFloatingWindow() ;
2259 if ( newActiveWindow )
2260 {
2261 wxWindow* win = wxFindWinFromMacWindow( newActiveWindow ) ;
2262 if ( win )
2263 win->MacActivate( ev , false ) ;
2264 }
2265 */
2266 }
2267 }
2268 break ;
2269 case mouseMovedMessage :
2270 {
2271 WindowRef window;
2272
2273 wxWindow* currentMouseWindow = NULL ;
2274
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
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);
2303
2304 if ( wxWindow::s_lastMouseWindow )
2305 {
2306 wxMouseEvent eventleave(event);
2307 eventleave.SetEventType( wxEVT_LEAVE_WINDOW );
2308 wxWindow::s_lastMouseWindow->ScreenToClient( &eventleave.m_x, &eventleave.m_y );
2309 eventleave.SetEventObject( wxWindow::s_lastMouseWindow ) ;
2310
2311 wxWindow::s_lastMouseWindow->GetEventHandler()->ProcessEvent(eventleave);
2312 }
2313 if ( currentMouseWindow )
2314 {
2315 wxMouseEvent evententer(event);
2316 evententer.SetEventType( wxEVT_ENTER_WINDOW );
2317 currentMouseWindow->ScreenToClient( &evententer.m_x, &evententer.m_y );
2318 evententer.SetEventObject( currentMouseWindow ) ;
2319 currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
2320 }
2321 wxWindow::s_lastMouseWindow = currentMouseWindow ;
2322 }
2323
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
2336 switch (windowPart)
2337 {
2338 case inContent :
2339 {
2340 wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
2341 if ( win )
2342 win->MacMouseMoved( ev , windowPart ) ;
2343 else
2344 {
2345 if ( wxIsBusy() )
2346 {
2347 }
2348 else
2349 UMAShowArrowCursor();
2350 }
2351 }
2352 break;
2353 default :
2354 {
2355 if ( wxIsBusy() )
2356 {
2357 }
2358 else
2359 UMAShowArrowCursor();
2360 }
2361 break ;
2362 }
2363 }
2364 break ;
2365
2366 }
2367 }
2368
2369 void wxApp::MacHandleMenuSelect( int macMenuId , int macMenuItemNum )
2370 {
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 {
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 /*
2406 wxWindow* frontwindow = wxFindWinFromMacWindow( ::FrontWindow() ) ;
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 */
2413 }
2414 HiliteMenu(0);
2415 }