LCOV - code coverage report
Current view: top level - dom/plugins/base - nsPluginInstanceOwner.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 844 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 77 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifdef MOZ_X11
       8             : #include <cairo-xlib.h>
       9             : #include "gfxXlibSurface.h"
      10             : /* X headers suck */
      11             : enum { XKeyPress = KeyPress };
      12             : #include "mozilla/X11Util.h"
      13             : using mozilla::DefaultXDisplay;
      14             : #endif
      15             : 
      16             : #include "nsPluginInstanceOwner.h"
      17             : 
      18             : #include "gfxUtils.h"
      19             : #include "nsIRunnable.h"
      20             : #include "nsContentUtils.h"
      21             : #include "nsRect.h"
      22             : #include "nsSize.h"
      23             : #include "nsDisplayList.h"
      24             : #include "ImageLayers.h"
      25             : #include "GLImages.h"
      26             : #include "nsPluginFrame.h"
      27             : #include "nsIPluginDocument.h"
      28             : #include "nsIStringStream.h"
      29             : #include "nsNetUtil.h"
      30             : #include "mozilla/Preferences.h"
      31             : #include "nsILinkHandler.h"
      32             : #include "nsIDocShellTreeItem.h"
      33             : #include "nsIWebBrowserChrome.h"
      34             : #include "nsLayoutUtils.h"
      35             : #include "nsIPluginWidget.h"
      36             : #include "nsViewManager.h"
      37             : #include "nsIDocShellTreeOwner.h"
      38             : #include "nsIDOMHTMLObjectElement.h"
      39             : #include "nsIAppShell.h"
      40             : #include "nsIDOMHTMLAppletElement.h"
      41             : #include "nsIObjectLoadingContent.h"
      42             : #include "nsObjectLoadingContent.h"
      43             : #include "nsAttrName.h"
      44             : #include "nsIFocusManager.h"
      45             : #include "nsFocusManager.h"
      46             : #include "nsIDOMDragEvent.h"
      47             : #include "nsIScriptSecurityManager.h"
      48             : #include "nsIScrollableFrame.h"
      49             : #include "nsIDocShell.h"
      50             : #include "ImageContainer.h"
      51             : #include "nsIDOMHTMLCollection.h"
      52             : #include "GLContext.h"
      53             : #include "EGLUtils.h"
      54             : #include "nsIContentInlines.h"
      55             : #include "mozilla/MiscEvents.h"
      56             : #include "mozilla/MouseEvents.h"
      57             : #include "mozilla/TextEvents.h"
      58             : #include "mozilla/dom/Event.h"
      59             : #include "mozilla/dom/HTMLObjectElementBinding.h"
      60             : #include "mozilla/dom/TabChild.h"
      61             : #include "nsFrameSelection.h"
      62             : #include "PuppetWidget.h"
      63             : #include "nsPIWindowRoot.h"
      64             : #include "mozilla/IMEStateManager.h"
      65             : #include "mozilla/TextComposition.h"
      66             : #include "mozilla/AutoRestore.h"
      67             : 
      68             : #include "nsContentCID.h"
      69             : #include "nsWidgetsCID.h"
      70             : static NS_DEFINE_CID(kWidgetCID, NS_CHILD_CID);
      71             : static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
      72             : 
      73             : #ifdef XP_WIN
      74             : #include <wtypes.h>
      75             : #include <winuser.h>
      76             : #include "mozilla/widget/WinMessages.h"
      77             : #endif // #ifdef XP_WIN
      78             : 
      79             : #ifdef XP_MACOSX
      80             : #include "ComplexTextInputPanel.h"
      81             : #include "nsIDOMXULDocument.h"
      82             : #include "nsIDOMXULCommandDispatcher.h"
      83             : #endif
      84             : 
      85             : #ifdef MOZ_WIDGET_GTK
      86             : #include <gdk/gdk.h>
      87             : #include <gtk/gtk.h>
      88             : #endif
      89             : 
      90             : #ifdef MOZ_WIDGET_ANDROID
      91             : #include "ANPBase.h"
      92             : #include "AndroidBridge.h"
      93             : #include "ClientLayerManager.h"
      94             : #include "FennecJNIWrappers.h"
      95             : #include "nsWindow.h"
      96             : 
      97             : static nsPluginInstanceOwner* sFullScreenInstance = nullptr;
      98             : 
      99             : using namespace mozilla::dom;
     100             : 
     101             : #include <android/log.h>
     102             : #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
     103             : #endif
     104             : 
     105             : using namespace mozilla;
     106             : using namespace mozilla::dom;
     107             : using namespace mozilla::layers;
     108             : 
     109             : // special class for handeling DOM context menu events because for
     110             : // some reason it starves other mouse events if implemented on the
     111             : // same class
     112             : class nsPluginDOMContextMenuListener : public nsIDOMEventListener
     113             : {
     114             :   virtual ~nsPluginDOMContextMenuListener();
     115             : 
     116             : public:
     117             :   explicit nsPluginDOMContextMenuListener(nsIContent* aContent);
     118             : 
     119             :   NS_DECL_ISUPPORTS
     120             :   NS_DECL_NSIDOMEVENTLISTENER
     121             : 
     122             :   void Destroy(nsIContent* aContent);
     123             : 
     124             :   nsEventStatus ProcessEvent(const WidgetGUIEvent& anEvent)
     125             :   {
     126             :     return nsEventStatus_eConsumeNoDefault;
     127             :   }
     128             : };
     129             : 
     130           0 : class AsyncPaintWaitEvent : public Runnable
     131             : {
     132             : public:
     133           0 :   AsyncPaintWaitEvent(nsIContent* aContent, bool aFinished) :
     134             :     Runnable("AsyncPaintWaitEvent"),
     135             :     mContent(aContent),
     136           0 :     mFinished(aFinished)
     137             :   {
     138           0 :   }
     139             : 
     140           0 :   NS_IMETHOD Run() override
     141             :   {
     142           0 :     nsContentUtils::DispatchTrustedEvent(mContent->OwnerDoc(), mContent,
     143           0 :         mFinished ? NS_LITERAL_STRING("MozPaintWaitFinished") : NS_LITERAL_STRING("MozPaintWait"),
     144           0 :         true, true);
     145           0 :     return NS_OK;
     146             :   }
     147             : 
     148             : private:
     149             :   nsCOMPtr<nsIContent> mContent;
     150             :   bool                 mFinished;
     151             : };
     152             : 
     153             : void
     154           0 : nsPluginInstanceOwner::NotifyPaintWaiter(nsDisplayListBuilder* aBuilder)
     155             : {
     156             :   // This is notification for reftests about async plugin paint start
     157           0 :   if (!mWaitingForPaint && !IsUpToDate() && aBuilder->ShouldSyncDecodeImages()) {
     158           0 :     nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
     159           0 :     nsCOMPtr<nsIRunnable> event = new AsyncPaintWaitEvent(content, false);
     160             :     // Run this event as soon as it's safe to do so, since listeners need to
     161             :     // receive it immediately
     162           0 :     nsContentUtils::AddScriptRunner(event);
     163           0 :     mWaitingForPaint = true;
     164             :   }
     165           0 : }
     166             : 
     167             : #if MOZ_WIDGET_ANDROID
     168             : static void
     169             : AttachToContainerAsSurface(ImageContainer* container,
     170             :                            nsNPAPIPluginInstance* instance,
     171             :                            const LayoutDeviceRect& rect,
     172             :                            RefPtr<Image>* out_image)
     173             : {
     174             :   MOZ_ASSERT(out_image);
     175             :   MOZ_ASSERT(!*out_image);
     176             : 
     177             :   java::GeckoSurface::LocalRef surface = instance->AsSurface();
     178             :   if (!surface) {
     179             :     return;
     180             :   }
     181             : 
     182             :   RefPtr<Image> img = new SurfaceTextureImage(
     183             :     surface->GetHandle(),
     184             :     gfx::IntSize::Truncate(rect.width, rect.height),
     185             :     true, // continuously update without a transaction
     186             :     instance->OriginPos());
     187             :   *out_image = img;
     188             : }
     189             : #endif
     190             : 
     191             : bool
     192           0 : nsPluginInstanceOwner::NeedsScrollImageLayer()
     193             : {
     194             : #if defined(XP_WIN)
     195             :   // If this is a windowed plugin and we're doing layout in the content
     196             :   // process, force the creation of an image layer for the plugin. We'll
     197             :   // paint to this when scrolling.
     198             :   return XRE_IsContentProcess() &&
     199             :          mPluginWindow &&
     200             :          mPluginWindow->type == NPWindowTypeWindow;
     201             : #else
     202           0 :   return false;
     203             : #endif
     204             : }
     205             : 
     206             : already_AddRefed<ImageContainer>
     207           0 : nsPluginInstanceOwner::GetImageContainer()
     208             : {
     209           0 :   if (!mInstance)
     210           0 :     return nullptr;
     211             : 
     212           0 :   RefPtr<ImageContainer> container;
     213             : 
     214             : #if MOZ_WIDGET_ANDROID
     215             :   LayoutDeviceRect r = GetPluginRect();
     216             : 
     217             :   // NotifySize() causes Flash to do a bunch of stuff like ask for surfaces to render
     218             :   // into, set y-flip flags, etc, so we do this at the beginning.
     219             :   float resolution = mPluginFrame->PresContext()->PresShell()->GetCumulativeResolution();
     220             :   ScreenSize screenSize = (r * LayoutDeviceToScreenScale(resolution)).Size();
     221             :   mInstance->NotifySize(nsIntSize::Truncate(screenSize.width, screenSize.height));
     222             : 
     223             :   container = LayerManager::CreateImageContainer();
     224             : 
     225             :   if (r.width && r.height) {
     226             :     // Try to get it as an EGLImage first.
     227             :     RefPtr<Image> img;
     228             :     AttachToContainerAsSurface(container, mInstance, r, &img);
     229             : 
     230             :     if (img) {
     231             :       container->SetCurrentImageInTransaction(img);
     232             :     }
     233             :   }
     234             : #else
     235           0 :   if (NeedsScrollImageLayer()) {
     236             :     // windowed plugin under e10s
     237             : #if defined(XP_WIN)
     238             :     mInstance->GetScrollCaptureContainer(getter_AddRefs(container));
     239             : #endif
     240             :   } else {
     241             :     // async windowless rendering
     242           0 :     mInstance->GetImageContainer(getter_AddRefs(container));
     243             :   }
     244             : #endif
     245             : 
     246           0 :   return container.forget();
     247             : }
     248             : 
     249             : void
     250           0 : nsPluginInstanceOwner::DidComposite()
     251             : {
     252           0 :   if (mInstance) {
     253           0 :     mInstance->DidComposite();
     254             :   }
     255           0 : }
     256             : 
     257             : void
     258           0 : nsPluginInstanceOwner::SetBackgroundUnknown()
     259             : {
     260           0 :   if (mInstance) {
     261           0 :     mInstance->SetBackgroundUnknown();
     262             :   }
     263           0 : }
     264             : 
     265             : already_AddRefed<mozilla::gfx::DrawTarget>
     266           0 : nsPluginInstanceOwner::BeginUpdateBackground(const nsIntRect& aRect)
     267             : {
     268           0 :   nsIntRect rect = aRect;
     269           0 :   RefPtr<DrawTarget> dt;
     270           0 :   if (mInstance &&
     271           0 :       NS_SUCCEEDED(mInstance->BeginUpdateBackground(&rect, getter_AddRefs(dt)))) {
     272           0 :     return dt.forget();
     273             :   }
     274           0 :   return nullptr;
     275             : }
     276             : 
     277             : void
     278           0 : nsPluginInstanceOwner::EndUpdateBackground(const nsIntRect& aRect)
     279             : {
     280           0 :   nsIntRect rect = aRect;
     281           0 :   if (mInstance) {
     282           0 :     mInstance->EndUpdateBackground(&rect);
     283             :   }
     284           0 : }
     285             : 
     286             : bool
     287           0 : nsPluginInstanceOwner::UseAsyncRendering()
     288             : {
     289             : #ifdef XP_MACOSX
     290             :   if (mUseAsyncRendering) {
     291             :     return true;
     292             :   }
     293             : #endif
     294             : 
     295             :   bool isOOP;
     296           0 :   bool result = (mInstance &&
     297           0 :           NS_SUCCEEDED(mInstance->GetIsOOP(&isOOP)) && isOOP
     298             : #ifndef XP_MACOSX
     299           0 :           && (!mPluginWindow ||
     300           0 :            mPluginWindow->type == NPWindowTypeDrawable)
     301             : #endif
     302           0 :           );
     303             : 
     304             : #ifdef XP_MACOSX
     305             :   if (result) {
     306             :     mUseAsyncRendering = true;
     307             :   }
     308             : #endif
     309             : 
     310           0 :   return result;
     311             : }
     312             : 
     313             : nsIntSize
     314           0 : nsPluginInstanceOwner::GetCurrentImageSize()
     315             : {
     316           0 :   nsIntSize size(0,0);
     317           0 :   if (mInstance) {
     318           0 :     mInstance->GetImageSize(&size);
     319             :   }
     320           0 :   return size;
     321             : }
     322             : 
     323           0 : nsPluginInstanceOwner::nsPluginInstanceOwner()
     324           0 :   : mPluginWindow(nullptr)
     325             : {
     326             :   // create nsPluginNativeWindow object, it is derived from NPWindow
     327             :   // struct and allows to manipulate native window procedure
     328           0 :   nsCOMPtr<nsIPluginHost> pluginHostCOM = do_GetService(MOZ_PLUGIN_HOST_CONTRACTID);
     329           0 :   mPluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
     330           0 :   if (mPluginHost)
     331           0 :     mPluginHost->NewPluginNativeWindow(&mPluginWindow);
     332             : 
     333           0 :   mPluginFrame = nullptr;
     334           0 :   mWidgetCreationComplete = false;
     335             : #ifdef XP_MACOSX
     336             :   mSentInitialTopLevelWindowEvent = false;
     337             :   mLastWindowIsActive = false;
     338             :   mLastContentFocused = false;
     339             :   mLastScaleFactor = 1.0;
     340             :   mShouldBlurOnActivate = false;
     341             : #endif
     342           0 :   mLastCSSZoomFactor = 1.0;
     343           0 :   mContentFocused = false;
     344           0 :   mWidgetVisible = true;
     345           0 :   mPluginWindowVisible = false;
     346           0 :   mPluginDocumentActiveState = true;
     347           0 :   mLastMouseDownButtonType = -1;
     348             : 
     349             : #ifdef XP_MACOSX
     350             : #ifndef NP_NO_CARBON
     351             :   // We don't support Carbon, but it is still the default model for i386 NPAPI.
     352             :   mEventModel = NPEventModelCarbon;
     353             : #else
     354             :   mEventModel = NPEventModelCocoa;
     355             : #endif
     356             :   mUseAsyncRendering = false;
     357             : #endif
     358             : 
     359           0 :   mWaitingForPaint = false;
     360             : 
     361             : #ifdef MOZ_WIDGET_ANDROID
     362             :   mFullScreen = false;
     363             :   mJavaView = nullptr;
     364             : #endif
     365             : 
     366             : #ifdef XP_WIN
     367             :   mGotCompositionData = false;
     368             :   mSentStartComposition = false;
     369             :   mPluginDidNotHandleIMEComposition = false;
     370             : #endif
     371           0 : }
     372             : 
     373           0 : nsPluginInstanceOwner::~nsPluginInstanceOwner()
     374             : {
     375           0 :   if (mWaitingForPaint) {
     376           0 :     nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
     377           0 :     if (content) {
     378             :       // We don't care when the event is dispatched as long as it's "soon",
     379             :       // since whoever needs it will be waiting for it.
     380           0 :       nsCOMPtr<nsIRunnable> event = new AsyncPaintWaitEvent(content, true);
     381           0 :       NS_DispatchToMainThread(event);
     382             :     }
     383             :   }
     384             : 
     385           0 :   mPluginFrame = nullptr;
     386             : 
     387           0 :   PLUG_DeletePluginNativeWindow(mPluginWindow);
     388           0 :   mPluginWindow = nullptr;
     389             : 
     390             : #ifdef MOZ_WIDGET_ANDROID
     391             :   RemovePluginView();
     392             : #endif
     393             : 
     394           0 :   if (mInstance) {
     395           0 :     mInstance->SetOwner(nullptr);
     396             :   }
     397           0 : }
     398             : 
     399           0 : NS_IMPL_ISUPPORTS(nsPluginInstanceOwner,
     400             :                   nsIPluginInstanceOwner,
     401             :                   nsIDOMEventListener,
     402             :                   nsIPrivacyTransitionObserver,
     403             :                   nsIKeyEventInPluginCallback,
     404             :                   nsISupportsWeakReference)
     405             : 
     406             : nsresult
     407           0 : nsPluginInstanceOwner::SetInstance(nsNPAPIPluginInstance *aInstance)
     408             : {
     409           0 :   NS_ASSERTION(!mInstance || !aInstance, "mInstance should only be set or unset!");
     410             : 
     411             :   // If we're going to null out mInstance after use, be sure to call
     412             :   // mInstance->SetOwner(nullptr) here, since it now won't be called
     413             :   // from our destructor.  This fixes bug 613376.
     414           0 :   if (mInstance && !aInstance) {
     415           0 :     mInstance->SetOwner(nullptr);
     416             : 
     417             : #ifdef MOZ_WIDGET_ANDROID
     418             :     RemovePluginView();
     419             : #endif
     420             :   }
     421             : 
     422           0 :   mInstance = aInstance;
     423             : 
     424           0 :   nsCOMPtr<nsIDocument> doc;
     425           0 :   GetDocument(getter_AddRefs(doc));
     426           0 :   if (doc) {
     427           0 :     if (nsCOMPtr<nsPIDOMWindowOuter> domWindow = doc->GetWindow()) {
     428           0 :       nsCOMPtr<nsIDocShell> docShell = domWindow->GetDocShell();
     429           0 :       if (docShell)
     430           0 :         docShell->AddWeakPrivacyTransitionObserver(this);
     431             :     }
     432             :   }
     433             : 
     434           0 :   return NS_OK;
     435             : }
     436             : 
     437           0 : NS_IMETHODIMP nsPluginInstanceOwner::GetWindow(NPWindow *&aWindow)
     438             : {
     439           0 :   NS_ASSERTION(mPluginWindow, "the plugin window object being returned is null");
     440           0 :   aWindow = mPluginWindow;
     441           0 :   return NS_OK;
     442             : }
     443             : 
     444           0 : NS_IMETHODIMP nsPluginInstanceOwner::GetMode(int32_t *aMode)
     445             : {
     446           0 :   nsCOMPtr<nsIDocument> doc;
     447           0 :   nsresult rv = GetDocument(getter_AddRefs(doc));
     448           0 :   nsCOMPtr<nsIPluginDocument> pDoc (do_QueryInterface(doc));
     449             : 
     450           0 :   if (pDoc) {
     451           0 :     *aMode = NP_FULL;
     452             :   } else {
     453           0 :     *aMode = NP_EMBED;
     454             :   }
     455             : 
     456           0 :   return rv;
     457             : }
     458             : 
     459           0 : void nsPluginInstanceOwner::GetAttributes(nsTArray<MozPluginParameter>& attributes)
     460             : {
     461           0 :   nsCOMPtr<nsIObjectLoadingContent> content = do_QueryReferent(mContent);
     462             :   nsObjectLoadingContent *loadingContent =
     463           0 :     static_cast<nsObjectLoadingContent*>(content.get());
     464             : 
     465           0 :   loadingContent->GetPluginAttributes(attributes);
     466           0 : }
     467             : 
     468           0 : NS_IMETHODIMP nsPluginInstanceOwner::GetDOMElement(nsIDOMElement* *result)
     469             : {
     470           0 :   return CallQueryReferent(mContent.get(), result);
     471             : }
     472             : 
     473           0 : nsresult nsPluginInstanceOwner::GetInstance(nsNPAPIPluginInstance **aInstance)
     474             : {
     475           0 :   NS_ENSURE_ARG_POINTER(aInstance);
     476             : 
     477           0 :   *aInstance = mInstance;
     478           0 :   NS_IF_ADDREF(*aInstance);
     479           0 :   return NS_OK;
     480             : }
     481             : 
     482           0 : NS_IMETHODIMP nsPluginInstanceOwner::GetURL(const char *aURL,
     483             :                                             const char *aTarget,
     484             :                                             nsIInputStream *aPostStream,
     485             :                                             void *aHeadersData,
     486             :                                             uint32_t aHeadersDataLen,
     487             :                                             bool aDoCheckLoadURIChecks)
     488             : {
     489           0 :   nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
     490           0 :   if (!content) {
     491           0 :     return NS_ERROR_NULL_POINTER;
     492             :   }
     493             : 
     494           0 :   if (content->IsEditable()) {
     495           0 :     return NS_OK;
     496             :   }
     497             : 
     498           0 :   nsIDocument *doc = content->GetUncomposedDoc();
     499           0 :   if (!doc) {
     500           0 :     return NS_ERROR_FAILURE;
     501             :   }
     502             : 
     503           0 :   nsIPresShell *presShell = doc->GetShell();
     504           0 :   if (!presShell) {
     505           0 :     return NS_ERROR_FAILURE;
     506             :   }
     507             : 
     508           0 :   nsPresContext *presContext = presShell->GetPresContext();
     509           0 :   if (!presContext) {
     510           0 :     return NS_ERROR_FAILURE;
     511             :   }
     512             : 
     513             :   // the container of the pres context will give us the link handler
     514           0 :   nsCOMPtr<nsISupports> container = presContext->GetContainerWeak();
     515           0 :   NS_ENSURE_TRUE(container,NS_ERROR_FAILURE);
     516           0 :   nsCOMPtr<nsILinkHandler> lh = do_QueryInterface(container);
     517           0 :   NS_ENSURE_TRUE(lh, NS_ERROR_FAILURE);
     518             : 
     519           0 :   nsAutoString unitarget;
     520           0 :   if ((0 == PL_strcmp(aTarget, "newwindow")) ||
     521           0 :       (0 == PL_strcmp(aTarget, "_new"))) {
     522           0 :     unitarget.AssignASCII("_blank");
     523             :   }
     524           0 :   else if (0 == PL_strcmp(aTarget, "_current")) {
     525           0 :     unitarget.AssignASCII("_self");
     526             :   }
     527             :   else {
     528           0 :     unitarget.AssignASCII(aTarget); // XXX could this be nonascii?
     529             :   }
     530             : 
     531           0 :   nsCOMPtr<nsIURI> baseURI = GetBaseURI();
     532             : 
     533             :   // Create an absolute URL
     534           0 :   nsCOMPtr<nsIURI> uri;
     535           0 :   nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, baseURI);
     536           0 :   NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
     537             : 
     538           0 :   nsCOMPtr<nsIInputStream> headersDataStream;
     539           0 :   if (aPostStream && aHeadersData) {
     540           0 :     if (!aHeadersDataLen)
     541           0 :       return NS_ERROR_UNEXPECTED;
     542             : 
     543           0 :     nsCOMPtr<nsIStringInputStream> sis = do_CreateInstance("@mozilla.org/io/string-input-stream;1");
     544           0 :     if (!sis)
     545           0 :       return NS_ERROR_OUT_OF_MEMORY;
     546             : 
     547           0 :     rv = sis->SetData((char *)aHeadersData, aHeadersDataLen);
     548           0 :     NS_ENSURE_SUCCESS(rv, rv);
     549           0 :     headersDataStream = do_QueryInterface(sis);
     550             :   }
     551             : 
     552             :   int32_t blockPopups =
     553           0 :     Preferences::GetInt("privacy.popups.disable_from_plugins");
     554           0 :   nsAutoPopupStatePusher popupStatePusher((PopupControlState)blockPopups);
     555             : 
     556             : 
     557             :   // if security checks (in particular CheckLoadURIWithPrincipal) needs
     558             :   // to be skipped we are creating a codebasePrincipal to make sure
     559             :   // that security check succeeds. Please note that we do not want to
     560             :   // fall back to using the systemPrincipal, because that would also
     561             :   // bypass ContentPolicy checks which should still be enforced.
     562           0 :   nsCOMPtr<nsIPrincipal> triggeringPrincipal;
     563           0 :   if (!aDoCheckLoadURIChecks) {
     564             :     mozilla::OriginAttributes attrs =
     565           0 :       BasePrincipal::Cast(content->NodePrincipal())->OriginAttributesRef();
     566           0 :     triggeringPrincipal = BasePrincipal::CreateCodebasePrincipal(uri, attrs);
     567             :   }
     568             : 
     569           0 :   rv = lh->OnLinkClick(content, uri, unitarget.get(), NullString(),
     570           0 :                        aPostStream, headersDataStream, true, triggeringPrincipal);
     571             : 
     572           0 :   return rv;
     573             : }
     574             : 
     575           0 : NS_IMETHODIMP nsPluginInstanceOwner::GetDocument(nsIDocument* *aDocument)
     576             : {
     577           0 :   nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
     578           0 :   if (!aDocument || !content) {
     579           0 :     return NS_ERROR_NULL_POINTER;
     580             :   }
     581             : 
     582             :   // XXX sXBL/XBL2 issue: current doc or owner doc?
     583             :   // But keep in mind bug 322414 comment 33
     584           0 :   NS_IF_ADDREF(*aDocument = content->OwnerDoc());
     585           0 :   return NS_OK;
     586             : }
     587             : 
     588           0 : NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect)
     589             : {
     590             :   // If our object frame has gone away, we won't be able to determine
     591             :   // up-to-date-ness, so just fire off the event.
     592           0 :   if (mWaitingForPaint && (!mPluginFrame || IsUpToDate())) {
     593           0 :     nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
     594             :     // We don't care when the event is dispatched as long as it's "soon",
     595             :     // since whoever needs it will be waiting for it.
     596           0 :     nsCOMPtr<nsIRunnable> event = new AsyncPaintWaitEvent(content, true);
     597           0 :     NS_DispatchToMainThread(event);
     598           0 :     mWaitingForPaint = false;
     599             :   }
     600             : 
     601           0 :   if (!mPluginFrame || !invalidRect || !mWidgetVisible)
     602           0 :     return NS_ERROR_FAILURE;
     603             : 
     604             : #if defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID)
     605             :   // Each time an asynchronously-drawing plugin sends a new surface to display,
     606             :   // the image in the ImageContainer is updated and InvalidateRect is called.
     607             :   // There are different side effects for (sync) Android plugins.
     608             :   RefPtr<ImageContainer> container;
     609             :   mInstance->GetImageContainer(getter_AddRefs(container));
     610             : #endif
     611             : 
     612             : #ifndef XP_MACOSX
     613             :   // Invalidate for windowed plugins needs to work.
     614           0 :   if (mWidget) {
     615           0 :     mWidget->Invalidate(
     616           0 :       LayoutDeviceIntRect(invalidRect->left, invalidRect->top,
     617           0 :                           invalidRect->right - invalidRect->left,
     618           0 :                           invalidRect->bottom - invalidRect->top));
     619             :     // Plugin instances also call invalidate when plugin windows are hidden
     620             :     // during scrolling. In this case fall through so we invalidate the
     621             :     // underlying layer.
     622           0 :     if (!NeedsScrollImageLayer()) {
     623           0 :       return NS_OK;
     624             :     }
     625             :   }
     626             : #endif
     627           0 :   nsIntRect rect(invalidRect->left,
     628           0 :                  invalidRect->top,
     629           0 :                  invalidRect->right - invalidRect->left,
     630           0 :                  invalidRect->bottom - invalidRect->top);
     631             :   // invalidRect is in "display pixels".  In non-HiDPI modes "display pixels"
     632             :   // are device pixels.  But in HiDPI modes each display pixel corresponds
     633             :   // to more than one device pixel.
     634           0 :   double scaleFactor = 1.0;
     635           0 :   GetContentsScaleFactor(&scaleFactor);
     636           0 :   rect.ScaleRoundOut(scaleFactor);
     637           0 :   mPluginFrame->InvalidateLayer(nsDisplayItem::TYPE_PLUGIN, &rect);
     638           0 :   return NS_OK;
     639             : }
     640             : 
     641           0 : NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRegion(NPRegion invalidRegion)
     642             : {
     643           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     644             : }
     645             : 
     646             : NS_IMETHODIMP
     647           0 : nsPluginInstanceOwner::RedrawPlugin()
     648             : {
     649           0 :   if (mPluginFrame) {
     650           0 :     mPluginFrame->InvalidateLayer(nsDisplayItem::TYPE_PLUGIN);
     651             :   }
     652           0 :   return NS_OK;
     653             : }
     654             : 
     655             : #if defined(XP_WIN)
     656             : nsIWidget*
     657             : nsPluginInstanceOwner::GetContainingWidgetIfOffset()
     658             : {
     659             :   MOZ_ASSERT(mPluginFrame, "Caller should have checked for null mPluginFrame.");
     660             : 
     661             :   // This property is provided to allow a "windowless" plugin to determine the window it is drawing
     662             :   // in, so it can translate mouse coordinates it receives directly from the operating system
     663             :   // to coordinates relative to itself.
     664             : 
     665             :   // The original code returns the document's window, which is OK if the window the "windowless" plugin
     666             :   // is drawing into has the same origin as the document's window, but this is not the case for "windowless" plugins inside of scrolling DIVs etc
     667             : 
     668             :   // To make sure "windowless" plugins always get the right origin for translating mouse coordinates, this code
     669             :   // determines the window handle of the mozilla window containing the "windowless" plugin.
     670             : 
     671             :   // Given that this HWND may not be that of the document's window, there is a slight risk
     672             :   // of confusing a plugin that is using this HWND for illicit purposes, but since the documentation
     673             :   // does not suggest this HWND IS that of the document window, rather that of the window
     674             :   // the plugin is drawn in, this seems like a safe fix.
     675             : 
     676             :   // we only attempt to get the nearest window if this really is a "windowless" plugin so as not
     677             :   // to change any behaviour for the much more common windowed plugins,
     678             :   // though why this method would even be being called for a windowed plugin escapes me.
     679             :   if (!XRE_IsContentProcess() &&
     680             :       mPluginWindow && mPluginWindow->type == NPWindowTypeDrawable) {
     681             :     // it turns out that flash also uses this window for determining focus, and is currently
     682             :     // unable to show a caret correctly if we return the enclosing window. Therefore for
     683             :     // now we only return the enclosing window when there is an actual offset which
     684             :     // would otherwise cause coordinates to be offset incorrectly. (i.e.
     685             :     // if the enclosing window if offset from the document window)
     686             :     //
     687             :     // fixing both the caret and ability to interact issues for a windowless control in a non document aligned windw
     688             :     // does not seem to be possible without a change to the flash plugin
     689             : 
     690             :     nsIWidget* win = mPluginFrame->GetNearestWidget();
     691             :     if (win) {
     692             :       nsView *view = nsView::GetViewFor(win);
     693             :       NS_ASSERTION(view, "No view for widget");
     694             :       nsPoint offset = view->GetOffsetTo(nullptr);
     695             : 
     696             :       if (offset.x || offset.y) {
     697             :         // in the case the two windows are offset from eachother, we do go ahead and return the correct enclosing window
     698             :         // so that mouse co-ordinates are not messed up.
     699             :         return win;
     700             :       }
     701             :     }
     702             :   }
     703             : 
     704             :   return nullptr;
     705             : }
     706             : 
     707             : static already_AddRefed<nsIWidget>
     708             : GetRootWidgetForPluginFrame(const nsPluginFrame* aPluginFrame)
     709             : {
     710             :   MOZ_ASSERT(aPluginFrame);
     711             : 
     712             :   nsViewManager* vm =
     713             :     aPluginFrame->PresContext()->GetPresShell()->GetViewManager();
     714             :   if (!vm) {
     715             :     NS_WARNING("Could not find view manager for plugin frame.");
     716             :     return nullptr;
     717             :   }
     718             : 
     719             :   nsCOMPtr<nsIWidget> rootWidget;
     720             :   vm->GetRootWidget(getter_AddRefs(rootWidget));
     721             :   return rootWidget.forget();
     722             : }
     723             : #endif
     724             : 
     725           0 : NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value)
     726             : {
     727           0 :   if (!mPluginFrame) {
     728           0 :     NS_WARNING("plugin owner has no owner in getting doc's window handle");
     729           0 :     return NS_ERROR_FAILURE;
     730             :   }
     731             : 
     732             : #if defined(XP_WIN)
     733             :   void** pvalue = (void**)value;
     734             :   nsIWidget* offsetContainingWidget = GetContainingWidgetIfOffset();
     735             :   if (offsetContainingWidget) {
     736             :     *pvalue = (void*)offsetContainingWidget->GetNativeData(NS_NATIVE_WINDOW);
     737             :     if (*pvalue) {
     738             :       return NS_OK;
     739             :     }
     740             :   }
     741             : 
     742             :   // simply return the topmost document window
     743             :   nsCOMPtr<nsIWidget> widget = GetRootWidgetForPluginFrame(mPluginFrame);
     744             :   if (widget) {
     745             :     *pvalue = widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW);
     746             :   } else {
     747             :     NS_ASSERTION(widget, "couldn't get doc's widget in getting doc's window handle");
     748             :   }
     749             : 
     750             :   return NS_OK;
     751             : #elif defined(MOZ_WIDGET_GTK) && defined(MOZ_X11)
     752             :   // X11 window managers want the toplevel window for WM_TRANSIENT_FOR.
     753           0 :   nsIWidget* win = mPluginFrame->GetNearestWidget();
     754           0 :   if (!win)
     755           0 :     return NS_ERROR_FAILURE;
     756           0 :   *static_cast<Window*>(value) = (long unsigned int)win->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW);
     757           0 :   return NS_OK;
     758             : #else
     759             :   return NS_ERROR_NOT_IMPLEMENTED;
     760             : #endif
     761             : }
     762             : 
     763             : #if defined(XP_WIN)
     764             : void
     765             : nsPluginInstanceOwner::SetWidgetWindowAsParent(HWND aWindowToAdopt)
     766             : {
     767             :   if (!mWidget) {
     768             :     NS_ERROR("mWidget should exist before this gets called.");
     769             :     return;
     770             :   }
     771             : 
     772             :   mWidget->SetNativeData(NS_NATIVE_CHILD_WINDOW,
     773             :                          reinterpret_cast<uintptr_t>(aWindowToAdopt));
     774             : }
     775             : 
     776             : nsresult
     777             : nsPluginInstanceOwner::SetNetscapeWindowAsParent(HWND aWindowToAdopt)
     778             : {
     779             :   if (!mPluginFrame) {
     780             :     NS_WARNING("Plugin owner has no plugin frame.");
     781             :     return NS_ERROR_FAILURE;
     782             :   }
     783             : 
     784             :   // If there is a containing window that is offset then ask that to adopt.
     785             :   nsIWidget* offsetWidget = GetContainingWidgetIfOffset();
     786             :   if (offsetWidget) {
     787             :     offsetWidget->SetNativeData(NS_NATIVE_CHILD_WINDOW,
     788             :                                 reinterpret_cast<uintptr_t>(aWindowToAdopt));
     789             :     return NS_OK;
     790             :   }
     791             : 
     792             :   // Otherwise ask the topmost document window to adopt.
     793             :   nsCOMPtr<nsIWidget> rootWidget = GetRootWidgetForPluginFrame(mPluginFrame);
     794             :   if (!rootWidget) {
     795             :     NS_ASSERTION(rootWidget, "Couldn't get topmost document's widget.");
     796             :     return NS_ERROR_FAILURE;
     797             :   }
     798             : 
     799             :   rootWidget->SetNativeData(NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW,
     800             :                             reinterpret_cast<uintptr_t>(aWindowToAdopt));
     801             :   return NS_OK;
     802             : }
     803             : 
     804             : bool
     805             : nsPluginInstanceOwner::GetCompositionString(uint32_t aType,
     806             :                                             nsTArray<uint8_t>* aDist,
     807             :                                             int32_t* aLength)
     808             : {
     809             :   // Mark pkugin calls ImmGetCompositionStringW correctly
     810             :   mGotCompositionData = true;
     811             : 
     812             :   RefPtr<TextComposition> composition = GetTextComposition();
     813             :   if (NS_WARN_IF(!composition)) {
     814             :     return false;
     815             :   }
     816             : 
     817             :   switch(aType) {
     818             :     case GCS_COMPSTR: {
     819             :       if (!composition->IsComposing()) {
     820             :         *aLength = 0;
     821             :         return true;
     822             :       }
     823             : 
     824             :       uint32_t len = composition->LastData().Length() * sizeof(char16_t);
     825             :       if (len) {
     826             :         aDist->SetLength(len);
     827             :         memcpy(aDist->Elements(), composition->LastData().get(), len);
     828             :       }
     829             :       *aLength = len;
     830             :       return true;
     831             :     }
     832             : 
     833             :     case GCS_RESULTSTR: {
     834             :       if (composition->IsComposing()) {
     835             :         *aLength = 0;
     836             :         return true;
     837             :       }
     838             : 
     839             :       uint32_t len = composition->LastData().Length() * sizeof(char16_t);
     840             :       if (len) {
     841             :         aDist->SetLength(len);
     842             :         memcpy(aDist->Elements(), composition->LastData().get(), len);
     843             :       }
     844             :       *aLength = len;
     845             :       return true;
     846             :     }
     847             : 
     848             :     case GCS_CURSORPOS: {
     849             :       *aLength = 0;
     850             :       TextRangeArray* ranges = composition->GetLastRanges();
     851             :       if (!ranges) {
     852             :         return true;
     853             :       }
     854             :       *aLength = ranges->GetCaretPosition();
     855             :       if (*aLength < 0) {
     856             :         return false;
     857             :       }
     858             :       return true;
     859             :     }
     860             : 
     861             :     case GCS_COMPATTR: {
     862             :       TextRangeArray* ranges = composition->GetLastRanges();
     863             :       if (!ranges || ranges->IsEmpty()) {
     864             :         *aLength = 0;
     865             :         return true;
     866             :       }
     867             : 
     868             :       aDist->SetLength(composition->LastData().Length());
     869             :       memset(aDist->Elements(), ATTR_INPUT, aDist->Length());
     870             : 
     871             :       for (TextRange& range : *ranges) {
     872             :         uint8_t type = ATTR_INPUT;
     873             :         switch(range.mRangeType) {
     874             :           case TextRangeType::eRawClause:
     875             :             type = ATTR_INPUT;
     876             :             break;
     877             :           case TextRangeType::eSelectedRawClause:
     878             :             type = ATTR_TARGET_NOTCONVERTED;
     879             :             break;
     880             :           case TextRangeType::eConvertedClause:
     881             :             type = ATTR_CONVERTED;
     882             :             break;
     883             :           case TextRangeType::eSelectedClause:
     884             :             type = ATTR_TARGET_CONVERTED;
     885             :             break;
     886             :           default:
     887             :             continue;
     888             :         }
     889             : 
     890             :         size_t minLen = std::min<size_t>(range.mEndOffset, aDist->Length());
     891             :         for (size_t i = range.mStartOffset; i < minLen; i++) {
     892             :           (*aDist)[i] = type;
     893             :         }
     894             :       }
     895             :       *aLength = aDist->Length();
     896             :       return true;
     897             :     }
     898             : 
     899             :     case GCS_COMPCLAUSE: {
     900             :       RefPtr<TextRangeArray> ranges = composition->GetLastRanges();
     901             :       if (!ranges || ranges->IsEmpty()) {
     902             :         aDist->SetLength(sizeof(uint32_t));
     903             :         memset(aDist->Elements(), 0, sizeof(uint32_t));
     904             :         *aLength = aDist->Length();
     905             :         return true;
     906             :       }
     907             :       AutoTArray<uint32_t, 16> clauses;
     908             :       clauses.AppendElement(0);
     909             :       for (TextRange& range : *ranges) {
     910             :         if (!range.IsClause()) {
     911             :           continue;
     912             :         }
     913             :         clauses.AppendElement(range.mEndOffset);
     914             :       }
     915             : 
     916             :       aDist->SetLength(clauses.Length() * sizeof(uint32_t));
     917             :       memcpy(aDist->Elements(), clauses.Elements(), aDist->Length());
     918             :       *aLength = aDist->Length();
     919             :       return true;
     920             :     }
     921             : 
     922             :     case GCS_RESULTREADSTR: {
     923             :       // When returning error causes unexpected error, so we return 0 instead.
     924             :       *aLength = 0;
     925             :       return true;
     926             :     }
     927             : 
     928             :     case GCS_RESULTCLAUSE: {
     929             :       // When returning error causes unexpected error, so we return 0 instead.
     930             :       *aLength = 0;
     931             :       return true;
     932             :     }
     933             : 
     934             :     default:
     935             :       NS_WARNING(
     936             :         nsPrintfCString("Unsupported type %x of ImmGetCompositionStringW hook",
     937             :                         aType).get());
     938             :       break;
     939             :   }
     940             : 
     941             :   return false;
     942             : }
     943             : 
     944             : bool
     945             : nsPluginInstanceOwner::SetCandidateWindow(
     946             :     const widget::CandidateWindowPosition& aPosition)
     947             : {
     948             :   if (NS_WARN_IF(!mPluginFrame)) {
     949             :     return false;
     950             :   }
     951             : 
     952             :   nsCOMPtr<nsIWidget> widget = GetContainingWidgetIfOffset();
     953             :   if (!widget) {
     954             :     widget = GetRootWidgetForPluginFrame(mPluginFrame);
     955             :     if (NS_WARN_IF(!widget)) {
     956             :       return false;
     957             :     }
     958             :   }
     959             : 
     960             :   widget->SetCandidateWindowForPlugin(aPosition);
     961             :   return true;
     962             : }
     963             : 
     964             : bool
     965             : nsPluginInstanceOwner::RequestCommitOrCancel(bool aCommitted)
     966             : {
     967             :   nsCOMPtr<nsIWidget> widget = GetContainingWidgetIfOffset();
     968             :   if (!widget) {
     969             :     widget = GetRootWidgetForPluginFrame(mPluginFrame);
     970             :     if (NS_WARN_IF(!widget)) {
     971             :       return false;
     972             :     }
     973             :   }
     974             : 
     975             :   if (aCommitted) {
     976             :     widget->NotifyIME(widget::REQUEST_TO_COMMIT_COMPOSITION);
     977             :   } else {
     978             :     widget->NotifyIME(widget::REQUEST_TO_CANCEL_COMPOSITION);
     979             :   }
     980             :   return true;
     981             : }
     982             : 
     983             : #endif // #ifdef XP_WIN
     984             : 
     985             : void
     986           0 : nsPluginInstanceOwner::HandledWindowedPluginKeyEvent(
     987             :                          const NativeEventData& aKeyEventData,
     988             :                          bool aIsConsumed)
     989             : {
     990           0 :   if (NS_WARN_IF(!mInstance)) {
     991           0 :     return;
     992             :   }
     993             :   DebugOnly<nsresult> rv =
     994           0 :     mInstance->HandledWindowedPluginKeyEvent(aKeyEventData, aIsConsumed);
     995           0 :   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HandledWindowedPluginKeyEvent fail");
     996             : }
     997             : 
     998             : void
     999           0 : nsPluginInstanceOwner::OnWindowedPluginKeyEvent(
    1000             :                          const NativeEventData& aKeyEventData)
    1001             : {
    1002           0 :   if (NS_WARN_IF(!mPluginFrame)) {
    1003             :     // Notifies the plugin process of the key event being not consumed by us.
    1004           0 :     HandledWindowedPluginKeyEvent(aKeyEventData, false);
    1005           0 :     return;
    1006             :   }
    1007             : 
    1008           0 :   nsCOMPtr<nsIWidget> widget = mPluginFrame->PresContext()->GetRootWidget();
    1009           0 :   if (NS_WARN_IF(!widget)) {
    1010             :     // Notifies the plugin process of the key event being not consumed by us.
    1011           0 :     HandledWindowedPluginKeyEvent(aKeyEventData, false);
    1012           0 :     return;
    1013             :   }
    1014             : 
    1015           0 :   nsresult rv = widget->OnWindowedPluginKeyEvent(aKeyEventData, this);
    1016           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    1017             :     // Notifies the plugin process of the key event being not consumed by us.
    1018           0 :     HandledWindowedPluginKeyEvent(aKeyEventData, false);
    1019           0 :     return;
    1020             :   }
    1021             : 
    1022             :   // If the key event is posted to another process, we need to wait a call
    1023             :   // of HandledWindowedPluginKeyEvent().  So, nothing to do here in this case.
    1024           0 :   if (rv == NS_SUCCESS_EVENT_HANDLED_ASYNCHRONOUSLY) {
    1025           0 :     return;
    1026             :   }
    1027             : 
    1028             :   // Otherwise, the key event is handled synchronously.  Let's notify the
    1029             :   // plugin process of the key event's result.
    1030           0 :   bool consumed = (rv == NS_SUCCESS_EVENT_CONSUMED);
    1031           0 :   HandledWindowedPluginKeyEvent(aKeyEventData, consumed);
    1032             : }
    1033             : 
    1034           0 : NS_IMETHODIMP nsPluginInstanceOwner::SetEventModel(int32_t eventModel)
    1035             : {
    1036             : #ifdef XP_MACOSX
    1037             :   mEventModel = static_cast<NPEventModel>(eventModel);
    1038             :   return NS_OK;
    1039             : #else
    1040           0 :   return NS_ERROR_NOT_IMPLEMENTED;
    1041             : #endif
    1042             : }
    1043             : 
    1044             : #ifdef XP_MACOSX
    1045             : NPBool nsPluginInstanceOwner::ConvertPointPuppet(PuppetWidget *widget,
    1046             :                                                  nsPluginFrame* pluginFrame,
    1047             :                                                  double sourceX, double sourceY,
    1048             :                                                  NPCoordinateSpace sourceSpace,
    1049             :                                                  double *destX, double *destY,
    1050             :                                                  NPCoordinateSpace destSpace)
    1051             : {
    1052             :   NS_ENSURE_TRUE(widget && widget->GetOwningTabChild() && pluginFrame, false);
    1053             :   // Caller has to want a result.
    1054             :   NS_ENSURE_TRUE(destX || destY, false);
    1055             : 
    1056             :   if (sourceSpace == destSpace) {
    1057             :     if (destX) {
    1058             :       *destX = sourceX;
    1059             :     }
    1060             :     if (destY) {
    1061             :       *destY = sourceY;
    1062             :     }
    1063             :     return true;
    1064             :   }
    1065             : 
    1066             :   nsPresContext* presContext = pluginFrame->PresContext();
    1067             :   CSSToLayoutDeviceScale scaleFactor(
    1068             :     double(nsPresContext::AppUnitsPerCSSPixel()) /
    1069             :     presContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom());
    1070             : 
    1071             :   PuppetWidget *puppetWidget = static_cast<PuppetWidget*>(widget);
    1072             :   PuppetWidget *rootWidget = static_cast<PuppetWidget*>(widget->GetTopLevelWidget());
    1073             :   if (!rootWidget) {
    1074             :     return false;
    1075             :   }
    1076             :   CSSIntPoint chromeSize = CSSIntPoint::Truncate(
    1077             :     LayoutDeviceIntPoint::FromUnknownPoint(rootWidget->GetChromeDimensions()) /
    1078             :     scaleFactor);
    1079             :   nsIntSize intScreenDims = rootWidget->GetScreenDimensions();
    1080             :   CSSIntSize screenDims = CSSIntSize::Truncate(
    1081             :     LayoutDeviceIntSize::FromUnknownSize(intScreenDims) / scaleFactor);
    1082             :   int32_t screenH = screenDims.height;
    1083             :   CSSIntPoint windowPosition = CSSIntPoint::Truncate(
    1084             :     LayoutDeviceIntPoint::FromUnknownPoint(rootWidget->GetWindowPosition()) /
    1085             :     scaleFactor);
    1086             : 
    1087             :   // Window size is tab size + chrome size.
    1088             :   LayoutDeviceIntRect tabContentBounds = puppetWidget->GetBounds();
    1089             :   tabContentBounds.ScaleInverseRoundOut(scaleFactor.scale);
    1090             :   int32_t windowH = tabContentBounds.height + int(chromeSize.y);
    1091             : 
    1092             :   CSSIntPoint pluginPosition = pluginFrame->GetScreenRect().TopLeft();
    1093             : 
    1094             :   // Convert (sourceX, sourceY) to 'real' (not PuppetWidget) screen space.
    1095             :   // In OSX, the Y-axis increases upward, which is the reverse of ours.
    1096             :   // We want OSX coordinates for window and screen so those equations are swapped.
    1097             :   CSSIntPoint sourcePoint = CSSIntPoint::Truncate(sourceX, sourceY);
    1098             :   CSSIntPoint screenPoint;
    1099             :   switch (sourceSpace) {
    1100             :     case NPCoordinateSpacePlugin:
    1101             :       screenPoint = sourcePoint + pluginPosition +
    1102             :         CSSIntPoint::Truncate(CSSPoint::FromAppUnits(
    1103             :           pluginFrame->GetContentRectRelativeToSelf().TopLeft()));
    1104             :       break;
    1105             :     case NPCoordinateSpaceWindow:
    1106             :       screenPoint = CSSIntPoint(sourcePoint.x, windowH-sourcePoint.y) +
    1107             :         windowPosition;
    1108             :       break;
    1109             :     case NPCoordinateSpaceFlippedWindow:
    1110             :       screenPoint = sourcePoint + windowPosition;
    1111             :       break;
    1112             :     case NPCoordinateSpaceScreen:
    1113             :       screenPoint = CSSIntPoint(sourcePoint.x, screenH-sourcePoint.y);
    1114             :       break;
    1115             :     case NPCoordinateSpaceFlippedScreen:
    1116             :       screenPoint = sourcePoint;
    1117             :       break;
    1118             :     default:
    1119             :       return false;
    1120             :   }
    1121             : 
    1122             :   // Convert from screen to dest space.
    1123             :   CSSIntPoint destPoint;
    1124             :   switch (destSpace) {
    1125             :     case NPCoordinateSpacePlugin:
    1126             :       destPoint = screenPoint - pluginPosition -
    1127             :         CSSIntPoint::Truncate(CSSPoint::FromAppUnits(
    1128             :           pluginFrame->GetContentRectRelativeToSelf().TopLeft()));
    1129             :       break;
    1130             :     case NPCoordinateSpaceWindow:
    1131             :       destPoint = screenPoint - windowPosition;
    1132             :       destPoint.y = windowH - destPoint.y;
    1133             :       break;
    1134             :     case NPCoordinateSpaceFlippedWindow:
    1135             :       destPoint = screenPoint - windowPosition;
    1136             :       break;
    1137             :     case NPCoordinateSpaceScreen:
    1138             :       destPoint = CSSIntPoint(screenPoint.x, screenH-screenPoint.y);
    1139             :       break;
    1140             :     case NPCoordinateSpaceFlippedScreen:
    1141             :       destPoint = screenPoint;
    1142             :       break;
    1143             :     default:
    1144             :       return false;
    1145             :   }
    1146             : 
    1147             :   if (destX) {
    1148             :     *destX = destPoint.x;
    1149             :   }
    1150             :   if (destY) {
    1151             :     *destY = destPoint.y;
    1152             :   }
    1153             : 
    1154             :   return true;
    1155             : }
    1156             : 
    1157             : NPBool nsPluginInstanceOwner::ConvertPointNoPuppet(nsIWidget *widget,
    1158             :                                                    nsPluginFrame* pluginFrame,
    1159             :                                                    double sourceX, double sourceY,
    1160             :                                                    NPCoordinateSpace sourceSpace,
    1161             :                                                    double *destX, double *destY,
    1162             :                                                    NPCoordinateSpace destSpace)
    1163             : {
    1164             :   NS_ENSURE_TRUE(widget && pluginFrame, false);
    1165             :   // Caller has to want a result.
    1166             :   NS_ENSURE_TRUE(destX || destY, false);
    1167             : 
    1168             :   if (sourceSpace == destSpace) {
    1169             :     if (destX) {
    1170             :       *destX = sourceX;
    1171             :     }
    1172             :     if (destY) {
    1173             :       *destY = sourceY;
    1174             :     }
    1175             :     return true;
    1176             :   }
    1177             : 
    1178             :   nsPresContext* presContext = pluginFrame->PresContext();
    1179             :   double scaleFactor = double(nsPresContext::AppUnitsPerCSSPixel())/
    1180             :     presContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom();
    1181             : 
    1182             :   nsCOMPtr<nsIScreen> screen = widget->GetWidgetScreen();
    1183             :   if (!screen) {
    1184             :     return false;
    1185             :   }
    1186             : 
    1187             :   int32_t screenX, screenY, screenWidth, screenHeight;
    1188             :   screen->GetRect(&screenX, &screenY, &screenWidth, &screenHeight);
    1189             :   screenHeight /= scaleFactor;
    1190             : 
    1191             :   LayoutDeviceIntRect windowScreenBounds = widget->GetScreenBounds();
    1192             :   windowScreenBounds.ScaleInverseRoundOut(scaleFactor);
    1193             :   int32_t windowX = windowScreenBounds.x;
    1194             :   int32_t windowY = windowScreenBounds.y;
    1195             :   int32_t windowHeight = windowScreenBounds.height;
    1196             : 
    1197             :   CSSIntRect pluginScreenRect = pluginFrame->GetScreenRect();
    1198             : 
    1199             :   double screenXGecko, screenYGecko;
    1200             :   switch (sourceSpace) {
    1201             :     case NPCoordinateSpacePlugin:
    1202             :       screenXGecko = pluginScreenRect.x + sourceX;
    1203             :       screenYGecko = pluginScreenRect.y + sourceY;
    1204             :       break;
    1205             :     case NPCoordinateSpaceWindow:
    1206             :       screenXGecko = windowX + sourceX;
    1207             :       screenYGecko = windowY + (windowHeight - sourceY);
    1208             :       break;
    1209             :     case NPCoordinateSpaceFlippedWindow:
    1210             :       screenXGecko = windowX + sourceX;
    1211             :       screenYGecko = windowY + sourceY;
    1212             :       break;
    1213             :     case NPCoordinateSpaceScreen:
    1214             :       screenXGecko = sourceX;
    1215             :       screenYGecko = screenHeight - sourceY;
    1216             :       break;
    1217             :     case NPCoordinateSpaceFlippedScreen:
    1218             :       screenXGecko = sourceX;
    1219             :       screenYGecko = sourceY;
    1220             :       break;
    1221             :     default:
    1222             :       return false;
    1223             :   }
    1224             : 
    1225             :   double destXCocoa, destYCocoa;
    1226             :   switch (destSpace) {
    1227             :     case NPCoordinateSpacePlugin:
    1228             :       destXCocoa = screenXGecko - pluginScreenRect.x;
    1229             :       destYCocoa = screenYGecko - pluginScreenRect.y;
    1230             :       break;
    1231             :     case NPCoordinateSpaceWindow:
    1232             :       destXCocoa = screenXGecko - windowX;
    1233             :       destYCocoa = windowHeight - (screenYGecko - windowY);
    1234             :       break;
    1235             :     case NPCoordinateSpaceFlippedWindow:
    1236             :       destXCocoa = screenXGecko - windowX;
    1237             :       destYCocoa = screenYGecko - windowY;
    1238             :       break;
    1239             :     case NPCoordinateSpaceScreen:
    1240             :       destXCocoa = screenXGecko;
    1241             :       destYCocoa = screenHeight - screenYGecko;
    1242             :       break;
    1243             :     case NPCoordinateSpaceFlippedScreen:
    1244             :       destXCocoa = screenXGecko;
    1245             :       destYCocoa = screenYGecko;
    1246             :       break;
    1247             :     default:
    1248             :       return false;
    1249             :   }
    1250             : 
    1251             :   if (destX) {
    1252             :     *destX = destXCocoa;
    1253             :   }
    1254             :   if (destY) {
    1255             :     *destY = destYCocoa;
    1256             :   }
    1257             : 
    1258             :   return true;
    1259             : }
    1260             : #endif // XP_MACOSX
    1261             : 
    1262           0 : NPBool nsPluginInstanceOwner::ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
    1263             :                                            double *destX, double *destY, NPCoordinateSpace destSpace)
    1264             : {
    1265             : #ifdef XP_MACOSX
    1266             :   if (!mPluginFrame) {
    1267             :     return false;
    1268             :   }
    1269             : 
    1270             :   MOZ_ASSERT(mPluginFrame->GetNearestWidget());
    1271             : 
    1272             :   if (nsIWidget::UsePuppetWidgets()) {
    1273             :     return ConvertPointPuppet(static_cast<PuppetWidget*>(mPluginFrame->GetNearestWidget()),
    1274             :                                mPluginFrame, sourceX, sourceY, sourceSpace,
    1275             :                                destX, destY, destSpace);
    1276             :   }
    1277             : 
    1278             :   return ConvertPointNoPuppet(mPluginFrame->GetNearestWidget(),
    1279             :                               mPluginFrame, sourceX, sourceY, sourceSpace,
    1280             :                               destX, destY, destSpace);
    1281             : #else
    1282           0 :   return false;
    1283             : #endif
    1284             : }
    1285             : 
    1286           0 : NPError nsPluginInstanceOwner::InitAsyncSurface(NPSize *size, NPImageFormat format,
    1287             :                                                 void *initData, NPAsyncSurface *surface)
    1288             : {
    1289           0 :   return NPERR_INCOMPATIBLE_VERSION_ERROR;
    1290             : }
    1291             : 
    1292           0 : NPError nsPluginInstanceOwner::FinalizeAsyncSurface(NPAsyncSurface *)
    1293             : {
    1294           0 :   return NPERR_INCOMPATIBLE_VERSION_ERROR;
    1295             : }
    1296             : 
    1297           0 : void nsPluginInstanceOwner::SetCurrentAsyncSurface(NPAsyncSurface *, NPRect*)
    1298             : {
    1299           0 : }
    1300             : 
    1301           0 : NS_IMETHODIMP nsPluginInstanceOwner::GetTagType(nsPluginTagType *result)
    1302             : {
    1303           0 :   NS_ENSURE_ARG_POINTER(result);
    1304             : 
    1305           0 :   *result = nsPluginTagType_Unknown;
    1306             : 
    1307           0 :   nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
    1308           0 :   if (content->IsHTMLElement(nsGkAtoms::applet))
    1309           0 :     *result = nsPluginTagType_Applet;
    1310           0 :   else if (content->IsHTMLElement(nsGkAtoms::embed))
    1311           0 :     *result = nsPluginTagType_Embed;
    1312           0 :   else if (content->IsHTMLElement(nsGkAtoms::object))
    1313           0 :     *result = nsPluginTagType_Object;
    1314             : 
    1315           0 :   return NS_OK;
    1316             : }
    1317             : 
    1318           0 : void nsPluginInstanceOwner::GetParameters(nsTArray<MozPluginParameter>& parameters)
    1319             : {
    1320           0 :   nsCOMPtr<nsIObjectLoadingContent> content = do_QueryReferent(mContent);
    1321             :   nsObjectLoadingContent *loadingContent =
    1322           0 :     static_cast<nsObjectLoadingContent*>(content.get());
    1323             : 
    1324           0 :   loadingContent->GetPluginParameters(parameters);
    1325           0 : }
    1326             : 
    1327             : #ifdef XP_MACOSX
    1328             : 
    1329             : static void InitializeNPCocoaEvent(NPCocoaEvent* event)
    1330             : {
    1331             :   memset(event, 0, sizeof(NPCocoaEvent));
    1332             : }
    1333             : 
    1334             : NPDrawingModel nsPluginInstanceOwner::GetDrawingModel()
    1335             : {
    1336             : #ifndef NP_NO_QUICKDRAW
    1337             :   // We don't support the Quickdraw drawing model any more but it's still
    1338             :   // the default model for i386 per NPAPI.
    1339             :   NPDrawingModel drawingModel = NPDrawingModelQuickDraw;
    1340             : #else
    1341             :   NPDrawingModel drawingModel = NPDrawingModelCoreGraphics;
    1342             : #endif
    1343             : 
    1344             :   if (!mInstance)
    1345             :     return drawingModel;
    1346             : 
    1347             :   mInstance->GetDrawingModel((int32_t*)&drawingModel);
    1348             :   return drawingModel;
    1349             : }
    1350             : 
    1351             : bool nsPluginInstanceOwner::IsRemoteDrawingCoreAnimation()
    1352             : {
    1353             :   if (!mInstance)
    1354             :     return false;
    1355             : 
    1356             :   bool coreAnimation;
    1357             :   if (!NS_SUCCEEDED(mInstance->IsRemoteDrawingCoreAnimation(&coreAnimation)))
    1358             :     return false;
    1359             : 
    1360             :   return coreAnimation;
    1361             : }
    1362             : 
    1363             : NPEventModel nsPluginInstanceOwner::GetEventModel()
    1364             : {
    1365             :   return mEventModel;
    1366             : }
    1367             : 
    1368             : #define DEFAULT_REFRESH_RATE 20 // 50 FPS
    1369             : 
    1370             : nsCOMPtr<nsITimer>               *nsPluginInstanceOwner::sCATimer = nullptr;
    1371             : nsTArray<nsPluginInstanceOwner*> *nsPluginInstanceOwner::sCARefreshListeners = nullptr;
    1372             : 
    1373             : void nsPluginInstanceOwner::CARefresh(nsITimer *aTimer, void *aClosure) {
    1374             :   if (!sCARefreshListeners) {
    1375             :     return;
    1376             :   }
    1377             :   for (size_t i = 0; i < sCARefreshListeners->Length(); i++) {
    1378             :     nsPluginInstanceOwner* instanceOwner = (*sCARefreshListeners)[i];
    1379             :     NPWindow *window;
    1380             :     instanceOwner->GetWindow(window);
    1381             :     if (!window) {
    1382             :       continue;
    1383             :     }
    1384             :     NPRect r;
    1385             :     r.left = 0;
    1386             :     r.top = 0;
    1387             :     r.right = window->width;
    1388             :     r.bottom = window->height;
    1389             :     instanceOwner->InvalidateRect(&r);
    1390             :   }
    1391             : }
    1392             : 
    1393             : void nsPluginInstanceOwner::AddToCARefreshTimer() {
    1394             :   if (!mInstance) {
    1395             :     return;
    1396             :   }
    1397             : 
    1398             :   // Flash invokes InvalidateRect for us.
    1399             :   const char* mime = nullptr;
    1400             :   if (NS_SUCCEEDED(mInstance->GetMIMEType(&mime)) && mime &&
    1401             :       nsPluginHost::GetSpecialType(nsDependentCString(mime)) ==
    1402             :       nsPluginHost::eSpecialType_Flash) {
    1403             :     return;
    1404             :   }
    1405             : 
    1406             :   if (!sCARefreshListeners) {
    1407             :     sCARefreshListeners = new nsTArray<nsPluginInstanceOwner*>();
    1408             :   }
    1409             : 
    1410             :   if (sCARefreshListeners->Contains(this)) {
    1411             :     return;
    1412             :   }
    1413             : 
    1414             :   sCARefreshListeners->AppendElement(this);
    1415             : 
    1416             :   if (!sCATimer) {
    1417             :     sCATimer = new nsCOMPtr<nsITimer>();
    1418             :   }
    1419             : 
    1420             :   if (sCARefreshListeners->Length() == 1) {
    1421             :     *sCATimer = do_CreateInstance("@mozilla.org/timer;1");
    1422             :     (*sCATimer)->InitWithNamedFuncCallback(CARefresh, nullptr,
    1423             :                                            DEFAULT_REFRESH_RATE, nsITimer::TYPE_REPEATING_SLACK,
    1424             :                                            "nsPluginInstanceOwner::CARefresh");
    1425             :   }
    1426             : }
    1427             : 
    1428             : void nsPluginInstanceOwner::RemoveFromCARefreshTimer() {
    1429             :   if (!sCARefreshListeners || sCARefreshListeners->Contains(this) == false) {
    1430             :     return;
    1431             :   }
    1432             : 
    1433             :   sCARefreshListeners->RemoveElement(this);
    1434             : 
    1435             :   if (sCARefreshListeners->Length() == 0) {
    1436             :     if (sCATimer) {
    1437             :       (*sCATimer)->Cancel();
    1438             :       delete sCATimer;
    1439             :       sCATimer = nullptr;
    1440             :     }
    1441             :     delete sCARefreshListeners;
    1442             :     sCARefreshListeners = nullptr;
    1443             :   }
    1444             : }
    1445             : 
    1446             : void nsPluginInstanceOwner::SetPluginPort()
    1447             : {
    1448             :   void* pluginPort = GetPluginPort();
    1449             :   if (!pluginPort || !mPluginWindow)
    1450             :     return;
    1451             :   mPluginWindow->window = pluginPort;
    1452             : }
    1453             : #endif
    1454             : #if defined(XP_MACOSX) || defined(XP_WIN)
    1455             : nsresult nsPluginInstanceOwner::ContentsScaleFactorChanged(double aContentsScaleFactor)
    1456             : {
    1457             :   if (!mInstance) {
    1458             :     return NS_ERROR_NULL_POINTER;
    1459             :   }
    1460             :   return mInstance->ContentsScaleFactorChanged(aContentsScaleFactor);
    1461             : }
    1462             : #endif
    1463             : 
    1464             : 
    1465             : // static
    1466             : uint32_t
    1467           0 : nsPluginInstanceOwner::GetEventloopNestingLevel()
    1468             : {
    1469           0 :   nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
    1470           0 :   uint32_t currentLevel = 0;
    1471           0 :   if (appShell) {
    1472           0 :     appShell->GetEventloopNestingLevel(&currentLevel);
    1473             : #ifdef XP_MACOSX
    1474             :     // Cocoa widget code doesn't process UI events through the normal
    1475             :     // appshell event loop, so it needs an additional count here.
    1476             :     currentLevel++;
    1477             : #endif
    1478             :   }
    1479             : 
    1480             :   // No idea how this happens... but Linux doesn't consistently
    1481             :   // process UI events through the appshell event loop. If we get a 0
    1482             :   // here on any platform we increment the level just in case so that
    1483             :   // we make sure we always tear the plugin down eventually.
    1484           0 :   if (!currentLevel) {
    1485           0 :     currentLevel++;
    1486             :   }
    1487             : 
    1488           0 :   return currentLevel;
    1489             : }
    1490             : 
    1491             : #ifdef MOZ_WIDGET_ANDROID
    1492             : 
    1493             : // Modified version of nsFrame::GetOffsetToCrossDoc that stops when it
    1494             : // hits an element with a displayport (or runs out of frames). This is
    1495             : // not really the right thing to do, but it's better than what was here before.
    1496             : static nsPoint
    1497             : GetOffsetRootContent(nsIFrame* aFrame)
    1498             : {
    1499             :   // offset will hold the final offset
    1500             :   // docOffset holds the currently accumulated offset at the current APD, it
    1501             :   // will be converted and added to offset when the current APD changes.
    1502             :   nsPoint offset(0, 0), docOffset(0, 0);
    1503             :   const nsIFrame* f = aFrame;
    1504             :   int32_t currAPD = aFrame->PresContext()->AppUnitsPerDevPixel();
    1505             :   int32_t apd = currAPD;
    1506             :   while (f) {
    1507             :     if (f->GetContent() && nsLayoutUtils::HasDisplayPort(f->GetContent()))
    1508             :       break;
    1509             : 
    1510             :     docOffset += f->GetPosition();
    1511             :     nsIFrame* parent = f->GetParent();
    1512             :     if (parent) {
    1513             :       f = parent;
    1514             :     } else {
    1515             :       nsPoint newOffset(0, 0);
    1516             :       f = nsLayoutUtils::GetCrossDocParentFrame(f, &newOffset);
    1517             :       int32_t newAPD = f ? f->PresContext()->AppUnitsPerDevPixel() : 0;
    1518             :       if (!f || newAPD != currAPD) {
    1519             :         // Convert docOffset to the right APD and add it to offset.
    1520             :         offset += docOffset.ScaleToOtherAppUnits(currAPD, apd);
    1521             :         docOffset.x = docOffset.y = 0;
    1522             :       }
    1523             :       currAPD = newAPD;
    1524             :       docOffset += newOffset;
    1525             :     }
    1526             :   }
    1527             : 
    1528             :   offset += docOffset.ScaleToOtherAppUnits(currAPD, apd);
    1529             : 
    1530             :   return offset;
    1531             : }
    1532             : 
    1533             : LayoutDeviceRect nsPluginInstanceOwner::GetPluginRect()
    1534             : {
    1535             :   // Get the offset of the content relative to the page
    1536             :   nsRect bounds = mPluginFrame->GetContentRectRelativeToSelf() + GetOffsetRootContent(mPluginFrame);
    1537             :   LayoutDeviceIntRect rect = LayoutDeviceIntRect::FromAppUnitsToNearest(bounds, mPluginFrame->PresContext()->AppUnitsPerDevPixel());
    1538             :   return LayoutDeviceRect(rect);
    1539             : }
    1540             : 
    1541             : bool nsPluginInstanceOwner::AddPluginView(const LayoutDeviceRect& aRect /* = LayoutDeviceRect(0, 0, 0, 0) */)
    1542             : {
    1543             :   if (!mJavaView) {
    1544             :     mJavaView = mInstance->GetJavaSurface();
    1545             : 
    1546             :     if (!mJavaView)
    1547             :       return false;
    1548             : 
    1549             :     mJavaView = (void*)jni::GetGeckoThreadEnv()->NewGlobalRef((jobject)mJavaView);
    1550             :   }
    1551             : 
    1552             :   if (mFullScreen && jni::IsFennec()) {
    1553             :     java::GeckoApp::AddPluginView(jni::Object::Ref::From(jobject(mJavaView)));
    1554             :     sFullScreenInstance = this;
    1555             :   }
    1556             : 
    1557             :   return true;
    1558             : }
    1559             : 
    1560             : void nsPluginInstanceOwner::RemovePluginView()
    1561             : {
    1562             :   if (!mInstance || !mJavaView)
    1563             :     return;
    1564             : 
    1565             :   if (mFullScreen && jni::IsFennec()) {
    1566             :     java::GeckoApp::RemovePluginView(jni::Object::Ref::From(jobject(mJavaView)));
    1567             :   }
    1568             :   jni::GetGeckoThreadEnv()->DeleteGlobalRef((jobject)mJavaView);
    1569             :   mJavaView = nullptr;
    1570             : 
    1571             :   if (mFullScreen)
    1572             :     sFullScreenInstance = nullptr;
    1573             : }
    1574             : 
    1575             : void
    1576             : nsPluginInstanceOwner::GetVideos(nsTArray<nsNPAPIPluginInstance::VideoInfo*>& aVideos)
    1577             : {
    1578             :   if (!mInstance)
    1579             :     return;
    1580             : 
    1581             :   mInstance->GetVideos(aVideos);
    1582             : }
    1583             : 
    1584             : already_AddRefed<ImageContainer>
    1585             : nsPluginInstanceOwner::GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInfo* aVideoInfo)
    1586             : {
    1587             :   RefPtr<ImageContainer> container = LayerManager::CreateImageContainer();
    1588             : 
    1589             :   if (aVideoInfo->mDimensions.width && aVideoInfo->mDimensions.height) {
    1590             :     RefPtr<Image> img = new SurfaceTextureImage(
    1591             :       aVideoInfo->mSurface->GetHandle(),
    1592             :       gfx::IntSize::Truncate(aVideoInfo->mDimensions.width, aVideoInfo->mDimensions.height),
    1593             :       true, /* continuous */
    1594             :       gl::OriginPos::BottomLeft);
    1595             :     container->SetCurrentImageInTransaction(img);
    1596             :   }
    1597             : 
    1598             :   return container.forget();
    1599             : }
    1600             : 
    1601             : void nsPluginInstanceOwner::Invalidate() {
    1602             :   NPRect rect;
    1603             :   rect.left = rect.top = 0;
    1604             :   rect.right = mPluginWindow->width;
    1605             :   rect.bottom = mPluginWindow->height;
    1606             :   InvalidateRect(&rect);
    1607             : }
    1608             : 
    1609             : void nsPluginInstanceOwner::Recomposite() {
    1610             :   nsIWidget* const widget = mPluginFrame->GetNearestWidget();
    1611             :   NS_ENSURE_TRUE_VOID(widget);
    1612             : 
    1613             :   LayerManager* const lm = widget->GetLayerManager();
    1614             :   NS_ENSURE_TRUE_VOID(lm);
    1615             : 
    1616             :   ClientLayerManager* const clm = lm->AsClientLayerManager();
    1617             :   NS_ENSURE_TRUE_VOID(clm && clm->GetRoot());
    1618             : 
    1619             :   clm->SendInvalidRegion(
    1620             :       clm->GetRoot()->GetLocalVisibleRegion().ToUnknownRegion().GetBounds());
    1621             :   clm->ScheduleComposite();
    1622             : }
    1623             : 
    1624             : void nsPluginInstanceOwner::RequestFullScreen() {
    1625             :   if (mFullScreen)
    1626             :     return;
    1627             : 
    1628             :   // Remove whatever view we currently have (if any, fullscreen or otherwise)
    1629             :   RemovePluginView();
    1630             : 
    1631             :   mFullScreen = true;
    1632             :   AddPluginView();
    1633             : 
    1634             :   mInstance->NotifyFullScreen(mFullScreen);
    1635             : }
    1636             : 
    1637             : void nsPluginInstanceOwner::ExitFullScreen() {
    1638             :   if (!mFullScreen)
    1639             :     return;
    1640             : 
    1641             :   RemovePluginView();
    1642             : 
    1643             :   mFullScreen = false;
    1644             : 
    1645             :   int32_t model = mInstance->GetANPDrawingModel();
    1646             : 
    1647             :   if (model == kSurface_ANPDrawingModel) {
    1648             :     // We need to do this immediately, otherwise Flash
    1649             :     // sometimes causes a deadlock (bug 762407)
    1650             :     AddPluginView(GetPluginRect());
    1651             :   }
    1652             : 
    1653             :   mInstance->NotifyFullScreen(mFullScreen);
    1654             : 
    1655             :   // This will cause Paint() to be called, which is where
    1656             :   // we normally add/update views and layers
    1657             :   Invalidate();
    1658             : }
    1659             : 
    1660             : void nsPluginInstanceOwner::ExitFullScreen(jobject view) {
    1661             :   JNIEnv* env = jni::GetGeckoThreadEnv();
    1662             : 
    1663             :   if (sFullScreenInstance && sFullScreenInstance->mInstance &&
    1664             :       env->IsSameObject(view, (jobject)sFullScreenInstance->mInstance->GetJavaSurface())) {
    1665             :     sFullScreenInstance->ExitFullScreen();
    1666             :   }
    1667             : }
    1668             : 
    1669             : #endif
    1670             : 
    1671           0 : nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
    1672             : {
    1673             : #ifdef MOZ_WIDGET_ANDROID
    1674             :   if (mInstance) {
    1675             :     ANPEvent event;
    1676             :     event.inSize = sizeof(ANPEvent);
    1677             :     event.eventType = kLifecycle_ANPEventType;
    1678             : 
    1679             :     nsAutoString eventType;
    1680             :     aFocusEvent->GetType(eventType);
    1681             :     if (eventType.EqualsLiteral("focus")) {
    1682             :       event.data.lifecycle.action = kGainFocus_ANPLifecycleAction;
    1683             :     }
    1684             :     else if (eventType.EqualsLiteral("blur")) {
    1685             :       event.data.lifecycle.action = kLoseFocus_ANPLifecycleAction;
    1686             :     }
    1687             :     else {
    1688             :       NS_ASSERTION(false, "nsPluginInstanceOwner::DispatchFocusToPlugin, wierd eventType");
    1689             :     }
    1690             :     mInstance->HandleEvent(&event, nullptr);
    1691             :   }
    1692             : #endif
    1693             : 
    1694             : #ifndef XP_MACOSX
    1695           0 :   if (!mPluginWindow || (mPluginWindow->type == NPWindowTypeWindow)) {
    1696             :     // continue only for cases without child window
    1697           0 :     return aFocusEvent->PreventDefault(); // consume event
    1698             :   }
    1699             : #endif
    1700             : 
    1701           0 :   WidgetEvent* theEvent = aFocusEvent->WidgetEventPtr();
    1702           0 :   if (theEvent) {
    1703           0 :     WidgetGUIEvent focusEvent(theEvent->IsTrusted(), theEvent->mMessage,
    1704           0 :                               nullptr);
    1705           0 :     nsEventStatus rv = ProcessEvent(focusEvent);
    1706           0 :     if (nsEventStatus_eConsumeNoDefault == rv) {
    1707           0 :       aFocusEvent->PreventDefault();
    1708           0 :       aFocusEvent->StopPropagation();
    1709             :     }
    1710             :   }
    1711             : 
    1712           0 :   return NS_OK;
    1713             : }
    1714             : 
    1715           0 : nsresult nsPluginInstanceOwner::ProcessKeyPress(nsIDOMEvent* aKeyEvent)
    1716             : {
    1717             : #ifdef XP_MACOSX
    1718             :   return DispatchKeyToPlugin(aKeyEvent);
    1719             : #else
    1720           0 :   if (SendNativeEvents())
    1721           0 :     DispatchKeyToPlugin(aKeyEvent);
    1722             : 
    1723           0 :   if (mInstance) {
    1724             :     // If this event is going to the plugin, we want to kill it.
    1725             :     // Not actually sending keypress to the plugin, since we didn't before.
    1726           0 :     aKeyEvent->PreventDefault();
    1727           0 :     aKeyEvent->StopPropagation();
    1728             :   }
    1729           0 :   return NS_OK;
    1730             : #endif
    1731             : }
    1732             : 
    1733           0 : nsresult nsPluginInstanceOwner::DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent)
    1734             : {
    1735             : #if !defined(XP_MACOSX)
    1736           0 :   if (!mPluginWindow || (mPluginWindow->type == NPWindowTypeWindow))
    1737           0 :     return aKeyEvent->PreventDefault(); // consume event
    1738             :   // continue only for cases without child window
    1739             : #endif
    1740             : 
    1741           0 :   if (mInstance) {
    1742             :     WidgetKeyboardEvent* keyEvent =
    1743           0 :       aKeyEvent->WidgetEventPtr()->AsKeyboardEvent();
    1744           0 :     if (keyEvent && keyEvent->mClass == eKeyboardEventClass) {
    1745           0 :       nsEventStatus rv = ProcessEvent(*keyEvent);
    1746           0 :       if (nsEventStatus_eConsumeNoDefault == rv) {
    1747           0 :         aKeyEvent->PreventDefault();
    1748           0 :         aKeyEvent->StopPropagation();
    1749             :       }
    1750             :     }
    1751             :   }
    1752             : 
    1753           0 :   return NS_OK;
    1754             : }
    1755             : 
    1756             : nsresult
    1757           0 : nsPluginInstanceOwner::ProcessMouseDown(nsIDOMEvent* aMouseEvent)
    1758             : {
    1759             : #if !defined(XP_MACOSX)
    1760           0 :   if (!mPluginWindow || (mPluginWindow->type == NPWindowTypeWindow))
    1761           0 :     return aMouseEvent->PreventDefault(); // consume event
    1762             :   // continue only for cases without child window
    1763             : #endif
    1764             : 
    1765             :   // if the plugin is windowless, we need to set focus ourselves
    1766             :   // otherwise, we might not get key events
    1767           0 :   if (mPluginFrame && mPluginWindow &&
    1768           0 :       mPluginWindow->type == NPWindowTypeDrawable) {
    1769             : 
    1770           0 :     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
    1771           0 :     if (fm) {
    1772           0 :       nsCOMPtr<nsIDOMElement> elem = do_QueryReferent(mContent);
    1773           0 :       fm->SetFocus(elem, 0);
    1774             :     }
    1775             :   }
    1776             : 
    1777             :   WidgetMouseEvent* mouseEvent =
    1778           0 :     aMouseEvent->WidgetEventPtr()->AsMouseEvent();
    1779           0 :   if (mouseEvent && mouseEvent->mClass == eMouseEventClass) {
    1780           0 :     mLastMouseDownButtonType = mouseEvent->button;
    1781           0 :     nsEventStatus rv = ProcessEvent(*mouseEvent);
    1782           0 :     if (nsEventStatus_eConsumeNoDefault == rv) {
    1783           0 :       return aMouseEvent->PreventDefault(); // consume event
    1784             :     }
    1785             :   }
    1786             : 
    1787           0 :   return NS_OK;
    1788             : }
    1789             : 
    1790           0 : nsresult nsPluginInstanceOwner::DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent,
    1791             :                                                       bool aAllowPropagate)
    1792             : {
    1793             : #if !defined(XP_MACOSX)
    1794           0 :   if (!mPluginWindow || (mPluginWindow->type == NPWindowTypeWindow))
    1795           0 :     return aMouseEvent->PreventDefault(); // consume event
    1796             :   // continue only for cases without child window
    1797             : #endif
    1798             :   // don't send mouse events if we are hidden
    1799           0 :   if (!mWidgetVisible)
    1800           0 :     return NS_OK;
    1801             : 
    1802             :   WidgetMouseEvent* mouseEvent =
    1803           0 :     aMouseEvent->WidgetEventPtr()->AsMouseEvent();
    1804           0 :   if (mouseEvent && mouseEvent->mClass == eMouseEventClass) {
    1805           0 :     nsEventStatus rv = ProcessEvent(*mouseEvent);
    1806           0 :     if (nsEventStatus_eConsumeNoDefault == rv) {
    1807           0 :       aMouseEvent->PreventDefault();
    1808           0 :       if (!aAllowPropagate) {
    1809           0 :         aMouseEvent->StopPropagation();
    1810             :       }
    1811             :     }
    1812           0 :     if (mouseEvent->mMessage == eMouseUp) {
    1813           0 :       mLastMouseDownButtonType = -1;
    1814             :     }
    1815             :   }
    1816           0 :   return NS_OK;
    1817             : }
    1818             : 
    1819             : #ifdef XP_WIN
    1820             : void
    1821             : nsPluginInstanceOwner::CallDefaultProc(const WidgetGUIEvent* aEvent)
    1822             : {
    1823             :   nsCOMPtr<nsIWidget> widget = GetContainingWidgetIfOffset();
    1824             :   if (!widget) {
    1825             :     widget = GetRootWidgetForPluginFrame(mPluginFrame);
    1826             :     if (NS_WARN_IF(!widget)) {
    1827             :       return;
    1828             :     }
    1829             :   }
    1830             : 
    1831             :   const NPEvent* npEvent =
    1832             :     static_cast<const NPEvent*>(aEvent->mPluginEvent);
    1833             :   if (NS_WARN_IF(!npEvent)) {
    1834             :     return;
    1835             :   }
    1836             : 
    1837             :   WidgetPluginEvent pluginEvent(true, ePluginInputEvent, widget);
    1838             :   pluginEvent.mPluginEvent.Copy(*npEvent);
    1839             :   widget->DefaultProcOfPluginEvent(pluginEvent);
    1840             : }
    1841             : 
    1842             : already_AddRefed<TextComposition>
    1843             : nsPluginInstanceOwner::GetTextComposition()
    1844             : {
    1845             :   if (NS_WARN_IF(!mPluginFrame)) {
    1846             :     return nullptr;
    1847             :   }
    1848             : 
    1849             :   nsCOMPtr<nsIWidget> widget = GetContainingWidgetIfOffset();
    1850             :   if (!widget) {
    1851             :     widget = GetRootWidgetForPluginFrame(mPluginFrame);
    1852             :     if (NS_WARN_IF(!widget)) {
    1853             :       return nullptr;
    1854             :     }
    1855             :   }
    1856             : 
    1857             :   RefPtr<TextComposition> composition =
    1858             :     IMEStateManager::GetTextCompositionFor(widget);
    1859             :   if (NS_WARN_IF(!composition)) {
    1860             :     return nullptr;
    1861             :   }
    1862             : 
    1863             :   return composition.forget();
    1864             : }
    1865             : 
    1866             : void
    1867             : nsPluginInstanceOwner::HandleNoConsumedCompositionMessage(
    1868             :   WidgetCompositionEvent* aCompositionEvent,
    1869             :   const NPEvent* aPluginEvent)
    1870             : {
    1871             :   nsCOMPtr<nsIWidget> widget = GetContainingWidgetIfOffset();
    1872             :   if (!widget) {
    1873             :     widget = GetRootWidgetForPluginFrame(mPluginFrame);
    1874             :     if (NS_WARN_IF(!widget)) {
    1875             :       return;
    1876             :     }
    1877             :   }
    1878             : 
    1879             :   NPEvent npevent;
    1880             :   if (aPluginEvent->lParam & GCS_RESULTSTR) {
    1881             :     // GCS_RESULTSTR's default proc will generate WM_CHAR. So emulate it.
    1882             :     for (size_t i = 0; i < aCompositionEvent->mData.Length(); i++) {
    1883             :       WidgetPluginEvent charEvent(true, ePluginInputEvent, widget);
    1884             :       npevent.event = WM_CHAR;
    1885             :       npevent.wParam = aCompositionEvent->mData[i];
    1886             :       npevent.lParam = 0;
    1887             :       charEvent.mPluginEvent.Copy(npevent);
    1888             :       ProcessEvent(charEvent);
    1889             :     }
    1890             :     return;
    1891             :   }
    1892             :   if (!mSentStartComposition) {
    1893             :     // We post WM_IME_COMPOSITION to default proc, but
    1894             :     // WM_IME_STARTCOMPOSITION isn't post yet.  We should post it at first.
    1895             :     WidgetPluginEvent startEvent(true, ePluginInputEvent, widget);
    1896             :     npevent.event = WM_IME_STARTCOMPOSITION;
    1897             :     npevent.wParam = 0;
    1898             :     npevent.lParam = 0;
    1899             :     startEvent.mPluginEvent.Copy(npevent);
    1900             :     CallDefaultProc(&startEvent);
    1901             :     mSentStartComposition = true;
    1902             :   }
    1903             : 
    1904             :   CallDefaultProc(aCompositionEvent);
    1905             : }
    1906             : #endif
    1907             : 
    1908             : nsresult
    1909           0 : nsPluginInstanceOwner::DispatchCompositionToPlugin(nsIDOMEvent* aEvent)
    1910             : {
    1911             : #ifdef XP_WIN
    1912             :   if (!mPluginWindow) {
    1913             :     // CompositionEvent isn't cancellable.  So it is unnecessary to call
    1914             :     // PreventDefaults() to consume event
    1915             :     return NS_OK;
    1916             :   }
    1917             :   WidgetCompositionEvent* compositionEvent =
    1918             :     aEvent->WidgetEventPtr()->AsCompositionEvent();
    1919             :   if (NS_WARN_IF(!compositionEvent)) {
    1920             :       return NS_ERROR_INVALID_ARG;
    1921             :   }
    1922             : 
    1923             :   if (compositionEvent->mMessage == eCompositionChange) {
    1924             :     RefPtr<TextComposition> composition = GetTextComposition();
    1925             :     if (NS_WARN_IF(!composition)) {
    1926             :       return NS_ERROR_FAILURE;
    1927             :     }
    1928             :     TextComposition::CompositionChangeEventHandlingMarker
    1929             :       compositionChangeEventHandlingMarker(composition, compositionEvent);
    1930             :   }
    1931             : 
    1932             :   const NPEvent* pPluginEvent =
    1933             :     static_cast<const NPEvent*>(compositionEvent->mPluginEvent);
    1934             :   if (pPluginEvent && pPluginEvent->event == WM_IME_COMPOSITION &&
    1935             :       mPluginDidNotHandleIMEComposition) {
    1936             :     // This is a workaround when running windowed and windowless Flash on
    1937             :     // same process.
    1938             :     // Flash with protected mode calls IMM APIs on own render process.  This
    1939             :     // is a bug of Flash's protected mode.
    1940             :     // ImmGetCompositionString with GCS_RESULTSTR returns *LAST* committed
    1941             :     // string.  So when windowed mode Flash handles IME composition,
    1942             :     // windowless plugin can get windowed mode's commited string by that API.
    1943             :     // So we never post WM_IME_COMPOSITION when plugin doesn't call
    1944             :     // ImmGetCompositionString() during WM_IME_COMPOSITION correctly.
    1945             :     HandleNoConsumedCompositionMessage(compositionEvent, pPluginEvent);
    1946             :     aEvent->StopImmediatePropagation();
    1947             :     return NS_OK;
    1948             :   }
    1949             : 
    1950             :   // Protected mode Flash returns noDefault by NPP_HandleEvent, but
    1951             :   // composition information into plugin is invalid because plugin's bug.
    1952             :   // So if plugin doesn't get composition data by WM_IME_COMPOSITION, we
    1953             :   // recongnize it isn't handled
    1954             :   AutoRestore<bool> restore(mGotCompositionData);
    1955             :   mGotCompositionData = false;
    1956             : 
    1957             :   nsEventStatus status = ProcessEvent(*compositionEvent);
    1958             :   aEvent->StopImmediatePropagation();
    1959             : 
    1960             :   // Composition event isn't handled by plugin, so we have to call default proc.
    1961             : 
    1962             :   if (NS_WARN_IF(!pPluginEvent)) {
    1963             :     return NS_OK;
    1964             :   }
    1965             : 
    1966             :   if (pPluginEvent->event == WM_IME_STARTCOMPOSITION) {
    1967             :     // Flash's protected mode lies that composition event is handled, but it
    1968             :     // cannot do it well.  So even if handled, we should post this message when
    1969             :     // no IMM API calls during WM_IME_COMPOSITION.
    1970             :     if (nsEventStatus_eConsumeNoDefault != status)  {
    1971             :       CallDefaultProc(compositionEvent);
    1972             :       mSentStartComposition = true;
    1973             :     } else {
    1974             :       mSentStartComposition = false;
    1975             :     }
    1976             :     mPluginDidNotHandleIMEComposition = false;
    1977             :     return NS_OK;
    1978             :   }
    1979             : 
    1980             :   if (pPluginEvent->event == WM_IME_ENDCOMPOSITION) {
    1981             :     // Always post WM_END_COMPOSITION to default proc. Because Flash may lie
    1982             :     // that it doesn't handle composition well, but event is handled.
    1983             :     // Even if posting this message, default proc do nothing if unnecessary.
    1984             :     CallDefaultProc(compositionEvent);
    1985             :     return NS_OK;
    1986             :   }
    1987             : 
    1988             :   if (pPluginEvent->event == WM_IME_COMPOSITION && !mGotCompositionData) {
    1989             :     // If plugin doesn't handle WM_IME_COMPOSITION correctly, we don't send
    1990             :     // composition event until end composition.
    1991             :     mPluginDidNotHandleIMEComposition = true;
    1992             : 
    1993             :     HandleNoConsumedCompositionMessage(compositionEvent, pPluginEvent);
    1994             :   }
    1995             : #endif // #ifdef XP_WIN
    1996           0 :   return NS_OK;
    1997             : }
    1998             : 
    1999             : nsresult
    2000           0 : nsPluginInstanceOwner::HandleEvent(nsIDOMEvent* aEvent)
    2001             : {
    2002           0 :   NS_ASSERTION(mInstance, "Should have a valid plugin instance or not receive events.");
    2003             : 
    2004           0 :   nsAutoString eventType;
    2005           0 :   aEvent->GetType(eventType);
    2006             : 
    2007             : #ifdef XP_MACOSX
    2008             :   if (eventType.EqualsLiteral("activate") ||
    2009             :       eventType.EqualsLiteral("deactivate")) {
    2010             :     WindowFocusMayHaveChanged();
    2011             :     return NS_OK;
    2012             :   }
    2013             :   if (eventType.EqualsLiteral("MozPerformDelayedBlur")) {
    2014             :     if (mShouldBlurOnActivate) {
    2015             :       WidgetGUIEvent blurEvent(true, eBlur, nullptr);
    2016             :       ProcessEvent(blurEvent);
    2017             :       mShouldBlurOnActivate = false;
    2018             :     }
    2019             :     return NS_OK;
    2020             :   }
    2021             : #endif
    2022             : 
    2023           0 :   if (eventType.EqualsLiteral("focus")) {
    2024           0 :     mContentFocused = true;
    2025           0 :     return DispatchFocusToPlugin(aEvent);
    2026             :   }
    2027           0 :   if (eventType.EqualsLiteral("blur")) {
    2028           0 :     mContentFocused = false;
    2029           0 :     return DispatchFocusToPlugin(aEvent);
    2030             :   }
    2031           0 :   if (eventType.EqualsLiteral("mousedown")) {
    2032           0 :     return ProcessMouseDown(aEvent);
    2033             :   }
    2034           0 :   if (eventType.EqualsLiteral("mouseup")) {
    2035           0 :     return DispatchMouseToPlugin(aEvent);
    2036             :   }
    2037           0 :   if (eventType.EqualsLiteral("mousemove")) {
    2038           0 :     return DispatchMouseToPlugin(aEvent, true);
    2039             :   }
    2040           0 :   if (eventType.EqualsLiteral("click") ||
    2041           0 :       eventType.EqualsLiteral("dblclick") ||
    2042           0 :       eventType.EqualsLiteral("mouseover") ||
    2043           0 :       eventType.EqualsLiteral("mouseout")) {
    2044           0 :     return DispatchMouseToPlugin(aEvent);
    2045             :   }
    2046           0 :   if (eventType.EqualsLiteral("keydown") ||
    2047           0 :       eventType.EqualsLiteral("keyup")) {
    2048           0 :     return DispatchKeyToPlugin(aEvent);
    2049             :   }
    2050           0 :   if (eventType.EqualsLiteral("keypress")) {
    2051           0 :     return ProcessKeyPress(aEvent);
    2052             :   }
    2053           0 :   if (eventType.EqualsLiteral("compositionstart") ||
    2054           0 :       eventType.EqualsLiteral("compositionend") ||
    2055           0 :       eventType.EqualsLiteral("text")) {
    2056           0 :     return DispatchCompositionToPlugin(aEvent);
    2057             :   }
    2058             : 
    2059           0 :   nsCOMPtr<nsIDOMDragEvent> dragEvent(do_QueryInterface(aEvent));
    2060           0 :   if (dragEvent && mInstance) {
    2061           0 :     WidgetEvent* ievent = aEvent->WidgetEventPtr();
    2062           0 :     if (ievent && ievent->IsTrusted() &&
    2063           0 :         ievent->mMessage != eDragEnter && ievent->mMessage != eDragOver) {
    2064           0 :       aEvent->PreventDefault();
    2065             :     }
    2066             : 
    2067             :     // Let the plugin handle drag events.
    2068           0 :     aEvent->StopPropagation();
    2069             :   }
    2070           0 :   return NS_OK;
    2071             : }
    2072             : 
    2073             : #ifdef MOZ_X11
    2074           0 : static unsigned int XInputEventState(const WidgetInputEvent& anEvent)
    2075             : {
    2076           0 :   unsigned int state = 0;
    2077           0 :   if (anEvent.IsShift()) state |= ShiftMask;
    2078           0 :   if (anEvent.IsControl()) state |= ControlMask;
    2079           0 :   if (anEvent.IsAlt()) state |= Mod1Mask;
    2080           0 :   if (anEvent.IsMeta()) state |= Mod4Mask;
    2081           0 :   return state;
    2082             : }
    2083             : #endif
    2084             : 
    2085             : #ifdef XP_MACOSX
    2086             : 
    2087             : // Returns whether or not content is the content that is or would be
    2088             : // focused if the top-level chrome window was active.
    2089             : static bool
    2090             : ContentIsFocusedWithinWindow(nsIContent* aContent)
    2091             : {
    2092             :   nsPIDOMWindowOuter* outerWindow = aContent->OwnerDoc()->GetWindow();
    2093             :   if (!outerWindow) {
    2094             :     return false;
    2095             :   }
    2096             : 
    2097             :   nsPIDOMWindowOuter* rootWindow = outerWindow->GetPrivateRoot();
    2098             :   if (!rootWindow) {
    2099             :     return false;
    2100             :   }
    2101             : 
    2102             :   nsFocusManager* fm = nsFocusManager::GetFocusManager();
    2103             :   if (!fm) {
    2104             :     return false;
    2105             :   }
    2106             : 
    2107             :   nsCOMPtr<nsPIDOMWindowOuter> focusedFrame;
    2108             :   nsCOMPtr<nsIContent> focusedContent = fm->GetFocusedDescendant(rootWindow, true, getter_AddRefs(focusedFrame));
    2109             :   return (focusedContent.get() == aContent);
    2110             : }
    2111             : 
    2112             : static NPCocoaEventType
    2113             : CocoaEventTypeForEvent(const WidgetGUIEvent& anEvent, nsIFrame* aObjectFrame)
    2114             : {
    2115             :   const NPCocoaEvent* event = static_cast<const NPCocoaEvent*>(anEvent.mPluginEvent);
    2116             :   if (event) {
    2117             :     return event->type;
    2118             :   }
    2119             : 
    2120             :   switch (anEvent.mMessage) {
    2121             :     case eMouseOver:
    2122             :       return NPCocoaEventMouseEntered;
    2123             :     case eMouseOut:
    2124             :       return NPCocoaEventMouseExited;
    2125             :     case eMouseMove: {
    2126             :       // We don't know via information on events from the widget code whether or not
    2127             :       // we're dragging. The widget code just generates mouse move events from native
    2128             :       // drag events. If anybody is capturing, this is a drag event.
    2129             :       if (nsIPresShell::GetCapturingContent()) {
    2130             :         return NPCocoaEventMouseDragged;
    2131             :       }
    2132             : 
    2133             :       return NPCocoaEventMouseMoved;
    2134             :     }
    2135             :     case eMouseDown:
    2136             :       return NPCocoaEventMouseDown;
    2137             :     case eMouseUp:
    2138             :       return NPCocoaEventMouseUp;
    2139             :     case eKeyDown:
    2140             :       return NPCocoaEventKeyDown;
    2141             :     case eKeyUp:
    2142             :       return NPCocoaEventKeyUp;
    2143             :     case eFocus:
    2144             :     case eBlur:
    2145             :       return NPCocoaEventFocusChanged;
    2146             :     case eLegacyMouseLineOrPageScroll:
    2147             :       return NPCocoaEventScrollWheel;
    2148             :     default:
    2149             :       return (NPCocoaEventType)0;
    2150             :   }
    2151             : }
    2152             : 
    2153             : static NPCocoaEvent
    2154             : TranslateToNPCocoaEvent(WidgetGUIEvent* anEvent, nsIFrame* aObjectFrame)
    2155             : {
    2156             :   NPCocoaEvent cocoaEvent;
    2157             :   InitializeNPCocoaEvent(&cocoaEvent);
    2158             :   cocoaEvent.type = CocoaEventTypeForEvent(*anEvent, aObjectFrame);
    2159             : 
    2160             :   if (anEvent->mMessage == eMouseMove ||
    2161             :       anEvent->mMessage == eMouseDown ||
    2162             :       anEvent->mMessage == eMouseUp ||
    2163             :       anEvent->mMessage == eLegacyMouseLineOrPageScroll ||
    2164             :       anEvent->mMessage == eMouseOver ||
    2165             :       anEvent->mMessage == eMouseOut)
    2166             :   {
    2167             :     nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(anEvent, aObjectFrame) -
    2168             :                  aObjectFrame->GetContentRectRelativeToSelf().TopLeft();
    2169             :     nsPresContext* presContext = aObjectFrame->PresContext();
    2170             :     // Plugin event coordinates need to be translated from device pixels
    2171             :     // into "display pixels" in HiDPI modes.
    2172             :     double scaleFactor = double(nsPresContext::AppUnitsPerCSSPixel())/
    2173             :       aObjectFrame->PresContext()->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom();
    2174             :     size_t intScaleFactor = ceil(scaleFactor);
    2175             :     nsIntPoint ptPx(presContext->AppUnitsToDevPixels(pt.x) / intScaleFactor,
    2176             :                     presContext->AppUnitsToDevPixels(pt.y) / intScaleFactor);
    2177             :     cocoaEvent.data.mouse.pluginX = double(ptPx.x);
    2178             :     cocoaEvent.data.mouse.pluginY = double(ptPx.y);
    2179             :   }
    2180             : 
    2181             :   switch (anEvent->mMessage) {
    2182             :     case eMouseDown:
    2183             :     case eMouseUp: {
    2184             :       WidgetMouseEvent* mouseEvent = anEvent->AsMouseEvent();
    2185             :       if (mouseEvent) {
    2186             :         switch (mouseEvent->button) {
    2187             :           case WidgetMouseEvent::eLeftButton:
    2188             :             cocoaEvent.data.mouse.buttonNumber = 0;
    2189             :             break;
    2190             :           case WidgetMouseEvent::eRightButton:
    2191             :             cocoaEvent.data.mouse.buttonNumber = 1;
    2192             :             break;
    2193             :           case WidgetMouseEvent::eMiddleButton:
    2194             :             cocoaEvent.data.mouse.buttonNumber = 2;
    2195             :             break;
    2196             :           default:
    2197             :             NS_WARNING("Mouse button we don't know about?");
    2198             :         }
    2199             :         cocoaEvent.data.mouse.clickCount = mouseEvent->mClickCount;
    2200             :       } else {
    2201             :         NS_WARNING("eMouseUp/DOWN is not a WidgetMouseEvent?");
    2202             :       }
    2203             :       break;
    2204             :     }
    2205             :     case eLegacyMouseLineOrPageScroll: {
    2206             :       WidgetWheelEvent* wheelEvent = anEvent->AsWheelEvent();
    2207             :       if (wheelEvent) {
    2208             :         cocoaEvent.data.mouse.deltaX = wheelEvent->mLineOrPageDeltaX;
    2209             :         cocoaEvent.data.mouse.deltaY = wheelEvent->mLineOrPageDeltaY;
    2210             :       } else {
    2211             :         NS_WARNING("eLegacyMouseLineOrPageScroll is not a WidgetWheelEvent? "
    2212             :                    "(could be, haven't checked)");
    2213             :       }
    2214             :       break;
    2215             :     }
    2216             :     case eKeyDown:
    2217             :     case eKeyUp:
    2218             :     {
    2219             :       WidgetKeyboardEvent* keyEvent = anEvent->AsKeyboardEvent();
    2220             : 
    2221             :       // That keyEvent->mPluginTextEventString is non-empty is a signal that we should
    2222             :       // create a text event for the plugin, instead of a key event.
    2223             :       if (anEvent->mMessage == eKeyDown &&
    2224             :           !keyEvent->mPluginTextEventString.IsEmpty()) {
    2225             :         cocoaEvent.type = NPCocoaEventTextInput;
    2226             :         const char16_t* pluginTextEventString = keyEvent->mPluginTextEventString.get();
    2227             :         cocoaEvent.data.text.text = (NPNSString*)
    2228             :           ::CFStringCreateWithCharacters(NULL,
    2229             :                                          reinterpret_cast<const UniChar*>(pluginTextEventString),
    2230             :                                          keyEvent->mPluginTextEventString.Length());
    2231             :       } else {
    2232             :         cocoaEvent.data.key.keyCode = keyEvent->mNativeKeyCode;
    2233             :         cocoaEvent.data.key.isARepeat = keyEvent->mIsRepeat;
    2234             :         cocoaEvent.data.key.modifierFlags = keyEvent->mNativeModifierFlags;
    2235             :         const char16_t* nativeChars = keyEvent->mNativeCharacters.get();
    2236             :         cocoaEvent.data.key.characters = (NPNSString*)
    2237             :           ::CFStringCreateWithCharacters(NULL,
    2238             :                                          reinterpret_cast<const UniChar*>(nativeChars),
    2239             :                                          keyEvent->mNativeCharacters.Length());
    2240             :         const char16_t* nativeCharsIgnoringModifiers = keyEvent->mNativeCharactersIgnoringModifiers.get();
    2241             :         cocoaEvent.data.key.charactersIgnoringModifiers = (NPNSString*)
    2242             :           ::CFStringCreateWithCharacters(NULL,
    2243             :                                          reinterpret_cast<const UniChar*>(nativeCharsIgnoringModifiers),
    2244             :                                          keyEvent->mNativeCharactersIgnoringModifiers.Length());
    2245             :       }
    2246             :       break;
    2247             :     }
    2248             :     case eFocus:
    2249             :     case eBlur:
    2250             :       cocoaEvent.data.focus.hasFocus = (anEvent->mMessage == eFocus);
    2251             :       break;
    2252             :     default:
    2253             :       break;
    2254             :   }
    2255             :   return cocoaEvent;
    2256             : }
    2257             : 
    2258             : void nsPluginInstanceOwner::PerformDelayedBlurs()
    2259             : {
    2260             :   nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
    2261             :   nsCOMPtr<EventTarget> windowRoot = content->OwnerDoc()->GetWindow()->GetTopWindowRoot();
    2262             :   nsContentUtils::DispatchTrustedEvent(content->OwnerDoc(),
    2263             :                                        windowRoot,
    2264             :                                        NS_LITERAL_STRING("MozPerformDelayedBlur"),
    2265             :                                        false, false, nullptr);
    2266             : }
    2267             : 
    2268             : #endif
    2269             : 
    2270           0 : nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
    2271             : {
    2272           0 :   nsEventStatus rv = nsEventStatus_eIgnore;
    2273             : 
    2274           0 :   if (!mInstance || !mPluginFrame) {
    2275           0 :     return nsEventStatus_eIgnore;
    2276             :   }
    2277             : 
    2278             : #ifdef XP_MACOSX
    2279             :   NPEventModel eventModel = GetEventModel();
    2280             :   if (eventModel != NPEventModelCocoa) {
    2281             :     return nsEventStatus_eIgnore;
    2282             :   }
    2283             : 
    2284             :   // In the Cocoa event model, focus is per-window. Don't tell a plugin it lost
    2285             :   // focus unless it lost focus within the window. For example, ignore a blur
    2286             :   // event if it's coming due to the plugin's window deactivating.
    2287             :   nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
    2288             :   if (anEvent.mMessage == eBlur && ContentIsFocusedWithinWindow(content)) {
    2289             :     mShouldBlurOnActivate = true;
    2290             :     return nsEventStatus_eIgnore;
    2291             :   }
    2292             : 
    2293             :   // Also, don't tell the plugin it gained focus again after we've already given
    2294             :   // it focus. This might happen if it has focus, its window is blurred, then the
    2295             :   // window is made active again. The plugin never lost in-window focus, so it
    2296             :   // shouldn't get a focus event again.
    2297             :   if (anEvent.mMessage == eFocus && mLastContentFocused == true) {
    2298             :     mShouldBlurOnActivate = false;
    2299             :     return nsEventStatus_eIgnore;
    2300             :   }
    2301             : 
    2302             :   // Now, if we're going to send a focus event, update mLastContentFocused and
    2303             :   // tell any plugins in our window that we have taken focus, so they should
    2304             :   // perform any delayed blurs.
    2305             :   if (anEvent.mMessage == eFocus || anEvent.mMessage == eBlur) {
    2306             :     mLastContentFocused = (anEvent.mMessage == eFocus);
    2307             :     mShouldBlurOnActivate = false;
    2308             :     PerformDelayedBlurs();
    2309             :   }
    2310             : 
    2311             :   NPCocoaEvent cocoaEvent = TranslateToNPCocoaEvent(const_cast<WidgetGUIEvent*>(&anEvent), mPluginFrame);
    2312             :   if (cocoaEvent.type == (NPCocoaEventType)0) {
    2313             :     return nsEventStatus_eIgnore;
    2314             :   }
    2315             : 
    2316             :   if (cocoaEvent.type == NPCocoaEventTextInput) {
    2317             :     mInstance->HandleEvent(&cocoaEvent, nullptr);
    2318             :     return nsEventStatus_eConsumeNoDefault;
    2319             :   }
    2320             : 
    2321             :   int16_t response = kNPEventNotHandled;
    2322             :   mInstance->HandleEvent(&cocoaEvent,
    2323             :                          &response,
    2324             :                          NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
    2325             :   if ((response == kNPEventStartIME) && (cocoaEvent.type == NPCocoaEventKeyDown)) {
    2326             :     nsIWidget* widget = mPluginFrame->GetNearestWidget();
    2327             :     if (widget) {
    2328             :       const WidgetKeyboardEvent* keyEvent = anEvent.AsKeyboardEvent();
    2329             :       double screenX, screenY;
    2330             :       ConvertPoint(0.0, mPluginFrame->GetScreenRect().height,
    2331             :                    NPCoordinateSpacePlugin, &screenX, &screenY,
    2332             :                    NPCoordinateSpaceScreen);
    2333             :       nsAutoString outText;
    2334             :       if (NS_SUCCEEDED(widget->StartPluginIME(*keyEvent, screenX, screenY, outText)) &&
    2335             :           !outText.IsEmpty()) {
    2336             :         CFStringRef cfString =
    2337             :           ::CFStringCreateWithCharacters(kCFAllocatorDefault,
    2338             :                                          reinterpret_cast<const UniChar*>(outText.get()),
    2339             :                                          outText.Length());
    2340             :         NPCocoaEvent textEvent;
    2341             :         InitializeNPCocoaEvent(&textEvent);
    2342             :         textEvent.type = NPCocoaEventTextInput;
    2343             :         textEvent.data.text.text = (NPNSString*)cfString;
    2344             :         mInstance->HandleEvent(&textEvent, nullptr);
    2345             :       }
    2346             :     }
    2347             :   }
    2348             : 
    2349             :   bool handled = (response == kNPEventHandled || response == kNPEventStartIME);
    2350             :   bool leftMouseButtonDown = (anEvent.mMessage == eMouseDown) &&
    2351             :                              (anEvent.AsMouseEvent()->button == WidgetMouseEvent::eLeftButton);
    2352             :   if (handled && !(leftMouseButtonDown && !mContentFocused)) {
    2353             :     rv = nsEventStatus_eConsumeNoDefault;
    2354             :   }
    2355             : #endif
    2356             : 
    2357             : #ifdef XP_WIN
    2358             :   // this code supports windowless plugins
    2359             :   const NPEvent *pPluginEvent = static_cast<const NPEvent*>(anEvent.mPluginEvent);
    2360             :   // we can get synthetic events from the EventStateManager... these
    2361             :   // have no pluginEvent
    2362             :   NPEvent pluginEvent;
    2363             :   if (anEvent.mClass == eMouseEventClass ||
    2364             :       anEvent.mClass == eWheelEventClass) {
    2365             :     if (!pPluginEvent) {
    2366             :       // XXX Should extend this list to synthesize events for more event
    2367             :       // types
    2368             :       pluginEvent.event = 0;
    2369             :       bool initWParamWithCurrentState = true;
    2370             :       switch (anEvent.mMessage) {
    2371             :       case eMouseMove: {
    2372             :         pluginEvent.event = WM_MOUSEMOVE;
    2373             :         break;
    2374             :       }
    2375             :       case eMouseDown: {
    2376             :         static const int downMsgs[] =
    2377             :           { WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN };
    2378             :         static const int dblClickMsgs[] =
    2379             :           { WM_LBUTTONDBLCLK, WM_MBUTTONDBLCLK, WM_RBUTTONDBLCLK };
    2380             :         const WidgetMouseEvent* mouseEvent = anEvent.AsMouseEvent();
    2381             :         if (mouseEvent->mClickCount == 2) {
    2382             :           pluginEvent.event = dblClickMsgs[mouseEvent->button];
    2383             :         } else {
    2384             :           pluginEvent.event = downMsgs[mouseEvent->button];
    2385             :         }
    2386             :         break;
    2387             :       }
    2388             :       case eMouseUp: {
    2389             :         static const int upMsgs[] =
    2390             :           { WM_LBUTTONUP, WM_MBUTTONUP, WM_RBUTTONUP };
    2391             :         const WidgetMouseEvent* mouseEvent = anEvent.AsMouseEvent();
    2392             :         pluginEvent.event = upMsgs[mouseEvent->button];
    2393             :         break;
    2394             :       }
    2395             :       // For plugins which don't support high-resolution scroll, we should
    2396             :       // generate legacy resolution wheel messages.  I.e., the delta value
    2397             :       // should be WHEEL_DELTA * n.
    2398             :       case eWheel: {
    2399             :         const WidgetWheelEvent* wheelEvent = anEvent.AsWheelEvent();
    2400             :         int32_t delta = 0;
    2401             :         if (wheelEvent->mLineOrPageDeltaY) {
    2402             :           switch (wheelEvent->mDeltaMode) {
    2403             :             case nsIDOMWheelEvent::DOM_DELTA_PAGE:
    2404             :               pluginEvent.event = WM_MOUSEWHEEL;
    2405             :               delta = -WHEEL_DELTA * wheelEvent->mLineOrPageDeltaY;
    2406             :               break;
    2407             :             case nsIDOMWheelEvent::DOM_DELTA_LINE: {
    2408             :               UINT linesPerWheelDelta = 0;
    2409             :               if (NS_WARN_IF(!::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0,
    2410             :                                                      &linesPerWheelDelta, 0))) {
    2411             :                 // Use system default scroll amount, 3, when
    2412             :                 // SPI_GETWHEELSCROLLLINES isn't available.
    2413             :                 linesPerWheelDelta = 3;
    2414             :               }
    2415             :               if (!linesPerWheelDelta) {
    2416             :                 break;
    2417             :               }
    2418             :               pluginEvent.event = WM_MOUSEWHEEL;
    2419             :               delta = -WHEEL_DELTA / linesPerWheelDelta;
    2420             :               delta *= wheelEvent->mLineOrPageDeltaY;
    2421             :               break;
    2422             :             }
    2423             :             case nsIDOMWheelEvent::DOM_DELTA_PIXEL:
    2424             :             default:
    2425             :               // We don't support WM_GESTURE with this path.
    2426             :               MOZ_ASSERT(!pluginEvent.event);
    2427             :               break;
    2428             :           }
    2429             :         } else if (wheelEvent->mLineOrPageDeltaX) {
    2430             :           switch (wheelEvent->mDeltaMode) {
    2431             :             case nsIDOMWheelEvent::DOM_DELTA_PAGE:
    2432             :               pluginEvent.event = WM_MOUSEHWHEEL;
    2433             :               delta = -WHEEL_DELTA * wheelEvent->mLineOrPageDeltaX;
    2434             :               break;
    2435             :             case nsIDOMWheelEvent::DOM_DELTA_LINE: {
    2436             :               pluginEvent.event = WM_MOUSEHWHEEL;
    2437             :               UINT charsPerWheelDelta = 0;
    2438             :               // FYI: SPI_GETWHEELSCROLLCHARS is available on Vista or later.
    2439             :               if (::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0,
    2440             :                                          &charsPerWheelDelta, 0)) {
    2441             :                 // Use system default scroll amount, 3, when
    2442             :                 // SPI_GETWHEELSCROLLCHARS isn't available.
    2443             :                 charsPerWheelDelta = 3;
    2444             :               }
    2445             :               if (!charsPerWheelDelta) {
    2446             :                 break;
    2447             :               }
    2448             :               delta = WHEEL_DELTA / charsPerWheelDelta;
    2449             :               delta *= wheelEvent->mLineOrPageDeltaX;
    2450             :               break;
    2451             :             }
    2452             :             case nsIDOMWheelEvent::DOM_DELTA_PIXEL:
    2453             :             default:
    2454             :               // We don't support WM_GESTURE with this path.
    2455             :               MOZ_ASSERT(!pluginEvent.event);
    2456             :               break;
    2457             :           }
    2458             :         }
    2459             : 
    2460             :         if (!pluginEvent.event) {
    2461             :           break;
    2462             :         }
    2463             : 
    2464             :         initWParamWithCurrentState = false;
    2465             :         int32_t modifiers =
    2466             :           (wheelEvent->IsControl() ?             MK_CONTROL  : 0) |
    2467             :           (wheelEvent->IsShift() ?               MK_SHIFT    : 0) |
    2468             :           (wheelEvent->IsLeftButtonPressed() ?   MK_LBUTTON  : 0) |
    2469             :           (wheelEvent->IsMiddleButtonPressed() ? MK_MBUTTON  : 0) |
    2470             :           (wheelEvent->IsRightButtonPressed() ?  MK_RBUTTON  : 0) |
    2471             :           (wheelEvent->Is4thButtonPressed() ?    MK_XBUTTON1 : 0) |
    2472             :           (wheelEvent->Is5thButtonPressed() ?    MK_XBUTTON2 : 0);
    2473             :         pluginEvent.wParam = MAKEWPARAM(modifiers, delta);
    2474             :         pPluginEvent = &pluginEvent;
    2475             :         break;
    2476             :       }
    2477             :       // don't synthesize anything for eMouseDoubleClick, since that
    2478             :       // is a synthetic event generated on mouse-up, and Windows WM_*DBLCLK
    2479             :       // messages are sent on mouse-down
    2480             :       default:
    2481             :         break;
    2482             :       }
    2483             :       if (pluginEvent.event && initWParamWithCurrentState) {
    2484             :         pPluginEvent = &pluginEvent;
    2485             :         pluginEvent.wParam =
    2486             :           (::GetKeyState(VK_CONTROL) ? MK_CONTROL : 0) |
    2487             :           (::GetKeyState(VK_SHIFT) ? MK_SHIFT : 0) |
    2488             :           (::GetKeyState(VK_LBUTTON) ? MK_LBUTTON : 0) |
    2489             :           (::GetKeyState(VK_MBUTTON) ? MK_MBUTTON : 0) |
    2490             :           (::GetKeyState(VK_RBUTTON) ? MK_RBUTTON : 0) |
    2491             :           (::GetKeyState(VK_XBUTTON1) ? MK_XBUTTON1 : 0) |
    2492             :           (::GetKeyState(VK_XBUTTON2) ? MK_XBUTTON2 : 0);
    2493             :       }
    2494             :     }
    2495             :     if (pPluginEvent) {
    2496             :       // Make event coordinates relative to our enclosing widget,
    2497             :       // not the widget they were received on.
    2498             :       // See use of NPEvent in widget/windows/nsWindow.cpp
    2499             :       // for why this assert should be safe
    2500             :       NS_ASSERTION(anEvent.mMessage == eMouseDown ||
    2501             :                    anEvent.mMessage == eMouseUp ||
    2502             :                    anEvent.mMessage == eMouseDoubleClick ||
    2503             :                    anEvent.mMessage == eMouseAuxClick ||
    2504             :                    anEvent.mMessage == eMouseOver ||
    2505             :                    anEvent.mMessage == eMouseOut ||
    2506             :                    anEvent.mMessage == eMouseMove ||
    2507             :                    anEvent.mMessage == eWheel,
    2508             :                    "Incorrect event type for coordinate translation");
    2509             :       nsPoint pt =
    2510             :         nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
    2511             :         mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
    2512             :       nsPresContext* presContext = mPluginFrame->PresContext();
    2513             :       nsIntPoint ptPx(presContext->AppUnitsToDevPixels(pt.x),
    2514             :                       presContext->AppUnitsToDevPixels(pt.y));
    2515             :       nsIntPoint widgetPtPx = ptPx + mPluginFrame->GetWindowOriginInPixels(true);
    2516             :       const_cast<NPEvent*>(pPluginEvent)->lParam = MAKELPARAM(widgetPtPx.x, widgetPtPx.y);
    2517             :     }
    2518             :   }
    2519             :   else if (!pPluginEvent) {
    2520             :     switch (anEvent.mMessage) {
    2521             :       case eFocus:
    2522             :         pluginEvent.event = WM_SETFOCUS;
    2523             :         pluginEvent.wParam = 0;
    2524             :         pluginEvent.lParam = 0;
    2525             :         pPluginEvent = &pluginEvent;
    2526             :         break;
    2527             :       case eBlur:
    2528             :         pluginEvent.event = WM_KILLFOCUS;
    2529             :         pluginEvent.wParam = 0;
    2530             :         pluginEvent.lParam = 0;
    2531             :         pPluginEvent = &pluginEvent;
    2532             :         break;
    2533             :       default:
    2534             :         break;
    2535             :     }
    2536             :   }
    2537             : 
    2538             :   if (pPluginEvent && !pPluginEvent->event) {
    2539             :     // Don't send null events to plugins.
    2540             :     NS_WARNING("nsPluginFrame ProcessEvent: trying to send null event to plugin.");
    2541             :     return rv;
    2542             :   }
    2543             : 
    2544             :   if (pPluginEvent) {
    2545             :     int16_t response = kNPEventNotHandled;
    2546             :     mInstance->HandleEvent(const_cast<NPEvent*>(pPluginEvent),
    2547             :                            &response,
    2548             :                            NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
    2549             :     if (response == kNPEventHandled)
    2550             :       rv = nsEventStatus_eConsumeNoDefault;
    2551             :   }
    2552             : #endif
    2553             : 
    2554             : #ifdef MOZ_X11
    2555             :   // this code supports windowless plugins
    2556           0 :   nsIWidget* widget = anEvent.mWidget;
    2557           0 :   XEvent pluginEvent = XEvent();
    2558           0 :   pluginEvent.type = 0;
    2559             : 
    2560           0 :   switch(anEvent.mClass) {
    2561             :     case eMouseEventClass:
    2562             :       {
    2563           0 :         switch (anEvent.mMessage) {
    2564             :           case eMouseClick:
    2565             :           case eMouseDoubleClick:
    2566             :           case eMouseAuxClick:
    2567             :             // Button up/down events sent instead.
    2568           0 :             return rv;
    2569             :           default:
    2570           0 :             break;
    2571             :           }
    2572             : 
    2573             :         // Get reference point relative to plugin origin.
    2574           0 :         const nsPresContext* presContext = mPluginFrame->PresContext();
    2575             :         nsPoint appPoint =
    2576           0 :           nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
    2577           0 :           mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
    2578             :         nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x),
    2579           0 :                                presContext->AppUnitsToDevPixels(appPoint.y));
    2580           0 :         const WidgetMouseEvent& mouseEvent = *anEvent.AsMouseEvent();
    2581             :         // Get reference point relative to screen:
    2582           0 :         LayoutDeviceIntPoint rootPoint(-1, -1);
    2583           0 :         if (widget) {
    2584           0 :           rootPoint = anEvent.mRefPoint + widget->WidgetToScreenOffset();
    2585             :         }
    2586             : #ifdef MOZ_WIDGET_GTK
    2587           0 :         Window root = GDK_ROOT_WINDOW();
    2588             : #else
    2589             :         Window root = X11None; // Could XQueryTree, but this is not important.
    2590             : #endif
    2591             : 
    2592           0 :         switch (anEvent.mMessage) {
    2593             :           case eMouseOver:
    2594             :           case eMouseOut:
    2595             :             {
    2596           0 :               XCrossingEvent& event = pluginEvent.xcrossing;
    2597           0 :               event.type = anEvent.mMessage == eMouseOver ?
    2598             :                 EnterNotify : LeaveNotify;
    2599           0 :               event.root = root;
    2600           0 :               event.time = anEvent.mTime;
    2601           0 :               event.x = pluginPoint.x;
    2602           0 :               event.y = pluginPoint.y;
    2603           0 :               event.x_root = rootPoint.x;
    2604           0 :               event.y_root = rootPoint.y;
    2605           0 :               event.state = XInputEventState(mouseEvent);
    2606             :               // information lost
    2607           0 :               event.subwindow = X11None;
    2608           0 :               event.mode = -1;
    2609           0 :               event.detail = NotifyDetailNone;
    2610           0 :               event.same_screen = True;
    2611           0 :               event.focus = mContentFocused;
    2612             :             }
    2613           0 :             break;
    2614             :           case eMouseMove:
    2615             :             {
    2616           0 :               XMotionEvent& event = pluginEvent.xmotion;
    2617           0 :               event.type = MotionNotify;
    2618           0 :               event.root = root;
    2619           0 :               event.time = anEvent.mTime;
    2620           0 :               event.x = pluginPoint.x;
    2621           0 :               event.y = pluginPoint.y;
    2622           0 :               event.x_root = rootPoint.x;
    2623           0 :               event.y_root = rootPoint.y;
    2624           0 :               event.state = XInputEventState(mouseEvent);
    2625             :               // information lost
    2626           0 :               event.subwindow = X11None;
    2627           0 :               event.is_hint = NotifyNormal;
    2628           0 :               event.same_screen = True;
    2629             :             }
    2630           0 :             break;
    2631             :           case eMouseDown:
    2632             :           case eMouseUp:
    2633             :             {
    2634           0 :               XButtonEvent& event = pluginEvent.xbutton;
    2635           0 :               event.type = anEvent.mMessage == eMouseDown ?
    2636             :                 ButtonPress : ButtonRelease;
    2637           0 :               event.root = root;
    2638           0 :               event.time = anEvent.mTime;
    2639           0 :               event.x = pluginPoint.x;
    2640           0 :               event.y = pluginPoint.y;
    2641           0 :               event.x_root = rootPoint.x;
    2642           0 :               event.y_root = rootPoint.y;
    2643           0 :               event.state = XInputEventState(mouseEvent);
    2644           0 :               switch (mouseEvent.button)
    2645             :                 {
    2646             :                 case WidgetMouseEvent::eMiddleButton:
    2647           0 :                   event.button = 2;
    2648           0 :                   break;
    2649             :                 case WidgetMouseEvent::eRightButton:
    2650           0 :                   event.button = 3;
    2651           0 :                   break;
    2652             :                 default: // WidgetMouseEvent::eLeftButton;
    2653           0 :                   event.button = 1;
    2654           0 :                   break;
    2655             :                 }
    2656             :               // information lost:
    2657           0 :               event.subwindow = X11None;
    2658           0 :               event.same_screen = True;
    2659             :             }
    2660           0 :             break;
    2661             :           default:
    2662           0 :             break;
    2663             :           }
    2664             :       }
    2665           0 :       break;
    2666             : 
    2667             :    //XXX case eMouseScrollEventClass: not received.
    2668             : 
    2669             :    case eKeyboardEventClass:
    2670           0 :       if (anEvent.mPluginEvent)
    2671             :         {
    2672           0 :           XKeyEvent &event = pluginEvent.xkey;
    2673             : #ifdef MOZ_WIDGET_GTK
    2674           0 :           event.root = GDK_ROOT_WINDOW();
    2675           0 :           event.time = anEvent.mTime;
    2676             :           const GdkEventKey* gdkEvent =
    2677           0 :             static_cast<const GdkEventKey*>(anEvent.mPluginEvent);
    2678           0 :           event.keycode = gdkEvent->hardware_keycode;
    2679           0 :           event.state = gdkEvent->state;
    2680           0 :           switch (anEvent.mMessage)
    2681             :             {
    2682             :             case eKeyDown:
    2683             :               // Handle eKeyDown for modifier key presses
    2684             :               // For non-modifiers we get eKeyPress
    2685           0 :               if (gdkEvent->is_modifier)
    2686           0 :                 event.type = XKeyPress;
    2687           0 :               break;
    2688             :             case eKeyPress:
    2689           0 :               event.type = XKeyPress;
    2690           0 :               break;
    2691             :             case eKeyUp:
    2692           0 :               event.type = KeyRelease;
    2693           0 :               break;
    2694             :             default:
    2695           0 :               break;
    2696             :             }
    2697             : #endif
    2698             : 
    2699             :           // Information that could be obtained from pluginEvent but we may not
    2700             :           // want to promise to provide:
    2701           0 :           event.subwindow = X11None;
    2702           0 :           event.x = 0;
    2703           0 :           event.y = 0;
    2704           0 :           event.x_root = -1;
    2705           0 :           event.y_root = -1;
    2706           0 :           event.same_screen = False;
    2707             :         }
    2708             :       else
    2709             :         {
    2710             :           // If we need to send synthesized key events, then
    2711             :           // DOMKeyCodeToGdkKeyCode(keyEvent.keyCode) and
    2712             :           // gdk_keymap_get_entries_for_keyval will be useful, but the
    2713             :           // mappings will not be unique.
    2714           0 :           NS_WARNING("Synthesized key event not sent to plugin");
    2715             :         }
    2716           0 :       break;
    2717             : 
    2718             :     default:
    2719           0 :       switch (anEvent.mMessage) {
    2720             :         case eFocus:
    2721             :         case eBlur:
    2722             :           {
    2723           0 :             XFocusChangeEvent &event = pluginEvent.xfocus;
    2724           0 :             event.type = anEvent.mMessage == eFocus ? FocusIn : FocusOut;
    2725             :             // information lost:
    2726           0 :             event.mode = -1;
    2727           0 :             event.detail = NotifyDetailNone;
    2728             :           }
    2729           0 :           break;
    2730             :         default:
    2731           0 :           break;
    2732             :       }
    2733             :     }
    2734             : 
    2735           0 :   if (!pluginEvent.type) {
    2736           0 :     return rv;
    2737             :   }
    2738             : 
    2739             :   // Fill in (useless) generic event information.
    2740           0 :   XAnyEvent& event = pluginEvent.xany;
    2741           0 :   event.display = widget ?
    2742           0 :     static_cast<Display*>(widget->GetNativeData(NS_NATIVE_DISPLAY)) : nullptr;
    2743           0 :   event.window = X11None; // not a real window
    2744             :   // information lost:
    2745           0 :   event.serial = 0;
    2746           0 :   event.send_event = False;
    2747             : 
    2748           0 :   int16_t response = kNPEventNotHandled;
    2749           0 :   mInstance->HandleEvent(&pluginEvent, &response, NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
    2750           0 :   if (response == kNPEventHandled)
    2751           0 :     rv = nsEventStatus_eConsumeNoDefault;
    2752             : #endif
    2753             : 
    2754             : #ifdef MOZ_WIDGET_ANDROID
    2755             :   // this code supports windowless plugins
    2756             :   {
    2757             :     // The plugin needs focus to receive keyboard and touch events
    2758             :     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
    2759             :     if (fm) {
    2760             :       nsCOMPtr<nsIDOMElement> elem = do_QueryReferent(mContent);
    2761             :       fm->SetFocus(elem, 0);
    2762             :     }
    2763             :   }
    2764             :   switch(anEvent.mClass) {
    2765             :     case eMouseEventClass:
    2766             :       {
    2767             :         switch (anEvent.mMessage) {
    2768             :           case eMouseClick:
    2769             :           case eMouseDoubleClick:
    2770             :           case eMouseAuxClick:
    2771             :             // Button up/down events sent instead.
    2772             :             return rv;
    2773             :           default:
    2774             :             break;
    2775             :           }
    2776             : 
    2777             :         // Get reference point relative to plugin origin.
    2778             :         const nsPresContext* presContext = mPluginFrame->PresContext();
    2779             :         nsPoint appPoint =
    2780             :           nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
    2781             :           mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
    2782             :         nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x),
    2783             :                                presContext->AppUnitsToDevPixels(appPoint.y));
    2784             : 
    2785             :         switch (anEvent.mMessage) {
    2786             :           case eMouseMove:
    2787             :             {
    2788             :               // are these going to be touch events?
    2789             :               // pluginPoint.x;
    2790             :               // pluginPoint.y;
    2791             :             }
    2792             :             break;
    2793             :           case eMouseDown:
    2794             :             {
    2795             :               ANPEvent event;
    2796             :               event.inSize = sizeof(ANPEvent);
    2797             :               event.eventType = kMouse_ANPEventType;
    2798             :               event.data.mouse.action = kDown_ANPMouseAction;
    2799             :               event.data.mouse.x = pluginPoint.x;
    2800             :               event.data.mouse.y = pluginPoint.y;
    2801             :               mInstance->HandleEvent(&event, nullptr, NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
    2802             :             }
    2803             :             break;
    2804             :           case eMouseUp:
    2805             :             {
    2806             :               ANPEvent event;
    2807             :               event.inSize = sizeof(ANPEvent);
    2808             :               event.eventType = kMouse_ANPEventType;
    2809             :               event.data.mouse.action = kUp_ANPMouseAction;
    2810             :               event.data.mouse.x = pluginPoint.x;
    2811             :               event.data.mouse.y = pluginPoint.y;
    2812             :               mInstance->HandleEvent(&event, nullptr, NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
    2813             :             }
    2814             :             break;
    2815             :           default:
    2816             :             break;
    2817             :           }
    2818             :       }
    2819             :       break;
    2820             : 
    2821             :     case eKeyboardEventClass:
    2822             :      {
    2823             :        const WidgetKeyboardEvent& keyEvent = *anEvent.AsKeyboardEvent();
    2824             :        LOG("Firing eKeyboardEventClass %d %d\n",
    2825             :            keyEvent.mKeyCode, keyEvent.mCharCode);
    2826             :        // pluginEvent is initialized by nsWindow::InitKeyEvent().
    2827             :        const ANPEvent* pluginEvent = static_cast<const ANPEvent*>(keyEvent.mPluginEvent);
    2828             :        if (pluginEvent) {
    2829             :          MOZ_ASSERT(pluginEvent->inSize == sizeof(ANPEvent));
    2830             :          MOZ_ASSERT(pluginEvent->eventType == kKey_ANPEventType);
    2831             :          mInstance->HandleEvent(const_cast<ANPEvent*>(pluginEvent),
    2832             :                                 nullptr,
    2833             :                                 NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
    2834             :        }
    2835             :      }
    2836             :      break;
    2837             : 
    2838             :     default:
    2839             :       break;
    2840             :     }
    2841             :     rv = nsEventStatus_eConsumeNoDefault;
    2842             : #endif
    2843             : 
    2844           0 :   return rv;
    2845             : }
    2846             : 
    2847             : nsresult
    2848           0 : nsPluginInstanceOwner::Destroy()
    2849             : {
    2850           0 :   SetFrame(nullptr);
    2851             : 
    2852             : #ifdef XP_MACOSX
    2853             :   RemoveFromCARefreshTimer();
    2854             : #endif
    2855             : 
    2856           0 :   nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
    2857             : 
    2858             :   // unregister context menu listener
    2859           0 :   if (mCXMenuListener) {
    2860           0 :     mCXMenuListener->Destroy(content);
    2861           0 :     mCXMenuListener = nullptr;
    2862             :   }
    2863             : 
    2864           0 :   content->RemoveEventListener(NS_LITERAL_STRING("focus"), this, false);
    2865           0 :   content->RemoveEventListener(NS_LITERAL_STRING("blur"), this, false);
    2866           0 :   content->RemoveEventListener(NS_LITERAL_STRING("mouseup"), this, false);
    2867           0 :   content->RemoveEventListener(NS_LITERAL_STRING("mousedown"), this, false);
    2868           0 :   content->RemoveEventListener(NS_LITERAL_STRING("mousemove"), this, false);
    2869           0 :   content->RemoveEventListener(NS_LITERAL_STRING("click"), this, false);
    2870           0 :   content->RemoveEventListener(NS_LITERAL_STRING("dblclick"), this, false);
    2871           0 :   content->RemoveEventListener(NS_LITERAL_STRING("mouseover"), this, false);
    2872           0 :   content->RemoveEventListener(NS_LITERAL_STRING("mouseout"), this, false);
    2873           0 :   content->RemoveEventListener(NS_LITERAL_STRING("keypress"), this, true);
    2874           0 :   content->RemoveEventListener(NS_LITERAL_STRING("keydown"), this, true);
    2875           0 :   content->RemoveEventListener(NS_LITERAL_STRING("keyup"), this, true);
    2876           0 :   content->RemoveEventListener(NS_LITERAL_STRING("drop"), this, true);
    2877           0 :   content->RemoveEventListener(NS_LITERAL_STRING("drag"), this, true);
    2878           0 :   content->RemoveEventListener(NS_LITERAL_STRING("dragenter"), this, true);
    2879           0 :   content->RemoveEventListener(NS_LITERAL_STRING("dragover"), this, true);
    2880           0 :   content->RemoveEventListener(NS_LITERAL_STRING("dragleave"), this, true);
    2881           0 :   content->RemoveEventListener(NS_LITERAL_STRING("dragexit"), this, true);
    2882           0 :   content->RemoveEventListener(NS_LITERAL_STRING("dragstart"), this, true);
    2883           0 :   content->RemoveEventListener(NS_LITERAL_STRING("dragend"), this, true);
    2884           0 :   content->RemoveSystemEventListener(NS_LITERAL_STRING("compositionstart"),
    2885           0 :                                      this, true);
    2886           0 :   content->RemoveSystemEventListener(NS_LITERAL_STRING("compositionend"),
    2887           0 :                                      this, true);
    2888           0 :   content->RemoveSystemEventListener(NS_LITERAL_STRING("text"), this, true);
    2889             : 
    2890             : #if MOZ_WIDGET_ANDROID
    2891             :   RemovePluginView();
    2892             : #endif
    2893             : 
    2894           0 :   if (mWidget) {
    2895           0 :     if (mPluginWindow) {
    2896           0 :       mPluginWindow->SetPluginWidget(nullptr);
    2897             :     }
    2898             : 
    2899           0 :     nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
    2900           0 :     if (pluginWidget) {
    2901           0 :       pluginWidget->SetPluginInstanceOwner(nullptr);
    2902             :     }
    2903           0 :     mWidget->Destroy();
    2904             :   }
    2905             : 
    2906           0 :   return NS_OK;
    2907             : }
    2908             : 
    2909             : // Paints are handled differently, so we just simulate an update event.
    2910             : 
    2911             : #ifdef XP_MACOSX
    2912             : void nsPluginInstanceOwner::Paint(const gfxRect& aDirtyRect, CGContextRef cgContext)
    2913             : {
    2914             :   if (!mInstance || !mPluginFrame)
    2915             :     return;
    2916             : 
    2917             :   gfxRect dirtyRectCopy = aDirtyRect;
    2918             :   double scaleFactor = 1.0;
    2919             :   GetContentsScaleFactor(&scaleFactor);
    2920             :   if (scaleFactor != 1.0) {
    2921             :     ::CGContextScaleCTM(cgContext, scaleFactor, scaleFactor);
    2922             :     // Convert aDirtyRect from device pixels to "display pixels"
    2923             :     // for HiDPI modes
    2924             :     dirtyRectCopy.ScaleRoundOut(1.0 / scaleFactor);
    2925             :   }
    2926             : 
    2927             :   DoCocoaEventDrawRect(dirtyRectCopy, cgContext);
    2928             : }
    2929             : 
    2930             : void nsPluginInstanceOwner::DoCocoaEventDrawRect(const gfxRect& aDrawRect, CGContextRef cgContext)
    2931             : {
    2932             :   if (!mInstance || !mPluginFrame)
    2933             :     return;
    2934             : 
    2935             :   // The context given here is only valid during the HandleEvent call.
    2936             :   NPCocoaEvent updateEvent;
    2937             :   InitializeNPCocoaEvent(&updateEvent);
    2938             :   updateEvent.type = NPCocoaEventDrawRect;
    2939             :   updateEvent.data.draw.context = cgContext;
    2940             :   updateEvent.data.draw.x = aDrawRect.X();
    2941             :   updateEvent.data.draw.y = aDrawRect.Y();
    2942             :   updateEvent.data.draw.width = aDrawRect.Width();
    2943             :   updateEvent.data.draw.height = aDrawRect.Height();
    2944             : 
    2945             :   mInstance->HandleEvent(&updateEvent, nullptr);
    2946             : }
    2947             : #endif
    2948             : 
    2949             : #ifdef XP_WIN
    2950             : void nsPluginInstanceOwner::Paint(const RECT& aDirty, HDC aDC)
    2951             : {
    2952             :   if (!mInstance || !mPluginFrame)
    2953             :     return;
    2954             : 
    2955             :   NPEvent pluginEvent;
    2956             :   pluginEvent.event = WM_PAINT;
    2957             :   pluginEvent.wParam = WPARAM(aDC);
    2958             :   pluginEvent.lParam = LPARAM(&aDirty);
    2959             :   mInstance->HandleEvent(&pluginEvent, nullptr);
    2960             : }
    2961             : #endif
    2962             : 
    2963             : #ifdef MOZ_WIDGET_ANDROID
    2964             : 
    2965             : void nsPluginInstanceOwner::Paint(gfxContext* aContext,
    2966             :                                   const gfxRect& aFrameRect,
    2967             :                                   const gfxRect& aDirtyRect)
    2968             : {
    2969             :   if (!mInstance || !mPluginFrame || !mPluginDocumentActiveState || mFullScreen)
    2970             :     return;
    2971             : 
    2972             :   int32_t model = mInstance->GetANPDrawingModel();
    2973             : 
    2974             :   if (model == kSurface_ANPDrawingModel) {
    2975             :     if (!AddPluginView(GetPluginRect())) {
    2976             :       Invalidate();
    2977             :     }
    2978             :     return;
    2979             :   }
    2980             : 
    2981             :   if (model != kBitmap_ANPDrawingModel)
    2982             :     return;
    2983             : 
    2984             : #ifdef ANP_BITMAP_DRAWING_MODEL
    2985             :   static RefPtr<gfxImageSurface> pluginSurface;
    2986             : 
    2987             :   if (pluginSurface == nullptr ||
    2988             :       aFrameRect.width  != pluginSurface->Width() ||
    2989             :       aFrameRect.height != pluginSurface->Height()) {
    2990             : 
    2991             :     pluginSurface = new gfxImageSurface(gfx::IntSize(aFrameRect.width, aFrameRect.height),
    2992             :                                         SurfaceFormat::A8R8G8B8_UINT32);
    2993             :     if (!pluginSurface)
    2994             :       return;
    2995             :   }
    2996             : 
    2997             :   // Clears buffer.  I think this is needed.
    2998             :   gfxUtils::ClearThebesSurface(pluginSurface);
    2999             : 
    3000             :   ANPEvent event;
    3001             :   event.inSize = sizeof(ANPEvent);
    3002             :   event.eventType = 4;
    3003             :   event.data.draw.model = 1;
    3004             : 
    3005             :   event.data.draw.clip.top     = 0;
    3006             :   event.data.draw.clip.left    = 0;
    3007             :   event.data.draw.clip.bottom  = aFrameRect.width;
    3008             :   event.data.draw.clip.right   = aFrameRect.height;
    3009             : 
    3010             :   event.data.draw.data.bitmap.format   = kRGBA_8888_ANPBitmapFormat;
    3011             :   event.data.draw.data.bitmap.width    = aFrameRect.width;
    3012             :   event.data.draw.data.bitmap.height   = aFrameRect.height;
    3013             :   event.data.draw.data.bitmap.baseAddr = pluginSurface->Data();
    3014             :   event.data.draw.data.bitmap.rowBytes = aFrameRect.width * 4;
    3015             : 
    3016             :   if (!mInstance)
    3017             :     return;
    3018             : 
    3019             :   mInstance->HandleEvent(&event, nullptr);
    3020             : 
    3021             :   aContext->SetOp(gfx::CompositionOp::OP_SOURCE);
    3022             :   aContext->SetSource(pluginSurface, gfxPoint(aFrameRect.x, aFrameRect.y));
    3023             :   aContext->Clip(aFrameRect);
    3024             :   aContext->Paint();
    3025             : #endif
    3026             : }
    3027             : #endif
    3028             : 
    3029             : #if defined(MOZ_X11)
    3030           0 : void nsPluginInstanceOwner::Paint(gfxContext* aContext,
    3031             :                                   const gfxRect& aFrameRect,
    3032             :                                   const gfxRect& aDirtyRect)
    3033             : {
    3034           0 :   if (!mInstance || !mPluginFrame)
    3035           0 :     return;
    3036             : 
    3037             :   // to provide crisper and faster drawing.
    3038           0 :   gfxRect pluginRect = aFrameRect;
    3039           0 :   if (aContext->UserToDevicePixelSnapped(pluginRect)) {
    3040           0 :     pluginRect = aContext->DeviceToUser(pluginRect);
    3041             :   }
    3042             : 
    3043             :   // Round out the dirty rect to plugin pixels to ensure the plugin draws
    3044             :   // enough pixels for interpolation to device pixels.
    3045           0 :   gfxRect dirtyRect = aDirtyRect - pluginRect.TopLeft();
    3046           0 :   dirtyRect.RoundOut();
    3047             : 
    3048             :   // Plugins can only draw an integer number of pixels.
    3049             :   //
    3050             :   // With translation-only transformation matrices, pluginRect is already
    3051             :   // pixel-aligned.
    3052             :   //
    3053             :   // With more complex transformations, modifying the scales in the
    3054             :   // transformation matrix could retain subpixel accuracy and let the plugin
    3055             :   // draw a suitable number of pixels for interpolation to device pixels in
    3056             :   // Renderer::Draw, but such cases are not common enough to warrant the
    3057             :   // effort now.
    3058             :   nsIntSize pluginSize(NS_lround(pluginRect.width),
    3059           0 :                        NS_lround(pluginRect.height));
    3060             : 
    3061             :   // Determine what the plugin needs to draw.
    3062           0 :   nsIntRect pluginDirtyRect(int32_t(dirtyRect.x),
    3063           0 :                             int32_t(dirtyRect.y),
    3064           0 :                             int32_t(dirtyRect.width),
    3065           0 :                             int32_t(dirtyRect.height));
    3066           0 :   if (!pluginDirtyRect.
    3067           0 :       IntersectRect(nsIntRect(0, 0, pluginSize.width, pluginSize.height),
    3068             :                     pluginDirtyRect))
    3069           0 :     return;
    3070             : 
    3071             :   NPWindow* window;
    3072           0 :   GetWindow(window);
    3073             : 
    3074           0 :   uint32_t rendererFlags = 0;
    3075           0 :   if (!mFlash10Quirks) {
    3076           0 :     rendererFlags |=
    3077             :       Renderer::DRAW_SUPPORTS_CLIP_RECT |
    3078             :       Renderer::DRAW_SUPPORTS_ALTERNATE_VISUAL;
    3079             :   }
    3080             : 
    3081             :   bool transparent;
    3082           0 :   mInstance->IsTransparent(&transparent);
    3083           0 :   if (!transparent)
    3084           0 :     rendererFlags |= Renderer::DRAW_IS_OPAQUE;
    3085             : 
    3086             :   // Renderer::Draw() draws a rectangle with top-left at the aContext origin.
    3087           0 :   gfxContextAutoSaveRestore autoSR(aContext);
    3088             :   aContext->SetMatrix(
    3089           0 :     aContext->CurrentMatrix().PreTranslate(pluginRect.TopLeft()));
    3090             : 
    3091           0 :   Renderer renderer(window, this, pluginSize, pluginDirtyRect);
    3092             : 
    3093           0 :   Display* dpy = mozilla::DefaultXDisplay();
    3094           0 :   Screen* screen = DefaultScreenOfDisplay(dpy);
    3095           0 :   Visual* visual = DefaultVisualOfScreen(screen);
    3096             : 
    3097           0 :   renderer.Draw(aContext, nsIntSize(window->width, window->height),
    3098           0 :                 rendererFlags, screen, visual);
    3099             : }
    3100             : nsresult
    3101           0 : nsPluginInstanceOwner::Renderer::DrawWithXlib(cairo_surface_t* xsurface,
    3102             :                                               nsIntPoint offset,
    3103             :                                               nsIntRect *clipRects,
    3104             :                                               uint32_t numClipRects)
    3105             : {
    3106           0 :   Screen *screen = cairo_xlib_surface_get_screen(xsurface);
    3107             :   Colormap colormap;
    3108             :   Visual* visual;
    3109           0 :   if (!gfxXlibSurface::GetColormapAndVisual(xsurface, &colormap, &visual)) {
    3110           0 :     NS_ERROR("Failed to get visual and colormap");
    3111           0 :     return NS_ERROR_UNEXPECTED;
    3112             :   }
    3113             : 
    3114           0 :   nsNPAPIPluginInstance *instance = mInstanceOwner->mInstance;
    3115           0 :   if (!instance)
    3116           0 :     return NS_ERROR_FAILURE;
    3117             : 
    3118             :   // See if the plugin must be notified of new window parameters.
    3119           0 :   bool doupdatewindow = false;
    3120             : 
    3121           0 :   if (mWindow->x != offset.x || mWindow->y != offset.y) {
    3122           0 :     mWindow->x = offset.x;
    3123           0 :     mWindow->y = offset.y;
    3124           0 :     doupdatewindow = true;
    3125             :   }
    3126             : 
    3127           0 :   if (nsIntSize(mWindow->width, mWindow->height) != mPluginSize) {
    3128           0 :     mWindow->width = mPluginSize.width;
    3129           0 :     mWindow->height = mPluginSize.height;
    3130           0 :     doupdatewindow = true;
    3131             :   }
    3132             : 
    3133             :   // The clip rect is relative to drawable top-left.
    3134           0 :   NS_ASSERTION(numClipRects <= 1, "We don't support multiple clip rectangles!");
    3135           0 :   nsIntRect clipRect;
    3136           0 :   if (numClipRects) {
    3137           0 :     clipRect.x = clipRects[0].x;
    3138           0 :     clipRect.y = clipRects[0].y;
    3139           0 :     clipRect.width  = clipRects[0].width;
    3140           0 :     clipRect.height = clipRects[0].height;
    3141             :     // NPRect members are unsigned, but clip rectangles should be contained by
    3142             :     // the surface.
    3143           0 :     NS_ASSERTION(clipRect.x >= 0 && clipRect.y >= 0,
    3144             :                  "Clip rectangle offsets are negative!");
    3145             :   }
    3146             :   else {
    3147           0 :     clipRect.x = offset.x;
    3148           0 :     clipRect.y = offset.y;
    3149           0 :     clipRect.width  = mWindow->width;
    3150           0 :     clipRect.height = mWindow->height;
    3151             :     // Don't ask the plugin to draw outside the drawable.
    3152             :     // This also ensures that the unsigned clip rectangle offsets won't be -ve.
    3153             :     clipRect.IntersectRect(clipRect,
    3154           0 :                            nsIntRect(0, 0,
    3155             :                                      cairo_xlib_surface_get_width(xsurface),
    3156           0 :                                      cairo_xlib_surface_get_height(xsurface)));
    3157             :   }
    3158             : 
    3159             :   NPRect newClipRect;
    3160           0 :   newClipRect.left = clipRect.x;
    3161           0 :   newClipRect.top = clipRect.y;
    3162           0 :   newClipRect.right = clipRect.XMost();
    3163           0 :   newClipRect.bottom = clipRect.YMost();
    3164           0 :   if (mWindow->clipRect.left    != newClipRect.left   ||
    3165           0 :       mWindow->clipRect.top     != newClipRect.top    ||
    3166           0 :       mWindow->clipRect.right   != newClipRect.right  ||
    3167           0 :       mWindow->clipRect.bottom  != newClipRect.bottom) {
    3168           0 :     mWindow->clipRect = newClipRect;
    3169           0 :     doupdatewindow = true;
    3170             :   }
    3171             : 
    3172             :   NPSetWindowCallbackStruct* ws_info =
    3173           0 :     static_cast<NPSetWindowCallbackStruct*>(mWindow->ws_info);
    3174             : #ifdef MOZ_X11
    3175           0 :   if (ws_info->visual != visual || ws_info->colormap != colormap) {
    3176           0 :     ws_info->visual = visual;
    3177           0 :     ws_info->colormap = colormap;
    3178           0 :     ws_info->depth = gfxXlibSurface::DepthOfVisual(screen, visual);
    3179           0 :     doupdatewindow = true;
    3180             :   }
    3181             : #endif
    3182             : 
    3183             :   {
    3184           0 :     if (doupdatewindow)
    3185           0 :       instance->SetWindow(mWindow);
    3186             :   }
    3187             : 
    3188             :   // Translate the dirty rect to drawable coordinates.
    3189           0 :   nsIntRect dirtyRect = mDirtyRect + offset;
    3190           0 :   if (mInstanceOwner->mFlash10Quirks) {
    3191             :     // Work around a bug in Flash up to 10.1 d51 at least, where expose event
    3192             :     // top left coordinates within the plugin-rect and not at the drawable
    3193             :     // origin are misinterpreted.  (We can move the top left coordinate
    3194             :     // provided it is within the clipRect.)
    3195           0 :     dirtyRect.SetRect(offset.x, offset.y,
    3196           0 :                       mDirtyRect.XMost(), mDirtyRect.YMost());
    3197             :   }
    3198             :   // Intersect the dirty rect with the clip rect to ensure that it lies within
    3199             :   // the drawable.
    3200           0 :   if (!dirtyRect.IntersectRect(dirtyRect, clipRect))
    3201           0 :     return NS_OK;
    3202             : 
    3203             :   {
    3204           0 :     XEvent pluginEvent = XEvent();
    3205           0 :     XGraphicsExposeEvent& exposeEvent = pluginEvent.xgraphicsexpose;
    3206             :     // set the drawing info
    3207           0 :     exposeEvent.type = GraphicsExpose;
    3208           0 :     exposeEvent.display = DisplayOfScreen(screen);
    3209           0 :     exposeEvent.drawable = cairo_xlib_surface_get_drawable(xsurface);
    3210           0 :     exposeEvent.x = dirtyRect.x;
    3211           0 :     exposeEvent.y = dirtyRect.y;
    3212           0 :     exposeEvent.width  = dirtyRect.width;
    3213           0 :     exposeEvent.height = dirtyRect.height;
    3214           0 :     exposeEvent.count = 0;
    3215             :     // information not set:
    3216           0 :     exposeEvent.serial = 0;
    3217           0 :     exposeEvent.send_event = False;
    3218           0 :     exposeEvent.major_code = 0;
    3219           0 :     exposeEvent.minor_code = 0;
    3220             : 
    3221           0 :     instance->HandleEvent(&pluginEvent, nullptr);
    3222             :   }
    3223           0 :   return NS_OK;
    3224             : }
    3225             : #endif
    3226             : 
    3227           0 : nsresult nsPluginInstanceOwner::Init(nsIContent* aContent)
    3228             : {
    3229           0 :   mLastEventloopNestingLevel = GetEventloopNestingLevel();
    3230             : 
    3231           0 :   mContent = do_GetWeakReference(aContent);
    3232             : 
    3233             :   // Get a frame, don't reflow. If a reflow was necessary it should have been
    3234             :   // done at a higher level than this (content).
    3235           0 :   nsIFrame* frame = aContent->GetPrimaryFrame();
    3236           0 :   nsIObjectFrame* iObjFrame = do_QueryFrame(frame);
    3237           0 :   nsPluginFrame* objFrame =  static_cast<nsPluginFrame*>(iObjFrame);
    3238           0 :   if (objFrame) {
    3239           0 :     SetFrame(objFrame);
    3240             :     // Some plugins require a specific sequence of shutdown and startup when
    3241             :     // a page is reloaded. Shutdown happens usually when the last instance
    3242             :     // is destroyed. Here we make sure the plugin instance in the old
    3243             :     // document is destroyed before we try to create the new one.
    3244           0 :     objFrame->PresContext()->EnsureVisible();
    3245             :   } else {
    3246           0 :     NS_NOTREACHED("Should not be initializing plugin without a frame");
    3247           0 :     return NS_ERROR_FAILURE;
    3248             :   }
    3249             : 
    3250             :   // register context menu listener
    3251           0 :   mCXMenuListener = new nsPluginDOMContextMenuListener(aContent);
    3252             : 
    3253           0 :   aContent->AddEventListener(NS_LITERAL_STRING("focus"), this, false,
    3254           0 :                              false);
    3255           0 :   aContent->AddEventListener(NS_LITERAL_STRING("blur"), this, false,
    3256           0 :                              false);
    3257           0 :   aContent->AddEventListener(NS_LITERAL_STRING("mouseup"), this, false,
    3258           0 :                              false);
    3259           0 :   aContent->AddEventListener(NS_LITERAL_STRING("mousedown"), this, false,
    3260           0 :                              false);
    3261           0 :   aContent->AddEventListener(NS_LITERAL_STRING("mousemove"), this, false,
    3262           0 :                              false);
    3263           0 :   aContent->AddEventListener(NS_LITERAL_STRING("click"), this, false,
    3264           0 :                              false);
    3265           0 :   aContent->AddEventListener(NS_LITERAL_STRING("dblclick"), this, false,
    3266           0 :                              false);
    3267           0 :   aContent->AddEventListener(NS_LITERAL_STRING("mouseover"), this, false,
    3268           0 :                              false);
    3269           0 :   aContent->AddEventListener(NS_LITERAL_STRING("mouseout"), this, false,
    3270           0 :                              false);
    3271           0 :   aContent->AddEventListener(NS_LITERAL_STRING("keypress"), this, true);
    3272           0 :   aContent->AddEventListener(NS_LITERAL_STRING("keydown"), this, true);
    3273           0 :   aContent->AddEventListener(NS_LITERAL_STRING("keyup"), this, true);
    3274           0 :   aContent->AddEventListener(NS_LITERAL_STRING("drop"), this, true);
    3275           0 :   aContent->AddEventListener(NS_LITERAL_STRING("drag"), this, true);
    3276           0 :   aContent->AddEventListener(NS_LITERAL_STRING("dragenter"), this, true);
    3277           0 :   aContent->AddEventListener(NS_LITERAL_STRING("dragover"), this, true);
    3278           0 :   aContent->AddEventListener(NS_LITERAL_STRING("dragleave"), this, true);
    3279           0 :   aContent->AddEventListener(NS_LITERAL_STRING("dragexit"), this, true);
    3280           0 :   aContent->AddEventListener(NS_LITERAL_STRING("dragstart"), this, true);
    3281           0 :   aContent->AddEventListener(NS_LITERAL_STRING("dragend"), this, true);
    3282           0 :   aContent->AddSystemEventListener(NS_LITERAL_STRING("compositionstart"),
    3283           0 :     this, true);
    3284           0 :   aContent->AddSystemEventListener(NS_LITERAL_STRING("compositionend"), this,
    3285           0 :     true);
    3286           0 :   aContent->AddSystemEventListener(NS_LITERAL_STRING("text"), this, true);
    3287             : 
    3288           0 :   return NS_OK;
    3289             : }
    3290             : 
    3291           0 : void* nsPluginInstanceOwner::GetPluginPort()
    3292             : {
    3293           0 :   void* result = nullptr;
    3294           0 :   if (mWidget) {
    3295             : #ifdef XP_WIN
    3296             :     if (!mPluginWindow || mPluginWindow->type == NPWindowTypeWindow)
    3297             : #endif
    3298           0 :       result = mWidget->GetNativeData(NS_NATIVE_PLUGIN_PORT); // HWND/gdk window
    3299             :   }
    3300             : 
    3301           0 :   return result;
    3302             : }
    3303             : 
    3304           0 : void nsPluginInstanceOwner::ReleasePluginPort(void * pluginPort)
    3305             : {
    3306           0 : }
    3307             : 
    3308           0 : NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
    3309             : {
    3310           0 :   NS_ENSURE_TRUE(mPluginWindow, NS_ERROR_NULL_POINTER);
    3311             : 
    3312             :   // Can't call this twice!
    3313           0 :   if (mWidget) {
    3314           0 :     NS_WARNING("Trying to create a plugin widget twice!");
    3315           0 :     return NS_ERROR_FAILURE;
    3316             :   }
    3317             : 
    3318           0 :   bool windowless = false;
    3319           0 :   mInstance->IsWindowless(&windowless);
    3320           0 :   if (!windowless) {
    3321             : #ifndef XP_WIN
    3322             :     // Only Windows supports windowed mode!
    3323           0 :     MOZ_ASSERT_UNREACHABLE();
    3324             :     return NS_ERROR_FAILURE;
    3325             : #else
    3326             :     // Try to get a parent widget, on some platforms widget creation will fail without
    3327             :     // a parent.
    3328             :     nsresult rv = NS_ERROR_FAILURE;
    3329             : 
    3330             :     nsCOMPtr<nsIWidget> parentWidget;
    3331             :     nsIDocument *doc = nullptr;
    3332             :     nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
    3333             :     if (content) {
    3334             :       doc = content->OwnerDoc();
    3335             :       parentWidget = nsContentUtils::WidgetForDocument(doc);
    3336             :       // If we're running in the content process, we need a remote widget created in chrome.
    3337             :       if (XRE_IsContentProcess()) {
    3338             :         if (nsCOMPtr<nsPIDOMWindowOuter> window = doc->GetWindow()) {
    3339             :           if (nsCOMPtr<nsPIDOMWindowOuter> topWindow = window->GetTop()) {
    3340             :             dom::TabChild* tc = dom::TabChild::GetFrom(topWindow);
    3341             :             if (tc) {
    3342             :               // This returns a PluginWidgetProxy which remotes a number of calls.
    3343             :               rv = tc->CreatePluginWidget(parentWidget.get(), getter_AddRefs(mWidget));
    3344             :               if (NS_FAILED(rv)) {
    3345             :                 return rv;
    3346             :               }
    3347             :             }
    3348             :           }
    3349             :         }
    3350             :       }
    3351             :     }
    3352             : 
    3353             :     // A failure here is terminal since we can't fall back on the non-e10s code
    3354             :     // path below.
    3355             :     if (!mWidget && XRE_IsContentProcess()) {
    3356             :       return NS_ERROR_UNEXPECTED;
    3357             :     }
    3358             : 
    3359             :     if (!mWidget) {
    3360             :       // native (single process)
    3361             :       mWidget = do_CreateInstance(kWidgetCID, &rv);
    3362             :       nsWidgetInitData initData;
    3363             :       initData.mWindowType = eWindowType_plugin;
    3364             :       initData.mUnicode = false;
    3365             :       initData.clipChildren = true;
    3366             :       initData.clipSiblings = true;
    3367             :       rv = mWidget->Create(parentWidget.get(), nullptr,
    3368             :                            LayoutDeviceIntRect(0, 0, 0, 0), &initData);
    3369             :       if (NS_FAILED(rv)) {
    3370             :         mWidget->Destroy();
    3371             :         mWidget = nullptr;
    3372             :         return rv;
    3373             :       }
    3374             :     }
    3375             : 
    3376             :     mWidget->EnableDragDrop(true);
    3377             :     mWidget->Show(false);
    3378             :     mWidget->Enable(false);
    3379             : #endif // XP_WIN
    3380             :   }
    3381             : 
    3382           0 :   if (mPluginFrame) {
    3383             :     // nullptr widget is fine, will result in windowless setup.
    3384           0 :     mPluginFrame->PrepForDrawing(mWidget);
    3385             :   }
    3386             : 
    3387           0 :   if (windowless) {
    3388           0 :     mPluginWindow->type = NPWindowTypeDrawable;
    3389             : 
    3390             :     // this needs to be a HDC according to the spec, but I do
    3391             :     // not see the right way to release it so let's postpone
    3392             :     // passing HDC till paint event when it is really
    3393             :     // needed. Change spec?
    3394           0 :     mPluginWindow->window = nullptr;
    3395             : #ifdef MOZ_X11
    3396             :     // Fill in the display field.
    3397             :     NPSetWindowCallbackStruct* ws_info =
    3398           0 :     static_cast<NPSetWindowCallbackStruct*>(mPluginWindow->ws_info);
    3399           0 :     ws_info->display = DefaultXDisplay();
    3400             : 
    3401           0 :     nsAutoCString description;
    3402           0 :     GetPluginDescription(description);
    3403           0 :     NS_NAMED_LITERAL_CSTRING(flash10Head, "Shockwave Flash 10.");
    3404           0 :     mFlash10Quirks = StringBeginsWith(description, flash10Head);
    3405             : #endif
    3406           0 :   } else if (mWidget) {
    3407             :     // mPluginWindow->type is used in |GetPluginPort| so it must
    3408             :     // be initialized first
    3409           0 :     mPluginWindow->type = NPWindowTypeWindow;
    3410           0 :     mPluginWindow->window = GetPluginPort();
    3411             :     // tell the plugin window about the widget
    3412           0 :     mPluginWindow->SetPluginWidget(mWidget);
    3413             : 
    3414             :     // tell the widget about the current plugin instance owner.
    3415           0 :     nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
    3416           0 :     if (pluginWidget) {
    3417           0 :       pluginWidget->SetPluginInstanceOwner(this);
    3418             :     }
    3419             :   }
    3420             : 
    3421             : #ifdef XP_MACOSX
    3422             :   if (GetDrawingModel() == NPDrawingModelCoreAnimation) {
    3423             :     AddToCARefreshTimer();
    3424             :   }
    3425             : #endif
    3426             : 
    3427           0 :   mWidgetCreationComplete = true;
    3428             : 
    3429           0 :   return NS_OK;
    3430             : }
    3431             : 
    3432             : // Mac specific code to fix up the port location and clipping region
    3433             : #ifdef XP_MACOSX
    3434             : 
    3435             : void nsPluginInstanceOwner::FixUpPluginWindow(int32_t inPaintState)
    3436             : {
    3437             :   if (!mPluginWindow || !mInstance || !mPluginFrame) {
    3438             :     return;
    3439             :   }
    3440             : 
    3441             :   SetPluginPort();
    3442             : 
    3443             :   LayoutDeviceIntSize widgetClip = mPluginFrame->GetWidgetlessClipRect().Size();
    3444             : 
    3445             :   mPluginWindow->x = 0;
    3446             :   mPluginWindow->y = 0;
    3447             : 
    3448             :   NPRect oldClipRect = mPluginWindow->clipRect;
    3449             : 
    3450             :   // fix up the clipping region
    3451             :   mPluginWindow->clipRect.top  = 0;
    3452             :   mPluginWindow->clipRect.left = 0;
    3453             : 
    3454             :   if (inPaintState == ePluginPaintDisable) {
    3455             :     mPluginWindow->clipRect.bottom = mPluginWindow->clipRect.top;
    3456             :     mPluginWindow->clipRect.right  = mPluginWindow->clipRect.left;
    3457             :   }
    3458             :   else if (inPaintState == ePluginPaintEnable)
    3459             :   {
    3460             :     mPluginWindow->clipRect.bottom = mPluginWindow->clipRect.top + widgetClip.height;
    3461             :     mPluginWindow->clipRect.right  = mPluginWindow->clipRect.left + widgetClip.width;
    3462             :   }
    3463             : 
    3464             :   // if the clip rect changed, call SetWindow()
    3465             :   // (RealPlayer needs this to draw correctly)
    3466             :   if (mPluginWindow->clipRect.left    != oldClipRect.left   ||
    3467             :       mPluginWindow->clipRect.top     != oldClipRect.top    ||
    3468             :       mPluginWindow->clipRect.right   != oldClipRect.right  ||
    3469             :       mPluginWindow->clipRect.bottom  != oldClipRect.bottom)
    3470             :   {
    3471             :     if (UseAsyncRendering()) {
    3472             :       mInstance->AsyncSetWindow(mPluginWindow);
    3473             :     }
    3474             :     else {
    3475             :       mPluginWindow->CallSetWindow(mInstance);
    3476             :     }
    3477             :   }
    3478             : 
    3479             :   // After the first NPP_SetWindow call we need to send an initial
    3480             :   // top-level window focus event.
    3481             :   if (!mSentInitialTopLevelWindowEvent) {
    3482             :     // Set this before calling ProcessEvent to avoid endless recursion.
    3483             :     mSentInitialTopLevelWindowEvent = true;
    3484             : 
    3485             :     bool isActive = WindowIsActive();
    3486             :     SendWindowFocusChanged(isActive);
    3487             :     mLastWindowIsActive = isActive;
    3488             :   }
    3489             : }
    3490             : 
    3491             : void
    3492             : nsPluginInstanceOwner::WindowFocusMayHaveChanged()
    3493             : {
    3494             :   if (!mSentInitialTopLevelWindowEvent) {
    3495             :     return;
    3496             :   }
    3497             : 
    3498             :   bool isActive = WindowIsActive();
    3499             :   if (isActive != mLastWindowIsActive) {
    3500             :     SendWindowFocusChanged(isActive);
    3501             :     mLastWindowIsActive = isActive;
    3502             :   }
    3503             : }
    3504             : 
    3505             : bool
    3506             : nsPluginInstanceOwner::WindowIsActive()
    3507             : {
    3508             :   if (!mPluginFrame) {
    3509             :     return false;
    3510             :   }
    3511             : 
    3512             :   EventStates docState = mPluginFrame->GetContent()->OwnerDoc()->GetDocumentState();
    3513             :   return !docState.HasState(NS_DOCUMENT_STATE_WINDOW_INACTIVE);
    3514             : }
    3515             : 
    3516             : void
    3517             : nsPluginInstanceOwner::SendWindowFocusChanged(bool aIsActive)
    3518             : {
    3519             :   if (!mInstance) {
    3520             :     return;
    3521             :   }
    3522             : 
    3523             :   NPCocoaEvent cocoaEvent;
    3524             :   InitializeNPCocoaEvent(&cocoaEvent);
    3525             :   cocoaEvent.type = NPCocoaEventWindowFocusChanged;
    3526             :   cocoaEvent.data.focus.hasFocus = aIsActive;
    3527             :   mInstance->HandleEvent(&cocoaEvent,
    3528             :                          nullptr,
    3529             :                          NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
    3530             : }
    3531             : 
    3532             : void
    3533             : nsPluginInstanceOwner::HidePluginWindow()
    3534             : {
    3535             :   if (!mPluginWindow || !mInstance) {
    3536             :     return;
    3537             :   }
    3538             : 
    3539             :   mPluginWindow->clipRect.bottom = mPluginWindow->clipRect.top;
    3540             :   mPluginWindow->clipRect.right  = mPluginWindow->clipRect.left;
    3541             :   mWidgetVisible = false;
    3542             :   if (UseAsyncRendering()) {
    3543             :     mInstance->AsyncSetWindow(mPluginWindow);
    3544             :   } else {
    3545             :     mInstance->SetWindow(mPluginWindow);
    3546             :   }
    3547             : }
    3548             : 
    3549             : #else // XP_MACOSX
    3550             : 
    3551           0 : void nsPluginInstanceOwner::UpdateWindowPositionAndClipRect(bool aSetWindow)
    3552             : {
    3553           0 :   if (!mPluginWindow)
    3554           0 :     return;
    3555             : 
    3556             :   // For windowless plugins a non-empty clip rectangle will be
    3557             :   // passed to the plugin during paint, an additional update
    3558             :   // of the the clip rectangle here is not required
    3559           0 :   if (aSetWindow && !mWidget && mPluginWindowVisible && !UseAsyncRendering())
    3560           0 :     return;
    3561             : 
    3562           0 :   const NPWindow oldWindow = *mPluginWindow;
    3563             : 
    3564           0 :   bool windowless = (mPluginWindow->type == NPWindowTypeDrawable);
    3565           0 :   nsIntPoint origin = mPluginFrame->GetWindowOriginInPixels(windowless);
    3566             : 
    3567           0 :   mPluginWindow->x = origin.x;
    3568           0 :   mPluginWindow->y = origin.y;
    3569             : 
    3570           0 :   mPluginWindow->clipRect.left = 0;
    3571           0 :   mPluginWindow->clipRect.top = 0;
    3572             : 
    3573           0 :   if (mPluginWindowVisible && mPluginDocumentActiveState) {
    3574           0 :     mPluginWindow->clipRect.right = mPluginWindow->width;
    3575           0 :     mPluginWindow->clipRect.bottom = mPluginWindow->height;
    3576             :   } else {
    3577           0 :     mPluginWindow->clipRect.right = 0;
    3578           0 :     mPluginWindow->clipRect.bottom = 0;
    3579             :   }
    3580             : 
    3581           0 :   if (!aSetWindow)
    3582           0 :     return;
    3583             : 
    3584           0 :   if (mPluginWindow->x               != oldWindow.x               ||
    3585           0 :       mPluginWindow->y               != oldWindow.y               ||
    3586           0 :       mPluginWindow->clipRect.left   != oldWindow.clipRect.left   ||
    3587           0 :       mPluginWindow->clipRect.top    != oldWindow.clipRect.top    ||
    3588           0 :       mPluginWindow->clipRect.right  != oldWindow.clipRect.right  ||
    3589           0 :       mPluginWindow->clipRect.bottom != oldWindow.clipRect.bottom) {
    3590           0 :     CallSetWindow();
    3591             :   }
    3592             : }
    3593             : 
    3594             : void
    3595           0 : nsPluginInstanceOwner::UpdateWindowVisibility(bool aVisible)
    3596             : {
    3597           0 :   mPluginWindowVisible = aVisible;
    3598           0 :   UpdateWindowPositionAndClipRect(true);
    3599           0 : }
    3600             : #endif // XP_MACOSX
    3601             : 
    3602             : void
    3603           0 : nsPluginInstanceOwner::ResolutionMayHaveChanged()
    3604             : {
    3605             : #if defined(XP_MACOSX) || defined(XP_WIN)
    3606             :   double scaleFactor = 1.0;
    3607             :   GetContentsScaleFactor(&scaleFactor);
    3608             :   if (scaleFactor != mLastScaleFactor) {
    3609             :     ContentsScaleFactorChanged(scaleFactor);
    3610             :     mLastScaleFactor = scaleFactor;
    3611             :   }
    3612             : #endif
    3613           0 :   float zoomFactor = 1.0;
    3614           0 :   GetCSSZoomFactor(&zoomFactor);
    3615           0 :   if (zoomFactor != mLastCSSZoomFactor) {
    3616           0 :     if (mInstance) {
    3617           0 :       mInstance->CSSZoomFactorChanged(zoomFactor);
    3618             :     }
    3619           0 :     mLastCSSZoomFactor = zoomFactor;
    3620             :   }
    3621             : 
    3622           0 : }
    3623             : 
    3624             : void
    3625           0 : nsPluginInstanceOwner::UpdateDocumentActiveState(bool aIsActive)
    3626             : {
    3627           0 :   AUTO_PROFILER_LABEL("nsPluginInstanceOwner::UpdateDocumentActiveState",
    3628             :                       OTHER);
    3629             : 
    3630           0 :   mPluginDocumentActiveState = aIsActive;
    3631             : #ifndef XP_MACOSX
    3632           0 :   UpdateWindowPositionAndClipRect(true);
    3633             : 
    3634             : #ifdef MOZ_WIDGET_ANDROID
    3635             :   if (mInstance) {
    3636             :     if (!mPluginDocumentActiveState) {
    3637             :       RemovePluginView();
    3638             :     }
    3639             : 
    3640             :     mInstance->NotifyOnScreen(mPluginDocumentActiveState);
    3641             : 
    3642             :     // This is, perhaps, incorrect. It is supposed to be sent
    3643             :     // when "the webview has paused or resumed". The side effect
    3644             :     // is that Flash video players pause or resume (if they were
    3645             :     // playing before) based on the value here. I personally think
    3646             :     // we want that on Android when switching to another tab, so
    3647             :     // that's why we call it here.
    3648             :     mInstance->NotifyForeground(mPluginDocumentActiveState);
    3649             :   }
    3650             : #endif // #ifdef MOZ_WIDGET_ANDROID
    3651             : 
    3652             :   // We don't have a connection to PluginWidgetParent in the chrome
    3653             :   // process when dealing with tab visibility changes, so this needs
    3654             :   // to be forwarded over after the active state is updated. If we
    3655             :   // don't hide plugin widgets in hidden tabs, the native child window
    3656             :   // in chrome will remain visible after a tab switch.
    3657           0 :   if (mWidget && XRE_IsContentProcess()) {
    3658           0 :     mWidget->Show(aIsActive);
    3659           0 :     mWidget->Enable(aIsActive);
    3660             :   }
    3661             : #endif // #ifndef XP_MACOSX
    3662           0 : }
    3663             : 
    3664             : NS_IMETHODIMP
    3665           0 : nsPluginInstanceOwner::CallSetWindow()
    3666             : {
    3667           0 :   if (!mWidgetCreationComplete) {
    3668             :     // No widget yet, we can't run this code
    3669           0 :     return NS_OK;
    3670             :   }
    3671           0 :   if (mPluginFrame) {
    3672           0 :     mPluginFrame->CallSetWindow(false);
    3673           0 :   } else if (mInstance) {
    3674           0 :     if (UseAsyncRendering()) {
    3675           0 :       mInstance->AsyncSetWindow(mPluginWindow);
    3676             :     } else {
    3677           0 :       mInstance->SetWindow(mPluginWindow);
    3678             :     }
    3679             :   }
    3680             : 
    3681           0 :   return NS_OK;
    3682             : }
    3683             : 
    3684             : NS_IMETHODIMP
    3685           0 : nsPluginInstanceOwner::GetContentsScaleFactor(double *result)
    3686             : {
    3687           0 :   NS_ENSURE_ARG_POINTER(result);
    3688           0 :   double scaleFactor = 1.0;
    3689             :   // On Mac, device pixels need to be translated to (and from) "display pixels"
    3690             :   // for plugins. On other platforms, plugin coordinates are always in device
    3691             :   // pixels.
    3692             : #if defined(XP_MACOSX) || defined(XP_WIN)
    3693             :   nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
    3694             :   nsIPresShell* presShell = nsContentUtils::FindPresShellForDocument(content->OwnerDoc());
    3695             :   if (presShell) {
    3696             :     scaleFactor = double(nsPresContext::AppUnitsPerCSSPixel())/
    3697             :       presShell->GetPresContext()->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom();
    3698             :   }
    3699             : #endif
    3700           0 :   *result = scaleFactor;
    3701           0 :   return NS_OK;
    3702             : }
    3703             : 
    3704             : void
    3705           0 : nsPluginInstanceOwner::GetCSSZoomFactor(float *result)
    3706             : {
    3707           0 :   nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
    3708           0 :   nsIPresShell* presShell = nsContentUtils::FindPresShellForDocument(content->OwnerDoc());
    3709           0 :   if (presShell) {
    3710           0 :     *result = presShell->GetPresContext()->DeviceContext()->GetFullZoom();
    3711             :   } else {
    3712           0 :     *result = 1.0;
    3713             :   }
    3714           0 : }
    3715             : 
    3716           0 : void nsPluginInstanceOwner::SetFrame(nsPluginFrame *aFrame)
    3717             : {
    3718             :   // Don't do anything if the frame situation hasn't changed.
    3719           0 :   if (mPluginFrame == aFrame) {
    3720           0 :     return;
    3721             :   }
    3722             : 
    3723           0 :   nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
    3724             : 
    3725             :   // If we already have a frame that is changing or going away...
    3726           0 :   if (mPluginFrame) {
    3727           0 :     if (content && content->OwnerDoc() && content->OwnerDoc()->GetWindow()) {
    3728           0 :       nsCOMPtr<EventTarget> windowRoot = content->OwnerDoc()->GetWindow()->GetTopWindowRoot();
    3729           0 :       if (windowRoot) {
    3730           0 :         windowRoot->RemoveEventListener(NS_LITERAL_STRING("activate"),
    3731           0 :                                               this, false);
    3732           0 :         windowRoot->RemoveEventListener(NS_LITERAL_STRING("deactivate"),
    3733           0 :                                               this, false);
    3734           0 :         windowRoot->RemoveEventListener(NS_LITERAL_STRING("MozPerformDelayedBlur"),
    3735           0 :                                               this, false);
    3736             :       }
    3737             :     }
    3738             : 
    3739             :     // Make sure the old frame isn't holding a reference to us.
    3740           0 :     mPluginFrame->SetInstanceOwner(nullptr);
    3741             :   }
    3742             : 
    3743             :   // Swap in the new frame (or no frame)
    3744           0 :   mPluginFrame = aFrame;
    3745             : 
    3746             :   // Set up a new frame
    3747           0 :   if (mPluginFrame) {
    3748           0 :     mPluginFrame->SetInstanceOwner(this);
    3749             :     // Can only call PrepForDrawing on an object frame once. Don't do it here unless
    3750             :     // widget creation is complete. Doesn't matter if we actually have a widget.
    3751           0 :     if (mWidgetCreationComplete) {
    3752           0 :       mPluginFrame->PrepForDrawing(mWidget);
    3753             :     }
    3754           0 :     mPluginFrame->FixupWindow(mPluginFrame->GetContentRectRelativeToSelf().Size());
    3755           0 :     mPluginFrame->InvalidateFrame();
    3756             : 
    3757           0 :     nsFocusManager* fm = nsFocusManager::GetFocusManager();
    3758           0 :     const nsIContent* content = aFrame->GetContent();
    3759           0 :     if (fm && content) {
    3760           0 :       mContentFocused = (content == fm->GetFocusedContent());
    3761             :     }
    3762             : 
    3763             :     // Register for widget-focus events on the window root.
    3764           0 :     if (content && content->OwnerDoc() && content->OwnerDoc()->GetWindow()) {
    3765           0 :       nsCOMPtr<EventTarget> windowRoot = content->OwnerDoc()->GetWindow()->GetTopWindowRoot();
    3766           0 :       if (windowRoot) {
    3767           0 :         windowRoot->AddEventListener(NS_LITERAL_STRING("activate"),
    3768           0 :                                            this, false, false);
    3769           0 :         windowRoot->AddEventListener(NS_LITERAL_STRING("deactivate"),
    3770           0 :                                            this, false, false);
    3771           0 :         windowRoot->AddEventListener(NS_LITERAL_STRING("MozPerformDelayedBlur"),
    3772           0 :                                            this, false, false);
    3773             :       }
    3774             :     }
    3775             :   }
    3776             : }
    3777             : 
    3778           0 : nsPluginFrame* nsPluginInstanceOwner::GetFrame()
    3779             : {
    3780           0 :   return mPluginFrame;
    3781             : }
    3782             : 
    3783           0 : NS_IMETHODIMP nsPluginInstanceOwner::PrivateModeChanged(bool aEnabled)
    3784             : {
    3785           0 :   return mInstance ? mInstance->PrivateModeStateChanged(aEnabled) : NS_OK;
    3786             : }
    3787             : 
    3788           0 : already_AddRefed<nsIURI> nsPluginInstanceOwner::GetBaseURI() const
    3789             : {
    3790           0 :   nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
    3791           0 :   if (!content) {
    3792           0 :     return nullptr;
    3793             :   }
    3794           0 :   return content->GetBaseURI();
    3795             : }
    3796             : 
    3797             : // static
    3798             : void
    3799           0 : nsPluginInstanceOwner::GeneratePluginEvent(
    3800             :   const WidgetCompositionEvent* aSrcCompositionEvent,
    3801             :   WidgetCompositionEvent* aDistCompositionEvent)
    3802             : {
    3803             : #ifdef XP_WIN
    3804             :   NPEvent newEvent;
    3805             :   switch (aDistCompositionEvent->mMessage) {
    3806             :     case eCompositionChange: {
    3807             :       newEvent.event = WM_IME_COMPOSITION;
    3808             :       newEvent.wParam = 0;
    3809             :       if (aSrcCompositionEvent &&
    3810             :           (aSrcCompositionEvent->mMessage == eCompositionCommit ||
    3811             :            aSrcCompositionEvent->mMessage == eCompositionCommitAsIs)) {
    3812             :         newEvent.lParam = GCS_RESULTSTR;
    3813             :       } else {
    3814             :         newEvent.lParam = GCS_COMPSTR | GCS_COMPATTR | GCS_COMPCLAUSE;
    3815             :       }
    3816             :       TextRangeArray* ranges = aDistCompositionEvent->mRanges;
    3817             :       if (ranges && ranges->HasCaret()) {
    3818             :         newEvent.lParam |= GCS_CURSORPOS;
    3819             :       }
    3820             :       break;
    3821             :     }
    3822             : 
    3823             :     case eCompositionStart:
    3824             :       newEvent.event = WM_IME_STARTCOMPOSITION;
    3825             :       newEvent.wParam = 0;
    3826             :       newEvent.lParam = 0;
    3827             :       break;
    3828             : 
    3829             :     case eCompositionEnd:
    3830             :       newEvent.event = WM_IME_ENDCOMPOSITION;
    3831             :       newEvent.wParam = 0;
    3832             :       newEvent.lParam = 0;
    3833             :       break;
    3834             : 
    3835             :     default:
    3836             :       return;
    3837             :   }
    3838             :   aDistCompositionEvent->mPluginEvent.Copy(newEvent);
    3839             : #endif
    3840           0 : }
    3841             : 
    3842             : // nsPluginDOMContextMenuListener class implementation
    3843             : 
    3844           0 : nsPluginDOMContextMenuListener::nsPluginDOMContextMenuListener(nsIContent* aContent)
    3845             : {
    3846           0 :   aContent->AddEventListener(NS_LITERAL_STRING("contextmenu"), this, true);
    3847           0 : }
    3848             : 
    3849           0 : nsPluginDOMContextMenuListener::~nsPluginDOMContextMenuListener()
    3850             : {
    3851           0 : }
    3852             : 
    3853           0 : NS_IMPL_ISUPPORTS(nsPluginDOMContextMenuListener,
    3854             :                   nsIDOMEventListener)
    3855             : 
    3856             : NS_IMETHODIMP
    3857           0 : nsPluginDOMContextMenuListener::HandleEvent(nsIDOMEvent* aEvent)
    3858             : {
    3859           0 :   aEvent->PreventDefault(); // consume event
    3860             : 
    3861           0 :   return NS_OK;
    3862             : }
    3863             : 
    3864           0 : void nsPluginDOMContextMenuListener::Destroy(nsIContent* aContent)
    3865             : {
    3866             :   // Unregister context menu listener
    3867           0 :   aContent->RemoveEventListener(NS_LITERAL_STRING("contextmenu"), this, true);
    3868           0 : }

Generated by: LCOV version 1.13