|
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/. */ |
|
5 |
|
6 /* rendering objects for replaced elements implemented by a plugin */ |
|
7 |
|
8 #ifndef nsObjectFrame_h___ |
|
9 #define nsObjectFrame_h___ |
|
10 |
|
11 #include "mozilla/Attributes.h" |
|
12 #include "nsIObjectFrame.h" |
|
13 #include "nsFrame.h" |
|
14 #include "nsRegion.h" |
|
15 #include "nsDisplayList.h" |
|
16 #include "nsIReflowCallback.h" |
|
17 |
|
18 #ifdef XP_WIN |
|
19 #include <windows.h> // For HWND :( |
|
20 #endif |
|
21 |
|
22 class nsPresContext; |
|
23 class nsRootPresContext; |
|
24 class nsDisplayPlugin; |
|
25 class nsIOSurface; |
|
26 class PluginBackgroundSink; |
|
27 class nsPluginInstanceOwner; |
|
28 |
|
29 namespace mozilla { |
|
30 namespace layers { |
|
31 class ImageContainer; |
|
32 class Layer; |
|
33 class LayerManager; |
|
34 } |
|
35 } |
|
36 |
|
37 typedef nsFrame nsObjectFrameSuper; |
|
38 |
|
39 class nsObjectFrame : public nsObjectFrameSuper, |
|
40 public nsIObjectFrame, |
|
41 public nsIReflowCallback { |
|
42 public: |
|
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; |
|
48 |
|
49 NS_DECL_FRAMEARENA_HELPERS |
|
50 |
|
51 friend nsIFrame* NS_NewObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); |
|
52 |
|
53 NS_DECL_QUERYFRAME |
|
54 NS_DECL_QUERYFRAME_TARGET(nsObjectFrame) |
|
55 |
|
56 virtual void Init(nsIContent* aContent, |
|
57 nsIFrame* aParent, |
|
58 nsIFrame* aPrevInFlow) MOZ_OVERRIDE; |
|
59 virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; |
|
60 virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; |
|
61 virtual nsresult Reflow(nsPresContext* aPresContext, |
|
62 nsHTMLReflowMetrics& aDesiredSize, |
|
63 const nsHTMLReflowState& aReflowState, |
|
64 nsReflowStatus& aStatus) MOZ_OVERRIDE; |
|
65 virtual nsresult DidReflow(nsPresContext* aPresContext, |
|
66 const nsHTMLReflowState* aReflowState, |
|
67 nsDidReflowStatus aStatus) MOZ_OVERRIDE; |
|
68 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, |
|
69 const nsRect& aDirtyRect, |
|
70 const nsDisplayListSet& aLists) MOZ_OVERRIDE; |
|
71 |
|
72 virtual nsresult HandleEvent(nsPresContext* aPresContext, |
|
73 mozilla::WidgetGUIEvent* aEvent, |
|
74 nsEventStatus* aEventStatus) MOZ_OVERRIDE; |
|
75 |
|
76 virtual nsIAtom* GetType() const MOZ_OVERRIDE; |
|
77 |
|
78 virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE |
|
79 { |
|
80 return nsObjectFrameSuper::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced)); |
|
81 } |
|
82 |
|
83 virtual bool NeedsView() MOZ_OVERRIDE { return true; } |
|
84 |
|
85 #ifdef DEBUG_FRAME_DUMP |
|
86 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; |
|
87 #endif |
|
88 |
|
89 virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; |
|
90 |
|
91 virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; |
|
92 |
|
93 NS_METHOD GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance) MOZ_OVERRIDE; |
|
94 |
|
95 virtual void SetIsDocumentActive(bool aIsActive) MOZ_OVERRIDE; |
|
96 |
|
97 virtual nsresult GetCursor(const nsPoint& aPoint, |
|
98 nsIFrame::Cursor& aCursor) MOZ_OVERRIDE; |
|
99 |
|
100 // APIs used by nsRootPresContext to set up the widget position/size/clip |
|
101 // region. |
|
102 /** |
|
103 * Set the next widget configuration for the plugin to the desired |
|
104 * position of the plugin's widget, on the assumption that it is not visible |
|
105 * (clipped out or covered by opaque content). |
|
106 * This will only be called for plugins which have been registered |
|
107 * with the root pres context for geometry updates. |
|
108 * If there is no widget associated with the plugin, this will have no effect. |
|
109 */ |
|
110 void SetEmptyWidgetConfiguration() |
|
111 { |
|
112 mNextConfigurationBounds = nsIntRect(0,0,0,0); |
|
113 mNextConfigurationClipRegion.Clear(); |
|
114 } |
|
115 /** |
|
116 * Append the desired widget configuration to aConfigurations. |
|
117 */ |
|
118 void GetWidgetConfiguration(nsTArray<nsIWidget::Configuration>* aConfigurations) |
|
119 { |
|
120 if (mWidget) { |
|
121 if (!mWidget->GetParent()) { |
|
122 // Plugin widgets should not be toplevel except when they're out of the |
|
123 // document, in which case the plugin should not be registered for |
|
124 // geometry updates and this should not be called. But apparently we |
|
125 // have bugs where mWidget sometimes is toplevel here. Bail out. |
|
126 NS_ERROR("Plugin widgets registered for geometry updates should not be toplevel"); |
|
127 return; |
|
128 } |
|
129 nsIWidget::Configuration* configuration = aConfigurations->AppendElement(); |
|
130 configuration->mChild = mWidget; |
|
131 configuration->mBounds = mNextConfigurationBounds; |
|
132 configuration->mClipRegion = mNextConfigurationClipRegion; |
|
133 } |
|
134 } |
|
135 /** |
|
136 * Called after all widget position/size/clip regions have been changed |
|
137 * (even if there isn't a widget for this plugin). |
|
138 */ |
|
139 void DidSetWidgetGeometry(); |
|
140 |
|
141 // accessibility support |
|
142 #ifdef ACCESSIBILITY |
|
143 virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE; |
|
144 #ifdef XP_WIN |
|
145 NS_IMETHOD GetPluginPort(HWND *aPort); |
|
146 #endif |
|
147 #endif |
|
148 |
|
149 //local methods |
|
150 nsresult PrepForDrawing(nsIWidget *aWidget); |
|
151 |
|
152 // for a given aRoot, this walks the frame tree looking for the next outFrame |
|
153 static nsIObjectFrame* GetNextObjectFrame(nsPresContext* aPresContext, |
|
154 nsIFrame* aRoot); |
|
155 |
|
156 // nsIReflowCallback |
|
157 virtual bool ReflowFinished() MOZ_OVERRIDE; |
|
158 virtual void ReflowCallbackCanceled() MOZ_OVERRIDE; |
|
159 |
|
160 /** |
|
161 * Builds either an ImageLayer or a ReadbackLayer, depending on the type |
|
162 * of aItem (TYPE_PLUGIN or TYPE_PLUGIN_READBACK respectively). |
|
163 */ |
|
164 already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, |
|
165 LayerManager* aManager, |
|
166 nsDisplayItem* aItem, |
|
167 const ContainerLayerParameters& aContainerParameters); |
|
168 |
|
169 LayerState GetLayerState(nsDisplayListBuilder* aBuilder, |
|
170 LayerManager* aManager); |
|
171 |
|
172 /** |
|
173 * Get the rectangle (relative to this frame) which it will paint. Normally |
|
174 * the frame's content-box but may be smaller if the plugin is rendering |
|
175 * asynchronously and has a different-sized image temporarily. |
|
176 */ |
|
177 nsRect GetPaintedRect(nsDisplayPlugin* aItem); |
|
178 |
|
179 /** |
|
180 * If aContent has a nsObjectFrame, then prepare it for a DocShell swap. |
|
181 * @see nsSubDocumentFrame::BeginSwapDocShells. |
|
182 * There will be a call to EndSwapDocShells after we were moved to the |
|
183 * new view tree. |
|
184 */ |
|
185 static void BeginSwapDocShells(nsIContent* aContent, void*); |
|
186 /** |
|
187 * If aContent has a nsObjectFrame, then set it up after a DocShell swap. |
|
188 * @see nsSubDocumentFrame::EndSwapDocShells. |
|
189 */ |
|
190 static void EndSwapDocShells(nsIContent* aContent, void*); |
|
191 |
|
192 nsIWidget* GetWidget() MOZ_OVERRIDE { return mInnerView ? mWidget : nullptr; } |
|
193 |
|
194 /** |
|
195 * Adjust the plugin's idea of its size, using aSize as its new size. |
|
196 * (aSize must be in twips) |
|
197 */ |
|
198 void FixupWindow(const nsSize& aSize); |
|
199 |
|
200 /* |
|
201 * Sets up the plugin window and calls SetWindow on the plugin. |
|
202 */ |
|
203 nsresult CallSetWindow(bool aCheckIsHidden = true); |
|
204 |
|
205 void SetInstanceOwner(nsPluginInstanceOwner* aOwner); |
|
206 |
|
207 protected: |
|
208 nsObjectFrame(nsStyleContext* aContext); |
|
209 virtual ~nsObjectFrame(); |
|
210 |
|
211 // NOTE: This frame class does not inherit from |nsLeafFrame|, so |
|
212 // this is not a virtual method implementation. |
|
213 void GetDesiredSize(nsPresContext* aPresContext, |
|
214 const nsHTMLReflowState& aReflowState, |
|
215 nsHTMLReflowMetrics& aDesiredSize); |
|
216 |
|
217 bool IsFocusable(int32_t *aTabIndex = nullptr, |
|
218 bool aWithMouse = false) MOZ_OVERRIDE; |
|
219 |
|
220 // check attributes and optionally CSS to see if we should display anything |
|
221 bool IsHidden(bool aCheckVisibilityStyle = true) const; |
|
222 |
|
223 bool IsOpaque() const; |
|
224 bool IsTransparentMode() const; |
|
225 bool IsPaintedByGecko() const; |
|
226 |
|
227 nsIntPoint GetWindowOriginInPixels(bool aWindowless); |
|
228 |
|
229 static void PaintPrintPlugin(nsIFrame* aFrame, |
|
230 nsRenderingContext* aRenderingContext, |
|
231 const nsRect& aDirtyRect, nsPoint aPt); |
|
232 void PrintPlugin(nsRenderingContext& aRenderingContext, |
|
233 const nsRect& aDirtyRect); |
|
234 void PaintPlugin(nsDisplayListBuilder* aBuilder, |
|
235 nsRenderingContext& aRenderingContext, |
|
236 const nsRect& aDirtyRect, const nsRect& aPluginRect); |
|
237 |
|
238 void NotifyPluginReflowObservers(); |
|
239 |
|
240 friend class nsPluginInstanceOwner; |
|
241 friend class nsDisplayPlugin; |
|
242 friend class PluginBackgroundSink; |
|
243 |
|
244 private: |
|
245 // Registers the plugin for a geometry update, and requests a geometry |
|
246 // update. This caches the root pres context in |
|
247 // mRootPresContextRegisteredWith, so that we can be sure we unregister |
|
248 // from the right root prest context in UnregisterPluginForGeometryUpdates. |
|
249 void RegisterPluginForGeometryUpdates(); |
|
250 |
|
251 // Unregisters the plugin for geometry updated with the root pres context |
|
252 // stored in mRootPresContextRegisteredWith. |
|
253 void UnregisterPluginForGeometryUpdates(); |
|
254 |
|
255 class PluginEventNotifier : public nsRunnable { |
|
256 public: |
|
257 PluginEventNotifier(const nsString &aEventType) : |
|
258 mEventType(aEventType) {} |
|
259 |
|
260 NS_IMETHOD Run() MOZ_OVERRIDE; |
|
261 private: |
|
262 nsString mEventType; |
|
263 }; |
|
264 |
|
265 nsPluginInstanceOwner* mInstanceOwner; // WEAK |
|
266 nsView* mInnerView; |
|
267 nsCOMPtr<nsIWidget> mWidget; |
|
268 nsIntRect mWindowlessRect; |
|
269 /** |
|
270 * This is owned by the ReadbackLayer for this nsObjectFrame. It is |
|
271 * automatically cleared if the PluginBackgroundSink is destroyed. |
|
272 */ |
|
273 PluginBackgroundSink* mBackgroundSink; |
|
274 |
|
275 /** |
|
276 * Bounds that we should set the plugin's widget to in the next composite, |
|
277 * for plugins with widgets. For plugins without widgets, bounds in device |
|
278 * pixels relative to the nearest frame that's a display list reference frame. |
|
279 */ |
|
280 nsIntRect mNextConfigurationBounds; |
|
281 /** |
|
282 * Clip region that we should set the plugin's widget to |
|
283 * in the next composite. Only meaningful for plugins with widgets. |
|
284 */ |
|
285 nsTArray<nsIntRect> mNextConfigurationClipRegion; |
|
286 |
|
287 bool mReflowCallbackPosted; |
|
288 |
|
289 // We keep this reference to ensure we can always unregister the |
|
290 // plugins we register on the root PresContext. |
|
291 // This is only non-null while we have a plugin registered for geometry |
|
292 // updates. |
|
293 nsRefPtr<nsRootPresContext> mRootPresContextRegisteredWith; |
|
294 }; |
|
295 |
|
296 class nsDisplayPlugin : public nsDisplayItem { |
|
297 public: |
|
298 nsDisplayPlugin(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) |
|
299 : nsDisplayItem(aBuilder, aFrame) |
|
300 { |
|
301 MOZ_COUNT_CTOR(nsDisplayPlugin); |
|
302 aBuilder->SetContainsPluginItem(); |
|
303 } |
|
304 #ifdef NS_BUILD_REFCNT_LOGGING |
|
305 virtual ~nsDisplayPlugin() { |
|
306 MOZ_COUNT_DTOR(nsDisplayPlugin); |
|
307 } |
|
308 #endif |
|
309 |
|
310 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; |
|
311 virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, |
|
312 bool* aSnap) MOZ_OVERRIDE; |
|
313 virtual void Paint(nsDisplayListBuilder* aBuilder, |
|
314 nsRenderingContext* aCtx) MOZ_OVERRIDE; |
|
315 virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, |
|
316 nsRegion* aVisibleRegion, |
|
317 const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; |
|
318 |
|
319 NS_DISPLAY_DECL_NAME("Plugin", TYPE_PLUGIN) |
|
320 |
|
321 virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, |
|
322 LayerManager* aManager, |
|
323 const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE |
|
324 { |
|
325 return static_cast<nsObjectFrame*>(mFrame)->BuildLayer(aBuilder, |
|
326 aManager, |
|
327 this, |
|
328 aContainerParameters); |
|
329 } |
|
330 |
|
331 virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, |
|
332 LayerManager* aManager, |
|
333 const ContainerLayerParameters& aParameters) MOZ_OVERRIDE |
|
334 { |
|
335 return static_cast<nsObjectFrame*>(mFrame)->GetLayerState(aBuilder, |
|
336 aManager); |
|
337 } |
|
338 }; |
|
339 |
|
340 #endif /* nsObjectFrame_h___ */ |