]> git.saurik.com Git - wxWidgets.git/blob - src/mac/app.cpp
bitmap and image updates
[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/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
38 // mac
39
40 #if __option(profile)
41 #include <profiler.h>
42 #endif
43
44 #include "apprsrc.h"
45
46 #include <wx/mac/uma.h>
47
48 extern char *wxBuffer;
49 extern wxList wxPendingDelete;
50 extern wxList *wxWinMacWindowList;
51 extern wxList *wxWinMacControlList;
52
53 extern wxApp *wxTheApp ;
54
55 #if !USE_SHARED_LIBRARY
56 IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
57 BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
58 EVT_IDLE(wxApp::OnIdle)
59 END_EVENT_TABLE()
60 #endif
61
62
63 const short kMacMinHeap = (29 * 1024) ;
64 // platform specific static variables
65
66 const short kwxMacMenuBarResource = 1 ;
67 const short kwxMacAppleMenuId = 1 ;
68
69 RgnHandle wxApp::s_macCursorRgn = NULL;
70 wxWindow* wxApp::s_captureWindow = NULL ;
71 int wxApp::s_lastMouseDown = 0 ;
72 long wxApp::sm_lastMessageTime = 0;
73
74 #ifdef __WXMAC__
75
76 bool wxApp::s_macDefaultEncodingIsPC = true ;
77 bool wxApp::s_macSupportPCMenuShortcuts = true ;
78 long wxApp::s_macAboutMenuItemId = wxID_ABOUT ;
79 wxString wxApp::s_macHelpMenuTitleName = "&Help" ;
80
81 OSErr AEHandleODoc( AppleEvent *event , AppleEvent *reply , long refcon )
82 {
83 wxApp* app = (wxApp*) refcon ;
84 return wxTheApp->MacHandleAEODoc( event , reply) ;
85 }
86
87 OSErr AEHandleOApp( AppleEvent *event , AppleEvent *reply , long refcon )
88 {
89 wxApp* app = (wxApp*) refcon ;
90 return wxTheApp->MacHandleAEOApp( event , reply ) ;
91 }
92
93 OSErr AEHandlePDoc( AppleEvent *event , AppleEvent *reply , long refcon )
94 {
95 wxApp* app = (wxApp*) refcon ;
96 return wxTheApp->MacHandleAEPDoc( event , reply ) ;
97 }
98
99 OSErr AEHandleQuit( AppleEvent *event , AppleEvent *reply , long refcon )
100 {
101 wxApp* app = (wxApp*) refcon ;
102 return wxTheApp->MacHandleAEQuit( event , reply) ;
103 }
104
105 OSErr 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
114 OSErr wxApp::MacHandleAEPDoc(AppleEvent *event , AppleEvent *reply)
115 {
116 return noErr ;
117 }
118
119 OSErr wxApp::MacHandleAEOApp(AppleEvent *event , AppleEvent *reply)
120 {
121 return noErr ;
122 }
123
124 OSErr 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
138 char 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
145 char 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
152 void 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
187 void 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
222 void wxMacConvertFromPC( char * p )
223 {
224 char *ptr = p ;
225 int len = strlen ( p ) ;
226
227 wxMacConvertFromPC( ptr , ptr , len ) ;
228 }
229
230 void 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
245 void wxMacConvertFromPC( unsigned char *p )
246 {
247 char *ptr = (char*) p + 1 ;
248 int len = p[0] ;
249
250 wxMacConvertFromPC( ptr , ptr , len ) ;
251 }
252
253 extern char *wxBuffer ;
254
255 wxString 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
275 void wxMacConvertToPC( char * p )
276 {
277 char *ptr = p ;
278 int len = strlen ( p ) ;
279
280 wxMacConvertToPC( ptr , ptr , len ) ;
281 }
282
283 void wxMacConvertToPC( unsigned char *p )
284 {
285 char *ptr = (char*) p + 1 ;
286 int len = p[0] ;
287
288 wxMacConvertToPC( ptr , ptr , len ) ;
289 }
290
291 wxString 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 }
310
311 #endif
312
313 bool wxApp::Initialize()
314 {
315 int error = 0 ;
316
317 // Mac-specific
318
319 UMAInitToolbox( 4 ) ;
320 UMAShowWatchCursor() ;
321
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 ) ;
326 #if 0
327 GUSISetup(GUSIwithInternetSockets);
328 #endif
329
330
331 // test the minimal configuration necessary
332
333 long theSystem ;
334 long theMachine;
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 }
348 else if ( theSystem < 0x0750 )
349 {
350 error = kMacSTROldSystem ;
351 }
352 #if !TARGET_CARBON
353 else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap)
354 {
355 error = kMacSTRSmallSize;
356 }
357 #endif
358 /*
359 else
360 {
361 if ( !UMAHasAppearance() )
362 {
363 error = kMacSTRNoPre8Yet ;
364 }
365 }
366 */
367
368 // if we encountered any problems so far, give the error code and exit immediately
369
370 if ( error )
371 {
372 short itemHit;
373 Str255 message;
374
375 GetIndString(message, 128, error);
376 UMAShowArrowCursor() ;
377 ParamText("\pFatal Error", message, (ConstStr255Param)"\p", (ConstStr255Param)"\p");
378 itemHit = Alert(128, nil);
379 return FALSE ;
380 }
381
382 #if __option(profile)
383 ProfilerInit( collectDetailed, bestTimeBase , 20000 , 30 ) ;
384 #endif
385
386 // now avoid exceptions thrown for new (bad_alloc)
387
388 std::__throws_bad_alloc = FALSE ;
389
390 s_macCursorRgn = ::NewRgn() ;
391
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();
422 if (!wxModule::InitializeModules())
423 return FALSE;
424
425 wxWinMacWindowList = new wxList(wxKEY_INTEGER);
426 wxWinMacControlList = new wxList(wxKEY_INTEGER);
427
428 UMAShowArrowCursor() ;
429
430 return TRUE;
431 }
432
433 void 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
465 if (wxWinMacWindowList)
466 delete wxWinMacWindowList ;
467
468 wxClassInfo::CleanUpClasses();
469
470 #if __option(profile)
471 ProfilerDump( "\papp.prof" ) ;
472 ProfilerTerm() ;
473 #endif
474
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);
496
497 ::PrClose() ;
498 if (s_macCursorRgn)
499 ::DisposeRgn(s_macCursorRgn);
500 #if 0
501 TerminateAE() ;
502 #endif
503 }
504
505 int 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
526 #ifdef __WXMAC__
527 argc = 1 ; // currently we don't support files as parameters
528 #endif
529
530 wxTheApp->argc = argc;
531 wxTheApp->argv = argv;
532
533 // GUI-specific initialization, such as creating an app context.
534 wxTheApp->OnInitGui();
535
536 // we could try to get the open apple events here to adjust argc and argv better
537
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
565 wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
566
567 wxApp::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;
576
577 m_printMode = wxPRINT_WINDOWS;
578
579 m_exitOnFrameDelete = TRUE;
580 m_auto3D = TRUE;
581 }
582
583 bool wxApp::Initialized()
584 {
585 if (GetTopWindow())
586 return TRUE;
587 else
588 return FALSE;
589 }
590
591 int wxApp::MainLoop()
592 {
593 m_keepGoing = TRUE;
594
595 while (m_keepGoing)
596 {
597 MacDoOneEvent() ;
598 }
599
600 return 0;
601 }
602
603 // Returns TRUE if more time is needed.
604 bool wxApp::ProcessIdle()
605 {
606 wxIdleEvent event;
607 event.SetEventObject(this);
608 ProcessEvent(event);
609
610 return event.MoreRequested();
611 }
612
613 void wxApp::ExitMainLoop()
614 {
615 m_keepGoing = FALSE;
616 }
617
618 // Is a message/event pending?
619 bool wxApp::Pending()
620 {
621 EventRecord event ;
622
623 return EventAvail( everyEvent , &event ) ;
624 }
625
626 // Dispatch a message.
627 void wxApp::Dispatch()
628 {
629 MacDoOneEvent() ;
630 }
631
632 void 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 void wxWakeUpIdle()
660 {
661 // **** please implement me! ****
662 // Wake up the idle handler processor, even if it is in another thread...
663 }
664
665 // Send idle event to all top-level windows
666 bool wxApp::SendIdleEvents()
667 {
668 bool needMore = FALSE;
669 wxNode* node = wxTopLevelWindows.First();
670 while (node)
671 {
672 wxWindow* win = (wxWindow*) node->Data();
673 if (SendIdleEvents(win))
674 needMore = TRUE;
675
676 node = node->Next();
677 }
678 return needMore;
679 }
680
681 // Send idle event to window and all subwindows
682 bool wxApp::SendIdleEvents(wxWindow* win)
683 {
684 bool needMore = FALSE;
685
686 wxIdleEvent event;
687 event.SetEventObject(win);
688 win->ProcessEvent(event);
689
690 if (event.MoreRequested())
691 needMore = TRUE;
692
693 wxNode* node = win->GetChildren().First();
694 while (node)
695 {
696 wxWindow* win = (wxWindow*) node->Data();
697 if (SendIdleEvents(win))
698 needMore = TRUE;
699
700 node = node->Next();
701 }
702 return needMore ;
703 }
704
705 void wxApp::DeletePendingObjects()
706 {
707 wxNode *node = wxPendingDelete.First();
708 while (node)
709 {
710 wxObject *obj = (wxObject *)node->Data();
711
712 delete obj;
713
714 if (wxPendingDelete.Member(obj))
715 delete node;
716
717 // Deleting one object may have deleted other pending
718 // objects, so start from beginning of list again.
719 node = wxPendingDelete.First();
720 }
721 }
722
723 wxLog* wxApp::CreateLogTarget()
724 {
725 return new wxLogGui;
726 }
727
728 wxWindow* wxApp::GetTopWindow() const
729 {
730 if (m_topWindow)
731 return m_topWindow;
732 else if (wxTopLevelWindows.Number() > 0)
733 return (wxWindow*) wxTopLevelWindows.First()->Data();
734 else
735 return NULL;
736 }
737
738 void wxExit()
739 {
740 wxApp::CleanUp();
741 ::ExitToShell() ;
742 }
743
744 // Yield to other processes
745 bool wxYield()
746 {
747 // YieldToAnyThread() ;
748 SystemTask() ;
749 return TRUE;
750 }
751
752 // platform specifics
753
754 void wxApp::MacSuspend( bool convertClipboard )
755 {
756 s_lastMouseDown = 0 ;
757 if( convertClipboard )
758 {
759 MacConvertPrivateToPublicScrap() ;
760 }
761
762 UMAHideFloatingWindows() ;
763 }
764
765 void wxApp::MacResume( bool convertClipboard )
766 {
767 s_lastMouseDown = 0 ;
768 if( convertClipboard )
769 {
770 MacConvertPublicToPrivateScrap() ;
771 }
772
773 UMAShowFloatingWindows() ;
774 }
775
776 void wxApp::MacConvertPrivateToPublicScrap()
777 {
778 ::ZeroScrap();
779 ::TEToScrap();
780 }
781
782 void wxApp::MacConvertPublicToPrivateScrap()
783 {
784 ::TEFromScrap() ;
785 }
786
787 void wxApp::MacDoOneEvent()
788 {
789 EventRecord event ;
790
791 long sleepTime = ::GetCaretTime();
792
793 if (WaitNextEvent(everyEvent, &event,sleepTime, s_macCursorRgn))
794 {
795 MacHandleOneEvent( &event );
796 }
797 else
798 {
799 // idlers
800 WindowPtr window = UMAFrontWindow() ;
801 if ( window )
802 UMAIdleControls( window ) ;
803
804 wxTheApp->ProcessIdle() ;
805 }
806 if ( event.what != kHighLevelEvent )
807 SetRectRgn( s_macCursorRgn , event.where.h - 1 , event.where.v - 1, event.where.h + 1 , event.where.v + 1 ) ;
808
809 // repeaters
810
811 #if 0
812 wxMacProcessSocketEvents() ;
813 #endif
814 }
815
816 void wxApp::MacHandleOneEvent( EventRecord *ev )
817 {
818 m_macCurrentEvent = ev ;
819
820 wxApp::sm_lastMessageTime = ev->when ;
821
822 switch (ev->what)
823 {
824 case mouseDown:
825 MacHandleMouseDownEvent( ev ) ;
826 if ( ev->modifiers & controlKey )
827 s_lastMouseDown = 2;
828 else
829 s_lastMouseDown = 1;
830 break;
831 case mouseUp:
832 if ( s_lastMouseDown == 2 )
833 {
834 ev->modifiers |= controlKey ;
835 }
836 else
837 {
838 ev->modifiers &= ~controlKey ;
839 }
840 MacHandleMouseUpEvent( ev ) ;
841 s_lastMouseDown = 0;
842 break;
843 case activateEvt:
844 MacHandleActivateEvent( ev ) ;
845 break;
846 case updateEvt:
847 MacHandleUpdateEvent( ev ) ;
848 break;
849 case keyDown:
850 case autoKey:
851 MacHandleKeyDownEvent( ev ) ;
852 break;
853 case keyUp:
854 MacHandleKeyUpEvent( ev ) ;
855 break;
856 case diskEvt:
857 MacHandleDiskEvent( ev ) ;
858 break;
859 case osEvt:
860 MacHandleOSEvent( ev ) ;
861 break;
862 case kHighLevelEvent:
863 MacHandleHighLevelEvent( ev ) ;
864 break;
865 default:
866 break;
867 }
868 }
869
870 void wxApp::MacHandleHighLevelEvent( EventRecord *ev )
871 {
872 ::AEProcessAppleEvent( ev ) ;
873 }
874
875 bool s_macIsInModalLoop = false ;
876
877 void wxApp::MacHandleMouseDownEvent( EventRecord *ev )
878 {
879 WindowRef window;
880 WindowRef frontWindow = UMAFrontNonFloatingWindow() ;
881 WindowAttributes frontWindowAttributes = NULL ;
882 if ( frontWindow )
883 UMAGetWindowAttributes( frontWindow , &frontWindowAttributes ) ;
884
885 short windowPart = ::FindWindow(ev->where, &window);
886 wxWindow* win = wxFindWinFromMacWindow( window ) ;
887
888 switch (windowPart)
889 {
890 case inMenuBar :
891 if ( s_macIsInModalLoop )
892 {
893 SysBeep ( 30 ) ;
894 }
895 else
896 {
897 UInt32 menuresult = MenuSelect(ev->where) ;
898 MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) );
899 s_lastMouseDown = 0;
900 }
901 break ;
902 case inSysWindow :
903 SystemClick( ev , window ) ;
904 s_lastMouseDown = 0;
905 break ;
906 case inDrag :
907 if ( window != frontWindow && s_macIsInModalLoop && !(ev->modifiers & cmdKey ) )
908 {
909 SysBeep ( 30 ) ;
910 }
911 else
912 {
913 DragWindow(window, ev->where, &qd.screenBits.bounds);
914 if (win)
915 {
916 GrafPtr port ;
917 GetPort( &port ) ;
918 Point pt = { 0, 0 } ;
919 SetPort( window ) ;
920 SetOrigin( 0 , 0 ) ;
921 LocalToGlobal( &pt ) ;
922 SetPort( port ) ;
923 win->SetSize( pt.h , pt.v , -1 ,
924 -1 , wxSIZE_USE_EXISTING);
925 }
926 s_lastMouseDown = 0;
927 }
928 break ;
929 case inGoAway:
930 if (TrackGoAway(window, ev->where))
931 {
932 if ( win )
933 win->Close() ;
934 }
935 s_lastMouseDown = 0;
936 break;
937 case inGrow:
938 int growResult = GrowWindow(window , ev->where, &qd.screenBits.bounds);
939 if (growResult != 0)
940 {
941 int newWidth = LoWord(growResult);
942 int newHeight = HiWord(growResult);
943 int oldWidth, oldHeight;
944
945 win->GetSize(&oldWidth, &oldHeight);
946 if (newWidth == 0)
947 newWidth = oldWidth;
948 if (newHeight == 0)
949 newHeight = oldHeight;
950
951 if (win)
952 win->SetSize( -1, -1, newWidth, newHeight, wxSIZE_USE_EXISTING);
953 }
954 s_lastMouseDown = 0;
955 break;
956 case inZoomIn:
957 case inZoomOut:
958 if (TrackBox(window, ev->where, windowPart))
959 {
960 // TODO setup size event
961 ZoomWindow( window , windowPart , false ) ;
962 if (win)
963 win->SetSize( -1, -1, window->portRect.right-window->portRect.left ,
964 window->portRect.bottom-window->portRect.top, wxSIZE_USE_EXISTING);
965 }
966 s_lastMouseDown = 0;
967 break;
968 case inCollapseBox :
969 // TODO setup size event
970 s_lastMouseDown = 0;
971 break ;
972
973 case inContent :
974 if ( window != frontWindow )
975 {
976 if ( s_macIsInModalLoop )
977 {
978 SysBeep ( 30 ) ;
979 }
980 else if ( UMAIsWindowFloating( window ) )
981 {
982 if ( win )
983 win->MacMouseDown( ev , windowPart ) ;
984 }
985 else
986 {
987 UMASelectWindow( window ) ;
988 }
989 }
990 else
991 {
992 if ( win )
993 win->MacMouseDown( ev , windowPart ) ;
994 }
995 break ;
996
997 default:
998 break;
999 }
1000 }
1001
1002 void wxApp::MacHandleMouseUpEvent( EventRecord *ev )
1003 {
1004 WindowRef window;
1005
1006 short windowPart = ::FindWindow(ev->where, &window);
1007
1008 switch (windowPart)
1009 {
1010 case inMenuBar :
1011 break ;
1012 case inSysWindow :
1013 break ;
1014 default:
1015 {
1016 wxWindow* win = wxFindWinFromMacWindow( window ) ;
1017 if ( win )
1018 win->MacMouseUp( ev , windowPart ) ;
1019 }
1020 break;
1021 }
1022 }
1023
1024 long wxMacTranslateKey(char key, char code)
1025 {
1026 switch (key)
1027 {
1028 case 0x01 :
1029 key = WXK_HOME;
1030 break;
1031 case 0x03 :
1032 key = WXK_RETURN;
1033 break;
1034 case 0x04 :
1035 key = WXK_END;
1036 break;
1037 case 0x05 :
1038 key = WXK_HELP;
1039 break;
1040 case 0x08 :
1041 key = WXK_BACK;
1042 break;
1043 case 0x09 :
1044 key = WXK_TAB;
1045 break;
1046 case 0x0b :
1047 key = WXK_PAGEUP;
1048 break;
1049 case 0x0c :
1050 key = WXK_PAGEDOWN;
1051 break;
1052 case 0x0d :
1053 key = WXK_RETURN;
1054 break;
1055 case 0x10 :
1056 {
1057 switch( code )
1058 {
1059 case 0x7a :
1060 key = WXK_F1 ;
1061 break;
1062 case 0x78 :
1063 key = WXK_F2 ;
1064 break;
1065 case 0x63 :
1066 key = WXK_F3 ;
1067 break;
1068 case 0x76 :
1069 key = WXK_F4 ;
1070 break;
1071 case 0x60 :
1072 key = WXK_F5 ;
1073 break;
1074 case 0x61 :
1075 key = WXK_F6 ;
1076 break;
1077 case 0x62:
1078 key = WXK_F7 ;
1079 break;
1080 case 0x64 :
1081 key = WXK_F8 ;
1082 break;
1083 case 0x65 :
1084 key = WXK_F9 ;
1085 break;
1086 case 0x6D :
1087 key = WXK_F10 ;
1088 break;
1089 case 0x67 :
1090 key = WXK_F11 ;
1091 break;
1092 case 0x6F :
1093 key = WXK_F12 ;
1094 break;
1095 case 0x69 :
1096 key = WXK_F13 ;
1097 break;
1098 case 0x6B :
1099 key = WXK_F14 ;
1100 break;
1101 case 0x71 :
1102 key = WXK_F15 ;
1103 break;
1104 }
1105 }
1106 break ;
1107 case 0x1b :
1108 key = WXK_DELETE ;
1109 break ;
1110 case 0x1c :
1111 key = WXK_LEFT ;
1112 break ;
1113 case 0x1d :
1114 key = WXK_RIGHT ;
1115 break ;
1116 case 0x1e :
1117 key = WXK_UP ;
1118 break ;
1119 case 0x1f :
1120 key = WXK_DOWN ;
1121 break ;
1122 default:
1123 break ;
1124 } // end switch
1125
1126 return key;
1127 }
1128
1129 void wxApp::MacHandleKeyDownEvent( EventRecord *ev )
1130 {
1131 UInt32 menuresult = UMAMenuEvent(ev) ;
1132 if ( HiWord( menuresult ) )
1133 MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ) ;
1134 else
1135 {
1136 short keycode ;
1137 short keychar ;
1138 keychar = short(ev->message & charCodeMask);
1139 keycode = short(ev->message & keyCodeMask) >> 8 ;
1140
1141 wxWindow* focus = wxWindow::FindFocus() ;
1142 if ( focus )
1143 {
1144 wxKeyEvent event(wxEVT_CHAR);
1145 event.m_shiftDown = ev->modifiers & shiftKey;
1146 event.m_controlDown = ev->modifiers & controlKey;
1147 event.m_altDown = ev->modifiers & optionKey;
1148 event.m_metaDown = ev->modifiers & cmdKey;
1149 event.m_keyCode = wxMacTranslateKey(keychar, keycode);
1150 event.m_x = ev->where.h;
1151 event.m_y = ev->where.v;
1152 event.m_timeStamp = ev->when;
1153 event.SetEventObject(focus);
1154 focus->GetEventHandler()->ProcessEvent( event ) ;
1155 }
1156 }
1157 }
1158
1159 void wxApp::MacHandleKeyUpEvent( EventRecord *ev )
1160 {
1161 // nothing to do
1162 }
1163
1164 void wxApp::MacHandleActivateEvent( EventRecord *ev )
1165 {
1166 WindowRef window = (WindowRef) ev->message ;
1167 if ( window )
1168 {
1169 bool activate = (ev->modifiers & activeFlag ) ;
1170 WindowClass wclass ;
1171 UMAGetWindowClass ( window , &wclass ) ;
1172 if ( wclass == kFloatingWindowClass )
1173 {
1174 // if it is a floater we activate/deactivate the front non-floating window instead
1175 window = UMAFrontNonFloatingWindow() ;
1176 }
1177 wxWindow* win = wxFindWinFromMacWindow( window ) ;
1178 if ( win )
1179 win->MacActivate( ev , activate ) ;
1180 }
1181 }
1182
1183 void wxApp::MacHandleUpdateEvent( EventRecord *ev )
1184 {
1185 WindowRef window = (WindowRef) ev->message ;
1186 wxWindow * win = wxFindWinFromMacWindow( window ) ;
1187 if ( win )
1188 {
1189 win->MacUpdate( ev ) ;
1190 }
1191 }
1192
1193 void wxApp::MacHandleDiskEvent( EventRecord *ev )
1194 {
1195 if ( HiWord( ev->message ) != noErr )
1196 {
1197 OSErr err ;
1198 Point point ;
1199 SetPt( &point , 100 , 100 ) ;
1200
1201 err = DIBadMount( point , ev->message ) ;
1202 wxASSERT( err == noErr ) ;
1203 }
1204 }
1205
1206 void wxApp::MacHandleOSEvent( EventRecord *ev )
1207 {
1208 switch( ( ev->message & osEvtMessageMask ) >> 24 )
1209 {
1210 case suspendResumeMessage :
1211 {
1212 bool isResuming = ev->message & resumeFlag ;
1213 bool convertClipboard = ev->message & convertClipboardFlag ;
1214 bool doesActivate = UMAGetProcessModeDoesActivateOnFGSwitch() ;
1215 if ( isResuming )
1216 {
1217 WindowRef oldFrontWindow = NULL ;
1218 WindowRef newFrontWindow = NULL ;
1219
1220 // in case we don't take care of activating ourselves, we have to synchronize
1221 // our idea of the active window with the process manager's - which it already activated
1222
1223 if ( !doesActivate )
1224 oldFrontWindow = UMAFrontNonFloatingWindow() ;
1225
1226 MacResume( convertClipboard ) ;
1227
1228 newFrontWindow = UMAFrontNonFloatingWindow() ;
1229
1230 if ( oldFrontWindow )
1231 {
1232 wxWindow* win = wxFindWinFromMacWindow( oldFrontWindow ) ;
1233 if ( win )
1234 win->MacActivate( ev , false ) ;
1235 }
1236 if ( newFrontWindow )
1237 {
1238 wxWindow* win = wxFindWinFromMacWindow( newFrontWindow ) ;
1239 if ( win )
1240 win->MacActivate( ev , true ) ;
1241 }
1242 }
1243 else
1244 {
1245 MacSuspend( convertClipboard ) ;
1246
1247 // in case this suspending did close an active window, another one might
1248 // have surfaced -> lets deactivate that one
1249
1250 WindowRef newActiveWindow = UMAGetActiveNonFloatingWindow() ;
1251 if ( newActiveWindow )
1252 {
1253 wxWindow* win = wxFindWinFromMacWindow( newActiveWindow ) ;
1254 if ( win )
1255 win->MacActivate( ev , false ) ;
1256 }
1257 }
1258 }
1259 break ;
1260 case mouseMovedMessage :
1261 {
1262 WindowRef window;
1263
1264 wxWindow* currentMouseWindow = NULL ;
1265
1266 MacGetWindowFromPoint( wxPoint( ev->where.h , ev->where.v ) , &currentMouseWindow ) ;
1267
1268 if ( currentMouseWindow != wxWindow::s_lastMouseWindow )
1269 {
1270 wxMouseEvent event ;
1271
1272 bool isDown = !(ev->modifiers & btnState) ; // 1 is for up
1273 bool controlDown = ev->modifiers & controlKey ; // for simulating right mouse
1274
1275 event.m_leftDown = isDown && !controlDown;
1276 event.m_middleDown = FALSE;
1277 event.m_rightDown = isDown && controlDown;
1278 event.m_shiftDown = ev->modifiers & shiftKey;
1279 event.m_controlDown = ev->modifiers & controlKey;
1280 event.m_altDown = ev->modifiers & optionKey;
1281 event.m_metaDown = ev->modifiers & cmdKey;
1282 event.m_x = ev->where.h;
1283 event.m_y = ev->where.v;
1284 event.m_timeStamp = ev->when;
1285 event.SetEventObject(this);
1286
1287 if ( wxWindow::s_lastMouseWindow )
1288 {
1289 wxMouseEvent eventleave(event ) ;
1290 eventleave.SetEventType( wxEVT_LEAVE_WINDOW ) ;
1291 wxWindow::s_lastMouseWindow->GetEventHandler()->ProcessEvent(eventleave);
1292 }
1293 if ( currentMouseWindow )
1294 {
1295 wxMouseEvent evententer(event ) ;
1296 evententer.SetEventType( wxEVT_ENTER_WINDOW ) ;
1297 currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
1298 }
1299 wxWindow::s_lastMouseWindow = currentMouseWindow ;
1300 }
1301
1302 short windowPart = ::FindWindow(ev->where, &window);
1303
1304 switch (windowPart)
1305 {
1306 case inMenuBar :
1307 break ;
1308 case inSysWindow :
1309 break ;
1310 default:
1311 {
1312 if ( s_lastMouseDown == 0 )
1313 ev->modifiers |= btnState ;
1314
1315 wxWindow* win = wxFindWinFromMacWindow( window ) ;
1316 if ( win )
1317 win->MacMouseMoved( ev , windowPart ) ;
1318 }
1319 break;
1320 }
1321 }
1322 break ;
1323
1324 }
1325 }
1326
1327 void wxApp::MacHandleMenuSelect( int macMenuId , int macMenuItemNum )
1328 {
1329 if (macMenuId == 0)
1330 return; // no menu item selected
1331
1332 if (macMenuId == kwxMacAppleMenuId && macMenuItemNum > 1)
1333 {
1334 #if ! TARGET_CARBON
1335 Str255 deskAccessoryName ;
1336 GrafPtr savedPort ;
1337
1338 GetMenuItemText(GetMenuHandle(kwxMacAppleMenuId), macMenuItemNum, deskAccessoryName);
1339 GetPort(&savedPort);
1340 OpenDeskAcc(deskAccessoryName);
1341 SetPort(savedPort);
1342 #endif
1343 }
1344 else
1345 {
1346 wxWindow* frontwindow = wxFindWinFromMacWindow( ::FrontWindow() ) ;
1347 if ( frontwindow && wxMenuBar::MacGetInstalledMenuBar() )
1348 wxMenuBar::MacGetInstalledMenuBar()->MacMenuSelect( frontwindow->GetEventHandler() , 0 , macMenuId , macMenuItemNum ) ;
1349 }
1350 HiliteMenu(0);
1351 }
1352
1353 /*
1354 long wxApp::MacTranslateKey(char key, int mods)
1355 {
1356 }
1357
1358 void wxApp::MacAdjustCursor()
1359 {
1360 }
1361
1362 */
1363 /*
1364 void
1365 wxApp::macAdjustCursor()
1366 {
1367 if (ev->what != kHighLevelEvent)
1368 {
1369 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow());
1370 if (theMacWxFrame)
1371 {
1372 if (!theMacWxFrame->MacAdjustCursor(ev->where))
1373 ::SetCursor(&(qd.arrow));
1374 }
1375 }
1376 }
1377 */