• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "FrameLoadRequest.h"
32 #include "HaltablePlugin.h"
33 #include "IntRect.h"
34 #include "MediaCanStartListener.h"
35 #include "PluginViewBase.h"
36 #include "ResourceRequest.h"
37 #include "Timer.h"
38 #include <wtf/HashMap.h>
39 #include <wtf/HashSet.h>
40 #include <wtf/OwnPtr.h>
41 #include <wtf/PassRefPtr.h>
42 #include <wtf/RefPtr.h>
43 #include <wtf/Vector.h>
44 #include <wtf/text/CString.h>
45 
46 #if ENABLE(NETSCAPE_PLUGIN_API)
47 #include "PluginStream.h"
48 #include "npruntime_internal.h"
49 #endif
50 
51 // ANDROID
52 // TODO: Upstream to webkit.org
53 #ifdef PLUGIN_SCHEDULE_TIMER
54 #include "PluginTimer.h"
55 #endif
56 
57 #if OS(WINDOWS) && (PLATFORM(QT) || PLATFORM(WX))
58 typedef struct HWND__* HWND;
59 typedef HWND PlatformPluginWidget;
60 #elif defined(ANDROID_PLUGINS)
61 typedef struct PluginWidgetAndroid* PlatformPluginWidget;
62 #else
63 typedef PlatformWidget PlatformPluginWidget;
64 #if defined(XP_MACOSX) && PLATFORM(QT)
65 #include <QPixmap>
66 #endif
67 #endif
68 #if PLATFORM(QT)
69 #include <QGraphicsItem>
70 #include <QImage>
71 QT_BEGIN_NAMESPACE
72 class QPainter;
73 QT_END_NAMESPACE
74 #endif
75 #if PLATFORM(GTK)
76 typedef struct _GtkSocket GtkSocket;
77 #endif
78 
79 #if USE(JSC)
80 namespace JSC {
81     namespace Bindings {
82         class Instance;
83     }
84 }
85 #endif
86 
87 class NPObject;
88 
89 namespace WebCore {
90     class Element;
91     class Frame;
92     class Image;
93     class KeyboardEvent;
94     class MouseEvent;
95 #ifdef ANDROID_PLUGINS
96     class TouchEvent;
97 #endif
98     class KURL;
99 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
100     class PluginMessageThrottlerWin;
101 #endif
102     class PluginPackage;
103     class PluginRequest;
104     class PluginStream;
105     class ResourceError;
106     class ResourceResponse;
107 
108     enum PluginStatus {
109         PluginStatusCanNotFindPlugin,
110         PluginStatusCanNotLoadPlugin,
111         PluginStatusLoadedSuccessfully
112     };
113 
114     class PluginRequest {
115         WTF_MAKE_NONCOPYABLE(PluginRequest); WTF_MAKE_FAST_ALLOCATED;
116     public:
PluginRequest(const FrameLoadRequest & frameLoadRequest,bool sendNotification,void * notifyData,bool shouldAllowPopups)117         PluginRequest(const FrameLoadRequest& frameLoadRequest, bool sendNotification, void* notifyData, bool shouldAllowPopups)
118             : m_frameLoadRequest(frameLoadRequest)
119             , m_notifyData(notifyData)
120             , m_sendNotification(sendNotification)
121             , m_shouldAllowPopups(shouldAllowPopups) { }
122     public:
frameLoadRequest()123         const FrameLoadRequest& frameLoadRequest() const { return m_frameLoadRequest; }
notifyData()124         void* notifyData() const { return m_notifyData; }
sendNotification()125         bool sendNotification() const { return m_sendNotification; }
shouldAllowPopups()126         bool shouldAllowPopups() const { return m_shouldAllowPopups; }
127     private:
128         FrameLoadRequest m_frameLoadRequest;
129         void* m_notifyData;
130         bool m_sendNotification;
131         bool m_shouldAllowPopups;
132     };
133 
134     class PluginManualLoader {
135     public:
~PluginManualLoader()136         virtual ~PluginManualLoader() {}
137         virtual void didReceiveResponse(const ResourceResponse&) = 0;
138         virtual void didReceiveData(const char*, int) = 0;
139         virtual void didFinishLoading() = 0;
140         virtual void didFail(const ResourceError&) = 0;
141     };
142 
143     class PluginView : public PluginViewBase
144 #if ENABLE(NETSCAPE_PLUGIN_API)
145                      , private PluginStreamClient
146 #endif
147                      , public PluginManualLoader
148                      , private HaltablePlugin
149                      , private MediaCanStartListener {
150     public:
151         static PassRefPtr<PluginView> create(Frame* parentFrame, const IntSize&, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
152         virtual ~PluginView();
153 
plugin()154         PluginPackage* plugin() const { return m_plugin.get(); }
155 #if ENABLE(NETSCAPE_PLUGIN_API)
instance()156         NPP instance() const { return m_instance; }
157 #endif
158 
159         void setNPWindowRect(const IntRect&);
160         static PluginView* currentPluginView();
161 
162 #if ENABLE(NETSCAPE_PLUGIN_API)
163         NPObject* npObject();
164 #endif
165 #if USE(JSC)
166         PassRefPtr<JSC::Bindings::Instance> bindingInstance();
167 #endif
168 
status()169         PluginStatus status() const { return m_status; }
170 
171 #if ENABLE(NETSCAPE_PLUGIN_API)
172         // NPN functions
173         NPError getURLNotify(const char* url, const char* target, void* notifyData);
174         NPError getURL(const char* url, const char* target);
175         NPError postURLNotify(const char* url, const char* target, uint32_t len, const char* but, NPBool file, void* notifyData);
176         NPError postURL(const char* url, const char* target, uint32_t len, const char* but, NPBool file);
177         NPError newStream(NPMIMEType type, const char* target, NPStream** stream);
178         int32_t write(NPStream* stream, int32_t len, void* buffer);
179         NPError destroyStream(NPStream* stream, NPReason reason);
180 #endif
181         const char* userAgent();
182 #if ENABLE(NETSCAPE_PLUGIN_API)
183         static const char* userAgentStatic();
184 #endif
185         void status(const char* message);
186 
187 #if ENABLE(NETSCAPE_PLUGIN_API)
188         NPError getValue(NPNVariable variable, void* value);
189         static NPError getValueStatic(NPNVariable variable, void* value);
190         NPError setValue(NPPVariable variable, void* value);
191         NPError getValueForURL(NPNURLVariable variable, const char* url, char** value, uint32_t* len);
192         NPError setValueForURL(NPNURLVariable variable, const char* url, const char* value, uint32_t len);
193         NPError getAuthenticationInfo(const char* protocol, const char* host, int32_t port, const char* scheme, const char* realm, char** username, uint32_t* ulen, char** password, uint32_t* plen);
194         void invalidateRect(NPRect*);
195         void invalidateRegion(NPRegion);
196 #endif
197         void forceRedraw();
198         void pushPopupsEnabledState(bool state);
199         void popPopupsEnabledState();
200 #ifdef PLUGIN_SCHEDULE_TIMER
201         uint32_t scheduleTimer(NPP, uint32_t interval, bool repeat,
202                              void (*timerFunc)(NPP, uint32_t timerID));
203         void unscheduleTimer(NPP, uint32_t timerID);
204 #endif
205         NPObject* getNPObject();
206 
207         virtual void invalidateRect(const IntRect&);
208 
209         bool arePopupsAllowed() const;
210 
211         void setJavaScriptPaused(bool);
212 
213         void privateBrowsingStateChanged(bool);
214 
215         void disconnectStream(PluginStream*);
streamDidFinishLoading(PluginStream * stream)216         void streamDidFinishLoading(PluginStream* stream) { disconnectStream(stream); }
217 
218         // Widget functions
219         virtual void setFrameRect(const IntRect&);
220         virtual void frameRectsChanged();
221         virtual void setFocus(bool);
222         virtual void show();
223         virtual void hide();
224         virtual void paint(GraphicsContext*, const IntRect&);
225 
226         // This method is used by plugins on all platforms to obtain a clip rect that includes clips set by WebCore,
227         // e.g., in overflow:auto sections.  The clip rects coordinates are in the containing window's coordinate space.
228         // This clip includes any clips that the widget itself sets up for its children.
229         IntRect windowClipRect() const;
230 
231         virtual void handleEvent(Event*);
232         virtual void setParent(ScrollView*);
233         virtual void setParentVisible(bool);
234 
isPluginView()235         virtual bool isPluginView() const { return true; }
236 
parentFrame()237         Frame* parentFrame() const { return m_parentFrame.get(); }
238 
239         void focusPluginElement();
240 
pluginsPage()241         const String& pluginsPage() const { return m_pluginsPage; }
mimeType()242         const String& mimeType() const { return m_mimeType; }
url()243         const KURL& url() const { return m_url; }
244 
245 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
246         static LRESULT CALLBACK PluginViewWndProc(HWND, UINT, WPARAM, LPARAM);
247         LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
pluginWndProc()248         WNDPROC pluginWndProc() const { return m_pluginWndProc; }
249 #endif
250 
251         // Used for manual loading
252         void didReceiveResponse(const ResourceResponse&);
253         void didReceiveData(const char*, int);
254         void didFinishLoading();
255         void didFail(const ResourceError&);
256 
257         // HaltablePlugin
258         virtual void halt();
259         virtual void restart();
260         virtual Node* node() const;
isWindowed()261         virtual bool isWindowed() const { return m_isWindowed; }
262         virtual String pluginName() const;
263 
isHalted()264         bool isHalted() const { return m_isHalted; }
hasBeenHalted()265         bool hasBeenHalted() const { return m_hasBeenHalted; }
266 
267         static bool isCallingPlugin();
268 
269 #ifdef ANDROID_PLUGINS
getElement()270         Element* getElement() const { return m_element; }
271 #endif
272 
273         bool start();
274 
275 #if ENABLE(NETSCAPE_PLUGIN_API)
276         static void keepAlive(NPP);
277 #endif
278         void keepAlive();
279 
280 #if USE(ACCELERATED_COMPOSITING)
281 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) && PLATFORM(QT)
282         virtual PlatformLayer* platformLayer() const;
283 #elif ENABLE(NETSCAPE_PLUGIN_API) && defined(ANDROID_PLUGINS)
284         virtual PlatformLayer* platformLayer() const;
285 #else
platformLayer()286         virtual PlatformLayer* platformLayer() const { return 0; }
287 #endif
288 #endif
289 
290     private:
291         PluginView(Frame* parentFrame, const IntSize&, PluginPackage*, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
292 
293         void setParameters(const Vector<String>& paramNames, const Vector<String>& paramValues);
294         bool startOrAddToUnstartedList();
295         void init();
296         bool platformStart();
297         void stop();
298         void platformDestroy();
299         static void setCurrentPluginView(PluginView*);
300 #if ENABLE(NETSCAPE_PLUGIN_API)
301         NPError load(const FrameLoadRequest&, bool sendNotification, void* notifyData);
302         NPError handlePost(const char* url, const char* target, uint32_t len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders);
303         NPError handlePostReadFile(Vector<char>& buffer, uint32_t len, const char* buf);
304 #endif
305         static void freeStringArray(char** stringArray, int length);
306         void setCallingPlugin(bool) const;
307 
308         void invalidateWindowlessPluginRect(const IntRect&);
309 
310         virtual void mediaCanStart();
311 
312 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
313         void paintWindowedPluginIntoContext(GraphicsContext*, const IntRect&);
314         static HDC WINAPI hookedBeginPaint(HWND, PAINTSTRUCT*);
315         static BOOL WINAPI hookedEndPaint(HWND, const PAINTSTRUCT*);
316 #endif
317 
318 #if ENABLE(NETSCAPE_PLUGIN_API)
319         static bool platformGetValueStatic(NPNVariable variable, void* value, NPError* result);
320         bool platformGetValue(NPNVariable variable, void* value, NPError* result);
321 #endif
322 
323         RefPtr<Frame> m_parentFrame;
324         RefPtr<PluginPackage> m_plugin;
325         Element* m_element;
326         bool m_isStarted;
327         KURL m_url;
328         KURL m_baseURL;
329         PluginStatus m_status;
330         Vector<IntRect> m_invalidRects;
331 
332         void performRequest(PluginRequest*);
333         void scheduleRequest(PluginRequest*);
334         void requestTimerFired(Timer<PluginView>*);
335         void invalidateTimerFired(Timer<PluginView>*);
336         Timer<PluginView> m_requestTimer;
337         Timer<PluginView> m_invalidateTimer;
338 
339         void popPopupsStateTimerFired(Timer<PluginView>*);
340         Timer<PluginView> m_popPopupsStateTimer;
341 
342         void lifeSupportTimerFired(Timer<PluginView>*);
343         Timer<PluginView> m_lifeSupportTimer;
344 
345 #ifndef NP_NO_CARBON
346 #if ENABLE(NETSCAPE_PLUGIN_API)
347         bool dispatchNPEvent(NPEvent&);
348 #endif // ENABLE(NETSCAPE_PLUGIN_API)
349 #endif
350         void updatePluginWidget();
351         void paintMissingPluginIcon(GraphicsContext*, const IntRect&);
352 
353         void handleKeyboardEvent(KeyboardEvent*);
354         void handleMouseEvent(MouseEvent*);
355 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
356         void handleFocusInEvent();
357         void handleFocusOutEvent();
358 #endif
359 
360 #if OS(WINDOWS)
361         void paintIntoTransformedContext(HDC);
362         PassRefPtr<Image> snapshot();
363 #endif
364 
365 #ifdef ANDROID_PLUGINS
366         void handleFocusEvent(bool hasFocus);
367         void handleTouchEvent(TouchEvent*);
368         // called at the end of the base constructor
369         void platformInit();
370 #endif
371 #ifdef PLUGIN_PLATFORM_SETVALUE
372         // called if the default setValue does not recognize the variable
373         NPError platformSetValue(NPPVariable variable, void* value);
374 #endif
375 
376         int m_mode;
377         int m_paramCount;
378         char** m_paramNames;
379         char** m_paramValues;
380         String m_pluginsPage;
381 
382         String m_mimeType;
383         WTF::CString m_userAgent;
384 
385 #if ENABLE(NETSCAPE_PLUGIN_API)
386         NPP m_instance;
387         NPP_t m_instanceStruct;
388         NPWindow m_npWindow;
389 #endif
390 
391         Vector<bool, 4> m_popupStateStack;
392 
393         HashSet<RefPtr<PluginStream> > m_streams;
394         Vector<PluginRequest*> m_requests;
395 
396         bool m_isWindowed;
397         bool m_isTransparent;
398         bool m_haveInitialized;
399         bool m_isWaitingToStart;
400 
401 #if defined(XP_UNIX)
402         bool m_needsXEmbed;
403 #endif
404 
405 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
406         OwnPtr<PluginMessageThrottlerWin> m_messageThrottler;
407         WNDPROC m_pluginWndProc;
408         unsigned m_lastMessage;
409         bool m_isCallingPluginWndProc;
410         HDC m_wmPrintHDC;
411         bool m_haveUpdatedPluginWidget;
412 #endif
413 
414 // ANDROID
415 // TODO: Upstream to webkit.org
416 #ifdef PLUGIN_SCHEDULE_TIMER
417         PluginTimerList m_timerList;
418 #endif
419 
420 #if ((PLATFORM(QT) || PLATFORM(WX)) && OS(WINDOWS)) || defined(XP_MACOSX)
421         // On Mac OSX and Qt/Windows the plugin does not have its own native widget,
422         // but is using the containing window as its reference for positioning/painting.
423         PlatformPluginWidget m_window;
424 public:
platformPluginWidget()425         PlatformPluginWidget platformPluginWidget() const { return m_window; }
setPlatformPluginWidget(PlatformPluginWidget widget)426         void setPlatformPluginWidget(PlatformPluginWidget widget) { m_window = widget; }
427 #elif defined(ANDROID_PLUGINS)
428 public:
429         PlatformPluginWidget m_window;
platformPluginWidget()430         PlatformPluginWidget platformPluginWidget() const { return m_window; } // MANUAL MERGE FIXME
431 #else
432 public:
setPlatformPluginWidget(PlatformPluginWidget widget)433         void setPlatformPluginWidget(PlatformPluginWidget widget) { setPlatformWidget(widget); }
platformPluginWidget()434         PlatformPluginWidget platformPluginWidget() const { return platformWidget(); }
435 #endif
436 
437 private:
438 
439 #if defined(XP_UNIX) || OS(SYMBIAN) || PLATFORM(GTK) || defined(ANDROID_PLUGINS)
440         void setNPWindowIfNeeded();
441 #elif defined(XP_MACOSX)
442         NP_CGContext m_npCgContext;
443         OwnPtr<Timer<PluginView> > m_nullEventTimer;
444         NPDrawingModel m_drawingModel;
445         NPEventModel m_eventModel;
446         CGContextRef m_contextRef;
447         WindowRef m_fakeWindow;
448 #if PLATFORM(QT)
449         QPixmap m_pixmap;
450 #endif
451 
452         Point m_lastMousePos;
453         void setNPWindowIfNeeded();
454         void nullEventTimerFired(Timer<PluginView>*);
455         Point globalMousePosForPlugin() const;
456         Point mousePosForPlugin(MouseEvent* event = 0) const;
457 #endif
458 
459 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
460         bool m_hasPendingGeometryChange;
461         Pixmap m_drawable;
462         Visual* m_visual;
463         Colormap m_colormap;
464         Display* m_pluginDisplay;
465 
466         void initXEvent(XEvent* event);
467 #endif
468 
469 #if PLATFORM(QT)
470 #if defined(MOZ_PLATFORM_MAEMO) && (MOZ_PLATFORM_MAEMO >= 5)
471         QImage m_image;
472         bool m_renderToImage;
473         void paintUsingImageSurfaceExtension(QPainter* painter, const IntRect& exposedRect);
474 #endif
475 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
476         void paintUsingXPixmap(QPainter* painter, const QRect &exposedRect);
477 #if USE(ACCELERATED_COMPOSITING)
478         OwnPtr<PlatformLayer> m_platformLayer;
479         friend class PluginGraphicsLayerQt;
480 #endif // USE(ACCELERATED_COMPOSITING)
481 #endif
482 #endif // PLATFORM(QT)
483 
484 #if PLATFORM(GTK)
485         static gboolean plugRemovedCallback(GtkSocket*, PluginView*);
486         static void plugAddedCallback(GtkSocket*, PluginView*);
487         bool m_plugAdded;
488         IntRect m_delayedAllocation;
489 #endif
490 
491         IntRect m_clipRect; // The clip rect to apply to a windowed plug-in
492         IntRect m_windowRect; // Our window rect.
493 #ifdef ANDROID_PLUGINS
494         IntRect m_pageRect; // The rect in page coordinate system.
495 #endif
496 
497         bool m_loadManually;
498         RefPtr<PluginStream> m_manualStream;
499 
500         bool m_isJavaScriptPaused;
501 
502         bool m_isHalted;
503         bool m_hasBeenHalted;
504 
505         bool m_haveCalledSetWindow;
506 
507         static PluginView* s_currentPluginView;
508     };
509 
510 } // namespace WebCore
511 
512 #endif
513