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 :(
23 class nsRootPresContext
;
24 class nsDisplayPlugin
;
26 class PluginBackgroundSink
;
27 class nsPluginInstanceOwner
;
37 #define nsObjectFrameSuper nsFrame
39 class nsObjectFrame
: public nsObjectFrameSuper
,
40 public nsIObjectFrame
,
41 public nsIReflowCallback
{
43 typedef mozilla::LayerState LayerState
;
44 typedef mozilla::layers::Layer Layer
;
45 typedef mozilla::layers::LayerManager LayerManager
;
46 typedef mozilla::layers::ImageContainer ImageContainer
;
47 typedef mozilla::ContainerLayerParameters ContainerLayerParameters
;
49 NS_DECL_FRAMEARENA_HELPERS
51 friend nsIFrame
* NS_NewObjectFrame(nsIPresShell
* aPresShell
, nsStyleContext
* aContext
);
54 NS_DECL_QUERYFRAME_TARGET(nsObjectFrame
)
56 virtual void Init(nsIContent
* aContent
,
58 nsIFrame
* aPrevInFlow
) MOZ_OVERRIDE
;
59 virtual nscoord
GetMinWidth(nsRenderingContext
*aRenderingContext
);
60 virtual nscoord
GetPrefWidth(nsRenderingContext
*aRenderingContext
);
61 NS_IMETHOD
Reflow(nsPresContext
* aPresContext
,
62 nsHTMLReflowMetrics
& aDesiredSize
,
63 const nsHTMLReflowState
& aReflowState
,
64 nsReflowStatus
& aStatus
);
65 NS_IMETHOD
DidReflow(nsPresContext
* aPresContext
,
66 const nsHTMLReflowState
* aReflowState
,
67 nsDidReflowStatus aStatus
);
68 virtual void BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
69 const nsRect
& aDirtyRect
,
70 const nsDisplayListSet
& aLists
) MOZ_OVERRIDE
;
72 NS_IMETHOD
HandleEvent(nsPresContext
* aPresContext
,
73 mozilla::WidgetGUIEvent
* aEvent
,
74 nsEventStatus
* aEventStatus
);
76 virtual nsIAtom
* GetType() const;
78 virtual bool IsFrameOfType(uint32_t aFlags
) const
80 return nsObjectFrameSuper::IsFrameOfType(aFlags
& ~(nsIFrame::eReplaced
));
83 virtual bool NeedsView() { return true; }
86 NS_IMETHOD
GetFrameName(nsAString
& aResult
) const;
89 virtual void DestroyFrom(nsIFrame
* aDestructRoot
);
91 virtual void DidSetStyleContext(nsStyleContext
* aOldStyleContext
);
93 NS_METHOD
GetPluginInstance(nsNPAPIPluginInstance
** aPluginInstance
) MOZ_OVERRIDE
;
95 virtual void SetIsDocumentActive(bool aIsActive
) MOZ_OVERRIDE
;
97 NS_IMETHOD
GetCursor(const nsPoint
& aPoint
, nsIFrame::Cursor
& aCursor
);
99 // APIs used by nsRootPresContext to set up the widget position/size/clip
102 * Set the next widget configuration for the plugin to the desired
103 * position of the plugin's widget, on the assumption that it is not visible
104 * (clipped out or covered by opaque content).
105 * This will only be called for plugins which have been registered
106 * with the root pres context for geometry updates.
107 * If there is no widget associated with the plugin, this will have no effect.
109 void SetEmptyWidgetConfiguration()
111 mNextConfigurationBounds
= nsIntRect(0,0,0,0);
112 mNextConfigurationClipRegion
.Clear();
115 * Append the desired widget configuration to aConfigurations.
117 void GetWidgetConfiguration(nsTArray
<nsIWidget::Configuration
>* aConfigurations
)
120 if (!mWidget
->GetParent()) {
121 // Plugin widgets should not be toplevel except when they're out of the
122 // document, in which case the plugin should not be registered for
123 // geometry updates and this should not be called. But apparently we
124 // have bugs where mWidget sometimes is toplevel here. Bail out.
125 NS_ERROR("Plugin widgets registered for geometry updates should not be toplevel");
128 nsIWidget::Configuration
* configuration
= aConfigurations
->AppendElement();
129 configuration
->mChild
= mWidget
;
130 configuration
->mBounds
= mNextConfigurationBounds
;
131 configuration
->mClipRegion
= mNextConfigurationClipRegion
;
135 * Called after all widget position/size/clip regions have been changed
136 * (even if there isn't a widget for this plugin).
138 void DidSetWidgetGeometry();
140 // accessibility support
142 virtual mozilla::a11y::AccType
AccessibleType() MOZ_OVERRIDE
;
144 NS_IMETHOD
GetPluginPort(HWND
*aPort
);
149 nsresult
PrepForDrawing(nsIWidget
*aWidget
);
151 // for a given aRoot, this walks the frame tree looking for the next outFrame
152 static nsIObjectFrame
* GetNextObjectFrame(nsPresContext
* aPresContext
,
156 virtual bool ReflowFinished() MOZ_OVERRIDE
;
157 virtual void ReflowCallbackCanceled() MOZ_OVERRIDE
;
160 * Builds either an ImageLayer or a ReadbackLayer, depending on the type
161 * of aItem (TYPE_PLUGIN or TYPE_PLUGIN_READBACK respectively).
163 already_AddRefed
<Layer
> BuildLayer(nsDisplayListBuilder
* aBuilder
,
164 LayerManager
* aManager
,
165 nsDisplayItem
* aItem
,
166 const ContainerLayerParameters
& aContainerParameters
);
168 LayerState
GetLayerState(nsDisplayListBuilder
* aBuilder
,
169 LayerManager
* aManager
);
172 * Get the rectangle (relative to this frame) which it will paint. Normally
173 * the frame's content-box but may be smaller if the plugin is rendering
174 * asynchronously and has a different-sized image temporarily.
176 nsRect
GetPaintedRect(nsDisplayPlugin
* aItem
);
179 * If aContent has a nsObjectFrame, then prepare it for a DocShell swap.
180 * @see nsSubDocumentFrame::BeginSwapDocShells.
181 * There will be a call to EndSwapDocShells after we were moved to the
184 static void BeginSwapDocShells(nsIContent
* aContent
, void*);
186 * If aContent has a nsObjectFrame, then set it up after a DocShell swap.
187 * @see nsSubDocumentFrame::EndSwapDocShells.
189 static void EndSwapDocShells(nsIContent
* aContent
, void*);
191 nsIWidget
* GetWidget() MOZ_OVERRIDE
{ return mInnerView
? mWidget
: nullptr; }
194 * Adjust the plugin's idea of its size, using aSize as its new size.
195 * (aSize must be in twips)
197 void FixupWindow(const nsSize
& aSize
);
200 * Sets up the plugin window and calls SetWindow on the plugin.
202 nsresult
CallSetWindow(bool aCheckIsHidden
= true);
204 void SetInstanceOwner(nsPluginInstanceOwner
* aOwner
);
207 nsObjectFrame(nsStyleContext
* aContext
);
208 virtual ~nsObjectFrame();
210 // NOTE: This frame class does not inherit from |nsLeafFrame|, so
211 // this is not a virtual method implementation.
212 void GetDesiredSize(nsPresContext
* aPresContext
,
213 const nsHTMLReflowState
& aReflowState
,
214 nsHTMLReflowMetrics
& aDesiredSize
);
216 bool IsFocusable(int32_t *aTabIndex
= nullptr, bool aWithMouse
= false);
218 // check attributes and optionally CSS to see if we should display anything
219 bool IsHidden(bool aCheckVisibilityStyle
= true) const;
221 bool IsOpaque() const;
222 bool IsTransparentMode() const;
223 bool IsPaintedByGecko() const;
225 nsIntPoint
GetWindowOriginInPixels(bool aWindowless
);
227 static void PaintPrintPlugin(nsIFrame
* aFrame
,
228 nsRenderingContext
* aRenderingContext
,
229 const nsRect
& aDirtyRect
, nsPoint aPt
);
230 void PrintPlugin(nsRenderingContext
& aRenderingContext
,
231 const nsRect
& aDirtyRect
);
232 void PaintPlugin(nsDisplayListBuilder
* aBuilder
,
233 nsRenderingContext
& aRenderingContext
,
234 const nsRect
& aDirtyRect
, const nsRect
& aPluginRect
);
236 void NotifyPluginReflowObservers();
238 friend class nsPluginInstanceOwner
;
239 friend class nsDisplayPlugin
;
240 friend class PluginBackgroundSink
;
243 // Registers the plugin for a geometry update, and requests a geometry
244 // update. This caches the root pres context in
245 // mRootPresContextRegisteredWith, so that we can be sure we unregister
246 // from the right root prest context in UnregisterPluginForGeometryUpdates.
247 void RegisterPluginForGeometryUpdates();
249 // Unregisters the plugin for geometry updated with the root pres context
250 // stored in mRootPresContextRegisteredWith.
251 void UnregisterPluginForGeometryUpdates();
253 class PluginEventNotifier
: public nsRunnable
{
255 PluginEventNotifier(const nsString
&aEventType
) :
256 mEventType(aEventType
) {}
258 NS_IMETHOD
Run() MOZ_OVERRIDE
;
263 nsPluginInstanceOwner
* mInstanceOwner
; // WEAK
265 nsCOMPtr
<nsIWidget
> mWidget
;
266 nsIntRect mWindowlessRect
;
268 * This is owned by the ReadbackLayer for this nsObjectFrame. It is
269 * automatically cleared if the PluginBackgroundSink is destroyed.
271 PluginBackgroundSink
* mBackgroundSink
;
274 * Bounds that we should set the plugin's widget to in the next composite,
275 * for plugins with widgets. For plugins without widgets, bounds in device
276 * pixels relative to the nearest frame that's a display list reference frame.
278 nsIntRect mNextConfigurationBounds
;
280 * Clip region that we should set the plugin's widget to
281 * in the next composite. Only meaningful for plugins with widgets.
283 nsTArray
<nsIntRect
> mNextConfigurationClipRegion
;
285 bool mReflowCallbackPosted
;
287 // We keep this reference to ensure we can always unregister the
288 // plugins we register on the root PresContext.
289 // This is only non-null while we have a plugin registered for geometry
291 nsRefPtr
<nsRootPresContext
> mRootPresContextRegisteredWith
;
294 class nsDisplayPlugin
: public nsDisplayItem
{
296 nsDisplayPlugin(nsDisplayListBuilder
* aBuilder
, nsIFrame
* aFrame
)
297 : nsDisplayItem(aBuilder
, aFrame
)
299 MOZ_COUNT_CTOR(nsDisplayPlugin
);
300 aBuilder
->SetContainsPluginItem();
302 #ifdef NS_BUILD_REFCNT_LOGGING
303 virtual ~nsDisplayPlugin() {
304 MOZ_COUNT_DTOR(nsDisplayPlugin
);
308 virtual nsRect
GetBounds(nsDisplayListBuilder
* aBuilder
, bool* aSnap
) MOZ_OVERRIDE
;
309 virtual nsRegion
GetOpaqueRegion(nsDisplayListBuilder
* aBuilder
,
310 bool* aSnap
) MOZ_OVERRIDE
;
311 virtual void Paint(nsDisplayListBuilder
* aBuilder
,
312 nsRenderingContext
* aCtx
) MOZ_OVERRIDE
;
313 virtual bool ComputeVisibility(nsDisplayListBuilder
* aBuilder
,
314 nsRegion
* aVisibleRegion
,
315 const nsRect
& aAllowVisibleRegionExpansion
) MOZ_OVERRIDE
;
317 NS_DISPLAY_DECL_NAME("Plugin", TYPE_PLUGIN
)
319 virtual already_AddRefed
<Layer
> BuildLayer(nsDisplayListBuilder
* aBuilder
,
320 LayerManager
* aManager
,
321 const ContainerLayerParameters
& aContainerParameters
) MOZ_OVERRIDE
323 return static_cast<nsObjectFrame
*>(mFrame
)->BuildLayer(aBuilder
,
326 aContainerParameters
);
329 virtual LayerState
GetLayerState(nsDisplayListBuilder
* aBuilder
,
330 LayerManager
* aManager
,
331 const ContainerLayerParameters
& aParameters
) MOZ_OVERRIDE
333 return static_cast<nsObjectFrame
*>(mFrame
)->GetLayerState(aBuilder
,
338 #endif /* nsObjectFrame_h___ */