/*
 * 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.
 */

#ifndef __LP64__

#import "WebBaseNetscapePluginView.h"

#import "WebDataSourceInternal.h"
#import "WebDefaultUIDelegate.h"
#import "WebFrameBridge.h"
#import "WebFrameInternal.h" 
#import "WebFrameView.h"
#import "WebGraphicsExtras.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 "WebNetscapePluginPackage.h"
#import "WebNetscapePluginStream.h"
#import "WebNullPluginView.h"
#import "WebPreferences.h"
#import "WebViewInternal.h"
#import "WebUIDelegatePrivate.h"
#import <Carbon/Carbon.h>
#import <JavaScriptCore/Assertions.h>
#import <JavaScriptCore/JSLock.h>
#import <JavaScriptCore/npruntime_impl.h>
#import <WebCore/Document.h>
#import <WebCore/Element.h>
#import <WebCore/Frame.h> 
#import <WebCore/FrameLoader.h> 
#import <WebCore/FrameTree.h> 
#import <WebCore/Page.h> 
#import <WebCore/SoftLinking.h> 
#import <WebCore/WebCoreObjCExtras.h>
#import <WebKit/DOMPrivate.h>
#import <WebKit/WebUIDelegate.h>
#import <objc/objc-runtime.h>

using namespace WebCore;

// Send null events 50 times a second when active, so plug-ins like Flash get high frame rates.
#define NullEventIntervalActive         0.02
#define NullEventIntervalNotActive      0.25

#define LoginWindowDidSwitchFromUserNotification    @"WebLoginWindowDidSwitchFromUserNotification"
#define LoginWindowDidSwitchToUserNotification      @"WebLoginWindowDidSwitchToUserNotification"

SOFT_LINK_FRAMEWORK(OpenGL)
SOFT_LINK_FRAMEWORK(AGL)

SOFT_LINK(OpenGL, CGLGetOffScreen, CGLError, (CGLContextObj ctx, GLsizei *width, GLsizei *height, GLint *rowbytes, void **baseaddr), (ctx, width, height, rowbytes, baseaddr))
SOFT_LINK(OpenGL, CGLSetOffScreen, CGLError, (CGLContextObj ctx, GLsizei width, GLsizei height, GLint rowbytes, void *baseaddr), (ctx, width, height, rowbytes, baseaddr))
SOFT_LINK(OpenGL, glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height), (x, y, width, height))
SOFT_LINK(AGL, aglCreateContext, AGLContext, (AGLPixelFormat pix, AGLContext share), (pix, share))
SOFT_LINK(AGL, aglSetWindowRef, GLboolean, (AGLContext ctx, WindowRef window), (ctx, window))
SOFT_LINK(AGL, aglSetDrawable, GLboolean, (AGLContext ctx, AGLDrawable draw), (ctx, draw))
#ifndef BUILDING_ON_TIGER
SOFT_LINK(AGL, aglChoosePixelFormat, AGLPixelFormat, (const void *gdevs, GLint ndev, const GLint *attribs), (gdevs, ndev, attribs))
#else
SOFT_LINK(AGL, aglChoosePixelFormat, AGLPixelFormat, (const AGLDevice *gdevs, GLint ndev, const GLint *attribs), (gdevs, ndev, attribs))
#endif
SOFT_LINK(AGL, aglDestroyPixelFormat, void, (AGLPixelFormat pix), (pix))
SOFT_LINK(AGL, aglDestroyContext, GLboolean, (AGLContext ctx), (ctx))
SOFT_LINK(AGL, aglGetCGLContext, GLboolean, (AGLContext ctx, void **cgl_ctx), (ctx, cgl_ctx))
SOFT_LINK(AGL, aglGetCurrentContext, AGLContext, (void), ())
SOFT_LINK(AGL, aglSetCurrentContext, GLboolean, (AGLContext ctx), (ctx))
SOFT_LINK(AGL, aglGetError, GLenum, (void), ())
SOFT_LINK(AGL, aglUpdateContext, GLboolean, (AGLContext ctx), (ctx))
SOFT_LINK(AGL, aglErrorString, const GLubyte *, (GLenum code), (code))

@interface WebBaseNetscapePluginView (Internal)
- (void)_viewHasMoved;
- (NPError)_createPlugin;
- (void)_destroyPlugin;
- (NSBitmapImageRep *)_printedPluginBitmap;
- (BOOL)_createAGLContextIfNeeded;
- (BOOL)_createWindowedAGLContext;
- (BOOL)_createWindowlessAGLContext;
- (CGLContextObj)_cglContext;
- (BOOL)_getAGLOffscreenBuffer:(GLvoid **)outBuffer width:(GLsizei *)outWidth height:(GLsizei *)outHeight;
- (void)_destroyAGLContext;
- (void)_reshapeAGLWindow;
- (void)_hideAGLWindow;
- (NSImage *)_aglOffscreenImageForDrawingInRect:(NSRect)drawingInRect;
- (void)_redeliverStream;
@end

static WebBaseNetscapePluginView *currentPluginView = nil;

typedef struct OpaquePortState* PortState;

#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;

typedef struct {
    AGLContext oldContext;
} PortState_GL;

@interface WebPluginRequest : NSObject
{
    NSURLRequest *_request;
    NSString *_frameName;
    void *_notifyData;
    BOOL _didStartFromUserGesture;
    BOOL _sendNotification;
}

- (id)initWithRequest:(NSURLRequest *)request frameName:(NSString *)frameName notifyData:(void *)notifyData sendNotification:(BOOL)sendNotification didStartFromUserGesture:(BOOL)currentEventIsUserGesture;

- (NSURLRequest *)request;
- (NSString *)frameName;
- (void *)notifyData;
- (BOOL)isCurrentEventUserGesture;
- (BOOL)sendNotification;

@end

@interface NSData (WebPluginDataExtras)
- (BOOL)_web_startsWithBlankLine;
- (NSInteger)_web_locationAfterFirstBlankLine;
@end

static OSStatus TSMEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void *pluginView);

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

@implementation WebBaseNetscapePluginView

+ (void)initialize
{
#ifndef BUILDING_ON_TIGER
    WebCoreObjCFinalizeOnMainThread(self);
#endif
    WKSendUserChangeNotifications();
}

#pragma mark EVENTS

+ (void)getCarbonEvent:(EventRecord *)carbonEvent
{
    carbonEvent->what = nullEvent;
    carbonEvent->message = 0;
    carbonEvent->when = TickCount();
    
    GetGlobalMouse(&carbonEvent->where);
    carbonEvent->where.h = static_cast<short>(carbonEvent->where.h * HIGetScaleFactor());
    carbonEvent->where.v = static_cast<short>(carbonEvent->where.v * HIGetScaleFactor());
    carbonEvent->modifiers = GetCurrentKeyModifiers();
    if (!Button())
        carbonEvent->modifiers |= btnState;
}

- (void)getCarbonEvent:(EventRecord *)carbonEvent
{
    [[self class] getCarbonEvent:carbonEvent];
}

- (EventModifiers)modifiersForEvent:(NSEvent *)event
{
    EventModifiers modifiers;
    unsigned int modifierFlags = [event modifierFlags];
    NSEventType eventType = [event type];
    
    modifiers = 0;
    
    if (eventType != NSLeftMouseDown && eventType != NSRightMouseDown)
        modifiers |= btnState;
    
    if (modifierFlags & NSCommandKeyMask)
        modifiers |= cmdKey;
    
    if (modifierFlags & NSShiftKeyMask)
        modifiers |= shiftKey;

    if (modifierFlags & NSAlphaShiftKeyMask)
        modifiers |= alphaLock;

    if (modifierFlags & NSAlternateKeyMask)
        modifiers |= optionKey;

    if (modifierFlags & NSControlKeyMask || eventType == NSRightMouseDown)
        modifiers |= controlKey;
    
    return modifiers;
}

- (void)getCarbonEvent:(EventRecord *)carbonEvent withEvent:(NSEvent *)cocoaEvent
{
    if (WKConvertNSEventToCarbonEvent(carbonEvent, cocoaEvent)) {
        carbonEvent->where.h = static_cast<short>(carbonEvent->where.h * HIGetScaleFactor());
        carbonEvent->where.v = static_cast<short>(carbonEvent->where.v * HIGetScaleFactor());
        return;
    }
    
    NSPoint where = [[cocoaEvent window] convertBaseToScreen:[cocoaEvent locationInWindow]];
        
    carbonEvent->what = nullEvent;
    carbonEvent->message = 0;
    carbonEvent->when = (UInt32)([cocoaEvent timestamp] * 60); // seconds to ticks
    carbonEvent->where.h = (short)where.x;
    carbonEvent->where.v = (short)(NSMaxY([[[NSScreen screens] objectAtIndex:0] frame]) - where.y);
    carbonEvent->modifiers = [self modifiersForEvent:cocoaEvent];
}

- (BOOL)superviewsHaveSuperviews
{
    NSView *contentView = [[self window] contentView];
    NSView *view;
    for (view = self; view != nil; view = [view superview]) { 
        if (view == contentView) {
            return YES;
        }
    }
    return NO;
}

