webengine/osswebengine/WebKit/Carbon/HIWebView.m
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2  * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  *
       
     8  * 1.  Redistributions of source code must retain the above copyright
       
     9  *     notice, this list of conditions and the following disclaimer. 
       
    10  * 2.  Redistributions in binary form must reproduce the above copyright
       
    11  *     notice, this list of conditions and the following disclaimer in the
       
    12  *     documentation and/or other materials provided with the distribution. 
       
    13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
       
    14  *     its contributors may be used to endorse or promote products derived
       
    15  *     from this software without specific prior written permission. 
       
    16  *
       
    17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
       
    18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
       
    20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
       
    21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
       
    22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
       
    23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
       
    24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
       
    26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    27  */
       
    28 
       
    29 #ifndef __LP64__
       
    30 
       
    31 #import "HIWebView.h"
       
    32 
       
    33 #import "CarbonWindowAdapter.h"
       
    34 #import "HIViewAdapter.h"
       
    35 #import "WebHTMLViewInternal.h"
       
    36 #import "WebKit.h"
       
    37 
       
    38 #import <objc/objc-runtime.h>
       
    39 #import <WebKitSystemInterface.h>
       
    40 
       
    41 @interface NSWindow (AppKitSecretsHIWebViewKnows)
       
    42 - (void)_removeWindowRef;
       
    43 @end
       
    44 
       
    45 @interface NSView (AppKitSecretsHIWebViewKnows)
       
    46 - (void)_clearDirtyRectsForTree;
       
    47 @end
       
    48 
       
    49 extern "C" void HIWebViewRegisterClass();
       
    50 
       
    51 @interface MenuItemProxy : NSObject <NSValidatedUserInterfaceItem>
       
    52 {
       
    53     int     _tag;
       
    54     SEL _action;
       
    55 }
       
    56 
       
    57 - (id)initWithAction:(SEL)action;
       
    58 - (SEL)action;
       
    59 - (int)tag;
       
    60 
       
    61 @end
       
    62 
       
    63 @implementation MenuItemProxy
       
    64 
       
    65 - (id)initWithAction:(SEL)action
       
    66 {
       
    67     [super init];
       
    68     if (self == nil) return nil;
       
    69 
       
    70     _action = action;
       
    71 
       
    72     return self;
       
    73 }
       
    74 
       
    75 - (SEL)action
       
    76 {
       
    77        return _action;
       
    78 }
       
    79 
       
    80 - (int)tag 
       
    81 {
       
    82     return 0;
       
    83 }
       
    84 
       
    85 @end
       
    86 
       
    87 struct HIWebView
       
    88 {
       
    89     HIViewRef							fViewRef;
       
    90 
       
    91     WebView*							fWebView;
       
    92     NSView*								fFirstResponder;
       
    93     CarbonWindowAdapter	*				fKitWindow;
       
    94     bool								fIsComposited;
       
    95     CFRunLoopObserverRef				fUpdateObserver;
       
    96 };
       
    97 typedef struct HIWebView HIWebView;
       
    98 
       
    99 static const OSType NSAppKitPropertyCreator = 'akit';
       
   100 /*
       
   101 These constants are not used. Commented out to make the compiler happy.
       
   102 static const OSType NSViewCarbonControlViewPropertyTag = 'view';
       
   103 static const OSType NSViewCarbonControlAutodisplayPropertyTag = 'autd';
       
   104 static const OSType NSViewCarbonControlFirstResponderViewPropertyTag = 'frvw';
       
   105 */
       
   106 static const OSType NSCarbonWindowPropertyTag = 'win ';
       
   107 
       
   108 #ifdef BUILDING_ON_TIGER
       
   109 const int typeByteCount = typeSInt32;
       
   110 #endif
       
   111 
       
   112 static SEL _NSSelectorForHICommand( const HICommand* hiCommand );
       
   113 
       
   114 static const EventTypeSpec kEvents[] = { 
       
   115 	{ kEventClassHIObject, kEventHIObjectConstruct },
       
   116 	{ kEventClassHIObject, kEventHIObjectDestruct },
       
   117 	
       
   118 	{ kEventClassMouse, kEventMouseUp },
       
   119 	{ kEventClassMouse, kEventMouseMoved },
       
   120 	{ kEventClassMouse, kEventMouseDragged },
       
   121 	{ kEventClassMouse, kEventMouseWheelMoved },
       
   122 
       
   123 	{ kEventClassKeyboard, kEventRawKeyDown },
       
   124 	{ kEventClassKeyboard, kEventRawKeyRepeat },
       
   125 
       
   126 	{ kEventClassCommand, kEventCommandProcess },
       
   127 	{ kEventClassCommand, kEventCommandUpdateStatus },
       
   128 
       
   129 	{ kEventClassControl, kEventControlInitialize },
       
   130 	{ kEventClassControl, kEventControlDraw },
       
   131 	{ kEventClassControl, kEventControlHitTest },
       
   132 	{ kEventClassControl, kEventControlGetPartRegion },
       
   133 	{ kEventClassControl, kEventControlGetData },
       
   134 	{ kEventClassControl, kEventControlBoundsChanged },
       
   135 	{ kEventClassControl, kEventControlActivate },
       
   136 	{ kEventClassControl, kEventControlDeactivate },
       
   137 	{ kEventClassControl, kEventControlOwningWindowChanged },
       
   138 	{ kEventClassControl, kEventControlClick },
       
   139 	{ kEventClassControl, kEventControlContextualMenuClick },
       
   140 	{ kEventClassControl, kEventControlSetFocusPart }
       
   141 };
       
   142 
       
   143 #define kHIViewBaseClassID		CFSTR( "com.apple.hiview" )
       
   144 #define kHIWebViewClassID		CFSTR( "com.apple.HIWebView" )
       
   145 
       
   146 static HIWebView*		HIWebViewConstructor( HIViewRef inView );
       
   147 static void				HIWebViewDestructor( HIWebView* view );
       
   148 
       
   149 static OSStatus			HIWebViewEventHandler(
       
   150 								EventHandlerCallRef	inCallRef,
       
   151 								EventRef			inEvent,
       
   152 								void *				inUserData );
       
   153 
       
   154 static UInt32			GetBehaviors();
       
   155 static ControlKind		GetKind();
       
   156 static void				Draw( HIWebView* inView, RgnHandle limitRgn, CGContextRef inContext );
       
   157 static ControlPartCode	HitTest( HIWebView* view, const HIPoint* where );
       
   158 static OSStatus			GetRegion( HIWebView* view, ControlPartCode inPart, RgnHandle outRgn );
       
   159 static void				BoundsChanged(
       
   160 								HIWebView*			inView,
       
   161 								UInt32				inOptions,
       
   162 								const HIRect*		inOriginalBounds,
       
   163 								const HIRect*		inCurrentBounds );
       
   164 static void				OwningWindowChanged(
       
   165 								HIWebView*			view,
       
   166 								WindowRef			oldWindow,
       
   167 								WindowRef			newWindow );
       
   168 static void				ActiveStateChanged( HIWebView* view );
       
   169 
       
   170 static OSStatus			Click( HIWebView* inView, EventRef inEvent );
       
   171 static OSStatus			ContextMenuClick( HIWebView* inView, EventRef inEvent );
       
   172 static OSStatus			MouseUp( HIWebView* inView, EventRef inEvent );
       
   173 static OSStatus			MouseMoved( HIWebView* inView, EventRef inEvent );
       
   174 static OSStatus			MouseDragged( HIWebView* inView, EventRef inEvent );
       
   175 static OSStatus			MouseWheelMoved( HIWebView* inView, EventRef inEvent );
       
   176 
       
   177 static OSStatus			ProcessCommand( HIWebView* inView, const HICommand* inCommand );
       
   178 static OSStatus			UpdateCommandStatus( HIWebView* inView, const HICommand* inCommand );
       
   179 
       
   180 static OSStatus			SetFocusPart(
       
   181 								HIWebView*				view,
       
   182 								ControlPartCode 		desiredFocus,
       
   183 								RgnHandle 				invalidRgn,
       
   184 								Boolean 				focusEverything,
       
   185 								ControlPartCode* 		actualFocus );
       
   186 static NSView*			AdvanceFocus( HIWebView* view, bool forward );
       
   187 static void				RelinquishFocus( HIWebView* view, bool inAutodisplay );
       
   188 
       
   189 static WindowRef		GetWindowRef( HIWebView* inView );
       
   190 static void				SyncFrame( HIWebView* inView );
       
   191 
       
   192 static OSStatus			WindowHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData );
       
   193 
       
   194 static void				StartUpdateObserver( HIWebView* view );
       
   195 static void				StopUpdateObserver( HIWebView* view );
       
   196 
       
   197 static inline void HIRectToQDRect( const HIRect* inRect, Rect* outRect )
       
   198 {
       
   199     outRect->top = (SInt16)CGRectGetMinY( *inRect );
       
   200     outRect->left = (SInt16)CGRectGetMinX( *inRect );
       
   201     outRect->bottom = (SInt16)CGRectGetMaxY( *inRect );
       
   202     outRect->right = (SInt16)CGRectGetMaxX( *inRect );
       
   203 }
       
   204 
       
   205 static Class webViewClass;
       
   206 
       
   207 //----------------------------------------------------------------------------------
       
   208 // HIWebViewCreate
       
   209 //----------------------------------------------------------------------------------
       
   210 //
       
   211 OSStatus
       
   212 HIWebViewCreate( HIViewRef* outControl )
       
   213 {
       
   214 	OSStatus			err;
       
   215     
       
   216 	HIWebViewRegisterClass();
       
   217 
       
   218     webViewClass = [WebView class];
       
   219 	err = HIObjectCreate( kHIWebViewClassID, NULL, (HIObjectRef*)outControl );
       
   220 
       
   221 	return err;
       
   222 }
       
   223 
       
   224 //----------------------------------------------------------------------------------
       
   225 // HIWebViewCreateWithClass
       
   226 //----------------------------------------------------------------------------------
       
   227 //
       
   228 OSStatus HIWebViewCreateWithClass(Class aClass, HIViewRef * outControl)
       
   229 {
       
   230 	OSStatus			err;
       
   231     
       
   232 	HIWebViewRegisterClass();
       
   233 
       
   234     webViewClass = aClass;
       
   235 	err = HIObjectCreate( kHIWebViewClassID, NULL, (HIObjectRef*)outControl );
       
   236 
       
   237 	return err;
       
   238 }
       
   239 
       
   240 //----------------------------------------------------------------------------------
       
   241 // HIWebViewGetWebView
       
   242 //----------------------------------------------------------------------------------
       
   243 //
       
   244 WebView*
       
   245 HIWebViewGetWebView( HIViewRef inView )
       
   246 {
       
   247 	HIWebView* 	view = (HIWebView*)HIObjectDynamicCast( (HIObjectRef)inView, kHIWebViewClassID );
       
   248 	WebView*			result = NULL;
       
   249 	
       
   250 	if ( view )
       
   251 		result = view->fWebView;
       
   252 	
       
   253 	return result;
       
   254 }
       
   255 
       
   256 //----------------------------------------------------------------------------------
       
   257 // HIWebViewConstructor
       
   258 //----------------------------------------------------------------------------------
       
   259 //
       
   260 
       
   261 static HIWebView*
       
   262 HIWebViewConstructor( HIViewRef inView )
       
   263 {
       
   264 	HIWebView*		view = (HIWebView*)malloc( sizeof( HIWebView ) );
       
   265 	
       
   266 	if ( view )
       
   267 	{
       
   268 		NSRect		frame = { { 0, 0 }, { 400, 400  } };
       
   269 	
       
   270 		view->fViewRef = inView;
       
   271 
       
   272                 WebView *webView = [[webViewClass alloc] initWithFrame: frame];
       
   273                 CFRetain(webView);
       
   274                 [webView release];
       
   275 		view->fWebView = webView;
       
   276 		[HIViewAdapter bindHIViewToNSView:inView nsView:view->fWebView];
       
   277 		
       
   278 		view->fFirstResponder = NULL;
       
   279 		view->fKitWindow = NULL;
       
   280         view->fIsComposited = false;
       
   281         view->fUpdateObserver = NULL;
       
   282 	}
       
   283 	
       
   284 	return view;
       
   285 }
       
   286 
       
   287 //----------------------------------------------------------------------------------
       
   288 // HIWebViewDestructor
       
   289 //----------------------------------------------------------------------------------
       
   290 //
       
   291 static void
       
   292 HIWebViewDestructor( HIWebView* inView )
       
   293 {
       
   294     [HIViewAdapter unbindNSView:inView->fWebView];
       
   295     CFRelease(inView->fWebView);
       
   296 
       
   297     free(inView);
       
   298 }
       
   299 
       
   300 //----------------------------------------------------------------------------------
       
   301 // HIWebViewRegisterClass
       
   302 //----------------------------------------------------------------------------------
       
   303 //
       
   304 void
       
   305 HIWebViewRegisterClass()
       
   306 {
       
   307 	static bool sRegistered;
       
   308 	
       
   309 	if ( !sRegistered )
       
   310 	{
       
   311 		HIObjectRegisterSubclass( kHIWebViewClassID, kHIViewBaseClassID, 0, HIWebViewEventHandler,
       
   312 			GetEventTypeCount( kEvents ), kEvents, 0, NULL );
       
   313 		sRegistered = true;
       
   314 	}
       
   315 }
       
   316 
       
   317 //----------------------------------------------------------------------------------
       
   318 // GetBehaviors
       
   319 //----------------------------------------------------------------------------------
       
   320 //
       
   321 static UInt32
       
   322 GetBehaviors()
       
   323 {
       
   324 	return kControlSupportsDataAccess | kControlSupportsGetRegion | kControlGetsFocusOnClick;
       
   325 }
       
   326 
       
   327 //----------------------------------------------------------------------------------
       
   328 // Draw
       
   329 //----------------------------------------------------------------------------------
       
   330 //
       
   331 static void
       
   332 Draw( HIWebView* inView, RgnHandle limitRgn, CGContextRef inContext )
       
   333 {
       
   334 	HIRect				bounds;
       
   335 	Rect				drawRect;
       
   336 	HIRect				hiRect;
       
   337 	bool				createdContext = false;
       
   338 
       
   339     if (!inView->fIsComposited)
       
   340     {
       
   341         GrafPtr port;
       
   342         Rect portRect;
       
   343 
       
   344         GetPort( &port );
       
   345         GetPortBounds( port, &portRect );
       
   346         CreateCGContextForPort( port, &inContext );
       
   347         SyncCGContextOriginWithPort( inContext, port );
       
   348         CGContextTranslateCTM( inContext, 0, (portRect.bottom - portRect.top) );
       
   349         CGContextScaleCTM( inContext, 1, -1 );
       
   350         createdContext = true;
       
   351     }
       
   352 
       
   353 	HIViewGetBounds( inView->fViewRef, &bounds );
       
   354 
       
   355     CGContextRef savedContext = WKNSWindowOverrideCGContext(inView->fKitWindow, inContext);
       
   356     [NSGraphicsContext setCurrentContext:[inView->fKitWindow graphicsContext]];
       
   357 
       
   358 	GetRegionBounds( limitRgn, &drawRect );
       
   359 
       
   360     if ( !inView->fIsComposited )
       
   361         OffsetRect( &drawRect, (SInt16)-bounds.origin.x, (SInt16)-bounds.origin.y );
       
   362     
       
   363 	hiRect.origin.x = drawRect.left;
       
   364 	hiRect.origin.y = bounds.size.height - drawRect.bottom; // flip y
       
   365 	hiRect.size.width = drawRect.right - drawRect.left;
       
   366 	hiRect.size.height = drawRect.bottom - drawRect.top;
       
   367 
       
   368 //    printf( "Drawing: drawRect is (%g %g) (%g %g)\n", hiRect.origin.x, hiRect.origin.y,
       
   369 //            hiRect.size.width, hiRect.size.height );
       
   370 
       
   371     // FIXME: We need to do layout before Carbon has decided what region needs drawn.
       
   372     // In Cocoa we make sure to do layout and invalidate any new regions before draw, so everything
       
   373     // can be drawn in one pass. Doing a layout here will cause new regions to be invalidated, but they
       
   374     // will not all be drawn in this pass since we already have a fixed rect we are going to display.
       
   375 
       
   376     NSView <WebDocumentView> *documentView = [[[inView->fWebView mainFrame] frameView] documentView];
       
   377     if ([documentView isKindOfClass:[WebHTMLView class]])
       
   378         [(WebHTMLView *)documentView _web_layoutIfNeededRecursive];
       
   379 
       
   380     if ( inView->fIsComposited )
       
   381         [inView->fWebView displayIfNeededInRect: *(NSRect*)&hiRect];
       
   382     else
       
   383         [inView->fWebView displayRect:*(NSRect*)&hiRect];
       
   384 
       
   385     WKNSWindowRestoreCGContext(inView->fKitWindow, savedContext);
       
   386 
       
   387     if ( !inView->fIsComposited )
       
   388     {
       
   389         HIViewRef      view;
       
   390         HIViewFindByID( HIViewGetRoot( GetControlOwner( inView->fViewRef ) ), kHIViewWindowGrowBoxID, &view );
       
   391         if ( view )
       
   392         {
       
   393             HIRect     frame;
       
   394 
       
   395             HIViewGetBounds( view, &frame );
       
   396             HIViewConvertRect( &frame, view, NULL );
       
   397 
       
   398             hiRect.origin.x = drawRect.left;
       
   399             hiRect.origin.y = drawRect.top;
       
   400             hiRect.size.width = drawRect.right - drawRect.left;
       
   401             hiRect.size.height = drawRect.bottom - drawRect.top;
       
   402 
       
   403             HIViewConvertRect( &hiRect, inView->fViewRef, NULL );
       
   404 
       
   405             if ( CGRectIntersectsRect( frame, hiRect ) )
       
   406                 HIViewSetNeedsDisplay( view, true );
       
   407         }
       
   408      }
       
   409 
       
   410     if ( createdContext )
       
   411     {
       
   412         CGContextSynchronize( inContext );
       
   413         CGContextRelease( inContext );
       
   414     }
       
   415 }
       
   416 
       
   417 //----------------------------------------------------------------------------------
       
   418 // HitTest
       
   419 //----------------------------------------------------------------------------------
       
   420 //
       
   421 static ControlPartCode
       
   422 HitTest( HIWebView* view, const HIPoint* where )
       
   423 {
       
   424 	HIRect		bounds;
       
   425 	
       
   426 	HIViewGetBounds( view->fViewRef, &bounds );
       
   427 
       
   428 	if ( CGRectContainsPoint( bounds, *where ) )
       
   429 		return 1;
       
   430 	else
       
   431 		return kControlNoPart;
       
   432 }
       
   433 
       
   434 //----------------------------------------------------------------------------------
       
   435 // GetRegion
       
   436 //----------------------------------------------------------------------------------
       
   437 //
       
   438 static OSStatus
       
   439 GetRegion(
       
   440 	HIWebView*			inView,
       
   441 	ControlPartCode		inPart,
       
   442 	RgnHandle			outRgn )
       
   443 {
       
   444 	OSStatus	 err = eventNotHandledErr;
       
   445 	
       
   446 	if ( inPart == -3 ) // kControlOpaqueMetaPart:
       
   447 	{
       
   448 		if ( [inView->fWebView isOpaque] )
       
   449 		{
       
   450 			HIRect	bounds;
       
   451 			Rect	temp;
       
   452 			
       
   453 			HIViewGetBounds( inView->fViewRef, &bounds );
       
   454 
       
   455 			temp.top = (SInt16)bounds.origin.y;
       
   456 			temp.left = (SInt16)bounds.origin.x;
       
   457 			temp.bottom = (SInt16)CGRectGetMaxY( bounds );
       
   458 			temp.right = (SInt16)CGRectGetMaxX( bounds );
       
   459 
       
   460 			RectRgn( outRgn, &temp );
       
   461 			err = noErr;
       
   462 		}
       
   463 	}
       
   464 	
       
   465 	return err;
       
   466 }
       
   467 
       
   468 static WindowRef
       
   469 GetWindowRef( HIWebView* inView )
       
   470 {
       
   471        return GetControlOwner( inView->fViewRef );
       
   472 }
       
   473 
       
   474 //----------------------------------------------------------------------------------
       
   475 // Click
       
   476 //----------------------------------------------------------------------------------
       
   477 //
       
   478 static OSStatus
       
   479 Click(HIWebView* inView, EventRef inEvent)
       
   480 {
       
   481     NSEvent *kitEvent = WKCreateNSEventWithCarbonClickEvent(inEvent, GetWindowRef(inView));
       
   482 
       
   483     if (!inView->fIsComposited)
       
   484         StartUpdateObserver(inView);
       
   485 
       
   486     [inView->fKitWindow sendEvent:kitEvent];
       
   487 
       
   488     if (!inView->fIsComposited)
       
   489         StopUpdateObserver(inView);
       
   490 
       
   491     [kitEvent release];
       
   492 
       
   493     return noErr;
       
   494 }
       
   495 
       
   496 //----------------------------------------------------------------------------------
       
   497 // MouseUp
       
   498 //----------------------------------------------------------------------------------
       
   499 //
       
   500 static OSStatus
       
   501 MouseUp( HIWebView* inView, EventRef inEvent )
       
   502 {
       
   503 	NSEvent* kitEvent = WKCreateNSEventWithCarbonEvent(inEvent);
       
   504 
       
   505     [inView->fKitWindow sendEvent:kitEvent];
       
   506 	
       
   507     [kitEvent release];
       
   508     
       
   509 	return noErr;
       
   510 }
       
   511 
       
   512 //----------------------------------------------------------------------------------
       
   513 // MouseMoved
       
   514 //----------------------------------------------------------------------------------
       
   515 //
       
   516 static OSStatus
       
   517 MouseMoved( HIWebView* inView, EventRef inEvent )
       
   518 {
       
   519     NSEvent *kitEvent = WKCreateNSEventWithCarbonMouseMoveEvent(inEvent, inView->fKitWindow);
       
   520     [inView->fKitWindow sendEvent:kitEvent];
       
   521 	[kitEvent release];
       
   522 
       
   523 	return noErr;
       
   524 }
       
   525 
       
   526 //----------------------------------------------------------------------------------
       
   527 // MouseDragged
       
   528 //----------------------------------------------------------------------------------
       
   529 //
       
   530 static OSStatus
       
   531 MouseDragged( HIWebView* inView, EventRef inEvent )
       
   532 {
       
   533 	NSEvent* kitEvent = WKCreateNSEventWithCarbonEvent(inEvent);
       
   534 
       
   535     [inView->fKitWindow sendEvent:kitEvent];
       
   536 
       
   537 	[kitEvent release];
       
   538 	
       
   539 	return noErr;
       
   540 }
       
   541 
       
   542 //----------------------------------------------------------------------------------
       
   543 // MouseDragged
       
   544 //----------------------------------------------------------------------------------
       
   545 //
       
   546 static OSStatus
       
   547 MouseWheelMoved( HIWebView* inView, EventRef inEvent )
       
   548 {
       
   549 	NSEvent* kitEvent = WKCreateNSEventWithCarbonEvent(inEvent);
       
   550 
       
   551     [inView->fKitWindow sendEvent:kitEvent];
       
   552 
       
   553 	[kitEvent release];
       
   554 	
       
   555 	return noErr;
       
   556 }
       
   557 
       
   558 //----------------------------------------------------------------------------------
       
   559 // ContextMenuClick
       
   560 //----------------------------------------------------------------------------------
       
   561 //
       
   562 static OSStatus
       
   563 ContextMenuClick( HIWebView* inView, EventRef inEvent )
       
   564 {
       
   565     NSView *webView = inView->fWebView;
       
   566     NSWindow *window = [webView window];
       
   567 
       
   568     // Get the point out of the event.
       
   569     HIPoint point;
       
   570     GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(point), NULL, &point);
       
   571     HIViewConvertPoint(&point, inView->fViewRef, NULL);
       
   572     
       
   573     // Flip the Y coordinate, since Carbon is flipped relative to the AppKit.
       
   574     NSPoint location = NSMakePoint(point.x, [window frame].size.height - point.y);
       
   575     
       
   576     // Make up an event with the point and send it to the window.
       
   577     NSEvent *kitEvent = [NSEvent mouseEventWithType:NSRightMouseDown
       
   578                                            location:location
       
   579                                       modifierFlags:0
       
   580                                           timestamp:GetEventTime(inEvent)
       
   581                                        windowNumber:[window windowNumber]
       
   582                                             context:0
       
   583                                         eventNumber:0
       
   584                                          clickCount:1
       
   585                                            pressure:0];
       
   586     [inView->fKitWindow sendEvent:kitEvent];
       
   587     return noErr;
       
   588 }
       
   589 
       
   590 //----------------------------------------------------------------------------------
       
   591 // GetKind
       
   592 //----------------------------------------------------------------------------------
       
   593 //
       
   594 static ControlKind
       
   595 GetKind()
       
   596 {
       
   597 	const ControlKind kMyKind = { 'appl', 'wbvw' };
       
   598 	
       
   599 	return kMyKind;
       
   600 }
       
   601 
       
   602 //----------------------------------------------------------------------------------
       
   603 // BoundsChanged
       
   604 //----------------------------------------------------------------------------------
       
   605 //
       
   606 static void
       
   607 BoundsChanged(
       
   608 	HIWebView*			inView,
       
   609 	UInt32				inOptions,
       
   610 	const HIRect*		inOriginalBounds,
       
   611 	const HIRect*		inCurrentBounds )
       
   612 {
       
   613 	if ( inView->fWebView )
       
   614 	{
       
   615 		SyncFrame( inView );
       
   616 	}
       
   617 }
       
   618 
       
   619 //----------------------------------------------------------------------------------
       
   620 // OwningWindowChanged
       
   621 //----------------------------------------------------------------------------------
       
   622 //
       
   623 static void
       
   624 OwningWindowChanged(
       
   625 	HIWebView*			view,
       
   626 	WindowRef			oldWindow,
       
   627 	WindowRef			newWindow )
       
   628 {
       
   629     if ( newWindow ){
       
   630         WindowAttributes	attrs;
       
   631         
       
   632         OSStatus err = GetWindowProperty(newWindow, NSAppKitPropertyCreator, NSCarbonWindowPropertyTag, sizeof(NSWindow *), NULL, &view->fKitWindow);
       
   633         if ( err != noErr )
       
   634         {
       
   635             const EventTypeSpec kWindowEvents[] = {
       
   636             { kEventClassWindow, kEventWindowClosed },
       
   637             { kEventClassMouse, kEventMouseMoved },
       
   638             { kEventClassMouse, kEventMouseUp },
       
   639             { kEventClassMouse, kEventMouseDragged },
       
   640             { kEventClassMouse, kEventMouseWheelMoved },
       
   641             { kEventClassKeyboard, kEventRawKeyDown },
       
   642             { kEventClassKeyboard, kEventRawKeyRepeat },
       
   643             { kEventClassKeyboard, kEventRawKeyUp },
       
   644             { kEventClassControl, kEventControlClick },
       
   645             };
       
   646             
       
   647             view->fKitWindow = [[CarbonWindowAdapter alloc] initWithCarbonWindowRef: newWindow takingOwnership: NO disableOrdering:NO carbon:YES];
       
   648             SetWindowProperty(newWindow, NSAppKitPropertyCreator, NSCarbonWindowPropertyTag, sizeof(NSWindow *), &view->fKitWindow);
       
   649             
       
   650             InstallWindowEventHandler( newWindow, WindowHandler, GetEventTypeCount( kWindowEvents ), kWindowEvents, newWindow, NULL );
       
   651         }
       
   652         
       
   653         [[view->fKitWindow contentView] addSubview:view->fWebView];
       
   654         
       
   655         GetWindowAttributes( newWindow, &attrs );
       
   656         view->fIsComposited = ( ( attrs & kWindowCompositingAttribute ) != 0 );
       
   657         
       
   658         SyncFrame( view );        
       
   659     }
       
   660     else
       
   661     {
       
   662         // Be sure to detach the cocoa view, too.
       
   663         if ( view->fWebView )
       
   664             [view->fWebView removeFromSuperview];
       
   665         
       
   666         view->fKitWindow = NULL; // break the ties that bind
       
   667     }
       
   668 }
       
   669 
       
   670 //-------------------------------------------------------------------------------------
       
   671 //	WindowHandler
       
   672 //-------------------------------------------------------------------------------------
       
   673 //	Redirect mouse events to the views beneath them. This is required for WebKit to work
       
   674 // 	properly. We install it once per window. We also tap into window close to release
       
   675 //	the NSWindow that shadows our Carbon window.
       
   676 //
       
   677 static OSStatus
       
   678 WindowHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
       
   679 {
       
   680 	WindowRef	window = (WindowRef)inUserData;
       
   681 	OSStatus	result = eventNotHandledErr;
       
   682 
       
   683     switch( GetEventClass( inEvent ) )
       
   684     {
       
   685     	case kEventClassControl:
       
   686             {
       
   687             switch( GetEventKind( inEvent ) )
       
   688             {
       
   689                 case kEventControlClick:
       
   690                     {
       
   691                         CarbonWindowAdapter *kitWindow;
       
   692                         OSStatus err;
       
   693                         
       
   694                         err = GetWindowProperty( window, NSAppKitPropertyCreator, NSCarbonWindowPropertyTag, sizeof(NSWindow *), NULL, &kitWindow);
       
   695                         
       
   696                         // We must be outside the HIWebView, relinquish focus.
       
   697                         [kitWindow relinquishFocus];
       
   698                     }
       
   699                     break;
       
   700                 }
       
   701             }
       
   702             break;
       
   703             
       
   704     	case kEventClassKeyboard:
       
   705     		{
       
   706                 NSWindow*		kitWindow;
       
   707                 OSStatus		err;
       
   708    				NSEvent*		kitEvent;
       
   709    				
       
   710    				// if the first responder in the kit window is something other than the
       
   711    				// window, we assume a subview of the webview is focused. we must send
       
   712    				// the event to the window so that it goes through the kit's normal TSM
       
   713    				// logic, and -- more importantly -- allows any delegates associated
       
   714    				// with the first responder to have a chance at the event.
       
   715    				
       
   716 				err = GetWindowProperty( window, NSAppKitPropertyCreator, NSCarbonWindowPropertyTag, sizeof(NSWindow *), NULL, &kitWindow);
       
   717 				if ( err == noErr )
       
   718 				{
       
   719 					NSResponder* responder = [kitWindow firstResponder];
       
   720 					if ( responder != kitWindow )
       
   721 					{
       
   722                         kitEvent = WKCreateNSEventWithCarbonEvent(inEvent);
       
   723 						
       
   724 						[kitWindow sendEvent:kitEvent];
       
   725 						[kitEvent release];
       
   726 						
       
   727 						result = noErr;
       
   728 					}
       
   729 				}
       
   730     		}
       
   731     		break;
       
   732 
       
   733         case kEventClassWindow:
       
   734             {
       
   735                 NSWindow*	kitWindow;
       
   736                 OSStatus	err;
       
   737                 
       
   738                 err = GetWindowProperty( window, NSAppKitPropertyCreator, NSCarbonWindowPropertyTag, sizeof(NSWindow *), NULL, &kitWindow);
       
   739                 if ( err == noErr )
       
   740                 {
       
   741                     [kitWindow _removeWindowRef];
       
   742                     [kitWindow close];
       
   743                 }
       
   744 	
       
   745                 result = noErr;
       
   746             }
       
   747             break;
       
   748         
       
   749         case kEventClassMouse:
       
   750             switch (GetEventKind(inEvent))
       
   751             {
       
   752                 case kEventMouseMoved:
       
   753                     {
       
   754                         Point where;
       
   755                         GetEventParameter(inEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &where);
       
   756 
       
   757                         WindowRef temp;
       
   758                         FindWindow(where, &temp);
       
   759                         if (temp == window)
       
   760                         {
       
   761                             Rect bounds;
       
   762                             GetWindowBounds(window, kWindowStructureRgn, &bounds);
       
   763                             where.h -= bounds.left;
       
   764                             where.v -= bounds.top;
       
   765                             SetEventParameter(inEvent, kEventParamWindowRef, typeWindowRef, sizeof(WindowRef), &window);
       
   766                             SetEventParameter(inEvent, kEventParamWindowMouseLocation, typeQDPoint, sizeof(Point), &where);
       
   767 
       
   768                             OSStatus err = noErr;
       
   769                             HIViewRef view = NULL;
       
   770 
       
   771                             err = HIViewGetViewForMouseEvent(HIViewGetRoot(window), inEvent, &view);
       
   772                             if (err == noErr && view && HIObjectIsOfClass((HIObjectRef)view, kHIWebViewClassID))
       
   773                                 result = SendEventToEventTargetWithOptions(inEvent, HIObjectGetEventTarget((HIObjectRef)view), kEventTargetDontPropagate);
       
   774                         }
       
   775                     }
       
   776                     break;
       
   777                 
       
   778                 case kEventMouseUp:
       
   779                 case kEventMouseDragged:
       
   780                 case kEventMouseWheelMoved:
       
   781                     {
       
   782                         OSStatus err = noErr;
       
   783                         HIViewRef view = NULL;
       
   784 
       
   785                         err = HIViewGetViewForMouseEvent(HIViewGetRoot(window), inEvent, &view);
       
   786                         if (err == noErr && view && HIObjectIsOfClass((HIObjectRef)view, kHIWebViewClassID))
       
   787                             result = SendEventToEventTargetWithOptions(inEvent, HIObjectGetEventTarget((HIObjectRef)view), kEventTargetDontPropagate);
       
   788                     }
       
   789                     break;
       
   790             }
       
   791             break;
       
   792     }
       
   793 
       
   794 	return result;
       
   795 }
       
   796 
       
   797 
       
   798 //----------------------------------------------------------------------------------
       
   799 // SyncFrame
       
   800 //----------------------------------------------------------------------------------
       
   801 //
       
   802 static void
       
   803 SyncFrame( HIWebView* inView )
       
   804 {
       
   805 	HIViewRef	parent = HIViewGetSuperview( inView->fViewRef );
       
   806 	
       
   807 	if ( parent )
       
   808 	{
       
   809         if ( inView->fIsComposited )
       
   810         {
       
   811             HIRect		frame;
       
   812             HIRect		parentBounds;
       
   813             NSPoint		origin;
       
   814 
       
   815             HIViewGetFrame( inView->fViewRef, &frame );
       
   816             HIViewGetBounds( parent, &parentBounds );
       
   817             
       
   818             origin.x = frame.origin.x;
       
   819             origin.y = parentBounds.size.height - CGRectGetMaxY( frame );
       
   820 //    printf( "syncing to (%g %g) (%g %g)\n", origin.x, origin.y,
       
   821 //            frame.size.width, frame.size.height );
       
   822             [inView->fWebView setFrameOrigin: origin];
       
   823             [inView->fWebView setFrameSize: *(NSSize*)&frame.size];
       
   824         }
       
   825         else
       
   826         {
       
   827             GrafPtr			port = GetWindowPort( GetControlOwner( inView->fViewRef ) );
       
   828             PixMapHandle	portPix = GetPortPixMap( port );
       
   829             Rect			bounds;
       
   830             HIRect			rootFrame;
       
   831             HIRect			frame;
       
   832 
       
   833             GetControlBounds( inView->fViewRef, &bounds );
       
   834             OffsetRect( &bounds, -(**portPix).bounds.left, -(**portPix).bounds.top );
       
   835 
       
   836 //            printf( "control lives at %d %d %d %d in window-coords\n", bounds.top, bounds.left,
       
   837 //                bounds.bottom, bounds.right );
       
   838   
       
   839             HIViewGetFrame( HIViewGetRoot( GetControlOwner( inView->fViewRef ) ), &rootFrame );
       
   840 
       
   841             frame.origin.x = bounds.left;
       
   842             frame.origin.y = rootFrame.size.height - bounds.bottom;
       
   843             frame.size.width = bounds.right - bounds.left;
       
   844             frame.size.height = bounds.bottom - bounds.top;
       
   845 
       
   846 //            printf( "   before frame convert (%g %g) (%g %g)\n", frame.origin.x, frame.origin.y,
       
   847 //                frame.size.width, frame.size.height );
       
   848             
       
   849             [inView->fWebView convertRect:*(NSRect*)&frame fromView:nil];
       
   850 
       
   851 //            printf( "   moving web view to (%g %g) (%g %g)\n", frame.origin.x, frame.origin.y,
       
   852 //                frame.size.width, frame.size.height );
       
   853 
       
   854             [inView->fWebView setFrameOrigin: *(NSPoint*)&frame.origin];
       
   855             [inView->fWebView setFrameSize: *(NSSize*)&frame.size];
       
   856         }
       
   857     }
       
   858 }
       
   859 
       
   860 //----------------------------------------------------------------------------------
       
   861 // SetFocusPart
       
   862 //----------------------------------------------------------------------------------
       
   863 //
       
   864 static OSStatus
       
   865 SetFocusPart(
       
   866 	HIWebView*				view,
       
   867 	ControlPartCode 		desiredFocus,
       
   868 	RgnHandle 				invalidRgn,
       
   869 	Boolean 				focusEverything,
       
   870 	ControlPartCode* 		actualFocus )
       
   871 {
       
   872     NSView *	freshlyMadeFirstResponderView;
       
   873     SInt32 		partCodeToReturn;
       
   874 
       
   875     // Do what Carbon is telling us to do.
       
   876     if ( desiredFocus == kControlFocusNoPart )
       
   877 	{
       
   878         // Relinquish the keyboard focus.
       
   879         RelinquishFocus( view, true ); //(autodisplay ? YES : NO));
       
   880         freshlyMadeFirstResponderView = nil;
       
   881         partCodeToReturn = kControlFocusNoPart;
       
   882 		//NSLog(@"Relinquished the key focus because we have no choice.");
       
   883     }
       
   884 	else if ( desiredFocus == kControlFocusNextPart || desiredFocus == kControlFocusPrevPart )
       
   885 	{
       
   886         BOOL goForward = (desiredFocus == kControlFocusNextPart );
       
   887 
       
   888         // Advance the keyboard focus, maybe right off of this view.  Maybe a subview of this one already has the keyboard focus, maybe not.
       
   889         freshlyMadeFirstResponderView = AdvanceFocus( view, goForward );
       
   890         if (freshlyMadeFirstResponderView)
       
   891             partCodeToReturn = desiredFocus;
       
   892         else
       
   893             partCodeToReturn = kControlFocusNoPart;
       
   894         //NSLog(freshlyMadeFirstResponderView ? @"Advanced the key focus." : @"Relinquished the key focus.");
       
   895     }
       
   896 	else
       
   897 	{
       
   898 		// What's this?
       
   899                 if (desiredFocus != kControlIndicatorPart) {
       
   900                     check(false);
       
   901                 }
       
   902 		freshlyMadeFirstResponderView = nil;
       
   903 		partCodeToReturn = desiredFocus;
       
   904     }
       
   905 
       
   906 	view->fFirstResponder = freshlyMadeFirstResponderView;
       
   907 
       
   908 	*actualFocus = partCodeToReturn;
       
   909 
       
   910 	// Done.
       
   911 	return noErr;
       
   912 }
       
   913 
       
   914 //----------------------------------------------------------------------------------
       
   915 // AdvanceFocus
       
   916 //----------------------------------------------------------------------------------
       
   917 //
       
   918 static NSView*
       
   919 AdvanceFocus( HIWebView* view, bool forward )
       
   920 {
       
   921     NSResponder*		oldFirstResponder;
       
   922     NSView*				currentKeyView;
       
   923     NSView*				viewWeMadeFirstResponder;
       
   924     
       
   925     //	Focus on some part (subview) of this control (view).  Maybe
       
   926 	//	a subview of this one already has the keyboard focus, maybe not.
       
   927 	
       
   928 	oldFirstResponder = [view->fKitWindow firstResponder];
       
   929 
       
   930 	// If we tab out of our NSView, it will no longer be the responder
       
   931 	// when we get here. We'll try this trick for now. We might need to
       
   932 	// tag the view appropriately.
       
   933 
       
   934 	if ( view->fFirstResponder && ( (NSResponder*)view->fFirstResponder != oldFirstResponder ) )
       
   935 	{
       
   936 		return NULL;
       
   937 	}
       
   938 	
       
   939 	if ( [oldFirstResponder isKindOfClass:[NSView class]] )
       
   940 	{
       
   941 		NSView*		tentativeNewKeyView;
       
   942 
       
   943         // Some view in this window already has the keyboard focus.  It better at least be a subview of this one.
       
   944         NSView*	oldFirstResponderView = (NSView *)oldFirstResponder;
       
   945         check( [oldFirstResponderView isDescendantOf:view->fWebView] );
       
   946 
       
   947 		if ( oldFirstResponderView != view->fFirstResponder
       
   948 			&& ![oldFirstResponderView isDescendantOf:view->fFirstResponder] )
       
   949 		{
       
   950             // Despite our efforts to record what view we made the first responder
       
   951 			// (for use in the next paragraph) we couldn't keep up because the user
       
   952 			// has clicked in a text field to make it the key focus, instead of using
       
   953 			// the tab key.  Find a control on which it's reasonable to invoke
       
   954 			// -[NSView nextValidKeyView], taking into account the fact that
       
   955 			// NSTextFields always pass on first-respondership to a temporarily-
       
   956 			// contained NSTextView.
       
   957 
       
   958 			NSView *viewBeingTested;
       
   959 			currentKeyView = oldFirstResponderView;
       
   960 			viewBeingTested = currentKeyView;
       
   961 			while ( viewBeingTested != view->fWebView )
       
   962 			{
       
   963 				if ( [viewBeingTested isKindOfClass:[NSTextField class]] )
       
   964 				{
       
   965 					currentKeyView = viewBeingTested;
       
   966 					break;
       
   967 				}
       
   968 				else
       
   969 				{
       
   970 					viewBeingTested = [viewBeingTested superview];
       
   971 				}
       
   972 			}
       
   973 		}
       
   974 		else 
       
   975 		{
       
   976 			// We recorded which view we made into the first responder the
       
   977 			// last time the user hit the tab key, and nothing has invalidated
       
   978 			// our recorded value since.
       
   979 			
       
   980 			currentKeyView = view->fFirstResponder;
       
   981 		}
       
   982 
       
   983         // Try to move on to the next or previous key view.  We use the laboriously
       
   984 		// recorded/figured currentKeyView instead of just oldFirstResponder as the
       
   985 		// jumping-off-point when searching for the next valid key view.  This is so
       
   986 		// we don't get fooled if we recently made some view the first responder, but
       
   987 		// it passed on first-responder-ness to some temporary subview.
       
   988 		
       
   989         // You can't put normal views in a window with Carbon-control-wrapped views.
       
   990 		// Stuff like this would break.  M.P. Notice - 12/2/00
       
   991 
       
   992         tentativeNewKeyView = forward ? [currentKeyView nextValidKeyView] : [currentKeyView previousValidKeyView];
       
   993         if ( tentativeNewKeyView && [tentativeNewKeyView isDescendantOf:view->fWebView] )
       
   994 		{
       
   995             // The user has tabbed to another subview of this control view.  Change the keyboard focus.
       
   996             //NSLog(@"Tabbed to the next or previous key view.");
       
   997 
       
   998             [view->fKitWindow makeFirstResponder:tentativeNewKeyView];
       
   999             viewWeMadeFirstResponder = tentativeNewKeyView;
       
  1000         }
       
  1001 		else
       
  1002 		{
       
  1003             // The user has tabbed past the subviews of this control view.  The window is the first responder now.
       
  1004             //NSLog(@"Tabbed past the first or last key view.");
       
  1005             [view->fKitWindow makeFirstResponder:view->fKitWindow];
       
  1006             viewWeMadeFirstResponder = nil;
       
  1007         }
       
  1008     }
       
  1009 	else
       
  1010 	{
       
  1011         // No view in this window has the keyboard focus.  This view should
       
  1012 		// try to select one of its key subviews.  We're not interested in
       
  1013 		// the subviews of sibling views here.
       
  1014 
       
  1015 		//NSLog(@"No keyboard focus in window. Attempting to set...");
       
  1016 
       
  1017 		NSView *tentativeNewKeyView;
       
  1018 		check(oldFirstResponder==fKitWindow);
       
  1019 		if ( [view->fWebView acceptsFirstResponder] )
       
  1020 			tentativeNewKeyView = view->fWebView;
       
  1021 		else
       
  1022 			tentativeNewKeyView = [view->fWebView nextValidKeyView];
       
  1023         if ( tentativeNewKeyView && [tentativeNewKeyView isDescendantOf:view->fWebView] )
       
  1024 		{
       
  1025             // This control view has at least one subview that can take the keyboard focus.
       
  1026             if ( !forward )
       
  1027 			{
       
  1028                 // The user has tabbed into this control view backwards.  Find
       
  1029 				// and select the last subview of this one that can take the
       
  1030 				// keyboard focus.  Watch out for loops of valid key views.
       
  1031 
       
  1032                 NSView *firstTentativeNewKeyView = tentativeNewKeyView;
       
  1033                 NSView *nextTentativeNewKeyView = [tentativeNewKeyView nextValidKeyView];
       
  1034                 while ( nextTentativeNewKeyView 
       
  1035 						&& [nextTentativeNewKeyView isDescendantOf:view->fWebView] 
       
  1036 						&& nextTentativeNewKeyView!=firstTentativeNewKeyView)
       
  1037 				{
       
  1038                     tentativeNewKeyView = nextTentativeNewKeyView;
       
  1039                     nextTentativeNewKeyView = [tentativeNewKeyView nextValidKeyView];
       
  1040                 }
       
  1041 
       
  1042             }
       
  1043 
       
  1044             // Set the keyboard focus.
       
  1045             //NSLog(@"Tabbed into the first or last key view.");
       
  1046             [view->fKitWindow makeFirstResponder:tentativeNewKeyView];
       
  1047             viewWeMadeFirstResponder = tentativeNewKeyView;
       
  1048         }
       
  1049 		else
       
  1050 		{
       
  1051             // This control view has no subviews that can take the keyboard focus.
       
  1052             //NSLog(@"Can't tab into this view.");
       
  1053             viewWeMadeFirstResponder = nil;
       
  1054         }
       
  1055     }
       
  1056 
       
  1057     // Done.
       
  1058     return viewWeMadeFirstResponder;
       
  1059 }
       
  1060 
       
  1061 
       
  1062 //----------------------------------------------------------------------------------
       
  1063 // RelinquishFocus
       
  1064 //----------------------------------------------------------------------------------
       
  1065 //
       
  1066 static void
       
  1067 RelinquishFocus( HIWebView* view, bool inAutodisplay )
       
  1068 {
       
  1069     NSResponder*  firstResponder;
       
  1070 
       
  1071     // Apparently Carbon thinks that some subview of this control view has the keyboard focus,
       
  1072 	// or we wouldn't be being asked to relinquish focus.
       
  1073 
       
  1074 	firstResponder = [view->fKitWindow firstResponder];
       
  1075 	if ( [firstResponder isKindOfClass:[NSView class]] )
       
  1076 	{
       
  1077 		// Some subview of this control view really is the first responder right now.
       
  1078 		check( [(NSView *)firstResponder isDescendantOf:view->fWebView] );
       
  1079 
       
  1080 		// Make the window the first responder, so that no view is the key view.
       
  1081         [view->fKitWindow makeFirstResponder:view->fKitWindow];
       
  1082 
       
  1083 		// 	If this control is not allowed to do autodisplay, don't let
       
  1084 		//	it autodisplay any just-changed focus rings or text on the
       
  1085 		//	next go around the event loop. I'm probably clearing more
       
  1086 		//	dirty rects than I have to, but it doesn't seem to hurt in
       
  1087 		//	the print panel accessory view case, and I don't have time
       
  1088 		//	to figure out exactly what -[NSCell _setKeyboardFocusRingNeedsDisplay]
       
  1089 		//	is doing when invoked indirectly from -makeFirstResponder up above.  M.P. Notice - 12/4/00
       
  1090 
       
  1091 		if ( !inAutodisplay )
       
  1092 			[[view->fWebView opaqueAncestor] _clearDirtyRectsForTree];
       
  1093     }
       
  1094 	else
       
  1095 	{
       
  1096 		//  The Cocoa first responder does not correspond to the Carbon
       
  1097 		//	control that has the keyboard focus.  This can happen when
       
  1098 		//	you've closed a dialog by hitting return in an NSTextView
       
  1099 		//	that's a subview of this one; Cocoa closed the window, and
       
  1100 		//	now Carbon is telling this control to relinquish the focus
       
  1101 		//	as it's being disposed.  There's nothing to do.
       
  1102 
       
  1103 		check(firstResponder==window);
       
  1104 	}
       
  1105 }
       
  1106 
       
  1107 //----------------------------------------------------------------------------------
       
  1108 // ActiveStateChanged
       
  1109 //----------------------------------------------------------------------------------
       
  1110 //
       
  1111 static void
       
  1112 ActiveStateChanged( HIWebView* view )
       
  1113 {
       
  1114 	if ( [view->fWebView respondsToSelector:@selector(setEnabled)] )
       
  1115 	{
       
  1116 		[(NSControl*)view->fWebView setEnabled: IsControlEnabled( view->fViewRef )];
       
  1117 		HIViewSetNeedsDisplay( view->fViewRef, true );
       
  1118 	}
       
  1119 }
       
  1120 
       
  1121 
       
  1122 //----------------------------------------------------------------------------------
       
  1123 // ProcessCommand
       
  1124 //----------------------------------------------------------------------------------
       
  1125 //
       
  1126 static OSStatus
       
  1127 ProcessCommand( HIWebView* inView, const HICommand* inCommand )
       
  1128 {
       
  1129 	OSStatus		result = eventNotHandledErr;
       
  1130 	NSResponder*	resp;
       
  1131 	
       
  1132 	resp = [inView->fKitWindow firstResponder];
       
  1133 
       
  1134 	if ( [resp isKindOfClass:[NSView class]] )
       
  1135 	{
       
  1136 		NSView*	respView = (NSView*)resp;
       
  1137 
       
  1138 		if ( respView == inView->fWebView
       
  1139 			|| [respView isDescendantOf: inView->fWebView] )
       
  1140 		{
       
  1141 			switch ( inCommand->commandID )
       
  1142 			{
       
  1143 				case kHICommandCut:
       
  1144 				case kHICommandCopy:
       
  1145 				case kHICommandPaste:
       
  1146 				case kHICommandClear:
       
  1147 				case kHICommandSelectAll:
       
  1148 					{
       
  1149 						SEL selector = _NSSelectorForHICommand( inCommand );
       
  1150 						if ( [respView respondsToSelector:selector] )
       
  1151 						{
       
  1152 							[respView performSelector:selector withObject:nil];
       
  1153 							result = noErr;
       
  1154 						}
       
  1155 					}
       
  1156 					break;
       
  1157 			}
       
  1158 		}
       
  1159 	}
       
  1160 	
       
  1161 	return result;
       
  1162 }
       
  1163 
       
  1164 //----------------------------------------------------------------------------------
       
  1165 // UpdateCommandStatus
       
  1166 //----------------------------------------------------------------------------------
       
  1167 //
       
  1168 static OSStatus
       
  1169 UpdateCommandStatus( HIWebView* inView, const HICommand* inCommand )
       
  1170 {
       
  1171 	OSStatus		result = eventNotHandledErr;
       
  1172 	MenuItemProxy* 	proxy = NULL;
       
  1173 	NSResponder*	resp;
       
  1174 	
       
  1175 	resp = [inView->fKitWindow firstResponder];
       
  1176 	
       
  1177 	if ( [resp isKindOfClass:[NSView class]] )
       
  1178 	{
       
  1179 		NSView*	respView = (NSView*)resp;
       
  1180 
       
  1181 		if ( respView == inView->fWebView
       
  1182 			|| [respView isDescendantOf: inView->fWebView] )
       
  1183 		{
       
  1184 			if ( inCommand->attributes & kHICommandFromMenu )
       
  1185 			{
       
  1186 				SEL selector = _NSSelectorForHICommand( inCommand );
       
  1187 	
       
  1188 				if ( selector )
       
  1189 				{
       
  1190 					if ( [resp respondsToSelector: selector] )
       
  1191 					{
       
  1192 						proxy = [[MenuItemProxy alloc] initWithAction: selector];
       
  1193 						
       
  1194                         // Can't use -performSelector:withObject: here because the method we're calling returns BOOL, while
       
  1195                         // -performSelector:withObject:'s return value is assumed to be an id.
       
  1196                         BOOL (*validationFunction)(id, SEL, id) = (BOOL (*)(id, SEL, id))objc_msgSend;
       
  1197                         if (validationFunction(resp, @selector(validateUserInterfaceItem:), proxy))
       
  1198 							EnableMenuItem( inCommand->menu.menuRef, inCommand->menu.menuItemIndex );
       
  1199 						else
       
  1200 							DisableMenuItem( inCommand->menu.menuRef, inCommand->menu.menuItemIndex );
       
  1201 						
       
  1202 						result = noErr;
       
  1203 					}
       
  1204 				}
       
  1205 			}
       
  1206 		}
       
  1207 	}
       
  1208 	
       
  1209 	if ( proxy )
       
  1210 		[proxy release];
       
  1211 
       
  1212 	return result;
       
  1213 }
       
  1214 
       
  1215 // Blatantly stolen from AppKit and cropped a bit
       
  1216 
       
  1217 //----------------------------------------------------------------------------------
       
  1218 // _NSSelectorForHICommand
       
  1219 //----------------------------------------------------------------------------------
       
  1220 //
       
  1221 static SEL
       
  1222 _NSSelectorForHICommand( const HICommand* inCommand )
       
  1223 {
       
  1224     switch ( inCommand->commandID )
       
  1225 	{
       
  1226         case kHICommandUndo: return @selector(undo:);
       
  1227         case kHICommandRedo: return @selector(redo:);
       
  1228         case kHICommandCut  : return @selector(cut:);
       
  1229         case kHICommandCopy : return @selector(copy:);
       
  1230         case kHICommandPaste: return @selector(paste:);
       
  1231         case kHICommandClear: return @selector(delete:);
       
  1232         case kHICommandSelectAll: return @selector(selectAll:);
       
  1233         default: return NULL;
       
  1234     }
       
  1235 
       
  1236     return NULL;
       
  1237 }
       
  1238 
       
  1239 
       
  1240 //-----------------------------------------------------------------------------------
       
  1241 //	HIWebViewEventHandler
       
  1242 //-----------------------------------------------------------------------------------
       
  1243 //	Our object's virtual event handler method. I'm not sure if we need this these days.
       
  1244 //	We used to do various things with it, but those days are long gone...
       
  1245 //
       
  1246 static OSStatus
       
  1247 HIWebViewEventHandler(
       
  1248 	EventHandlerCallRef	inCallRef,
       
  1249 	EventRef			inEvent,
       
  1250 	void *				inUserData )
       
  1251 {
       
  1252 	OSStatus			result = eventNotHandledErr;
       
  1253 	HIPoint				where;
       
  1254 	OSType				tag;
       
  1255 	void *				ptr;
       
  1256 	Size				size;
       
  1257 	UInt32				features;
       
  1258 	RgnHandle			region = NULL;
       
  1259 	ControlPartCode		part;
       
  1260 	HIWebView*			view = (HIWebView*)inUserData;
       
  1261 
       
  1262         // [NSApp setWindowsNeedUpdate:YES] must be called before events so that ActivateTSMDocument is called to set an active document. 
       
  1263         // Without an active document, TSM will use a default document which uses a bottom-line input window which we don't want.
       
  1264         [NSApp setWindowsNeedUpdate:YES];
       
  1265         
       
  1266 	switch ( GetEventClass( inEvent ) )
       
  1267 	{
       
  1268 		case kEventClassHIObject:
       
  1269 			switch ( GetEventKind( inEvent ) )
       
  1270 			{
       
  1271 				case kEventHIObjectConstruct:
       
  1272 					{
       
  1273 						HIObjectRef		object;
       
  1274 
       
  1275 						result = GetEventParameter( inEvent, kEventParamHIObjectInstance,
       
  1276 								typeHIObjectRef, NULL, sizeof( HIObjectRef ), NULL, &object );
       
  1277 						require_noerr( result, MissingParameter );
       
  1278 						
       
  1279 						// on entry for our construct event, we're passed the
       
  1280 						// creation proc we registered with for this class.
       
  1281 						// we use it now to create the instance, and then we
       
  1282 						// replace the instance parameter data with said instance
       
  1283 						// as type void.
       
  1284 
       
  1285 						view = HIWebViewConstructor( (HIViewRef)object );
       
  1286 
       
  1287 						if ( view )
       
  1288 						{
       
  1289 							SetEventParameter( inEvent, kEventParamHIObjectInstance,
       
  1290 									typeVoidPtr, sizeof( void * ), &view ); 
       
  1291 						}
       
  1292 					}
       
  1293 					break;
       
  1294 				
       
  1295 				case kEventHIObjectDestruct:
       
  1296 					HIWebViewDestructor( view );
       
  1297 					// result is unimportant
       
  1298 					break;
       
  1299 			}
       
  1300 			break;
       
  1301 
       
  1302 		case kEventClassKeyboard:
       
  1303 			{
       
  1304 				NSEvent* kitEvent = WKCreateNSEventWithCarbonEvent(inEvent);
       
  1305 				[view->fKitWindow sendSuperEvent:kitEvent];
       
  1306 				[kitEvent release];
       
  1307 				result = noErr;
       
  1308 			}
       
  1309 			break;
       
  1310 
       
  1311 		case kEventClassMouse:
       
  1312 			switch ( GetEventKind( inEvent ) )
       
  1313 			{
       
  1314 				case kEventMouseUp:
       
  1315 					result = MouseUp( view, inEvent );
       
  1316 					break;
       
  1317 				
       
  1318 				case kEventMouseWheelMoved:
       
  1319 					result = MouseWheelMoved( view, inEvent );
       
  1320 					break;
       
  1321 
       
  1322 				case kEventMouseMoved:
       
  1323 					result = MouseMoved( view, inEvent );
       
  1324 					break;
       
  1325 
       
  1326 				case kEventMouseDragged:
       
  1327 					result = MouseDragged( view, inEvent );
       
  1328 					break;
       
  1329 			}
       
  1330 			break;
       
  1331 
       
  1332 		case kEventClassCommand:
       
  1333 			{
       
  1334 				HICommand		command;
       
  1335 				
       
  1336 				result = GetEventParameter( inEvent, kEventParamDirectObject, typeHICommand, NULL,
       
  1337 								sizeof( HICommand ), NULL, &command );
       
  1338 				require_noerr( result, MissingParameter );
       
  1339 				
       
  1340 				switch ( GetEventKind( inEvent ) )
       
  1341 				{
       
  1342 					case kEventCommandProcess:
       
  1343 						result = ProcessCommand( view, &command );
       
  1344 						break;
       
  1345 					
       
  1346 					case kEventCommandUpdateStatus:
       
  1347 						result = UpdateCommandStatus( view, &command );
       
  1348 						break;
       
  1349 				}
       
  1350 			}
       
  1351 			break;
       
  1352 
       
  1353 		case kEventClassControl:
       
  1354 			switch ( GetEventKind( inEvent ) )
       
  1355 			{
       
  1356 				case kEventControlInitialize:
       
  1357 					features = GetBehaviors();
       
  1358 					SetEventParameter( inEvent, kEventParamControlFeatures, typeUInt32,
       
  1359 							sizeof( UInt32 ), &features );
       
  1360 					result = noErr;
       
  1361 					break;
       
  1362 					
       
  1363 				case kEventControlDraw:
       
  1364 					{
       
  1365 						CGContextRef		context = NULL;
       
  1366 						
       
  1367 						GetEventParameter( inEvent, kEventParamRgnHandle, typeQDRgnHandle, NULL,
       
  1368 								sizeof( RgnHandle ), NULL, &region );
       
  1369 						GetEventParameter( inEvent, kEventParamCGContextRef, typeCGContextRef, NULL,
       
  1370 								sizeof( CGContextRef ), NULL, &context );
       
  1371 
       
  1372 						Draw( view, region, context );
       
  1373 
       
  1374 						result = noErr;
       
  1375 					}
       
  1376 					break;
       
  1377 				
       
  1378 				case kEventControlHitTest:
       
  1379 					GetEventParameter( inEvent, kEventParamMouseLocation, typeHIPoint, NULL,
       
  1380 							sizeof( HIPoint ), NULL, &where );
       
  1381 					part = HitTest( view, &where );
       
  1382 					SetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode, sizeof( ControlPartCode ), &part );
       
  1383 					result = noErr;
       
  1384 					break;
       
  1385 					
       
  1386 				case kEventControlGetPartRegion:
       
  1387 					GetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode, NULL,
       
  1388 							sizeof( ControlPartCode ), NULL, &part );
       
  1389 					GetEventParameter( inEvent, kEventParamControlRegion, typeQDRgnHandle, NULL,
       
  1390 							sizeof( RgnHandle ), NULL, &region );
       
  1391 					result = GetRegion( view, part, region );
       
  1392 					break;
       
  1393 				
       
  1394 				case kEventControlGetData:
       
  1395 					GetEventParameter(inEvent, kEventParamControlPart, typeControlPartCode, NULL, sizeof(ControlPartCode), NULL, &part);
       
  1396 					GetEventParameter(inEvent, kEventParamControlDataTag, typeEnumeration, NULL, sizeof(OSType), NULL, &tag);
       
  1397 					GetEventParameter(inEvent, kEventParamControlDataBuffer, typePtr, NULL, sizeof(Ptr), NULL, &ptr);
       
  1398 					GetEventParameter(inEvent, kEventParamControlDataBufferSize, typeByteCount, NULL, sizeof(Size), NULL, &size);
       
  1399 
       
  1400 					if (tag == kControlKindTag) {
       
  1401 						Size outSize;
       
  1402 						result = noErr;
       
  1403 
       
  1404 						if (ptr) {
       
  1405 							if (size != sizeof(ControlKind))
       
  1406 								result = errDataSizeMismatch;
       
  1407 							else
       
  1408 								(*(ControlKind *)ptr) = GetKind();
       
  1409 						}
       
  1410 
       
  1411 						outSize = sizeof(ControlKind);
       
  1412 						SetEventParameter(inEvent, kEventParamControlDataBufferSize, typeByteCount, sizeof(Size), &outSize);
       
  1413 					}
       
  1414 
       
  1415 					break;
       
  1416 				
       
  1417 				case kEventControlBoundsChanged:
       
  1418 					{
       
  1419 						HIRect		prevRect, currRect;
       
  1420 						UInt32		attrs;
       
  1421 						
       
  1422 						GetEventParameter( inEvent, kEventParamAttributes, typeUInt32, NULL,
       
  1423 								sizeof( UInt32 ), NULL, &attrs );
       
  1424 						GetEventParameter( inEvent, kEventParamOriginalBounds, typeHIRect, NULL,
       
  1425 								sizeof( HIRect ), NULL, &prevRect );
       
  1426 						GetEventParameter( inEvent, kEventParamCurrentBounds, typeHIRect, NULL,
       
  1427 								sizeof( HIRect ), NULL, &currRect );
       
  1428 
       
  1429 						BoundsChanged( view, attrs, &prevRect, &currRect );
       
  1430 						result = noErr;
       
  1431 					}
       
  1432 					break;
       
  1433 				
       
  1434 				case kEventControlActivate:
       
  1435 					ActiveStateChanged( view );
       
  1436 					result = noErr;
       
  1437 					break;
       
  1438 					
       
  1439 				case kEventControlDeactivate:
       
  1440 					ActiveStateChanged( view );
       
  1441 					result = noErr;
       
  1442 					break;
       
  1443 															
       
  1444 				case kEventControlOwningWindowChanged:
       
  1445 					{
       
  1446 						WindowRef		fromWindow, toWindow;
       
  1447 						
       
  1448 						result = GetEventParameter( inEvent, kEventParamControlOriginalOwningWindow, typeWindowRef, NULL,
       
  1449 										sizeof( WindowRef ), NULL, &fromWindow );
       
  1450 						require_noerr( result, MissingParameter );
       
  1451 
       
  1452 						result = GetEventParameter( inEvent, kEventParamControlCurrentOwningWindow, typeWindowRef, NULL,
       
  1453 										sizeof( WindowRef ), NULL, &toWindow );
       
  1454 						require_noerr( result, MissingParameter );
       
  1455 
       
  1456 						OwningWindowChanged( view, fromWindow, toWindow );
       
  1457 						
       
  1458 						result = noErr;
       
  1459 					}
       
  1460 					break;
       
  1461                                     
       
  1462 				case kEventControlClick:
       
  1463 					result = Click( view, inEvent );
       
  1464 					break;
       
  1465                                     
       
  1466 				case kEventControlContextualMenuClick:
       
  1467 					result = ContextMenuClick( view, inEvent );
       
  1468 					break;
       
  1469                                     
       
  1470 				case kEventControlSetFocusPart:
       
  1471 					{
       
  1472 						ControlPartCode		desiredFocus;
       
  1473 						RgnHandle			invalidRgn;
       
  1474 						Boolean				focusEverything;
       
  1475 						ControlPartCode		actualFocus;
       
  1476 						
       
  1477 						result = GetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode, NULL,
       
  1478 										sizeof( ControlPartCode ), NULL, &desiredFocus ); 
       
  1479 						require_noerr( result, MissingParameter );
       
  1480 						
       
  1481 						GetEventParameter( inEvent, kEventParamControlInvalRgn, typeQDRgnHandle, NULL,
       
  1482 								sizeof( RgnHandle ), NULL, &invalidRgn );
       
  1483 
       
  1484 						focusEverything = false; // a good default in case the parameter doesn't exist
       
  1485 
       
  1486 						GetEventParameter( inEvent, kEventParamControlFocusEverything, typeBoolean, NULL,
       
  1487 								sizeof( Boolean ), NULL, &focusEverything );
       
  1488 
       
  1489 						result = SetFocusPart( view, desiredFocus, invalidRgn, focusEverything, &actualFocus );
       
  1490 						
       
  1491 						if ( result == noErr )
       
  1492 							verify_noerr( SetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode,
       
  1493 									sizeof( ControlPartCode ), &actualFocus ) );
       
  1494 					}
       
  1495 					break;
       
  1496 				
       
  1497 				// some other kind of Control event
       
  1498 				default:
       
  1499 					break;
       
  1500 			}
       
  1501 			break;
       
  1502 			
       
  1503 		// some other event class
       
  1504 		default:
       
  1505 			break;
       
  1506 	}
       
  1507 
       
  1508 MissingParameter:
       
  1509 	return result;
       
  1510 }
       
  1511 
       
  1512 
       
  1513 static void UpdateObserver(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info);
       
  1514 
       
  1515 static void
       
  1516 StartUpdateObserver( HIWebView* view )
       
  1517 {
       
  1518 	CFRunLoopObserverContext	context;
       
  1519 	CFRunLoopObserverRef		observer;
       
  1520     CFRunLoopRef				mainRunLoop;
       
  1521     
       
  1522     check( view->fIsComposited == false );
       
  1523     check( view->fUpdateObserver == NULL );
       
  1524 
       
  1525 	context.version = 0;
       
  1526 	context.info = view;
       
  1527 	context.retain = NULL;
       
  1528 	context.release = NULL;
       
  1529 	context.copyDescription = NULL;
       
  1530 
       
  1531     mainRunLoop = (CFRunLoopRef)GetCFRunLoopFromEventLoop( GetMainEventLoop() );
       
  1532 	observer = CFRunLoopObserverCreate( NULL, kCFRunLoopEntry | kCFRunLoopBeforeWaiting, true, 0, UpdateObserver, &context );
       
  1533 	CFRunLoopAddObserver( mainRunLoop, observer, kCFRunLoopCommonModes ); 
       
  1534 
       
  1535     view->fUpdateObserver = observer;
       
  1536     
       
  1537 //    printf( "Update observer started\n" );
       
  1538 }
       
  1539 
       
  1540 static void
       
  1541 StopUpdateObserver( HIWebView* view )
       
  1542 {
       
  1543     check( view->fIsComposited == false );
       
  1544     check( view->fUpdateObserver != NULL );
       
  1545 
       
  1546     CFRunLoopObserverInvalidate( view->fUpdateObserver );
       
  1547     CFRelease( view->fUpdateObserver );
       
  1548     view->fUpdateObserver = NULL;
       
  1549 
       
  1550 //    printf( "Update observer removed\n" );
       
  1551 }
       
  1552 
       
  1553 static void 
       
  1554 UpdateObserver( CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info )
       
  1555 {
       
  1556 	HIWebView*			view = (HIWebView*)info;
       
  1557     RgnHandle			region = NewRgn();
       
  1558     
       
  1559 //    printf( "Update observer called\n" );
       
  1560 
       
  1561     if ( region )
       
  1562     {
       
  1563         GetWindowRegion( GetControlOwner( view->fViewRef ), kWindowUpdateRgn, region );
       
  1564         
       
  1565         if ( !EmptyRgn( region ) )
       
  1566         {
       
  1567             RgnHandle		ourRgn = NewRgn();
       
  1568             Rect			rect;
       
  1569             
       
  1570             GetWindowBounds( GetControlOwner( view->fViewRef ), kWindowStructureRgn, &rect );
       
  1571             
       
  1572 //            printf( "Update region is non-empty\n" );
       
  1573             
       
  1574             if ( ourRgn )
       
  1575             {
       
  1576                 Rect		rect;
       
  1577                 GrafPtr		savePort, port;
       
  1578                 Point		offset = { 0, 0 };
       
  1579                 
       
  1580                 port = GetWindowPort( GetControlOwner( view->fViewRef ) );
       
  1581                 
       
  1582                 GetPort( &savePort );
       
  1583                 SetPort( port );
       
  1584                 
       
  1585                 GlobalToLocal( &offset );
       
  1586                 OffsetRgn( region, offset.h, offset.v );
       
  1587 
       
  1588                 GetControlBounds( view->fViewRef, &rect );
       
  1589                 RectRgn( ourRgn, &rect );
       
  1590                 
       
  1591 //                printf( "our control is at %d %d %d %d\n",
       
  1592 //                        rect.top, rect.left, rect.bottom, rect.right );
       
  1593                 
       
  1594                 GetRegionBounds( region, &rect );
       
  1595 //                printf( "region is at %d %d %d %d\n",
       
  1596 //                        rect.top, rect.left, rect.bottom, rect.right );
       
  1597 
       
  1598                 SectRgn( ourRgn, region, ourRgn );
       
  1599                 
       
  1600                 GetRegionBounds( ourRgn, &rect );
       
  1601 //                printf( "intersection is  %d %d %d %d\n",
       
  1602 //                       rect.top, rect.left, rect.bottom, rect.right );
       
  1603                 if ( !EmptyRgn( ourRgn ) )
       
  1604                 {
       
  1605                     RgnHandle	saveVis = NewRgn();
       
  1606                     
       
  1607 //                    printf( "looks like we should draw\n" );
       
  1608 
       
  1609                     if ( saveVis )
       
  1610                     {
       
  1611 //                        RGBColor	kRedColor = { 0xffff, 0, 0 };
       
  1612                         
       
  1613                         GetPortVisibleRegion( GetWindowPort( GetControlOwner( view->fViewRef ) ), saveVis );
       
  1614                         SetPortVisibleRegion( GetWindowPort( GetControlOwner( view->fViewRef ) ), ourRgn );
       
  1615                         
       
  1616 //                        RGBForeColor( &kRedColor );
       
  1617 //                        PaintRgn( ourRgn );
       
  1618 //                        QDFlushPortBuffer( port, NULL );
       
  1619 //                        Delay( 15, NULL );
       
  1620 
       
  1621                         Draw1Control( view->fViewRef );
       
  1622                         ValidWindowRgn( GetControlOwner( view->fViewRef ), ourRgn );
       
  1623                         
       
  1624                         SetPortVisibleRegion( GetWindowPort( GetControlOwner( view->fViewRef ) ), saveVis );
       
  1625                         DisposeRgn( saveVis );
       
  1626                     }
       
  1627                 }
       
  1628 
       
  1629                 SetPort( savePort );
       
  1630                 
       
  1631                 DisposeRgn( ourRgn );
       
  1632             }
       
  1633         }
       
  1634         
       
  1635         DisposeRgn( region );
       
  1636     }
       
  1637 }
       
  1638 
       
  1639 #endif