summaryrefslogtreecommitdiffstats
path: root/layout/generic/nsPluginFrame.h
diff options
context:
space:
mode:
Diffstat (limited to 'layout/generic/nsPluginFrame.h')
-rw-r--r--layout/generic/nsPluginFrame.h399
1 files changed, 399 insertions, 0 deletions
diff --git a/layout/generic/nsPluginFrame.h b/layout/generic/nsPluginFrame.h
new file mode 100644
index 0000000000..7a1509c876
--- /dev/null
+++ b/layout/generic/nsPluginFrame.h
@@ -0,0 +1,399 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/* rendering objects for replaced elements implemented by a plugin */
+
+#ifndef nsPluginFrame_h___
+#define nsPluginFrame_h___
+
+#include "mozilla/Attributes.h"
+#include "mozilla/EventForwards.h"
+#include "mozilla/UniquePtr.h"
+#include "nsIObjectFrame.h"
+#include "nsIFrame.h"
+#include "nsRegion.h"
+#include "nsDisplayList.h"
+#include "nsIReflowCallback.h"
+#include "Units.h"
+#include "mozilla/layers/StackingContextHelper.h"
+#include "mozilla/webrender/WebRenderAPI.h"
+
+#ifdef XP_WIN
+# include <windows.h> // For HWND :(
+// Undo the windows.h damage
+# undef GetMessage
+# undef CreateEvent
+# undef GetClassName
+# undef GetBinaryType
+# undef RemoveDirectory
+# undef LoadIcon
+# undef LoadImage
+# undef GetObject
+#endif
+
+class nsPresContext;
+class nsRootPresContext;
+class nsDisplayPlugin;
+class PluginBackgroundSink;
+class nsPluginInstanceOwner;
+
+namespace mozilla {
+class PresShell;
+namespace layers {
+class ImageContainer;
+class Layer;
+class LayerManager;
+} // namespace layers
+} // namespace mozilla
+
+class PluginFrameDidCompositeObserver;
+
+class nsPluginFrame final : public nsIFrame,
+ public nsIObjectFrame,
+ public nsIReflowCallback {
+ public:
+ typedef mozilla::LayerState LayerState;
+ typedef mozilla::LayoutDeviceIntPoint LayoutDeviceIntPoint;
+ typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
+ typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion;
+ typedef mozilla::layers::Layer Layer;
+ typedef mozilla::layers::LayerManager LayerManager;
+ typedef mozilla::layers::ImageContainer ImageContainer;
+ typedef mozilla::layers::StackingContextHelper StackingContextHelper;
+ typedef mozilla::layers::RenderRootStateManager RenderRootStateManager;
+ typedef mozilla::layers::WebRenderParentCommand WebRenderParentCommand;
+ typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
+
+ NS_DECL_FRAMEARENA_HELPERS(nsPluginFrame)
+ NS_DECL_QUERYFRAME
+
+ friend nsIFrame* NS_NewObjectFrame(mozilla::PresShell* aPresShell,
+ ComputedStyle* aStyle);
+
+ virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
+ nsIFrame* aPrevInFlow) override;
+ virtual nscoord GetMinISize(gfxContext* aRenderingContext) override;
+ virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override;
+ virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
+ const ReflowInput& aReflowInput,
+ nsReflowStatus& aStatus) override;
+ virtual void DidReflow(nsPresContext* aPresContext,
+ const ReflowInput* aReflowInput) override;
+ virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
+ const nsDisplayListSet& aLists) override;
+
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual nsresult HandleEvent(
+ nsPresContext* aPresContext, mozilla::WidgetGUIEvent* aEvent,
+ nsEventStatus* aEventStatus) override;
+
+ virtual bool IsFrameOfType(uint32_t aFlags) const override {
+ return nsIFrame::IsFrameOfType(
+ aFlags & ~(nsIFrame::eReplaced | nsIFrame::eReplacedSizing));
+ }
+
+#ifdef DEBUG_FRAME_DUMP
+ virtual nsresult GetFrameName(nsAString& aResult) const override;
+#endif
+
+ virtual void DestroyFrom(nsIFrame* aDestructRoot,
+ PostDestroyData& aPostDestroyData) override;
+
+ virtual void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;
+
+ nsNPAPIPluginInstance* GetPluginInstance() override;
+
+ virtual void SetIsDocumentActive(bool aIsActive) override;
+
+ mozilla::Maybe<Cursor> GetCursor(const nsPoint&) override;
+
+ // APIs used by nsRootPresContext to set up the widget position/size/clip
+ // region.
+ /**
+ * Set the next widget configuration for the plugin to the desired
+ * position of the plugin's widget, on the assumption that it is not visible
+ * (clipped out or covered by opaque content).
+ * This will only be called for plugins which have been registered
+ * with the root pres context for geometry updates.
+ * If there is no widget associated with the plugin, this will have no effect.
+ */
+ void SetEmptyWidgetConfiguration() {
+ mNextConfigurationBounds = LayoutDeviceIntRect(0, 0, 0, 0);
+ mNextConfigurationClipRegion.Clear();
+ }
+ /**
+ * Append the desired widget configuration to aConfigurations.
+ */
+ void GetWidgetConfiguration(
+ nsTArray<nsIWidget::Configuration>* aConfigurations);
+
+ LayoutDeviceIntRect GetWidgetlessClipRect() {
+ return RegionFromArray(mNextConfigurationClipRegion).GetBounds();
+ }
+
+ /**
+ * Called after all widget position/size/clip regions have been changed
+ * (even if there isn't a widget for this plugin).
+ */
+ void DidSetWidgetGeometry();
+
+ // accessibility support
+#ifdef ACCESSIBILITY
+ virtual mozilla::a11y::AccType AccessibleType() override;
+# ifdef XP_WIN
+ NS_IMETHOD GetPluginPort(HWND* aPort);
+# endif
+#endif
+
+ // local methods
+ nsresult PrepForDrawing(nsIWidget* aWidget);
+
+ // for a given aRoot, this walks the frame tree looking for the next outFrame
+ static nsIObjectFrame* GetNextObjectFrame(nsPresContext* aPresContext,
+ nsIFrame* aRoot);
+
+ // nsIReflowCallback
+ virtual bool ReflowFinished() override;
+ virtual void ReflowCallbackCanceled() override;
+
+ /**
+ * Builds either an ImageLayer or a ReadbackLayer, depending on the type
+ * of aItem (TYPE_PLUGIN or TYPE_PLUGIN_READBACK respectively).
+ */
+ already_AddRefed<Layer> BuildLayer(
+ nsDisplayListBuilder* aBuilder, LayerManager* aManager,
+ nsDisplayItem* aItem,
+ const ContainerLayerParameters& aContainerParameters);
+
+ LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
+ LayerManager* aManager);
+
+ /**
+ * Get the rectangle (relative to this frame) which it will paint. Normally
+ * the frame's content-box but may be smaller if the plugin is rendering
+ * asynchronously and has a different-sized image temporarily.
+ */
+ nsRect GetPaintedRect(const nsDisplayPlugin* aItem) const;
+
+ /**
+ * If aSupports has a nsPluginFrame, then prepare it for a DocShell swap.
+ * @see nsSubDocumentFrame::BeginSwapDocShells.
+ * There will be a call to EndSwapDocShells after we were moved to the
+ * new view tree.
+ */
+ static void BeginSwapDocShells(nsISupports* aSupports);
+ /**
+ * If aSupports has a nsPluginFrame, then set it up after a DocShell swap.
+ * @see nsSubDocumentFrame::EndSwapDocShells.
+ */
+ static void EndSwapDocShells(nsISupports* aSupports);
+
+ nsIWidget* GetWidget() override {
+ if (!mInnerView) {
+ return nullptr;
+ }
+ return mWidget;
+ }
+
+ /**
+ * Adjust the plugin's idea of its size, using aSize as its new size.
+ * (aSize must be in twips)
+ */
+ void FixupWindow(const nsSize& aSize);
+
+ /*
+ * Sets up the plugin window and calls SetWindow on the plugin.
+ */
+ nsresult CallSetWindow(bool aCheckIsHidden = true);
+
+ void SetInstanceOwner(nsPluginInstanceOwner* aOwner);
+
+ /**
+ * HandleWheelEventAsDefaultAction() handles eWheel event as default action.
+ * This should be called only when WantsToHandleWheelEventAsDefaultAction()
+ * returns true.
+ */
+ void HandleWheelEventAsDefaultAction(mozilla::WidgetWheelEvent* aEvent);
+
+ /**
+ * WantsToHandleWheelEventAsDefaultAction() returns true if the plugin
+ * may want to handle wheel events as default action.
+ */
+ bool WantsToHandleWheelEventAsDefaultAction() const;
+
+ bool CreateWebRenderCommands(
+ nsDisplayItem* aItem, mozilla::wr::DisplayListBuilder& aBuilder,
+ mozilla::wr::IpcResourceUpdateQueue& aResources,
+ const StackingContextHelper& aSc,
+ mozilla::layers::RenderRootStateManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder);
+
+ protected:
+ explicit nsPluginFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
+ virtual ~nsPluginFrame();
+
+ // NOTE: This frame class does not inherit from |nsLeafFrame|, so
+ // this is not a virtual method implementation.
+ void GetDesiredSize(nsPresContext* aPresContext,
+ const ReflowInput& aReflowInput,
+ ReflowOutput& aDesiredSize);
+
+ // check attributes and optionally CSS to see if we should display anything
+ bool IsHidden(bool aCheckVisibilityStyle = true) const;
+
+ bool IsOpaque() const;
+ bool IsTransparentMode() const;
+ bool IsPaintedByGecko() const;
+
+ nsIntPoint GetWindowOriginInPixels(bool aWindowless);
+
+ /*
+ * If this frame is in a remote tab, return the tab offset to
+ * the origin of the chrome window. In non-e10s, this return 0,0.
+ * This api sends a sync ipc request so be careful about use.
+ */
+ LayoutDeviceIntPoint GetRemoteTabChromeOffset();
+
+ static void PaintPrintPlugin(nsIFrame* aFrame, gfxContext* aRenderingContext,
+ const nsRect& aDirtyRect, nsPoint aPt);
+ void PrintPlugin(gfxContext& aRenderingContext, const nsRect& aDirtyRect);
+ void PaintPlugin(nsDisplayListBuilder* aBuilder,
+ gfxContext& aRenderingContext, const nsRect& aDirtyRect,
+ const nsRect& aPluginRect);
+
+ void NotifyPluginReflowObservers();
+
+ friend class nsPluginInstanceOwner;
+ friend class nsDisplayPlugin;
+ friend class PluginBackgroundSink;
+
+ nsView* GetViewInternal() const override { return mOuterView; }
+ void SetViewInternal(nsView* aView) override { mOuterView = aView; }
+ bool GetBounds(nsDisplayItem* aItem, mozilla::gfx::IntSize& aSize,
+ gfxRect& aRect);
+
+ private:
+ // Registers the plugin for a geometry update, and requests a geometry
+ // update. This caches the root pres context in
+ // mRootPresContextRegisteredWith, so that we can be sure we unregister
+ // from the right root prest context in UnregisterPluginForGeometryUpdates.
+ void RegisterPluginForGeometryUpdates();
+
+ // Unregisters the plugin for geometry updated with the root pres context
+ // stored in mRootPresContextRegisteredWith.
+ void UnregisterPluginForGeometryUpdates();
+
+ static const LayoutDeviceIntRegion RegionFromArray(
+ const nsTArray<LayoutDeviceIntRect>& aRects) {
+ LayoutDeviceIntRegion region;
+ for (uint32_t i = 0; i < aRects.Length(); ++i) {
+ region.Or(region, aRects[i]);
+ }
+ return region;
+ }
+
+ class PluginEventNotifier : public mozilla::Runnable {
+ public:
+ explicit PluginEventNotifier(const nsString& aEventType)
+ : mozilla::Runnable("nsPluginFrame::PluginEventNotifier"),
+ mEventType(aEventType) {}
+
+ NS_IMETHOD Run() override;
+
+ private:
+ nsString mEventType;
+ };
+
+ nsPluginInstanceOwner* mInstanceOwner; // WEAK
+ nsView* mOuterView;
+ nsView* mInnerView;
+ nsCOMPtr<nsIWidget> mWidget;
+ nsIntRect mWindowlessRect;
+ /**
+ * This is owned by the ReadbackLayer for this nsPluginFrame. It is
+ * automatically cleared if the PluginBackgroundSink is destroyed.
+ */
+ PluginBackgroundSink* mBackgroundSink;
+
+ /**
+ * Bounds that we should set the plugin's widget to in the next composite,
+ * for plugins with widgets. For plugins without widgets, bounds in device
+ * pixels relative to the nearest frame that's a display list reference frame.
+ */
+ LayoutDeviceIntRect mNextConfigurationBounds;
+ /**
+ * Clip region that we should set the plugin's widget to
+ * in the next composite. Only meaningful for plugins with widgets.
+ */
+ nsTArray<LayoutDeviceIntRect> mNextConfigurationClipRegion;
+
+ bool mReflowCallbackPosted;
+
+ // We keep this reference to ensure we can always unregister the
+ // plugins we register on the root PresContext.
+ // This is only non-null while we have a plugin registered for geometry
+ // updates.
+ RefPtr<nsRootPresContext> mRootPresContextRegisteredWith;
+
+ mozilla::UniquePtr<PluginFrameDidCompositeObserver> mDidCompositeObserver;
+};
+
+class nsDisplayPluginGeometry : public nsDisplayItemGenericGeometry {
+ public:
+ nsDisplayPluginGeometry(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder)
+ : nsDisplayItemGenericGeometry(aItem, aBuilder) {}
+
+ // Plugins MozPaintWait event depends on sync decode, so we always want
+ // to rebuild the display list when sync decoding.
+ virtual bool InvalidateForSyncDecodeImages() const override { return true; }
+};
+
+class nsDisplayPlugin final : public nsPaintedDisplayItem {
+ public:
+ nsDisplayPlugin(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
+ : nsPaintedDisplayItem(aBuilder, aFrame) {
+ MOZ_COUNT_CTOR(nsDisplayPlugin);
+ aBuilder->SetContainsPluginItem();
+ }
+ MOZ_COUNTED_DTOR_OVERRIDE(nsDisplayPlugin)
+
+ virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
+ bool* aSnap) const override;
+ virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
+ bool* aSnap) const override;
+ virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
+ virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
+ nsRegion* aVisibleRegion) override;
+
+ NS_DISPLAY_DECL_NAME("Plugin", TYPE_PLUGIN)
+
+ virtual already_AddRefed<Layer> BuildLayer(
+ nsDisplayListBuilder* aBuilder, LayerManager* aManager,
+ const ContainerLayerParameters& aContainerParameters) override {
+ return static_cast<nsPluginFrame*>(mFrame)->BuildLayer(
+ aBuilder, aManager, this, aContainerParameters);
+ }
+
+ virtual LayerState GetLayerState(
+ nsDisplayListBuilder* aBuilder, LayerManager* aManager,
+ const ContainerLayerParameters& aParameters) override {
+ return static_cast<nsPluginFrame*>(mFrame)->GetLayerState(aBuilder,
+ aManager);
+ }
+
+ virtual nsDisplayItemGeometry* AllocateGeometry(
+ nsDisplayListBuilder* aBuilder) override {
+ return new nsDisplayPluginGeometry(this, aBuilder);
+ }
+
+ virtual bool CreateWebRenderCommands(
+ mozilla::wr::DisplayListBuilder& aBuilder,
+ mozilla::wr::IpcResourceUpdateQueue& aResources,
+ const StackingContextHelper& aSc,
+ mozilla::layers::RenderRootStateManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder) override;
+};
+
+#endif /* nsPluginFrame_h___ */