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