#ifndef NP_NO_QUICKDRAW

// 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
{
    ASSERT(drawingModel == NPDrawingModelQuickDraw);
    
    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);
}

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>(cgr.origin.y);
    npr.left = static_cast<uint16>(cgr.origin.x);
    npr.bottom = static_cast<uint16>(CGRectGetMaxY(cgr));
    npr.right = static_cast<uint16>(CGRectGetMaxX(cgr));
}

#endif

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

- (NSRect)visibleRect
{
    // WebCore may impose an additional clip (via CSS overflow or clip properties).  Fetch
    // that clip now.    
    return NSIntersectionRect([self convertRect:[element _windowClipRect] fromView:nil], [super visibleRect]);
}

- (PortState)saveAndSetNewPortStateForUpdate:(BOOL)forUpdate
{
    ASSERT([self currentWindow] != nil);

#ifndef NP_NO_QUICKDRAW
    // 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.
    if (drawingModel == NPDrawingModelQuickDraw)
        [self fixWindowPort];
#endif

    WindowRef windowRef = (WindowRef)[[self currentWindow] windowRef];
    ASSERT(windowRef);
    
    // Use AppKit to convert view coordinates to NSWindow coordinates.
    NSRect boundsInWindow = [self convertRect:[self bounds] toView:nil];
    NSRect visibleRectInWindow = [self convertRect:[self visibleRect] toView:nil];
    
    // Flip Y to convert NSWindow 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
    // Look at the Carbon port to convert top-left-based window coordinates into top-left-based content coordinates.
    if (drawingModel == NPDrawingModelQuickDraw) {
        ::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.x = (int32)boundsInWindow.origin.x; 
    window.y = (int32)boundsInWindow.origin.y;
    window.width = static_cast<uint32>(NSWidth(boundsInWindow));
    window.height = static_cast<uint32>(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.
    NSWindow *realWindow = [self window];
    if (window.width <= 0 || window.height <= 0 || window.x < -100000
            || realWindow == nil || [realWindow isMiniaturized]
            || [NSApp isHidden]
            || ![self superviewsHaveSuperviews]
            || [self isHiddenOrHasHiddenAncestor]) {

        // 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;
    } 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)-boundsInWindow.origin.x;
            nPort.qdPort.porty = (int32)-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 && !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>(-boundsInWindow.origin.x + origin.x);
                        nPort.qdPort.porty = static_cast<int32>(-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 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: {            
            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;
            
            // Update the plugin's window/context
            nPort.cgPort.window = windowRef;
            nPort.cgPort.context = context;
            window.window = &nPort.cgPort;

            // Save current graphics context's state; will be restored by -restorePortState:
            CGContextSaveGState(context);
            
            // 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 NPDrawingModelOpenGL: {
            ASSERT([NSView focusView] == self);

            // Clear the "current" window and context -- they will be assigned below (if all goes well)
            nPort.aglPort.window = NULL;
            nPort.aglPort.context = NULL;
            
            // Create AGL context if needed
            if (![self _createAGLContextIfNeeded]) {
                LOG_ERROR("Could not create AGL context");
                return NULL;
            }
            
            // Update the plugin's window/context
            nPort.aglPort.window = windowRef;
            nPort.aglPort.context = [self _cglContext];
            window.window = &nPort.aglPort;
            
            // Save/set current AGL context
            PortState_GL *glPortState = (PortState_GL *)malloc(sizeof(PortState_GL));
            portState = (PortState)glPortState;
            glPortState->oldContext = aglGetCurrentContext();
            aglSetCurrentContext(aglContext);
            
            // Adjust viewport according to clip
            switch (window.type) {
                case NPWindowTypeWindow:
                    glViewport(static_cast<GLint>(NSMinX(boundsInWindow) - NSMinX(visibleRectInWindow)),
                        static_cast<GLint>(NSMaxY(visibleRectInWindow) - NSMaxY(boundsInWindow)),
                            window.width, window.height);
                    break;
                
                case NPWindowTypeDrawable: {
                    GLsizei width, height;
                    if ([self _getAGLOffscreenBuffer:NULL width:&width height:&height])
                        glViewport(0, 0, width, height);
                    break;
                }
                
                default:
                    ASSERT_NOT_REACHED();
                    break;
            }
            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);
            ASSERT(((PortState_CG *)portState)->context == nPort.cgPort.context);
            CGContextRestoreGState(nPort.cgPort.context);
            break;
        
        case NPDrawingModelOpenGL:
            aglSetCurrentContext(((PortState_GL *)portState)->oldContext);
            break;
        
        default:
            ASSERT_NOT_REACHED();
            break;
    }
}

- (BOOL)sendEvent:(EventRecord *)event
{
    if (![self window])
        return NO;
    ASSERT(event);
   
    // If at any point the user clicks or presses a key from within a plugin, set the 
    // currentEventIsUserGesture flag to true. This is important to differentiate legitimate 
    // window.open() calls;  we still want to allow those.  See rdar://problem/4010765
    if (event->what == mouseDown || event->what == keyDown || event->what == mouseUp || event->what == autoKey)
        currentEventIsUserGesture = YES;
    
    suspendKeyUpEvents = NO;
    
    if (!isStarted)
        return NO;

    ASSERT(NPP_HandleEvent);
    
    // 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 updateEvt to CoreGraphics and OpenGL plugins when actually drawing
    ASSERT((drawingModel != NPDrawingModelCoreGraphics && drawingModel != NPDrawingModelOpenGL) || event->what != updateEvt || [NSView focusView] == self);
    
    BOOL updating = event->what == updateEvt;
    PortState portState;
    if ((drawingModel != NPDrawingModelCoreGraphics && drawingModel != NPDrawingModelOpenGL) || event->what == updateEvt) {
        // In CoreGraphics or OpenGL 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:updating];
        
        // We may have changed the window, so inform the plug-in.
        [self setWindowIfNecessary];
    } else
        portState = NULL;
    
#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 (drawingModel == NPDrawingModelQuickDraw && !isTransparent && event->what == updateEvt) {
        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];
    {
        KJS::JSLock::DropAllLocks dropAllLocks;
        acceptedEvent = NPP_HandleEvent(plugin, event);
    }
    [self didCallPlugInFunction];
    
    currentEventIsUserGesture = NO;
    
    if (portState) {
        if ([self currentWindow])
            [self restorePortState:portState];
        free(portState);
    }

    return acceptedEvent;
}

- (void)sendActivateEvent:(BOOL)activate
{
    EventRecord event;
    
    [self getCarbonEvent:&event];
    event.what = activateEvt;
    WindowRef windowRef = (WindowRef)[[self window] windowRef];
    event.message = (unsigned long)windowRef;
    if (activate) {
        event.modifiers |= activeFlag;
    }
    
    BOOL acceptedEvent;
    acceptedEvent = [self sendEvent:&event]; 
    
    LOG(PluginEvents, "NPP_HandleEvent(activateEvent): %d  isActive: %d", acceptedEvent, activate);
}

- (BOOL)sendUpdateEvent
{
    EventRecord event;
    
    [self getCarbonEvent:&event];
    event.what = updateEvt;
    WindowRef windowRef = (WindowRef)[[self window] windowRef];
    event.message = (unsigned long)windowRef;

    BOOL acceptedEvent = [self sendEvent:&event];

    LOG(PluginEvents, "NPP_HandleEvent(updateEvt): %d", acceptedEvent);

    return acceptedEvent;
}

-(void)sendNullEvent
{
    EventRecord event;

    [self getCarbonEvent:&event];

    // Plug-in should not react to cursor position when not active or when a menu is down.
    MenuTrackingData trackingData;
    OSStatus error = GetMenuTrackingData(NULL, &trackingData);

    // Plug-in should not react to cursor position when the actual window is not key.
    if (![[self window] isKeyWindow] || (error == noErr && trackingData.menu)) {
        // FIXME: Does passing a v and h of -1 really prevent it from reacting to the cursor position?
        event.where.v = -1;
        event.where.h = -1;
    }
    
    [self sendEvent:&event];
}

- (void)stopNullEvents
{
    [nullEventTimer invalidate];
    [nullEventTimer release];
    nullEventTimer = nil;
}

- (void)restartNullEvents
{
    ASSERT([self window]);
    
    if (nullEventTimer)
        [self stopNullEvents];
    
    if (!isStarted || [[self window] isMiniaturized])
        return;

    NSTimeInterval interval;

    // If the plugin is completely obscured (scrolled out of view, for example), then we will
    // send null events at a reduced rate.
    interval = !isCompletelyObscured ? NullEventIntervalActive : NullEventIntervalNotActive;    
    nullEventTimer = [[NSTimer scheduledTimerWithTimeInterval:interval
                                                       target:self
                                                     selector:@selector(sendNullEvent)
                                                     userInfo:nil
                                                      repeats:YES] retain];
}

- (BOOL)acceptsFirstResponder
{
    return YES;
}

