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