/*
 * Copyright (C) 2005, 2006, 2007 Apple 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.
 */

#if ENABLE(NETSCAPE_PLUGIN_API)

#import "WebNetscapePluginView.h"

#import "QuickDrawCompatibility.h"
#import "WebDataSourceInternal.h"
#import "WebDefaultUIDelegate.h"
#import "WebFrameInternal.h" 
#import "WebFrameView.h"
#import "WebKitErrorsPrivate.h"
#import "WebKitLogging.h"
#import "WebKitNSStringExtras.h"
#import "WebKitSystemInterface.h"
#import "WebNSDataExtras.h"
#import "WebNSDictionaryExtras.h"
#import "WebNSObjectExtras.h"
#import "WebNSURLExtras.h"
#import "WebNSURLRequestExtras.h"
#import "WebNSViewExtras.h"
#import "WebNetscapeContainerCheckContextInfo.h"
#import "WebNetscapeContainerCheckPrivate.h"
#import "WebNetscapePluginEventHandler.h"
#import "WebNetscapePluginPackage.h"
#import "WebNetscapePluginStream.h"
#import "WebPluginContainerCheck.h"
#import "WebPluginRequest.h"
#import "WebPreferences.h"
#import "WebUIDelegatePrivate.h"
#import "WebViewInternal.h"
#import <Carbon/Carbon.h>
#import <WebCore/CookieJar.h>
#import <WebCore/DocumentLoader.h>
#import <WebCore/Element.h>
#import <WebCore/Frame.h> 
#import <WebCore/FrameLoader.h> 
#import <WebCore/FrameTree.h>
#import <WebCore/FrameView.h>
#import <WebCore/HTMLPlugInElement.h>
#import <WebCore/Page.h> 
#import <WebCore/PluginMainThreadScheduler.h>
#import <WebCore/ProxyServer.h>
#import <WebCore/ScriptController.h>
#import <WebCore/SecurityOrigin.h>
#import <WebCore/SoftLinking.h> 
#import <WebCore/WebCoreObjCExtras.h>
#import <WebCore/WebCoreURLResponse.h>
#import <WebCore/npruntime_impl.h>
#import <WebKit/DOMPrivate.h>
#import <WebKit/WebUIDelegate.h>
#import <objc/objc-runtime.h>
#import <runtime/InitializeThreading.h>
#import <runtime/JSLock.h>
#import <wtf/Assertions.h>
#import <wtf/Threading.h>
#import <wtf/text/CString.h>

#define LoginWindowDidSwitchFromUserNotification    @"WebLoginWindowDidSwitchFromUserNotification"
#define LoginWindowDidSwitchToUserNotification      @"WebLoginWindowDidSwitchToUserNotification"
#define WKNVSupportsCompositingCoreAnimationPluginsBool 74656  /* TRUE if the browser supports hardware compositing of Core Animation plug-ins  */
static const int WKNVSilverlightFullscreenPerformanceIssueFixed = 7288546; /* TRUE if Siverlight addressed its underlying  bug in <rdar://problem/7288546> */

using namespace WebCore;
using namespace WebKit;
using namespace std;

static inline bool isDrawingModelQuickDraw(NPDrawingModel drawingModel)
{
#ifndef NP_NO_QUICKDRAW
    return drawingModel == NPDrawingModelQuickDraw;
#else
    return false;
#endif
};

@interface WebNetscapePluginView (Internal)
- (NPError)_createPlugin;
- (void)_destroyPlugin;
- (NSBitmapImageRep *)_printedPluginBitmap;
- (void)_redeliverStream;
- (BOOL)_shouldCancelSrcStream;
@end

static WebNetscapePluginView *currentPluginView = nil;

typedef struct OpaquePortState* PortState;

static const double ThrottledTimerInterval = 0.25;

class PluginTimer : public TimerBase {
public:
    typedef void (*TimerFunc)(NPP npp, uint32_t timerID);
    
    PluginTimer(NPP npp, uint32_t timerID, uint32_t interval, NPBool repeat, TimerFunc timerFunc)
        : m_npp(npp)
        , m_timerID(timerID)
        , m_interval(interval)
        , m_repeat(repeat)
        , m_timerFunc(timerFunc)
    {
    }
    
    void start(bool throttle)
    {
        ASSERT(!isActive());

        double timeInterval = m_interval / 1000.0;
        
        if (throttle)
            timeInterval = max(timeInterval, ThrottledTimerInterval);
        
        if (m_repeat)
            startRepeating(timeInterval);
        else
            startOneShot(timeInterval);
    }

private:
    virtual void fired() 
    {
        m_timerFunc(m_npp, m_timerID);
        if (!m_repeat)
            delete this;
    }
    
    NPP m_npp;
    uint32_t m_timerID;
    uint32_t m_interval;
    NPBool m_repeat;
    TimerFunc m_timerFunc;
};

#ifndef NP_NO_QUICKDRAW

// QuickDraw is not available in 64-bit

typedef struct {
    GrafPtr oldPort;
    GDHandle oldDevice;
    Point oldOrigin;
    RgnHandle oldClipRegion;
    RgnHandle oldVisibleRegion;
    RgnHandle clipRegion;
    BOOL forUpdate;
} PortState_QD;

#endif /* NP_NO_QUICKDRAW */

typedef struct {
    CGContextRef context;
} PortState_CG;

@class NSTextInputContext;
@interface NSResponder (AppKitDetails)
- (NSTextInputContext *)inputContext;
@end

@interface WebNetscapePluginView (ForwardDeclarations)
- (void)setWindowIfNecessary;
- (NPError)loadRequest:(NSMutableURLRequest *)request inTarget:(const char *)cTarget withNotifyData:(void *)notifyData sendNotification:(BOOL)sendNotification;
@end

@implementation WebNetscapePluginView

+ (void)initialize
{
    JSC::initializeThreading();
    WTF::initializeMainThreadToProcessMainThread();
#ifndef BUILDING_ON_TIGER
    WebCoreObjCFinalizeOnMainThread(self);
#endif
    WKSendUserChangeNotifications();
}

// MARK: EVENTS

// The WindowRef created by -[NSWindow windowRef] has a QuickDraw GrafPort that covers 
// the entire window frame (or structure region to use the Carbon term) rather then just the window content.
// We can remove this when <rdar://problem/4201099> is fixed.
- (void)fixWindowPort
{
#ifndef NP_NO_QUICKDRAW
    ASSERT(isDrawingModelQuickDraw(drawingModel));
    
    NSWindow *currentWindow = [self currentWindow];
    if ([currentWindow isKindOfClass:objc_getClass("NSCarbonWindow")])
        return;
    
    float windowHeight = [currentWindow frame].size.height;
    NSView *contentView = [currentWindow contentView];
    NSRect contentRect = [contentView convertRect:[contentView frame] toView:nil]; // convert to window-relative coordinates
    
    CGrafPtr oldPort;
    GetPort(&oldPort);    
    SetPort(GetWindowPort((WindowRef)[currentWindow windowRef]));
    
    MovePortTo(static_cast<short>(contentRect.origin.x), /* Flip Y */ static_cast<short>(windowHeight - NSMaxY(contentRect)));
    PortSize(static_cast<short>(contentRect.size.width), static_cast<short>(contentRect.size.height));
    
    SetPort(oldPort);
#endif
}

#ifndef NP_NO_QUICKDRAW
static UInt32 getQDPixelFormatForBitmapContext(CGContextRef context)
{
    UInt32 byteOrder = CGBitmapContextGetBitmapInfo(context) & kCGBitmapByteOrderMask;
    if (byteOrder == kCGBitmapByteOrderDefault)
        switch (CGBitmapContextGetBitsPerPixel(context)) {
            case 16:
                byteOrder = kCGBitmapByteOrder16Host;
                break;
            case 32:
                byteOrder = kCGBitmapByteOrder32Host;
                break;
        }
    switch (byteOrder) {
        case kCGBitmapByteOrder16Little:
            return k16LE555PixelFormat;
        case kCGBitmapByteOrder32Little:
            return k32BGRAPixelFormat;
        case kCGBitmapByteOrder16Big:
            return k16BE555PixelFormat;
        case kCGBitmapByteOrder32Big:
            return k32ARGBPixelFormat;
    }
    ASSERT_NOT_REACHED();
    return 0;
}

static inline void getNPRect(const CGRect& cgr, NPRect& npr)
{
    npr.top = static_cast<uint16_t>(cgr.origin.y);
    npr.left = static_cast<uint16_t>(cgr.origin.x);
    npr.bottom = static_cast<uint16_t>(CGRectGetMaxY(cgr));
    npr.right = static_cast<uint16_t>(CGRectGetMaxX(cgr));
}

#endif

static inline void getNPRect(const NSRect& nr, NPRect& npr)
{
    npr.top = static_cast<uint16_t>(nr.origin.y);
    npr.left = static_cast<uint16_t>(nr.origin.x);
    npr.bottom = static_cast<uint16_t>(NSMaxY(nr));
    npr.right = static_cast<uint16_t>(NSMaxX(nr));
}

