/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ // vim:set ts=2 sts=2 sw=2 et cin: /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef nsPluginInstanceOwner_h_ #define nsPluginInstanceOwner_h_ #include "mozilla/Attributes.h" #include "npapi.h" #include "nsCOMPtr.h" #include "nsIKeyEventInPluginCallback.h" #include "nsIPluginInstanceOwner.h" #include "nsIPrivacyTransitionObserver.h" #include "nsIDOMEventListener.h" #include "nsPluginHost.h" #include "nsPluginNativeWindow.h" #include "nsWeakReference.h" #include "gfxRect.h" #ifdef XP_MACOSX #include "mozilla/gfx/QuartzSupport.h" #include <ApplicationServices/ApplicationServices.h> #endif class nsIInputStream; class nsPluginDOMContextMenuListener; class nsPluginFrame; class nsDisplayListBuilder; #if defined(MOZ_X11) || defined(ANDROID) class gfxContext; #endif namespace mozilla { class TextComposition; namespace dom { struct MozPluginParameter; } // namespace dom namespace widget { class PuppetWidget; } // namespace widget } // namespace mozilla using mozilla::widget::PuppetWidget; #ifdef MOZ_X11 #include "gfxXlibNativeRenderer.h" #endif class nsPluginInstanceOwner final : public nsIPluginInstanceOwner , public nsIDOMEventListener , public nsIPrivacyTransitionObserver , public nsIKeyEventInPluginCallback , public nsSupportsWeakReference { public: typedef mozilla::gfx::DrawTarget DrawTarget; nsPluginInstanceOwner(); NS_DECL_ISUPPORTS NS_DECL_NSIPLUGININSTANCEOWNER NS_DECL_NSIPRIVACYTRANSITIONOBSERVER NS_IMETHOD GetURL(const char *aURL, const char *aTarget, nsIInputStream *aPostStream, void *aHeadersData, uint32_t aHeadersDataLen, bool aDoCheckLoadURIChecks) override; NPBool ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace) override; NPError InitAsyncSurface(NPSize *size, NPImageFormat format, void *initData, NPAsyncSurface *surface) override; NPError FinalizeAsyncSurface(NPAsyncSurface *surface) override; void SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed) override; /** * Get the type of the HTML tag that was used ot instantiate this * plugin. Currently supported tags are EMBED, OBJECT and APPLET. */ NS_IMETHOD GetTagType(nsPluginTagType *aResult); void GetParameters(nsTArray<mozilla::dom::MozPluginParameter>& parameters); void GetAttributes(nsTArray<mozilla::dom::MozPluginParameter>& attributes); /** * Returns the DOM element corresponding to the tag which references * this plugin in the document. * * @param aDOMElement - resulting DOM element * @result - NS_OK if this operation was successful */ NS_IMETHOD GetDOMElement(nsIDOMElement* * aResult); // nsIDOMEventListener interfaces NS_DECL_NSIDOMEVENTLISTENER nsresult ProcessMouseDown(nsIDOMEvent* aKeyEvent); nsresult ProcessKeyPress(nsIDOMEvent* aKeyEvent); 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); #endif //locals nsresult Init(nsIContent* aContent); void* GetPluginPort(); void ReleasePluginPort(void* pluginPort); nsEventStatus ProcessEvent(const mozilla::WidgetGUIEvent& anEvent); static void GeneratePluginEvent( const mozilla::WidgetCompositionEvent* aSrcCompositionEvent, mozilla::WidgetCompositionEvent* aDistCompositionEvent); #if defined(XP_WIN) void SetWidgetWindowAsParent(HWND aWindowToAdopt); nsresult SetNetscapeWindowAsParent(HWND aWindowToAdopt); #endif #ifdef XP_MACOSX enum { ePluginPaintEnable, ePluginPaintDisable }; void WindowFocusMayHaveChanged(); bool WindowIsActive(); void SendWindowFocusChanged(bool aIsActive); 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(int32_t inPaintState); void HidePluginWindow(); // Set plugin port info in the plugin (in the 'window' member of the // NPWindow structure passed to the plugin by SetWindow()). void SetPluginPort(); #else // XP_MACOSX void UpdateWindowPositionAndClipRect(bool aSetWindow); void UpdateWindowVisibility(bool aVisible); #endif // XP_MACOSX void ResolutionMayHaveChanged(); #if defined(XP_MACOSX) || defined(XP_WIN) nsresult ContentsScaleFactorChanged(double aContentsScaleFactor); #endif void UpdateDocumentActiveState(bool aIsActive); void SetFrame(nsPluginFrame *aFrame); nsPluginFrame* GetFrame(); uint32_t GetLastEventloopNestingLevel() const { return mLastEventloopNestingLevel; } static uint32_t GetEventloopNestingLevel(); void ConsiderNewEventloopNestingLevel() { uint32_t currentLevel = GetEventloopNestingLevel(); if (currentLevel < mLastEventloopNestingLevel) { mLastEventloopNestingLevel = currentLevel; } } const char* GetPluginName() { if (mInstance && mPluginHost) { const char* name = nullptr; if (NS_SUCCEEDED(mPluginHost->GetPluginName(mInstance, &name)) && name) return name; } return ""; } #ifdef MOZ_X11 void GetPluginDescription(nsACString& aDescription) { aDescription.Truncate(); if (mInstance && mPluginHost) { nsCOMPtr<nsIPluginTag> 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<mozilla::layers::ImageContainer> GetImageContainer(); // Returns true if this is windowed plugin that can return static captures // for scroll operations. bool NeedsScrollImageLayer(); void DidComposite(); /** * 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<DrawTarget> BeginUpdateBackground(const nsIntRect& aRect); void EndUpdateBackground(const nsIntRect& aRect); bool UseAsyncRendering(); already_AddRefed<nsIURI> GetBaseURI() const; #ifdef MOZ_WIDGET_ANDROID // Returns the image container for the specified VideoInfo void GetVideos(nsTArray<nsNPAPIPluginInstance::VideoInfo*>& aVideos); already_AddRefed<mozilla::layers::ImageContainer> GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInfo* aVideoInfo); void Invalidate(); void Recomposite(); void RequestFullScreen(); void ExitFullScreen(); // Called from nsAppShell when we removed the fullscreen view. static void ExitFullScreen(jobject view); #endif void NotifyHostAsyncInitFailed(); void NotifyHostCreateWidget(); void NotifyDestroyPending(); bool GetCompositionString(uint32_t aIndex, nsTArray<uint8_t>* aString, int32_t* aLength); bool SetCandidateWindow( const mozilla::widget::CandidateWindowPosition& aPosition); bool RequestCommitOrCancel(bool aCommitted); // See nsIKeyEventInPluginCallback virtual void HandledWindowedPluginKeyEvent( const mozilla::NativeEventData& aKeyEventData, bool aIsConsumed) override; /** * OnWindowedPluginKeyEvent() is called when the plugin process receives * native key event directly. * * @param aNativeKeyData The key event which was received by the * plugin process directly. */ void OnWindowedPluginKeyEvent( const mozilla::NativeEventData& aNativeKeyData); void GetCSSZoomFactor(float *result); private: virtual ~nsPluginInstanceOwner(); // 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); } #ifdef MOZ_WIDGET_ANDROID mozilla::LayoutDeviceRect GetPluginRect(); bool AddPluginView(const mozilla::LayoutDeviceRect& aRect = mozilla::LayoutDeviceRect(0, 0, 0, 0)); void RemovePluginView(); bool mFullScreen; void* mJavaView; #endif #if defined(XP_WIN) nsIWidget* GetContainingWidgetIfOffset(); already_AddRefed<mozilla::TextComposition> GetTextComposition(); void HandleNoConsumedCompositionMessage( mozilla::WidgetCompositionEvent* aCompositionEvent, const NPEvent* aPluginEvent); bool mGotCompositionData; bool mSentStartComposition; bool mPluginDidNotHandleIMEComposition; #endif nsPluginNativeWindow *mPluginWindow; RefPtr<nsNPAPIPluginInstance> mInstance; nsPluginFrame *mPluginFrame; nsWeakPtr mContent; // WEAK, content owns us nsCString mDocumentBase; bool mWidgetCreationComplete; nsCOMPtr<nsIWidget> mWidget; RefPtr<nsPluginHost> mPluginHost; #ifdef XP_MACOSX static nsCOMPtr<nsITimer> *sCATimer; static nsTArray<nsPluginInstanceOwner*> *sCARefreshListeners; bool mSentInitialTopLevelWindowEvent; bool mLastWindowIsActive; bool mLastContentFocused; // True if, the next time the window is activated, we should blur ourselves. bool mShouldBlurOnActivate; #endif double mLastScaleFactor; double mLastCSSZoomFactor; // 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. uint32_t mLastEventloopNestingLevel; bool mContentFocused; bool mWidgetVisible; // used on Mac to store our widget's visible state #ifdef MOZ_X11 // Used with windowless plugins only, initialized in CreateWidget(). bool mFlash10Quirks; #endif bool mPluginWindowVisible; bool mPluginDocumentActiveState; #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 RefPtr<nsPluginDOMContextMenuListener> mCXMenuListener; nsresult DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent); nsresult DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent, bool aAllowPropagate = false); nsresult DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent); nsresult DispatchCompositionToPlugin(nsIDOMEvent* aEvent); #ifdef XP_WIN void CallDefaultProc(const mozilla::WidgetGUIEvent* aEvent); #endif #ifdef XP_MACOSX static NPBool ConvertPointPuppet(PuppetWidget *widget, nsPluginFrame* pluginFrame, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace); static NPBool ConvertPointNoPuppet(nsIWidget *widget, nsPluginFrame* pluginFrame, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace); void PerformDelayedBlurs(); #endif // XP_MACOSX int mLastMouseDownButtonType; #ifdef MOZ_X11 class Renderer : public gfxXlibNativeRenderer { public: Renderer(NPWindow* aWindow, nsPluginInstanceOwner* aInstanceOwner, const nsIntSize& aPluginSize, const nsIntRect& aDirtyRect) : mWindow(aWindow), mInstanceOwner(aInstanceOwner), mPluginSize(aPluginSize), mDirtyRect(aDirtyRect) {} virtual nsresult DrawWithXlib(cairo_surface_t* surface, nsIntPoint offset, nsIntRect* clipRects, uint32_t numClipRects) override; private: NPWindow* mWindow; nsPluginInstanceOwner* mInstanceOwner; const nsIntSize& mPluginSize; const nsIntRect& mDirtyRect; }; #endif bool mWaitingForPaint; }; #endif // nsPluginInstanceOwner_h_