2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Collabora Ltd. All rights reserved.
4 * Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "FrameLoadRequest.h"
32 #include "HaltablePlugin.h"
34 #include "MediaCanStartListener.h"
35 #include "PluginStream.h"
36 #include "ResourceRequest.h"
39 #include "npruntime_internal.h"
40 #include <wtf/HashMap.h>
41 #include <wtf/HashSet.h>
42 #include <wtf/OwnPtr.h>
43 #include <wtf/PassRefPtr.h>
44 #include <wtf/RefPtr.h>
45 #include <wtf/Vector.h>
46 #include <wtf/text/CString.h>
49 // TODO: Upstream to webkit.org
50 #ifdef PLUGIN_SCHEDULE_TIMER
51 #include "PluginTimer.h"
54 #if OS(WINDOWS) && (PLATFORM(QT) || PLATFORM(WX))
55 typedef struct HWND__* HWND;
56 typedef HWND PlatformPluginWidget;
57 #elif defined(ANDROID_PLUGINS)
58 typedef struct PluginWidgetAndroid* PlatformPluginWidget;
60 typedef PlatformWidget PlatformPluginWidget;
61 #if defined(XP_MACOSX) && PLATFORM(QT)
82 #ifdef ANDROID_PLUGINS
86 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
87 class PluginMessageThrottlerWin;
93 class ResourceResponse;
96 PluginStatusCanNotFindPlugin,
97 PluginStatusCanNotLoadPlugin,
98 PluginStatusLoadedSuccessfully
101 class PluginRequest : public Noncopyable {
103 PluginRequest(const FrameLoadRequest& frameLoadRequest, bool sendNotification, void* notifyData, bool shouldAllowPopups)
104 : m_frameLoadRequest(frameLoadRequest)
105 , m_notifyData(notifyData)
106 , m_sendNotification(sendNotification)
107 , m_shouldAllowPopups(shouldAllowPopups) { }
109 const FrameLoadRequest& frameLoadRequest() const { return m_frameLoadRequest; }
110 void* notifyData() const { return m_notifyData; }
111 bool sendNotification() const { return m_sendNotification; }
112 bool shouldAllowPopups() const { return m_shouldAllowPopups; }
114 FrameLoadRequest m_frameLoadRequest;
116 bool m_sendNotification;
117 bool m_shouldAllowPopups;
120 class PluginManualLoader {
122 virtual ~PluginManualLoader() {}
123 virtual void didReceiveResponse(const ResourceResponse&) = 0;
124 virtual void didReceiveData(const char*, int) = 0;
125 virtual void didFinishLoading() = 0;
126 virtual void didFail(const ResourceError&) = 0;
129 class PluginView : public Widget, private PluginStreamClient, public PluginManualLoader, private HaltablePlugin, private MediaCanStartListener {
131 static PassRefPtr<PluginView> create(Frame* parentFrame, const IntSize&, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
132 virtual ~PluginView();
134 PluginPackage* plugin() const { return m_plugin.get(); }
135 NPP instance() const { return m_instance; }
137 void setNPWindowRect(const IntRect&);
138 static PluginView* currentPluginView();
141 PassRefPtr<JSC::Bindings::Instance> bindingInstance();
144 PluginStatus status() const { return m_status; }
147 NPError getURLNotify(const char* url, const char* target, void* notifyData);
148 NPError getURL(const char* url, const char* target);
149 NPError postURLNotify(const char* url, const char* target, uint32_t len, const char* but, NPBool file, void* notifyData);
150 NPError postURL(const char* url, const char* target, uint32_t len, const char* but, NPBool file);
151 NPError newStream(NPMIMEType type, const char* target, NPStream** stream);
152 int32_t write(NPStream* stream, int32_t len, void* buffer);
153 NPError destroyStream(NPStream* stream, NPReason reason);
154 const char* userAgent();
155 #if ENABLE(NETSCAPE_PLUGIN_API)
156 static const char* userAgentStatic();
158 void status(const char* message);
160 #if ENABLE(NETSCAPE_PLUGIN_API)
161 NPError getValue(NPNVariable variable, void* value);
162 static NPError getValueStatic(NPNVariable variable, void* value);
164 NPError setValue(NPPVariable variable, void* value);
165 void invalidateRect(NPRect*);
166 void invalidateRegion(NPRegion);
168 void pushPopupsEnabledState(bool state);
169 void popPopupsEnabledState();
170 #ifdef PLUGIN_SCHEDULE_TIMER
171 uint32_t scheduleTimer(NPP, uint32_t interval, bool repeat,
172 void (*timerFunc)(NPP, uint32_t timerID));
173 void unscheduleTimer(NPP, uint32_t timerID);
176 NPObject* getNPObject();
179 virtual void invalidateRect(const IntRect&);
181 bool arePopupsAllowed() const;
183 void setJavaScriptPaused(bool);
185 void privateBrowsingStateChanged(bool);
187 void disconnectStream(PluginStream*);
188 void streamDidFinishLoading(PluginStream* stream) { disconnectStream(stream); }
191 virtual void setFrameRect(const IntRect&);
192 virtual void frameRectsChanged();
193 virtual void setFocus(bool);
196 virtual void paint(GraphicsContext*, const IntRect&);
198 // This method is used by plugins on all platforms to obtain a clip rect that includes clips set by WebCore,
199 // e.g., in overflow:auto sections. The clip rects coordinates are in the containing window's coordinate space.
200 // This clip includes any clips that the widget itself sets up for its children.
201 IntRect windowClipRect() const;
203 virtual void handleEvent(Event*);
204 virtual void setParent(ScrollView*);
205 virtual void setParentVisible(bool);
207 virtual bool isPluginView() const { return true; }
209 Frame* parentFrame() const { return m_parentFrame.get(); }
211 void focusPluginElement();
213 const String& pluginsPage() const { return m_pluginsPage; }
214 const String& mimeType() const { return m_mimeType; }
215 const KURL& url() const { return m_url; }
217 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
218 static LRESULT CALLBACK PluginViewWndProc(HWND, UINT, WPARAM, LPARAM);
219 LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
220 WNDPROC pluginWndProc() const { return m_pluginWndProc; }
223 // Used for manual loading
224 void didReceiveResponse(const ResourceResponse&);
225 void didReceiveData(const char*, int);
226 void didFinishLoading();
227 void didFail(const ResourceError&);
231 virtual void restart();
232 virtual Node* node() const;
233 virtual bool isWindowed() const { return m_isWindowed; }
234 virtual String pluginName() const;
236 bool isHalted() const { return m_isHalted; }
237 bool hasBeenHalted() const { return m_hasBeenHalted; }
239 static bool isCallingPlugin();
241 #ifdef ANDROID_PLUGINS
242 Element* getElement() const { return m_element; }
247 #if ENABLE(NETSCAPE_PLUGIN_API)
248 static void keepAlive(NPP);
253 PluginView(Frame* parentFrame, const IntSize&, PluginPackage*, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
255 void setParameters(const Vector<String>& paramNames, const Vector<String>& paramValues);
256 bool startOrAddToUnstartedList();
258 bool platformStart();
260 void platformDestroy();
261 static void setCurrentPluginView(PluginView*);
262 NPError load(const FrameLoadRequest&, bool sendNotification, void* notifyData);
263 NPError handlePost(const char* url, const char* target, uint32_t len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders);
264 NPError handlePostReadFile(Vector<char>& buffer, uint32_t len, const char* buf);
265 static void freeStringArray(char** stringArray, int length);
266 void setCallingPlugin(bool) const;
268 void invalidateWindowlessPluginRect(const IntRect&);
270 virtual void mediaCanStart();
272 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
273 void paintWindowedPluginIntoContext(GraphicsContext*, const IntRect&);
274 static HDC WINAPI hookedBeginPaint(HWND, PAINTSTRUCT*);
275 static BOOL WINAPI hookedEndPaint(HWND, const PAINTSTRUCT*);
278 static bool platformGetValueStatic(NPNVariable variable, void* value, NPError* result);
279 bool platformGetValue(NPNVariable variable, void* value, NPError* result);
281 RefPtr<Frame> m_parentFrame;
282 RefPtr<PluginPackage> m_plugin;
287 PluginStatus m_status;
288 Vector<IntRect> m_invalidRects;
290 void performRequest(PluginRequest*);
291 void scheduleRequest(PluginRequest*);
292 void requestTimerFired(Timer<PluginView>*);
293 void invalidateTimerFired(Timer<PluginView>*);
294 Timer<PluginView> m_requestTimer;
295 Timer<PluginView> m_invalidateTimer;
297 void popPopupsStateTimerFired(Timer<PluginView>*);
298 Timer<PluginView> m_popPopupsStateTimer;
300 void lifeSupportTimerFired(Timer<PluginView>*);
301 Timer<PluginView> m_lifeSupportTimer;
304 bool dispatchNPEvent(NPEvent&);
306 void updatePluginWidget();
307 void paintMissingPluginIcon(GraphicsContext*, const IntRect&);
309 void handleKeyboardEvent(KeyboardEvent*);
310 void handleMouseEvent(MouseEvent*);
311 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
312 void handleFocusInEvent();
313 void handleFocusOutEvent();
317 void paintIntoTransformedContext(HDC);
318 PassRefPtr<Image> snapshot();
321 #ifdef ANDROID_PLUGINS
322 void handleFocusEvent(bool hasFocus);
323 void handleTouchEvent(TouchEvent*);
324 // called at the end of the base constructor
327 #ifdef PLUGIN_PLATFORM_SETVALUE
328 // called if the default setValue does not recognize the variable
329 NPError platformSetValue(NPPVariable variable, void* value);
335 char** m_paramValues;
336 String m_pluginsPage;
339 WTF::CString m_userAgent;
342 NPP_t m_instanceStruct;
345 Vector<bool, 4> m_popupStateStack;
347 HashSet<RefPtr<PluginStream> > m_streams;
348 Vector<PluginRequest*> m_requests;
351 bool m_isTransparent;
352 bool m_haveInitialized;
353 bool m_isWaitingToStart;
359 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
360 OwnPtr<PluginMessageThrottlerWin> m_messageThrottler;
361 WNDPROC m_pluginWndProc;
362 unsigned m_lastMessage;
363 bool m_isCallingPluginWndProc;
365 bool m_haveUpdatedPluginWidget;
369 // TODO: Upstream to webkit.org
370 #ifdef PLUGIN_SCHEDULE_TIMER
371 PluginTimerList m_timerList;
374 #if ((PLATFORM(QT) || PLATFORM(WX)) && OS(WINDOWS)) || defined(XP_MACOSX)
375 // On Mac OSX and Qt/Windows the plugin does not have its own native widget,
376 // but is using the containing window as its reference for positioning/painting.
377 PlatformPluginWidget m_window;
379 PlatformPluginWidget platformPluginWidget() const { return m_window; }
380 void setPlatformPluginWidget(PlatformPluginWidget widget) { m_window = widget; }
381 #elif defined(ANDROID_PLUGINS)
383 PlatformPluginWidget m_window;
384 PlatformPluginWidget platformPluginWidget() const { return m_window; } // MANUAL MERGE FIXME
387 void setPlatformPluginWidget(PlatformPluginWidget widget) { setPlatformWidget(widget); }
388 PlatformPluginWidget platformPluginWidget() const { return platformWidget(); }
393 #if defined(XP_UNIX) || OS(SYMBIAN) || defined(ANDROID_PLUGINS)
394 void setNPWindowIfNeeded();
395 #elif defined(XP_MACOSX)
396 NP_CGContext m_npCgContext;
397 OwnPtr<Timer<PluginView> > m_nullEventTimer;
398 NPDrawingModel m_drawingModel;
399 NPEventModel m_eventModel;
400 CGContextRef m_contextRef;
401 WindowRef m_fakeWindow;
406 Point m_lastMousePos;
407 void setNPWindowIfNeeded();
408 void nullEventTimerFired(Timer<PluginView>*);
409 Point globalMousePosForPlugin() const;
410 Point mousePosForPlugin(MouseEvent* event = 0) const;
413 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
414 bool m_hasPendingGeometryChange;
418 Display* m_pluginDisplay;
420 void initXEvent(XEvent* event);
423 IntRect m_clipRect; // The clip rect to apply to a windowed plug-in
424 IntRect m_windowRect; // Our window rect.
425 #ifdef ANDROID_PLUGINS
426 IntRect m_pageRect; // The rect in page coordinate system.
430 RefPtr<PluginStream> m_manualStream;
432 bool m_isJavaScriptPaused;
435 bool m_hasBeenHalted;
437 bool m_haveCalledSetWindow;
439 static PluginView* s_currentPluginView;
442 } // namespace WebCore