1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/generic/nsObjectFrame.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,2063 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +// vim:set ts=2 sts=2 sw=2 et cin: 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +/* rendering objects for replaced elements implemented by a plugin */ 1.11 + 1.12 +#include "nsObjectFrame.h" 1.13 + 1.14 +#include "gfx2DGlue.h" 1.15 +#include "mozilla/BasicEvents.h" 1.16 +#ifdef XP_WIN 1.17 +// This is needed for DoublePassRenderingEvent. 1.18 +#include "mozilla/plugins/PluginMessageUtils.h" 1.19 +#endif 1.20 + 1.21 +#include "nscore.h" 1.22 +#include "nsCOMPtr.h" 1.23 +#include "nsPresContext.h" 1.24 +#include "nsIPresShell.h" 1.25 +#include "nsWidgetsCID.h" 1.26 +#include "nsView.h" 1.27 +#include "nsViewManager.h" 1.28 +#include "nsString.h" 1.29 +#include "nsGkAtoms.h" 1.30 +#include "nsIPluginInstanceOwner.h" 1.31 +#include "nsNPAPIPluginInstance.h" 1.32 +#include "nsIDOMElement.h" 1.33 +#include "nsRenderingContext.h" 1.34 +#include "npapi.h" 1.35 +#include "nsIObjectLoadingContent.h" 1.36 +#include "nsContentUtils.h" 1.37 +#include "nsDisplayList.h" 1.38 +#include "nsFocusManager.h" 1.39 +#include "nsLayoutUtils.h" 1.40 +#include "nsFrameManager.h" 1.41 +#include "nsIObserverService.h" 1.42 +#include "GeckoProfiler.h" 1.43 +#include <algorithm> 1.44 + 1.45 +#include "nsIObjectFrame.h" 1.46 +#include "nsPluginNativeWindow.h" 1.47 +#include "FrameLayerBuilder.h" 1.48 + 1.49 +#include "ImageLayers.h" 1.50 +#include "nsPluginInstanceOwner.h" 1.51 + 1.52 +#ifdef XP_WIN 1.53 +#include "gfxWindowsNativeDrawing.h" 1.54 +#include "gfxWindowsSurface.h" 1.55 +#endif 1.56 + 1.57 +#include "Layers.h" 1.58 +#include "ReadbackLayer.h" 1.59 +#include "ImageContainer.h" 1.60 + 1.61 +// accessibility support 1.62 +#ifdef ACCESSIBILITY 1.63 +#include "nsAccessibilityService.h" 1.64 +#endif 1.65 + 1.66 +#ifdef MOZ_LOGGING 1.67 +#define FORCE_PR_LOG 1 /* Allow logging in the release build */ 1.68 +#endif /* MOZ_LOGGING */ 1.69 +#include "prlog.h" 1.70 + 1.71 +#ifdef XP_MACOSX 1.72 +#include "gfxQuartzNativeDrawing.h" 1.73 +#include "nsPluginUtilsOSX.h" 1.74 +#include "mozilla/gfx/QuartzSupport.h" 1.75 +#endif 1.76 + 1.77 +#ifdef MOZ_X11 1.78 +#include "mozilla/X11Util.h" 1.79 +using mozilla::DefaultXDisplay; 1.80 +#endif 1.81 + 1.82 +#ifdef XP_WIN 1.83 +#include <wtypes.h> 1.84 +#include <winuser.h> 1.85 +#endif 1.86 + 1.87 +#ifdef MOZ_WIDGET_ANDROID 1.88 +#include "AndroidBridge.h" 1.89 +#include "GLContext.h" 1.90 +#endif 1.91 + 1.92 +#ifdef CreateEvent // Thank you MS. 1.93 +#undef CreateEvent 1.94 +#endif 1.95 + 1.96 +#ifdef PR_LOGGING 1.97 +static PRLogModuleInfo * 1.98 +GetObjectFrameLog() 1.99 +{ 1.100 + static PRLogModuleInfo *sLog; 1.101 + if (!sLog) 1.102 + sLog = PR_NewLogModule("nsObjectFrame"); 1.103 + return sLog; 1.104 +} 1.105 +#endif /* PR_LOGGING */ 1.106 + 1.107 +#if defined(XP_MACOSX) && !defined(__LP64__) 1.108 + 1.109 +// The header files QuickdrawAPI.h and QDOffscreen.h are missing on OS X 10.7 1.110 +// and up (though the QuickDraw APIs defined in them are still present) -- so 1.111 +// we need to supply the relevant parts of their contents here. It's likely 1.112 +// that Apple will eventually remove the APIs themselves (probably in OS X 1.113 +// 10.8), so we need to make them weak imports, and test for their presence 1.114 +// before using them. 1.115 +extern "C" { 1.116 + #if !defined(__QUICKDRAWAPI__) 1.117 + extern void SetRect( 1.118 + Rect * r, 1.119 + short left, 1.120 + short top, 1.121 + short right, 1.122 + short bottom) 1.123 + __attribute__((weak_import)); 1.124 + #endif /* __QUICKDRAWAPI__ */ 1.125 + 1.126 + #if !defined(__QDOFFSCREEN__) 1.127 + extern QDErr NewGWorldFromPtr( 1.128 + GWorldPtr * offscreenGWorld, 1.129 + UInt32 PixelFormat, 1.130 + const Rect * boundsRect, 1.131 + CTabHandle cTable, /* can be nullptr */ 1.132 + GDHandle aGDevice, /* can be nullptr */ 1.133 + GWorldFlags flags, 1.134 + Ptr newBuffer, 1.135 + SInt32 rowBytes) 1.136 + __attribute__((weak_import)); 1.137 + extern void DisposeGWorld(GWorldPtr offscreenGWorld) 1.138 + __attribute__((weak_import)); 1.139 + #endif /* __QDOFFSCREEN__ */ 1.140 +} 1.141 + 1.142 +#endif /* #if defined(XP_MACOSX) && !defined(__LP64__) */ 1.143 + 1.144 +using namespace mozilla; 1.145 +using namespace mozilla::gfx; 1.146 +using namespace mozilla::layers; 1.147 + 1.148 +class PluginBackgroundSink : public ReadbackSink { 1.149 +public: 1.150 + PluginBackgroundSink(nsObjectFrame* aFrame, uint64_t aStartSequenceNumber) 1.151 + : mLastSequenceNumber(aStartSequenceNumber), mFrame(aFrame) {} 1.152 + ~PluginBackgroundSink() 1.153 + { 1.154 + if (mFrame) { 1.155 + mFrame->mBackgroundSink = nullptr; 1.156 + } 1.157 + } 1.158 + 1.159 + virtual void SetUnknown(uint64_t aSequenceNumber) 1.160 + { 1.161 + if (!AcceptUpdate(aSequenceNumber)) 1.162 + return; 1.163 + mFrame->mInstanceOwner->SetBackgroundUnknown(); 1.164 + } 1.165 + 1.166 + virtual already_AddRefed<gfxContext> 1.167 + BeginUpdate(const nsIntRect& aRect, uint64_t aSequenceNumber) 1.168 + { 1.169 + if (!AcceptUpdate(aSequenceNumber)) 1.170 + return nullptr; 1.171 + return mFrame->mInstanceOwner->BeginUpdateBackground(aRect); 1.172 + } 1.173 + 1.174 + virtual void EndUpdate(gfxContext* aContext, const nsIntRect& aRect) 1.175 + { 1.176 + return mFrame->mInstanceOwner->EndUpdateBackground(aContext, aRect); 1.177 + } 1.178 + 1.179 + void Destroy() { mFrame = nullptr; } 1.180 + 1.181 +protected: 1.182 + bool AcceptUpdate(uint64_t aSequenceNumber) { 1.183 + if (aSequenceNumber > mLastSequenceNumber && mFrame && 1.184 + mFrame->mInstanceOwner) { 1.185 + mLastSequenceNumber = aSequenceNumber; 1.186 + return true; 1.187 + } 1.188 + return false; 1.189 + } 1.190 + 1.191 + uint64_t mLastSequenceNumber; 1.192 + nsObjectFrame* mFrame; 1.193 +}; 1.194 + 1.195 +nsObjectFrame::nsObjectFrame(nsStyleContext* aContext) 1.196 + : nsObjectFrameSuper(aContext) 1.197 + , mReflowCallbackPosted(false) 1.198 +{ 1.199 + PR_LOG(GetObjectFrameLog(), PR_LOG_DEBUG, 1.200 + ("Created new nsObjectFrame %p\n", this)); 1.201 +} 1.202 + 1.203 +nsObjectFrame::~nsObjectFrame() 1.204 +{ 1.205 + PR_LOG(GetObjectFrameLog(), PR_LOG_DEBUG, 1.206 + ("nsObjectFrame %p deleted\n", this)); 1.207 +} 1.208 + 1.209 +NS_QUERYFRAME_HEAD(nsObjectFrame) 1.210 + NS_QUERYFRAME_ENTRY(nsObjectFrame) 1.211 + NS_QUERYFRAME_ENTRY(nsIObjectFrame) 1.212 +NS_QUERYFRAME_TAIL_INHERITING(nsObjectFrameSuper) 1.213 + 1.214 +#ifdef ACCESSIBILITY 1.215 +a11y::AccType 1.216 +nsObjectFrame::AccessibleType() 1.217 +{ 1.218 + return a11y::ePluginType; 1.219 +} 1.220 + 1.221 +#ifdef XP_WIN 1.222 +NS_IMETHODIMP nsObjectFrame::GetPluginPort(HWND *aPort) 1.223 +{ 1.224 + *aPort = (HWND) mInstanceOwner->GetPluginPortFromWidget(); 1.225 + return NS_OK; 1.226 +} 1.227 +#endif 1.228 +#endif 1.229 + 1.230 +void 1.231 +nsObjectFrame::Init(nsIContent* aContent, 1.232 + nsIFrame* aParent, 1.233 + nsIFrame* aPrevInFlow) 1.234 +{ 1.235 + PR_LOG(GetObjectFrameLog(), PR_LOG_DEBUG, 1.236 + ("Initializing nsObjectFrame %p for content %p\n", this, aContent)); 1.237 + 1.238 + nsObjectFrameSuper::Init(aContent, aParent, aPrevInFlow); 1.239 +} 1.240 + 1.241 +void 1.242 +nsObjectFrame::DestroyFrom(nsIFrame* aDestructRoot) 1.243 +{ 1.244 + if (mReflowCallbackPosted) { 1.245 + PresContext()->PresShell()->CancelReflowCallback(this); 1.246 + } 1.247 + 1.248 + // Tell content owner of the instance to disconnect its frame. 1.249 + nsCOMPtr<nsIObjectLoadingContent> objContent(do_QueryInterface(mContent)); 1.250 + NS_ASSERTION(objContent, "Why not an object loading content?"); 1.251 + 1.252 + // The content might not have a reference to the instance owner any longer in 1.253 + // the case of re-entry during instantiation or teardown, so make sure we're 1.254 + // dissociated. 1.255 + if (mInstanceOwner) { 1.256 + mInstanceOwner->SetFrame(nullptr); 1.257 + } 1.258 + objContent->HasNewFrame(nullptr); 1.259 + 1.260 + if (mBackgroundSink) { 1.261 + mBackgroundSink->Destroy(); 1.262 + } 1.263 + 1.264 + nsObjectFrameSuper::DestroyFrom(aDestructRoot); 1.265 +} 1.266 + 1.267 +/* virtual */ void 1.268 +nsObjectFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) 1.269 +{ 1.270 + if (HasView()) { 1.271 + nsView* view = GetView(); 1.272 + nsViewManager* vm = view->GetViewManager(); 1.273 + if (vm) { 1.274 + nsViewVisibility visibility = 1.275 + IsHidden() ? nsViewVisibility_kHide : nsViewVisibility_kShow; 1.276 + vm->SetViewVisibility(view, visibility); 1.277 + } 1.278 + } 1.279 + 1.280 + nsObjectFrameSuper::DidSetStyleContext(aOldStyleContext); 1.281 +} 1.282 + 1.283 +nsIAtom* 1.284 +nsObjectFrame::GetType() const 1.285 +{ 1.286 + return nsGkAtoms::objectFrame; 1.287 +} 1.288 + 1.289 +#ifdef DEBUG_FRAME_DUMP 1.290 +nsresult 1.291 +nsObjectFrame::GetFrameName(nsAString& aResult) const 1.292 +{ 1.293 + return MakeFrameName(NS_LITERAL_STRING("ObjectFrame"), aResult); 1.294 +} 1.295 +#endif 1.296 + 1.297 +nsresult 1.298 +nsObjectFrame::PrepForDrawing(nsIWidget *aWidget) 1.299 +{ 1.300 + mWidget = aWidget; 1.301 + 1.302 + nsView* view = GetView(); 1.303 + NS_ASSERTION(view, "Object frames must have views"); 1.304 + if (!view) { 1.305 + return NS_ERROR_FAILURE; 1.306 + } 1.307 + 1.308 + nsViewManager* viewMan = view->GetViewManager(); 1.309 + // mark the view as hidden since we don't know the (x,y) until Paint 1.310 + // XXX is the above comment correct? 1.311 + viewMan->SetViewVisibility(view, nsViewVisibility_kHide); 1.312 + 1.313 + //this is ugly. it was ripped off from didreflow(). MMP 1.314 + // Position and size view relative to its parent, not relative to our 1.315 + // parent frame (our parent frame may not have a view). 1.316 + 1.317 + nsView* parentWithView; 1.318 + nsPoint origin; 1.319 + nsRect r(0, 0, mRect.width, mRect.height); 1.320 + 1.321 + GetOffsetFromView(origin, &parentWithView); 1.322 + viewMan->ResizeView(view, r); 1.323 + viewMan->MoveViewTo(view, origin.x, origin.y); 1.324 + 1.325 + nsPresContext* presContext = PresContext(); 1.326 + nsRootPresContext* rpc = presContext->GetRootPresContext(); 1.327 + if (!rpc) { 1.328 + return NS_ERROR_FAILURE; 1.329 + } 1.330 + 1.331 + if (mWidget) { 1.332 + // Disallow windowed plugins in popups 1.333 + nsIFrame* rootFrame = rpc->PresShell()->FrameManager()->GetRootFrame(); 1.334 + nsIWidget* parentWidget = rootFrame->GetNearestWidget(); 1.335 + if (!parentWidget || nsLayoutUtils::GetDisplayRootFrame(this) != rootFrame) { 1.336 + return NS_ERROR_FAILURE; 1.337 + } 1.338 + 1.339 + mInnerView = viewMan->CreateView(GetContentRectRelativeToSelf(), view); 1.340 + if (!mInnerView) { 1.341 + NS_ERROR("Could not create inner view"); 1.342 + return NS_ERROR_OUT_OF_MEMORY; 1.343 + } 1.344 + viewMan->InsertChild(view, mInnerView, nullptr, true); 1.345 + 1.346 + mWidget->SetParent(parentWidget); 1.347 + mWidget->Show(true); 1.348 + mWidget->Enable(true); 1.349 + 1.350 + // Set the plugin window to have an empty clip region until we know 1.351 + // what our true position, size and clip region are. These 1.352 + // will be reset when nsRootPresContext computes our true 1.353 + // geometry. The plugin window does need to have a good size here, so 1.354 + // set the size explicitly to a reasonable guess. 1.355 + nsAutoTArray<nsIWidget::Configuration,1> configurations; 1.356 + nsIWidget::Configuration* configuration = configurations.AppendElement(); 1.357 + nscoord appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel(); 1.358 + configuration->mChild = mWidget; 1.359 + configuration->mBounds.width = NSAppUnitsToIntPixels(mRect.width, appUnitsPerDevPixel); 1.360 + configuration->mBounds.height = NSAppUnitsToIntPixels(mRect.height, appUnitsPerDevPixel); 1.361 + parentWidget->ConfigureChildren(configurations); 1.362 + 1.363 + nsRefPtr<nsDeviceContext> dx = viewMan->GetDeviceContext(); 1.364 + mInnerView->AttachWidgetEventHandler(mWidget); 1.365 + 1.366 +#ifdef XP_MACOSX 1.367 + // On Mac, we need to invalidate ourselves since even windowed 1.368 + // plugins are painted through Thebes and we need to ensure 1.369 + // the Thebes layer containing the plugin is updated. 1.370 + if (parentWidget == GetNearestWidget()) { 1.371 + InvalidateFrame(); 1.372 + } 1.373 +#endif 1.374 + 1.375 + RegisterPluginForGeometryUpdates(); 1.376 + 1.377 + // Here we set the background color for this widget because some plugins will use 1.378 + // the child window background color when painting. If it's not set, it may default to gray 1.379 + // Sometimes, a frame doesn't have a background color or is transparent. In this 1.380 + // case, walk up the frame tree until we do find a frame with a background color 1.381 + for (nsIFrame* frame = this; frame; frame = frame->GetParent()) { 1.382 + nscolor bgcolor = 1.383 + frame->GetVisitedDependentColor(eCSSProperty_background_color); 1.384 + if (NS_GET_A(bgcolor) > 0) { // make sure we got an actual color 1.385 + mWidget->SetBackgroundColor(bgcolor); 1.386 + break; 1.387 + } 1.388 + } 1.389 + } else { 1.390 + // Changing to windowless mode changes the NPWindow geometry. 1.391 + FixupWindow(GetContentRectRelativeToSelf().Size()); 1.392 + 1.393 +#ifndef XP_MACOSX 1.394 + RegisterPluginForGeometryUpdates(); 1.395 +#endif 1.396 + } 1.397 + 1.398 + if (!IsHidden()) { 1.399 + viewMan->SetViewVisibility(view, nsViewVisibility_kShow); 1.400 + } 1.401 + 1.402 +#ifdef ACCESSIBILITY 1.403 + nsAccessibilityService* accService = nsIPresShell::AccService(); 1.404 + if (accService) { 1.405 + accService->RecreateAccessible(PresContext()->PresShell(), mContent); 1.406 + } 1.407 +#endif 1.408 + 1.409 + return NS_OK; 1.410 +} 1.411 + 1.412 +#define EMBED_DEF_WIDTH 240 1.413 +#define EMBED_DEF_HEIGHT 200 1.414 + 1.415 +/* virtual */ nscoord 1.416 +nsObjectFrame::GetMinWidth(nsRenderingContext *aRenderingContext) 1.417 +{ 1.418 + nscoord result = 0; 1.419 + 1.420 + if (!IsHidden(false)) { 1.421 + nsIAtom *atom = mContent->Tag(); 1.422 + if (atom == nsGkAtoms::applet || atom == nsGkAtoms::embed) { 1.423 + result = nsPresContext::CSSPixelsToAppUnits(EMBED_DEF_WIDTH); 1.424 + } 1.425 + } 1.426 + 1.427 + DISPLAY_MIN_WIDTH(this, result); 1.428 + return result; 1.429 +} 1.430 + 1.431 +/* virtual */ nscoord 1.432 +nsObjectFrame::GetPrefWidth(nsRenderingContext *aRenderingContext) 1.433 +{ 1.434 + return nsObjectFrame::GetMinWidth(aRenderingContext); 1.435 +} 1.436 + 1.437 +void 1.438 +nsObjectFrame::GetDesiredSize(nsPresContext* aPresContext, 1.439 + const nsHTMLReflowState& aReflowState, 1.440 + nsHTMLReflowMetrics& aMetrics) 1.441 +{ 1.442 + // By default, we have no area 1.443 + aMetrics.Width() = 0; 1.444 + aMetrics.Height() = 0; 1.445 + 1.446 + if (IsHidden(false)) { 1.447 + return; 1.448 + } 1.449 + 1.450 + aMetrics.Width() = aReflowState.ComputedWidth(); 1.451 + aMetrics.Height() = aReflowState.ComputedHeight(); 1.452 + 1.453 + // for EMBED and APPLET, default to 240x200 for compatibility 1.454 + nsIAtom *atom = mContent->Tag(); 1.455 + if (atom == nsGkAtoms::applet || atom == nsGkAtoms::embed) { 1.456 + if (aMetrics.Width() == NS_UNCONSTRAINEDSIZE) { 1.457 + aMetrics.Width() = clamped(nsPresContext::CSSPixelsToAppUnits(EMBED_DEF_WIDTH), 1.458 + aReflowState.ComputedMinWidth(), 1.459 + aReflowState.ComputedMaxWidth()); 1.460 + } 1.461 + if (aMetrics.Height() == NS_UNCONSTRAINEDSIZE) { 1.462 + aMetrics.Height() = clamped(nsPresContext::CSSPixelsToAppUnits(EMBED_DEF_HEIGHT), 1.463 + aReflowState.ComputedMinHeight(), 1.464 + aReflowState.ComputedMaxHeight()); 1.465 + } 1.466 + 1.467 +#if defined(MOZ_WIDGET_GTK) 1.468 + // We need to make sure that the size of the object frame does not 1.469 + // exceed the maximum size of X coordinates. See bug #225357 for 1.470 + // more information. In theory Gtk2 can handle large coordinates, 1.471 + // but underlying plugins can't. 1.472 + aMetrics.Height() = std::min(aPresContext->DevPixelsToAppUnits(INT16_MAX), aMetrics.Height()); 1.473 + aMetrics.Width() = std::min(aPresContext->DevPixelsToAppUnits(INT16_MAX), aMetrics.Width()); 1.474 +#endif 1.475 + } 1.476 + 1.477 + // At this point, the width has an unconstrained value only if we have 1.478 + // nothing to go on (no width set, no information from the plugin, nothing). 1.479 + // Make up a number. 1.480 + if (aMetrics.Width() == NS_UNCONSTRAINEDSIZE) { 1.481 + aMetrics.Width() = 1.482 + (aReflowState.ComputedMinWidth() != NS_UNCONSTRAINEDSIZE) ? 1.483 + aReflowState.ComputedMinWidth() : 0; 1.484 + } 1.485 + 1.486 + // At this point, the height has an unconstrained value only in two cases: 1.487 + // a) We are in standards mode with percent heights and parent is auto-height 1.488 + // b) We have no height information at all. 1.489 + // In either case, we have to make up a number. 1.490 + if (aMetrics.Height() == NS_UNCONSTRAINEDSIZE) { 1.491 + aMetrics.Height() = 1.492 + (aReflowState.ComputedMinHeight() != NS_UNCONSTRAINEDSIZE) ? 1.493 + aReflowState.ComputedMinHeight() : 0; 1.494 + } 1.495 + 1.496 + // XXXbz don't add in the border and padding, because we screw up our 1.497 + // plugin's size and positioning if we do... Eventually we _do_ want to 1.498 + // paint borders, though! At that point, we will need to adjust the desired 1.499 + // size either here or in Reflow.... Further, we will need to fix Paint() to 1.500 + // call the superclass in all cases. 1.501 +} 1.502 + 1.503 +nsresult 1.504 +nsObjectFrame::Reflow(nsPresContext* aPresContext, 1.505 + nsHTMLReflowMetrics& aMetrics, 1.506 + const nsHTMLReflowState& aReflowState, 1.507 + nsReflowStatus& aStatus) 1.508 +{ 1.509 + DO_GLOBAL_REFLOW_COUNT("nsObjectFrame"); 1.510 + DISPLAY_REFLOW(aPresContext, this, aReflowState, aMetrics, aStatus); 1.511 + 1.512 + // Get our desired size 1.513 + GetDesiredSize(aPresContext, aReflowState, aMetrics); 1.514 + aMetrics.SetOverflowAreasToDesiredBounds(); 1.515 + FinishAndStoreOverflow(&aMetrics); 1.516 + 1.517 + // delay plugin instantiation until all children have 1.518 + // arrived. Otherwise there may be PARAMs or other stuff that the 1.519 + // plugin needs to see that haven't arrived yet. 1.520 + if (!GetContent()->IsDoneAddingChildren()) { 1.521 + aStatus = NS_FRAME_COMPLETE; 1.522 + return NS_OK; 1.523 + } 1.524 + 1.525 + // if we are printing or print previewing, bail for now 1.526 + if (aPresContext->Medium() == nsGkAtoms::print) { 1.527 + aStatus = NS_FRAME_COMPLETE; 1.528 + return NS_OK; 1.529 + } 1.530 + 1.531 + nsRect r(0, 0, aMetrics.Width(), aMetrics.Height()); 1.532 + r.Deflate(aReflowState.ComputedPhysicalBorderPadding()); 1.533 + 1.534 + if (mInnerView) { 1.535 + nsViewManager* vm = mInnerView->GetViewManager(); 1.536 + vm->MoveViewTo(mInnerView, r.x, r.y); 1.537 + vm->ResizeView(mInnerView, nsRect(nsPoint(0, 0), r.Size()), true); 1.538 + } 1.539 + 1.540 + FixupWindow(r.Size()); 1.541 + if (!mReflowCallbackPosted) { 1.542 + mReflowCallbackPosted = true; 1.543 + aPresContext->PresShell()->PostReflowCallback(this); 1.544 + } 1.545 + 1.546 + aStatus = NS_FRAME_COMPLETE; 1.547 + 1.548 + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); 1.549 + return NS_OK; 1.550 +} 1.551 + 1.552 +///////////// nsIReflowCallback /////////////// 1.553 + 1.554 +bool 1.555 +nsObjectFrame::ReflowFinished() 1.556 +{ 1.557 + mReflowCallbackPosted = false; 1.558 + CallSetWindow(); 1.559 + return true; 1.560 +} 1.561 + 1.562 +void 1.563 +nsObjectFrame::ReflowCallbackCanceled() 1.564 +{ 1.565 + mReflowCallbackPosted = false; 1.566 +} 1.567 + 1.568 +void 1.569 +nsObjectFrame::FixupWindow(const nsSize& aSize) 1.570 +{ 1.571 + nsPresContext* presContext = PresContext(); 1.572 + 1.573 + if (!mInstanceOwner) 1.574 + return; 1.575 + 1.576 + NPWindow *window; 1.577 + mInstanceOwner->GetWindow(window); 1.578 + 1.579 + NS_ENSURE_TRUE_VOID(window); 1.580 + 1.581 +#ifdef XP_MACOSX 1.582 + nsWeakFrame weakFrame(this); 1.583 + mInstanceOwner->FixUpPluginWindow(nsPluginInstanceOwner::ePluginPaintDisable); 1.584 + if (!weakFrame.IsAlive()) { 1.585 + return; 1.586 + } 1.587 +#endif 1.588 + 1.589 + bool windowless = (window->type == NPWindowTypeDrawable); 1.590 + 1.591 + nsIntPoint origin = GetWindowOriginInPixels(windowless); 1.592 + 1.593 + // window must be in "display pixels" 1.594 + double scaleFactor = 1.0; 1.595 + if (NS_FAILED(mInstanceOwner->GetContentsScaleFactor(&scaleFactor))) { 1.596 + scaleFactor = 1.0; 1.597 + } 1.598 + int intScaleFactor = ceil(scaleFactor); 1.599 + window->x = origin.x / intScaleFactor; 1.600 + window->y = origin.y / intScaleFactor; 1.601 + window->width = presContext->AppUnitsToDevPixels(aSize.width) / intScaleFactor; 1.602 + window->height = presContext->AppUnitsToDevPixels(aSize.height) / intScaleFactor; 1.603 + 1.604 + // on the Mac we need to set the clipRect to { 0, 0, 0, 0 } for now. This will keep 1.605 + // us from drawing on screen until the widget is properly positioned, which will not 1.606 + // happen until we have finished the reflow process. 1.607 +#ifdef XP_MACOSX 1.608 + window->clipRect.top = 0; 1.609 + window->clipRect.left = 0; 1.610 + window->clipRect.bottom = 0; 1.611 + window->clipRect.right = 0; 1.612 +#else 1.613 + mInstanceOwner->UpdateWindowPositionAndClipRect(false); 1.614 +#endif 1.615 + 1.616 + NotifyPluginReflowObservers(); 1.617 +} 1.618 + 1.619 +nsresult 1.620 +nsObjectFrame::CallSetWindow(bool aCheckIsHidden) 1.621 +{ 1.622 + NPWindow *win = nullptr; 1.623 + 1.624 + nsresult rv = NS_ERROR_FAILURE; 1.625 + nsRefPtr<nsNPAPIPluginInstance> pi; 1.626 + if (!mInstanceOwner || 1.627 + NS_FAILED(rv = mInstanceOwner->GetInstance(getter_AddRefs(pi))) || 1.628 + !pi || 1.629 + NS_FAILED(rv = mInstanceOwner->GetWindow(win)) || 1.630 + !win) 1.631 + return rv; 1.632 + 1.633 + nsPluginNativeWindow *window = (nsPluginNativeWindow *)win; 1.634 +#ifdef XP_MACOSX 1.635 + nsWeakFrame weakFrame(this); 1.636 + mInstanceOwner->FixUpPluginWindow(nsPluginInstanceOwner::ePluginPaintDisable); 1.637 + if (!weakFrame.IsAlive()) { 1.638 + return NS_ERROR_NOT_AVAILABLE; 1.639 + } 1.640 +#endif 1.641 + 1.642 + if (aCheckIsHidden && IsHidden()) 1.643 + return NS_ERROR_FAILURE; 1.644 + 1.645 + // refresh the plugin port as well 1.646 + window->window = mInstanceOwner->GetPluginPortFromWidget(); 1.647 + 1.648 + // Adjust plugin dimensions according to pixel snap results 1.649 + // and reduce amount of SetWindow calls 1.650 + nsPresContext* presContext = PresContext(); 1.651 + nsRootPresContext* rootPC = presContext->GetRootPresContext(); 1.652 + if (!rootPC) 1.653 + return NS_ERROR_FAILURE; 1.654 + int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel(); 1.655 + nsIFrame* rootFrame = rootPC->PresShell()->FrameManager()->GetRootFrame(); 1.656 + nsRect bounds = GetContentRectRelativeToSelf() + GetOffsetToCrossDoc(rootFrame); 1.657 + nsIntRect intBounds = bounds.ToNearestPixels(appUnitsPerDevPixel); 1.658 + 1.659 + // window must be in "display pixels" 1.660 + double scaleFactor = 1.0; 1.661 + if (NS_FAILED(mInstanceOwner->GetContentsScaleFactor(&scaleFactor))) { 1.662 + scaleFactor = 1.0; 1.663 + } 1.664 + size_t intScaleFactor = ceil(scaleFactor); 1.665 + window->x = intBounds.x / intScaleFactor; 1.666 + window->y = intBounds.y / intScaleFactor; 1.667 + window->width = intBounds.width / intScaleFactor; 1.668 + window->height = intBounds.height / intScaleFactor; 1.669 + 1.670 + // Calling SetWindow might destroy this frame. We need to use the instance 1.671 + // owner to clean up so hold a ref. 1.672 + nsRefPtr<nsPluginInstanceOwner> instanceOwnerRef(mInstanceOwner); 1.673 + 1.674 + // This will call pi->SetWindow and take care of window subclassing 1.675 + // if needed, see bug 132759. Calling SetWindow can destroy this frame 1.676 + // so check for that before doing anything else with this frame's memory. 1.677 + if (mInstanceOwner->UseAsyncRendering()) { 1.678 + rv = pi->AsyncSetWindow(window); 1.679 + } 1.680 + else { 1.681 + rv = window->CallSetWindow(pi); 1.682 + } 1.683 + 1.684 + instanceOwnerRef->ReleasePluginPort(window->window); 1.685 + 1.686 + return rv; 1.687 +} 1.688 + 1.689 +void 1.690 +nsObjectFrame::RegisterPluginForGeometryUpdates() 1.691 +{ 1.692 + nsRootPresContext* rpc = PresContext()->GetRootPresContext(); 1.693 + NS_ASSERTION(rpc, "We should have a root pres context!"); 1.694 + if (mRootPresContextRegisteredWith == rpc || !rpc) { 1.695 + // Already registered with current root pres context, 1.696 + // or null root pres context... 1.697 + return; 1.698 + } 1.699 + if (mRootPresContextRegisteredWith && mRootPresContextRegisteredWith != rpc) { 1.700 + // Registered to some other root pres context. Unregister, and 1.701 + // re-register with our current one... 1.702 + UnregisterPluginForGeometryUpdates(); 1.703 + } 1.704 + mRootPresContextRegisteredWith = rpc; 1.705 + mRootPresContextRegisteredWith->RegisterPluginForGeometryUpdates(mContent); 1.706 +} 1.707 + 1.708 +void 1.709 +nsObjectFrame::UnregisterPluginForGeometryUpdates() 1.710 +{ 1.711 + if (!mRootPresContextRegisteredWith) { 1.712 + // Not registered... 1.713 + return; 1.714 + } 1.715 + mRootPresContextRegisteredWith->UnregisterPluginForGeometryUpdates(mContent); 1.716 + mRootPresContextRegisteredWith = nullptr; 1.717 +} 1.718 + 1.719 +void 1.720 +nsObjectFrame::SetInstanceOwner(nsPluginInstanceOwner* aOwner) 1.721 +{ 1.722 + // The ownership model here is historically fuzzy. This should only be called 1.723 + // by nsPluginInstanceOwner when it is given a new frame, and 1.724 + // nsObjectLoadingContent should be arbitrating frame-ownership via its 1.725 + // HasNewFrame callback. 1.726 + mInstanceOwner = aOwner; 1.727 + if (mInstanceOwner) { 1.728 + return; 1.729 + } 1.730 + UnregisterPluginForGeometryUpdates(); 1.731 + if (mWidget && mInnerView) { 1.732 + mInnerView->DetachWidgetEventHandler(mWidget); 1.733 + // Make sure the plugin is hidden in case an update of plugin geometry 1.734 + // hasn't happened since this plugin became hidden. 1.735 + nsIWidget* parent = mWidget->GetParent(); 1.736 + if (parent) { 1.737 + nsTArray<nsIWidget::Configuration> configurations; 1.738 + nsIWidget::Configuration* configuration = configurations.AppendElement(); 1.739 + configuration->mChild = mWidget; 1.740 + parent->ConfigureChildren(configurations); 1.741 + 1.742 + mWidget->Show(false); 1.743 + mWidget->Enable(false); 1.744 + mWidget->SetParent(nullptr); 1.745 + } 1.746 + } 1.747 +} 1.748 + 1.749 +bool 1.750 +nsObjectFrame::IsFocusable(int32_t *aTabIndex, bool aWithMouse) 1.751 +{ 1.752 + if (aTabIndex) 1.753 + *aTabIndex = -1; 1.754 + return nsObjectFrameSuper::IsFocusable(aTabIndex, aWithMouse); 1.755 +} 1.756 + 1.757 +bool 1.758 +nsObjectFrame::IsHidden(bool aCheckVisibilityStyle) const 1.759 +{ 1.760 + if (aCheckVisibilityStyle) { 1.761 + if (!StyleVisibility()->IsVisibleOrCollapsed()) 1.762 + return true; 1.763 + } 1.764 + 1.765 + // only <embed> tags support the HIDDEN attribute 1.766 + if (mContent->Tag() == nsGkAtoms::embed) { 1.767 + // Yes, these are really the kooky ways that you could tell 4.x 1.768 + // not to hide the <embed> once you'd put the 'hidden' attribute 1.769 + // on the tag... 1.770 + 1.771 + // HIDDEN w/ no attributes gets translated as we are hidden for 1.772 + // compatibility w/ 4.x and IE so we don't create a non-painting 1.773 + // widget in layout. See bug 188959. 1.774 + nsAutoString hidden; 1.775 + if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::hidden, hidden) && 1.776 + (hidden.IsEmpty() || 1.777 + (!hidden.LowerCaseEqualsLiteral("false") && 1.778 + !hidden.LowerCaseEqualsLiteral("no") && 1.779 + !hidden.LowerCaseEqualsLiteral("off")))) { 1.780 + return true; 1.781 + } 1.782 + } 1.783 + 1.784 + return false; 1.785 +} 1.786 + 1.787 +nsIntPoint nsObjectFrame::GetWindowOriginInPixels(bool aWindowless) 1.788 +{ 1.789 + nsView * parentWithView; 1.790 + nsPoint origin(0,0); 1.791 + 1.792 + GetOffsetFromView(origin, &parentWithView); 1.793 + 1.794 + // if it's windowless, let's make sure we have our origin set right 1.795 + // it may need to be corrected, like after scrolling 1.796 + if (aWindowless && parentWithView) { 1.797 + nsPoint offsetToWidget; 1.798 + parentWithView->GetNearestWidget(&offsetToWidget); 1.799 + origin += offsetToWidget; 1.800 + } 1.801 + origin += GetContentRectRelativeToSelf().TopLeft(); 1.802 + 1.803 + return nsIntPoint(PresContext()->AppUnitsToDevPixels(origin.x), 1.804 + PresContext()->AppUnitsToDevPixels(origin.y)); 1.805 +} 1.806 + 1.807 +nsresult 1.808 +nsObjectFrame::DidReflow(nsPresContext* aPresContext, 1.809 + const nsHTMLReflowState* aReflowState, 1.810 + nsDidReflowStatus aStatus) 1.811 +{ 1.812 + // Do this check before calling the superclass, as that clears 1.813 + // NS_FRAME_FIRST_REFLOW 1.814 + if (aStatus == nsDidReflowStatus::FINISHED && 1.815 + (GetStateBits() & NS_FRAME_FIRST_REFLOW)) { 1.816 + nsCOMPtr<nsIObjectLoadingContent> objContent(do_QueryInterface(mContent)); 1.817 + NS_ASSERTION(objContent, "Why not an object loading content?"); 1.818 + objContent->HasNewFrame(this); 1.819 + } 1.820 + 1.821 + nsresult rv = nsObjectFrameSuper::DidReflow(aPresContext, aReflowState, aStatus); 1.822 + 1.823 + // The view is created hidden; once we have reflowed it and it has been 1.824 + // positioned then we show it. 1.825 + if (aStatus != nsDidReflowStatus::FINISHED) 1.826 + return rv; 1.827 + 1.828 + if (HasView()) { 1.829 + nsView* view = GetView(); 1.830 + nsViewManager* vm = view->GetViewManager(); 1.831 + if (vm) 1.832 + vm->SetViewVisibility(view, IsHidden() ? nsViewVisibility_kHide : nsViewVisibility_kShow); 1.833 + } 1.834 + 1.835 + return rv; 1.836 +} 1.837 + 1.838 +/* static */ void 1.839 +nsObjectFrame::PaintPrintPlugin(nsIFrame* aFrame, nsRenderingContext* aCtx, 1.840 + const nsRect& aDirtyRect, nsPoint aPt) 1.841 +{ 1.842 + nsPoint pt = aPt + aFrame->GetContentRectRelativeToSelf().TopLeft(); 1.843 + nsRenderingContext::AutoPushTranslation translate(aCtx, pt); 1.844 + // FIXME - Bug 385435: Doesn't aDirtyRect need translating too? 1.845 + static_cast<nsObjectFrame*>(aFrame)->PrintPlugin(*aCtx, aDirtyRect); 1.846 +} 1.847 + 1.848 +class nsDisplayPluginReadback : public nsDisplayItem { 1.849 +public: 1.850 + nsDisplayPluginReadback(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) 1.851 + : nsDisplayItem(aBuilder, aFrame) 1.852 + { 1.853 + MOZ_COUNT_CTOR(nsDisplayPluginReadback); 1.854 + } 1.855 +#ifdef NS_BUILD_REFCNT_LOGGING 1.856 + virtual ~nsDisplayPluginReadback() { 1.857 + MOZ_COUNT_DTOR(nsDisplayPluginReadback); 1.858 + } 1.859 +#endif 1.860 + 1.861 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, 1.862 + bool* aSnap) MOZ_OVERRIDE; 1.863 + virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.864 + nsRegion* aVisibleRegion, 1.865 + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; 1.866 + 1.867 + NS_DISPLAY_DECL_NAME("PluginReadback", TYPE_PLUGIN_READBACK) 1.868 + 1.869 + virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, 1.870 + LayerManager* aManager, 1.871 + const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE 1.872 + { 1.873 + return static_cast<nsObjectFrame*>(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters); 1.874 + } 1.875 + 1.876 + virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, 1.877 + LayerManager* aManager, 1.878 + const ContainerLayerParameters& aParameters) MOZ_OVERRIDE 1.879 + { 1.880 + return LAYER_ACTIVE; 1.881 + } 1.882 +}; 1.883 + 1.884 +static nsRect 1.885 +GetDisplayItemBounds(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem, nsIFrame* aFrame) 1.886 +{ 1.887 + // XXX For slightly more accurate region computations we should pixel-snap this 1.888 + return aFrame->GetContentRectRelativeToSelf() + aItem->ToReferenceFrame(); 1.889 +} 1.890 + 1.891 +nsRect 1.892 +nsDisplayPluginReadback::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) 1.893 +{ 1.894 + *aSnap = false; 1.895 + return GetDisplayItemBounds(aBuilder, this, mFrame); 1.896 +} 1.897 + 1.898 +bool 1.899 +nsDisplayPluginReadback::ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.900 + nsRegion* aVisibleRegion, 1.901 + const nsRect& aAllowVisibleRegionExpansion) 1.902 +{ 1.903 + if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion, 1.904 + aAllowVisibleRegionExpansion)) 1.905 + return false; 1.906 + 1.907 + nsRect expand; 1.908 + bool snap; 1.909 + expand.IntersectRect(aAllowVisibleRegionExpansion, GetBounds(aBuilder, &snap)); 1.910 + // *Add* our bounds to the visible region so that stuff underneath us is 1.911 + // likely to be made visible, so we can use it for a background! This is 1.912 + // a bit crazy since we normally only subtract from the visible region. 1.913 + aVisibleRegion->Or(*aVisibleRegion, expand); 1.914 + return true; 1.915 +} 1.916 + 1.917 +#ifdef MOZ_WIDGET_ANDROID 1.918 + 1.919 +class nsDisplayPluginVideo : public nsDisplayItem { 1.920 +public: 1.921 + nsDisplayPluginVideo(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsNPAPIPluginInstance::VideoInfo* aVideoInfo) 1.922 + : nsDisplayItem(aBuilder, aFrame), mVideoInfo(aVideoInfo) 1.923 + { 1.924 + MOZ_COUNT_CTOR(nsDisplayPluginVideo); 1.925 + } 1.926 +#ifdef NS_BUILD_REFCNT_LOGGING 1.927 + virtual ~nsDisplayPluginVideo() { 1.928 + MOZ_COUNT_DTOR(nsDisplayPluginVideo); 1.929 + } 1.930 +#endif 1.931 + 1.932 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, 1.933 + bool* aSnap) MOZ_OVERRIDE; 1.934 + virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.935 + nsRegion* aVisibleRegion, 1.936 + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; 1.937 + 1.938 + NS_DISPLAY_DECL_NAME("PluginVideo", TYPE_PLUGIN_VIDEO) 1.939 + 1.940 + virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, 1.941 + LayerManager* aManager, 1.942 + const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE 1.943 + { 1.944 + return static_cast<nsObjectFrame*>(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters); 1.945 + } 1.946 + 1.947 + virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, 1.948 + LayerManager* aManager, 1.949 + const ContainerLayerParameters& aParameters) MOZ_OVERRIDE 1.950 + { 1.951 + return LAYER_ACTIVE; 1.952 + } 1.953 + 1.954 + nsNPAPIPluginInstance::VideoInfo* VideoInfo() { return mVideoInfo; } 1.955 + 1.956 +private: 1.957 + nsNPAPIPluginInstance::VideoInfo* mVideoInfo; 1.958 +}; 1.959 + 1.960 +nsRect 1.961 +nsDisplayPluginVideo::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) 1.962 +{ 1.963 + *aSnap = false; 1.964 + return GetDisplayItemBounds(aBuilder, this, mFrame); 1.965 +} 1.966 + 1.967 +bool 1.968 +nsDisplayPluginVideo::ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.969 + nsRegion* aVisibleRegion, 1.970 + const nsRect& aAllowVisibleRegionExpansion) 1.971 +{ 1.972 + return nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion, 1.973 + aAllowVisibleRegionExpansion); 1.974 +} 1.975 + 1.976 +#endif 1.977 + 1.978 +nsRect 1.979 +nsDisplayPlugin::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) 1.980 +{ 1.981 + *aSnap = true; 1.982 + return GetDisplayItemBounds(aBuilder, this, mFrame); 1.983 +} 1.984 + 1.985 +void 1.986 +nsDisplayPlugin::Paint(nsDisplayListBuilder* aBuilder, 1.987 + nsRenderingContext* aCtx) 1.988 +{ 1.989 + nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame); 1.990 + bool snap; 1.991 + f->PaintPlugin(aBuilder, *aCtx, mVisibleRect, GetBounds(aBuilder, &snap)); 1.992 +} 1.993 + 1.994 +bool 1.995 +nsDisplayPlugin::ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.996 + nsRegion* aVisibleRegion, 1.997 + const nsRect& aAllowVisibleRegionExpansion) 1.998 +{ 1.999 + if (aBuilder->IsForPluginGeometry()) { 1.1000 + nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame); 1.1001 + if (!aBuilder->IsInTransform() || f->IsPaintedByGecko()) { 1.1002 + // Since transforms induce reference frames, we don't need to worry 1.1003 + // about this method fluffing out due to non-rectilinear transforms. 1.1004 + nsRect rAncestor = nsLayoutUtils::TransformFrameRectToAncestor(f, 1.1005 + f->GetContentRectRelativeToSelf(), ReferenceFrame()); 1.1006 + nscoord appUnitsPerDevPixel = 1.1007 + ReferenceFrame()->PresContext()->AppUnitsPerDevPixel(); 1.1008 + f->mNextConfigurationBounds = rAncestor.ToNearestPixels(appUnitsPerDevPixel); 1.1009 + 1.1010 + nsRegion visibleRegion; 1.1011 + visibleRegion.And(*aVisibleRegion, GetClippedBounds(aBuilder)); 1.1012 + // Make visibleRegion relative to f 1.1013 + visibleRegion.MoveBy(-ToReferenceFrame()); 1.1014 + 1.1015 + f->mNextConfigurationClipRegion.Clear(); 1.1016 + nsRegionRectIterator iter(visibleRegion); 1.1017 + for (const nsRect* r = iter.Next(); r; r = iter.Next()) { 1.1018 + nsRect rAncestor = 1.1019 + nsLayoutUtils::TransformFrameRectToAncestor(f, *r, ReferenceFrame()); 1.1020 + nsIntRect rPixels = rAncestor.ToNearestPixels(appUnitsPerDevPixel) 1.1021 + - f->mNextConfigurationBounds.TopLeft(); 1.1022 + if (!rPixels.IsEmpty()) { 1.1023 + f->mNextConfigurationClipRegion.AppendElement(rPixels); 1.1024 + } 1.1025 + } 1.1026 + } 1.1027 + 1.1028 + if (f->mInnerView) { 1.1029 + // This should produce basically the same rectangle (but not relative 1.1030 + // to the root frame). We only call this here for the side-effect of 1.1031 + // setting mViewToWidgetOffset on the view. 1.1032 + f->mInnerView->CalcWidgetBounds(eWindowType_plugin); 1.1033 + } 1.1034 + } 1.1035 + 1.1036 + return nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion, 1.1037 + aAllowVisibleRegionExpansion); 1.1038 +} 1.1039 + 1.1040 +nsRegion 1.1041 +nsDisplayPlugin::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, 1.1042 + bool* aSnap) 1.1043 +{ 1.1044 + *aSnap = false; 1.1045 + nsRegion result; 1.1046 + nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame); 1.1047 + if (!aBuilder->IsForPluginGeometry()) { 1.1048 + nsIWidget* widget = f->GetWidget(); 1.1049 + if (widget) { 1.1050 + // Be conservative and treat plugins with widgets as not opaque, 1.1051 + // because that's simple and we might need the content under the widget 1.1052 + // if the widget is unexpectedly clipped away. (As can happen when 1.1053 + // chrome content over a plugin forces us to clip out the plugin for 1.1054 + // security reasons.) 1.1055 + // We shouldn't be repainting the content under plugins much anyway 1.1056 + // since there generally shouldn't be anything to invalidate or paint 1.1057 + // in ThebesLayers there. 1.1058 + return result; 1.1059 + } 1.1060 + } 1.1061 + 1.1062 + if (f->IsOpaque()) { 1.1063 + nsRect bounds = GetBounds(aBuilder, aSnap); 1.1064 + if (aBuilder->IsForPluginGeometry() || 1.1065 + (f->GetPaintedRect(this) + ToReferenceFrame()).Contains(bounds)) { 1.1066 + // We can treat this as opaque 1.1067 + result = bounds; 1.1068 + } 1.1069 + } 1.1070 + 1.1071 + return result; 1.1072 +} 1.1073 + 1.1074 +nsresult 1.1075 +nsObjectFrame::PluginEventNotifier::Run() { 1.1076 + nsCOMPtr<nsIObserverService> obsSvc = 1.1077 + mozilla::services::GetObserverService(); 1.1078 + obsSvc->NotifyObservers(nullptr, "plugin-changed-event", mEventType.get()); 1.1079 + return NS_OK; 1.1080 +} 1.1081 + 1.1082 +void 1.1083 +nsObjectFrame::NotifyPluginReflowObservers() 1.1084 +{ 1.1085 + nsContentUtils::AddScriptRunner(new PluginEventNotifier(NS_LITERAL_STRING("reflow"))); 1.1086 +} 1.1087 + 1.1088 +void 1.1089 +nsObjectFrame::DidSetWidgetGeometry() 1.1090 +{ 1.1091 +#if defined(XP_MACOSX) 1.1092 + if (mInstanceOwner) { 1.1093 + mInstanceOwner->FixUpPluginWindow(nsPluginInstanceOwner::ePluginPaintEnable); 1.1094 + } 1.1095 +#else 1.1096 + if (!mWidget && mInstanceOwner) { 1.1097 + // UpdateWindowVisibility will notify the plugin of position changes 1.1098 + // by updating the NPWindow and calling NPP_SetWindow/AsyncSetWindow. 1.1099 + // We treat windowless plugins inside popups as always visible, since 1.1100 + // plugins inside popups don't get valid mNextConfigurationBounds 1.1101 + // set up. 1.1102 + mInstanceOwner->UpdateWindowVisibility( 1.1103 + nsLayoutUtils::IsPopup(nsLayoutUtils::GetDisplayRootFrame(this)) || 1.1104 + !mNextConfigurationBounds.IsEmpty()); 1.1105 + } 1.1106 +#endif 1.1107 +} 1.1108 + 1.1109 +bool 1.1110 +nsObjectFrame::IsOpaque() const 1.1111 +{ 1.1112 +#if defined(XP_MACOSX) 1.1113 + // ??? 1.1114 + return false; 1.1115 +#elif defined(MOZ_WIDGET_ANDROID) 1.1116 + // We don't know, so just assume transparent 1.1117 + return false; 1.1118 +#else 1.1119 + return !IsTransparentMode(); 1.1120 +#endif 1.1121 +} 1.1122 + 1.1123 +bool 1.1124 +nsObjectFrame::IsTransparentMode() const 1.1125 +{ 1.1126 +#if defined(XP_MACOSX) 1.1127 + // ??? 1.1128 + return false; 1.1129 +#else 1.1130 + if (!mInstanceOwner) 1.1131 + return false; 1.1132 + 1.1133 + NPWindow *window = nullptr; 1.1134 + mInstanceOwner->GetWindow(window); 1.1135 + if (!window) { 1.1136 + return false; 1.1137 + } 1.1138 + 1.1139 + if (window->type != NPWindowTypeDrawable) 1.1140 + return false; 1.1141 + 1.1142 + nsresult rv; 1.1143 + nsRefPtr<nsNPAPIPluginInstance> pi; 1.1144 + rv = mInstanceOwner->GetInstance(getter_AddRefs(pi)); 1.1145 + if (NS_FAILED(rv) || !pi) 1.1146 + return false; 1.1147 + 1.1148 + bool transparent = false; 1.1149 + pi->IsTransparent(&transparent); 1.1150 + return transparent; 1.1151 +#endif 1.1152 +} 1.1153 + 1.1154 +void 1.1155 +nsObjectFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, 1.1156 + const nsRect& aDirtyRect, 1.1157 + const nsDisplayListSet& aLists) 1.1158 +{ 1.1159 + // XXX why are we painting collapsed object frames? 1.1160 + if (!IsVisibleOrCollapsedForPainting(aBuilder)) 1.1161 + return; 1.1162 + 1.1163 + DisplayBorderBackgroundOutline(aBuilder, aLists); 1.1164 + 1.1165 + nsPresContext::nsPresContextType type = PresContext()->Type(); 1.1166 + 1.1167 + // If we are painting in Print Preview do nothing.... 1.1168 + if (type == nsPresContext::eContext_PrintPreview) 1.1169 + return; 1.1170 + 1.1171 + DO_GLOBAL_REFLOW_COUNT_DSP("nsObjectFrame"); 1.1172 + 1.1173 +#ifndef XP_MACOSX 1.1174 + if (mWidget && aBuilder->IsInTransform()) { 1.1175 + // Windowed plugins should not be rendered inside a transform. 1.1176 + return; 1.1177 + } 1.1178 +#endif 1.1179 + 1.1180 + if (aBuilder->IsForPainting() && mInstanceOwner && mInstanceOwner->UseAsyncRendering()) { 1.1181 + NPWindow* window = nullptr; 1.1182 + mInstanceOwner->GetWindow(window); 1.1183 + bool isVisible = window && window->width > 0 && window->height > 0; 1.1184 + if (isVisible && aBuilder->ShouldSyncDecodeImages()) { 1.1185 + #ifndef XP_MACOSX 1.1186 + mInstanceOwner->UpdateWindowVisibility(true); 1.1187 + #endif 1.1188 + } 1.1189 + 1.1190 + mInstanceOwner->NotifyPaintWaiter(aBuilder); 1.1191 + } 1.1192 + 1.1193 + DisplayListClipState::AutoClipContainingBlockDescendantsToContentBox 1.1194 + clip(aBuilder, this, DisplayListClipState::ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT); 1.1195 + 1.1196 + // determine if we are printing 1.1197 + if (type == nsPresContext::eContext_Print) { 1.1198 + aLists.Content()->AppendNewToTop(new (aBuilder) 1.1199 + nsDisplayGeneric(aBuilder, this, PaintPrintPlugin, "PrintPlugin", 1.1200 + nsDisplayItem::TYPE_PRINT_PLUGIN)); 1.1201 + } else { 1.1202 + LayerState state = GetLayerState(aBuilder, nullptr); 1.1203 + if (state == LAYER_INACTIVE && 1.1204 + nsDisplayItem::ForceActiveLayers()) { 1.1205 + state = LAYER_ACTIVE; 1.1206 + } 1.1207 + // We don't need this on Android, and it just confuses things 1.1208 +#if !MOZ_WIDGET_ANDROID 1.1209 + if (aBuilder->IsPaintingToWindow() && 1.1210 + state == LAYER_ACTIVE && 1.1211 + IsTransparentMode()) { 1.1212 + aLists.Content()->AppendNewToTop(new (aBuilder) 1.1213 + nsDisplayPluginReadback(aBuilder, this)); 1.1214 + } 1.1215 +#endif 1.1216 + 1.1217 +#if MOZ_WIDGET_ANDROID 1.1218 + if (aBuilder->IsPaintingToWindow() && 1.1219 + state == LAYER_ACTIVE) { 1.1220 + 1.1221 + nsTArray<nsNPAPIPluginInstance::VideoInfo*> videos; 1.1222 + mInstanceOwner->GetVideos(videos); 1.1223 + 1.1224 + for (uint32_t i = 0; i < videos.Length(); i++) { 1.1225 + aLists.Content()->AppendNewToTop(new (aBuilder) 1.1226 + nsDisplayPluginVideo(aBuilder, this, videos[i])); 1.1227 + } 1.1228 + } 1.1229 +#endif 1.1230 + 1.1231 + aLists.Content()->AppendNewToTop(new (aBuilder) 1.1232 + nsDisplayPlugin(aBuilder, this)); 1.1233 + } 1.1234 +} 1.1235 + 1.1236 +void 1.1237 +nsObjectFrame::PrintPlugin(nsRenderingContext& aRenderingContext, 1.1238 + const nsRect& aDirtyRect) 1.1239 +{ 1.1240 + nsCOMPtr<nsIObjectLoadingContent> obj(do_QueryInterface(mContent)); 1.1241 + if (!obj) 1.1242 + return; 1.1243 + 1.1244 + nsIFrame* frame = nullptr; 1.1245 + obj->GetPrintFrame(&frame); 1.1246 + if (!frame) 1.1247 + return; 1.1248 + 1.1249 + nsPresContext* presContext = PresContext(); 1.1250 + // make sure this is REALLY an nsIObjectFrame 1.1251 + // we may need to go through the children to get it 1.1252 + nsIObjectFrame* objectFrame = do_QueryFrame(frame); 1.1253 + if (!objectFrame) 1.1254 + objectFrame = GetNextObjectFrame(presContext,frame); 1.1255 + if (!objectFrame) 1.1256 + return; 1.1257 + 1.1258 + // finally we can get our plugin instance 1.1259 + nsRefPtr<nsNPAPIPluginInstance> pi; 1.1260 + if (NS_FAILED(objectFrame->GetPluginInstance(getter_AddRefs(pi))) || !pi) 1.1261 + return; 1.1262 + 1.1263 + // now we need to setup the correct location for printing 1.1264 + NPWindow window; 1.1265 + window.window = nullptr; 1.1266 + 1.1267 + // prepare embedded mode printing struct 1.1268 + NPPrint npprint; 1.1269 + npprint.mode = NP_EMBED; 1.1270 + 1.1271 + // we need to find out if we are windowless or not 1.1272 + bool windowless = false; 1.1273 + pi->IsWindowless(&windowless); 1.1274 + window.type = windowless ? NPWindowTypeDrawable : NPWindowTypeWindow; 1.1275 + 1.1276 + window.clipRect.bottom = 0; window.clipRect.top = 0; 1.1277 + window.clipRect.left = 0; window.clipRect.right = 0; 1.1278 + 1.1279 +// platform specific printing code 1.1280 +#if defined(XP_MACOSX) && !defined(__LP64__) 1.1281 +#pragma clang diagnostic ignored "-Wdeprecated-declarations" 1.1282 + // Don't use this code if any of the QuickDraw APIs it currently requires 1.1283 + // are missing (as they probably will be on OS X 10.8 and up). 1.1284 + if (!&::SetRect || !&::NewGWorldFromPtr || !&::DisposeGWorld) { 1.1285 + NS_WARNING("Cannot print plugin -- required QuickDraw APIs are missing!"); 1.1286 + return; 1.1287 + } 1.1288 + 1.1289 + nsSize contentSize = GetContentRectRelativeToSelf().Size(); 1.1290 + window.x = 0; 1.1291 + window.y = 0; 1.1292 + window.width = presContext->AppUnitsToDevPixels(contentSize.width); 1.1293 + window.height = presContext->AppUnitsToDevPixels(contentSize.height); 1.1294 + 1.1295 + gfxContext *ctx = aRenderingContext.ThebesContext(); 1.1296 + if (!ctx) 1.1297 + return; 1.1298 + gfxContextAutoSaveRestore save(ctx); 1.1299 + 1.1300 + ctx->NewPath(); 1.1301 + 1.1302 + gfxRect rect(window.x, window.y, window.width, window.height); 1.1303 + 1.1304 + ctx->Rectangle(rect); 1.1305 + ctx->Clip(); 1.1306 + 1.1307 + gfxQuartzNativeDrawing nativeDraw(ctx, rect); 1.1308 + CGContextRef cgContext = nativeDraw.BeginNativeDrawing(); 1.1309 + if (!cgContext) { 1.1310 + nativeDraw.EndNativeDrawing(); 1.1311 + return; 1.1312 + } 1.1313 + 1.1314 + window.clipRect.right = window.width; 1.1315 + window.clipRect.bottom = window.height; 1.1316 + window.type = NPWindowTypeDrawable; 1.1317 + 1.1318 + ::Rect gwBounds; 1.1319 + ::SetRect(&gwBounds, 0, 0, window.width, window.height); 1.1320 + 1.1321 + nsTArray<char> buffer(window.width * window.height * 4); 1.1322 + CGColorSpaceRef cspace = ::CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); 1.1323 + if (!cspace) { 1.1324 + nativeDraw.EndNativeDrawing(); 1.1325 + return; 1.1326 + } 1.1327 + CGContextRef cgBuffer = 1.1328 + ::CGBitmapContextCreate(buffer.Elements(), 1.1329 + window.width, window.height, 8, window.width * 4, 1.1330 + cspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedFirst); 1.1331 + ::CGColorSpaceRelease(cspace); 1.1332 + if (!cgBuffer) { 1.1333 + nativeDraw.EndNativeDrawing(); 1.1334 + return; 1.1335 + } 1.1336 + GWorldPtr gWorld; 1.1337 + if (::NewGWorldFromPtr(&gWorld, k32ARGBPixelFormat, &gwBounds, 1.1338 + nullptr, nullptr, 0, 1.1339 + buffer.Elements(), window.width * 4) != noErr) { 1.1340 + ::CGContextRelease(cgBuffer); 1.1341 + nativeDraw.EndNativeDrawing(); 1.1342 + return; 1.1343 + } 1.1344 + 1.1345 + window.clipRect.right = window.width; 1.1346 + window.clipRect.bottom = window.height; 1.1347 + window.type = NPWindowTypeDrawable; 1.1348 + // Setting nsPluginPrint/NPPrint.print.embedPrint.window.window to 1.1349 + // &GWorldPtr and nsPluginPrint/NPPrint.print.embedPrint.platformPrint to 1.1350 + // GWorldPtr isn't any kind of standard (it's not documented anywhere). 1.1351 + // But that's what WebKit does. And it's what the Flash plugin (apparently 1.1352 + // the only NPAPI plugin on OS X to support printing) seems to expect. So 1.1353 + // we do the same. The Flash plugin uses the CoreGraphics drawing mode. 1.1354 + // But a GWorldPtr should be usable in either CoreGraphics or QuickDraw 1.1355 + // drawing mode. See bug 191046. 1.1356 + window.window = &gWorld; 1.1357 + npprint.print.embedPrint.platformPrint = gWorld; 1.1358 + npprint.print.embedPrint.window = window; 1.1359 + pi->Print(&npprint); 1.1360 + 1.1361 + ::CGContextTranslateCTM(cgContext, 0.0f, float(window.height)); 1.1362 + ::CGContextScaleCTM(cgContext, 1.0f, -1.0f); 1.1363 + CGImageRef image = ::CGBitmapContextCreateImage(cgBuffer); 1.1364 + if (!image) { 1.1365 + ::CGContextRestoreGState(cgContext); 1.1366 + ::CGContextRelease(cgBuffer); 1.1367 + ::DisposeGWorld(gWorld); 1.1368 + nativeDraw.EndNativeDrawing(); 1.1369 + return; 1.1370 + } 1.1371 + ::CGContextDrawImage(cgContext, 1.1372 + ::CGRectMake(0, 0, window.width, window.height), 1.1373 + image); 1.1374 + ::CGImageRelease(image); 1.1375 + ::CGContextRelease(cgBuffer); 1.1376 + 1.1377 + ::DisposeGWorld(gWorld); 1.1378 + 1.1379 + nativeDraw.EndNativeDrawing(); 1.1380 +#pragma clang diagnostic warning "-Wdeprecated-declarations" 1.1381 +#elif defined(XP_UNIX) 1.1382 + 1.1383 + /* XXX this just flat-out doesn't work in a thebes world -- 1.1384 + * RenderEPS is a no-op. So don't bother to do any work here. 1.1385 + */ 1.1386 + (void)window; 1.1387 + (void)npprint; 1.1388 + 1.1389 +#elif defined(XP_WIN) 1.1390 + 1.1391 + /* On Windows, we use the win32 printing surface to print. This, in 1.1392 + * turn, uses the Cairo paginated surface, which in turn uses the 1.1393 + * meta surface to record all operations and then play them back. 1.1394 + * This doesn't work too well for plugins, because if plugins render 1.1395 + * directly into the DC, the meta surface won't have any knowledge 1.1396 + * of them, and so at the end when it actually does the replay step, 1.1397 + * it'll fill the background with white and draw over whatever was 1.1398 + * rendered before. 1.1399 + * 1.1400 + * So, to avoid this, we use PushGroup, which creates a new windows 1.1401 + * surface, the plugin renders to that, and then we use normal 1.1402 + * cairo methods to composite that in such that it's recorded using the 1.1403 + * meta surface. 1.1404 + */ 1.1405 + 1.1406 + /* we'll already be translated into the right spot by gfxWindowsNativeDrawing */ 1.1407 + nsSize contentSize = GetContentRectRelativeToSelf().Size(); 1.1408 + window.x = 0; 1.1409 + window.y = 0; 1.1410 + window.width = presContext->AppUnitsToDevPixels(contentSize.width); 1.1411 + window.height = presContext->AppUnitsToDevPixels(contentSize.height); 1.1412 + 1.1413 + gfxContext *ctx = aRenderingContext.ThebesContext(); 1.1414 + 1.1415 + ctx->Save(); 1.1416 + 1.1417 + /* Make sure plugins don't do any damage outside of where they're supposed to */ 1.1418 + ctx->NewPath(); 1.1419 + gfxRect r(window.x, window.y, window.width, window.height); 1.1420 + ctx->Rectangle(r); 1.1421 + ctx->Clip(); 1.1422 + 1.1423 + gfxWindowsNativeDrawing nativeDraw(ctx, r); 1.1424 + do { 1.1425 + HDC dc = nativeDraw.BeginNativeDrawing(); 1.1426 + if (!dc) 1.1427 + return; 1.1428 + 1.1429 + // XXX don't we need to call nativeDraw.TransformToNativeRect here? 1.1430 + npprint.print.embedPrint.platformPrint = dc; 1.1431 + npprint.print.embedPrint.window = window; 1.1432 + // send off print info to plugin 1.1433 + pi->Print(&npprint); 1.1434 + 1.1435 + nativeDraw.EndNativeDrawing(); 1.1436 + } while (nativeDraw.ShouldRenderAgain()); 1.1437 + nativeDraw.PaintToContext(); 1.1438 + 1.1439 + ctx->Restore(); 1.1440 +#endif 1.1441 + 1.1442 + // XXX Nav 4.x always sent a SetWindow call after print. Should we do the same? 1.1443 + // XXX Calling DidReflow here makes no sense!!! 1.1444 + nsDidReflowStatus status = nsDidReflowStatus::FINISHED; // should we use a special status? 1.1445 + frame->DidReflow(presContext, 1.1446 + nullptr, status); // DidReflow will take care of it 1.1447 +} 1.1448 + 1.1449 +nsRect 1.1450 +nsObjectFrame::GetPaintedRect(nsDisplayPlugin* aItem) 1.1451 +{ 1.1452 + if (!mInstanceOwner) 1.1453 + return nsRect(); 1.1454 + nsRect r = GetContentRectRelativeToSelf(); 1.1455 + if (!mInstanceOwner->UseAsyncRendering()) 1.1456 + return r; 1.1457 + 1.1458 + nsIntSize size = mInstanceOwner->GetCurrentImageSize(); 1.1459 + nsPresContext* pc = PresContext(); 1.1460 + r.IntersectRect(r, nsRect(0, 0, pc->DevPixelsToAppUnits(size.width), 1.1461 + pc->DevPixelsToAppUnits(size.height))); 1.1462 + return r; 1.1463 +} 1.1464 + 1.1465 +LayerState 1.1466 +nsObjectFrame::GetLayerState(nsDisplayListBuilder* aBuilder, 1.1467 + LayerManager* aManager) 1.1468 +{ 1.1469 + if (!mInstanceOwner) 1.1470 + return LAYER_NONE; 1.1471 + 1.1472 +#ifdef MOZ_WIDGET_ANDROID 1.1473 + // We always want a layer on Honeycomb and later 1.1474 + if (AndroidBridge::Bridge()->GetAPIVersion() >= 11) 1.1475 + return LAYER_ACTIVE; 1.1476 +#endif 1.1477 + 1.1478 + if (!mInstanceOwner->UseAsyncRendering()) { 1.1479 + return LAYER_NONE; 1.1480 + } 1.1481 + 1.1482 + return LAYER_ACTIVE; 1.1483 +} 1.1484 + 1.1485 +already_AddRefed<Layer> 1.1486 +nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder, 1.1487 + LayerManager* aManager, 1.1488 + nsDisplayItem* aItem, 1.1489 + const ContainerLayerParameters& aContainerParameters) 1.1490 +{ 1.1491 + if (!mInstanceOwner) 1.1492 + return nullptr; 1.1493 + 1.1494 + NPWindow* window = nullptr; 1.1495 + mInstanceOwner->GetWindow(window); 1.1496 + if (!window) 1.1497 + return nullptr; 1.1498 + 1.1499 + if (window->width <= 0 || window->height <= 0) 1.1500 + return nullptr; 1.1501 + 1.1502 + // window is in "display pixels", but size needs to be in device pixels 1.1503 + double scaleFactor = 1.0; 1.1504 + if (NS_FAILED(mInstanceOwner->GetContentsScaleFactor(&scaleFactor))) { 1.1505 + scaleFactor = 1.0; 1.1506 + } 1.1507 + int intScaleFactor = ceil(scaleFactor); 1.1508 + IntSize size(window->width * intScaleFactor, window->height * intScaleFactor); 1.1509 + 1.1510 + nsRect area = GetContentRectRelativeToSelf() + aItem->ToReferenceFrame(); 1.1511 + gfxRect r = nsLayoutUtils::RectToGfxRect(area, PresContext()->AppUnitsPerDevPixel()); 1.1512 + // to provide crisper and faster drawing. 1.1513 + r.Round(); 1.1514 + nsRefPtr<Layer> layer = 1.1515 + (aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aItem)); 1.1516 + 1.1517 + if (aItem->GetType() == nsDisplayItem::TYPE_PLUGIN) { 1.1518 + // Create image 1.1519 + nsRefPtr<ImageContainer> container = mInstanceOwner->GetImageContainer(); 1.1520 + if (!container) { 1.1521 + // This can occur if our instance is gone. 1.1522 + return nullptr; 1.1523 + } 1.1524 + 1.1525 + if (!layer) { 1.1526 + mInstanceOwner->NotifyPaintWaiter(aBuilder); 1.1527 + // Initialize ImageLayer 1.1528 + layer = aManager->CreateImageLayer(); 1.1529 + if (!layer) 1.1530 + return nullptr; 1.1531 + } 1.1532 + 1.1533 + NS_ASSERTION(layer->GetType() == Layer::TYPE_IMAGE, "Bad layer type"); 1.1534 + ImageLayer* imglayer = static_cast<ImageLayer*>(layer.get()); 1.1535 +#ifdef XP_MACOSX 1.1536 + if (!mInstanceOwner->UseAsyncRendering()) { 1.1537 + mInstanceOwner->DoCocoaEventDrawRect(r, nullptr); 1.1538 + } 1.1539 +#endif 1.1540 + 1.1541 + imglayer->SetScaleToSize(size, ScaleMode::STRETCH); 1.1542 + imglayer->SetContainer(container); 1.1543 + GraphicsFilter filter = 1.1544 + nsLayoutUtils::GetGraphicsFilterForFrame(this); 1.1545 +#ifdef MOZ_GFX_OPTIMIZE_MOBILE 1.1546 + if (!aManager->IsCompositingCheap()) { 1.1547 + // Pixman just horrible with bilinear filter scaling 1.1548 + filter = GraphicsFilter::FILTER_NEAREST; 1.1549 + } 1.1550 +#endif 1.1551 + imglayer->SetFilter(filter); 1.1552 + 1.1553 + layer->SetContentFlags(IsOpaque() ? Layer::CONTENT_OPAQUE : 0); 1.1554 +#ifdef MOZ_WIDGET_ANDROID 1.1555 + } else if (aItem->GetType() == nsDisplayItem::TYPE_PLUGIN_VIDEO) { 1.1556 + nsDisplayPluginVideo* videoItem = reinterpret_cast<nsDisplayPluginVideo*>(aItem); 1.1557 + nsNPAPIPluginInstance::VideoInfo* videoInfo = videoItem->VideoInfo(); 1.1558 + 1.1559 + nsRefPtr<ImageContainer> container = mInstanceOwner->GetImageContainerForVideo(videoInfo); 1.1560 + if (!container) 1.1561 + return nullptr; 1.1562 + 1.1563 + if (!layer) { 1.1564 + // Initialize ImageLayer 1.1565 + layer = aManager->CreateImageLayer(); 1.1566 + if (!layer) 1.1567 + return nullptr; 1.1568 + } 1.1569 + 1.1570 + ImageLayer* imglayer = static_cast<ImageLayer*>(layer.get()); 1.1571 + imglayer->SetContainer(container); 1.1572 + 1.1573 + layer->SetContentFlags(IsOpaque() ? Layer::CONTENT_OPAQUE : 0); 1.1574 + 1.1575 + // Set the offset and size according to the video dimensions 1.1576 + r.MoveBy(videoInfo->mDimensions.TopLeft()); 1.1577 + size.width = videoInfo->mDimensions.width; 1.1578 + size.height = videoInfo->mDimensions.height; 1.1579 +#endif 1.1580 + } else { 1.1581 + NS_ASSERTION(aItem->GetType() == nsDisplayItem::TYPE_PLUGIN_READBACK, 1.1582 + "Unknown item type"); 1.1583 + NS_ABORT_IF_FALSE(!IsOpaque(), "Opaque plugins don't use backgrounds"); 1.1584 + 1.1585 + if (!layer) { 1.1586 + layer = aManager->CreateReadbackLayer(); 1.1587 + if (!layer) 1.1588 + return nullptr; 1.1589 + } 1.1590 + NS_ASSERTION(layer->GetType() == Layer::TYPE_READBACK, "Bad layer type"); 1.1591 + 1.1592 + ReadbackLayer* readback = static_cast<ReadbackLayer*>(layer.get()); 1.1593 + if (readback->GetSize() != ThebesIntSize(size)) { 1.1594 + // This will destroy any old background sink and notify us that the 1.1595 + // background is now unknown 1.1596 + readback->SetSink(nullptr); 1.1597 + readback->SetSize(ThebesIntSize(size)); 1.1598 + 1.1599 + if (mBackgroundSink) { 1.1600 + // Maybe we still have a background sink associated with another 1.1601 + // readback layer that wasn't recycled for some reason? Unhook it 1.1602 + // now so that if this frame goes away, it doesn't have a dangling 1.1603 + // reference to us. 1.1604 + mBackgroundSink->Destroy(); 1.1605 + } 1.1606 + mBackgroundSink = 1.1607 + new PluginBackgroundSink(this, 1.1608 + readback->AllocateSequenceNumber()); 1.1609 + readback->SetSink(mBackgroundSink); 1.1610 + // The layer has taken ownership of our sink. When either the sink dies 1.1611 + // or the frame dies, the connection from the surviving object is nulled out. 1.1612 + } 1.1613 + } 1.1614 + 1.1615 + // Set a transform on the layer to draw the plugin in the right place 1.1616 + Matrix transform; 1.1617 + gfxPoint p = r.TopLeft() + aContainerParameters.mOffset; 1.1618 + transform.Translate(p.x, p.y); 1.1619 + 1.1620 + layer->SetBaseTransform(Matrix4x4::From2D(transform)); 1.1621 + layer->SetVisibleRegion(ThebesIntRect(IntRect(IntPoint(0, 0), size))); 1.1622 + return layer.forget(); 1.1623 +} 1.1624 + 1.1625 +void 1.1626 +nsObjectFrame::PaintPlugin(nsDisplayListBuilder* aBuilder, 1.1627 + nsRenderingContext& aRenderingContext, 1.1628 + const nsRect& aDirtyRect, const nsRect& aPluginRect) 1.1629 +{ 1.1630 +#if defined(MOZ_WIDGET_ANDROID) 1.1631 + if (mInstanceOwner) { 1.1632 + gfxRect frameGfxRect = 1.1633 + PresContext()->AppUnitsToGfxUnits(aPluginRect); 1.1634 + gfxRect dirtyGfxRect = 1.1635 + PresContext()->AppUnitsToGfxUnits(aDirtyRect); 1.1636 + 1.1637 + gfxContext* ctx = aRenderingContext.ThebesContext(); 1.1638 + 1.1639 + mInstanceOwner->Paint(ctx, frameGfxRect, dirtyGfxRect); 1.1640 + return; 1.1641 + } 1.1642 +#endif 1.1643 + 1.1644 + // Screen painting code 1.1645 +#if defined(XP_MACOSX) 1.1646 + // delegate all painting to the plugin instance. 1.1647 + if (mInstanceOwner) { 1.1648 + if (mInstanceOwner->GetDrawingModel() == NPDrawingModelCoreGraphics || 1.1649 + mInstanceOwner->GetDrawingModel() == NPDrawingModelCoreAnimation || 1.1650 + mInstanceOwner->GetDrawingModel() == 1.1651 + NPDrawingModelInvalidatingCoreAnimation) { 1.1652 + int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel(); 1.1653 + // Clip to the content area where the plugin should be drawn. If 1.1654 + // we don't do this, the plugin can draw outside its bounds. 1.1655 + nsIntRect contentPixels = aPluginRect.ToNearestPixels(appUnitsPerDevPixel); 1.1656 + nsIntRect dirtyPixels = aDirtyRect.ToOutsidePixels(appUnitsPerDevPixel); 1.1657 + nsIntRect clipPixels; 1.1658 + clipPixels.IntersectRect(contentPixels, dirtyPixels); 1.1659 + 1.1660 + // Don't invoke the drawing code if the clip is empty. 1.1661 + if (clipPixels.IsEmpty()) 1.1662 + return; 1.1663 + 1.1664 + gfxRect nativeClipRect(clipPixels.x, clipPixels.y, 1.1665 + clipPixels.width, clipPixels.height); 1.1666 + gfxContext* ctx = aRenderingContext.ThebesContext(); 1.1667 + 1.1668 + gfxContextAutoSaveRestore save(ctx); 1.1669 + ctx->NewPath(); 1.1670 + ctx->Rectangle(nativeClipRect); 1.1671 + ctx->Clip(); 1.1672 + gfxPoint offset(contentPixels.x, contentPixels.y); 1.1673 + ctx->Translate(offset); 1.1674 + 1.1675 + gfxQuartzNativeDrawing nativeDrawing(ctx, nativeClipRect - offset); 1.1676 + 1.1677 + CGContextRef cgContext = nativeDrawing.BeginNativeDrawing(); 1.1678 + if (!cgContext) { 1.1679 + NS_WARNING("null CGContextRef during PaintPlugin"); 1.1680 + return; 1.1681 + } 1.1682 + 1.1683 + nsRefPtr<nsNPAPIPluginInstance> inst; 1.1684 + GetPluginInstance(getter_AddRefs(inst)); 1.1685 + if (!inst) { 1.1686 + NS_WARNING("null plugin instance during PaintPlugin"); 1.1687 + nativeDrawing.EndNativeDrawing(); 1.1688 + return; 1.1689 + } 1.1690 + NPWindow* window; 1.1691 + mInstanceOwner->GetWindow(window); 1.1692 + if (!window) { 1.1693 + NS_WARNING("null plugin window during PaintPlugin"); 1.1694 + nativeDrawing.EndNativeDrawing(); 1.1695 + return; 1.1696 + } 1.1697 + NP_CGContext* cgPluginPortCopy = 1.1698 + static_cast<NP_CGContext*>(mInstanceOwner->GetPluginPortCopy()); 1.1699 + if (!cgPluginPortCopy) { 1.1700 + NS_WARNING("null plugin port copy during PaintPlugin"); 1.1701 + nativeDrawing.EndNativeDrawing(); 1.1702 + return; 1.1703 + } 1.1704 + 1.1705 + mInstanceOwner->BeginCGPaint(); 1.1706 + if (mInstanceOwner->GetDrawingModel() == NPDrawingModelCoreAnimation || 1.1707 + mInstanceOwner->GetDrawingModel() == 1.1708 + NPDrawingModelInvalidatingCoreAnimation) { 1.1709 + // CoreAnimation is updated, render the layer and perform a readback. 1.1710 + mInstanceOwner->RenderCoreAnimation(cgContext, window->width, window->height); 1.1711 + } else { 1.1712 + mInstanceOwner->Paint(nativeClipRect - offset, cgContext); 1.1713 + } 1.1714 + mInstanceOwner->EndCGPaint(); 1.1715 + 1.1716 + nativeDrawing.EndNativeDrawing(); 1.1717 + } else { 1.1718 + // FIXME - Bug 385435: Doesn't aDirtyRect need translating too? 1.1719 + nsRenderingContext::AutoPushTranslation 1.1720 + translate(&aRenderingContext, aPluginRect.TopLeft()); 1.1721 + 1.1722 + // this rect is used only in the CoreGraphics drawing model 1.1723 + gfxRect tmpRect(0, 0, 0, 0); 1.1724 + mInstanceOwner->Paint(tmpRect, nullptr); 1.1725 + } 1.1726 + } 1.1727 +#elif defined(MOZ_X11) 1.1728 + if (mInstanceOwner) { 1.1729 + NPWindow *window; 1.1730 + mInstanceOwner->GetWindow(window); 1.1731 + if (window->type == NPWindowTypeDrawable) { 1.1732 + gfxRect frameGfxRect = 1.1733 + PresContext()->AppUnitsToGfxUnits(aPluginRect); 1.1734 + gfxRect dirtyGfxRect = 1.1735 + PresContext()->AppUnitsToGfxUnits(aDirtyRect); 1.1736 + gfxContext* ctx = aRenderingContext.ThebesContext(); 1.1737 + 1.1738 + mInstanceOwner->Paint(ctx, frameGfxRect, dirtyGfxRect); 1.1739 + } 1.1740 + } 1.1741 +#elif defined(XP_WIN) 1.1742 + nsRefPtr<nsNPAPIPluginInstance> inst; 1.1743 + GetPluginInstance(getter_AddRefs(inst)); 1.1744 + if (inst) { 1.1745 + gfxRect frameGfxRect = 1.1746 + PresContext()->AppUnitsToGfxUnits(aPluginRect); 1.1747 + gfxRect dirtyGfxRect = 1.1748 + PresContext()->AppUnitsToGfxUnits(aDirtyRect); 1.1749 + gfxContext *ctx = aRenderingContext.ThebesContext(); 1.1750 + gfxMatrix currentMatrix = ctx->CurrentMatrix(); 1.1751 + 1.1752 + if (ctx->UserToDevicePixelSnapped(frameGfxRect, false)) { 1.1753 + dirtyGfxRect = ctx->UserToDevice(dirtyGfxRect); 1.1754 + ctx->IdentityMatrix(); 1.1755 + } 1.1756 + dirtyGfxRect.RoundOut(); 1.1757 + 1.1758 + // Look if it's windowless 1.1759 + NPWindow *window; 1.1760 + mInstanceOwner->GetWindow(window); 1.1761 + 1.1762 + if (window->type == NPWindowTypeDrawable) { 1.1763 + // the offset of the DC 1.1764 + nsPoint origin; 1.1765 + 1.1766 + gfxWindowsNativeDrawing nativeDraw(ctx, frameGfxRect); 1.1767 + if (nativeDraw.IsDoublePass()) { 1.1768 + // OOP plugin specific: let the shim know before we paint if we are doing a 1.1769 + // double pass render. If this plugin isn't oop, the register window message 1.1770 + // will be ignored. 1.1771 + NPEvent pluginEvent; 1.1772 + pluginEvent.event = plugins::DoublePassRenderingEvent(); 1.1773 + pluginEvent.wParam = 0; 1.1774 + pluginEvent.lParam = 0; 1.1775 + if (pluginEvent.event) 1.1776 + inst->HandleEvent(&pluginEvent, nullptr); 1.1777 + } 1.1778 + do { 1.1779 + HDC hdc = nativeDraw.BeginNativeDrawing(); 1.1780 + if (!hdc) 1.1781 + return; 1.1782 + 1.1783 + RECT dest; 1.1784 + nativeDraw.TransformToNativeRect(frameGfxRect, dest); 1.1785 + RECT dirty; 1.1786 + nativeDraw.TransformToNativeRect(dirtyGfxRect, dirty); 1.1787 + 1.1788 + window->window = hdc; 1.1789 + window->x = dest.left; 1.1790 + window->y = dest.top; 1.1791 + window->clipRect.left = 0; 1.1792 + window->clipRect.top = 0; 1.1793 + // if we're painting, we're visible. 1.1794 + window->clipRect.right = window->width; 1.1795 + window->clipRect.bottom = window->height; 1.1796 + 1.1797 + // Windowless plugins on windows need a special event to update their location, 1.1798 + // see bug 135737. 1.1799 + // 1.1800 + // bug 271442: note, the rectangle we send is now purely the bounds of the plugin 1.1801 + // relative to the window it is contained in, which is useful for the plugin to 1.1802 + // correctly translate mouse coordinates. 1.1803 + // 1.1804 + // this does not mesh with the comments for bug 135737 which imply that the rectangle 1.1805 + // must be clipped in some way to prevent the plugin attempting to paint over areas 1.1806 + // it shouldn't. 1.1807 + // 1.1808 + // since the two uses of the rectangle are mutually exclusive in some cases, and 1.1809 + // since I don't see any incorrect painting (at least with Flash and ViewPoint - 1.1810 + // the originator of bug 135737), it seems that windowless plugins are not relying 1.1811 + // on information here for clipping their drawing, and we can safely use this message 1.1812 + // to tell the plugin exactly where it is in all cases. 1.1813 + 1.1814 + nsIntPoint origin = GetWindowOriginInPixels(true); 1.1815 + nsIntRect winlessRect = nsIntRect(origin, nsIntSize(window->width, window->height)); 1.1816 + 1.1817 + if (!mWindowlessRect.IsEqualEdges(winlessRect)) { 1.1818 + mWindowlessRect = winlessRect; 1.1819 + 1.1820 + WINDOWPOS winpos; 1.1821 + memset(&winpos, 0, sizeof(winpos)); 1.1822 + winpos.x = mWindowlessRect.x; 1.1823 + winpos.y = mWindowlessRect.y; 1.1824 + winpos.cx = mWindowlessRect.width; 1.1825 + winpos.cy = mWindowlessRect.height; 1.1826 + 1.1827 + // finally, update the plugin by sending it a WM_WINDOWPOSCHANGED event 1.1828 + NPEvent pluginEvent; 1.1829 + pluginEvent.event = WM_WINDOWPOSCHANGED; 1.1830 + pluginEvent.wParam = 0; 1.1831 + pluginEvent.lParam = (LPARAM)&winpos; 1.1832 + inst->HandleEvent(&pluginEvent, nullptr); 1.1833 + } 1.1834 + 1.1835 + inst->SetWindow(window); 1.1836 + 1.1837 + mInstanceOwner->Paint(dirty, hdc); 1.1838 + nativeDraw.EndNativeDrawing(); 1.1839 + } while (nativeDraw.ShouldRenderAgain()); 1.1840 + nativeDraw.PaintToContext(); 1.1841 + } 1.1842 + 1.1843 + ctx->SetMatrix(currentMatrix); 1.1844 + } 1.1845 +#endif 1.1846 +} 1.1847 + 1.1848 +nsresult 1.1849 +nsObjectFrame::HandleEvent(nsPresContext* aPresContext, 1.1850 + WidgetGUIEvent* anEvent, 1.1851 + nsEventStatus* anEventStatus) 1.1852 +{ 1.1853 + NS_ENSURE_ARG_POINTER(anEvent); 1.1854 + NS_ENSURE_ARG_POINTER(anEventStatus); 1.1855 + nsresult rv = NS_OK; 1.1856 + 1.1857 + if (!mInstanceOwner) 1.1858 + return NS_ERROR_NULL_POINTER; 1.1859 + 1.1860 + mInstanceOwner->ConsiderNewEventloopNestingLevel(); 1.1861 + 1.1862 + if (anEvent->message == NS_PLUGIN_ACTIVATE) { 1.1863 + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); 1.1864 + nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(GetContent()); 1.1865 + if (fm && elem) 1.1866 + return fm->SetFocus(elem, 0); 1.1867 + } 1.1868 + else if (anEvent->message == NS_PLUGIN_FOCUS) { 1.1869 + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); 1.1870 + if (fm) 1.1871 + return fm->FocusPlugin(GetContent()); 1.1872 + } 1.1873 + 1.1874 +#ifdef XP_MACOSX 1.1875 + if (anEvent->message == NS_PLUGIN_RESOLUTION_CHANGED) { 1.1876 + double scaleFactor = 1.0; 1.1877 + mInstanceOwner->GetContentsScaleFactor(&scaleFactor); 1.1878 + mInstanceOwner->ContentsScaleFactorChanged(scaleFactor); 1.1879 + return NS_OK; 1.1880 + } 1.1881 +#endif 1.1882 + 1.1883 + if (mInstanceOwner->SendNativeEvents() && 1.1884 + anEvent->IsNativeEventDelivererForPlugin()) { 1.1885 + *anEventStatus = mInstanceOwner->ProcessEvent(*anEvent); 1.1886 + // Due to plugin code reentering Gecko, this frame may be dead at this 1.1887 + // point. 1.1888 + return rv; 1.1889 + } 1.1890 + 1.1891 +#ifdef XP_WIN 1.1892 + rv = nsObjectFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus); 1.1893 + return rv; 1.1894 +#endif 1.1895 + 1.1896 +#ifdef XP_MACOSX 1.1897 + // we want to process some native mouse events in the cocoa event model 1.1898 + if ((anEvent->message == NS_MOUSE_ENTER || 1.1899 + anEvent->message == NS_WHEEL_WHEEL) && 1.1900 + mInstanceOwner->GetEventModel() == NPEventModelCocoa) { 1.1901 + *anEventStatus = mInstanceOwner->ProcessEvent(*anEvent); 1.1902 + // Due to plugin code reentering Gecko, this frame may be dead at this 1.1903 + // point. 1.1904 + return rv; 1.1905 + } 1.1906 + 1.1907 + // These two calls to nsIPresShell::SetCapturingContext() (on mouse-down 1.1908 + // and mouse-up) are needed to make the routing of mouse events while 1.1909 + // dragging conform to standard OS X practice, and to the Cocoa NPAPI spec. 1.1910 + // See bug 525078 and bug 909678. 1.1911 + if (anEvent->message == NS_MOUSE_BUTTON_DOWN) { 1.1912 + nsIPresShell::SetCapturingContent(GetContent(), CAPTURE_IGNOREALLOWED); 1.1913 + } 1.1914 +#endif 1.1915 + 1.1916 + rv = nsObjectFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus); 1.1917 + 1.1918 + // We need to be careful from this point because the call to 1.1919 + // nsObjectFrameSuper::HandleEvent() might have killed us. 1.1920 + 1.1921 +#ifdef XP_MACOSX 1.1922 + if (anEvent->message == NS_MOUSE_BUTTON_UP) { 1.1923 + nsIPresShell::SetCapturingContent(nullptr, 0); 1.1924 + } 1.1925 +#endif 1.1926 + 1.1927 + return rv; 1.1928 +} 1.1929 + 1.1930 +nsresult 1.1931 +nsObjectFrame::GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance) 1.1932 +{ 1.1933 + *aPluginInstance = nullptr; 1.1934 + 1.1935 + if (!mInstanceOwner) { 1.1936 + return NS_OK; 1.1937 + } 1.1938 + 1.1939 + return mInstanceOwner->GetInstance(aPluginInstance); 1.1940 +} 1.1941 + 1.1942 +nsresult 1.1943 +nsObjectFrame::GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor) 1.1944 +{ 1.1945 + if (!mInstanceOwner) { 1.1946 + return NS_ERROR_FAILURE; 1.1947 + } 1.1948 + 1.1949 + nsRefPtr<nsNPAPIPluginInstance> inst; 1.1950 + mInstanceOwner->GetInstance(getter_AddRefs(inst)); 1.1951 + if (!inst) { 1.1952 + return NS_ERROR_FAILURE; 1.1953 + } 1.1954 + 1.1955 + bool useDOMCursor = static_cast<nsNPAPIPluginInstance*>(inst.get())->UsesDOMForCursor(); 1.1956 + if (!useDOMCursor) { 1.1957 + return NS_ERROR_FAILURE; 1.1958 + } 1.1959 + 1.1960 + return nsObjectFrameSuper::GetCursor(aPoint, aCursor); 1.1961 +} 1.1962 + 1.1963 +void 1.1964 +nsObjectFrame::SetIsDocumentActive(bool aIsActive) 1.1965 +{ 1.1966 +#ifndef XP_MACOSX 1.1967 + if (mInstanceOwner) { 1.1968 + mInstanceOwner->UpdateDocumentActiveState(aIsActive); 1.1969 + } 1.1970 +#endif 1.1971 +} 1.1972 + 1.1973 +// static 1.1974 +nsIObjectFrame * 1.1975 +nsObjectFrame::GetNextObjectFrame(nsPresContext* aPresContext, nsIFrame* aRoot) 1.1976 +{ 1.1977 + nsIFrame* child = aRoot->GetFirstPrincipalChild(); 1.1978 + 1.1979 + while (child) { 1.1980 + nsIObjectFrame* outFrame = do_QueryFrame(child); 1.1981 + if (outFrame) { 1.1982 + nsRefPtr<nsNPAPIPluginInstance> pi; 1.1983 + outFrame->GetPluginInstance(getter_AddRefs(pi)); // make sure we have a REAL plugin 1.1984 + if (pi) 1.1985 + return outFrame; 1.1986 + } 1.1987 + 1.1988 + outFrame = GetNextObjectFrame(aPresContext, child); 1.1989 + if (outFrame) 1.1990 + return outFrame; 1.1991 + child = child->GetNextSibling(); 1.1992 + } 1.1993 + 1.1994 + return nullptr; 1.1995 +} 1.1996 + 1.1997 +/*static*/ void 1.1998 +nsObjectFrame::BeginSwapDocShells(nsIContent* aContent, void*) 1.1999 +{ 1.2000 + NS_PRECONDITION(aContent, ""); 1.2001 + 1.2002 + // This function is called from a document content enumerator so we need 1.2003 + // to filter out the nsObjectFrames and ignore the rest. 1.2004 + nsIObjectFrame* obj = do_QueryFrame(aContent->GetPrimaryFrame()); 1.2005 + if (!obj) 1.2006 + return; 1.2007 + 1.2008 + nsObjectFrame* objectFrame = static_cast<nsObjectFrame*>(obj); 1.2009 + NS_ASSERTION(!objectFrame->mWidget || objectFrame->mWidget->GetParent(), 1.2010 + "Plugin windows must not be toplevel"); 1.2011 + objectFrame->UnregisterPluginForGeometryUpdates(); 1.2012 +} 1.2013 + 1.2014 +/*static*/ void 1.2015 +nsObjectFrame::EndSwapDocShells(nsIContent* aContent, void*) 1.2016 +{ 1.2017 + NS_PRECONDITION(aContent, ""); 1.2018 + 1.2019 + // This function is called from a document content enumerator so we need 1.2020 + // to filter out the nsObjectFrames and ignore the rest. 1.2021 + nsIObjectFrame* obj = do_QueryFrame(aContent->GetPrimaryFrame()); 1.2022 + if (!obj) 1.2023 + return; 1.2024 + 1.2025 + nsObjectFrame* objectFrame = static_cast<nsObjectFrame*>(obj); 1.2026 + nsRootPresContext* rootPC = objectFrame->PresContext()->GetRootPresContext(); 1.2027 + NS_ASSERTION(rootPC, "unable to register the plugin frame"); 1.2028 + nsIWidget* widget = objectFrame->mWidget; 1.2029 + if (widget) { 1.2030 + // Reparent the widget. 1.2031 + nsIWidget* parent = 1.2032 + rootPC->PresShell()->GetRootFrame()->GetNearestWidget(); 1.2033 + widget->SetParent(parent); 1.2034 + nsWeakFrame weakFrame(objectFrame); 1.2035 + objectFrame->CallSetWindow(); 1.2036 + if (!weakFrame.IsAlive()) { 1.2037 + return; 1.2038 + } 1.2039 + } 1.2040 + 1.2041 +#ifdef XP_MACOSX 1.2042 + if (objectFrame->mWidget) { 1.2043 + objectFrame->RegisterPluginForGeometryUpdates(); 1.2044 + } 1.2045 +#else 1.2046 + objectFrame->RegisterPluginForGeometryUpdates(); 1.2047 +#endif 1.2048 +} 1.2049 + 1.2050 +nsIFrame* 1.2051 +NS_NewObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) 1.2052 +{ 1.2053 + return new (aPresShell) nsObjectFrame(aContext); 1.2054 +} 1.2055 + 1.2056 +bool 1.2057 +nsObjectFrame::IsPaintedByGecko() const 1.2058 +{ 1.2059 +#ifdef XP_MACOSX 1.2060 + return true; 1.2061 +#else 1.2062 + return !mWidget; 1.2063 +#endif 1.2064 +} 1.2065 + 1.2066 +NS_IMPL_FRAMEARENA_HELPERS(nsObjectFrame)