- (PortState)saveAndSetNewPortStateForUpdate:(BOOL)forUpdate
{
    ASSERT([self currentWindow] != nil);
    
    // The base coordinates of a window and it's contentView happen to be the equal at a userSpaceScaleFactor
    // of 1. For non-1.0 scale factors this assumption is false.
    NSView *windowContentView = [[self window] contentView];
    NSRect boundsInWindow = [self convertRect:[self bounds] toView:windowContentView];
    NSRect visibleRectInWindow = [self actualVisibleRectInWindow];
    
    // Flip Y to convert -[NSWindow contentView] coordinates to top-left-based window coordinates.
    float borderViewHeight = [[self currentWindow] frame].size.height;
    boundsInWindow.origin.y = borderViewHeight - NSMaxY(boundsInWindow);
    visibleRectInWindow.origin.y = borderViewHeight - NSMaxY(visibleRectInWindow);
    
#ifndef NP_NO_QUICKDRAW
    WindowRef windowRef = (WindowRef)[[self currentWindow] windowRef];
    ASSERT(windowRef);

    // Look at the Carbon port to convert top-left-based window coordinates into top-left-based content coordinates.
    if (isDrawingModelQuickDraw(drawingModel)) {
        // If drawing with QuickDraw, fix the window port so that it has the same bounds as the NSWindow's
        // content view.  This makes it easier to convert between AppKit view and QuickDraw port coordinates.
        [self fixWindowPort];
        
        ::Rect portBounds;
        CGrafPtr port = GetWindowPort(windowRef);
        GetPortBounds(port, &portBounds);

        PixMap *pix = *GetPortPixMap(port);
        boundsInWindow.origin.x += pix->bounds.left - portBounds.left;
        boundsInWindow.origin.y += pix->bounds.top - portBounds.top;
        visibleRectInWindow.origin.x += pix->bounds.left - portBounds.left;
        visibleRectInWindow.origin.y += pix->bounds.top - portBounds.top;
    }
#endif
    
    window.type = NPWindowTypeWindow;
    window.x = (int32_t)boundsInWindow.origin.x; 
    window.y = (int32_t)boundsInWindow.origin.y;
    window.width = static_cast<uint32_t>(NSWidth(boundsInWindow));
    window.height = static_cast<uint32_t>(NSHeight(boundsInWindow));
    
    // "Clip-out" the plug-in when:
    // 1) it's not really in a window or off-screen or has no height or width.
    // 2) window.x is a "big negative number" which is how WebCore expresses off-screen widgets.
    // 3) the window is miniaturized or the app is hidden
    // 4) we're inside of viewWillMoveToWindow: with a nil window. In this case, superviews may already have nil 
    // superviews and nil windows and results from convertRect:toView: are incorrect.
    if (window.width <= 0 || window.height <= 0 || window.x < -100000 || [self shouldClipOutPlugin]) {

        // The following code tries to give plug-ins the same size they will eventually have.
        // The specifiedWidth and specifiedHeight variables are used to predict the size that
        // WebCore will eventually resize us to.

        // The QuickTime plug-in has problems if you give it a width or height of 0.
        // Since other plug-ins also might have the same sort of trouble, we make sure
        // to always give plug-ins a size other than 0,0.

        if (window.width <= 0)
            window.width = specifiedWidth > 0 ? specifiedWidth : 100;
        if (window.height <= 0)
            window.height = specifiedHeight > 0 ? specifiedHeight : 100;

        window.clipRect.bottom = window.clipRect.top;
        window.clipRect.left = window.clipRect.right;
        
        // Core Animation plug-ins need to be updated (with a 0,0,0,0 clipRect) when
        // moved to a background tab. We don't do this for Core Graphics plug-ins as
        // older versions of Flash have historical WebKit-specific code that isn't
        // compatible with this behavior.
        if (drawingModel == NPDrawingModelCoreAnimation)
            getNPRect(NSZeroRect, window.clipRect);
    } else {
        getNPRect(visibleRectInWindow, window.clipRect);
    }
    
    // Save the port state, set up the port for entry into the plugin
    PortState portState;
    switch (drawingModel) {
#ifndef NP_NO_QUICKDRAW
        case NPDrawingModelQuickDraw: {
            // Set up NS_Port.
            ::Rect portBounds;
            CGrafPtr port = GetWindowPort(windowRef);
            GetPortBounds(port, &portBounds);
            nPort.qdPort.port = port;
            nPort.qdPort.portx = (int32_t)-boundsInWindow.origin.x;
            nPort.qdPort.porty = (int32_t)-boundsInWindow.origin.y;
            window.window = &nPort;

            PortState_QD *qdPortState = (PortState_QD*)malloc(sizeof(PortState_QD));
            portState = (PortState)qdPortState;
            
            GetGWorld(&qdPortState->oldPort, &qdPortState->oldDevice);    

            qdPortState->oldOrigin.h = portBounds.left;
            qdPortState->oldOrigin.v = portBounds.top;

            qdPortState->oldClipRegion = NewRgn();
            GetPortClipRegion(port, qdPortState->oldClipRegion);
            
            qdPortState->oldVisibleRegion = NewRgn();
            GetPortVisibleRegion(port, qdPortState->oldVisibleRegion);
            
            RgnHandle clipRegion = NewRgn();
            qdPortState->clipRegion = clipRegion;

            CGContextRef currentContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
            if (currentContext && WKCGContextIsBitmapContext(currentContext)) {
                // We use WKCGContextIsBitmapContext here, because if we just called CGBitmapContextGetData
                // on any context, we'd log to the console every time. But even if WKCGContextIsBitmapContext
                // returns true, it still might not be a context we need to create a GWorld for; for example
                // transparency layers will return true, but return 0 for CGBitmapContextGetData.
                void* offscreenData = CGBitmapContextGetData(currentContext);
                if (offscreenData) {
                    // If the current context is an offscreen bitmap, then create a GWorld for it.
                    ::Rect offscreenBounds;
                    offscreenBounds.top = 0;
                    offscreenBounds.left = 0;
                    offscreenBounds.right = CGBitmapContextGetWidth(currentContext);
                    offscreenBounds.bottom = CGBitmapContextGetHeight(currentContext);
                    GWorldPtr newOffscreenGWorld;
                    QDErr err = NewGWorldFromPtr(&newOffscreenGWorld,
                        getQDPixelFormatForBitmapContext(currentContext), &offscreenBounds, 0, 0, 0,
                        static_cast<char*>(offscreenData), CGBitmapContextGetBytesPerRow(currentContext));
                    ASSERT(newOffscreenGWorld);
                    ASSERT(!err);
                    if (!err) {
                        if (offscreenGWorld)
                            DisposeGWorld(offscreenGWorld);
                        offscreenGWorld = newOffscreenGWorld;

                        SetGWorld(offscreenGWorld, NULL);

                        port = offscreenGWorld;

                        nPort.qdPort.port = port;
                        boundsInWindow = [self bounds];
                        
                        // Generate a QD origin based on the current affine transform for currentContext.
                        CGAffineTransform offscreenMatrix = CGContextGetCTM(currentContext);
                        CGPoint origin = {0,0};
                        CGPoint axisFlip = {1,1};
                        origin = CGPointApplyAffineTransform(origin, offscreenMatrix);
                        axisFlip = CGPointApplyAffineTransform(axisFlip, offscreenMatrix);
                        
                        // Quartz bitmaps have origins at the bottom left, but the axes may be inverted, so handle that.
                        origin.x = offscreenBounds.left - origin.x * (axisFlip.x - origin.x);
                        origin.y = offscreenBounds.bottom + origin.y * (axisFlip.y - origin.y);
                        
                        nPort.qdPort.portx = static_cast<int32_t>(-boundsInWindow.origin.x + origin.x);
                        nPort.qdPort.porty = static_cast<int32_t>(-boundsInWindow.origin.y - origin.y);
                        window.x = 0;
                        window.y = 0;
                        window.window = &nPort;

                        // Use the clip bounds from the context instead of the bounds we created
                        // from the window above.
                        getNPRect(CGRectOffset(CGContextGetClipBoundingBox(currentContext), -origin.x, origin.y), window.clipRect);
                    }
                }
            }

            MacSetRectRgn(clipRegion,
                window.clipRect.left + nPort.qdPort.portx, window.clipRect.top + nPort.qdPort.porty,
                window.clipRect.right + nPort.qdPort.portx, window.clipRect.bottom + nPort.qdPort.porty);
            
            // Clip to the dirty region if drawing to a window. When drawing to another bitmap context, do not clip.
            if ([NSGraphicsContext currentContext] == [[self currentWindow] graphicsContext]) {
                // Clip to dirty region so plug-in does not draw over already-drawn regions of the window that are
                // not going to be redrawn this update.  This forces plug-ins to play nice with z-index ordering.
                if (forUpdate) {
                    RgnHandle viewClipRegion = NewRgn();
                    
                    // Get list of dirty rects from the opaque ancestor -- WebKit does some tricks with invalidation and
                    // display to enable z-ordering for NSViews; a side-effect of this is that only the WebHTMLView
                    // knows about the true set of dirty rects.
                    NSView *opaqueAncestor = [self opaqueAncestor];
                    const NSRect *dirtyRects;
                    NSInteger dirtyRectCount, dirtyRectIndex;
                    [opaqueAncestor getRectsBeingDrawn:&dirtyRects count:&dirtyRectCount];

                    for (dirtyRectIndex = 0; dirtyRectIndex < dirtyRectCount; dirtyRectIndex++) {
                        NSRect dirtyRect = [self convertRect:dirtyRects[dirtyRectIndex] fromView:opaqueAncestor];
                        if (!NSEqualSizes(dirtyRect.size, NSZeroSize)) {
                            // Create a region for this dirty rect
                            RgnHandle dirtyRectRegion = NewRgn();
                            SetRectRgn(dirtyRectRegion, static_cast<short>(NSMinX(dirtyRect)), static_cast<short>(NSMinY(dirtyRect)), static_cast<short>(NSMaxX(dirtyRect)), static_cast<short>(NSMaxY(dirtyRect)));
                            
                            // Union this dirty rect with the rest of the dirty rects
                            UnionRgn(viewClipRegion, dirtyRectRegion, viewClipRegion);
                            DisposeRgn(dirtyRectRegion);
                        }
                    }
                
                    // Intersect the dirty region with the clip region, so that we only draw over dirty parts
                    SectRgn(clipRegion, viewClipRegion, clipRegion);
                    DisposeRgn(viewClipRegion);
                }
            }

            // Switch to the port and set it up.
            SetPort(port);
            PenNormal();
            ForeColor(blackColor);
            BackColor(whiteColor);
            SetOrigin(nPort.qdPort.portx, nPort.qdPort.porty);
            SetPortClipRegion(nPort.qdPort.port, clipRegion);

            if (forUpdate) {
                // AppKit may have tried to help us by doing a BeginUpdate.
                // But the invalid region at that level didn't include AppKit's notion of what was not valid.
                // We reset the port's visible region to counteract what BeginUpdate did.
                SetPortVisibleRegion(nPort.qdPort.port, clipRegion);
                InvalWindowRgn(windowRef, clipRegion);
            }
            
            qdPortState->forUpdate = forUpdate;
            break;
        }
#endif /* NP_NO_QUICKDRAW */

        case NPDrawingModelCoreGraphics: {            
            if (![self canDraw]) {
                portState = NULL;
                break;
            }
            
            ASSERT([NSView focusView] == self);

            CGContextRef context = static_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]);

            PortState_CG *cgPortState = (PortState_CG *)malloc(sizeof(PortState_CG));
            portState = (PortState)cgPortState;
            cgPortState->context = context;
            
#ifndef NP_NO_CARBON            
            if (eventModel != NPEventModelCocoa) {
                // Update the plugin's window/context
                nPort.cgPort.window = windowRef;
                nPort.cgPort.context = context;
                window.window = &nPort.cgPort;
            }                
#endif /* NP_NO_CARBON */

            // Save current graphics context's state; will be restored by -restorePortState:
            CGContextSaveGState(context);

            // Clip to the dirty region if drawing to a window. When drawing to another bitmap context, do not clip.
            if ([NSGraphicsContext currentContext] == [[self currentWindow] graphicsContext]) {
                // Get list of dirty rects from the opaque ancestor -- WebKit does some tricks with invalidation and
                // display to enable z-ordering for NSViews; a side-effect of this is that only the WebHTMLView
                // knows about the true set of dirty rects.
                NSView *opaqueAncestor = [self opaqueAncestor];
                const NSRect *dirtyRects;
                NSInteger count;
                [opaqueAncestor getRectsBeingDrawn:&dirtyRects count:&count];
                Vector<CGRect, 16> convertedDirtyRects;
                convertedDirtyRects.resize(count);
                for (int i = 0; i < count; ++i)
                    reinterpret_cast<NSRect&>(convertedDirtyRects[i]) = [self convertRect:dirtyRects[i] fromView:opaqueAncestor];
                CGContextClipToRects(context, convertedDirtyRects.data(), count);
            }

            break;
        }
          
        case NPDrawingModelCoreAnimation:
            // Just set the port state to a dummy value.
            portState = (PortState)1;
            break;
        
        default:
            ASSERT_NOT_REACHED();
            portState = NULL;
            break;
    }
    
    return portState;
}

- (PortState)saveAndSetNewPortState
{
    return [self saveAndSetNewPortStateForUpdate:NO];
}

