michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: // vim:set ts=2 sts=2 sw=2 et cin: michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsPluginInstanceOwner_h_ michael@0: #define nsPluginInstanceOwner_h_ michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "npapi.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsIPluginInstanceOwner.h" michael@0: #include "nsIPrivacyTransitionObserver.h" michael@0: #include "nsIDOMEventListener.h" michael@0: #include "nsPluginHost.h" michael@0: #include "nsPluginNativeWindow.h" michael@0: #include "nsWeakReference.h" michael@0: #include "gfxRect.h" michael@0: michael@0: #ifdef XP_MACOSX michael@0: #include "mozilla/gfx/QuartzSupport.h" michael@0: #include michael@0: #endif michael@0: michael@0: class nsIInputStream; michael@0: struct nsIntRect; michael@0: class nsPluginDOMContextMenuListener; michael@0: class nsObjectFrame; michael@0: class nsDisplayListBuilder; michael@0: michael@0: #ifdef MOZ_X11 michael@0: class gfxXlibSurface; michael@0: #ifdef MOZ_WIDGET_QT michael@0: #include "gfxQtNativeRenderer.h" michael@0: #else michael@0: #include "gfxXlibNativeRenderer.h" michael@0: #endif michael@0: #endif michael@0: michael@0: class nsPluginInstanceOwner : public nsIPluginInstanceOwner, michael@0: public nsIDOMEventListener, michael@0: public nsIPrivacyTransitionObserver, michael@0: public nsSupportsWeakReference michael@0: { michael@0: public: michael@0: nsPluginInstanceOwner(); michael@0: virtual ~nsPluginInstanceOwner(); michael@0: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSIPLUGININSTANCEOWNER michael@0: NS_DECL_NSIPRIVACYTRANSITIONOBSERVER michael@0: michael@0: NS_IMETHOD GetURL(const char *aURL, const char *aTarget, michael@0: nsIInputStream *aPostStream, michael@0: void *aHeadersData, uint32_t aHeadersDataLen) MOZ_OVERRIDE; michael@0: michael@0: NS_IMETHOD ShowStatus(const char16_t *aStatusMsg) MOZ_OVERRIDE; michael@0: michael@0: NPError ShowNativeContextMenu(NPMenu* menu, void* event) MOZ_OVERRIDE; michael@0: michael@0: NPBool ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, michael@0: double *destX, double *destY, NPCoordinateSpace destSpace) MOZ_OVERRIDE; michael@0: michael@0: virtual NPError InitAsyncSurface(NPSize *size, NPImageFormat format, michael@0: void *initData, NPAsyncSurface *surface) MOZ_OVERRIDE; michael@0: virtual NPError FinalizeAsyncSurface(NPAsyncSurface *surface) MOZ_OVERRIDE; michael@0: virtual void SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed) MOZ_OVERRIDE; michael@0: michael@0: /** michael@0: * Get the type of the HTML tag that was used ot instantiate this michael@0: * plugin. Currently supported tags are EMBED, OBJECT and APPLET. michael@0: */ michael@0: NS_IMETHOD GetTagType(nsPluginTagType *aResult); michael@0: michael@0: /** michael@0: * Get a ptr to the paired list of parameter names and values, michael@0: * returns the length of the array. michael@0: * michael@0: * Each name or value is a null-terminated string. michael@0: */ michael@0: NS_IMETHOD GetParameters(uint16_t& aCount, michael@0: const char*const*& aNames, michael@0: const char*const*& aValues); michael@0: michael@0: /** michael@0: * Get the value for the named parameter. Returns null michael@0: * if the parameter was not set. michael@0: * michael@0: * @param aName - name of the parameter michael@0: * @param aResult - parameter value michael@0: * @result - NS_OK if this operation was successful michael@0: */ michael@0: NS_IMETHOD GetParameter(const char* aName, const char* *aResult); michael@0: michael@0: /** michael@0: * QueryInterface on nsIPluginInstancePeer to get this. michael@0: * michael@0: * (Corresponds to NPP_New's argc, argn, and argv arguments.) michael@0: * Get a ptr to the paired list of attribute names and values, michael@0: * returns the length of the array. michael@0: * michael@0: * Each name or value is a null-terminated string. michael@0: */ michael@0: NS_IMETHOD GetAttributes(uint16_t& aCount, michael@0: const char*const*& aNames, michael@0: const char*const*& aValues); michael@0: michael@0: michael@0: /** michael@0: * Gets the value for the named attribute. michael@0: * michael@0: * @param aName - the name of the attribute to find michael@0: * @param aResult - the resulting attribute michael@0: * @result - NS_OK if this operation was successful, NS_ERROR_FAILURE if michael@0: * this operation failed. result is set to NULL if the attribute is not found michael@0: * else to the found value. michael@0: */ michael@0: NS_IMETHOD GetAttribute(const char* aName, const char* *aResult); michael@0: michael@0: /** michael@0: * Returns the DOM element corresponding to the tag which references michael@0: * this plugin in the document. michael@0: * michael@0: * @param aDOMElement - resulting DOM element michael@0: * @result - NS_OK if this operation was successful michael@0: */ michael@0: NS_IMETHOD GetDOMElement(nsIDOMElement* * aResult); michael@0: michael@0: // nsIDOMEventListener interfaces michael@0: NS_DECL_NSIDOMEVENTLISTENER michael@0: michael@0: nsresult ProcessMouseDown(nsIDOMEvent* aKeyEvent); michael@0: nsresult ProcessKeyPress(nsIDOMEvent* aKeyEvent); michael@0: nsresult Destroy(); michael@0: michael@0: #ifdef XP_WIN michael@0: void Paint(const RECT& aDirty, HDC aDC); michael@0: #elif defined(XP_MACOSX) michael@0: void Paint(const gfxRect& aDirtyRect, CGContextRef cgContext); michael@0: void RenderCoreAnimation(CGContextRef aCGContext, int aWidth, int aHeight); michael@0: void DoCocoaEventDrawRect(const gfxRect& aDrawRect, CGContextRef cgContext); michael@0: #elif defined(MOZ_X11) || defined(ANDROID) michael@0: void Paint(gfxContext* aContext, michael@0: const gfxRect& aFrameRect, michael@0: const gfxRect& aDirtyRect); michael@0: #endif michael@0: michael@0: //locals michael@0: michael@0: nsresult Init(nsIContent* aContent); michael@0: michael@0: void* GetPluginPortFromWidget(); michael@0: void ReleasePluginPort(void* pluginPort); michael@0: michael@0: nsEventStatus ProcessEvent(const mozilla::WidgetGUIEvent& anEvent); michael@0: michael@0: #ifdef XP_MACOSX michael@0: enum { ePluginPaintEnable, ePluginPaintDisable }; michael@0: michael@0: NPDrawingModel GetDrawingModel(); michael@0: bool IsRemoteDrawingCoreAnimation(); michael@0: nsresult ContentsScaleFactorChanged(double aContentsScaleFactor); michael@0: NPEventModel GetEventModel(); michael@0: static void CARefresh(nsITimer *aTimer, void *aClosure); michael@0: void AddToCARefreshTimer(); michael@0: void RemoveFromCARefreshTimer(); michael@0: // This calls into the plugin (NPP_SetWindow) and can run script. michael@0: void* FixUpPluginWindow(int32_t inPaintState); michael@0: void HidePluginWindow(); michael@0: // Set a flag that (if true) indicates the plugin port info has changed and michael@0: // SetWindow() needs to be called. michael@0: void SetPluginPortChanged(bool aState) { mPluginPortChanged = aState; } michael@0: // Return a pointer to the internal nsPluginPort structure that's used to michael@0: // store a copy of plugin port info and to detect when it's been changed. michael@0: void* GetPluginPortCopy(); michael@0: // Set plugin port info in the plugin (in the 'window' member of the michael@0: // NPWindow structure passed to the plugin by SetWindow()) and set a michael@0: // flag (mPluginPortChanged) to indicate whether or not this info has michael@0: // changed, and SetWindow() needs to be called again. michael@0: void* SetPluginPortAndDetectChange(); michael@0: // Flag when we've set up a Thebes (and CoreGraphics) context in michael@0: // nsObjectFrame::PaintPlugin(). We need to know this in michael@0: // FixUpPluginWindow() (i.e. we need to know when FixUpPluginWindow() has michael@0: // been called from nsObjectFrame::PaintPlugin() when we're using the michael@0: // CoreGraphics drawing model). michael@0: void BeginCGPaint(); michael@0: void EndCGPaint(); michael@0: #else // XP_MACOSX michael@0: void UpdateWindowPositionAndClipRect(bool aSetWindow); michael@0: void UpdateWindowVisibility(bool aVisible); michael@0: void UpdateDocumentActiveState(bool aIsActive); michael@0: #endif // XP_MACOSX michael@0: michael@0: void SetFrame(nsObjectFrame *aFrame); michael@0: nsObjectFrame* GetFrame(); michael@0: michael@0: uint32_t GetLastEventloopNestingLevel() const { michael@0: return mLastEventloopNestingLevel; michael@0: } michael@0: michael@0: static uint32_t GetEventloopNestingLevel(); michael@0: michael@0: void ConsiderNewEventloopNestingLevel() { michael@0: uint32_t currentLevel = GetEventloopNestingLevel(); michael@0: michael@0: if (currentLevel < mLastEventloopNestingLevel) { michael@0: mLastEventloopNestingLevel = currentLevel; michael@0: } michael@0: } michael@0: michael@0: const char* GetPluginName() michael@0: { michael@0: if (mInstance && mPluginHost) { michael@0: const char* name = nullptr; michael@0: if (NS_SUCCEEDED(mPluginHost->GetPluginName(mInstance, &name)) && name) michael@0: return name; michael@0: } michael@0: return ""; michael@0: } michael@0: michael@0: #ifdef MOZ_X11 michael@0: void GetPluginDescription(nsACString& aDescription) michael@0: { michael@0: aDescription.Truncate(); michael@0: if (mInstance && mPluginHost) { michael@0: nsCOMPtr pluginTag; michael@0: michael@0: mPluginHost->GetPluginTagForInstance(mInstance, michael@0: getter_AddRefs(pluginTag)); michael@0: if (pluginTag) { michael@0: pluginTag->GetDescription(aDescription); michael@0: } michael@0: } michael@0: } michael@0: #endif michael@0: michael@0: bool SendNativeEvents() michael@0: { michael@0: #ifdef XP_WIN michael@0: // XXX we should remove the plugin name check michael@0: return mPluginWindow->type == NPWindowTypeDrawable && michael@0: (MatchPluginName("Shockwave Flash") || michael@0: MatchPluginName("Test Plug-in")); michael@0: #elif defined(MOZ_X11) || defined(XP_MACOSX) michael@0: return true; michael@0: #else michael@0: return false; michael@0: #endif michael@0: } michael@0: michael@0: bool MatchPluginName(const char *aPluginName) michael@0: { michael@0: return strncmp(GetPluginName(), aPluginName, strlen(aPluginName)) == 0; michael@0: } michael@0: michael@0: void NotifyPaintWaiter(nsDisplayListBuilder* aBuilder); michael@0: michael@0: // Returns the image container that has our currently displayed image. michael@0: already_AddRefed GetImageContainer(); michael@0: michael@0: /** michael@0: * Returns the bounds of the current async-rendered surface. This can only michael@0: * change in response to messages received by the event loop (i.e. not during michael@0: * painting). michael@0: */ michael@0: nsIntSize GetCurrentImageSize(); michael@0: michael@0: // Methods to update the background image we send to async plugins. michael@0: // The eventual target of these operations is PluginInstanceParent, michael@0: // but it takes several hops to get there. michael@0: void SetBackgroundUnknown(); michael@0: already_AddRefed BeginUpdateBackground(const nsIntRect& aRect); michael@0: void EndUpdateBackground(gfxContext* aContext, const nsIntRect& aRect); michael@0: michael@0: bool UseAsyncRendering(); michael@0: michael@0: already_AddRefed GetBaseURI() const; michael@0: michael@0: #ifdef MOZ_WIDGET_ANDROID michael@0: // Returns the image container for the specified VideoInfo michael@0: void GetVideos(nsTArray& aVideos); michael@0: already_AddRefed GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInfo* aVideoInfo); michael@0: michael@0: void Invalidate(); michael@0: michael@0: void RequestFullScreen(); michael@0: void ExitFullScreen(); michael@0: michael@0: // Called from AndroidJNI when we removed the fullscreen view. michael@0: static void ExitFullScreen(jobject view); michael@0: #endif michael@0: michael@0: private: michael@0: michael@0: // return FALSE if LayerSurface dirty (newly created and don't have valid plugin content yet) michael@0: bool IsUpToDate() michael@0: { michael@0: nsIntSize size; michael@0: return NS_SUCCEEDED(mInstance->GetImageSize(&size)) && michael@0: size == nsIntSize(mPluginWindow->width, mPluginWindow->height); michael@0: } michael@0: michael@0: void FixUpURLS(const nsString &name, nsAString &value); michael@0: #ifdef MOZ_WIDGET_ANDROID michael@0: mozilla::LayoutDeviceRect GetPluginRect(); michael@0: bool AddPluginView(const mozilla::LayoutDeviceRect& aRect = mozilla::LayoutDeviceRect(0, 0, 0, 0)); michael@0: void RemovePluginView(); michael@0: michael@0: bool mFullScreen; michael@0: void* mJavaView; michael@0: #endif michael@0: michael@0: nsPluginNativeWindow *mPluginWindow; michael@0: nsRefPtr mInstance; michael@0: nsObjectFrame *mObjectFrame; michael@0: nsIContent *mContent; // WEAK, content owns us michael@0: nsCString mDocumentBase; michael@0: bool mWidgetCreationComplete; michael@0: nsCOMPtr mWidget; michael@0: nsRefPtr mPluginHost; michael@0: michael@0: #ifdef XP_MACOSX michael@0: NP_CGContext mCGPluginPortCopy; michael@0: int32_t mInCGPaintLevel; michael@0: mozilla::RefPtr mIOSurface; michael@0: mozilla::RefPtr mCARenderer; michael@0: CGColorSpaceRef mColorProfile; michael@0: static nsCOMPtr *sCATimer; michael@0: static nsTArray *sCARefreshListeners; michael@0: bool mSentInitialTopLevelWindowEvent; michael@0: #endif michael@0: michael@0: // Initially, the event loop nesting level we were created on, it's updated michael@0: // if we detect the appshell is on a lower level as long as we're not stopped. michael@0: // We delay DoStopPlugin() until the appshell reaches this level or lower. michael@0: uint32_t mLastEventloopNestingLevel; michael@0: bool mContentFocused; michael@0: bool mWidgetVisible; // used on Mac to store our widget's visible state michael@0: #ifdef XP_MACOSX michael@0: bool mPluginPortChanged; michael@0: #endif michael@0: #ifdef MOZ_X11 michael@0: // Used with windowless plugins only, initialized in CreateWidget(). michael@0: bool mFlash10Quirks; michael@0: #endif michael@0: bool mPluginWindowVisible; michael@0: bool mPluginDocumentActiveState; michael@0: michael@0: uint16_t mNumCachedAttrs; michael@0: uint16_t mNumCachedParams; michael@0: char **mCachedAttrParamNames; michael@0: char **mCachedAttrParamValues; michael@0: michael@0: #ifdef XP_MACOSX michael@0: NPEventModel mEventModel; michael@0: // This is a hack! UseAsyncRendering() can incorrectly return false michael@0: // when we don't have an object frame (possible as of bug 90268). michael@0: // We hack around this by always returning true if we've ever michael@0: // returned true. michael@0: bool mUseAsyncRendering; michael@0: #endif michael@0: michael@0: // pointer to wrapper for nsIDOMContextMenuListener michael@0: nsRefPtr mCXMenuListener; michael@0: michael@0: nsresult DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent); michael@0: nsresult DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent, michael@0: bool aAllowPropagate = false); michael@0: nsresult DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent); michael@0: michael@0: int mLastMouseDownButtonType; michael@0: michael@0: nsresult EnsureCachedAttrParamArrays(); michael@0: michael@0: #ifdef MOZ_X11 michael@0: class Renderer michael@0: #if defined(MOZ_WIDGET_QT) michael@0: : public gfxQtNativeRenderer michael@0: #else michael@0: : public gfxXlibNativeRenderer michael@0: #endif michael@0: { michael@0: public: michael@0: Renderer(NPWindow* aWindow, nsPluginInstanceOwner* aInstanceOwner, michael@0: const nsIntSize& aPluginSize, const nsIntRect& aDirtyRect) michael@0: : mWindow(aWindow), mInstanceOwner(aInstanceOwner), michael@0: mPluginSize(aPluginSize), mDirtyRect(aDirtyRect) michael@0: {} michael@0: virtual nsresult DrawWithXlib(cairo_surface_t* surface, michael@0: nsIntPoint offset, michael@0: nsIntRect* clipRects, uint32_t numClipRects) MOZ_OVERRIDE; michael@0: private: michael@0: NPWindow* mWindow; michael@0: nsPluginInstanceOwner* mInstanceOwner; michael@0: const nsIntSize& mPluginSize; michael@0: const nsIntRect& mDirtyRect; michael@0: }; michael@0: #endif michael@0: michael@0: bool mWaitingForPaint; michael@0: }; michael@0: michael@0: #endif // nsPluginInstanceOwner_h_ michael@0: