2011-06-01 04:37:54 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
// vim:set ts=2 sts=2 sw=2 et cin:
|
2012-05-21 11:12:37 +00:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
#ifdef MOZ_X11
|
|
|
|
#include <cairo-xlib.h>
|
|
|
|
#include "gfxXlibSurface.h"
|
|
|
|
/* X headers suck */
|
|
|
|
enum { XKeyPress = KeyPress };
|
|
|
|
#include "mozilla/X11Util.h"
|
|
|
|
using mozilla::DefaultXDisplay;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "nsPluginInstanceOwner.h"
|
2014-06-24 09:02:10 +00:00
|
|
|
|
|
|
|
#include "gfxUtils.h"
|
2011-06-01 04:37:54 +00:00
|
|
|
#include "nsIRunnable.h"
|
|
|
|
#include "nsContentUtils.h"
|
|
|
|
#include "nsRect.h"
|
|
|
|
#include "nsSize.h"
|
|
|
|
#include "nsDisplayList.h"
|
|
|
|
#include "ImageLayers.h"
|
2014-09-17 13:13:29 +00:00
|
|
|
#include "GLImages.h"
|
2014-09-24 04:33:00 +00:00
|
|
|
#include "nsPluginFrame.h"
|
2011-06-01 04:37:54 +00:00
|
|
|
#include "nsIPluginDocument.h"
|
|
|
|
#include "nsIStringStream.h"
|
|
|
|
#include "nsNetUtil.h"
|
|
|
|
#include "mozilla/Preferences.h"
|
|
|
|
#include "nsILinkHandler.h"
|
|
|
|
#include "nsIDocShellTreeItem.h"
|
|
|
|
#include "nsIWebBrowserChrome.h"
|
|
|
|
#include "nsLayoutUtils.h"
|
|
|
|
#include "nsIPluginWidget.h"
|
2013-01-05 03:12:24 +00:00
|
|
|
#include "nsViewManager.h"
|
2011-06-01 04:37:54 +00:00
|
|
|
#include "nsIDocShellTreeOwner.h"
|
|
|
|
#include "nsIDOMHTMLObjectElement.h"
|
|
|
|
#include "nsIAppShell.h"
|
|
|
|
#include "nsIDOMHTMLAppletElement.h"
|
2013-03-22 01:02:23 +00:00
|
|
|
#include "nsIObjectLoadingContent.h"
|
2014-08-15 21:17:35 +00:00
|
|
|
#include "nsObjectLoadingContent.h"
|
2011-06-01 04:37:54 +00:00
|
|
|
#include "nsAttrName.h"
|
|
|
|
#include "nsIFocusManager.h"
|
|
|
|
#include "nsFocusManager.h"
|
|
|
|
#include "nsIDOMDragEvent.h"
|
2015-08-05 03:06:03 +00:00
|
|
|
#include "nsIScriptSecurityManager.h"
|
2011-06-01 04:37:54 +00:00
|
|
|
#include "nsIScrollableFrame.h"
|
2012-04-24 04:49:25 +00:00
|
|
|
#include "nsIDocShell.h"
|
2012-08-19 19:33:25 +00:00
|
|
|
#include "ImageContainer.h"
|
2013-08-19 22:55:18 +00:00
|
|
|
#include "nsIDOMHTMLCollection.h"
|
2013-09-07 02:13:37 +00:00
|
|
|
#include "GLContext.h"
|
2014-09-17 13:13:29 +00:00
|
|
|
#include "EGLUtils.h"
|
2013-10-02 11:40:07 +00:00
|
|
|
#include "nsIContentInlines.h"
|
2013-09-25 11:21:20 +00:00
|
|
|
#include "mozilla/MiscEvents.h"
|
2013-09-25 11:21:18 +00:00
|
|
|
#include "mozilla/MouseEvents.h"
|
2013-09-25 11:21:19 +00:00
|
|
|
#include "mozilla/TextEvents.h"
|
2016-01-12 04:19:08 +00:00
|
|
|
#include "mozilla/dom/Event.h"
|
2014-08-15 21:17:35 +00:00
|
|
|
#include "mozilla/dom/HTMLObjectElementBinding.h"
|
2014-11-12 20:59:20 +00:00
|
|
|
#include "mozilla/dom/TabChild.h"
|
2014-08-06 05:19:27 +00:00
|
|
|
#include "nsFrameSelection.h"
|
2014-12-11 14:44:07 +00:00
|
|
|
#include "PuppetWidget.h"
|
|
|
|
#include "nsPIWindowRoot.h"
|
2015-12-29 13:57:38 +00:00
|
|
|
#include "mozilla/IMEStateManager.h"
|
|
|
|
#include "mozilla/TextComposition.h"
|
2015-12-29 13:57:38 +00:00
|
|
|
#include "mozilla/AutoRestore.h"
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
#include "nsContentCID.h"
|
|
|
|
#include "nsWidgetsCID.h"
|
2012-01-31 21:55:54 +00:00
|
|
|
static NS_DEFINE_CID(kWidgetCID, NS_CHILD_CID);
|
2011-06-01 04:37:54 +00:00
|
|
|
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
|
|
|
|
|
|
|
#ifdef XP_WIN
|
|
|
|
#include <wtypes.h>
|
|
|
|
#include <winuser.h>
|
2016-04-09 06:15:31 +00:00
|
|
|
#include "mozilla/widget/WinMessages.h"
|
|
|
|
#endif // #ifdef XP_WIN
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
#ifdef XP_MACOSX
|
2014-12-11 14:44:07 +00:00
|
|
|
#include "ComplexTextInputPanel.h"
|
|
|
|
#include "nsIDOMXULDocument.h"
|
|
|
|
#include "nsIDOMXULCommandDispatcher.h"
|
2011-06-01 04:37:54 +00:00
|
|
|
#endif
|
|
|
|
|
2014-05-28 08:23:00 +00:00
|
|
|
#ifdef MOZ_WIDGET_GTK
|
2011-06-01 04:37:54 +00:00
|
|
|
#include <gdk/gdk.h>
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#endif
|
|
|
|
|
2011-11-11 00:17:46 +00:00
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
2011-09-16 21:34:31 +00:00
|
|
|
#include "ANPBase.h"
|
|
|
|
#include "AndroidBridge.h"
|
2012-05-30 16:10:49 +00:00
|
|
|
#include "nsWindow.h"
|
|
|
|
|
2012-07-30 14:20:58 +00:00
|
|
|
static nsPluginInstanceOwner* sFullScreenInstance = nullptr;
|
2012-05-30 16:10:49 +00:00
|
|
|
|
2011-09-16 21:34:31 +00:00
|
|
|
using namespace mozilla::dom;
|
|
|
|
|
|
|
|
#include <android/log.h>
|
|
|
|
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
|
|
|
#endif
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
using namespace mozilla;
|
2014-08-15 21:17:35 +00:00
|
|
|
using namespace mozilla::dom;
|
2012-11-10 15:45:52 +00:00
|
|
|
using namespace mozilla::layers;
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
static inline nsPoint AsNsPoint(const nsIntPoint &p) {
|
|
|
|
return nsPoint(p.x, p.y);
|
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
// special class for handeling DOM context menu events because for
|
|
|
|
// some reason it starves other mouse events if implemented on the
|
|
|
|
// same class
|
2011-08-08 18:26:26 +00:00
|
|
|
class nsPluginDOMContextMenuListener : public nsIDOMEventListener
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
2014-06-23 19:56:07 +00:00
|
|
|
virtual ~nsPluginDOMContextMenuListener();
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
public:
|
2014-09-01 22:26:43 +00:00
|
|
|
explicit nsPluginDOMContextMenuListener(nsIContent* aContent);
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
2011-08-08 18:26:26 +00:00
|
|
|
NS_DECL_NSIDOMEVENTLISTENER
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2013-04-19 22:18:32 +00:00
|
|
|
void Destroy(nsIContent* aContent);
|
|
|
|
|
2013-10-02 03:46:03 +00:00
|
|
|
nsEventStatus ProcessEvent(const WidgetGUIEvent& anEvent)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
return nsEventStatus_eConsumeNoDefault;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-04-26 00:23:21 +00:00
|
|
|
class AsyncPaintWaitEvent : public Runnable
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
public:
|
2011-09-29 06:19:26 +00:00
|
|
|
AsyncPaintWaitEvent(nsIContent* aContent, bool aFinished) :
|
2011-06-01 04:37:54 +00:00
|
|
|
mContent(aContent), mFinished(aFinished)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHOD Run()
|
|
|
|
{
|
2011-10-18 10:53:36 +00:00
|
|
|
nsContentUtils::DispatchTrustedEvent(mContent->OwnerDoc(), mContent,
|
2011-06-01 04:37:54 +00:00
|
|
|
mFinished ? NS_LITERAL_STRING("MozPaintWaitFinished") : NS_LITERAL_STRING("MozPaintWait"),
|
2011-09-30 06:02:59 +00:00
|
|
|
true, true);
|
2011-06-01 04:37:54 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
nsCOMPtr<nsIContent> mContent;
|
2011-09-29 06:19:26 +00:00
|
|
|
bool mFinished;
|
2011-06-01 04:37:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::NotifyPaintWaiter(nsDisplayListBuilder* aBuilder)
|
|
|
|
{
|
|
|
|
// This is notification for reftests about async plugin paint start
|
|
|
|
if (!mWaitingForPaint && !IsUpToDate() && aBuilder->ShouldSyncDecodeImages()) {
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
|
|
|
|
nsCOMPtr<nsIRunnable> event = new AsyncPaintWaitEvent(content, false);
|
2011-06-01 04:37:54 +00:00
|
|
|
// Run this event as soon as it's safe to do so, since listeners need to
|
|
|
|
// receive it immediately
|
2016-05-06 08:09:03 +00:00
|
|
|
nsContentUtils::AddScriptRunner(event);
|
|
|
|
mWaitingForPaint = true;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-17 13:13:29 +00:00
|
|
|
#if MOZ_WIDGET_ANDROID
|
|
|
|
static void
|
|
|
|
AttachToContainerAsSurfaceTexture(ImageContainer* container,
|
|
|
|
nsNPAPIPluginInstance* instance,
|
|
|
|
const LayoutDeviceRect& rect,
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<Image>* out_image)
|
2014-09-17 13:13:29 +00:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(out_image);
|
|
|
|
MOZ_ASSERT(!*out_image);
|
|
|
|
|
2014-10-21 13:53:00 +00:00
|
|
|
mozilla::gl::AndroidSurfaceTexture* surfTex = instance->AsSurfaceTexture();
|
2014-09-17 13:13:29 +00:00
|
|
|
if (!surfTex) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-11-17 08:09:00 +00:00
|
|
|
RefPtr<Image> img = new SurfaceTextureImage(
|
|
|
|
surfTex,
|
|
|
|
gfx::IntSize(rect.width, rect.height),
|
|
|
|
instance->OriginPos());
|
2014-09-17 13:13:29 +00:00
|
|
|
*out_image = img;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-03-01 18:48:26 +00:00
|
|
|
bool
|
|
|
|
nsPluginInstanceOwner::NeedsScrollImageLayer()
|
|
|
|
{
|
|
|
|
#if defined(XP_WIN)
|
|
|
|
// If this is a windowed plugin and we're doing layout in the content
|
|
|
|
// process, force the creation of an image layer for the plugin. We'll
|
|
|
|
// paint to this when scrolling.
|
|
|
|
return XRE_IsContentProcess() &&
|
|
|
|
mPluginWindow &&
|
|
|
|
mPluginWindow->type == NPWindowTypeWindow;
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-02-08 15:34:27 +00:00
|
|
|
already_AddRefed<ImageContainer>
|
|
|
|
nsPluginInstanceOwner::GetImageContainer()
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
2012-10-26 17:49:50 +00:00
|
|
|
if (!mInstance)
|
|
|
|
return nullptr;
|
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<ImageContainer> container;
|
2012-10-26 17:49:50 +00:00
|
|
|
|
2012-07-20 19:20:51 +00:00
|
|
|
#if MOZ_WIDGET_ANDROID
|
|
|
|
// Right now we only draw with Gecko layers on Honeycomb and higher. See Paint()
|
|
|
|
// for what we do on other versions.
|
|
|
|
if (AndroidBridge::Bridge()->GetAPIVersion() < 11)
|
2013-10-23 20:34:30 +00:00
|
|
|
return nullptr;
|
2014-01-15 15:16:40 +00:00
|
|
|
|
|
|
|
LayoutDeviceRect r = GetPluginRect();
|
|
|
|
|
|
|
|
// NotifySize() causes Flash to do a bunch of stuff like ask for surfaces to render
|
|
|
|
// into, set y-flip flags, etc, so we do this at the beginning.
|
2015-03-06 23:07:59 +00:00
|
|
|
float resolution = mPluginFrame->PresContext()->PresShell()->GetCumulativeResolution();
|
|
|
|
ScreenSize screenSize = (r * LayoutDeviceToScreenScale(resolution)).Size();
|
2014-01-15 15:16:40 +00:00
|
|
|
mInstance->NotifySize(nsIntSize(screenSize.width, screenSize.height));
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2012-10-26 17:49:50 +00:00
|
|
|
container = LayerManager::CreateImageContainer();
|
2012-07-20 19:20:51 +00:00
|
|
|
|
2014-09-17 13:13:29 +00:00
|
|
|
// Try to get it as an EGLImage first.
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<Image> img;
|
2016-03-03 15:30:53 +00:00
|
|
|
AttachToContainerAsSurfaceTexture(container, mInstance, r, &img);
|
2012-07-20 19:20:51 +00:00
|
|
|
|
2015-11-23 02:03:00 +00:00
|
|
|
if (img) {
|
|
|
|
container->SetCurrentImageInTransaction(img);
|
|
|
|
}
|
2014-09-17 13:13:29 +00:00
|
|
|
#else
|
2016-03-01 18:48:26 +00:00
|
|
|
if (NeedsScrollImageLayer()) {
|
|
|
|
// windowed plugin under e10s
|
|
|
|
#if defined(XP_WIN)
|
|
|
|
mInstance->GetScrollCaptureContainer(getter_AddRefs(container));
|
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
// async windowless rendering
|
|
|
|
mInstance->GetImageContainer(getter_AddRefs(container));
|
|
|
|
}
|
2012-07-20 19:20:51 +00:00
|
|
|
#endif
|
|
|
|
|
2013-04-17 02:21:06 +00:00
|
|
|
return container.forget();
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
2015-12-02 19:31:17 +00:00
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::DidComposite()
|
|
|
|
{
|
|
|
|
if (mInstance) {
|
|
|
|
mInstance->DidComposite();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::SetBackgroundUnknown()
|
|
|
|
{
|
|
|
|
if (mInstance) {
|
|
|
|
mInstance->SetBackgroundUnknown();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-18 03:39:10 +00:00
|
|
|
already_AddRefed<mozilla::gfx::DrawTarget>
|
2011-06-01 04:37:54 +00:00
|
|
|
nsPluginInstanceOwner::BeginUpdateBackground(const nsIntRect& aRect)
|
|
|
|
{
|
|
|
|
nsIntRect rect = aRect;
|
2015-12-18 03:39:10 +00:00
|
|
|
RefPtr<DrawTarget> dt;
|
2011-06-01 04:37:54 +00:00
|
|
|
if (mInstance &&
|
2015-12-18 03:39:10 +00:00
|
|
|
NS_SUCCEEDED(mInstance->BeginUpdateBackground(&rect, getter_AddRefs(dt)))) {
|
|
|
|
return dt.forget();
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
2012-07-30 14:20:58 +00:00
|
|
|
return nullptr;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-12-18 03:39:09 +00:00
|
|
|
nsPluginInstanceOwner::EndUpdateBackground(const nsIntRect& aRect)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
nsIntRect rect = aRect;
|
|
|
|
if (mInstance) {
|
2015-12-18 03:39:09 +00:00
|
|
|
mInstance->EndUpdateBackground(&rect);
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
bool
|
2011-05-19 21:08:14 +00:00
|
|
|
nsPluginInstanceOwner::UseAsyncRendering()
|
|
|
|
{
|
|
|
|
#ifdef XP_MACOSX
|
2012-01-31 21:55:54 +00:00
|
|
|
if (mUseAsyncRendering) {
|
|
|
|
return true;
|
|
|
|
}
|
2011-05-19 21:08:14 +00:00
|
|
|
#endif
|
|
|
|
|
2012-09-27 00:22:51 +00:00
|
|
|
bool isOOP;
|
2011-09-29 06:19:26 +00:00
|
|
|
bool result = (mInstance &&
|
2012-09-27 00:22:51 +00:00
|
|
|
NS_SUCCEEDED(mInstance->GetIsOOP(&isOOP)) && isOOP
|
2012-02-01 02:18:30 +00:00
|
|
|
#ifndef XP_MACOSX
|
2012-02-02 01:09:34 +00:00
|
|
|
&& (!mPluginWindow ||
|
2011-05-19 21:08:14 +00:00
|
|
|
mPluginWindow->type == NPWindowTypeDrawable)
|
|
|
|
#endif
|
|
|
|
);
|
2011-06-30 16:46:26 +00:00
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
#ifdef XP_MACOSX
|
|
|
|
if (result) {
|
|
|
|
mUseAsyncRendering = true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return result;
|
2011-05-19 21:08:14 +00:00
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
nsIntSize
|
|
|
|
nsPluginInstanceOwner::GetCurrentImageSize()
|
|
|
|
{
|
|
|
|
nsIntSize size(0,0);
|
|
|
|
if (mInstance) {
|
|
|
|
mInstance->GetImageSize(&size);
|
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2016-03-01 18:48:26 +00:00
|
|
|
bool
|
|
|
|
nsPluginInstanceOwner::UpdateScrollState(bool aIsScrolling)
|
|
|
|
{
|
|
|
|
#if defined(XP_WIN)
|
|
|
|
if (!mInstance) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
mScrollState = aIsScrolling;
|
|
|
|
nsresult rv = mInstance->UpdateScrollState(aIsScrolling);
|
|
|
|
return NS_SUCCEEDED(rv);
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
nsPluginInstanceOwner::nsPluginInstanceOwner()
|
2016-04-29 06:51:00 +00:00
|
|
|
: mPluginWindow(nullptr)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
// create nsPluginNativeWindow object, it is derived from NPWindow
|
|
|
|
// struct and allows to manipulate native window procedure
|
|
|
|
nsCOMPtr<nsIPluginHost> pluginHostCOM = do_GetService(MOZ_PLUGIN_HOST_CONTRACTID);
|
2014-07-11 22:41:41 +00:00
|
|
|
mPluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
|
2012-01-31 21:55:54 +00:00
|
|
|
if (mPluginHost)
|
|
|
|
mPluginHost->NewPluginNativeWindow(&mPluginWindow);
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2014-09-24 04:35:00 +00:00
|
|
|
mPluginFrame = nullptr;
|
2012-01-31 21:55:54 +00:00
|
|
|
mWidgetCreationComplete = false;
|
2011-06-01 04:37:54 +00:00
|
|
|
#ifdef XP_MACOSX
|
2011-09-30 06:02:59 +00:00
|
|
|
mSentInitialTopLevelWindowEvent = false;
|
2014-12-11 14:44:07 +00:00
|
|
|
mLastWindowIsActive = false;
|
|
|
|
mLastContentFocused = false;
|
|
|
|
mLastScaleFactor = 1.0;
|
|
|
|
mShouldBlurOnActivate = false;
|
2011-06-01 04:37:54 +00:00
|
|
|
#endif
|
2016-03-17 19:00:59 +00:00
|
|
|
mLastCSSZoomFactor = 1.0;
|
2011-09-30 06:02:59 +00:00
|
|
|
mContentFocused = false;
|
|
|
|
mWidgetVisible = true;
|
|
|
|
mPluginWindowVisible = false;
|
|
|
|
mPluginDocumentActiveState = true;
|
2013-09-17 23:36:03 +00:00
|
|
|
mLastMouseDownButtonType = -1;
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
#ifdef XP_MACOSX
|
2012-08-30 19:10:55 +00:00
|
|
|
#ifndef NP_NO_CARBON
|
2012-10-15 12:38:34 +00:00
|
|
|
// We don't support Carbon, but it is still the default model for i386 NPAPI.
|
2011-06-01 04:37:54 +00:00
|
|
|
mEventModel = NPEventModelCarbon;
|
|
|
|
#else
|
|
|
|
mEventModel = NPEventModelCocoa;
|
|
|
|
#endif
|
2012-01-31 21:55:54 +00:00
|
|
|
mUseAsyncRendering = false;
|
2011-06-01 04:37:54 +00:00
|
|
|
#endif
|
|
|
|
|
2011-09-30 06:02:59 +00:00
|
|
|
mWaitingForPaint = false;
|
2011-11-21 07:55:50 +00:00
|
|
|
|
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
2012-05-30 16:10:49 +00:00
|
|
|
mFullScreen = false;
|
2012-07-30 14:20:58 +00:00
|
|
|
mJavaView = nullptr;
|
2011-11-21 07:55:50 +00:00
|
|
|
#endif
|
2015-12-29 13:57:38 +00:00
|
|
|
|
|
|
|
#ifdef XP_WIN
|
|
|
|
mGotCompositionData = false;
|
|
|
|
mSentStartComposition = false;
|
2016-01-12 08:47:38 +00:00
|
|
|
mPluginDidNotHandleIMEComposition = false;
|
2016-03-01 18:48:26 +00:00
|
|
|
mScrollState = false;
|
2015-12-29 13:57:38 +00:00
|
|
|
#endif
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsPluginInstanceOwner::~nsPluginInstanceOwner()
|
|
|
|
{
|
|
|
|
if (mWaitingForPaint) {
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
|
|
|
|
if (content) {
|
|
|
|
// We don't care when the event is dispatched as long as it's "soon",
|
|
|
|
// since whoever needs it will be waiting for it.
|
|
|
|
nsCOMPtr<nsIRunnable> event = new AsyncPaintWaitEvent(content, true);
|
|
|
|
NS_DispatchToMainThread(event);
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
2014-09-24 04:35:00 +00:00
|
|
|
mPluginFrame = nullptr;
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
PLUG_DeletePluginNativeWindow(mPluginWindow);
|
2012-07-30 14:20:58 +00:00
|
|
|
mPluginWindow = nullptr;
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2012-01-31 14:40:58 +00:00
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
2012-02-15 20:34:31 +00:00
|
|
|
RemovePluginView();
|
2012-01-31 14:40:58 +00:00
|
|
|
#endif
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
if (mInstance) {
|
2012-10-03 02:43:18 +00:00
|
|
|
mInstance->SetOwner(nullptr);
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-27 07:06:00 +00:00
|
|
|
NS_IMPL_ISUPPORTS(nsPluginInstanceOwner,
|
|
|
|
nsIPluginInstanceOwner,
|
|
|
|
nsIDOMEventListener,
|
|
|
|
nsIPrivacyTransitionObserver,
|
Bug 1257759 part.5 PluginInstanceChild should post received native key event to chrome process if the key combination may be a shortcut key r=jimm
When PluginInstanceChild receives native key events, it should post the events to the chrome process first for checking if the key combination is reserved. However, posting all key events to the chrome process may make damage to the performance of text input. Therefore, this patch starts to post a key event whose key combination may be a shortcut key. However, for avoiding to shuffle the event order, it posts following key events until all posted key events are handled by the chrome process.
For receiving response from widget, this patch defines nsIKeyEventInPluginCallback. It's specified by nsIWidget::OnWindowedPluginKeyEvent() for ensuring the caller will receive the reply. Basically, the caller of nsIWidget::OnWindowedPluginKeyEvent() should reply to the child process. However, if the widget is a PuppetWidget, it cannot return the result synchronously. Therefore, PuppetWidget::OnWindowedPluginKeyEvent() returns NS_SUCCESS_EVENT_HANDLED_ASYNCHRONOUSLY and stores the callback to mKeyEventInPluginCallbacks. Then, TabParent::HandledWindowedPluginKeyEvent() will call PuppetWidget::HandledWindowedPluginKeyEvent().
MozReview-Commit-ID: G6brOU26NwQ
--HG--
extra : rebase_source : 8140456de278956d2d594e85c7b397ae366b4962
2016-04-19 11:09:37 +00:00
|
|
|
nsIKeyEventInPluginCallback,
|
2014-04-27 07:06:00 +00:00
|
|
|
nsISupportsWeakReference)
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsPluginInstanceOwner::SetInstance(nsNPAPIPluginInstance *aInstance)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(!mInstance || !aInstance, "mInstance should only be set or unset!");
|
|
|
|
|
|
|
|
// If we're going to null out mInstance after use, be sure to call
|
2012-10-03 02:43:18 +00:00
|
|
|
// mInstance->SetOwner(nullptr) here, since it now won't be called
|
2011-06-01 04:37:54 +00:00
|
|
|
// from our destructor. This fixes bug 613376.
|
2012-03-14 21:15:46 +00:00
|
|
|
if (mInstance && !aInstance) {
|
2012-10-03 02:43:18 +00:00
|
|
|
mInstance->SetOwner(nullptr);
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2012-03-14 21:15:46 +00:00
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
|
|
|
RemovePluginView();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
mInstance = aInstance;
|
|
|
|
|
2012-04-24 04:49:25 +00:00
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
GetDocument(getter_AddRefs(doc));
|
|
|
|
if (doc) {
|
2016-01-30 17:05:36 +00:00
|
|
|
if (nsCOMPtr<nsPIDOMWindowOuter> domWindow = doc->GetWindow()) {
|
2012-04-24 04:49:25 +00:00
|
|
|
nsCOMPtr<nsIDocShell> docShell = domWindow->GetDocShell();
|
|
|
|
if (docShell)
|
|
|
|
docShell->AddWeakPrivacyTransitionObserver(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPluginInstanceOwner::GetWindow(NPWindow *&aWindow)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(mPluginWindow, "the plugin window object being returned is null");
|
|
|
|
aWindow = mPluginWindow;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
NS_IMETHODIMP nsPluginInstanceOwner::GetMode(int32_t *aMode)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
nsresult rv = GetDocument(getter_AddRefs(doc));
|
|
|
|
nsCOMPtr<nsIPluginDocument> pDoc (do_QueryInterface(doc));
|
|
|
|
|
|
|
|
if (pDoc) {
|
|
|
|
*aMode = NP_FULL;
|
|
|
|
} else {
|
|
|
|
*aMode = NP_EMBED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2014-08-15 21:17:35 +00:00
|
|
|
void nsPluginInstanceOwner::GetAttributes(nsTArray<MozPluginParameter>& attributes)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIObjectLoadingContent> content = do_QueryReferent(mContent);
|
2014-08-15 21:17:35 +00:00
|
|
|
nsObjectLoadingContent *loadingContent =
|
|
|
|
static_cast<nsObjectLoadingContent*>(content.get());
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2014-08-15 21:17:35 +00:00
|
|
|
loadingContent->GetPluginAttributes(attributes);
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPluginInstanceOwner::GetDOMElement(nsIDOMElement* *result)
|
|
|
|
{
|
2015-04-04 18:39:36 +00:00
|
|
|
return CallQueryReferent(mContent.get(), result);
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult nsPluginInstanceOwner::GetInstance(nsNPAPIPluginInstance **aInstance)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aInstance);
|
|
|
|
|
|
|
|
*aInstance = mInstance;
|
2011-09-16 20:22:44 +00:00
|
|
|
NS_IF_ADDREF(*aInstance);
|
2011-06-01 04:37:54 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPluginInstanceOwner::GetURL(const char *aURL,
|
|
|
|
const char *aTarget,
|
|
|
|
nsIInputStream *aPostStream,
|
|
|
|
void *aHeadersData,
|
2015-08-05 03:06:03 +00:00
|
|
|
uint32_t aHeadersDataLen,
|
|
|
|
bool aDoCheckLoadURIChecks)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
|
|
|
|
if (!content) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2015-04-04 18:39:36 +00:00
|
|
|
if (content->IsEditable()) {
|
2011-06-01 04:37:54 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2016-03-31 11:46:32 +00:00
|
|
|
nsIDocument *doc = content->GetUncomposedDoc();
|
2012-01-31 21:55:54 +00:00
|
|
|
if (!doc) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIPresShell *presShell = doc->GetShell();
|
|
|
|
if (!presShell) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsPresContext *presContext = presShell->GetPresContext();
|
|
|
|
if (!presContext) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
// the container of the pres context will give us the link handler
|
2013-11-20 19:18:25 +00:00
|
|
|
nsCOMPtr<nsISupports> container = presContext->GetContainerWeak();
|
2011-06-01 04:37:54 +00:00
|
|
|
NS_ENSURE_TRUE(container,NS_ERROR_FAILURE);
|
|
|
|
nsCOMPtr<nsILinkHandler> lh = do_QueryInterface(container);
|
|
|
|
NS_ENSURE_TRUE(lh, NS_ERROR_FAILURE);
|
|
|
|
|
2015-08-05 03:06:03 +00:00
|
|
|
nsAutoString unitarget;
|
|
|
|
if ((0 == PL_strcmp(aTarget, "newwindow")) ||
|
|
|
|
(0 == PL_strcmp(aTarget, "_new"))) {
|
|
|
|
unitarget.AssignASCII("_blank");
|
|
|
|
}
|
|
|
|
else if (0 == PL_strcmp(aTarget, "_current")) {
|
|
|
|
unitarget.AssignASCII("_self");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
unitarget.AssignASCII(aTarget); // XXX could this be nonascii?
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2012-11-27 14:14:38 +00:00
|
|
|
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
// Create an absolute URL
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, baseURI);
|
|
|
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
|
|
|
|
|
2015-08-05 03:06:03 +00:00
|
|
|
if (aDoCheckLoadURIChecks) {
|
|
|
|
nsCOMPtr<nsIScriptSecurityManager> secMan(
|
|
|
|
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv));
|
|
|
|
NS_ENSURE_TRUE(secMan, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
rv = secMan->CheckLoadURIWithPrincipal(content->NodePrincipal(), uri,
|
|
|
|
nsIScriptSecurityManager::STANDARD);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
nsCOMPtr<nsIInputStream> headersDataStream;
|
|
|
|
if (aPostStream && aHeadersData) {
|
|
|
|
if (!aHeadersDataLen)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStringInputStream> sis = do_CreateInstance("@mozilla.org/io/string-input-stream;1");
|
|
|
|
if (!sis)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
rv = sis->SetData((char *)aHeadersData, aHeadersDataLen);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
headersDataStream = do_QueryInterface(sis);
|
|
|
|
}
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t blockPopups =
|
2011-06-01 04:37:54 +00:00
|
|
|
Preferences::GetInt("privacy.popups.disable_from_plugins");
|
|
|
|
nsAutoPopupStatePusher popupStatePusher((PopupControlState)blockPopups);
|
|
|
|
|
2015-04-04 18:39:36 +00:00
|
|
|
rv = lh->OnLinkClick(content, uri, unitarget.get(), NullString(),
|
2011-09-30 06:02:59 +00:00
|
|
|
aPostStream, headersDataStream, true);
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPluginInstanceOwner::GetDocument(nsIDocument* *aDocument)
|
|
|
|
{
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
|
|
|
|
if (!aDocument || !content) {
|
2011-06-01 04:37:54 +00:00
|
|
|
return NS_ERROR_NULL_POINTER;
|
2015-03-16 21:11:13 +00:00
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
// XXX sXBL/XBL2 issue: current doc or owner doc?
|
|
|
|
// But keep in mind bug 322414 comment 33
|
2015-04-04 18:39:36 +00:00
|
|
|
NS_IF_ADDREF(*aDocument = content->OwnerDoc());
|
2011-06-01 04:37:54 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect)
|
|
|
|
{
|
|
|
|
// If our object frame has gone away, we won't be able to determine
|
|
|
|
// up-to-date-ness, so just fire off the event.
|
2014-09-24 04:35:00 +00:00
|
|
|
if (mWaitingForPaint && (!mPluginFrame || IsUpToDate())) {
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
|
2011-06-01 04:37:54 +00:00
|
|
|
// We don't care when the event is dispatched as long as it's "soon",
|
|
|
|
// since whoever needs it will be waiting for it.
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIRunnable> event = new AsyncPaintWaitEvent(content, true);
|
2011-06-01 04:37:54 +00:00
|
|
|
NS_DispatchToMainThread(event);
|
|
|
|
mWaitingForPaint = false;
|
|
|
|
}
|
|
|
|
|
2014-09-24 04:35:00 +00:00
|
|
|
if (!mPluginFrame || !invalidRect || !mWidgetVisible)
|
2011-06-01 04:37:54 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2012-10-31 02:54:06 +00:00
|
|
|
#if defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID)
|
2011-06-01 04:37:54 +00:00
|
|
|
// Each time an asynchronously-drawing plugin sends a new surface to display,
|
2012-10-31 02:54:06 +00:00
|
|
|
// the image in the ImageContainer is updated and InvalidateRect is called.
|
|
|
|
// There are different side effects for (sync) Android plugins.
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<ImageContainer> container;
|
2012-02-08 15:34:27 +00:00
|
|
|
mInstance->GetImageContainer(getter_AddRefs(container));
|
2012-10-31 02:54:06 +00:00
|
|
|
#endif
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
#ifndef XP_MACOSX
|
2016-03-01 18:48:26 +00:00
|
|
|
// Silverlight calls invalidate for windowed plugins so this needs to work.
|
2011-06-01 04:37:54 +00:00
|
|
|
if (mWidget) {
|
2015-11-17 05:18:31 +00:00
|
|
|
mWidget->Invalidate(
|
|
|
|
LayoutDeviceIntRect(invalidRect->left, invalidRect->top,
|
|
|
|
invalidRect->right - invalidRect->left,
|
|
|
|
invalidRect->bottom - invalidRect->top));
|
2016-03-01 18:48:26 +00:00
|
|
|
// Plugin instances also call invalidate when plugin windows are hidden
|
|
|
|
// during scrolling. In this case fall through so we invalidate the
|
|
|
|
// underlying layer.
|
|
|
|
if (!NeedsScrollImageLayer()) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
#endif
|
2012-08-29 05:47:18 +00:00
|
|
|
nsIntRect rect(invalidRect->left,
|
|
|
|
invalidRect->top,
|
|
|
|
invalidRect->right - invalidRect->left,
|
|
|
|
invalidRect->bottom - invalidRect->top);
|
2012-10-02 19:48:05 +00:00
|
|
|
// invalidRect is in "display pixels". In non-HiDPI modes "display pixels"
|
|
|
|
// are device pixels. But in HiDPI modes each display pixel corresponds
|
|
|
|
// to more than one device pixel.
|
|
|
|
double scaleFactor = 1.0;
|
|
|
|
GetContentsScaleFactor(&scaleFactor);
|
|
|
|
rect.ScaleRoundOut(scaleFactor);
|
2014-09-24 04:35:00 +00:00
|
|
|
mPluginFrame->InvalidateLayer(nsDisplayItem::TYPE_PLUGIN, &rect);
|
2011-06-01 04:37:54 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRegion(NPRegion invalidRegion)
|
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2012-02-16 03:30:22 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginInstanceOwner::RedrawPlugin()
|
|
|
|
{
|
2014-09-24 04:35:00 +00:00
|
|
|
if (mPluginFrame) {
|
|
|
|
mPluginFrame->InvalidateLayer(nsDisplayItem::TYPE_PLUGIN);
|
2012-02-16 03:30:22 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2015-08-12 15:00:26 +00:00
|
|
|
#if defined(XP_WIN)
|
|
|
|
nsIWidget*
|
|
|
|
nsPluginInstanceOwner::GetContainingWidgetIfOffset()
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
2015-08-12 15:00:26 +00:00
|
|
|
MOZ_ASSERT(mPluginFrame, "Caller should have checked for null mPluginFrame.");
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
// This property is provided to allow a "windowless" plugin to determine the window it is drawing
|
|
|
|
// in, so it can translate mouse coordinates it receives directly from the operating system
|
|
|
|
// to coordinates relative to itself.
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2015-08-12 15:00:26 +00:00
|
|
|
// The original code returns the document's window, which is OK if the window the "windowless" plugin
|
2011-06-01 04:37:54 +00:00
|
|
|
// 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
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
// To make sure "windowless" plugins always get the right origin for translating mouse coordinates, this code
|
|
|
|
// determines the window handle of the mozilla window containing the "windowless" plugin.
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
// Given that this HWND may not be that of the document's window, there is a slight risk
|
|
|
|
// of confusing a plugin that is using this HWND for illicit purposes, but since the documentation
|
|
|
|
// does not suggest this HWND IS that of the document window, rather that of the window
|
|
|
|
// the plugin is drawn in, this seems like a safe fix.
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
// we only attempt to get the nearest window if this really is a "windowless" plugin so as not
|
|
|
|
// to change any behaviour for the much more common windowed plugins,
|
|
|
|
// though why this method would even be being called for a windowed plugin escapes me.
|
2015-07-04 01:29:00 +00:00
|
|
|
if (!XRE_IsContentProcess() &&
|
2015-01-23 10:10:52 +00:00
|
|
|
mPluginWindow && mPluginWindow->type == NPWindowTypeDrawable) {
|
2011-06-01 04:37:54 +00:00
|
|
|
// it turns out that flash also uses this window for determining focus, and is currently
|
|
|
|
// unable to show a caret correctly if we return the enclosing window. Therefore for
|
|
|
|
// now we only return the enclosing window when there is an actual offset which
|
|
|
|
// would otherwise cause coordinates to be offset incorrectly. (i.e.
|
|
|
|
// if the enclosing window if offset from the document window)
|
|
|
|
//
|
|
|
|
// fixing both the caret and ability to interact issues for a windowless control in a non document aligned windw
|
|
|
|
// does not seem to be possible without a change to the flash plugin
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2014-09-24 04:35:00 +00:00
|
|
|
nsIWidget* win = mPluginFrame->GetNearestWidget();
|
2011-06-01 04:37:54 +00:00
|
|
|
if (win) {
|
2013-01-03 13:23:11 +00:00
|
|
|
nsView *view = nsView::GetViewFor(win);
|
2011-06-01 04:37:54 +00:00
|
|
|
NS_ASSERTION(view, "No view for widget");
|
2012-07-30 14:20:58 +00:00
|
|
|
nsPoint offset = view->GetOffsetTo(nullptr);
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
if (offset.x || offset.y) {
|
|
|
|
// in the case the two windows are offset from eachother, we do go ahead and return the correct enclosing window
|
|
|
|
// so that mouse co-ordinates are not messed up.
|
2015-08-12 15:00:26 +00:00
|
|
|
return win;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-08-12 15:00:26 +00:00
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static already_AddRefed<nsIWidget>
|
|
|
|
GetRootWidgetForPluginFrame(const nsPluginFrame* aPluginFrame)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(aPluginFrame);
|
|
|
|
|
|
|
|
nsViewManager* vm =
|
|
|
|
aPluginFrame->PresContext()->GetPresShell()->GetViewManager();
|
|
|
|
if (!vm) {
|
|
|
|
NS_WARNING("Could not find view manager for plugin frame.");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIWidget> rootWidget;
|
|
|
|
vm->GetRootWidget(getter_AddRefs(rootWidget));
|
|
|
|
return rootWidget.forget();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value)
|
|
|
|
{
|
|
|
|
if (!mPluginFrame) {
|
|
|
|
NS_WARNING("plugin owner has no owner in getting doc's window handle");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(XP_WIN)
|
|
|
|
void** pvalue = (void**)value;
|
|
|
|
nsIWidget* offsetContainingWidget = GetContainingWidgetIfOffset();
|
|
|
|
if (offsetContainingWidget) {
|
|
|
|
*pvalue = (void*)offsetContainingWidget->GetNativeData(NS_NATIVE_WINDOW);
|
|
|
|
if (*pvalue) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
// simply return the topmost document window
|
2015-08-12 15:00:26 +00:00
|
|
|
nsCOMPtr<nsIWidget> widget = GetRootWidgetForPluginFrame(mPluginFrame);
|
2011-06-01 04:37:54 +00:00
|
|
|
if (widget) {
|
2015-08-12 15:00:26 +00:00
|
|
|
*pvalue = widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW);
|
2011-06-01 04:37:54 +00:00
|
|
|
} else {
|
|
|
|
NS_ASSERTION(widget, "couldn't get doc's widget in getting doc's window handle");
|
|
|
|
}
|
|
|
|
|
2013-01-05 03:13:05 +00:00
|
|
|
return NS_OK;
|
2012-06-28 00:15:32 +00:00
|
|
|
#elif (defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)) && defined(MOZ_X11)
|
2011-06-01 04:37:54 +00:00
|
|
|
// X11 window managers want the toplevel window for WM_TRANSIENT_FOR.
|
2014-09-24 04:35:00 +00:00
|
|
|
nsIWidget* win = mPluginFrame->GetNearestWidget();
|
2011-06-01 04:37:54 +00:00
|
|
|
if (!win)
|
|
|
|
return NS_ERROR_FAILURE;
|
2011-08-31 19:01:38 +00:00
|
|
|
*static_cast<Window*>(value) = (long unsigned int)win->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW);
|
2011-06-01 04:37:54 +00:00
|
|
|
return NS_OK;
|
|
|
|
#else
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-08-12 15:00:26 +00:00
|
|
|
#if defined(XP_WIN)
|
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::SetWidgetWindowAsParent(HWND aWindowToAdopt)
|
|
|
|
{
|
|
|
|
if (!mWidget) {
|
|
|
|
NS_ERROR("mWidget should exist before this gets called.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mWidget->SetNativeData(NS_NATIVE_CHILD_WINDOW,
|
|
|
|
reinterpret_cast<uintptr_t>(aWindowToAdopt));
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsPluginInstanceOwner::SetNetscapeWindowAsParent(HWND aWindowToAdopt)
|
|
|
|
{
|
|
|
|
if (!mPluginFrame) {
|
|
|
|
NS_WARNING("Plugin owner has no plugin frame.");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If there is a containing window that is offset then ask that to adopt.
|
|
|
|
nsIWidget* offsetWidget = GetContainingWidgetIfOffset();
|
|
|
|
if (offsetWidget) {
|
|
|
|
offsetWidget->SetNativeData(NS_NATIVE_CHILD_WINDOW,
|
|
|
|
reinterpret_cast<uintptr_t>(aWindowToAdopt));
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise ask the topmost document window to adopt.
|
|
|
|
nsCOMPtr<nsIWidget> rootWidget = GetRootWidgetForPluginFrame(mPluginFrame);
|
|
|
|
if (!rootWidget) {
|
|
|
|
NS_ASSERTION(rootWidget, "Couldn't get topmost document's widget.");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
rootWidget->SetNativeData(NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW,
|
|
|
|
reinterpret_cast<uintptr_t>(aWindowToAdopt));
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2015-12-29 13:57:38 +00:00
|
|
|
|
|
|
|
bool
|
|
|
|
nsPluginInstanceOwner::GetCompositionString(uint32_t aType,
|
|
|
|
nsTArray<uint8_t>* aDist,
|
|
|
|
int32_t* aLength)
|
|
|
|
{
|
2015-12-29 13:57:38 +00:00
|
|
|
// Mark pkugin calls ImmGetCompositionStringW correctly
|
|
|
|
mGotCompositionData = true;
|
|
|
|
|
2015-12-29 13:57:38 +00:00
|
|
|
RefPtr<TextComposition> composition = GetTextComposition();
|
|
|
|
if (NS_WARN_IF(!composition)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(aType) {
|
|
|
|
case GCS_COMPSTR: {
|
|
|
|
if (!composition->IsComposing()) {
|
|
|
|
*aLength = 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t len = composition->LastData().Length() * sizeof(char16_t);
|
|
|
|
if (len) {
|
|
|
|
aDist->SetLength(len);
|
|
|
|
memcpy(aDist->Elements(), composition->LastData().get(), len);
|
|
|
|
}
|
|
|
|
*aLength = len;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GCS_RESULTSTR: {
|
|
|
|
if (composition->IsComposing()) {
|
|
|
|
*aLength = 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t len = composition->LastData().Length() * sizeof(char16_t);
|
|
|
|
if (len) {
|
|
|
|
aDist->SetLength(len);
|
|
|
|
memcpy(aDist->Elements(), composition->LastData().get(), len);
|
|
|
|
}
|
|
|
|
*aLength = len;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GCS_CURSORPOS: {
|
|
|
|
*aLength = 0;
|
|
|
|
TextRangeArray* ranges = composition->GetLastRanges();
|
|
|
|
if (!ranges) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
*aLength = ranges->GetCaretPosition();
|
|
|
|
if (*aLength < 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GCS_COMPATTR: {
|
|
|
|
TextRangeArray* ranges = composition->GetLastRanges();
|
|
|
|
if (!ranges || ranges->IsEmpty()) {
|
|
|
|
*aLength = 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
aDist->SetLength(composition->LastData().Length());
|
|
|
|
memset(aDist->Elements(), ATTR_INPUT, aDist->Length());
|
|
|
|
|
|
|
|
for (TextRange& range : *ranges) {
|
|
|
|
uint8_t type = ATTR_INPUT;
|
|
|
|
switch(range.mRangeType) {
|
|
|
|
case NS_TEXTRANGE_RAWINPUT:
|
|
|
|
type = ATTR_INPUT;
|
|
|
|
break;
|
|
|
|
case NS_TEXTRANGE_SELECTEDRAWTEXT:
|
|
|
|
type = ATTR_TARGET_NOTCONVERTED;
|
|
|
|
break;
|
|
|
|
case NS_TEXTRANGE_CONVERTEDTEXT:
|
|
|
|
type = ATTR_CONVERTED;
|
|
|
|
break;
|
|
|
|
case NS_TEXTRANGE_SELECTEDCONVERTEDTEXT:
|
|
|
|
type = ATTR_TARGET_CONVERTED;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t minLen = std::min<size_t>(range.mEndOffset, aDist->Length());
|
|
|
|
for (size_t i = range.mStartOffset; i < minLen; i++) {
|
|
|
|
(*aDist)[i] = type;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*aLength = aDist->Length();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GCS_COMPCLAUSE: {
|
|
|
|
RefPtr<TextRangeArray> ranges = composition->GetLastRanges();
|
|
|
|
if (!ranges || ranges->IsEmpty()) {
|
|
|
|
aDist->SetLength(sizeof(uint32_t));
|
|
|
|
memset(aDist->Elements(), 0, sizeof(uint32_t));
|
|
|
|
*aLength = aDist->Length();
|
|
|
|
return true;
|
|
|
|
}
|
2016-02-02 15:36:30 +00:00
|
|
|
AutoTArray<uint32_t, 16> clauses;
|
2015-12-29 13:57:38 +00:00
|
|
|
clauses.AppendElement(0);
|
|
|
|
for (TextRange& range : *ranges) {
|
|
|
|
if (!range.IsClause()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
clauses.AppendElement(range.mEndOffset);
|
|
|
|
}
|
|
|
|
|
|
|
|
aDist->SetLength(clauses.Length() * sizeof(uint32_t));
|
|
|
|
memcpy(aDist->Elements(), clauses.Elements(), aDist->Length());
|
|
|
|
*aLength = aDist->Length();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GCS_RESULTREADSTR: {
|
|
|
|
// When returning error causes unexpected error, so we return 0 instead.
|
|
|
|
*aLength = 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GCS_RESULTCLAUSE: {
|
|
|
|
// When returning error causes unexpected error, so we return 0 instead.
|
|
|
|
*aLength = 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
NS_WARNING(
|
|
|
|
nsPrintfCString("Unsupported type %x of ImmGetCompositionStringW hook",
|
|
|
|
aType).get());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2016-02-02 08:05:56 +00:00
|
|
|
nsPluginInstanceOwner::SetCandidateWindow(
|
|
|
|
const widget::CandidateWindowPosition& aPosition)
|
2015-12-29 13:57:38 +00:00
|
|
|
{
|
|
|
|
if (NS_WARN_IF(!mPluginFrame)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIWidget> widget = GetContainingWidgetIfOffset();
|
|
|
|
if (!widget) {
|
|
|
|
widget = GetRootWidgetForPluginFrame(mPluginFrame);
|
|
|
|
if (NS_WARN_IF(!widget)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-02 08:05:56 +00:00
|
|
|
widget->SetCandidateWindowForPlugin(aPosition);
|
2015-12-29 13:57:38 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
nsPluginInstanceOwner::RequestCommitOrCancel(bool aCommitted)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIWidget> widget = GetContainingWidgetIfOffset();
|
|
|
|
if (!widget) {
|
|
|
|
widget = GetRootWidgetForPluginFrame(mPluginFrame);
|
|
|
|
if (NS_WARN_IF(!widget)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aCommitted) {
|
2016-03-03 15:30:53 +00:00
|
|
|
widget->NotifyIME(widget::REQUEST_TO_COMMIT_COMPOSITION);
|
2015-12-29 13:57:38 +00:00
|
|
|
} else {
|
2016-03-03 15:30:53 +00:00
|
|
|
widget->NotifyIME(widget::REQUEST_TO_CANCEL_COMPOSITION);
|
2015-12-29 13:57:38 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
Bug 1257759 part.5 PluginInstanceChild should post received native key event to chrome process if the key combination may be a shortcut key r=jimm
When PluginInstanceChild receives native key events, it should post the events to the chrome process first for checking if the key combination is reserved. However, posting all key events to the chrome process may make damage to the performance of text input. Therefore, this patch starts to post a key event whose key combination may be a shortcut key. However, for avoiding to shuffle the event order, it posts following key events until all posted key events are handled by the chrome process.
For receiving response from widget, this patch defines nsIKeyEventInPluginCallback. It's specified by nsIWidget::OnWindowedPluginKeyEvent() for ensuring the caller will receive the reply. Basically, the caller of nsIWidget::OnWindowedPluginKeyEvent() should reply to the child process. However, if the widget is a PuppetWidget, it cannot return the result synchronously. Therefore, PuppetWidget::OnWindowedPluginKeyEvent() returns NS_SUCCESS_EVENT_HANDLED_ASYNCHRONOUSLY and stores the callback to mKeyEventInPluginCallbacks. Then, TabParent::HandledWindowedPluginKeyEvent() will call PuppetWidget::HandledWindowedPluginKeyEvent().
MozReview-Commit-ID: G6brOU26NwQ
--HG--
extra : rebase_source : 8140456de278956d2d594e85c7b397ae366b4962
2016-04-19 11:09:37 +00:00
|
|
|
|
2015-12-29 13:57:38 +00:00
|
|
|
#endif // #ifdef XP_WIN
|
2015-08-12 15:00:26 +00:00
|
|
|
|
Bug 1257759 part.5 PluginInstanceChild should post received native key event to chrome process if the key combination may be a shortcut key r=jimm
When PluginInstanceChild receives native key events, it should post the events to the chrome process first for checking if the key combination is reserved. However, posting all key events to the chrome process may make damage to the performance of text input. Therefore, this patch starts to post a key event whose key combination may be a shortcut key. However, for avoiding to shuffle the event order, it posts following key events until all posted key events are handled by the chrome process.
For receiving response from widget, this patch defines nsIKeyEventInPluginCallback. It's specified by nsIWidget::OnWindowedPluginKeyEvent() for ensuring the caller will receive the reply. Basically, the caller of nsIWidget::OnWindowedPluginKeyEvent() should reply to the child process. However, if the widget is a PuppetWidget, it cannot return the result synchronously. Therefore, PuppetWidget::OnWindowedPluginKeyEvent() returns NS_SUCCESS_EVENT_HANDLED_ASYNCHRONOUSLY and stores the callback to mKeyEventInPluginCallbacks. Then, TabParent::HandledWindowedPluginKeyEvent() will call PuppetWidget::HandledWindowedPluginKeyEvent().
MozReview-Commit-ID: G6brOU26NwQ
--HG--
extra : rebase_source : 8140456de278956d2d594e85c7b397ae366b4962
2016-04-19 11:09:37 +00:00
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::HandledWindowedPluginKeyEvent(
|
|
|
|
const NativeEventData& aKeyEventData,
|
|
|
|
bool aIsConsumed)
|
|
|
|
{
|
|
|
|
if (NS_WARN_IF(!mInstance)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
nsresult rv =
|
|
|
|
mInstance->HandledWindowedPluginKeyEvent(aKeyEventData, aIsConsumed);
|
|
|
|
NS_WARN_IF(NS_FAILED(rv));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::OnWindowedPluginKeyEvent(
|
|
|
|
const NativeEventData& aKeyEventData)
|
|
|
|
{
|
|
|
|
if (NS_WARN_IF(!mPluginFrame)) {
|
|
|
|
// Notifies the plugin process of the key event being not consumed by us.
|
|
|
|
HandledWindowedPluginKeyEvent(aKeyEventData, false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIWidget> widget = mPluginFrame->PresContext()->GetRootWidget();
|
|
|
|
if (NS_WARN_IF(!widget)) {
|
|
|
|
// Notifies the plugin process of the key event being not consumed by us.
|
|
|
|
HandledWindowedPluginKeyEvent(aKeyEventData, false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult rv = widget->OnWindowedPluginKeyEvent(aKeyEventData, this);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
// Notifies the plugin process of the key event being not consumed by us.
|
|
|
|
HandledWindowedPluginKeyEvent(aKeyEventData, false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the key event is posted to another process, we need to wait a call
|
|
|
|
// of HandledWindowedPluginKeyEvent(). So, nothing to do here in this case.
|
|
|
|
if (rv == NS_SUCCESS_EVENT_HANDLED_ASYNCHRONOUSLY) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, the key event is handled synchronously. Let's notify the
|
|
|
|
// plugin process of the key event's result.
|
|
|
|
bool consumed = (rv == NS_SUCCESS_EVENT_CONSUMED);
|
|
|
|
HandledWindowedPluginKeyEvent(aKeyEventData, consumed);
|
|
|
|
}
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
NS_IMETHODIMP nsPluginInstanceOwner::SetEventModel(int32_t eventModel)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
#ifdef XP_MACOSX
|
2012-10-15 12:38:34 +00:00
|
|
|
mEventModel = static_cast<NPEventModel>(eventModel);
|
2011-06-01 04:37:54 +00:00
|
|
|
return NS_OK;
|
|
|
|
#else
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef XP_MACOSX
|
2014-12-11 14:44:07 +00:00
|
|
|
NPBool nsPluginInstanceOwner::ConvertPointPuppet(PuppetWidget *widget,
|
|
|
|
nsPluginFrame* pluginFrame,
|
|
|
|
double sourceX, double sourceY,
|
|
|
|
NPCoordinateSpace sourceSpace,
|
|
|
|
double *destX, double *destY,
|
|
|
|
NPCoordinateSpace destSpace)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(widget && widget->GetOwningTabChild() && pluginFrame, false);
|
|
|
|
// Caller has to want a result.
|
|
|
|
NS_ENSURE_TRUE(destX || destY, false);
|
|
|
|
|
|
|
|
if (sourceSpace == destSpace) {
|
|
|
|
if (destX) {
|
|
|
|
*destX = sourceX;
|
|
|
|
}
|
|
|
|
if (destY) {
|
|
|
|
*destY = sourceY;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
nsPresContext* presContext = pluginFrame->PresContext();
|
|
|
|
double scaleFactor = double(nsPresContext::AppUnitsPerCSSPixel())/
|
|
|
|
presContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom();
|
|
|
|
|
|
|
|
PuppetWidget *puppetWidget = static_cast<PuppetWidget*>(widget);
|
|
|
|
PuppetWidget *rootWidget = static_cast<PuppetWidget*>(widget->GetTopLevelWidget());
|
|
|
|
if (!rootWidget) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
nsPoint chromeSize = AsNsPoint(rootWidget->GetChromeDimensions()) / scaleFactor;
|
|
|
|
nsIntSize intScreenDims = rootWidget->GetScreenDimensions();
|
|
|
|
nsSize screenDims = nsSize(intScreenDims.width / scaleFactor,
|
|
|
|
intScreenDims.height / scaleFactor);
|
|
|
|
int32_t screenH = screenDims.height;
|
|
|
|
nsPoint windowPosition = AsNsPoint(rootWidget->GetWindowPosition()) / scaleFactor;
|
|
|
|
|
|
|
|
// Window size is tab size + chrome size.
|
2015-11-26 04:32:47 +00:00
|
|
|
LayoutDeviceIntRect tabContentBounds;
|
|
|
|
NS_ENSURE_SUCCESS(puppetWidget->GetBounds(tabContentBounds), false);
|
2014-12-11 14:44:07 +00:00
|
|
|
tabContentBounds.ScaleInverseRoundOut(scaleFactor);
|
|
|
|
int32_t windowH = tabContentBounds.height + int(chromeSize.y);
|
|
|
|
|
|
|
|
nsPoint pluginPosition = AsNsPoint(pluginFrame->GetScreenRect().TopLeft());
|
|
|
|
|
|
|
|
// Convert (sourceX, sourceY) to 'real' (not PuppetWidget) screen space.
|
|
|
|
// In OSX, the Y-axis increases upward, which is the reverse of ours.
|
|
|
|
// We want OSX coordinates for window and screen so those equations are swapped.
|
|
|
|
nsPoint sourcePoint(sourceX, sourceY);
|
|
|
|
nsPoint screenPoint;
|
|
|
|
switch (sourceSpace) {
|
|
|
|
case NPCoordinateSpacePlugin:
|
2015-03-31 20:39:02 +00:00
|
|
|
screenPoint = sourcePoint + pluginPosition +
|
|
|
|
pluginFrame->GetContentRectRelativeToSelf().TopLeft() / nsPresContext::AppUnitsPerCSSPixel();
|
2014-12-11 14:44:07 +00:00
|
|
|
break;
|
|
|
|
case NPCoordinateSpaceWindow:
|
|
|
|
screenPoint = nsPoint(sourcePoint.x, windowH-sourcePoint.y) +
|
|
|
|
windowPosition;
|
|
|
|
break;
|
|
|
|
case NPCoordinateSpaceFlippedWindow:
|
|
|
|
screenPoint = sourcePoint + windowPosition;
|
|
|
|
break;
|
|
|
|
case NPCoordinateSpaceScreen:
|
|
|
|
screenPoint = nsPoint(sourcePoint.x, screenH-sourcePoint.y);
|
|
|
|
break;
|
|
|
|
case NPCoordinateSpaceFlippedScreen:
|
|
|
|
screenPoint = sourcePoint;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert from screen to dest space.
|
|
|
|
nsPoint destPoint;
|
|
|
|
switch (destSpace) {
|
|
|
|
case NPCoordinateSpacePlugin:
|
2015-03-31 20:39:02 +00:00
|
|
|
destPoint = screenPoint - pluginPosition -
|
|
|
|
pluginFrame->GetContentRectRelativeToSelf().TopLeft() / nsPresContext::AppUnitsPerCSSPixel();
|
2014-12-11 14:44:07 +00:00
|
|
|
break;
|
|
|
|
case NPCoordinateSpaceWindow:
|
|
|
|
destPoint = screenPoint - windowPosition;
|
|
|
|
destPoint.y = windowH - destPoint.y;
|
|
|
|
break;
|
|
|
|
case NPCoordinateSpaceFlippedWindow:
|
|
|
|
destPoint = screenPoint - windowPosition;
|
|
|
|
break;
|
|
|
|
case NPCoordinateSpaceScreen:
|
|
|
|
destPoint = nsPoint(screenPoint.x, screenH-screenPoint.y);
|
|
|
|
break;
|
|
|
|
case NPCoordinateSpaceFlippedScreen:
|
|
|
|
destPoint = screenPoint;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (destX) {
|
|
|
|
*destX = destPoint.x;
|
|
|
|
}
|
|
|
|
if (destY) {
|
|
|
|
*destY = destPoint.y;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
NPBool nsPluginInstanceOwner::ConvertPointNoPuppet(nsIWidget *widget,
|
|
|
|
nsPluginFrame* pluginFrame,
|
|
|
|
double sourceX, double sourceY,
|
|
|
|
NPCoordinateSpace sourceSpace,
|
|
|
|
double *destX, double *destY,
|
|
|
|
NPCoordinateSpace destSpace)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(widget && pluginFrame, false);
|
|
|
|
// Caller has to want a result.
|
|
|
|
NS_ENSURE_TRUE(destX || destY, false);
|
|
|
|
|
|
|
|
if (sourceSpace == destSpace) {
|
|
|
|
if (destX) {
|
|
|
|
*destX = sourceX;
|
|
|
|
}
|
|
|
|
if (destY) {
|
|
|
|
*destY = sourceY;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsPresContext* presContext = pluginFrame->PresContext();
|
|
|
|
double scaleFactor = double(nsPresContext::AppUnitsPerCSSPixel())/
|
|
|
|
presContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom();
|
|
|
|
|
|
|
|
nsCOMPtr<nsIScreenManager> screenMgr = do_GetService("@mozilla.org/gfx/screenmanager;1");
|
|
|
|
if (!screenMgr) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIScreen> screen;
|
|
|
|
screenMgr->ScreenForNativeWidget(widget->GetNativeData(NS_NATIVE_WINDOW), getter_AddRefs(screen));
|
|
|
|
if (!screen) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t screenX, screenY, screenWidth, screenHeight;
|
|
|
|
screen->GetRect(&screenX, &screenY, &screenWidth, &screenHeight);
|
|
|
|
screenHeight /= scaleFactor;
|
|
|
|
|
2015-11-10 05:37:32 +00:00
|
|
|
LayoutDeviceIntRect windowScreenBounds;
|
2014-12-11 14:44:07 +00:00
|
|
|
NS_ENSURE_SUCCESS(widget->GetScreenBounds(windowScreenBounds), false);
|
|
|
|
windowScreenBounds.ScaleInverseRoundOut(scaleFactor);
|
|
|
|
int32_t windowX = windowScreenBounds.x;
|
|
|
|
int32_t windowY = windowScreenBounds.y;
|
|
|
|
int32_t windowHeight = windowScreenBounds.height;
|
|
|
|
|
|
|
|
nsIntRect pluginScreenRect = pluginFrame->GetScreenRect();
|
|
|
|
|
|
|
|
double screenXGecko, screenYGecko;
|
|
|
|
switch (sourceSpace) {
|
|
|
|
case NPCoordinateSpacePlugin:
|
|
|
|
screenXGecko = pluginScreenRect.x + sourceX;
|
|
|
|
screenYGecko = pluginScreenRect.y + sourceY;
|
|
|
|
break;
|
|
|
|
case NPCoordinateSpaceWindow:
|
|
|
|
screenXGecko = windowX + sourceX;
|
|
|
|
screenYGecko = windowY + (windowHeight - sourceY);
|
|
|
|
break;
|
|
|
|
case NPCoordinateSpaceFlippedWindow:
|
|
|
|
screenXGecko = windowX + sourceX;
|
|
|
|
screenYGecko = windowY + sourceY;
|
|
|
|
break;
|
|
|
|
case NPCoordinateSpaceScreen:
|
|
|
|
screenXGecko = sourceX;
|
|
|
|
screenYGecko = screenHeight - sourceY;
|
|
|
|
break;
|
|
|
|
case NPCoordinateSpaceFlippedScreen:
|
|
|
|
screenXGecko = sourceX;
|
|
|
|
screenYGecko = sourceY;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
double destXCocoa, destYCocoa;
|
|
|
|
switch (destSpace) {
|
|
|
|
case NPCoordinateSpacePlugin:
|
|
|
|
destXCocoa = screenXGecko - pluginScreenRect.x;
|
|
|
|
destYCocoa = screenYGecko - pluginScreenRect.y;
|
|
|
|
break;
|
|
|
|
case NPCoordinateSpaceWindow:
|
|
|
|
destXCocoa = screenXGecko - windowX;
|
|
|
|
destYCocoa = windowHeight - (screenYGecko - windowY);
|
|
|
|
break;
|
|
|
|
case NPCoordinateSpaceFlippedWindow:
|
|
|
|
destXCocoa = screenXGecko - windowX;
|
|
|
|
destYCocoa = screenYGecko - windowY;
|
|
|
|
break;
|
|
|
|
case NPCoordinateSpaceScreen:
|
|
|
|
destXCocoa = screenXGecko;
|
|
|
|
destYCocoa = screenHeight - screenYGecko;
|
|
|
|
break;
|
|
|
|
case NPCoordinateSpaceFlippedScreen:
|
|
|
|
destXCocoa = screenXGecko;
|
|
|
|
destYCocoa = screenYGecko;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (destX) {
|
|
|
|
*destX = destXCocoa;
|
|
|
|
}
|
|
|
|
if (destY) {
|
|
|
|
*destY = destYCocoa;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
2014-12-11 14:44:07 +00:00
|
|
|
#endif // XP_MACOSX
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
NPBool nsPluginInstanceOwner::ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
|
|
|
|
double *destX, double *destY, NPCoordinateSpace destSpace)
|
|
|
|
{
|
|
|
|
#ifdef XP_MACOSX
|
2014-12-11 14:44:07 +00:00
|
|
|
if (!mPluginFrame) {
|
2011-09-30 06:02:59 +00:00
|
|
|
return false;
|
2014-12-11 14:44:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(mPluginFrame->GetNearestWidget());
|
|
|
|
|
|
|
|
if (nsIWidget::UsePuppetWidgets()) {
|
|
|
|
return ConvertPointPuppet(static_cast<PuppetWidget*>(mPluginFrame->GetNearestWidget()),
|
|
|
|
mPluginFrame, sourceX, sourceY, sourceSpace,
|
|
|
|
destX, destY, destSpace);
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
return ConvertPointNoPuppet(mPluginFrame->GetNearestWidget(),
|
|
|
|
mPluginFrame, sourceX, sourceY, sourceSpace,
|
|
|
|
destX, destY, destSpace);
|
2011-06-01 04:37:54 +00:00
|
|
|
#else
|
2011-09-30 06:02:59 +00:00
|
|
|
return false;
|
2011-06-01 04:37:54 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-12-02 19:31:16 +00:00
|
|
|
NPError nsPluginInstanceOwner::InitAsyncSurface(NPSize *size, NPImageFormat format,
|
|
|
|
void *initData, NPAsyncSurface *surface)
|
|
|
|
{
|
|
|
|
return NPERR_INCOMPATIBLE_VERSION_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
NPError nsPluginInstanceOwner::FinalizeAsyncSurface(NPAsyncSurface *)
|
|
|
|
{
|
|
|
|
return NPERR_INCOMPATIBLE_VERSION_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsPluginInstanceOwner::SetCurrentAsyncSurface(NPAsyncSurface *, NPRect*)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
NS_IMETHODIMP nsPluginInstanceOwner::GetTagType(nsPluginTagType *result)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
|
|
|
|
|
|
*result = nsPluginTagType_Unknown;
|
|
|
|
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
|
|
|
|
if (content->IsHTMLElement(nsGkAtoms::applet))
|
2011-06-01 04:37:54 +00:00
|
|
|
*result = nsPluginTagType_Applet;
|
2015-04-04 18:39:36 +00:00
|
|
|
else if (content->IsHTMLElement(nsGkAtoms::embed))
|
2011-06-01 04:37:54 +00:00
|
|
|
*result = nsPluginTagType_Embed;
|
2015-04-04 18:39:36 +00:00
|
|
|
else if (content->IsHTMLElement(nsGkAtoms::object))
|
2011-06-01 04:37:54 +00:00
|
|
|
*result = nsPluginTagType_Object;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2014-08-15 21:17:35 +00:00
|
|
|
void nsPluginInstanceOwner::GetParameters(nsTArray<MozPluginParameter>& parameters)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIObjectLoadingContent> content = do_QueryReferent(mContent);
|
2014-08-15 21:17:35 +00:00
|
|
|
nsObjectLoadingContent *loadingContent =
|
|
|
|
static_cast<nsObjectLoadingContent*>(content.get());
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2014-08-15 21:17:35 +00:00
|
|
|
loadingContent->GetPluginParameters(parameters);
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef XP_MACOSX
|
|
|
|
|
|
|
|
static void InitializeNPCocoaEvent(NPCocoaEvent* event)
|
|
|
|
{
|
|
|
|
memset(event, 0, sizeof(NPCocoaEvent));
|
|
|
|
}
|
|
|
|
|
|
|
|
NPDrawingModel nsPluginInstanceOwner::GetDrawingModel()
|
|
|
|
{
|
|
|
|
#ifndef NP_NO_QUICKDRAW
|
2012-08-30 19:10:55 +00:00
|
|
|
// We don't support the Quickdraw drawing model any more but it's still
|
|
|
|
// the default model for i386 per NPAPI.
|
2011-06-01 04:37:54 +00:00
|
|
|
NPDrawingModel drawingModel = NPDrawingModelQuickDraw;
|
|
|
|
#else
|
|
|
|
NPDrawingModel drawingModel = NPDrawingModelCoreGraphics;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!mInstance)
|
|
|
|
return drawingModel;
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
mInstance->GetDrawingModel((int32_t*)&drawingModel);
|
2011-06-01 04:37:54 +00:00
|
|
|
return drawingModel;
|
|
|
|
}
|
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
bool nsPluginInstanceOwner::IsRemoteDrawingCoreAnimation()
|
2011-06-30 16:46:26 +00:00
|
|
|
{
|
|
|
|
if (!mInstance)
|
2011-09-30 06:02:59 +00:00
|
|
|
return false;
|
2011-06-30 16:46:26 +00:00
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
bool coreAnimation;
|
2011-06-30 16:46:26 +00:00
|
|
|
if (!NS_SUCCEEDED(mInstance->IsRemoteDrawingCoreAnimation(&coreAnimation)))
|
2011-09-30 06:02:59 +00:00
|
|
|
return false;
|
2011-06-30 16:46:26 +00:00
|
|
|
|
|
|
|
return coreAnimation;
|
|
|
|
}
|
|
|
|
|
2012-10-16 19:41:21 +00:00
|
|
|
nsresult nsPluginInstanceOwner::ContentsScaleFactorChanged(double aContentsScaleFactor)
|
|
|
|
{
|
|
|
|
if (!mInstance) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
return mInstance->ContentsScaleFactorChanged(aContentsScaleFactor);
|
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
NPEventModel nsPluginInstanceOwner::GetEventModel()
|
|
|
|
{
|
|
|
|
return mEventModel;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define DEFAULT_REFRESH_RATE 20 // 50 FPS
|
|
|
|
|
2013-10-23 20:34:30 +00:00
|
|
|
nsCOMPtr<nsITimer> *nsPluginInstanceOwner::sCATimer = nullptr;
|
|
|
|
nsTArray<nsPluginInstanceOwner*> *nsPluginInstanceOwner::sCARefreshListeners = nullptr;
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
void nsPluginInstanceOwner::CARefresh(nsITimer *aTimer, void *aClosure) {
|
|
|
|
if (!sCARefreshListeners) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (size_t i = 0; i < sCARefreshListeners->Length(); i++) {
|
|
|
|
nsPluginInstanceOwner* instanceOwner = (*sCARefreshListeners)[i];
|
|
|
|
NPWindow *window;
|
|
|
|
instanceOwner->GetWindow(window);
|
|
|
|
if (!window) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
NPRect r;
|
|
|
|
r.left = 0;
|
|
|
|
r.top = 0;
|
|
|
|
r.right = window->width;
|
2014-07-11 22:41:41 +00:00
|
|
|
r.bottom = window->height;
|
2011-06-01 04:37:54 +00:00
|
|
|
instanceOwner->InvalidateRect(&r);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-17 02:27:37 +00:00
|
|
|
void nsPluginInstanceOwner::AddToCARefreshTimer() {
|
|
|
|
if (!mInstance) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Flash invokes InvalidateRect for us.
|
2012-07-30 14:20:58 +00:00
|
|
|
const char* mime = nullptr;
|
2015-01-30 15:54:19 +00:00
|
|
|
if (NS_SUCCEEDED(mInstance->GetMIMEType(&mime)) && mime &&
|
|
|
|
nsPluginHost::GetSpecialType(nsDependentCString(mime)) ==
|
|
|
|
nsPluginHost::eSpecialType_Flash) {
|
|
|
|
return;
|
2012-02-17 02:27:37 +00:00
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
if (!sCARefreshListeners) {
|
|
|
|
sCARefreshListeners = new nsTArray<nsPluginInstanceOwner*>();
|
|
|
|
}
|
|
|
|
|
2012-02-17 02:27:37 +00:00
|
|
|
if (sCARefreshListeners->Contains(this)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
sCARefreshListeners->AppendElement(this);
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
if (!sCATimer) {
|
|
|
|
sCATimer = new nsCOMPtr<nsITimer>();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sCARefreshListeners->Length() == 1) {
|
|
|
|
*sCATimer = do_CreateInstance("@mozilla.org/timer;1");
|
2014-07-11 22:41:41 +00:00
|
|
|
(*sCATimer)->InitWithFuncCallback(CARefresh, nullptr,
|
2011-06-01 04:37:54 +00:00
|
|
|
DEFAULT_REFRESH_RATE, nsITimer::TYPE_REPEATING_SLACK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-17 02:27:37 +00:00
|
|
|
void nsPluginInstanceOwner::RemoveFromCARefreshTimer() {
|
|
|
|
if (!sCARefreshListeners || sCARefreshListeners->Contains(this) == false) {
|
2011-06-01 04:37:54 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-02-17 02:27:37 +00:00
|
|
|
sCARefreshListeners->RemoveElement(this);
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
if (sCARefreshListeners->Length() == 0) {
|
|
|
|
if (sCATimer) {
|
|
|
|
(*sCATimer)->Cancel();
|
|
|
|
delete sCATimer;
|
2013-10-23 20:34:30 +00:00
|
|
|
sCATimer = nullptr;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
delete sCARefreshListeners;
|
2013-10-23 20:34:30 +00:00
|
|
|
sCARefreshListeners = nullptr;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
void nsPluginInstanceOwner::SetPluginPort()
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
2014-12-11 14:44:07 +00:00
|
|
|
void* pluginPort = GetPluginPort();
|
|
|
|
if (!pluginPort || !mPluginWindow)
|
|
|
|
return;
|
2011-06-01 04:37:54 +00:00
|
|
|
mPluginWindow->window = pluginPort;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// static
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t
|
2011-06-01 04:37:54 +00:00
|
|
|
nsPluginInstanceOwner::GetEventloopNestingLevel()
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t currentLevel = 0;
|
2011-06-01 04:37:54 +00:00
|
|
|
if (appShell) {
|
|
|
|
appShell->GetEventloopNestingLevel(¤tLevel);
|
|
|
|
#ifdef XP_MACOSX
|
|
|
|
// Cocoa widget code doesn't process UI events through the normal
|
|
|
|
// appshell event loop, so it needs an additional count here.
|
|
|
|
currentLevel++;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
// No idea how this happens... but Linux doesn't consistently
|
|
|
|
// process UI events through the appshell event loop. If we get a 0
|
|
|
|
// here on any platform we increment the level just in case so that
|
|
|
|
// we make sure we always tear the plugin down eventually.
|
|
|
|
if (!currentLevel) {
|
|
|
|
currentLevel++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return currentLevel;
|
|
|
|
}
|
|
|
|
|
2011-11-11 00:17:46 +00:00
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
2012-01-31 14:40:58 +00:00
|
|
|
|
2012-06-11 17:50:59 +00:00
|
|
|
// Modified version of nsFrame::GetOffsetToCrossDoc that stops when it
|
|
|
|
// hits an element with a displayport (or runs out of frames). This is
|
|
|
|
// not really the right thing to do, but it's better than what was here before.
|
|
|
|
static nsPoint
|
|
|
|
GetOffsetRootContent(nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
// offset will hold the final offset
|
|
|
|
// docOffset holds the currently accumulated offset at the current APD, it
|
|
|
|
// will be converted and added to offset when the current APD changes.
|
|
|
|
nsPoint offset(0, 0), docOffset(0, 0);
|
|
|
|
const nsIFrame* f = aFrame;
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t currAPD = aFrame->PresContext()->AppUnitsPerDevPixel();
|
|
|
|
int32_t apd = currAPD;
|
2012-06-11 17:50:59 +00:00
|
|
|
while (f) {
|
2016-01-08 00:27:48 +00:00
|
|
|
if (f->GetContent() && nsLayoutUtils::HasDisplayPort(f->GetContent()))
|
2012-06-11 17:50:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
docOffset += f->GetPosition();
|
|
|
|
nsIFrame* parent = f->GetParent();
|
|
|
|
if (parent) {
|
|
|
|
f = parent;
|
|
|
|
} else {
|
|
|
|
nsPoint newOffset(0, 0);
|
|
|
|
f = nsLayoutUtils::GetCrossDocParentFrame(f, &newOffset);
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t newAPD = f ? f->PresContext()->AppUnitsPerDevPixel() : 0;
|
2012-06-11 17:50:59 +00:00
|
|
|
if (!f || newAPD != currAPD) {
|
|
|
|
// Convert docOffset to the right APD and add it to offset.
|
2015-03-26 21:44:40 +00:00
|
|
|
offset += docOffset.ScaleToOtherAppUnits(currAPD, apd);
|
2012-06-11 17:50:59 +00:00
|
|
|
docOffset.x = docOffset.y = 0;
|
|
|
|
}
|
|
|
|
currAPD = newAPD;
|
|
|
|
docOffset += newOffset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-26 21:44:40 +00:00
|
|
|
offset += docOffset.ScaleToOtherAppUnits(currAPD, apd);
|
2012-06-11 17:50:59 +00:00
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
2013-08-13 15:49:21 +00:00
|
|
|
LayoutDeviceRect nsPluginInstanceOwner::GetPluginRect()
|
2012-06-11 17:50:59 +00:00
|
|
|
{
|
|
|
|
// Get the offset of the content relative to the page
|
2014-09-24 04:35:00 +00:00
|
|
|
nsRect bounds = mPluginFrame->GetContentRectRelativeToSelf() + GetOffsetRootContent(mPluginFrame);
|
|
|
|
LayoutDeviceIntRect rect = LayoutDeviceIntRect::FromAppUnitsToNearest(bounds, mPluginFrame->PresContext()->AppUnitsPerDevPixel());
|
2013-08-13 15:49:21 +00:00
|
|
|
return LayoutDeviceRect(rect);
|
2012-06-11 17:50:59 +00:00
|
|
|
}
|
|
|
|
|
2013-08-13 15:49:21 +00:00
|
|
|
bool nsPluginInstanceOwner::AddPluginView(const LayoutDeviceRect& aRect /* = LayoutDeviceRect(0, 0, 0, 0) */)
|
2011-10-05 18:44:19 +00:00
|
|
|
{
|
2012-05-30 16:10:49 +00:00
|
|
|
if (!mJavaView) {
|
|
|
|
mJavaView = mInstance->GetJavaSurface();
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2012-05-30 16:10:49 +00:00
|
|
|
if (!mJavaView)
|
|
|
|
return false;
|
|
|
|
|
2015-08-13 04:53:39 +00:00
|
|
|
mJavaView = (void*)jni::GetGeckoThreadEnv()->NewGlobalRef((jobject)mJavaView);
|
2011-11-21 07:55:50 +00:00
|
|
|
}
|
2011-10-05 18:44:19 +00:00
|
|
|
|
2012-04-27 20:04:47 +00:00
|
|
|
if (AndroidBridge::Bridge())
|
2012-06-07 02:39:36 +00:00
|
|
|
AndroidBridge::Bridge()->AddPluginView((jobject)mJavaView, aRect, mFullScreen);
|
2012-05-30 16:10:49 +00:00
|
|
|
|
|
|
|
if (mFullScreen)
|
|
|
|
sFullScreenInstance = this;
|
2011-11-21 07:55:50 +00:00
|
|
|
|
|
|
|
return true;
|
2011-10-05 18:44:19 +00:00
|
|
|
}
|
|
|
|
|
2011-09-16 21:34:31 +00:00
|
|
|
void nsPluginInstanceOwner::RemovePluginView()
|
|
|
|
{
|
2012-05-30 16:10:49 +00:00
|
|
|
if (!mInstance || !mJavaView)
|
2012-05-30 15:58:50 +00:00
|
|
|
return;
|
2012-05-30 14:29:16 +00:00
|
|
|
|
2015-01-10 00:33:57 +00:00
|
|
|
widget::GeckoAppShell::RemovePluginView(
|
|
|
|
jni::Object::Ref::From(jobject(mJavaView)), mFullScreen);
|
2015-08-13 04:53:39 +00:00
|
|
|
jni::GetGeckoThreadEnv()->DeleteGlobalRef((jobject)mJavaView);
|
2012-07-30 14:20:58 +00:00
|
|
|
mJavaView = nullptr;
|
2012-05-30 16:10:49 +00:00
|
|
|
|
|
|
|
if (mFullScreen)
|
2012-07-30 14:20:58 +00:00
|
|
|
sFullScreenInstance = nullptr;
|
2012-01-31 14:40:58 +00:00
|
|
|
}
|
2012-01-29 04:16:26 +00:00
|
|
|
|
2014-09-17 13:13:29 +00:00
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::GetVideos(nsTArray<nsNPAPIPluginInstance::VideoInfo*>& aVideos)
|
2012-07-20 19:20:51 +00:00
|
|
|
{
|
|
|
|
if (!mInstance)
|
|
|
|
return;
|
|
|
|
|
|
|
|
mInstance->GetVideos(aVideos);
|
|
|
|
}
|
|
|
|
|
2014-09-17 13:13:29 +00:00
|
|
|
already_AddRefed<ImageContainer>
|
|
|
|
nsPluginInstanceOwner::GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInfo* aVideoInfo)
|
2012-07-20 19:20:51 +00:00
|
|
|
{
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<ImageContainer> container = LayerManager::CreateImageContainer();
|
2012-07-20 19:20:51 +00:00
|
|
|
|
2015-11-17 08:09:00 +00:00
|
|
|
RefPtr<Image> img = new SurfaceTextureImage(
|
|
|
|
aVideoInfo->mSurfaceTexture,
|
|
|
|
gfx::IntSize(aVideoInfo->mDimensions.width, aVideoInfo->mDimensions.height),
|
|
|
|
gl::OriginPos::BottomLeft);
|
2012-07-26 18:11:22 +00:00
|
|
|
container->SetCurrentImageInTransaction(img);
|
2012-07-20 19:20:51 +00:00
|
|
|
|
|
|
|
return container.forget();
|
|
|
|
}
|
|
|
|
|
2012-01-31 14:40:58 +00:00
|
|
|
void nsPluginInstanceOwner::Invalidate() {
|
|
|
|
NPRect rect;
|
|
|
|
rect.left = rect.top = 0;
|
|
|
|
rect.right = mPluginWindow->width;
|
|
|
|
rect.bottom = mPluginWindow->height;
|
|
|
|
InvalidateRect(&rect);
|
2011-09-16 21:34:31 +00:00
|
|
|
}
|
2012-01-31 14:40:58 +00:00
|
|
|
|
2012-05-30 16:10:49 +00:00
|
|
|
void nsPluginInstanceOwner::RequestFullScreen() {
|
|
|
|
if (mFullScreen)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Remove whatever view we currently have (if any, fullscreen or otherwise)
|
|
|
|
RemovePluginView();
|
|
|
|
|
|
|
|
mFullScreen = true;
|
|
|
|
AddPluginView();
|
|
|
|
|
|
|
|
mInstance->NotifyFullScreen(mFullScreen);
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsPluginInstanceOwner::ExitFullScreen() {
|
|
|
|
if (!mFullScreen)
|
|
|
|
return;
|
|
|
|
|
|
|
|
RemovePluginView();
|
|
|
|
|
|
|
|
mFullScreen = false;
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t model = mInstance->GetANPDrawingModel();
|
2012-05-30 16:10:49 +00:00
|
|
|
|
|
|
|
if (model == kSurface_ANPDrawingModel) {
|
2012-06-11 17:50:59 +00:00
|
|
|
// We need to do this immediately, otherwise Flash
|
|
|
|
// sometimes causes a deadlock (bug 762407)
|
|
|
|
AddPluginView(GetPluginRect());
|
2012-05-30 16:10:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mInstance->NotifyFullScreen(mFullScreen);
|
2012-06-11 17:50:59 +00:00
|
|
|
|
|
|
|
// This will cause Paint() to be called, which is where
|
|
|
|
// we normally add/update views and layers
|
|
|
|
Invalidate();
|
2012-05-30 16:10:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void nsPluginInstanceOwner::ExitFullScreen(jobject view) {
|
2015-08-13 04:53:39 +00:00
|
|
|
JNIEnv* env = jni::GetGeckoThreadEnv();
|
2012-05-30 16:10:49 +00:00
|
|
|
|
2014-01-18 05:32:24 +00:00
|
|
|
if (sFullScreenInstance && sFullScreenInstance->mInstance &&
|
2012-05-30 16:10:49 +00:00
|
|
|
env->IsSameObject(view, (jobject)sFullScreenInstance->mInstance->GetJavaSurface())) {
|
|
|
|
sFullScreenInstance->ExitFullScreen();
|
2014-01-18 05:32:24 +00:00
|
|
|
}
|
2012-05-30 16:10:49 +00:00
|
|
|
}
|
|
|
|
|
2011-09-16 21:34:31 +00:00
|
|
|
#endif
|
|
|
|
|
2014-12-29 23:12:40 +00:00
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::NotifyHostAsyncInitFailed()
|
|
|
|
{
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIObjectLoadingContent> content = do_QueryReferent(mContent);
|
2014-12-29 23:12:40 +00:00
|
|
|
content->StopPluginInstance();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::NotifyHostCreateWidget()
|
|
|
|
{
|
|
|
|
mPluginHost->CreateWidget(this);
|
|
|
|
#ifdef XP_MACOSX
|
|
|
|
FixUpPluginWindow(ePluginPaintEnable);
|
|
|
|
#else
|
|
|
|
if (mPluginFrame) {
|
|
|
|
mPluginFrame->InvalidateFrame();
|
|
|
|
} else {
|
|
|
|
CallSetWindow();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-02-27 19:59:07 +00:00
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::NotifyDestroyPending()
|
|
|
|
{
|
|
|
|
if (!mInstance) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
bool isOOP = false;
|
|
|
|
if (NS_FAILED(mInstance->GetIsOOP(&isOOP)) || !isOOP) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
NPP npp = nullptr;
|
|
|
|
if (NS_FAILED(mInstance->GetNPP(&npp)) || !npp) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
PluginAsyncSurrogate::NotifyDestroyPending(npp);
|
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
|
|
|
|
{
|
2011-11-11 00:17:46 +00:00
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
2013-04-03 22:00:45 +00:00
|
|
|
if (mInstance) {
|
2011-09-16 21:34:31 +00:00
|
|
|
ANPEvent event;
|
|
|
|
event.inSize = sizeof(ANPEvent);
|
|
|
|
event.eventType = kLifecycle_ANPEventType;
|
|
|
|
|
|
|
|
nsAutoString eventType;
|
|
|
|
aFocusEvent->GetType(eventType);
|
|
|
|
if (eventType.EqualsLiteral("focus")) {
|
|
|
|
event.data.lifecycle.action = kGainFocus_ANPLifecycleAction;
|
|
|
|
}
|
|
|
|
else if (eventType.EqualsLiteral("blur")) {
|
|
|
|
event.data.lifecycle.action = kLoseFocus_ANPLifecycleAction;
|
|
|
|
}
|
|
|
|
else {
|
2014-07-11 22:41:41 +00:00
|
|
|
NS_ASSERTION(false, "nsPluginInstanceOwner::DispatchFocusToPlugin, wierd eventType");
|
2011-09-16 21:34:31 +00:00
|
|
|
}
|
2012-07-30 14:20:58 +00:00
|
|
|
mInstance->HandleEvent(&event, nullptr);
|
2011-09-16 21:34:31 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
#ifndef XP_MACOSX
|
|
|
|
if (!mPluginWindow || (mPluginWindow->type == NPWindowTypeWindow)) {
|
|
|
|
// continue only for cases without child window
|
|
|
|
return aFocusEvent->PreventDefault(); // consume event
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-02-12 15:40:07 +00:00
|
|
|
WidgetEvent* theEvent = aFocusEvent->WidgetEventPtr();
|
2012-06-10 23:44:50 +00:00
|
|
|
if (theEvent) {
|
2016-03-17 07:01:30 +00:00
|
|
|
WidgetGUIEvent focusEvent(theEvent->IsTrusted(), theEvent->mMessage,
|
2013-10-02 03:46:03 +00:00
|
|
|
nullptr);
|
2015-12-29 16:42:02 +00:00
|
|
|
nsEventStatus rv = ProcessEvent(focusEvent);
|
|
|
|
if (nsEventStatus_eConsumeNoDefault == rv) {
|
2012-06-10 23:44:50 +00:00
|
|
|
aFocusEvent->PreventDefault();
|
2015-12-29 16:42:02 +00:00
|
|
|
aFocusEvent->StopPropagation();
|
2014-07-11 22:41:41 +00:00
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
return NS_OK;
|
2014-07-11 22:41:41 +00:00
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2012-10-03 02:43:18 +00:00
|
|
|
nsresult nsPluginInstanceOwner::ProcessKeyPress(nsIDOMEvent* aKeyEvent)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
#ifdef XP_MACOSX
|
|
|
|
return DispatchKeyToPlugin(aKeyEvent);
|
|
|
|
#else
|
|
|
|
if (SendNativeEvents())
|
|
|
|
DispatchKeyToPlugin(aKeyEvent);
|
|
|
|
|
|
|
|
if (mInstance) {
|
|
|
|
// If this event is going to the plugin, we want to kill it.
|
|
|
|
// Not actually sending keypress to the plugin, since we didn't before.
|
|
|
|
aKeyEvent->PreventDefault();
|
|
|
|
aKeyEvent->StopPropagation();
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult nsPluginInstanceOwner::DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent)
|
|
|
|
{
|
|
|
|
#if !defined(XP_MACOSX)
|
|
|
|
if (!mPluginWindow || (mPluginWindow->type == NPWindowTypeWindow))
|
|
|
|
return aKeyEvent->PreventDefault(); // consume event
|
|
|
|
// continue only for cases without child window
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (mInstance) {
|
2013-10-22 08:55:20 +00:00
|
|
|
WidgetKeyboardEvent* keyEvent =
|
2016-02-12 15:40:07 +00:00
|
|
|
aKeyEvent->WidgetEventPtr()->AsKeyboardEvent();
|
2014-08-04 05:28:48 +00:00
|
|
|
if (keyEvent && keyEvent->mClass == eKeyboardEventClass) {
|
2013-10-22 08:55:20 +00:00
|
|
|
nsEventStatus rv = ProcessEvent(*keyEvent);
|
2012-06-10 23:44:50 +00:00
|
|
|
if (nsEventStatus_eConsumeNoDefault == rv) {
|
|
|
|
aKeyEvent->PreventDefault();
|
|
|
|
aKeyEvent->StopPropagation();
|
2014-07-11 22:41:41 +00:00
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
2014-07-11 22:41:41 +00:00
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
nsresult
|
2012-10-03 02:43:18 +00:00
|
|
|
nsPluginInstanceOwner::ProcessMouseDown(nsIDOMEvent* aMouseEvent)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
#if !defined(XP_MACOSX)
|
|
|
|
if (!mPluginWindow || (mPluginWindow->type == NPWindowTypeWindow))
|
|
|
|
return aMouseEvent->PreventDefault(); // consume event
|
|
|
|
// continue only for cases without child window
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// if the plugin is windowless, we need to set focus ourselves
|
|
|
|
// otherwise, we might not get key events
|
2014-09-24 04:35:00 +00:00
|
|
|
if (mPluginFrame && mPluginWindow &&
|
2011-06-01 04:37:54 +00:00
|
|
|
mPluginWindow->type == NPWindowTypeDrawable) {
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
|
|
|
if (fm) {
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIDOMElement> elem = do_QueryReferent(mContent);
|
2011-06-01 04:37:54 +00:00
|
|
|
fm->SetFocus(elem, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-22 08:55:20 +00:00
|
|
|
WidgetMouseEvent* mouseEvent =
|
2016-02-12 15:40:07 +00:00
|
|
|
aMouseEvent->WidgetEventPtr()->AsMouseEvent();
|
2014-08-04 05:28:50 +00:00
|
|
|
if (mouseEvent && mouseEvent->mClass == eMouseEventClass) {
|
2013-10-22 08:55:20 +00:00
|
|
|
mLastMouseDownButtonType = mouseEvent->button;
|
|
|
|
nsEventStatus rv = ProcessEvent(*mouseEvent);
|
2012-06-10 23:44:50 +00:00
|
|
|
if (nsEventStatus_eConsumeNoDefault == rv) {
|
|
|
|
return aMouseEvent->PreventDefault(); // consume event
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
}
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2013-10-24 21:04:36 +00:00
|
|
|
nsresult nsPluginInstanceOwner::DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent,
|
|
|
|
bool aAllowPropagate)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
#if !defined(XP_MACOSX)
|
|
|
|
if (!mPluginWindow || (mPluginWindow->type == NPWindowTypeWindow))
|
|
|
|
return aMouseEvent->PreventDefault(); // consume event
|
|
|
|
// continue only for cases without child window
|
|
|
|
#endif
|
|
|
|
// don't send mouse events if we are hidden
|
|
|
|
if (!mWidgetVisible)
|
|
|
|
return NS_OK;
|
|
|
|
|
2013-10-22 08:55:20 +00:00
|
|
|
WidgetMouseEvent* mouseEvent =
|
2016-02-12 15:40:07 +00:00
|
|
|
aMouseEvent->WidgetEventPtr()->AsMouseEvent();
|
2014-08-04 05:28:50 +00:00
|
|
|
if (mouseEvent && mouseEvent->mClass == eMouseEventClass) {
|
2013-10-22 08:55:20 +00:00
|
|
|
nsEventStatus rv = ProcessEvent(*mouseEvent);
|
2012-06-10 23:44:50 +00:00
|
|
|
if (nsEventStatus_eConsumeNoDefault == rv) {
|
|
|
|
aMouseEvent->PreventDefault();
|
2013-10-24 21:04:36 +00:00
|
|
|
if (!aAllowPropagate) {
|
|
|
|
aMouseEvent->StopPropagation();
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
2015-08-28 23:58:30 +00:00
|
|
|
if (mouseEvent->mMessage == eMouseUp) {
|
2013-09-17 23:36:03 +00:00
|
|
|
mLastMouseDownButtonType = -1;
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2015-12-29 13:57:38 +00:00
|
|
|
#ifdef XP_WIN
|
2015-12-29 13:57:38 +00:00
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::CallDefaultProc(const WidgetGUIEvent* aEvent)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIWidget> widget = GetContainingWidgetIfOffset();
|
|
|
|
if (!widget) {
|
|
|
|
widget = GetRootWidgetForPluginFrame(mPluginFrame);
|
|
|
|
if (NS_WARN_IF(!widget)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const NPEvent* npEvent =
|
|
|
|
static_cast<const NPEvent*>(aEvent->mPluginEvent);
|
|
|
|
if (NS_WARN_IF(!npEvent)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
WidgetPluginEvent pluginEvent(true, ePluginInputEvent, widget);
|
|
|
|
pluginEvent.mPluginEvent.Copy(*npEvent);
|
|
|
|
widget->DefaultProcOfPluginEvent(pluginEvent);
|
|
|
|
}
|
|
|
|
|
2015-12-29 13:57:38 +00:00
|
|
|
already_AddRefed<TextComposition>
|
|
|
|
nsPluginInstanceOwner::GetTextComposition()
|
|
|
|
{
|
|
|
|
if (NS_WARN_IF(!mPluginFrame)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIWidget> widget = GetContainingWidgetIfOffset();
|
|
|
|
if (!widget) {
|
|
|
|
widget = GetRootWidgetForPluginFrame(mPluginFrame);
|
|
|
|
if (NS_WARN_IF(!widget)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<TextComposition> composition =
|
|
|
|
IMEStateManager::GetTextCompositionFor(widget);
|
|
|
|
if (NS_WARN_IF(!composition)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return composition.forget();
|
|
|
|
}
|
2016-01-12 08:47:38 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::HandleNoConsumedCompositionMessage(
|
|
|
|
WidgetCompositionEvent* aCompositionEvent,
|
|
|
|
const NPEvent* aPluginEvent)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIWidget> widget = GetContainingWidgetIfOffset();
|
|
|
|
if (!widget) {
|
|
|
|
widget = GetRootWidgetForPluginFrame(mPluginFrame);
|
|
|
|
if (NS_WARN_IF(!widget)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NPEvent npevent;
|
|
|
|
if (aPluginEvent->lParam & GCS_RESULTSTR) {
|
|
|
|
// GCS_RESULTSTR's default proc will generate WM_CHAR. So emulate it.
|
|
|
|
for (size_t i = 0; i < aCompositionEvent->mData.Length(); i++) {
|
|
|
|
WidgetPluginEvent charEvent(true, ePluginInputEvent, widget);
|
|
|
|
npevent.event = WM_CHAR;
|
|
|
|
npevent.wParam = aCompositionEvent->mData[i];
|
|
|
|
npevent.lParam = 0;
|
|
|
|
charEvent.mPluginEvent.Copy(npevent);
|
|
|
|
ProcessEvent(charEvent);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!mSentStartComposition) {
|
|
|
|
// We post WM_IME_COMPOSITION to default proc, but
|
|
|
|
// WM_IME_STARTCOMPOSITION isn't post yet. We should post it at first.
|
|
|
|
WidgetPluginEvent startEvent(true, ePluginInputEvent, widget);
|
|
|
|
npevent.event = WM_IME_STARTCOMPOSITION;
|
|
|
|
npevent.wParam = 0;
|
|
|
|
npevent.lParam = 0;
|
|
|
|
startEvent.mPluginEvent.Copy(npevent);
|
|
|
|
CallDefaultProc(&startEvent);
|
|
|
|
mSentStartComposition = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
CallDefaultProc(aCompositionEvent);
|
|
|
|
}
|
2015-12-29 13:57:38 +00:00
|
|
|
#endif
|
|
|
|
|
2015-12-29 13:57:37 +00:00
|
|
|
nsresult
|
|
|
|
nsPluginInstanceOwner::DispatchCompositionToPlugin(nsIDOMEvent* aEvent)
|
|
|
|
{
|
|
|
|
#ifdef XP_WIN
|
|
|
|
if (!mPluginWindow) {
|
|
|
|
// CompositionEvent isn't cancellable. So it is unnecessary to call
|
|
|
|
// PreventDefaults() to consume event
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
WidgetCompositionEvent* compositionEvent =
|
2016-02-12 15:40:07 +00:00
|
|
|
aEvent->WidgetEventPtr()->AsCompositionEvent();
|
2015-12-29 13:57:37 +00:00
|
|
|
if (NS_WARN_IF(!compositionEvent)) {
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
2015-12-29 13:57:38 +00:00
|
|
|
|
|
|
|
if (compositionEvent->mMessage == eCompositionChange) {
|
|
|
|
RefPtr<TextComposition> composition = GetTextComposition();
|
|
|
|
if (NS_WARN_IF(!composition)) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
TextComposition::CompositionChangeEventHandlingMarker
|
|
|
|
compositionChangeEventHandlingMarker(composition, compositionEvent);
|
|
|
|
}
|
|
|
|
|
2016-01-12 08:47:38 +00:00
|
|
|
const NPEvent* pPluginEvent =
|
|
|
|
static_cast<const NPEvent*>(compositionEvent->mPluginEvent);
|
|
|
|
if (pPluginEvent && pPluginEvent->event == WM_IME_COMPOSITION &&
|
|
|
|
mPluginDidNotHandleIMEComposition) {
|
|
|
|
// This is a workaround when running windowed and windowless Flash on
|
|
|
|
// same process.
|
|
|
|
// Flash with protected mode calls IMM APIs on own render process. This
|
|
|
|
// is a bug of Flash's protected mode.
|
|
|
|
// ImmGetCompositionString with GCS_RESULTSTR returns *LAST* committed
|
|
|
|
// string. So when windowed mode Flash handles IME composition,
|
|
|
|
// windowless plugin can get windowed mode's commited string by that API.
|
|
|
|
// So we never post WM_IME_COMPOSITION when plugin doesn't call
|
|
|
|
// ImmGetCompositionString() during WM_IME_COMPOSITION correctly.
|
|
|
|
HandleNoConsumedCompositionMessage(compositionEvent, pPluginEvent);
|
|
|
|
aEvent->StopImmediatePropagation();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2015-12-29 13:57:38 +00:00
|
|
|
// Protected mode Flash returns noDefault by NPP_HandleEvent, but
|
|
|
|
// composition information into plugin is invalid because plugin's bug.
|
|
|
|
// So if plugin doesn't get composition data by WM_IME_COMPOSITION, we
|
|
|
|
// recongnize it isn't handled
|
|
|
|
AutoRestore<bool> restore(mGotCompositionData);
|
|
|
|
mGotCompositionData = false;
|
|
|
|
|
|
|
|
nsEventStatus status = ProcessEvent(*compositionEvent);
|
|
|
|
aEvent->StopImmediatePropagation();
|
|
|
|
|
|
|
|
// Composition event isn't handled by plugin, so we have to call default proc.
|
2016-01-12 08:47:38 +00:00
|
|
|
|
2015-12-29 13:57:38 +00:00
|
|
|
if (NS_WARN_IF(!pPluginEvent)) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pPluginEvent->event == WM_IME_STARTCOMPOSITION) {
|
|
|
|
// Flash's protected mode lies that composition event is handled, but it
|
|
|
|
// cannot do it well. So even if handled, we should post this message when
|
|
|
|
// no IMM API calls during WM_IME_COMPOSITION.
|
|
|
|
if (nsEventStatus_eConsumeNoDefault != status) {
|
|
|
|
CallDefaultProc(compositionEvent);
|
|
|
|
mSentStartComposition = true;
|
|
|
|
} else {
|
|
|
|
mSentStartComposition = false;
|
|
|
|
}
|
2016-01-12 08:47:38 +00:00
|
|
|
mPluginDidNotHandleIMEComposition = false;
|
2015-12-29 13:57:38 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pPluginEvent->event == WM_IME_ENDCOMPOSITION) {
|
|
|
|
// Always post WM_END_COMPOSITION to default proc. Because Flash may lie
|
|
|
|
// that it doesn't handle composition well, but event is handled.
|
|
|
|
// Even if posting this message, default proc do nothing if unnecessary.
|
|
|
|
CallDefaultProc(compositionEvent);
|
|
|
|
return NS_OK;
|
2015-12-29 13:57:37 +00:00
|
|
|
}
|
2015-12-29 13:57:38 +00:00
|
|
|
|
|
|
|
if (pPluginEvent->event == WM_IME_COMPOSITION && !mGotCompositionData) {
|
2016-01-12 08:47:38 +00:00
|
|
|
// If plugin doesn't handle WM_IME_COMPOSITION correctly, we don't send
|
|
|
|
// composition event until end composition.
|
|
|
|
mPluginDidNotHandleIMEComposition = true;
|
2015-12-29 13:57:38 +00:00
|
|
|
|
2016-01-12 08:47:38 +00:00
|
|
|
HandleNoConsumedCompositionMessage(compositionEvent, pPluginEvent);
|
2015-12-29 13:57:38 +00:00
|
|
|
}
|
|
|
|
#endif // #ifdef XP_WIN
|
2015-12-29 13:57:37 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
nsresult
|
|
|
|
nsPluginInstanceOwner::HandleEvent(nsIDOMEvent* aEvent)
|
|
|
|
{
|
2013-04-03 22:00:45 +00:00
|
|
|
NS_ASSERTION(mInstance, "Should have a valid plugin instance or not receive events.");
|
|
|
|
|
2011-08-08 18:26:22 +00:00
|
|
|
nsAutoString eventType;
|
|
|
|
aEvent->GetType(eventType);
|
2014-12-11 14:44:07 +00:00
|
|
|
|
|
|
|
#ifdef XP_MACOSX
|
|
|
|
if (eventType.EqualsLiteral("activate") ||
|
|
|
|
eventType.EqualsLiteral("deactivate")) {
|
|
|
|
WindowFocusMayHaveChanged();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
if (eventType.EqualsLiteral("MozPerformDelayedBlur")) {
|
|
|
|
if (mShouldBlurOnActivate) {
|
2015-09-02 06:08:00 +00:00
|
|
|
WidgetGUIEvent blurEvent(true, eBlur, nullptr);
|
2014-12-11 14:44:07 +00:00
|
|
|
ProcessEvent(blurEvent);
|
|
|
|
mShouldBlurOnActivate = false;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-08-08 18:26:22 +00:00
|
|
|
if (eventType.EqualsLiteral("focus")) {
|
2011-09-30 06:02:59 +00:00
|
|
|
mContentFocused = true;
|
2011-08-08 18:26:22 +00:00
|
|
|
return DispatchFocusToPlugin(aEvent);
|
|
|
|
}
|
|
|
|
if (eventType.EqualsLiteral("blur")) {
|
2011-09-30 06:02:59 +00:00
|
|
|
mContentFocused = false;
|
2011-08-08 18:26:22 +00:00
|
|
|
return DispatchFocusToPlugin(aEvent);
|
|
|
|
}
|
|
|
|
if (eventType.EqualsLiteral("mousedown")) {
|
2012-10-03 02:43:18 +00:00
|
|
|
return ProcessMouseDown(aEvent);
|
2011-08-08 18:26:22 +00:00
|
|
|
}
|
|
|
|
if (eventType.EqualsLiteral("mouseup")) {
|
|
|
|
return DispatchMouseToPlugin(aEvent);
|
|
|
|
}
|
2013-10-24 21:04:36 +00:00
|
|
|
if (eventType.EqualsLiteral("mousemove")) {
|
|
|
|
return DispatchMouseToPlugin(aEvent, true);
|
|
|
|
}
|
|
|
|
if (eventType.EqualsLiteral("click") ||
|
2011-08-08 18:26:22 +00:00
|
|
|
eventType.EqualsLiteral("dblclick") ||
|
|
|
|
eventType.EqualsLiteral("mouseover") ||
|
|
|
|
eventType.EqualsLiteral("mouseout")) {
|
|
|
|
return DispatchMouseToPlugin(aEvent);
|
|
|
|
}
|
|
|
|
if (eventType.EqualsLiteral("keydown") ||
|
|
|
|
eventType.EqualsLiteral("keyup")) {
|
|
|
|
return DispatchKeyToPlugin(aEvent);
|
|
|
|
}
|
|
|
|
if (eventType.EqualsLiteral("keypress")) {
|
2012-10-03 02:43:18 +00:00
|
|
|
return ProcessKeyPress(aEvent);
|
2011-08-08 18:26:22 +00:00
|
|
|
}
|
2015-12-29 13:57:37 +00:00
|
|
|
if (eventType.EqualsLiteral("compositionstart") ||
|
|
|
|
eventType.EqualsLiteral("compositionend") ||
|
|
|
|
eventType.EqualsLiteral("text")) {
|
|
|
|
return DispatchCompositionToPlugin(aEvent);
|
|
|
|
}
|
2011-08-08 18:26:22 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMDragEvent> dragEvent(do_QueryInterface(aEvent));
|
|
|
|
if (dragEvent && mInstance) {
|
2016-02-12 15:40:07 +00:00
|
|
|
WidgetEvent* ievent = aEvent->WidgetEventPtr();
|
2016-03-17 07:01:30 +00:00
|
|
|
if (ievent && ievent->IsTrusted() &&
|
2015-09-02 06:08:02 +00:00
|
|
|
ievent->mMessage != eDragEnter && ievent->mMessage != eDragOver) {
|
2012-06-10 23:44:50 +00:00
|
|
|
aEvent->PreventDefault();
|
2012-06-10 23:37:47 +00:00
|
|
|
}
|
2012-06-10 23:44:50 +00:00
|
|
|
|
|
|
|
// Let the plugin handle drag events.
|
|
|
|
aEvent->StopPropagation();
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef MOZ_X11
|
2013-10-01 07:23:02 +00:00
|
|
|
static unsigned int XInputEventState(const WidgetInputEvent& anEvent)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
unsigned int state = 0;
|
2012-04-25 03:00:02 +00:00
|
|
|
if (anEvent.IsShift()) state |= ShiftMask;
|
|
|
|
if (anEvent.IsControl()) state |= ControlMask;
|
|
|
|
if (anEvent.IsAlt()) state |= Mod1Mask;
|
|
|
|
if (anEvent.IsMeta()) state |= Mod4Mask;
|
2011-06-01 04:37:54 +00:00
|
|
|
return state;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
#ifdef XP_MACOSX
|
|
|
|
|
|
|
|
// Returns whether or not content is the content that is or would be
|
|
|
|
// focused if the top-level chrome window was active.
|
|
|
|
static bool
|
|
|
|
ContentIsFocusedWithinWindow(nsIContent* aContent)
|
|
|
|
{
|
2016-01-30 17:05:36 +00:00
|
|
|
nsPIDOMWindowOuter* outerWindow = aContent->OwnerDoc()->GetWindow();
|
2014-12-11 14:44:07 +00:00
|
|
|
if (!outerWindow) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-01-30 17:05:36 +00:00
|
|
|
nsPIDOMWindowOuter* rootWindow = outerWindow->GetPrivateRoot();
|
2014-12-11 14:44:07 +00:00
|
|
|
if (!rootWindow) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
|
|
|
if (!fm) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-01-30 17:05:36 +00:00
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> focusedFrame;
|
2014-12-11 14:44:07 +00:00
|
|
|
nsCOMPtr<nsIContent> focusedContent = fm->GetFocusedDescendant(rootWindow, true, getter_AddRefs(focusedFrame));
|
|
|
|
return (focusedContent.get() == aContent);
|
|
|
|
}
|
|
|
|
|
|
|
|
static NPCocoaEventType
|
|
|
|
CocoaEventTypeForEvent(const WidgetGUIEvent& anEvent, nsIFrame* aObjectFrame)
|
|
|
|
{
|
|
|
|
const NPCocoaEvent* event = static_cast<const NPCocoaEvent*>(anEvent.mPluginEvent);
|
|
|
|
if (event) {
|
|
|
|
return event->type;
|
|
|
|
}
|
|
|
|
|
2015-08-22 01:34:51 +00:00
|
|
|
switch (anEvent.mMessage) {
|
2015-08-28 23:58:32 +00:00
|
|
|
case eMouseOver:
|
2014-12-11 14:44:07 +00:00
|
|
|
return NPCocoaEventMouseEntered;
|
2015-08-28 23:58:32 +00:00
|
|
|
case eMouseOut:
|
2014-12-11 14:44:07 +00:00
|
|
|
return NPCocoaEventMouseExited;
|
2015-08-28 23:58:29 +00:00
|
|
|
case eMouseMove: {
|
2014-12-11 14:44:07 +00:00
|
|
|
// We don't know via information on events from the widget code whether or not
|
|
|
|
// we're dragging. The widget code just generates mouse move events from native
|
|
|
|
// drag events. If anybody is capturing, this is a drag event.
|
|
|
|
if (nsIPresShell::GetCapturingContent()) {
|
|
|
|
return NPCocoaEventMouseDragged;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NPCocoaEventMouseMoved;
|
|
|
|
}
|
2015-08-28 23:58:30 +00:00
|
|
|
case eMouseDown:
|
2014-12-11 14:44:07 +00:00
|
|
|
return NPCocoaEventMouseDown;
|
2015-08-28 23:58:30 +00:00
|
|
|
case eMouseUp:
|
2014-12-11 14:44:07 +00:00
|
|
|
return NPCocoaEventMouseUp;
|
2015-08-28 23:58:27 +00:00
|
|
|
case eKeyDown:
|
2014-12-11 14:44:07 +00:00
|
|
|
return NPCocoaEventKeyDown;
|
2015-08-28 23:58:27 +00:00
|
|
|
case eKeyUp:
|
2014-12-11 14:44:07 +00:00
|
|
|
return NPCocoaEventKeyUp;
|
2015-09-02 06:08:00 +00:00
|
|
|
case eFocus:
|
2015-09-02 06:08:00 +00:00
|
|
|
case eBlur:
|
2014-12-11 14:44:07 +00:00
|
|
|
return NPCocoaEventFocusChanged;
|
2015-09-10 01:40:04 +00:00
|
|
|
case eLegacyMouseLineOrPageScroll:
|
2014-12-11 14:44:07 +00:00
|
|
|
return NPCocoaEventScrollWheel;
|
|
|
|
default:
|
|
|
|
return (NPCocoaEventType)0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static NPCocoaEvent
|
|
|
|
TranslateToNPCocoaEvent(WidgetGUIEvent* anEvent, nsIFrame* aObjectFrame)
|
|
|
|
{
|
|
|
|
NPCocoaEvent cocoaEvent;
|
|
|
|
InitializeNPCocoaEvent(&cocoaEvent);
|
|
|
|
cocoaEvent.type = CocoaEventTypeForEvent(*anEvent, aObjectFrame);
|
|
|
|
|
2015-08-28 23:58:29 +00:00
|
|
|
if (anEvent->mMessage == eMouseMove ||
|
2015-08-28 23:58:30 +00:00
|
|
|
anEvent->mMessage == eMouseDown ||
|
2015-08-28 23:58:30 +00:00
|
|
|
anEvent->mMessage == eMouseUp ||
|
2015-09-10 01:40:04 +00:00
|
|
|
anEvent->mMessage == eLegacyMouseLineOrPageScroll ||
|
2015-08-28 23:58:32 +00:00
|
|
|
anEvent->mMessage == eMouseOver ||
|
2015-08-28 23:58:32 +00:00
|
|
|
anEvent->mMessage == eMouseOut)
|
2014-12-11 14:44:07 +00:00
|
|
|
{
|
|
|
|
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(anEvent, aObjectFrame) -
|
|
|
|
aObjectFrame->GetContentRectRelativeToSelf().TopLeft();
|
|
|
|
nsPresContext* presContext = aObjectFrame->PresContext();
|
|
|
|
// Plugin event coordinates need to be translated from device pixels
|
|
|
|
// into "display pixels" in HiDPI modes.
|
|
|
|
double scaleFactor = double(nsPresContext::AppUnitsPerCSSPixel())/
|
|
|
|
aObjectFrame->PresContext()->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom();
|
|
|
|
size_t intScaleFactor = ceil(scaleFactor);
|
|
|
|
nsIntPoint ptPx(presContext->AppUnitsToDevPixels(pt.x) / intScaleFactor,
|
|
|
|
presContext->AppUnitsToDevPixels(pt.y) / intScaleFactor);
|
|
|
|
cocoaEvent.data.mouse.pluginX = double(ptPx.x);
|
|
|
|
cocoaEvent.data.mouse.pluginY = double(ptPx.y);
|
|
|
|
}
|
|
|
|
|
2015-08-22 01:34:51 +00:00
|
|
|
switch (anEvent->mMessage) {
|
2015-08-28 23:58:30 +00:00
|
|
|
case eMouseDown:
|
2015-08-28 23:58:30 +00:00
|
|
|
case eMouseUp: {
|
2014-12-11 14:44:07 +00:00
|
|
|
WidgetMouseEvent* mouseEvent = anEvent->AsMouseEvent();
|
|
|
|
if (mouseEvent) {
|
|
|
|
switch (mouseEvent->button) {
|
|
|
|
case WidgetMouseEvent::eLeftButton:
|
|
|
|
cocoaEvent.data.mouse.buttonNumber = 0;
|
|
|
|
break;
|
|
|
|
case WidgetMouseEvent::eRightButton:
|
|
|
|
cocoaEvent.data.mouse.buttonNumber = 1;
|
|
|
|
break;
|
|
|
|
case WidgetMouseEvent::eMiddleButton:
|
|
|
|
cocoaEvent.data.mouse.buttonNumber = 2;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
NS_WARNING("Mouse button we don't know about?");
|
|
|
|
}
|
2016-05-10 14:29:14 +00:00
|
|
|
cocoaEvent.data.mouse.clickCount = mouseEvent->mClickCount;
|
2014-12-11 14:44:07 +00:00
|
|
|
} else {
|
2015-08-28 23:58:30 +00:00
|
|
|
NS_WARNING("eMouseUp/DOWN is not a WidgetMouseEvent?");
|
2014-12-11 14:44:07 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2015-09-10 01:40:04 +00:00
|
|
|
case eLegacyMouseLineOrPageScroll: {
|
2014-12-11 14:44:07 +00:00
|
|
|
WidgetWheelEvent* wheelEvent = anEvent->AsWheelEvent();
|
|
|
|
if (wheelEvent) {
|
2016-03-31 15:10:46 +00:00
|
|
|
cocoaEvent.data.mouse.deltaX = wheelEvent->mLineOrPageDeltaX;
|
2016-03-31 15:10:09 +00:00
|
|
|
cocoaEvent.data.mouse.deltaY = wheelEvent->mLineOrPageDeltaY;
|
2014-12-11 14:44:07 +00:00
|
|
|
} else {
|
2015-09-10 01:40:04 +00:00
|
|
|
NS_WARNING("eLegacyMouseLineOrPageScroll is not a WidgetWheelEvent? "
|
|
|
|
"(could be, haven't checked)");
|
2014-12-11 14:44:07 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2015-08-28 23:58:27 +00:00
|
|
|
case eKeyDown:
|
2015-08-28 23:58:27 +00:00
|
|
|
case eKeyUp:
|
2014-12-11 14:44:07 +00:00
|
|
|
{
|
|
|
|
WidgetKeyboardEvent* keyEvent = anEvent->AsKeyboardEvent();
|
|
|
|
|
2015-02-20 16:37:02 +00:00
|
|
|
// That keyEvent->mPluginTextEventString is non-empty is a signal that we should
|
|
|
|
// create a text event for the plugin, instead of a key event.
|
2015-08-28 23:58:27 +00:00
|
|
|
if (anEvent->mMessage == eKeyDown &&
|
2015-08-22 01:34:51 +00:00
|
|
|
!keyEvent->mPluginTextEventString.IsEmpty()) {
|
2015-02-20 16:37:02 +00:00
|
|
|
cocoaEvent.type = NPCocoaEventTextInput;
|
|
|
|
const char16_t* pluginTextEventString = keyEvent->mPluginTextEventString.get();
|
|
|
|
cocoaEvent.data.text.text = (NPNSString*)
|
|
|
|
::CFStringCreateWithCharacters(NULL,
|
|
|
|
reinterpret_cast<const UniChar*>(pluginTextEventString),
|
|
|
|
keyEvent->mPluginTextEventString.Length());
|
|
|
|
} else {
|
|
|
|
cocoaEvent.data.key.keyCode = keyEvent->mNativeKeyCode;
|
|
|
|
cocoaEvent.data.key.isARepeat = keyEvent->mIsRepeat;
|
|
|
|
cocoaEvent.data.key.modifierFlags = keyEvent->mNativeModifierFlags;
|
|
|
|
const char16_t* nativeChars = keyEvent->mNativeCharacters.get();
|
|
|
|
cocoaEvent.data.key.characters = (NPNSString*)
|
|
|
|
::CFStringCreateWithCharacters(NULL,
|
|
|
|
reinterpret_cast<const UniChar*>(nativeChars),
|
|
|
|
keyEvent->mNativeCharacters.Length());
|
|
|
|
const char16_t* nativeCharsIgnoringModifiers = keyEvent->mNativeCharactersIgnoringModifiers.get();
|
|
|
|
cocoaEvent.data.key.charactersIgnoringModifiers = (NPNSString*)
|
|
|
|
::CFStringCreateWithCharacters(NULL,
|
|
|
|
reinterpret_cast<const UniChar*>(nativeCharsIgnoringModifiers),
|
|
|
|
keyEvent->mNativeCharactersIgnoringModifiers.Length());
|
|
|
|
}
|
2014-12-11 14:44:07 +00:00
|
|
|
break;
|
|
|
|
}
|
2015-09-02 06:08:00 +00:00
|
|
|
case eFocus:
|
2015-09-02 06:08:00 +00:00
|
|
|
case eBlur:
|
2015-09-02 06:08:00 +00:00
|
|
|
cocoaEvent.data.focus.hasFocus = (anEvent->mMessage == eFocus);
|
2014-12-11 14:44:07 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return cocoaEvent;
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsPluginInstanceOwner::PerformDelayedBlurs()
|
|
|
|
{
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
|
|
|
|
nsCOMPtr<EventTarget> windowRoot = content->OwnerDoc()->GetWindow()->GetTopWindowRoot();
|
|
|
|
nsContentUtils::DispatchTrustedEvent(content->OwnerDoc(),
|
2014-12-11 14:44:07 +00:00
|
|
|
windowRoot,
|
|
|
|
NS_LITERAL_STRING("MozPerformDelayedBlur"),
|
|
|
|
false, false, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2013-10-02 03:46:03 +00:00
|
|
|
nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
nsEventStatus rv = nsEventStatus_eIgnore;
|
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
if (!mInstance || !mPluginFrame) {
|
2011-06-01 04:37:54 +00:00
|
|
|
return nsEventStatus_eIgnore;
|
2014-12-11 14:44:07 +00:00
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
#ifdef XP_MACOSX
|
2014-12-11 14:44:07 +00:00
|
|
|
NPEventModel eventModel = GetEventModel();
|
|
|
|
if (eventModel != NPEventModelCocoa) {
|
2011-06-01 04:37:54 +00:00
|
|
|
return nsEventStatus_eIgnore;
|
2014-12-11 14:44:07 +00:00
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
// In the Cocoa event model, focus is per-window. Don't tell a plugin it lost
|
|
|
|
// focus unless it lost focus within the window. For example, ignore a blur
|
|
|
|
// event if it's coming due to the plugin's window deactivating.
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
|
2015-09-02 06:08:00 +00:00
|
|
|
if (anEvent.mMessage == eBlur && ContentIsFocusedWithinWindow(content)) {
|
2014-12-11 14:44:07 +00:00
|
|
|
mShouldBlurOnActivate = true;
|
2011-06-01 04:37:54 +00:00
|
|
|
return nsEventStatus_eIgnore;
|
2014-12-11 14:44:07 +00:00
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
// Also, don't tell the plugin it gained focus again after we've already given
|
|
|
|
// it focus. This might happen if it has focus, its window is blurred, then the
|
|
|
|
// window is made active again. The plugin never lost in-window focus, so it
|
|
|
|
// shouldn't get a focus event again.
|
2015-09-02 06:08:00 +00:00
|
|
|
if (anEvent.mMessage == eFocus && mLastContentFocused == true) {
|
2014-12-11 14:44:07 +00:00
|
|
|
mShouldBlurOnActivate = false;
|
2011-06-01 04:37:54 +00:00
|
|
|
return nsEventStatus_eIgnore;
|
2014-12-11 14:44:07 +00:00
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
// Now, if we're going to send a focus event, update mLastContentFocused and
|
|
|
|
// tell any plugins in our window that we have taken focus, so they should
|
|
|
|
// perform any delayed blurs.
|
2015-09-02 06:08:00 +00:00
|
|
|
if (anEvent.mMessage == eFocus || anEvent.mMessage == eBlur) {
|
2015-09-02 06:08:00 +00:00
|
|
|
mLastContentFocused = (anEvent.mMessage == eFocus);
|
2014-12-11 14:44:07 +00:00
|
|
|
mShouldBlurOnActivate = false;
|
|
|
|
PerformDelayedBlurs();
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
NPCocoaEvent cocoaEvent = TranslateToNPCocoaEvent(const_cast<WidgetGUIEvent*>(&anEvent), mPluginFrame);
|
|
|
|
if (cocoaEvent.type == (NPCocoaEventType)0) {
|
|
|
|
return nsEventStatus_eIgnore;
|
|
|
|
}
|
2012-10-15 12:38:34 +00:00
|
|
|
|
2015-02-20 16:37:02 +00:00
|
|
|
if (cocoaEvent.type == NPCocoaEventTextInput) {
|
|
|
|
mInstance->HandleEvent(&cocoaEvent, nullptr);
|
|
|
|
return nsEventStatus_eConsumeNoDefault;
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2015-02-20 16:37:02 +00:00
|
|
|
int16_t response = kNPEventNotHandled;
|
|
|
|
mInstance->HandleEvent(&cocoaEvent,
|
|
|
|
&response,
|
|
|
|
NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
|
|
|
|
if ((response == kNPEventStartIME) && (cocoaEvent.type == NPCocoaEventKeyDown)) {
|
|
|
|
nsIWidget* widget = mPluginFrame->GetNearestWidget();
|
|
|
|
if (widget) {
|
|
|
|
const WidgetKeyboardEvent* keyEvent = anEvent.AsKeyboardEvent();
|
|
|
|
double screenX, screenY;
|
|
|
|
ConvertPoint(0.0, mPluginFrame->GetScreenRect().height,
|
|
|
|
NPCoordinateSpacePlugin, &screenX, &screenY,
|
|
|
|
NPCoordinateSpaceScreen);
|
|
|
|
nsAutoString outText;
|
|
|
|
if (NS_SUCCEEDED(widget->StartPluginIME(*keyEvent, screenX, screenY, outText)) &&
|
|
|
|
!outText.IsEmpty()) {
|
|
|
|
CFStringRef cfString =
|
|
|
|
::CFStringCreateWithCharacters(kCFAllocatorDefault,
|
|
|
|
reinterpret_cast<const UniChar*>(outText.get()),
|
|
|
|
outText.Length());
|
2014-12-11 14:44:07 +00:00
|
|
|
NPCocoaEvent textEvent;
|
|
|
|
InitializeNPCocoaEvent(&textEvent);
|
|
|
|
textEvent.type = NPCocoaEventTextInput;
|
|
|
|
textEvent.data.text.text = (NPNSString*)cfString;
|
|
|
|
mInstance->HandleEvent(&textEvent, nullptr);
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
bool handled = (response == kNPEventHandled || response == kNPEventStartIME);
|
2015-08-28 23:58:30 +00:00
|
|
|
bool leftMouseButtonDown = (anEvent.mMessage == eMouseDown) &&
|
2014-12-11 14:44:07 +00:00
|
|
|
(anEvent.AsMouseEvent()->button == WidgetMouseEvent::eLeftButton);
|
|
|
|
if (handled && !(leftMouseButtonDown && !mContentFocused)) {
|
2011-06-01 04:37:54 +00:00
|
|
|
rv = nsEventStatus_eConsumeNoDefault;
|
2013-10-22 08:55:20 +00:00
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef XP_WIN
|
|
|
|
// this code supports windowless plugins
|
2014-07-23 19:55:51 +00:00
|
|
|
const NPEvent *pPluginEvent = static_cast<const NPEvent*>(anEvent.mPluginEvent);
|
2014-04-01 04:09:23 +00:00
|
|
|
// we can get synthetic events from the EventStateManager... these
|
2011-06-01 04:37:54 +00:00
|
|
|
// have no pluginEvent
|
|
|
|
NPEvent pluginEvent;
|
2015-10-16 04:19:27 +00:00
|
|
|
if (anEvent.mClass == eMouseEventClass ||
|
|
|
|
anEvent.mClass == eWheelEventClass) {
|
2011-06-01 04:37:54 +00:00
|
|
|
if (!pPluginEvent) {
|
|
|
|
// XXX Should extend this list to synthesize events for more event
|
|
|
|
// types
|
|
|
|
pluginEvent.event = 0;
|
2015-10-16 04:19:27 +00:00
|
|
|
bool initWParamWithCurrentState = true;
|
2015-08-22 01:34:51 +00:00
|
|
|
switch (anEvent.mMessage) {
|
2015-10-16 04:19:27 +00:00
|
|
|
case eMouseMove: {
|
2011-06-01 04:37:54 +00:00
|
|
|
pluginEvent.event = WM_MOUSEMOVE;
|
|
|
|
break;
|
2015-10-16 04:19:27 +00:00
|
|
|
}
|
2015-08-28 23:58:30 +00:00
|
|
|
case eMouseDown: {
|
2011-06-01 04:37:54 +00:00
|
|
|
static const int downMsgs[] =
|
|
|
|
{ WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN };
|
|
|
|
static const int dblClickMsgs[] =
|
|
|
|
{ WM_LBUTTONDBLCLK, WM_MBUTTONDBLCLK, WM_RBUTTONDBLCLK };
|
2015-10-16 04:19:27 +00:00
|
|
|
const WidgetMouseEvent* mouseEvent = anEvent.AsMouseEvent();
|
2016-05-10 14:29:14 +00:00
|
|
|
if (mouseEvent->mClickCount == 2) {
|
2011-06-01 04:37:54 +00:00
|
|
|
pluginEvent.event = dblClickMsgs[mouseEvent->button];
|
|
|
|
} else {
|
|
|
|
pluginEvent.event = downMsgs[mouseEvent->button];
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2015-08-28 23:58:30 +00:00
|
|
|
case eMouseUp: {
|
2011-06-01 04:37:54 +00:00
|
|
|
static const int upMsgs[] =
|
|
|
|
{ WM_LBUTTONUP, WM_MBUTTONUP, WM_RBUTTONUP };
|
2015-10-16 04:19:27 +00:00
|
|
|
const WidgetMouseEvent* mouseEvent = anEvent.AsMouseEvent();
|
2011-06-01 04:37:54 +00:00
|
|
|
pluginEvent.event = upMsgs[mouseEvent->button];
|
|
|
|
break;
|
|
|
|
}
|
2015-10-16 04:19:27 +00:00
|
|
|
// For plugins which don't support high-resolution scroll, we should
|
|
|
|
// generate legacy resolution wheel messages. I.e., the delta value
|
|
|
|
// should be WHEEL_DELTA * n.
|
|
|
|
case eWheel: {
|
|
|
|
const WidgetWheelEvent* wheelEvent = anEvent.AsWheelEvent();
|
|
|
|
int32_t delta = 0;
|
2016-03-31 15:10:09 +00:00
|
|
|
if (wheelEvent->mLineOrPageDeltaY) {
|
2016-03-31 09:35:24 +00:00
|
|
|
switch (wheelEvent->mDeltaMode) {
|
2015-10-16 04:19:27 +00:00
|
|
|
case nsIDOMWheelEvent::DOM_DELTA_PAGE:
|
|
|
|
pluginEvent.event = WM_MOUSEWHEEL;
|
2016-03-31 15:10:09 +00:00
|
|
|
delta = -WHEEL_DELTA * wheelEvent->mLineOrPageDeltaY;
|
2015-10-16 04:19:27 +00:00
|
|
|
break;
|
|
|
|
case nsIDOMWheelEvent::DOM_DELTA_LINE: {
|
|
|
|
UINT linesPerWheelDelta = 0;
|
|
|
|
if (NS_WARN_IF(!::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0,
|
|
|
|
&linesPerWheelDelta, 0))) {
|
|
|
|
// Use system default scroll amount, 3, when
|
|
|
|
// SPI_GETWHEELSCROLLLINES isn't available.
|
|
|
|
linesPerWheelDelta = 3;
|
|
|
|
}
|
|
|
|
if (!linesPerWheelDelta) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
pluginEvent.event = WM_MOUSEWHEEL;
|
2016-03-31 15:10:09 +00:00
|
|
|
delta = -WHEEL_DELTA / linesPerWheelDelta;
|
|
|
|
delta *= wheelEvent->mLineOrPageDeltaY;
|
2015-10-16 04:19:27 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case nsIDOMWheelEvent::DOM_DELTA_PIXEL:
|
|
|
|
default:
|
|
|
|
// We don't support WM_GESTURE with this path.
|
|
|
|
MOZ_ASSERT(!pluginEvent.event);
|
|
|
|
break;
|
|
|
|
}
|
2016-03-31 15:10:46 +00:00
|
|
|
} else if (wheelEvent->mLineOrPageDeltaX) {
|
2016-03-31 09:35:24 +00:00
|
|
|
switch (wheelEvent->mDeltaMode) {
|
2015-10-16 04:19:27 +00:00
|
|
|
case nsIDOMWheelEvent::DOM_DELTA_PAGE:
|
|
|
|
pluginEvent.event = WM_MOUSEHWHEEL;
|
2016-03-31 15:10:46 +00:00
|
|
|
delta = -WHEEL_DELTA * wheelEvent->mLineOrPageDeltaX;
|
2015-10-16 04:19:27 +00:00
|
|
|
break;
|
|
|
|
case nsIDOMWheelEvent::DOM_DELTA_LINE: {
|
|
|
|
pluginEvent.event = WM_MOUSEHWHEEL;
|
|
|
|
UINT charsPerWheelDelta = 0;
|
|
|
|
// FYI: SPI_GETWHEELSCROLLCHARS is available on Vista or later.
|
|
|
|
if (::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0,
|
|
|
|
&charsPerWheelDelta, 0)) {
|
|
|
|
// Use system default scroll amount, 3, when
|
|
|
|
// SPI_GETWHEELSCROLLCHARS isn't available.
|
|
|
|
charsPerWheelDelta = 3;
|
|
|
|
}
|
|
|
|
if (!charsPerWheelDelta) {
|
|
|
|
break;
|
|
|
|
}
|
2016-03-31 15:10:46 +00:00
|
|
|
delta = WHEEL_DELTA / charsPerWheelDelta;
|
|
|
|
delta *= wheelEvent->mLineOrPageDeltaX;
|
2015-10-16 04:19:27 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case nsIDOMWheelEvent::DOM_DELTA_PIXEL:
|
|
|
|
default:
|
|
|
|
// We don't support WM_GESTURE with this path.
|
|
|
|
MOZ_ASSERT(!pluginEvent.event);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!pluginEvent.event) {
|
2015-10-16 04:19:27 +00:00
|
|
|
break;
|
|
|
|
}
|
2015-10-16 04:19:27 +00:00
|
|
|
|
2015-10-16 04:19:27 +00:00
|
|
|
initWParamWithCurrentState = false;
|
|
|
|
int32_t modifiers =
|
|
|
|
(wheelEvent->IsControl() ? MK_CONTROL : 0) |
|
|
|
|
(wheelEvent->IsShift() ? MK_SHIFT : 0) |
|
|
|
|
(wheelEvent->IsLeftButtonPressed() ? MK_LBUTTON : 0) |
|
|
|
|
(wheelEvent->IsMiddleButtonPressed() ? MK_MBUTTON : 0) |
|
|
|
|
(wheelEvent->IsRightButtonPressed() ? MK_RBUTTON : 0) |
|
|
|
|
(wheelEvent->Is4thButtonPressed() ? MK_XBUTTON1 : 0) |
|
|
|
|
(wheelEvent->Is5thButtonPressed() ? MK_XBUTTON2 : 0);
|
|
|
|
pluginEvent.wParam = MAKEWPARAM(modifiers, delta);
|
|
|
|
pPluginEvent = &pluginEvent;
|
|
|
|
break;
|
|
|
|
}
|
2015-08-28 23:58:31 +00:00
|
|
|
// don't synthesize anything for eMouseDoubleClick, since that
|
2011-06-01 04:37:54 +00:00
|
|
|
// is a synthetic event generated on mouse-up, and Windows WM_*DBLCLK
|
|
|
|
// messages are sent on mouse-down
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2015-10-16 04:19:27 +00:00
|
|
|
if (pluginEvent.event && initWParamWithCurrentState) {
|
2011-06-01 04:37:54 +00:00
|
|
|
pPluginEvent = &pluginEvent;
|
|
|
|
pluginEvent.wParam =
|
|
|
|
(::GetKeyState(VK_CONTROL) ? MK_CONTROL : 0) |
|
|
|
|
(::GetKeyState(VK_SHIFT) ? MK_SHIFT : 0) |
|
|
|
|
(::GetKeyState(VK_LBUTTON) ? MK_LBUTTON : 0) |
|
|
|
|
(::GetKeyState(VK_MBUTTON) ? MK_MBUTTON : 0) |
|
|
|
|
(::GetKeyState(VK_RBUTTON) ? MK_RBUTTON : 0) |
|
|
|
|
(::GetKeyState(VK_XBUTTON1) ? MK_XBUTTON1 : 0) |
|
|
|
|
(::GetKeyState(VK_XBUTTON2) ? MK_XBUTTON2 : 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (pPluginEvent) {
|
|
|
|
// Make event coordinates relative to our enclosing widget,
|
|
|
|
// not the widget they were received on.
|
2012-01-04 03:09:29 +00:00
|
|
|
// See use of NPEvent in widget/windows/nsWindow.cpp
|
2011-06-01 04:37:54 +00:00
|
|
|
// for why this assert should be safe
|
2015-08-28 23:58:30 +00:00
|
|
|
NS_ASSERTION(anEvent.mMessage == eMouseDown ||
|
2015-08-28 23:58:30 +00:00
|
|
|
anEvent.mMessage == eMouseUp ||
|
2015-08-28 23:58:31 +00:00
|
|
|
anEvent.mMessage == eMouseDoubleClick ||
|
2015-08-28 23:58:32 +00:00
|
|
|
anEvent.mMessage == eMouseOver ||
|
2015-08-28 23:58:32 +00:00
|
|
|
anEvent.mMessage == eMouseOut ||
|
2015-10-16 04:19:27 +00:00
|
|
|
anEvent.mMessage == eMouseMove ||
|
|
|
|
anEvent.mMessage == eWheel,
|
2011-06-01 04:37:54 +00:00
|
|
|
"Incorrect event type for coordinate translation");
|
|
|
|
nsPoint pt =
|
2014-09-24 04:35:00 +00:00
|
|
|
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
|
|
|
|
mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
|
|
|
|
nsPresContext* presContext = mPluginFrame->PresContext();
|
2011-06-01 04:37:54 +00:00
|
|
|
nsIntPoint ptPx(presContext->AppUnitsToDevPixels(pt.x),
|
|
|
|
presContext->AppUnitsToDevPixels(pt.y));
|
2014-09-24 04:35:00 +00:00
|
|
|
nsIntPoint widgetPtPx = ptPx + mPluginFrame->GetWindowOriginInPixels(true);
|
2014-07-23 19:55:51 +00:00
|
|
|
const_cast<NPEvent*>(pPluginEvent)->lParam = MAKELPARAM(widgetPtPx.x, widgetPtPx.y);
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!pPluginEvent) {
|
2015-08-22 01:34:51 +00:00
|
|
|
switch (anEvent.mMessage) {
|
2015-09-02 06:08:00 +00:00
|
|
|
case eFocus:
|
2011-06-01 04:37:54 +00:00
|
|
|
pluginEvent.event = WM_SETFOCUS;
|
|
|
|
pluginEvent.wParam = 0;
|
|
|
|
pluginEvent.lParam = 0;
|
|
|
|
pPluginEvent = &pluginEvent;
|
|
|
|
break;
|
2015-09-02 06:08:00 +00:00
|
|
|
case eBlur:
|
2011-06-01 04:37:54 +00:00
|
|
|
pluginEvent.event = WM_KILLFOCUS;
|
|
|
|
pluginEvent.wParam = 0;
|
|
|
|
pluginEvent.lParam = 0;
|
|
|
|
pPluginEvent = &pluginEvent;
|
|
|
|
break;
|
2015-08-26 12:56:59 +00:00
|
|
|
default:
|
|
|
|
break;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pPluginEvent && !pPluginEvent->event) {
|
|
|
|
// Don't send null events to plugins.
|
2014-09-24 04:34:00 +00:00
|
|
|
NS_WARNING("nsPluginFrame ProcessEvent: trying to send null event to plugin.");
|
2011-06-01 04:37:54 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pPluginEvent) {
|
2012-08-22 15:56:38 +00:00
|
|
|
int16_t response = kNPEventNotHandled;
|
2014-07-23 19:55:51 +00:00
|
|
|
mInstance->HandleEvent(const_cast<NPEvent*>(pPluginEvent),
|
|
|
|
&response,
|
|
|
|
NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
|
2011-06-01 04:37:54 +00:00
|
|
|
if (response == kNPEventHandled)
|
|
|
|
rv = nsEventStatus_eConsumeNoDefault;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef MOZ_X11
|
|
|
|
// this code supports windowless plugins
|
2016-04-14 08:03:14 +00:00
|
|
|
nsIWidget* widget = anEvent.mWidget;
|
2011-06-01 04:37:54 +00:00
|
|
|
XEvent pluginEvent = XEvent();
|
|
|
|
pluginEvent.type = 0;
|
|
|
|
|
2014-08-04 05:28:46 +00:00
|
|
|
switch(anEvent.mClass) {
|
2014-08-04 05:28:50 +00:00
|
|
|
case eMouseEventClass:
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
2015-08-28 23:58:32 +00:00
|
|
|
switch (anEvent.mMessage) {
|
|
|
|
case eMouseClick:
|
2015-08-28 23:58:31 +00:00
|
|
|
case eMouseDoubleClick:
|
2011-06-01 04:37:54 +00:00
|
|
|
// Button up/down events sent instead.
|
|
|
|
return rv;
|
2015-08-26 12:56:59 +00:00
|
|
|
default:
|
|
|
|
break;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get reference point relative to plugin origin.
|
2014-09-24 04:35:00 +00:00
|
|
|
const nsPresContext* presContext = mPluginFrame->PresContext();
|
2011-06-01 04:37:54 +00:00
|
|
|
nsPoint appPoint =
|
2014-09-24 04:35:00 +00:00
|
|
|
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
|
|
|
|
mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
|
2011-06-01 04:37:54 +00:00
|
|
|
nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x),
|
|
|
|
presContext->AppUnitsToDevPixels(appPoint.y));
|
2013-10-22 08:55:20 +00:00
|
|
|
const WidgetMouseEvent& mouseEvent = *anEvent.AsMouseEvent();
|
2011-06-01 04:37:54 +00:00
|
|
|
// Get reference point relative to screen:
|
2013-08-02 07:05:16 +00:00
|
|
|
LayoutDeviceIntPoint rootPoint(-1, -1);
|
2016-04-18 14:09:02 +00:00
|
|
|
if (widget) {
|
|
|
|
rootPoint = anEvent.mRefPoint + widget->WidgetToScreenOffset();
|
|
|
|
}
|
2012-06-28 00:15:32 +00:00
|
|
|
#ifdef MOZ_WIDGET_GTK
|
2011-06-01 04:37:54 +00:00
|
|
|
Window root = GDK_ROOT_WINDOW();
|
|
|
|
#elif defined(MOZ_WIDGET_QT)
|
2012-03-22 23:24:40 +00:00
|
|
|
Window root = RootWindowOfScreen(DefaultScreenOfDisplay(mozilla::DefaultXDisplay()));
|
2011-06-01 04:37:54 +00:00
|
|
|
#else
|
|
|
|
Window root = None; // Could XQueryTree, but this is not important.
|
|
|
|
#endif
|
|
|
|
|
2015-08-28 23:58:32 +00:00
|
|
|
switch (anEvent.mMessage) {
|
|
|
|
case eMouseOver:
|
2015-08-28 23:58:32 +00:00
|
|
|
case eMouseOut:
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
XCrossingEvent& event = pluginEvent.xcrossing;
|
2015-08-28 23:58:32 +00:00
|
|
|
event.type = anEvent.mMessage == eMouseOver ?
|
2011-06-01 04:37:54 +00:00
|
|
|
EnterNotify : LeaveNotify;
|
|
|
|
event.root = root;
|
2016-03-28 04:29:42 +00:00
|
|
|
event.time = anEvent.mTime;
|
2011-06-01 04:37:54 +00:00
|
|
|
event.x = pluginPoint.x;
|
|
|
|
event.y = pluginPoint.y;
|
|
|
|
event.x_root = rootPoint.x;
|
|
|
|
event.y_root = rootPoint.y;
|
|
|
|
event.state = XInputEventState(mouseEvent);
|
|
|
|
// information lost
|
|
|
|
event.subwindow = None;
|
|
|
|
event.mode = -1;
|
|
|
|
event.detail = NotifyDetailNone;
|
|
|
|
event.same_screen = True;
|
|
|
|
event.focus = mContentFocused;
|
|
|
|
}
|
|
|
|
break;
|
2015-08-28 23:58:29 +00:00
|
|
|
case eMouseMove:
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
XMotionEvent& event = pluginEvent.xmotion;
|
|
|
|
event.type = MotionNotify;
|
|
|
|
event.root = root;
|
2016-03-28 04:29:42 +00:00
|
|
|
event.time = anEvent.mTime;
|
2011-06-01 04:37:54 +00:00
|
|
|
event.x = pluginPoint.x;
|
|
|
|
event.y = pluginPoint.y;
|
|
|
|
event.x_root = rootPoint.x;
|
|
|
|
event.y_root = rootPoint.y;
|
|
|
|
event.state = XInputEventState(mouseEvent);
|
|
|
|
// information lost
|
|
|
|
event.subwindow = None;
|
|
|
|
event.is_hint = NotifyNormal;
|
|
|
|
event.same_screen = True;
|
|
|
|
}
|
|
|
|
break;
|
2015-08-28 23:58:30 +00:00
|
|
|
case eMouseDown:
|
2015-08-28 23:58:30 +00:00
|
|
|
case eMouseUp:
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
XButtonEvent& event = pluginEvent.xbutton;
|
2015-08-28 23:58:30 +00:00
|
|
|
event.type = anEvent.mMessage == eMouseDown ?
|
2011-06-01 04:37:54 +00:00
|
|
|
ButtonPress : ButtonRelease;
|
|
|
|
event.root = root;
|
2016-03-28 04:29:42 +00:00
|
|
|
event.time = anEvent.mTime;
|
2011-06-01 04:37:54 +00:00
|
|
|
event.x = pluginPoint.x;
|
|
|
|
event.y = pluginPoint.y;
|
|
|
|
event.x_root = rootPoint.x;
|
|
|
|
event.y_root = rootPoint.y;
|
|
|
|
event.state = XInputEventState(mouseEvent);
|
|
|
|
switch (mouseEvent.button)
|
|
|
|
{
|
2013-10-02 06:38:27 +00:00
|
|
|
case WidgetMouseEvent::eMiddleButton:
|
2011-06-01 04:37:54 +00:00
|
|
|
event.button = 2;
|
|
|
|
break;
|
2013-10-02 06:38:27 +00:00
|
|
|
case WidgetMouseEvent::eRightButton:
|
2011-06-01 04:37:54 +00:00
|
|
|
event.button = 3;
|
|
|
|
break;
|
2013-10-02 06:38:27 +00:00
|
|
|
default: // WidgetMouseEvent::eLeftButton;
|
2011-06-01 04:37:54 +00:00
|
|
|
event.button = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// information lost:
|
|
|
|
event.subwindow = None;
|
|
|
|
event.same_screen = True;
|
|
|
|
}
|
|
|
|
break;
|
2015-08-26 12:56:59 +00:00
|
|
|
default:
|
|
|
|
break;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2014-08-04 05:28:51 +00:00
|
|
|
//XXX case eMouseScrollEventClass: not received.
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2014-08-04 05:28:48 +00:00
|
|
|
case eKeyboardEventClass:
|
2014-07-23 19:55:51 +00:00
|
|
|
if (anEvent.mPluginEvent)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
XKeyEvent &event = pluginEvent.xkey;
|
2012-06-28 00:15:32 +00:00
|
|
|
#ifdef MOZ_WIDGET_GTK
|
2011-06-01 04:37:54 +00:00
|
|
|
event.root = GDK_ROOT_WINDOW();
|
2016-03-28 04:29:42 +00:00
|
|
|
event.time = anEvent.mTime;
|
2011-06-01 04:37:54 +00:00
|
|
|
const GdkEventKey* gdkEvent =
|
2014-07-23 19:55:51 +00:00
|
|
|
static_cast<const GdkEventKey*>(anEvent.mPluginEvent);
|
2011-06-01 04:37:54 +00:00
|
|
|
event.keycode = gdkEvent->hardware_keycode;
|
|
|
|
event.state = gdkEvent->state;
|
2015-08-22 01:34:51 +00:00
|
|
|
switch (anEvent.mMessage)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
2015-08-28 23:58:27 +00:00
|
|
|
case eKeyDown:
|
|
|
|
// Handle eKeyDown for modifier key presses
|
2015-08-28 23:58:27 +00:00
|
|
|
// For non-modifiers we get eKeyPress
|
2011-06-01 04:37:54 +00:00
|
|
|
if (gdkEvent->is_modifier)
|
|
|
|
event.type = XKeyPress;
|
|
|
|
break;
|
2015-08-28 23:58:27 +00:00
|
|
|
case eKeyPress:
|
2011-06-01 04:37:54 +00:00
|
|
|
event.type = XKeyPress;
|
|
|
|
break;
|
2015-08-28 23:58:27 +00:00
|
|
|
case eKeyUp:
|
2011-06-01 04:37:54 +00:00
|
|
|
event.type = KeyRelease;
|
|
|
|
break;
|
2015-08-26 12:56:59 +00:00
|
|
|
default:
|
|
|
|
break;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Information that could be obtained from pluginEvent but we may not
|
|
|
|
// want to promise to provide:
|
|
|
|
event.subwindow = None;
|
|
|
|
event.x = 0;
|
|
|
|
event.y = 0;
|
|
|
|
event.x_root = -1;
|
|
|
|
event.y_root = -1;
|
|
|
|
event.same_screen = False;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// If we need to send synthesized key events, then
|
|
|
|
// DOMKeyCodeToGdkKeyCode(keyEvent.keyCode) and
|
|
|
|
// gdk_keymap_get_entries_for_keyval will be useful, but the
|
|
|
|
// mappings will not be unique.
|
|
|
|
NS_WARNING("Synthesized key event not sent to plugin");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2014-07-11 22:41:41 +00:00
|
|
|
default:
|
2015-08-26 12:56:59 +00:00
|
|
|
switch (anEvent.mMessage) {
|
2015-09-02 06:08:00 +00:00
|
|
|
case eFocus:
|
2015-09-02 06:08:00 +00:00
|
|
|
case eBlur:
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
XFocusChangeEvent &event = pluginEvent.xfocus;
|
2015-09-02 06:08:00 +00:00
|
|
|
event.type = anEvent.mMessage == eFocus ? FocusIn : FocusOut;
|
2011-06-01 04:37:54 +00:00
|
|
|
// information lost:
|
|
|
|
event.mode = -1;
|
|
|
|
event.detail = NotifyDetailNone;
|
|
|
|
}
|
|
|
|
break;
|
2015-08-26 12:56:59 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!pluginEvent.type) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fill in (useless) generic event information.
|
|
|
|
XAnyEvent& event = pluginEvent.xany;
|
|
|
|
event.display = widget ?
|
2012-07-30 14:20:58 +00:00
|
|
|
static_cast<Display*>(widget->GetNativeData(NS_NATIVE_DISPLAY)) : nullptr;
|
2011-06-01 04:37:54 +00:00
|
|
|
event.window = None; // not a real window
|
|
|
|
// information lost:
|
|
|
|
event.serial = 0;
|
|
|
|
event.send_event = False;
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
int16_t response = kNPEventNotHandled;
|
2013-02-27 11:50:28 +00:00
|
|
|
mInstance->HandleEvent(&pluginEvent, &response, NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
|
2011-06-01 04:37:54 +00:00
|
|
|
if (response == kNPEventHandled)
|
|
|
|
rv = nsEventStatus_eConsumeNoDefault;
|
|
|
|
#endif
|
|
|
|
|
2011-11-11 00:17:46 +00:00
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
2011-09-16 21:34:31 +00:00
|
|
|
// this code supports windowless plugins
|
|
|
|
{
|
|
|
|
// The plugin needs focus to receive keyboard and touch events
|
|
|
|
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
|
|
|
if (fm) {
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIDOMElement> elem = do_QueryReferent(mContent);
|
2011-09-16 21:34:31 +00:00
|
|
|
fm->SetFocus(elem, 0);
|
|
|
|
}
|
|
|
|
}
|
2014-08-04 05:28:46 +00:00
|
|
|
switch(anEvent.mClass) {
|
2014-08-04 05:28:50 +00:00
|
|
|
case eMouseEventClass:
|
2011-09-16 21:34:31 +00:00
|
|
|
{
|
2015-08-28 23:58:32 +00:00
|
|
|
switch (anEvent.mMessage) {
|
|
|
|
case eMouseClick:
|
2015-08-28 23:58:31 +00:00
|
|
|
case eMouseDoubleClick:
|
2011-09-16 21:34:31 +00:00
|
|
|
// Button up/down events sent instead.
|
|
|
|
return rv;
|
2015-08-26 12:56:59 +00:00
|
|
|
default:
|
|
|
|
break;
|
2011-09-16 21:34:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get reference point relative to plugin origin.
|
2014-09-24 04:35:00 +00:00
|
|
|
const nsPresContext* presContext = mPluginFrame->PresContext();
|
2011-09-16 21:34:31 +00:00
|
|
|
nsPoint appPoint =
|
2014-09-24 04:35:00 +00:00
|
|
|
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
|
|
|
|
mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
|
2011-09-16 21:34:31 +00:00
|
|
|
nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x),
|
|
|
|
presContext->AppUnitsToDevPixels(appPoint.y));
|
|
|
|
|
2015-08-28 23:58:29 +00:00
|
|
|
switch (anEvent.mMessage) {
|
|
|
|
case eMouseMove:
|
2011-09-16 21:34:31 +00:00
|
|
|
{
|
|
|
|
// are these going to be touch events?
|
|
|
|
// pluginPoint.x;
|
|
|
|
// pluginPoint.y;
|
|
|
|
}
|
|
|
|
break;
|
2015-08-28 23:58:30 +00:00
|
|
|
case eMouseDown:
|
2011-09-16 21:34:31 +00:00
|
|
|
{
|
|
|
|
ANPEvent event;
|
|
|
|
event.inSize = sizeof(ANPEvent);
|
|
|
|
event.eventType = kMouse_ANPEventType;
|
|
|
|
event.data.mouse.action = kDown_ANPMouseAction;
|
|
|
|
event.data.mouse.x = pluginPoint.x;
|
|
|
|
event.data.mouse.y = pluginPoint.y;
|
2013-02-27 11:50:28 +00:00
|
|
|
mInstance->HandleEvent(&event, nullptr, NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
|
2011-09-16 21:34:31 +00:00
|
|
|
}
|
|
|
|
break;
|
2015-08-28 23:58:30 +00:00
|
|
|
case eMouseUp:
|
2011-09-16 21:34:31 +00:00
|
|
|
{
|
|
|
|
ANPEvent event;
|
|
|
|
event.inSize = sizeof(ANPEvent);
|
|
|
|
event.eventType = kMouse_ANPEventType;
|
|
|
|
event.data.mouse.action = kUp_ANPMouseAction;
|
|
|
|
event.data.mouse.x = pluginPoint.x;
|
|
|
|
event.data.mouse.y = pluginPoint.y;
|
2013-02-27 11:50:28 +00:00
|
|
|
mInstance->HandleEvent(&event, nullptr, NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
|
2011-09-16 21:34:31 +00:00
|
|
|
}
|
|
|
|
break;
|
2015-08-26 12:56:59 +00:00
|
|
|
default:
|
|
|
|
break;
|
2011-09-16 21:34:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2014-08-04 05:28:48 +00:00
|
|
|
case eKeyboardEventClass:
|
2011-09-16 21:34:31 +00:00
|
|
|
{
|
2013-10-18 06:10:24 +00:00
|
|
|
const WidgetKeyboardEvent& keyEvent = *anEvent.AsKeyboardEvent();
|
2014-08-04 05:28:48 +00:00
|
|
|
LOG("Firing eKeyboardEventClass %d %d\n",
|
2016-05-13 07:06:18 +00:00
|
|
|
keyEvent.mKeyCode, keyEvent.mCharCode);
|
2012-04-19 17:49:31 +00:00
|
|
|
// pluginEvent is initialized by nsWindow::InitKeyEvent().
|
2014-07-23 19:55:51 +00:00
|
|
|
const ANPEvent* pluginEvent = static_cast<const ANPEvent*>(keyEvent.mPluginEvent);
|
2012-04-19 17:49:31 +00:00
|
|
|
if (pluginEvent) {
|
|
|
|
MOZ_ASSERT(pluginEvent->inSize == sizeof(ANPEvent));
|
|
|
|
MOZ_ASSERT(pluginEvent->eventType == kKey_ANPEventType);
|
2014-07-23 19:55:51 +00:00
|
|
|
mInstance->HandleEvent(const_cast<ANPEvent*>(pluginEvent),
|
|
|
|
nullptr,
|
|
|
|
NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
|
2012-04-19 17:49:31 +00:00
|
|
|
}
|
2011-09-16 21:34:31 +00:00
|
|
|
}
|
2012-11-20 06:05:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
2011-09-16 21:34:31 +00:00
|
|
|
}
|
|
|
|
rv = nsEventStatus_eConsumeNoDefault;
|
|
|
|
#endif
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsPluginInstanceOwner::Destroy()
|
|
|
|
{
|
2013-04-17 22:11:21 +00:00
|
|
|
SetFrame(nullptr);
|
2012-02-02 22:55:25 +00:00
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
#ifdef XP_MACOSX
|
2012-02-17 02:27:37 +00:00
|
|
|
RemoveFromCARefreshTimer();
|
2011-06-01 04:37:54 +00:00
|
|
|
#endif
|
|
|
|
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
// unregister context menu listener
|
|
|
|
if (mCXMenuListener) {
|
2015-04-04 18:39:36 +00:00
|
|
|
mCXMenuListener->Destroy(content);
|
2012-07-30 14:20:58 +00:00
|
|
|
mCXMenuListener = nullptr;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
2015-04-04 18:39:36 +00:00
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("focus"), this, false);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("blur"), this, false);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("mouseup"), this, false);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("mousedown"), this, false);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("mousemove"), this, false);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("click"), this, false);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("dblclick"), this, false);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("mouseover"), this, false);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("mouseout"), this, false);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("keypress"), this, true);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("keydown"), this, true);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("keyup"), this, true);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("drop"), this, true);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("dragdrop"), this, true);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("drag"), this, true);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("dragenter"), this, true);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("dragover"), this, true);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("dragleave"), this, true);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("dragexit"), this, true);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("dragstart"), this, true);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("draggesture"), this, true);
|
|
|
|
content->RemoveEventListener(NS_LITERAL_STRING("dragend"), this, true);
|
2015-12-29 13:57:37 +00:00
|
|
|
content->RemoveSystemEventListener(NS_LITERAL_STRING("compositionstart"),
|
|
|
|
this, true);
|
|
|
|
content->RemoveSystemEventListener(NS_LITERAL_STRING("compositionend"),
|
|
|
|
this, true);
|
|
|
|
content->RemoveSystemEventListener(NS_LITERAL_STRING("text"), this, true);
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2012-02-15 20:34:31 +00:00
|
|
|
#if MOZ_WIDGET_ANDROID
|
|
|
|
RemovePluginView();
|
|
|
|
#endif
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
if (mWidget) {
|
2012-01-31 21:55:54 +00:00
|
|
|
if (mPluginWindow) {
|
2012-07-30 14:20:58 +00:00
|
|
|
mPluginWindow->SetPluginWidget(nullptr);
|
2012-01-31 21:55:54 +00:00
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
|
2012-01-31 21:55:54 +00:00
|
|
|
if (pluginWidget) {
|
2012-07-30 14:20:58 +00:00
|
|
|
pluginWidget->SetPluginInstanceOwner(nullptr);
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
2012-01-31 21:55:54 +00:00
|
|
|
mWidget->Destroy();
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
return NS_OK;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Paints are handled differently, so we just simulate an update event.
|
|
|
|
|
|
|
|
#ifdef XP_MACOSX
|
|
|
|
void nsPluginInstanceOwner::Paint(const gfxRect& aDirtyRect, CGContextRef cgContext)
|
|
|
|
{
|
2014-09-24 04:35:00 +00:00
|
|
|
if (!mInstance || !mPluginFrame)
|
2011-06-01 04:37:54 +00:00
|
|
|
return;
|
2012-10-02 19:48:05 +00:00
|
|
|
|
2014-07-11 22:41:41 +00:00
|
|
|
gfxRect dirtyRectCopy = aDirtyRect;
|
2012-10-02 19:48:05 +00:00
|
|
|
double scaleFactor = 1.0;
|
|
|
|
GetContentsScaleFactor(&scaleFactor);
|
|
|
|
if (scaleFactor != 1.0) {
|
|
|
|
::CGContextScaleCTM(cgContext, scaleFactor, scaleFactor);
|
|
|
|
// Convert aDirtyRect from device pixels to "display pixels"
|
|
|
|
// for HiDPI modes
|
|
|
|
dirtyRectCopy.ScaleRoundOut(1.0 / scaleFactor);
|
|
|
|
}
|
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
DoCocoaEventDrawRect(dirtyRectCopy, cgContext);
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void nsPluginInstanceOwner::DoCocoaEventDrawRect(const gfxRect& aDrawRect, CGContextRef cgContext)
|
|
|
|
{
|
2014-09-24 04:35:00 +00:00
|
|
|
if (!mInstance || !mPluginFrame)
|
2011-06-01 04:37:54 +00:00
|
|
|
return;
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
// The context given here is only valid during the HandleEvent call.
|
|
|
|
NPCocoaEvent updateEvent;
|
|
|
|
InitializeNPCocoaEvent(&updateEvent);
|
|
|
|
updateEvent.type = NPCocoaEventDrawRect;
|
|
|
|
updateEvent.data.draw.context = cgContext;
|
|
|
|
updateEvent.data.draw.x = aDrawRect.X();
|
|
|
|
updateEvent.data.draw.y = aDrawRect.Y();
|
|
|
|
updateEvent.data.draw.width = aDrawRect.Width();
|
|
|
|
updateEvent.data.draw.height = aDrawRect.Height();
|
|
|
|
|
2012-07-30 14:20:58 +00:00
|
|
|
mInstance->HandleEvent(&updateEvent, nullptr);
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef XP_WIN
|
|
|
|
void nsPluginInstanceOwner::Paint(const RECT& aDirty, HDC aDC)
|
|
|
|
{
|
2014-09-24 04:35:00 +00:00
|
|
|
if (!mInstance || !mPluginFrame)
|
2011-06-01 04:37:54 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
NPEvent pluginEvent;
|
|
|
|
pluginEvent.event = WM_PAINT;
|
|
|
|
pluginEvent.wParam = WPARAM(aDC);
|
|
|
|
pluginEvent.lParam = LPARAM(&aDirty);
|
2012-07-30 14:20:58 +00:00
|
|
|
mInstance->HandleEvent(&pluginEvent, nullptr);
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-11-11 00:17:46 +00:00
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
2011-09-16 21:34:31 +00:00
|
|
|
|
|
|
|
void nsPluginInstanceOwner::Paint(gfxContext* aContext,
|
|
|
|
const gfxRect& aFrameRect,
|
|
|
|
const gfxRect& aDirtyRect)
|
|
|
|
{
|
2014-09-24 04:35:00 +00:00
|
|
|
if (!mInstance || !mPluginFrame || !mPluginDocumentActiveState || mFullScreen)
|
2011-09-16 21:34:31 +00:00
|
|
|
return;
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t model = mInstance->GetANPDrawingModel();
|
2011-09-16 21:34:31 +00:00
|
|
|
|
|
|
|
if (model == kSurface_ANPDrawingModel) {
|
2012-07-20 19:20:51 +00:00
|
|
|
if (!AddPluginView(GetPluginRect())) {
|
2012-01-31 14:40:58 +00:00
|
|
|
Invalidate();
|
2011-09-16 21:34:31 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (model != kBitmap_ANPDrawingModel)
|
|
|
|
return;
|
|
|
|
|
|
|
|
#ifdef ANP_BITMAP_DRAWING_MODEL
|
2015-10-18 05:24:48 +00:00
|
|
|
static RefPtr<gfxImageSurface> pluginSurface;
|
2011-09-16 21:34:31 +00:00
|
|
|
|
2012-07-30 14:20:58 +00:00
|
|
|
if (pluginSurface == nullptr ||
|
2011-09-16 21:34:31 +00:00
|
|
|
aFrameRect.width != pluginSurface->Width() ||
|
|
|
|
aFrameRect.height != pluginSurface->Height()) {
|
|
|
|
|
2015-09-23 18:49:05 +00:00
|
|
|
pluginSurface = new gfxImageSurface(gfx::IntSize(aFrameRect.width, aFrameRect.height),
|
2016-01-08 04:57:38 +00:00
|
|
|
SurfaceFormat::A8R8G8B8_UINT32);
|
2011-09-16 21:34:31 +00:00
|
|
|
if (!pluginSurface)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clears buffer. I think this is needed.
|
2014-06-24 09:02:10 +00:00
|
|
|
gfxUtils::ClearThebesSurface(pluginSurface);
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2011-09-16 21:34:31 +00:00
|
|
|
ANPEvent event;
|
|
|
|
event.inSize = sizeof(ANPEvent);
|
|
|
|
event.eventType = 4;
|
|
|
|
event.data.draw.model = 1;
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2011-09-16 21:34:31 +00:00
|
|
|
event.data.draw.clip.top = 0;
|
|
|
|
event.data.draw.clip.left = 0;
|
|
|
|
event.data.draw.clip.bottom = aFrameRect.width;
|
|
|
|
event.data.draw.clip.right = aFrameRect.height;
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2011-09-16 21:34:31 +00:00
|
|
|
event.data.draw.data.bitmap.format = kRGBA_8888_ANPBitmapFormat;
|
|
|
|
event.data.draw.data.bitmap.width = aFrameRect.width;
|
|
|
|
event.data.draw.data.bitmap.height = aFrameRect.height;
|
|
|
|
event.data.draw.data.bitmap.baseAddr = pluginSurface->Data();
|
|
|
|
event.data.draw.data.bitmap.rowBytes = aFrameRect.width * 4;
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2011-09-16 21:34:31 +00:00
|
|
|
if (!mInstance)
|
|
|
|
return;
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2012-07-30 14:20:58 +00:00
|
|
|
mInstance->HandleEvent(&event, nullptr);
|
2011-09-16 21:34:31 +00:00
|
|
|
|
2015-09-25 05:38:58 +00:00
|
|
|
aContext->SetOp(gfx::CompositionOp::OP_SOURCE);
|
2011-09-16 21:34:31 +00:00
|
|
|
aContext->SetSource(pluginSurface, gfxPoint(aFrameRect.x, aFrameRect.y));
|
|
|
|
aContext->Clip(aFrameRect);
|
|
|
|
aContext->Paint();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
#if defined(MOZ_X11)
|
|
|
|
void nsPluginInstanceOwner::Paint(gfxContext* aContext,
|
|
|
|
const gfxRect& aFrameRect,
|
|
|
|
const gfxRect& aDirtyRect)
|
|
|
|
{
|
2014-09-24 04:35:00 +00:00
|
|
|
if (!mInstance || !mPluginFrame)
|
2011-06-01 04:37:54 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
// to provide crisper and faster drawing.
|
|
|
|
gfxRect pluginRect = aFrameRect;
|
|
|
|
if (aContext->UserToDevicePixelSnapped(pluginRect)) {
|
|
|
|
pluginRect = aContext->DeviceToUser(pluginRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Round out the dirty rect to plugin pixels to ensure the plugin draws
|
|
|
|
// enough pixels for interpolation to device pixels.
|
|
|
|
gfxRect dirtyRect = aDirtyRect - pluginRect.TopLeft();
|
|
|
|
dirtyRect.RoundOut();
|
|
|
|
|
|
|
|
// Plugins can only draw an integer number of pixels.
|
|
|
|
//
|
|
|
|
// With translation-only transformation matrices, pluginRect is already
|
|
|
|
// pixel-aligned.
|
|
|
|
//
|
|
|
|
// With more complex transformations, modifying the scales in the
|
|
|
|
// transformation matrix could retain subpixel accuracy and let the plugin
|
|
|
|
// draw a suitable number of pixels for interpolation to device pixels in
|
|
|
|
// Renderer::Draw, but such cases are not common enough to warrant the
|
|
|
|
// effort now.
|
|
|
|
nsIntSize pluginSize(NS_lround(pluginRect.width),
|
|
|
|
NS_lround(pluginRect.height));
|
|
|
|
|
|
|
|
// Determine what the plugin needs to draw.
|
2012-08-22 15:56:38 +00:00
|
|
|
nsIntRect pluginDirtyRect(int32_t(dirtyRect.x),
|
|
|
|
int32_t(dirtyRect.y),
|
|
|
|
int32_t(dirtyRect.width),
|
|
|
|
int32_t(dirtyRect.height));
|
2011-06-01 04:37:54 +00:00
|
|
|
if (!pluginDirtyRect.
|
|
|
|
IntersectRect(nsIntRect(0, 0, pluginSize.width, pluginSize.height),
|
|
|
|
pluginDirtyRect))
|
|
|
|
return;
|
|
|
|
|
|
|
|
NPWindow* window;
|
|
|
|
GetWindow(window);
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t rendererFlags = 0;
|
2011-06-01 04:37:54 +00:00
|
|
|
if (!mFlash10Quirks) {
|
|
|
|
rendererFlags |=
|
|
|
|
Renderer::DRAW_SUPPORTS_CLIP_RECT |
|
|
|
|
Renderer::DRAW_SUPPORTS_ALTERNATE_VISUAL;
|
|
|
|
}
|
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
bool transparent;
|
2011-06-01 04:37:54 +00:00
|
|
|
mInstance->IsTransparent(&transparent);
|
|
|
|
if (!transparent)
|
|
|
|
rendererFlags |= Renderer::DRAW_IS_OPAQUE;
|
|
|
|
|
|
|
|
// Renderer::Draw() draws a rectangle with top-left at the aContext origin.
|
|
|
|
gfxContextAutoSaveRestore autoSR(aContext);
|
2014-09-11 06:57:38 +00:00
|
|
|
aContext->SetMatrix(
|
|
|
|
aContext->CurrentMatrix().Translate(pluginRect.TopLeft()));
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
Renderer renderer(window, this, pluginSize, pluginDirtyRect);
|
2012-06-28 00:15:32 +00:00
|
|
|
|
2012-03-22 23:24:40 +00:00
|
|
|
Display* dpy = mozilla::DefaultXDisplay();
|
|
|
|
Screen* screen = DefaultScreenOfDisplay(dpy);
|
|
|
|
Visual* visual = DefaultVisualOfScreen(screen);
|
2012-06-28 00:15:32 +00:00
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
renderer.Draw(aContext, nsIntSize(window->width, window->height),
|
2013-10-25 21:25:40 +00:00
|
|
|
rendererFlags, screen, visual);
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
nsresult
|
2013-10-25 21:25:40 +00:00
|
|
|
nsPluginInstanceOwner::Renderer::DrawWithXlib(cairo_surface_t* xsurface,
|
2011-06-01 04:37:54 +00:00
|
|
|
nsIntPoint offset,
|
2014-07-11 22:41:41 +00:00
|
|
|
nsIntRect *clipRects,
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t numClipRects)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
2013-10-25 21:25:40 +00:00
|
|
|
Screen *screen = cairo_xlib_surface_get_screen(xsurface);
|
2011-06-01 04:37:54 +00:00
|
|
|
Colormap colormap;
|
|
|
|
Visual* visual;
|
2013-10-25 21:25:40 +00:00
|
|
|
if (!gfxXlibSurface::GetColormapAndVisual(xsurface, &colormap, &visual)) {
|
2011-06-01 04:37:54 +00:00
|
|
|
NS_ERROR("Failed to get visual and colormap");
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsNPAPIPluginInstance *instance = mInstanceOwner->mInstance;
|
|
|
|
if (!instance)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
// See if the plugin must be notified of new window parameters.
|
2011-09-29 06:19:26 +00:00
|
|
|
bool doupdatewindow = false;
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
if (mWindow->x != offset.x || mWindow->y != offset.y) {
|
|
|
|
mWindow->x = offset.x;
|
|
|
|
mWindow->y = offset.y;
|
2011-09-30 06:02:59 +00:00
|
|
|
doupdatewindow = true;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (nsIntSize(mWindow->width, mWindow->height) != mPluginSize) {
|
|
|
|
mWindow->width = mPluginSize.width;
|
|
|
|
mWindow->height = mPluginSize.height;
|
2011-09-30 06:02:59 +00:00
|
|
|
doupdatewindow = true;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// The clip rect is relative to drawable top-left.
|
|
|
|
NS_ASSERTION(numClipRects <= 1, "We don't support multiple clip rectangles!");
|
|
|
|
nsIntRect clipRect;
|
|
|
|
if (numClipRects) {
|
|
|
|
clipRect.x = clipRects[0].x;
|
|
|
|
clipRect.y = clipRects[0].y;
|
|
|
|
clipRect.width = clipRects[0].width;
|
|
|
|
clipRect.height = clipRects[0].height;
|
|
|
|
// NPRect members are unsigned, but clip rectangles should be contained by
|
|
|
|
// the surface.
|
|
|
|
NS_ASSERTION(clipRect.x >= 0 && clipRect.y >= 0,
|
|
|
|
"Clip rectangle offsets are negative!");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
clipRect.x = offset.x;
|
|
|
|
clipRect.y = offset.y;
|
|
|
|
clipRect.width = mWindow->width;
|
|
|
|
clipRect.height = mWindow->height;
|
|
|
|
// Don't ask the plugin to draw outside the drawable.
|
|
|
|
// This also ensures that the unsigned clip rectangle offsets won't be -ve.
|
|
|
|
clipRect.IntersectRect(clipRect,
|
|
|
|
nsIntRect(0, 0,
|
2013-10-25 21:25:40 +00:00
|
|
|
cairo_xlib_surface_get_width(xsurface),
|
|
|
|
cairo_xlib_surface_get_height(xsurface)));
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NPRect newClipRect;
|
|
|
|
newClipRect.left = clipRect.x;
|
|
|
|
newClipRect.top = clipRect.y;
|
|
|
|
newClipRect.right = clipRect.XMost();
|
|
|
|
newClipRect.bottom = clipRect.YMost();
|
|
|
|
if (mWindow->clipRect.left != newClipRect.left ||
|
|
|
|
mWindow->clipRect.top != newClipRect.top ||
|
|
|
|
mWindow->clipRect.right != newClipRect.right ||
|
|
|
|
mWindow->clipRect.bottom != newClipRect.bottom) {
|
|
|
|
mWindow->clipRect = newClipRect;
|
2011-09-30 06:02:59 +00:00
|
|
|
doupdatewindow = true;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 22:41:41 +00:00
|
|
|
NPSetWindowCallbackStruct* ws_info =
|
2011-06-01 04:37:54 +00:00
|
|
|
static_cast<NPSetWindowCallbackStruct*>(mWindow->ws_info);
|
|
|
|
#ifdef MOZ_X11
|
|
|
|
if (ws_info->visual != visual || ws_info->colormap != colormap) {
|
|
|
|
ws_info->visual = visual;
|
|
|
|
ws_info->colormap = colormap;
|
|
|
|
ws_info->depth = gfxXlibSurface::DepthOfVisual(screen, visual);
|
2011-09-30 06:02:59 +00:00
|
|
|
doupdatewindow = true;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
{
|
|
|
|
if (doupdatewindow)
|
|
|
|
instance->SetWindow(mWindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Translate the dirty rect to drawable coordinates.
|
|
|
|
nsIntRect dirtyRect = mDirtyRect + offset;
|
|
|
|
if (mInstanceOwner->mFlash10Quirks) {
|
|
|
|
// Work around a bug in Flash up to 10.1 d51 at least, where expose event
|
|
|
|
// top left coordinates within the plugin-rect and not at the drawable
|
|
|
|
// origin are misinterpreted. (We can move the top left coordinate
|
|
|
|
// provided it is within the clipRect.)
|
|
|
|
dirtyRect.SetRect(offset.x, offset.y,
|
|
|
|
mDirtyRect.XMost(), mDirtyRect.YMost());
|
|
|
|
}
|
|
|
|
// Intersect the dirty rect with the clip rect to ensure that it lies within
|
|
|
|
// the drawable.
|
|
|
|
if (!dirtyRect.IntersectRect(dirtyRect, clipRect))
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
{
|
|
|
|
XEvent pluginEvent = XEvent();
|
|
|
|
XGraphicsExposeEvent& exposeEvent = pluginEvent.xgraphicsexpose;
|
|
|
|
// set the drawing info
|
|
|
|
exposeEvent.type = GraphicsExpose;
|
|
|
|
exposeEvent.display = DisplayOfScreen(screen);
|
2013-10-25 21:25:40 +00:00
|
|
|
exposeEvent.drawable = cairo_xlib_surface_get_drawable(xsurface);
|
2011-06-01 04:37:54 +00:00
|
|
|
exposeEvent.x = dirtyRect.x;
|
|
|
|
exposeEvent.y = dirtyRect.y;
|
|
|
|
exposeEvent.width = dirtyRect.width;
|
|
|
|
exposeEvent.height = dirtyRect.height;
|
|
|
|
exposeEvent.count = 0;
|
|
|
|
// information not set:
|
|
|
|
exposeEvent.serial = 0;
|
|
|
|
exposeEvent.send_event = False;
|
|
|
|
exposeEvent.major_code = 0;
|
|
|
|
exposeEvent.minor_code = 0;
|
|
|
|
|
2012-07-30 14:20:58 +00:00
|
|
|
instance->HandleEvent(&pluginEvent, nullptr);
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
nsresult nsPluginInstanceOwner::Init(nsIContent* aContent)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
mLastEventloopNestingLevel = GetEventloopNestingLevel();
|
|
|
|
|
2015-04-04 18:39:36 +00:00
|
|
|
mContent = do_GetWeakReference(aContent);
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
// Get a frame, don't reflow. If a reflow was necessary it should have been
|
|
|
|
// done at a higher level than this (content).
|
|
|
|
nsIFrame* frame = aContent->GetPrimaryFrame();
|
|
|
|
nsIObjectFrame* iObjFrame = do_QueryFrame(frame);
|
2014-09-24 04:34:00 +00:00
|
|
|
nsPluginFrame* objFrame = static_cast<nsPluginFrame*>(iObjFrame);
|
2012-01-31 21:55:54 +00:00
|
|
|
if (objFrame) {
|
|
|
|
SetFrame(objFrame);
|
|
|
|
// Some plugins require a specific sequence of shutdown and startup when
|
|
|
|
// a page is reloaded. Shutdown happens usually when the last instance
|
|
|
|
// is destroyed. Here we make sure the plugin instance in the old
|
|
|
|
// document is destroyed before we try to create the new one.
|
|
|
|
objFrame->PresContext()->EnsureVisible();
|
2012-02-07 21:25:28 +00:00
|
|
|
} else {
|
2012-08-31 17:52:50 +00:00
|
|
|
NS_NOTREACHED("Should not be initializing plugin without a frame");
|
2012-02-07 21:25:28 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// register context menu listener
|
2013-04-19 22:18:32 +00:00
|
|
|
mCXMenuListener = new nsPluginDOMContextMenuListener(aContent);
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2015-04-04 18:39:36 +00:00
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("focus"), this, false,
|
2011-09-30 06:02:59 +00:00
|
|
|
false);
|
2015-04-04 18:39:36 +00:00
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("blur"), this, false,
|
2011-09-30 06:02:59 +00:00
|
|
|
false);
|
2015-04-04 18:39:36 +00:00
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("mouseup"), this, false,
|
2011-09-30 06:02:59 +00:00
|
|
|
false);
|
2015-04-04 18:39:36 +00:00
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("mousedown"), this, false,
|
2011-09-30 06:02:59 +00:00
|
|
|
false);
|
2015-04-04 18:39:36 +00:00
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("mousemove"), this, false,
|
2011-09-30 06:02:59 +00:00
|
|
|
false);
|
2015-04-04 18:39:36 +00:00
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("click"), this, false,
|
2011-09-30 06:02:59 +00:00
|
|
|
false);
|
2015-04-04 18:39:36 +00:00
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("dblclick"), this, false,
|
2011-09-30 06:02:59 +00:00
|
|
|
false);
|
2015-04-04 18:39:36 +00:00
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("mouseover"), this, false,
|
2011-09-30 06:02:59 +00:00
|
|
|
false);
|
2015-04-04 18:39:36 +00:00
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("mouseout"), this, false,
|
2011-09-30 06:02:59 +00:00
|
|
|
false);
|
2015-04-04 18:39:36 +00:00
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("keypress"), this, true);
|
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("keydown"), this, true);
|
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("keyup"), this, true);
|
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("drop"), this, true);
|
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("dragdrop"), this, true);
|
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("drag"), this, true);
|
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("dragenter"), this, true);
|
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("dragover"), this, true);
|
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("dragleave"), this, true);
|
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("dragexit"), this, true);
|
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("dragstart"), this, true);
|
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("draggesture"), this, true);
|
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("dragend"), this, true);
|
2015-12-29 13:57:37 +00:00
|
|
|
aContent->AddSystemEventListener(NS_LITERAL_STRING("compositionstart"),
|
|
|
|
this, true);
|
|
|
|
aContent->AddSystemEventListener(NS_LITERAL_STRING("compositionend"), this,
|
|
|
|
true);
|
|
|
|
aContent->AddSystemEventListener(NS_LITERAL_STRING("text"), this, true);
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2014-07-11 22:41:41 +00:00
|
|
|
return NS_OK;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
void* nsPluginInstanceOwner::GetPluginPort()
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
2013-10-23 20:34:30 +00:00
|
|
|
void* result = nullptr;
|
2011-06-01 04:37:54 +00:00
|
|
|
if (mWidget) {
|
|
|
|
#ifdef XP_WIN
|
2016-04-21 19:02:08 +00:00
|
|
|
if (!mPluginWindow || mPluginWindow->type == NPWindowTypeWindow)
|
2011-06-01 04:37:54 +00:00
|
|
|
#endif
|
2014-11-12 20:59:20 +00:00
|
|
|
result = mWidget->GetNativeData(NS_NATIVE_PLUGIN_PORT); // HWND/gdk window
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
2014-12-11 14:44:07 +00:00
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsPluginInstanceOwner::ReleasePluginPort(void * pluginPort)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(mPluginWindow, NS_ERROR_NULL_POINTER);
|
|
|
|
|
2012-02-17 02:27:37 +00:00
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
// Can't call this twice!
|
|
|
|
if (mWidget) {
|
|
|
|
NS_WARNING("Trying to create a plugin widget twice!");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
bool windowless = false;
|
|
|
|
mInstance->IsWindowless(&windowless);
|
2014-11-12 20:59:20 +00:00
|
|
|
if (!windowless) {
|
2012-01-31 21:55:54 +00:00
|
|
|
// Try to get a parent widget, on some platforms widget creation will fail without
|
|
|
|
// a parent.
|
|
|
|
nsCOMPtr<nsIWidget> parentWidget;
|
2012-07-30 14:20:58 +00:00
|
|
|
nsIDocument *doc = nullptr;
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
|
|
|
|
if (content) {
|
|
|
|
doc = content->OwnerDoc();
|
2012-01-31 21:55:54 +00:00
|
|
|
parentWidget = nsContentUtils::WidgetForDocument(doc);
|
2014-11-12 20:59:20 +00:00
|
|
|
#ifndef XP_MACOSX
|
|
|
|
// If we're running in the content process, we need a remote widget created in chrome.
|
2015-07-04 01:29:00 +00:00
|
|
|
if (XRE_IsContentProcess()) {
|
2016-01-30 17:05:36 +00:00
|
|
|
if (nsCOMPtr<nsPIDOMWindowOuter> window = doc->GetWindow()) {
|
|
|
|
if (nsCOMPtr<nsPIDOMWindowOuter> topWindow = window->GetTop()) {
|
2014-11-12 20:59:20 +00:00
|
|
|
dom::TabChild* tc = dom::TabChild::GetFrom(topWindow);
|
|
|
|
if (tc) {
|
|
|
|
// This returns a PluginWidgetProxy which remotes a number of calls.
|
2015-02-05 21:48:44 +00:00
|
|
|
rv = tc->CreatePluginWidget(parentWidget.get(), getter_AddRefs(mWidget));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2014-11-12 20:59:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // XP_MACOSX
|
2012-01-31 21:55:54 +00:00
|
|
|
}
|
2015-07-06 18:10:46 +00:00
|
|
|
|
|
|
|
#ifndef XP_MACOSX
|
|
|
|
// A failure here is terminal since we can't fall back on the non-e10s code
|
|
|
|
// path below.
|
|
|
|
if (!mWidget && XRE_IsContentProcess()) {
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
#endif // XP_MACOSX
|
|
|
|
|
2014-11-12 20:59:20 +00:00
|
|
|
if (!mWidget) {
|
|
|
|
// native (single process)
|
|
|
|
mWidget = do_CreateInstance(kWidgetCID, &rv);
|
|
|
|
nsWidgetInitData initData;
|
|
|
|
initData.mWindowType = eWindowType_plugin;
|
|
|
|
initData.mUnicode = false;
|
|
|
|
initData.clipChildren = true;
|
|
|
|
initData.clipSiblings = true;
|
2015-11-16 08:35:18 +00:00
|
|
|
rv = mWidget->Create(parentWidget.get(), nullptr,
|
|
|
|
LayoutDeviceIntRect(0, 0, 0, 0), &initData);
|
2014-11-12 20:59:20 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
mWidget->Destroy();
|
|
|
|
mWidget = nullptr;
|
|
|
|
return rv;
|
|
|
|
}
|
2012-01-31 21:55:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
mWidget->EnableDragDrop(true);
|
|
|
|
mWidget->Show(false);
|
|
|
|
mWidget->Enable(false);
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2014-09-24 04:35:00 +00:00
|
|
|
if (mPluginFrame) {
|
2013-10-23 20:34:30 +00:00
|
|
|
// nullptr widget is fine, will result in windowless setup.
|
2014-09-24 04:35:00 +00:00
|
|
|
mPluginFrame->PrepForDrawing(mWidget);
|
2012-01-31 21:55:54 +00:00
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
if (windowless) {
|
|
|
|
mPluginWindow->type = NPWindowTypeDrawable;
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
// this needs to be a HDC according to the spec, but I do
|
|
|
|
// not see the right way to release it so let's postpone
|
|
|
|
// passing HDC till paint event when it is really
|
|
|
|
// needed. Change spec?
|
2012-07-30 14:20:58 +00:00
|
|
|
mPluginWindow->window = nullptr;
|
2012-01-31 21:55:54 +00:00
|
|
|
#ifdef MOZ_X11
|
|
|
|
// Fill in the display field.
|
2014-07-11 22:41:41 +00:00
|
|
|
NPSetWindowCallbackStruct* ws_info =
|
2012-01-31 21:55:54 +00:00
|
|
|
static_cast<NPSetWindowCallbackStruct*>(mPluginWindow->ws_info);
|
|
|
|
ws_info->display = DefaultXDisplay();
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString description;
|
2012-01-31 21:55:54 +00:00
|
|
|
GetPluginDescription(description);
|
|
|
|
NS_NAMED_LITERAL_CSTRING(flash10Head, "Shockwave Flash 10.");
|
|
|
|
mFlash10Quirks = StringBeginsWith(description, flash10Head);
|
|
|
|
#endif
|
|
|
|
} else if (mWidget) {
|
|
|
|
// mPluginWindow->type is used in |GetPluginPort| so it must
|
|
|
|
// be initialized first
|
|
|
|
mPluginWindow->type = NPWindowTypeWindow;
|
2014-12-11 14:44:07 +00:00
|
|
|
mPluginWindow->window = GetPluginPort();
|
2012-01-31 21:55:54 +00:00
|
|
|
// tell the plugin window about the widget
|
|
|
|
mPluginWindow->SetPluginWidget(mWidget);
|
2014-07-11 22:41:41 +00:00
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
// tell the widget about the current plugin instance owner.
|
|
|
|
nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
|
|
|
|
if (pluginWidget) {
|
|
|
|
pluginWidget->SetPluginInstanceOwner(this);
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
#ifdef XP_MACOSX
|
|
|
|
if (GetDrawingModel() == NPDrawingModelCoreAnimation) {
|
|
|
|
AddToCARefreshTimer();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
mWidgetCreationComplete = true;
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
return NS_OK;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Mac specific code to fix up the port location and clipping region
|
|
|
|
#ifdef XP_MACOSX
|
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
void nsPluginInstanceOwner::FixUpPluginWindow(int32_t inPaintState)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
2014-12-11 14:44:07 +00:00
|
|
|
if (!mPluginWindow || !mInstance || !mPluginFrame) {
|
|
|
|
return;
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2015-10-28 17:50:45 +00:00
|
|
|
SetPluginPort();
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2015-12-02 22:32:55 +00:00
|
|
|
LayoutDeviceIntSize widgetClip = mPluginFrame->GetWidgetlessClipRect().Size();
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
mPluginWindow->x = 0;
|
|
|
|
mPluginWindow->y = 0;
|
2012-08-30 19:10:55 +00:00
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
NPRect oldClipRect = mPluginWindow->clipRect;
|
2014-05-16 19:52:45 +00:00
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
// fix up the clipping region
|
2014-12-11 14:44:07 +00:00
|
|
|
mPluginWindow->clipRect.top = 0;
|
|
|
|
mPluginWindow->clipRect.left = 0;
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
if (inPaintState == ePluginPaintDisable) {
|
2011-06-01 04:37:54 +00:00
|
|
|
mPluginWindow->clipRect.bottom = mPluginWindow->clipRect.top;
|
|
|
|
mPluginWindow->clipRect.right = mPluginWindow->clipRect.left;
|
|
|
|
}
|
2015-07-04 01:29:00 +00:00
|
|
|
else if (!XRE_IsParentProcess())
|
2014-05-16 19:52:45 +00:00
|
|
|
{
|
|
|
|
// For e10s we only support async windowless plugin. This means that
|
|
|
|
// we're always going to allocate a full window for the plugin to draw
|
|
|
|
// for even if the plugin is mostly outside of the scroll port. Thus
|
|
|
|
// we never trim the window to the bounds of the widget.
|
|
|
|
mPluginWindow->clipRect.bottom = mPluginWindow->clipRect.top + mPluginWindow->height;
|
|
|
|
mPluginWindow->clipRect.right = mPluginWindow->clipRect.left + mPluginWindow->width;
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
else if (inPaintState == ePluginPaintEnable)
|
|
|
|
{
|
|
|
|
mPluginWindow->clipRect.bottom = mPluginWindow->clipRect.top + widgetClip.height;
|
2014-05-16 19:52:45 +00:00
|
|
|
mPluginWindow->clipRect.right = mPluginWindow->clipRect.left + widgetClip.width;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// if the clip rect changed, call SetWindow()
|
|
|
|
// (RealPlayer needs this to draw correctly)
|
|
|
|
if (mPluginWindow->clipRect.left != oldClipRect.left ||
|
|
|
|
mPluginWindow->clipRect.top != oldClipRect.top ||
|
|
|
|
mPluginWindow->clipRect.right != oldClipRect.right ||
|
2014-12-11 14:44:07 +00:00
|
|
|
mPluginWindow->clipRect.bottom != oldClipRect.bottom)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
2012-01-31 21:55:54 +00:00
|
|
|
if (UseAsyncRendering()) {
|
|
|
|
mInstance->AsyncSetWindow(mPluginWindow);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mPluginWindow->CallSetWindow(mInstance);
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// After the first NPP_SetWindow call we need to send an initial
|
|
|
|
// top-level window focus event.
|
2012-10-15 12:38:34 +00:00
|
|
|
if (!mSentInitialTopLevelWindowEvent) {
|
2011-06-01 04:37:54 +00:00
|
|
|
// Set this before calling ProcessEvent to avoid endless recursion.
|
2011-09-30 06:02:59 +00:00
|
|
|
mSentInitialTopLevelWindowEvent = true;
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
bool isActive = WindowIsActive();
|
|
|
|
SendWindowFocusChanged(isActive);
|
|
|
|
mLastWindowIsActive = isActive;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
2014-12-11 14:44:07 +00:00
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2014-12-11 14:44:07 +00:00
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::WindowFocusMayHaveChanged()
|
|
|
|
{
|
|
|
|
if (!mSentInitialTopLevelWindowEvent) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isActive = WindowIsActive();
|
|
|
|
if (isActive != mLastWindowIsActive) {
|
|
|
|
SendWindowFocusChanged(isActive);
|
|
|
|
mLastWindowIsActive = isActive;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
nsPluginInstanceOwner::WindowIsActive()
|
|
|
|
{
|
|
|
|
if (!mPluginFrame) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
EventStates docState = mPluginFrame->GetContent()->OwnerDoc()->GetDocumentState();
|
|
|
|
return !docState.HasState(NS_DOCUMENT_STATE_WINDOW_INACTIVE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::SendWindowFocusChanged(bool aIsActive)
|
|
|
|
{
|
|
|
|
if (!mInstance) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
NPCocoaEvent cocoaEvent;
|
|
|
|
InitializeNPCocoaEvent(&cocoaEvent);
|
|
|
|
cocoaEvent.type = NPCocoaEventWindowFocusChanged;
|
|
|
|
cocoaEvent.data.focus.hasFocus = aIsActive;
|
|
|
|
mInstance->HandleEvent(&cocoaEvent,
|
|
|
|
nullptr,
|
|
|
|
NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
|
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::HidePluginWindow()
|
|
|
|
{
|
|
|
|
if (!mPluginWindow || !mInstance) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mPluginWindow->clipRect.bottom = mPluginWindow->clipRect.top;
|
|
|
|
mPluginWindow->clipRect.right = mPluginWindow->clipRect.left;
|
2011-09-30 06:02:59 +00:00
|
|
|
mWidgetVisible = false;
|
2012-01-31 21:55:54 +00:00
|
|
|
if (UseAsyncRendering()) {
|
2011-05-19 21:08:14 +00:00
|
|
|
mInstance->AsyncSetWindow(mPluginWindow);
|
|
|
|
} else {
|
|
|
|
mInstance->SetWindow(mPluginWindow);
|
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#else // XP_MACOSX
|
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
void nsPluginInstanceOwner::UpdateWindowPositionAndClipRect(bool aSetWindow)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
if (!mPluginWindow)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// For windowless plugins a non-empty clip rectangle will be
|
|
|
|
// passed to the plugin during paint, an additional update
|
|
|
|
// of the the clip rectangle here is not required
|
|
|
|
if (aSetWindow && !mWidget && mPluginWindowVisible && !UseAsyncRendering())
|
|
|
|
return;
|
|
|
|
|
|
|
|
const NPWindow oldWindow = *mPluginWindow;
|
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
bool windowless = (mPluginWindow->type == NPWindowTypeDrawable);
|
2014-09-24 04:35:00 +00:00
|
|
|
nsIntPoint origin = mPluginFrame->GetWindowOriginInPixels(windowless);
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
mPluginWindow->x = origin.x;
|
|
|
|
mPluginWindow->y = origin.y;
|
|
|
|
|
|
|
|
mPluginWindow->clipRect.left = 0;
|
|
|
|
mPluginWindow->clipRect.top = 0;
|
|
|
|
|
2011-08-18 20:08:38 +00:00
|
|
|
if (mPluginWindowVisible && mPluginDocumentActiveState) {
|
2011-06-01 04:37:54 +00:00
|
|
|
mPluginWindow->clipRect.right = mPluginWindow->width;
|
|
|
|
mPluginWindow->clipRect.bottom = mPluginWindow->height;
|
|
|
|
} else {
|
|
|
|
mPluginWindow->clipRect.right = 0;
|
|
|
|
mPluginWindow->clipRect.bottom = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!aSetWindow)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (mPluginWindow->x != oldWindow.x ||
|
|
|
|
mPluginWindow->y != oldWindow.y ||
|
|
|
|
mPluginWindow->clipRect.left != oldWindow.clipRect.left ||
|
|
|
|
mPluginWindow->clipRect.top != oldWindow.clipRect.top ||
|
|
|
|
mPluginWindow->clipRect.right != oldWindow.clipRect.right ||
|
|
|
|
mPluginWindow->clipRect.bottom != oldWindow.clipRect.bottom) {
|
|
|
|
CallSetWindow();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-19 21:08:14 +00:00
|
|
|
void
|
2011-09-29 06:19:26 +00:00
|
|
|
nsPluginInstanceOwner::UpdateWindowVisibility(bool aVisible)
|
2011-05-19 21:08:14 +00:00
|
|
|
{
|
|
|
|
mPluginWindowVisible = aVisible;
|
2011-09-30 06:02:59 +00:00
|
|
|
UpdateWindowPositionAndClipRect(true);
|
2011-05-19 21:08:14 +00:00
|
|
|
}
|
2014-11-12 20:59:20 +00:00
|
|
|
#endif // XP_MACOSX
|
2011-05-19 21:08:14 +00:00
|
|
|
|
2016-03-17 19:00:59 +00:00
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::ResolutionMayHaveChanged()
|
|
|
|
{
|
|
|
|
#ifdef XP_MACOSX
|
|
|
|
double scaleFactor = 1.0;
|
|
|
|
GetContentsScaleFactor(&scaleFactor);
|
|
|
|
if (scaleFactor != mLastScaleFactor) {
|
|
|
|
ContentsScaleFactorChanged(scaleFactor);
|
|
|
|
mLastScaleFactor = scaleFactor;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
float zoomFactor = 1.0;
|
|
|
|
GetCSSZoomFactor(&zoomFactor);
|
|
|
|
if (zoomFactor != mLastCSSZoomFactor) {
|
|
|
|
if (mInstance) {
|
|
|
|
mInstance->CSSZoomFactorChanged(zoomFactor);
|
|
|
|
}
|
|
|
|
mLastCSSZoomFactor = zoomFactor;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-08-18 20:08:38 +00:00
|
|
|
void
|
2011-09-29 06:19:26 +00:00
|
|
|
nsPluginInstanceOwner::UpdateDocumentActiveState(bool aIsActive)
|
2011-08-18 20:08:38 +00:00
|
|
|
{
|
2016-01-15 10:38:03 +00:00
|
|
|
PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
|
|
|
|
|
2011-08-18 20:08:38 +00:00
|
|
|
mPluginDocumentActiveState = aIsActive;
|
2014-11-12 20:59:20 +00:00
|
|
|
#ifndef XP_MACOSX
|
2011-09-30 06:02:59 +00:00
|
|
|
UpdateWindowPositionAndClipRect(true);
|
2012-02-15 20:34:31 +00:00
|
|
|
|
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
|
|
|
if (mInstance) {
|
2014-11-12 20:59:20 +00:00
|
|
|
if (!mPluginDocumentActiveState) {
|
2012-02-15 20:34:31 +00:00
|
|
|
RemovePluginView();
|
2014-11-12 20:59:20 +00:00
|
|
|
}
|
2012-02-15 20:34:31 +00:00
|
|
|
|
|
|
|
mInstance->NotifyOnScreen(mPluginDocumentActiveState);
|
|
|
|
|
|
|
|
// This is, perhaps, incorrect. It is supposed to be sent
|
|
|
|
// when "the webview has paused or resumed". The side effect
|
|
|
|
// is that Flash video players pause or resume (if they were
|
|
|
|
// playing before) based on the value here. I personally think
|
|
|
|
// we want that on Android when switching to another tab, so
|
|
|
|
// that's why we call it here.
|
|
|
|
mInstance->NotifyForeground(mPluginDocumentActiveState);
|
|
|
|
}
|
2014-11-12 20:59:20 +00:00
|
|
|
#endif // #ifdef MOZ_WIDGET_ANDROID
|
|
|
|
|
|
|
|
// We don't have a connection to PluginWidgetParent in the chrome
|
|
|
|
// process when dealing with tab visibility changes, so this needs
|
|
|
|
// to be forwarded over after the active state is updated. If we
|
|
|
|
// don't hide plugin widgets in hidden tabs, the native child window
|
|
|
|
// in chrome will remain visible after a tab switch.
|
2015-07-04 01:29:00 +00:00
|
|
|
if (mWidget && XRE_IsContentProcess()) {
|
2014-11-12 20:59:20 +00:00
|
|
|
mWidget->Show(aIsActive);
|
|
|
|
mWidget->Enable(aIsActive);
|
|
|
|
}
|
|
|
|
#endif // #ifndef XP_MACOSX
|
2011-08-18 20:08:38 +00:00
|
|
|
}
|
2011-05-19 21:08:14 +00:00
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
NS_IMETHODIMP
|
2011-06-01 04:37:54 +00:00
|
|
|
nsPluginInstanceOwner::CallSetWindow()
|
|
|
|
{
|
2014-12-29 23:12:40 +00:00
|
|
|
if (!mWidgetCreationComplete) {
|
|
|
|
// No widget yet, we can't run this code
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2014-09-24 04:35:00 +00:00
|
|
|
if (mPluginFrame) {
|
|
|
|
mPluginFrame->CallSetWindow(false);
|
2012-01-31 21:55:54 +00:00
|
|
|
} else if (mInstance) {
|
|
|
|
if (UseAsyncRendering()) {
|
|
|
|
mInstance->AsyncSetWindow(mPluginWindow);
|
|
|
|
} else {
|
|
|
|
mInstance->SetWindow(mPluginWindow);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-10-02 19:48:05 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginInstanceOwner::GetContentsScaleFactor(double *result)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
|
|
double scaleFactor = 1.0;
|
2012-10-08 10:36:06 +00:00
|
|
|
// On Mac, device pixels need to be translated to (and from) "display pixels"
|
|
|
|
// for plugins. On other platforms, plugin coordinates are always in device
|
|
|
|
// pixels.
|
|
|
|
#if defined(XP_MACOSX)
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
|
|
|
|
nsIPresShell* presShell = nsContentUtils::FindPresShellForDocument(content->OwnerDoc());
|
2012-10-08 11:24:18 +00:00
|
|
|
if (presShell) {
|
|
|
|
scaleFactor = double(nsPresContext::AppUnitsPerCSSPixel())/
|
2014-11-13 11:53:02 +00:00
|
|
|
presShell->GetPresContext()->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom();
|
2012-10-02 19:48:05 +00:00
|
|
|
}
|
2012-10-08 10:36:06 +00:00
|
|
|
#endif
|
2012-10-02 19:48:05 +00:00
|
|
|
*result = scaleFactor;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2016-03-17 19:00:59 +00:00
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::GetCSSZoomFactor(float *result)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
|
|
|
|
nsIPresShell* presShell = nsContentUtils::FindPresShellForDocument(content->OwnerDoc());
|
|
|
|
if (presShell) {
|
|
|
|
*result = presShell->GetPresContext()->DeviceContext()->GetFullZoom();
|
|
|
|
} else {
|
|
|
|
*result = 1.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-24 04:34:00 +00:00
|
|
|
void nsPluginInstanceOwner::SetFrame(nsPluginFrame *aFrame)
|
2012-01-31 21:55:54 +00:00
|
|
|
{
|
|
|
|
// Don't do anything if the frame situation hasn't changed.
|
2014-09-24 04:35:00 +00:00
|
|
|
if (mPluginFrame == aFrame) {
|
2011-06-01 04:37:54 +00:00
|
|
|
return;
|
2012-01-31 21:55:54 +00:00
|
|
|
}
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
|
|
|
|
|
2012-02-21 18:59:38 +00:00
|
|
|
// If we already have a frame that is changing or going away...
|
2014-09-24 04:35:00 +00:00
|
|
|
if (mPluginFrame) {
|
2015-04-04 18:39:36 +00:00
|
|
|
if (content && content->OwnerDoc() && content->OwnerDoc()->GetWindow()) {
|
|
|
|
nsCOMPtr<EventTarget> windowRoot = content->OwnerDoc()->GetWindow()->GetTopWindowRoot();
|
2014-12-11 14:44:07 +00:00
|
|
|
if (windowRoot) {
|
|
|
|
windowRoot->RemoveEventListener(NS_LITERAL_STRING("activate"),
|
|
|
|
this, false);
|
|
|
|
windowRoot->RemoveEventListener(NS_LITERAL_STRING("deactivate"),
|
|
|
|
this, false);
|
|
|
|
windowRoot->RemoveEventListener(NS_LITERAL_STRING("MozPerformDelayedBlur"),
|
|
|
|
this, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
// Make sure the old frame isn't holding a reference to us.
|
2014-09-24 04:35:00 +00:00
|
|
|
mPluginFrame->SetInstanceOwner(nullptr);
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
2012-01-31 21:55:54 +00:00
|
|
|
|
|
|
|
// Swap in the new frame (or no frame)
|
2014-09-24 04:35:00 +00:00
|
|
|
mPluginFrame = aFrame;
|
2012-01-31 21:55:54 +00:00
|
|
|
|
|
|
|
// Set up a new frame
|
2014-09-24 04:35:00 +00:00
|
|
|
if (mPluginFrame) {
|
|
|
|
mPluginFrame->SetInstanceOwner(this);
|
2012-01-31 21:55:54 +00:00
|
|
|
// Can only call PrepForDrawing on an object frame once. Don't do it here unless
|
|
|
|
// widget creation is complete. Doesn't matter if we actually have a widget.
|
|
|
|
if (mWidgetCreationComplete) {
|
2014-09-24 04:35:00 +00:00
|
|
|
mPluginFrame->PrepForDrawing(mWidget);
|
2012-01-31 21:55:54 +00:00
|
|
|
}
|
2014-09-24 04:35:00 +00:00
|
|
|
mPluginFrame->FixupWindow(mPluginFrame->GetContentRectRelativeToSelf().Size());
|
|
|
|
mPluginFrame->InvalidateFrame();
|
2013-04-17 22:11:21 +00:00
|
|
|
|
2012-08-10 18:28:34 +00:00
|
|
|
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
|
|
|
const nsIContent* content = aFrame->GetContent();
|
|
|
|
if (fm && content) {
|
|
|
|
mContentFocused = (content == fm->GetFocusedContent());
|
|
|
|
}
|
2014-12-11 14:44:07 +00:00
|
|
|
|
|
|
|
// Register for widget-focus events on the window root.
|
2015-04-04 18:39:36 +00:00
|
|
|
if (content && content->OwnerDoc() && content->OwnerDoc()->GetWindow()) {
|
|
|
|
nsCOMPtr<EventTarget> windowRoot = content->OwnerDoc()->GetWindow()->GetTopWindowRoot();
|
2014-12-11 14:44:07 +00:00
|
|
|
if (windowRoot) {
|
|
|
|
windowRoot->AddEventListener(NS_LITERAL_STRING("activate"),
|
|
|
|
this, false, false);
|
|
|
|
windowRoot->AddEventListener(NS_LITERAL_STRING("deactivate"),
|
|
|
|
this, false, false);
|
|
|
|
windowRoot->AddEventListener(NS_LITERAL_STRING("MozPerformDelayedBlur"),
|
|
|
|
this, false, false);
|
|
|
|
}
|
|
|
|
}
|
2012-01-31 21:55:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-24 04:34:00 +00:00
|
|
|
nsPluginFrame* nsPluginInstanceOwner::GetFrame()
|
2012-01-31 21:55:54 +00:00
|
|
|
{
|
2014-09-24 04:35:00 +00:00
|
|
|
return mPluginFrame;
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
2012-04-24 04:49:25 +00:00
|
|
|
NS_IMETHODIMP nsPluginInstanceOwner::PrivateModeChanged(bool aEnabled)
|
|
|
|
{
|
|
|
|
return mInstance ? mInstance->PrivateModeStateChanged(aEnabled) : NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-11-27 14:14:38 +00:00
|
|
|
already_AddRefed<nsIURI> nsPluginInstanceOwner::GetBaseURI() const
|
|
|
|
{
|
2015-04-04 18:39:36 +00:00
|
|
|
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
|
|
|
|
if (!content) {
|
2012-11-27 14:14:38 +00:00
|
|
|
return nullptr;
|
|
|
|
}
|
2015-04-04 18:39:36 +00:00
|
|
|
return content->GetBaseURI();
|
2012-11-27 14:14:38 +00:00
|
|
|
}
|
|
|
|
|
2015-12-29 13:57:37 +00:00
|
|
|
// static
|
|
|
|
void
|
|
|
|
nsPluginInstanceOwner::GeneratePluginEvent(
|
|
|
|
const WidgetCompositionEvent* aSrcCompositionEvent,
|
|
|
|
WidgetCompositionEvent* aDistCompositionEvent)
|
|
|
|
{
|
|
|
|
#ifdef XP_WIN
|
|
|
|
NPEvent newEvent;
|
|
|
|
switch (aDistCompositionEvent->mMessage) {
|
|
|
|
case eCompositionChange: {
|
|
|
|
newEvent.event = WM_IME_COMPOSITION;
|
|
|
|
newEvent.wParam = 0;
|
|
|
|
if (aSrcCompositionEvent &&
|
|
|
|
(aSrcCompositionEvent->mMessage == eCompositionCommit ||
|
|
|
|
aSrcCompositionEvent->mMessage == eCompositionCommitAsIs)) {
|
|
|
|
newEvent.lParam = GCS_RESULTSTR;
|
|
|
|
} else {
|
|
|
|
newEvent.lParam = GCS_COMPSTR | GCS_COMPATTR | GCS_COMPCLAUSE;
|
|
|
|
}
|
|
|
|
TextRangeArray* ranges = aDistCompositionEvent->mRanges;
|
|
|
|
if (ranges && ranges->HasCaret()) {
|
|
|
|
newEvent.lParam |= GCS_CURSORPOS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case eCompositionStart:
|
|
|
|
newEvent.event = WM_IME_STARTCOMPOSITION;
|
|
|
|
newEvent.wParam = 0;
|
|
|
|
newEvent.lParam = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eCompositionEnd:
|
|
|
|
newEvent.event = WM_IME_ENDCOMPOSITION;
|
|
|
|
newEvent.wParam = 0;
|
|
|
|
newEvent.lParam = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
aDistCompositionEvent->mPluginEvent.Copy(newEvent);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-06-01 04:37:54 +00:00
|
|
|
// nsPluginDOMContextMenuListener class implementation
|
|
|
|
|
2013-04-19 22:18:32 +00:00
|
|
|
nsPluginDOMContextMenuListener::nsPluginDOMContextMenuListener(nsIContent* aContent)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
2013-04-19 22:18:32 +00:00
|
|
|
aContent->AddEventListener(NS_LITERAL_STRING("contextmenu"), this, true);
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsPluginDOMContextMenuListener::~nsPluginDOMContextMenuListener()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-04-27 07:06:00 +00:00
|
|
|
NS_IMPL_ISUPPORTS(nsPluginDOMContextMenuListener,
|
|
|
|
nsIDOMEventListener)
|
2011-06-01 04:37:54 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2011-08-08 18:26:26 +00:00
|
|
|
nsPluginDOMContextMenuListener::HandleEvent(nsIDOMEvent* aEvent)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
2011-08-08 18:26:26 +00:00
|
|
|
aEvent->PreventDefault(); // consume event
|
2011-06-01 04:37:54 +00:00
|
|
|
|
2013-04-19 22:18:32 +00:00
|
|
|
return NS_OK;
|
2013-04-11 17:59:02 +00:00
|
|
|
}
|
|
|
|
|
2013-04-19 22:18:32 +00:00
|
|
|
void nsPluginDOMContextMenuListener::Destroy(nsIContent* aContent)
|
2011-06-01 04:37:54 +00:00
|
|
|
{
|
|
|
|
// Unregister context menu listener
|
2013-04-19 22:18:32 +00:00
|
|
|
aContent->RemoveEventListener(NS_LITERAL_STRING("contextmenu"), this, true);
|
2011-06-01 04:37:54 +00:00
|
|
|
}
|