- (void)restorePortState:(PortState)portState
{
    ASSERT([self currentWindow]);
    ASSERT(portState);
    
    switch (drawingModel) {
#ifndef NP_NO_QUICKDRAW
        case NPDrawingModelQuickDraw: {
            PortState_QD *qdPortState = (PortState_QD *)portState;
            WindowRef windowRef = (WindowRef)[[self currentWindow] windowRef];
            CGrafPtr port = GetWindowPort(windowRef);

            SetPort(port);

            if (qdPortState->forUpdate)
                ValidWindowRgn(windowRef, qdPortState->clipRegion);

            SetOrigin(qdPortState->oldOrigin.h, qdPortState->oldOrigin.v);

            SetPortClipRegion(port, qdPortState->oldClipRegion);
            if (qdPortState->forUpdate)
                SetPortVisibleRegion(port, qdPortState->oldVisibleRegion);

            DisposeRgn(qdPortState->oldClipRegion);
            DisposeRgn(qdPortState->oldVisibleRegion);
            DisposeRgn(qdPortState->clipRegion);

            SetGWorld(qdPortState->oldPort, qdPortState->oldDevice);
            break;
        }
#endif /* NP_NO_QUICKDRAW */
        
        case NPDrawingModelCoreGraphics: {
            ASSERT([NSView focusView] == self);
            
            CGContextRef context = ((PortState_CG *)portState)->context;
            ASSERT(!nPort.cgPort.context || (context == nPort.cgPort.context));
            CGContextRestoreGState(context);
            break;
        }
        
        case NPDrawingModelCoreAnimation:
            ASSERT(portState == (PortState)1);
            break;
        default:
            ASSERT_NOT_REACHED();
            break;
    }
}

- (BOOL)sendEvent:(void*)event isDrawRect:(BOOL)eventIsDrawRect
{
    if (![self window])
        return NO;
    ASSERT(event);
       
    if (!_isStarted)
        return NO;

    ASSERT([_pluginPackage.get() pluginFuncs]->event);
    
    // Make sure we don't call NPP_HandleEvent while we're inside NPP_SetWindow.
    // We probably don't want more general reentrancy protection; we are really
    // protecting only against this one case, which actually comes up when
    // you first install the SVG viewer plug-in.
    if (inSetWindow)
        return NO;

    Frame* frame = core([self webFrame]);
    if (!frame)
        return NO;
    Page* page = frame->page();
    if (!page)
        return NO;

    // Can only send drawRect (updateEvt) to CoreGraphics plugins when actually drawing
    ASSERT((drawingModel != NPDrawingModelCoreGraphics) || !eventIsDrawRect || [NSView focusView] == self);
    
    PortState portState = NULL;
    
    if (isDrawingModelQuickDraw(drawingModel) || (drawingModel != NPDrawingModelCoreAnimation && eventIsDrawRect)) {
        // In CoreGraphics mode, the port state only needs to be saved/set when redrawing the plug-in view.
        // The plug-in is not allowed to draw at any other time.
        portState = [self saveAndSetNewPortStateForUpdate:eventIsDrawRect];
        // We may have changed the window, so inform the plug-in.
        [self setWindowIfNecessary];
    }
    
#if !defined(NDEBUG) && !defined(NP_NO_QUICKDRAW)
    // Draw green to help debug.
    // If we see any green we know something's wrong.
    // Note that PaintRect() only works for QuickDraw plugins; otherwise the current QD port is undefined.
    if (isDrawingModelQuickDraw(drawingModel) && eventIsDrawRect) {
        ForeColor(greenColor);
        const ::Rect bigRect = { -10000, -10000, 10000, 10000 };
        PaintRect(&bigRect);
        ForeColor(blackColor);
    }
#endif
    
    // Temporarily retain self in case the plug-in view is released while sending an event. 
    [[self retain] autorelease];

    BOOL acceptedEvent;
    [self willCallPlugInFunction];
    // Set the pluginAllowPopup flag.
    ASSERT(_eventHandler);
    bool oldAllowPopups = frame->script()->allowPopupsFromPlugin();
    frame->script()->setAllowPopupsFromPlugin(_eventHandler->currentEventIsUserGesture());    
    {
        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
        acceptedEvent = [_pluginPackage.get() pluginFuncs]->event(plugin, event);
    }
    // Restore the old pluginAllowPopup flag.
    frame->script()->setAllowPopupsFromPlugin(oldAllowPopups);     
    [self didCallPlugInFunction];
        
    if (portState) {
        if ([self currentWindow])
            [self restorePortState:portState];
        if (portState != (PortState)1)
            free(portState);
    }

    return acceptedEvent;
}

- (void)windowFocusChanged:(BOOL)hasFocus
{
    _eventHandler->windowFocusChanged(hasFocus);
}

- (void)sendDrawRectEvent:(NSRect)rect
{
    ASSERT(_eventHandler);
    
    CGContextRef context = static_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]);
    _eventHandler->drawRect(context, rect);
}

- (void)stopTimers
{
    [super stopTimers];
    
    if (_eventHandler)
        _eventHandler->stopTimers();
    
    if (!timers)
        return;

    HashMap<uint32_t, PluginTimer*>::const_iterator end = timers->end();
    for (HashMap<uint32_t, PluginTimer*>::const_iterator it = timers->begin(); it != end; ++it) {
        PluginTimer* timer = it->second;
        timer->stop();
    }    
}

- (void)startTimers
{
    [super startTimers];
    
    // If the plugin is completely obscured (scrolled out of view, for example), then we will
    // send null events at a reduced rate.
    _eventHandler->startTimers(_isCompletelyObscured);
    
    if (!timers)
        return;
    
    HashMap<uint32_t, PluginTimer*>::const_iterator end = timers->end();
    for (HashMap<uint32_t, PluginTimer*>::const_iterator it = timers->begin(); it != end; ++it) {
        PluginTimer* timer = it->second;
        ASSERT(!timer->isActive());
        timer->start(_isCompletelyObscured);
    }    
}

- (void)focusChanged
{
    // We need to null check the event handler here because
    // the plug-in view can resign focus after it's been stopped
    // and the event handler has been deleted.
    if (_eventHandler)
        _eventHandler->focusChanged(_hasFocus);
}

- (void)mouseDown:(NSEvent *)theEvent
{
    if (!_isStarted)
        return;

    _eventHandler->mouseDown(theEvent);
}

- (void)mouseUp:(NSEvent *)theEvent
{
    if (!_isStarted)
        return;

    _eventHandler->mouseUp(theEvent);
}

- (void)handleMouseEntered:(NSEvent *)theEvent
{
    if (!_isStarted)
        return;

    // Set cursor to arrow. Plugins often handle cursor internally, but those that don't will just get this default one.
    [[NSCursor arrowCursor] set];

    _eventHandler->mouseEntered(theEvent);
}

- (void)handleMouseExited:(NSEvent *)theEvent
{
    if (!_isStarted)
        return;

    _eventHandler->mouseExited(theEvent);
    
    // Set cursor back to arrow cursor.  Because NSCursor doesn't know about changes that the plugin made, we could get confused about what we think the
    // current cursor is otherwise.  Therefore we have no choice but to unconditionally reset the cursor when the mouse exits the plugin.
    [[NSCursor arrowCursor] set];
}

- (void)handleMouseMoved:(NSEvent *)theEvent
{
    if (!_isStarted)
        return;

    _eventHandler->mouseMoved(theEvent);
}
    
- (void)mouseDragged:(NSEvent *)theEvent
{
    if (!_isStarted)
        return;

    _eventHandler->mouseDragged(theEvent);
}

- (void)scrollWheel:(NSEvent *)theEvent
{
    if (!_isStarted) {
        [super scrollWheel:theEvent];
        return;
    }

    if (!_eventHandler->scrollWheel(theEvent))
        [super scrollWheel:theEvent];
}

- (void)keyUp:(NSEvent *)theEvent
{
    if (!_isStarted)
        return;

    _eventHandler->keyUp(theEvent);
}

- (void)keyDown:(NSEvent *)theEvent
{
    if (!_isStarted)
        return;

    _eventHandler->keyDown(theEvent);
}

- (void)flagsChanged:(NSEvent *)theEvent
{
    if (!_isStarted)
        return;

    _eventHandler->flagsChanged(theEvent);
}

- (void)sendModifierEventWithKeyCode:(int)keyCode character:(char)character
{
    if (!_isStarted)
        return;
    
    _eventHandler->syntheticKeyDownWithCommandModifier(keyCode, character);
}

- (void)privateBrowsingModeDidChange
{
    if (!_isStarted)
        return;
    
    NPBool value = _isPrivateBrowsingEnabled;

    [self willCallPlugInFunction];
    {
        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
        if ([_pluginPackage.get() pluginFuncs]->setvalue)
            [_pluginPackage.get() pluginFuncs]->setvalue(plugin, NPNVprivateModeBool, &value);
    }
    [self didCallPlugInFunction];
}

// MARK: WEB_NETSCAPE_PLUGIN

- (BOOL)isNewWindowEqualToOldWindow
{
    if (window.x != lastSetWindow.x)
        return NO;
    if (window.y != lastSetWindow.y)
        return NO;
    if (window.width != lastSetWindow.width)
        return NO;
    if (window.height != lastSetWindow.height)
        return NO;
    if (window.clipRect.top != lastSetWindow.clipRect.top)
        return NO;
    if (window.clipRect.left != lastSetWindow.clipRect.left)
        return NO;
    if (window.clipRect.bottom  != lastSetWindow.clipRect.bottom)
        return NO;
    if (window.clipRect.right != lastSetWindow.clipRect.right)
        return NO;
    if (window.type != lastSetWindow.type)
        return NO;
    
    switch (drawingModel) {
#ifndef NP_NO_QUICKDRAW
        case NPDrawingModelQuickDraw:
            if (nPort.qdPort.portx != lastSetPort.qdPort.portx)
                return NO;
            if (nPort.qdPort.porty != lastSetPort.qdPort.porty)
                return NO;
            if (nPort.qdPort.port != lastSetPort.qdPort.port)
                return NO;
        break;
#endif /* NP_NO_QUICKDRAW */
            
        case NPDrawingModelCoreGraphics:
            if (nPort.cgPort.window != lastSetPort.cgPort.window)
                return NO;
            if (nPort.cgPort.context != lastSetPort.cgPort.context)
                return NO;
        break;
                    
        case NPDrawingModelCoreAnimation:
          if (window.window != lastSetWindow.window)
              return NO;
          break;
        default:
            ASSERT_NOT_REACHED();
        break;
    }
    
    return YES;
}

-(void)tellQuickTimeToChill
{
#ifndef NP_NO_QUICKDRAW
    ASSERT(isDrawingModelQuickDraw(drawingModel));
    
    // Make a call to the secret QuickDraw API that makes QuickTime calm down.
    WindowRef windowRef = (WindowRef)[[self window] windowRef];
    if (!windowRef) {
        return;
    }
    CGrafPtr port = GetWindowPort(windowRef);
    ::Rect bounds;
    GetPortBounds(port, &bounds);
    WKCallDrawingNotification(port, &bounds);
#endif /* NP_NO_QUICKDRAW */
}

