1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/DebugOnly.h"
8 #include <stdint.h> // for intptr_t
10 #include "PluginInstanceParent.h"
11 #include "BrowserStreamParent.h"
12 #include "PluginBackgroundDestroyer.h"
13 #include "PluginModuleParent.h"
14 #include "PluginStreamParent.h"
15 #include "StreamNotifyParent.h"
16 #include "npfunctions.h"
17 #include "nsAutoPtr.h"
18 #include "gfxASurface.h"
19 #include "gfxContext.h"
20 #include "gfxPlatform.h"
21 #include "gfxSharedImageSurface.h"
22 #include "nsNPAPIPluginInstance.h"
24 #include "gfxXlibSurface.h"
26 #include "gfxContext.h"
29 #include "mozilla/gfx/2D.h"
31 #include "ImageContainer.h"
32 #include "GLContext.h"
33 #include "GLContextProvider.h"
36 #include "MacIOSurfaceImage.h"
41 #include "gfxWindowsPlatform.h"
42 #include "mozilla/plugins/PluginSurfaceParent.h"
44 // Plugin focus event for widget.
45 extern const wchar_t* kOOPPPluginFocusEventId
;
46 UINT gOOPPPluginFocusEvent
=
47 RegisterWindowMessage(kOOPPPluginFocusEventId
);
48 extern const wchar_t* kFlashFullscreenClass
;
49 #elif defined(MOZ_WIDGET_GTK)
51 #elif defined(XP_MACOSX)
52 #include <ApplicationServices/ApplicationServices.h>
53 #endif // defined(XP_MACOSX)
55 using namespace mozilla::plugins
;
56 using namespace mozilla::layers
;
57 using namespace mozilla::gl
;
60 StreamNotifyParent::ActorDestroy(ActorDestroyReason aWhy
)
62 // Implement me! Bug 1005162
66 StreamNotifyParent::RecvRedirectNotifyResponse(const bool& allow
)
68 PluginInstanceParent
* instance
= static_cast<PluginInstanceParent
*>(Manager());
69 instance
->mNPNIface
->urlredirectresponse(instance
->mNPP
, this, static_cast<NPBool
>(allow
));
73 PluginInstanceParent::PluginInstanceParent(PluginModuleParent
* parent
,
75 const nsCString
& aMimeType
,
76 const NPNetscapeFuncs
* npniface
)
80 , mWindowType(NPWindowTypeWindow
)
81 , mDrawingModel(kDefaultDrawingModel
)
83 , mPluginHWND(nullptr)
84 , mPluginWndProc(nullptr)
85 , mNestedEventState(false)
86 #endif // defined(XP_WIN)
87 #if defined(XP_MACOSX)
90 , mShColorSpace(nullptr)
95 PluginInstanceParent::~PluginInstanceParent()
98 mNPP
->pdata
= nullptr;
101 NS_ASSERTION(!(mPluginHWND
|| mPluginWndProc
),
102 "Subclass was not reset correctly before the dtor was reached!");
104 #if defined(MOZ_WIDGET_COCOA)
105 if (mShWidth
!= 0 && mShHeight
!= 0) {
106 DeallocShmem(mShSurface
);
109 ::CGColorSpaceRelease(mShColorSpace
);
111 if (mRemoteImageDataShmem
.IsWritable()) {
112 if (mImageContainer
) {
113 mImageContainer
->SetRemoteImageData(nullptr, nullptr);
114 mImageContainer
->SetCompositionNotifySink(nullptr);
116 DeallocShmem(mRemoteImageDataShmem
);
121 PluginInstanceParent::Init()
127 PluginInstanceParent::ActorDestroy(ActorDestroyReason why
)
130 if (why
== AbnormalShutdown
) {
131 // If the plugin process crashes, this is the only
132 // chance we get to destroy resources.
133 SharedSurfaceRelease();
134 UnsubclassPluginWindow();
137 // After this method, the data backing the remote surface may no
138 // longer be valid. The X surface may be destroyed, or the shared
139 // memory backing this surface may no longer be valid.
141 mFrontSurface
= nullptr;
142 if (mImageContainer
) {
143 mImageContainer
->SetCurrentImage(nullptr);
146 FinishX(DefaultXDisplay());
152 PluginInstanceParent::Destroy()
155 if (!CallNPP_Destroy(&retval
))
156 retval
= NPERR_GENERIC_ERROR
;
159 SharedSurfaceRelease();
160 UnsubclassPluginWindow();
166 PBrowserStreamParent
*
167 PluginInstanceParent::AllocPBrowserStreamParent(const nsCString
& url
,
168 const uint32_t& length
,
169 const uint32_t& lastmodified
,
170 PStreamNotifyParent
* notifyData
,
171 const nsCString
& headers
,
172 const nsCString
& mimeType
,
173 const bool& seekable
,
177 NS_RUNTIMEABORT("Not reachable");
182 PluginInstanceParent::DeallocPBrowserStreamParent(PBrowserStreamParent
* stream
)
189 PluginInstanceParent::AllocPPluginStreamParent(const nsCString
& mimeType
,
190 const nsCString
& target
,
193 return new PluginStreamParent(this, mimeType
, target
, result
);
197 PluginInstanceParent::DeallocPPluginStreamParent(PPluginStreamParent
* stream
)
204 PluginInstanceParent::AnswerNPN_GetValue_NPNVnetscapeWindow(NativeWindowHandle
* value
,
209 #elif defined(MOZ_X11)
211 #elif defined(XP_MACOSX)
213 #elif defined(ANDROID)
214 // TODO: Need Android impl
216 #elif defined(MOZ_WIDGET_QT)
217 // TODO: Need Qt non X impl
220 #warning Implement me
223 *result
= mNPNIface
->getvalue(mNPP
, NPNVnetscapeWindow
, &id
);
229 PluginInstanceParent::InternalGetValueForNPObject(
230 NPNVariable aVariable
,
231 PPluginScriptableObjectParent
** aValue
,
235 NPError result
= mNPNIface
->getvalue(mNPP
, aVariable
, (void*)&npobject
);
236 if (result
== NPERR_NO_ERROR
) {
237 NS_ASSERTION(npobject
, "Shouldn't return null and NPERR_NO_ERROR!");
239 PluginScriptableObjectParent
* actor
= GetActorForNPObject(npobject
);
240 mNPNIface
->releaseobject(npobject
);
243 *aResult
= NPERR_NO_ERROR
;
247 NS_ERROR("Failed to get actor!");
248 result
= NPERR_GENERIC_ERROR
;
257 PluginInstanceParent::IsAsyncDrawing()
259 return IsDrawingModelAsync(mDrawingModel
);
263 PluginInstanceParent::AnswerNPN_GetValue_NPNVWindowNPObject(
264 PPluginScriptableObjectParent
** aValue
,
267 return InternalGetValueForNPObject(NPNVWindowNPObject
, aValue
, aResult
);
271 PluginInstanceParent::AnswerNPN_GetValue_NPNVPluginElementNPObject(
272 PPluginScriptableObjectParent
** aValue
,
275 return InternalGetValueForNPObject(NPNVPluginElementNPObject
, aValue
,
280 PluginInstanceParent::AnswerNPN_GetValue_NPNVprivateModeBool(bool* value
,
284 *result
= mNPNIface
->getvalue(mNPP
, NPNVprivateModeBool
, &v
);
290 PluginInstanceParent::AnswerNPN_GetValue_DrawingModelSupport(const NPNVariable
& model
, bool* value
)
296 case NPNVsupportsAsyncWindowsDXGISurfaceBool
: {
297 if (gfxWindowsPlatform::GetPlatform()->GetRenderMode() == gfxWindowsPlatform::RENDER_DIRECT2D
) {
308 PluginInstanceParent::AnswerNPN_GetValue_NPNVdocumentOrigin(nsCString
* value
,
312 *result
= mNPNIface
->getvalue(mNPP
, NPNVdocumentOrigin
, &v
);
313 if (*result
== NPERR_NO_ERROR
&& v
) {
314 value
->Adopt(static_cast<char*>(v
));
320 PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginWindow(
321 const bool& windowed
, NPError
* result
)
323 // Yes, we are passing a boolean as a void*. We have to cast to intptr_t
324 // first to avoid gcc warnings about casting to a pointer from a
325 // non-pointer-sized integer.
326 *result
= mNPNIface
->setvalue(mNPP
, NPPVpluginWindowBool
,
327 (void*)(intptr_t)windowed
);
332 PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginTransparent(
333 const bool& transparent
, NPError
* result
)
335 *result
= mNPNIface
->setvalue(mNPP
, NPPVpluginTransparentBool
,
336 (void*)(intptr_t)transparent
);
341 PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginUsesDOMForCursor(
342 const bool& useDOMForCursor
, NPError
* result
)
344 *result
= mNPNIface
->setvalue(mNPP
, NPPVpluginUsesDOMForCursorBool
,
345 (void*)(intptr_t)useDOMForCursor
);
349 class NotificationSink
: public CompositionNotifySink
352 NotificationSink(PluginInstanceParent
*aInstance
) : mInstance(aInstance
)
355 virtual void DidComposite() { mInstance
->DidComposite(); }
357 PluginInstanceParent
*mInstance
;
361 PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginDrawingModel(
362 const int& drawingModel
, OptionalShmem
*shmem
, CrossProcessMutexHandle
*mutex
, NPError
* result
)
367 if (drawingModel
== NPDrawingModelCoreAnimation
||
368 drawingModel
== NPDrawingModelInvalidatingCoreAnimation
) {
369 // We need to request CoreGraphics otherwise
370 // the nsObjectFrame will try to draw a CALayer
371 // that can not be shared across process.
372 mDrawingModel
= drawingModel
;
373 *result
= mNPNIface
->setvalue(mNPP
, NPPVpluginDrawingModel
,
374 (void*)NPDrawingModelCoreGraphics
);
377 if (drawingModel
== NPDrawingModelAsyncBitmapSurface
379 || drawingModel
== NPDrawingModelAsyncWindowsDXGISurface
382 ImageContainer
*container
= GetImageContainer();
384 *result
= NPERR_GENERIC_ERROR
;
389 if (drawingModel
== NPDrawingModelAsyncWindowsDXGISurface
&&
390 gfxWindowsPlatform::GetPlatform()->GetRenderMode() != gfxWindowsPlatform::RENDER_DIRECT2D
) {
391 *result
= NPERR_GENERIC_ERROR
;
396 mDrawingModel
= drawingModel
;
397 *result
= mNPNIface
->setvalue(mNPP
, NPPVpluginDrawingModel
,
398 reinterpret_cast<void*>(static_cast<uintptr_t>(drawingModel
)));
401 if (*result
!= NPERR_NO_ERROR
) {
405 AllocUnsafeShmem(sizeof(RemoteImageData
), SharedMemory::TYPE_BASIC
, &mRemoteImageDataShmem
);
407 *shmem
= mRemoteImageDataShmem
;
409 mRemoteImageDataMutex
= new CrossProcessMutex("PluginInstanceParent.mRemoteImageDataMutex");
411 *mutex
= mRemoteImageDataMutex
->ShareToProcess(OtherProcess());
412 container
->SetRemoteImageData(mRemoteImageDataShmem
.get
<RemoteImageData
>(), mRemoteImageDataMutex
);
414 mNotifySink
= new NotificationSink(this);
416 container
->SetCompositionNotifySink(mNotifySink
);
419 drawingModel
== NPDrawingModelSyncWin
420 #elif defined(XP_MACOSX)
421 drawingModel
== NPDrawingModelOpenGL
||
422 drawingModel
== NPDrawingModelCoreGraphics
423 #elif defined(MOZ_X11)
424 drawingModel
== NPDrawingModelSyncX
431 mDrawingModel
= drawingModel
;
432 *result
= mNPNIface
->setvalue(mNPP
, NPPVpluginDrawingModel
,
433 (void*)(intptr_t)drawingModel
);
435 if (mRemoteImageDataShmem
.IsWritable()) {
436 if (mImageContainer
) {
437 mImageContainer
->SetRemoteImageData(nullptr, nullptr);
438 mImageContainer
->SetCompositionNotifySink(nullptr);
440 DeallocShmem(mRemoteImageDataShmem
);
441 mRemoteImageDataMutex
= nullptr;
444 *result
= NPERR_GENERIC_ERROR
;
450 PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginEventModel(
451 const int& eventModel
, NPError
* result
)
454 *result
= mNPNIface
->setvalue(mNPP
, NPPVpluginEventModel
,
455 (void*)(intptr_t)eventModel
);
458 *result
= NPERR_GENERIC_ERROR
;
464 PluginInstanceParent::AnswerNPN_GetURL(const nsCString
& url
,
465 const nsCString
& target
,
468 *result
= mNPNIface
->geturl(mNPP
,
469 NullableStringGet(url
),
470 NullableStringGet(target
));
475 PluginInstanceParent::AnswerNPN_PostURL(const nsCString
& url
,
476 const nsCString
& target
,
477 const nsCString
& buffer
,
481 *result
= mNPNIface
->posturl(mNPP
, url
.get(), NullableStringGet(target
),
482 buffer
.Length(), buffer
.get(), file
);
487 PluginInstanceParent::AllocPStreamNotifyParent(const nsCString
& url
,
488 const nsCString
& target
,
490 const nsCString
& buffer
,
494 return new StreamNotifyParent();
498 PluginInstanceParent::AnswerPStreamNotifyConstructor(PStreamNotifyParent
* actor
,
499 const nsCString
& url
,
500 const nsCString
& target
,
502 const nsCString
& buffer
,
506 bool streamDestroyed
= false;
507 static_cast<StreamNotifyParent
*>(actor
)->
508 SetDestructionFlag(&streamDestroyed
);
511 *result
= mNPNIface
->geturlnotify(mNPP
,
512 NullableStringGet(url
),
513 NullableStringGet(target
),
517 *result
= mNPNIface
->posturlnotify(mNPP
,
518 NullableStringGet(url
),
519 NullableStringGet(target
),
521 NullableStringGet(buffer
),
525 if (streamDestroyed
) {
526 // If the stream was destroyed, we must return an error code in the
528 *result
= NPERR_GENERIC_ERROR
;
531 static_cast<StreamNotifyParent
*>(actor
)->ClearDestructionFlag();
532 if (*result
!= NPERR_NO_ERROR
)
533 return PStreamNotifyParent::Send__delete__(actor
,
534 NPERR_GENERIC_ERROR
);
541 PluginInstanceParent::DeallocPStreamNotifyParent(PStreamNotifyParent
* notifyData
)
548 PluginInstanceParent::RecvNPN_InvalidateRect(const NPRect
& rect
)
550 mNPNIface
->invalidaterect(mNPP
, const_cast<NPRect
*>(&rect
));
555 PluginInstanceParent::RecvShow(const NPRect
& updatedRect
,
556 const SurfaceDescriptor
& newSurface
,
557 SurfaceDescriptor
* prevSurface
)
560 ("[InstanceParent][%p] RecvShow for <x=%d,y=%d, w=%d,h=%d>",
561 this, updatedRect
.left
, updatedRect
.top
,
562 updatedRect
.right
- updatedRect
.left
,
563 updatedRect
.bottom
- updatedRect
.top
));
565 // XXXjwatt rewrite to use Moz2D
566 nsRefPtr
<gfxASurface
> surface
;
567 if (newSurface
.type() == SurfaceDescriptor::TShmem
) {
568 if (!newSurface
.get_Shmem().IsReadable()) {
569 NS_WARNING("back surface not readable");
572 surface
= gfxSharedImageSurface::Open(newSurface
.get_Shmem());
575 else if (newSurface
.type() == SurfaceDescriptor::TIOSurfaceDescriptor
) {
576 IOSurfaceDescriptor iodesc
= newSurface
.get_IOSurfaceDescriptor();
578 RefPtr
<MacIOSurface
> newIOSurface
=
579 MacIOSurface::LookupSurface(iodesc
.surfaceId(),
580 iodesc
.contentsScaleFactor());
583 NS_WARNING("Got bad IOSurfaceDescriptor in RecvShow");
588 *prevSurface
= IOSurfaceDescriptor(mFrontIOSurface
->GetIOSurfaceID(),
589 mFrontIOSurface
->GetContentsScaleFactor());
591 *prevSurface
= null_t();
593 mFrontIOSurface
= newIOSurface
;
595 RecvNPN_InvalidateRect(updatedRect
);
597 PLUGIN_LOG_DEBUG((" (RecvShow invalidated for surface %p)",
598 mFrontSurface
.get()));
604 else if (newSurface
.type() == SurfaceDescriptor::TSurfaceDescriptorX11
) {
605 surface
= newSurface
.get_SurfaceDescriptorX11().OpenForeign();
609 else if (newSurface
.type() == SurfaceDescriptor::TPPluginSurfaceParent
) {
610 PluginSurfaceParent
* s
=
611 static_cast<PluginSurfaceParent
*>(newSurface
.get_PPluginSurfaceParent());
612 surface
= s
->Surface();
617 // This is the "old front buffer" we're about to hand back to
618 // the plugin. We might still have drawing operations
621 if (mFrontSurface
->GetType() == gfxSurfaceType::Xlib
) {
622 // Finish with the surface and XSync here to ensure the server has
623 // finished operations on the surface before the plugin starts
624 // scribbling on it again, or worse, destroys it.
625 mFrontSurface
->Finish();
626 FinishX(DefaultXDisplay());
630 mFrontSurface
->Flush();
634 if (mFrontSurface
&& gfxSharedImageSurface::IsSharedImage(mFrontSurface
))
635 *prevSurface
= static_cast<gfxSharedImageSurface
*>(mFrontSurface
.get())->GetShmem();
637 *prevSurface
= null_t();
640 // Notify the cairo backend that this surface has changed behind
642 gfxRect
ur(updatedRect
.left
, updatedRect
.top
,
643 updatedRect
.right
- updatedRect
.left
,
644 updatedRect
.bottom
- updatedRect
.top
);
645 surface
->MarkDirty(ur
);
647 ImageContainer
*container
= GetImageContainer();
648 nsRefPtr
<Image
> image
= container
->CreateImage(ImageFormat::CAIRO_SURFACE
);
649 NS_ASSERTION(image
->GetFormat() == ImageFormat::CAIRO_SURFACE
, "Wrong format?");
650 CairoImage
* cairoImage
= static_cast<CairoImage
*>(image
.get());
651 CairoImage::Data cairoData
;
652 cairoData
.mSize
= surface
->GetSize().ToIntSize();
653 cairoData
.mSourceSurface
= gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, surface
);
654 cairoImage
->SetData(cairoData
);
656 container
->SetCurrentImage(cairoImage
);
658 else if (mImageContainer
) {
659 mImageContainer
->SetCurrentImage(nullptr);
662 mFrontSurface
= surface
;
663 RecvNPN_InvalidateRect(updatedRect
);
665 PLUGIN_LOG_DEBUG((" (RecvShow invalidated for surface %p)",
666 mFrontSurface
.get()));
672 PluginInstanceParent::AsyncSetWindow(NPWindow
* aWindow
)
674 NPRemoteWindow window
;
675 mWindowType
= aWindow
->type
;
676 window
.window
= reinterpret_cast<uint64_t>(aWindow
->window
);
677 window
.x
= aWindow
->x
;
678 window
.y
= aWindow
->y
;
679 window
.width
= aWindow
->width
;
680 window
.height
= aWindow
->height
;
681 window
.clipRect
= aWindow
->clipRect
;
682 window
.type
= aWindow
->type
;
684 double scaleFactor
= 1.0;
685 mNPNIface
->getvalue(mNPP
, NPNVcontentsScaleFactor
, &scaleFactor
);
686 window
.contentsScaleFactor
= scaleFactor
;
688 if (!SendAsyncSetWindow(gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType(),
690 return NS_ERROR_FAILURE
;
696 PluginInstanceParent::GetImageContainer(ImageContainer
** aContainer
)
699 MacIOSurface
* ioSurface
= nullptr;
701 if (mFrontIOSurface
) {
702 ioSurface
= mFrontIOSurface
;
703 } else if (mIOSurface
) {
704 ioSurface
= mIOSurface
;
707 if (!mFrontSurface
&& !ioSurface
)
711 return NS_ERROR_NOT_AVAILABLE
;
713 ImageContainer
*container
= GetImageContainer();
716 return NS_ERROR_FAILURE
;
719 if (IsAsyncDrawing()) {
720 NS_IF_ADDREF(container
);
721 *aContainer
= container
;
727 nsRefPtr
<Image
> image
= container
->CreateImage(ImageFormat::MAC_IOSURFACE
);
729 return NS_ERROR_FAILURE
;
732 NS_ASSERTION(image
->GetFormat() == ImageFormat::MAC_IOSURFACE
, "Wrong format?");
734 MacIOSurfaceImage
* pluginImage
= static_cast<MacIOSurfaceImage
*>(image
.get());
735 pluginImage
->SetSurface(ioSurface
);
737 container
->SetCurrentImageInTransaction(pluginImage
);
739 NS_IF_ADDREF(container
);
740 *aContainer
= container
;
745 NS_IF_ADDREF(container
);
746 *aContainer
= container
;
751 PluginInstanceParent::GetImageSize(nsIntSize
* aSize
)
754 gfxIntSize size
= mFrontSurface
->GetSize();
755 *aSize
= nsIntSize(size
.width
, size
.height
);
760 if (mFrontIOSurface
) {
761 *aSize
= nsIntSize(mFrontIOSurface
->GetWidth(), mFrontIOSurface
->GetHeight());
763 } else if (mIOSurface
) {
764 *aSize
= nsIntSize(mIOSurface
->GetWidth(), mIOSurface
->GetHeight());
769 return NS_ERROR_NOT_AVAILABLE
;
774 PluginInstanceParent::IsRemoteDrawingCoreAnimation(bool *aDrawing
)
776 *aDrawing
= (NPDrawingModelCoreAnimation
== (NPDrawingModel
)mDrawingModel
||
777 NPDrawingModelInvalidatingCoreAnimation
== (NPDrawingModel
)mDrawingModel
);
782 PluginInstanceParent::ContentsScaleFactorChanged(double aContentsScaleFactor
)
784 bool rv
= SendContentsScaleFactorChanged(aContentsScaleFactor
);
785 return rv
? NS_OK
: NS_ERROR_FAILURE
;
787 #endif // #ifdef XP_MACOSX
790 PluginInstanceParent::SetBackgroundUnknown()
792 PLUGIN_LOG_DEBUG(("[InstanceParent][%p] SetBackgroundUnknown", this));
796 NS_ABORT_IF_FALSE(!mBackground
, "Background not destroyed");
803 PluginInstanceParent::BeginUpdateBackground(const nsIntRect
& aRect
,
807 ("[InstanceParent][%p] BeginUpdateBackground for <x=%d,y=%d, w=%d,h=%d>",
808 this, aRect
.x
, aRect
.y
, aRect
.width
, aRect
.height
));
811 // XXX if we failed to create a background surface on one
812 // update, there's no guarantee that later updates will be for
813 // the entire background area until successful. We might want
814 // to fix that eventually.
815 NS_ABORT_IF_FALSE(aRect
.TopLeft() == nsIntPoint(0, 0),
816 "Expecting rect for whole frame");
817 if (!CreateBackground(aRect
.Size())) {
823 gfxIntSize sz
= mBackground
->GetSize();
825 NS_ABORT_IF_FALSE(nsIntRect(0, 0, sz
.width
, sz
.height
).Contains(aRect
),
826 "Update outside of background area");
829 RefPtr
<gfx::DrawTarget
> dt
= gfxPlatform::GetPlatform()->
830 CreateDrawTargetForSurface(mBackground
, gfx::IntSize(sz
.width
, sz
.height
));
831 nsRefPtr
<gfxContext
> ctx
= new gfxContext(dt
);
838 PluginInstanceParent::EndUpdateBackground(gfxContext
* aCtx
,
839 const nsIntRect
& aRect
)
842 ("[InstanceParent][%p] EndUpdateBackground for <x=%d,y=%d, w=%d,h=%d>",
843 this, aRect
.x
, aRect
.y
, aRect
.width
, aRect
.height
));
846 // Have to XSync here to avoid the plugin trying to draw with this
847 // surface racing with its creation in the X server. We also want
848 // to avoid the plugin drawing onto stale pixels, then handing us
849 // back a front surface from those pixels that we might
850 // recomposite for "a while" until the next update. This XSync
851 // still doesn't guarantee that the plugin draws onto a consistent
852 // view of its background, but it does mean that the plugin is
853 // drawing onto pixels no older than those in the latest
854 // EndUpdateBackground().
855 XSync(DefaultXDisplay(), False
);
858 unused
<< SendUpdateBackground(BackgroundDescriptor(), aRect
);
864 PluginInstanceParent::CreateBackground(const nsIntSize
& aSize
)
866 NS_ABORT_IF_FALSE(!mBackground
, "Already have a background");
871 Screen
* screen
= DefaultScreenOfDisplay(DefaultXDisplay());
872 Visual
* visual
= DefaultVisualOfScreen(screen
);
873 mBackground
= gfxXlibSurface::Create(screen
, visual
,
874 gfxIntSize(aSize
.width
, aSize
.height
));
875 return !!mBackground
;
877 #elif defined(XP_WIN)
878 // We have chosen to create an unsafe surface in which the plugin
879 // can read from the region while we're writing to it.
881 gfxSharedImageSurface::CreateUnsafe(
883 gfxIntSize(aSize
.width
, aSize
.height
),
884 gfxImageFormat::RGB24
);
885 return !!mBackground
;
892 PluginInstanceParent::DestroyBackground()
898 // Relinquish ownership of |mBackground| to its destroyer
899 PPluginBackgroundDestroyerParent
* pbd
=
900 new PluginBackgroundDestroyerParent(mBackground
);
901 mBackground
= nullptr;
903 // If this fails, there's no problem: |bd| will be destroyed along
904 // with the old background surface.
905 unused
<< SendPPluginBackgroundDestroyerConstructor(pbd
);
908 mozilla::plugins::SurfaceDescriptor
909 PluginInstanceParent::BackgroundDescriptor()
911 NS_ABORT_IF_FALSE(mBackground
, "Need a background here");
916 gfxXlibSurface
* xsurf
= static_cast<gfxXlibSurface
*>(mBackground
.get());
917 return SurfaceDescriptorX11(xsurf
);
921 NS_ABORT_IF_FALSE(gfxSharedImageSurface::IsSharedImage(mBackground
),
922 "Expected shared image surface");
923 gfxSharedImageSurface
* shmem
=
924 static_cast<gfxSharedImageSurface
*>(mBackground
.get());
925 return shmem
->GetShmem();
928 // If this is ever used, which it shouldn't be, it will trigger a
929 // hard assertion in IPDL-generated code.
930 return mozilla::plugins::SurfaceDescriptor();
934 PluginInstanceParent::GetImageContainer()
936 if (mImageContainer
) {
937 return mImageContainer
;
940 mImageContainer
= LayerManager::CreateImageContainer();
941 return mImageContainer
;
944 PPluginBackgroundDestroyerParent
*
945 PluginInstanceParent::AllocPPluginBackgroundDestroyerParent()
947 NS_RUNTIMEABORT("'Power-user' ctor is used exclusively");
952 PluginInstanceParent::DeallocPPluginBackgroundDestroyerParent(
953 PPluginBackgroundDestroyerParent
* aActor
)
960 PluginInstanceParent::NPP_SetWindow(const NPWindow
* aWindow
)
962 PLUGIN_LOG_DEBUG(("%s (aWindow=%p)", FULLFUNCTION
, (void*) aWindow
));
964 NS_ENSURE_TRUE(aWindow
, NPERR_GENERIC_ERROR
);
966 NPRemoteWindow window
;
967 mWindowType
= aWindow
->type
;
970 // On windowless controls, reset the shared memory surface as needed.
971 if (mWindowType
== NPWindowTypeDrawable
) {
972 // SharedSurfaceSetWindow will take care of NPRemoteWindow.
973 if (!SharedSurfaceSetWindow(aWindow
, window
)) {
974 return NPERR_OUT_OF_MEMORY_ERROR
;
978 SubclassPluginWindow(reinterpret_cast<HWND
>(aWindow
->window
));
980 window
.window
= reinterpret_cast<uint64_t>(aWindow
->window
);
981 window
.x
= aWindow
->x
;
982 window
.y
= aWindow
->y
;
983 window
.width
= aWindow
->width
;
984 window
.height
= aWindow
->height
;
985 window
.type
= aWindow
->type
;
988 window
.window
= reinterpret_cast<uint64_t>(aWindow
->window
);
989 window
.x
= aWindow
->x
;
990 window
.y
= aWindow
->y
;
991 window
.width
= aWindow
->width
;
992 window
.height
= aWindow
->height
;
993 window
.clipRect
= aWindow
->clipRect
; // MacOS specific
994 window
.type
= aWindow
->type
;
997 #if defined(XP_MACOSX)
998 double floatScaleFactor
= 1.0;
999 mNPNIface
->getvalue(mNPP
, NPNVcontentsScaleFactor
, &floatScaleFactor
);
1000 int scaleFactor
= ceil(floatScaleFactor
);
1001 window
.contentsScaleFactor
= floatScaleFactor
;
1003 if (mShWidth
!= window
.width
* scaleFactor
|| mShHeight
!= window
.height
* scaleFactor
) {
1004 if (mDrawingModel
== NPDrawingModelCoreAnimation
||
1005 mDrawingModel
== NPDrawingModelInvalidatingCoreAnimation
) {
1006 mIOSurface
= MacIOSurface::CreateIOSurface(window
.width
, window
.height
,
1008 } else if (uint32_t(mShWidth
* mShHeight
) !=
1009 window
.width
* scaleFactor
* window
.height
* scaleFactor
) {
1010 if (mShWidth
!= 0 && mShHeight
!= 0) {
1011 DeallocShmem(mShSurface
);
1016 if (window
.width
!= 0 && window
.height
!= 0) {
1017 if (!AllocShmem(window
.width
* scaleFactor
* window
.height
*4 * scaleFactor
,
1018 SharedMemory::TYPE_BASIC
, &mShSurface
)) {
1019 PLUGIN_LOG_DEBUG(("Shared memory could not be allocated."));
1020 return NPERR_GENERIC_ERROR
;
1024 mShWidth
= window
.width
* scaleFactor
;
1025 mShHeight
= window
.height
* scaleFactor
;
1029 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
1030 const NPSetWindowCallbackStruct
* ws_info
=
1031 static_cast<NPSetWindowCallbackStruct
*>(aWindow
->ws_info
);
1032 window
.visualID
= ws_info
->visual
? ws_info
->visual
->visualid
: None
;
1033 window
.colormap
= ws_info
->colormap
;
1036 if (!CallNPP_SetWindow(window
))
1037 return NPERR_GENERIC_ERROR
;
1039 return NPERR_NO_ERROR
;
1043 PluginInstanceParent::NPP_GetValue(NPPVariable aVariable
,
1046 switch (aVariable
) {
1048 case NPPVpluginWantsAllNetworkStreams
: {
1049 bool wantsAllStreams
;
1052 if (!CallNPP_GetValue_NPPVpluginWantsAllNetworkStreams(&wantsAllStreams
, &rv
)) {
1053 return NPERR_GENERIC_ERROR
;
1056 if (NPERR_NO_ERROR
!= rv
) {
1060 (*(NPBool
*)_retval
) = wantsAllStreams
;
1061 return NPERR_NO_ERROR
;
1065 case NPPVpluginNeedsXEmbed
: {
1069 if (!CallNPP_GetValue_NPPVpluginNeedsXEmbed(&needsXEmbed
, &rv
)) {
1070 return NPERR_GENERIC_ERROR
;
1073 if (NPERR_NO_ERROR
!= rv
) {
1077 (*(NPBool
*)_retval
) = needsXEmbed
;
1078 return NPERR_NO_ERROR
;
1082 case NPPVpluginScriptableNPObject
: {
1083 PPluginScriptableObjectParent
* actor
;
1085 if (!CallNPP_GetValue_NPPVpluginScriptableNPObject(&actor
, &rv
)) {
1086 return NPERR_GENERIC_ERROR
;
1089 if (NPERR_NO_ERROR
!= rv
) {
1094 NS_ERROR("NPPVpluginScriptableNPObject succeeded but null.");
1095 return NPERR_GENERIC_ERROR
;
1098 const NPNetscapeFuncs
* npn
= mParent
->GetNetscapeFuncs();
1100 NS_WARNING("No netscape functions?!");
1101 return NPERR_GENERIC_ERROR
;
1105 static_cast<PluginScriptableObjectParent
*>(actor
)->GetObject(true);
1106 NS_ASSERTION(object
, "This shouldn't ever be null!");
1108 (*(NPObject
**)_retval
) = npn
->retainobject(object
);
1109 return NPERR_NO_ERROR
;
1112 #ifdef MOZ_ACCESSIBILITY_ATK
1113 case NPPVpluginNativeAccessibleAtkPlugId
: {
1116 if (!CallNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId(&plugId
, &rv
)) {
1117 return NPERR_GENERIC_ERROR
;
1120 if (NPERR_NO_ERROR
!= rv
) {
1124 (*(nsCString
*)_retval
) = plugId
;
1125 return NPERR_NO_ERROR
;
1130 PR_LOG(GetPluginLog(), PR_LOG_WARNING
,
1131 ("In PluginInstanceParent::NPP_GetValue: Unhandled NPPVariable %i (%s)",
1132 (int) aVariable
, NPPVariableToString(aVariable
)));
1133 return NPERR_GENERIC_ERROR
;
1138 PluginInstanceParent::NPP_SetValue(NPNVariable variable
, void* value
)
1141 case NPNVprivateModeBool
:
1143 if (!CallNPP_SetValue_NPNVprivateModeBool(*static_cast<NPBool
*>(value
),
1145 return NPERR_GENERIC_ERROR
;
1150 NS_ERROR("Unhandled NPNVariable in NPP_SetValue");
1151 PR_LOG(GetPluginLog(), PR_LOG_WARNING
,
1152 ("In PluginInstanceParent::NPP_SetValue: Unhandled NPNVariable %i (%s)",
1153 (int) variable
, NPNVariableToString(variable
)));
1154 return NPERR_GENERIC_ERROR
;
1159 PluginInstanceParent::NPP_URLRedirectNotify(const char* url
, int32_t status
,
1165 PStreamNotifyParent
* streamNotify
= static_cast<PStreamNotifyParent
*>(notifyData
);
1166 unused
<< streamNotify
->SendRedirectNotify(NullableString(url
), status
);
1170 PluginInstanceParent::NPP_HandleEvent(void* event
)
1172 PLUGIN_LOG_DEBUG_FUNCTION
;
1174 #if defined(XP_MACOSX)
1175 NPCocoaEvent
* npevent
= reinterpret_cast<NPCocoaEvent
*>(event
);
1177 NPEvent
* npevent
= reinterpret_cast<NPEvent
*>(event
);
1179 NPRemoteEvent npremoteevent
;
1180 npremoteevent
.event
= *npevent
;
1181 #if defined(XP_MACOSX)
1182 double scaleFactor
= 1.0;
1183 mNPNIface
->getvalue(mNPP
, NPNVcontentsScaleFactor
, &scaleFactor
);
1184 npremoteevent
.contentsScaleFactor
= scaleFactor
;
1186 int16_t handled
= 0;
1189 if (mWindowType
== NPWindowTypeDrawable
) {
1190 if (IsAsyncDrawing()) {
1191 if (npevent
->event
== WM_PAINT
|| npevent
->event
== DoublePassRenderingEvent()) {
1192 // This plugin maintains its own async drawing.
1196 if (DoublePassRenderingEvent() == npevent
->event
) {
1197 return CallPaint(npremoteevent
, &handled
) && handled
;
1200 switch (npevent
->event
) {
1204 SharedSurfaceBeforePaint(rect
, npremoteevent
);
1205 if (!CallPaint(npremoteevent
, &handled
)) {
1208 SharedSurfaceAfterPaint(npevent
);
1215 // When the user selects fullscreen mode in Flash video players,
1216 // WM_KILLFOCUS will be delayed by deferred event processing:
1217 // WM_LBUTTONUP results in a call to CreateWindow within Flash,
1218 // which fires WM_KILLFOCUS. Delayed delivery causes Flash to
1219 // misinterpret the event, dropping back out of fullscreen. Trap
1220 // this event and drop it.
1221 wchar_t szClass
[26];
1222 HWND hwnd
= GetForegroundWindow();
1223 if (hwnd
&& hwnd
!= mPluginHWND
&&
1224 GetClassNameW(hwnd
, szClass
,
1225 sizeof(szClass
)/sizeof(char16_t
)) &&
1226 !wcscmp(szClass
, kFlashFullscreenClass
)) {
1232 case WM_WINDOWPOSCHANGED
:
1234 // We send this in nsObjectFrame just before painting
1235 return SendWindowPosChanged(npremoteevent
);
1242 #if defined(MOZ_X11)
1243 switch (npevent
->type
) {
1244 case GraphicsExpose
:
1245 PLUGIN_LOG_DEBUG((" schlepping drawable 0x%lx across the pipe\n",
1246 npevent
->xgraphicsexpose
.drawable
));
1247 // Make sure the X server has created the Drawable and completes any
1248 // drawing before the plugin draws on top.
1250 // XSync() waits for the X server to complete. Really this parent
1251 // process does not need to wait; the child is the process that needs
1252 // to wait. A possibly-slightly-better alternative would be to send
1253 // an X event to the child that the child would wait for.
1254 FinishX(DefaultXDisplay());
1256 return CallPaint(npremoteevent
, &handled
) ? handled
: 0;
1259 // Release any active pointer grab so that the plugin X client can
1260 // grab the pointer if it wishes.
1261 Display
*dpy
= DefaultXDisplay();
1262 # ifdef MOZ_WIDGET_GTK
1263 // GDK attempts to (asynchronously) track whether there is an active
1264 // grab so ungrab through GDK.
1265 gdk_pointer_ungrab(npevent
->xbutton
.time
);
1267 XUngrabPointer(dpy
, npevent
->xbutton
.time
);
1269 // Wait for the ungrab to complete.
1276 if (npevent
->type
== NPCocoaEventDrawRect
) {
1277 if (mDrawingModel
== NPDrawingModelCoreAnimation
||
1278 mDrawingModel
== NPDrawingModelInvalidatingCoreAnimation
) {
1280 NS_ERROR("No IOSurface allocated.");
1283 if (!CallNPP_HandleEvent_IOSurface(npremoteevent
,
1284 mIOSurface
->GetIOSurfaceID(),
1286 return false; // no good way to handle errors here...
1288 CGContextRef cgContext
= npevent
->data
.draw
.context
;
1289 if (!mShColorSpace
) {
1290 mShColorSpace
= CreateSystemColorSpace();
1292 if (!mShColorSpace
) {
1293 PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
1297 nsCARenderer::DrawSurfaceToCGContext(cgContext
, mIOSurface
,
1299 npevent
->data
.draw
.x
,
1300 npevent
->data
.draw
.y
,
1301 npevent
->data
.draw
.width
,
1302 npevent
->data
.draw
.height
);
1305 } else if (mFrontIOSurface
) {
1306 CGContextRef cgContext
= npevent
->data
.draw
.context
;
1307 if (!mShColorSpace
) {
1308 mShColorSpace
= CreateSystemColorSpace();
1310 if (!mShColorSpace
) {
1311 PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
1315 nsCARenderer::DrawSurfaceToCGContext(cgContext
, mFrontIOSurface
,
1317 npevent
->data
.draw
.x
,
1318 npevent
->data
.draw
.y
,
1319 npevent
->data
.draw
.width
,
1320 npevent
->data
.draw
.height
);
1324 if (mShWidth
== 0 && mShHeight
== 0) {
1325 PLUGIN_LOG_DEBUG(("NPCocoaEventDrawRect on window of size 0."));
1328 if (!mShSurface
.IsReadable()) {
1329 PLUGIN_LOG_DEBUG(("Shmem is not readable."));
1333 if (!CallNPP_HandleEvent_Shmem(npremoteevent
, mShSurface
,
1334 &handled
, &mShSurface
))
1335 return false; // no good way to handle errors here...
1337 if (!mShSurface
.IsReadable()) {
1338 PLUGIN_LOG_DEBUG(("Shmem not returned. Either the plugin crashed "
1339 "or we have a bug."));
1343 char* shContextByte
= mShSurface
.get
<char>();
1345 if (!mShColorSpace
) {
1346 mShColorSpace
= CreateSystemColorSpace();
1348 if (!mShColorSpace
) {
1349 PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
1352 CGContextRef shContext
= ::CGBitmapContextCreate(shContextByte
,
1353 mShWidth
, mShHeight
, 8,
1354 mShWidth
*4, mShColorSpace
,
1355 kCGImageAlphaPremultipliedFirst
|
1356 kCGBitmapByteOrder32Host
);
1358 PLUGIN_LOG_DEBUG(("Could not allocate CGBitmapContext."));
1362 CGImageRef shImage
= ::CGBitmapContextCreateImage(shContext
);
1364 CGContextRef cgContext
= npevent
->data
.draw
.context
;
1366 ::CGContextDrawImage(cgContext
,
1367 CGRectMake(0,0,mShWidth
,mShHeight
),
1369 ::CGImageRelease(shImage
);
1371 ::CGContextRelease(shContext
);
1374 ::CGContextRelease(shContext
);
1380 if (!CallNPP_HandleEvent(npremoteevent
, &handled
))
1381 return 0; // no good way to handle errors here...
1387 PluginInstanceParent::NPP_NewStream(NPMIMEType type
, NPStream
* stream
,
1388 NPBool seekable
, uint16_t* stype
)
1390 PLUGIN_LOG_DEBUG(("%s (type=%s, stream=%p, seekable=%i)",
1391 FULLFUNCTION
, (char*) type
, (void*) stream
, (int) seekable
));
1393 BrowserStreamParent
* bs
= new BrowserStreamParent(this, stream
);
1396 if (!CallPBrowserStreamConstructor(bs
,
1397 NullableString(stream
->url
),
1399 stream
->lastmodified
,
1400 static_cast<PStreamNotifyParent
*>(stream
->notifyData
),
1401 NullableString(stream
->headers
),
1402 NullableString(type
), seekable
,
1404 return NPERR_GENERIC_ERROR
;
1406 if (NPERR_NO_ERROR
!= err
)
1407 unused
<< PBrowserStreamParent::Send__delete__(bs
);
1413 PluginInstanceParent::NPP_DestroyStream(NPStream
* stream
, NPReason reason
)
1415 PLUGIN_LOG_DEBUG(("%s (stream=%p, reason=%i)",
1416 FULLFUNCTION
, (void*) stream
, (int) reason
));
1418 AStream
* s
= static_cast<AStream
*>(stream
->pdata
);
1419 if (s
->IsBrowserStream()) {
1420 BrowserStreamParent
* sp
=
1421 static_cast<BrowserStreamParent
*>(s
);
1422 if (sp
->mNPP
!= this)
1423 NS_RUNTIMEABORT("Mismatched plugin data");
1425 sp
->NPP_DestroyStream(reason
);
1426 return NPERR_NO_ERROR
;
1429 PluginStreamParent
* sp
=
1430 static_cast<PluginStreamParent
*>(s
);
1431 if (sp
->mInstance
!= this)
1432 NS_RUNTIMEABORT("Mismatched plugin data");
1434 return PPluginStreamParent::Call__delete__(sp
, reason
, false) ?
1435 NPERR_NO_ERROR
: NPERR_GENERIC_ERROR
;
1440 PluginInstanceParent::NPP_Print(NPPrint
* platformPrint
)
1442 // TODO: implement me
1443 NS_ERROR("Not implemented");
1446 PPluginScriptableObjectParent
*
1447 PluginInstanceParent::AllocPPluginScriptableObjectParent()
1449 return new PluginScriptableObjectParent(Proxy
);
1455 struct ActorSearchData
1457 PluginScriptableObjectParent
* actor
;
1462 ActorSearch(NPObject
* aKey
,
1463 PluginScriptableObjectParent
* aData
,
1466 ActorSearchData
* asd
= reinterpret_cast<ActorSearchData
*>(aUserData
);
1467 if (asd
->actor
== aData
) {
1469 return PL_DHASH_STOP
;
1471 return PL_DHASH_NEXT
;
1474 } // anonymous namespace
1478 PluginInstanceParent::DeallocPPluginScriptableObjectParent(
1479 PPluginScriptableObjectParent
* aObject
)
1481 PluginScriptableObjectParent
* actor
=
1482 static_cast<PluginScriptableObjectParent
*>(aObject
);
1484 NPObject
* object
= actor
->GetObject(false);
1486 NS_ASSERTION(mScriptableObjects
.Get(object
, nullptr),
1487 "NPObject not in the hash!");
1488 mScriptableObjects
.Remove(object
);
1492 ActorSearchData asd
= { actor
, false };
1493 mScriptableObjects
.EnumerateRead(ActorSearch
, &asd
);
1494 NS_ASSERTION(!asd
.found
, "Actor in the hash with a null NPObject!");
1503 PluginInstanceParent::RecvPPluginScriptableObjectConstructor(
1504 PPluginScriptableObjectParent
* aActor
)
1506 // This is only called in response to the child process requesting the
1507 // creation of an actor. This actor will represent an NPObject that is
1508 // created by the plugin and returned to the browser.
1509 PluginScriptableObjectParent
* actor
=
1510 static_cast<PluginScriptableObjectParent
*>(aActor
);
1511 NS_ASSERTION(!actor
->GetObject(false), "Actor already has an object?!");
1513 actor
->InitializeProxy();
1514 NS_ASSERTION(actor
->GetObject(false), "Actor should have an object!");
1520 PluginInstanceParent::NPP_URLNotify(const char* url
, NPReason reason
,
1523 PLUGIN_LOG_DEBUG(("%s (%s, %i, %p)",
1524 FULLFUNCTION
, url
, (int) reason
, notifyData
));
1526 PStreamNotifyParent
* streamNotify
=
1527 static_cast<PStreamNotifyParent
*>(notifyData
);
1528 unused
<< PStreamNotifyParent::Send__delete__(streamNotify
, reason
);
1532 PluginInstanceParent::RegisterNPObjectForActor(
1534 PluginScriptableObjectParent
* aActor
)
1536 NS_ASSERTION(aObject
&& aActor
, "Null pointers!");
1537 NS_ASSERTION(!mScriptableObjects
.Get(aObject
, nullptr), "Duplicate entry!");
1538 mScriptableObjects
.Put(aObject
, aActor
);
1543 PluginInstanceParent::UnregisterNPObject(NPObject
* aObject
)
1545 NS_ASSERTION(aObject
, "Null pointer!");
1546 NS_ASSERTION(mScriptableObjects
.Get(aObject
, nullptr), "Unknown entry!");
1547 mScriptableObjects
.Remove(aObject
);
1550 PluginScriptableObjectParent
*
1551 PluginInstanceParent::GetActorForNPObject(NPObject
* aObject
)
1553 NS_ASSERTION(aObject
, "Null pointer!");
1555 if (aObject
->_class
== PluginScriptableObjectParent::GetClass()) {
1557 ParentNPObject
* object
= static_cast<ParentNPObject
*>(aObject
);
1558 NS_ASSERTION(object
->parent
, "Null actor!");
1559 return object
->parent
;
1562 PluginScriptableObjectParent
* actor
;
1563 if (mScriptableObjects
.Get(aObject
, &actor
)) {
1567 actor
= new PluginScriptableObjectParent(LocalObject
);
1569 NS_ERROR("Out of memory!");
1573 if (!SendPPluginScriptableObjectConstructor(actor
)) {
1574 NS_WARNING("Failed to send constructor message!");
1578 actor
->InitializeLocal(aObject
);
1582 PPluginSurfaceParent
*
1583 PluginInstanceParent::AllocPPluginSurfaceParent(const WindowsSharedMemoryHandle
& handle
,
1584 const gfxIntSize
& size
,
1585 const bool& transparent
)
1588 return new PluginSurfaceParent(handle
, size
, transparent
);
1590 NS_ERROR("This shouldn't be called!");
1596 PluginInstanceParent::DeallocPPluginSurfaceParent(PPluginSurfaceParent
* s
)
1607 PluginInstanceParent::AnswerNPN_PushPopupsEnabledState(const bool& aState
)
1609 mNPNIface
->pushpopupsenabledstate(mNPP
, aState
? 1 : 0);
1614 PluginInstanceParent::AnswerNPN_PopPopupsEnabledState()
1616 mNPNIface
->poppopupsenabledstate(mNPP
);
1621 PluginInstanceParent::AnswerNPN_GetValueForURL(const NPNURLVariable
& variable
,
1622 const nsCString
& url
,
1629 *result
= mNPNIface
->getvalueforurl(mNPP
, (NPNURLVariable
) variable
,
1630 url
.get(), &v
, &len
);
1631 if (NPERR_NO_ERROR
== *result
)
1632 value
->Adopt(v
, len
);
1638 PluginInstanceParent::AnswerNPN_SetValueForURL(const NPNURLVariable
& variable
,
1639 const nsCString
& url
,
1640 const nsCString
& value
,
1643 *result
= mNPNIface
->setvalueforurl(mNPP
, (NPNURLVariable
) variable
,
1644 url
.get(), value
.get(),
1650 PluginInstanceParent::AnswerNPN_GetAuthenticationInfo(const nsCString
& protocol
,
1651 const nsCString
& host
,
1652 const int32_t& port
,
1653 const nsCString
& scheme
,
1654 const nsCString
& realm
,
1655 nsCString
* username
,
1656 nsCString
* password
,
1664 *result
= mNPNIface
->getauthenticationinfo(mNPP
, protocol
.get(),
1666 scheme
.get(), realm
.get(),
1667 &u
, &ulen
, &p
, &plen
);
1668 if (NPERR_NO_ERROR
== *result
) {
1669 username
->Adopt(u
, ulen
);
1670 password
->Adopt(p
, plen
);
1676 PluginInstanceParent::AnswerNPN_ConvertPoint(const double& sourceX
,
1677 const bool& ignoreDestX
,
1678 const double& sourceY
,
1679 const bool& ignoreDestY
,
1680 const NPCoordinateSpace
& sourceSpace
,
1681 const NPCoordinateSpace
& destSpace
,
1686 *result
= mNPNIface
->convertpoint(mNPP
, sourceX
, sourceY
, sourceSpace
,
1687 ignoreDestX
? nullptr : destX
,
1688 ignoreDestY
? nullptr : destY
,
1695 PluginInstanceParent::AnswerNPN_InitAsyncSurface(const gfxIntSize
& size
,
1696 const NPImageFormat
& format
,
1697 NPRemoteAsyncSurface
* surfData
,
1700 if (!IsAsyncDrawing()) {
1705 switch (mDrawingModel
) {
1706 case NPDrawingModelAsyncBitmapSurface
: {
1708 if (!AllocUnsafeShmem(size
.width
* size
.height
* 4, SharedMemory::TYPE_BASIC
, &sharedMem
)) {
1713 surfData
->size() = size
;
1714 surfData
->hostPtr() = (uintptr_t)sharedMem
.get
<unsigned char>();
1715 surfData
->stride() = size
.width
* 4;
1716 surfData
->format() = format
;
1717 surfData
->data() = sharedMem
;
1722 case NPDrawingModelAsyncWindowsDXGISurface
: {
1723 ID3D10Device1
*device
= gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
1725 nsRefPtr
<ID3D10Texture2D
> texture
;
1727 CD3D10_TEXTURE2D_DESC
desc(DXGI_FORMAT_B8G8R8A8_UNORM
, size
.width
, size
.height
, 1, 1);
1728 desc
.MiscFlags
= D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX
;
1729 desc
.BindFlags
= D3D10_BIND_RENDER_TARGET
| D3D10_BIND_SHADER_RESOURCE
;
1730 if (FAILED(device
->CreateTexture2D(&desc
, nullptr, getter_AddRefs(texture
)))) {
1735 nsRefPtr
<IDXGIResource
> resource
;
1736 if (FAILED(texture
->QueryInterface(IID_IDXGIResource
, getter_AddRefs(resource
)))) {
1741 HANDLE sharedHandle
;
1743 if (FAILED(resource
->GetSharedHandle(&sharedHandle
))) {
1748 surfData
->size() = size
;
1749 surfData
->data() = sharedHandle
;
1750 surfData
->format() = format
;
1752 mTextureMap
.Put(sharedHandle
, texture
);
1762 PluginInstanceParent::RecvRedrawPlugin()
1764 nsNPAPIPluginInstance
*inst
= static_cast<nsNPAPIPluginInstance
*>(mNPP
->ndata
);
1769 inst
->RedrawPlugin();
1774 PluginInstanceParent::RecvNegotiatedCarbon()
1776 nsNPAPIPluginInstance
*inst
= static_cast<nsNPAPIPluginInstance
*>(mNPP
->ndata
);
1780 inst
->CarbonNPAPIFailure();
1785 PluginInstanceParent::RecvReleaseDXGISharedSurface(const DXGISharedSurfaceHandle
&aHandle
)
1788 mTextureMap
.Remove(aHandle
);
1796 plugin focus changes between processes
1798 focus from dom -> child:
1799 Focus manager calls on widget to set the focus on the window.
1800 We pick up the resulting wm_setfocus event here, and forward
1801 that over ipc to the child which calls set focus on itself.
1803 focus from child -> focus manager:
1804 Child picks up the local wm_setfocus and sends it via ipc over
1805 here. We then post a custom event to widget/windows/nswindow
1806 which fires off a gui event letting the browser know.
1809 static const wchar_t kPluginInstanceParentProperty
[] =
1810 L
"PluginInstanceParentProperty";
1814 PluginInstanceParent::PluginWindowHookProc(HWND hWnd
,
1819 PluginInstanceParent
* self
= reinterpret_cast<PluginInstanceParent
*>(
1820 ::GetPropW(hWnd
, kPluginInstanceParentProperty
));
1822 NS_NOTREACHED("PluginInstanceParent::PluginWindowHookProc null this ptr!");
1823 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
1826 NS_ASSERTION(self
->mPluginHWND
== hWnd
, "Wrong window!");
1830 // Let the child plugin window know it should take focus.
1831 unused
<< self
->CallSetPluginFocus();
1835 self
->UnsubclassPluginWindow();
1839 if (self
->mPluginWndProc
== PluginWindowHookProc
) {
1841 "PluginWindowHookProc invoking mPluginWndProc w/"
1842 "mPluginWndProc == PluginWindowHookProc????");
1843 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
1845 return ::CallWindowProc(self
->mPluginWndProc
, hWnd
, message
, wParam
,
1850 PluginInstanceParent::SubclassPluginWindow(HWND aWnd
)
1852 NS_ASSERTION(!(mPluginHWND
&& aWnd
!= mPluginHWND
),
1853 "PluginInstanceParent::SubclassPluginWindow hwnd is not our window!");
1858 (WNDPROC
)::SetWindowLongPtrA(mPluginHWND
, GWLP_WNDPROC
,
1859 reinterpret_cast<LONG_PTR
>(PluginWindowHookProc
));
1860 DebugOnly
<bool> bRes
= ::SetPropW(mPluginHWND
, kPluginInstanceParentProperty
, this);
1861 NS_ASSERTION(mPluginWndProc
,
1862 "PluginInstanceParent::SubclassPluginWindow failed to set subclass!");
1864 "PluginInstanceParent::SubclassPluginWindow failed to set prop!");
1869 PluginInstanceParent::UnsubclassPluginWindow()
1871 if (mPluginHWND
&& mPluginWndProc
) {
1872 ::SetWindowLongPtrA(mPluginHWND
, GWLP_WNDPROC
,
1873 reinterpret_cast<LONG_PTR
>(mPluginWndProc
));
1875 ::RemovePropW(mPluginHWND
, kPluginInstanceParentProperty
);
1877 mPluginWndProc
= nullptr;
1878 mPluginHWND
= nullptr;
1882 /* windowless drawing helpers */
1887 * windowless, offscreen:
1889 * WM_WINDOWPOSCHANGED: origin is relative to container
1890 * setwindow: origin is 0,0
1891 * WM_PAINT: origin is 0,0
1893 * windowless, native:
1895 * WM_WINDOWPOSCHANGED: origin is relative to container
1896 * setwindow: origin is relative to container
1897 * WM_PAINT: origin is relative to container
1899 * PluginInstanceParent:
1901 * painting: mPluginPort (nsIntRect, saved in SetWindow)
1905 PluginInstanceParent::SharedSurfaceRelease()
1907 mSharedSurfaceDib
.Close();
1911 PluginInstanceParent::SharedSurfaceSetWindow(const NPWindow
* aWindow
,
1912 NPRemoteWindow
& aRemoteWindow
)
1914 aRemoteWindow
.window
= 0;
1915 aRemoteWindow
.x
= aWindow
->x
;
1916 aRemoteWindow
.y
= aWindow
->y
;
1917 aRemoteWindow
.width
= aWindow
->width
;
1918 aRemoteWindow
.height
= aWindow
->height
;
1919 aRemoteWindow
.type
= aWindow
->type
;
1921 nsIntRect
newPort(aWindow
->x
, aWindow
->y
, aWindow
->width
, aWindow
->height
);
1923 // save the the rect location within the browser window.
1924 mPluginPort
= newPort
;
1926 // move the port to our shared surface origin
1927 newPort
.MoveTo(0,0);
1929 // check to see if we have the room in shared surface
1930 if (mSharedSurfaceDib
.IsValid() && mSharedSize
.Contains(newPort
)) {
1932 aRemoteWindow
.surfaceHandle
= 0;
1936 // allocate a new shared surface
1937 SharedSurfaceRelease();
1938 if (NS_FAILED(mSharedSurfaceDib
.Create(reinterpret_cast<HDC
>(aWindow
->window
),
1939 newPort
.width
, newPort
.height
, false)))
1942 // save the new shared surface size we just allocated
1943 mSharedSize
= newPort
;
1945 base::SharedMemoryHandle handle
;
1946 if (NS_FAILED(mSharedSurfaceDib
.ShareToProcess(mParent
->ChildProcessHandle(), &handle
)))
1949 aRemoteWindow
.surfaceHandle
= handle
;
1955 PluginInstanceParent::SharedSurfaceBeforePaint(RECT
& rect
,
1956 NPRemoteEvent
& npremoteevent
)
1958 RECT
* dr
= (RECT
*)npremoteevent
.event
.lParam
;
1959 HDC parentHdc
= (HDC
)npremoteevent
.event
.wParam
;
1961 nsIntRect
dirtyRect(dr
->left
, dr
->top
, dr
->right
-dr
->left
, dr
->bottom
-dr
->top
);
1962 dirtyRect
.MoveBy(-mPluginPort
.x
, -mPluginPort
.y
); // should always be smaller than dirtyRect
1964 ::BitBlt(mSharedSurfaceDib
.GetHDC(),
1974 // setup the translated dirty rect we'll send to the child
1975 rect
.left
= dirtyRect
.x
;
1976 rect
.top
= dirtyRect
.y
;
1977 rect
.right
= dirtyRect
.x
+ dirtyRect
.width
;
1978 rect
.bottom
= dirtyRect
.y
+ dirtyRect
.height
;
1980 npremoteevent
.event
.wParam
= WPARAM(0);
1981 npremoteevent
.event
.lParam
= LPARAM(&rect
);
1985 PluginInstanceParent::SharedSurfaceAfterPaint(NPEvent
* npevent
)
1987 RECT
* dr
= (RECT
*)npevent
->lParam
;
1988 HDC parentHdc
= (HDC
)npevent
->wParam
;
1990 nsIntRect
dirtyRect(dr
->left
, dr
->top
, dr
->right
-dr
->left
, dr
->bottom
-dr
->top
);
1991 dirtyRect
.MoveBy(-mPluginPort
.x
, -mPluginPort
.y
);
1993 // src copy the shared dib into the parent surface we are handed.
1999 mSharedSurfaceDib
.GetHDC(),
2005 #endif // defined(OS_WIN)
2008 PluginInstanceParent::AnswerPluginFocusChange(const bool& gotFocus
)
2010 PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION
));
2012 // Currently only in use on windows - an rpc event we receive from the
2013 // child when it's plugin window (or one of it's children) receives keyboard
2014 // focus. We forward the event down to widget so the dom/focus manager can
2017 ::SendMessage(mPluginHWND
, gOOPPPluginFocusEvent
, gotFocus
? 1 : 0, 0);
2020 NS_NOTREACHED("PluginInstanceParent::AnswerPluginFocusChange not implemented!");