/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ // vim:set ts=2 sts=2 sw=2 et cin: /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla Communicator client code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Pierre Phaneuf * Jacek Piskozub * Leon Sha * Roland Mainz * Robert O'Callahan * Christian Biesinger * Josh Aas * Mats Palmgren * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #ifndef nsPluginInstanceOwner_h_ #define nsPluginInstanceOwner_h_ #include "prtypes.h" #include "npapi.h" #include "nsCOMPtr.h" #include "nsIPluginInstanceOwner.h" #include "nsIPluginTagInfo.h" #include "nsIDOMEventListener.h" #include "nsIScrollPositionListener.h" #include "nsPluginHost.h" #include "nsPluginNativeWindow.h" #include "gfxRect.h" // X.h defines KeyPress #ifdef KeyPress #undef KeyPress #endif #ifdef XP_MACOSX #include "nsCoreAnimationSupport.h" #include #endif class nsIInputStream; struct nsIntRect; class nsPluginDOMContextMenuListener; class nsObjectFrame; class nsDisplayListBuilder; #ifdef MOZ_X11 class gfxXlibSurface; #endif #ifdef MOZ_WIDGET_GTK2 #include "gfxXlibNativeRenderer.h" #endif #ifdef MOZ_WIDGET_QT #ifdef MOZ_X11 #include "gfxQtNativeRenderer.h" #endif #endif #ifdef XP_OS2 #define INCL_PM #define INCL_GPI #include #endif #ifdef MOZ_WIDGET_ANDROID namespace mozilla { class AndroidMediaLayer; } #endif // X.h defines KeyPress #ifdef KeyPress #undef KeyPress #endif class nsPluginInstanceOwner : public nsIPluginInstanceOwner, public nsIPluginTagInfo, public nsIDOMEventListener, public nsIScrollPositionListener { public: nsPluginInstanceOwner(); virtual ~nsPluginInstanceOwner(); NS_DECL_ISUPPORTS NS_DECL_NSIPLUGININSTANCEOWNER NS_IMETHOD GetURL(const char *aURL, const char *aTarget, nsIInputStream *aPostStream, void *aHeadersData, PRUint32 aHeadersDataLen); NS_IMETHOD ShowStatus(const PRUnichar *aStatusMsg); NPError ShowNativeContextMenu(NPMenu* menu, void* event); NPBool ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace); virtual NPError InitAsyncSurface(NPSize *size, NPImageFormat format, void *initData, NPAsyncSurface *surface); virtual NPError FinalizeAsyncSurface(NPAsyncSurface *surface); virtual void SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed); //nsIPluginTagInfo interface NS_DECL_NSIPLUGINTAGINFO // nsIDOMEventListener interfaces NS_DECL_NSIDOMEVENTLISTENER nsresult MouseDown(nsIDOMEvent* aKeyEvent); nsresult KeyPress(nsIDOMEvent* aKeyEvent); #if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6) nsresult Text(nsIDOMEvent* aTextEvent); #endif nsresult Destroy(); #ifdef XP_WIN void Paint(const RECT& aDirty, HDC aDC); #elif defined(XP_MACOSX) void Paint(const gfxRect& aDirtyRect, CGContextRef cgContext); void RenderCoreAnimation(CGContextRef aCGContext, int aWidth, int aHeight); void DoCocoaEventDrawRect(const gfxRect& aDrawRect, CGContextRef cgContext); #elif defined(MOZ_X11) || defined(ANDROID) void Paint(gfxContext* aContext, const gfxRect& aFrameRect, const gfxRect& aDirtyRect); #elif defined(XP_OS2) void Paint(const nsRect& aDirtyRect, HPS aHPS); #endif #ifdef MAC_CARBON_PLUGINS void CancelTimer(); void StartTimer(bool isVisible); #endif void SendIdleEvent(); // nsIScrollPositionListener interface virtual void ScrollPositionWillChange(nscoord aX, nscoord aY); virtual void ScrollPositionDidChange(nscoord aX, nscoord aY); //locals nsresult Init(nsIContent* aContent); void* GetPluginPortFromWidget(); void ReleasePluginPort(void* pluginPort); nsEventStatus ProcessEvent(const nsGUIEvent & anEvent); #ifdef XP_MACOSX enum { ePluginPaintEnable, ePluginPaintDisable }; NPDrawingModel GetDrawingModel(); bool IsRemoteDrawingCoreAnimation(); NPEventModel GetEventModel(); static void CARefresh(nsITimer *aTimer, void *aClosure); void AddToCARefreshTimer(); void RemoveFromCARefreshTimer(); // This calls into the plugin (NPP_SetWindow) and can run script. void* FixUpPluginWindow(PRInt32 inPaintState); void HidePluginWindow(); // Set a flag that (if true) indicates the plugin port info has changed and // SetWindow() needs to be called. void SetPluginPortChanged(bool aState) { mPluginPortChanged = aState; } // Return a pointer to the internal nsPluginPort structure that's used to // store a copy of plugin port info and to detect when it's been changed. void* GetPluginPortCopy(); // Set plugin port info in the plugin (in the 'window' member of the // NPWindow structure passed to the plugin by SetWindow()) and set a // flag (mPluginPortChanged) to indicate whether or not this info has // changed, and SetWindow() needs to be called again. void* SetPluginPortAndDetectChange(); // Flag when we've set up a Thebes (and CoreGraphics) context in // nsObjectFrame::PaintPlugin(). We need to know this in // FixUpPluginWindow() (i.e. we need to know when FixUpPluginWindow() has // been called from nsObjectFrame::PaintPlugin() when we're using the // CoreGraphics drawing model). void BeginCGPaint(); void EndCGPaint(); #else // XP_MACOSX void UpdateWindowPositionAndClipRect(bool aSetWindow); void UpdateWindowVisibility(bool aVisible); void UpdateDocumentActiveState(bool aIsActive); #endif // XP_MACOSX void SetFrame(nsObjectFrame *aFrame); nsObjectFrame* GetFrame(); PRUint32 GetLastEventloopNestingLevel() const { return mLastEventloopNestingLevel; } static PRUint32 GetEventloopNestingLevel(); void ConsiderNewEventloopNestingLevel() { PRUint32 currentLevel = GetEventloopNestingLevel(); if (currentLevel < mLastEventloopNestingLevel) { mLastEventloopNestingLevel = currentLevel; } } const char* GetPluginName() { if (mInstance && mPluginHost) { const char* name = NULL; if (NS_SUCCEEDED(mPluginHost->GetPluginName(mInstance, &name)) && name) return name; } return ""; } #ifdef MOZ_X11 void GetPluginDescription(nsACString& aDescription) { aDescription.Truncate(); if (mInstance && mPluginHost) { nsCOMPtr pluginTag; mPluginHost->GetPluginTagForInstance(mInstance, getter_AddRefs(pluginTag)); if (pluginTag) { pluginTag->GetDescription(aDescription); } } } #endif bool SendNativeEvents() { #ifdef XP_WIN // XXX we should remove the plugin name check return mPluginWindow->type == NPWindowTypeDrawable && (MatchPluginName("Shockwave Flash") || MatchPluginName("Test Plug-in")); #elif defined(MOZ_X11) || defined(XP_MACOSX) return true; #else return false; #endif } bool MatchPluginName(const char *aPluginName) { return strncmp(GetPluginName(), aPluginName, strlen(aPluginName)) == 0; } void NotifyPaintWaiter(nsDisplayListBuilder* aBuilder); // Returns the image container that has our currently displayed image. already_AddRefed GetImageContainer(); /** * Returns the bounds of the current async-rendered surface. This can only * change in response to messages received by the event loop (i.e. not during * painting). */ nsIntSize GetCurrentImageSize(); // Methods to update the background image we send to async plugins. // The eventual target of these operations is PluginInstanceParent, // but it takes several hops to get there. void SetBackgroundUnknown(); already_AddRefed BeginUpdateBackground(const nsIntRect& aRect); void EndUpdateBackground(gfxContext* aContext, const nsIntRect& aRect); bool UseAsyncRendering(); #ifdef MOZ_WIDGET_ANDROID nsIntRect GetVisibleRect() { return nsIntRect(0, 0, mPluginWindow->width, mPluginWindow->height); } void SetInverted(bool aInverted) { mInverted = aInverted; } bool Inverted() { return mInverted; } mozilla::AndroidMediaLayer* Layer() { return mLayer; } void Invalidate(); #endif private: // return FALSE if LayerSurface dirty (newly created and don't have valid plugin content yet) bool IsUpToDate() { nsIntSize size; return NS_SUCCEEDED(mInstance->GetImageSize(&size)) && size == nsIntSize(mPluginWindow->width, mPluginWindow->height); } void FixUpURLS(const nsString &name, nsAString &value); #ifdef MOZ_WIDGET_ANDROID void SendSize(int width, int height); bool AddPluginView(const gfxRect& aRect); void RemovePluginView(); bool mInverted; // For kOpenGL_ANPDrawingModel nsRefPtr mLayer; #endif nsPluginNativeWindow *mPluginWindow; nsRefPtr mInstance; nsObjectFrame *mObjectFrame; nsIContent *mContent; // WEAK, content owns us nsCString mDocumentBase; char *mTagText; bool mWidgetCreationComplete; nsCOMPtr mWidget; nsRefPtr mPluginHost; #ifdef XP_MACOSX NP_CGContext mCGPluginPortCopy; #ifndef NP_NO_QUICKDRAW NP_Port mQDPluginPortCopy; #endif PRInt32 mInCGPaintLevel; nsRefPtr mIOSurface; nsCARenderer mCARenderer; CGColorSpaceRef mColorProfile; static nsCOMPtr *sCATimer; static nsTArray *sCARefreshListeners; bool mSentInitialTopLevelWindowEvent; #endif // We need to know if async hide window is required since we // can not check UseAsyncRendering when executing StopPlugin bool mAsyncHidePluginWindow; // Initially, the event loop nesting level we were created on, it's updated // if we detect the appshell is on a lower level as long as we're not stopped. // We delay DoStopPlugin() until the appshell reaches this level or lower. PRUint32 mLastEventloopNestingLevel; bool mContentFocused; bool mWidgetVisible; // used on Mac to store our widget's visible state #ifdef XP_MACOSX bool mPluginPortChanged; #endif #ifdef MOZ_X11 // Used with windowless plugins only, initialized in CreateWidget(). bool mFlash10Quirks; #endif bool mPluginWindowVisible; bool mPluginDocumentActiveState; PRUint16 mNumCachedAttrs; PRUint16 mNumCachedParams; char **mCachedAttrParamNames; char **mCachedAttrParamValues; #ifdef XP_MACOSX NPEventModel mEventModel; // This is a hack! UseAsyncRendering() can incorrectly return false // when we don't have an object frame (possible as of bug 90268). // We hack around this by always returning true if we've ever // returned true. bool mUseAsyncRendering; #endif // pointer to wrapper for nsIDOMContextMenuListener nsRefPtr mCXMenuListener; nsresult DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent); nsresult DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent); nsresult DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent); nsresult EnsureCachedAttrParamArrays(); #ifdef MOZ_X11 class Renderer #if defined(MOZ_WIDGET_GTK2) : public gfxXlibNativeRenderer #elif defined(MOZ_WIDGET_QT) : public gfxQtNativeRenderer #endif { public: Renderer(NPWindow* aWindow, nsPluginInstanceOwner* aInstanceOwner, const nsIntSize& aPluginSize, const nsIntRect& aDirtyRect) : mWindow(aWindow), mInstanceOwner(aInstanceOwner), mPluginSize(aPluginSize), mDirtyRect(aDirtyRect) {} virtual nsresult DrawWithXlib(gfxXlibSurface* surface, nsIntPoint offset, nsIntRect* clipRects, PRUint32 numClipRects); private: NPWindow* mWindow; nsPluginInstanceOwner* mInstanceOwner; const nsIntSize& mPluginSize; const nsIntRect& mDirtyRect; }; #endif bool mWaitingForPaint; }; #endif // nsPluginInstanceOwner_h_