Home | History | Annotate | Download | only in plugins
      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 (at) 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:
    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:
    123         const FrameLoadRequest& frameLoadRequest() const { return m_frameLoadRequest; }
    124         void* notifyData() const { return m_notifyData; }
    125         bool sendNotification() const { return m_sendNotification; }
    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:
    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 
    154         PluginPackage* plugin() const { return m_plugin.get(); }
    155 #if ENABLE(NETSCAPE_PLUGIN_API)
    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 
    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*);
    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 
    235         virtual bool isPluginView() const { return true; }
    236 
    237         Frame* parentFrame() const { return m_parentFrame.get(); }
    238 
    239         void focusPluginElement();
    240 
    241         const String& pluginsPage() const { return m_pluginsPage; }
    242         const String& mimeType() const { return m_mimeType; }
    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);
    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;
    261         virtual bool isWindowed() const { return m_isWindowed; }
    262         virtual String pluginName() const;
    263 
    264         bool isHalted() const { return m_isHalted; }
    265         bool hasBeenHalted() const { return m_hasBeenHalted; }
    266 
    267         static bool isCallingPlugin();
    268 
    269 #ifdef ANDROID_PLUGINS
    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
    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:
    425         PlatformPluginWidget platformPluginWidget() const { return m_window; }
    426         void setPlatformPluginWidget(PlatformPluginWidget widget) { m_window = widget; }
    427 #elif defined(ANDROID_PLUGINS)
    428 public:
    429         PlatformPluginWidget m_window;
    430         PlatformPluginWidget platformPluginWidget() const { return m_window; } // MANUAL MERGE FIXME
    431 #else
    432 public:
    433         void setPlatformPluginWidget(PlatformPluginWidget widget) { setPlatformWidget(widget); }
    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