- (void)installKeyEventHandler
{
    static const EventTypeSpec sTSMEvents[] =
    {
    { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent }
    };
    
    if (!keyEventHandler) {
        InstallEventHandler(GetWindowEventTarget((WindowRef)[[self window] windowRef]),
                            NewEventHandlerUPP(TSMEventHandler),
                            GetEventTypeCount(sTSMEvents),
                            sTSMEvents,
                            self,
                            &keyEventHandler);
    }
}

- (void)removeKeyEventHandler
{
    if (keyEventHandler) {
        RemoveEventHandler(keyEventHandler);
        keyEventHandler = NULL;
    }
}

- (void)setHasFocus:(BOOL)flag
{
    if (hasFocus != flag) {
        hasFocus = flag;
        EventRecord event;
        [self getCarbonEvent:&event];
        BOOL acceptedEvent;
        if (hasFocus) {
            event.what = getFocusEvent;
            acceptedEvent = [self sendEvent:&event]; 
            LOG(PluginEvents, "NPP_HandleEvent(getFocusEvent): %d", acceptedEvent);
            [self installKeyEventHandler];
        } else {
            event.what = loseFocusEvent;
            acceptedEvent = [self sendEvent:&event]; 
            LOG(PluginEvents, "NPP_HandleEvent(loseFocusEvent): %d", acceptedEvent);
            [self removeKeyEventHandler];
        }
    }
}

- (BOOL)becomeFirstResponder
{
    [self setHasFocus:YES];
    return YES;
}

- (BOOL)resignFirstResponder
{
    [self setHasFocus:NO];    
    return YES;
}

// AppKit doesn't call mouseDown or mouseUp on right-click. Simulate control-click
// mouseDown and mouseUp so plug-ins get the right-click event as they do in Carbon (3125743).
- (void)rightMouseDown:(NSEvent *)theEvent
{
    [self mouseDown:theEvent];
}

- (void)rightMouseUp:(NSEvent *)theEvent
{
    [self mouseUp:theEvent];
}

- (void)mouseDown:(NSEvent *)theEvent
{
    EventRecord event;

    [self getCarbonEvent:&event withEvent:theEvent];
    event.what = mouseDown;

    BOOL acceptedEvent;
    acceptedEvent = [self sendEvent:&event]; 
    
    LOG(PluginEvents, "NPP_HandleEvent(mouseDown): %d pt.v=%d, pt.h=%d", acceptedEvent, event.where.v, event.where.h);
}

- (void)mouseUp:(NSEvent *)theEvent
{
    EventRecord event;
    
    [self getCarbonEvent:&event withEvent:theEvent];
    event.what = mouseUp;

    BOOL acceptedEvent;
    acceptedEvent = [self sendEvent:&event]; 
    
    LOG(PluginEvents, "NPP_HandleEvent(mouseUp): %d pt.v=%d, pt.h=%d", acceptedEvent, event.where.v, event.where.h);
}

- (void)mouseEntered:(NSEvent *)theEvent
{
    EventRecord event;
    
    [self getCarbonEvent:&event withEvent:theEvent];
    event.what = adjustCursorEvent;

    BOOL acceptedEvent;
    acceptedEvent = [self sendEvent:&event]; 

    LOG(PluginEvents, "NPP_HandleEvent(mouseEntered): %d", acceptedEvent);
}

- (void)mouseExited:(NSEvent *)theEvent
{
    EventRecord event;
    
    [self getCarbonEvent:&event withEvent:theEvent];
    event.what = adjustCursorEvent;

    BOOL acceptedEvent;
    acceptedEvent = [self sendEvent:&event]; 

    // 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];

    LOG(PluginEvents, "NPP_HandleEvent(mouseExited): %d", acceptedEvent);
}

- (void)mouseDragged:(NSEvent *)theEvent
{
    // Do nothing so that other responders don't respond to the drag that initiated in this view.
}

- (UInt32)keyMessageForEvent:(NSEvent *)event
{
    NSData *data = [[event characters] dataUsingEncoding:CFStringConvertEncodingToNSStringEncoding(CFStringGetSystemEncoding())];
    if (!data) {
        return 0;
    }
    UInt8 characterCode;
    [data getBytes:&characterCode length:1];
    UInt16 keyCode = [event keyCode];
    return keyCode << 8 | characterCode;
}

- (void)keyUp:(NSEvent *)theEvent
{
    WKSendKeyEventToTSM(theEvent);
    
    // TSM won't send keyUp events so we have to send them ourselves.
    // Only send keyUp events after we receive the TSM callback because this is what plug-in expect from OS 9.
    if (!suspendKeyUpEvents) {
        EventRecord event;
        
        [self getCarbonEvent:&event withEvent:theEvent];
        event.what = keyUp;
        
        if (event.message == 0) {
            event.message = [self keyMessageForEvent:theEvent];
        }
        
        [self sendEvent:&event];
    }
}

- (void)keyDown:(NSEvent *)theEvent
{
    suspendKeyUpEvents = YES;
    WKSendKeyEventToTSM(theEvent);
}

static OSStatus TSMEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void *pluginView)
{    
    EventRef rawKeyEventRef;
    OSStatus status = GetEventParameter(inEvent, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(EventRef), NULL, &rawKeyEventRef);
    if (status != noErr) {
        LOG_ERROR("GetEventParameter failed with error: %d", status);
        return noErr;
    }
    
    // Two-pass read to allocate/extract Mac charCodes
    ByteCount numBytes;    
    status = GetEventParameter(rawKeyEventRef, kEventParamKeyMacCharCodes, typeChar, NULL, 0, &numBytes, NULL);
    if (status != noErr) {
        LOG_ERROR("GetEventParameter failed with error: %d", status);
        return noErr;
    }
    char *buffer = (char *)malloc(numBytes);
    status = GetEventParameter(rawKeyEventRef, kEventParamKeyMacCharCodes, typeChar, NULL, numBytes, NULL, buffer);
    if (status != noErr) {
        LOG_ERROR("GetEventParameter failed with error: %d", status);
        free(buffer);
        return noErr;
    }
    
    EventRef cloneEvent = CopyEvent(rawKeyEventRef);
    unsigned i;
    for (i = 0; i < numBytes; i++) {
        status = SetEventParameter(cloneEvent, kEventParamKeyMacCharCodes, typeChar, 1 /* one char code */, &buffer[i]);
        if (status != noErr) {
            LOG_ERROR("SetEventParameter failed with error: %d", status);
            free(buffer);
            return noErr;
        }
        
        EventRecord eventRec;
        if (ConvertEventRefToEventRecord(cloneEvent, &eventRec)) {
            BOOL acceptedEvent;
            acceptedEvent = [(WebBaseNetscapePluginView *)pluginView sendEvent:&eventRec];
            
            LOG(PluginEvents, "NPP_HandleEvent(keyDown): %d charCode:%c keyCode:%lu",
                acceptedEvent, (char) (eventRec.message & charCodeMask), (eventRec.message & keyCodeMask));
            
            // We originally thought that if the plug-in didn't accept this event,
            // we should pass it along so that keyboard scrolling, for example, will work.
            // In practice, this is not a good idea, because plug-ins tend to eat the event but return false.
            // MacIE handles each key event twice because of this, but we will emulate the other browsers instead.
        }
    }
    ReleaseEvent(cloneEvent);
    
    free(buffer);

    return noErr;
}

// Fake up command-modified events so cut, copy, paste and select all menus work.
- (void)sendModifierEventWithKeyCode:(int)keyCode character:(char)character
{
    EventRecord event;
    [self getCarbonEvent:&event];
    event.what = keyDown;
    event.modifiers |= cmdKey;
    event.message = keyCode << 8 | character;
    [self sendEvent:&event];
}

- (void)cut:(id)sender
{
    [self sendModifierEventWithKeyCode:7 character:'x'];
}

- (void)copy:(id)sender
{
    [self sendModifierEventWithKeyCode:8 character:'c'];
}

- (void)paste:(id)sender
{
    [self sendModifierEventWithKeyCode:9 character:'v'];
}

- (void)selectAll:(id)sender
{
    [self sendModifierEventWithKeyCode:0 character:'a'];
}

#pragma 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 NPDrawingModelOpenGL:
            if (nPort.aglPort.window != lastSetPort.aglPort.window)
                return NO;
            if (nPort.aglPort.context != lastSetPort.aglPort.context)
                return NO;
        break;
        
        default:
            ASSERT_NOT_REACHED();
        break;
    }
    
    return YES;
}