- (void)updateAndSetWindow
{
    // A plug-in can only update if it's (1) already been started (2) isn't stopped
    // and (3) is able to draw on-screen. To meet condition (3) the plug-in must not
    // be hidden and be attached to a window. There are two exceptions to this rule:
    //
    // Exception 1: QuickDraw plug-ins must be manually told when to stop writing
    // bits to the window backing store, thus to do so requires a new call to
    // NPP_SetWindow() with an empty NPWindow struct.
    //
    // Exception 2: CoreGraphics plug-ins expect to have their drawable area updated
    // when they are moved to a background tab, via a NPP_SetWindow call. This is
    // accomplished by allowing -saveAndSetNewPortStateForUpdate to "clip-out" the window's
    // clipRect. Flash is curently an exception to this. See 6453738.
    //
    
    if (!_isStarted)
        return;
    
#ifdef NP_NO_QUICKDRAW
    if (![self canDraw])
        return;
#else
    if (drawingModel == NPDrawingModelQuickDraw)
        [self tellQuickTimeToChill];
    else if (drawingModel == NPDrawingModelCoreGraphics && ![self canDraw] && _isFlash) {
        // The Flash plug-in does not expect an NPP_SetWindow call from WebKit in this case.
        // See Exception 2 above.
        return;
    }
#endif // NP_NO_QUICKDRAW
    
    BOOL didLockFocus = [NSView focusView] != self && [self lockFocusIfCanDraw];

    PortState portState = [self saveAndSetNewPortState];
    if (portState) {
        [self setWindowIfNecessary];
        [self restorePortState:portState];
        if (portState != (PortState)1)
            free(portState);
    } else if (drawingModel == NPDrawingModelCoreGraphics)
        [self setWindowIfNecessary];        

    if (didLockFocus)
        [self unlockFocus];
}

- (void)setWindowIfNecessary
{
    if (!_isStarted) 
        return;
    
    if (![self isNewWindowEqualToOldWindow]) {        
        // Make sure we don't call NPP_HandleEvent while we're inside NPP_SetWindow.
        // We probably don't want more general reentrancy protection; we are really
        // protecting only against this one case, which actually comes up when
        // you first install the SVG viewer plug-in.
        NPError npErr;
        
        BOOL wasInSetWindow = inSetWindow;
        inSetWindow = YES;        
        [self willCallPlugInFunction];
        {
            JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
            npErr = [_pluginPackage.get() pluginFuncs]->setwindow(plugin, &window);
        }
        [self didCallPlugInFunction];
        inSetWindow = wasInSetWindow;

#ifndef NDEBUG
        switch (drawingModel) {
#ifndef NP_NO_QUICKDRAW
            case NPDrawingModelQuickDraw:
                LOG(Plugins, "NPP_SetWindow (QuickDraw): %d, port=0x%08x, window.x:%d window.y:%d window.width:%d window.height:%d",
                npErr, (int)nPort.qdPort.port, (int)window.x, (int)window.y, (int)window.width, (int)window.height);
            break;
#endif /* NP_NO_QUICKDRAW */
            
            case NPDrawingModelCoreGraphics:
                LOG(Plugins, "NPP_SetWindow (CoreGraphics): %d, window=%p, context=%p, window.x:%d window.y:%d window.width:%d window.height:%d window.clipRect size:%dx%d",
                npErr, nPort.cgPort.window, nPort.cgPort.context, (int)window.x, (int)window.y, (int)window.width, (int)window.height, 
                    window.clipRect.right - window.clipRect.left, window.clipRect.bottom - window.clipRect.top);
            break;

            case NPDrawingModelCoreAnimation:
                LOG(Plugins, "NPP_SetWindow (CoreAnimation): %d, window=%p window.x:%d window.y:%d window.width:%d window.height:%d",
                npErr, window.window, nPort.cgPort.context, (int)window.x, (int)window.y, (int)window.width, (int)window.height);
            break;

            default:
                ASSERT_NOT_REACHED();
            break;
        }
#endif /* !defined(NDEBUG) */
        
        lastSetWindow = window;
        lastSetPort = nPort;
    }
}

+ (void)setCurrentPluginView:(WebNetscapePluginView *)view
{
    currentPluginView = view;
}

+ (WebNetscapePluginView *)currentPluginView
{
    return currentPluginView;
}

- (BOOL)createPlugin
{
    // Open the plug-in package so it remains loaded while our plugin uses it
    [_pluginPackage.get() open];
    
    // Initialize drawingModel to an invalid value so that we can detect when the plugin does not specify a drawingModel
    drawingModel = (NPDrawingModel)-1;
    
    // Initialize eventModel to an invalid value so that we can detect when the plugin does not specify an event model.
    eventModel = (NPEventModel)-1;
    
    NPError npErr = [self _createPlugin];
    if (npErr != NPERR_NO_ERROR) {
        LOG_ERROR("NPP_New failed with error: %d", npErr);
        [self _destroyPlugin];
        [_pluginPackage.get() close];
        return NO;
    }
    
    if (drawingModel == (NPDrawingModel)-1) {
#ifndef NP_NO_QUICKDRAW
        // Default to QuickDraw if the plugin did not specify a drawing model.
        drawingModel = NPDrawingModelQuickDraw;
#else
        // QuickDraw is not available, so we can't default to it. Instead, default to CoreGraphics.
        drawingModel = NPDrawingModelCoreGraphics;
#endif
    }

    if (eventModel == (NPEventModel)-1) {
        // If the plug-in did not specify a drawing model we default to Carbon when it is available.
#ifndef NP_NO_CARBON
        eventModel = NPEventModelCarbon;
#else
        eventModel = NPEventModelCocoa;
#endif // NP_NO_CARBON
    }

#ifndef NP_NO_CARBON
    if (eventModel == NPEventModelCocoa && isDrawingModelQuickDraw(drawingModel)) {
        LOG(Plugins, "Plugin can't use use Cocoa event model with QuickDraw drawing model: %@", _pluginPackage.get());
        [self _destroyPlugin];
        [_pluginPackage.get() close];
        
        return NO;
    }        
#endif // NP_NO_CARBON
    
#ifndef BUILDING_ON_TIGER
    if (drawingModel == NPDrawingModelCoreAnimation) {
        void *value = 0;
        if ([_pluginPackage.get() pluginFuncs]->getvalue(plugin, NPPVpluginCoreAnimationLayer, &value) == NPERR_NO_ERROR && value) {

            // The plug-in gives us a retained layer.
            _pluginLayer.adoptNS((CALayer *)value);

            BOOL accleratedCompositingEnabled = false;
#if USE(ACCELERATED_COMPOSITING)
            accleratedCompositingEnabled = [[[self webView] preferences] acceleratedCompositingEnabled];
#endif
            if (accleratedCompositingEnabled) {
                // FIXME: This code can be shared between WebHostedNetscapePluginView and WebNetscapePluginView.
#ifndef BUILDING_ON_LEOPARD
                // Since this layer isn't going to be inserted into a view, we need to create another layer and flip its geometry
                // in order to get the coordinate system right.
                RetainPtr<CALayer> realPluginLayer(AdoptNS, _pluginLayer.releaseRef());
                
                _pluginLayer.adoptNS([[CALayer alloc] init]);
                _pluginLayer.get().bounds = realPluginLayer.get().bounds;
                _pluginLayer.get().geometryFlipped = YES;

                realPluginLayer.get().autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
                [_pluginLayer.get() addSublayer:realPluginLayer.get()];
#endif
                // Eagerly enter compositing mode, since we know we'll need it. This avoids firing setNeedsStyleRecalc()
                // for iframes that contain composited plugins at bad times. https://bugs.webkit.org/show_bug.cgi?id=39033
                core([self webFrame])->view()->enterCompositingMode();
                [self element]->setNeedsStyleRecalc(SyntheticStyleChange);
            } else
                [self setWantsLayer:YES];

            LOG(Plugins, "%@ is using Core Animation drawing model with layer %@", _pluginPackage.get(), _pluginLayer.get());
        }

        ASSERT(_pluginLayer);
    }
#endif
    
    // Create the event handler
    _eventHandler.set(WebNetscapePluginEventHandler::create(self));
        
    return YES;
}

#ifndef BUILDING_ON_TIGER
// FIXME: This method is an ideal candidate to move up to the base class
- (CALayer *)pluginLayer
{
    return _pluginLayer.get();
}

- (void)setLayer:(CALayer *)newLayer
{
    [super setLayer:newLayer];

    if (newLayer && _pluginLayer) {
        _pluginLayer.get().frame = [newLayer frame];
        _pluginLayer.get().autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
        [newLayer addSublayer:_pluginLayer.get()];
    }
}
#endif

- (void)loadStream
{
    if ([self _shouldCancelSrcStream])
        return;
    
    if (_loadManually) {
        [self _redeliverStream];
        return;
    }
    
    // If the OBJECT/EMBED tag has no SRC, the URL is passed to us as "".
    // Check for this and don't start a load in this case.
    if (_sourceURL && ![_sourceURL.get() _web_isEmpty]) {
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:_sourceURL.get()];
        [request _web_setHTTPReferrer:core([self webFrame])->loader()->outgoingReferrer()];
        [self loadRequest:request inTarget:nil withNotifyData:nil sendNotification:NO];
    } 
}

- (BOOL)shouldStop
{
    // If we're already calling a plug-in function, do not call NPP_Destroy().  The plug-in function we are calling
    // may assume that its instance->pdata, or other memory freed by NPP_Destroy(), is valid and unchanged until said
    // plugin-function returns.
    // See <rdar://problem/4480737>.
    if (pluginFunctionCallDepth > 0) {
        shouldStopSoon = YES;
        return NO;
    }

    return YES;
}

- (void)destroyPlugin
{
    // To stop active streams it's necessary to invoke stop() on a copy 
    // of streams. This is because calling WebNetscapePluginStream::stop() also has the side effect
    // of removing a stream from this hash set.
    Vector<RefPtr<WebNetscapePluginStream> > streamsCopy;
    copyToVector(streams, streamsCopy);
    for (size_t i = 0; i < streamsCopy.size(); i++)
        streamsCopy[i]->stop();
    
    [[_pendingFrameLoads.get() allKeys] makeObjectsPerformSelector:@selector(_setInternalLoadDelegate:) withObject:nil];
    [NSObject cancelPreviousPerformRequestsWithTarget:self];

    // Setting the window type to 0 ensures that NPP_SetWindow will be called if the plug-in is restarted.
    lastSetWindow.type = (NPWindowType)0;
    
#ifndef BUILDING_ON_TIGER
    _pluginLayer = 0;
#endif
    
    [self _destroyPlugin];
    [_pluginPackage.get() close];
    
    _eventHandler.clear();
}

- (NPEventModel)eventModel
{
    return eventModel;
}

- (NPP)plugin
{
    return plugin;
}

