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 #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*);
    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 
    237         virtual bool isPluginView() const { return true; }
    238 
    239         Frame* parentFrame() const { return m_parentFrame.get(); }
    240 
    241         void focusPluginElement();
    242 
    243         const String& pluginsPage() const { return m_pluginsPage; }
    244         const String& mimeType() const { return m_mimeType; }
    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);
    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;
    263         virtual bool isWindowed() const { return m_isWindowed; }
    264         virtual String pluginName() const;
    265 
    266         bool isHalted() const { return m_isHalted; }
    267         bool hasBeenHalted() const { return m_hasBeenHalted; }
    268 
    269         static bool isCallingPlugin();
    270 
    271 #ifdef ANDROID_PLUGINS
    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
    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:
    427         PlatformPluginWidget platformPluginWidget() const { return m_window; }
    428         void setPlatformPluginWidget(PlatformPluginWidget widget) { m_window = widget; }
    429 #elif defined(ANDROID_PLUGINS)
    430 public:
    431         PlatformPluginWidget m_window;
    432         PlatformPluginWidget platformPluginWidget() const { return m_window; } // MANUAL MERGE FIXME
    433 #else
    434 public:
    435         void setPlatformPluginWidget(PlatformPluginWidget widget) { setPlatformWidget(widget); }
    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