• 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 #if USE(V8)
206         NPObject* getNPObject();
207 #endif
208 
209         virtual void invalidateRect(const IntRect&);
210 
211         bool arePopupsAllowed() const;
212 
213         void setJavaScriptPaused(bool);
214 
215         void privateBrowsingStateChanged(bool);
216 
217         void disconnectStream(PluginStream*);
streamDidFinishLoading(PluginStream * stream)218         void streamDidFinishLoading(PluginStream* stream) { disconnectStream(stream); }
219 
220         // Widget functions
221         virtual void setFrameRect(const IntRect&);
222         virtual void frameRectsChanged();
223         virtual void setFocus(bool);
224         virtual void show();
225         virtual void hide();
226         virtual void paint(GraphicsContext*, const IntRect&);
227 
228         // This method is used by plugins on all platforms to obtain a clip rect that includes clips set by WebCore,
229         // e.g., in overflow:auto sections.  The clip rects coordinates are in the containing window's coordinate space.
230         // This clip includes any clips that the widget itself sets up for its children.
231         IntRect windowClipRect() const;
232 
233         virtual void handleEvent(Event*);
234         virtual void setParent(ScrollView*);
235         virtual void setParentVisible(bool);
236 
isPluginView()237         virtual bool isPluginView() const { return true; }
238 
parentFrame()239         Frame* parentFrame() const { return m_parentFrame.get(); }
240 
241         void focusPluginElement();
242 
pluginsPage()243         const String& pluginsPage() const { return m_pluginsPage; }
mimeType()244         const String& mimeType() const { return m_mimeType; }
url()245         const KURL& url() const { return m_url; }
246 
247 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
248         static LRESULT CALLBACK PluginViewWndProc(HWND, UINT, WPARAM, LPARAM);
249         LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
pluginWndProc()250         WNDPROC pluginWndProc() const { return m_pluginWndProc; }
251 #endif
252 
253         // Used for manual loading
254         void didReceiveResponse(const ResourceResponse&);
255         void didReceiveData(const char*, int);
256         void didFinishLoading();
257         void didFail(const ResourceError&);
258 
259         // HaltablePlugin
260         virtual void halt();
261         virtual void restart();
262         virtual Node* node() const;
isWindowed()263         virtual bool isWindowed() const { return m_isWindowed; }
264         virtual String pluginName() const;
265 
isHalted()266         bool isHalted() const { return m_isHalted; }
hasBeenHalted()267         bool hasBeenHalted() const { return m_hasBeenHalted; }
268 
269         static bool isCallingPlugin();
270 
271 #ifdef ANDROID_PLUGINS
getElement()272         Element* getElement() const { return m_element; }
273 #endif
274 
275         bool start();
276 
277 #if ENABLE(NETSCAPE_PLUGIN_API)
278         static void keepAlive(NPP);
279 #endif
280         void keepAlive();
281 
282 #if USE(ACCELERATED_COMPOSITING)
283 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) && PLATFORM(QT)
284         virtual PlatformLayer* platformLayer() const;
285 #elif ENABLE(NETSCAPE_PLUGIN_API) && defined(ANDROID_PLUGINS)
286         virtual PlatformLayer* platformLayer() const;
287 #else
platformLayer()288         virtual PlatformLayer* platformLayer() const { return 0; }
289 #endif
290 #endif
291 
292     private:
293         PluginView(Frame* parentFrame, const IntSize&, PluginPackage*, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
294 
295         void setParameters(const Vector<String>& paramNames, const Vector<String>& paramValues);
296         bool startOrAddToUnstartedList();
297         void init();
298         bool platformStart();
299         void stop();
300         void platformDestroy();
301         static void setCurrentPluginView(PluginView*);
302 #if ENABLE(NETSCAPE_PLUGIN_API)
303         NPError load(const FrameLoadRequest&, bool sendNotification, void* notifyData);
304         NPError handlePost(const char* url, const char* target, uint32_t len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders);
305         NPError handlePostReadFile(Vector<char>& buffer, uint32_t len, const char* buf);
306 #endif
307         static void freeStringArray(char** stringArray, int length);
308         void setCallingPlugin(bool) const;
309 
310         void invalidateWindowlessPluginRect(const IntRect&);
311 
312         virtual void mediaCanStart();
313 
314 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
315         void paintWindowedPluginIntoContext(GraphicsContext*, const IntRect&);
316         static HDC WINAPI hookedBeginPaint(HWND, PAINTSTRUCT*);
317         static BOOL WINAPI hookedEndPaint(HWND, const PAINTSTRUCT*);
318 #endif
319 
320 #if ENABLE(NETSCAPE_PLUGIN_API)
321         static bool platformGetValueStatic(NPNVariable variable, void* value, NPError* result);
322         bool platformGetValue(NPNVariable variable, void* value, NPError* result);
323 #endif
324 
325         RefPtr<Frame> m_parentFrame;
326         RefPtr<PluginPackage> m_plugin;
327         Element* m_element;
328         bool m_isStarted;
329         KURL m_url;
330         KURL m_baseURL;
331         PluginStatus m_status;
332         Vector<IntRect> m_invalidRects;
333 
334         void performRequest(PluginRequest*);
335         void scheduleRequest(PluginRequest*);
336         void requestTimerFired(Timer<PluginView>*);
337         void invalidateTimerFired(Timer<PluginView>*);
338         Timer<PluginView> m_requestTimer;
339         Timer<PluginView> m_invalidateTimer;
340 
341         void popPopupsStateTimerFired(Timer<PluginView>*);
342         Timer<PluginView> m_popPopupsStateTimer;
343 
344         void lifeSupportTimerFired(Timer<PluginView>*);
345         Timer<PluginView> m_lifeSupportTimer;
346 
347 #ifndef NP_NO_CARBON
348 #if ENABLE(NETSCAPE_PLUGIN_API)
349         bool dispatchNPEvent(NPEvent&);
350 #endif // ENABLE(NETSCAPE_PLUGIN_API)
351 #endif
352         void updatePluginWidget();
353         void paintMissingPluginIcon(GraphicsContext*, const IntRect&);
354 
355         void handleKeyboardEvent(KeyboardEvent*);
356         void handleMouseEvent(MouseEvent*);
357 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
358         void handleFocusInEvent();
359         void handleFocusOutEvent();
360 #endif
361 
362 #if OS(WINDOWS)
363         void paintIntoTransformedContext(HDC);
364         PassRefPtr<Image> snapshot();
365 #endif
366 
367 #ifdef ANDROID_PLUGINS
368         void handleFocusEvent(bool hasFocus);
369         void handleTouchEvent(TouchEvent*);
370         // called at the end of the base constructor
371         void platformInit();
372 #endif
373 #ifdef PLUGIN_PLATFORM_SETVALUE
374         // called if the default setValue does not recognize the variable
375         NPError platformSetValue(NPPVariable variable, void* value);
376 #endif
377 
378         int m_mode;
379         int m_paramCount;
380         char** m_paramNames;
381         char** m_paramValues;
382         String m_pluginsPage;
383 
384         String m_mimeType;
385         WTF::CString m_userAgent;
386 
387 #if ENABLE(NETSCAPE_PLUGIN_API)
388         NPP m_instance;
389         NPP_t m_instanceStruct;
390         NPWindow m_npWindow;
391 #endif
392 
393         Vector<bool, 4> m_popupStateStack;
394 
395         HashSet<RefPtr<PluginStream> > m_streams;
396         Vector<PluginRequest*> m_requests;
397 
398         bool m_isWindowed;
399         bool m_isTransparent;
400         bool m_haveInitialized;
401         bool m_isWaitingToStart;
402 
403 #if defined(XP_UNIX)
404         bool m_needsXEmbed;
405 #endif
406 
407 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
408         OwnPtr<PluginMessageThrottlerWin> m_messageThrottler;
409         WNDPROC m_pluginWndProc;
410         unsigned m_lastMessage;
411         bool m_isCallingPluginWndProc;
412         HDC m_wmPrintHDC;
413         bool m_haveUpdatedPluginWidget;
414 #endif
415 
416 // ANDROID
417 // TODO: Upstream to webkit.org
418 #ifdef PLUGIN_SCHEDULE_TIMER
419         PluginTimerList m_timerList;
420 #endif
421 
422 #if ((PLATFORM(QT) || PLATFORM(WX)) && OS(WINDOWS)) || defined(XP_MACOSX)
423         // On Mac OSX and Qt/Windows the plugin does not have its own native widget,
424         // but is using the containing window as its reference for positioning/painting.
425         PlatformPluginWidget m_window;
426 public:
platformPluginWidget()427         PlatformPluginWidget platformPluginWidget() const { return m_window; }
setPlatformPluginWidget(PlatformPluginWidget widget)428         void setPlatformPluginWidget(PlatformPluginWidget widget) { m_window = widget; }
429 #elif defined(ANDROID_PLUGINS)
430 public:
431         PlatformPluginWidget m_window;
platformPluginWidget()432         PlatformPluginWidget platformPluginWidget() const { return m_window; } // MANUAL MERGE FIXME
433 #else
434 public:
setPlatformPluginWidget(PlatformPluginWidget widget)435         void setPlatformPluginWidget(PlatformPluginWidget widget) { setPlatformWidget(widget); }
platformPluginWidget()436         PlatformPluginWidget platformPluginWidget() const { return platformWidget(); }
437 #endif
438 
439 private:
440 
441 #if defined(XP_UNIX) || OS(SYMBIAN) || PLATFORM(GTK) || defined(ANDROID_PLUGINS)
442         void setNPWindowIfNeeded();
443 #elif defined(XP_MACOSX)
444         NP_CGContext m_npCgContext;
445         OwnPtr<Timer<PluginView> > m_nullEventTimer;
446         NPDrawingModel m_drawingModel;
447         NPEventModel m_eventModel;
448         CGContextRef m_contextRef;
449         WindowRef m_fakeWindow;
450 #if PLATFORM(QT)
451         QPixmap m_pixmap;
452 #endif
453 
454         Point m_lastMousePos;
455         void setNPWindowIfNeeded();
456         void nullEventTimerFired(Timer<PluginView>*);
457         Point globalMousePosForPlugin() const;
458         Point mousePosForPlugin(MouseEvent* event = 0) const;
459 #endif
460 
461 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
462         bool m_hasPendingGeometryChange;
463         Pixmap m_drawable;
464         Visual* m_visual;
465         Colormap m_colormap;
466         Display* m_pluginDisplay;
467 
468         void initXEvent(XEvent* event);
469 #endif
470 
471 #if PLATFORM(QT)
472 #if defined(MOZ_PLATFORM_MAEMO) && (MOZ_PLATFORM_MAEMO >= 5)
473         QImage m_image;
474         bool m_renderToImage;
475         void paintUsingImageSurfaceExtension(QPainter* painter, const IntRect& exposedRect);
476 #endif
477 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
478         void paintUsingXPixmap(QPainter* painter, const QRect &exposedRect);
479 #if USE(ACCELERATED_COMPOSITING)
480         OwnPtr<PlatformLayer> m_platformLayer;
481         friend class PluginGraphicsLayerQt;
482 #endif // USE(ACCELERATED_COMPOSITING)
483 #endif
484 #endif // PLATFORM(QT)
485 
486 #if PLATFORM(GTK)
487         static gboolean plugRemovedCallback(GtkSocket*, PluginView*);
488         static void plugAddedCallback(GtkSocket*, PluginView*);
489         bool m_plugAdded;
490         IntRect m_delayedAllocation;
491 #endif
492 
493         IntRect m_clipRect; // The clip rect to apply to a windowed plug-in
494         IntRect m_windowRect; // Our window rect.
495 #ifdef ANDROID_PLUGINS
496         IntRect m_pageRect; // The rect in page coordinate system.
497 #endif
498 
499         bool m_loadManually;
500         RefPtr<PluginStream> m_manualStream;
501 
502         bool m_isJavaScriptPaused;
503 
504         bool m_isHalted;
505         bool m_hasBeenHalted;
506 
507         bool m_haveCalledSetWindow;
508 
509         static PluginView* s_currentPluginView;
510     };
511 
512 } // namespace WebCore
513 
514 #endif
515