- (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. QuickDraw plug-ins are an important
    // excpetion to rule (3) because they manually must be 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.
    if (!isStarted)
        return;
    if (drawingModel != NPDrawingModelQuickDraw && ![self canDraw])
        return;
    
    BOOL didLockFocus = [NSView focusView] != self && [self lockFocusIfCanDraw];
    PortState portState = [self saveAndSetNewPortState];
    if (portState) {
        [self setWindowIfNecessary];
        [self restorePortState:portState];
        free(portState);
    }   
    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;
        ASSERT(!inSetWindow);
        
        inSetWindow = YES;
        
        // A CoreGraphics or OpenGL plugin's window may only be set while the plugin is being updated
        ASSERT((drawingModel != NPDrawingModelCoreGraphics && drawingModel != NPDrawingModelOpenGL) || [NSView focusView] == self);
        
        [self willCallPlugInFunction];
        {
            KJS::JSLock::DropAllLocks dropAllLocks;
            npErr = NPP_SetWindow(plugin, &window);
        }
        [self didCallPlugInFunction];
        inSetWindow = NO;

#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",
                npErr, nPort.cgPort.window, nPort.cgPort.context, (int)window.x, (int)window.y, (int)window.width, (int)window.height);
            break;

            case NPDrawingModelOpenGL:
                LOG(Plugins, "NPP_SetWindow (CoreGraphics): %d, window=%p, context=%p, window.x:%d window.y:%d window.width:%d window.height:%d",
                npErr, nPort.aglPort.window, nPort.aglPort.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)removeTrackingRect
{
    if (trackingTag) {
        [self removeTrackingRect:trackingTag];
        trackingTag = 0;

        // Do the following after setting trackingTag to 0 so we don't re-enter.

        // Balance the retain in resetTrackingRect. Use autorelease in case we hold 
        // the last reference to the window during tear-down, to avoid crashing AppKit. 
        [[self window] autorelease];
    }
}

- (void)resetTrackingRect
{
    [self removeTrackingRect];
    if (isStarted) {
        // Retain the window so that removeTrackingRect can work after the window is closed.
        [[self window] retain];
        trackingTag = [self addTrackingRect:[self bounds] owner:self userData:nil assumeInside:NO];
    }
}

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

+ (WebBaseNetscapePluginView *)currentPluginView
{
    return currentPluginView;
}

- (BOOL)canStart
{
    return YES;
}

- (void)didStart
{
    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 != nil && ![sourceURL _web_isEmpty]) {
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:sourceURL];
        [request _web_setHTTPReferrer:core([self webFrame])->loader()->outgoingReferrer()];
        [self loadRequest:request inTarget:nil withNotifyData:nil sendNotification:NO];
    } 
}

- (void)addWindowObservers
{
    ASSERT([self window]);

    NSWindow *theWindow = [self window];
    
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    [notificationCenter addObserver:self selector:@selector(windowWillClose:) 
                               name:NSWindowWillCloseNotification object:theWindow]; 
    [notificationCenter addObserver:self selector:@selector(windowBecameKey:)
                               name:NSWindowDidBecomeKeyNotification object:theWindow];
    [notificationCenter addObserver:self selector:@selector(windowResignedKey:)
                               name:NSWindowDidResignKeyNotification object:theWindow];
    [notificationCenter addObserver:self selector:@selector(windowDidMiniaturize:)
                               name:NSWindowDidMiniaturizeNotification object:theWindow];
    [notificationCenter addObserver:self selector:@selector(windowDidDeminiaturize:)
                               name:NSWindowDidDeminiaturizeNotification object:theWindow];
    
    [notificationCenter addObserver:self selector:@selector(loginWindowDidSwitchFromUser:)
                               name:LoginWindowDidSwitchFromUserNotification object:nil];
    [notificationCenter addObserver:self selector:@selector(loginWindowDidSwitchToUser:)
                               name:LoginWindowDidSwitchToUserNotification object:nil];
}

- (void)removeWindowObservers
{
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    [notificationCenter removeObserver:self name:NSWindowWillCloseNotification        object:nil]; 
    [notificationCenter removeObserver:self name:NSWindowDidBecomeKeyNotification     object:nil];
    [notificationCenter removeObserver:self name:NSWindowDidResignKeyNotification     object:nil];
    [notificationCenter removeObserver:self name:NSWindowDidMiniaturizeNotification   object:nil];
    [notificationCenter removeObserver:self name:NSWindowDidDeminiaturizeNotification object:nil];
    [notificationCenter removeObserver:self name:LoginWindowDidSwitchFromUserNotification   object:nil];
    [notificationCenter removeObserver:self name:LoginWindowDidSwitchToUserNotification     object:nil];
}

- (BOOL)start
{
    ASSERT([self currentWindow]);
    
    if (isStarted)
        return YES;

    if (![self canStart])
        return NO;
    
    ASSERT([self webView]);
    
    if (![[[self webView] preferences] arePlugInsEnabled])
        return NO;

    // Open the plug-in package so it remains loaded while our plugin uses it
    [pluginPackage open];
    
    // Initialize drawingModel to an invalid value so that we can detect when the plugin does not specify a drawingModel
    drawingModel = (NPDrawingModel)-1;
    
    // Plug-ins are "windowed" by default.  On MacOS, windowed plug-ins share the same window and graphics port as the main
    // browser window.  Windowless plug-ins are rendered off-screen, then copied into the main browser window.
    window.type = NPWindowTypeWindow;
    
    NPError npErr = [self _createPlugin];
    if (npErr != NPERR_NO_ERROR) {
        LOG_ERROR("NPP_New failed with error: %d", npErr);
        [self _destroyPlugin];
        [pluginPackage 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.  We could default to CoreGraphics instead, but
        // if the plugin did not specify the CoreGraphics drawing model then it must be one of the old QuickDraw
        // plugins.  Thus, the plugin is unsupported and should not be started.  Destroy it here and bail out.
        LOG(Plugins, "Plugin only supports QuickDraw, but QuickDraw is unavailable: %@", pluginPackage);
        [self _destroyPlugin];
        [pluginPackage close];
        return NO;
#endif
    }

    isStarted = YES;
        
    [self updateAndSetWindow];

    if ([self window]) {
        [self addWindowObservers];
        if ([[self window] isKeyWindow]) {
            [self sendActivateEvent:YES];
        }
        [self restartNullEvents];
    }

    [self resetTrackingRect];
    
    [self didStart];
    
    return YES;
}

- (void)stop
{
    // 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;
    }
    
    [self removeTrackingRect];

    if (!isStarted)
        return;
    
    isStarted = NO;
    // To stop active streams it's necessary to invoke makeObjectsPerformSelector on a copy 
    // of streams. This is because calling -[WebNetscapePluginStream stop] also has the side effect
    // of removing a stream from this collection.
    NSArray *streamsCopy = [streams copy];
    [streamsCopy makeObjectsPerformSelector:@selector(stop)];
    [streamsCopy release];
   
    // Stop the null events
    [self stopNullEvents];
    
    // Stop notifications and callbacks.
    [self removeWindowObservers];
    [[pendingFrameLoads 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;
    
    [self _destroyPlugin];
    [pluginPackage close];
    
    // We usually remove the key event handler in resignFirstResponder but it is possible that resignFirstResponder 
    // may never get called so we can't completely rely on it.
    [self removeKeyEventHandler];
    
    if (drawingModel == NPDrawingModelOpenGL)
        [self _destroyAGLContext];
}

- (BOOL)isStarted
{
    return isStarted;
}

- (WebDataSource *)dataSource
{
    WebFrame *webFrame = kit(core(element)->document()->frame());
    return [webFrame _dataSource];
}

- (WebFrame *)webFrame
{
    return [[self dataSource] webFrame];
}

- (WebView *)webView
{
    return [[self webFrame] webView];
}

- (NSWindow *)currentWindow
{
    return [self window] ? [self window] : [[self webView] hostWindow];
}

- (NPP)plugin
{
    return plugin;
}

- (WebNetscapePluginPackage *)pluginPackage
{
    return pluginPackage;
}

- (void)setPluginPackage:(WebNetscapePluginPackage *)thePluginPackage;
{
    [thePluginPackage retain];
    [pluginPackage release];
    pluginPackage = thePluginPackage;

    NPP_New =           [pluginPackage NPP_New];
    NPP_Destroy =       [pluginPackage NPP_Destroy];
    NPP_SetWindow =     [pluginPackage NPP_SetWindow];
    NPP_NewStream =     [pluginPackage NPP_NewStream];
    NPP_WriteReady =    [pluginPackage NPP_WriteReady];
    NPP_Write =         [pluginPackage NPP_Write];
    NPP_StreamAsFile =  [pluginPackage NPP_StreamAsFile];
    NPP_DestroyStream = [pluginPackage NPP_DestroyStream];
    NPP_HandleEvent =   [pluginPackage NPP_HandleEvent];
    NPP_URLNotify =     [pluginPackage NPP_URLNotify];
    NPP_GetValue =      [pluginPackage NPP_GetValue];
    NPP_SetValue =      [pluginPackage NPP_SetValue];
    NPP_Print =         [pluginPackage NPP_Print];
}

- (void)setMIMEType:(NSString *)theMIMEType
{
    NSString *type = [theMIMEType copy];
    [MIMEType release];
    MIMEType = type;
}

- (void)setBaseURL:(NSURL *)theBaseURL
{
    [theBaseURL retain];
    [baseURL release];
    baseURL = theBaseURL;
}

- (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 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 _web_URLCString]);
        argsCount++;
    } else {
        cAttributes = (char **)malloc([keys count] * sizeof(char *));
        cValues = (char **)malloc([values count] * sizeof(char *));
    }

    BOOL isWMP = [[[pluginPackage bundle] bundleIdentifier] isEqualToString:@"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++;
    }
}

