/*
 * Copyright (C) 2005-2017 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 Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#if ENABLE(NETSCAPE_PLUGIN_API)

#import "WebBaseNetscapePluginView.h"

#import "NetworkStorageSessionMap.h"
#import "WebFrameInternal.h"
#import "WebKitLogging.h"
#import "WebKitNSStringExtras.h"
#import "WebNSURLExtras.h"
#import "WebNSURLRequestExtras.h"
#import "WebView.h"
#import "WebViewInternal.h"
#import <JavaScriptCore/InitializeThreading.h>
#import <WebCore/AuthenticationMac.h>
#import <WebCore/BitmapImage.h>
#import <WebCore/Credential.h>
#import <WebCore/CredentialStorage.h>
#import <WebCore/Document.h>
#import <WebCore/Element.h>
#import <WebCore/Frame.h>
#import <WebCore/FrameLoader.h>
#import <WebCore/HTMLPlugInElement.h>
#import <WebCore/NetworkStorageSession.h>
#import <WebCore/Page.h>
#import <WebCore/ProtectionSpace.h>
#import <WebCore/RenderEmbeddedObject.h>
#import <WebCore/RenderView.h>
#import <WebCore/SecurityOrigin.h>
#import <WebKitLegacy/DOMPrivate.h>
#import <pal/spi/cg/CoreGraphicsSPI.h>
#import <wtf/Assertions.h>
#import <wtf/MainThread.h>
#import <wtf/RunLoop.h>
#import <wtf/text/CString.h>

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

using namespace WebCore;

@implementation WebBaseNetscapePluginView

+ (void)initialize
{
    JSC::initializeThreading();
    WTF::initializeMainThreadToProcessMainThread();
    RunLoop::initializeMainRunLoop();
    WebKit::sendUserChangeNotifications();
}

- (id)initWithFrame:(NSRect)frame
      pluginPackage:(WebNetscapePluginPackage *)pluginPackage
                URL:(NSURL *)URL
            baseURL:(NSURL *)baseURL
           MIMEType:(NSString *)MIME
      attributeKeys:(NSArray *)keys
    attributeValues:(NSArray *)values
       loadManually:(BOOL)loadManually
            element:(RefPtr<WebCore::HTMLPlugInElement>&&)element
{
    self = [super initWithFrame:frame];
    if (!self)
        return nil;
    
    _pluginPackage = pluginPackage;
    _element = WTFMove(element);
    _sourceURL = adoptNS([URL copy]);
    _baseURL = adoptNS([baseURL copy]);
    _MIMEType = adoptNS([MIME copy]);

    [self setAttributeKeys:keys andValues:values];

    if (loadManually)
        _mode = NP_FULL;
    else
        _mode = NP_EMBED;
    
    _loadManually = loadManually;
    return self;
}

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

    [super dealloc];
}

- (WebNetscapePluginPackage *)pluginPackage
{
    return _pluginPackage.get();
}
    
- (BOOL)isFlipped
{
    return YES;
}

- (NSURL *)URLWithCString:(const char *)cString
{
    if (!cString)
        return nil;
    
    NSString *string = [NSString stringWithCString:cString encoding:NSISOLatin1StringEncoding];
    string = [string stringByReplacingOccurrencesOfString:@"\r" withString:@""];
    string = [string stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    return [NSURL _web_URLWithDataAsString:string relativeToURL:_baseURL.get()];
}

- (NSMutableURLRequest *)requestWithURLCString:(const char *)URLCString
{
    NSURL *URL = [self URLWithCString:URLCString];
    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;
}

// Methods that subclasses must override
- (void)setAttributeKeys:(NSArray *)keys andValues:(NSArray *)values
{
    // This needs to be overridden by subclasses.
}

- (void)handleMouseMoved:(NSEvent *)event
{
    // This needs to be overridden by subclasses.
}

- (void)handleMouseEntered:(NSEvent *)event
{
    // This needs to be overridden by subclasses.
}

- (void)handleMouseExited:(NSEvent *)event
{
    // This needs to be overridden by subclasses.
}

- (void)focusChanged
{
    // This needs to be overridden by subclasses.
}

- (void)windowFocusChanged:(BOOL)hasFocus
{
    // This needs to be overridden by subclasses.
}

- (BOOL)createPlugin
{
    // This needs to be overridden by subclasses.
    return NO;
}

- (void)loadStream
{
    // This needs to be overridden by subclasses.
}

- (BOOL)shouldStop
{
    // This needs to be overridden by subclasses.
    return YES;
}

- (void)destroyPlugin
{
    // This needs to be overridden by subclasses.
}

- (void)updateAndSetWindow
{
    // This needs to be overridden by subclasses.
}

- (void)sendModifierEventWithKeyCode:(int)keyCode character:(char)character
{
    // This needs to be overridden by subclasses.
}

- (void)privateBrowsingModeDidChange
{
}

- (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)stopTimers
{
    _shouldFireTimers = NO;
}

- (void)startTimers
{
    _shouldFireTimers = YES;
}

- (void)restartTimers
{
    [self stopTimers];
    
    if (!_isStarted || [[self window] isMiniaturized])
        return;
    
    [self startTimers];
}

- (NSRect)_windowClipRect
{
    auto* renderer = _element->renderer();
    if (!is<RenderEmbeddedObject>(renderer))
        return NSZeroRect;
    return downcast<RenderEmbeddedObject>(*renderer).windowClipRect();
}

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

- (BOOL)acceptsFirstResponder
{
    return YES;
}

- (void)sendActivateEvent:(BOOL)activate
{
    if (!_isStarted)
        return;
    
    [self windowFocusChanged:activate];
}

- (void)setHasFocus:(BOOL)flag
{
    if (!_isStarted)
        return;
    
    if (_hasFocus == flag)
        return;
    
    _hasFocus = flag;
    
    [self focusChanged];
}

- (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];
}

- (void)start
{
    ASSERT([self currentWindow]);
    
    if (_isStarted)
        return;
    
    if (_triedAndFailedToCreatePlugin)
        return;
    
    ASSERT([self webView]);
    
    if (![[[self webView] preferences] arePlugInsEnabled])
        return;
   
    Frame* frame = core([self webFrame]);
    if (!frame)
        return;
    Page* page = frame->page();
    if (!page)
        return;
    
    bool wasDeferring = page->defersLoading();
    if (!wasDeferring)
        page->setDefersLoading(true);

    BOOL result = [self createPlugin];
    
    if (!wasDeferring)
        page->setDefersLoading(false);

    if (!result) {
        _triedAndFailedToCreatePlugin = YES;
        return;
    }
    
    _isStarted = YES;

    [[self webView] addPluginInstanceView:self];

    if ([self currentWindow])
        [self updateAndSetWindow];

    if ([self window]) {
        [self addWindowObservers];
        if ([[self window] isKeyWindow]) {
            [self sendActivateEvent:YES];
        }
        [self restartTimers];
    }
    
    [self resetTrackingRect];
    
    [self loadStream];
}

- (void)stop
{
    if (![self shouldStop])
        return;
    
    [self removeTrackingRect];
    
    if (!_isStarted)
        return;

    _isStarted = NO;
    
    [[self webView] removePluginInstanceView:self];
    
    // Stop the timers
    [self stopTimers];
    
    // Stop notifications and callbacks.
    [self removeWindowObservers];
    
    [self destroyPlugin];
}

- (BOOL)shouldClipOutPlugin
{
    NSWindow *window = [self window];
    return !window || [window isMiniaturized] || [NSApp isHidden] || ![self isDescendantOf:[[self window] contentView]] || [self isHiddenOrHasHiddenAncestor];
}

- (BOOL)supportsSnapshotting
{
    return [_pluginPackage.get() supportsSnapshotting];
}

- (void)cacheSnapshot
{
    NSSize boundsSize = [self bounds].size;
    if (!boundsSize.height || !boundsSize.width)
        return;

    NSImage *snapshot = [[NSImage alloc] initWithSize:boundsSize];
        
    _snapshotting = YES;
    [snapshot lockFocus];
    [self drawRect:[self bounds]];
    [snapshot unlockFocus];
    _snapshotting = NO;
    
    _cachedSnapshot = adoptNS(snapshot);
}

- (void)clearCachedSnapshot
{
    _cachedSnapshot.clear();
}

- (void)viewWillMoveToWindow:(NSWindow *)newWindow
{
    // 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) {
        if ([[self webView] hostWindow]) {
            // View will be moved out of the actual window but it still has a host window.
            [self stopTimers];
        } else {
            // View will have no associated windows.
            [self stop];
            
            // Stop observing WebPreferencesChangedInternalNotification -- 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:WebPreferencesChangedInternalNotification 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 WebPreferencesChangedInternalNotification -- 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:WebPreferencesChangedInternalNotification object:nil];
    }
}

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

        _isPrivateBrowsingEnabled = [[[self webView] preferences] privateBrowsingEnabled];
        
        // View moved to an actual window. Start it if not already started.
        [self start];

        // Starting the plug-in can result in it removing itself from the window so we need to ensure that we're still in
        // place before doing anything that requires a window.
        if ([self window]) {
            [self restartTimers];
            [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 WebPreferencesChangedInternalNotification observer -- we will observe once again when we move back into the window
        [[NSNotificationCenter defaultCenter] removeObserver:self name:WebPreferencesChangedInternalNotification object:nil];
    }
}

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

// MARK: NOTIFICATIONS

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

- (void)windowBecameKey:(NSNotification *)notification
{
    [self sendActivateEvent:YES];
    [self invalidatePluginContentRect:[self bounds]];
    [self restartTimers];
}

- (void)windowResignedKey:(NSNotification *)notification
{
    [self sendActivateEvent:NO];
    [self invalidatePluginContentRect:[self bounds]];
    [self restartTimers];
}

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

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

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

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

- (void)preferencesHaveChanged:(NSNotification *)notification
{
    WebPreferences *preferences = [[self webView] preferences];

    if ([notification object] != preferences)
        return;
    
    BOOL arePlugInsEnabled = [preferences arePlugInsEnabled];
    if (_isStarted != arePlugInsEnabled) {
        if (arePlugInsEnabled) {
            if ([self currentWindow]) {
                [self start];
            }
        } else {
            [self stop];
            [self invalidatePluginContentRect:[self bounds]];
        }
    }
    
    BOOL isPrivateBrowsingEnabled = [preferences privateBrowsingEnabled];
    if (isPrivateBrowsingEnabled != _isPrivateBrowsingEnabled) {
        _isPrivateBrowsingEnabled = isPrivateBrowsingEnabled;
        [self privateBrowsingModeDidChange];
    }
}

IGNORE_WARNINGS_BEGIN("deprecated-implementations")
- (void)renewGState
IGNORE_WARNINGS_END
{
    [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.
    
    // 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;
    
    [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 restartTimers];
}

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

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

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

- (WebFrame *)webFrame
{
    return kit(_element->document().frame());
}

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

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

- (WebCore::HTMLPlugInElement*)element
{
    return _element.get();
}

- (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'];
}

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


- (BOOL)convertFromX:(double)sourceX andY:(double)sourceY space:(NPCoordinateSpace)sourceSpace
                 toX:(double *)destX andY:(double *)destY space:(NPCoordinateSpace)destSpace
{
    // Nothing to do
    if (sourceSpace == destSpace) {
        if (destX)
            *destX = sourceX;
        if (destY)
            *destY = sourceY;
        return YES;
    }
    
    NSPoint sourcePoint = NSMakePoint(sourceX, sourceY);
    
    NSPoint sourcePointInScreenSpace;
    
    // First convert to screen space
    switch (sourceSpace) {
        case NPCoordinateSpacePlugin:
            sourcePointInScreenSpace = [self convertPoint:sourcePoint toView:nil];
            ALLOW_DEPRECATED_DECLARATIONS_BEGIN
            sourcePointInScreenSpace = [[self currentWindow] convertBaseToScreen:sourcePointInScreenSpace];
            ALLOW_DEPRECATED_DECLARATIONS_END
            break;
            
        case NPCoordinateSpaceWindow:
            ALLOW_DEPRECATED_DECLARATIONS_BEGIN
            sourcePointInScreenSpace = [[self currentWindow] convertBaseToScreen:sourcePoint];
            ALLOW_DEPRECATED_DECLARATIONS_END
            break;
            
        case NPCoordinateSpaceFlippedWindow:
            sourcePoint.y = [[self currentWindow] frame].size.height - sourcePoint.y;
            ALLOW_DEPRECATED_DECLARATIONS_BEGIN
            sourcePointInScreenSpace = [[self currentWindow] convertBaseToScreen:sourcePoint];
            ALLOW_DEPRECATED_DECLARATIONS_END
            break;
            
        case NPCoordinateSpaceScreen:
            sourcePointInScreenSpace = sourcePoint;
            break;
            
        case NPCoordinateSpaceFlippedScreen:
            sourcePoint.y = [(NSScreen *)[[NSScreen screens] objectAtIndex:0] frame].size.height - sourcePoint.y;
            sourcePointInScreenSpace = sourcePoint;
            break;
        default:
            return FALSE;
    }
    
    NSPoint destPoint;
    
    // Then convert back to the destination space
    switch (destSpace) {
        case NPCoordinateSpacePlugin:
            ALLOW_DEPRECATED_DECLARATIONS_BEGIN
            destPoint = [[self currentWindow] convertScreenToBase:sourcePointInScreenSpace];
            ALLOW_DEPRECATED_DECLARATIONS_END
            destPoint = [self convertPoint:destPoint fromView:nil];
            break;
            
        case NPCoordinateSpaceWindow:
            ALLOW_DEPRECATED_DECLARATIONS_BEGIN
            destPoint = [[self currentWindow] convertScreenToBase:sourcePointInScreenSpace];
            ALLOW_DEPRECATED_DECLARATIONS_END
            break;
            
        case NPCoordinateSpaceFlippedWindow:
            ALLOW_DEPRECATED_DECLARATIONS_BEGIN
            destPoint = [[self currentWindow] convertScreenToBase:sourcePointInScreenSpace];
            ALLOW_DEPRECATED_DECLARATIONS_END
            destPoint.y = [[self currentWindow] frame].size.height - destPoint.y;
            break;
            
        case NPCoordinateSpaceScreen:
            destPoint = sourcePointInScreenSpace;
            break;
            
        case NPCoordinateSpaceFlippedScreen:
            destPoint = sourcePointInScreenSpace;
            destPoint.y = [(NSScreen *)[[NSScreen screens] objectAtIndex:0] frame].size.height - destPoint.y;
            break;
            
        default:
            return FALSE;
    }
    
    if (destX)
        *destX = destPoint.x;
    if (destY)
        *destY = destPoint.y;
    
    return TRUE;
}


- (void)invalidatePluginContentRect:(NSRect)rect
{
    auto* renderer = _element->renderer();
    if (!is<RenderEmbeddedObject>(renderer))
        return;
    auto& object = downcast<RenderEmbeddedObject>(*renderer);
    IntRect contentRect(rect);
    contentRect.move(object.borderLeft() + object.paddingLeft(), object.borderTop() + object.paddingTop());
    object.repaintRectangle(contentRect);
}

- (NSRect)actualVisibleRectInWindow
{
    auto* renderer = _element->renderer();
    if (!is<RenderEmbeddedObject>(renderer))
        return NSZeroRect;
    auto& object = downcast<RenderEmbeddedObject>(*renderer);
    auto widgetRect = object.view().frameView().contentsToWindow(object.pixelSnappedAbsoluteClippedOverflowRect());
    return intersection(object.windowClipRect(), widgetRect);
}

- (CALayer *)pluginLayer
{
    // This needs to be overridden by subclasses.
    return nil;
}

- (BOOL)getFormValue:(NSString **)value
{
    // This needs to be overridden by subclasses.
    return false;
}

@end

namespace WebKit {

bool getAuthenticationInfo(const char* protocolStr, const char* hostStr, int32_t port, const char* schemeStr, const char* realmStr, CString& username, CString& password)
{
    if (!equalLettersIgnoringASCIICase(protocolStr, "http") && !equalLettersIgnoringASCIICase(protocolStr, "https"))
        return false;

    NSString *host = [NSString stringWithUTF8String:hostStr];
    if (!hostStr)
        return false;
    
    NSString *protocol = [NSString stringWithUTF8String:protocolStr];
    if (!protocol)
        return false;
    
    NSString *realm = [NSString stringWithUTF8String:realmStr];
    if (!realm)
        return NPERR_GENERIC_ERROR;
    
    NSString *authenticationMethod = NSURLAuthenticationMethodDefault;
    if (equalLettersIgnoringASCIICase(protocolStr, "http")) {
        if (equalLettersIgnoringASCIICase(schemeStr, "basic"))
            authenticationMethod = NSURLAuthenticationMethodHTTPBasic;
        else if (equalLettersIgnoringASCIICase(schemeStr, "digest"))
            authenticationMethod = NSURLAuthenticationMethodHTTPDigest;
    }
    
    RetainPtr<NSURLProtectionSpace> protectionSpace = adoptNS([[NSURLProtectionSpace alloc] initWithHost:host port:port protocol:protocol realm:realm authenticationMethod:authenticationMethod]);
    
    NSURLCredential *credential = NetworkStorageSessionMap::defaultStorageSession().credentialStorage().get(emptyString(), ProtectionSpace(protectionSpace.get())).nsCredential();
    if (!credential)
        credential = [[NSURLCredentialStorage sharedCredentialStorage] defaultCredentialForProtectionSpace:protectionSpace.get()];
    if (!credential)
        return false;
  
    if (![credential hasPassword])
        return false;
    
    username = [[credential user] UTF8String];
    password = [[credential password] UTF8String];
    
    return true;
}

void sendUserChangeNotifications()
{
    auto consoleConnectionChangeNotifyProc = [](CGSNotificationType type, CGSNotificationData, CGSByteCount, CGSNotificationArg) {
        NSString *notificationName = nil;
        if (type == kCGSessionConsoleConnect)
            notificationName = LoginWindowDidSwitchToUserNotification;
        else if (type == kCGSessionConsoleDisconnect)
            notificationName = LoginWindowDidSwitchFromUserNotification;
        else
            ASSERT_NOT_REACHED();
        [[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:nil];
    };

    CGSRegisterNotifyProc(consoleConnectionChangeNotifyProc, kCGSessionConsoleConnect, nullptr);
    CGSRegisterNotifyProc(consoleConnectionChangeNotifyProc, kCGSessionConsoleDisconnect, nullptr);
}

} // namespace WebKit

#endif //  ENABLE(NETSCAPE_PLUGIN_API)