- (void)setAttributeKeys:(NSArray *)keys andValues:(NSArray *)values
{
    ASSERT([keys count] == [values count]);
    
    // Convert the attributes to 2 C string arrays.
    // These arrays are passed to NPP_New, but the strings need to be
    // modifiable and live the entire life of the plugin.

    // The Java plug-in requires the first argument to be the base URL
    if ([_MIMEType.get() isEqualToString:@"application/x-java-applet"]) {
        cAttributes = (char **)malloc(([keys count] + 1) * sizeof(char *));
        cValues = (char **)malloc(([values count] + 1) * sizeof(char *));
        cAttributes[0] = strdup("DOCBASE");
        cValues[0] = strdup([_baseURL.get() _web_URLCString]);
        argsCount++;
    } else {
        cAttributes = (char **)malloc([keys count] * sizeof(char *));
        cValues = (char **)malloc([values count] * sizeof(char *));
    }

    BOOL isWMP = [_pluginPackage.get() bundleIdentifier] == "com.microsoft.WMP.defaultplugin";
    
    unsigned i;
    unsigned count = [keys count];
    for (i = 0; i < count; i++) {
        NSString *key = [keys objectAtIndex:i];
        NSString *value = [values objectAtIndex:i];
        if ([key _webkit_isCaseInsensitiveEqualToString:@"height"]) {
            specifiedHeight = [value intValue];
        } else if ([key _webkit_isCaseInsensitiveEqualToString:@"width"]) {
            specifiedWidth = [value intValue];
        }
        // Avoid Window Media Player crash when these attributes are present.
        if (isWMP && ([key _webkit_isCaseInsensitiveEqualToString:@"SAMIStyle"] || [key _webkit_isCaseInsensitiveEqualToString:@"SAMILang"])) {
            continue;
        }
        cAttributes[argsCount] = strdup([key UTF8String]);
        cValues[argsCount] = strdup([value UTF8String]);
        LOG(Plugins, "%@ = %@", key, value);
        argsCount++;
    }
}

- (uint32_t)checkIfAllowedToLoadURL:(const char*)urlCString frame:(const char*)frameNameCString 
                       callbackFunc:(void (*)(NPP npp, uint32_t checkID, NPBool allowed, void* context))callbackFunc 
                            context:(void*)context
{
    if (!_containerChecksInProgress) 
        _containerChecksInProgress = [[NSMutableDictionary alloc] init];
    
    NSString *frameName = frameNameCString ? [NSString stringWithCString:frameNameCString encoding:NSISOLatin1StringEncoding] : nil;
    
    ++_currentContainerCheckRequestID;
    WebNetscapeContainerCheckContextInfo *contextInfo = [[WebNetscapeContainerCheckContextInfo alloc] initWithCheckRequestID:_currentContainerCheckRequestID 
                                                                                                                callbackFunc:callbackFunc
                                                                                                                      context:context];
    
    WebPluginContainerCheck *check = [WebPluginContainerCheck checkWithRequest:[self requestWithURLCString:urlCString]
                                                                        target:frameName
                                                                  resultObject:self
                                                                      selector:@selector(_containerCheckResult:contextInfo:)
                                                                    controller:self 
                                                                   contextInfo:contextInfo];
    
    [contextInfo release];
    [_containerChecksInProgress setObject:check forKey:[NSNumber numberWithInt:_currentContainerCheckRequestID]];
    [check start];
    
    return _currentContainerCheckRequestID;
}

- (void)_containerCheckResult:(PolicyAction)policy contextInfo:(id)contextInfo
{
    ASSERT([contextInfo isKindOfClass:[WebNetscapeContainerCheckContextInfo class]]);
    void (*pluginCallback)(NPP npp, uint32_t, NPBool, void*) = [contextInfo callback];
    
    if (!pluginCallback) {
        ASSERT_NOT_REACHED();
        return;
    }
    
    pluginCallback([self plugin], [contextInfo checkRequestID], (policy == PolicyUse), [contextInfo context]);
}

- (void)cancelCheckIfAllowedToLoadURL:(uint32_t)checkID
{
    WebPluginContainerCheck *check = (WebPluginContainerCheck *)[_containerChecksInProgress objectForKey:[NSNumber numberWithInt:checkID]];
    
    if (!check)
        return;
    
    [check cancel];
    [_containerChecksInProgress removeObjectForKey:[NSNumber numberWithInt:checkID]];
}

// WebPluginContainerCheck automatically calls this method after invoking our _containerCheckResult: selector.
// It works this way because calling -[WebPluginContainerCheck cancel] allows it to do it's teardown process.
- (void)_webPluginContainerCancelCheckIfAllowedToLoadRequest:(id)webPluginContainerCheck
{
    ASSERT([webPluginContainerCheck isKindOfClass:[WebPluginContainerCheck class]]);
    WebPluginContainerCheck *check = (WebPluginContainerCheck *)webPluginContainerCheck;
    ASSERT([[check contextInfo] isKindOfClass:[WebNetscapeContainerCheckContextInfo class]]);
    
    [self cancelCheckIfAllowedToLoadURL:[[check contextInfo] checkRequestID]];
}

#ifdef BUILDING_ON_TIGER
// The Tiger compiler requires these two methods be present. Otherwise it doesn't think WebNetscapePluginView
// conforms to the WebPluginContainerCheckController protocol.
- (WebView *)webView
{
    return [super webView];   
}

- (WebFrame *)webFrame
{
    return [super webFrame];   
}
#endif

// MARK: NSVIEW

- (id)initWithFrame:(NSRect)frame
      pluginPackage:(WebNetscapePluginPackage *)pluginPackage
                URL:(NSURL *)URL
            baseURL:(NSURL *)baseURL
           MIMEType:(NSString *)MIME
      attributeKeys:(NSArray *)keys
    attributeValues:(NSArray *)values
       loadManually:(BOOL)loadManually
            element:(PassRefPtr<WebCore::HTMLPlugInElement>)element
{
    self = [super initWithFrame:frame pluginPackage:pluginPackage URL:URL baseURL:baseURL MIMEType:MIME attributeKeys:keys attributeValues:values loadManually:loadManually element:element];
    if (!self)
        return nil;
 
    _pendingFrameLoads.adoptNS([[NSMutableDictionary alloc] init]);
    
    // load the plug-in if it is not already loaded
    if (![pluginPackage load]) {
        [self release];
        return nil;
    }

    return self;
}

- (id)initWithFrame:(NSRect)frame
{
    ASSERT_NOT_REACHED();
    return nil;
}

- (void)fini
{
#ifndef NP_NO_QUICKDRAW
    if (offscreenGWorld)
        DisposeGWorld(offscreenGWorld);
#endif

    for (unsigned i = 0; i < argsCount; i++) {
        free(cAttributes[i]);
        free(cValues[i]);
    }
    free(cAttributes);
    free(cValues);
    
    ASSERT(!_eventHandler);
    
    if (timers) {
        deleteAllValues(*timers);
        delete timers;
    }  
    
    [_containerChecksInProgress release];
}

- (void)disconnectStream:(WebNetscapePluginStream*)stream
{
    streams.remove(stream);
}

- (void)dealloc
{
    ASSERT(!_isStarted);
    ASSERT(!plugin);

    [self fini];

    [super dealloc];
}

- (void)finalize
{
    ASSERT_MAIN_THREAD();
    ASSERT(!_isStarted);

    [self fini];

    [super finalize];
}

- (void)drawRect:(NSRect)rect
{
    if (_cachedSnapshot) {
        NSRect sourceRect = { NSZeroPoint, [_cachedSnapshot.get() size] };
        [_cachedSnapshot.get() drawInRect:[self bounds] fromRect:sourceRect operation:NSCompositeSourceOver fraction:1];
        return;
    }
    
    if (drawingModel == NPDrawingModelCoreAnimation && (!_snapshotting || ![self supportsSnapshotting]))
        return;

    if (!_isStarted)
        return;
    
    if ([NSGraphicsContext currentContextDrawingToScreen] || _isFlash)
        [self sendDrawRectEvent:rect];
    else {
        NSBitmapImageRep *printedPluginBitmap = [self _printedPluginBitmap];
        if (printedPluginBitmap) {
            // Flip the bitmap before drawing because the QuickDraw port is flipped relative
            // to this view.
            CGContextRef cgContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
            CGContextSaveGState(cgContext);
            NSRect bounds = [self bounds];
            CGContextTranslateCTM(cgContext, 0.0f, NSHeight(bounds));
            CGContextScaleCTM(cgContext, 1.0f, -1.0f);
            [printedPluginBitmap drawInRect:bounds];
            CGContextRestoreGState(cgContext);
        }
    }
}

- (NPObject *)createPluginScriptableObject
{
    if (![_pluginPackage.get() pluginFuncs]->getvalue || !_isStarted)
        return NULL;
        
    NPObject *value = NULL;
    NPError error;
    [self willCallPlugInFunction];
    {
        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
        error = [_pluginPackage.get() pluginFuncs]->getvalue(plugin, NPPVpluginScriptableNPObject, &value);
    }
    [self didCallPlugInFunction];
    if (error != NPERR_NO_ERROR)
        return NULL;
    
    return value;
}

- (void)willCallPlugInFunction
{
    ASSERT(plugin);

    // Could try to prevent infinite recursion here, but it's probably not worth the effort.
    pluginFunctionCallDepth++;
}

- (void)didCallPlugInFunction
{
    ASSERT(pluginFunctionCallDepth > 0);
    pluginFunctionCallDepth--;
    
    // If -stop was called while we were calling into a plug-in function, and we're no longer
    // inside a plug-in function, stop now.
    if (pluginFunctionCallDepth == 0 && shouldStopSoon) {
        shouldStopSoon = NO;
        [self stop];
    }
}

-(void)pluginView:(NSView *)pluginView receivedResponse:(NSURLResponse *)response
{
    ASSERT(_loadManually);
    ASSERT(!_manualStream);

    _manualStream = WebNetscapePluginStream::create(core([self webFrame])->loader());
}

- (void)pluginView:(NSView *)pluginView receivedData:(NSData *)data
{
    ASSERT(_loadManually);
    ASSERT(_manualStream);
    
    _dataLengthReceived += [data length];
    
    if (!_isStarted)
        return;

    if (!_manualStream->plugin()) {
        // Check if the load should be cancelled
        if ([self _shouldCancelSrcStream]) {
            NSURLResponse *response = [[self dataSource] response];
            
            NSError *error = [[NSError alloc] _initWithPluginErrorCode:WebKitErrorPlugInWillHandleLoad
                                                            contentURL:[response URL]
                                                         pluginPageURL:nil
                                                            pluginName:nil // FIXME: Get this from somewhere
                                                              MIMEType:[response MIMEType]];
            [[self dataSource] _documentLoader]->cancelMainResourceLoad(error);
            [error release];
            return;
        }
        
        _manualStream->setRequestURL([[[self dataSource] request] URL]);
        _manualStream->setPlugin([self plugin]);
        ASSERT(_manualStream->plugin());
        
        _manualStream->startStreamWithResponse([[self dataSource] response]);
    }

    if (_manualStream->plugin())
        _manualStream->didReceiveData(0, static_cast<const char *>([data bytes]), [data length]);
}

- (void)pluginView:(NSView *)pluginView receivedError:(NSError *)error
{
    ASSERT(_loadManually);

    _error = error;
    
    if (!_isStarted) {
        return;
    }

    _manualStream->destroyStreamWithError(error);
}

- (void)pluginViewFinishedLoading:(NSView *)pluginView 
{
    ASSERT(_loadManually);
    ASSERT(_manualStream);
    
    if (_isStarted)
        _manualStream->didFinishLoading(0);
}

- (NSTextInputContext *)inputContext
{
    return nil;
}

@end

@implementation WebNetscapePluginView (WebNPPCallbacks)

