| /* |
| * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. |
| * Copyright (C) 2008 Collabora Ltd. All rights reserved. |
| * Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in> |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef PluginView_h |
| #define PluginView_h |
| |
| #include "FrameLoadRequest.h" |
| #include "HaltablePlugin.h" |
| #include "IntRect.h" |
| #include "MediaCanStartListener.h" |
| #include "PluginViewBase.h" |
| #include "ResourceRequest.h" |
| #include "Timer.h" |
| #include <wtf/HashMap.h> |
| #include <wtf/HashSet.h> |
| #include <wtf/OwnPtr.h> |
| #include <wtf/PassRefPtr.h> |
| #include <wtf/RefPtr.h> |
| #include <wtf/Vector.h> |
| #include <wtf/text/CString.h> |
| |
| #if ENABLE(NETSCAPE_PLUGIN_API) |
| #include "PluginStream.h" |
| #include "npruntime_internal.h" |
| #endif |
| |
| // ANDROID |
| // TODO: Upstream to webkit.org |
| #ifdef PLUGIN_SCHEDULE_TIMER |
| #include "PluginTimer.h" |
| #endif |
| |
| #if OS(WINDOWS) && (PLATFORM(QT) || PLATFORM(WX)) |
| typedef struct HWND__* HWND; |
| typedef HWND PlatformPluginWidget; |
| #elif defined(ANDROID_PLUGINS) |
| typedef struct PluginWidgetAndroid* PlatformPluginWidget; |
| #else |
| typedef PlatformWidget PlatformPluginWidget; |
| #if defined(XP_MACOSX) && PLATFORM(QT) |
| #include <QPixmap> |
| #endif |
| #endif |
| #if PLATFORM(QT) |
| #include <QGraphicsItem> |
| #include <QImage> |
| QT_BEGIN_NAMESPACE |
| class QPainter; |
| QT_END_NAMESPACE |
| #endif |
| #if PLATFORM(GTK) |
| typedef struct _GtkSocket GtkSocket; |
| #endif |
| |
| #if USE(JSC) |
| namespace JSC { |
| namespace Bindings { |
| class Instance; |
| } |
| } |
| #endif |
| |
| class NPObject; |
| |
| namespace WebCore { |
| class Element; |
| class Frame; |
| class Image; |
| class KeyboardEvent; |
| class MouseEvent; |
| #ifdef ANDROID_PLUGINS |
| class TouchEvent; |
| #endif |
| class KURL; |
| #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API) |
| class PluginMessageThrottlerWin; |
| #endif |
| class PluginPackage; |
| class PluginRequest; |
| class PluginStream; |
| class ResourceError; |
| class ResourceResponse; |
| |
| enum PluginStatus { |
| PluginStatusCanNotFindPlugin, |
| PluginStatusCanNotLoadPlugin, |
| PluginStatusLoadedSuccessfully |
| }; |
| |
| class PluginRequest { |
| WTF_MAKE_NONCOPYABLE(PluginRequest); WTF_MAKE_FAST_ALLOCATED; |
| public: |
| PluginRequest(const FrameLoadRequest& frameLoadRequest, bool sendNotification, void* notifyData, bool shouldAllowPopups) |
| : m_frameLoadRequest(frameLoadRequest) |
| , m_notifyData(notifyData) |
| , m_sendNotification(sendNotification) |
| , m_shouldAllowPopups(shouldAllowPopups) { } |
| public: |
| const FrameLoadRequest& frameLoadRequest() const { return m_frameLoadRequest; } |
| void* notifyData() const { return m_notifyData; } |
| bool sendNotification() const { return m_sendNotification; } |
| bool shouldAllowPopups() const { return m_shouldAllowPopups; } |
| private: |
| FrameLoadRequest m_frameLoadRequest; |
| void* m_notifyData; |
| bool m_sendNotification; |
| bool m_shouldAllowPopups; |
| }; |
| |
| class PluginManualLoader { |
| public: |
| virtual ~PluginManualLoader() {} |
| virtual void didReceiveResponse(const ResourceResponse&) = 0; |
| virtual void didReceiveData(const char*, int) = 0; |
| virtual void didFinishLoading() = 0; |
| virtual void didFail(const ResourceError&) = 0; |
| }; |
| |
| class PluginView : public PluginViewBase |
| #if ENABLE(NETSCAPE_PLUGIN_API) |
| , private PluginStreamClient |
| #endif |
| , public PluginManualLoader |
| , private HaltablePlugin |
| , private MediaCanStartListener { |
| public: |
| static PassRefPtr<PluginView> create(Frame* parentFrame, const IntSize&, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually); |
| virtual ~PluginView(); |
| |
| PluginPackage* plugin() const { return m_plugin.get(); } |
| #if ENABLE(NETSCAPE_PLUGIN_API) |
| NPP instance() const { return m_instance; } |
| #endif |
| |
| void setNPWindowRect(const IntRect&); |
| static PluginView* currentPluginView(); |
| |
| #if ENABLE(NETSCAPE_PLUGIN_API) |
| NPObject* npObject(); |
| #endif |
| #if USE(JSC) |
| PassRefPtr<JSC::Bindings::Instance> bindingInstance(); |
| #endif |
| |
| PluginStatus status() const { return m_status; } |
| |
| #if ENABLE(NETSCAPE_PLUGIN_API) |
| // NPN functions |
| NPError getURLNotify(const char* url, const char* target, void* notifyData); |
| NPError getURL(const char* url, const char* target); |
| NPError postURLNotify(const char* url, const char* target, uint32_t len, const char* but, NPBool file, void* notifyData); |
| NPError postURL(const char* url, const char* target, uint32_t len, const char* but, NPBool file); |
| NPError newStream(NPMIMEType type, const char* target, NPStream** stream); |
| int32_t write(NPStream* stream, int32_t len, void* buffer); |
| NPError destroyStream(NPStream* stream, NPReason reason); |
| #endif |
| const char* userAgent(); |
| #if ENABLE(NETSCAPE_PLUGIN_API) |
| static const char* userAgentStatic(); |
| #endif |
| void status(const char* message); |
| |
| #if ENABLE(NETSCAPE_PLUGIN_API) |
| NPError getValue(NPNVariable variable, void* value); |
| static NPError getValueStatic(NPNVariable variable, void* value); |
| NPError setValue(NPPVariable variable, void* value); |
| NPError getValueForURL(NPNURLVariable variable, const char* url, char** value, uint32_t* len); |
| NPError setValueForURL(NPNURLVariable variable, const char* url, const char* value, uint32_t len); |
| 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); |
| void invalidateRect(NPRect*); |
| void invalidateRegion(NPRegion); |
| #endif |
| void forceRedraw(); |
| void pushPopupsEnabledState(bool state); |
| void popPopupsEnabledState(); |
| #ifdef PLUGIN_SCHEDULE_TIMER |
| uint32_t scheduleTimer(NPP, uint32_t interval, bool repeat, |
| void (*timerFunc)(NPP, uint32_t timerID)); |
| void unscheduleTimer(NPP, uint32_t timerID); |
| #endif |
| NPObject* getNPObject(); |
| |
| virtual void invalidateRect(const IntRect&); |
| |
| bool arePopupsAllowed() const; |
| |
| void setJavaScriptPaused(bool); |
| |
| void privateBrowsingStateChanged(bool); |
| |
| void disconnectStream(PluginStream*); |
| void streamDidFinishLoading(PluginStream* stream) { disconnectStream(stream); } |
| |
| // Widget functions |
| virtual void setFrameRect(const IntRect&); |
| virtual void frameRectsChanged(); |
| virtual void setFocus(bool); |
| virtual void show(); |
| virtual void hide(); |
| virtual void paint(GraphicsContext*, const IntRect&); |
| |
| // This method is used by plugins on all platforms to obtain a clip rect that includes clips set by WebCore, |
| // e.g., in overflow:auto sections. The clip rects coordinates are in the containing window's coordinate space. |
| // This clip includes any clips that the widget itself sets up for its children. |
| IntRect windowClipRect() const; |
| |
| virtual void handleEvent(Event*); |
| virtual void setParent(ScrollView*); |
| virtual void setParentVisible(bool); |
| |
| virtual bool isPluginView() const { return true; } |
| |
| Frame* parentFrame() const { return m_parentFrame.get(); } |
| |
| void focusPluginElement(); |
| |
| const String& pluginsPage() const { return m_pluginsPage; } |
| const String& mimeType() const { return m_mimeType; } |
| const KURL& url() const { return m_url; } |
| |
| #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API) |
| static LRESULT CALLBACK PluginViewWndProc(HWND, UINT, WPARAM, LPARAM); |
| LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); |
| WNDPROC pluginWndProc() const { return m_pluginWndProc; } |
| #endif |
| |
| // Used for manual loading |
| void didReceiveResponse(const ResourceResponse&); |
| void didReceiveData(const char*, int); |
| void didFinishLoading(); |
| void didFail(const ResourceError&); |
| |
| // HaltablePlugin |
| virtual void halt(); |
| virtual void restart(); |
| virtual Node* node() const; |
| virtual bool isWindowed() const { return m_isWindowed; } |
| virtual String pluginName() const; |
| |
| bool isHalted() const { return m_isHalted; } |
| bool hasBeenHalted() const { return m_hasBeenHalted; } |
| |
| static bool isCallingPlugin(); |
| |
| #ifdef ANDROID_PLUGINS |
| Element* getElement() const { return m_element; } |
| #endif |
| |
| bool start(); |
| |
| #if ENABLE(NETSCAPE_PLUGIN_API) |
| static void keepAlive(NPP); |
| #endif |
| void keepAlive(); |
| |
| #if USE(ACCELERATED_COMPOSITING) |
| #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) && PLATFORM(QT) |
| virtual PlatformLayer* platformLayer() const; |
| #elif ENABLE(NETSCAPE_PLUGIN_API) && defined(ANDROID_PLUGINS) |
| virtual PlatformLayer* platformLayer() const; |
| #else |
| virtual PlatformLayer* platformLayer() const { return 0; } |
| #endif |
| #endif |
| |
| private: |
| PluginView(Frame* parentFrame, const IntSize&, PluginPackage*, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually); |
| |
| void setParameters(const Vector<String>& paramNames, const Vector<String>& paramValues); |
| bool startOrAddToUnstartedList(); |
| void init(); |
| bool platformStart(); |
| void stop(); |
| void platformDestroy(); |
| static void setCurrentPluginView(PluginView*); |
| #if ENABLE(NETSCAPE_PLUGIN_API) |
| NPError load(const FrameLoadRequest&, bool sendNotification, void* notifyData); |
| NPError handlePost(const char* url, const char* target, uint32_t len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders); |
| NPError handlePostReadFile(Vector<char>& buffer, uint32_t len, const char* buf); |
| #endif |
| static void freeStringArray(char** stringArray, int length); |
| void setCallingPlugin(bool) const; |
| |
| void invalidateWindowlessPluginRect(const IntRect&); |
| |
| virtual void mediaCanStart(); |
| |
| #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API) |
| void paintWindowedPluginIntoContext(GraphicsContext*, const IntRect&); |
| static HDC WINAPI hookedBeginPaint(HWND, PAINTSTRUCT*); |
| static BOOL WINAPI hookedEndPaint(HWND, const PAINTSTRUCT*); |
| #endif |
| |
| #if ENABLE(NETSCAPE_PLUGIN_API) |
| static bool platformGetValueStatic(NPNVariable variable, void* value, NPError* result); |
| bool platformGetValue(NPNVariable variable, void* value, NPError* result); |
| #endif |
| |
| RefPtr<Frame> m_parentFrame; |
| RefPtr<PluginPackage> m_plugin; |
| Element* m_element; |
| bool m_isStarted; |
| KURL m_url; |
| KURL m_baseURL; |
| PluginStatus m_status; |
| Vector<IntRect> m_invalidRects; |
| |
| void performRequest(PluginRequest*); |
| void scheduleRequest(PluginRequest*); |
| void requestTimerFired(Timer<PluginView>*); |
| void invalidateTimerFired(Timer<PluginView>*); |
| Timer<PluginView> m_requestTimer; |
| Timer<PluginView> m_invalidateTimer; |
| |
| void popPopupsStateTimerFired(Timer<PluginView>*); |
| Timer<PluginView> m_popPopupsStateTimer; |
| |
| void lifeSupportTimerFired(Timer<PluginView>*); |
| Timer<PluginView> m_lifeSupportTimer; |
| |
| #ifndef NP_NO_CARBON |
| #if ENABLE(NETSCAPE_PLUGIN_API) |
| bool dispatchNPEvent(NPEvent&); |
| #endif // ENABLE(NETSCAPE_PLUGIN_API) |
| #endif |
| void updatePluginWidget(); |
| void paintMissingPluginIcon(GraphicsContext*, const IntRect&); |
| |
| void handleKeyboardEvent(KeyboardEvent*); |
| void handleMouseEvent(MouseEvent*); |
| #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) |
| void handleFocusInEvent(); |
| void handleFocusOutEvent(); |
| #endif |
| |
| #if OS(WINDOWS) |
| void paintIntoTransformedContext(HDC); |
| PassRefPtr<Image> snapshot(); |
| #endif |
| |
| #ifdef ANDROID_PLUGINS |
| void handleFocusEvent(bool hasFocus); |
| void handleTouchEvent(TouchEvent*); |
| // called at the end of the base constructor |
| void platformInit(); |
| #endif |
| #ifdef PLUGIN_PLATFORM_SETVALUE |
| // called if the default setValue does not recognize the variable |
| NPError platformSetValue(NPPVariable variable, void* value); |
| #endif |
| |
| int m_mode; |
| int m_paramCount; |
| char** m_paramNames; |
| char** m_paramValues; |
| String m_pluginsPage; |
| |
| String m_mimeType; |
| WTF::CString m_userAgent; |
| |
| #if ENABLE(NETSCAPE_PLUGIN_API) |
| NPP m_instance; |
| NPP_t m_instanceStruct; |
| NPWindow m_npWindow; |
| #endif |
| |
| Vector<bool, 4> m_popupStateStack; |
| |
| HashSet<RefPtr<PluginStream> > m_streams; |
| Vector<PluginRequest*> m_requests; |
| |
| bool m_isWindowed; |
| bool m_isTransparent; |
| bool m_haveInitialized; |
| bool m_isWaitingToStart; |
| |
| #if defined(XP_UNIX) |
| bool m_needsXEmbed; |
| #endif |
| |
| #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API) |
| OwnPtr<PluginMessageThrottlerWin> m_messageThrottler; |
| WNDPROC m_pluginWndProc; |
| unsigned m_lastMessage; |
| bool m_isCallingPluginWndProc; |
| HDC m_wmPrintHDC; |
| bool m_haveUpdatedPluginWidget; |
| #endif |
| |
| // ANDROID |
| // TODO: Upstream to webkit.org |
| #ifdef PLUGIN_SCHEDULE_TIMER |
| PluginTimerList m_timerList; |
| #endif |
| |
| #if ((PLATFORM(QT) || PLATFORM(WX)) && OS(WINDOWS)) || defined(XP_MACOSX) |
| // On Mac OSX and Qt/Windows the plugin does not have its own native widget, |
| // but is using the containing window as its reference for positioning/painting. |
| PlatformPluginWidget m_window; |
| public: |
| PlatformPluginWidget platformPluginWidget() const { return m_window; } |
| void setPlatformPluginWidget(PlatformPluginWidget widget) { m_window = widget; } |
| #elif defined(ANDROID_PLUGINS) |
| public: |
| PlatformPluginWidget m_window; |
| PlatformPluginWidget platformPluginWidget() const { return m_window; } // MANUAL MERGE FIXME |
| #else |
| public: |
| void setPlatformPluginWidget(PlatformPluginWidget widget) { setPlatformWidget(widget); } |
| PlatformPluginWidget platformPluginWidget() const { return platformWidget(); } |
| #endif |
| |
| private: |
| |
| #if defined(XP_UNIX) || OS(SYMBIAN) || PLATFORM(GTK) || defined(ANDROID_PLUGINS) |
| void setNPWindowIfNeeded(); |
| #elif defined(XP_MACOSX) |
| NP_CGContext m_npCgContext; |
| OwnPtr<Timer<PluginView> > m_nullEventTimer; |
| NPDrawingModel m_drawingModel; |
| NPEventModel m_eventModel; |
| CGContextRef m_contextRef; |
| WindowRef m_fakeWindow; |
| #if PLATFORM(QT) |
| QPixmap m_pixmap; |
| #endif |
| |
| Point m_lastMousePos; |
| void setNPWindowIfNeeded(); |
| void nullEventTimerFired(Timer<PluginView>*); |
| Point globalMousePosForPlugin() const; |
| Point mousePosForPlugin(MouseEvent* event = 0) const; |
| #endif |
| |
| #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) |
| bool m_hasPendingGeometryChange; |
| Pixmap m_drawable; |
| Visual* m_visual; |
| Colormap m_colormap; |
| Display* m_pluginDisplay; |
| |
| void initXEvent(XEvent* event); |
| #endif |
| |
| #if PLATFORM(QT) |
| #if defined(MOZ_PLATFORM_MAEMO) && (MOZ_PLATFORM_MAEMO >= 5) |
| QImage m_image; |
| bool m_renderToImage; |
| void paintUsingImageSurfaceExtension(QPainter* painter, const IntRect& exposedRect); |
| #endif |
| #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) |
| void paintUsingXPixmap(QPainter* painter, const QRect &exposedRect); |
| #if USE(ACCELERATED_COMPOSITING) |
| OwnPtr<PlatformLayer> m_platformLayer; |
| friend class PluginGraphicsLayerQt; |
| #endif // USE(ACCELERATED_COMPOSITING) |
| #endif |
| #endif // PLATFORM(QT) |
| |
| #if PLATFORM(GTK) |
| static gboolean plugRemovedCallback(GtkSocket*, PluginView*); |
| static void plugAddedCallback(GtkSocket*, PluginView*); |
| bool m_plugAdded; |
| IntRect m_delayedAllocation; |
| #endif |
| |
| IntRect m_clipRect; // The clip rect to apply to a windowed plug-in |
| IntRect m_windowRect; // Our window rect. |
| #ifdef ANDROID_PLUGINS |
| IntRect m_pageRect; // The rect in page coordinate system. |
| #endif |
| |
| bool m_loadManually; |
| RefPtr<PluginStream> m_manualStream; |
| |
| bool m_isJavaScriptPaused; |
| |
| bool m_isHalted; |
| bool m_hasBeenHalted; |
| |
| bool m_haveCalledSetWindow; |
| |
| static PluginView* s_currentPluginView; |
| }; |
| |
| } // namespace WebCore |
| |
| #endif |