- (void)setMode:(int)theMode
{
    mode = theMode;
}

#pragma mark NSVIEW

- (id)initWithFrame:(NSRect)frame
      pluginPackage:(WebNetscapePluginPackage *)thePluginPackage
                URL:(NSURL *)theURL
            baseURL:(NSURL *)theBaseURL
           MIMEType:(NSString *)MIME
      attributeKeys:(NSArray *)keys
    attributeValues:(NSArray *)values
       loadManually:(BOOL)loadManually
         DOMElement:(DOMElement *)anElement
{
    [super initWithFrame:frame];
 
    streams = [[NSMutableArray alloc] init];
    pendingFrameLoads = [[NSMutableDictionary alloc] init];    
    
    // load the plug-in if it is not already loaded
    if (![thePluginPackage load]) {
        [self release];
        return nil;
    }
    [self setPluginPackage:thePluginPackage];
    
    element = [anElement retain];
    sourceURL = [theURL retain];
    
    [self setMIMEType:MIME];
    [self setBaseURL:theBaseURL];
    [self setAttributeKeys:keys andValues:values];
    if (loadManually)
        [self setMode:NP_FULL];
    else
        [self setMode:NP_EMBED];
    
    _loadManually = loadManually;
    
    return self;
}

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

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

    unsigned i;
    for (i = 0; i < argsCount; i++) {
        free(cAttributes[i]);
        free(cValues[i]);
    }
    free(cAttributes);
    free(cValues);
}

- (void)disconnectStream:(WebBaseNetscapePluginStream*)stream
{
    [streams removeObjectIdenticalTo:stream];    
}

- (void)dealloc
{
    ASSERT(!isStarted);

    [sourceURL release];
    [_manualStream release];
    [_error release];
    
    [pluginPackage release];
    [streams release];
    [MIMEType release];
    [baseURL release];
    [pendingFrameLoads release];
    [element release];
    
    ASSERT(!plugin);
    ASSERT(!aglWindow);
    ASSERT(!aglContext);

    [self fini];

    [super dealloc];
}

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

    [self fini];

    [super finalize];
}

- (void)drawRect:(NSRect)rect
{
    if (!isStarted) {
        return;
    }
    
    if ([NSGraphicsContext currentContextDrawingToScreen])
        [self sendUpdateEvent];
    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);
        }
    }
    
    // If this is a windowless OpenGL plugin, blit its contents back into this view.  The plug-in just drew into the offscreen context.
    if (drawingModel == NPDrawingModelOpenGL && window.type == NPWindowTypeDrawable) {
        NSImage *aglOffscreenImage = [self _aglOffscreenImageForDrawingInRect:rect];
        if (aglOffscreenImage) {
            // Flip the context before drawing because the CGL context 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);
            
            // Copy 'rect' from the offscreen buffer to this view (the flip above makes this sort of tricky)
            NSRect flippedRect = rect;
            flippedRect.origin.y = NSMaxY(bounds) - NSMaxY(flippedRect);
            [aglOffscreenImage drawInRect:flippedRect fromRect:flippedRect operation:NSCompositeSourceOver fraction:1.0f];
            CGContextRestoreGState(cgContext);
        }
    }
}

- (BOOL)isFlipped
{
    return YES;
}

- (void)renewGState
{
    [super renewGState];
    
    // -renewGState is called whenever the view's geometry changes.  It's a little hacky to override this method, but
    // much safer than walking up the view hierarchy and observing frame/bounds changed notifications, since you don't
    // have to track subsequent changes to the view hierarchy and add/remove notification observers.
    // NSOpenGLView uses the exact same technique to reshape its OpenGL surface.
    [self _viewHasMoved];
}

#ifndef NP_NO_QUICKDRAW
-(void)tellQuickTimeToChill
{
    ASSERT(drawingModel == NPDrawingModelQuickDraw);
    
    // 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)viewWillMoveToWindow:(NSWindow *)newWindow
{
#ifndef NP_NO_QUICKDRAW
    if (drawingModel == NPDrawingModelQuickDraw)
        [self tellQuickTimeToChill];
#endif

    // We must remove the tracking rect before we move to the new window.
    // Once we move to the new window, it will be too late.
    [self removeTrackingRect];
    [self removeWindowObservers];
    
    // Workaround for: <rdar://problem/3822871> resignFirstResponder is not sent to first responder view when it is removed from the window
    [self setHasFocus:NO];

    if (!newWindow) {
        // Hide the AGL child window
        if (drawingModel == NPDrawingModelOpenGL)
            [self _hideAGLWindow];
        
        if ([[self webView] hostWindow]) {
            // View will be moved out of the actual window but it still has a host window.
            [self stopNullEvents];
        } else {
            // View will have no associated windows.
            [self stop];

            // Stop observing WebPreferencesChangedNotification -- we only need to observe this when installed in the view hierarchy.
            // When not in the view hierarchy, -viewWillMoveToWindow: and -viewDidMoveToWindow will start/stop the plugin as needed.
            [[NSNotificationCenter defaultCenter] removeObserver:self name:WebPreferencesChangedNotification object:nil];
        }
    }
}

- (void)viewWillMoveToSuperview:(NSView *)newSuperview
{
    if (!newSuperview) {
        // Stop the plug-in when it is removed from its superview.  It is not sufficient to do this in -viewWillMoveToWindow:nil, because
        // the WebView might still has a hostWindow at that point, which prevents the plug-in from being destroyed.
        // There is no need to start the plug-in when moving into a superview.  -viewDidMoveToWindow takes care of that.
        [self stop];
        
        // Stop observing WebPreferencesChangedNotification -- we only need to observe this when installed in the view hierarchy.
        // When not in the view hierarchy, -viewWillMoveToWindow: and -viewDidMoveToWindow will start/stop the plugin as needed.
        [[NSNotificationCenter defaultCenter] removeObserver:self name:WebPreferencesChangedNotification object:nil];
    }
}

- (void)viewDidMoveToWindow
{
    [self resetTrackingRect];
    
    if ([self window]) {
        // While in the view hierarchy, observe WebPreferencesChangedNotification so that we can start/stop depending
        // on whether plugins are enabled.
        [[NSNotificationCenter defaultCenter] addObserver:self
                                              selector:@selector(preferencesHaveChanged:)
                                              name:WebPreferencesChangedNotification
                                              object:nil];

        // View moved to an actual window. Start it if not already started.
        [self start];
        [self restartNullEvents];
        [self addWindowObservers];
    } else if ([[self webView] hostWindow]) {
        // View moved out of an actual window, but still has a host window.
        // Call setWindow to explicitly "clip out" the plug-in from sight.
        // FIXME: It would be nice to do this where we call stopNullEvents in viewWillMoveToWindow.
        [self updateAndSetWindow];
    }
}

- (void)viewWillMoveToHostWindow:(NSWindow *)hostWindow
{
    if (!hostWindow && ![self window]) {
        // View will have no associated windows.
        [self stop];

        // Remove WebPreferencesChangedNotification observer -- we will observe once again when we move back into the window
        [[NSNotificationCenter defaultCenter] removeObserver:self name:WebPreferencesChangedNotification object:nil];
    }
}

- (void)viewDidMoveToHostWindow
{
    if ([[self webView] hostWindow]) {
        // View now has an associated window. Start it if not already started.
        [self start];
    }
}

#pragma mark NOTIFICATIONS

- (void)windowWillClose:(NSNotification *)notification 
{
    [self stop]; 
} 

- (void)windowBecameKey:(NSNotification *)notification
{
    [self sendActivateEvent:YES];
    [self setNeedsDisplay:YES];
    [self restartNullEvents];
    SetUserFocusWindow((WindowRef)[[self window] windowRef]);
}

- (void)windowResignedKey:(NSNotification *)notification
{
    [self sendActivateEvent:NO];
    [self setNeedsDisplay:YES];
    [self restartNullEvents];
}

- (void)windowDidMiniaturize:(NSNotification *)notification
{
    [self stopNullEvents];
}

- (void)windowDidDeminiaturize:(NSNotification *)notification
{
    [self restartNullEvents];
}

- (void)loginWindowDidSwitchFromUser:(NSNotification *)notification
{
    [self stopNullEvents];
}

-(void)loginWindowDidSwitchToUser:(NSNotification *)notification
{
    [self restartNullEvents];
}

- (void)preferencesHaveChanged:(NSNotification *)notification
{
    WebPreferences *preferences = [[self webView] preferences];
    BOOL arePlugInsEnabled = [preferences arePlugInsEnabled];
    
    if ([notification object] == preferences && isStarted != arePlugInsEnabled) {
        if (arePlugInsEnabled) {
            if ([self currentWindow]) {
                [self start];
            }
        } else {
            [self stop];
            [self setNeedsDisplay:YES];
        }
    }
}

- (NPObject *)createPluginScriptableObject
{
    if (!NPP_GetValue || ![self isStarted])
        return NULL;
        
    NPObject *value = NULL;
    NPError error;
    [self willCallPlugInFunction];
    {
        KJS::JSLock::DropAllLocks dropAllLocks;
        error = NPP_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 alloc] initWithFrameLoader:core([self webFrame])->loader()];
}

