summaryrefslogtreecommitdiff
path: root/layout/generic/nsPluginFrame.h
diff options
context:
space:
mode:
Diffstat (limited to 'layout/generic/nsPluginFrame.h')
-rw-r--r--layout/generic/nsPluginFrame.h381
1 files changed, 381 insertions, 0 deletions
diff --git a/layout/generic/nsPluginFrame.h b/layout/generic/nsPluginFrame.h
new file mode 100644
index 0000000000..5d9f9f4757
--- /dev/null
+++ b/layout/generic/nsPluginFrame.h
@@ -0,0 +1,381 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 "nsFrame.h"
+#include "nsRegion.h"
+#include "nsDisplayList.h"
+#include "nsIReflowCallback.h"
+#include "Units.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 {
+namespace layers {
+class ImageContainer;
+class Layer;
+class LayerManager;
+} // namespace layers
+} // namespace mozilla
+
+class PluginFrameDidCompositeObserver;
+
+class nsPluginFrame : public nsFrame
+ , 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::ContainerLayerParameters ContainerLayerParameters;
+
+ NS_DECL_FRAMEARENA_HELPERS
+
+ friend nsIFrame* NS_NewObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+
+ NS_DECL_QUERYFRAME
+ NS_DECL_QUERYFRAME_TARGET(nsPluginFrame)
+
+ virtual void Init(nsIContent* aContent,
+ nsContainerFrame* aParent,
+ nsIFrame* aPrevInFlow) override;
+ virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override;
+ virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override;
+ virtual void Reflow(nsPresContext* aPresContext,
+ ReflowOutput& aDesiredSize,
+ const ReflowInput& aReflowInput,
+ nsReflowStatus& aStatus) override;
+ virtual void DidReflow(nsPresContext* aPresContext,
+ const ReflowInput* aReflowInput,
+ nsDidReflowStatus aStatus) override;
+ virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
+ const nsRect& aDirtyRect,
+ const nsDisplayListSet& aLists) override;
+
+ virtual nsresult HandleEvent(nsPresContext* aPresContext,
+ mozilla::WidgetGUIEvent* aEvent,
+ nsEventStatus* aEventStatus) override;
+
+ virtual nsIAtom* GetType() const override;
+
+ virtual bool IsFrameOfType(uint32_t aFlags) const override
+ {
+ return nsFrame::IsFrameOfType(aFlags &
+ ~(nsIFrame::eReplaced | nsIFrame::eReplacedSizing));
+ }
+
+ virtual bool NeedsView() override { return true; }
+
+#ifdef DEBUG_FRAME_DUMP
+ virtual nsresult GetFrameName(nsAString& aResult) const override;
+#endif
+
+ virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
+
+ virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override;
+
+ NS_IMETHOD GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance) override;
+
+ virtual void SetIsDocumentActive(bool aIsActive) override;
+
+ virtual nsresult GetCursor(const nsPoint& aPoint,
+ nsIFrame::Cursor& aCursor) 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(nsDisplayPlugin* aItem);
+
+ /**
+ * 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, void*);
+ /**
+ * If aSupports has a nsPluginFrame, then set it up after a DocShell swap.
+ * @see nsSubDocumentFrame::EndSwapDocShells.
+ */
+ static void EndSwapDocShells(nsISupports* aSupports, void*);
+
+ 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;
+
+protected:
+ explicit nsPluginFrame(nsStyleContext* aContext);
+ 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);
+
+ bool IsFocusable(int32_t *aTabIndex = nullptr,
+ bool aWithMouse = false) override;
+
+ // 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,
+ nsRenderingContext* aRenderingContext,
+ const nsRect& aDirtyRect, nsPoint aPt);
+ void PrintPlugin(nsRenderingContext& aRenderingContext,
+ const nsRect& aDirtyRect);
+ void PaintPlugin(nsDisplayListBuilder* aBuilder,
+ nsRenderingContext& aRenderingContext,
+ const nsRect& aDirtyRect, const nsRect& aPluginRect);
+
+ void NotifyPluginReflowObservers();
+
+ friend class nsPluginInstanceOwner;
+ friend class nsDisplayPlugin;
+ friend class PluginBackgroundSink;
+
+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) :
+ mEventType(aEventType) {}
+
+ NS_IMETHOD Run() override;
+ private:
+ nsString mEventType;
+ };
+
+ nsPluginInstanceOwner* mInstanceOwner; // WEAK
+ 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 nsDisplayPlugin : public nsDisplayItem {
+public:
+ nsDisplayPlugin(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
+ : nsDisplayItem(aBuilder, aFrame)
+ {
+ MOZ_COUNT_CTOR(nsDisplayPlugin);
+ aBuilder->SetContainsPluginItem();
+ }
+#ifdef NS_BUILD_REFCNT_LOGGING
+ virtual ~nsDisplayPlugin() {
+ MOZ_COUNT_DTOR(nsDisplayPlugin);
+ }
+#endif
+
+ virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
+ virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
+ bool* aSnap) override;
+ virtual void Paint(nsDisplayListBuilder* aBuilder,
+ nsRenderingContext* 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);
+ }
+};
+
+#endif /* nsPluginFrame_h___ */