WebKit:
[WebKit-https.git] / WebKit / mac / Plugins / Hosted / WebHostedNetscapePluginView.mm
1 /*
2  * Copyright (C) 2008 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25 #if USE(PLUGIN_HOST_PROCESS)
26
27 #import "WebHostedNetscapePluginView.h"
28
29 #import "NetscapePluginInstanceProxy.h"
30 #import "NetscapePluginHostManager.h"
31 #import "NetscapePluginHostProxy.h"
32 #import "WebView.h"
33 #import "WebViewInternal.h"
34 #import "WebUIDelegate.h"
35
36 #import <CoreFoundation/CoreFoundation.h>
37 #import <WebCore/runtime.h>
38 #import <WebCore/runtime_root.h>
39 #import <WebCore/WebCoreObjCExtras.h>
40 #import <runtime/InitializeThreading.h>
41 #import <wtf/Assertions.h>
42
43 using namespace WebKit;
44
45 extern "C" {
46 #include "WebKitPluginClientServer.h"
47 #include "WebKitPluginHost.h"
48 }
49
50 @implementation WebHostedNetscapePluginView
51
52 + (void)initialize
53 {
54     JSC::initializeThreading();
55 #ifndef BUILDING_ON_TIGER
56     WebCoreObjCFinalizeOnMainThread(self);
57 #endif
58     WKSendUserChangeNotifications();
59 }
60
61 - (id)initWithFrame:(NSRect)frame
62       pluginPackage:(WebNetscapePluginPackage *)pluginPackage
63                 URL:(NSURL *)URL
64             baseURL:(NSURL *)baseURL
65            MIMEType:(NSString *)MIME
66       attributeKeys:(NSArray *)keys
67     attributeValues:(NSArray *)values
68        loadManually:(BOOL)loadManually
69          DOMElement:(DOMElement *)element
70 {
71     self = [super initWithFrame:frame pluginPackage:pluginPackage URL:URL baseURL:baseURL MIMEType:MIME attributeKeys:keys attributeValues:values loadManually:loadManually DOMElement:element];
72     if (!self)
73         return nil;
74     
75     return self;
76 }    
77
78 - (void)handleMouseMoved:(NSEvent *)event
79 {
80     if (_isStarted && _proxy)
81         _proxy->mouseEvent(self, event, NPCocoaEventMouseMoved);
82 }
83
84 - (void)setAttributeKeys:(NSArray *)keys andValues:(NSArray *)values
85 {
86     ASSERT(!_attributeKeys && !_attributeValues);
87     
88     _attributeKeys.adoptNS([keys copy]);
89     _attributeValues.adoptNS([values copy]);
90 }    
91
92 - (BOOL)createPlugin
93 {
94     ASSERT(!_proxy);
95
96     NSString *userAgent = [[self webView] userAgentForURL:_baseURL.get()];
97
98     _proxy = NetscapePluginHostManager::shared().instantiatePlugin(_pluginPackage.get(), self, _MIMEType.get(), _attributeKeys.get(), _attributeValues.get(), userAgent, _sourceURL.get());
99     if (!_proxy) 
100         return NO;
101
102     if (_proxy->useSoftwareRenderer())
103         _softwareRenderer = WKSoftwareCARendererCreate(_proxy->renderContextID());
104     else {
105         _pluginLayer = WKMakeRenderLayer(_proxy->renderContextID());
106         self.wantsLayer = YES;
107     }
108     
109     // Update the window frame.
110     _proxy->windowFrameChanged([[self window] frame]);
111     
112     return YES;
113 }
114
115 - (void)setLayer:(CALayer *)newLayer
116 {
117     [super setLayer:newLayer];
118     
119     if (_pluginLayer)
120         [newLayer addSublayer:_pluginLayer.get()];
121 }
122
123 - (void)loadStream
124 {
125 }
126
127 - (void)updateAndSetWindow
128 {
129     if (!_proxy)
130         return;
131     
132     // Use AppKit to convert view coordinates to NSWindow coordinates.
133     NSRect boundsInWindow = [self convertRect:[self bounds] toView:nil];
134     NSRect visibleRectInWindow = [self convertRect:[self visibleRect] toView:nil];
135     
136     // Flip Y to convert NSWindow coordinates to top-left-based window coordinates.
137     float borderViewHeight = [[self currentWindow] frame].size.height;
138     boundsInWindow.origin.y = borderViewHeight - NSMaxY(boundsInWindow);
139     visibleRectInWindow.origin.y = borderViewHeight - NSMaxY(visibleRectInWindow);
140
141     _proxy->resize(boundsInWindow, visibleRectInWindow);
142 }
143
144 - (void)windowFocusChanged:(BOOL)hasFocus
145 {
146     if (_proxy)
147         _proxy->windowFocusChanged(hasFocus);
148 }
149
150 - (BOOL)shouldStop
151 {
152     return YES;
153 }
154
155 - (void)destroyPlugin
156 {
157     if (_proxy) {
158         if (_softwareRenderer) {
159             WKSoftwareCARendererDestroy(_softwareRenderer);
160             _softwareRenderer = 0;
161         }
162         
163         _proxy->destroy();
164         _proxy = 0;
165     }
166     
167     _pluginLayer = 0;
168 }
169
170 - (void)startTimers
171 {
172     if (_proxy)
173         _proxy->startTimers(_isCompletelyObscured);
174 }
175
176 - (void)stopTimers
177 {
178     if (_proxy)
179         _proxy->stopTimers();
180 }
181
182 - (void)focusChanged
183 {
184     if (_proxy)
185         _proxy->focusChanged(_hasFocus);
186 }
187
188 - (void)windowFrameDidChange:(NSNotification *)notification 
189 {
190     if (_proxy && [self window])
191         _proxy->windowFrameChanged([[self window] frame]);
192 }
193
194 - (void)addWindowObservers
195 {
196     [super addWindowObservers];
197     
198     ASSERT([self window]);
199     
200     NSWindow *theWindow = [self window];
201     
202     NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
203     [notificationCenter addObserver:self selector:@selector(windowFrameDidChange:) 
204                                name:NSWindowDidMoveNotification object:theWindow];
205     [notificationCenter addObserver:self selector:@selector(windowFrameDidChange:)
206                                name:NSWindowDidResizeNotification object:theWindow];    
207 }
208
209 - (void)removeWindowObservers
210 {
211     [super removeWindowObservers];
212     
213     NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
214     [notificationCenter removeObserver:self name:NSWindowDidMoveNotification object:nil];
215     [notificationCenter removeObserver:self name:NSWindowDidResizeNotification object:nil];
216 }
217
218 - (void)mouseDown:(NSEvent *)event
219 {
220     if (_isStarted && _proxy)
221         _proxy->mouseEvent(self, event, NPCocoaEventMouseDown);
222 }
223
224 - (void)mouseUp:(NSEvent *)event
225 {
226     if (_isStarted && _proxy)
227         _proxy->mouseEvent(self, event, NPCocoaEventMouseUp);
228 }
229
230 - (void)mouseDragged:(NSEvent *)event
231 {
232     if (_isStarted && _proxy)
233         _proxy->mouseEvent(self, event, NPCocoaEventMouseDragged);
234 }
235
236 - (void)mouseEntered:(NSEvent *)event
237 {
238     if (_isStarted && _proxy)
239         _proxy->mouseEvent(self, event, NPCocoaEventMouseEntered);
240 }
241
242 - (void)mouseExited:(NSEvent *)event
243 {
244     if (_isStarted && _proxy)
245         _proxy->mouseEvent(self, event, NPCocoaEventMouseExited);
246 }
247
248 - (void)keyDown:(NSEvent *)event
249 {
250     if (_isStarted && _proxy)
251         _proxy->keyEvent(self, event, NPCocoaEventKeyDown);
252 }
253
254 - (void)keyUp:(NSEvent *)event
255 {
256     if (_isStarted && _proxy)
257         _proxy->keyEvent(self, event, NPCocoaEventKeyUp);
258 }
259
260 - (void)pluginHostDied
261 {
262     _pluginHostDied = YES;
263
264     _pluginLayer = nil;
265     _proxy = 0;
266     
267     // No need for us to be layer backed anymore
268     self.wantsLayer = NO;
269     
270     [self setNeedsDisplay:YES];
271 }
272
273
274 - (void)drawRect:(NSRect)rect
275 {
276     if (_proxy) {
277         if (_softwareRenderer)
278             WKSoftwareCARendererRender(_softwareRenderer, (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort], NSRectToCGRect(rect));
279         return;
280     }
281     
282     if (_pluginHostDied) {
283         // Fill the area with a nice red color for now.
284         [[NSColor redColor] set];
285         NSRectFill(rect);
286     }
287 }
288
289 - (PassRefPtr<JSC::Bindings::Instance>)createPluginBindingsInstance:(PassRefPtr<JSC::Bindings::RootObject>)rootObject
290 {
291     return _proxy->createBindingsInstance(rootObject);
292 }
293
294 @end
295
296 #endif