- (void)pluginView:(NSView *)pluginView receivedData:(NSData *)data
{
    ASSERT(_loadManually);
    ASSERT(_manualStream);
    
    _dataLengthReceived += [data length];
    
    if (![self isStarted])
        return;
    
    if ([_manualStream plugin] == NULL) {
        [_manualStream setRequestURL:[[[self dataSource] request] URL]];
        [_manualStream setPlugin:[self plugin]];
        ASSERT([_manualStream plugin]);
        [_manualStream startStreamWithResponse:[[self dataSource] response]];
    }
    
    if ([_manualStream plugin])
        [_manualStream receivedData:data];
}

- (void)pluginView:(NSView *)pluginView receivedError:(NSError *)error
{
    ASSERT(_loadManually);
    
    [error retain];
    [_error release];
    _error = error;
    
    if (![self isStarted]) {
        return;
    }
    
    [_manualStream destroyStreamWithError:error];
}

- (void)pluginViewFinishedLoading:(NSView *)pluginView 
{
    ASSERT(_loadManually);
    ASSERT(_manualStream);
    
    if ([self isStarted])
        [_manualStream finishedLoading];
}

@end

@implementation WebBaseNetscapePluginView (WebNPPCallbacks)

- (NSMutableURLRequest *)requestWithURLCString:(const char *)URLCString
{
    if (!URLCString)
        return nil;
    
    CFStringRef string = CFStringCreateWithCString(kCFAllocatorDefault, URLCString, kCFStringEncodingISOLatin1);
    ASSERT(string); // All strings should be representable in ISO Latin 1
    
    NSString *URLString = [(NSString *)string _web_stringByStrippingReturnCharacters];
    NSURL *URL = [NSURL _web_URLWithDataAsString:URLString relativeToURL:baseURL];
    CFRelease(string);
    if (!URL)
        return nil;

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
    Frame* frame = core([self webFrame]);
    if (!frame)
        return nil;
    [request _web_setHTTPReferrer:frame->loader()->outgoingReferrer()];
    return request;
}

- (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] _bridge] 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];
            {
                KJS::JSLock::DropAllLocks dropAllLocks;
                NPP_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];
        WebBaseNetscapePluginStream *stream = [[WebBaseNetscapePluginStream alloc] initWithRequestURL:URL
                                                                                               plugin:plugin
                                                                                           notifyData:[JSPluginRequest notifyData]
                                                                                     sendNotification:[JSPluginRequest sendNotification]];
        [stream startStreamResponseURL:URL
                 expectedContentLength:[JSData length]
                      lastModifiedDate:nil
                              MIMEType:@"text/plain"
                               headers:nil];
        [stream receivedData:JSData];
        [stream finishedLoading];
        [stream release];
    }
}

- (void)webFrame:(WebFrame *)webFrame didFinishLoadWithReason:(NPReason)reason
{
    ASSERT(isStarted);
    
    WebPluginRequest *pluginRequest = [pendingFrameLoads objectForKey:webFrame];
    ASSERT(pluginRequest != nil);
    ASSERT([pluginRequest sendNotification]);
        
    [self willCallPlugInFunction];
    {
        KJS::JSLock::DropAllLocks dropAllLocks;
        NPP_URLNotify(plugin, [[[pluginRequest request] URL] _web_URLCString], reason, [pluginRequest notifyData]);
    }
    [self didCallPlugInFunction];
    
    [pendingFrameLoads removeObjectForKey:webFrame];
    [webFrame _setInternalLoadDelegate:nil];
}

- (void)webFrame:(WebFrame *)webFrame didFinishLoadWithError:(NSError *)error
{
    NPReason reason = NPRES_DONE;
    if (error != nil) {
        reason = [WebBaseNetscapePluginStream 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([[self webFrame] _frameLoader]->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];
                    {
                        KJS::JSLock::DropAllLocks dropAllLocks;
                        NPP_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.
            WebBaseNetscapePluginView *view = [frame _internalLoadDelegate];
            if (view != nil) {
                ASSERT([view isKindOfClass:[WebBaseNetscapePluginView class]]);
                [view webFrame:frame didFinishLoadWithReason:NPRES_USER_BREAK];
            }
            [pendingFrameLoads _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;

    NSString *target = nil;
    if (cTarget) {
        // Find the frame given the target string.
        target = (NSString *)CFStringCreateWithCString(kCFAllocatorDefault, cTarget, kCFStringEncodingWindowsLatin1);
    }
    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] != [[self webFrame] _frameLoader]->activeDocumentLoader() &&
        (!cTarget || [frame findFrameNamed:target] != frame)) {
        if (target)
            CFRelease(target);
        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 (!FrameLoader::canLoad(URL, core([self webFrame])->document()))
            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 != nil && target != nil && [frame findFrameNamed:target] != frame) {
            // For security reasons, only allow JS requests to be made on the frame that contains the plug-in.
            CFRelease(target);
            return NPERR_INVALID_PARAM;
        }
        
        WebPluginRequest *pluginRequest = [[WebPluginRequest alloc] initWithRequest:request frameName:target notifyData:notifyData sendNotification:sendNotification didStartFromUserGesture:currentEventIsUserGesture];
        [self performSelector:@selector(loadPluginRequest:) withObject:pluginRequest afterDelay:0];
        [pluginRequest release];
        if (target)
            CFRelease(target);
    } else {
        WebNetscapePluginStream *stream = [[WebNetscapePluginStream alloc] initWithRequest:request 
                                                                                    plugin:plugin 
                                                                                notifyData:notifyData 
                                                                          sendNotification:sendNotification];
        if (!stream)
            return NPERR_INVALID_URL;

        [streams addObject:stream];
        [stream start];
        [stream release];
    }
    
    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 || [WebBaseNetscapePluginStream ownerForStream:stream] != plugin) {
        LOG(Plugins, "Invalid NPStream passed to NPN_DestroyStream: %p", stream);
        return NPERR_INVALID_INSTANCE_ERROR;
    }
    
    WebBaseNetscapePluginStream *browserStream = static_cast<WebBaseNetscapePluginStream *>(stream->ndata);
    [browserStream cancelLoadAndDestroyStreamWithError:[browserStream errorForReason:reason]];
    
    return NPERR_NO_ERROR;
}

- (const char *)userAgent
{
    return [[[self webView] userAgentForURL:baseURL] UTF8String];
}

-(void)status:(const char *)message
{    
    if (!message) {
        LOG_ERROR("NPN_Status passed a NULL status message");
        return;
    }

    CFStringRef status = CFStringCreateWithCString(NULL, 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 setNeedsDisplayInRect:NSMakeRect(invalidRect->left, invalidRect->top,
        (float)invalidRect->right - invalidRect->left, (float)invalidRect->bottom - invalidRect->top)];
}

-(bool)isOpaque
{
    return YES;
}

- (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:
        case NPDrawingModelOpenGL:
        {
            CGRect cgRect = CGPathGetBoundingBox((NPCGRegion)invalidRegion);
            invalidRect = *(NSRect *)&cgRect;
        }
        break;
    
        default:
            ASSERT_NOT_REACHED();
        break;
    }
    
    [self setNeedsDisplayInRect:invalidRect];
}

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

- (NPError)getVariable:(NPNVariable)variable value:(void *)value
{
    switch (variable) {
        case NPNVWindowNPObject:
        {
            Frame* frame = core([self webFrame]);
            NPObject* windowScriptObject = frame ? frame->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 = (NPObject *)[element _NPObject];

            // 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 = TRUE;
            return NPERR_NO_ERROR;
        }
        
        default:
            break;
    }

    return NPERR_GENERIC_ERROR;
}

- (NPError)setVariable:(NPPVariable)variable value:(void *)value
{
    switch (variable) {
        case NPPVpluginWindowBool:
        {
            NPWindowType newWindowType = (value ? NPWindowTypeWindow : NPWindowTypeDrawable);

            // Redisplay if window type is changing (some drawing models can only have their windows set while updating).
            if (newWindowType != window.type)
                [self setNeedsDisplay:YES];
            
            window.type = newWindowType;
        }
        
        case NPPVpluginTransparentBool:
        {
            BOOL newTransparent = (value != 0);
            
            // Redisplay if transparency is changing
            if (isTransparent != newTransparent)
                [self setNeedsDisplay:YES];
            
            isTransparent = newTransparent;
            
            return NPERR_NO_ERROR;
        }
        
        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:
                case NPDrawingModelOpenGL:
                    drawingModel = newDrawingModel;
                    return NPERR_NO_ERROR;
                
                // Unsupported (or unknown) drawing models:
                default:
                    LOG(Plugins, "Plugin %@ uses unsupported drawing model: %d", pluginPackage, drawingModel);
                    return NPERR_GENERIC_ERROR;
            }
        }
        
        default:
            return NPERR_GENERIC_ERROR;
    }
}

