]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/app.cpp
CW5.2 Pro Adaptions, wxMac starting to move in
[wxWidgets.git] / src / mac / carbon / app.cpp
CommitLineData
e9576ca5
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: app.cpp
3// Purpose: wxApp
4// Author: AUTHOR
5// Modified by:
6// Created: ??/??/98
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "app.h"
14#endif
15
16#include "wx/frame.h"
17#include "wx/app.h"
18#include "wx/utils.h"
19#include "wx/gdicmn.h"
20#include "wx/pen.h"
21#include "wx/brush.h"
22#include "wx/cursor.h"
23#include "wx/icon.h"
24#include "wx/palette.h"
25#include "wx/dc.h"
26#include "wx/dialog.h"
27#include "wx/msgdlg.h"
28#include "wx/log.h"
29#include "wx/module.h"
30#include "wx/memory.h"
31
32#if wxUSE_WX_RESOURCES
33#include "wx/resource.h"
34#endif
35
36#include <string.h>
37
8be97d65
SC
38// mac
39
519cb848
SC
40#if __option(profile)
41 #include <profiler.h>
42#endif
43
8be97d65
SC
44#include "apprsrc.h"
45
519cb848
SC
46#include <wx/mac/uma.h>
47
e9576ca5
SC
48extern char *wxBuffer;
49extern wxList wxPendingDelete;
519cb848
SC
50extern wxList *wxWinMacWindowList;
51extern wxList *wxWinMacControlList;
e9576ca5
SC
52
53wxApp *wxTheApp = NULL;
54
55#if !USE_SHARED_LIBRARY
56IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
57BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
58 EVT_IDLE(wxApp::OnIdle)
59END_EVENT_TABLE()
60#endif
61
169935ad 62
8be97d65
SC
63const short kMacMinHeap = (29 * 1024) ;
64// platform specific static variables
169935ad 65
519cb848
SC
66const short kwxMacMenuBarResource = 1 ;
67const short kwxMacAppleMenuId = 1 ;
68
69RgnHandle wxApp::s_macCursorRgn = NULL;
70wxWindow* wxApp::s_captureWindow = NULL ;
71int wxApp::s_lastMouseDown = 0 ;
72long wxApp::sm_lastMessageTime = 0;
73
74#ifdef __WXMAC__
75
76bool wxApp::s_macDefaultEncodingIsPC = true ;
77bool wxApp::s_macSupportPCMenuShortcuts = true ;
78long wxApp::s_macAboutMenuItemId = wxID_ABOUT ;
79wxString wxApp::s_macHelpMenuTitleName = "&Help" ;
80
81OSErr AEHandleODoc( AppleEvent *event , AppleEvent *reply , long refcon )
82{
83 wxApp* app = (wxApp*) refcon ;
84 return wxTheApp->MacHandleAEODoc( event , reply) ;
85}
86
87OSErr AEHandleOApp( AppleEvent *event , AppleEvent *reply , long refcon )
88{
89 wxApp* app = (wxApp*) refcon ;
90 return wxTheApp->MacHandleAEOApp( event , reply ) ;
91}
92
93OSErr AEHandlePDoc( AppleEvent *event , AppleEvent *reply , long refcon )
94{
95 wxApp* app = (wxApp*) refcon ;
96 return wxTheApp->MacHandleAEPDoc( event , reply ) ;
97}
98
99OSErr AEHandleQuit( AppleEvent *event , AppleEvent *reply , long refcon )
100{
101 wxApp* app = (wxApp*) refcon ;
102 return wxTheApp->MacHandleAEQuit( event , reply) ;
103}
104
105OSErr wxApp::MacHandleAEODoc(AppleEvent *event , AppleEvent *reply)
106{
107 ProcessSerialNumber PSN ;
108 PSN.highLongOfPSN = 0 ;
109 PSN.lowLongOfPSN = kCurrentProcess ;
110 SetFrontProcess( &PSN ) ;
111 return noErr ;
112}
113
114OSErr wxApp::MacHandleAEPDoc(AppleEvent *event , AppleEvent *reply)
115{
116 return noErr ;
117}
118
119OSErr wxApp::MacHandleAEOApp(AppleEvent *event , AppleEvent *reply)
120{
121 return noErr ;
122}
123
124OSErr wxApp::MacHandleAEQuit(AppleEvent *event , AppleEvent *reply)
125{
126 wxWindow* win = GetTopWindow() ;
127 if ( win )
128 {
129 win->Close(TRUE ) ;
130 }
131 else
132 {
133 ExitMainLoop() ;
134 }
135 return noErr ;
136}
137
138char StringMac[] = "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
139 "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
140 "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf"
141 "\xb1\xb4\xb5\xb6\xbb\xbc\xbe\xbf"
142 "\xc0\xc1\xc2\xc4\xc7\xc8\xc9\xcb\xcc\xcd\xce\xcf"
143 "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xca\xdb" ;
144
145char StringANSI[] = "\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8"
146 "\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC"
147 "\x86\xBA\xA2\xA3\xA7\x95\xB6\xDF\xAE\xA9\x99\xB4\xA8\xC6\xD8"
148 "\xB1\xA5\xB5\xF0\xAA\xBA\xE6\xF8"
149 "\xBF\xA1\xAC\x83\xAB\xBB\x85\xC0\xC3\xD5\x8C\x9C"
150 "\x96\x97\x93\x94\x91\x92\xF7\xFF\xA0\x80" ;
151
152void wxMacConvertFromPC( const char *from , char *to , int len )
153{
154 char *c ;
155 if ( from == to )
156 {
157 for( int i = 0 ; i < len ; ++ i )
158 {
159 c = strchr( StringANSI , *from ) ;
160 if ( c != NULL )
161 {
162 *to = StringMac[ c - StringANSI] ;
163 }
164 ++to ;
165 ++from ;
166 }
167 }
168 else
169 {
170 for( int i = 0 ; i < len ; ++ i )
171 {
172 c = strchr( StringANSI , *from ) ;
173 if ( c != NULL )
174 {
175 *to = StringMac[ c - StringANSI] ;
176 }
177 else
178 {
179 *to = *from ;
180 }
181 ++to ;
182 ++from ;
183 }
184 }
185}
186
187void wxMacConvertToPC( const char *from , char *to , int len )
188{
189 char *c ;
190 if ( from == to )
191 {
192 for( int i = 0 ; i < len ; ++ i )
193 {
194 c = strchr( StringMac , *from ) ;
195 if ( c != NULL )
196 {
197 *to = StringANSI[ c - StringMac] ;
198 }
199 ++to ;
200 ++from ;
201 }
202 }
203 else
204 {
205 for( int i = 0 ; i < len ; ++ i )
206 {
207 c = strchr( StringMac , *from ) ;
208 if ( c != NULL )
209 {
210 *to = StringANSI[ c - StringMac] ;
211 }
212 else
213 {
214 *to = *from ;
215 }
216 ++to ;
217 ++from ;
218 }
219 }
220}
221
222void wxMacConvertFromPC( char * p )
223{
224 char *ptr = p ;
225 int len = strlen ( p ) ;
226
227 wxMacConvertFromPC( ptr , ptr , len ) ;
228}
229
230void wxMacConvertFromPCForControls( char * p )
231{
232 char *ptr = p ;
233 int len = strlen ( p ) ;
234
235 wxMacConvertFromPC( ptr , ptr , len ) ;
236 for ( int i = 0 ; i < strlen ( ptr ) ; i++ )
237 {
238 if ( ptr[i] == '&' && ptr[i]+1 != ' ' )
239 {
240 memmove( &ptr[i] , &ptr[i+1] , strlen( &ptr[i+1] ) + 1) ;
241 }
242 }
243}
244
245void wxMacConvertFromPC( unsigned char *p )
246{
247 char *ptr = (char*) p + 1 ;
248 int len = p[0] ;
249
250 wxMacConvertFromPC( ptr , ptr , len ) ;
251}
252
253extern char *wxBuffer ;
254
255wxString wxMacMakeMacStringFromPC( const char * p )
256{
257 const char *ptr = p ;
258 int len = strlen ( p ) ;
259 char *buf = wxBuffer ;
260
261 if ( len >= BUFSIZ + 512 )
262 {
263 buf = new char [len+1] ;
264 }
265
266 wxMacConvertFromPC( ptr , buf , len ) ;
267 buf[len] = 0 ;
268 wxString result( buf ) ;
269 if ( buf != wxBuffer )
270 delete buf ;
271 return result ;
272}
273
274
275void wxMacConvertToPC( char * p )
276{
277 char *ptr = p ;
278 int len = strlen ( p ) ;
279
280 wxMacConvertToPC( ptr , ptr , len ) ;
281}
282
283void wxMacConvertToPC( unsigned char *p )
284{
285 char *ptr = (char*) p + 1 ;
286 int len = p[0] ;
287
288 wxMacConvertToPC( ptr , ptr , len ) ;
289}
290
291wxString wxMacMakePCStringFromMac( const char * p )
292{
293 const char *ptr = p ;
294 int len = strlen ( p ) ;
295 char *buf = wxBuffer ;
296
297 if ( len >= BUFSIZ + 512 )
298 {
299 buf = new char [len+1] ;
300 }
301
302 wxMacConvertToPC( ptr , buf , len ) ;
303 buf[len] = 0 ;
304
305 wxString result( buf ) ;
306 if ( buf != wxBuffer )
307 delete buf ;
308 return result ;
309}
169935ad 310
519cb848 311#endif
e9576ca5
SC
312
313bool wxApp::Initialize()
314{
169935ad
SC
315 int error = 0 ;
316
8be97d65 317 // Mac-specific
8be97d65 318
519cb848
SC
319 UMAInitToolbox( 4 ) ;
320 UMAShowWatchCursor() ;
8be97d65 321
519cb848
SC
322 AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments , NewAEEventHandlerProc(AEHandleODoc) , (long) wxTheApp , FALSE ) ;
323 AEInstallEventHandler( kCoreEventClass , kAEOpenApplication , NewAEEventHandlerProc(AEHandleOApp) , (long) wxTheApp , FALSE ) ;
324 AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments , NewAEEventHandlerProc(AEHandlePDoc) , (long) wxTheApp , FALSE ) ;
325 AEInstallEventHandler( kCoreEventClass , kAEQuitApplication , NewAEEventHandlerProc(AEHandleQuit) , (long) wxTheApp , FALSE ) ;
8be97d65 326#if 0
8be97d65
SC
327 GUSISetup(GUSIwithInternetSockets);
328#endif
329
519cb848 330
8be97d65
SC
331 // test the minimal configuration necessary
332
333 long theSystem ;
334 long theMachine;
8be97d65
SC
335
336 if (Gestalt(gestaltMachineType, &theMachine) != noErr)
337 {
338 error = kMacSTRWrongMachine;
339 }
340 else if (theMachine < gestaltMacPlus)
341 {
342 error = kMacSTRWrongMachine;
343 }
344 else if (Gestalt(gestaltSystemVersion, &theSystem) != noErr )
345 {
346 error = kMacSTROldSystem ;
347 }
519cb848 348 else if ( theSystem < 0x0750 )
8be97d65
SC
349 {
350 error = kMacSTROldSystem ;
351 }
519cb848 352 #if !TARGET_CARBON
8be97d65
SC
353 else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap)
354 {
355 error = kMacSTRSmallSize;
356 }
519cb848
SC
357 #endif
358 /*
8be97d65
SC
359 else
360 {
519cb848 361 if ( !UMAHasAppearance() )
8be97d65 362 {
8be97d65 363 error = kMacSTRNoPre8Yet ;
519cb848 364 }
8be97d65 365 }
519cb848 366 */
8be97d65
SC
367
368 // if we encountered any problems so far, give the error code and exit immediately
369
169935ad 370 if ( error )
8be97d65
SC
371 {
372 short itemHit;
373 Str255 message;
519cb848 374
8be97d65 375 GetIndString(message, 128, error);
519cb848
SC
376 UMAShowArrowCursor() ;
377 ParamText("\pFatal Error", message, (ConstStr255Param)"\p", (ConstStr255Param)"\p");
378 itemHit = Alert(128, nil);
8be97d65 379 return FALSE ;
169935ad 380 }
519cb848
SC
381
382#if __option(profile)
383 ProfilerInit( collectDetailed, bestTimeBase , 20000 , 30 ) ;
384#endif
385
8be97d65
SC
386 // now avoid exceptions thrown for new (bad_alloc)
387
388 std::__throws_bad_alloc = FALSE ;
389
519cb848 390 s_macCursorRgn = ::NewRgn() ;
8be97d65 391
e9576ca5
SC
392#ifdef __WXMSW__
393 wxBuffer = new char[1500];
394#else
395 wxBuffer = new char[BUFSIZ + 512];
396#endif
397
398/* No longer used
399#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
400
401 streambuf* sBuf = new wxDebugStreamBuf;
402 ostream* oStr = new ostream(sBuf) ;
403 wxDebugContext::SetStream(oStr, sBuf);
404#endif
405*/
406
407 wxClassInfo::InitializeClasses();
408
409 wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
410 wxTheColourDatabase->Initialize();
411
412 wxInitializeStockLists();
413 wxInitializeStockObjects();
414
415#if wxUSE_WX_RESOURCES
416 wxInitializeResourceSystem();
417#endif
418
419 wxBitmap::InitStandardHandlers();
420
421 wxModule::RegisterModules();
519cb848
SC
422 if (!wxModule::InitializeModules())
423 return FALSE;
e9576ca5 424
519cb848
SC
425 wxWinMacWindowList = new wxList(wxKEY_INTEGER);
426 wxWinMacControlList = new wxList(wxKEY_INTEGER);
427
428 UMAShowArrowCursor() ;
429
e9576ca5
SC
430 return TRUE;
431}
432
433void wxApp::CleanUp()
434{
435 wxModule::CleanUpModules();
436
437#if wxUSE_WX_RESOURCES
438 wxCleanUpResourceSystem();
439#endif
440
441 wxDeleteStockObjects() ;
442
443 // Destroy all GDI lists, etc.
444
445 delete wxTheBrushList;
446 wxTheBrushList = NULL;
447
448 delete wxThePenList;
449 wxThePenList = NULL;
450
451 delete wxTheFontList;
452 wxTheFontList = NULL;
453
454 delete wxTheBitmapList;
455 wxTheBitmapList = NULL;
456
457 delete wxTheColourDatabase;
458 wxTheColourDatabase = NULL;
459
460 wxBitmap::CleanUpHandlers();
461
462 delete[] wxBuffer;
463 wxBuffer = NULL;
464
519cb848
SC
465 if (wxWinMacWindowList)
466 delete wxWinMacWindowList ;
467
e9576ca5
SC
468 wxClassInfo::CleanUpClasses();
469
519cb848
SC
470#if __option(profile)
471 ProfilerDump( "\papp.prof" ) ;
472 ProfilerTerm() ;
473#endif
474
e9576ca5
SC
475 delete wxTheApp;
476 wxTheApp = NULL;
477
478#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
479 // At this point we want to check if there are any memory
480 // blocks that aren't part of the wxDebugContext itself,
481 // as a special case. Then when dumping we need to ignore
482 // wxDebugContext, too.
483 if (wxDebugContext::CountObjectsLeft() > 0)
484 {
485 wxTrace("There were memory leaks.\n");
486 wxDebugContext::Dump();
487 wxDebugContext::PrintStatistics();
488 }
489// wxDebugContext::SetStream(NULL, NULL);
490#endif
491
492 // do it as the very last thing because everything else can log messages
493 wxLog::DontCreateOnDemand();
494 // do it as the very last thing because everything else can log messages
495 delete wxLog::SetActiveTarget(NULL);
169935ad 496
8be97d65 497 ::PrClose() ;
519cb848
SC
498 if (s_macCursorRgn)
499 ::DisposeRgn(s_macCursorRgn);
8be97d65
SC
500 #if 0
501 TerminateAE() ;
502 #endif
e9576ca5
SC
503}
504
505int wxEntry( int argc, char *argv[] )
506{
507 if (!wxApp::Initialize())
508 return FALSE;
509 if (!wxTheApp)
510 {
511 if (!wxApp::GetInitializerFunction())
512 {
513 printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" );
514 return 0;
515 };
516
517 wxTheApp = (wxApp*) (* wxApp::GetInitializerFunction()) ();
518 };
519
520 if (!wxTheApp)
521 {
522 printf( "wxWindows error: wxTheApp == NULL\n" );
523 return 0;
524 };
525
519cb848
SC
526#ifdef __WXMAC__
527 argc = 1 ; // currently we don't support files as parameters
528#endif
529
e9576ca5
SC
530 wxTheApp->argc = argc;
531 wxTheApp->argv = argv;
532
533 // GUI-specific initialization, such as creating an app context.
534 wxTheApp->OnInitGui();
519cb848
SC
535
536 // we could try to get the open apple events here to adjust argc and argv better
537
e9576ca5
SC
538
539 // Here frames insert themselves automatically
540 // into wxTopLevelWindows by getting created
541 // in OnInit().
542
543 if (!wxTheApp->OnInit()) return 0;
544
545 int retValue = 0;
546
547 if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun();
548
549 if (wxTheApp->GetTopWindow())
550 {
551 delete wxTheApp->GetTopWindow();
552 wxTheApp->SetTopWindow(NULL);
553 }
554
555 wxTheApp->DeletePendingObjects();
556
557 wxTheApp->OnExit();
558
559 wxApp::CleanUp();
560
561 return retValue;
562};
563
564// Static member initialization
565wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
566
567wxApp::wxApp()
568{
569 m_topWindow = NULL;
570 wxTheApp = this;
571 m_className = "";
572 m_wantDebugOutput = TRUE ;
573 m_appName = "";
574 argc = 0;
575 argv = NULL;
519cb848 576
e9576ca5 577 m_printMode = wxPRINT_WINDOWS;
519cb848 578
e9576ca5
SC
579 m_exitOnFrameDelete = TRUE;
580 m_auto3D = TRUE;
581}
582
583bool wxApp::Initialized()
584{
519cb848 585 if (GetTopWindow())
e9576ca5 586 return TRUE;
519cb848
SC
587 else
588 return FALSE;
e9576ca5
SC
589}
590
591int wxApp::MainLoop()
592{
593 m_keepGoing = TRUE;
594
e9576ca5
SC
595 while (m_keepGoing)
596 {
8be97d65 597 MacDoOneEvent() ;
e9576ca5 598 }
e9576ca5
SC
599
600 return 0;
601}
602
603// Returns TRUE if more time is needed.
604bool wxApp::ProcessIdle()
605{
606 wxIdleEvent event;
607 event.SetEventObject(this);
608 ProcessEvent(event);
609
610 return event.MoreRequested();
611}
612
613void wxApp::ExitMainLoop()
614{
615 m_keepGoing = FALSE;
616}
617
618// Is a message/event pending?
619bool wxApp::Pending()
620{
519cb848
SC
621 EventRecord event ;
622
623 return EventAvail( everyEvent , &event ) ;
e9576ca5
SC
624}
625
626// Dispatch a message.
627void wxApp::Dispatch()
628{
519cb848 629 MacDoOneEvent() ;
e9576ca5
SC
630}
631
632void wxApp::OnIdle(wxIdleEvent& event)
633{
634 static bool inOnIdle = FALSE;
635
636 // Avoid recursion (via ProcessEvent default case)
637 if (inOnIdle)
638 return;
639
640 inOnIdle = TRUE;
641
642 // 'Garbage' collection of windows deleted with Close().
643 DeletePendingObjects();
644
645 // flush the logged messages if any
646 wxLog *pLog = wxLog::GetActiveTarget();
647 if ( pLog != NULL && pLog->HasPendingMessages() )
648 pLog->Flush();
649
650 // Send OnIdle events to all windows
651 bool needMore = SendIdleEvents();
652
653 if (needMore)
654 event.RequestMore(TRUE);
655
656 inOnIdle = FALSE;
657}
658
659// Send idle event to all top-level windows
660bool wxApp::SendIdleEvents()
661{
662 bool needMore = FALSE;
663 wxNode* node = wxTopLevelWindows.First();
664 while (node)
665 {
666 wxWindow* win = (wxWindow*) node->Data();
667 if (SendIdleEvents(win))
668 needMore = TRUE;
669
670 node = node->Next();
671 }
672 return needMore;
673}
674
675// Send idle event to window and all subwindows
676bool wxApp::SendIdleEvents(wxWindow* win)
677{
678 bool needMore = FALSE;
679
680 wxIdleEvent event;
681 event.SetEventObject(win);
682 win->ProcessEvent(event);
683
684 if (event.MoreRequested())
685 needMore = TRUE;
686
687 wxNode* node = win->GetChildren().First();
688 while (node)
689 {
690 wxWindow* win = (wxWindow*) node->Data();
691 if (SendIdleEvents(win))
692 needMore = TRUE;
693
694 node = node->Next();
695 }
696 return needMore ;
697}
698
699void wxApp::DeletePendingObjects()
700{
701 wxNode *node = wxPendingDelete.First();
702 while (node)
703 {
704 wxObject *obj = (wxObject *)node->Data();
705
706 delete obj;
707
708 if (wxPendingDelete.Member(obj))
709 delete node;
710
711 // Deleting one object may have deleted other pending
712 // objects, so start from beginning of list again.
713 node = wxPendingDelete.First();
714 }
715}
716
717wxLog* wxApp::CreateLogTarget()
718{
719 return new wxLogGui;
720}
721
722wxWindow* wxApp::GetTopWindow() const
723{
724 if (m_topWindow)
725 return m_topWindow;
726 else if (wxTopLevelWindows.Number() > 0)
727 return (wxWindow*) wxTopLevelWindows.First()->Data();
728 else
729 return NULL;
730}
731
732void wxExit()
733{
734 wxApp::CleanUp();
8be97d65 735 ::ExitToShell() ;
e9576ca5
SC
736}
737
738// Yield to other processes
739bool wxYield()
740{
519cb848
SC
741// YieldToAnyThread() ;
742 SystemTask() ;
8be97d65 743 return TRUE;
169935ad
SC
744}
745
8be97d65 746// platform specifics
169935ad 747
519cb848
SC
748void wxApp::MacSuspend( bool convertClipboard )
749{
750 s_lastMouseDown = 0 ;
751 if( convertClipboard )
752 {
753 MacConvertPrivateToPublicScrap() ;
754 }
755
756 UMAHideFloatingWindows() ;
757}
758
759void wxApp::MacResume( bool convertClipboard )
760{
761 s_lastMouseDown = 0 ;
762 if( convertClipboard )
763 {
764 MacConvertPublicToPrivateScrap() ;
765 }
766
767 UMAShowFloatingWindows() ;
768}
769
770void wxApp::MacConvertPrivateToPublicScrap()
771{
772 ::ZeroScrap();
773 ::TEToScrap();
774}
775
776void wxApp::MacConvertPublicToPrivateScrap()
777{
778 ::TEFromScrap() ;
779}
780
8be97d65 781void wxApp::MacDoOneEvent()
169935ad
SC
782{
783 EventRecord event ;
784
519cb848 785 long sleepTime = ::GetCaretTime();
169935ad 786
519cb848 787 if (WaitNextEvent(everyEvent, &event,sleepTime, s_macCursorRgn))
169935ad 788 {
8be97d65 789 MacHandleOneEvent( &event );
169935ad
SC
790 }
791 else
792 {
8be97d65 793 // idlers
519cb848
SC
794 WindowPtr window = UMAFrontWindow() ;
795 if ( window )
796 UMAIdleControls( window ) ;
797
8be97d65 798 wxTheApp->ProcessIdle() ;
169935ad 799 }
519cb848
SC
800 if ( event.what != kHighLevelEvent )
801 SetRectRgn( s_macCursorRgn , event.where.h - 1 , event.where.v - 1, event.where.h + 1 , event.where.v + 1 ) ;
802
8be97d65 803 // repeaters
519cb848 804
8be97d65
SC
805#if 0
806 wxMacProcessSocketEvents() ;
807#endif
169935ad
SC
808}
809
8be97d65 810void wxApp::MacHandleOneEvent( EventRecord *ev )
169935ad 811{
519cb848
SC
812 m_macCurrentEvent = ev ;
813
814 wxApp::sm_lastMessageTime = ev->when ;
815
169935ad
SC
816 switch (ev->what)
817 {
169935ad 818 case mouseDown:
8be97d65 819 MacHandleMouseDownEvent( ev ) ;
519cb848
SC
820 if ( ev->modifiers & controlKey )
821 s_lastMouseDown = 2;
822 else
823 s_lastMouseDown = 1;
169935ad
SC
824 break;
825 case mouseUp:
519cb848
SC
826 if ( s_lastMouseDown == 2 )
827 {
828 ev->modifiers |= controlKey ;
829 }
830 else
831 {
832 ev->modifiers &= ~controlKey ;
833 }
8be97d65 834 MacHandleMouseUpEvent( ev ) ;
519cb848 835 s_lastMouseDown = 0;
169935ad
SC
836 break;
837 case activateEvt:
8be97d65 838 MacHandleActivateEvent( ev ) ;
169935ad
SC
839 break;
840 case updateEvt:
8be97d65 841 MacHandleUpdateEvent( ev ) ;
169935ad 842 break;
519cb848
SC
843 case keyDown:
844 case autoKey:
845 MacHandleKeyDownEvent( ev ) ;
846 break;
847 case keyUp:
848 MacHandleKeyUpEvent( ev ) ;
849 break;
169935ad 850 case diskEvt:
8be97d65 851 MacHandleDiskEvent( ev ) ;
169935ad
SC
852 break;
853 case osEvt:
8be97d65 854 MacHandleOSEvent( ev ) ;
169935ad 855 break;
519cb848
SC
856 case kHighLevelEvent:
857 MacHandleHighLevelEvent( ev ) ;
858 break;
169935ad
SC
859 default:
860 break;
861 }
169935ad
SC
862}
863
8be97d65 864void wxApp::MacHandleHighLevelEvent( EventRecord *ev )
169935ad 865{
519cb848 866 ::AEProcessAppleEvent( ev ) ;
169935ad
SC
867}
868
519cb848
SC
869bool s_macIsInModalLoop = false ;
870
8be97d65 871void wxApp::MacHandleMouseDownEvent( EventRecord *ev )
169935ad 872{
519cb848
SC
873 WindowRef window;
874 WindowRef frontWindow = UMAFrontNonFloatingWindow() ;
875 WindowAttributes frontWindowAttributes = NULL ;
876 if ( frontWindow )
877 UMAGetWindowAttributes( frontWindow , &frontWindowAttributes ) ;
878
879 short windowPart = ::FindWindow(ev->where, &window);
880 wxWindow* win = wxFindWinFromMacWindow( window ) ;
881
882 switch (windowPart)
883 {
884 case inMenuBar :
885 if ( s_macIsInModalLoop )
886 {
887 SysBeep ( 30 ) ;
888 }
889 else
890 {
891 UInt32 menuresult = MenuSelect(ev->where) ;
892 MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) );
893 s_lastMouseDown = 0;
894 }
895 break ;
896 case inSysWindow :
897 SystemClick( ev , window ) ;
898 s_lastMouseDown = 0;
899 break ;
900 case inDrag :
901 if ( window != frontWindow && s_macIsInModalLoop && !(ev->modifiers & cmdKey ) )
902 {
903 SysBeep ( 30 ) ;
904 }
905 else
906 {
907 DragWindow(window, ev->where, &qd.screenBits.bounds);
908 if (win)
909 {
910 GrafPtr port ;
911 GetPort( &port ) ;
912 Point pt = { 0, 0 } ;
913 SetPort( window ) ;
914 SetOrigin( 0 , 0 ) ;
915 LocalToGlobal( &pt ) ;
916 SetPort( port ) ;
917 win->SetSize( pt.h , pt.v , -1 ,
918 -1 , wxSIZE_USE_EXISTING);
919 }
920 s_lastMouseDown = 0;
921 }
922 break ;
923 case inGoAway:
924 if (TrackGoAway(window, ev->where))
925 {
926 if ( win )
927 win->Close() ;
928 }
929 s_lastMouseDown = 0;
930 break;
931 case inGrow:
932 int growResult = GrowWindow(window , ev->where, &qd.screenBits.bounds);
933 if (growResult != 0)
934 {
935 int newWidth = LoWord(growResult);
936 int newHeight = HiWord(growResult);
937 int oldWidth, oldHeight;
938
939 win->GetSize(&oldWidth, &oldHeight);
940 if (newWidth == 0)
941 newWidth = oldWidth;
942 if (newHeight == 0)
943 newHeight = oldHeight;
944
945 if (win)
946 win->SetSize( -1, -1, newWidth, newHeight, wxSIZE_USE_EXISTING);
947 }
948 s_lastMouseDown = 0;
949 break;
950 case inZoomIn:
951 case inZoomOut:
952 if (TrackBox(window, ev->where, windowPart))
953 {
954 // TODO setup size event
955 ZoomWindow( window , windowPart , false ) ;
956 if (win)
957 win->SetSize( -1, -1, window->portRect.right-window->portRect.left ,
958 window->portRect.bottom-window->portRect.top, wxSIZE_USE_EXISTING);
959 }
960 s_lastMouseDown = 0;
961 break;
962 case inCollapseBox :
963 // TODO setup size event
964 s_lastMouseDown = 0;
965 break ;
169935ad 966
519cb848
SC
967 case inContent :
968 if ( window != frontWindow )
969 {
970 if ( s_macIsInModalLoop )
971 {
972 SysBeep ( 30 ) ;
973 }
974 else if ( UMAIsWindowFloating( window ) )
975 {
976 if ( win )
977 win->MacMouseDown( ev , windowPart ) ;
978 }
979 else
980 {
981 UMASelectWindow( window ) ;
982 }
983 }
984 else
985 {
986 if ( win )
987 win->MacMouseDown( ev , windowPart ) ;
988 }
989 break ;
990
991 default:
992 break;
993 }
169935ad
SC
994}
995
519cb848 996void wxApp::MacHandleMouseUpEvent( EventRecord *ev )
169935ad 997{
519cb848
SC
998 WindowRef window;
999
1000 short windowPart = ::FindWindow(ev->where, &window);
1001
1002 switch (windowPart)
1003 {
1004 case inMenuBar :
1005 break ;
1006 case inSysWindow :
1007 break ;
1008 default:
1009 {
1010 wxWindow* win = wxFindWinFromMacWindow( window ) ;
1011 if ( win )
1012 win->MacMouseUp( ev , windowPart ) ;
1013 }
1014 break;
1015 }
169935ad
SC
1016}
1017
519cb848
SC
1018long wxMacTranslateKey(char key, char code)
1019{
1020 switch (key)
1021 {
1022 case 0x01 :
1023 key = WXK_HOME;
1024 break;
1025 case 0x03 :
1026 key = WXK_RETURN;
1027 break;
1028 case 0x04 :
1029 key = WXK_END;
1030 break;
1031 case 0x05 :
1032 key = WXK_HELP;
1033 break;
1034 case 0x08 :
1035 key = WXK_BACK;
1036 break;
1037 case 0x09 :
1038 key = WXK_TAB;
1039 break;
1040 case 0x0b :
1041 key = WXK_PAGEUP;
1042 break;
1043 case 0x0c :
1044 key = WXK_PAGEDOWN;
1045 break;
1046 case 0x0d :
1047 key = WXK_RETURN;
1048 break;
1049 case 0x10 :
169935ad 1050 {
519cb848
SC
1051 switch( code )
1052 {
1053 case 0x7a :
1054 key = WXK_F1 ;
1055 break;
1056 case 0x78 :
1057 key = WXK_F2 ;
1058 break;
1059 case 0x63 :
1060 key = WXK_F3 ;
1061 break;
1062 case 0x76 :
1063 key = WXK_F4 ;
1064 break;
1065 case 0x60 :
1066 key = WXK_F5 ;
1067 break;
1068 case 0x61 :
1069 key = WXK_F6 ;
1070 break;
1071 case 0x62:
1072 key = WXK_F7 ;
1073 break;
1074 case 0x64 :
1075 key = WXK_F8 ;
1076 break;
1077 case 0x65 :
1078 key = WXK_F9 ;
1079 break;
1080 case 0x6D :
1081 key = WXK_F10 ;
1082 break;
1083 case 0x67 :
1084 key = WXK_F11 ;
1085 break;
1086 case 0x6F :
1087 key = WXK_F12 ;
1088 break;
1089 case 0x69 :
1090 key = WXK_F13 ;
1091 break;
1092 case 0x6B :
1093 key = WXK_F14 ;
1094 break;
1095 case 0x71 :
1096 key = WXK_F15 ;
1097 break;
1098 }
169935ad 1099 }
519cb848
SC
1100 break ;
1101 case 0x1b :
1102 key = WXK_DELETE ;
1103 break ;
1104 case 0x1c :
1105 key = WXK_LEFT ;
1106 break ;
1107 case 0x1d :
1108 key = WXK_RIGHT ;
1109 break ;
1110 case 0x1e :
1111 key = WXK_UP ;
1112 break ;
1113 case 0x1f :
1114 key = WXK_DOWN ;
1115 break ;
1116 default:
1117 break ;
1118 } // end switch
169935ad 1119
519cb848 1120 return key;
169935ad
SC
1121}
1122
519cb848 1123void wxApp::MacHandleKeyDownEvent( EventRecord *ev )
169935ad 1124{
519cb848
SC
1125 UInt32 menuresult = UMAMenuEvent(ev) ;
1126 if ( HiWord( menuresult ) )
1127 MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ) ;
169935ad
SC
1128 else
1129 {
519cb848
SC
1130 short keycode ;
1131 short keychar ;
1132 keychar = short(ev->message & charCodeMask);
1133 keycode = short(ev->message & keyCodeMask) >> 8 ;
169935ad 1134
519cb848
SC
1135 wxWindow* focus = wxWindow::FindFocus() ;
1136 if ( focus )
1137 {
1138 wxKeyEvent event(wxEVT_CHAR);
1139 event.m_shiftDown = ev->modifiers & shiftKey;
1140 event.m_controlDown = ev->modifiers & controlKey;
1141 event.m_altDown = ev->modifiers & optionKey;
1142 event.m_metaDown = ev->modifiers & cmdKey;
1143 event.m_keyCode = wxMacTranslateKey(keychar, keycode);
1144 event.m_x = ev->where.h;
1145 event.m_y = ev->where.v;
1146 event.m_timeStamp = ev->when;
1147 event.SetEventObject(focus);
1148 focus->GetEventHandler()->ProcessEvent( event ) ;
169935ad
SC
1149 }
1150 }
1151}
1152
519cb848 1153void wxApp::MacHandleKeyUpEvent( EventRecord *ev )
169935ad 1154{
519cb848 1155 // nothing to do
169935ad
SC
1156}
1157
519cb848 1158void wxApp::MacHandleActivateEvent( EventRecord *ev )
169935ad 1159{
519cb848
SC
1160 WindowRef window = (WindowRef) ev->message ;
1161 if ( window )
169935ad 1162 {
519cb848
SC
1163 bool activate = (ev->modifiers & activeFlag ) ;
1164 WindowClass wclass ;
1165 UMAGetWindowClass ( window , &wclass ) ;
1166 if ( wclass == kFloatingWindowClass )
1167 {
1168 // if it is a floater we activate/deactivate the front non-floating window instead
1169 window = UMAFrontNonFloatingWindow() ;
1170 }
1171 wxWindow* win = wxFindWinFromMacWindow( window ) ;
1172 if ( win )
1173 win->MacActivate( ev , activate ) ;
169935ad
SC
1174 }
1175}
1176
519cb848 1177void wxApp::MacHandleUpdateEvent( EventRecord *ev )
169935ad 1178{
519cb848
SC
1179 WindowRef window = (WindowRef) ev->message ;
1180 wxWindow * win = wxFindWinFromMacWindow( window ) ;
1181 if ( win )
169935ad 1182 {
519cb848 1183 win->MacUpdate( ev ) ;
169935ad
SC
1184 }
1185}
1186
519cb848 1187void wxApp::MacHandleDiskEvent( EventRecord *ev )
169935ad 1188{
519cb848
SC
1189 if ( HiWord( ev->message ) != noErr )
1190 {
1191 OSErr err ;
1192 Point point ;
1193 SetPt( &point , 100 , 100 ) ;
1194
1195 err = DIBadMount( point , ev->message ) ;
1196 wxASSERT( err == noErr ) ;
169935ad 1197 }
169935ad
SC
1198}
1199
519cb848 1200void wxApp::MacHandleOSEvent( EventRecord *ev )
169935ad 1201{
519cb848 1202 switch( ( ev->message & osEvtMessageMask ) >> 24 )
169935ad 1203 {
519cb848 1204 case suspendResumeMessage :
169935ad 1205 {
519cb848
SC
1206 bool isResuming = ev->message & resumeFlag ;
1207 bool convertClipboard = ev->message & convertClipboardFlag ;
1208 bool doesActivate = UMAGetProcessModeDoesActivateOnFGSwitch() ;
1209 if ( isResuming )
169935ad 1210 {
519cb848
SC
1211 WindowRef oldFrontWindow = NULL ;
1212 WindowRef newFrontWindow = NULL ;
1213
1214 // in case we don't take care of activating ourselves, we have to synchronize
1215 // our idea of the active window with the process manager's - which it already activated
1216
1217 if ( !doesActivate )
1218 oldFrontWindow = UMAFrontNonFloatingWindow() ;
1219
1220 MacResume( convertClipboard ) ;
1221
1222 newFrontWindow = UMAFrontNonFloatingWindow() ;
1223
1224 if ( oldFrontWindow )
1225 {
1226 wxWindow* win = wxFindWinFromMacWindow( oldFrontWindow ) ;
1227 if ( win )
1228 win->MacActivate( ev , false ) ;
1229 }
1230 if ( newFrontWindow )
1231 {
1232 wxWindow* win = wxFindWinFromMacWindow( newFrontWindow ) ;
1233 if ( win )
1234 win->MacActivate( ev , true ) ;
1235 }
169935ad
SC
1236 }
1237 else
519cb848
SC
1238 {
1239 MacSuspend( convertClipboard ) ;
169935ad 1240
519cb848
SC
1241 // in case this suspending did close an active window, another one might
1242 // have surfaced -> lets deactivate that one
1243
1244 WindowRef newActiveWindow = UMAGetActiveNonFloatingWindow() ;
1245 if ( newActiveWindow )
1246 {
1247 wxWindow* win = wxFindWinFromMacWindow( newActiveWindow ) ;
1248 if ( win )
1249 win->MacActivate( ev , false ) ;
1250 }
169935ad
SC
1251 }
1252 }
519cb848
SC
1253 break ;
1254 case mouseMovedMessage :
169935ad 1255 {
519cb848
SC
1256 WindowRef window;
1257
1258 wxWindow* currentMouseWindow = NULL ;
1259
1260 MacGetWindowFromPoint( wxPoint( ev->where.h , ev->where.v ) , &currentMouseWindow ) ;
1261
1262 if ( currentMouseWindow != wxWindow::s_lastMouseWindow )
169935ad 1263 {
519cb848
SC
1264 wxMouseEvent event ;
1265
1266 bool isDown = !(ev->modifiers & btnState) ; // 1 is for up
1267 bool controlDown = ev->modifiers & controlKey ; // for simulating right mouse
1268
1269 event.m_leftDown = isDown && !controlDown;
1270 event.m_middleDown = FALSE;
1271 event.m_rightDown = isDown && controlDown;
1272 event.m_shiftDown = ev->modifiers & shiftKey;
1273 event.m_controlDown = ev->modifiers & controlKey;
1274 event.m_altDown = ev->modifiers & optionKey;
1275 event.m_metaDown = ev->modifiers & cmdKey;
1276 event.m_x = ev->where.h;
1277 event.m_y = ev->where.v;
1278 event.m_timeStamp = ev->when;
1279 event.SetEventObject(this);
1280
1281 if ( wxWindow::s_lastMouseWindow )
1282 {
1283 wxMouseEvent eventleave(event ) ;
1284 eventleave.SetEventType( wxEVT_LEAVE_WINDOW ) ;
1285 wxWindow::s_lastMouseWindow->GetEventHandler()->ProcessEvent(eventleave);
1286 }
1287 if ( currentMouseWindow )
1288 {
1289 wxMouseEvent evententer(event ) ;
1290 evententer.SetEventType( wxEVT_ENTER_WINDOW ) ;
1291 currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
1292 }
1293 wxWindow::s_lastMouseWindow = currentMouseWindow ;
169935ad 1294 }
519cb848
SC
1295
1296 short windowPart = ::FindWindow(ev->where, &window);
1297
1298 switch (windowPart)
1299 {
1300 case inMenuBar :
1301 break ;
1302 case inSysWindow :
1303 break ;
1304 default:
1305 {
1306 if ( s_lastMouseDown == 0 )
1307 ev->modifiers |= btnState ;
1308
1309 wxWindow* win = wxFindWinFromMacWindow( window ) ;
1310 if ( win )
1311 win->MacMouseMoved( ev , windowPart ) ;
1312 }
1313 break;
1314 }
1315 }
1316 break ;
1317
169935ad 1318 }
169935ad
SC
1319}
1320
519cb848 1321void wxApp::MacHandleMenuSelect( int macMenuId , int macMenuItemNum )
169935ad 1322{
519cb848
SC
1323 if (macMenuId == 0)
1324 return; // no menu item selected
1325
1326 if (macMenuId == kwxMacAppleMenuId && macMenuItemNum > 1)
169935ad 1327 {
519cb848
SC
1328 #if ! TARGET_CARBON
1329 Str255 deskAccessoryName ;
1330 GrafPtr savedPort ;
1331
1332 GetMenuItemText(GetMenuHandle(kwxMacAppleMenuId), macMenuItemNum, deskAccessoryName);
1333 GetPort(&savedPort);
1334 OpenDeskAcc(deskAccessoryName);
1335 SetPort(savedPort);
169935ad 1336 #endif
169935ad 1337 }
519cb848 1338 else
169935ad 1339 {
519cb848
SC
1340 wxWindow* frontwindow = wxFindWinFromMacWindow( ::FrontWindow() ) ;
1341 if ( frontwindow && wxMenuBar::s_macInstalledMenuBar )
1342 wxMenuBar::s_macInstalledMenuBar->MacMenuSelect( frontwindow->GetEventHandler() , 0 , macMenuId , macMenuItemNum ) ;
1343 }
1344 HiliteMenu(0);
169935ad
SC
1345}
1346
519cb848
SC
1347/*
1348long wxApp::MacTranslateKey(char key, int mods)
169935ad 1349{
169935ad
SC
1350}
1351
519cb848 1352void wxApp::MacAdjustCursor()
169935ad 1353{
169935ad
SC
1354}
1355
519cb848
SC
1356*/
1357/*
169935ad
SC
1358void
1359wxApp::macAdjustCursor()
1360{
519cb848 1361 if (ev->what != kHighLevelEvent)
169935ad
SC
1362 {
1363 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow());
1364 if (theMacWxFrame)
1365 {
519cb848 1366 if (!theMacWxFrame->MacAdjustCursor(ev->where))
169935ad
SC
1367 ::SetCursor(&(qd.arrow));
1368 }
1369 }
1370}
519cb848 1371*/