Home | History | Annotate | Download | only in plugins
      1 
      2 /*
      3  * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
      4  * Copyright (C) 2008 Collabora Ltd. All rights reserved.
      5  * Copyright (C) 2009 Girish Ramakrishnan <girish (at) forwardbias.in>
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     23  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     24  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #ifndef PluginView_H
     30 #define PluginView_H
     31 
     32 #include "CString.h"
     33 #include "FrameLoadRequest.h"
     34 #include "HaltablePlugin.h"
     35 #include "IntRect.h"
     36 #include "KURL.h"
     37 #include "PlatformString.h"
     38 #include "PluginStream.h"
     39 #include "ResourceRequest.h"
     40 #include "Timer.h"
     41 #include "Widget.h"
     42 #include "npruntime_internal.h"
     43 #include <wtf/HashMap.h>
     44 #include <wtf/HashSet.h>
     45 #include <wtf/OwnPtr.h>
     46 #include <wtf/PassRefPtr.h>
     47 #include <wtf/RefPtr.h>
     48 #include <wtf/Vector.h>
     49 
     50 // ANDROID
     51 // TODO: Upstream to webkit.org
     52 #ifdef PLUGIN_SCHEDULE_TIMER
     53 #include "PluginTimer.h"
     54 #endif
     55 
     56 #if OS(WINDOWS) && (PLATFORM(QT) || PLATFORM(WX))
     57 typedef struct HWND__* HWND;
     58 typedef HWND PlatformPluginWidget;
     59 #elif defined(ANDROID_PLUGINS)
     60 typedef struct PluginWidgetAndroid* PlatformPluginWidget;
     61 #else
     62 typedef PlatformWidget PlatformPluginWidget;
     63 #if defined(XP_MACOSX) && PLATFORM(QT)
     64 #include <QPixmap>
     65 #endif
     66 #endif
     67 
     68 #if USE(JSC)
     69 namespace JSC {
     70     namespace Bindings {
     71         class Instance;
     72     }
     73 }
     74 #endif
     75 
     76 class NPObject;
     77 
     78 namespace WebCore {
     79     class Element;
     80     class Frame;
     81     class Image;
     82     class KeyboardEvent;
     83     class MouseEvent;
     84 #ifdef ANDROID_PLUGINS
     85     class TouchEvent;
     86 #endif
     87     class KURL;
     88 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
     89     class PluginMessageThrottlerWin;
     90 #endif
     91     class PluginPackage;
     92     class PluginRequest;
     93     class PluginStream;
     94     class ResourceError;
     95     class ResourceResponse;
     96 
     97     enum PluginStatus {
     98         PluginStatusCanNotFindPlugin,
     99         PluginStatusCanNotLoadPlugin,
    100         PluginStatusLoadedSuccessfully
    101     };
    102 
    103     class PluginRequest : public Noncopyable {
    104     public:
    105         PluginRequest(const FrameLoadRequest& frameLoadRequest, bool sendNotification, void* notifyData, bool shouldAllowPopups)
    106             : m_frameLoadRequest(frameLoadRequest)
    107             , m_notifyData(notifyData)
    108             , m_sendNotification(sendNotification)
    109             , m_shouldAllowPopups(shouldAllowPopups) { }
    110     public:
    111         const FrameLoadRequest& frameLoadRequest() const { return m_frameLoadRequest; }
    112         void* notifyData() const { return m_notifyData; }
    113         bool sendNotification() const { return m_sendNotification; }
    114         bool shouldAllowPopups() const { return m_shouldAllowPopups; }
    115     private:
    116         FrameLoadRequest m_frameLoadRequest;
    117         void* m_notifyData;
    118         bool m_sendNotification;
    119         bool m_shouldAllowPopups;
    120     };
    121 
    122     class PluginManualLoader {
    123     public:
    124         virtual ~PluginManualLoader() {}
    125         virtual void didReceiveResponse(const ResourceResponse&) = 0;
    126         virtual void didReceiveData(const char*, int) = 0;
    127         virtual void didFinishLoading() = 0;
    128         virtual void didFail(const ResourceError&) = 0;
    129     };
    130 
    131     class PluginView : public Widget, private PluginStreamClient, public PluginManualLoader, private HaltablePlugin {
    132     public:
    133         static PassRefPtr<PluginView> create(Frame* parentFrame, const IntSize&, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
    134         virtual ~PluginView();
    135 
    136         PluginPackage* plugin() const { return m_plugin.get(); }
    137         NPP instance() const { return m_instance; }
    138 
    139         void setNPWindowRect(const IntRect&);
    140         static PluginView* currentPluginView();
    141 
    142 #if USE(JSC)
    143         PassRefPtr<JSC::Bindings::Instance> bindingInstance();
    144 #elif USE(V8)
    145         NPObject* getNPObject();
    146 #endif
    147 
    148         PluginStatus status() const { return m_status; }
    149 
    150         // NPN functions
    151         NPError getURLNotify(const char* url, const char* target, void* notifyData);
    152         NPError getURL(const char* url, const char* target);
    153         NPError postURLNotify(const char* url, const char* target, uint32 len, const char* but, NPBool file, void* notifyData);
    154         NPError postURL(const char* url, const char* target, uint32 len, const char* but, NPBool file);
    155         NPError newStream(NPMIMEType type, const char* target, NPStream** stream);
    156         int32 write(NPStream* stream, int32 len, void* buffer);
    157         NPError destroyStream(NPStream* stream, NPReason reason);
    158         const char* userAgent();
    159 #if ENABLE(NETSCAPE_PLUGIN_API)
    160         static const char* userAgentStatic();
    161 #endif
    162         void status(const char* message);
    163         NPError getValue(NPNVariable variable, void* value);
    164 #if ENABLE(NETSCAPE_PLUGIN_API)
    165         static NPError getValueStatic(NPNVariable variable, void* value);
    166 #endif
    167         NPError setValue(NPPVariable variable, void* value);
    168         void invalidateRect(NPRect*);
    169         void invalidateRegion(NPRegion);
    170         void forceRedraw();
    171         void pushPopupsEnabledState(bool state);
    172         void popPopupsEnabledState();
    173 #ifdef PLUGIN_SCHEDULE_TIMER
    174         uint32 scheduleTimer(NPP, uint32 interval, bool repeat,
    175                              void (*timerFunc)(NPP, uint32 timerID));
    176         void unscheduleTimer(NPP, uint32 timerID);
    177 #endif
    178 
    179         virtual void invalidateRect(const IntRect&);
    180 
    181         bool arePopupsAllowed() const;
    182 
    183         void setJavaScriptPaused(bool);
    184 
    185         void disconnectStream(PluginStream*);
    186         void streamDidFinishLoading(PluginStream* stream) { disconnectStream(stream); }
    187 
    188         // Widget functions
    189         virtual void setFrameRect(const IntRect&);
    190         virtual void frameRectsChanged();
    191         virtual void setFocus();
    192         virtual void show();
    193         virtual void hide();
    194         virtual void paint(GraphicsContext*, const IntRect&);
    195 
    196         // This method is used by plugins on all platforms to obtain a clip rect that includes clips set by WebCore,
    197         // e.g., in overflow:auto sections.  The clip rects coordinates are in the containing window's coordinate space.
    198         // This clip includes any clips that the widget itself sets up for its children.
    199         IntRect windowClipRect() const;
    200 
    201         virtual void handleEvent(Event*);
    202         virtual void setParent(ScrollView*);
    203         virtual void setParentVisible(bool);
    204 
    205         virtual bool isPluginView() const { return true; }
    206 
    207         Frame* parentFrame() const { return m_parentFrame.get(); }
    208 
    209         void focusPluginElement();
    210 
    211         const String& pluginsPage() const { return m_pluginsPage; }
    212         const String& mimeType() const { return m_mimeType; }
    213         const KURL& url() const { return m_url; }
    214 
    215 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
    216         static LRESULT CALLBACK PluginViewWndProc(HWND, UINT, WPARAM, LPARAM);
    217         LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    218         WNDPROC pluginWndProc() const { return m_pluginWndProc; }
    219 #endif
    220 
    221         // Used for manual loading
    222         void didReceiveResponse(const ResourceResponse&);
    223         void didReceiveData(const char*, int);
    224         void didFinishLoading();
    225         void didFail(const ResourceError&);
    226 
    227         // HaltablePlugin
    228         virtual void halt();
    229         virtual void restart();
    230         virtual Node* node() const;
    231         virtual bool isWindowed() const { return m_isWindowed; }
    232         virtual String pluginName() const;
    233 
    234         bool isHalted() const { return m_isHalted; }
    235         bool hasBeenHalted() const { return m_hasBeenHalted; }
    236 
    237         static bool isCallingPlugin();
    238 
    239 #ifdef ANDROID_PLUGINS
    240         Element* getElement() const { return m_element; }
    241 #endif
    242 
    243         bool start();
    244 
    245         static void keepAlive(NPP);
    246         void keepAlive();
    247 
    248     private:
    249         PluginView(Frame* parentFrame, const IntSize&, PluginPackage*, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
    250 
    251         void setParameters(const Vector<String>& paramNames, const Vector<String>& paramValues);
    252         bool startOrAddToUnstartedList();
    253         void removeFromUnstartedListIfNecessary();
    254         void init();
    255         bool platformStart();
    256         void stop();
    257         void platformDestroy();
    258         static void setCurrentPluginView(PluginView*);
    259         NPError load(const FrameLoadRequest&, bool sendNotification, void* notifyData);
    260         NPError handlePost(const char* url, const char* target, uint32 len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders);
    261         NPError handlePostReadFile(Vector<char>& buffer, uint32 len, const char* buf);
    262         static void freeStringArray(char** stringArray, int length);
    263         void setCallingPlugin(bool) const;
    264 
    265         void invalidateWindowlessPluginRect(const IntRect&);
    266 
    267 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
    268         void paintWindowedPluginIntoContext(GraphicsContext*, const IntRect&);
    269         static HDC WINAPI hookedBeginPaint(HWND, PAINTSTRUCT*);
    270         static BOOL WINAPI hookedEndPaint(HWND, const PAINTSTRUCT*);
    271 #endif
    272 
    273         RefPtr<Frame> m_parentFrame;
    274         RefPtr<PluginPackage> m_plugin;
    275         Element* m_element;
    276         bool m_isStarted;
    277         KURL m_url;
    278         KURL m_baseURL;
    279         PluginStatus m_status;
    280         Vector<IntRect> m_invalidRects;
    281 
    282         void performRequest(PluginRequest*);
    283         void scheduleRequest(PluginRequest*);
    284         void requestTimerFired(Timer<PluginView>*);
    285         void invalidateTimerFired(Timer<PluginView>*);
    286         Timer<PluginView> m_requestTimer;
    287         Timer<PluginView> m_invalidateTimer;
    288 
    289         void popPopupsStateTimerFired(Timer<PluginView>*);
    290         Timer<PluginView> m_popPopupsStateTimer;
    291 
    292         void lifeSupportTimerFired(Timer<PluginView>*);
    293         Timer<PluginView> m_lifeSupportTimer;
    294 
    295 #ifndef NP_NO_CARBON
    296         bool dispatchNPEvent(NPEvent&);
    297 #endif
    298         void updatePluginWidget();
    299         void paintMissingPluginIcon(GraphicsContext*, const IntRect&);
    300 
    301         void handleKeyboardEvent(KeyboardEvent*);
    302         void handleMouseEvent(MouseEvent*);
    303 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
    304         void handleFocusInEvent();
    305         void handleFocusOutEvent();
    306 #endif
    307 
    308 #if OS(WINDOWS)
    309         void paintIntoTransformedContext(HDC);
    310         PassRefPtr<Image> snapshot();
    311 #endif
    312 
    313 #ifdef ANDROID_PLUGINS
    314         void handleFocusEvent(bool hasFocus);
    315         void handleTouchEvent(TouchEvent*);
    316         // called at the end of the base constructor
    317         void platformInit();
    318 #endif
    319 #ifdef PLUGIN_PLATFORM_SETVALUE
    320         // called if the default setValue does not recognize the variable
    321         NPError platformSetValue(NPPVariable variable, void* value);
    322 #endif
    323 
    324         int m_mode;
    325         int m_paramCount;
    326         char** m_paramNames;
    327         char** m_paramValues;
    328         String m_pluginsPage;
    329 
    330         String m_mimeType;
    331         CString m_userAgent;
    332 
    333         NPP m_instance;
    334         NPP_t m_instanceStruct;
    335         NPWindow m_npWindow;
    336 
    337         Vector<bool, 4> m_popupStateStack;
    338 
    339         HashSet<RefPtr<PluginStream> > m_streams;
    340         Vector<PluginRequest*> m_requests;
    341 
    342         bool m_isWindowed;
    343         bool m_isTransparent;
    344         bool m_haveInitialized;
    345         bool m_isWaitingToStart;
    346 
    347 #if defined(XP_UNIX)
    348         bool m_needsXEmbed;
    349 #endif
    350 
    351 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
    352         OwnPtr<PluginMessageThrottlerWin> m_messageThrottler;
    353         WNDPROC m_pluginWndProc;
    354         unsigned m_lastMessage;
    355         bool m_isCallingPluginWndProc;
    356         HDC m_wmPrintHDC;
    357         bool m_haveUpdatedPluginWidget;
    358 #endif
    359 
    360 // ANDROID
    361 // TODO: Upstream to webkit.org
    362 #ifdef PLUGIN_SCHEDULE_TIMER
    363         PluginTimerList m_timerList;
    364 #endif
    365 
    366 #if ((PLATFORM(QT) || PLATFORM(WX)) && OS(WINDOWS)) || defined(XP_MACOSX)
    367         // On Mac OSX and Qt/Windows the plugin does not have its own native widget,
    368         // but is using the containing window as its reference for positioning/painting.
    369         PlatformPluginWidget m_window;
    370 public:
    371         PlatformPluginWidget platformPluginWidget() const { return m_window; }
    372         void setPlatformPluginWidget(PlatformPluginWidget widget) { m_window = widget; }
    373 #elif defined(ANDROID_PLUGINS)
    374 public:
    375         PlatformPluginWidget m_window;
    376         PlatformPluginWidget platformPluginWidget() const { return m_window; } // MANUAL MERGE FIXME
    377 #else
    378 public:
    379         void setPlatformPluginWidget(PlatformPluginWidget widget) { setPlatformWidget(widget); }
    380         PlatformPluginWidget platformPluginWidget() const { return platformWidget(); }
    381 #endif
    382 
    383 private:
    384 
    385 #if defined(XP_UNIX) || OS(SYMBIAN) || defined(ANDROID_PLUGINS)
    386         void setNPWindowIfNeeded();
    387 #elif defined(XP_MACOSX)
    388         NP_CGContext m_npCgContext;
    389         NPDrawingModel m_drawingModel;
    390         NPEventModel m_eventModel;
    391         CGContextRef m_contextRef;
    392         WindowRef m_fakeWindow;
    393 #if PLATFORM(QT)
    394         QPixmap m_pixmap;
    395 #endif
    396 
    397         void setNPWindowIfNeeded();
    398         Point globalMousePosForPlugin() const;
    399 #endif
    400 
    401 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
    402         bool m_hasPendingGeometryChange;
    403         Pixmap m_drawable;
    404         Visual* m_visual;
    405         Colormap m_colormap;
    406         Display* m_pluginDisplay;
    407 
    408         void initXEvent(XEvent* event);
    409 #endif
    410 
    411         IntRect m_clipRect; // The clip rect to apply to a windowed plug-in
    412         IntRect m_windowRect; // Our window rect.
    413 #ifdef ANDROID_PLUGINS
    414         IntRect m_pageRect; // The rect in page coordinate system.
    415 #endif
    416 
    417         bool m_loadManually;
    418         RefPtr<PluginStream> m_manualStream;
    419 
    420         bool m_isJavaScriptPaused;
    421 
    422         bool m_isHalted;
    423         bool m_hasBeenHalted;
    424 
    425         static PluginView* s_currentPluginView;
    426     };
    427 
    428 } // namespace WebCore
    429 
    430 #endif
    431