]> git.saurik.com Git - wxWidgets.git/blame - src/mac/app.cpp
crash in some very special case when arrows were used to move around fixed
[wxWidgets.git] / src / mac / app.cpp
CommitLineData
e9576ca5
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: app.cpp
3// Purpose: wxApp
4// Author: AUTHOR
5// Modified by:
6// Created: ??/??/98
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
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
40#include "apprsrc.h"
41
e9576ca5
SC
42extern char *wxBuffer;
43extern wxList wxPendingDelete;
44
45wxApp *wxTheApp = NULL;
46
47#if !USE_SHARED_LIBRARY
48IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
49BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
50 EVT_IDLE(wxApp::OnIdle)
51END_EVENT_TABLE()
52#endif
53
8be97d65 54long wxApp::sm_lastMessageTime = 0;
169935ad 55
8be97d65
SC
56const short kMacMinHeap = (29 * 1024) ;
57// platform specific static variables
169935ad 58
8be97d65
SC
59bool gMacHasAppearance = false ;
60long gMacAppearanceVersion = 0 ;
61RgnHandle gMacCursorRgn = NULL ;
169935ad 62
e9576ca5
SC
63
64bool wxApp::Initialize()
65{
169935ad
SC
66 int error = 0 ;
67
8be97d65
SC
68 // Mac-specific
69 long total,contig;
70
71 // init all managers
72
73 ::InitGraf(&qd.thePort);
74 ::InitFonts();
75 ::InitWindows();
76 ::InitMenus();
77 ::TEInit();
78 ::InitDialogs(0L);
79 ::InitCursor();
80 CursHandle aCursHandle = ::GetCursor(watchCursor); // Watch should be in system
81 if (aCursHandle)
82 ::SetCursor(*aCursHandle);
83 ::FlushEvents(everyEvent, 0);
84
85 // setup memory of application
169935ad 86
8be97d65
SC
87 ::MaxApplZone();
88 for (long i = 1; i <= 4; i++)
89 ::MoreMasters();
90 PurgeSpace(&total, &contig);
91 ::SetCursor( &qd.arrow ) ;
92
93#if 0
94 InitAEHandlers();
95 InitializeAECore() ;
96 GUSISetup(GUSIwithInternetSockets);
97#endif
98
99 // test the minimal configuration necessary
100
101 long theSystem ;
102 long theMachine;
103 long theAppearance ;
104
105 if (Gestalt(gestaltMachineType, &theMachine) != noErr)
106 {
107 error = kMacSTRWrongMachine;
108 }
109 else if (theMachine < gestaltMacPlus)
110 {
111 error = kMacSTRWrongMachine;
112 }
113 else if (Gestalt(gestaltSystemVersion, &theSystem) != noErr )
114 {
115 error = kMacSTROldSystem ;
116 }
117 else if ( theSystem < 0x0700 )
118 {
119 error = kMacSTROldSystem ;
120 }
121 else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap)
122 {
123 error = kMacSTRSmallSize;
124 }
125 else
126 {
127 if ( Gestalt( gestaltAppearanceAttr, &theAppearance ) == noErr )
128 {
129 gMacHasAppearance = true ;
130 RegisterAppearanceClient();
131 if ( Gestalt( gestaltAppearanceVersion, &theAppearance ) == noErr )
132 {
133 gMacAppearanceVersion = theAppearance ;
134 }
135 else
136 {
137 gMacAppearanceVersion = 0x0100 ;
138 }
139 }
140 else
141 error = kMacSTRNoPre8Yet ;
142 }
143
144 // if we encountered any problems so far, give the error code and exit immediately
145
169935ad 146 if ( error )
8be97d65
SC
147 {
148 short itemHit;
149 Str255 message;
150
151 SetCursor(&qd.arrow);
152 GetIndString(message, 128, error);
153 ParamText(message, (ConstStr255Param)"\p", (ConstStr255Param)"\p", (ConstStr255Param)"\p");
154 itemHit = Alert(129, nil);
155 return FALSE ;
169935ad
SC
156 }
157
8be97d65
SC
158 // now avoid exceptions thrown for new (bad_alloc)
159
160 std::__throws_bad_alloc = FALSE ;
161
162 gMacCursorRgn = ::NewRgn() ;
163
e9576ca5
SC
164#ifdef __WXMSW__
165 wxBuffer = new char[1500];
166#else
167 wxBuffer = new char[BUFSIZ + 512];
168#endif
169
170/* No longer used
171#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
172
173 streambuf* sBuf = new wxDebugStreamBuf;
174 ostream* oStr = new ostream(sBuf) ;
175 wxDebugContext::SetStream(oStr, sBuf);
176#endif
177*/
178
179 wxClassInfo::InitializeClasses();
180
181 wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
182 wxTheColourDatabase->Initialize();
183
184 wxInitializeStockLists();
185 wxInitializeStockObjects();
186
187#if wxUSE_WX_RESOURCES
188 wxInitializeResourceSystem();
189#endif
190
191 wxBitmap::InitStandardHandlers();
192
193 wxModule::RegisterModules();
194 wxASSERT( wxModule::InitializeModules() == TRUE );
195
196 return TRUE;
197}
198
199void wxApp::CleanUp()
200{
201 wxModule::CleanUpModules();
202
203#if wxUSE_WX_RESOURCES
204 wxCleanUpResourceSystem();
205#endif
206
207 wxDeleteStockObjects() ;
208
209 // Destroy all GDI lists, etc.
210
211 delete wxTheBrushList;
212 wxTheBrushList = NULL;
213
214 delete wxThePenList;
215 wxThePenList = NULL;
216
217 delete wxTheFontList;
218 wxTheFontList = NULL;
219
220 delete wxTheBitmapList;
221 wxTheBitmapList = NULL;
222
223 delete wxTheColourDatabase;
224 wxTheColourDatabase = NULL;
225
226 wxBitmap::CleanUpHandlers();
227
228 delete[] wxBuffer;
229 wxBuffer = NULL;
230
231 wxClassInfo::CleanUpClasses();
232
233 delete wxTheApp;
234 wxTheApp = NULL;
235
236#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
237 // At this point we want to check if there are any memory
238 // blocks that aren't part of the wxDebugContext itself,
239 // as a special case. Then when dumping we need to ignore
240 // wxDebugContext, too.
241 if (wxDebugContext::CountObjectsLeft() > 0)
242 {
243 wxTrace("There were memory leaks.\n");
244 wxDebugContext::Dump();
245 wxDebugContext::PrintStatistics();
246 }
247// wxDebugContext::SetStream(NULL, NULL);
248#endif
249
250 // do it as the very last thing because everything else can log messages
251 wxLog::DontCreateOnDemand();
252 // do it as the very last thing because everything else can log messages
253 delete wxLog::SetActiveTarget(NULL);
169935ad 254
8be97d65
SC
255 ::PrClose() ;
256 if (gMacCursorRgn)
257 ::DisposeRgn(gMacCursorRgn);
258 #if 0
259 TerminateAE() ;
260 #endif
e9576ca5
SC
261}
262
263int wxEntry( int argc, char *argv[] )
264{
265 if (!wxApp::Initialize())
266 return FALSE;
267 if (!wxTheApp)
268 {
269 if (!wxApp::GetInitializerFunction())
270 {
271 printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" );
272 return 0;
273 };
274
275 wxTheApp = (wxApp*) (* wxApp::GetInitializerFunction()) ();
276 };
277
278 if (!wxTheApp)
279 {
280 printf( "wxWindows error: wxTheApp == NULL\n" );
281 return 0;
282 };
283
284 wxTheApp->argc = argc;
285 wxTheApp->argv = argv;
286
287 // GUI-specific initialization, such as creating an app context.
288 wxTheApp->OnInitGui();
289
290 // Here frames insert themselves automatically
291 // into wxTopLevelWindows by getting created
292 // in OnInit().
293
294 if (!wxTheApp->OnInit()) return 0;
295
296 int retValue = 0;
297
298 if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun();
299
300 if (wxTheApp->GetTopWindow())
301 {
302 delete wxTheApp->GetTopWindow();
303 wxTheApp->SetTopWindow(NULL);
304 }
305
306 wxTheApp->DeletePendingObjects();
307
308 wxTheApp->OnExit();
309
310 wxApp::CleanUp();
311
312 return retValue;
313};
314
315// Static member initialization
316wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
317
318wxApp::wxApp()
319{
320 m_topWindow = NULL;
321 wxTheApp = this;
322 m_className = "";
323 m_wantDebugOutput = TRUE ;
324 m_appName = "";
325 argc = 0;
326 argv = NULL;
327#ifdef __WXMSW__
328 m_printMode = wxPRINT_WINDOWS;
329#else
330 m_printMode = wxPRINT_POSTSCRIPT;
331#endif
332 m_exitOnFrameDelete = TRUE;
333 m_auto3D = TRUE;
334}
335
336bool wxApp::Initialized()
337{
e9576ca5 338 return TRUE;
169935ad
SC
339// if (GetTopWindow())
340// return TRUE;
341// else
342// return FALSE;
e9576ca5
SC
343}
344
345int wxApp::MainLoop()
346{
347 m_keepGoing = TRUE;
348
e9576ca5
SC
349 while (m_keepGoing)
350 {
8be97d65 351 MacDoOneEvent() ;
e9576ca5 352 }
e9576ca5
SC
353
354 return 0;
355}
356
357// Returns TRUE if more time is needed.
358bool wxApp::ProcessIdle()
359{
360 wxIdleEvent event;
361 event.SetEventObject(this);
362 ProcessEvent(event);
363
364 return event.MoreRequested();
365}
366
367void wxApp::ExitMainLoop()
368{
369 m_keepGoing = FALSE;
370}
371
372// Is a message/event pending?
373bool wxApp::Pending()
374{
375/* TODO.
376 */
377 return FALSE;
378}
379
380// Dispatch a message.
381void wxApp::Dispatch()
382{
383/* TODO.
384 */
385}
386
387void wxApp::OnIdle(wxIdleEvent& event)
388{
389 static bool inOnIdle = FALSE;
390
391 // Avoid recursion (via ProcessEvent default case)
392 if (inOnIdle)
393 return;
394
395 inOnIdle = TRUE;
396
397 // 'Garbage' collection of windows deleted with Close().
398 DeletePendingObjects();
399
400 // flush the logged messages if any
401 wxLog *pLog = wxLog::GetActiveTarget();
402 if ( pLog != NULL && pLog->HasPendingMessages() )
403 pLog->Flush();
404
405 // Send OnIdle events to all windows
406 bool needMore = SendIdleEvents();
407
408 if (needMore)
409 event.RequestMore(TRUE);
410
411 inOnIdle = FALSE;
412}
413
414// Send idle event to all top-level windows
415bool wxApp::SendIdleEvents()
416{
417 bool needMore = FALSE;
418 wxNode* node = wxTopLevelWindows.First();
419 while (node)
420 {
421 wxWindow* win = (wxWindow*) node->Data();
422 if (SendIdleEvents(win))
423 needMore = TRUE;
424
425 node = node->Next();
426 }
427 return needMore;
428}
429
430// Send idle event to window and all subwindows
431bool wxApp::SendIdleEvents(wxWindow* win)
432{
433 bool needMore = FALSE;
434
435 wxIdleEvent event;
436 event.SetEventObject(win);
437 win->ProcessEvent(event);
438
439 if (event.MoreRequested())
440 needMore = TRUE;
441
442 wxNode* node = win->GetChildren().First();
443 while (node)
444 {
445 wxWindow* win = (wxWindow*) node->Data();
446 if (SendIdleEvents(win))
447 needMore = TRUE;
448
449 node = node->Next();
450 }
451 return needMore ;
452}
453
454void wxApp::DeletePendingObjects()
455{
456 wxNode *node = wxPendingDelete.First();
457 while (node)
458 {
459 wxObject *obj = (wxObject *)node->Data();
460
461 delete obj;
462
463 if (wxPendingDelete.Member(obj))
464 delete node;
465
466 // Deleting one object may have deleted other pending
467 // objects, so start from beginning of list again.
468 node = wxPendingDelete.First();
469 }
470}
471
472wxLog* wxApp::CreateLogTarget()
473{
474 return new wxLogGui;
475}
476
477wxWindow* wxApp::GetTopWindow() const
478{
479 if (m_topWindow)
480 return m_topWindow;
481 else if (wxTopLevelWindows.Number() > 0)
482 return (wxWindow*) wxTopLevelWindows.First()->Data();
483 else
484 return NULL;
485}
486
487void wxExit()
488{
489 wxApp::CleanUp();
8be97d65 490 ::ExitToShell() ;
e9576ca5
SC
491}
492
493// Yield to other processes
494bool wxYield()
495{
169935ad 496#if 0
8be97d65
SC
497 ::YieldToOtherThreads() ;
498 ::SystemTime() ;
169935ad 499#endif
8be97d65 500 return TRUE;
169935ad
SC
501}
502
8be97d65 503// platform specifics
169935ad 504
8be97d65 505void wxApp::MacDoOneEvent()
169935ad
SC
506{
507 EventRecord event ;
508
509 long sleepTime = 60;
510
169935ad
SC
511 if (WaitNextEvent(everyEvent, &event,sleepTime, gMacCursorRgn))
512 {
8be97d65 513 MacHandleOneEvent( &event );
169935ad
SC
514 }
515 else
516 {
8be97d65
SC
517 // idlers
518 wxTheApp->ProcessIdle() ;
169935ad 519 }
8be97d65
SC
520
521 // repeaters
522#if 0
523 wxMacProcessSocketEvents() ;
524#endif
169935ad
SC
525}
526
8be97d65 527void wxApp::MacHandleOneEvent( EventRecord *ev )
169935ad 528{
169935ad
SC
529 switch (ev->what)
530 {
531 case nullEvent:
8be97d65 532 MacHandleNullEvent( ev ) ;
169935ad
SC
533 break ;
534 case kHighLevelEvent:
8be97d65 535 MacHandleHighLevelEvent( ev ) ;
169935ad
SC
536 break;
537 case mouseDown:
8be97d65 538 MacHandleMouseDownEvent( ev ) ;
169935ad
SC
539 wxTheApp->ExitMainLoop() ;
540 break;
541 case mouseUp:
8be97d65 542 MacHandleMouseUpEvent( ev ) ;
169935ad
SC
543 break;
544 case keyDown:
8be97d65 545 MacHandleKeyDownEvent( ev ) ;
169935ad
SC
546 break;
547 case autoKey:
8be97d65 548 MacHandleAutoKeyEvent( ev ) ;
169935ad
SC
549 break;
550 case keyUp:
8be97d65 551 MacHandleKeyUpEvent( ev ) ;
169935ad
SC
552 break;
553 case activateEvt:
8be97d65 554 MacHandleActivateEvent( ev ) ;
169935ad
SC
555 break;
556 case updateEvt:
8be97d65 557 MacHandleUpdateEvent( ev ) ;
169935ad
SC
558 break;
559 case diskEvt:
8be97d65 560 MacHandleDiskEvent( ev ) ;
169935ad
SC
561 break;
562 case osEvt:
8be97d65 563 MacHandleOSEvent( ev ) ;
169935ad
SC
564 break;
565 default:
566 break;
567 }
169935ad
SC
568}
569
8be97d65 570void wxApp::MacHandleNullEvent( EventRecord *ev )
169935ad
SC
571{
572}
573
8be97d65 574void wxApp::MacHandleHighLevelEvent( EventRecord *ev )
169935ad
SC
575{
576}
577
8be97d65 578void wxApp::MacHandleMouseDownEvent( EventRecord *ev )
169935ad
SC
579{
580}
581
8be97d65 582void wxApp::MacHandleMouseUpEvent( EventRecord *ev )
169935ad
SC
583{
584}
585
8be97d65 586void wxApp::MacHandleKeyDownEvent( EventRecord *ev )
169935ad
SC
587{
588}
589
8be97d65 590void wxApp::MacHandleKeyUpEvent( EventRecord *ev )
169935ad
SC
591{
592}
593
8be97d65 594void wxApp::MacHandleAutoKeyEvent( EventRecord *ev )
169935ad
SC
595{
596}
597
8be97d65 598void wxApp::MacHandleActivateEvent( EventRecord *ev )
169935ad
SC
599{
600}
601
8be97d65 602void wxApp::MacHandleUpdateEvent( EventRecord *ev )
169935ad
SC
603{
604}
605
8be97d65 606void wxApp::MacHandleDiskEvent( EventRecord *ev )
169935ad
SC
607{
608}
609
8be97d65 610void wxApp::MacHandleOSEvent( EventRecord *ev )
169935ad
SC
611{
612}
613
614
615
616/*
617
618void wxApp::doMacMouseDown(void)
619{
620 WindowPtr window;
621 short windowPart = ::FindWindow(m_event.where, &window);
622 if ( windowPart != inMenuBar )
623 {
624 WindowPtr frontWindow = FrontWindow();
625 if (WindowIsModal(frontWindow) && (window != frontWindow))
626 SysBeep(1);
627 else
628 {
629 switch (windowPart)
630 {
631 case inMenuBar:
632 break;
633 case inContent:
634 doMacInContent(window); break;
635 case inDrag:
636 doMacInDrag(window); break;
637 case inGrow:
638 doMacInGrow(window); break;
639 case inGoAway:
640 doMacInGoAway(window); break;
641 case inZoomIn:
642 case inZoomOut:
643 doMacInZoom(window, windowPart); break;
644 default:
645 break;
646 }
647
648 }
649 }
650 else
651 {
652 doMacInMenuBar(::MenuSelect(m_event.where));
653 }
654}
655
656void wxApp::doMacMouseUp(void)
657{
658 if (m_mouseWindow)
659 {
660#if 0
661 int hitX = m_event.where.h; // screen window c.s.
662 int hitY = m_event.where.v; // screen window c.s.
663 m_mouseWindow->ScreenToClient(&hitX, &hitY); // mouseWindow client c.s.
664 m_mouseWindow->ClientToLogical(&hitX, &hitY); // mouseWindow logical c.s.
665#endif
666
667 wxMouseEvent event(wxEVT_LEFT_UP);
668 event.m_shiftDown = m_event.modifiers & shiftKey;
669 event.m_controlDown = m_event.modifiers & controlKey;
670 event.m_altDown = m_event.modifiers & optionKey;
671 event.m_metaDown = m_event.modifiers & cmdKey;
672 event.m_leftDown = FALSE;
673 event.m_middleDown = FALSE;
674 event.m_rightDown = FALSE;
675 event.m_x = m_event.where.h;
676 event.m_y = m_event.where.v;
677 event.m_timeStamp = m_event.when;
678 event.SetEventObject(m_mouseWindow);
679
680 m_mouseWindow->ProcessEvent(event);
681 }
682 else
683 {
684 //??? Can't we just throw away mouse up events without matching mouse down
685 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow());
686 if (theMacWxFrame)
687 {
688#if 0
689 int hitX = cCurrentEvent.where.h; // screen window c.s.
690 int hitY = cCurrentEvent.where.v; // screen window c.s.
691 theMacWxFrame->ScreenToWindow(&hitX, &hitY);
692#endif
693
694 wxMouseEvent event(wxEVT_LEFT_UP);
695 event.m_shiftDown = m_event.modifiers & shiftKey;
696 event.m_controlDown = m_event.modifiers & controlKey;
697 event.m_altDown = m_event.modifiers & optionKey;
698 event.m_metaDown = m_event.modifiers & cmdKey;
699 event.m_leftDown = FALSE;
700 event.m_middleDown = FALSE;
701 event.m_rightDown = FALSE;
702 event.m_x = m_event.where.h;
703 event.m_y = m_event.where.v;
704 event.m_timeStamp = m_event.when;
705 event.SetEventObject(m_mouseWindow);
706
707 theMacWxFrame->ProcessEvent(event);
708 }
709 }
710}
711
712void wxApp::doMacMouseMotion(void)
713{
714 if (m_mouseWindow) {
715 wxMouseEvent event(wxEVT_MOTION);
716 event.m_shiftDown = m_event.modifiers & shiftKey;
717 event.m_controlDown = m_event.modifiers & controlKey;
718 event.m_altDown = m_event.modifiers & optionKey;
719 event.m_metaDown = m_event.modifiers & cmdKey;
720 event.m_leftDown = !(m_event.modifiers & btnState);
721 event.m_middleDown = FALSE;
722 event.m_rightDown = FALSE;
723 event.m_x = m_event.where.h;
724 event.m_y = m_event.where.v;
725 event.m_timeStamp = m_event.when;
726 event.SetEventObject(m_mouseWindow);
727
728 m_mouseWindow->ProcessEvent(event);
729 }
730 else
731 {
732 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow());
733 if (theMacWxFrame)
734 {
735 wxMouseEvent event(wxEVT_MOTION);
736 event.m_shiftDown = m_event.modifiers & shiftKey;
737 event.m_controlDown = m_event.modifiers & controlKey;
738 event.m_altDown = m_event.modifiers & optionKey;
739 event.m_metaDown = m_event.modifiers & cmdKey;
740 event.m_leftDown = !(m_event.modifiers & btnState);
741 event.m_middleDown = FALSE;
742 event.m_rightDown = FALSE;
743 event.m_x = m_event.where.h;
744 event.m_y = m_event.where.v;
745 event.m_timeStamp = m_event.when;
746 event.SetEventObject(m_mouseWindow);
747
748 m_mouseWindow->ProcessEvent(event);
749 }
750 }
751
752 //??? Need to work with floating windows... isn't there a toolbox call to find the
753 // top window intersecting a point is screen coordinates??
754#if 0
755 else // will only work for one floating window at the moment... ?
756 {
757 WindowPtr frontDocPtr = findFrontNonFloatingWindow();
758 WindowPtr frontFloatingPtr = ::FrontWindow();
759
760 int hitX = cCurrentEvent.where.h;
761 int hitY = cCurrentEvent.where.v;
762
763 wxFrame* macWxFrame = findMacWxFrame(frontDocPtr);
764
765 if ((frontFloatingPtr != frontDocPtr) & (frontFloatingPtr != NULL))
766 {
767 RgnHandle frontFloatStrRgn = getStructureRegion(frontFloatingPtr);
768 Rect frontFloatRect = (**frontFloatStrRgn).rgnBBox;
769
770 if ((hitX >= frontFloatRect.left) &
771 (hitX <= frontFloatRect.right) &
772 (hitY >= frontFloatRect.top) &
773 (hitY <= frontFloatRect.bottom))
774 {
775 macWxFrame = findMacWxFrame(frontFloatingPtr);
776 }
777 }
778 }
779#endif
780}
781
782void wxApp::doMacKeyDown(void)
783{
784 long menuResult = 0 ;
785 short keycode ;
786 short keychar ;
787 keychar = short(m_event.message & charCodeMask);
788 keycode = short(m_event.message & keyCodeMask) >> 8 ;
789
790 // Handle menu accelerators
791 if ( gSFMacHasAppearance )
792 {
793 menuResult = MenuEvent( &m_event ) ;
794 if ( HiWord( menuResult ) )
795 {
796 doMacInMenuBar( menuResult ) ;
797 }
798 else
799 {
800 ControlHandle control ;
801
802 GetKeyboardFocus( FrontNonFloatingWindow() , &control ) ;
803 if ( control && keychar != 0x07 )
804 HandleControlKey( control , keycode , keychar , m_event.modifiers ) ;
805 else
806 {
807 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow());
808 if (theMacWxFrame)
809 {
810 wxKeyEvent event(wxEVT_CHAR);
811 event.m_shiftDown = m_event.modifiers & shiftKey;
812 event.m_controlDown = m_event.modifiers & controlKey;
813 event.m_altDown = m_event.modifiers & optionKey;
814 event.m_metaDown = m_event.modifiers & cmdKey;
815 event.m_keyCode = macTranslateKey(keychar, m_event.modifiers & (shiftKey|optionKey));
816 event.m_x = m_event.where.h;
817 event.m_y = m_event.where.v;
818 event.m_timeStamp = m_event.when;
819 event.SetEventObject(theMacWxFrame);
820
821 theMacWxFrame->ProcessEvent(event);
822 }
823 }
824 }
825 }
826 else
827 {
828 if (GetMenuHandle( kwxMacAppleMenuId ) )
829 {
830// menuResult = MDEF_MenuKey(m_event.message, m_event.modifiers , GetMenuHandle( kwxMacAppleMenuId ) );
831 }
832 else
833 {
834 if (m_event.modifiers & cmdKey)
835 {
836 menuResult = MenuKey( keychar ) ;
837 }
838 }
839
840 if ( HiWord( menuResult ) )
841 {
842 doMacInMenuBar( menuResult ) ;
843 }
844 else
845 {
846 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow());
847 if (theMacWxFrame)
848 {
849 wxKeyEvent event(wxEVT_CHAR);
850 event.m_shiftDown = m_event.modifiers & shiftKey;
851 event.m_controlDown = m_event.modifiers & controlKey;
852 event.m_altDown = m_event.modifiers & optionKey;
853 event.m_metaDown = m_event.modifiers & cmdKey;
854 event.m_keyCode = macTranslateKey(keychar, m_event.modifiers & (shiftKey|optionKey));
855 event.m_x = m_event.where.h;
856 event.m_y = m_event.where.v;
857 event.m_timeStamp = m_event.when;
858 event.SetEventObject(theMacWxFrame);
859
860 theMacWxFrame->ProcessEvent(event);
861 }
862 }
863 }
864}
865
866void wxApp::doMacAutoKey(void)
867{
868 doMacKeyDown();
869}
870
871void wxApp::doMacKeyUp(void)
872{
873}
874
875void wxApp::doMacActivateEvt(void)
876{
877 HighlightAndActivateWindow( (WindowPtr) m_event.message , m_event.modifiers & activeFlag ) ;
878}
879
880void wxApp::doMacUpdateEvt(void)
881{
882 WindowPtr theMacWindow = (WindowPtr)(m_event.message);
883 ::BeginUpdate(theMacWindow);
884
885 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(theMacWindow);
886 if (theMacWxFrame)
887 {
888// if (!::EmptyRgn(theMacWindow->visRgn)) // this doesn't work with windowshade
889// {
890 if ( theMacWxFrame->MacSetupPort() )
891 {
892 // Erase update region
893 // we must do this, because controls add their former rect to the inval
894 // rgn and the background might not have been correct at that moment
895 ::EraseRect(&theMacWindow->portRect);
896
897 // Can't use UpdateControls since each control has it's own coordinate system
898 // ::UpdateControls(theMacWindow, theMacWindow->visRgn);
899
900 ::UpdateControls( theMacWindow , theMacWindow->visRgn ) ;
901 #if 0
902 // Draw the grow box
903 if (cStyle & wxRESIZE_BORDER)
904 MacDrawGrowIcon();
905 #endif
906
907 wxPaintEvent event;
908 event.m_timeStamp = m_event.when;
909 event.SetEventObject(theMacWxFrame);
910
911 theMacWxFrame->ProcessEvent(event);
912 // ::SetThemeWindowBackground( theMacWindow , kThemeActiveDialogBackgroundBrush , false ) ;
913 ::ClipRect( &theMacWindow->portRect ) ;
914 ::SetOrigin( 0 , 0 );
915 }
916 else
917 {
918 wxASSERT_MSG( false , "unabled to setup window mac port") ;
919 }
920
921// }
922 }
923
924 ::EndUpdate(theMacWindow);
925}
926
927void wxApp::doMacDiskEvt(void)
928{ // based on "Programming for System 7" by Gary Little and Tim Swihart
929 if ((m_event.message >> 16) != noErr)
930 {
931 const int kDILeft = 0x0050; // top coord for disk init dialog
932 const int kDITop = 0x0070; // left coord for disk init dialog
933 Point mountPoint;
934 mountPoint.h = kDILeft;
935 mountPoint.v = kDITop;
936 int myError = DIBadMount(mountPoint, m_event.message);
937 }
938}
939
940void wxApp::doMacOsEvt(void)
941{ // based on "Programming for System 7" by Gary Little and Tim Swihart
942 switch ((m_event.message >> 24) & 0x0ff)
943 {
944 case suspendResumeMessage:
945 if (m_event.message & resumeFlag)
946 doMacResumeEvent();
947 else
948 doMacSuspendEvent();
949 break;
950 case mouseMovedMessage:
951 doMacMouseMovedMessage();
952 break;
953 }
954}
955
956void wxApp::doMacHighLevelEvent(void)
957{
958 ::AEProcessAppleEvent(&m_event); // System 7 or higher
959}
960
961void wxApp::doMacResumeEvent(void)
962{
963 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow());
964 if (theMacWxFrame)
965 {
966 if (m_event.message & convertClipboardFlag)
967 ::TEFromScrap();
968
969 wxActivateEvent event(wxEVT_ACTIVATE, TRUE);
970 event.m_timeStamp = m_event.when;
971 event.SetEventObject(theMacWxFrame);
972
973 theMacWxFrame->ProcessEvent(event);
974 }
975}
976
977void wxApp::doMacSuspendEvent(void)
978{
979 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow());
980 if (theMacWxFrame)
981 {
982 ::ZeroScrap();
983 ::TEToScrap();
984
985 wxActivateEvent event(wxEVT_ACTIVATE, FALSE);
986 event.m_timeStamp = m_event.when;
987 event.SetEventObject(theMacWxFrame);
988
989 theMacWxFrame->ProcessEvent(event);
990 }
991}
992
993void wxApp::doMacMouseMovedMessage(void)
994{ // based on "Programming for System 7" by Gary Little and Tim Swihart
995 if (m_cursorRgn)
996 ::DisposeRgn(m_cursorRgn);
997 m_cursorRgn = ::NewRgn();
998 ::SetRectRgn(m_cursorRgn, -32768, -32768, 32766, 32766);
999}
1000
1001void wxApp::doMacInMenuBar(long menuResult)
1002{
1003 int macMenuId = HiWord(menuResult);
1004 int macMenuItemNum = LoWord(menuResult); // counting from 1
1005
1006 if (macMenuId == 0) // no menu item selected;
1007 return;
1008 if (macMenuId == 128)
1009 {
1010 if (macMenuItemNum != 1)
1011 { // if not the "About" entry (or the separator)
1012 Str255 daName;
1013 ::GetMenuItemText(GetMenuHandle(128), macMenuItemNum, daName);
1014 (void)::OpenDeskAcc(daName);
1015 ::HiliteMenu(0);
1016 return;
1017 }
1018 }
1019
1020 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow());
1021 if (theMacWxFrame)
1022 {
1023 if ( theMacWxFrame->IsKindOf( CLASSINFO( wxDialog ) ) )
1024 (( wxDialog *) theMacWxFrame)->MacMenuSelect(m_event, macMenuId, macMenuItemNum);
1025 else if ( theMacWxFrame->IsKindOf( CLASSINFO( wxFrame ) ) )
1026 (( wxFrame *) theMacWxFrame)->MacMenuSelect(m_event, macMenuId, macMenuItemNum);
1027 }
1028 ::HiliteMenu(0);
1029}
1030
1031void wxApp::doMacInContent(WindowPtr window)
1032{
1033 WindowPtr frontWindow = FrontWindow();
1034 if (window != frontWindow )
1035 {
1036// SFSelectWindow( window ) ;
1037 }
1038 else
1039 {
1040 ControlHandle control ;
1041 Point localwhere = m_event.where ;
1042 GrafPtr port ;
1043 SInt16 controlpart ;
1044
1045 ::GetPort( &port ) ;
1046 ::SetPort( window ) ;
1047 ::GlobalToLocal( &localwhere ) ;
1048
1049 ::SetPort( port ) ;
1050
1051 if ( !gSFMacHasAppearance )
1052 {
1053 controlpart = FindControl( localwhere , window , &control ) ;
1054 }
1055 else
1056 {
1057 control = FindControlUnderMouse( localwhere , window , &controlpart ) ;
1058 }
1059
1060 if ( control && IsControlActive( control ) )
1061 {
1062 wxControl* wxc = (wxControl*) GetControlReference( control ) ;
1063
1064 if ( wxWindow::FindFocus() != wxc && wxc->AcceptsFocus() )
1065 {
1066 wxc->SetFocus() ;
1067 if ( wxWindow::FindFocus() != wxc )
1068 control = NULL ; // we were not able to change focus
1069 }
1070
1071 if ( control )
1072 {
1073 if ( !gSFMacHasAppearance)
1074 {
1075 controlpart = TrackControl( control , localwhere , NULL ) ;
1076 }
1077 else
1078 {
1079 controlpart = HandleControlClick( control , localwhere , m_event.modifiers , (ControlActionUPP) -1 ) ;
1080 }
1081
1082 if ( controlpart )
1083 {
1084 wxControl* wx = (wxControl*) GetControlReference( control ) ;
1085 if ( wx )
1086 wx->MacHandleControlClick( control , controlpart ) ;
1087 }
1088 }
1089 }
1090 else
1091 {
1092 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(window);
1093 if (theMacWxFrame)
1094 {
1095 doMacContentClick((wxFrame*)theMacWxFrame); // todo : this cast is wrong
1096 }
1097 }
1098 }
1099
1100#if 0
1101 wxFrame* theMacWxFrame = findMacWxFrame(window);
1102 if (theMacWxFrame)
1103 {
1104 WindowPtr MacWindow = findFrontNonFloatingWindow();
1105 if (window != MacWindow)
1106 {
1107 wxFrame* frontFrame = findMacWxFrame(MacWindow);
1108 if (!frontFrame) wxFatalError("No wxFrame for frontnonfloatingWindow.");
1109 if (!frontFrame->IsModal())
1110 {
1111 frontFrame->SetFocus();
1112 doMacContentClick(theMacWxFrame); // jonto - to deal with doc windows behind floaters ?
1113 ::newSelectWindow(window); // WCH : should I be calling some wxMethod?
1114 if (!IsFloating(MacWindow))
1115 {
1116 KeyMap keyMap;
1117 GetKeys(keyMap);
1118 if (!(keyMap[1] & 0x8000)) theMacWxFrame->ShowAsActive(true); // temporary measure...
1119 }
1120 } // jonto : not sure yet, but let's try this ...
1121 else ::SysBeep(3);
1122 }
1123 else
1124 {
1125 doMacContentClick(theMacWxFrame);
1126 }
1127 }
1128#endif
1129}
1130
1131void wxApp::doMacContentClick(wxWindow* frame)
1132{
1133 m_mouseWindow = frame;
1134
1135 wxMouseEvent event(wxEVT_LEFT_DOWN);
1136 event.m_shiftDown = m_event.modifiers & shiftKey;
1137 event.m_controlDown = m_event.modifiers & controlKey;
1138 event.m_altDown = m_event.modifiers & optionKey;
1139 event.m_metaDown = m_event.modifiers & cmdKey;
1140 event.m_leftDown = FALSE;
1141 event.m_middleDown = FALSE;
1142 event.m_rightDown = FALSE;
1143 if ( m_event.modifiers & controlKey )
1144 {
1145 event.m_rightDown = TRUE;
1146 }
1147 else
1148 {
1149 event.m_leftDown = TRUE;
1150 }
1151#if 0
1152 event.m_leftDown = !(m_event.modifiers & btnState);
1153 event.m_middleDown = FALSE;
1154 event.m_rightDown = FALSE;
1155#endif
1156 event.m_x = m_event.where.h;
1157 event.m_y = m_event.where.v;
1158 event.m_timeStamp = m_event.when;
1159 event.SetEventObject(m_mouseWindow);
1160
1161// m_mouseWindow->ProcessEvent(event);
1162 m_mouseWindow->MacDispatchMouseEvent(event);
1163
1164#if 0
1165 // RightButton is cmdKey click on the mac platform for one-button mouse
1166 Bool rightButton = cCurrentEvent.modifiers & cmdKey;
1167 // altKey is optionKey on the mac platform:
1168 Bool isAltKey = cCurrentEvent.modifiers & optionKey;
1169
1170 WXTYPE mouseEventType = rightButton ? wxEVENT_TYPE_RIGHT_DOWN
1171 : wxEVENT_TYPE_LEFT_DOWN;
1172 wxMouseEvent theMouseEvent(mouseEventType);
1173 theMouseEvent.leftDown = !rightButton;
1174 theMouseEvent.middleDown = FALSE;
1175 theMouseEvent.rightDown = rightButton;
1176 theMouseEvent.shiftDown = cCurrentEvent.modifiers & shiftKey;
1177 theMouseEvent.controlDown = cCurrentEvent.modifiers & controlKey;
1178 theMouseEvent.altDown = isAltKey;
1179 theMouseEvent.metaDown = FALSE; // mflatt
1180 theMouseEvent.timeStamp = cCurrentEvent.when; // mflatt
1181
1182 int hitX = cCurrentEvent.where.h; // screen window c.s.
1183 int hitY = cCurrentEvent.where.v; // screen window c.s.
1184
1185 frame->ScreenToWindow(&hitX, &hitY);
1186// frameParentArea->ScreenToArea(&hitX, &hitY); // tx coords ?
1187 theMouseEvent.x = hitX; // frame parent area c.s.
1188 theMouseEvent.y = hitY; // frame parent area c.s.
1189
1190 frame->SeekMouseEventArea(theMouseEvent);
1191#endif
1192}
1193
1194void wxApp::doMacInDrag(WindowPtr window)
1195{
1196 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(window);
1197 if (theMacWxFrame)
1198 {
1199 // should be desktop, not screen
1200 Rect dragBoundsRect = qd.screenBits.bounds; // can't move to a different screen
1201//xxx ::InsetRect(&dragBoundsRect, 4, ::GetMBarHeight() + 4); // This is not really necessary
1202 Rect oldPos = (**(((WindowPeek)window)->strucRgn)).rgnBBox;
1203 ::DragReferencedWindow(window, m_event.where, &dragBoundsRect); // jonto
1204 #if 0
1205 theMacWxFrame->m_x += (**(((WindowPeek)window)->strucRgn)).rgnBBox.left - oldPos.left;
1206 theMacWxFrame->m_y += (**(((WindowPeek)window)->strucRgn)).rgnBBox.top - oldPos.top;
1207 #endif
1208 Move( (**(((WindowPeek)window)->strucRgn)).rgnBBox.left , (**(((WindowPeek)window)->strucRgn)).rgnBBox.top ) ;
1209#if 0
1210 theMacWxFrame->wxMacRecalcNewSize(); // Actually, recalc new position only
1211#endif
1212 }
1213
1214#if 0
1215// if (window != ::FrontWindow())
1216 if (window != findFrontNonFloatingWindow())
1217 {
1218// wxFrame* frontFrame = findMacWxFrame(::FrontWindow());
1219 wxFrame* frontFrame = findMacWxFrame(findFrontNonFloatingWindow());
1220 if (!frontFrame) wxFatalError("No wxFrame for frontWindow.");
1221 if (frontFrame->IsModal())
1222 {
1223 ::SysBeep(3);
1224 return;
1225 }
1226 }
1227
1228 wxFrame* theMacWxFrame = findMacWxFrame(window);
1229 if (theMacWxFrame)
1230 {
1231 Rect dragBoundsRect = qd.screenBits.bounds; // can't move to a different screen
1232 ::InsetRect(&dragBoundsRect, 4, ::GetMBarHeight() + 4); // This is not really necessary
1233 newDragWindow(window, cCurrentEvent.where, &dragBoundsRect); // jonto
1234 theMacWxFrame->wxMacRecalcNewSize(); // Actually, recalc new position only
1235 if (!IsFloating(window))
1236 {
1237 theMacWxFrame->ShowAsActive(true); // temporary measure...
1238 }
1239 }
1240#endif
1241}
1242
1243void wxApp::doMacInGrow(WindowPtr window)
1244{
1245 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(window);
1246 if (theMacWxFrame)
1247 {
1248 Rect growSizeRect; // WCH: growSizeRect should be a member of wxFrame class
1249 growSizeRect.top = 1; // minimum window height
1250 growSizeRect.left = 1; // minimum window width
1251 growSizeRect.bottom = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top;
1252 growSizeRect.right = qd.screenBits.bounds.right - qd.screenBits.bounds.left;
1253 long windSize = ::GrowWindow(window, m_event.where, &growSizeRect);
1254 if (windSize != 0)
1255 {
1256 int nWidth = LoWord(windSize);
1257 int nHeight = HiWord(windSize);
1258 int oWidth, oHeight;
1259 theMacWxFrame->GetSize(&oWidth, &oHeight);
1260 if (nWidth == 0) nWidth = oWidth;
1261 if (nHeight == 0) nHeight = oHeight;
1262 theMacWxFrame->SetSize( -1, -1, nWidth, nHeight, wxSIZE_USE_EXISTING);
1263 }
1264 }
1265}
1266
1267void wxApp::doMacInGoAway(WindowPtr window)
1268{
1269 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(window);
1270 if (theMacWxFrame)
1271 {
1272 if (TrackGoAway(window, m_event.where))
1273 {
e3065973
JS
1274 // TODO: Stefan, I think you need to send a wxCloseEvent to the window
1275 // here. The OnCloseWindow handler will take care of delete the frame
1276 // if it wishes to (there should be a default wxFrame::OnCloseWindow
1277 // that destroys the frame).
169935ad
SC
1278 if (theMacWxFrame->OnClose()) {
1279#if WXGARBAGE_COLLECTION_ON
1280 theMacWxFrame->Show(FALSE);
1281#else
1282 delete theMacWxFrame;
1283#endif
1284 }
1285 }
1286 }
1287}
1288
1289void wxApp::doMacInZoom(WindowPtr window, short windowPart)
1290{
1291 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(window);
1292 if (theMacWxFrame)
1293 {
1294 if (TrackBox(window, m_event.where, windowPart))
1295 {
1296#if 0
1297 theMacWxFrame->Maximize(windowPart == inZoomOut);
1298#endif
1299 }
1300 }
1301}
1302
1303long wxApp::macTranslateKey(char key, int mods)
1304{
1305 static Handle transH = NULL;
1306 static unsigned long transState = 0;
1307 static Handle ScriptH = NULL;
1308 static short region_code = 1;
1309
1310 if (!ScriptH) { // tom: don't guess the regioncode!!!!
1311 struct ItlbRecord * r;
1312 ScriptH = GetResource('itlb',0);
1313 if (ScriptH) {
1314 HLock(ScriptH);
1315 r = (ItlbRecord*)*ScriptH;
1316 region_code = r->itlbKeys;
1317 HUnlock(ScriptH);
1318 }
1319 }
1320
1321 switch (key) {
1322 case 0x7e:
1323 case 0x3e:
1324 key = WXK_UP;
1325 break;
1326 case 0x7d:
1327 case 0x3d:
1328 key = WXK_DOWN;
1329 break;
1330 case 0x7b:
1331 case 0x3b:
1332 key = WXK_LEFT;
1333 break;
1334 case 0x7c:
1335 case 0x3c:
1336 key = WXK_RIGHT;
1337 break;
1338 case 0x24:
1339 case 0x4c:
1340 key = WXK_RETURN;
1341 break;
1342 case 0x30:
1343 key = WXK_TAB;
1344 break;
1345 case 0x33:
1346 key = WXK_BACK;
1347 break;
1348 case 0x75:
1349 key = WXK_DELETE;
1350 break;
1351 case 0x73:
1352 key = WXK_HOME;
1353 break;
1354 case 0x77:
1355 key = WXK_END;
1356 break;
1357 case 0x74:
1358 key = WXK_PAGEUP;
1359 break;
1360 case 0x79:
1361 key = WXK_PAGEDOWN;
1362 break;
1363 default:
1364 if (!transH) {
1365 transH = GetIndResource('KCHR', 1);
1366 HNoPurge(transH);
1367 }
1368#if 0 //Tom replaces
1369 if (transH) {
1370 // Only let shift & option modify the key:
1371 HLock(transH);
1372 key = KeyTranslate(*transH, (key & 0x7F) | mods, &transState) & charCodeMask;
1373 HUnlock(transH);
1374#else
1375 if (0) { // tom fettig@dfki.uni-sb.de
1376 // why if(0):
1377 // code is not correct, see inside Macintosh: Text 1-87
1378 // and 'itlk'-resource!!
1379 // and it is not necessary, as the translated char is in
1380 // cCurrrentEvent.message!!
1381 // Only let shift & option modify the key:
1382 HLock(transH);
1383 key = KeyTranslate(*transH, (key & 0x7F) | mods, &transState) & charCodeMask;
1384 HUnlock(transH);
1385#endif
1386 }
1387 } // end switch
1388
1389 return key;
1390}
1391
1392void
1393wxApp::macAdjustCursor()
1394{
1395 if (m_event.what != kHighLevelEvent)
1396 {
1397 wxWindow* theMacWxFrame = wxFrame::MacFindFrameOrDialog(::FrontWindow());
1398 if (theMacWxFrame)
1399 {
1400 if (!theMacWxFrame->MacAdjustCursor(m_event.where))
1401 ::SetCursor(&(qd.arrow));
1402 }
1403 }
1404}
1405*/