51b21272ab0ce94c8eef6be9e71b2ee500428067
[WebKit-https.git] / WebCore / plugins / PluginView.h
1 /*
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>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
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.
14  *
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. 
26  */
27
28 #ifndef PluginView_h
29 #define PluginView_h
30
31 #include "CString.h"
32 #include "FrameLoadRequest.h"
33 #include "HaltablePlugin.h"
34 #include "IntRect.h"
35 #include "MediaCanStartListener.h"
36 #include "PluginStream.h"
37 #include "ResourceRequest.h"
38 #include "Timer.h"
39 #include "Widget.h"
40 #include "npruntime_internal.h"
41 #include <wtf/HashMap.h>
42 #include <wtf/HashSet.h>
43 #include <wtf/OwnPtr.h>
44 #include <wtf/PassRefPtr.h>
45 #include <wtf/RefPtr.h>
46 #include <wtf/Vector.h>
47
48 #if OS(WINDOWS) && (PLATFORM(QT) || PLATFORM(WX))
49 typedef struct HWND__* HWND;
50 typedef HWND PlatformPluginWidget;
51 #else
52 typedef PlatformWidget PlatformPluginWidget;
53 #if defined(XP_MACOSX) && PLATFORM(QT)
54 #include <QPixmap>
55 #endif
56 #endif
57
58 namespace JSC {
59     namespace Bindings {
60         class Instance;
61     }
62 }
63
64 namespace WebCore {
65     class Element;
66     class Frame;
67     class Image;
68     class KeyboardEvent;
69     class MouseEvent;
70     class KURL;
71 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
72     class PluginMessageThrottlerWin;
73 #endif
74     class PluginPackage;
75     class PluginRequest;
76     class PluginStream;
77     class ResourceError;
78     class ResourceResponse;
79
80     enum PluginStatus {
81         PluginStatusCanNotFindPlugin,
82         PluginStatusCanNotLoadPlugin,
83         PluginStatusLoadedSuccessfully
84     };
85
86     class PluginRequest : public Noncopyable {
87     public:
88         PluginRequest(const FrameLoadRequest& frameLoadRequest, bool sendNotification, void* notifyData, bool shouldAllowPopups)
89             : m_frameLoadRequest(frameLoadRequest)
90             , m_notifyData(notifyData)
91             , m_sendNotification(sendNotification)
92             , m_shouldAllowPopups(shouldAllowPopups) { }
93     public:
94         const FrameLoadRequest& frameLoadRequest() const { return m_frameLoadRequest; }
95         void* notifyData() const { return m_notifyData; }
96         bool sendNotification() const { return m_sendNotification; }
97         bool shouldAllowPopups() const { return m_shouldAllowPopups; }
98     private:
99         FrameLoadRequest m_frameLoadRequest;
100         void* m_notifyData;
101         bool m_sendNotification;
102         bool m_shouldAllowPopups;
103     };
104
105     class PluginManualLoader {
106     public:
107         virtual ~PluginManualLoader() {}
108         virtual void didReceiveResponse(const ResourceResponse&) = 0;
109         virtual void didReceiveData(const char*, int) = 0;
110         virtual void didFinishLoading() = 0;
111         virtual void didFail(const ResourceError&) = 0;
112     };
113
114     class PluginView : public Widget, private PluginStreamClient, public PluginManualLoader, private HaltablePlugin, private MediaCanStartListener {
115     public:
116         static PassRefPtr<PluginView> create(Frame* parentFrame, const IntSize&, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
117         virtual ~PluginView();
118
119         PluginPackage* plugin() const { return m_plugin.get(); }
120         NPP instance() const { return m_instance; }
121
122         void setNPWindowRect(const IntRect&);
123         static PluginView* currentPluginView();
124
125         PassRefPtr<JSC::Bindings::Instance> bindingInstance();
126
127         PluginStatus status() const { return m_status; }
128
129         // NPN functions
130         NPError getURLNotify(const char* url, const char* target, void* notifyData);
131         NPError getURL(const char* url, const char* target);
132         NPError postURLNotify(const char* url, const char* target, uint32 len, const char* but, NPBool file, void* notifyData);
133         NPError postURL(const char* url, const char* target, uint32 len, const char* but, NPBool file);
134         NPError newStream(NPMIMEType type, const char* target, NPStream** stream);
135         int32 write(NPStream* stream, int32 len, void* buffer);
136         NPError destroyStream(NPStream* stream, NPReason reason);
137         const char* userAgent();
138 #if ENABLE(NETSCAPE_PLUGIN_API)
139         static const char* userAgentStatic();
140 #endif
141         void status(const char* message);
142         
143 #if ENABLE(NETSCAPE_PLUGIN_API)
144         NPError getValue(NPNVariable variable, void* value);
145         static NPError getValueStatic(NPNVariable variable, void* value);
146 #endif
147         NPError setValue(NPPVariable variable, void* value);
148         void invalidateRect(NPRect*);
149         void invalidateRegion(NPRegion);
150         void forceRedraw();
151         void pushPopupsEnabledState(bool state);
152         void popPopupsEnabledState();
153
154         virtual void invalidateRect(const IntRect&);
155
156         bool arePopupsAllowed() const;
157
158         void setJavaScriptPaused(bool);
159
160         void privateBrowsingStateChanged(bool);
161
162         void disconnectStream(PluginStream*);
163         void streamDidFinishLoading(PluginStream* stream) { disconnectStream(stream); }
164
165         // Widget functions
166         virtual void setFrameRect(const IntRect&);
167         virtual void frameRectsChanged();
168         virtual void setFocus();
169         virtual void show();
170         virtual void hide();
171         virtual void paint(GraphicsContext*, const IntRect&);
172
173         // This method is used by plugins on all platforms to obtain a clip rect that includes clips set by WebCore,
174         // e.g., in overflow:auto sections.  The clip rects coordinates are in the containing window's coordinate space.
175         // This clip includes any clips that the widget itself sets up for its children.
176         IntRect windowClipRect() const;
177
178         virtual void handleEvent(Event*);
179         virtual void setParent(ScrollView*);
180         virtual void setParentVisible(bool);
181
182         virtual bool isPluginView() const { return true; }
183
184         Frame* parentFrame() const { return m_parentFrame.get(); }
185
186         void focusPluginElement();
187
188         const String& pluginsPage() const { return m_pluginsPage; }
189         const String& mimeType() const { return m_mimeType; }
190         const KURL& url() const { return m_url; }
191
192 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
193         static LRESULT CALLBACK PluginViewWndProc(HWND, UINT, WPARAM, LPARAM);
194         LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
195         WNDPROC pluginWndProc() const { return m_pluginWndProc; }
196 #endif
197
198         // Used for manual loading
199         void didReceiveResponse(const ResourceResponse&);
200         void didReceiveData(const char*, int);
201         void didFinishLoading();
202         void didFail(const ResourceError&);
203
204         // HaltablePlugin
205         virtual void halt();
206         virtual void restart();
207         virtual Node* node() const;
208         virtual bool isWindowed() const { return m_isWindowed; }
209         virtual String pluginName() const;
210
211         bool isHalted() const { return m_isHalted; }
212         bool hasBeenHalted() const { return m_hasBeenHalted; }
213
214         static bool isCallingPlugin();
215
216         bool start();
217
218 #if ENABLE(NETSCAPE_PLUGIN_API)
219         static void keepAlive(NPP);
220 #endif
221         void keepAlive();
222
223     private:
224         PluginView(Frame* parentFrame, const IntSize&, PluginPackage*, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
225
226         void setParameters(const Vector<String>& paramNames, const Vector<String>& paramValues);
227         bool startOrAddToUnstartedList();
228         void removeFromUnstartedListIfNecessary();
229         void init();
230         bool platformStart();
231         void stop();
232         void platformDestroy();
233         static void setCurrentPluginView(PluginView*);
234         NPError load(const FrameLoadRequest&, bool sendNotification, void* notifyData);
235         NPError handlePost(const char* url, const char* target, uint32 len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders);
236         NPError handlePostReadFile(Vector<char>& buffer, uint32 len, const char* buf);
237         static void freeStringArray(char** stringArray, int length);
238         void setCallingPlugin(bool) const;
239
240         void invalidateWindowlessPluginRect(const IntRect&);
241
242         virtual void mediaCanStart();
243
244 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
245         void paintWindowedPluginIntoContext(GraphicsContext*, const IntRect&);
246         static HDC WINAPI hookedBeginPaint(HWND, PAINTSTRUCT*);
247         static BOOL WINAPI hookedEndPaint(HWND, const PAINTSTRUCT*);
248 #endif
249
250         static bool platformGetValueStatic(NPNVariable variable, void* value, NPError* result);
251         bool platformGetValue(NPNVariable variable, void* value, NPError* result);
252
253         RefPtr<Frame> m_parentFrame;
254         RefPtr<PluginPackage> m_plugin;
255         Element* m_element;
256         bool m_isStarted;
257         KURL m_url;
258         KURL m_baseURL;
259         PluginStatus m_status;
260         Vector<IntRect> m_invalidRects;
261
262         void performRequest(PluginRequest*);
263         void scheduleRequest(PluginRequest*);
264         void requestTimerFired(Timer<PluginView>*);
265         void invalidateTimerFired(Timer<PluginView>*);
266         Timer<PluginView> m_requestTimer;
267         Timer<PluginView> m_invalidateTimer;
268
269         void popPopupsStateTimerFired(Timer<PluginView>*);
270         Timer<PluginView> m_popPopupsStateTimer;
271
272         void lifeSupportTimerFired(Timer<PluginView>*);
273         Timer<PluginView> m_lifeSupportTimer;
274
275 #ifndef NP_NO_CARBON
276         bool dispatchNPEvent(NPEvent&);
277 #endif
278         void updatePluginWidget();
279         void paintMissingPluginIcon(GraphicsContext*, const IntRect&);
280
281         void handleKeyboardEvent(KeyboardEvent*);
282         void handleMouseEvent(MouseEvent*);
283 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
284         void handleFocusInEvent();
285         void handleFocusOutEvent();
286 #endif
287
288 #if OS(WINDOWS)
289         void paintIntoTransformedContext(HDC);
290         PassRefPtr<Image> snapshot();
291 #endif
292
293         int m_mode;
294         int m_paramCount;
295         char** m_paramNames;
296         char** m_paramValues;
297         String m_pluginsPage;
298
299         String m_mimeType;
300         CString m_userAgent;
301
302         NPP m_instance;
303         NPP_t m_instanceStruct;
304         NPWindow m_npWindow;
305
306         Vector<bool, 4> m_popupStateStack;
307
308         HashSet<RefPtr<PluginStream> > m_streams;
309         Vector<PluginRequest*> m_requests;
310
311         bool m_isWindowed;
312         bool m_isTransparent;
313         bool m_haveInitialized;
314         bool m_isWaitingToStart;
315
316 #if defined(XP_UNIX)
317         bool m_needsXEmbed;
318 #endif
319
320 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
321         OwnPtr<PluginMessageThrottlerWin> m_messageThrottler;
322         WNDPROC m_pluginWndProc;
323         unsigned m_lastMessage;
324         bool m_isCallingPluginWndProc;
325         HDC m_wmPrintHDC;
326         bool m_haveUpdatedPluginWidget;
327 #endif
328
329 #if ((PLATFORM(QT) || PLATFORM(WX)) && OS(WINDOWS)) || defined(XP_MACOSX)
330         // On Mac OSX and Qt/Windows the plugin does not have its own native widget,
331         // but is using the containing window as its reference for positioning/painting.
332         PlatformPluginWidget m_window;
333 public:
334         PlatformPluginWidget platformPluginWidget() const { return m_window; }
335         void setPlatformPluginWidget(PlatformPluginWidget widget) { m_window = widget; }
336 #else
337 public:
338         void setPlatformPluginWidget(PlatformPluginWidget widget) { setPlatformWidget(widget); }
339         PlatformPluginWidget platformPluginWidget() const { return platformWidget(); }
340 #endif
341
342 private:
343
344 #if defined(XP_UNIX) || OS(SYMBIAN)
345         void setNPWindowIfNeeded();
346 #elif defined(XP_MACOSX)
347         NP_CGContext m_npCgContext;
348         OwnPtr<Timer<PluginView> > m_nullEventTimer;
349         NPDrawingModel m_drawingModel;
350         NPEventModel m_eventModel;
351         CGContextRef m_contextRef;
352         WindowRef m_fakeWindow;
353 #if PLATFORM(QT)
354         QPixmap m_pixmap;
355 #endif
356
357         Point m_lastMousePos;
358         void setNPWindowIfNeeded();
359         void nullEventTimerFired(Timer<PluginView>*);
360         Point globalMousePosForPlugin() const;
361         Point mousePosForPlugin(MouseEvent* event = 0) const;
362 #endif
363
364 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
365         bool m_hasPendingGeometryChange;
366         Pixmap m_drawable;
367         Visual* m_visual;
368         Colormap m_colormap;
369         Display* m_pluginDisplay;
370
371         void initXEvent(XEvent* event);
372 #endif
373
374         IntRect m_clipRect; // The clip rect to apply to a windowed plug-in
375         IntRect m_windowRect; // Our window rect.
376
377         bool m_loadManually;
378         RefPtr<PluginStream> m_manualStream;
379
380         bool m_isJavaScriptPaused;
381
382         bool m_isHalted;
383         bool m_hasBeenHalted;
384
385         static PluginView* s_currentPluginView;
386     };
387
388 } // namespace WebCore
389
390 #endif