@end

@implementation WebPluginRequest

- (id)initWithRequest:(NSURLRequest *)request frameName:(NSString *)frameName notifyData:(void *)notifyData sendNotification:(BOOL)sendNotification didStartFromUserGesture:(BOOL)currentEventIsUserGesture
{
    [super init];
    _didStartFromUserGesture = currentEventIsUserGesture;
    _request = [request retain];
    _frameName = [frameName retain];
    _notifyData = notifyData;
    _sendNotification = sendNotification;
    return self;
}

- (void)dealloc
{
    [_request release];
    [_frameName release];
    [super dealloc];
}

- (NSURLRequest *)request
{
    return _request;
}

- (NSString *)frameName
{
    return _frameName;
}

- (BOOL)isCurrentEventUserGesture
{
    return _didStartFromUserGesture;
}

- (BOOL)sendNotification
{
    return _sendNotification;
}

- (void *)notifyData
{
    return _notifyData;
}

@end

@implementation WebBaseNetscapePluginView (Internal)

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

    ASSERT(NPP_New);

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

    [[self class] setCurrentPluginView:self];
    NPError npErr = NPP_New((char *)[MIMEType cString], plugin, mode, argsCount, cAttributes, cValues, NULL);
    [[self class] setCurrentPluginView:nil];
    
    LOG(Plugins, "NPP_New: %d", npErr);
    return npErr;
}

- (void)_destroyPlugin
{
    NPError npErr;
    npErr = NPP_Destroy(plugin, NULL);
    LOG(Plugins, "NPP_Destroy: %d", npErr);
    
    if (Frame* frame = core([self webFrame]))
        frame->cleanupScriptObjectsForPlugin(self);
        
    free(plugin);
    plugin = NULL;
}

- (void)_viewHasMoved
{
    // All of the work this method does may safely be skipped if the view is not in a window.  When the view
    // is moved back into a window, everything should be set up correctly.
    if (![self window])
        return;
    
    if (drawingModel == NPDrawingModelOpenGL)
        [self _reshapeAGLWindow];

#ifndef NP_NO_QUICKDRAW
    if (drawingModel == NPDrawingModelQuickDraw)
        [self tellQuickTimeToChill];
#endif
    [self updateAndSetWindow];
    [self resetTrackingRect];
    
    // Check to see if the plugin view is completely obscured (scrolled out of view, for example).
    // For performance reasons, we send null events at a lower rate to plugins which are obscured.
    BOOL oldIsObscured = isCompletelyObscured;
    isCompletelyObscured = NSIsEmptyRect([self visibleRect]);
    if (isCompletelyObscured != oldIsObscured)
        [self restartNullEvents];
}