- (void)evaluateJavaScriptPluginRequest:(WebPluginRequest *)JSPluginRequest
{
    // FIXME: Is this isStarted check needed here? evaluateJavaScriptPluginRequest should not be called
    // if we are stopped since this method is called after a delay and we call 
    // cancelPreviousPerformRequestsWithTarget inside of stop.
    if (!_isStarted) {
        return;
    }
    
    NSURL *URL = [[JSPluginRequest request] URL];
    NSString *JSString = [URL _webkit_scriptIfJavaScriptURL];
    ASSERT(JSString);
    
    NSString *result = [[self webFrame] _stringByEvaluatingJavaScriptFromString:JSString forceUserGesture:[JSPluginRequest isCurrentEventUserGesture]];
    
    // Don't continue if stringByEvaluatingJavaScriptFromString caused the plug-in to stop.
    if (!_isStarted) {
        return;
    }
        
    if ([JSPluginRequest frameName] != nil) {
        // FIXME: If the result is a string, we probably want to put that string into the frame.
        if ([JSPluginRequest sendNotification]) {
            [self willCallPlugInFunction];
            {
                JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
                [_pluginPackage.get() pluginFuncs]->urlnotify(plugin, [URL _web_URLCString], NPRES_DONE, [JSPluginRequest notifyData]);
            }
            [self didCallPlugInFunction];
        }
    } else if ([result length] > 0) {
        // Don't call NPP_NewStream and other stream methods if there is no JS result to deliver. This is what Mozilla does.
        NSData *JSData = [result dataUsingEncoding:NSUTF8StringEncoding];
        
        RefPtr<WebNetscapePluginStream> stream = WebNetscapePluginStream::create([NSURLRequest requestWithURL:URL], plugin, [JSPluginRequest sendNotification], [JSPluginRequest notifyData]);
        
        RetainPtr<NSURLResponse> response(AdoptNS, [[NSURLResponse alloc] initWithURL:URL 
                                                                             MIMEType:@"text/plain" 
                                                                expectedContentLength:[JSData length]
                                                                     textEncodingName:nil]);
        
        stream->startStreamWithResponse(response.get());
        stream->didReceiveData(0, static_cast<const char*>([JSData bytes]), [JSData length]);
        stream->didFinishLoading(0);
    }
}

- (void)webFrame:(WebFrame *)webFrame didFinishLoadWithReason:(NPReason)reason
{
    ASSERT(_isStarted);
    
    WebPluginRequest *pluginRequest = [_pendingFrameLoads.get() objectForKey:webFrame];
    ASSERT(pluginRequest != nil);
    ASSERT([pluginRequest sendNotification]);
        
    [self willCallPlugInFunction];
    {
        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
        [_pluginPackage.get() pluginFuncs]->urlnotify(plugin, [[[pluginRequest request] URL] _web_URLCString], reason, [pluginRequest notifyData]);
    }
    [self didCallPlugInFunction];
    
    [_pendingFrameLoads.get() removeObjectForKey:webFrame];
    [webFrame _setInternalLoadDelegate:nil];
}

- (void)webFrame:(WebFrame *)webFrame didFinishLoadWithError:(NSError *)error
{
    NPReason reason = NPRES_DONE;
    if (error != nil)
        reason = WebNetscapePluginStream::reasonForError(error);
    [self webFrame:webFrame didFinishLoadWithReason:reason];
}

- (void)loadPluginRequest:(WebPluginRequest *)pluginRequest
{
    NSURLRequest *request = [pluginRequest request];
    NSString *frameName = [pluginRequest frameName];
    WebFrame *frame = nil;
    
    NSURL *URL = [request URL];
    NSString *JSString = [URL _webkit_scriptIfJavaScriptURL];
    
    ASSERT(frameName || JSString);
    
    if (frameName) {
        // FIXME - need to get rid of this window creation which
        // bypasses normal targeted link handling
        frame = kit(core([self webFrame])->loader()->findFrameForNavigation(frameName));
        if (frame == nil) {
            WebView *currentWebView = [self webView];
            NSDictionary *features = [[NSDictionary alloc] init];
            WebView *newWebView = [[currentWebView _UIDelegateForwarder] webView:currentWebView
                                                        createWebViewWithRequest:nil
                                                                  windowFeatures:features];
            [features release];

            if (!newWebView) {
                if ([pluginRequest sendNotification]) {
                    [self willCallPlugInFunction];
                    {
                        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
                        [_pluginPackage.get() pluginFuncs]->urlnotify(plugin, [[[pluginRequest request] URL] _web_URLCString], NPERR_GENERIC_ERROR, [pluginRequest notifyData]);
                    }
                    [self didCallPlugInFunction];
                }
                return;
            }
            
            frame = [newWebView mainFrame];
            core(frame)->tree()->setName(frameName);
            [[newWebView _UIDelegateForwarder] webViewShow:newWebView];
        }
    }

    if (JSString) {
        ASSERT(frame == nil || [self webFrame] == frame);
        [self evaluateJavaScriptPluginRequest:pluginRequest];
    } else {
        [frame loadRequest:request];
        if ([pluginRequest sendNotification]) {
            // Check if another plug-in view or even this view is waiting for the frame to load.
            // If it is, tell it that the load was cancelled because it will be anyway.
            WebNetscapePluginView *view = [frame _internalLoadDelegate];
            if (view != nil) {
                ASSERT([view isKindOfClass:[WebNetscapePluginView class]]);
                [view webFrame:frame didFinishLoadWithReason:NPRES_USER_BREAK];
            }
            [_pendingFrameLoads.get() _webkit_setObject:pluginRequest forUncopiedKey:frame];
            [frame _setInternalLoadDelegate:self];
        }
    }
}

- (NPError)loadRequest:(NSMutableURLRequest *)request inTarget:(const char *)cTarget withNotifyData:(void *)notifyData sendNotification:(BOOL)sendNotification
{
    NSURL *URL = [request URL];

    if (!URL) 
        return NPERR_INVALID_URL;

    // Don't allow requests to be loaded when the document loader is stopping all loaders.
    if ([[self dataSource] _documentLoader]->isStopping())
        return NPERR_GENERIC_ERROR;
    
    NSString *target = nil;
    if (cTarget) {
        // Find the frame given the target string.
        target = [NSString stringWithCString:cTarget encoding:NSISOLatin1StringEncoding];
    }
    WebFrame *frame = [self webFrame];

    // don't let a plugin start any loads if it is no longer part of a document that is being 
    // displayed unless the loads are in the same frame as the plugin.
    if ([[self dataSource] _documentLoader] != core([self webFrame])->loader()->activeDocumentLoader() &&
        (!cTarget || [frame findFrameNamed:target] != frame)) {
        return NPERR_GENERIC_ERROR; 
    }
    
    NSString *JSString = [URL _webkit_scriptIfJavaScriptURL];
    if (JSString != nil) {
        if (![[[self webView] preferences] isJavaScriptEnabled]) {
            // Return NPERR_GENERIC_ERROR if JS is disabled. This is what Mozilla does.
            return NPERR_GENERIC_ERROR;
        } else if (cTarget == NULL && _mode == NP_FULL) {
            // Don't allow a JavaScript request from a standalone plug-in that is self-targetted
            // because this can cause the user to be redirected to a blank page (3424039).
            return NPERR_INVALID_PARAM;
        }
    } else {
        if (!core([self webFrame])->document()->securityOrigin()->canDisplay(URL))
            return NPERR_GENERIC_ERROR;
    }
        
    if (cTarget || JSString) {
        // Make when targetting a frame or evaluating a JS string, perform the request after a delay because we don't
        // want to potentially kill the plug-in inside of its URL request.
        
        if (JSString && target && [frame findFrameNamed:target] != frame) {
            // For security reasons, only allow JS requests to be made on the frame that contains the plug-in.
            return NPERR_INVALID_PARAM;
        }
        
        bool currentEventIsUserGesture = false;
        if (_eventHandler)
            currentEventIsUserGesture = _eventHandler->currentEventIsUserGesture();
        
        WebPluginRequest *pluginRequest = [[WebPluginRequest alloc] initWithRequest:request 
                                                                          frameName:target
                                                                         notifyData:notifyData 
                                                                   sendNotification:sendNotification
                                                            didStartFromUserGesture:currentEventIsUserGesture];
        [self performSelector:@selector(loadPluginRequest:) withObject:pluginRequest afterDelay:0];
        [pluginRequest release];
    } else {
        RefPtr<WebNetscapePluginStream> stream = WebNetscapePluginStream::create(request, plugin, sendNotification, notifyData);

        streams.add(stream.get());
        stream->start();
    }
    
    return NPERR_NO_ERROR;
}

-(NPError)getURLNotify:(const char *)URLCString target:(const char *)cTarget notifyData:(void *)notifyData
{
    LOG(Plugins, "NPN_GetURLNotify: %s target: %s", URLCString, cTarget);

    NSMutableURLRequest *request = [self requestWithURLCString:URLCString];
    return [self loadRequest:request inTarget:cTarget withNotifyData:notifyData sendNotification:YES];
}

-(NPError)getURL:(const char *)URLCString target:(const char *)cTarget
{
    LOG(Plugins, "NPN_GetURL: %s target: %s", URLCString, cTarget);

    NSMutableURLRequest *request = [self requestWithURLCString:URLCString];
    return [self loadRequest:request inTarget:cTarget withNotifyData:NULL sendNotification:NO];
}

- (NPError)_postURL:(const char *)URLCString
             target:(const char *)target
                len:(UInt32)len
                buf:(const char *)buf
               file:(NPBool)file
         notifyData:(void *)notifyData
   sendNotification:(BOOL)sendNotification
       allowHeaders:(BOOL)allowHeaders
{
    if (!URLCString || !len || !buf) {
        return NPERR_INVALID_PARAM;
    }
    
    NSData *postData = nil;

    if (file) {
        // If we're posting a file, buf is either a file URL or a path to the file.
        NSString *bufString = (NSString *)CFStringCreateWithCString(kCFAllocatorDefault, buf, kCFStringEncodingWindowsLatin1);
        if (!bufString) {
            return NPERR_INVALID_PARAM;
        }
        NSURL *fileURL = [NSURL _web_URLWithDataAsString:bufString];
        NSString *path;
        if ([fileURL isFileURL]) {
            path = [fileURL path];
        } else {
            path = bufString;
        }
        postData = [NSData dataWithContentsOfFile:[path _webkit_fixedCarbonPOSIXPath]];
        CFRelease(bufString);
        if (!postData) {
            return NPERR_FILE_NOT_FOUND;
        }
    } else {
        postData = [NSData dataWithBytes:buf length:len];
    }

    if ([postData length] == 0) {
        return NPERR_INVALID_PARAM;
    }

    NSMutableURLRequest *request = [self requestWithURLCString:URLCString];
    [request setHTTPMethod:@"POST"];
    
    if (allowHeaders) {
        if ([postData _web_startsWithBlankLine]) {
            postData = [postData subdataWithRange:NSMakeRange(1, [postData length] - 1)];
        } else {
            NSInteger location = [postData _web_locationAfterFirstBlankLine];
            if (location != NSNotFound) {
                // If the blank line is somewhere in the middle of postData, everything before is the header.
                NSData *headerData = [postData subdataWithRange:NSMakeRange(0, location)];
                NSMutableDictionary *header = [headerData _webkit_parseRFC822HeaderFields];
                unsigned dataLength = [postData length] - location;

                // Sometimes plugins like to set Content-Length themselves when they post,
                // but WebFoundation does not like that. So we will remove the header
                // and instead truncate the data to the requested length.
                NSString *contentLength = [header objectForKey:@"Content-Length"];

                if (contentLength != nil)
                    dataLength = min<unsigned>([contentLength intValue], dataLength);
                [header removeObjectForKey:@"Content-Length"];

                if ([header count] > 0) {
                    [request setAllHTTPHeaderFields:header];
                }
                // Everything after the blank line is the actual content of the POST.
                postData = [postData subdataWithRange:NSMakeRange(location, dataLength)];

            }
        }
        if ([postData length] == 0) {
            return NPERR_INVALID_PARAM;
        }
    }

    // Plug-ins expect to receive uncached data when doing a POST (3347134).
    [request setCachePolicy:NSURLRequestReloadIgnoringCacheData];
    [request setHTTPBody:postData];
    
    return [self loadRequest:request inTarget:target withNotifyData:notifyData sendNotification:sendNotification];
}

