74e79c0de4bc1afe0e1863c203089d67dbf8e4f2
[WebKit-https.git] / Source / WebKitLegacy / mac / Plugins / WebBaseNetscapePluginView.mm
1 /*
2  * Copyright (C) 2005-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer. 
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution. 
13  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission. 
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #if ENABLE(NETSCAPE_PLUGIN_API)
30
31 #import "WebBaseNetscapePluginView.h"
32
33 #import "WebFrameInternal.h"
34 #import "WebKitLogging.h"
35 #import "WebKitNSStringExtras.h"
36 #import "WebNSURLExtras.h"
37 #import "WebNSURLRequestExtras.h"
38 #import "WebView.h"
39 #import "WebViewInternal.h"
40 #import <WebCore/AuthenticationMac.h>
41 #import <WebCore/BitmapImage.h>
42 #import <WebCore/Credential.h>
43 #import <WebCore/CredentialStorage.h>
44 #import <WebCore/Document.h>
45 #import <WebCore/Element.h>
46 #import <WebCore/Frame.h>
47 #import <WebCore/FrameLoader.h>
48 #import <WebCore/HTMLPlugInElement.h>
49 #import <WebCore/Page.h>
50 #import <WebCore/ProtectionSpace.h>
51 #import <WebCore/RenderEmbeddedObject.h>
52 #import <WebCore/RenderView.h>
53 #import <WebCore/SecurityOrigin.h>
54 #import <WebKitLegacy/DOMPrivate.h>
55 #import <pal/spi/cg/CoreGraphicsSPI.h>
56 #import <runtime/InitializeThreading.h>
57 #import <wtf/Assertions.h>
58 #import <wtf/MainThread.h>
59 #import <wtf/RunLoop.h>
60 #import <wtf/text/CString.h>
61
62 #define LoginWindowDidSwitchFromUserNotification    @"WebLoginWindowDidSwitchFromUserNotification"
63 #define LoginWindowDidSwitchToUserNotification      @"WebLoginWindowDidSwitchToUserNotification"
64
65 using namespace WebCore;
66
67 @implementation WebBaseNetscapePluginView
68
69 + (void)initialize
70 {
71     JSC::initializeThreading();
72     WTF::initializeMainThreadToProcessMainThread();
73     RunLoop::initializeMainRunLoop();
74     WebKit::sendUserChangeNotifications();
75 }
76
77 - (id)initWithFrame:(NSRect)frame
78       pluginPackage:(WebNetscapePluginPackage *)pluginPackage
79                 URL:(NSURL *)URL
80             baseURL:(NSURL *)baseURL
81            MIMEType:(NSString *)MIME
82       attributeKeys:(NSArray *)keys
83     attributeValues:(NSArray *)values
84        loadManually:(BOOL)loadManually
85             element:(RefPtr<WebCore::HTMLPlugInElement>&&)element
86 {
87     self = [super initWithFrame:frame];
88     if (!self)
89         return nil;
90     
91     _pluginPackage = pluginPackage;
92     _element = WTFMove(element);
93     _sourceURL = adoptNS([URL copy]);
94     _baseURL = adoptNS([baseURL copy]);
95     _MIMEType = adoptNS([MIME copy]);
96
97     // Enable "kiosk mode" when instantiating the QT plug-in inside of Dashboard. See <rdar://problem/6878105>
98     if ([[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.dashboard.client"] &&
99         [_pluginPackage.get() bundleIdentifier] == "com.apple.QuickTime Plugin.plugin") {
100         RetainPtr<NSMutableArray> mutableKeys = adoptNS([keys mutableCopy]);
101         RetainPtr<NSMutableArray> mutableValues = adoptNS([values mutableCopy]);
102
103         [mutableKeys.get() addObject:@"kioskmode"];
104         [mutableValues.get() addObject:@"true"];
105         [self setAttributeKeys:mutableKeys.get() andValues:mutableValues.get()];
106     } else
107          [self setAttributeKeys:keys andValues:values];
108
109     if (loadManually)
110         _mode = NP_FULL;
111     else
112         _mode = NP_EMBED;
113     
114     _loadManually = loadManually;
115     return self;
116 }
117
118 - (void)dealloc
119 {
120     ASSERT(!_isStarted);
121
122     [super dealloc];
123 }
124
125 - (WebNetscapePluginPackage *)pluginPackage
126 {
127     return _pluginPackage.get();
128 }
129     
130 - (BOOL)isFlipped
131 {
132     return YES;
133 }
134
135 - (NSURL *)URLWithCString:(const char *)URLCString
136 {
137     if (!URLCString)
138         return nil;
139     
140     CFStringRef string = CFStringCreateWithCString(kCFAllocatorDefault, URLCString, kCFStringEncodingISOLatin1);
141     ASSERT(string); // All strings should be representable in ISO Latin 1
142     
143     NSString *URLString = [(NSString *)string _web_stringByStrippingReturnCharacters];
144     NSURL *URL = [NSURL _web_URLWithDataAsString:URLString relativeToURL:_baseURL.get()];
145     CFRelease(string);
146     if (!URL)
147         return nil;
148     
149     return URL;
150 }
151
152 - (NSMutableURLRequest *)requestWithURLCString:(const char *)URLCString
153 {
154     NSURL *URL = [self URLWithCString:URLCString];
155     if (!URL)
156         return nil;
157     
158     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
159     Frame* frame = core([self webFrame]);
160     if (!frame)
161         return nil;
162     [request _web_setHTTPReferrer:frame->loader().outgoingReferrer()];
163     return request;
164 }
165
166 // Methods that subclasses must override
167 - (void)setAttributeKeys:(NSArray *)keys andValues:(NSArray *)values
168 {
169     // This needs to be overridden by subclasses.
170 }
171
172 - (void)handleMouseMoved:(NSEvent *)event
173 {
174     // This needs to be overriden by subclasses.
175 }
176
177 - (void)handleMouseEntered:(NSEvent *)event
178 {
179     // This needs to be overridden by subclasses.
180 }
181
182 - (void)handleMouseExited:(NSEvent *)event
183 {
184     // This needs to be overridden by subclasses.
185 }
186
187 - (void)focusChanged
188 {
189     // This needs to be overridden by subclasses.
190 }
191
192 - (void)windowFocusChanged:(BOOL)hasFocus
193 {
194     // This needs to be overridden by subclasses.
195 }
196
197 - (BOOL)createPlugin
198 {
199     // This needs to be overridden by subclasses.
200     return NO;
201 }
202
203 - (void)loadStream
204 {
205     // This needs to be overridden by subclasses.
206 }
207
208 - (BOOL)shouldStop
209 {
210     // This needs to be overridden by subclasses.
211     return YES;
212 }
213
214 - (void)destroyPlugin
215 {
216     // This needs to be overridden by subclasses.
217 }
218
219 - (void)updateAndSetWindow
220 {
221     // This needs to be overridden by subclasses.
222 }
223
224 - (void)sendModifierEventWithKeyCode:(int)keyCode character:(char)character
225 {
226     // This needs to be overridden by subclasses.
227 }
228
229 - (void)privateBrowsingModeDidChange
230 {
231 }
232
233 - (void)removeTrackingRect
234 {
235     if (_trackingTag) {
236         [self removeTrackingRect:_trackingTag];
237         _trackingTag = 0;
238         
239         // Do the following after setting trackingTag to 0 so we don't re-enter.
240         
241         // Balance the retain in resetTrackingRect. Use autorelease in case we hold 
242         // the last reference to the window during tear-down, to avoid crashing AppKit. 
243         [[self window] autorelease];
244     }
245 }
246
247 - (void)resetTrackingRect
248 {
249     [self removeTrackingRect];
250     if (_isStarted) {
251         // Retain the window so that removeTrackingRect can work after the window is closed.
252         [[self window] retain];
253         _trackingTag = [self addTrackingRect:[self bounds] owner:self userData:nil assumeInside:NO];
254     }
255 }
256
257 - (void)stopTimers
258 {
259     _shouldFireTimers = NO;
260 }
261
262 - (void)startTimers
263 {
264     _shouldFireTimers = YES;
265 }
266
267 - (void)restartTimers
268 {
269     [self stopTimers];
270     
271     if (!_isStarted || [[self window] isMiniaturized])
272         return;
273     
274     [self startTimers];
275 }
276
277 - (NSRect)_windowClipRect
278 {
279     auto* renderer = _element->renderer();
280     if (!is<RenderEmbeddedObject>(renderer))
281         return NSZeroRect;
282     return downcast<RenderEmbeddedObject>(*renderer).windowClipRect();
283 }
284
285 - (NSRect)visibleRect
286 {
287     // WebCore may impose an additional clip (via CSS overflow or clip properties).  Fetch
288     // that clip now.    
289     return NSIntersectionRect([self convertRect:[self _windowClipRect] fromView:nil], [super visibleRect]);
290 }
291
292 - (BOOL)acceptsFirstResponder
293 {
294     return YES;
295 }
296
297 - (void)sendActivateEvent:(BOOL)activate
298 {
299     if (!_isStarted)
300         return;
301     
302     [self windowFocusChanged:activate];
303 }
304
305 - (void)setHasFocus:(BOOL)flag
306 {
307     if (!_isStarted)
308         return;
309     
310     if (_hasFocus == flag)
311         return;
312     
313     _hasFocus = flag;
314     
315     [self focusChanged];
316 }
317
318 - (void)addWindowObservers
319 {
320     ASSERT([self window]);
321     
322     NSWindow *theWindow = [self window];
323     
324     NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
325     [notificationCenter addObserver:self selector:@selector(windowWillClose:) 
326                                name:NSWindowWillCloseNotification object:theWindow]; 
327     [notificationCenter addObserver:self selector:@selector(windowBecameKey:)
328                                name:NSWindowDidBecomeKeyNotification object:theWindow];
329     [notificationCenter addObserver:self selector:@selector(windowResignedKey:)
330                                name:NSWindowDidResignKeyNotification object:theWindow];
331     [notificationCenter addObserver:self selector:@selector(windowDidMiniaturize:)
332                                name:NSWindowDidMiniaturizeNotification object:theWindow];
333     [notificationCenter addObserver:self selector:@selector(windowDidDeminiaturize:)
334                                name:NSWindowDidDeminiaturizeNotification object:theWindow];
335     
336     [notificationCenter addObserver:self selector:@selector(loginWindowDidSwitchFromUser:)
337                                name:LoginWindowDidSwitchFromUserNotification object:nil];
338     [notificationCenter addObserver:self selector:@selector(loginWindowDidSwitchToUser:)
339                                name:LoginWindowDidSwitchToUserNotification object:nil];
340 }
341
342 - (void)removeWindowObservers
343 {
344     NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
345     [notificationCenter removeObserver:self name:NSWindowWillCloseNotification        object:nil]; 
346     [notificationCenter removeObserver:self name:NSWindowDidBecomeKeyNotification     object:nil];
347     [notificationCenter removeObserver:self name:NSWindowDidResignKeyNotification     object:nil];
348     [notificationCenter removeObserver:self name:NSWindowDidMiniaturizeNotification   object:nil];
349     [notificationCenter removeObserver:self name:NSWindowDidDeminiaturizeNotification object:nil];
350     [notificationCenter removeObserver:self name:LoginWindowDidSwitchFromUserNotification   object:nil];
351     [notificationCenter removeObserver:self name:LoginWindowDidSwitchToUserNotification     object:nil];
352 }
353
354 - (void)start
355 {
356     ASSERT([self currentWindow]);
357     
358     if (_isStarted)
359         return;
360     
361     if (_triedAndFailedToCreatePlugin)
362         return;
363     
364     ASSERT([self webView]);
365     
366     if (![[[self webView] preferences] arePlugInsEnabled])
367         return;
368    
369     Frame* frame = core([self webFrame]);
370     if (!frame)
371         return;
372     Page* page = frame->page();
373     if (!page)
374         return;
375     
376     bool wasDeferring = page->defersLoading();
377     if (!wasDeferring)
378         page->setDefersLoading(true);
379
380     BOOL result = [self createPlugin];
381     
382     if (!wasDeferring)
383         page->setDefersLoading(false);
384
385     if (!result) {
386         _triedAndFailedToCreatePlugin = YES;
387         return;
388     }
389     
390     _isStarted = YES;
391
392     [[self webView] addPluginInstanceView:self];
393
394     if ([self currentWindow])
395         [self updateAndSetWindow];
396
397     if ([self window]) {
398         [self addWindowObservers];
399         if ([[self window] isKeyWindow]) {
400             [self sendActivateEvent:YES];
401         }
402         [self restartTimers];
403     }
404     
405     [self resetTrackingRect];
406     
407     [self loadStream];
408 }
409
410 - (void)stop
411 {
412     if (![self shouldStop])
413         return;
414     
415     [self removeTrackingRect];
416     
417     if (!_isStarted)
418         return;
419
420     _isStarted = NO;
421     
422     [[self webView] removePluginInstanceView:self];
423     
424     // Stop the timers
425     [self stopTimers];
426     
427     // Stop notifications and callbacks.
428     [self removeWindowObservers];
429     
430     [self destroyPlugin];
431 }
432
433 - (BOOL)shouldClipOutPlugin
434 {
435     NSWindow *window = [self window];
436     return !window || [window isMiniaturized] || [NSApp isHidden] || ![self isDescendantOf:[[self window] contentView]] || [self isHiddenOrHasHiddenAncestor];
437 }
438
439 - (BOOL)supportsSnapshotting
440 {
441     return [_pluginPackage.get() supportsSnapshotting];
442 }
443
444 - (void)cacheSnapshot
445 {
446     NSSize boundsSize = [self bounds].size;
447     if (!boundsSize.height || !boundsSize.width)
448         return;
449
450     NSImage *snapshot = [[NSImage alloc] initWithSize:boundsSize];
451         
452     _snapshotting = YES;
453     [snapshot lockFocus];
454     [self drawRect:[self bounds]];
455     [snapshot unlockFocus];
456     _snapshotting = NO;
457     
458     _cachedSnapshot = adoptNS(snapshot);
459 }
460
461 - (void)clearCachedSnapshot
462 {
463     _cachedSnapshot.clear();
464 }
465
466 - (void)viewWillMoveToWindow:(NSWindow *)newWindow
467 {
468     // We must remove the tracking rect before we move to the new window.
469     // Once we move to the new window, it will be too late.
470     [self removeTrackingRect];
471     [self removeWindowObservers];
472     
473     // Workaround for: <rdar://problem/3822871> resignFirstResponder is not sent to first responder view when it is removed from the window
474     [self setHasFocus:NO];
475     
476     if (!newWindow) {
477         if ([[self webView] hostWindow]) {
478             // View will be moved out of the actual window but it still has a host window.
479             [self stopTimers];
480         } else {
481             // View will have no associated windows.
482             [self stop];
483             
484             // Stop observing WebPreferencesChangedInternalNotification -- we only need to observe this when installed in the view hierarchy.
485             // When not in the view hierarchy, -viewWillMoveToWindow: and -viewDidMoveToWindow will start/stop the plugin as needed.
486             [[NSNotificationCenter defaultCenter] removeObserver:self name:WebPreferencesChangedInternalNotification object:nil];
487         }
488     }
489 }
490
491 - (void)viewWillMoveToSuperview:(NSView *)newSuperview
492 {
493     if (!newSuperview) {
494         // Stop the plug-in when it is removed from its superview.  It is not sufficient to do this in -viewWillMoveToWindow:nil, because
495         // the WebView might still has a hostWindow at that point, which prevents the plug-in from being destroyed.
496         // There is no need to start the plug-in when moving into a superview.  -viewDidMoveToWindow takes care of that.
497         [self stop];
498         
499         // Stop observing WebPreferencesChangedInternalNotification -- we only need to observe this when installed in the view hierarchy.
500         // When not in the view hierarchy, -viewWillMoveToWindow: and -viewDidMoveToWindow will start/stop the plugin as needed.
501         [[NSNotificationCenter defaultCenter] removeObserver:self name:WebPreferencesChangedInternalNotification object:nil];
502     }
503 }
504
505 - (void)viewDidMoveToWindow
506 {
507     [self resetTrackingRect];
508     
509     if ([self window]) {
510         // While in the view hierarchy, observe WebPreferencesChangedInternalNotification so that we can start/stop depending
511         // on whether plugins are enabled.
512         [[NSNotificationCenter defaultCenter] addObserver:self
513                                                  selector:@selector(preferencesHaveChanged:)
514                                                      name:WebPreferencesChangedInternalNotification
515                                                    object:nil];
516
517         _isPrivateBrowsingEnabled = [[[self webView] preferences] privateBrowsingEnabled];
518         
519         // View moved to an actual window. Start it if not already started.
520         [self start];
521
522         // Starting the plug-in can result in it removing itself from the window so we need to ensure that we're still in
523         // place before doing anything that requires a window.
524         if ([self window]) {
525             [self restartTimers];
526             [self addWindowObservers];
527         }
528     } else if ([[self webView] hostWindow]) {
529         // View moved out of an actual window, but still has a host window.
530         // Call setWindow to explicitly "clip out" the plug-in from sight.
531         // FIXME: It would be nice to do this where we call stopNullEvents in viewWillMoveToWindow.
532         [self updateAndSetWindow];
533     }
534 }
535
536 - (void)viewWillMoveToHostWindow:(NSWindow *)hostWindow
537 {
538     if (!hostWindow && ![self window]) {
539         // View will have no associated windows.
540         [self stop];
541         
542         // Remove WebPreferencesChangedInternalNotification observer -- we will observe once again when we move back into the window
543         [[NSNotificationCenter defaultCenter] removeObserver:self name:WebPreferencesChangedInternalNotification object:nil];
544     }
545 }
546
547 - (void)viewDidMoveToHostWindow
548 {
549     if ([[self webView] hostWindow]) {
550         // View now has an associated window. Start it if not already started.
551         [self start];
552     }
553 }
554
555 // MARK: NOTIFICATIONS
556
557 - (void)windowWillClose:(NSNotification *)notification 
558 {
559     [self stop]; 
560
561
562 - (void)windowBecameKey:(NSNotification *)notification
563 {
564     [self sendActivateEvent:YES];
565     [self invalidatePluginContentRect:[self bounds]];
566     [self restartTimers];
567 }
568
569 - (void)windowResignedKey:(NSNotification *)notification
570 {
571     [self sendActivateEvent:NO];
572     [self invalidatePluginContentRect:[self bounds]];
573     [self restartTimers];
574 }
575
576 - (void)windowDidMiniaturize:(NSNotification *)notification
577 {
578     [self stopTimers];
579 }
580
581 - (void)windowDidDeminiaturize:(NSNotification *)notification
582 {
583     [self restartTimers];
584 }
585
586 - (void)loginWindowDidSwitchFromUser:(NSNotification *)notification
587 {
588     [self stopTimers];
589 }
590
591 -(void)loginWindowDidSwitchToUser:(NSNotification *)notification
592 {
593     [self restartTimers];
594 }
595
596 - (void)preferencesHaveChanged:(NSNotification *)notification
597 {
598     WebPreferences *preferences = [[self webView] preferences];
599
600     if ([notification object] != preferences)
601         return;
602     
603     BOOL arePlugInsEnabled = [preferences arePlugInsEnabled];
604     if (_isStarted != arePlugInsEnabled) {
605         if (arePlugInsEnabled) {
606             if ([self currentWindow]) {
607                 [self start];
608             }
609         } else {
610             [self stop];
611             [self invalidatePluginContentRect:[self bounds]];
612         }
613     }
614     
615     BOOL isPrivateBrowsingEnabled = [preferences privateBrowsingEnabled];
616     if (isPrivateBrowsingEnabled != _isPrivateBrowsingEnabled) {
617         _isPrivateBrowsingEnabled = isPrivateBrowsingEnabled;
618         [self privateBrowsingModeDidChange];
619     }
620 }
621
622 - (void)renewGState
623 {
624     [super renewGState];
625     
626     // -renewGState is called whenever the view's geometry changes.  It's a little hacky to override this method, but
627     // much safer than walking up the view hierarchy and observing frame/bounds changed notifications, since you don't
628     // have to track subsequent changes to the view hierarchy and add/remove notification observers.
629     // NSOpenGLView uses the exact same technique to reshape its OpenGL surface.
630     
631     // All of the work this method does may safely be skipped if the view is not in a window.  When the view
632     // is moved back into a window, everything should be set up correctly.
633     if (![self window])
634         return;
635     
636     [self updateAndSetWindow];
637     
638     [self resetTrackingRect];
639     
640     // Check to see if the plugin view is completely obscured (scrolled out of view, for example).
641     // For performance reasons, we send null events at a lower rate to plugins which are obscured.
642     BOOL oldIsObscured = _isCompletelyObscured;
643     _isCompletelyObscured = NSIsEmptyRect([self visibleRect]);
644     if (_isCompletelyObscured != oldIsObscured)
645         [self restartTimers];
646 }
647
648 - (BOOL)becomeFirstResponder
649 {
650     [self setHasFocus:YES];
651     return YES;
652 }
653
654 - (BOOL)resignFirstResponder
655 {
656     [self setHasFocus:NO];    
657     return YES;
658 }
659
660 - (WebDataSource *)dataSource
661 {
662     return [[self webFrame] _dataSource];
663 }
664
665 - (WebFrame *)webFrame
666 {
667     return kit(_element->document().frame());
668 }
669
670 - (WebView *)webView
671 {
672     return [[self webFrame] webView];
673 }
674
675 - (NSWindow *)currentWindow
676 {
677     return [self window] ? [self window] : [[self webView] hostWindow];
678 }
679
680 - (WebCore::HTMLPlugInElement*)element
681 {
682     return _element.get();
683 }
684
685 - (void)cut:(id)sender
686 {
687     [self sendModifierEventWithKeyCode:7 character:'x'];
688 }
689
690 - (void)copy:(id)sender
691 {
692     [self sendModifierEventWithKeyCode:8 character:'c'];
693 }
694
695 - (void)paste:(id)sender
696 {
697     [self sendModifierEventWithKeyCode:9 character:'v'];
698 }
699
700 - (void)selectAll:(id)sender
701 {
702     [self sendModifierEventWithKeyCode:0 character:'a'];
703 }
704
705 // AppKit doesn't call mouseDown or mouseUp on right-click. Simulate control-click
706 // mouseDown and mouseUp so plug-ins get the right-click event as they do in Carbon (3125743).
707 - (void)rightMouseDown:(NSEvent *)theEvent
708 {
709     [self mouseDown:theEvent];
710 }
711
712 - (void)rightMouseUp:(NSEvent *)theEvent
713 {
714     [self mouseUp:theEvent];
715 }
716
717
718 - (BOOL)convertFromX:(double)sourceX andY:(double)sourceY space:(NPCoordinateSpace)sourceSpace
719                  toX:(double *)destX andY:(double *)destY space:(NPCoordinateSpace)destSpace
720 {
721     // Nothing to do
722     if (sourceSpace == destSpace) {
723         if (destX)
724             *destX = sourceX;
725         if (destY)
726             *destY = sourceY;
727         return YES;
728     }
729     
730     NSPoint sourcePoint = NSMakePoint(sourceX, sourceY);
731     
732     NSPoint sourcePointInScreenSpace;
733     
734     // First convert to screen space
735     switch (sourceSpace) {
736         case NPCoordinateSpacePlugin:
737             sourcePointInScreenSpace = [self convertPoint:sourcePoint toView:nil];
738 #pragma clang diagnostic push
739 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
740             sourcePointInScreenSpace = [[self currentWindow] convertBaseToScreen:sourcePointInScreenSpace];
741 #pragma clang diagnostic pop
742             break;
743             
744         case NPCoordinateSpaceWindow:
745 #pragma clang diagnostic push
746 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
747             sourcePointInScreenSpace = [[self currentWindow] convertBaseToScreen:sourcePoint];
748 #pragma clang diagnostic pop
749             break;
750             
751         case NPCoordinateSpaceFlippedWindow:
752             sourcePoint.y = [[self currentWindow] frame].size.height - sourcePoint.y;
753 #pragma clang diagnostic push
754 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
755             sourcePointInScreenSpace = [[self currentWindow] convertBaseToScreen:sourcePoint];
756 #pragma clang diagnostic pop
757             break;
758             
759         case NPCoordinateSpaceScreen:
760             sourcePointInScreenSpace = sourcePoint;
761             break;
762             
763         case NPCoordinateSpaceFlippedScreen:
764             sourcePoint.y = [(NSScreen *)[[NSScreen screens] objectAtIndex:0] frame].size.height - sourcePoint.y;
765             sourcePointInScreenSpace = sourcePoint;
766             break;
767         default:
768             return FALSE;
769     }
770     
771     NSPoint destPoint;
772     
773     // Then convert back to the destination space
774     switch (destSpace) {
775         case NPCoordinateSpacePlugin:
776 #pragma clang diagnostic push
777 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
778             destPoint = [[self currentWindow] convertScreenToBase:sourcePointInScreenSpace];
779 #pragma clang diagnostic pop
780             destPoint = [self convertPoint:destPoint fromView:nil];
781             break;
782             
783         case NPCoordinateSpaceWindow:
784 #pragma clang diagnostic push
785 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
786             destPoint = [[self currentWindow] convertScreenToBase:sourcePointInScreenSpace];
787 #pragma clang diagnostic pop
788             break;
789             
790         case NPCoordinateSpaceFlippedWindow:
791 #pragma clang diagnostic push
792 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
793             destPoint = [[self currentWindow] convertScreenToBase:sourcePointInScreenSpace];
794 #pragma clang diagnostic pop
795             destPoint.y = [[self currentWindow] frame].size.height - destPoint.y;
796             break;
797             
798         case NPCoordinateSpaceScreen:
799             destPoint = sourcePointInScreenSpace;
800             break;
801             
802         case NPCoordinateSpaceFlippedScreen:
803             destPoint = sourcePointInScreenSpace;
804             destPoint.y = [(NSScreen *)[[NSScreen screens] objectAtIndex:0] frame].size.height - destPoint.y;
805             break;
806             
807         default:
808             return FALSE;
809     }
810     
811     if (destX)
812         *destX = destPoint.x;
813     if (destY)
814         *destY = destPoint.y;
815     
816     return TRUE;
817 }
818
819
820 - (void)invalidatePluginContentRect:(NSRect)rect
821 {
822     auto* renderer = _element->renderer();
823     if (!is<RenderEmbeddedObject>(renderer))
824         return;
825     auto& object = downcast<RenderEmbeddedObject>(*renderer);
826     IntRect contentRect(rect);
827     contentRect.move(object.borderLeft() + object.paddingLeft(), object.borderTop() + object.paddingTop());
828     object.repaintRectangle(contentRect);
829 }
830
831 - (NSRect)actualVisibleRectInWindow
832 {
833     auto* renderer = _element->renderer();
834     if (!is<RenderEmbeddedObject>(renderer))
835         return NSZeroRect;
836     auto& object = downcast<RenderEmbeddedObject>(*renderer);
837     auto widgetRect = object.view().frameView().contentsToWindow(object.pixelSnappedAbsoluteClippedOverflowRect());
838     return intersection(object.windowClipRect(), widgetRect);
839 }
840
841 - (CALayer *)pluginLayer
842 {
843     // This needs to be overridden by subclasses.
844     return nil;
845 }
846
847 - (BOOL)getFormValue:(NSString **)value
848 {
849     // This needs to be overridden by subclasses.
850     return false;
851 }
852
853 @end
854
855 namespace WebKit {
856
857 bool getAuthenticationInfo(const char* protocolStr, const char* hostStr, int32_t port, const char* schemeStr, const char* realmStr,
858                            CString& username, CString& password)
859 {
860     if (strcasecmp(protocolStr, "http") != 0 && 
861         strcasecmp(protocolStr, "https") != 0)
862         return false;
863
864     NSString *host = [NSString stringWithUTF8String:hostStr];
865     if (!hostStr)
866         return false;
867     
868     NSString *protocol = [NSString stringWithUTF8String:protocolStr];
869     if (!protocol)
870         return false;
871     
872     NSString *realm = [NSString stringWithUTF8String:realmStr];
873     if (!realm)
874         return NPERR_GENERIC_ERROR;
875     
876     NSString *authenticationMethod = NSURLAuthenticationMethodDefault;
877     if (!strcasecmp(protocolStr, "http")) {
878         if (!strcasecmp(schemeStr, "basic"))
879             authenticationMethod = NSURLAuthenticationMethodHTTPBasic;
880         else if (!strcasecmp(schemeStr, "digest"))
881             authenticationMethod = NSURLAuthenticationMethodHTTPDigest;
882     }
883     
884     RetainPtr<NSURLProtectionSpace> protectionSpace = adoptNS([[NSURLProtectionSpace alloc] initWithHost:host port:port protocol:protocol realm:realm authenticationMethod:authenticationMethod]);
885     
886     NSURLCredential *credential = CredentialStorage::defaultCredentialStorage().get(emptyString(), ProtectionSpace(protectionSpace.get())).nsCredential();
887     if (!credential)
888         credential = [[NSURLCredentialStorage sharedCredentialStorage] defaultCredentialForProtectionSpace:protectionSpace.get()];
889     if (!credential)
890         return false;
891   
892     if (![credential hasPassword])
893         return false;
894     
895     username = [[credential user] UTF8String];
896     password = [[credential password] UTF8String];
897     
898     return true;
899 }
900
901 void sendUserChangeNotifications()
902 {
903     auto consoleConnectionChangeNotifyProc = [](CGSNotificationType type, CGSNotificationData, CGSByteCount, CGSNotificationArg) {
904         NSString *notificationName = nil;
905         if (type == kCGSessionConsoleConnect)
906             notificationName = LoginWindowDidSwitchToUserNotification;
907         else if (type == kCGSessionConsoleDisconnect)
908             notificationName = LoginWindowDidSwitchFromUserNotification;
909         else
910             ASSERT_NOT_REACHED();
911         [[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:nil];
912     };
913
914     CGSRegisterNotifyProc(consoleConnectionChangeNotifyProc, kCGSessionConsoleConnect, nullptr);
915     CGSRegisterNotifyProc(consoleConnectionChangeNotifyProc, kCGSessionConsoleDisconnect, nullptr);
916 }
917
918 } // namespace WebKit
919
920 #endif //  ENABLE(NETSCAPE_PLUGIN_API)
921