1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612 |
- /*
- * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #ifndef __LP64__
- #import "HIWebView.h"
- #import "CarbonWindowAdapter.h"
- #import "HIViewAdapter.h"
- #import "QuickDrawCompatibility.h"
- #import "WebHTMLViewInternal.h"
- #import "WebKit.h"
- #import <WebKitSystemInterface.h>
- #import <wtf/ObjcRuntimeExtras.h>
- @interface NSWindow (AppKitSecretsHIWebViewKnows)
- - (void)_removeWindowRef;
- @end
- @interface NSView (AppKitSecretsHIWebViewKnows)
- - (void)_clearDirtyRectsForTree;
- @end
- extern "C" void HIWebViewRegisterClass();
- @interface MenuItemProxy : NSObject <NSValidatedUserInterfaceItem>
- {
- int _tag;
- SEL _action;
- }
- - (id)initWithAction:(SEL)action;
- - (SEL)action;
- - (int)tag;
- @end
- @implementation MenuItemProxy
- - (id)initWithAction:(SEL)action
- {
- [super init];
- if (self == nil) return nil;
- _action = action;
- return self;
- }
- - (SEL)action
- {
- return _action;
- }
- - (int)tag
- {
- return 0;
- }
- @end
- struct HIWebView
- {
- HIViewRef fViewRef;
- WebView* fWebView;
- NSView* fFirstResponder;
- CarbonWindowAdapter * fKitWindow;
- bool fIsComposited;
- CFRunLoopObserverRef fUpdateObserver;
- };
- typedef struct HIWebView HIWebView;
- static const OSType NSAppKitPropertyCreator = 'akit';
- /*
- These constants are not used. Commented out to make the compiler happy.
- static const OSType NSViewCarbonControlViewPropertyTag = 'view';
- static const OSType NSViewCarbonControlAutodisplayPropertyTag = 'autd';
- static const OSType NSViewCarbonControlFirstResponderViewPropertyTag = 'frvw';
- */
- static const OSType NSCarbonWindowPropertyTag = 'win ';
- static SEL _NSSelectorForHICommand( const HICommand* hiCommand );
- static const EventTypeSpec kEvents[] = {
- { kEventClassHIObject, kEventHIObjectConstruct },
- { kEventClassHIObject, kEventHIObjectDestruct },
-
- { kEventClassMouse, kEventMouseUp },
- { kEventClassMouse, kEventMouseMoved },
- { kEventClassMouse, kEventMouseDragged },
- { kEventClassMouse, kEventMouseWheelMoved },
- { kEventClassKeyboard, kEventRawKeyDown },
- { kEventClassKeyboard, kEventRawKeyRepeat },
- { kEventClassCommand, kEventCommandProcess },
- { kEventClassCommand, kEventCommandUpdateStatus },
- { kEventClassControl, kEventControlInitialize },
- { kEventClassControl, kEventControlDraw },
- { kEventClassControl, kEventControlHitTest },
- { kEventClassControl, kEventControlGetPartRegion },
- { kEventClassControl, kEventControlGetData },
- { kEventClassControl, kEventControlBoundsChanged },
- { kEventClassControl, kEventControlActivate },
- { kEventClassControl, kEventControlDeactivate },
- { kEventClassControl, kEventControlOwningWindowChanged },
- { kEventClassControl, kEventControlClick },
- { kEventClassControl, kEventControlContextualMenuClick },
- { kEventClassControl, kEventControlSetFocusPart }
- };
- #define kHIViewBaseClassID CFSTR( "com.apple.hiview" )
- #define kHIWebViewClassID CFSTR( "com.apple.HIWebView" )
- static HIWebView* HIWebViewConstructor( HIViewRef inView );
- static void HIWebViewDestructor( HIWebView* view );
- static OSStatus HIWebViewEventHandler(
- EventHandlerCallRef inCallRef,
- EventRef inEvent,
- void * inUserData );
- static UInt32 GetBehaviors();
- static ControlKind GetKind();
- static void Draw( HIWebView* inView, RgnHandle limitRgn, CGContextRef inContext );
- static ControlPartCode HitTest( HIWebView* view, const HIPoint* where );
- static OSStatus GetRegion( HIWebView* view, ControlPartCode inPart, RgnHandle outRgn );
- static void BoundsChanged(
- HIWebView* inView,
- UInt32 inOptions,
- const HIRect* inOriginalBounds,
- const HIRect* inCurrentBounds );
- static void OwningWindowChanged(
- HIWebView* view,
- WindowRef oldWindow,
- WindowRef newWindow );
- static void ActiveStateChanged( HIWebView* view );
- static OSStatus Click( HIWebView* inView, EventRef inEvent );
- static OSStatus ContextMenuClick( HIWebView* inView, EventRef inEvent );
- static OSStatus MouseUp( HIWebView* inView, EventRef inEvent );
- static OSStatus MouseMoved( HIWebView* inView, EventRef inEvent );
- static OSStatus MouseDragged( HIWebView* inView, EventRef inEvent );
- static OSStatus MouseWheelMoved( HIWebView* inView, EventRef inEvent );
- static OSStatus ProcessCommand( HIWebView* inView, const HICommand* inCommand );
- static OSStatus UpdateCommandStatus( HIWebView* inView, const HICommand* inCommand );
- static OSStatus SetFocusPart(
- HIWebView* view,
- ControlPartCode desiredFocus,
- RgnHandle invalidRgn,
- Boolean focusEverything,
- ControlPartCode* actualFocus );
- static NSView* AdvanceFocus( HIWebView* view, bool forward );
- static void RelinquishFocus( HIWebView* view, bool inAutodisplay );
- static WindowRef GetWindowRef( HIWebView* inView );
- static void SyncFrame( HIWebView* inView );
- static OSStatus WindowHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData );
- static void StartUpdateObserver( HIWebView* view );
- static void StopUpdateObserver( HIWebView* view );
- static inline void HIRectToQDRect( const HIRect* inRect, Rect* outRect )
- {
- outRect->top = (SInt16)CGRectGetMinY( *inRect );
- outRect->left = (SInt16)CGRectGetMinX( *inRect );
- outRect->bottom = (SInt16)CGRectGetMaxY( *inRect );
- outRect->right = (SInt16)CGRectGetMaxX( *inRect );
- }
- //----------------------------------------------------------------------------------
- // HIWebViewCreate
- //----------------------------------------------------------------------------------
- //
- OSStatus
- HIWebViewCreate(HIViewRef* outControl)
- {
- HIWebViewRegisterClass();
- return HIObjectCreate(kHIWebViewClassID, NULL, (HIObjectRef*)outControl);
- }
- //----------------------------------------------------------------------------------
- // HIWebViewGetWebView
- //----------------------------------------------------------------------------------
- //
- WebView*
- HIWebViewGetWebView( HIViewRef inView )
- {
- HIWebView* view = (HIWebView*)HIObjectDynamicCast( (HIObjectRef)inView, kHIWebViewClassID );
- WebView* result = NULL;
-
- if ( view )
- result = view->fWebView;
-
- return result;
- }
- //----------------------------------------------------------------------------------
- // HIWebViewConstructor
- //----------------------------------------------------------------------------------
- //
- static HIWebView*
- HIWebViewConstructor( HIViewRef inView )
- {
- HIWebView* view = (HIWebView*)malloc( sizeof( HIWebView ) );
-
- if ( view )
- {
- NSRect frame = { { 0, 0 }, { 400, 400 } };
-
- view->fViewRef = inView;
- WebView *webView = [[WebView alloc] initWithFrame: frame];
- CFRetain(webView);
- [webView release];
- view->fWebView = webView;
- [HIViewAdapter bindHIViewToNSView:inView nsView:view->fWebView];
-
- view->fFirstResponder = NULL;
- view->fKitWindow = NULL;
- view->fIsComposited = false;
- view->fUpdateObserver = NULL;
- }
-
- return view;
- }
- //----------------------------------------------------------------------------------
- // HIWebViewDestructor
- //----------------------------------------------------------------------------------
- //
- static void
- HIWebViewDestructor( HIWebView* inView )
- {
- [HIViewAdapter unbindNSView:inView->fWebView];
- CFRelease(inView->fWebView);
- free(inView);
- }
- //----------------------------------------------------------------------------------
- // HIWebViewRegisterClass
- //----------------------------------------------------------------------------------
- //
- void
- HIWebViewRegisterClass()
- {
- static bool sRegistered;
-
- if ( !sRegistered )
- {
- HIObjectRegisterSubclass( kHIWebViewClassID, kHIViewBaseClassID, 0, HIWebViewEventHandler,
- GetEventTypeCount( kEvents ), kEvents, 0, NULL );
- sRegistered = true;
- }
- }
- //----------------------------------------------------------------------------------
- // GetBehaviors
- //----------------------------------------------------------------------------------
- //
- static UInt32
- GetBehaviors()
- {
- return kControlSupportsDataAccess | kControlSupportsGetRegion | kControlGetsFocusOnClick;
- }
- //----------------------------------------------------------------------------------
- // Draw
- //----------------------------------------------------------------------------------
- //
- static void
- Draw( HIWebView* inView, RgnHandle limitRgn, CGContextRef inContext )
- {
- HIRect bounds;
- Rect drawRect;
- HIRect hiRect;
- bool createdContext = false;
- if (!inView->fIsComposited)
- {
- GrafPtr port;
- Rect portRect;
- GetPort( &port );
- GetPortBounds( port, &portRect );
- CreateCGContextForPort( port, &inContext );
- SyncCGContextOriginWithPort( inContext, port );
- CGContextTranslateCTM( inContext, 0, (portRect.bottom - portRect.top) );
- CGContextScaleCTM( inContext, 1, -1 );
- createdContext = true;
- }
- HIViewGetBounds( inView->fViewRef, &bounds );
- CGContextRef savedContext = WKNSWindowOverrideCGContext(inView->fKitWindow, inContext);
- [NSGraphicsContext setCurrentContext:[inView->fKitWindow graphicsContext]];
- GetRegionBounds( limitRgn, &drawRect );
- if ( !inView->fIsComposited )
- OffsetRect( &drawRect, (SInt16)-bounds.origin.x, (SInt16)-bounds.origin.y );
-
- hiRect.origin.x = drawRect.left;
- hiRect.origin.y = bounds.size.height - drawRect.bottom; // flip y
- hiRect.size.width = drawRect.right - drawRect.left;
- hiRect.size.height = drawRect.bottom - drawRect.top;
- // printf( "Drawing: drawRect is (%g %g) (%g %g)\n", hiRect.origin.x, hiRect.origin.y,
- // hiRect.size.width, hiRect.size.height );
- // FIXME: We need to do layout before Carbon has decided what region needs drawn.
- // In Cocoa we make sure to do layout and invalidate any new regions before draw, so everything
- // can be drawn in one pass. Doing a layout here will cause new regions to be invalidated, but they
- // will not all be drawn in this pass since we already have a fixed rect we are going to display.
- NSView <WebDocumentView> *documentView = [[[inView->fWebView mainFrame] frameView] documentView];
- if ([documentView isKindOfClass:[WebHTMLView class]])
- [(WebHTMLView *)documentView _web_updateLayoutAndStyleIfNeededRecursive];
- if ( inView->fIsComposited )
- [inView->fWebView displayIfNeededInRect: *(NSRect*)&hiRect];
- else
- [inView->fWebView displayRect:*(NSRect*)&hiRect];
- WKNSWindowRestoreCGContext(inView->fKitWindow, savedContext);
- if ( !inView->fIsComposited )
- {
- HIViewRef view;
- HIViewFindByID( HIViewGetRoot( GetControlOwner( inView->fViewRef ) ), kHIViewWindowGrowBoxID, &view );
- if ( view )
- {
- HIRect frame;
- HIViewGetBounds( view, &frame );
- HIViewConvertRect( &frame, view, NULL );
- hiRect.origin.x = drawRect.left;
- hiRect.origin.y = drawRect.top;
- hiRect.size.width = drawRect.right - drawRect.left;
- hiRect.size.height = drawRect.bottom - drawRect.top;
- HIViewConvertRect( &hiRect, inView->fViewRef, NULL );
- if ( CGRectIntersectsRect( frame, hiRect ) )
- HIViewSetNeedsDisplay( view, true );
- }
- }
- if ( createdContext )
- {
- CGContextSynchronize( inContext );
- CGContextRelease( inContext );
- }
- }
- //----------------------------------------------------------------------------------
- // HitTest
- //----------------------------------------------------------------------------------
- //
- static ControlPartCode
- HitTest( HIWebView* view, const HIPoint* where )
- {
- HIRect bounds;
-
- HIViewGetBounds( view->fViewRef, &bounds );
- if ( CGRectContainsPoint( bounds, *where ) )
- return 1;
- else
- return kControlNoPart;
- }
- //----------------------------------------------------------------------------------
- // GetRegion
- //----------------------------------------------------------------------------------
- //
- static OSStatus
- GetRegion(
- HIWebView* inView,
- ControlPartCode inPart,
- RgnHandle outRgn )
- {
- OSStatus err = eventNotHandledErr;
-
- if ( inPart == -3 ) // kControlOpaqueMetaPart:
- {
- if ( [inView->fWebView isOpaque] )
- {
- HIRect bounds;
- Rect temp;
-
- HIViewGetBounds( inView->fViewRef, &bounds );
- temp.top = (SInt16)bounds.origin.y;
- temp.left = (SInt16)bounds.origin.x;
- temp.bottom = (SInt16)CGRectGetMaxY( bounds );
- temp.right = (SInt16)CGRectGetMaxX( bounds );
- RectRgn( outRgn, &temp );
- err = noErr;
- }
- }
-
- return err;
- }
- static WindowRef
- GetWindowRef( HIWebView* inView )
- {
- return GetControlOwner( inView->fViewRef );
- }
- //----------------------------------------------------------------------------------
- // Click
- //----------------------------------------------------------------------------------
- //
- static OSStatus
- Click(HIWebView* inView, EventRef inEvent)
- {
- NSEvent *kitEvent = WKCreateNSEventWithCarbonClickEvent(inEvent, GetWindowRef(inView));
- if (!inView->fIsComposited)
- StartUpdateObserver(inView);
- [inView->fKitWindow sendEvent:kitEvent];
- if (!inView->fIsComposited)
- StopUpdateObserver(inView);
- [kitEvent release];
- return noErr;
- }
- //----------------------------------------------------------------------------------
- // MouseUp
- //----------------------------------------------------------------------------------
- //
- static OSStatus
- MouseUp( HIWebView* inView, EventRef inEvent )
- {
- NSEvent* kitEvent = WKCreateNSEventWithCarbonEvent(inEvent);
- [inView->fKitWindow sendEvent:kitEvent];
-
- [kitEvent release];
-
- return noErr;
- }
- //----------------------------------------------------------------------------------
- // MouseMoved
- //----------------------------------------------------------------------------------
- //
- static OSStatus
- MouseMoved( HIWebView* inView, EventRef inEvent )
- {
- NSEvent *kitEvent = WKCreateNSEventWithCarbonMouseMoveEvent(inEvent, inView->fKitWindow);
- [inView->fKitWindow sendEvent:kitEvent];
- [kitEvent release];
- return noErr;
- }
- //----------------------------------------------------------------------------------
- // MouseDragged
- //----------------------------------------------------------------------------------
- //
- static OSStatus
- MouseDragged( HIWebView* inView, EventRef inEvent )
- {
- NSEvent* kitEvent = WKCreateNSEventWithCarbonEvent(inEvent);
- [inView->fKitWindow sendEvent:kitEvent];
- [kitEvent release];
-
- return noErr;
- }
- //----------------------------------------------------------------------------------
- // MouseDragged
- //----------------------------------------------------------------------------------
- //
- static OSStatus
- MouseWheelMoved( HIWebView* inView, EventRef inEvent )
- {
- NSEvent* kitEvent = WKCreateNSEventWithCarbonEvent(inEvent);
- [inView->fKitWindow sendEvent:kitEvent];
- [kitEvent release];
-
- return noErr;
- }
- //----------------------------------------------------------------------------------
- // ContextMenuClick
- //----------------------------------------------------------------------------------
- //
- static OSStatus
- ContextMenuClick( HIWebView* inView, EventRef inEvent )
- {
- NSView *webView = inView->fWebView;
- NSWindow *window = [webView window];
- // Get the point out of the event.
- HIPoint point;
- GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(point), NULL, &point);
- HIViewConvertPoint(&point, inView->fViewRef, NULL);
-
- // Flip the Y coordinate, since Carbon is flipped relative to the AppKit.
- NSPoint location = NSMakePoint(point.x, [window frame].size.height - point.y);
-
- // Make up an event with the point and send it to the window.
- NSEvent *kitEvent = [NSEvent mouseEventWithType:NSRightMouseDown
- location:location
- modifierFlags:0
- timestamp:GetEventTime(inEvent)
- windowNumber:[window windowNumber]
- context:0
- eventNumber:0
- clickCount:1
- pressure:0];
- [inView->fKitWindow sendEvent:kitEvent];
- return noErr;
- }
- //----------------------------------------------------------------------------------
- // GetKind
- //----------------------------------------------------------------------------------
- //
- static ControlKind
- GetKind()
- {
- const ControlKind kMyKind = { 'appl', 'wbvw' };
-
- return kMyKind;
- }
- //----------------------------------------------------------------------------------
- // BoundsChanged
- //----------------------------------------------------------------------------------
- //
- static void
- BoundsChanged(
- HIWebView* inView,
- UInt32 inOptions,
- const HIRect* inOriginalBounds,
- const HIRect* inCurrentBounds )
- {
- if ( inView->fWebView )
- {
- SyncFrame( inView );
- }
- }
- //----------------------------------------------------------------------------------
- // OwningWindowChanged
- //----------------------------------------------------------------------------------
- //
- static void
- OwningWindowChanged(
- HIWebView* view,
- WindowRef oldWindow,
- WindowRef newWindow )
- {
- if ( newWindow ){
- WindowAttributes attrs;
-
- OSStatus err = GetWindowProperty(newWindow, NSAppKitPropertyCreator, NSCarbonWindowPropertyTag, sizeof(NSWindow *), NULL, &view->fKitWindow);
- if ( err != noErr )
- {
- const EventTypeSpec kWindowEvents[] = {
- { kEventClassWindow, kEventWindowClosed },
- { kEventClassMouse, kEventMouseMoved },
- { kEventClassMouse, kEventMouseUp },
- { kEventClassMouse, kEventMouseDragged },
- { kEventClassMouse, kEventMouseWheelMoved },
- { kEventClassKeyboard, kEventRawKeyDown },
- { kEventClassKeyboard, kEventRawKeyRepeat },
- { kEventClassKeyboard, kEventRawKeyUp },
- { kEventClassControl, kEventControlClick },
- };
-
- view->fKitWindow = [[CarbonWindowAdapter alloc] initWithCarbonWindowRef: newWindow takingOwnership: NO disableOrdering:NO carbon:YES];
- SetWindowProperty(newWindow, NSAppKitPropertyCreator, NSCarbonWindowPropertyTag, sizeof(NSWindow *), &view->fKitWindow);
-
- InstallWindowEventHandler( newWindow, WindowHandler, GetEventTypeCount( kWindowEvents ), kWindowEvents, newWindow, NULL );
- }
-
- [[view->fKitWindow contentView] addSubview:view->fWebView];
-
- GetWindowAttributes( newWindow, &attrs );
- view->fIsComposited = ( ( attrs & kWindowCompositingAttribute ) != 0 );
-
- SyncFrame( view );
- }
- else
- {
- // Be sure to detach the cocoa view, too.
- if ( view->fWebView )
- [view->fWebView removeFromSuperview];
-
- view->fKitWindow = NULL; // break the ties that bind
- }
- }
- //-------------------------------------------------------------------------------------
- // WindowHandler
- //-------------------------------------------------------------------------------------
- // Redirect mouse events to the views beneath them. This is required for WebKit to work
- // properly. We install it once per window. We also tap into window close to release
- // the NSWindow that shadows our Carbon window.
- //
- static OSStatus
- WindowHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
- {
- WindowRef window = (WindowRef)inUserData;
- OSStatus result = eventNotHandledErr;
- switch( GetEventClass( inEvent ) )
- {
- case kEventClassControl:
- {
- switch( GetEventKind( inEvent ) )
- {
- case kEventControlClick:
- {
- CarbonWindowAdapter *kitWindow;
- OSStatus err;
-
- err = GetWindowProperty( window, NSAppKitPropertyCreator, NSCarbonWindowPropertyTag, sizeof(NSWindow *), NULL, &kitWindow);
-
- // We must be outside the HIWebView, relinquish focus.
- [kitWindow relinquishFocus];
- }
- break;
- }
- }
- break;
-
- case kEventClassKeyboard:
- {
- NSWindow* kitWindow;
- OSStatus err;
- NSEvent* kitEvent;
-
- // if the first responder in the kit window is something other than the
- // window, we assume a subview of the webview is focused. we must send
- // the event to the window so that it goes through the kit's normal TSM
- // logic, and -- more importantly -- allows any delegates associated
- // with the first responder to have a chance at the event.
-
- err = GetWindowProperty( window, NSAppKitPropertyCreator, NSCarbonWindowPropertyTag, sizeof(NSWindow *), NULL, &kitWindow);
- if ( err == noErr )
- {
- NSResponder* responder = [kitWindow firstResponder];
- if ( responder != kitWindow )
- {
- kitEvent = WKCreateNSEventWithCarbonEvent(inEvent);
-
- [kitWindow sendEvent:kitEvent];
- [kitEvent release];
-
- result = noErr;
- }
- }
- }
- break;
- case kEventClassWindow:
- {
- NSWindow* kitWindow;
- OSStatus err;
-
- err = GetWindowProperty( window, NSAppKitPropertyCreator, NSCarbonWindowPropertyTag, sizeof(NSWindow *), NULL, &kitWindow);
- if ( err == noErr )
- {
- [kitWindow _removeWindowRef];
- [kitWindow close];
- }
-
- result = noErr;
- }
- break;
-
- case kEventClassMouse:
- switch (GetEventKind(inEvent))
- {
- case kEventMouseMoved:
- {
- Point where;
- GetEventParameter(inEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &where);
- WindowRef temp;
- FindWindow(where, &temp);
- if (temp == window)
- {
- Rect bounds;
- GetWindowBounds(window, kWindowStructureRgn, &bounds);
- where.h -= bounds.left;
- where.v -= bounds.top;
- SetEventParameter(inEvent, kEventParamWindowRef, typeWindowRef, sizeof(WindowRef), &window);
- SetEventParameter(inEvent, kEventParamWindowMouseLocation, typeQDPoint, sizeof(Point), &where);
- OSStatus err = noErr;
- HIViewRef view = NULL;
- err = HIViewGetViewForMouseEvent(HIViewGetRoot(window), inEvent, &view);
- if (err == noErr && view && HIObjectIsOfClass((HIObjectRef)view, kHIWebViewClassID))
- result = SendEventToEventTargetWithOptions(inEvent, HIObjectGetEventTarget((HIObjectRef)view), kEventTargetDontPropagate);
- }
- }
- break;
-
- case kEventMouseUp:
- case kEventMouseDragged:
- case kEventMouseWheelMoved:
- {
- OSStatus err = noErr;
- HIViewRef view = NULL;
- err = HIViewGetViewForMouseEvent(HIViewGetRoot(window), inEvent, &view);
- if (err == noErr && view && HIObjectIsOfClass((HIObjectRef)view, kHIWebViewClassID))
- result = SendEventToEventTargetWithOptions(inEvent, HIObjectGetEventTarget((HIObjectRef)view), kEventTargetDontPropagate);
- }
- break;
- }
- break;
- }
- return result;
- }
- //----------------------------------------------------------------------------------
- // SyncFrame
- //----------------------------------------------------------------------------------
- //
- static void
- SyncFrame( HIWebView* inView )
- {
- HIViewRef parent = HIViewGetSuperview( inView->fViewRef );
-
- if ( parent )
- {
- if ( inView->fIsComposited )
- {
- HIRect frame;
- HIRect parentBounds;
- NSPoint origin;
- HIViewGetFrame( inView->fViewRef, &frame );
- HIViewGetBounds( parent, &parentBounds );
-
- origin.x = frame.origin.x;
- origin.y = parentBounds.size.height - CGRectGetMaxY( frame );
- // printf( "syncing to (%g %g) (%g %g)\n", origin.x, origin.y,
- // frame.size.width, frame.size.height );
- [inView->fWebView setFrameOrigin: origin];
- [inView->fWebView setFrameSize: *(NSSize*)&frame.size];
- }
- else
- {
- GrafPtr port = GetWindowPort( GetControlOwner( inView->fViewRef ) );
- PixMapHandle portPix = GetPortPixMap( port );
- Rect bounds;
- HIRect rootFrame;
- HIRect frame;
- GetControlBounds( inView->fViewRef, &bounds );
- OffsetRect( &bounds, -(**portPix).bounds.left, -(**portPix).bounds.top );
- // printf( "control lives at %d %d %d %d in window-coords\n", bounds.top, bounds.left,
- // bounds.bottom, bounds.right );
-
- HIViewGetFrame( HIViewGetRoot( GetControlOwner( inView->fViewRef ) ), &rootFrame );
- frame.origin.x = bounds.left;
- frame.origin.y = rootFrame.size.height - bounds.bottom;
- frame.size.width = bounds.right - bounds.left;
- frame.size.height = bounds.bottom - bounds.top;
- // printf( " before frame convert (%g %g) (%g %g)\n", frame.origin.x, frame.origin.y,
- // frame.size.width, frame.size.height );
-
- [inView->fWebView convertRect:*(NSRect*)&frame fromView:nil];
- // printf( " moving web view to (%g %g) (%g %g)\n", frame.origin.x, frame.origin.y,
- // frame.size.width, frame.size.height );
- [inView->fWebView setFrameOrigin: *(NSPoint*)&frame.origin];
- [inView->fWebView setFrameSize: *(NSSize*)&frame.size];
- }
- }
- }
- //----------------------------------------------------------------------------------
- // SetFocusPart
- //----------------------------------------------------------------------------------
- //
- static OSStatus
- SetFocusPart(
- HIWebView* view,
- ControlPartCode desiredFocus,
- RgnHandle invalidRgn,
- Boolean focusEverything,
- ControlPartCode* actualFocus )
- {
- NSView * freshlyMadeFirstResponderView;
- SInt32 partCodeToReturn;
- // Do what Carbon is telling us to do.
- if ( desiredFocus == kControlFocusNoPart )
- {
- // Relinquish the keyboard focus.
- RelinquishFocus( view, true ); //(autodisplay ? YES : NO));
- freshlyMadeFirstResponderView = nil;
- partCodeToReturn = kControlFocusNoPart;
- //NSLog(@"Relinquished the key focus because we have no choice.");
- }
- else if ( desiredFocus == kControlFocusNextPart || desiredFocus == kControlFocusPrevPart )
- {
- BOOL goForward = (desiredFocus == kControlFocusNextPart );
- // Advance the keyboard focus, maybe right off of this view. Maybe a subview of this one already has the keyboard focus, maybe not.
- freshlyMadeFirstResponderView = AdvanceFocus( view, goForward );
- if (freshlyMadeFirstResponderView)
- partCodeToReturn = desiredFocus;
- else
- partCodeToReturn = kControlFocusNoPart;
- //NSLog(freshlyMadeFirstResponderView ? @"Advanced the key focus." : @"Relinquished the key focus.");
- }
- else
- {
- // What's this?
- if (desiredFocus != kControlIndicatorPart) {
- check(false);
- }
- freshlyMadeFirstResponderView = nil;
- partCodeToReturn = desiredFocus;
- }
- view->fFirstResponder = freshlyMadeFirstResponderView;
- *actualFocus = partCodeToReturn;
- // Done.
- return noErr;
- }
- //----------------------------------------------------------------------------------
- // AdvanceFocus
- //----------------------------------------------------------------------------------
- //
- static NSView*
- AdvanceFocus( HIWebView* view, bool forward )
- {
- NSResponder* oldFirstResponder;
- NSView* currentKeyView;
- NSView* viewWeMadeFirstResponder;
-
- // Focus on some part (subview) of this control (view). Maybe
- // a subview of this one already has the keyboard focus, maybe not.
-
- oldFirstResponder = [view->fKitWindow firstResponder];
- // If we tab out of our NSView, it will no longer be the responder
- // when we get here. We'll try this trick for now. We might need to
- // tag the view appropriately.
- if ( view->fFirstResponder && ( (NSResponder*)view->fFirstResponder != oldFirstResponder ) )
- {
- return NULL;
- }
-
- if ( [oldFirstResponder isKindOfClass:[NSView class]] )
- {
- NSView* tentativeNewKeyView;
- // Some view in this window already has the keyboard focus. It better at least be a subview of this one.
- NSView* oldFirstResponderView = (NSView *)oldFirstResponder;
- check( [oldFirstResponderView isDescendantOf:view->fWebView] );
- if ( oldFirstResponderView != view->fFirstResponder
- && ![oldFirstResponderView isDescendantOf:view->fFirstResponder] )
- {
- // Despite our efforts to record what view we made the first responder
- // (for use in the next paragraph) we couldn't keep up because the user
- // has clicked in a text field to make it the key focus, instead of using
- // the tab key. Find a control on which it's reasonable to invoke
- // -[NSView nextValidKeyView], taking into account the fact that
- // NSTextFields always pass on first-respondership to a temporarily-
- // contained NSTextView.
- NSView *viewBeingTested;
- currentKeyView = oldFirstResponderView;
- viewBeingTested = currentKeyView;
- while ( viewBeingTested != view->fWebView )
- {
- if ( [viewBeingTested isKindOfClass:[NSTextField class]] )
- {
- currentKeyView = viewBeingTested;
- break;
- }
- else
- {
- viewBeingTested = [viewBeingTested superview];
- }
- }
- }
- else
- {
- // We recorded which view we made into the first responder the
- // last time the user hit the tab key, and nothing has invalidated
- // our recorded value since.
-
- currentKeyView = view->fFirstResponder;
- }
- // Try to move on to the next or previous key view. We use the laboriously
- // recorded/figured currentKeyView instead of just oldFirstResponder as the
- // jumping-off-point when searching for the next valid key view. This is so
- // we don't get fooled if we recently made some view the first responder, but
- // it passed on first-responder-ness to some temporary subview.
-
- // You can't put normal views in a window with Carbon-control-wrapped views.
- // Stuff like this would break. M.P. Notice - 12/2/00
- tentativeNewKeyView = forward ? [currentKeyView nextValidKeyView] : [currentKeyView previousValidKeyView];
- if ( tentativeNewKeyView && [tentativeNewKeyView isDescendantOf:view->fWebView] )
- {
- // The user has tabbed to another subview of this control view. Change the keyboard focus.
- //NSLog(@"Tabbed to the next or previous key view.");
- [view->fKitWindow makeFirstResponder:tentativeNewKeyView];
- viewWeMadeFirstResponder = tentativeNewKeyView;
- }
- else
- {
- // The user has tabbed past the subviews of this control view. The window is the first responder now.
- //NSLog(@"Tabbed past the first or last key view.");
- [view->fKitWindow makeFirstResponder:view->fKitWindow];
- viewWeMadeFirstResponder = nil;
- }
- }
- else
- {
- // No view in this window has the keyboard focus. This view should
- // try to select one of its key subviews. We're not interested in
- // the subviews of sibling views here.
- //NSLog(@"No keyboard focus in window. Attempting to set...");
- NSView *tentativeNewKeyView;
- check(oldFirstResponder==fKitWindow);
- if ( [view->fWebView acceptsFirstResponder] )
- tentativeNewKeyView = view->fWebView;
- else
- tentativeNewKeyView = [view->fWebView nextValidKeyView];
- if ( tentativeNewKeyView && [tentativeNewKeyView isDescendantOf:view->fWebView] )
- {
- // This control view has at least one subview that can take the keyboard focus.
- if ( !forward )
- {
- // The user has tabbed into this control view backwards. Find
- // and select the last subview of this one that can take the
- // keyboard focus. Watch out for loops of valid key views.
- NSView *firstTentativeNewKeyView = tentativeNewKeyView;
- NSView *nextTentativeNewKeyView = [tentativeNewKeyView nextValidKeyView];
- while ( nextTentativeNewKeyView
- && [nextTentativeNewKeyView isDescendantOf:view->fWebView]
- && nextTentativeNewKeyView!=firstTentativeNewKeyView)
- {
- tentativeNewKeyView = nextTentativeNewKeyView;
- nextTentativeNewKeyView = [tentativeNewKeyView nextValidKeyView];
- }
- }
- // Set the keyboard focus.
- //NSLog(@"Tabbed into the first or last key view.");
- [view->fKitWindow makeFirstResponder:tentativeNewKeyView];
- viewWeMadeFirstResponder = tentativeNewKeyView;
- }
- else
- {
- // This control view has no subviews that can take the keyboard focus.
- //NSLog(@"Can't tab into this view.");
- viewWeMadeFirstResponder = nil;
- }
- }
- // Done.
- return viewWeMadeFirstResponder;
- }
- //----------------------------------------------------------------------------------
- // RelinquishFocus
- //----------------------------------------------------------------------------------
- //
- static void
- RelinquishFocus( HIWebView* view, bool inAutodisplay )
- {
- NSResponder* firstResponder;
- // Apparently Carbon thinks that some subview of this control view has the keyboard focus,
- // or we wouldn't be being asked to relinquish focus.
- firstResponder = [view->fKitWindow firstResponder];
- if ( [firstResponder isKindOfClass:[NSView class]] )
- {
- // Some subview of this control view really is the first responder right now.
- check( [(NSView *)firstResponder isDescendantOf:view->fWebView] );
- // Make the window the first responder, so that no view is the key view.
- [view->fKitWindow makeFirstResponder:view->fKitWindow];
- // If this control is not allowed to do autodisplay, don't let
- // it autodisplay any just-changed focus rings or text on the
- // next go around the event loop. I'm probably clearing more
- // dirty rects than I have to, but it doesn't seem to hurt in
- // the print panel accessory view case, and I don't have time
- // to figure out exactly what -[NSCell _setKeyboardFocusRingNeedsDisplay]
- // is doing when invoked indirectly from -makeFirstResponder up above. M.P. Notice - 12/4/00
- if ( !inAutodisplay )
- [[view->fWebView opaqueAncestor] _clearDirtyRectsForTree];
- }
- else
- {
- // The Cocoa first responder does not correspond to the Carbon
- // control that has the keyboard focus. This can happen when
- // you've closed a dialog by hitting return in an NSTextView
- // that's a subview of this one; Cocoa closed the window, and
- // now Carbon is telling this control to relinquish the focus
- // as it's being disposed. There's nothing to do.
- check(firstResponder==window);
- }
- }
- //----------------------------------------------------------------------------------
- // ActiveStateChanged
- //----------------------------------------------------------------------------------
- //
- static void
- ActiveStateChanged( HIWebView* view )
- {
- if ( [view->fWebView respondsToSelector:@selector(setEnabled)] )
- {
- [(NSControl*)view->fWebView setEnabled: IsControlEnabled( view->fViewRef )];
- HIViewSetNeedsDisplay( view->fViewRef, true );
- }
- }
- //----------------------------------------------------------------------------------
- // ProcessCommand
- //----------------------------------------------------------------------------------
- //
- static OSStatus
- ProcessCommand( HIWebView* inView, const HICommand* inCommand )
- {
- OSStatus result = eventNotHandledErr;
- NSResponder* resp;
-
- resp = [inView->fKitWindow firstResponder];
- if ( [resp isKindOfClass:[NSView class]] )
- {
- NSView* respView = (NSView*)resp;
- if ( respView == inView->fWebView
- || [respView isDescendantOf: inView->fWebView] )
- {
- switch ( inCommand->commandID )
- {
- case kHICommandCut:
- case kHICommandCopy:
- case kHICommandPaste:
- case kHICommandClear:
- case kHICommandSelectAll:
- {
- SEL selector = _NSSelectorForHICommand( inCommand );
- if ( [respView respondsToSelector:selector] )
- {
- [respView performSelector:selector withObject:nil];
- result = noErr;
- }
- }
- break;
- }
- }
- }
-
- return result;
- }
- //----------------------------------------------------------------------------------
- // UpdateCommandStatus
- //----------------------------------------------------------------------------------
- //
- static OSStatus
- UpdateCommandStatus( HIWebView* inView, const HICommand* inCommand )
- {
- OSStatus result = eventNotHandledErr;
- MenuItemProxy* proxy = NULL;
- NSResponder* resp;
-
- resp = [inView->fKitWindow firstResponder];
-
- if ( [resp isKindOfClass:[NSView class]] )
- {
- NSView* respView = (NSView*)resp;
- if ( respView == inView->fWebView
- || [respView isDescendantOf: inView->fWebView] )
- {
- if ( inCommand->attributes & kHICommandFromMenu )
- {
- SEL selector = _NSSelectorForHICommand( inCommand );
-
- if ( selector )
- {
- if ( [resp respondsToSelector: selector] )
- {
- proxy = [[MenuItemProxy alloc] initWithAction: selector];
-
- // Can't use -performSelector:withObject: here because the method we're calling returns BOOL, while
- // -performSelector:withObject:'s return value is assumed to be an id.
- if (wtfObjcMsgSend<BOOL>(resp, @selector(validateUserInterfaceItem:), proxy))
- EnableMenuItem( inCommand->menu.menuRef, inCommand->menu.menuItemIndex );
- else
- DisableMenuItem( inCommand->menu.menuRef, inCommand->menu.menuItemIndex );
-
- result = noErr;
- }
- }
- }
- }
- }
-
- if ( proxy )
- [proxy release];
- return result;
- }
- // Blatantly stolen from AppKit and cropped a bit
- //----------------------------------------------------------------------------------
- // _NSSelectorForHICommand
- //----------------------------------------------------------------------------------
- //
- static SEL
- _NSSelectorForHICommand( const HICommand* inCommand )
- {
- switch ( inCommand->commandID )
- {
- case kHICommandUndo: return @selector(undo:);
- case kHICommandRedo: return @selector(redo:);
- case kHICommandCut : return @selector(cut:);
- case kHICommandCopy : return @selector(copy:);
- case kHICommandPaste: return @selector(paste:);
- case kHICommandClear: return @selector(delete:);
- case kHICommandSelectAll: return @selector(selectAll:);
- default: return NULL;
- }
- return NULL;
- }
- //-----------------------------------------------------------------------------------
- // HIWebViewEventHandler
- //-----------------------------------------------------------------------------------
- // Our object's virtual event handler method. I'm not sure if we need this these days.
- // We used to do various things with it, but those days are long gone...
- //
- static OSStatus
- HIWebViewEventHandler(
- EventHandlerCallRef inCallRef,
- EventRef inEvent,
- void * inUserData )
- {
- OSStatus result = eventNotHandledErr;
- HIPoint where;
- OSType tag;
- void * ptr;
- Size size;
- UInt32 features;
- RgnHandle region = NULL;
- ControlPartCode part;
- HIWebView* view = (HIWebView*)inUserData;
- // [NSApp setWindowsNeedUpdate:YES] must be called before events so that ActivateTSMDocument is called to set an active document.
- // Without an active document, TSM will use a default document which uses a bottom-line input window which we don't want.
- [NSApp setWindowsNeedUpdate:YES];
-
- switch ( GetEventClass( inEvent ) )
- {
- case kEventClassHIObject:
- switch ( GetEventKind( inEvent ) )
- {
- case kEventHIObjectConstruct:
- {
- HIObjectRef object;
- result = GetEventParameter( inEvent, kEventParamHIObjectInstance,
- typeHIObjectRef, NULL, sizeof( HIObjectRef ), NULL, &object );
- require_noerr( result, MissingParameter );
-
- // on entry for our construct event, we're passed the
- // creation proc we registered with for this class.
- // we use it now to create the instance, and then we
- // replace the instance parameter data with said instance
- // as type void.
- view = HIWebViewConstructor( (HIViewRef)object );
- if ( view )
- {
- SetEventParameter( inEvent, kEventParamHIObjectInstance,
- typeVoidPtr, sizeof( void * ), &view );
- }
- }
- break;
-
- case kEventHIObjectDestruct:
- HIWebViewDestructor( view );
- // result is unimportant
- break;
- }
- break;
- case kEventClassKeyboard:
- {
- NSEvent* kitEvent = WKCreateNSEventWithCarbonEvent(inEvent);
- [view->fKitWindow sendSuperEvent:kitEvent];
- [kitEvent release];
- result = noErr;
- }
- break;
- case kEventClassMouse:
- switch ( GetEventKind( inEvent ) )
- {
- case kEventMouseUp:
- result = MouseUp( view, inEvent );
- break;
-
- case kEventMouseWheelMoved:
- result = MouseWheelMoved( view, inEvent );
- break;
- case kEventMouseMoved:
- result = MouseMoved( view, inEvent );
- break;
- case kEventMouseDragged:
- result = MouseDragged( view, inEvent );
- break;
- }
- break;
- case kEventClassCommand:
- {
- HICommand command;
-
- result = GetEventParameter( inEvent, kEventParamDirectObject, typeHICommand, NULL,
- sizeof( HICommand ), NULL, &command );
- require_noerr( result, MissingParameter );
-
- switch ( GetEventKind( inEvent ) )
- {
- case kEventCommandProcess:
- result = ProcessCommand( view, &command );
- break;
-
- case kEventCommandUpdateStatus:
- result = UpdateCommandStatus( view, &command );
- break;
- }
- }
- break;
- case kEventClassControl:
- switch ( GetEventKind( inEvent ) )
- {
- case kEventControlInitialize:
- features = GetBehaviors();
- SetEventParameter( inEvent, kEventParamControlFeatures, typeUInt32,
- sizeof( UInt32 ), &features );
- result = noErr;
- break;
-
- case kEventControlDraw:
- {
- CGContextRef context = NULL;
-
- GetEventParameter( inEvent, kEventParamRgnHandle, typeQDRgnHandle, NULL,
- sizeof( RgnHandle ), NULL, ®ion );
- GetEventParameter( inEvent, kEventParamCGContextRef, typeCGContextRef, NULL,
- sizeof( CGContextRef ), NULL, &context );
- Draw( view, region, context );
- result = noErr;
- }
- break;
-
- case kEventControlHitTest:
- GetEventParameter( inEvent, kEventParamMouseLocation, typeHIPoint, NULL,
- sizeof( HIPoint ), NULL, &where );
- part = HitTest( view, &where );
- SetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode, sizeof( ControlPartCode ), &part );
- result = noErr;
- break;
-
- case kEventControlGetPartRegion:
- GetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode, NULL,
- sizeof( ControlPartCode ), NULL, &part );
- GetEventParameter( inEvent, kEventParamControlRegion, typeQDRgnHandle, NULL,
- sizeof( RgnHandle ), NULL, ®ion );
- result = GetRegion( view, part, region );
- break;
-
- case kEventControlGetData:
- GetEventParameter(inEvent, kEventParamControlPart, typeControlPartCode, NULL, sizeof(ControlPartCode), NULL, &part);
- GetEventParameter(inEvent, kEventParamControlDataTag, typeEnumeration, NULL, sizeof(OSType), NULL, &tag);
- GetEventParameter(inEvent, kEventParamControlDataBuffer, typePtr, NULL, sizeof(Ptr), NULL, &ptr);
- GetEventParameter(inEvent, kEventParamControlDataBufferSize, typeByteCount, NULL, sizeof(Size), NULL, &size);
- if (tag == kControlKindTag) {
- Size outSize;
- result = noErr;
- if (ptr) {
- if (size != sizeof(ControlKind))
- result = errDataSizeMismatch;
- else
- (*(ControlKind *)ptr) = GetKind();
- }
- outSize = sizeof(ControlKind);
- SetEventParameter(inEvent, kEventParamControlDataBufferSize, typeByteCount, sizeof(Size), &outSize);
- }
- break;
-
- case kEventControlBoundsChanged:
- {
- HIRect prevRect, currRect;
- UInt32 attrs;
-
- GetEventParameter( inEvent, kEventParamAttributes, typeUInt32, NULL,
- sizeof( UInt32 ), NULL, &attrs );
- GetEventParameter( inEvent, kEventParamOriginalBounds, typeHIRect, NULL,
- sizeof( HIRect ), NULL, &prevRect );
- GetEventParameter( inEvent, kEventParamCurrentBounds, typeHIRect, NULL,
- sizeof( HIRect ), NULL, &currRect );
- BoundsChanged( view, attrs, &prevRect, &currRect );
- result = noErr;
- }
- break;
-
- case kEventControlActivate:
- ActiveStateChanged( view );
- result = noErr;
- break;
-
- case kEventControlDeactivate:
- ActiveStateChanged( view );
- result = noErr;
- break;
-
- case kEventControlOwningWindowChanged:
- {
- WindowRef fromWindow, toWindow;
-
- result = GetEventParameter( inEvent, kEventParamControlOriginalOwningWindow, typeWindowRef, NULL,
- sizeof( WindowRef ), NULL, &fromWindow );
- require_noerr( result, MissingParameter );
- result = GetEventParameter( inEvent, kEventParamControlCurrentOwningWindow, typeWindowRef, NULL,
- sizeof( WindowRef ), NULL, &toWindow );
- require_noerr( result, MissingParameter );
- OwningWindowChanged( view, fromWindow, toWindow );
-
- result = noErr;
- }
- break;
-
- case kEventControlClick:
- result = Click( view, inEvent );
- break;
-
- case kEventControlContextualMenuClick:
- result = ContextMenuClick( view, inEvent );
- break;
-
- case kEventControlSetFocusPart:
- {
- ControlPartCode desiredFocus;
- RgnHandle invalidRgn;
- Boolean focusEverything;
- ControlPartCode actualFocus;
-
- result = GetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode, NULL,
- sizeof( ControlPartCode ), NULL, &desiredFocus );
- require_noerr( result, MissingParameter );
-
- GetEventParameter( inEvent, kEventParamControlInvalRgn, typeQDRgnHandle, NULL,
- sizeof( RgnHandle ), NULL, &invalidRgn );
- focusEverything = false; // a good default in case the parameter doesn't exist
- GetEventParameter( inEvent, kEventParamControlFocusEverything, typeBoolean, NULL,
- sizeof( Boolean ), NULL, &focusEverything );
- result = SetFocusPart( view, desiredFocus, invalidRgn, focusEverything, &actualFocus );
-
- if ( result == noErr )
- verify_noerr( SetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode,
- sizeof( ControlPartCode ), &actualFocus ) );
- }
- break;
-
- // some other kind of Control event
- default:
- break;
- }
- break;
-
- // some other event class
- default:
- break;
- }
- MissingParameter:
- return result;
- }
- static void UpdateObserver(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info);
- static void
- StartUpdateObserver( HIWebView* view )
- {
- CFRunLoopObserverContext context;
- CFRunLoopObserverRef observer;
- CFRunLoopRef mainRunLoop;
-
- check( view->fIsComposited == false );
- check( view->fUpdateObserver == NULL );
- context.version = 0;
- context.info = view;
- context.retain = NULL;
- context.release = NULL;
- context.copyDescription = NULL;
- mainRunLoop = (CFRunLoopRef)GetCFRunLoopFromEventLoop( GetMainEventLoop() );
- observer = CFRunLoopObserverCreate( NULL, kCFRunLoopEntry | kCFRunLoopBeforeWaiting, true, 0, UpdateObserver, &context );
- CFRunLoopAddObserver( mainRunLoop, observer, kCFRunLoopCommonModes );
- view->fUpdateObserver = observer;
-
- // printf( "Update observer started\n" );
- }
- static void
- StopUpdateObserver( HIWebView* view )
- {
- check( view->fIsComposited == false );
- check( view->fUpdateObserver != NULL );
- CFRunLoopObserverInvalidate( view->fUpdateObserver );
- CFRelease( view->fUpdateObserver );
- view->fUpdateObserver = NULL;
- // printf( "Update observer removed\n" );
- }
- static void
- UpdateObserver( CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info )
- {
- HIWebView* view = (HIWebView*)info;
- RgnHandle region = NewRgn();
-
- // printf( "Update observer called\n" );
- if ( region )
- {
- GetWindowRegion( GetControlOwner( view->fViewRef ), kWindowUpdateRgn, region );
-
- if ( !EmptyRgn( region ) )
- {
- RgnHandle ourRgn = NewRgn();
- Rect rect;
-
- GetWindowBounds( GetControlOwner( view->fViewRef ), kWindowStructureRgn, &rect );
-
- // printf( "Update region is non-empty\n" );
-
- if ( ourRgn )
- {
- Rect rect;
- GrafPtr savePort, port;
- Point offset = { 0, 0 };
-
- port = GetWindowPort( GetControlOwner( view->fViewRef ) );
-
- GetPort( &savePort );
- SetPort( port );
-
- GlobalToLocal( &offset );
- OffsetRgn( region, offset.h, offset.v );
- GetControlBounds( view->fViewRef, &rect );
- RectRgn( ourRgn, &rect );
-
- // printf( "our control is at %d %d %d %d\n",
- // rect.top, rect.left, rect.bottom, rect.right );
-
- GetRegionBounds( region, &rect );
- // printf( "region is at %d %d %d %d\n",
- // rect.top, rect.left, rect.bottom, rect.right );
- SectRgn( ourRgn, region, ourRgn );
-
- GetRegionBounds( ourRgn, &rect );
- // printf( "intersection is %d %d %d %d\n",
- // rect.top, rect.left, rect.bottom, rect.right );
- if ( !EmptyRgn( ourRgn ) )
- {
- RgnHandle saveVis = NewRgn();
-
- // printf( "looks like we should draw\n" );
- if ( saveVis )
- {
- // RGBColor kRedColor = { 0xffff, 0, 0 };
-
- GetPortVisibleRegion( GetWindowPort( GetControlOwner( view->fViewRef ) ), saveVis );
- SetPortVisibleRegion( GetWindowPort( GetControlOwner( view->fViewRef ) ), ourRgn );
-
- // RGBForeColor( &kRedColor );
- // PaintRgn( ourRgn );
- // QDFlushPortBuffer( port, NULL );
- // Delay( 15, NULL );
- Draw1Control( view->fViewRef );
- ValidWindowRgn( GetControlOwner( view->fViewRef ), ourRgn );
-
- SetPortVisibleRegion( GetWindowPort( GetControlOwner( view->fViewRef ) ), saveVis );
- DisposeRgn( saveVis );
- }
- }
- SetPort( savePort );
-
- DisposeRgn( ourRgn );
- }
- }
-
- DisposeRgn( region );
- }
- }
- #endif
|