- (NPError)postURLNotify:(const char *)URLCString
                  target:(const char *)target
                     len:(UInt32)len
                     buf:(const char *)buf
                    file:(NPBool)file
              notifyData:(void *)notifyData
{
    LOG(Plugins, "NPN_PostURLNotify: %s", URLCString);
    return [self _postURL:URLCString target:target len:len buf:buf file:file notifyData:notifyData sendNotification:YES allowHeaders:YES];
}

-(NPError)postURL:(const char *)URLCString
           target:(const char *)target
              len:(UInt32)len
              buf:(const char *)buf
             file:(NPBool)file
{
    LOG(Plugins, "NPN_PostURL: %s", URLCString);        
    // As documented, only allow headers to be specified via NPP_PostURL when using a file.
    return [self _postURL:URLCString target:target len:len buf:buf file:file notifyData:NULL sendNotification:NO allowHeaders:file];
}

-(NPError)newStream:(NPMIMEType)type target:(const char *)target stream:(NPStream**)stream
{
    LOG(Plugins, "NPN_NewStream");
    return NPERR_GENERIC_ERROR;
}

-(NPError)write:(NPStream*)stream len:(SInt32)len buffer:(void *)buffer
{
    LOG(Plugins, "NPN_Write");
    return NPERR_GENERIC_ERROR;
}

-(NPError)destroyStream:(NPStream*)stream reason:(NPReason)reason
{
    LOG(Plugins, "NPN_DestroyStream");
    // This function does a sanity check to ensure that the NPStream provided actually
    // belongs to the plug-in that provided it, which fixes a crash in the DivX 
    // plug-in: <rdar://problem/5093862> | http://bugs.webkit.org/show_bug.cgi?id=13203
    if (!stream || WebNetscapePluginStream::ownerForStream(stream) != plugin) {
        LOG(Plugins, "Invalid NPStream passed to NPN_DestroyStream: %p", stream);
        return NPERR_INVALID_INSTANCE_ERROR;
    }
    
    WebNetscapePluginStream* browserStream = static_cast<WebNetscapePluginStream*>(stream->ndata);
    browserStream->cancelLoadAndDestroyStreamWithError(browserStream->errorForReason(reason));
    
    return NPERR_NO_ERROR;
}

- (const char *)userAgent
{
    NSString *userAgent = [[self webView] userAgentForURL:_baseURL.get()];
    
    if (_isSilverlight) {
        // Silverlight has a workaround for a leak in Safari 2. This workaround is 
        // applied when the user agent does not contain "Version/3" so we append it
        // at the end of the user agent.
        userAgent = [userAgent stringByAppendingString:@" Version/3.2.1"];
    }        
        
    return [userAgent UTF8String];
}

-(void)status:(const char *)message
{    
    CFStringRef status = CFStringCreateWithCString(NULL, message ? message : "", kCFStringEncodingUTF8);
    if (!status) {
        LOG_ERROR("NPN_Status: the message was not valid UTF-8");
        return;
    }
    
    LOG(Plugins, "NPN_Status: %@", status);
    WebView *wv = [self webView];
    [[wv _UIDelegateForwarder] webView:wv setStatusText:(NSString *)status];
    CFRelease(status);
}

-(void)invalidateRect:(NPRect *)invalidRect
{
    LOG(Plugins, "NPN_InvalidateRect");
    [self invalidatePluginContentRect:NSMakeRect(invalidRect->left, invalidRect->top,
        (float)invalidRect->right - invalidRect->left, (float)invalidRect->bottom - invalidRect->top)];
}

- (void)invalidateRegion:(NPRegion)invalidRegion
{
    LOG(Plugins, "NPN_InvalidateRegion");
    NSRect invalidRect = NSZeroRect;
    switch (drawingModel) {
#ifndef NP_NO_QUICKDRAW
        case NPDrawingModelQuickDraw:
        {
            ::Rect qdRect;
            GetRegionBounds((NPQDRegion)invalidRegion, &qdRect);
            invalidRect = NSMakeRect(qdRect.left, qdRect.top, qdRect.right - qdRect.left, qdRect.bottom - qdRect.top);
        }
        break;
#endif /* NP_NO_QUICKDRAW */
        
        case NPDrawingModelCoreGraphics:
        {
            CGRect cgRect = CGPathGetBoundingBox((NPCGRegion)invalidRegion);
            invalidRect = *(NSRect*)&cgRect;
            break;
        }
        default:
            ASSERT_NOT_REACHED();
        break;
    }
    
    [self invalidatePluginContentRect:invalidRect];
}

-(void)forceRedraw
{
    LOG(Plugins, "forceRedraw");
    [self invalidatePluginContentRect:[self bounds]];
    [[self window] displayIfNeeded];
}

- (NPError)getVariable:(NPNVariable)variable value:(void *)value
{
    switch (variable) {
        case NPNVWindowNPObject:
        {
            Frame* frame = core([self webFrame]);
            NPObject* windowScriptObject = frame ? frame->script()->windowScriptNPObject() : 0;

            // Return value is expected to be retained, as described here: <http://www.mozilla.org/projects/plugins/npruntime.html#browseraccess>
            if (windowScriptObject)
                _NPN_RetainObject(windowScriptObject);
            
            void **v = (void **)value;
            *v = windowScriptObject;

            return NPERR_NO_ERROR;
        }

        case NPNVPluginElementNPObject:
        {
            if (!_element)
                return NPERR_GENERIC_ERROR;
            
            NPObject *plugInScriptObject = _element->getNPObject();

            // Return value is expected to be retained, as described here: <http://www.mozilla.org/projects/plugins/npruntime.html#browseraccess>
            if (plugInScriptObject)
                _NPN_RetainObject(plugInScriptObject);

            void **v = (void **)value;
            *v = plugInScriptObject;

            return NPERR_NO_ERROR;
        }
        
        case NPNVpluginDrawingModel:
        {
            *(NPDrawingModel *)value = drawingModel;
            return NPERR_NO_ERROR;
        }

#ifndef NP_NO_QUICKDRAW
        case NPNVsupportsQuickDrawBool:
        {
            *(NPBool *)value = TRUE;
            return NPERR_NO_ERROR;
        }
#endif /* NP_NO_QUICKDRAW */
        
        case NPNVsupportsCoreGraphicsBool:
        {
            *(NPBool *)value = TRUE;
            return NPERR_NO_ERROR;
        }

        case NPNVsupportsOpenGLBool:
        {
            *(NPBool *)value = FALSE;
            return NPERR_NO_ERROR;
        }
        
        case NPNVsupportsCoreAnimationBool:
        {
#ifdef BUILDING_ON_TIGER
            *(NPBool *)value = FALSE;
#else
            *(NPBool *)value = TRUE;
#endif
            return NPERR_NO_ERROR;
        }
            
#ifndef NP_NO_CARBON
        case NPNVsupportsCarbonBool:
        {
            *(NPBool *)value = TRUE;
            return NPERR_NO_ERROR;
        }
#endif /* NP_NO_CARBON */

        case NPNVsupportsCocoaBool:
        {
            *(NPBool *)value = TRUE;
            return NPERR_NO_ERROR;
        }

        case NPNVprivateModeBool:
        {
            *(NPBool *)value = _isPrivateBrowsingEnabled;
            return NPERR_NO_ERROR;
        }

        case WKNVBrowserContainerCheckFuncs:
        {
            *(WKNBrowserContainerCheckFuncs **)value = browserContainerCheckFuncs();
            return NPERR_NO_ERROR;
        }
#if USE(ACCELERATED_COMPOSITING)
        case WKNVSupportsCompositingCoreAnimationPluginsBool:
        {
            *(NPBool *)value = [[[self webView] preferences] acceleratedCompositingEnabled];
            return NPERR_NO_ERROR;
        }
#endif
        default:
            break;
    }

    return NPERR_GENERIC_ERROR;
}

- (NPError)setVariable:(NPPVariable)variable value:(void *)value
{
    switch (variable) {
        case NPPVpluginDrawingModel:
        {
            // Can only set drawing model inside NPP_New()
            if (self != [[self class] currentPluginView])
                return NPERR_GENERIC_ERROR;
            
            // Check for valid, supported drawing model
            NPDrawingModel newDrawingModel = (NPDrawingModel)(uintptr_t)value;
            switch (newDrawingModel) {
                // Supported drawing models:
#ifndef NP_NO_QUICKDRAW
                case NPDrawingModelQuickDraw:
#endif
                case NPDrawingModelCoreGraphics:
#ifndef BUILDING_ON_TIGER
                case NPDrawingModelCoreAnimation:
#endif
                    drawingModel = newDrawingModel;
                    return NPERR_NO_ERROR;
                    

                // Unsupported (or unknown) drawing models:
                default:
                    LOG(Plugins, "Plugin %@ uses unsupported drawing model: %d", _eventHandler.get(), drawingModel);
                    return NPERR_GENERIC_ERROR;
            }
        }
        
        case NPPVpluginEventModel:
        {
            // Can only set event model inside NPP_New()
            if (self != [[self class] currentPluginView])
                return NPERR_GENERIC_ERROR;
            
            // Check for valid, supported event model
            NPEventModel newEventModel = (NPEventModel)(uintptr_t)value;
            switch (newEventModel) {
                // Supported event models:
#ifndef NP_NO_CARBON
                case NPEventModelCarbon:
#endif
                case NPEventModelCocoa:
                    eventModel = newEventModel;
                    return NPERR_NO_ERROR;
                    
                    // Unsupported (or unknown) event models:
                default:
                    LOG(Plugins, "Plugin %@ uses unsupported event model: %d", _eventHandler.get(), eventModel);
                    return NPERR_GENERIC_ERROR;
            }
        }
            
        default:
            return NPERR_GENERIC_ERROR;
    }
}

- (uint32_t)scheduleTimerWithInterval:(uint32_t)interval repeat:(NPBool)repeat timerFunc:(void (*)(NPP npp, uint32_t timerID))timerFunc
{
    if (!timerFunc)
        return 0;
    
    if (!timers)
        timers = new HashMap<uint32_t, PluginTimer*>;
    
    uint32_t timerID;
    
    do {
        timerID = ++currentTimerID;
    } while (timers->contains(timerID) || timerID == 0);
    
    PluginTimer* timer = new PluginTimer(plugin, timerID, interval, repeat, timerFunc);
    timers->set(timerID, timer);

    if (_shouldFireTimers)
        timer->start(_isCompletelyObscured);
    
    return timerID;
}

- (void)unscheduleTimer:(uint32_t)timerID
{
    if (!timers)
        return;
    
    if (PluginTimer* timer = timers->take(timerID))
        delete timer;
}

