LCOV - app.info - layout/generic/nsObjectFrame.cpp

LCOV - code coverage report
| Current view: | directory - layout/generic - nsObjectFrame.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 635 | 2 | 0.3 %
| Date: | 2012-06-02 | Functions: | 76 | 2 | 2.6 %

           1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
           2                 : // vim:set ts=2 sts=2 sw=2 et cin:
           3                 : /* ***** BEGIN LICENSE BLOCK *****
           4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           5                 :  *
           6                 :  * The contents of this file are subject to the Mozilla Public License Version
           7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           8                 :  * the License. You may obtain a copy of the License at
           9                 :  * http://www.mozilla.org/MPL/
          10                 :  *
          11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          13                 :  * for the specific language governing rights and limitations under the
          14                 :  * License.
          15                 :  *
          16                 :  * The Original Code is Mozilla Communicator client code.
          17                 :  *
          18                 :  * The Initial Developer of the Original Code is
          19                 :  * Netscape Communications Corporation.
          20                 :  * Portions created by the Initial Developer are Copyright (C) 1998
          21                 :  * the Initial Developer. All Rights Reserved.
          22                 :  *
          23                 :  * Contributor(s):
          24                 :  *   Pierre Phaneuf <pp@ludusdesign.com>
          25                 :  *   Jacek Piskozub <piskozub@iopan.gda.pl>
          26                 :  *   Leon Sha <leon.sha@sun.com>
          27                 :  *   Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
          28                 :  *   Robert O'Callahan <roc+moz@cs.cmu.edu>
          29                 :  *   Christian Biesinger <cbiesinger@web.de>
          30                 :  *   Josh Aas <josh@mozilla.com>
          31                 :  *   Mats Palmgren <matspal@gmail.com>
          32                 :  *
          33                 :  * Alternatively, the contents of this file may be used under the terms of
          34                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          35                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          36                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          37                 :  * of those above. If you wish to allow use of your version of this file only
          38                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          39                 :  * use your version of this file under the terms of the MPL, indicate your
          40                 :  * decision by deleting the provisions above and replace them with the notice
          41                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          42                 :  * the provisions above, a recipient may use your version of this file under
          43                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          44                 :  *
          45                 :  * ***** END LICENSE BLOCK ***** */
          46                 :
          47                 : /* rendering objects for replaced elements implemented by a plugin */
          48                 :
          49                 : #include "mozilla/plugins/PluginMessageUtils.h"
          50                 :
          51                 : #include "nscore.h"
          52                 : #include "nsCOMPtr.h"
          53                 : #include "nsPresContext.h"
          54                 : #include "nsIPresShell.h"
          55                 : #include "nsWidgetsCID.h"
          56                 : #include "nsIView.h"
          57                 : #include "nsIViewManager.h"
          58                 : #include "nsIDOMEventListener.h"
          59                 : #include "nsIDOMDragEvent.h"
          60                 : #include "nsPluginHost.h"
          61                 : #include "nsString.h"
          62                 : #include "nsReadableUtils.h"
          63                 : #include "prmem.h"
          64                 : #include "nsGkAtoms.h"
          65                 : #include "nsIAppShell.h"
          66                 : #include "nsIDocument.h"
          67                 : #include "nsINodeInfo.h"
          68                 : #include "nsIURL.h"
          69                 : #include "nsNetUtil.h"
          70                 : #include "nsIPluginInstanceOwner.h"
          71                 : #include "nsNPAPIPluginInstance.h"
          72                 : #include "nsIPluginTagInfo.h"
          73                 : #include "plstr.h"
          74                 : #include "nsILinkHandler.h"
          75                 : #include "nsIScrollPositionListener.h"
          76                 : #include "nsITimer.h"
          77                 : #include "nsIDocShellTreeItem.h"
          78                 : #include "nsIDocShellTreeOwner.h"
          79                 : #include "nsDocShellCID.h"
          80                 : #include "nsIWebBrowserChrome.h"
          81                 : #include "nsIDOMElement.h"
          82                 : #include "nsIDOMNodeList.h"
          83                 : #include "nsIDOMHTMLObjectElement.h"
          84                 : #include "nsIDOMHTMLEmbedElement.h"
          85                 : #include "nsIDOMHTMLAppletElement.h"
          86                 : #include "nsIDOMWindow.h"
          87                 : #include "nsIDOMEventTarget.h"
          88                 : #include "nsIDOMNSEvent.h"
          89                 : #include "nsIPrivateDOMEvent.h"
          90                 : #include "nsIDocumentEncoder.h"
          91                 : #include "nsXPIDLString.h"
          92                 : #include "nsIDOMRange.h"
          93                 : #include "nsIPluginWidget.h"
          94                 : #include "nsGUIEvent.h"
          95                 : #include "nsRenderingContext.h"
          96                 : #include "npapi.h"
          97                 : #include "nsTransform2D.h"
          98                 : #include "nsIImageLoadingContent.h"
          99                 : #include "nsIObjectLoadingContent.h"
         100                 : #include "nsPIDOMWindow.h"
         101                 : #include "nsContentUtils.h"
         102                 : #include "nsDisplayList.h"
         103                 : #include "nsAttrName.h"
         104                 : #include "nsDataHashtable.h"
         105                 : #include "nsDOMClassInfo.h"
         106                 : #include "nsFocusManager.h"
         107                 : #include "nsLayoutUtils.h"
         108                 : #include "nsFrameManager.h"
         109                 : #include "nsComponentManagerUtils.h"
         110                 : #include "nsIObserverService.h"
         111                 : #include "nsIScrollableFrame.h"
         112                 : #include "mozilla/Preferences.h"
         113                 : #include "sampler.h"
         114                 :
         115                 : // headers for plugin scriptability
         116                 : #include "nsIScriptGlobalObject.h"
         117                 : #include "nsIScriptContext.h"
         118                 : #include "nsIXPConnect.h"
         119                 : #include "nsIXPCScriptable.h"
         120                 : #include "nsIClassInfo.h"
         121                 : #include "nsIDOMClientRect.h"
         122                 :
         123                 : #include "nsObjectFrame.h"
         124                 : #include "nsIObjectFrame.h"
         125                 : #include "nsPluginNativeWindow.h"
         126                 : #include "nsIPluginDocument.h"
         127                 : #include "FrameLayerBuilder.h"
         128                 :
         129                 : #include "nsThreadUtils.h"
         130                 :
         131                 : #include "gfxContext.h"
         132                 : #include "gfxPlatform.h"
         133                 :
         134                 : #ifdef XP_WIN
         135                 : #include "gfxWindowsNativeDrawing.h"
         136                 : #include "gfxWindowsSurface.h"
         137                 : #endif
         138                 :
         139                 : #include "gfxImageSurface.h"
         140                 : #include "gfxUtils.h"
         141                 : #include "Layers.h"
         142                 : #include "ReadbackLayer.h"
         143                 :
         144                 : // accessibility support
         145                 : #ifdef ACCESSIBILITY
         146                 : #include "nsAccessibilityService.h"
         147                 : #endif
         148                 :
         149                 : #ifdef MOZ_LOGGING
         150                 : #define FORCE_PR_LOG 1 /* Allow logging in the release build */
         151                 : #endif /* MOZ_LOGGING */
         152                 : #include "prlog.h"
         153                 :
         154                 : #include <errno.h>
         155                 :
         156                 : #include "nsContentCID.h"
         157                 : static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
         158                 :
         159                 : #ifdef XP_MACOSX
         160                 : #include "gfxQuartzNativeDrawing.h"
         161                 : #include "nsPluginUtilsOSX.h"
         162                 : #include "nsCoreAnimationSupport.h"
         163                 : #endif
         164                 :
         165                 : #ifdef MOZ_WIDGET_GTK2
         166                 : #include <gdk/gdk.h>
         167                 : #include <gdk/gdkx.h>
         168                 : #include <gtk/gtk.h>
         169                 : #include "gfxXlibNativeRenderer.h"
         170                 : #endif
         171                 :
         172                 : #ifdef MOZ_X11
         173                 : #include "mozilla/X11Util.h"
         174                 : using mozilla::DefaultXDisplay;
         175                 : #endif
         176                 :
         177                 : #ifdef XP_WIN
         178                 : #include <wtypes.h>
         179                 : #include <winuser.h>
         180                 : #endif
         181                 :
         182                 : #ifdef XP_OS2
         183                 : #define INCL_PM
         184                 : #define INCL_GPI
         185                 : #include <os2.h>
         186                 : #include "gfxOS2Surface.h"
         187                 : #endif
         188                 :
         189                 : #ifdef CreateEvent // Thank you MS.
         190                 : #undef CreateEvent
         191                 : #endif
         192                 :
         193                 : #ifdef PR_LOGGING
         194            1464 : static PRLogModuleInfo *nsObjectFrameLM = PR_NewLogModule("nsObjectFrame");
         195                 : #endif /* PR_LOGGING */
         196                 :
         197                 : #if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
         198                 :
         199                 : #define MAC_CARBON_PLUGINS
         200                 :
         201                 : // The header files QuickdrawAPI.h and QDOffscreen.h are missing on OS X 10.7
         202                 : // and up (though the QuickDraw APIs defined in them are still present) -- so
         203                 : // we need to supply the relevant parts of their contents here.  It's likely
         204                 : // that Apple will eventually remove the APIs themselves (probably in OS X
         205                 : // 10.8), so we need to make them weak imports, and test for their presence
         206                 : // before using them.
         207                 : extern "C" {
         208                 :   #if !defined(__QUICKDRAWAPI__)
         209                 :   extern void SetRect(
         210                 :     Rect * r,
         211                 :     short  left,
         212                 :     short  top,
         213                 :     short  right,
         214                 :     short  bottom)
         215                 :     __attribute__((weak_import));
         216                 :   #endif /* __QUICKDRAWAPI__ */
         217                 :
         218                 :   #if !defined(__QDOFFSCREEN__)
         219                 :   extern QDErr NewGWorldFromPtr(
         220                 :     GWorldPtr *   offscreenGWorld,
         221                 :     UInt32        PixelFormat,
         222                 :     const Rect *  boundsRect,
         223                 :     CTabHandle    cTable,                /* can be NULL */
         224                 :     GDHandle      aGDevice,              /* can be NULL */
         225                 :     GWorldFlags   flags,
         226                 :     Ptr           newBuffer,
         227                 :     SInt32        rowBytes)
         228                 :     __attribute__((weak_import));
         229                 :   extern void DisposeGWorld(GWorldPtr offscreenGWorld)
         230                 :     __attribute__((weak_import));
         231                 :   #endif /* __QDOFFSCREEN__ */
         232                 : }
         233                 :
         234                 : #endif /* #if defined(XP_MACOSX) && !defined(NP_NO_CARBON) */
         235                 :
         236                 : using namespace mozilla;
         237                 : using namespace mozilla::plugins;
         238                 : using namespace mozilla::layers;
         239                 :
         240                 : class PluginBackgroundSink : public ReadbackSink {
         241                 : public:
         242               0 :   PluginBackgroundSink(nsObjectFrame* aFrame, PRUint64 aStartSequenceNumber)
         243               0 :     : mLastSequenceNumber(aStartSequenceNumber), mFrame(aFrame) {}
         244               0 :   ~PluginBackgroundSink()
         245               0 :   {
         246               0 :     if (mFrame) {
         247               0 :       mFrame->mBackgroundSink = nsnull;
         248                 :     }
         249               0 :   }
         250                 :
         251               0 :   virtual void SetUnknown(PRUint64 aSequenceNumber)
         252                 :   {
         253               0 :     if (!AcceptUpdate(aSequenceNumber))
         254               0 :       return;
         255               0 :     mFrame->mInstanceOwner->SetBackgroundUnknown();
         256                 :   }
         257                 :
         258                 :   virtual already_AddRefed<gfxContext>
         259               0 :       BeginUpdate(const nsIntRect& aRect, PRUint64 aSequenceNumber)
         260                 :   {
         261               0 :     if (!AcceptUpdate(aSequenceNumber))
         262               0 :       return nsnull;
         263               0 :     return mFrame->mInstanceOwner->BeginUpdateBackground(aRect);
         264                 :   }
         265                 :
         266               0 :   virtual void EndUpdate(gfxContext* aContext, const nsIntRect& aRect)
         267                 :   {
         268               0 :     return mFrame->mInstanceOwner->EndUpdateBackground(aContext, aRect);
         269                 :   }
         270                 :
         271               0 :   void Destroy() { mFrame = nsnull; }
         272                 :
         273                 : protected:
         274               0 :   bool AcceptUpdate(PRUint64 aSequenceNumber) {
         275               0 :     if (aSequenceNumber > mLastSequenceNumber && mFrame &&
         276                 :         mFrame->mInstanceOwner) {
         277               0 :       mLastSequenceNumber = aSequenceNumber;
         278               0 :       return true;
         279                 :     }
         280               0 :     return false;
         281                 :   }
         282                 :
         283                 :   PRUint64 mLastSequenceNumber;
         284                 :   nsObjectFrame* mFrame;
         285                 : };
         286                 :
         287               0 : nsObjectFrame::nsObjectFrame(nsStyleContext* aContext)
         288                 :   : nsObjectFrameSuper(aContext)
         289               0 :   , mReflowCallbackPosted(false)
         290                 : {
         291               0 :   PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
         292                 :          ("Created new nsObjectFrame %p\n", this));
         293               0 : }
         294                 :
         295               0 : nsObjectFrame::~nsObjectFrame()
         296                 : {
         297               0 :   PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
         298                 :          ("nsObjectFrame %p deleted\n", this));
         299               0 : }
         300                 :
         301               0 : NS_QUERYFRAME_HEAD(nsObjectFrame)
         302               0 :   NS_QUERYFRAME_ENTRY(nsIObjectFrame)
         303               0 : NS_QUERYFRAME_TAIL_INHERITING(nsObjectFrameSuper)
         304                 :
         305                 : #ifdef ACCESSIBILITY
         306                 : already_AddRefed<nsAccessible>
         307               0 : nsObjectFrame::CreateAccessible()
         308                 : {
         309               0 :   nsAccessibilityService* accService = nsIPresShell::AccService();
         310                 :   return accService ?
         311                 :     accService->CreateHTMLObjectFrameAccessible(this, mContent,
         312               0 :                                                 PresContext()->PresShell()) :
         313               0 :     nsnull;
         314                 : }
         315                 :
         316                 : #ifdef XP_WIN
         317                 : NS_IMETHODIMP nsObjectFrame::GetPluginPort(HWND *aPort)
         318                 : {
         319                 :   *aPort = (HWND) mInstanceOwner->GetPluginPortFromWidget();
         320                 :   return NS_OK;
         321                 : }
         322                 : #endif
         323                 : #endif
         324                 :
         325                 : NS_IMETHODIMP
         326               0 : nsObjectFrame::Init(nsIContent*      aContent,
         327                 :                     nsIFrame*        aParent,
         328                 :                     nsIFrame*        aPrevInFlow)
         329                 : {
         330               0 :   PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
         331                 :          ("Initializing nsObjectFrame %p for content %p\n", this, aContent));
         332                 :
         333               0 :   nsresult rv = nsObjectFrameSuper::Init(aContent, aParent, aPrevInFlow);
         334                 :
         335               0 :   return rv;
         336                 : }
         337                 :
         338                 : void
         339               0 : nsObjectFrame::DestroyFrom(nsIFrame* aDestructRoot)
         340                 : {
         341               0 :   if (mReflowCallbackPosted) {
         342               0 :     PresContext()->PresShell()->CancelReflowCallback(this);
         343                 :   }
         344                 :
         345                 :   // Tell content owner of the instance to disconnect its frame.
         346               0 :   nsCOMPtr<nsIObjectLoadingContent> objContent(do_QueryInterface(mContent));
         347               0 :   NS_ASSERTION(objContent, "Why not an object loading content?");
         348               0 :   objContent->DisconnectFrame();
         349                 :
         350               0 :   if (mBackgroundSink) {
         351               0 :     mBackgroundSink->Destroy();
         352                 :   }
         353                 :
         354               0 :   if (mInstanceOwner) {
         355               0 :     mInstanceOwner->SetFrame(nsnull);
         356                 :   }
         357               0 :   SetInstanceOwner(nsnull);
         358                 :
         359               0 :   nsObjectFrameSuper::DestroyFrom(aDestructRoot);
         360               0 : }
         361                 :
         362                 : /* virtual */ void
         363               0 : nsObjectFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
         364                 : {
         365               0 :   if (HasView()) {
         366               0 :     nsIView* view = GetView();
         367               0 :     nsIViewManager* vm = view->GetViewManager();
         368               0 :     if (vm) {
         369                 :       nsViewVisibility visibility =
         370               0 :         IsHidden() ? nsViewVisibility_kHide : nsViewVisibility_kShow;
         371               0 :       vm->SetViewVisibility(view, visibility);
         372                 :     }
         373                 :   }
         374                 :
         375               0 :   nsObjectFrameSuper::DidSetStyleContext(aOldStyleContext);
         376               0 : }
         377                 :
         378                 : nsIAtom*
         379               0 : nsObjectFrame::GetType() const
         380                 : {
         381               0 :   return nsGkAtoms::objectFrame;
         382                 : }
         383                 :
         384                 : #ifdef DEBUG
         385                 : NS_IMETHODIMP
         386               0 : nsObjectFrame::GetFrameName(nsAString& aResult) const
         387                 : {
         388               0 :   return MakeFrameName(NS_LITERAL_STRING("ObjectFrame"), aResult);
         389                 : }
         390                 : #endif
         391                 :
         392                 : nsresult
         393               0 : nsObjectFrame::PrepForDrawing(nsIWidget *aWidget)
         394                 : {
         395               0 :   mWidget = aWidget;
         396                 :
         397               0 :   nsIView* view = GetView();
         398               0 :   NS_ASSERTION(view, "Object frames must have views");
         399               0 :   if (!view) {
         400               0 :     return NS_ERROR_FAILURE;
         401                 :   }
         402                 :
         403               0 :   nsIViewManager* viewMan = view->GetViewManager();
         404                 :   // mark the view as hidden since we don't know the (x,y) until Paint
         405                 :   // XXX is the above comment correct?
         406               0 :   viewMan->SetViewVisibility(view, nsViewVisibility_kHide);
         407                 :
         408                 :   //this is ugly. it was ripped off from didreflow(). MMP
         409                 :   // Position and size view relative to its parent, not relative to our
         410                 :   // parent frame (our parent frame may not have a view).
         411                 :
         412                 :   nsIView* parentWithView;
         413               0 :   nsPoint origin;
         414               0 :   nsRect r(0, 0, mRect.width, mRect.height);
         415                 :
         416               0 :   GetOffsetFromView(origin, &parentWithView);
         417               0 :   viewMan->ResizeView(view, r);
         418               0 :   viewMan->MoveViewTo(view, origin.x, origin.y);
         419                 :
         420               0 :   nsRootPresContext* rpc = PresContext()->GetRootPresContext();
         421               0 :   if (!rpc) {
         422               0 :     return NS_ERROR_FAILURE;
         423                 :   }
         424                 :
         425               0 :   if (mWidget) {
         426                 :     // XXX this breaks plugins in popups ... do we care?
         427               0 :     nsIWidget* parentWidget = rpc->PresShell()->FrameManager()->GetRootFrame()->GetNearestWidget();
         428               0 :     if (!parentWidget) {
         429               0 :       return NS_ERROR_FAILURE;
         430                 :     }
         431                 :
         432               0 :     mInnerView = viewMan->CreateView(GetContentRectRelativeToSelf(), view);
         433               0 :     if (!mInnerView) {
         434               0 :       NS_ERROR("Could not create inner view");
         435               0 :       return NS_ERROR_OUT_OF_MEMORY;
         436                 :     }
         437               0 :     viewMan->InsertChild(view, mInnerView, nsnull, true);
         438                 :
         439               0 :     mWidget->SetParent(parentWidget);
         440               0 :     mWidget->Show(true);
         441               0 :     mWidget->Enable(true);
         442                 :
         443                 :     // Set the plugin window to have an empty cliprect. The cliprect
         444                 :     // will be reset when nsRootPresContext::UpdatePluginGeometry
         445                 :     // runs later. The plugin window does need to have the correct
         446                 :     // size here. GetEmptyClipConfiguration will probably give it the
         447                 :     // size, but just in case we haven't been reflowed or something, set
         448                 :     // the size explicitly.
         449               0 :     nsAutoTArray<nsIWidget::Configuration,1> configuration;
         450               0 :     GetEmptyClipConfiguration(&configuration);
         451               0 :     NS_ASSERTION(configuration.Length() > 0, "Empty widget configuration array!");
         452               0 :     configuration[0].mBounds.width = mRect.width;
         453               0 :     configuration[0].mBounds.height = mRect.height;
         454               0 :     parentWidget->ConfigureChildren(configuration);
         455                 :
         456               0 :     nsRefPtr<nsDeviceContext> dx;
         457               0 :     viewMan->GetDeviceContext(*getter_AddRefs(dx));
         458               0 :     EVENT_CALLBACK eventHandler = mInnerView->AttachWidgetEventHandler(mWidget);
         459               0 :     mWidget->SetEventCallback(eventHandler, dx);
         460                 :
         461                 : #ifdef XP_MACOSX
         462                 :     // On Mac, we need to invalidate ourselves since even windowed
         463                 :     // plugins are painted through Thebes and we need to ensure
         464                 :     // the Thebes layer containing the plugin is updated.
         465                 :     if (parentWidget == GetNearestWidget()) {
         466                 :       Invalidate(GetContentRectRelativeToSelf());
         467                 :     }
         468                 : #endif
         469                 :
         470               0 :     rpc->RegisterPluginForGeometryUpdates(this);
         471               0 :     rpc->RequestUpdatePluginGeometry(this);
         472                 :
         473                 :     // Here we set the background color for this widget because some plugins will use
         474                 :     // the child window background color when painting. If it's not set, it may default to gray
         475                 :     // Sometimes, a frame doesn't have a background color or is transparent. In this
         476                 :     // case, walk up the frame tree until we do find a frame with a background color
         477               0 :     for (nsIFrame* frame = this; frame; frame = frame->GetParent()) {
         478                 :       nscolor bgcolor =
         479               0 :         frame->GetVisitedDependentColor(eCSSProperty_background_color);
         480               0 :       if (NS_GET_A(bgcolor) > 0) {  // make sure we got an actual color
         481               0 :         mWidget->SetBackgroundColor(bgcolor);
         482               0 :         break;
         483                 :       }
         484                 :     }
         485                 :   } else {
         486                 :     // Changing to windowless mode changes the NPWindow geometry.
         487               0 :     FixupWindow(GetContentRectRelativeToSelf().Size());
         488                 :
         489                 : #ifndef XP_MACOSX
         490               0 :     rpc->RegisterPluginForGeometryUpdates(this);
         491               0 :     rpc->RequestUpdatePluginGeometry(this);
         492                 : #endif
         493                 :   }
         494                 :
         495               0 :   if (!IsHidden()) {
         496               0 :     viewMan->SetViewVisibility(view, nsViewVisibility_kShow);
         497                 :   }
         498                 :
         499                 : #ifdef ACCESSIBILITY
         500               0 :   nsAccessibilityService* accService = nsIPresShell::AccService();
         501               0 :   if (accService) {
         502               0 :     accService->RecreateAccessible(PresContext()->PresShell(), mContent);
         503                 :   }
         504                 : #endif
         505                 :
         506               0 :   return NS_OK;
         507                 : }
         508                 :
         509                 : #define EMBED_DEF_WIDTH 240
         510                 : #define EMBED_DEF_HEIGHT 200
         511                 :
         512                 : /* virtual */ nscoord
         513               0 : nsObjectFrame::GetMinWidth(nsRenderingContext *aRenderingContext)
         514                 : {
         515               0 :   nscoord result = 0;
         516                 :
         517               0 :   if (!IsHidden(false)) {
         518               0 :     nsIAtom *atom = mContent->Tag();
         519               0 :     if (atom == nsGkAtoms::applet || atom == nsGkAtoms::embed) {
         520               0 :       result = nsPresContext::CSSPixelsToAppUnits(EMBED_DEF_WIDTH);
         521                 :     }
         522                 :   }
         523                 :
         524               0 :   DISPLAY_MIN_WIDTH(this, result);
         525               0 :   return result;
         526                 : }
         527                 :
         528                 : /* virtual */ nscoord
         529               0 : nsObjectFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
         530                 : {
         531               0 :   return nsObjectFrame::GetMinWidth(aRenderingContext);
         532                 : }
         533                 :
         534                 : void
         535               0 : nsObjectFrame::GetDesiredSize(nsPresContext* aPresContext,
         536                 :                               const nsHTMLReflowState& aReflowState,
         537                 :                               nsHTMLReflowMetrics& aMetrics)
         538                 : {
         539                 :   // By default, we have no area
         540               0 :   aMetrics.width = 0;
         541               0 :   aMetrics.height = 0;
         542                 :
         543               0 :   if (IsHidden(false)) {
         544               0 :     return;
         545                 :   }
         546                 :
         547               0 :   aMetrics.width = aReflowState.ComputedWidth();
         548               0 :   aMetrics.height = aReflowState.ComputedHeight();
         549                 :
         550                 :   // for EMBED and APPLET, default to 240x200 for compatibility
         551               0 :   nsIAtom *atom = mContent->Tag();
         552               0 :   if (atom == nsGkAtoms::applet || atom == nsGkAtoms::embed) {
         553               0 :     if (aMetrics.width == NS_UNCONSTRAINEDSIZE) {
         554               0 :       aMetrics.width = clamped(nsPresContext::CSSPixelsToAppUnits(EMBED_DEF_WIDTH),
         555                 :                                aReflowState.mComputedMinWidth,
         556               0 :                                aReflowState.mComputedMaxWidth);
         557                 :     }
         558               0 :     if (aMetrics.height == NS_UNCONSTRAINEDSIZE) {
         559               0 :       aMetrics.height = clamped(nsPresContext::CSSPixelsToAppUnits(EMBED_DEF_HEIGHT),
         560                 :                                 aReflowState.mComputedMinHeight,
         561               0 :                                 aReflowState.mComputedMaxHeight);
         562                 :     }
         563                 :
         564                 : #if defined (MOZ_WIDGET_GTK2)
         565                 :     // We need to make sure that the size of the object frame does not
         566                 :     // exceed the maximum size of X coordinates.  See bug #225357 for
         567                 :     // more information.  In theory Gtk2 can handle large coordinates,
         568                 :     // but underlying plugins can't.
         569               0 :     aMetrics.height = NS_MIN(aPresContext->DevPixelsToAppUnits(PR_INT16_MAX), aMetrics.height);
         570               0 :     aMetrics.width = NS_MIN(aPresContext->DevPixelsToAppUnits(PR_INT16_MAX), aMetrics.width);
         571                 : #endif
         572                 :   }
         573                 :
         574                 :   // At this point, the width has an unconstrained value only if we have
         575                 :   // nothing to go on (no width set, no information from the plugin, nothing).
         576                 :   // Make up a number.
         577               0 :   if (aMetrics.width == NS_UNCONSTRAINEDSIZE) {
         578                 :     aMetrics.width =
         579                 :       (aReflowState.mComputedMinWidth != NS_UNCONSTRAINEDSIZE) ?
         580               0 :         aReflowState.mComputedMinWidth : 0;
         581                 :   }
         582                 :
         583                 :   // At this point, the height has an unconstrained value only in two cases:
         584                 :   // a) We are in standards mode with percent heights and parent is auto-height
         585                 :   // b) We have no height information at all.
         586                 :   // In either case, we have to make up a number.
         587               0 :   if (aMetrics.height == NS_UNCONSTRAINEDSIZE) {
         588                 :     aMetrics.height =
         589                 :       (aReflowState.mComputedMinHeight != NS_UNCONSTRAINEDSIZE) ?
         590               0 :         aReflowState.mComputedMinHeight : 0;
         591                 :   }
         592                 :
         593                 :   // XXXbz don't add in the border and padding, because we screw up our
         594                 :   // plugin's size and positioning if we do...  Eventually we _do_ want to
         595                 :   // paint borders, though!  At that point, we will need to adjust the desired
         596                 :   // size either here or in Reflow....  Further, we will need to fix Paint() to
         597                 :   // call the superclass in all cases.
         598                 : }
         599                 :
         600                 : NS_IMETHODIMP
         601               0 : nsObjectFrame::Reflow(nsPresContext*           aPresContext,
         602                 :                       nsHTMLReflowMetrics&     aMetrics,
         603                 :                       const nsHTMLReflowState& aReflowState,
         604                 :                       nsReflowStatus&          aStatus)
         605                 : {
         606               0 :   DO_GLOBAL_REFLOW_COUNT("nsObjectFrame");
         607               0 :   DISPLAY_REFLOW(aPresContext, this, aReflowState, aMetrics, aStatus);
         608                 :
         609                 :   // Get our desired size
         610               0 :   GetDesiredSize(aPresContext, aReflowState, aMetrics);
         611               0 :   aMetrics.SetOverflowAreasToDesiredBounds();
         612               0 :   FinishAndStoreOverflow(&aMetrics);
         613                 :
         614                 :   // delay plugin instantiation until all children have
         615                 :   // arrived. Otherwise there may be PARAMs or other stuff that the
         616                 :   // plugin needs to see that haven't arrived yet.
         617               0 :   if (!GetContent()->IsDoneAddingChildren()) {
         618               0 :     aStatus = NS_FRAME_COMPLETE;
         619               0 :     return NS_OK;
         620                 :   }
         621                 :
         622                 :   // if we are printing or print previewing, bail for now
         623               0 :   if (aPresContext->Medium() == nsGkAtoms::print) {
         624               0 :     aStatus = NS_FRAME_COMPLETE;
         625               0 :     return NS_OK;
         626                 :   }
         627                 :
         628               0 :   nsRect r(0, 0, aMetrics.width, aMetrics.height);
         629               0 :   r.Deflate(aReflowState.mComputedBorderPadding);
         630                 :
         631               0 :   if (mInnerView) {
         632               0 :     nsIViewManager* vm = mInnerView->GetViewManager();
         633               0 :     vm->MoveViewTo(mInnerView, r.x, r.y);
         634               0 :     vm->ResizeView(mInnerView, nsRect(nsPoint(0, 0), r.Size()), true);
         635                 :   }
         636                 :
         637               0 :   FixupWindow(r.Size());
         638               0 :   if (!mReflowCallbackPosted) {
         639               0 :     mReflowCallbackPosted = true;
         640               0 :     aPresContext->PresShell()->PostReflowCallback(this);
         641                 :   }
         642                 :
         643               0 :   aStatus = NS_FRAME_COMPLETE;
         644                 :
         645               0 :   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics);
         646               0 :   return NS_OK;
         647                 : }
         648                 :
         649                 : ///////////// nsIReflowCallback ///////////////
         650                 :
         651                 : bool
         652               0 : nsObjectFrame::ReflowFinished()
         653                 : {
         654               0 :   mReflowCallbackPosted = false;
         655               0 :   CallSetWindow();
         656               0 :   return true;
         657                 : }
         658                 :
         659                 : void
         660               0 : nsObjectFrame::ReflowCallbackCanceled()
         661                 : {
         662               0 :   mReflowCallbackPosted = false;
         663               0 : }
         664                 :
         665                 : void
         666               0 : nsObjectFrame::FixupWindow(const nsSize& aSize)
         667                 : {
         668               0 :   nsPresContext* presContext = PresContext();
         669                 :
         670               0 :   if (!mInstanceOwner)
         671               0 :     return;
         672                 :
         673                 :   NPWindow *window;
         674               0 :   mInstanceOwner->GetWindow(window);
         675                 :
         676               0 :   NS_ENSURE_TRUE(window, /**/);
         677                 :
         678                 : #ifdef XP_MACOSX
         679                 :   nsWeakFrame weakFrame(this);
         680                 :   mInstanceOwner->FixUpPluginWindow(nsPluginInstanceOwner::ePluginPaintDisable);
         681                 :   if (!weakFrame.IsAlive()) {
         682                 :     return;
         683                 :   }
         684                 : #endif
         685                 :
         686               0 :   bool windowless = (window->type == NPWindowTypeDrawable);
         687                 :
         688               0 :   nsIntPoint origin = GetWindowOriginInPixels(windowless);
         689                 :
         690               0 :   window->x = origin.x;
         691               0 :   window->y = origin.y;
         692                 :
         693               0 :   window->width = presContext->AppUnitsToDevPixels(aSize.width);
         694               0 :   window->height = presContext->AppUnitsToDevPixels(aSize.height);
         695                 :
         696                 :   // on the Mac we need to set the clipRect to { 0, 0, 0, 0 } for now. This will keep
         697                 :   // us from drawing on screen until the widget is properly positioned, which will not
         698                 :   // happen until we have finished the reflow process.
         699                 : #ifdef XP_MACOSX
         700                 :   window->clipRect.top = 0;
         701                 :   window->clipRect.left = 0;
         702                 :   window->clipRect.bottom = 0;
         703                 :   window->clipRect.right = 0;
         704                 : #else
         705               0 :   mInstanceOwner->UpdateWindowPositionAndClipRect(false);
         706                 : #endif
         707                 :
         708               0 :   NotifyPluginReflowObservers();
         709                 : }
         710                 :
         711                 : nsresult
         712               0 : nsObjectFrame::CallSetWindow(bool aCheckIsHidden)
         713                 : {
         714               0 :   NPWindow *win = nsnull;
         715                 :
         716               0 :   nsresult rv = NS_ERROR_FAILURE;
         717               0 :   nsRefPtr<nsNPAPIPluginInstance> pi;
         718               0 :   if (!mInstanceOwner ||
         719               0 :       NS_FAILED(rv = mInstanceOwner->GetInstance(getter_AddRefs(pi))) ||
         720               0 :       !pi ||
         721               0 :       NS_FAILED(rv = mInstanceOwner->GetWindow(win)) ||
         722               0 :       !win)
         723               0 :     return rv;
         724                 :
         725               0 :   nsPluginNativeWindow *window = (nsPluginNativeWindow *)win;
         726                 : #ifdef XP_MACOSX
         727                 :   nsWeakFrame weakFrame(this);
         728                 :   mInstanceOwner->FixUpPluginWindow(nsPluginInstanceOwner::ePluginPaintDisable);
         729                 :   if (!weakFrame.IsAlive()) {
         730                 :     return NS_ERROR_NOT_AVAILABLE;
         731                 :   }
         732                 : #endif
         733                 :
         734               0 :   if (aCheckIsHidden && IsHidden())
         735               0 :     return NS_ERROR_FAILURE;
         736                 :
         737                 :   // refresh the plugin port as well
         738               0 :   window->window = mInstanceOwner->GetPluginPortFromWidget();
         739                 :
         740                 :   // Adjust plugin dimensions according to pixel snap results
         741                 :   // and reduce amount of SetWindow calls
         742               0 :   nsPresContext* presContext = PresContext();
         743               0 :   nsRootPresContext* rootPC = presContext->GetRootPresContext();
         744               0 :   if (!rootPC)
         745               0 :     return NS_ERROR_FAILURE;
         746               0 :   PRInt32 appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
         747               0 :   nsIFrame* rootFrame = rootPC->PresShell()->FrameManager()->GetRootFrame();
         748               0 :   nsRect bounds = GetContentRectRelativeToSelf() + GetOffsetToCrossDoc(rootFrame);
         749               0 :   nsIntRect intBounds = bounds.ToNearestPixels(appUnitsPerDevPixel);
         750               0 :   window->x = intBounds.x;
         751               0 :   window->y = intBounds.y;
         752               0 :   window->width = intBounds.width;
         753               0 :   window->height = intBounds.height;
         754                 :
         755                 :   // Calling SetWindow might destroy this frame. We need to use the instance
         756                 :   // owner to clean up so hold a ref.
         757               0 :   nsRefPtr<nsPluginInstanceOwner> instanceOwnerRef(mInstanceOwner);
         758                 :
         759                 :   // This will call pi->SetWindow and take care of window subclassing
         760                 :   // if needed, see bug 132759. Calling SetWindow can destroy this frame
         761                 :   // so check for that before doing anything else with this frame's memory.
         762               0 :   if (mInstanceOwner->UseAsyncRendering()) {
         763               0 :     rv = pi->AsyncSetWindow(window);
         764                 :   }
         765                 :   else {
         766               0 :     rv = window->CallSetWindow(pi);
         767                 :   }
         768                 :
         769               0 :   instanceOwnerRef->ReleasePluginPort(window->window);
         770                 :
         771               0 :   return rv;
         772                 : }
         773                 :
         774                 : void
         775               0 : nsObjectFrame::SetInstanceOwner(nsPluginInstanceOwner* aOwner)
         776                 : {
         777               0 :   mInstanceOwner = aOwner;
         778               0 :   if (!mInstanceOwner) {
         779               0 :     nsRootPresContext* rpc = PresContext()->GetRootPresContext();
         780               0 :     if (rpc) {
         781               0 :       if (mWidget) {
         782               0 :         if (mInnerView) {
         783               0 :           mInnerView->DetachWidgetEventHandler(mWidget);
         784                 :         }
         785                 :
         786               0 :         rpc->UnregisterPluginForGeometryUpdates(this);
         787                 :         // Make sure the plugin is hidden in case an update of plugin geometry
         788                 :         // hasn't happened since this plugin became hidden.
         789               0 :         nsIWidget* parent = mWidget->GetParent();
         790               0 :         if (parent) {
         791               0 :           nsTArray<nsIWidget::Configuration> configurations;
         792               0 :           this->GetEmptyClipConfiguration(&configurations);
         793               0 :           parent->ConfigureChildren(configurations);
         794                 :
         795               0 :           mWidget->Show(false);
         796               0 :           mWidget->Enable(false);
         797               0 :           mWidget->SetParent(nsnull);
         798                 :         }
         799                 :       } else {
         800                 : #ifndef XP_MACOSX
         801               0 :         rpc->UnregisterPluginForGeometryUpdates(this);
         802                 : #endif
         803                 :       }
         804                 :     }
         805                 :   }
         806               0 : }
         807                 :
         808                 : bool
         809               0 : nsObjectFrame::IsFocusable(PRInt32 *aTabIndex, bool aWithMouse)
         810                 : {
         811               0 :   if (aTabIndex)
         812               0 :     *aTabIndex = -1;
         813               0 :   return nsObjectFrameSuper::IsFocusable(aTabIndex, aWithMouse);
         814                 : }
         815                 :
         816                 : bool
         817               0 : nsObjectFrame::IsHidden(bool aCheckVisibilityStyle) const
         818                 : {
         819               0 :   if (aCheckVisibilityStyle) {
         820               0 :     if (!GetStyleVisibility()->IsVisibleOrCollapsed())
         821               0 :       return true;
         822                 :   }
         823                 :
         824                 :   // only <embed> tags support the HIDDEN attribute
         825               0 :   if (mContent->Tag() == nsGkAtoms::embed) {
         826                 :     // Yes, these are really the kooky ways that you could tell 4.x
         827                 :     // not to hide the <embed> once you'd put the 'hidden' attribute
         828                 :     // on the tag...
         829                 :
         830                 :     // HIDDEN w/ no attributes gets translated as we are hidden for
         831                 :     // compatibility w/ 4.x and IE so we don't create a non-painting
         832                 :     // widget in layout. See bug 188959.
         833               0 :     nsAutoString hidden;
         834               0 :     if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::hidden, hidden) &&
         835               0 :        (hidden.IsEmpty() ||
         836               0 :         (!hidden.LowerCaseEqualsLiteral("false") &&
         837               0 :          !hidden.LowerCaseEqualsLiteral("no") &&
         838               0 :          !hidden.LowerCaseEqualsLiteral("off")))) {
         839               0 :       return true;
         840                 :     }
         841                 :   }
         842                 :
         843               0 :   return false;
         844                 : }
         845                 :
         846               0 : nsIntPoint nsObjectFrame::GetWindowOriginInPixels(bool aWindowless)
         847                 : {
         848                 :   nsIView * parentWithView;
         849               0 :   nsPoint origin(0,0);
         850                 :
         851               0 :   GetOffsetFromView(origin, &parentWithView);
         852                 :
         853                 :   // if it's windowless, let's make sure we have our origin set right
         854                 :   // it may need to be corrected, like after scrolling
         855               0 :   if (aWindowless && parentWithView) {
         856               0 :     nsPoint offsetToWidget;
         857               0 :     parentWithView->GetNearestWidget(&offsetToWidget);
         858               0 :     origin += offsetToWidget;
         859                 :   }
         860               0 :   origin += GetContentRectRelativeToSelf().TopLeft();
         861                 :
         862                 :   return nsIntPoint(PresContext()->AppUnitsToDevPixels(origin.x),
         863               0 :                     PresContext()->AppUnitsToDevPixels(origin.y));
         864                 : }
         865                 :
         866                 : NS_IMETHODIMP
         867               0 : nsObjectFrame::DidReflow(nsPresContext*            aPresContext,
         868                 :                          const nsHTMLReflowState*  aReflowState,
         869                 :                          nsDidReflowStatus         aStatus)
         870                 : {
         871                 :   // Do this check before calling the superclass, as that clears
         872                 :   // NS_FRAME_FIRST_REFLOW
         873               0 :   if (aStatus == NS_FRAME_REFLOW_FINISHED &&
         874               0 :       (GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
         875               0 :     nsCOMPtr<nsIObjectLoadingContent> objContent(do_QueryInterface(mContent));
         876               0 :     NS_ASSERTION(objContent, "Why not an object loading content?");
         877               0 :     objContent->HasNewFrame(this);
         878                 :   }
         879                 :
         880               0 :   nsresult rv = nsObjectFrameSuper::DidReflow(aPresContext, aReflowState, aStatus);
         881                 :
         882                 :   // The view is created hidden; once we have reflowed it and it has been
         883                 :   // positioned then we show it.
         884               0 :   if (aStatus != NS_FRAME_REFLOW_FINISHED)
         885               0 :     return rv;
         886                 :
         887               0 :   if (HasView()) {
         888               0 :     nsIView* view = GetView();
         889               0 :     nsIViewManager* vm = view->GetViewManager();
         890               0 :     if (vm)
         891               0 :       vm->SetViewVisibility(view, IsHidden() ? nsViewVisibility_kHide : nsViewVisibility_kShow);
         892                 :   }
         893                 :
         894               0 :   return rv;
         895                 : }
         896                 :
         897                 : /* static */ void
         898               0 : nsObjectFrame::PaintPrintPlugin(nsIFrame* aFrame, nsRenderingContext* aCtx,
         899                 :                                 const nsRect& aDirtyRect, nsPoint aPt)
         900                 : {
         901               0 :   nsPoint pt = aPt + aFrame->GetContentRectRelativeToSelf().TopLeft();
         902               0 :   nsRenderingContext::AutoPushTranslation translate(aCtx, pt);
         903                 :   // FIXME - Bug 385435: Doesn't aDirtyRect need translating too?
         904               0 :   static_cast<nsObjectFrame*>(aFrame)->PrintPlugin(*aCtx, aDirtyRect);
         905               0 : }
         906                 :
         907                 : class nsDisplayPluginReadback : public nsDisplayItem {
         908                 : public:
         909               0 :   nsDisplayPluginReadback(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
         910               0 :     : nsDisplayItem(aBuilder, aFrame)
         911                 :   {
         912               0 :     MOZ_COUNT_CTOR(nsDisplayPluginReadback);
         913               0 :   }
         914                 : #ifdef NS_BUILD_REFCNT_LOGGING
         915               0 :   virtual ~nsDisplayPluginReadback() {
         916               0 :     MOZ_COUNT_DTOR(nsDisplayPluginReadback);
         917               0 :   }
         918                 : #endif
         919                 :
         920                 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
         921                 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
         922                 :                                    nsRegion* aVisibleRegion,
         923                 :                                    const nsRect& aAllowVisibleRegionExpansion);
         924                 :
         925               0 :   NS_DISPLAY_DECL_NAME("PluginReadback", TYPE_PLUGIN_READBACK)
         926                 :
         927               0 :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
         928                 :                                              LayerManager* aManager,
         929                 :                                              const ContainerParameters& aContainerParameters)
         930                 :   {
         931               0 :     return static_cast<nsObjectFrame*>(mFrame)->BuildLayer(aBuilder, aManager, this);
         932                 :   }
         933                 :
         934               0 :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
         935                 :                                    LayerManager* aManager)
         936                 :   {
         937               0 :     return LAYER_ACTIVE;
         938                 :   }
         939                 : };
         940                 :
         941                 : static nsRect
         942               0 : GetDisplayItemBounds(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem, nsIFrame* aFrame)
         943                 : {
         944                 :   // XXX For slightly more accurate region computations we should pixel-snap this
         945               0 :   return aFrame->GetContentRectRelativeToSelf() + aItem->ToReferenceFrame();
         946                 : }
         947                 :
         948                 : nsRect
         949               0 : nsDisplayPluginReadback::GetBounds(nsDisplayListBuilder* aBuilder)
         950                 : {
         951               0 :   return GetDisplayItemBounds(aBuilder, this, mFrame);
         952                 : }
         953                 :
         954                 : bool
         955               0 : nsDisplayPluginReadback::ComputeVisibility(nsDisplayListBuilder* aBuilder,
         956                 :                                            nsRegion* aVisibleRegion,
         957                 :                                            const nsRect& aAllowVisibleRegionExpansion)
         958                 : {
         959               0 :   if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
         960               0 :                                         aAllowVisibleRegionExpansion))
         961               0 :     return false;
         962                 :
         963               0 :   nsRect expand;
         964               0 :   expand.IntersectRect(aAllowVisibleRegionExpansion, GetBounds(aBuilder));
         965                 :   // *Add* our bounds to the visible region so that stuff underneath us is
         966                 :   // likely to be made visible, so we can use it for a background! This is
         967                 :   // a bit crazy since we normally only subtract from the visible region.
         968               0 :   aVisibleRegion->Or(*aVisibleRegion, expand);
         969               0 :   return true;
         970                 : }
         971                 :
         972                 : nsRect
         973               0 : nsDisplayPlugin::GetBounds(nsDisplayListBuilder* aBuilder)
         974                 : {
         975               0 :   return GetDisplayItemBounds(aBuilder, this, mFrame);
         976                 : }
         977                 :
         978                 : void
         979               0 : nsDisplayPlugin::Paint(nsDisplayListBuilder* aBuilder,
         980                 :                        nsRenderingContext* aCtx)
         981                 : {
         982               0 :   nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame);
         983               0 :   f->PaintPlugin(aBuilder, *aCtx, mVisibleRect, GetBounds(aBuilder));
         984               0 : }
         985                 :
         986                 : bool
         987               0 : nsDisplayPlugin::ComputeVisibility(nsDisplayListBuilder* aBuilder,
         988                 :                                    nsRegion* aVisibleRegion,
         989                 :                                    const nsRect& aAllowVisibleRegionExpansion)
         990                 : {
         991               0 :   mVisibleRegion.And(*aVisibleRegion, GetBounds(aBuilder));
         992                 :   return nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
         993               0 :                                           aAllowVisibleRegionExpansion);
         994                 : }
         995                 :
         996                 : nsRegion
         997               0 : nsDisplayPlugin::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
         998                 :                                  bool* aForceTransparentSurface)
         999                 : {
        1000               0 :   if (aForceTransparentSurface) {
        1001               0 :     *aForceTransparentSurface = false;
        1002                 :   }
        1003               0 :   nsRegion result;
        1004               0 :   nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame);
        1005               0 :   if (!aBuilder->IsForPluginGeometry()) {
        1006               0 :     nsIWidget* widget = f->GetWidget();
        1007               0 :     if (widget) {
        1008               0 :       nsTArray<nsIntRect> clip;
        1009               0 :       widget->GetWindowClipRegion(&clip);
        1010               0 :       nsTArray<nsIWidget::Configuration> configuration;
        1011               0 :       GetWidgetConfiguration(aBuilder, &configuration);
        1012               0 :       NS_ASSERTION(configuration.Length() == 1, "No configuration found");
        1013               0 :       if (clip != configuration[0].mClipRegion) {
        1014                 :         // Something has clipped us unexpectedly. Perhaps there is a translucent
        1015                 :         // chrome element overlaying us that forced us to be clipped away. Treat
        1016                 :         // us as non-opaque since we may have holes.
        1017                 :         return result;
        1018                 :       }
        1019                 :     }
        1020                 :   }
        1021               0 :   if (f->IsOpaque() &&
        1022               0 :       (aBuilder->IsForPluginGeometry() ||
        1023               0 :        (f->GetPaintedRect(this) + ToReferenceFrame()).Contains(GetBounds(aBuilder)))) {
        1024                 :     // We can treat this as opaque
        1025               0 :     result = GetBounds(aBuilder);
        1026                 :   }
        1027               0 :   return result;
        1028                 : }
        1029                 :
        1030                 : void
        1031               0 : nsDisplayPlugin::GetWidgetConfiguration(nsDisplayListBuilder* aBuilder,
        1032                 :                                         nsTArray<nsIWidget::Configuration>* aConfigurations)
        1033                 : {
        1034               0 :   nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame);
        1035               0 :   nsPoint pluginOrigin = mFrame->GetContentRectRelativeToSelf().TopLeft() +
        1036               0 :     ToReferenceFrame();
        1037               0 :   f->ComputeWidgetGeometry(mVisibleRegion, pluginOrigin, aConfigurations);
        1038               0 : }
        1039                 :
        1040                 : void
        1041               0 : nsObjectFrame::ComputeWidgetGeometry(const nsRegion& aRegion,
        1042                 :                                      const nsPoint& aPluginOrigin,
        1043                 :                                      nsTArray<nsIWidget::Configuration>* aConfigurations)
        1044                 : {
        1045               0 :   if (!mWidget) {
        1046                 : #ifndef XP_MACOSX
        1047               0 :     if (mInstanceOwner) {
        1048                 :       // UpdateWindowVisibility will notify the plugin of position changes
        1049                 :       // by updating the NPWindow and calling NPP_SetWindow/AsyncSetWindow.
        1050               0 :       mInstanceOwner->UpdateWindowVisibility(!aRegion.IsEmpty());
        1051                 :     }
        1052                 : #endif
        1053               0 :     return;
        1054                 :   }
        1055                 :
        1056               0 :   nsPresContext* presContext = PresContext();
        1057               0 :   nsRootPresContext* rootPC = presContext->GetRootPresContext();
        1058               0 :   if (!rootPC)
        1059               0 :     return;
        1060                 :
        1061               0 :   nsIWidget::Configuration* configuration = aConfigurations->AppendElement();
        1062               0 :   if (!configuration)
        1063               0 :     return;
        1064               0 :   configuration->mChild = mWidget;
        1065                 :
        1066               0 :   PRInt32 appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
        1067               0 :   nsIFrame* rootFrame = rootPC->PresShell()->FrameManager()->GetRootFrame();
        1068               0 :   nsRect bounds = GetContentRectRelativeToSelf() + GetOffsetToCrossDoc(rootFrame);
        1069               0 :   configuration->mBounds = bounds.ToNearestPixels(appUnitsPerDevPixel);
        1070                 :
        1071                 :   // This should produce basically the same rectangle (but not relative
        1072                 :   // to the root frame). We only call this here for the side-effect of
        1073                 :   // setting mViewToWidgetOffset on the view.
        1074               0 :   mInnerView->CalcWidgetBounds(eWindowType_plugin);
        1075                 :
        1076               0 :   nsRegionRectIterator iter(aRegion);
        1077               0 :   nsIntPoint pluginOrigin = aPluginOrigin.ToNearestPixels(appUnitsPerDevPixel);
        1078               0 :   for (const nsRect* r = iter.Next(); r; r = iter.Next()) {
        1079                 :     // Snap *r to pixels while it's relative to the painted widget, to
        1080                 :     // improve consistency with rectangle and image drawing
        1081                 :     nsIntRect pixRect =
        1082               0 :       r->ToNearestPixels(appUnitsPerDevPixel) - pluginOrigin;
        1083               0 :     if (!pixRect.IsEmpty()) {
        1084               0 :       configuration->mClipRegion.AppendElement(pixRect);
        1085                 :     }
        1086                 :   }
        1087                 : }
        1088                 :
        1089                 : nsresult
        1090               0 : nsObjectFrame::PluginEventNotifier::Run() {
        1091                 :   nsCOMPtr<nsIObserverService> obsSvc =
        1092               0 :     mozilla::services::GetObserverService();
        1093               0 :   obsSvc->NotifyObservers(nsnull, "plugin-changed-event", mEventType.get());
        1094               0 :   return NS_OK;
        1095                 : }
        1096                 :
        1097                 : void
        1098               0 : nsObjectFrame::NotifyPluginReflowObservers()
        1099                 : {
        1100               0 :   nsContentUtils::AddScriptRunner(new PluginEventNotifier(NS_LITERAL_STRING("reflow")));
        1101               0 : }
        1102                 :
        1103                 : void
        1104               0 : nsObjectFrame::DidSetWidgetGeometry()
        1105                 : {
        1106                 : #if defined(XP_MACOSX)
        1107                 :   if (mInstanceOwner) {
        1108                 :     mInstanceOwner->FixUpPluginWindow(nsPluginInstanceOwner::ePluginPaintEnable);
        1109                 :   }
        1110                 : #endif
        1111               0 : }
        1112                 :
        1113                 : bool
        1114               0 : nsObjectFrame::IsOpaque() const
        1115                 : {
        1116                 : #if defined(XP_MACOSX)
        1117                 :   // ???
        1118                 :   return false;
        1119                 : #else
        1120               0 :   return !IsTransparentMode();
        1121                 : #endif
        1122                 : }
        1123                 :
        1124                 : bool
        1125               0 : nsObjectFrame::IsTransparentMode() const
        1126                 : {
        1127                 : #if defined(XP_MACOSX)
        1128                 :   // ???
        1129                 :   return false;
        1130                 : #else
        1131               0 :   if (!mInstanceOwner)
        1132               0 :     return false;
        1133                 :
        1134               0 :   NPWindow *window = nsnull;
        1135               0 :   mInstanceOwner->GetWindow(window);
        1136               0 :   if (!window) {
        1137               0 :     return false;
        1138                 :   }
        1139                 :
        1140               0 :   if (window->type != NPWindowTypeDrawable)
        1141               0 :     return false;
        1142                 :
        1143                 :   nsresult rv;
        1144               0 :   nsRefPtr<nsNPAPIPluginInstance> pi;
        1145               0 :   rv = mInstanceOwner->GetInstance(getter_AddRefs(pi));
        1146               0 :   if (NS_FAILED(rv) || !pi)
        1147               0 :     return false;
        1148                 :
        1149               0 :   bool transparent = false;
        1150               0 :   pi->IsTransparent(&transparent);
        1151               0 :   return transparent;
        1152                 : #endif
        1153                 : }
        1154                 :
        1155                 : NS_IMETHODIMP
        1156               0 : nsObjectFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
        1157                 :                                 const nsRect&           aDirtyRect,
        1158                 :                                 const nsDisplayListSet& aLists)
        1159                 : {
        1160                 :   // XXX why are we painting collapsed object frames?
        1161               0 :   if (!IsVisibleOrCollapsedForPainting(aBuilder))
        1162               0 :     return NS_OK;
        1163                 :
        1164               0 :   nsresult rv = DisplayBorderBackgroundOutline(aBuilder, aLists);
        1165               0 :   NS_ENSURE_SUCCESS(rv, rv);
        1166                 :
        1167               0 :   nsPresContext::nsPresContextType type = PresContext()->Type();
        1168                 :
        1169                 :   // If we are painting in Print Preview do nothing....
        1170               0 :   if (type == nsPresContext::eContext_PrintPreview)
        1171               0 :     return NS_OK;
        1172                 :
        1173               0 :   DO_GLOBAL_REFLOW_COUNT_DSP("nsObjectFrame");
        1174                 :
        1175                 : #ifndef XP_MACOSX
        1176               0 :   if (mWidget && aBuilder->IsInTransform()) {
        1177                 :     // Windowed plugins should not be rendered inside a transform.
        1178               0 :     return NS_OK;
        1179                 :   }
        1180                 : #endif
        1181                 :
        1182               0 :   nsDisplayList replacedContent;
        1183                 :
        1184               0 :   if (aBuilder->IsForPainting() && mInstanceOwner && mInstanceOwner->UseAsyncRendering()) {
        1185               0 :     NPWindow* window = nsnull;
        1186               0 :     mInstanceOwner->GetWindow(window);
        1187               0 :     bool isVisible = window && window->width > 0 && window->height > 0;
        1188               0 :     if (isVisible && aBuilder->ShouldSyncDecodeImages()) {
        1189                 :   #ifndef XP_MACOSX
        1190               0 :       mInstanceOwner->UpdateWindowVisibility(true);
        1191                 :   #endif
        1192                 :     }
        1193                 :
        1194               0 :     nsRefPtr<ImageContainer> container = GetImageContainer();
        1195               0 :     if (container && container->HasCurrentImage() || !isVisible ||
        1196               0 :         container->GetCurrentSize() != gfxIntSize(window->width, window->height)) {
        1197               0 :       mInstanceOwner->NotifyPaintWaiter(aBuilder);
        1198                 :     }
        1199                 :   }
        1200                 :
        1201                 :   // determine if we are printing
        1202               0 :   if (type == nsPresContext::eContext_Print) {
        1203                 :     rv = replacedContent.AppendNewToTop(new (aBuilder)
        1204                 :         nsDisplayGeneric(aBuilder, this, PaintPrintPlugin, "PrintPlugin",
        1205               0 :                          nsDisplayItem::TYPE_PRINT_PLUGIN));
        1206                 :   } else {
        1207               0 :     if (aBuilder->IsPaintingToWindow() &&
        1208               0 :         GetLayerState(aBuilder, nsnull) == LAYER_ACTIVE &&
        1209               0 :         IsTransparentMode()) {
        1210                 :       rv = replacedContent.AppendNewToTop(new (aBuilder)
        1211               0 :           nsDisplayPluginReadback(aBuilder, this));
        1212               0 :       NS_ENSURE_SUCCESS(rv, rv);
        1213                 :     }
        1214                 :
        1215                 :     rv = replacedContent.AppendNewToTop(new (aBuilder)
        1216               0 :         nsDisplayPlugin(aBuilder, this));
        1217                 :   }
        1218               0 :   NS_ENSURE_SUCCESS(rv, rv);
        1219                 :
        1220               0 :   WrapReplacedContentForBorderRadius(aBuilder, &replacedContent, aLists);
        1221                 :
        1222               0 :   return NS_OK;
        1223                 : }
        1224                 :
        1225                 : #ifdef XP_OS2
        1226                 : static void *
        1227                 : GetPSFromRC(nsRenderingContext& aRenderingContext)
        1228                 : {
        1229                 :   nsRefPtr<gfxASurface>
        1230                 :     surf = aRenderingContext.ThebesContext()->CurrentSurface();
        1231                 :   if (!surf || surf->CairoStatus())
        1232                 :     return nsnull;
        1233                 :   return (void *)(static_cast<gfxOS2Surface*>
        1234                 :                   (static_cast<gfxASurface*>(surf.get()))->GetPS());
        1235                 : }
        1236                 : #endif
        1237                 :
        1238                 : void
        1239               0 : nsObjectFrame::PrintPlugin(nsRenderingContext& aRenderingContext,
        1240                 :                            const nsRect& aDirtyRect)
        1241                 : {
        1242               0 :   nsCOMPtr<nsIObjectLoadingContent> obj(do_QueryInterface(mContent));
        1243               0 :   if (!obj)
        1244                 :     return;
        1245                 :
        1246               0 :   nsIFrame* frame = nsnull;
        1247               0 :   obj->GetPrintFrame(&frame);
        1248               0 :   if (!frame)
        1249                 :     return;
        1250                 :
        1251               0 :   nsPresContext* presContext = PresContext();
        1252                 :   // make sure this is REALLY an nsIObjectFrame
        1253                 :   // we may need to go through the children to get it
        1254               0 :   nsIObjectFrame* objectFrame = do_QueryFrame(frame);
        1255               0 :   if (!objectFrame)
        1256               0 :     objectFrame = GetNextObjectFrame(presContext,frame);
        1257               0 :   if (!objectFrame)
        1258                 :     return;
        1259                 :
        1260                 :   // finally we can get our plugin instance
        1261               0 :   nsRefPtr<nsNPAPIPluginInstance> pi;
        1262               0 :   if (NS_FAILED(objectFrame->GetPluginInstance(getter_AddRefs(pi))) || !pi)
        1263                 :     return;
        1264                 :
        1265                 :   // now we need to setup the correct location for printing
        1266                 :   NPWindow window;
        1267               0 :   window.window = nsnull;
        1268                 :
        1269                 :   // prepare embedded mode printing struct
        1270                 :   NPPrint npprint;
        1271               0 :   npprint.mode = NP_EMBED;
        1272                 :
        1273                 :   // we need to find out if we are windowless or not
        1274               0 :   bool windowless = false;
        1275               0 :   pi->IsWindowless(&windowless);
        1276               0 :   window.type = windowless ? NPWindowTypeDrawable : NPWindowTypeWindow;
        1277                 :
        1278               0 :   window.clipRect.bottom = 0; window.clipRect.top = 0;
        1279               0 :   window.clipRect.left = 0; window.clipRect.right = 0;
        1280                 :
        1281                 : // platform specific printing code
        1282                 : #ifdef MAC_CARBON_PLUGINS
        1283                 :   // Don't use this code if any of the QuickDraw APIs it currently requires
        1284                 :   // are missing (as they probably will be on OS X 10.8 and up).
        1285                 :   if (!::SetRect || !::NewGWorldFromPtr || !::DisposeGWorld) {
        1286                 :     NS_WARNING("Cannot print plugin -- required QuickDraw APIs are missing!");
        1287                 :     return;
        1288                 :   }
        1289                 :
        1290                 :   nsSize contentSize = GetContentRectRelativeToSelf().Size();
        1291                 :   window.x = 0;
        1292                 :   window.y = 0;
        1293                 :   window.width = presContext->AppUnitsToDevPixels(contentSize.width);
        1294                 :   window.height = presContext->AppUnitsToDevPixels(contentSize.height);
        1295                 :
        1296                 :   gfxContext *ctx = aRenderingContext.ThebesContext();
        1297                 :   if (!ctx)
        1298                 :     return;
        1299                 :   gfxContextAutoSaveRestore save(ctx);
        1300                 :
        1301                 :   ctx->NewPath();
        1302                 :
        1303                 :   gfxRect rect(window.x, window.y, window.width, window.height);
        1304                 :
        1305                 :   ctx->Rectangle(rect);
        1306                 :   ctx->Clip();
        1307                 :
        1308                 :   gfxQuartzNativeDrawing nativeDraw(ctx, rect);
        1309                 :   CGContextRef cgContext = nativeDraw.BeginNativeDrawing();
        1310                 :   if (!cgContext) {
        1311                 :     nativeDraw.EndNativeDrawing();
        1312                 :     return;
        1313                 :   }
        1314                 :
        1315                 :   window.clipRect.right = window.width;
        1316                 :   window.clipRect.bottom = window.height;
        1317                 :   window.type = NPWindowTypeDrawable;
        1318                 :
        1319                 :   ::Rect gwBounds;
        1320                 :   ::SetRect(&gwBounds, 0, 0, window.width, window.height);
        1321                 :
        1322                 :   nsTArray<char> buffer(window.width * window.height * 4);
        1323                 :   CGColorSpaceRef cspace = ::CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
        1324                 :   if (!cspace) {
        1325                 :     nativeDraw.EndNativeDrawing();
        1326                 :     return;
        1327                 :   }
        1328                 :   CGContextRef cgBuffer =
        1329                 :     ::CGBitmapContextCreate(buffer.Elements(),
        1330                 :                             window.width, window.height, 8, window.width * 4,
        1331                 :                             cspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedFirst);
        1332                 :   ::CGColorSpaceRelease(cspace);
        1333                 :   if (!cgBuffer) {
        1334                 :     nativeDraw.EndNativeDrawing();
        1335                 :     return;
        1336                 :   }
        1337                 :   GWorldPtr gWorld;
        1338                 :   if (::NewGWorldFromPtr(&gWorld, k32ARGBPixelFormat, &gwBounds, NULL, NULL, 0,
        1339                 :                          buffer.Elements(), window.width * 4) != noErr) {
        1340                 :     ::CGContextRelease(cgBuffer);
        1341                 :     nativeDraw.EndNativeDrawing();
        1342                 :     return;
        1343                 :   }
        1344                 :
        1345                 :   window.clipRect.right = window.width;
        1346                 :   window.clipRect.bottom = window.height;
        1347                 :   window.type = NPWindowTypeDrawable;
        1348                 :   // Setting nsPluginPrint/NPPrint.print.embedPrint.window.window to
        1349                 :   // &GWorldPtr and nsPluginPrint/NPPrint.print.embedPrint.platformPrint to
        1350                 :   // GWorldPtr isn't any kind of standard (it's not documented anywhere).
        1351                 :   // But that's what WebKit does.  And it's what the Flash plugin (apparently
        1352                 :   // the only NPAPI plugin on OS X to support printing) seems to expect.  So
        1353                 :   // we do the same.  The Flash plugin uses the CoreGraphics drawing mode.
        1354                 :   // But a GWorldPtr should be usable in either CoreGraphics or QuickDraw
        1355                 :   // drawing mode.  See bug 191046.
        1356                 :   window.window = &gWorld;
        1357                 :   npprint.print.embedPrint.platformPrint = gWorld;
        1358                 :   npprint.print.embedPrint.window = window;
        1359                 :   pi->Print(&npprint);
        1360                 :
        1361                 :   ::CGContextTranslateCTM(cgContext, 0.0f, float(window.height));
        1362                 :   ::CGContextScaleCTM(cgContext, 1.0f, -1.0f);
        1363                 :   CGImageRef image = ::CGBitmapContextCreateImage(cgBuffer);
        1364                 :   if (!image) {
        1365                 :     ::CGContextRestoreGState(cgContext);
        1366                 :     ::CGContextRelease(cgBuffer);
        1367                 :     ::DisposeGWorld(gWorld);
        1368                 :     nativeDraw.EndNativeDrawing();
        1369                 :     return;
        1370                 :   }
        1371                 :   ::CGContextDrawImage(cgContext,
        1372                 :                        ::CGRectMake(0, 0, window.width, window.height),
        1373                 :                        image);
        1374                 :   ::CGImageRelease(image);
        1375                 :   ::CGContextRelease(cgBuffer);
        1376                 :
        1377                 :   ::DisposeGWorld(gWorld);
        1378                 :
        1379                 :   nativeDraw.EndNativeDrawing();
        1380                 : #elif defined(XP_UNIX)
        1381                 :
        1382                 :   /* XXX this just flat-out doesn't work in a thebes world --
        1383                 :    * RenderEPS is a no-op.  So don't bother to do any work here.
        1384                 :    */
        1385                 :   (void)window;
        1386                 :   (void)npprint;
        1387                 :
        1388                 : #elif defined(XP_OS2)
        1389                 :   void *hps = GetPSFromRC(aRenderingContext);
        1390                 :   if (!hps)
        1391                 :     return;
        1392                 :
        1393                 :   npprint.print.embedPrint.platformPrint = hps;
        1394                 :   npprint.print.embedPrint.window = window;
        1395                 :   // send off print info to plugin
        1396                 :   pi->Print(&npprint);
        1397                 : #elif defined(XP_WIN)
        1398                 :
        1399                 :   /* On Windows, we use the win32 printing surface to print.  This, in
        1400                 :    * turn, uses the Cairo paginated surface, which in turn uses the
        1401                 :    * meta surface to record all operations and then play them back.
        1402                 :    * This doesn't work too well for plugins, because if plugins render
        1403                 :    * directly into the DC, the meta surface won't have any knowledge
        1404                 :    * of them, and so at the end when it actually does the replay step,
        1405                 :    * it'll fill the background with white and draw over whatever was
        1406                 :    * rendered before.
        1407                 :    *
        1408                 :    * So, to avoid this, we use PushGroup, which creates a new windows
        1409                 :    * surface, the plugin renders to that, and then we use normal
        1410                 :    * cairo methods to composite that in such that it's recorded using the
        1411                 :    * meta surface.
        1412                 :    */
        1413                 :
        1414                 :   /* we'll already be translated into the right spot by gfxWindowsNativeDrawing */
        1415                 :   nsSize contentSize = GetContentRectRelativeToSelf().Size();
        1416                 :   window.x = 0;
        1417                 :   window.y = 0;
        1418                 :   window.width = presContext->AppUnitsToDevPixels(contentSize.width);
        1419                 :   window.height = presContext->AppUnitsToDevPixels(contentSize.height);
        1420                 :
        1421                 :   gfxContext *ctx = aRenderingContext.ThebesContext();
        1422                 :
        1423                 :   ctx->Save();
        1424                 :
        1425                 :   /* Make sure plugins don't do any damage outside of where they're supposed to */
        1426                 :   ctx->NewPath();
        1427                 :   gfxRect r(window.x, window.y, window.width, window.height);
        1428                 :   ctx->Rectangle(r);
        1429                 :   ctx->Clip();
        1430                 :
        1431                 :   gfxWindowsNativeDrawing nativeDraw(ctx, r);
        1432                 :   do {
        1433                 :     HDC dc = nativeDraw.BeginNativeDrawing();
        1434                 :     if (!dc)
        1435                 :       return;
        1436                 :
        1437                 :     // XXX don't we need to call nativeDraw.TransformToNativeRect here?
        1438                 :     npprint.print.embedPrint.platformPrint = dc;
        1439                 :     npprint.print.embedPrint.window = window;
        1440                 :     // send off print info to plugin
        1441                 :     pi->Print(&npprint);
        1442                 :
        1443                 :     nativeDraw.EndNativeDrawing();
        1444                 :   } while (nativeDraw.ShouldRenderAgain());
        1445                 :   nativeDraw.PaintToContext();
        1446                 :
        1447                 :   ctx->Restore();
        1448                 : #endif
        1449                 :
        1450                 :   // XXX Nav 4.x always sent a SetWindow call after print. Should we do the same?
        1451                 :   // XXX Calling DidReflow here makes no sense!!!
        1452               0 :   nsDidReflowStatus status = NS_FRAME_REFLOW_FINISHED; // should we use a special status?
        1453                 :   frame->DidReflow(presContext,
        1454               0 :                    nsnull, status);  // DidReflow will take care of it
        1455                 : }
        1456                 :
        1457                 : already_AddRefed<ImageContainer>
        1458               0 : nsObjectFrame::GetImageContainer()
        1459                 : {
        1460               0 :   nsRefPtr<ImageContainer> container = mImageContainer;
        1461                 :
        1462               0 :   if (container) {
        1463               0 :     return container.forget();
        1464                 :   }
        1465                 :
        1466               0 :   container = mImageContainer = LayerManager::CreateImageContainer();
        1467                 :
        1468               0 :   return container.forget();
        1469                 : }
        1470                 :
        1471                 : nsRect
        1472               0 : nsObjectFrame::GetPaintedRect(nsDisplayPlugin* aItem)
        1473                 : {
        1474               0 :   if (!mInstanceOwner)
        1475               0 :     return nsRect();
        1476               0 :   nsRect r = GetContentRectRelativeToSelf();
        1477               0 :   if (!mInstanceOwner->UseAsyncRendering())
        1478               0 :     return r;
        1479                 :
        1480               0 :   nsIntSize size = mInstanceOwner->GetCurrentImageSize();
        1481               0 :   nsPresContext* pc = PresContext();
        1482                 :   r.IntersectRect(r, nsRect(0, 0, pc->DevPixelsToAppUnits(size.width),
        1483               0 :                                   pc->DevPixelsToAppUnits(size.height)));
        1484               0 :   return r;
        1485                 : }
        1486                 :
        1487                 : void
        1488               0 : nsObjectFrame::UpdateImageLayer(const gfxRect& aRect)
        1489                 : {
        1490               0 :   if (!mInstanceOwner) {
        1491               0 :     return;
        1492                 :   }
        1493                 :
        1494                 : #ifdef XP_MACOSX
        1495                 :   if (!mInstanceOwner->UseAsyncRendering()) {
        1496                 :     mInstanceOwner->DoCocoaEventDrawRect(aRect, nsnull);
        1497                 :     // This makes sure the image on the container is up to date.
        1498                 :     // XXX - Eventually we probably just want to make sure DoCocoaEventDrawRect
        1499                 :     // updates the image container, to make this truly use 'push' semantics
        1500                 :     // too.
        1501                 :     mInstanceOwner->GetImageContainer();
        1502                 :   }
        1503                 : #endif
        1504                 : }
        1505                 :
        1506                 : LayerState
        1507               0 : nsObjectFrame::GetLayerState(nsDisplayListBuilder* aBuilder,
        1508                 :                              LayerManager* aManager)
        1509                 : {
        1510               0 :   if (!mInstanceOwner)
        1511               0 :     return LAYER_NONE;
        1512                 :
        1513                 : #ifdef XP_MACOSX
        1514                 :   if (!mInstanceOwner->UseAsyncRendering() &&
        1515                 :       mInstanceOwner->IsRemoteDrawingCoreAnimation() &&
        1516                 :       mInstanceOwner->GetEventModel() == NPEventModelCocoa) {
        1517                 :     return LAYER_ACTIVE;
        1518                 :   }
        1519                 : #endif
        1520                 :
        1521               0 :   if (!mInstanceOwner->UseAsyncRendering()) {
        1522               0 :     return LAYER_NONE;
        1523                 :   }
        1524                 :
        1525               0 :   return LAYER_ACTIVE;
        1526                 : }
        1527                 :
        1528                 : already_AddRefed<Layer>
        1529               0 : nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
        1530                 :                           LayerManager* aManager,
        1531                 :                           nsDisplayItem* aItem)
        1532                 : {
        1533               0 :   if (!mInstanceOwner)
        1534               0 :     return nsnull;
        1535                 :
        1536               0 :   NPWindow* window = nsnull;
        1537               0 :   mInstanceOwner->GetWindow(window);
        1538               0 :   if (!window)
        1539               0 :     return nsnull;
        1540                 :
        1541               0 :   if (window->width <= 0 || window->height <= 0)
        1542               0 :     return nsnull;
        1543                 :
        1544                 :   // Create image
        1545               0 :   nsRefPtr<ImageContainer> container = mInstanceOwner->GetImageContainer();
        1546                 :
        1547               0 :   if (!container) {
        1548                 :     // This can occur if our instance is gone.
        1549               0 :     return nsnull;
        1550                 :   }
        1551                 :
        1552               0 :   gfxIntSize size;
        1553                 :
        1554               0 :   if (mInstanceOwner->UseAsyncRendering()) {
        1555               0 :     size = container->GetCurrentSize();
        1556                 :   } else {
        1557               0 :     size = gfxIntSize(window->width, window->height);
        1558                 :   }
        1559                 :
        1560               0 :   nsRect area = GetContentRectRelativeToSelf() + aItem->ToReferenceFrame();
        1561               0 :   gfxRect r = nsLayoutUtils::RectToGfxRect(area, PresContext()->AppUnitsPerDevPixel());
        1562                 :   // to provide crisper and faster drawing.
        1563               0 :   r.Round();
        1564                 :   nsRefPtr<Layer> layer =
        1565               0 :     (aBuilder->LayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem));
        1566                 :
        1567               0 :   if (aItem->GetType() == nsDisplayItem::TYPE_PLUGIN) {
        1568               0 :     if (!layer) {
        1569               0 :       mInstanceOwner->NotifyPaintWaiter(aBuilder);
        1570                 :       // Initialize ImageLayer
        1571               0 :       layer = aManager->CreateImageLayer();
        1572               0 :       if (!layer)
        1573               0 :         return nsnull;
        1574                 :     }
        1575                 :
        1576               0 :     NS_ASSERTION(layer->GetType() == Layer::TYPE_IMAGE, "Bad layer type");
        1577                 :
        1578               0 :     ImageLayer* imglayer = static_cast<ImageLayer*>(layer.get());
        1579               0 :     UpdateImageLayer(r);
        1580                 :
        1581               0 :     if (!mInstanceOwner->UseAsyncRendering()) {
        1582               0 :       imglayer->SetScaleToSize(size, ImageLayer::SCALE_STRETCH);
        1583                 :     }
        1584               0 :     imglayer->SetContainer(container);
        1585                 :     gfxPattern::GraphicsFilter filter =
        1586               0 :       nsLayoutUtils::GetGraphicsFilterForFrame(this);
        1587                 : #ifdef MOZ_GFX_OPTIMIZE_MOBILE
        1588                 :     if (!aManager->IsCompositingCheap()) {
        1589                 :       // Pixman just horrible with bilinear filter scaling
        1590                 :       filter = gfxPattern::FILTER_NEAREST;
        1591                 :     }
        1592                 : #endif
        1593               0 :     imglayer->SetFilter(filter);
        1594                 :
        1595               0 :     layer->SetContentFlags(IsOpaque() ? Layer::CONTENT_OPAQUE : 0);
        1596                 :   } else {
        1597               0 :     NS_ASSERTION(aItem->GetType() == nsDisplayItem::TYPE_PLUGIN_READBACK,
        1598                 :                  "Unknown item type");
        1599               0 :     NS_ABORT_IF_FALSE(!IsOpaque(), "Opaque plugins don't use backgrounds");
        1600                 :
        1601               0 :     if (!layer) {
        1602               0 :       layer = aManager->CreateReadbackLayer();
        1603               0 :       if (!layer)
        1604               0 :         return nsnull;
        1605                 :     }
        1606               0 :     NS_ASSERTION(layer->GetType() == Layer::TYPE_READBACK, "Bad layer type");
        1607                 :
        1608               0 :     ReadbackLayer* readback = static_cast<ReadbackLayer*>(layer.get());
        1609               0 :     if (readback->GetSize() != nsIntSize(size.width, size.height)) {
        1610                 :       // This will destroy any old background sink and notify us that the
        1611                 :       // background is now unknown
        1612               0 :       readback->SetSink(nsnull);
        1613               0 :       readback->SetSize(nsIntSize(size.width, size.height));
        1614                 :
        1615               0 :       if (mBackgroundSink) {
        1616                 :         // Maybe we still have a background sink associated with another
        1617                 :         // readback layer that wasn't recycled for some reason? Unhook it
        1618                 :         // now so that if this frame goes away, it doesn't have a dangling
        1619                 :         // reference to us.
        1620               0 :         mBackgroundSink->Destroy();
        1621                 :       }
        1622                 :       mBackgroundSink =
        1623                 :         new PluginBackgroundSink(this,
        1624               0 :                                  readback->AllocateSequenceNumber());
        1625               0 :       readback->SetSink(mBackgroundSink);
        1626                 :       // The layer has taken ownership of our sink. When either the sink dies
        1627                 :       // or the frame dies, the connection from the surviving object is nulled out.
        1628                 :     }
        1629                 :   }
        1630                 :
        1631                 :   // Set a transform on the layer to draw the plugin in the right place
        1632               0 :   gfxMatrix transform;
        1633               0 :   transform.Translate(r.TopLeft());
        1634                 :
        1635               0 :   layer->SetTransform(gfx3DMatrix::From2D(transform));
        1636               0 :   layer->SetVisibleRegion(nsIntRect(0, 0, size.width, size.height));
        1637               0 :   return layer.forget();
        1638                 : }
        1639                 :
        1640                 : void
        1641               0 : nsObjectFrame::PaintPlugin(nsDisplayListBuilder* aBuilder,
        1642                 :                            nsRenderingContext& aRenderingContext,
        1643                 :                            const nsRect& aDirtyRect, const nsRect& aPluginRect)
        1644                 : {
        1645                 : #if defined(MOZ_WIDGET_ANDROID)
        1646                 :   if (mInstanceOwner) {
        1647                 :     NPWindow *window;
        1648                 :     mInstanceOwner->GetWindow(window);
        1649                 :
        1650                 :     gfxRect frameGfxRect =
        1651                 :       PresContext()->AppUnitsToGfxUnits(aPluginRect);
        1652                 :     gfxRect dirtyGfxRect =
        1653                 :       PresContext()->AppUnitsToGfxUnits(aDirtyRect);
        1654                 :     gfxContext* ctx = aRenderingContext.ThebesContext();
        1655                 :
        1656                 :     gfx3DMatrix matrix3d = nsLayoutUtils::GetTransformToAncestor(this, nsnull);
        1657                 :
        1658                 :     gfxMatrix matrix2d;
        1659                 :     if (!matrix3d.Is2D(&matrix2d))
        1660                 :       return;
        1661                 :
        1662                 :     // The matrix includes the frame's position, so we need to transform
        1663                 :     // from 0,0 to get the correct coordinates.
        1664                 :     frameGfxRect.MoveTo(0, 0);
        1665                 :
        1666                 :     mInstanceOwner->Paint(ctx, matrix2d.Transform(frameGfxRect), dirtyGfxRect);
        1667                 :     return;
        1668                 :   }
        1669                 : #endif
        1670                 :
        1671                 :   // Screen painting code
        1672                 : #if defined(XP_MACOSX)
        1673                 :   // delegate all painting to the plugin instance.
        1674                 :   if (mInstanceOwner) {
        1675                 :     if (mInstanceOwner->GetDrawingModel() == NPDrawingModelCoreGraphics ||
        1676                 :         mInstanceOwner->GetDrawingModel() == NPDrawingModelCoreAnimation ||
        1677                 :         mInstanceOwner->GetDrawingModel() ==
        1678                 :                                   NPDrawingModelInvalidatingCoreAnimation) {
        1679                 :       PRInt32 appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel();
        1680                 :       // Clip to the content area where the plugin should be drawn. If
        1681                 :       // we don't do this, the plugin can draw outside its bounds.
        1682                 :       nsIntRect contentPixels = aPluginRect.ToNearestPixels(appUnitsPerDevPixel);
        1683                 :       nsIntRect dirtyPixels = aDirtyRect.ToOutsidePixels(appUnitsPerDevPixel);
        1684                 :       nsIntRect clipPixels;
        1685                 :       clipPixels.IntersectRect(contentPixels, dirtyPixels);
        1686                 :
        1687                 :       // Don't invoke the drawing code if the clip is empty.
        1688                 :       if (clipPixels.IsEmpty())
        1689                 :         return;
        1690                 :
        1691                 :       gfxRect nativeClipRect(clipPixels.x, clipPixels.y,
        1692                 :                              clipPixels.width, clipPixels.height);
        1693                 :       gfxContext* ctx = aRenderingContext.ThebesContext();
        1694                 :
        1695                 :       gfxContextAutoSaveRestore save(ctx);
        1696                 :       ctx->NewPath();
        1697                 :       ctx->Rectangle(nativeClipRect);
        1698                 :       ctx->Clip();
        1699                 :       gfxPoint offset(contentPixels.x, contentPixels.y);
        1700                 :       ctx->Translate(offset);
        1701                 :
        1702                 :       gfxQuartzNativeDrawing nativeDrawing(ctx, nativeClipRect - offset);
        1703                 :
        1704                 :       CGContextRef cgContext = nativeDrawing.BeginNativeDrawing();
        1705                 :       if (!cgContext) {
        1706                 :         NS_WARNING("null CGContextRef during PaintPlugin");
        1707                 :         return;
        1708                 :       }
        1709                 :
        1710                 :       nsRefPtr<nsNPAPIPluginInstance> inst;
        1711                 :       GetPluginInstance(getter_AddRefs(inst));
        1712                 :       if (!inst) {
        1713                 :         NS_WARNING("null plugin instance during PaintPlugin");
        1714                 :         nativeDrawing.EndNativeDrawing();
        1715                 :         return;
        1716                 :       }
        1717                 :       NPWindow* window;
        1718                 :       mInstanceOwner->GetWindow(window);
        1719                 :       if (!window) {
        1720                 :         NS_WARNING("null plugin window during PaintPlugin");
        1721                 :         nativeDrawing.EndNativeDrawing();
        1722                 :         return;
        1723                 :       }
        1724                 :       NP_CGContext* cgPluginPortCopy =
        1725                 :                 static_cast<NP_CGContext*>(mInstanceOwner->GetPluginPortCopy());
        1726                 :       if (!cgPluginPortCopy) {
        1727                 :         NS_WARNING("null plugin port copy during PaintPlugin");
        1728                 :         nativeDrawing.EndNativeDrawing();
        1729                 :         return;
        1730                 :       }
        1731                 : #ifndef NP_NO_CARBON
        1732                 :       if (mInstanceOwner->GetEventModel() == NPEventModelCarbon &&
        1733                 :           !mInstanceOwner->SetPluginPortAndDetectChange()) {
        1734                 :         NS_WARNING("null plugin port during PaintPlugin");
        1735                 :         nativeDrawing.EndNativeDrawing();
        1736                 :         return;
        1737                 :       }
        1738                 :
        1739                 :       // In the Carbon event model...
        1740                 :       // If gfxQuartzNativeDrawing hands out a CGContext different from the
        1741                 :       // one set by SetPluginPortAndDetectChange(), we need to pass it to the
        1742                 :       // plugin via SetWindow().  This will happen in nsPluginInstanceOwner::
        1743                 :       // FixUpPluginWindow(), called from nsPluginInstanceOwner::Paint().
        1744                 :       // (If SetPluginPortAndDetectChange() made any changes itself, this has
        1745                 :       // already been detected in that method, and will likewise result in a
        1746                 :       // call to SetWindow() from FixUpPluginWindow().)
        1747                 :       NP_CGContext* windowContext = static_cast<NP_CGContext*>(window->window);
        1748                 :       if (mInstanceOwner->GetEventModel() == NPEventModelCarbon &&
        1749                 :           windowContext->context != cgContext) {
        1750                 :         windowContext->context = cgContext;
        1751                 :         cgPluginPortCopy->context = cgContext;
        1752                 :         mInstanceOwner->SetPluginPortChanged(true);
        1753                 :       }
        1754                 : #endif
        1755                 :
        1756                 :       mInstanceOwner->BeginCGPaint();
        1757                 :       if (mInstanceOwner->GetDrawingModel() == NPDrawingModelCoreAnimation ||
        1758                 :           mInstanceOwner->GetDrawingModel() ==
        1759                 :                                    NPDrawingModelInvalidatingCoreAnimation) {
        1760                 :         // CoreAnimation is updated, render the layer and perform a readback.
        1761                 :         mInstanceOwner->RenderCoreAnimation(cgContext, window->width, window->height);
        1762                 :       } else {
        1763                 :         mInstanceOwner->Paint(nativeClipRect - offset, cgContext);
        1764                 :       }
        1765                 :       mInstanceOwner->EndCGPaint();
        1766                 :
        1767                 :       nativeDrawing.EndNativeDrawing();
        1768                 :     } else {
        1769                 :       // FIXME - Bug 385435: Doesn't aDirtyRect need translating too?
        1770                 :       nsRenderingContext::AutoPushTranslation
        1771                 :         translate(&aRenderingContext, aPluginRect.TopLeft());
        1772                 :
        1773                 :       // this rect is used only in the CoreGraphics drawing model
        1774                 :       gfxRect tmpRect(0, 0, 0, 0);
        1775                 :       mInstanceOwner->Paint(tmpRect, NULL);
        1776                 :     }
        1777                 :   }
        1778                 : #elif defined(MOZ_X11)
        1779               0 :   if (mInstanceOwner) {
        1780                 :     NPWindow *window;
        1781               0 :     mInstanceOwner->GetWindow(window);
        1782               0 :     if (window->type == NPWindowTypeDrawable) {
        1783                 :       gfxRect frameGfxRect =
        1784               0 :         PresContext()->AppUnitsToGfxUnits(aPluginRect);
        1785                 :       gfxRect dirtyGfxRect =
        1786               0 :         PresContext()->AppUnitsToGfxUnits(aDirtyRect);
        1787               0 :       gfxContext* ctx = aRenderingContext.ThebesContext();
        1788                 :
        1789               0 :       mInstanceOwner->Paint(ctx, frameGfxRect, dirtyGfxRect);
        1790                 :     }
        1791                 :   }
        1792                 : #elif defined(XP_WIN)
        1793                 :   nsRefPtr<nsNPAPIPluginInstance> inst;
        1794                 :   GetPluginInstance(getter_AddRefs(inst));
        1795                 :   if (inst) {
        1796                 :     gfxRect frameGfxRect =
        1797                 :       PresContext()->AppUnitsToGfxUnits(aPluginRect);
        1798                 :     gfxRect dirtyGfxRect =
        1799                 :       PresContext()->AppUnitsToGfxUnits(aDirtyRect);
        1800                 :     gfxContext *ctx = aRenderingContext.ThebesContext();
        1801                 :     gfxMatrix currentMatrix = ctx->CurrentMatrix();
        1802                 :
        1803                 :     if (ctx->UserToDevicePixelSnapped(frameGfxRect, false)) {
        1804                 :       dirtyGfxRect = ctx->UserToDevice(dirtyGfxRect);
        1805                 :       ctx->IdentityMatrix();
        1806                 :     }
        1807                 :     dirtyGfxRect.RoundOut();
        1808                 :
        1809                 :     // Look if it's windowless
        1810                 :     NPWindow *window;
        1811                 :     mInstanceOwner->GetWindow(window);
        1812                 :
        1813                 :     if (window->type == NPWindowTypeDrawable) {
        1814                 :       // the offset of the DC
        1815                 :       nsPoint origin;
        1816                 :
        1817                 :       gfxWindowsNativeDrawing nativeDraw(ctx, frameGfxRect);
        1818                 :       if (nativeDraw.IsDoublePass()) {
        1819                 :         // OOP plugin specific: let the shim know before we paint if we are doing a
        1820                 :         // double pass render. If this plugin isn't oop, the register window message
        1821                 :         // will be ignored.
        1822                 :         NPEvent pluginEvent;
        1823                 :         pluginEvent.event = DoublePassRenderingEvent();
        1824                 :         pluginEvent.wParam = 0;
        1825                 :         pluginEvent.lParam = 0;
        1826                 :         if (pluginEvent.event)
        1827                 :           inst->HandleEvent(&pluginEvent, nsnull);
        1828                 :       }
        1829                 :       do {
        1830                 :         HDC hdc = nativeDraw.BeginNativeDrawing();
        1831                 :         if (!hdc)
        1832                 :           return;
        1833                 :
        1834                 :         RECT dest;
        1835                 :         nativeDraw.TransformToNativeRect(frameGfxRect, dest);
        1836                 :         RECT dirty;
        1837                 :         nativeDraw.TransformToNativeRect(dirtyGfxRect, dirty);
        1838                 :
        1839                 :         window->window = hdc;
        1840                 :         window->x = dest.left;
        1841                 :         window->y = dest.top;
        1842                 :         window->clipRect.left = 0;
        1843                 :         window->clipRect.top = 0;
        1844                 :         // if we're painting, we're visible.
        1845                 :         window->clipRect.right = window->width;
        1846                 :         window->clipRect.bottom = window->height;
        1847                 :
        1848                 :         // Windowless plugins on windows need a special event to update their location,
        1849                 :         // see bug 135737.
        1850                 :         //
        1851                 :         // bug 271442: note, the rectangle we send is now purely the bounds of the plugin
        1852                 :         // relative to the window it is contained in, which is useful for the plugin to
        1853                 :         // correctly translate mouse coordinates.
        1854                 :         //
        1855                 :         // this does not mesh with the comments for bug 135737 which imply that the rectangle
        1856                 :         // must be clipped in some way to prevent the plugin attempting to paint over areas
        1857                 :         // it shouldn't.
        1858                 :         //
        1859                 :         // since the two uses of the rectangle are mutually exclusive in some cases, and
        1860                 :         // since I don't see any incorrect painting (at least with Flash and ViewPoint -
        1861                 :         // the originator of bug 135737), it seems that windowless plugins are not relying
        1862                 :         // on information here for clipping their drawing, and we can safely use this message
        1863                 :         // to tell the plugin exactly where it is in all cases.
        1864                 :
        1865                 :         nsIntPoint origin = GetWindowOriginInPixels(true);
        1866                 :         nsIntRect winlessRect = nsIntRect(origin, nsIntSize(window->width, window->height));
        1867                 :
        1868                 :         if (!mWindowlessRect.IsEqualEdges(winlessRect)) {
        1869                 :           mWindowlessRect = winlessRect;
        1870                 :
        1871                 :           WINDOWPOS winpos;
        1872                 :           memset(&winpos, 0, sizeof(winpos));
        1873                 :           winpos.x = mWindowlessRect.x;
        1874                 :           winpos.y = mWindowlessRect.y;
        1875                 :           winpos.cx = mWindowlessRect.width;
        1876                 :           winpos.cy = mWindowlessRect.height;
        1877                 :
        1878                 :           // finally, update the plugin by sending it a WM_WINDOWPOSCHANGED event
        1879                 :           NPEvent pluginEvent;
        1880                 :           pluginEvent.event = WM_WINDOWPOSCHANGED;
        1881                 :           pluginEvent.wParam = 0;
        1882                 :           pluginEvent.lParam = (LPARAM)&winpos;
        1883                 :           inst->HandleEvent(&pluginEvent, nsnull);
        1884                 :         }
        1885                 :
        1886                 :         inst->SetWindow(window);
        1887                 :
        1888                 :         mInstanceOwner->Paint(dirty, hdc);
        1889                 :         nativeDraw.EndNativeDrawing();
        1890                 :       } while (nativeDraw.ShouldRenderAgain());
        1891                 :       nativeDraw.PaintToContext();
        1892                 :     }
        1893                 :
        1894                 :     ctx->SetMatrix(currentMatrix);
        1895                 :   }
        1896                 : #elif defined(XP_OS2)
        1897                 :   nsRefPtr<nsNPAPIPluginInstance> inst;
        1898                 :   GetPluginInstance(getter_AddRefs(inst));
        1899                 :   if (inst) {
        1900                 :     // Look if it's windowless
        1901                 :     NPWindow *window;
        1902                 :     mInstanceOwner->GetWindow(window);
        1903                 :
        1904                 :     if (window->type == NPWindowTypeDrawable) {
        1905                 :       // FIXME - Bug 385435: Doesn't aDirtyRect need translating too?
        1906                 :       nsRenderingContext::AutoPushTranslation
        1907                 :         translate(&aRenderingContext, aPluginRect.TopLeft());
        1908                 :
        1909                 :       // check if we need to call SetWindow with updated parameters
        1910                 :       bool doupdatewindow = false;
        1911                 :       // the offset of the DC
        1912                 :       nsIntPoint origin;
        1913                 :
        1914                 :       /*
        1915                 :        * Layout now has an optimized way of painting. Now we always get
        1916                 :        * a new drawing surface, sized to be just what's needed. Windowless
        1917                 :        * plugins need a transform applied to their origin so they paint
        1918                 :        * in the right place. Since |SetWindow| is no longer being used
        1919                 :        * to tell the plugin where it is, we dispatch a NPWindow through
        1920                 :        * |HandleEvent| to tell the plugin when its window moved
        1921                 :        */
        1922                 :       gfxContext *ctx = aRenderingContext.ThebesContext();
        1923                 :
        1924                 :       gfxMatrix ctxMatrix = ctx->CurrentMatrix();
        1925                 :       if (ctxMatrix.HasNonTranslation()) {
        1926                 :         // soo; in the future, we should be able to render
        1927                 :         // the object content to an offscreen DC, and then
        1928                 :         // composite it in with the right transforms.
        1929                 :
        1930                 :         // But, we don't bother doing that, because we don't
        1931                 :         // have the event handling story figured out yet.
        1932                 :         // Instead, let's just bail.
        1933                 :
        1934                 :         return;
        1935                 :       }
        1936                 :
        1937                 :       origin.x = NSToIntRound(float(ctxMatrix.GetTranslation().x));
        1938                 :       origin.y = NSToIntRound(float(ctxMatrix.GetTranslation().y));
        1939                 :
        1940                 :       /* Need to force the clip to be set */
        1941                 :       ctx->UpdateSurfaceClip();
        1942                 :
        1943                 :       /* Set the device offsets as appropriate, for whatever our current group offsets might be */
        1944                 :       gfxFloat xoff, yoff;
        1945                 :       nsRefPtr<gfxASurface> surf = ctx->CurrentSurface(&xoff, &yoff);
        1946                 :
        1947                 :       if (surf->CairoStatus() != 0) {
        1948                 :         NS_WARNING("Plugin is being asked to render to a surface that's in error!");
        1949                 :         return;
        1950                 :       }
        1951                 :
        1952                 :       // check if we need to update the PS
        1953                 :       HPS hps = (HPS)GetPSFromRC(aRenderingContext);
        1954                 :       if (reinterpret_cast<HPS>(window->window) != hps) {
        1955                 :         window->window = reinterpret_cast<void*>(hps);
        1956                 :         doupdatewindow = true;
        1957                 :       }
        1958                 :       LONG lPSid = GpiSavePS(hps);
        1959                 :       RECTL rclViewport;
        1960                 :       if (GpiQueryDevice(hps) != NULLHANDLE) { // ensure that we have an associated HDC
        1961                 :         if (GpiQueryPageViewport(hps, &rclViewport)) {
        1962                 :           rclViewport.xLeft += (LONG)xoff;
        1963                 :           rclViewport.xRight += (LONG)xoff;
        1964                 :           rclViewport.yBottom += (LONG)yoff;
        1965                 :           rclViewport.yTop += (LONG)yoff;
        1966                 :           GpiSetPageViewport(hps, &rclViewport);
        1967                 :         }
        1968                 :       }
        1969                 :
        1970                 :       if ((window->x != origin.x) || (window->y != origin.y)) {
        1971                 :         window->x = origin.x;
        1972                 :         window->y = origin.y;
        1973                 :         doupdatewindow = true;
        1974                 :       }
        1975                 :
        1976                 :       // if our location or visible area has changed, we need to tell the plugin
        1977                 :       if (doupdatewindow) {
        1978                 :         inst->SetWindow(window);
        1979                 :       }
        1980                 :
        1981                 :       mInstanceOwner->Paint(aDirtyRect, hps);
        1982                 :       if (lPSid >= 1) {
        1983                 :         GpiRestorePS(hps, lPSid);
        1984                 :       }
        1985                 :       surf->MarkDirty();
        1986                 :     }
        1987                 :   }
        1988                 : #endif
        1989               0 : }
        1990                 :
        1991                 : NS_IMETHODIMP
        1992               0 : nsObjectFrame::HandleEvent(nsPresContext* aPresContext,
        1993                 :                            nsGUIEvent*     anEvent,
        1994                 :                            nsEventStatus*  anEventStatus)
        1995                 : {
        1996               0 :   NS_ENSURE_ARG_POINTER(anEvent);
        1997               0 :   NS_ENSURE_ARG_POINTER(anEventStatus);
        1998               0 :   nsresult rv = NS_OK;
        1999                 :
        2000               0 :   if (!mInstanceOwner)
        2001               0 :     return NS_ERROR_NULL_POINTER;
        2002                 :
        2003               0 :   mInstanceOwner->ConsiderNewEventloopNestingLevel();
        2004                 :
        2005               0 :   if (anEvent->message == NS_PLUGIN_ACTIVATE) {
        2006               0 :     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
        2007               0 :     nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(GetContent());
        2008               0 :     if (fm && elem)
        2009               0 :       return fm->SetFocus(elem, 0);
        2010                 :   }
        2011               0 :   else if (anEvent->message == NS_PLUGIN_FOCUS) {
        2012               0 :     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
        2013               0 :     if (fm)
        2014               0 :       return fm->FocusPlugin(GetContent());
        2015                 :   }
        2016                 :
        2017               0 :   if (mInstanceOwner->SendNativeEvents() &&
        2018                 :       NS_IS_PLUGIN_EVENT(anEvent)) {
        2019               0 :     *anEventStatus = mInstanceOwner->ProcessEvent(*anEvent);
        2020               0 :     return rv;
        2021                 :   }
        2022                 :
        2023                 : #ifdef XP_WIN
        2024                 :   rv = nsObjectFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus);
        2025                 :   return rv;
        2026                 : #endif
        2027                 :
        2028                 : #ifdef XP_MACOSX
        2029                 :   // we want to process some native mouse events in the cocoa event model
        2030                 :   if ((anEvent->message == NS_MOUSE_ENTER || anEvent->message == NS_MOUSE_SCROLL) &&
        2031                 :       mInstanceOwner->GetEventModel() == NPEventModelCocoa) {
        2032                 :     *anEventStatus = mInstanceOwner->ProcessEvent(*anEvent);
        2033                 :     return rv;
        2034                 :   }
        2035                 : #endif
        2036                 :
        2037               0 :   if (anEvent->message == NS_DESTROY) {
        2038                 : #ifdef MAC_CARBON_PLUGINS
        2039                 :     mInstanceOwner->CancelTimer();
        2040                 : #endif
        2041               0 :     return rv;
        2042                 :   }
        2043                 :
        2044               0 :   return nsObjectFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus);
        2045                 : }
        2046                 :
        2047                 : #ifdef XP_MACOSX
        2048                 : // Needed to make the routing of mouse events while dragging conform to
        2049                 : // standard OS X practice, and to the Cocoa NPAPI spec.  See bug 525078.
        2050                 : NS_IMETHODIMP
        2051                 : nsObjectFrame::HandlePress(nsPresContext* aPresContext,
        2052                 :                            nsGUIEvent*    anEvent,
        2053                 :                            nsEventStatus* anEventStatus)
        2054                 : {
        2055                 :   nsIPresShell::SetCapturingContent(GetContent(), CAPTURE_IGNOREALLOWED);
        2056                 :   return nsObjectFrameSuper::HandlePress(aPresContext, anEvent, anEventStatus);
        2057                 : }
        2058                 : #endif
        2059                 :
        2060                 : nsresult
        2061               0 : nsObjectFrame::GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance)
        2062                 : {
        2063               0 :   *aPluginInstance = nsnull;
        2064                 :
        2065               0 :   if (!mInstanceOwner) {
        2066               0 :     return NS_OK;
        2067                 :   }
        2068                 :
        2069               0 :   return mInstanceOwner->GetInstance(aPluginInstance);
        2070                 : }
        2071                 :
        2072                 : NS_IMETHODIMP
        2073               0 : nsObjectFrame::GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor)
        2074                 : {
        2075               0 :   if (!mInstanceOwner) {
        2076               0 :     return NS_ERROR_FAILURE;
        2077                 :   }
        2078                 :
        2079               0 :   nsRefPtr<nsNPAPIPluginInstance> inst;
        2080               0 :   mInstanceOwner->GetInstance(getter_AddRefs(inst));
        2081               0 :   if (!inst) {
        2082               0 :     return NS_ERROR_FAILURE;
        2083                 :   }
        2084                 :
        2085               0 :   bool useDOMCursor = static_cast<nsNPAPIPluginInstance*>(inst.get())->UsesDOMForCursor();
        2086               0 :   if (!useDOMCursor) {
        2087               0 :     return NS_ERROR_FAILURE;
        2088                 :   }
        2089                 :
        2090               0 :   return nsObjectFrameSuper::GetCursor(aPoint, aCursor);
        2091                 : }
        2092                 :
        2093                 : void
        2094               0 : nsObjectFrame::SetIsDocumentActive(bool aIsActive)
        2095                 : {
        2096                 : #ifndef XP_MACOSX
        2097               0 :   if (mInstanceOwner) {
        2098               0 :     mInstanceOwner->UpdateDocumentActiveState(aIsActive);
        2099                 :   }
        2100                 : #endif
        2101               0 : }
        2102                 :
        2103                 : // static
        2104                 : nsIObjectFrame *
        2105               0 : nsObjectFrame::GetNextObjectFrame(nsPresContext* aPresContext, nsIFrame* aRoot)
        2106                 : {
        2107               0 :   nsIFrame* child = aRoot->GetFirstPrincipalChild();
        2108                 :
        2109               0 :   while (child) {
        2110               0 :     nsIObjectFrame* outFrame = do_QueryFrame(child);
        2111               0 :     if (outFrame) {
        2112               0 :       nsRefPtr<nsNPAPIPluginInstance> pi;
        2113               0 :       outFrame->GetPluginInstance(getter_AddRefs(pi));  // make sure we have a REAL plugin
        2114               0 :       if (pi)
        2115               0 :         return outFrame;
        2116                 :     }
        2117                 :
        2118               0 :     outFrame = GetNextObjectFrame(aPresContext, child);
        2119               0 :     if (outFrame)
        2120               0 :       return outFrame;
        2121               0 :     child = child->GetNextSibling();
        2122                 :   }
        2123                 :
        2124               0 :   return nsnull;
        2125                 : }
        2126                 :
        2127                 : /*static*/ void
        2128               0 : nsObjectFrame::BeginSwapDocShells(nsIContent* aContent, void*)
        2129                 : {
        2130               0 :   NS_PRECONDITION(aContent, "");
        2131                 :
        2132                 :   // This function is called from a document content enumerator so we need
        2133                 :   // to filter out the nsObjectFrames and ignore the rest.
        2134               0 :   nsIObjectFrame* obj = do_QueryFrame(aContent->GetPrimaryFrame());
        2135               0 :   if (!obj)
        2136               0 :     return;
        2137                 :
        2138               0 :   nsObjectFrame* objectFrame = static_cast<nsObjectFrame*>(obj);
        2139               0 :   NS_ASSERTION(!objectFrame->mWidget || objectFrame->mWidget->GetParent(),
        2140                 :                "Plugin windows must not be toplevel");
        2141               0 :   nsRootPresContext* rootPC = objectFrame->PresContext()->GetRootPresContext();
        2142               0 :   NS_ASSERTION(rootPC, "unable to unregister the plugin frame");
        2143               0 :   rootPC->UnregisterPluginForGeometryUpdates(objectFrame);
        2144                 : }
        2145                 :
        2146                 : /*static*/ void
        2147               0 : nsObjectFrame::EndSwapDocShells(nsIContent* aContent, void*)
        2148                 : {
        2149               0 :   NS_PRECONDITION(aContent, "");
        2150                 :
        2151                 :   // This function is called from a document content enumerator so we need
        2152                 :   // to filter out the nsObjectFrames and ignore the rest.
        2153               0 :   nsIObjectFrame* obj = do_QueryFrame(aContent->GetPrimaryFrame());
        2154               0 :   if (!obj)
        2155               0 :     return;
        2156                 :
        2157               0 :   nsObjectFrame* objectFrame = static_cast<nsObjectFrame*>(obj);
        2158               0 :   nsRootPresContext* rootPC = objectFrame->PresContext()->GetRootPresContext();
        2159               0 :   NS_ASSERTION(rootPC, "unable to register the plugin frame");
        2160               0 :   nsIWidget* widget = objectFrame->GetWidget();
        2161               0 :   if (widget) {
        2162                 :     // Reparent the widget.
        2163                 :     nsIWidget* parent =
        2164               0 :       rootPC->PresShell()->GetRootFrame()->GetNearestWidget();
        2165               0 :     widget->SetParent(parent);
        2166               0 :     objectFrame->CallSetWindow();
        2167                 :
        2168                 :     // Register for geometry updates and make a request.
        2169               0 :     rootPC->RegisterPluginForGeometryUpdates(objectFrame);
        2170               0 :     rootPC->RequestUpdatePluginGeometry(objectFrame);
        2171                 :   }
        2172                 : }
        2173                 :
        2174                 : nsIFrame*
        2175               0 : NS_NewObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
        2176                 : {
        2177               0 :   return new (aPresShell) nsObjectFrame(aContext);
        2178                 : }
        2179                 :
        2180                 : bool
        2181               0 : nsObjectFrame::PaintedByGecko()
        2182                 : {
        2183                 : #ifdef XP_MACOSX
        2184                 :   return true;
        2185                 : #else
        2186               0 :   return !mWidget;
        2187                 : #endif
        2188                 : }
        2189                 :
        2190            4392 : NS_IMPL_FRAMEARENA_HELPERS(nsObjectFrame)

Generated by: LCOV version 1.7