]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/toplevel.cpp
trying to avoid redraw problems at wrong places
[wxWidgets.git] / src / mac / carbon / toplevel.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: mac/toplevel.cpp
3 // Purpose: implements wxTopLevelWindow for MSW
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 24.09.01
7 // RCS-ID: $Id$
8 // Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
9 // License: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "toplevel.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/app.h"
33 #include "wx/toplevel.h"
34 #include "wx/frame.h"
35 #include "wx/string.h"
36 #include "wx/log.h"
37 #include "wx/intl.h"
38 #endif //WX_PRECOMP
39
40 #include "wx/mac/uma.h"
41 #include "wx/mac/aga.h"
42 #include "wx/app.h"
43 #include "wx/tooltip.h"
44 #include "wx/dnd.h"
45
46 #include "ToolUtils.h"
47
48
49 #define wxMAC_DEBUG_REDRAW 0
50 #ifndef wxMAC_DEBUG_REDRAW
51 #define wxMAC_DEBUG_REDRAW 0
52 #endif
53
54 // ----------------------------------------------------------------------------
55 // globals
56 // ----------------------------------------------------------------------------
57
58 // list of all frames and modeless dialogs
59 wxWindowList wxModelessWindows;
60
61 // double click testing
62 static Point gs_lastWhere;
63 static long gs_lastWhen = 0;
64
65
66 #if TARGET_CARBON
67 static pascal long wxShapedMacWindowDef(short varCode, WindowRef window, SInt16 message, SInt32 param);
68 #endif
69
70 // ============================================================================
71 // wxTopLevelWindowMac implementation
72 // ============================================================================
73
74 // ---------------------------------------------------------------------------
75 // Carbon Events
76 // ---------------------------------------------------------------------------
77
78 #if TARGET_CARBON
79
80 extern long wxMacTranslateKey(unsigned char key, unsigned char code) ;
81
82 static const EventTypeSpec eventList[] =
83 {
84 { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } ,
85
86 { kEventClassKeyboard, kEventRawKeyDown } ,
87 { kEventClassKeyboard, kEventRawKeyRepeat } ,
88 { kEventClassKeyboard, kEventRawKeyUp } ,
89 { kEventClassKeyboard, kEventRawKeyModifiersChanged } ,
90
91 { kEventClassWindow , kEventWindowUpdate } ,
92 { kEventClassWindow , kEventWindowActivated } ,
93 { kEventClassWindow , kEventWindowDeactivated } ,
94 { kEventClassWindow , kEventWindowBoundsChanging } ,
95 { kEventClassWindow , kEventWindowBoundsChanged } ,
96 { kEventClassWindow , kEventWindowClose } ,
97
98 { kEventClassMouse , kEventMouseDown } ,
99 { kEventClassMouse , kEventMouseUp } ,
100 { kEventClassMouse , kEventMouseMoved } ,
101 { kEventClassMouse , kEventMouseDragged } ,
102
103 } ;
104
105 static pascal OSStatus TextInputEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
106 {
107 OSStatus result = eventNotHandledErr ;
108
109 wxWindow* focus = wxWindow::FindFocus() ;
110 char charCode ;
111 UInt32 keyCode ;
112 UInt32 modifiers ;
113 Point point ;
114
115 EventRef rawEvent ;
116
117 GetEventParameter( event , kEventParamTextInputSendKeyboardEvent ,typeEventRef,NULL,sizeof(rawEvent),NULL,&rawEvent ) ;
118
119 GetEventParameter( rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL,sizeof(char), NULL,&charCode );
120 GetEventParameter( rawEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
121 GetEventParameter( rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
122 GetEventParameter( rawEvent, kEventParamMouseLocation, typeQDPoint, NULL,
123 sizeof( Point ), NULL, &point );
124
125 switch ( GetEventKind( event ) )
126 {
127 case kEventTextInputUnicodeForKeyEvent :
128 // this is only called when no default handler has jumped in, eg a wxControl on a floater window does not
129 // get its own kEventTextInputUnicodeForKeyEvent, so we route back the
130 wxControl* control = wxDynamicCast( focus , wxControl ) ;
131 if ( control )
132 {
133 ControlHandle macControl = (ControlHandle) control->GetMacControl() ;
134 if ( macControl )
135 {
136 ::HandleControlKey( macControl , keyCode , charCode , modifiers ) ;
137 result = noErr ;
138 }
139 }
140 /*
141 // this may lead to double events sent to a window in case all handlers have skipped the key down event
142 UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
143 UInt32 message = (keyCode << 8) + charCode;
144
145 if ( (focus != NULL) && wxTheApp->MacSendKeyDownEvent(
146 focus , message , modifiers , when , point.h , point.v ) )
147 {
148 result = noErr ;
149 }
150 */
151 break ;
152 }
153
154 return result ;
155 }
156
157 static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
158 {
159 OSStatus result = eventNotHandledErr ;
160
161 wxWindow* focus = wxWindow::FindFocus() ;
162 char charCode ;
163 UInt32 keyCode ;
164 UInt32 modifiers ;
165 Point point ;
166 UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
167
168 GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, NULL,sizeof(char), NULL,&charCode );
169 GetEventParameter( event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
170 GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
171 GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL,
172 sizeof( Point ), NULL, &point );
173
174 UInt32 message = (keyCode << 8) + charCode;
175 switch( GetEventKind( event ) )
176 {
177 case kEventRawKeyRepeat :
178 case kEventRawKeyDown :
179 {
180 WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;
181 WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
182 wxTheApp->MacSetCurrentEvent( event , handler ) ;
183 if ( (focus != NULL) && wxTheApp->MacSendKeyDownEvent(
184 focus , message , modifiers , when , point.h , point.v ) )
185 {
186 result = noErr ;
187 }
188 wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;
189 }
190 break ;
191 case kEventRawKeyUp :
192 if ( (focus != NULL) && wxTheApp->MacSendKeyUpEvent(
193 focus , message , modifiers , when , point.h , point.v ) )
194 {
195 result = noErr ;
196 }
197 break ;
198 case kEventRawKeyModifiersChanged :
199 {
200 wxKeyEvent event(wxEVT_KEY_DOWN);
201
202 event.m_shiftDown = modifiers & shiftKey;
203 event.m_controlDown = modifiers & controlKey;
204 event.m_altDown = modifiers & optionKey;
205 event.m_metaDown = modifiers & cmdKey;
206
207 event.m_x = point.h;
208 event.m_y = point.v;
209 event.m_timeStamp = when;
210 wxWindow* focus = wxWindow::FindFocus() ;
211 event.SetEventObject(focus);
212
213 if ( focus && (modifiers ^ wxTheApp->s_lastModifiers ) & controlKey )
214 {
215 event.m_keyCode = WXK_CONTROL ;
216 event.SetEventType( ( modifiers & controlKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
217 focus->GetEventHandler()->ProcessEvent( event ) ;
218 }
219 if ( focus && (modifiers ^ wxTheApp->s_lastModifiers ) & shiftKey )
220 {
221 event.m_keyCode = WXK_SHIFT ;
222 event.SetEventType( ( modifiers & shiftKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
223 focus->GetEventHandler()->ProcessEvent( event ) ;
224 }
225 if ( focus && (modifiers ^ wxTheApp->s_lastModifiers ) & optionKey )
226 {
227 event.m_keyCode = WXK_ALT ;
228 event.SetEventType( ( modifiers & optionKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
229 focus->GetEventHandler()->ProcessEvent( event ) ;
230 }
231 if ( focus && (modifiers ^ wxTheApp->s_lastModifiers ) & cmdKey )
232 {
233 event.m_keyCode = WXK_COMMAND ;
234 event.SetEventType( ( modifiers & cmdKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
235 focus->GetEventHandler()->ProcessEvent( event ) ;
236 }
237 wxTheApp->s_lastModifiers = modifiers ;
238 }
239 break ;
240 }
241
242 return result ;
243 }
244
245 static pascal OSStatus MouseEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
246 {
247 OSStatus result = eventNotHandledErr ;
248
249 wxTopLevelWindowMac* toplevelWindow = (wxTopLevelWindowMac*) data ;
250 Point point ;
251 UInt32 modifiers = 0;
252 EventMouseButton button = 0 ;
253 UInt32 click = 0 ;
254
255 GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL,
256 sizeof( Point ), NULL, &point );
257 GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL,
258 sizeof( UInt32 ), NULL, &modifiers );
259 GetEventParameter( event, kEventParamMouseButton, typeMouseButton, NULL,
260 sizeof( EventMouseButton ), NULL, &button );
261 GetEventParameter( event, kEventParamClickCount, typeUInt32, NULL,
262 sizeof( UInt32 ), NULL, &click );
263
264 if ( button == 0 || GetEventKind( event ) == kEventMouseUp )
265 modifiers += btnState ;
266
267 WindowRef window ;
268 short windowPart = ::FindWindow(point, &window);
269
270 if ( IsWindowActive(window) && windowPart == inContent )
271 {
272 switch ( GetEventKind( event ) )
273 {
274 case kEventMouseDown :
275 toplevelWindow->MacFireMouseEvent( mouseDown , point.h , point.v , modifiers , EventTimeToTicks( GetEventTime( event ) ) ) ;
276 result = noErr ;
277 break ;
278 case kEventMouseUp :
279 toplevelWindow->MacFireMouseEvent( mouseUp , point.h , point.v , modifiers , EventTimeToTicks( GetEventTime( event ) ) ) ;
280 result = noErr ;
281 break ;
282 case kEventMouseMoved :
283 wxTheApp->MacHandleMouseMovedEvent( point.h , point.v , modifiers , EventTimeToTicks( GetEventTime( event ) ) ) ;
284 result = noErr ;
285 break ;
286 case kEventMouseDragged :
287 toplevelWindow->MacFireMouseEvent( nullEvent , point.h , point.v , modifiers , EventTimeToTicks( GetEventTime( event ) ) ) ;
288 result = noErr ;
289 break ;
290 default :
291 break ;
292 }
293 }
294
295 return result ;
296
297
298 }
299 static pascal OSStatus WindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
300 {
301 OSStatus result = eventNotHandledErr ;
302 OSStatus err = noErr ;
303
304 UInt32 attributes;
305 WindowRef windowRef ;
306 wxTopLevelWindowMac* toplevelWindow = (wxTopLevelWindowMac*) data ;
307
308 GetEventParameter( event, kEventParamDirectObject, typeWindowRef, NULL,
309 sizeof( WindowRef ), NULL, &windowRef );
310
311 switch( GetEventKind( event ) )
312 {
313 case kEventWindowUpdate :
314 if ( !wxPendingDelete.Member(toplevelWindow) )
315 toplevelWindow->MacUpdate( EventTimeToTicks( GetEventTime( event ) ) ) ;
316 result = noErr ;
317 break ;
318 case kEventWindowActivated :
319 toplevelWindow->MacActivate( EventTimeToTicks( GetEventTime( event ) ) , true) ;
320 result = noErr ;
321 break ;
322 case kEventWindowDeactivated :
323 toplevelWindow->MacActivate( EventTimeToTicks( GetEventTime( event ) ) , false) ;
324 result = noErr ;
325 break ;
326 case kEventWindowClose :
327 toplevelWindow->Close() ;
328 result = noErr ;
329 break ;
330 case kEventWindowBoundsChanged :
331 err = GetEventParameter( event, kEventParamAttributes, typeUInt32,
332 NULL, sizeof( UInt32 ), NULL, &attributes );
333 if ( err == noErr )
334 {
335 Rect newContentRect ;
336
337 GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL,
338 sizeof( newContentRect ), NULL, &newContentRect );
339
340 toplevelWindow->SetSize( newContentRect.left , newContentRect.top ,
341 newContentRect.right - newContentRect.left ,
342 newContentRect.bottom - newContentRect.top, wxSIZE_USE_EXISTING);
343
344 result = noErr;
345 }
346 break ;
347 case kEventWindowBoundsChanging :
348 err = GetEventParameter( event, kEventParamAttributes, typeUInt32,
349 NULL, sizeof( UInt32 ), NULL, &attributes );
350 if ( err == noErr )
351 {
352 Rect newContentRect ;
353
354 GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL,
355 sizeof( newContentRect ), NULL, &newContentRect );
356
357 wxSize formerSize = toplevelWindow->GetSize() ;
358
359 if ( (attributes & kWindowBoundsChangeSizeChanged ) ||
360 ( attributes & kWindowBoundsChangeOriginChanged ) )
361 toplevelWindow->SetSize( newContentRect.left , newContentRect.top ,
362 newContentRect.right - newContentRect.left ,
363 newContentRect.bottom - newContentRect.top, wxSIZE_USE_EXISTING);
364
365 int x , y , w , h ;
366 toplevelWindow->GetPosition( &x , &y ) ;
367 toplevelWindow->GetSize( &w , &h ) ;
368 Rect adjustedRect = { y , x , y + h , x + w } ;
369
370 if ( !EqualRect( &newContentRect , &adjustedRect ) )
371 {
372 SetEventParameter( event , kEventParamCurrentBounds , typeQDRectangle, sizeof( adjustedRect ) , &adjustedRect ) ;
373 }
374
375 if ( toplevelWindow->GetSize() != formerSize )
376 toplevelWindow->Update() ;
377
378 result = noErr ;
379 }
380 break ;
381 default :
382 break ;
383 }
384 return result ;
385 }
386
387 pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
388 {
389 OSStatus result = eventNotHandledErr ;
390
391 switch ( GetEventClass( event ) )
392 {
393 case kEventClassKeyboard :
394 result = KeyboardEventHandler( handler, event , data ) ;
395 break ;
396 case kEventClassTextInput :
397 result = TextInputEventHandler( handler, event , data ) ;
398 break ;
399 case kEventClassWindow :
400 result = WindowEventHandler( handler, event , data ) ;
401 break ;
402 case kEventClassMouse :
403 result = MouseEventHandler( handler, event , data ) ;
404 break ;
405 default :
406 break ;
407 }
408 return result ;
409 }
410
411 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler )
412
413 #endif
414
415 // ---------------------------------------------------------------------------
416 // wxWindowMac utility functions
417 // ---------------------------------------------------------------------------
418
419 // Find an item given the Macintosh Window Reference
420
421 wxList *wxWinMacWindowList = NULL;
422 wxTopLevelWindowMac *wxFindWinFromMacWindow(WXWindow inWindowRef)
423 {
424 if ( wxWinMacWindowList == NULL )
425 return NULL ;
426 wxNode *node = wxWinMacWindowList->Find((long)inWindowRef);
427 if (!node)
428 return NULL;
429 return (wxTopLevelWindowMac *)node->GetData();
430 }
431
432 void wxAssociateWinWithMacWindow(WXWindow inWindowRef, wxTopLevelWindowMac *win)
433 {
434 // adding NULL WindowRef is (first) surely a result of an error and
435 // (secondly) breaks menu command processing
436 wxCHECK_RET( inWindowRef != (WindowRef) NULL, wxT("attempt to add a NULL WindowRef to window list") );
437
438 if ( !wxWinMacWindowList->Find((long)inWindowRef) )
439 wxWinMacWindowList->Append((long)inWindowRef, win);
440 }
441
442 void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win)
443 {
444 wxWinMacWindowList->DeleteObject(win);
445 }
446
447
448 // ----------------------------------------------------------------------------
449 // wxTopLevelWindowMac creation
450 // ----------------------------------------------------------------------------
451
452 WXHWND wxTopLevelWindowMac::s_macWindowInUpdate = NULL;
453 wxTopLevelWindowMac *wxTopLevelWindowMac::s_macDeactivateWindow = NULL;
454
455 void wxTopLevelWindowMac::Init()
456 {
457 m_iconized =
458 m_maximizeOnShow = FALSE;
459 m_macNoEraseUpdateRgn = NewRgn() ;
460 m_macNeedsErasing = false ;
461 m_macWindow = NULL ;
462 #if TARGET_CARBON
463 m_macEventHandler = NULL ;
464 #endif
465 }
466
467 class wxMacDeferredWindowDeleter : public wxObject
468 {
469 public :
470 wxMacDeferredWindowDeleter( WindowRef windowRef )
471 {
472 m_macWindow = windowRef ;
473 }
474 virtual ~wxMacDeferredWindowDeleter()
475 {
476 UMADisposeWindow( (WindowRef) m_macWindow ) ;
477 }
478 protected :
479 WindowRef m_macWindow ;
480 } ;
481
482 bool wxTopLevelWindowMac::Create(wxWindow *parent,
483 wxWindowID id,
484 const wxString& title,
485 const wxPoint& pos,
486 const wxSize& size,
487 long style,
488 const wxString& name)
489 {
490 // init our fields
491 Init();
492
493 m_windowStyle = style;
494
495 SetName(name);
496
497 m_windowId = id == -1 ? NewControlId() : id;
498
499 wxTopLevelWindows.Append(this);
500
501 if ( parent )
502 parent->AddChild(this);
503
504 return TRUE;
505 }
506
507 wxTopLevelWindowMac::~wxTopLevelWindowMac()
508 {
509 if ( m_macWindow )
510 {
511 wxToolTip::NotifyWindowDelete(m_macWindow) ;
512 wxPendingDelete.Append( new wxMacDeferredWindowDeleter( (WindowRef) m_macWindow ) ) ;
513 }
514
515 #if TARGET_CARBON
516 if ( m_macEventHandler )
517 {
518 ::RemoveEventHandler((EventHandlerRef) m_macEventHandler);
519 m_macEventHandler = NULL ;
520 }
521 #endif
522
523 wxRemoveMacWindowAssociation( this ) ;
524
525 if ( wxModelessWindows.Find(this) )
526 wxModelessWindows.DeleteObject(this);
527
528 DisposeRgn( (RgnHandle) m_macNoEraseUpdateRgn ) ;
529 }
530
531
532 // ----------------------------------------------------------------------------
533 // wxTopLevelWindowMac maximize/minimize
534 // ----------------------------------------------------------------------------
535
536 void wxTopLevelWindowMac::Maximize(bool maximize)
537 {
538 ZoomWindow( (WindowRef)m_macWindow , maximize ? inZoomOut : inZoomIn , false ) ;
539
540 Rect tempRect ;
541 GrafPtr port ;
542 GetPort( &port ) ;
543 Point pt = { 0, 0 } ;
544 SetPortWindowPort((WindowRef)m_macWindow) ;
545 LocalToGlobal( &pt ) ;
546 SetPort( port ) ;
547
548 GetWindowPortBounds((WindowRef)m_macWindow, &tempRect ) ;
549 SetSize( pt.h , pt.v , tempRect.right-tempRect.left ,
550 tempRect.bottom-tempRect.top, wxSIZE_USE_EXISTING);
551 }
552
553 bool wxTopLevelWindowMac::IsMaximized() const
554 {
555 return IsWindowInStandardState( (WindowRef)m_macWindow , NULL , NULL ) ;
556 }
557
558 void wxTopLevelWindowMac::Iconize(bool iconize)
559 {
560 if ( IsWindowCollapsable((WindowRef)m_macWindow) )
561 CollapseWindow((WindowRef)m_macWindow , iconize ) ;
562 }
563
564 bool wxTopLevelWindowMac::IsIconized() const
565 {
566 return IsWindowCollapsed((WindowRef)m_macWindow ) ;
567 }
568
569 void wxTopLevelWindowMac::Restore()
570 {
571 // not available on mac
572 }
573
574 // ----------------------------------------------------------------------------
575 // wxTopLevelWindowMac misc
576 // ----------------------------------------------------------------------------
577
578 void wxTopLevelWindowMac::SetIcon(const wxIcon& icon)
579 {
580 // this sets m_icon
581 wxTopLevelWindowBase::SetIcon(icon);
582 }
583
584 void wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title,
585 const wxPoint& pos,
586 const wxSize& size,
587 long style,
588 const wxString& name )
589 {
590 OSStatus err = noErr ;
591 SetName(name);
592 m_windowStyle = style;
593 m_isShown = FALSE;
594
595 // create frame.
596
597 Rect theBoundsRect;
598
599 m_x = (int)pos.x;
600 m_y = (int)pos.y;
601 if ( m_y < 50 )
602 m_y = 50 ;
603 if ( m_x < 20 )
604 m_x = 20 ;
605
606 m_width = size.x;
607 if (m_width == -1)
608 m_width = 20;
609 m_height = size.y;
610 if (m_height == -1)
611 m_height = 20;
612
613 ::SetRect(&theBoundsRect, m_x, m_y , m_x + m_width, m_y + m_height);
614
615 // translate the window attributes in the appropriate window class and attributes
616
617 WindowClass wclass = 0;
618 WindowAttributes attr = kWindowNoAttributes ;
619
620 if ( HasFlag( wxFRAME_TOOL_WINDOW) )
621 {
622 if (
623 HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) ||
624 HasFlag( wxSYSTEM_MENU ) || HasFlag( wxCAPTION ) ||
625 HasFlag(wxTINY_CAPTION_HORIZ) || HasFlag(wxTINY_CAPTION_VERT)
626 )
627 {
628 wclass = kFloatingWindowClass ;
629 if ( HasFlag(wxTINY_CAPTION_VERT) )
630 {
631 attr |= kWindowSideTitlebarAttribute ;
632 }
633 }
634 else
635 {
636 #if TARGET_CARBON
637 wclass = kPlainWindowClass ;
638 #else
639 wclass = kFloatingWindowClass ;
640 #endif
641 }
642 }
643 else if ( HasFlag( wxCAPTION ) )
644 {
645 wclass = kDocumentWindowClass ;
646 }
647 else
648 {
649 if ( HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) ||
650 HasFlag( wxCLOSE_BOX ) || HasFlag( wxSYSTEM_MENU ) )
651 {
652 wclass = kDocumentWindowClass ;
653 }
654 else
655 {
656 #if TARGET_CARBON
657 wclass = kPlainWindowClass ;
658 #else
659 wclass = kModalWindowClass ;
660 #endif
661 }
662 }
663
664 if ( HasFlag( wxMINIMIZE_BOX ) )
665 {
666 attr |= kWindowCollapseBoxAttribute ;
667 }
668 if ( HasFlag( wxMAXIMIZE_BOX ) )
669 {
670 attr |= kWindowFullZoomAttribute ;
671 }
672 if ( HasFlag( wxRESIZE_BORDER ) )
673 {
674 attr |= kWindowResizableAttribute ;
675 }
676 if ( HasFlag( wxCLOSE_BOX) )
677 {
678 attr |= kWindowCloseBoxAttribute ;
679 }
680
681 #if TARGET_CARBON
682 #if 0 // having problems right now with that
683 if (HasFlag(wxSTAY_ON_TOP))
684 wclass = kUtilityWindowClass;
685 #endif
686 #endif
687
688 #if TARGET_CARBON
689 if ( HasFlag(wxFRAME_SHAPED) )
690 {
691 WindowDefSpec customWindowDefSpec;
692 customWindowDefSpec.defType = kWindowDefProcPtr;
693 customWindowDefSpec.u.defProc = NewWindowDefUPP(wxShapedMacWindowDef);
694
695 err = ::CreateCustomWindow( &customWindowDefSpec, wclass,
696 attr, &theBoundsRect,
697 (WindowRef*) &m_macWindow);
698 }
699 else
700 #endif
701 {
702 err = ::CreateNewWindow( wclass , attr , &theBoundsRect , (WindowRef*)&m_macWindow ) ;
703 }
704
705 wxCHECK_RET( err == noErr, wxT("Mac OS error when trying to create new window") );
706 wxAssociateWinWithMacWindow( m_macWindow , this ) ;
707 UMASetWTitle( (WindowRef)m_macWindow , title ) ;
708 ::CreateRootControl( (WindowRef)m_macWindow , (ControlHandle*)&m_macRootControl ) ;
709 #if TARGET_CARBON
710 InstallStandardEventHandler( GetWindowEventTarget(MAC_WXHWND(m_macWindow)) ) ;
711 InstallWindowEventHandler(MAC_WXHWND(m_macWindow), GetwxMacWindowEventHandlerUPP(),
712 GetEventTypeCount(eventList), eventList, this, (EventHandlerRef *)&m_macEventHandler);
713 #endif
714 m_macFocus = NULL ;
715
716
717 #if TARGET_CARBON
718 if ( HasFlag(wxFRAME_SHAPED) )
719 {
720 // default shape matches the window size
721 wxRegion rgn(0, 0, m_width, m_height);
722 SetShape(rgn);
723 }
724 #endif
725 }
726
727 void wxTopLevelWindowMac::MacGetPortParams(WXPOINTPTR localOrigin, WXRECTPTR clipRect, WXHWND *window , wxWindowMac** rootwin)
728 {
729 ((Point*)localOrigin)->h = 0;
730 ((Point*)localOrigin)->v = 0;
731 ((Rect*)clipRect)->left = 0;
732 ((Rect*)clipRect)->top = 0;
733 ((Rect*)clipRect)->right = m_width;
734 ((Rect*)clipRect)->bottom = m_height;
735 *window = m_macWindow ;
736 *rootwin = this ;
737 }
738
739 void wxTopLevelWindowMac::ClearBackground()
740 {
741 wxWindow::ClearBackground() ;
742 }
743
744 WXWidget wxTopLevelWindowMac::MacGetContainerForEmbedding()
745 {
746 return m_macRootControl ;
747 }
748
749
750 void wxTopLevelWindowMac::MacUpdate( long timestamp)
751 {
752 wxMacPortStateHelper help( (GrafPtr) GetWindowPort( (WindowRef) m_macWindow) ) ;
753
754 RgnHandle visRgn = NewRgn() ;
755 GetPortVisibleRegion( GetWindowPort( (WindowRef)m_macWindow ), visRgn );
756 BeginUpdate( (WindowRef)m_macWindow ) ;
757
758 RgnHandle updateRgn = NewRgn();
759 RgnHandle diffRgn = NewRgn() ;
760
761 if ( updateRgn && diffRgn )
762 {
763 #if 1
764 // macos internal control redraws clean up areas we'd like to redraw ourselves
765 // therefore we pick the boundary rect and make sure we can redraw it
766 // this has to be intersected by the visRgn in order to avoid drawing over its own
767 // boundaries
768 RgnHandle trueUpdateRgn = NewRgn() ;
769 Rect trueUpdateRgnBoundary ;
770 GetPortVisibleRegion( GetWindowPort( (WindowRef)m_macWindow ), trueUpdateRgn );
771 GetRegionBounds( trueUpdateRgn , &trueUpdateRgnBoundary ) ;
772 RectRgn( updateRgn , &trueUpdateRgnBoundary ) ;
773 SectRgn( updateRgn , visRgn , updateRgn ) ;
774 if ( trueUpdateRgn )
775 DisposeRgn( trueUpdateRgn ) ;
776 SetPortVisibleRegion( GetWindowPort( (WindowRef)m_macWindow ), updateRgn ) ;
777 #else
778 GetPortVisibleRegion( GetWindowPort( (WindowRef)m_macWindow ), updateRgn );
779 #endif
780 DiffRgn( updateRgn , (RgnHandle) m_macNoEraseUpdateRgn , diffRgn ) ;
781 if ( !EmptyRgn( updateRgn ) )
782 {
783 MacRedraw( updateRgn , timestamp , m_macNeedsErasing || !EmptyRgn( diffRgn ) ) ;
784 }
785 }
786 if ( updateRgn )
787 DisposeRgn( updateRgn );
788 if ( diffRgn )
789 DisposeRgn( diffRgn );
790 if ( visRgn )
791 DisposeRgn( visRgn ) ;
792
793 EndUpdate( (WindowRef)m_macWindow ) ;
794 SetEmptyRgn( (RgnHandle) m_macNoEraseUpdateRgn ) ;
795 m_macNeedsErasing = false ;
796 }
797
798
799 // Raise the window to the top of the Z order
800 void wxTopLevelWindowMac::Raise()
801 {
802 ::SelectWindow( (WindowRef)m_macWindow ) ;
803 }
804
805 // Lower the window to the bottom of the Z order
806 void wxTopLevelWindowMac::Lower()
807 {
808 ::SendBehind( (WindowRef)m_macWindow , NULL ) ;
809 }
810
811 void wxTopLevelWindowMac::MacFireMouseEvent(
812 wxUint16 kind , wxInt32 x , wxInt32 y ,wxUint32 modifiers , long timestamp )
813 {
814 wxMouseEvent event(wxEVT_LEFT_DOWN);
815 bool isDown = !(modifiers & btnState) ; // 1 is for up
816 bool controlDown = modifiers & controlKey ; // for simulating right mouse
817
818 event.m_leftDown = isDown && !controlDown;
819
820 event.m_middleDown = FALSE;
821 event.m_rightDown = isDown && controlDown;
822
823 if ( kind == mouseDown )
824 {
825 if ( controlDown )
826 event.SetEventType(wxEVT_RIGHT_DOWN ) ;
827 else
828 event.SetEventType(wxEVT_LEFT_DOWN ) ;
829 }
830 else if ( kind == mouseUp )
831 {
832 if ( controlDown )
833 event.SetEventType(wxEVT_RIGHT_UP ) ;
834 else
835 event.SetEventType(wxEVT_LEFT_UP ) ;
836 }
837 else
838 {
839 event.SetEventType(wxEVT_MOTION ) ;
840 }
841
842 event.m_shiftDown = modifiers & shiftKey;
843 event.m_controlDown = modifiers & controlKey;
844 event.m_altDown = modifiers & optionKey;
845 event.m_metaDown = modifiers & cmdKey;
846
847 Point localwhere ;
848 localwhere.h = x ;
849 localwhere.v = y ;
850
851 GrafPtr port ;
852 ::GetPort( &port ) ;
853 ::SetPort( UMAGetWindowPort( (WindowRef)m_macWindow ) ) ;
854 ::GlobalToLocal( &localwhere ) ;
855 ::SetPort( port ) ;
856
857 if ( kind == mouseDown )
858 {
859 if ( timestamp - gs_lastWhen <= (long) GetDblTime() )
860 {
861 if ( abs( localwhere.h - gs_lastWhere.h ) < 3 && abs( localwhere.v - gs_lastWhere.v ) < 3 )
862 {
863 // This is not right if the second mouse down
864 // event occured in a differen window. We
865 // correct this in MacDispatchMouseEvent.
866 if ( controlDown )
867 event.SetEventType(wxEVT_RIGHT_DCLICK ) ;
868 else
869 event.SetEventType(wxEVT_LEFT_DCLICK ) ;
870 }
871 gs_lastWhen = 0 ;
872 }
873 else
874 {
875 gs_lastWhen = timestamp ;
876 }
877 gs_lastWhere = localwhere ;
878 }
879
880 event.m_x = localwhere.h;
881 event.m_y = localwhere.v;
882 event.m_x += m_x;
883 event.m_y += m_y;
884
885 event.m_timeStamp = timestamp;
886 event.SetEventObject(this);
887 if ( wxTheApp->s_captureWindow )
888 {
889 int x = event.m_x ;
890 int y = event.m_y ;
891 wxTheApp->s_captureWindow->ScreenToClient( &x , &y ) ;
892 event.m_x = x ;
893 event.m_y = y ;
894 event.SetEventObject( wxTheApp->s_captureWindow ) ;
895 wxTheApp->s_captureWindow->GetEventHandler()->ProcessEvent( event ) ;
896
897 if ( kind == mouseUp )
898 {
899 wxTheApp->s_captureWindow = NULL ;
900 if ( !wxIsBusy() )
901 {
902 m_cursor.MacInstall() ;
903 }
904 }
905 }
906 else
907 {
908 MacDispatchMouseEvent( event ) ;
909 }
910 }
911
912 #if !TARGET_CARBON
913
914 void wxTopLevelWindowMac::MacMouseDown( WXEVENTREF ev , short part)
915 {
916 MacFireMouseEvent( mouseDown , ((EventRecord*)ev)->where.h , ((EventRecord*)ev)->where.v ,
917 ((EventRecord*)ev)->modifiers , ((EventRecord*)ev)->when ) ;
918 }
919
920 void wxTopLevelWindowMac::MacMouseUp( WXEVENTREF ev , short part)
921 {
922 switch (part)
923 {
924 case inContent:
925 {
926 MacFireMouseEvent( mouseUp , ((EventRecord*)ev)->where.h , ((EventRecord*)ev)->where.v ,
927 ((EventRecord*)ev)->modifiers , ((EventRecord*)ev)->when ) ;
928 }
929 break ;
930 }
931 }
932
933 void wxTopLevelWindowMac::MacMouseMoved( WXEVENTREF ev , short part)
934 {
935 switch (part)
936 {
937 case inContent:
938 {
939 MacFireMouseEvent( nullEvent /*moved*/ , ((EventRecord*)ev)->where.h , ((EventRecord*)ev)->where.v ,
940 ((EventRecord*)ev)->modifiers , ((EventRecord*)ev)->when ) ;
941 }
942 break ;
943 }
944 }
945
946 #endif
947
948 void wxTopLevelWindowMac::MacDelayedDeactivation(long timestamp)
949 {
950 if(s_macDeactivateWindow)
951 {
952 wxLogDebug(wxT("Doing delayed deactivation of %p"),s_macDeactivateWindow);
953 s_macDeactivateWindow->MacActivate(timestamp, false);
954 }
955 }
956
957 void wxTopLevelWindowMac::MacActivate( long timestamp , bool inIsActivating )
958 {
959 // wxLogDebug(wxT("TopLevel=%p::MacActivate"),this);
960
961 if(s_macDeactivateWindow==this)
962 s_macDeactivateWindow=NULL;
963 MacDelayedDeactivation(timestamp);
964 wxActivateEvent event(wxEVT_ACTIVATE, inIsActivating , m_windowId);
965 event.m_timeStamp = timestamp ;
966 event.SetEventObject(this);
967
968 GetEventHandler()->ProcessEvent(event);
969
970 UMAHighlightAndActivateWindow( (WindowRef)m_macWindow , inIsActivating ) ;
971
972 // Early versions of MacOS X don't refresh backgrounds properly,
973 // so refresh the whole window on activation and deactivation.
974 long osVersion = UMAGetSystemVersion();
975 if (osVersion >= 0x1000 && osVersion < 0x1020 )
976 {
977 Refresh(TRUE);
978 }
979 else
980 {
981 // for the moment we have to resolve some redrawing issues like this
982 // the OS is stealing some redrawing areas as soon as it draws a control
983 Refresh(TRUE);
984 }
985 }
986
987 #if !TARGET_CARBON
988
989 void wxTopLevelWindowMac::MacKeyDown( WXEVENTREF ev )
990 {
991 }
992
993 #endif
994
995 void wxTopLevelWindowMac::SetTitle(const wxString& title)
996 {
997 wxWindow::SetTitle( title ) ;
998 UMASetWTitle( (WindowRef)m_macWindow , title ) ;
999 }
1000
1001 bool wxTopLevelWindowMac::Show(bool show)
1002 {
1003 if ( !wxWindow::Show(show) )
1004 return FALSE;
1005
1006 if (show)
1007 {
1008 ::TransitionWindow((WindowRef)m_macWindow,kWindowZoomTransitionEffect,kWindowShowTransitionAction,nil);
1009 ::SelectWindow( (WindowRef)m_macWindow ) ;
1010 // no need to generate events here, they will get them triggered by macos
1011 // actually they should be , but apparently they are not
1012 wxSize size(m_width, m_height);
1013 wxSizeEvent event(size, m_windowId);
1014 event.SetEventObject(this);
1015 GetEventHandler()->ProcessEvent(event);
1016 }
1017 else
1018 {
1019 ::TransitionWindow((WindowRef)m_macWindow,kWindowZoomTransitionEffect,kWindowHideTransitionAction,nil);
1020 }
1021
1022 if ( !show )
1023 {
1024 }
1025 else
1026 {
1027 Refresh() ;
1028 }
1029
1030 return TRUE;
1031 }
1032
1033 void wxTopLevelWindowMac::DoMoveWindow(int x, int y, int width, int height)
1034 {
1035 int former_x = m_x ;
1036 int former_y = m_y ;
1037 int former_w = m_width ;
1038 int former_h = m_height ;
1039
1040 int actualWidth = width;
1041 int actualHeight = height;
1042 int actualX = x;
1043 int actualY = y;
1044
1045 if ((m_minWidth != -1) && (actualWidth < m_minWidth))
1046 actualWidth = m_minWidth;
1047 if ((m_minHeight != -1) && (actualHeight < m_minHeight))
1048 actualHeight = m_minHeight;
1049 if ((m_maxWidth != -1) && (actualWidth > m_maxWidth))
1050 actualWidth = m_maxWidth;
1051 if ((m_maxHeight != -1) && (actualHeight > m_maxHeight))
1052 actualHeight = m_maxHeight;
1053
1054 bool doMove = false ;
1055 bool doResize = false ;
1056
1057 if ( actualX != former_x || actualY != former_y )
1058 {
1059 doMove = true ;
1060 }
1061 if ( actualWidth != former_w || actualHeight != former_h )
1062 {
1063 doResize = true ;
1064 }
1065
1066 if ( doMove || doResize )
1067 {
1068 m_x = actualX ;
1069 m_y = actualY ;
1070 m_width = actualWidth ;
1071 m_height = actualHeight ;
1072
1073 if ( doMove )
1074 ::MoveWindow((WindowRef)m_macWindow, m_x, m_y , false); // don't make frontmost
1075
1076 if ( doResize )
1077 ::SizeWindow((WindowRef)m_macWindow, m_width, m_height , true);
1078
1079 // the OS takes care of invalidating and erasing the new area so we only have to
1080 // take care of refreshing for full repaints
1081
1082 if ( doResize && !HasFlag(wxNO_FULL_REPAINT_ON_RESIZE) )
1083 Refresh() ;
1084
1085
1086 if ( IsKindOf( CLASSINFO( wxFrame ) ) )
1087 {
1088 wxFrame* frame = (wxFrame*) this ;
1089 frame->PositionStatusBar();
1090 frame->PositionToolBar();
1091 }
1092 if ( doMove )
1093 wxWindowMac::MacTopLevelWindowChangedPosition() ; // like this only children will be notified
1094
1095 MacRepositionScrollBars() ;
1096 if ( doMove )
1097 {
1098 wxPoint point(m_x, m_y);
1099 wxMoveEvent event(point, m_windowId);
1100 event.SetEventObject(this);
1101 GetEventHandler()->ProcessEvent(event) ;
1102 }
1103 if ( doResize )
1104 {
1105 MacRepositionScrollBars() ;
1106 wxSize size(m_width, m_height);
1107 wxSizeEvent event(size, m_windowId);
1108 event.SetEventObject(this);
1109 GetEventHandler()->ProcessEvent(event);
1110 }
1111 }
1112
1113 }
1114
1115 /*
1116 * Invalidation Mechanism
1117 *
1118 * The update mechanism reflects exactely the windows mechanism
1119 * the rect gets added to the window invalidate region, if the eraseBackground flag
1120 * has been true for any part of the update rgn the background is erased in the entire region
1121 * not just in the specified rect.
1122 *
1123 * In order to achive this, we also have an internal m_macNoEraseUpdateRgn, all rects that have
1124 * the eraseBackground flag set to false are also added to this rgn. upon receiving an update event
1125 * the update rgn is compared to the m_macNoEraseUpdateRgn and in case they differ, every window
1126 * will get the eraseBackground event first
1127 */
1128
1129 void wxTopLevelWindowMac::MacInvalidate( const WXRECTPTR rect, bool eraseBackground )
1130 {
1131 GrafPtr formerPort ;
1132 GetPort( &formerPort ) ;
1133 SetPortWindowPort( (WindowRef)m_macWindow ) ;
1134
1135 m_macNeedsErasing |= eraseBackground ;
1136
1137 // if we already know that we will have to erase, there's no need to track the rest
1138 if ( !m_macNeedsErasing)
1139 {
1140 // we end only here if eraseBackground is false
1141 // if we already have a difference between m_macNoEraseUpdateRgn and UpdateRgn
1142 // we will have to erase anyway
1143
1144 RgnHandle updateRgn = NewRgn();
1145 RgnHandle diffRgn = NewRgn() ;
1146 if ( updateRgn && diffRgn )
1147 {
1148 GetWindowUpdateRgn( (WindowRef)m_macWindow , updateRgn );
1149 Point pt = {0,0} ;
1150 LocalToGlobal( &pt ) ;
1151 OffsetRgn( updateRgn , -pt.h , -pt.v ) ;
1152 DiffRgn( updateRgn , (RgnHandle) m_macNoEraseUpdateRgn , diffRgn ) ;
1153 if ( !EmptyRgn( diffRgn ) )
1154 {
1155 m_macNeedsErasing = true ;
1156 }
1157 }
1158 if ( updateRgn )
1159 DisposeRgn( updateRgn );
1160 if ( diffRgn )
1161 DisposeRgn( diffRgn );
1162
1163 if ( !m_macNeedsErasing )
1164 {
1165 RgnHandle rectRgn = NewRgn() ;
1166 SetRectRgn( rectRgn , ((Rect*)rect)->left , ((Rect*)rect)->top , ((Rect*)rect)->right , ((Rect*)rect)->bottom ) ;
1167 UnionRgn( (RgnHandle) m_macNoEraseUpdateRgn , rectRgn , (RgnHandle) m_macNoEraseUpdateRgn ) ;
1168 DisposeRgn( rectRgn ) ;
1169 }
1170 }
1171 InvalWindowRect( (WindowRef)m_macWindow , (Rect*)rect ) ;
1172 // turn this on to debug the refreshing cycle
1173 #if wxMAC_DEBUG_REDRAW
1174 PaintRect( rect ) ;
1175 #endif
1176 SetPort( formerPort ) ;
1177 }
1178
1179
1180 bool wxTopLevelWindowMac::SetShape(const wxRegion& region)
1181 {
1182 wxCHECK_MSG( HasFlag(wxFRAME_SHAPED), FALSE,
1183 _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
1184
1185 #if TARGET_CARBON
1186 // The empty region signifies that the shape should be removed from the
1187 // window.
1188 if ( region.IsEmpty() )
1189 {
1190 wxSize sz = GetClientSize();
1191 wxRegion rgn(0, 0, sz.x, sz.y);
1192 return SetShape(rgn);
1193 }
1194
1195 // Make a copy of the region
1196 RgnHandle shapeRegion = NewRgn();
1197 CopyRgn( (RgnHandle)region.GetWXHRGN(), shapeRegion );
1198
1199 // Dispose of any shape region we may already have
1200 RgnHandle oldRgn = (RgnHandle)GetWRefCon( (WindowRef)MacGetWindowRef() );
1201 if ( oldRgn )
1202 DisposeRgn(oldRgn);
1203
1204 // Save the region so we can use it later
1205 SetWRefCon((WindowRef)MacGetWindowRef(), (SInt32)shapeRegion);
1206
1207 // Tell the window manager that the window has changed shape
1208 ReshapeCustomWindow((WindowRef)MacGetWindowRef());
1209 return TRUE;
1210 #else
1211 return FALSE;
1212 #endif
1213 }
1214
1215 // ---------------------------------------------------------------------------
1216 // Support functions for shaped windows, based on Apple's CustomWindow sample at
1217 // http://developer.apple.com/samplecode/Sample_Code/Human_Interface_Toolbox/Mac_OS_High_Level_Toolbox/CustomWindow.htm
1218 // ---------------------------------------------------------------------------
1219
1220 #if TARGET_CARBON
1221
1222 static void wxShapedMacWindowGetPos(WindowRef window, Rect* inRect)
1223 {
1224 GetWindowPortBounds(window, inRect);
1225 Point pt = {inRect->left, inRect->top};
1226 SetPort((GrafPtr) GetWindowPort(window));
1227 LocalToGlobal(&pt);
1228 inRect->top = pt.v;
1229 inRect->left = pt.h;
1230 inRect->bottom += pt.v;
1231 inRect->right += pt.h;
1232 }
1233
1234
1235 static SInt32 wxShapedMacWindowGetFeatures(WindowRef window, SInt32 param)
1236 {
1237 /*------------------------------------------------------
1238 Define which options your custom window supports.
1239 --------------------------------------------------------*/
1240 //just enable everything for our demo
1241 *(OptionBits*)param=//kWindowCanGrow|
1242 //kWindowCanZoom|
1243 //kWindowCanCollapse|
1244 //kWindowCanGetWindowRegion|
1245 //kWindowHasTitleBar|
1246 //kWindowSupportsDragHilite|
1247 kWindowCanDrawInCurrentPort|
1248 //kWindowCanMeasureTitle|
1249 kWindowWantsDisposeAtProcessDeath|
1250 kWindowSupportsSetGrowImageRegion|
1251 kWindowDefSupportsColorGrafPort;
1252 return 1;
1253 }
1254
1255 // The content region is left as a rectangle matching the window size, this is
1256 // so the origin in the paint event, and etc. still matches what the
1257 // programmer expects.
1258 static void wxShapedMacWindowContentRegion(WindowRef window, RgnHandle rgn)
1259 {
1260 SetEmptyRgn(rgn);
1261 wxTopLevelWindowMac* win = wxFindWinFromMacWindow(window);
1262 if (win)
1263 {
1264 wxRect r = win->GetRect();
1265 SetRectRgn(rgn, r.GetLeft(), r.GetTop(), r.GetRight(), r.GetBottom());
1266 }
1267 }
1268
1269 // The structure region is set to the shape given to the SetShape method.
1270 static void wxShapedMacWindowStructureRegion(WindowRef window, RgnHandle rgn)
1271 {
1272 RgnHandle cachedRegion = (RgnHandle) GetWRefCon(window);
1273
1274 SetEmptyRgn(rgn);
1275 if (cachedRegion)
1276 {
1277 Rect windowRect;
1278 wxShapedMacWindowGetPos(window, &windowRect); //how big is the window
1279 CopyRgn(cachedRegion, rgn); //make a copy of our cached region
1280 OffsetRgn(rgn, windowRect.left, windowRect.top); // position it over window
1281 //MapRgn(rgn, &mMaskSize, &windowRect); //scale it to our actual window size
1282 }
1283 }
1284
1285
1286
1287 static SInt32 wxShapedMacWindowGetRegion(WindowRef window, SInt32 param)
1288 {
1289 GetWindowRegionPtr rgnRec=(GetWindowRegionPtr)param;
1290
1291 switch(rgnRec->regionCode)
1292 {
1293 case kWindowStructureRgn:
1294 wxShapedMacWindowStructureRegion(window, rgnRec->winRgn);
1295 break;
1296 case kWindowContentRgn:
1297 wxShapedMacWindowContentRegion(window, rgnRec->winRgn);
1298 break;
1299 default:
1300 SetEmptyRgn(rgnRec->winRgn);
1301 } //switch
1302
1303 return noErr;
1304 }
1305
1306
1307 static SInt32 wxShapedMacWindowHitTest(WindowRef window,SInt32 param)
1308 {
1309 /*------------------------------------------------------
1310 Determine the region of the window which was hit
1311 --------------------------------------------------------*/
1312 Point hitPoint;
1313 static RgnHandle tempRgn=nil;
1314
1315 if(!tempRgn)
1316 tempRgn=NewRgn();
1317
1318 SetPt(&hitPoint,LoWord(param),HiWord(param));//get the point clicked
1319
1320 //Mac OS 8.5 or later
1321 wxShapedMacWindowStructureRegion(window, tempRgn);
1322 if (PtInRgn(hitPoint, tempRgn)) //in window content region?
1323 return wInContent;
1324
1325 return wNoHit;//no significant area was hit.
1326 }
1327
1328
1329 static pascal long wxShapedMacWindowDef(short varCode, WindowRef window, SInt16 message, SInt32 param)
1330 {
1331 switch(message)
1332 {
1333 case kWindowMsgHitTest:
1334 return wxShapedMacWindowHitTest(window,param);
1335
1336 case kWindowMsgGetFeatures:
1337 return wxShapedMacWindowGetFeatures(window,param);
1338
1339 // kWindowMsgGetRegion is sent during CreateCustomWindow and ReshapeCustomWindow
1340 case kWindowMsgGetRegion:
1341 return wxShapedMacWindowGetRegion(window,param);
1342 }
1343
1344 return 0;
1345 }
1346
1347 #endif
1348 // ---------------------------------------------------------------------------
1349