- (NPError)popUpContextMenu:(NPMenu *)menu
{
    NSEvent *currentEvent = [NSApp currentEvent];
    
    // NPN_PopUpContextMenu must be called from within the plug-in's NPP_HandleEvent.
    if (!currentEvent)
        return NPERR_GENERIC_ERROR;
    
    [NSMenu popUpContextMenu:(NSMenu *)menu withEvent:currentEvent forView:self];
    return NPERR_NO_ERROR;
}

- (NPError)getVariable:(NPNURLVariable)variable forURL:(const char*)url value:(char**)value length:(uint32_t*)length
{
    switch (variable) {
        case NPNURLVCookie: {
            if (!value)
                break;
            
            NSURL *URL = [self URLWithCString:url];
            if (!URL)
                break;
            
            if (Frame* frame = core([self webFrame])) {
                String cookieString = cookies(frame->document(), URL); 
                CString cookieStringUTF8 = cookieString.utf8();
                if (cookieStringUTF8.isNull())
                    return NPERR_GENERIC_ERROR;

                *value = static_cast<char*>(NPN_MemAlloc(cookieStringUTF8.length()));
                memcpy(*value, cookieStringUTF8.data(), cookieStringUTF8.length());
                
                if (length)
                    *length = cookieStringUTF8.length();
                return NPERR_NO_ERROR;
            }
            break;
        }
        case NPNURLVProxy: {
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
            if (!value)
                break;
            
            NSURL *URL = [self URLWithCString:url];
            if (!URL)
                break;

            Vector<ProxyServer> proxyServers = proxyServersForURL(URL, 0);
            CString proxiesUTF8 = toString(proxyServers).utf8();
            
            *value = static_cast<char*>(NPN_MemAlloc(proxiesUTF8.length()));
            memcpy(*value, proxiesUTF8.data(), proxiesUTF8.length());
            
           if (length)
               *length = proxiesUTF8.length();
            
            return NPERR_NO_ERROR;
#else
            break;
#endif
        }
    }
    return NPERR_GENERIC_ERROR;
}

- (NPError)setVariable:(NPNURLVariable)variable forURL:(const char*)url value:(const char*)value length:(uint32_t)length
{
    switch (variable) {
        case NPNURLVCookie: {
            NSURL *URL = [self URLWithCString:url];
            if (!URL)
                break;
            
            String cookieString = String::fromUTF8(value, length);
            if (!cookieString)
                break;
            
            if (Frame* frame = core([self webFrame])) {
                setCookies(frame->document(), URL, cookieString);
                return NPERR_NO_ERROR;
            }
            
            break;
        }
        case NPNURLVProxy:
            // Can't set the proxy for a URL.
            break;
    }
    return NPERR_GENERIC_ERROR;
}

- (NPError)getAuthenticationInfoWithProtocol:(const char*)protocolStr host:(const char*)hostStr port:(int32_t)port scheme:(const char*)schemeStr realm:(const char*)realmStr
                                    username:(char**)usernameStr usernameLength:(uint32_t*)usernameLength 
                                    password:(char**)passwordStr passwordLength:(uint32_t*)passwordLength
{
    if (!protocolStr || !hostStr || !schemeStr || !realmStr || !usernameStr || !usernameLength || !passwordStr || !passwordLength)
        return NPERR_GENERIC_ERROR;
  
    CString username;
    CString password;
    if (!getAuthenticationInfo(protocolStr, hostStr, port, schemeStr, realmStr, username, password))
        return NPERR_GENERIC_ERROR;
    
    *usernameLength = username.length();
    *usernameStr = static_cast<char*>(NPN_MemAlloc(username.length()));
    memcpy(*usernameStr, username.data(), username.length());
    
    *passwordLength = password.length();
    *passwordStr = static_cast<char*>(NPN_MemAlloc(password.length()));
    memcpy(*passwordStr, password.data(), password.length());
    
    return NPERR_NO_ERROR;
}

- (char*)resolveURL:(const char*)url forTarget:(const char*)target
{
    CString location = [self resolvedURLStringForURL:url target:target];

    if (location.isNull())
        return 0;
    
    // We use strdup here because the caller needs to free it with NPN_MemFree (which calls free).
    return strdup(location.data());
}

@end

@implementation WebNetscapePluginView (Internal)

- (BOOL)_shouldCancelSrcStream
{
    ASSERT(_isStarted);
    
    // Check if we should cancel the load
    NPBool cancelSrcStream = 0;
    if ([_pluginPackage.get() pluginFuncs]->getvalue &&
        [_pluginPackage.get() pluginFuncs]->getvalue(plugin, NPPVpluginCancelSrcStream, &cancelSrcStream) == NPERR_NO_ERROR && cancelSrcStream)
        return YES;
    
    return NO;
}

// Work around Silverlight full screen performance issue by maintaining an accelerated GL pixel format.
// We can safely remove it at some point in the future when both:
// 1) Microsoft releases a genuine fix for 7288546.
// 2) Enough Silverlight users update to the new Silverlight.
// For now, we'll distinguish older broken versions of Silverlight by asking the plug-in if it resolved its full screen badness.
- (void)_workaroundSilverlightFullscreenBug:(BOOL)initializedPlugin
{
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
    ASSERT(_isSilverlight);
    NPBool isFullscreenPerformanceIssueFixed = 0;
    NPPluginFuncs *pluginFuncs = [_pluginPackage.get() pluginFuncs];
    if (pluginFuncs->getvalue && pluginFuncs->getvalue(plugin, static_cast<NPPVariable>(WKNVSilverlightFullscreenPerformanceIssueFixed), &isFullscreenPerformanceIssueFixed) == NPERR_NO_ERROR && isFullscreenPerformanceIssueFixed)
        return;
    
    static CGLPixelFormatObj pixelFormatObject = 0;
    static unsigned refCount = 0;
    
    if (initializedPlugin) {
        refCount++;
        if (refCount == 1) {
            const CGLPixelFormatAttribute attributes[] = { kCGLPFAAccelerated, static_cast<CGLPixelFormatAttribute>(0) };
            GLint npix;
            CGLChoosePixelFormat(attributes, &pixelFormatObject, &npix);
        }  
    } else {
        ASSERT(pixelFormatObject);
        refCount--;
        if (!refCount) 
            CGLReleasePixelFormat(pixelFormatObject);
    }
#endif
}

- (NPError)_createPlugin
{
    plugin = (NPP)calloc(1, sizeof(NPP_t));
    plugin->ndata = self;

    ASSERT([_pluginPackage.get() pluginFuncs]->newp);

    // NPN_New(), which creates the plug-in instance, should never be called while calling a plug-in function for that instance.
    ASSERT(pluginFunctionCallDepth == 0);

    PluginMainThreadScheduler::scheduler().registerPlugin(plugin);

    _isFlash = [_pluginPackage.get() bundleIdentifier] == "com.macromedia.Flash Player.plugin";
    _isSilverlight = [_pluginPackage.get() bundleIdentifier] == "com.microsoft.SilverlightPlugin";

    [[self class] setCurrentPluginView:self];
    NPError npErr = [_pluginPackage.get() pluginFuncs]->newp((char *)[_MIMEType.get() cString], plugin, _mode, argsCount, cAttributes, cValues, NULL);
    [[self class] setCurrentPluginView:nil];
    if (_isSilverlight)
        [self _workaroundSilverlightFullscreenBug:YES];
    LOG(Plugins, "NPP_New: %d", npErr);
    return npErr;
}

- (void)_destroyPlugin
{
    PluginMainThreadScheduler::scheduler().unregisterPlugin(plugin);
    
    if (_isSilverlight)
        [self _workaroundSilverlightFullscreenBug:NO];
    
    NPError npErr;
    npErr = ![_pluginPackage.get() pluginFuncs]->destroy(plugin, NULL);
    LOG(Plugins, "NPP_Destroy: %d", npErr);
    
    if (Frame* frame = core([self webFrame]))
        frame->script()->cleanupScriptObjectsForPlugin(self);
        
    free(plugin);
    plugin = NULL;
}

- (NSBitmapImageRep *)_printedPluginBitmap
{
#ifdef NP_NO_QUICKDRAW
    return nil;
#else
    // Cannot print plugins that do not implement NPP_Print
    if (![_pluginPackage.get() pluginFuncs]->print)
        return nil;

    // This NSBitmapImageRep will share its bitmap buffer with a GWorld that the plugin will draw into.
    // The bitmap is created in 32-bits-per-pixel ARGB format, which is the default GWorld pixel format.
    NSBitmapImageRep *bitmap = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
                                                         pixelsWide:window.width
                                                         pixelsHigh:window.height
                                                         bitsPerSample:8
                                                         samplesPerPixel:4
                                                         hasAlpha:YES
                                                         isPlanar:NO
                                                         colorSpaceName:NSDeviceRGBColorSpace
                                                         bitmapFormat:NSAlphaFirstBitmapFormat
                                                         bytesPerRow:0
                                                         bitsPerPixel:0] autorelease];
    ASSERT(bitmap);
    
    // Create a GWorld with the same underlying buffer into which the plugin can draw
    ::Rect printGWorldBounds;
    SetRect(&printGWorldBounds, 0, 0, window.width, window.height);
    GWorldPtr printGWorld;
    if (NewGWorldFromPtr(&printGWorld,
                         k32ARGBPixelFormat,
                         &printGWorldBounds,
                         NULL,
                         NULL,
                         0,
                         (Ptr)[bitmap bitmapData],
                         [bitmap bytesPerRow]) != noErr) {
        LOG_ERROR("Could not create GWorld for printing");
        return nil;
    }
    
    /// Create NPWindow for the GWorld
    NPWindow printNPWindow;
    printNPWindow.window = &printGWorld; // Normally this is an NP_Port, but when printing it is the actual CGrafPtr
    printNPWindow.x = 0;
    printNPWindow.y = 0;
    printNPWindow.width = window.width;
    printNPWindow.height = window.height;
    printNPWindow.clipRect.top = 0;
    printNPWindow.clipRect.left = 0;
    printNPWindow.clipRect.right = window.width;
    printNPWindow.clipRect.bottom = window.height;
    printNPWindow.type = NPWindowTypeDrawable; // Offscreen graphics port as opposed to a proper window
    
    // Create embed-mode NPPrint
    NPPrint npPrint;
    npPrint.mode = NP_EMBED;
    npPrint.print.embedPrint.window = printNPWindow;
    npPrint.print.embedPrint.platformPrint = printGWorld;
    
    // Tell the plugin to print into the GWorld
    [self willCallPlugInFunction];
    {
        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
        [_pluginPackage.get() pluginFuncs]->print(plugin, &npPrint);
    }
    [self didCallPlugInFunction];

    // Don't need the GWorld anymore
    DisposeGWorld(printGWorld);
        
    return bitmap;
#endif
}

- (void)_redeliverStream
{
    if ([self dataSource] && _isStarted) {
        // Deliver what has not been passed to the plug-in up to this point.
        if (_dataLengthReceived > 0) {
            NSData *data = [[[self dataSource] data] subdataWithRange:NSMakeRange(0, _dataLengthReceived)];
            _dataLengthReceived = 0;
            [self pluginView:self receivedData:data];
            if (![[self dataSource] isLoading]) {
                if (_error)
                    [self pluginView:self receivedError:_error.get()];
                else
                    [self pluginViewFinishedLoading:self];
            }
        }
    }
}

@end

#endif
