/* * 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 * * 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 #include #include #include #include #include #include #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 #endif #endif #if PLATFORM(QT) #include #include 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 create(Frame* parentFrame, const IntSize&, Element*, const KURL&, const Vector& paramNames, const Vector& 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 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& paramNames, const Vector& paramValues, const String& mimeType, bool loadManually); void setParameters(const Vector& paramNames, const Vector& 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& 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 m_parentFrame; RefPtr m_plugin; Element* m_element; bool m_isStarted; KURL m_url; KURL m_baseURL; PluginStatus m_status; Vector m_invalidRects; void performRequest(PluginRequest*); void scheduleRequest(PluginRequest*); void requestTimerFired(Timer*); void invalidateTimerFired(Timer*); Timer m_requestTimer; Timer m_invalidateTimer; void popPopupsStateTimerFired(Timer*); Timer m_popPopupsStateTimer; void lifeSupportTimerFired(Timer*); Timer 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 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 m_popupStateStack; HashSet > m_streams; Vector 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 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 > 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*); 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 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 m_manualStream; bool m_isJavaScriptPaused; bool m_isHalted; bool m_hasBeenHalted; bool m_haveCalledSetWindow; static PluginView* s_currentPluginView; }; } // namespace WebCore #endif