1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* rendering objects for replaced elements implemented by a plugin */
8 #ifndef nsObjectFrame_h___
9 #define nsObjectFrame_h___
11 #include "mozilla/Attributes.h"
12 #include "nsIObjectFrame.h"
15 #include "nsDisplayList.h"
16 #include "nsIReflowCallback.h"
19 #include <windows.h> // For HWND :(
20 // Undo the windows.h damage
25 #undef RemoveDirectory
29 class nsRootPresContext
;
30 class nsDisplayPlugin
;
32 class PluginBackgroundSink
;
33 class nsPluginInstanceOwner
;
43 typedef nsFrame nsObjectFrameSuper
;
45 class nsObjectFrame
: public nsObjectFrameSuper
,
46 public nsIObjectFrame
,
47 public nsIReflowCallback
{
49 typedef mozilla::LayerState LayerState
;
50 typedef mozilla::layers::Layer Layer
;
51 typedef mozilla::layers::LayerManager LayerManager
;
52 typedef mozilla::layers::ImageContainer ImageContainer
;
53 typedef mozilla::ContainerLayerParameters ContainerLayerParameters
;
55 NS_DECL_FRAMEARENA_HELPERS
57 friend nsIFrame
* NS_NewObjectFrame(nsIPresShell
* aPresShell
, nsStyleContext
* aContext
);
60 NS_DECL_QUERYFRAME_TARGET(nsObjectFrame
)
62 virtual void Init(nsIContent
* aContent
,
63 nsContainerFrame
* aParent
,
64 nsIFrame
* aPrevInFlow
) MOZ_OVERRIDE
;
65 virtual nscoord
GetMinISize(nsRenderingContext
*aRenderingContext
) MOZ_OVERRIDE
;
66 virtual nscoord
GetPrefISize(nsRenderingContext
*aRenderingContext
) MOZ_OVERRIDE
;
67 virtual void Reflow(nsPresContext
* aPresContext
,
68 nsHTMLReflowMetrics
& aDesiredSize
,
69 const nsHTMLReflowState
& aReflowState
,
70 nsReflowStatus
& aStatus
) MOZ_OVERRIDE
;
71 virtual void DidReflow(nsPresContext
* aPresContext
,
72 const nsHTMLReflowState
* aReflowState
,
73 nsDidReflowStatus aStatus
) MOZ_OVERRIDE
;
74 virtual void BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
75 const nsRect
& aDirtyRect
,
76 const nsDisplayListSet
& aLists
) MOZ_OVERRIDE
;
78 virtual nsresult
HandleEvent(nsPresContext
* aPresContext
,
79 mozilla::WidgetGUIEvent
* aEvent
,
80 nsEventStatus
* aEventStatus
) MOZ_OVERRIDE
;
82 virtual nsIAtom
* GetType() const MOZ_OVERRIDE
;
84 virtual bool IsFrameOfType(uint32_t aFlags
) const MOZ_OVERRIDE
86 return nsObjectFrameSuper::IsFrameOfType(aFlags
& ~(nsIFrame::eReplaced
));
89 virtual bool NeedsView() MOZ_OVERRIDE
{ return true; }
91 #ifdef DEBUG_FRAME_DUMP
92 virtual nsresult
GetFrameName(nsAString
& aResult
) const MOZ_OVERRIDE
;
95 virtual void DestroyFrom(nsIFrame
* aDestructRoot
) MOZ_OVERRIDE
;
97 virtual void DidSetStyleContext(nsStyleContext
* aOldStyleContext
) MOZ_OVERRIDE
;
99 NS_METHOD
GetPluginInstance(nsNPAPIPluginInstance
** aPluginInstance
) MOZ_OVERRIDE
;
101 virtual void SetIsDocumentActive(bool aIsActive
) MOZ_OVERRIDE
;
103 virtual nsresult
GetCursor(const nsPoint
& aPoint
,
104 nsIFrame::Cursor
& aCursor
) MOZ_OVERRIDE
;
106 // APIs used by nsRootPresContext to set up the widget position/size/clip
109 * Set the next widget configuration for the plugin to the desired
110 * position of the plugin's widget, on the assumption that it is not visible
111 * (clipped out or covered by opaque content).
112 * This will only be called for plugins which have been registered
113 * with the root pres context for geometry updates.
114 * If there is no widget associated with the plugin, this will have no effect.
116 void SetEmptyWidgetConfiguration()
118 mNextConfigurationBounds
= nsIntRect(0,0,0,0);
119 mNextConfigurationClipRegion
.Clear();
122 * Append the desired widget configuration to aConfigurations.
124 void GetWidgetConfiguration(nsTArray
<nsIWidget::Configuration
>* aConfigurations
)
127 if (!mWidget
->GetParent()) {
128 // Plugin widgets should not be toplevel except when they're out of the
129 // document, in which case the plugin should not be registered for
130 // geometry updates and this should not be called. But apparently we
131 // have bugs where mWidget sometimes is toplevel here. Bail out.
132 NS_ERROR("Plugin widgets registered for geometry updates should not be toplevel");
135 nsIWidget::Configuration
* configuration
= aConfigurations
->AppendElement();
136 configuration
->mChild
= mWidget
;
137 configuration
->mBounds
= mNextConfigurationBounds
;
138 configuration
->mClipRegion
= mNextConfigurationClipRegion
;
142 * Called after all widget position/size/clip regions have been changed
143 * (even if there isn't a widget for this plugin).
145 void DidSetWidgetGeometry();
147 // accessibility support
149 virtual mozilla::a11y::AccType
AccessibleType() MOZ_OVERRIDE
;
151 NS_IMETHOD
GetPluginPort(HWND
*aPort
);
156 nsresult
PrepForDrawing(nsIWidget
*aWidget
);
158 // for a given aRoot, this walks the frame tree looking for the next outFrame
159 static nsIObjectFrame
* GetNextObjectFrame(nsPresContext
* aPresContext
,
163 virtual bool ReflowFinished() MOZ_OVERRIDE
;
164 virtual void ReflowCallbackCanceled() MOZ_OVERRIDE
;
167 * Builds either an ImageLayer or a ReadbackLayer, depending on the type
168 * of aItem (TYPE_PLUGIN or TYPE_PLUGIN_READBACK respectively).
170 already_AddRefed
<Layer
> BuildLayer(nsDisplayListBuilder
* aBuilder
,
171 LayerManager
* aManager
,
172 nsDisplayItem
* aItem
,
173 const ContainerLayerParameters
& aContainerParameters
);
175 LayerState
GetLayerState(nsDisplayListBuilder
* aBuilder
,
176 LayerManager
* aManager
);
179 * Get the rectangle (relative to this frame) which it will paint. Normally
180 * the frame's content-box but may be smaller if the plugin is rendering
181 * asynchronously and has a different-sized image temporarily.
183 nsRect
GetPaintedRect(nsDisplayPlugin
* aItem
);
186 * If aSupports has a nsObjectFrame, then prepare it for a DocShell swap.
187 * @see nsSubDocumentFrame::BeginSwapDocShells.
188 * There will be a call to EndSwapDocShells after we were moved to the
191 static void BeginSwapDocShells(nsISupports
* aSupports
, void*);
193 * If aSupports has a nsObjectFrame, then set it up after a DocShell swap.
194 * @see nsSubDocumentFrame::EndSwapDocShells.
196 static void EndSwapDocShells(nsISupports
* aSupports
, void*);
198 nsIWidget
* GetWidget() MOZ_OVERRIDE
{ return mInnerView
? mWidget
: nullptr; }
201 * Adjust the plugin's idea of its size, using aSize as its new size.
202 * (aSize must be in twips)
204 void FixupWindow(const nsSize
& aSize
);
207 * Sets up the plugin window and calls SetWindow on the plugin.
209 nsresult
CallSetWindow(bool aCheckIsHidden
= true);
211 void SetInstanceOwner(nsPluginInstanceOwner
* aOwner
);
214 explicit nsObjectFrame(nsStyleContext
* aContext
);
215 virtual ~nsObjectFrame();
217 // NOTE: This frame class does not inherit from |nsLeafFrame|, so
218 // this is not a virtual method implementation.
219 void GetDesiredSize(nsPresContext
* aPresContext
,
220 const nsHTMLReflowState
& aReflowState
,
221 nsHTMLReflowMetrics
& aDesiredSize
);
223 bool IsFocusable(int32_t *aTabIndex
= nullptr,
224 bool aWithMouse
= false) MOZ_OVERRIDE
;
226 // check attributes and optionally CSS to see if we should display anything
227 bool IsHidden(bool aCheckVisibilityStyle
= true) const;
229 bool IsOpaque() const;
230 bool IsTransparentMode() const;
231 bool IsPaintedByGecko() const;
233 nsIntPoint
GetWindowOriginInPixels(bool aWindowless
);
235 static void PaintPrintPlugin(nsIFrame
* aFrame
,
236 nsRenderingContext
* aRenderingContext
,
237 const nsRect
& aDirtyRect
, nsPoint aPt
);
238 void PrintPlugin(nsRenderingContext
& aRenderingContext
,
239 const nsRect
& aDirtyRect
);
240 void PaintPlugin(nsDisplayListBuilder
* aBuilder
,
241 nsRenderingContext
& aRenderingContext
,
242 const nsRect
& aDirtyRect
, const nsRect
& aPluginRect
);
244 void NotifyPluginReflowObservers();
246 friend class nsPluginInstanceOwner
;
247 friend class nsDisplayPlugin
;
248 friend class PluginBackgroundSink
;
251 // Registers the plugin for a geometry update, and requests a geometry
252 // update. This caches the root pres context in
253 // mRootPresContextRegisteredWith, so that we can be sure we unregister
254 // from the right root prest context in UnregisterPluginForGeometryUpdates.
255 void RegisterPluginForGeometryUpdates();
257 // Unregisters the plugin for geometry updated with the root pres context
258 // stored in mRootPresContextRegisteredWith.
259 void UnregisterPluginForGeometryUpdates();
261 class PluginEventNotifier
: public nsRunnable
{
263 explicit PluginEventNotifier(const nsString
&aEventType
) :
264 mEventType(aEventType
) {}
266 NS_IMETHOD
Run() MOZ_OVERRIDE
;
271 nsPluginInstanceOwner
* mInstanceOwner
; // WEAK
273 nsCOMPtr
<nsIWidget
> mWidget
;
274 nsIntRect mWindowlessRect
;
276 * This is owned by the ReadbackLayer for this nsObjectFrame. It is
277 * automatically cleared if the PluginBackgroundSink is destroyed.
279 PluginBackgroundSink
* mBackgroundSink
;
282 * Bounds that we should set the plugin's widget to in the next composite,
283 * for plugins with widgets. For plugins without widgets, bounds in device
284 * pixels relative to the nearest frame that's a display list reference frame.
286 nsIntRect mNextConfigurationBounds
;
288 * Clip region that we should set the plugin's widget to
289 * in the next composite. Only meaningful for plugins with widgets.
291 nsTArray
<nsIntRect
> mNextConfigurationClipRegion
;
293 bool mReflowCallbackPosted
;
295 // We keep this reference to ensure we can always unregister the
296 // plugins we register on the root PresContext.
297 // This is only non-null while we have a plugin registered for geometry
299 nsRefPtr
<nsRootPresContext
> mRootPresContextRegisteredWith
;
302 class nsDisplayPlugin
: public nsDisplayItem
{
304 nsDisplayPlugin(nsDisplayListBuilder
* aBuilder
, nsIFrame
* aFrame
)
305 : nsDisplayItem(aBuilder
, aFrame
)
307 MOZ_COUNT_CTOR(nsDisplayPlugin
);
308 aBuilder
->SetContainsPluginItem();
310 #ifdef NS_BUILD_REFCNT_LOGGING
311 virtual ~nsDisplayPlugin() {
312 MOZ_COUNT_DTOR(nsDisplayPlugin
);
316 virtual nsRect
GetBounds(nsDisplayListBuilder
* aBuilder
, bool* aSnap
) MOZ_OVERRIDE
;
317 virtual nsRegion
GetOpaqueRegion(nsDisplayListBuilder
* aBuilder
,
318 bool* aSnap
) MOZ_OVERRIDE
;
319 virtual void Paint(nsDisplayListBuilder
* aBuilder
,
320 nsRenderingContext
* aCtx
) MOZ_OVERRIDE
;
321 virtual bool ComputeVisibility(nsDisplayListBuilder
* aBuilder
,
322 nsRegion
* aVisibleRegion
) MOZ_OVERRIDE
;
324 NS_DISPLAY_DECL_NAME("Plugin", TYPE_PLUGIN
)
326 virtual already_AddRefed
<Layer
> BuildLayer(nsDisplayListBuilder
* aBuilder
,
327 LayerManager
* aManager
,
328 const ContainerLayerParameters
& aContainerParameters
) MOZ_OVERRIDE
330 return static_cast<nsObjectFrame
*>(mFrame
)->BuildLayer(aBuilder
,
333 aContainerParameters
);
336 virtual LayerState
GetLayerState(nsDisplayListBuilder
* aBuilder
,
337 LayerManager
* aManager
,
338 const ContainerLayerParameters
& aParameters
) MOZ_OVERRIDE
340 return static_cast<nsObjectFrame
*>(mFrame
)->GetLayerState(aBuilder
,
345 #endif /* nsObjectFrame_h___ */