- (NSBitmapImageRep *)_printedPluginBitmap
{
#ifdef NP_NO_QUICKDRAW
    return nil;
#else
    // Cannot print plugins that do not implement NPP_Print
    if (!NPP_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];
    {
        KJS::JSLock::DropAllLocks dropAllLocks;
        NPP_Print(plugin, &npPrint);
    }
    [self didCallPlugInFunction];

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

- (BOOL)_createAGLContextIfNeeded
{
    ASSERT(drawingModel == NPDrawingModelOpenGL);

    // Do nothing (but indicate success) if the AGL context already exists
    if (aglContext)
        return YES;
        
    switch (window.type) {
        case NPWindowTypeWindow:
            return [self _createWindowedAGLContext];
        
        case NPWindowTypeDrawable:
            return [self _createWindowlessAGLContext];
        
        default:
            ASSERT_NOT_REACHED();
            return NO;
    }
}

- (BOOL)_createWindowedAGLContext
{
    ASSERT(drawingModel == NPDrawingModelOpenGL);
    ASSERT(!aglContext);
    ASSERT(!aglWindow);
    ASSERT([self window]);
    
    GLint pixelFormatAttributes[] = {
        AGL_RGBA,
        AGL_RED_SIZE, 8,
        AGL_GREEN_SIZE, 8,
        AGL_BLUE_SIZE, 8,
        AGL_ALPHA_SIZE, 8,
        AGL_DEPTH_SIZE, 32,
        AGL_WINDOW,
        AGL_ACCELERATED,
#ifndef BUILDING_ON_TIGER
        AGL_ALLOW_OFFLINE_RENDERERS,
#endif
        0
    };
    
    // Choose AGL pixel format
    AGLPixelFormat pixelFormat = aglChoosePixelFormat(NULL, 0, pixelFormatAttributes);
    if (!pixelFormat) {
        LOG_ERROR("Could not find suitable AGL pixel format: %s", aglErrorString(aglGetError()));
        return NO;
    }
    
    // Create AGL context
    aglContext = aglCreateContext(pixelFormat, NULL);
    aglDestroyPixelFormat(pixelFormat);
    if (!aglContext) {
        LOG_ERROR("Could not create AGL context: %s", aglErrorString(aglGetError()));
        return NO;
    }
    
    // Create AGL window
    aglWindow = [[NSWindow alloc] initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
    if (!aglWindow) {
        LOG_ERROR("Could not create window for AGL drawable.");
        return NO;
    }
    
    // AGL window should allow clicks to go through -- mouse events are tracked by WebCore
    [aglWindow setIgnoresMouseEvents:YES];
    
    // Make sure the window is not opaque -- windowed plug-ins cannot layer with other page elements
    [aglWindow setOpaque:YES];

    // Position and order in the AGL window
    [self _reshapeAGLWindow];

    // Attach the AGL context to its window
    GLboolean success;
#ifdef AGL_VERSION_3_0
    success = aglSetWindowRef(aglContext, (WindowRef)[aglWindow windowRef]);
#else
    success = aglSetDrawable(aglContext, (AGLDrawable)GetWindowPort((WindowRef)[aglWindow windowRef]));
#endif
    if (!success) {
        LOG_ERROR("Could not set AGL drawable: %s", aglErrorString(aglGetError()));
        aglDestroyContext(aglContext);
        aglContext = NULL;
        return NO;
    }
        
    return YES;
}

- (BOOL)_createWindowlessAGLContext
{
    ASSERT(drawingModel == NPDrawingModelOpenGL);
    ASSERT(!aglContext);
    ASSERT(!aglWindow);
    
    GLint pixelFormatAttributes[] = {
        AGL_RGBA,
        AGL_RED_SIZE, 8,
        AGL_GREEN_SIZE, 8,
        AGL_BLUE_SIZE, 8,
        AGL_ALPHA_SIZE, 8,
        AGL_DEPTH_SIZE, 32,
        AGL_OFFSCREEN,
#ifndef BUILDING_ON_TIGER
        AGL_ALLOW_OFFLINE_RENDERERS,
#endif
        0
    };

    // Choose AGL pixel format
    AGLPixelFormat pixelFormat = aglChoosePixelFormat(NULL, 0, pixelFormatAttributes);
    if (!pixelFormat) {
        LOG_ERROR("Could not find suitable AGL pixel format: %s", aglErrorString(aglGetError()));
        return NO;
    }
    
    // Create AGL context
    aglContext = aglCreateContext(pixelFormat, NULL);
    aglDestroyPixelFormat(pixelFormat);
    if (!aglContext) {
        LOG_ERROR("Could not create AGL context: %s", aglErrorString(aglGetError()));
        return NO;
    }
    
    // Create offscreen buffer for AGL context
    NSSize boundsSize = [self bounds].size;
    GLvoid *offscreenBuffer = (GLvoid *)malloc(static_cast<size_t>(boundsSize.width * boundsSize.height * 4));
    if (!offscreenBuffer) {
        LOG_ERROR("Could not allocate offscreen buffer for AGL context");
        aglDestroyContext(aglContext);
        aglContext = NULL;
        return NO;
    }
    
    // Attach AGL context to offscreen buffer
    CGLContextObj cglContext = [self _cglContext];
    CGLError error = CGLSetOffScreen(cglContext, static_cast<long>(boundsSize.width), static_cast<long>(boundsSize.height), static_cast<long>(boundsSize.width * 4), offscreenBuffer);
    if (error) {
        LOG_ERROR("Could not set offscreen buffer for AGL context: %d", error);
        aglDestroyContext(aglContext);
        aglContext = NULL;
        return NO;
    }
    
    return YES;
}

- (CGLContextObj)_cglContext
{
    ASSERT(drawingModel == NPDrawingModelOpenGL);

    CGLContextObj cglContext = NULL;
    if (!aglGetCGLContext(aglContext, (void **)&cglContext) || !cglContext)
        LOG_ERROR("Could not get CGL context for AGL context: %s", aglErrorString(aglGetError()));
        
    return cglContext;
}

- (BOOL)_getAGLOffscreenBuffer:(GLvoid **)outBuffer width:(GLsizei *)outWidth height:(GLsizei *)outHeight
{
    ASSERT(drawingModel == NPDrawingModelOpenGL);
    
    if (outBuffer)
        *outBuffer = NULL;
    if (outWidth)
        *outWidth = 0;
    if (outHeight)
        *outHeight = 0;
    
    // Only windowless plug-ins have offscreen buffers
    if (window.type != NPWindowTypeDrawable)
        return NO;
    
    CGLContextObj cglContext = [self _cglContext];
    if (!cglContext)
        return NO;
    
    GLsizei width, height;
    GLint rowBytes;
    void *offscreenBuffer = NULL;
    CGLError error = CGLGetOffScreen(cglContext, &width, &height, &rowBytes, &offscreenBuffer);
    if (error || !offscreenBuffer) {
        LOG_ERROR("Could not get offscreen buffer for AGL context: %d", error);
        return NO;
    }
    
    if (outBuffer)
        *outBuffer = offscreenBuffer;
    if (outWidth)
        *outWidth = width;
    if (outHeight)
        *outHeight = height;
    
    return YES;
}

- (void)_destroyAGLContext
{    
    ASSERT(drawingModel == NPDrawingModelOpenGL);

    if (!aglContext)
        return;

    if (aglContext) {
        // If this is a windowless plug-in, free its offscreen buffer
        GLvoid *offscreenBuffer;
        if ([self _getAGLOffscreenBuffer:&offscreenBuffer width:NULL height:NULL])
            free(offscreenBuffer);
        
        // Detach context from the AGL window
#ifdef AGL_VERSION_3_0
        aglSetWindowRef(aglContext, NULL);
#else
        aglSetDrawable(aglContext, NULL);
#endif
        
        // Destroy the context
        aglDestroyContext(aglContext);
        aglContext = NULL;
    }
    
    // Destroy the AGL window
    if (aglWindow) {
        [self _hideAGLWindow];
        aglWindow = nil;
    }
}

- (void)_reshapeAGLWindow
{
    ASSERT(drawingModel == NPDrawingModelOpenGL);
    
    if (!aglContext)
        return;

    switch (window.type) {
        case NPWindowTypeWindow:
        {
            if (!aglWindow)
                break;
                
            // The AGL window is being reshaped because the plugin view has moved.  Since the view has moved, it will soon redraw.
            // We want the AGL window to update at the same time as its underlying view.  So, we disable screen updates until the
            // plugin view's window flushes.
            NSWindow *browserWindow = [self window];
            ASSERT(browserWindow);
            [browserWindow disableScreenUpdatesUntilFlush];

            // Add the AGL window as a child of the main window if necessary
            if ([aglWindow parentWindow] != browserWindow)
                [browserWindow addChildWindow:aglWindow ordered:NSWindowAbove];
            
            // Update the AGL window frame
            NSRect aglWindowFrame = [self convertRect:[self visibleRect] toView:nil];
            aglWindowFrame.origin = [browserWindow convertBaseToScreen:aglWindowFrame.origin];
            [aglWindow setFrame:aglWindowFrame display:NO];
            
            // Update the AGL context
            aglUpdateContext(aglContext);
        }
        break;
        
        case NPWindowTypeDrawable:
        {
            // Get offscreen buffer; we can skip this step if we don't have one yet
            GLvoid *offscreenBuffer;
            GLsizei width, height;
            if (![self _getAGLOffscreenBuffer:&offscreenBuffer width:&width height:&height] || !offscreenBuffer)
                break;
            
            // Don't resize the offscreen buffer if it's already the same size as the view bounds
            NSSize boundsSize = [self bounds].size;
            if (boundsSize.width == width && boundsSize.height == height)
                break;
            
            // Resize the offscreen buffer
            offscreenBuffer = realloc(offscreenBuffer, static_cast<size_t>(boundsSize.width * boundsSize.height * 4));
            if (!offscreenBuffer) {
                LOG_ERROR("Could not allocate offscreen buffer for AGL context");
                break;
            }

            // Update the offscreen 
            CGLContextObj cglContext = [self _cglContext];
            CGLError error = CGLSetOffScreen(cglContext, static_cast<long>(boundsSize.width), static_cast<long>(boundsSize.height), static_cast<long>(boundsSize.width * 4), offscreenBuffer);
            if (error) {
                LOG_ERROR("Could not set offscreen buffer for AGL context: %d", error);
                break;
            }

            // Update the AGL context
            aglUpdateContext(aglContext);
        }
        break;
        
        default:
            ASSERT_NOT_REACHED();
        break;
    }
}

- (void)_hideAGLWindow
{
    ASSERT(drawingModel == NPDrawingModelOpenGL);
    
    if (!aglWindow)
        return;
    
    // aglWindow should only be set for a windowed OpenGL plug-in
    ASSERT(window.type == NPWindowTypeWindow);
    
    NSWindow *parentWindow = [aglWindow parentWindow];
    if (parentWindow) {
        // Disable screen updates so that this AGL window orders out atomically with other plugins' AGL windows
        [parentWindow disableScreenUpdatesUntilFlush];
        ASSERT(parentWindow == [self window]);
        [parentWindow removeChildWindow:aglWindow];
    }
    [aglWindow orderOut:nil];
}

- (NSImage *)_aglOffscreenImageForDrawingInRect:(NSRect)drawingInRect
{
    ASSERT(drawingModel == NPDrawingModelOpenGL);

    CGLContextObj cglContext = [self _cglContext];
    if (!cglContext)
        return nil;

    // Get the offscreen buffer
    GLvoid *offscreenBuffer;
    GLsizei width, height;
    if (![self _getAGLOffscreenBuffer:&offscreenBuffer width:&width height:&height])
        return nil;

    unsigned char *plane = (unsigned char *)offscreenBuffer;

#if defined(__i386__) || defined(__x86_64__)
    // Make rect inside the offscreen buffer because we're about to directly modify the bits inside drawingInRect
    NSRect rect = NSIntegralRect(NSIntersectionRect(drawingInRect, NSMakeRect(0, 0, width, height)));

    // The offscreen buffer, being an OpenGL framebuffer, is in BGRA format on x86.  We need to swap the blue and red channels before
    // wrapping the buffer in an NSBitmapImageRep, which only supports RGBA and ARGB.
    // On PowerPC, the OpenGL framebuffer is in ARGB format.  Since that is a format that NSBitmapImageRep supports, all that is
    // needed on PowerPC is to pass the NSAlphaFirstBitmapFormat flag when creating the NSBitmapImageRep.  On x86, we need to swap the
    // framebuffer color components such that they are in ARGB order, as they are on PowerPC.
    // If only a small region of the plug-in is being redrawn, then it would be a waste to convert the entire image from BGRA to ARGB.
    // Since we know what region of the image will ultimately be drawn to screen (drawingInRect), we restrict the channel swapping to
    // just that region within the offscreen buffer.
    if (!WebConvertBGRAToARGB(plane, width * 4, (int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height))
        return nil;
#endif /* defined(__i386__) || defined(__x86_64__) */
    
    NSBitmapImageRep *aglBitmap = [[NSBitmapImageRep alloc]
        initWithBitmapDataPlanes:&plane
                      pixelsWide:width
                      pixelsHigh:height
                   bitsPerSample:8
                 samplesPerPixel:4
                        hasAlpha:YES
                        isPlanar:NO
                  colorSpaceName:NSDeviceRGBColorSpace
                    bitmapFormat:NSAlphaFirstBitmapFormat
                     bytesPerRow:width * 4
                    bitsPerPixel:32];
    if (!aglBitmap) {
        LOG_ERROR("Could not create bitmap for AGL offscreen buffer");
        return nil;
    }

    // Wrap the bitmap in an NSImage.  This allocation isn't very expensive -- the actual image data is already in the bitmap rep
    NSImage *aglImage = [[[NSImage alloc] initWithSize:[aglBitmap size]] autorelease];
    [aglImage addRepresentation:aglBitmap];
    [aglBitmap release];
    
    return aglImage;
}

- (void)_redeliverStream
{
    if ([self dataSource] && [self 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];
                else
                    [self pluginViewFinishedLoading:self];
            }
        }
    }
}

@end

@implementation NSData (PluginExtras)

- (BOOL)_web_startsWithBlankLine
{
    return [self length] > 0 && ((const char *)[self bytes])[0] == '\n';
}


- (NSInteger)_web_locationAfterFirstBlankLine
{
    const char *bytes = (const char *)[self bytes];
    unsigned length = [self length];
    
    unsigned i;
    for (i = 0; i < length - 4; i++) {
        
        //  Support for Acrobat. It sends "\n\n".
        if (bytes[i] == '\n' && bytes[i+1] == '\n') {
            return i+2;
        }
        
        // Returns the position after 2 CRLF's or 1 CRLF if it is the first line.
        if (bytes[i] == '\r' && bytes[i+1] == '\n') {
            i += 2;
            if (i == 2) {
                return i;
            } else if (bytes[i] == '\n') {
                // Support for Director. It sends "\r\n\n" (3880387).
                return i+1;
            } else if (bytes[i] == '\r' && bytes[i+1] == '\n') {
                // Support for Flash. It sends "\r\n\r\n" (3758113).
                return i+2;
            }
        }
    }
    return NSNotFound;
}

@end
#endif
