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

    bool wasDeferring = page->defersLoading();
    if (!wasDeferring)
        page->setDefersLoading(true);

    // 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);
    }

    if (!wasDeferring)
        page->setDefersLoading(false);
            
    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;
        }
    }
        
    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
