dom/plugins/ipc/PluginInstanceParent.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/plugins/ipc/PluginInstanceParent.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,2017 @@
     1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     1.5 + * vim: sw=4 ts=4 et :
     1.6 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#include "mozilla/DebugOnly.h"
    1.11 +#include <stdint.h> // for intptr_t
    1.12 +
    1.13 +#include "PluginInstanceParent.h"
    1.14 +#include "BrowserStreamParent.h"
    1.15 +#include "PluginBackgroundDestroyer.h"
    1.16 +#include "PluginModuleParent.h"
    1.17 +#include "PluginStreamParent.h"
    1.18 +#include "StreamNotifyParent.h"
    1.19 +#include "npfunctions.h"
    1.20 +#include "nsAutoPtr.h"
    1.21 +#include "gfxASurface.h"
    1.22 +#include "gfxContext.h"
    1.23 +#include "gfxPlatform.h"
    1.24 +#include "gfxSharedImageSurface.h"
    1.25 +#include "nsNPAPIPluginInstance.h"
    1.26 +#ifdef MOZ_X11
    1.27 +#include "gfxXlibSurface.h"
    1.28 +#endif
    1.29 +#include "gfxContext.h"
    1.30 +#include "gfxColor.h"
    1.31 +#include "gfxUtils.h"
    1.32 +#include "mozilla/gfx/2D.h"
    1.33 +#include "Layers.h"
    1.34 +#include "SharedTextureImage.h"
    1.35 +#include "GLContext.h"
    1.36 +#include "GLContextProvider.h"
    1.37 +
    1.38 +#ifdef XP_MACOSX
    1.39 +#include "MacIOSurfaceImage.h"
    1.40 +#endif
    1.41 +
    1.42 +#if defined(OS_WIN)
    1.43 +#include <windowsx.h>
    1.44 +#include "gfxWindowsPlatform.h"
    1.45 +#include "mozilla/plugins/PluginSurfaceParent.h"
    1.46 +
    1.47 +// Plugin focus event for widget.
    1.48 +extern const wchar_t* kOOPPPluginFocusEventId;
    1.49 +UINT gOOPPPluginFocusEvent =
    1.50 +    RegisterWindowMessage(kOOPPPluginFocusEventId);
    1.51 +extern const wchar_t* kFlashFullscreenClass;
    1.52 +#elif defined(MOZ_WIDGET_GTK)
    1.53 +#include <gdk/gdk.h>
    1.54 +#elif defined(XP_MACOSX)
    1.55 +#include <ApplicationServices/ApplicationServices.h>
    1.56 +#endif // defined(XP_MACOSX)
    1.57 +
    1.58 +using namespace mozilla::plugins;
    1.59 +using namespace mozilla::layers;
    1.60 +using namespace mozilla::gl;
    1.61 +
    1.62 +bool
    1.63 +StreamNotifyParent::RecvRedirectNotifyResponse(const bool& allow)
    1.64 +{
    1.65 +  PluginInstanceParent* instance = static_cast<PluginInstanceParent*>(Manager());
    1.66 +  instance->mNPNIface->urlredirectresponse(instance->mNPP, this, static_cast<NPBool>(allow));
    1.67 +  return true;
    1.68 +}
    1.69 +
    1.70 +PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent,
    1.71 +                                           NPP npp,
    1.72 +                                           const nsCString& aMimeType,
    1.73 +                                           const NPNetscapeFuncs* npniface)
    1.74 +  : mParent(parent)
    1.75 +    , mNPP(npp)
    1.76 +    , mNPNIface(npniface)
    1.77 +    , mWindowType(NPWindowTypeWindow)
    1.78 +    , mDrawingModel(kDefaultDrawingModel)
    1.79 +#if defined(OS_WIN)
    1.80 +    , mPluginHWND(nullptr)
    1.81 +    , mPluginWndProc(nullptr)
    1.82 +    , mNestedEventState(false)
    1.83 +#endif // defined(XP_WIN)
    1.84 +#if defined(XP_MACOSX)
    1.85 +    , mShWidth(0)
    1.86 +    , mShHeight(0)
    1.87 +    , mShColorSpace(nullptr)
    1.88 +#endif
    1.89 +{
    1.90 +}
    1.91 +
    1.92 +PluginInstanceParent::~PluginInstanceParent()
    1.93 +{
    1.94 +    if (mNPP)
    1.95 +        mNPP->pdata = nullptr;
    1.96 +
    1.97 +#if defined(OS_WIN)
    1.98 +    NS_ASSERTION(!(mPluginHWND || mPluginWndProc),
    1.99 +        "Subclass was not reset correctly before the dtor was reached!");
   1.100 +#endif
   1.101 +#if defined(MOZ_WIDGET_COCOA)
   1.102 +    if (mShWidth != 0 && mShHeight != 0) {
   1.103 +        DeallocShmem(mShSurface);
   1.104 +    }
   1.105 +    if (mShColorSpace)
   1.106 +        ::CGColorSpaceRelease(mShColorSpace);
   1.107 +#endif
   1.108 +    if (mRemoteImageDataShmem.IsWritable()) {
   1.109 +        if (mImageContainer) {
   1.110 +            mImageContainer->SetRemoteImageData(nullptr, nullptr);
   1.111 +            mImageContainer->SetCompositionNotifySink(nullptr);
   1.112 +        }
   1.113 +        DeallocShmem(mRemoteImageDataShmem);
   1.114 +    }
   1.115 +}
   1.116 +
   1.117 +bool
   1.118 +PluginInstanceParent::Init()
   1.119 +{
   1.120 +    return true;
   1.121 +}
   1.122 +
   1.123 +void
   1.124 +PluginInstanceParent::ActorDestroy(ActorDestroyReason why)
   1.125 +{
   1.126 +#if defined(OS_WIN)
   1.127 +    if (why == AbnormalShutdown) {
   1.128 +        // If the plugin process crashes, this is the only
   1.129 +        // chance we get to destroy resources.
   1.130 +        SharedSurfaceRelease();
   1.131 +        UnsubclassPluginWindow();
   1.132 +    }
   1.133 +#endif
   1.134 +    // After this method, the data backing the remote surface may no
   1.135 +    // longer be valid. The X surface may be destroyed, or the shared
   1.136 +    // memory backing this surface may no longer be valid.
   1.137 +    if (mFrontSurface) {
   1.138 +        mFrontSurface = nullptr;
   1.139 +        if (mImageContainer) {
   1.140 +            mImageContainer->SetCurrentImage(nullptr);
   1.141 +        }
   1.142 +#ifdef MOZ_X11
   1.143 +        FinishX(DefaultXDisplay());
   1.144 +#endif
   1.145 +    }
   1.146 +}
   1.147 +
   1.148 +NPError
   1.149 +PluginInstanceParent::Destroy()
   1.150 +{
   1.151 +    NPError retval;
   1.152 +    if (!CallNPP_Destroy(&retval))
   1.153 +        retval = NPERR_GENERIC_ERROR;
   1.154 +
   1.155 +#if defined(OS_WIN)
   1.156 +    SharedSurfaceRelease();
   1.157 +    UnsubclassPluginWindow();
   1.158 +#endif
   1.159 +
   1.160 +    return retval;
   1.161 +}
   1.162 +
   1.163 +PBrowserStreamParent*
   1.164 +PluginInstanceParent::AllocPBrowserStreamParent(const nsCString& url,
   1.165 +                                                const uint32_t& length,
   1.166 +                                                const uint32_t& lastmodified,
   1.167 +                                                PStreamNotifyParent* notifyData,
   1.168 +                                                const nsCString& headers,
   1.169 +                                                const nsCString& mimeType,
   1.170 +                                                const bool& seekable,
   1.171 +                                                NPError* rv,
   1.172 +                                                uint16_t *stype)
   1.173 +{
   1.174 +    NS_RUNTIMEABORT("Not reachable");
   1.175 +    return nullptr;
   1.176 +}
   1.177 +
   1.178 +bool
   1.179 +PluginInstanceParent::DeallocPBrowserStreamParent(PBrowserStreamParent* stream)
   1.180 +{
   1.181 +    delete stream;
   1.182 +    return true;
   1.183 +}
   1.184 +
   1.185 +PPluginStreamParent*
   1.186 +PluginInstanceParent::AllocPPluginStreamParent(const nsCString& mimeType,
   1.187 +                                               const nsCString& target,
   1.188 +                                               NPError* result)
   1.189 +{
   1.190 +    return new PluginStreamParent(this, mimeType, target, result);
   1.191 +}
   1.192 +
   1.193 +bool
   1.194 +PluginInstanceParent::DeallocPPluginStreamParent(PPluginStreamParent* stream)
   1.195 +{
   1.196 +    delete stream;
   1.197 +    return true;
   1.198 +}
   1.199 +
   1.200 +bool
   1.201 +PluginInstanceParent::AnswerNPN_GetValue_NPNVnetscapeWindow(NativeWindowHandle* value,
   1.202 +                                                            NPError* result)
   1.203 +{
   1.204 +#ifdef XP_WIN
   1.205 +    HWND id;
   1.206 +#elif defined(MOZ_X11)
   1.207 +    XID id;
   1.208 +#elif defined(XP_MACOSX)
   1.209 +    intptr_t id;
   1.210 +#elif defined(ANDROID)
   1.211 +    // TODO: Need Android impl
   1.212 +    int id;
   1.213 +#elif defined(MOZ_WIDGET_QT)
   1.214 +    // TODO: Need Qt non X impl
   1.215 +    int id;
   1.216 +#else
   1.217 +#warning Implement me
   1.218 +#endif
   1.219 +
   1.220 +    *result = mNPNIface->getvalue(mNPP, NPNVnetscapeWindow, &id);
   1.221 +    *value = id;
   1.222 +    return true;
   1.223 +}
   1.224 +
   1.225 +bool
   1.226 +PluginInstanceParent::InternalGetValueForNPObject(
   1.227 +                                         NPNVariable aVariable,
   1.228 +                                         PPluginScriptableObjectParent** aValue,
   1.229 +                                         NPError* aResult)
   1.230 +{
   1.231 +    NPObject* npobject;
   1.232 +    NPError result = mNPNIface->getvalue(mNPP, aVariable, (void*)&npobject);
   1.233 +    if (result == NPERR_NO_ERROR) {
   1.234 +        NS_ASSERTION(npobject, "Shouldn't return null and NPERR_NO_ERROR!");
   1.235 +
   1.236 +        PluginScriptableObjectParent* actor = GetActorForNPObject(npobject);
   1.237 +        mNPNIface->releaseobject(npobject);
   1.238 +        if (actor) {
   1.239 +            *aValue = actor;
   1.240 +            *aResult = NPERR_NO_ERROR;
   1.241 +            return true;
   1.242 +        }
   1.243 +
   1.244 +        NS_ERROR("Failed to get actor!");
   1.245 +        result = NPERR_GENERIC_ERROR;
   1.246 +    }
   1.247 +
   1.248 +    *aValue = nullptr;
   1.249 +    *aResult = result;
   1.250 +    return true;
   1.251 +}
   1.252 +
   1.253 +bool
   1.254 +PluginInstanceParent::IsAsyncDrawing()
   1.255 +{
   1.256 +  return IsDrawingModelAsync(mDrawingModel);
   1.257 +}
   1.258 +
   1.259 +bool
   1.260 +PluginInstanceParent::AnswerNPN_GetValue_NPNVWindowNPObject(
   1.261 +                                         PPluginScriptableObjectParent** aValue,
   1.262 +                                         NPError* aResult)
   1.263 +{
   1.264 +    return InternalGetValueForNPObject(NPNVWindowNPObject, aValue, aResult);
   1.265 +}
   1.266 +
   1.267 +bool
   1.268 +PluginInstanceParent::AnswerNPN_GetValue_NPNVPluginElementNPObject(
   1.269 +                                         PPluginScriptableObjectParent** aValue,
   1.270 +                                         NPError* aResult)
   1.271 +{
   1.272 +    return InternalGetValueForNPObject(NPNVPluginElementNPObject, aValue,
   1.273 +                                       aResult);
   1.274 +}
   1.275 +
   1.276 +bool
   1.277 +PluginInstanceParent::AnswerNPN_GetValue_NPNVprivateModeBool(bool* value,
   1.278 +                                                             NPError* result)
   1.279 +{
   1.280 +    NPBool v;
   1.281 +    *result = mNPNIface->getvalue(mNPP, NPNVprivateModeBool, &v);
   1.282 +    *value = v;
   1.283 +    return true;
   1.284 +}
   1.285 +
   1.286 +bool
   1.287 +PluginInstanceParent::AnswerNPN_GetValue_DrawingModelSupport(const NPNVariable& model, bool* value)
   1.288 +{
   1.289 +    *value = false;
   1.290 +
   1.291 +#ifdef XP_WIN
   1.292 +    switch (model) {
   1.293 +        case NPNVsupportsAsyncWindowsDXGISurfaceBool: {
   1.294 +            if (gfxWindowsPlatform::GetPlatform()->GetRenderMode() == gfxWindowsPlatform::RENDER_DIRECT2D) {
   1.295 +                *value = true;
   1.296 +            }
   1.297 +        }
   1.298 +    }
   1.299 +#endif
   1.300 +
   1.301 +    return true;
   1.302 +}
   1.303 +
   1.304 +bool
   1.305 +PluginInstanceParent::AnswerNPN_GetValue_NPNVdocumentOrigin(nsCString* value,
   1.306 +                                                            NPError* result)
   1.307 +{
   1.308 +    void *v = nullptr;
   1.309 +    *result = mNPNIface->getvalue(mNPP, NPNVdocumentOrigin, &v);
   1.310 +    if (*result == NPERR_NO_ERROR && v) {
   1.311 +        value->Adopt(static_cast<char*>(v));
   1.312 +    }
   1.313 +    return true;
   1.314 +}
   1.315 +
   1.316 +bool
   1.317 +PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginWindow(
   1.318 +    const bool& windowed, NPError* result)
   1.319 +{
   1.320 +    // Yes, we are passing a boolean as a void*.  We have to cast to intptr_t
   1.321 +    // first to avoid gcc warnings about casting to a pointer from a
   1.322 +    // non-pointer-sized integer.
   1.323 +    *result = mNPNIface->setvalue(mNPP, NPPVpluginWindowBool,
   1.324 +                                  (void*)(intptr_t)windowed);
   1.325 +    return true;
   1.326 +}
   1.327 +
   1.328 +bool
   1.329 +PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginTransparent(
   1.330 +    const bool& transparent, NPError* result)
   1.331 +{
   1.332 +    *result = mNPNIface->setvalue(mNPP, NPPVpluginTransparentBool,
   1.333 +                                  (void*)(intptr_t)transparent);
   1.334 +    return true;
   1.335 +}
   1.336 +
   1.337 +bool
   1.338 +PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginUsesDOMForCursor(
   1.339 +    const bool& useDOMForCursor, NPError* result)
   1.340 +{
   1.341 +    *result = mNPNIface->setvalue(mNPP, NPPVpluginUsesDOMForCursorBool,
   1.342 +                                  (void*)(intptr_t)useDOMForCursor);
   1.343 +    return true;
   1.344 +}
   1.345 +
   1.346 +class NotificationSink : public CompositionNotifySink
   1.347 +{
   1.348 +public:
   1.349 +  NotificationSink(PluginInstanceParent *aInstance) : mInstance(aInstance)
   1.350 +  { }
   1.351 +
   1.352 +  virtual void DidComposite() { mInstance->DidComposite(); }
   1.353 +private:
   1.354 +  PluginInstanceParent *mInstance;
   1.355 +};
   1.356 +
   1.357 +bool
   1.358 +PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginDrawingModel(
   1.359 +    const int& drawingModel, OptionalShmem *shmem, CrossProcessMutexHandle *mutex, NPError* result)
   1.360 +{
   1.361 +    *shmem = null_t();
   1.362 +
   1.363 +#ifdef XP_MACOSX
   1.364 +    if (drawingModel == NPDrawingModelCoreAnimation ||
   1.365 +        drawingModel == NPDrawingModelInvalidatingCoreAnimation) {
   1.366 +        // We need to request CoreGraphics otherwise
   1.367 +        // the nsObjectFrame will try to draw a CALayer
   1.368 +        // that can not be shared across process.
   1.369 +        mDrawingModel = drawingModel;
   1.370 +        *result = mNPNIface->setvalue(mNPP, NPPVpluginDrawingModel,
   1.371 +                                  (void*)NPDrawingModelCoreGraphics);
   1.372 +    } else
   1.373 +#endif
   1.374 +    if (drawingModel == NPDrawingModelAsyncBitmapSurface
   1.375 +#ifdef XP_WIN
   1.376 +        || drawingModel == NPDrawingModelAsyncWindowsDXGISurface
   1.377 +#endif
   1.378 +        ) {
   1.379 +        ImageContainer *container = GetImageContainer();
   1.380 +        if (!container) {
   1.381 +            *result = NPERR_GENERIC_ERROR;
   1.382 +            return true;
   1.383 +        }
   1.384 +
   1.385 +#ifdef XP_WIN
   1.386 +        if (drawingModel == NPDrawingModelAsyncWindowsDXGISurface &&
   1.387 +            gfxWindowsPlatform::GetPlatform()->GetRenderMode() != gfxWindowsPlatform::RENDER_DIRECT2D) {
   1.388 +            *result = NPERR_GENERIC_ERROR;
   1.389 +            return true;
   1.390 +        }
   1.391 +#endif
   1.392 +
   1.393 +        mDrawingModel = drawingModel;
   1.394 +        *result = mNPNIface->setvalue(mNPP, NPPVpluginDrawingModel,
   1.395 +                                      reinterpret_cast<void*>(static_cast<uintptr_t>(drawingModel)));
   1.396 +
   1.397 +
   1.398 +        if (*result != NPERR_NO_ERROR) {
   1.399 +            return true;
   1.400 +        }
   1.401 +
   1.402 +        AllocUnsafeShmem(sizeof(RemoteImageData), SharedMemory::TYPE_BASIC, &mRemoteImageDataShmem);
   1.403 +
   1.404 +        *shmem = mRemoteImageDataShmem;
   1.405 +
   1.406 +        mRemoteImageDataMutex = new CrossProcessMutex("PluginInstanceParent.mRemoteImageDataMutex");
   1.407 +
   1.408 +        *mutex = mRemoteImageDataMutex->ShareToProcess(OtherProcess());
   1.409 +        container->SetRemoteImageData(mRemoteImageDataShmem.get<RemoteImageData>(), mRemoteImageDataMutex);
   1.410 +
   1.411 +        mNotifySink = new NotificationSink(this);
   1.412 +
   1.413 +        container->SetCompositionNotifySink(mNotifySink);
   1.414 +    } else if (
   1.415 +#if defined(XP_WIN)
   1.416 +               drawingModel == NPDrawingModelSyncWin
   1.417 +#elif defined(XP_MACOSX)
   1.418 +               drawingModel == NPDrawingModelOpenGL ||
   1.419 +               drawingModel == NPDrawingModelCoreGraphics
   1.420 +#elif defined(MOZ_X11)
   1.421 +               drawingModel == NPDrawingModelSyncX
   1.422 +#else
   1.423 +               false
   1.424 +#endif
   1.425 +               ) {
   1.426 +        *shmem = null_t();
   1.427 +
   1.428 +        mDrawingModel = drawingModel;
   1.429 +        *result = mNPNIface->setvalue(mNPP, NPPVpluginDrawingModel,
   1.430 +                                      (void*)(intptr_t)drawingModel);
   1.431 +
   1.432 +        if (mRemoteImageDataShmem.IsWritable()) {
   1.433 +            if (mImageContainer) {
   1.434 +                mImageContainer->SetRemoteImageData(nullptr, nullptr);
   1.435 +                mImageContainer->SetCompositionNotifySink(nullptr);
   1.436 +            }
   1.437 +            DeallocShmem(mRemoteImageDataShmem);
   1.438 +            mRemoteImageDataMutex = nullptr;
   1.439 +        }
   1.440 +    } else {
   1.441 +        *result = NPERR_GENERIC_ERROR;
   1.442 +    }
   1.443 +    return true;
   1.444 +}
   1.445 +
   1.446 +bool
   1.447 +PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginEventModel(
   1.448 +    const int& eventModel, NPError* result)
   1.449 +{
   1.450 +#ifdef XP_MACOSX
   1.451 +    *result = mNPNIface->setvalue(mNPP, NPPVpluginEventModel,
   1.452 +                                  (void*)(intptr_t)eventModel);
   1.453 +    return true;
   1.454 +#else
   1.455 +    *result = NPERR_GENERIC_ERROR;
   1.456 +    return true;
   1.457 +#endif
   1.458 +}
   1.459 +
   1.460 +bool
   1.461 +PluginInstanceParent::AnswerNPN_GetURL(const nsCString& url,
   1.462 +                                       const nsCString& target,
   1.463 +                                       NPError* result)
   1.464 +{
   1.465 +    *result = mNPNIface->geturl(mNPP,
   1.466 +                                NullableStringGet(url),
   1.467 +                                NullableStringGet(target));
   1.468 +    return true;
   1.469 +}
   1.470 +
   1.471 +bool
   1.472 +PluginInstanceParent::AnswerNPN_PostURL(const nsCString& url,
   1.473 +                                        const nsCString& target,
   1.474 +                                        const nsCString& buffer,
   1.475 +                                        const bool& file,
   1.476 +                                        NPError* result)
   1.477 +{
   1.478 +    *result = mNPNIface->posturl(mNPP, url.get(), NullableStringGet(target),
   1.479 +                                 buffer.Length(), buffer.get(), file);
   1.480 +    return true;
   1.481 +}
   1.482 +
   1.483 +PStreamNotifyParent*
   1.484 +PluginInstanceParent::AllocPStreamNotifyParent(const nsCString& url,
   1.485 +                                               const nsCString& target,
   1.486 +                                               const bool& post,
   1.487 +                                               const nsCString& buffer,
   1.488 +                                               const bool& file,
   1.489 +                                               NPError* result)
   1.490 +{
   1.491 +    return new StreamNotifyParent();
   1.492 +}
   1.493 +
   1.494 +bool
   1.495 +PluginInstanceParent::AnswerPStreamNotifyConstructor(PStreamNotifyParent* actor,
   1.496 +                                                     const nsCString& url,
   1.497 +                                                     const nsCString& target,
   1.498 +                                                     const bool& post,
   1.499 +                                                     const nsCString& buffer,
   1.500 +                                                     const bool& file,
   1.501 +                                                     NPError* result)
   1.502 +{
   1.503 +    bool streamDestroyed = false;
   1.504 +    static_cast<StreamNotifyParent*>(actor)->
   1.505 +        SetDestructionFlag(&streamDestroyed);
   1.506 +
   1.507 +    if (!post) {
   1.508 +        *result = mNPNIface->geturlnotify(mNPP,
   1.509 +                                          NullableStringGet(url),
   1.510 +                                          NullableStringGet(target),
   1.511 +                                          actor);
   1.512 +    }
   1.513 +    else {
   1.514 +        *result = mNPNIface->posturlnotify(mNPP,
   1.515 +                                           NullableStringGet(url),
   1.516 +                                           NullableStringGet(target),
   1.517 +                                           buffer.Length(),
   1.518 +                                           NullableStringGet(buffer),
   1.519 +                                           file, actor);
   1.520 +    }
   1.521 +
   1.522 +    if (streamDestroyed) {
   1.523 +        // If the stream was destroyed, we must return an error code in the
   1.524 +        // constructor.
   1.525 +        *result = NPERR_GENERIC_ERROR;
   1.526 +    }
   1.527 +    else {
   1.528 +        static_cast<StreamNotifyParent*>(actor)->ClearDestructionFlag();
   1.529 +        if (*result != NPERR_NO_ERROR)
   1.530 +            return PStreamNotifyParent::Send__delete__(actor,
   1.531 +                                                       NPERR_GENERIC_ERROR);
   1.532 +    }
   1.533 +
   1.534 +    return true;
   1.535 +}
   1.536 +
   1.537 +bool
   1.538 +PluginInstanceParent::DeallocPStreamNotifyParent(PStreamNotifyParent* notifyData)
   1.539 +{
   1.540 +    delete notifyData;
   1.541 +    return true;
   1.542 +}
   1.543 +
   1.544 +bool
   1.545 +PluginInstanceParent::RecvNPN_InvalidateRect(const NPRect& rect)
   1.546 +{
   1.547 +    mNPNIface->invalidaterect(mNPP, const_cast<NPRect*>(&rect));
   1.548 +    return true;
   1.549 +}
   1.550 +
   1.551 +bool
   1.552 +PluginInstanceParent::RecvShow(const NPRect& updatedRect,
   1.553 +                               const SurfaceDescriptor& newSurface,
   1.554 +                               SurfaceDescriptor* prevSurface)
   1.555 +{
   1.556 +    PLUGIN_LOG_DEBUG(
   1.557 +        ("[InstanceParent][%p] RecvShow for <x=%d,y=%d, w=%d,h=%d>",
   1.558 +         this, updatedRect.left, updatedRect.top,
   1.559 +         updatedRect.right - updatedRect.left,
   1.560 +         updatedRect.bottom - updatedRect.top));
   1.561 +
   1.562 +    // XXXjwatt rewrite to use Moz2D
   1.563 +    nsRefPtr<gfxASurface> surface;
   1.564 +    if (newSurface.type() == SurfaceDescriptor::TShmem) {
   1.565 +        if (!newSurface.get_Shmem().IsReadable()) {
   1.566 +            NS_WARNING("back surface not readable");
   1.567 +            return false;
   1.568 +        }
   1.569 +        surface = gfxSharedImageSurface::Open(newSurface.get_Shmem());
   1.570 +    }
   1.571 +#ifdef XP_MACOSX
   1.572 +    else if (newSurface.type() == SurfaceDescriptor::TIOSurfaceDescriptor) {
   1.573 +        IOSurfaceDescriptor iodesc = newSurface.get_IOSurfaceDescriptor();
   1.574 +
   1.575 +        RefPtr<MacIOSurface> newIOSurface =
   1.576 +          MacIOSurface::LookupSurface(iodesc.surfaceId(),
   1.577 +                                      iodesc.contentsScaleFactor());
   1.578 +
   1.579 +        if (!newIOSurface) {
   1.580 +            NS_WARNING("Got bad IOSurfaceDescriptor in RecvShow");
   1.581 +            return false;
   1.582 +        }
   1.583 +      
   1.584 +        if (mFrontIOSurface)
   1.585 +            *prevSurface = IOSurfaceDescriptor(mFrontIOSurface->GetIOSurfaceID(),
   1.586 +                                               mFrontIOSurface->GetContentsScaleFactor());
   1.587 +        else
   1.588 +            *prevSurface = null_t();
   1.589 +
   1.590 +        mFrontIOSurface = newIOSurface;
   1.591 +
   1.592 +        RecvNPN_InvalidateRect(updatedRect);
   1.593 +
   1.594 +        PLUGIN_LOG_DEBUG(("   (RecvShow invalidated for surface %p)",
   1.595 +                          mFrontSurface.get()));
   1.596 +
   1.597 +        return true;
   1.598 +    }
   1.599 +#endif
   1.600 +#ifdef MOZ_X11
   1.601 +    else if (newSurface.type() == SurfaceDescriptor::TSurfaceDescriptorX11) {
   1.602 +        surface = newSurface.get_SurfaceDescriptorX11().OpenForeign();
   1.603 +    }
   1.604 +#endif
   1.605 +#ifdef XP_WIN
   1.606 +    else if (newSurface.type() == SurfaceDescriptor::TPPluginSurfaceParent) {
   1.607 +        PluginSurfaceParent* s =
   1.608 +            static_cast<PluginSurfaceParent*>(newSurface.get_PPluginSurfaceParent());
   1.609 +        surface = s->Surface();
   1.610 +    }
   1.611 +#endif
   1.612 +
   1.613 +    if (mFrontSurface) {
   1.614 +        // This is the "old front buffer" we're about to hand back to
   1.615 +        // the plugin.  We might still have drawing operations
   1.616 +        // referencing it.
   1.617 +#ifdef MOZ_X11
   1.618 +        if (mFrontSurface->GetType() == gfxSurfaceType::Xlib) {
   1.619 +            // Finish with the surface and XSync here to ensure the server has
   1.620 +            // finished operations on the surface before the plugin starts
   1.621 +            // scribbling on it again, or worse, destroys it.
   1.622 +            mFrontSurface->Finish();
   1.623 +            FinishX(DefaultXDisplay());
   1.624 +        } else 
   1.625 +#endif
   1.626 +        {
   1.627 +            mFrontSurface->Flush();
   1.628 +        }
   1.629 +    }
   1.630 +
   1.631 +    if (mFrontSurface && gfxSharedImageSurface::IsSharedImage(mFrontSurface))
   1.632 +        *prevSurface = static_cast<gfxSharedImageSurface*>(mFrontSurface.get())->GetShmem();
   1.633 +    else
   1.634 +        *prevSurface = null_t();
   1.635 +
   1.636 +    if (surface) {
   1.637 +        // Notify the cairo backend that this surface has changed behind
   1.638 +        // its back.
   1.639 +        gfxRect ur(updatedRect.left, updatedRect.top,
   1.640 +                   updatedRect.right - updatedRect.left,
   1.641 +                   updatedRect.bottom - updatedRect.top);
   1.642 +        surface->MarkDirty(ur);
   1.643 +
   1.644 +        ImageContainer *container = GetImageContainer();
   1.645 +        nsRefPtr<Image> image = container->CreateImage(ImageFormat::CAIRO_SURFACE);
   1.646 +        NS_ASSERTION(image->GetFormat() == ImageFormat::CAIRO_SURFACE, "Wrong format?");
   1.647 +        CairoImage* cairoImage = static_cast<CairoImage*>(image.get());
   1.648 +        CairoImage::Data cairoData;
   1.649 +        cairoData.mSize = surface->GetSize().ToIntSize();
   1.650 +        cairoData.mSourceSurface = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, surface);
   1.651 +        cairoImage->SetData(cairoData);
   1.652 +
   1.653 +        container->SetCurrentImage(cairoImage);
   1.654 +    }
   1.655 +    else if (mImageContainer) {
   1.656 +        mImageContainer->SetCurrentImage(nullptr);
   1.657 +    }
   1.658 +
   1.659 +    mFrontSurface = surface;
   1.660 +    RecvNPN_InvalidateRect(updatedRect);
   1.661 +
   1.662 +    PLUGIN_LOG_DEBUG(("   (RecvShow invalidated for surface %p)",
   1.663 +                      mFrontSurface.get()));
   1.664 +
   1.665 +    return true;
   1.666 +}
   1.667 +
   1.668 +nsresult
   1.669 +PluginInstanceParent::AsyncSetWindow(NPWindow* aWindow)
   1.670 +{
   1.671 +    NPRemoteWindow window;
   1.672 +    mWindowType = aWindow->type;
   1.673 +    window.window = reinterpret_cast<uint64_t>(aWindow->window);
   1.674 +    window.x = aWindow->x;
   1.675 +    window.y = aWindow->y;
   1.676 +    window.width = aWindow->width;
   1.677 +    window.height = aWindow->height;
   1.678 +    window.clipRect = aWindow->clipRect;
   1.679 +    window.type = aWindow->type;
   1.680 +#ifdef XP_MACOSX
   1.681 +    double scaleFactor = 1.0;
   1.682 +    mNPNIface->getvalue(mNPP, NPNVcontentsScaleFactor, &scaleFactor);
   1.683 +    window.contentsScaleFactor = scaleFactor;
   1.684 +#endif
   1.685 +    if (!SendAsyncSetWindow(gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType(),
   1.686 +                            window))
   1.687 +        return NS_ERROR_FAILURE;
   1.688 +
   1.689 +    return NS_OK;
   1.690 +}
   1.691 +
   1.692 +nsresult
   1.693 +PluginInstanceParent::GetImageContainer(ImageContainer** aContainer)
   1.694 +{
   1.695 +#ifdef XP_MACOSX
   1.696 +    MacIOSurface* ioSurface = nullptr;
   1.697 +  
   1.698 +    if (mFrontIOSurface) {
   1.699 +      ioSurface = mFrontIOSurface;
   1.700 +    } else if (mIOSurface) {
   1.701 +      ioSurface = mIOSurface;
   1.702 +    }
   1.703 +
   1.704 +    if (!mFrontSurface && !ioSurface)
   1.705 +#else
   1.706 +    if (!mFrontSurface)
   1.707 +#endif
   1.708 +        return NS_ERROR_NOT_AVAILABLE;
   1.709 +
   1.710 +    ImageContainer *container = GetImageContainer();
   1.711 +
   1.712 +    if (!container) {
   1.713 +        return NS_ERROR_FAILURE;
   1.714 +    }
   1.715 +
   1.716 +    if (IsAsyncDrawing()) {
   1.717 +      NS_IF_ADDREF(container);
   1.718 +      *aContainer = container;
   1.719 +      return NS_OK;
   1.720 +    }
   1.721 +
   1.722 +#ifdef XP_MACOSX
   1.723 +    if (ioSurface) {
   1.724 +        nsRefPtr<Image> image = container->CreateImage(ImageFormat::MAC_IOSURFACE);
   1.725 +        if (!image) {
   1.726 +            return NS_ERROR_FAILURE;
   1.727 +        }
   1.728 +
   1.729 +        NS_ASSERTION(image->GetFormat() == ImageFormat::MAC_IOSURFACE, "Wrong format?");
   1.730 +
   1.731 +        MacIOSurfaceImage* pluginImage = static_cast<MacIOSurfaceImage*>(image.get());
   1.732 +        pluginImage->SetSurface(ioSurface);
   1.733 +
   1.734 +        container->SetCurrentImageInTransaction(pluginImage);
   1.735 +
   1.736 +        NS_IF_ADDREF(container);
   1.737 +        *aContainer = container;
   1.738 +        return NS_OK;
   1.739 +    }
   1.740 +#endif
   1.741 +
   1.742 +    NS_IF_ADDREF(container);
   1.743 +    *aContainer = container;
   1.744 +    return NS_OK;
   1.745 +}
   1.746 +
   1.747 +nsresult
   1.748 +PluginInstanceParent::GetImageSize(nsIntSize* aSize)
   1.749 +{
   1.750 +    if (mFrontSurface) {
   1.751 +        gfxIntSize size = mFrontSurface->GetSize();
   1.752 +        *aSize = nsIntSize(size.width, size.height);
   1.753 +        return NS_OK;
   1.754 +    }
   1.755 +
   1.756 +#ifdef XP_MACOSX
   1.757 +    if (mFrontIOSurface) {
   1.758 +        *aSize = nsIntSize(mFrontIOSurface->GetWidth(), mFrontIOSurface->GetHeight());
   1.759 +        return NS_OK;
   1.760 +    } else if (mIOSurface) {
   1.761 +        *aSize = nsIntSize(mIOSurface->GetWidth(), mIOSurface->GetHeight());
   1.762 +        return NS_OK;
   1.763 +    }
   1.764 +#endif
   1.765 +
   1.766 +    return NS_ERROR_NOT_AVAILABLE;
   1.767 +}
   1.768 +
   1.769 +#ifdef XP_MACOSX
   1.770 +nsresult
   1.771 +PluginInstanceParent::IsRemoteDrawingCoreAnimation(bool *aDrawing)
   1.772 +{
   1.773 +    *aDrawing = (NPDrawingModelCoreAnimation == (NPDrawingModel)mDrawingModel ||
   1.774 +                 NPDrawingModelInvalidatingCoreAnimation == (NPDrawingModel)mDrawingModel);
   1.775 +    return NS_OK;
   1.776 +}
   1.777 +
   1.778 +nsresult
   1.779 +PluginInstanceParent::ContentsScaleFactorChanged(double aContentsScaleFactor)
   1.780 +{
   1.781 +    bool rv = SendContentsScaleFactorChanged(aContentsScaleFactor);
   1.782 +    return rv ? NS_OK : NS_ERROR_FAILURE;
   1.783 +}
   1.784 +#endif // #ifdef XP_MACOSX
   1.785 +
   1.786 +nsresult
   1.787 +PluginInstanceParent::SetBackgroundUnknown()
   1.788 +{
   1.789 +    PLUGIN_LOG_DEBUG(("[InstanceParent][%p] SetBackgroundUnknown", this));
   1.790 +
   1.791 +    if (mBackground) {
   1.792 +        DestroyBackground();
   1.793 +        NS_ABORT_IF_FALSE(!mBackground, "Background not destroyed");
   1.794 +    }
   1.795 +
   1.796 +    return NS_OK;
   1.797 +}
   1.798 +
   1.799 +nsresult
   1.800 +PluginInstanceParent::BeginUpdateBackground(const nsIntRect& aRect,
   1.801 +                                            gfxContext** aCtx)
   1.802 +{
   1.803 +    PLUGIN_LOG_DEBUG(
   1.804 +        ("[InstanceParent][%p] BeginUpdateBackground for <x=%d,y=%d, w=%d,h=%d>",
   1.805 +         this, aRect.x, aRect.y, aRect.width, aRect.height));
   1.806 +
   1.807 +    if (!mBackground) {
   1.808 +        // XXX if we failed to create a background surface on one
   1.809 +        // update, there's no guarantee that later updates will be for
   1.810 +        // the entire background area until successful.  We might want
   1.811 +        // to fix that eventually.
   1.812 +        NS_ABORT_IF_FALSE(aRect.TopLeft() == nsIntPoint(0, 0),
   1.813 +                          "Expecting rect for whole frame");
   1.814 +        if (!CreateBackground(aRect.Size())) {
   1.815 +            *aCtx = nullptr;
   1.816 +            return NS_OK;
   1.817 +        }
   1.818 +    }
   1.819 +
   1.820 +    gfxIntSize sz = mBackground->GetSize();
   1.821 +#ifdef DEBUG
   1.822 +    NS_ABORT_IF_FALSE(nsIntRect(0, 0, sz.width, sz.height).Contains(aRect),
   1.823 +                      "Update outside of background area");
   1.824 +#endif
   1.825 +
   1.826 +    RefPtr<gfx::DrawTarget> dt = gfxPlatform::GetPlatform()->
   1.827 +      CreateDrawTargetForSurface(mBackground, gfx::IntSize(sz.width, sz.height));
   1.828 +    nsRefPtr<gfxContext> ctx = new gfxContext(dt);
   1.829 +    ctx.forget(aCtx);
   1.830 +
   1.831 +    return NS_OK;
   1.832 +}
   1.833 +
   1.834 +nsresult
   1.835 +PluginInstanceParent::EndUpdateBackground(gfxContext* aCtx,
   1.836 +                                          const nsIntRect& aRect)
   1.837 +{
   1.838 +    PLUGIN_LOG_DEBUG(
   1.839 +        ("[InstanceParent][%p] EndUpdateBackground for <x=%d,y=%d, w=%d,h=%d>",
   1.840 +         this, aRect.x, aRect.y, aRect.width, aRect.height));
   1.841 +
   1.842 +#ifdef MOZ_X11
   1.843 +    // Have to XSync here to avoid the plugin trying to draw with this
   1.844 +    // surface racing with its creation in the X server.  We also want
   1.845 +    // to avoid the plugin drawing onto stale pixels, then handing us
   1.846 +    // back a front surface from those pixels that we might
   1.847 +    // recomposite for "a while" until the next update.  This XSync
   1.848 +    // still doesn't guarantee that the plugin draws onto a consistent
   1.849 +    // view of its background, but it does mean that the plugin is
   1.850 +    // drawing onto pixels no older than those in the latest
   1.851 +    // EndUpdateBackground().
   1.852 +    XSync(DefaultXDisplay(), False);
   1.853 +#endif
   1.854 +
   1.855 +    unused << SendUpdateBackground(BackgroundDescriptor(), aRect);
   1.856 +
   1.857 +    return NS_OK;
   1.858 +}
   1.859 +
   1.860 +bool
   1.861 +PluginInstanceParent::CreateBackground(const nsIntSize& aSize)
   1.862 +{
   1.863 +    NS_ABORT_IF_FALSE(!mBackground, "Already have a background");
   1.864 +
   1.865 +    // XXX refactor me
   1.866 +
   1.867 +#if defined(MOZ_X11)
   1.868 +    Screen* screen = DefaultScreenOfDisplay(DefaultXDisplay());
   1.869 +    Visual* visual = DefaultVisualOfScreen(screen);
   1.870 +    mBackground = gfxXlibSurface::Create(screen, visual,
   1.871 +                                         gfxIntSize(aSize.width, aSize.height));
   1.872 +    return !!mBackground;
   1.873 +
   1.874 +#elif defined(XP_WIN)
   1.875 +    // We have chosen to create an unsafe surface in which the plugin
   1.876 +    // can read from the region while we're writing to it.
   1.877 +    mBackground =
   1.878 +        gfxSharedImageSurface::CreateUnsafe(
   1.879 +            this,
   1.880 +            gfxIntSize(aSize.width, aSize.height),
   1.881 +            gfxImageFormat::RGB24);
   1.882 +    return !!mBackground;
   1.883 +#else
   1.884 +    return nullptr;
   1.885 +#endif
   1.886 +}
   1.887 +
   1.888 +void
   1.889 +PluginInstanceParent::DestroyBackground()
   1.890 +{
   1.891 +    if (!mBackground) {
   1.892 +        return;
   1.893 +    }
   1.894 +
   1.895 +    // Relinquish ownership of |mBackground| to its destroyer
   1.896 +    PPluginBackgroundDestroyerParent* pbd =
   1.897 +        new PluginBackgroundDestroyerParent(mBackground);
   1.898 +    mBackground = nullptr;
   1.899 +
   1.900 +    // If this fails, there's no problem: |bd| will be destroyed along
   1.901 +    // with the old background surface.
   1.902 +    unused << SendPPluginBackgroundDestroyerConstructor(pbd);
   1.903 +}
   1.904 +
   1.905 +mozilla::plugins::SurfaceDescriptor
   1.906 +PluginInstanceParent::BackgroundDescriptor()
   1.907 +{
   1.908 +    NS_ABORT_IF_FALSE(mBackground, "Need a background here");
   1.909 +
   1.910 +    // XXX refactor me
   1.911 +
   1.912 +#ifdef MOZ_X11
   1.913 +    gfxXlibSurface* xsurf = static_cast<gfxXlibSurface*>(mBackground.get());
   1.914 +    return SurfaceDescriptorX11(xsurf);
   1.915 +#endif
   1.916 +
   1.917 +#ifdef XP_WIN
   1.918 +    NS_ABORT_IF_FALSE(gfxSharedImageSurface::IsSharedImage(mBackground),
   1.919 +                      "Expected shared image surface");
   1.920 +    gfxSharedImageSurface* shmem =
   1.921 +        static_cast<gfxSharedImageSurface*>(mBackground.get());
   1.922 +    return shmem->GetShmem();
   1.923 +#endif
   1.924 +
   1.925 +    // If this is ever used, which it shouldn't be, it will trigger a
   1.926 +    // hard assertion in IPDL-generated code.
   1.927 +    return mozilla::plugins::SurfaceDescriptor();
   1.928 +}
   1.929 +
   1.930 +ImageContainer*
   1.931 +PluginInstanceParent::GetImageContainer()
   1.932 +{
   1.933 +  if (mImageContainer) {
   1.934 +    return mImageContainer;
   1.935 +  }
   1.936 +
   1.937 +  mImageContainer = LayerManager::CreateImageContainer();
   1.938 +  return mImageContainer;
   1.939 +}
   1.940 +
   1.941 +PPluginBackgroundDestroyerParent*
   1.942 +PluginInstanceParent::AllocPPluginBackgroundDestroyerParent()
   1.943 +{
   1.944 +    NS_RUNTIMEABORT("'Power-user' ctor is used exclusively");
   1.945 +    return nullptr;
   1.946 +}
   1.947 +
   1.948 +bool
   1.949 +PluginInstanceParent::DeallocPPluginBackgroundDestroyerParent(
   1.950 +    PPluginBackgroundDestroyerParent* aActor)
   1.951 +{
   1.952 +    delete aActor;
   1.953 +    return true;
   1.954 +}
   1.955 +
   1.956 +NPError
   1.957 +PluginInstanceParent::NPP_SetWindow(const NPWindow* aWindow)
   1.958 +{
   1.959 +    PLUGIN_LOG_DEBUG(("%s (aWindow=%p)", FULLFUNCTION, (void*) aWindow));
   1.960 +
   1.961 +    NS_ENSURE_TRUE(aWindow, NPERR_GENERIC_ERROR);
   1.962 +
   1.963 +    NPRemoteWindow window;
   1.964 +    mWindowType = aWindow->type;
   1.965 +
   1.966 +#if defined(OS_WIN)
   1.967 +    // On windowless controls, reset the shared memory surface as needed.
   1.968 +    if (mWindowType == NPWindowTypeDrawable) {
   1.969 +        // SharedSurfaceSetWindow will take care of NPRemoteWindow.
   1.970 +        if (!SharedSurfaceSetWindow(aWindow, window)) {
   1.971 +          return NPERR_OUT_OF_MEMORY_ERROR;
   1.972 +        }
   1.973 +    }
   1.974 +    else {
   1.975 +        SubclassPluginWindow(reinterpret_cast<HWND>(aWindow->window));
   1.976 +
   1.977 +        window.window = reinterpret_cast<uint64_t>(aWindow->window);
   1.978 +        window.x = aWindow->x;
   1.979 +        window.y = aWindow->y;
   1.980 +        window.width = aWindow->width;
   1.981 +        window.height = aWindow->height;
   1.982 +        window.type = aWindow->type;
   1.983 +    }
   1.984 +#else
   1.985 +    window.window = reinterpret_cast<uint64_t>(aWindow->window);
   1.986 +    window.x = aWindow->x;
   1.987 +    window.y = aWindow->y;
   1.988 +    window.width = aWindow->width;
   1.989 +    window.height = aWindow->height;
   1.990 +    window.clipRect = aWindow->clipRect; // MacOS specific
   1.991 +    window.type = aWindow->type;
   1.992 +#endif
   1.993 +
   1.994 +#if defined(XP_MACOSX)
   1.995 +    double floatScaleFactor = 1.0;
   1.996 +    mNPNIface->getvalue(mNPP, NPNVcontentsScaleFactor, &floatScaleFactor);
   1.997 +    int scaleFactor = ceil(floatScaleFactor);
   1.998 +    window.contentsScaleFactor = floatScaleFactor;
   1.999 +
  1.1000 +    if (mShWidth != window.width * scaleFactor || mShHeight != window.height * scaleFactor) {
  1.1001 +        if (mDrawingModel == NPDrawingModelCoreAnimation || 
  1.1002 +            mDrawingModel == NPDrawingModelInvalidatingCoreAnimation) {
  1.1003 +            mIOSurface = MacIOSurface::CreateIOSurface(window.width, window.height,
  1.1004 +                                                       floatScaleFactor);
  1.1005 +        } else if (uint32_t(mShWidth * mShHeight) !=
  1.1006 +                   window.width * scaleFactor * window.height * scaleFactor) {
  1.1007 +            if (mShWidth != 0 && mShHeight != 0) {
  1.1008 +                DeallocShmem(mShSurface);
  1.1009 +                mShWidth = 0;
  1.1010 +                mShHeight = 0;
  1.1011 +            }
  1.1012 +
  1.1013 +            if (window.width != 0 && window.height != 0) {
  1.1014 +                if (!AllocShmem(window.width * scaleFactor * window.height*4 * scaleFactor,
  1.1015 +                                SharedMemory::TYPE_BASIC, &mShSurface)) {
  1.1016 +                    PLUGIN_LOG_DEBUG(("Shared memory could not be allocated."));
  1.1017 +                    return NPERR_GENERIC_ERROR;
  1.1018 +                } 
  1.1019 +            }
  1.1020 +        }
  1.1021 +        mShWidth = window.width * scaleFactor;
  1.1022 +        mShHeight = window.height * scaleFactor;
  1.1023 +    }
  1.1024 +#endif
  1.1025 +
  1.1026 +#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
  1.1027 +    const NPSetWindowCallbackStruct* ws_info =
  1.1028 +      static_cast<NPSetWindowCallbackStruct*>(aWindow->ws_info);
  1.1029 +    window.visualID = ws_info->visual ? ws_info->visual->visualid : None;
  1.1030 +    window.colormap = ws_info->colormap;
  1.1031 +#endif
  1.1032 +
  1.1033 +    if (!CallNPP_SetWindow(window))
  1.1034 +        return NPERR_GENERIC_ERROR;
  1.1035 +
  1.1036 +    return NPERR_NO_ERROR;
  1.1037 +}
  1.1038 +
  1.1039 +NPError
  1.1040 +PluginInstanceParent::NPP_GetValue(NPPVariable aVariable,
  1.1041 +                                   void* _retval)
  1.1042 +{
  1.1043 +    switch (aVariable) {
  1.1044 +
  1.1045 +    case NPPVpluginWantsAllNetworkStreams: {
  1.1046 +        bool wantsAllStreams;
  1.1047 +        NPError rv;
  1.1048 +
  1.1049 +        if (!CallNPP_GetValue_NPPVpluginWantsAllNetworkStreams(&wantsAllStreams, &rv)) {
  1.1050 +            return NPERR_GENERIC_ERROR;
  1.1051 +        }
  1.1052 +
  1.1053 +        if (NPERR_NO_ERROR != rv) {
  1.1054 +            return rv;
  1.1055 +        }
  1.1056 +
  1.1057 +        (*(NPBool*)_retval) = wantsAllStreams;
  1.1058 +        return NPERR_NO_ERROR;
  1.1059 +    }
  1.1060 +
  1.1061 +#ifdef MOZ_X11
  1.1062 +    case NPPVpluginNeedsXEmbed: {
  1.1063 +        bool needsXEmbed;
  1.1064 +        NPError rv;
  1.1065 +
  1.1066 +        if (!CallNPP_GetValue_NPPVpluginNeedsXEmbed(&needsXEmbed, &rv)) {
  1.1067 +            return NPERR_GENERIC_ERROR;
  1.1068 +        }
  1.1069 +
  1.1070 +        if (NPERR_NO_ERROR != rv) {
  1.1071 +            return rv;
  1.1072 +        }
  1.1073 +
  1.1074 +        (*(NPBool*)_retval) = needsXEmbed;
  1.1075 +        return NPERR_NO_ERROR;
  1.1076 +    }
  1.1077 +#endif
  1.1078 +
  1.1079 +    case NPPVpluginScriptableNPObject: {
  1.1080 +        PPluginScriptableObjectParent* actor;
  1.1081 +        NPError rv;
  1.1082 +        if (!CallNPP_GetValue_NPPVpluginScriptableNPObject(&actor, &rv)) {
  1.1083 +            return NPERR_GENERIC_ERROR;
  1.1084 +        }
  1.1085 +
  1.1086 +        if (NPERR_NO_ERROR != rv) {
  1.1087 +            return rv;
  1.1088 +        }
  1.1089 +
  1.1090 +        if (!actor) {
  1.1091 +            NS_ERROR("NPPVpluginScriptableNPObject succeeded but null.");
  1.1092 +            return NPERR_GENERIC_ERROR;
  1.1093 +        }
  1.1094 +
  1.1095 +        const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs();
  1.1096 +        if (!npn) {
  1.1097 +            NS_WARNING("No netscape functions?!");
  1.1098 +            return NPERR_GENERIC_ERROR;
  1.1099 +        }
  1.1100 +
  1.1101 +        NPObject* object =
  1.1102 +            static_cast<PluginScriptableObjectParent*>(actor)->GetObject(true);
  1.1103 +        NS_ASSERTION(object, "This shouldn't ever be null!");
  1.1104 +
  1.1105 +        (*(NPObject**)_retval) = npn->retainobject(object);
  1.1106 +        return NPERR_NO_ERROR;
  1.1107 +    }
  1.1108 +
  1.1109 +#ifdef MOZ_ACCESSIBILITY_ATK
  1.1110 +    case NPPVpluginNativeAccessibleAtkPlugId: {
  1.1111 +        nsCString plugId;
  1.1112 +        NPError rv;
  1.1113 +        if (!CallNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId(&plugId, &rv)) {
  1.1114 +            return NPERR_GENERIC_ERROR;
  1.1115 +        }
  1.1116 +
  1.1117 +        if (NPERR_NO_ERROR != rv) {
  1.1118 +            return rv;
  1.1119 +        }
  1.1120 +
  1.1121 +        (*(nsCString*)_retval) = plugId;
  1.1122 +        return NPERR_NO_ERROR;
  1.1123 +    }
  1.1124 +#endif
  1.1125 +
  1.1126 +    default:
  1.1127 +        PR_LOG(GetPluginLog(), PR_LOG_WARNING,
  1.1128 +               ("In PluginInstanceParent::NPP_GetValue: Unhandled NPPVariable %i (%s)",
  1.1129 +                (int) aVariable, NPPVariableToString(aVariable)));
  1.1130 +        return NPERR_GENERIC_ERROR;
  1.1131 +    }
  1.1132 +}
  1.1133 +
  1.1134 +NPError
  1.1135 +PluginInstanceParent::NPP_SetValue(NPNVariable variable, void* value)
  1.1136 +{
  1.1137 +    switch (variable) {
  1.1138 +    case NPNVprivateModeBool:
  1.1139 +        NPError result;
  1.1140 +        if (!CallNPP_SetValue_NPNVprivateModeBool(*static_cast<NPBool*>(value),
  1.1141 +                                                  &result))
  1.1142 +            return NPERR_GENERIC_ERROR;
  1.1143 +
  1.1144 +        return result;
  1.1145 +
  1.1146 +    default:
  1.1147 +        NS_ERROR("Unhandled NPNVariable in NPP_SetValue");
  1.1148 +        PR_LOG(GetPluginLog(), PR_LOG_WARNING,
  1.1149 +               ("In PluginInstanceParent::NPP_SetValue: Unhandled NPNVariable %i (%s)",
  1.1150 +                (int) variable, NPNVariableToString(variable)));
  1.1151 +        return NPERR_GENERIC_ERROR;
  1.1152 +    }
  1.1153 +}
  1.1154 +
  1.1155 +void
  1.1156 +PluginInstanceParent::NPP_URLRedirectNotify(const char* url, int32_t status,
  1.1157 +                                            void* notifyData)
  1.1158 +{
  1.1159 +  if (!notifyData)
  1.1160 +    return;
  1.1161 +
  1.1162 +  PStreamNotifyParent* streamNotify = static_cast<PStreamNotifyParent*>(notifyData);
  1.1163 +  unused << streamNotify->SendRedirectNotify(NullableString(url), status);
  1.1164 +}
  1.1165 +
  1.1166 +int16_t
  1.1167 +PluginInstanceParent::NPP_HandleEvent(void* event)
  1.1168 +{
  1.1169 +    PLUGIN_LOG_DEBUG_FUNCTION;
  1.1170 +
  1.1171 +#if defined(XP_MACOSX)
  1.1172 +    NPCocoaEvent* npevent = reinterpret_cast<NPCocoaEvent*>(event);
  1.1173 +#else
  1.1174 +    NPEvent* npevent = reinterpret_cast<NPEvent*>(event);
  1.1175 +#endif
  1.1176 +    NPRemoteEvent npremoteevent;
  1.1177 +    npremoteevent.event = *npevent;
  1.1178 +#if defined(XP_MACOSX)
  1.1179 +    double scaleFactor = 1.0;
  1.1180 +    mNPNIface->getvalue(mNPP, NPNVcontentsScaleFactor, &scaleFactor);
  1.1181 +    npremoteevent.contentsScaleFactor = scaleFactor;
  1.1182 +#endif
  1.1183 +    int16_t handled = 0;
  1.1184 +
  1.1185 +#if defined(OS_WIN)
  1.1186 +    if (mWindowType == NPWindowTypeDrawable) {
  1.1187 +        if (IsAsyncDrawing()) {
  1.1188 +            if (npevent->event == WM_PAINT || npevent->event == DoublePassRenderingEvent()) {
  1.1189 +                // This plugin maintains its own async drawing.
  1.1190 +                return handled;
  1.1191 +            }
  1.1192 +        }
  1.1193 +        if (DoublePassRenderingEvent() == npevent->event) {
  1.1194 +            return CallPaint(npremoteevent, &handled) && handled;
  1.1195 +        }
  1.1196 +
  1.1197 +        switch (npevent->event) {
  1.1198 +            case WM_PAINT:
  1.1199 +            {
  1.1200 +                RECT rect;
  1.1201 +                SharedSurfaceBeforePaint(rect, npremoteevent);
  1.1202 +                if (!CallPaint(npremoteevent, &handled)) {
  1.1203 +                    handled = false;
  1.1204 +                }
  1.1205 +                SharedSurfaceAfterPaint(npevent);
  1.1206 +                return handled;
  1.1207 +            }
  1.1208 +            break;
  1.1209 +
  1.1210 +            case WM_KILLFOCUS:
  1.1211 +            {
  1.1212 +              // When the user selects fullscreen mode in Flash video players,
  1.1213 +              // WM_KILLFOCUS will be delayed by deferred event processing:
  1.1214 +              // WM_LBUTTONUP results in a call to CreateWindow within Flash,
  1.1215 +              // which fires WM_KILLFOCUS. Delayed delivery causes Flash to
  1.1216 +              // misinterpret the event, dropping back out of fullscreen. Trap
  1.1217 +              // this event and drop it.
  1.1218 +              wchar_t szClass[26];
  1.1219 +              HWND hwnd = GetForegroundWindow();
  1.1220 +              if (hwnd && hwnd != mPluginHWND &&
  1.1221 +                  GetClassNameW(hwnd, szClass,
  1.1222 +                                sizeof(szClass)/sizeof(char16_t)) &&
  1.1223 +                  !wcscmp(szClass, kFlashFullscreenClass)) {
  1.1224 +                  return 0;
  1.1225 +              }
  1.1226 +            }
  1.1227 +            break;
  1.1228 +
  1.1229 +            case WM_WINDOWPOSCHANGED:
  1.1230 +            {
  1.1231 +                // We send this in nsObjectFrame just before painting
  1.1232 +                return SendWindowPosChanged(npremoteevent);
  1.1233 +            }
  1.1234 +            break;
  1.1235 +        }
  1.1236 +    }
  1.1237 +#endif
  1.1238 +
  1.1239 +#if defined(MOZ_X11)
  1.1240 +    switch (npevent->type) {
  1.1241 +    case GraphicsExpose:
  1.1242 +        PLUGIN_LOG_DEBUG(("  schlepping drawable 0x%lx across the pipe\n",
  1.1243 +                          npevent->xgraphicsexpose.drawable));
  1.1244 +        // Make sure the X server has created the Drawable and completes any
  1.1245 +        // drawing before the plugin draws on top.
  1.1246 +        //
  1.1247 +        // XSync() waits for the X server to complete.  Really this parent
  1.1248 +        // process does not need to wait; the child is the process that needs
  1.1249 +        // to wait.  A possibly-slightly-better alternative would be to send
  1.1250 +        // an X event to the child that the child would wait for.
  1.1251 +        FinishX(DefaultXDisplay());
  1.1252 +
  1.1253 +        return CallPaint(npremoteevent, &handled) ? handled : 0;
  1.1254 +
  1.1255 +    case ButtonPress:
  1.1256 +        // Release any active pointer grab so that the plugin X client can
  1.1257 +        // grab the pointer if it wishes.
  1.1258 +        Display *dpy = DefaultXDisplay();
  1.1259 +#  ifdef MOZ_WIDGET_GTK
  1.1260 +        // GDK attempts to (asynchronously) track whether there is an active
  1.1261 +        // grab so ungrab through GDK.
  1.1262 +        gdk_pointer_ungrab(npevent->xbutton.time);
  1.1263 +#  else
  1.1264 +        XUngrabPointer(dpy, npevent->xbutton.time);
  1.1265 +#  endif
  1.1266 +        // Wait for the ungrab to complete.
  1.1267 +        XSync(dpy, False);
  1.1268 +        break;
  1.1269 +    }
  1.1270 +#endif
  1.1271 +
  1.1272 +#ifdef XP_MACOSX
  1.1273 +    if (npevent->type == NPCocoaEventDrawRect) {
  1.1274 +        if (mDrawingModel == NPDrawingModelCoreAnimation ||
  1.1275 +            mDrawingModel == NPDrawingModelInvalidatingCoreAnimation) {
  1.1276 +            if (!mIOSurface) {
  1.1277 +                NS_ERROR("No IOSurface allocated.");
  1.1278 +                return false;
  1.1279 +            }
  1.1280 +            if (!CallNPP_HandleEvent_IOSurface(npremoteevent, 
  1.1281 +                                               mIOSurface->GetIOSurfaceID(), 
  1.1282 +                                               &handled)) 
  1.1283 +                return false; // no good way to handle errors here...
  1.1284 +
  1.1285 +            CGContextRef cgContext = npevent->data.draw.context;
  1.1286 +            if (!mShColorSpace) {
  1.1287 +                mShColorSpace = CreateSystemColorSpace();
  1.1288 +            }
  1.1289 +            if (!mShColorSpace) {
  1.1290 +                PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
  1.1291 +                return false;
  1.1292 +            }
  1.1293 +            if (cgContext) {
  1.1294 +                nsCARenderer::DrawSurfaceToCGContext(cgContext, mIOSurface, 
  1.1295 +                                                     mShColorSpace,
  1.1296 +                                                     npevent->data.draw.x,
  1.1297 +                                                     npevent->data.draw.y,
  1.1298 +                                                     npevent->data.draw.width,
  1.1299 +                                                     npevent->data.draw.height);
  1.1300 +            }
  1.1301 +            return true;
  1.1302 +        } else if (mFrontIOSurface) {
  1.1303 +            CGContextRef cgContext = npevent->data.draw.context;
  1.1304 +            if (!mShColorSpace) {
  1.1305 +                mShColorSpace = CreateSystemColorSpace();
  1.1306 +            }
  1.1307 +            if (!mShColorSpace) {
  1.1308 +                PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
  1.1309 +                return false;
  1.1310 +            }
  1.1311 +            if (cgContext) {
  1.1312 +                nsCARenderer::DrawSurfaceToCGContext(cgContext, mFrontIOSurface, 
  1.1313 +                                                     mShColorSpace,
  1.1314 +                                                     npevent->data.draw.x,
  1.1315 +                                                     npevent->data.draw.y,
  1.1316 +                                                     npevent->data.draw.width,
  1.1317 +                                                     npevent->data.draw.height);
  1.1318 +            }
  1.1319 +            return true;
  1.1320 +        } else {
  1.1321 +            if (mShWidth == 0 && mShHeight == 0) {
  1.1322 +                PLUGIN_LOG_DEBUG(("NPCocoaEventDrawRect on window of size 0."));
  1.1323 +                return false;
  1.1324 +            }
  1.1325 +            if (!mShSurface.IsReadable()) {
  1.1326 +                PLUGIN_LOG_DEBUG(("Shmem is not readable."));
  1.1327 +                return false;
  1.1328 +            }
  1.1329 +
  1.1330 +            if (!CallNPP_HandleEvent_Shmem(npremoteevent, mShSurface, 
  1.1331 +                                           &handled, &mShSurface)) 
  1.1332 +                return false; // no good way to handle errors here...
  1.1333 +
  1.1334 +            if (!mShSurface.IsReadable()) {
  1.1335 +                PLUGIN_LOG_DEBUG(("Shmem not returned. Either the plugin crashed "
  1.1336 +                                  "or we have a bug."));
  1.1337 +                return false;
  1.1338 +            }
  1.1339 +
  1.1340 +            char* shContextByte = mShSurface.get<char>();
  1.1341 +
  1.1342 +            if (!mShColorSpace) {
  1.1343 +                mShColorSpace = CreateSystemColorSpace();
  1.1344 +            }
  1.1345 +            if (!mShColorSpace) {
  1.1346 +                PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
  1.1347 +                return false;
  1.1348 +            } 
  1.1349 +            CGContextRef shContext = ::CGBitmapContextCreate(shContextByte, 
  1.1350 +                                    mShWidth, mShHeight, 8, 
  1.1351 +                                    mShWidth*4, mShColorSpace, 
  1.1352 +                                    kCGImageAlphaPremultipliedFirst | 
  1.1353 +                                    kCGBitmapByteOrder32Host);
  1.1354 +            if (!shContext) {
  1.1355 +                PLUGIN_LOG_DEBUG(("Could not allocate CGBitmapContext."));
  1.1356 +                return false;
  1.1357 +            }
  1.1358 +
  1.1359 +            CGImageRef shImage = ::CGBitmapContextCreateImage(shContext);
  1.1360 +            if (shImage) {
  1.1361 +                CGContextRef cgContext = npevent->data.draw.context;
  1.1362 +     
  1.1363 +                ::CGContextDrawImage(cgContext, 
  1.1364 +                                     CGRectMake(0,0,mShWidth,mShHeight), 
  1.1365 +                                     shImage);
  1.1366 +                ::CGImageRelease(shImage);
  1.1367 +            } else {
  1.1368 +                ::CGContextRelease(shContext);
  1.1369 +                return false;
  1.1370 +            }
  1.1371 +            ::CGContextRelease(shContext);
  1.1372 +            return true;
  1.1373 +        }
  1.1374 +    }
  1.1375 +#endif
  1.1376 +
  1.1377 +    if (!CallNPP_HandleEvent(npremoteevent, &handled))
  1.1378 +        return 0; // no good way to handle errors here...
  1.1379 +
  1.1380 +    return handled;
  1.1381 +}
  1.1382 +
  1.1383 +NPError
  1.1384 +PluginInstanceParent::NPP_NewStream(NPMIMEType type, NPStream* stream,
  1.1385 +                                    NPBool seekable, uint16_t* stype)
  1.1386 +{
  1.1387 +    PLUGIN_LOG_DEBUG(("%s (type=%s, stream=%p, seekable=%i)",
  1.1388 +                      FULLFUNCTION, (char*) type, (void*) stream, (int) seekable));
  1.1389 +
  1.1390 +    BrowserStreamParent* bs = new BrowserStreamParent(this, stream);
  1.1391 +
  1.1392 +    NPError err;
  1.1393 +    if (!CallPBrowserStreamConstructor(bs,
  1.1394 +                                       NullableString(stream->url),
  1.1395 +                                       stream->end,
  1.1396 +                                       stream->lastmodified,
  1.1397 +                                       static_cast<PStreamNotifyParent*>(stream->notifyData),
  1.1398 +                                       NullableString(stream->headers),
  1.1399 +                                       NullableString(type), seekable,
  1.1400 +                                       &err, stype))
  1.1401 +        return NPERR_GENERIC_ERROR;
  1.1402 +
  1.1403 +    if (NPERR_NO_ERROR != err)
  1.1404 +        unused << PBrowserStreamParent::Send__delete__(bs);
  1.1405 +
  1.1406 +    return err;
  1.1407 +}
  1.1408 +
  1.1409 +NPError
  1.1410 +PluginInstanceParent::NPP_DestroyStream(NPStream* stream, NPReason reason)
  1.1411 +{
  1.1412 +    PLUGIN_LOG_DEBUG(("%s (stream=%p, reason=%i)",
  1.1413 +                      FULLFUNCTION, (void*) stream, (int) reason));
  1.1414 +
  1.1415 +    AStream* s = static_cast<AStream*>(stream->pdata);
  1.1416 +    if (s->IsBrowserStream()) {
  1.1417 +        BrowserStreamParent* sp =
  1.1418 +            static_cast<BrowserStreamParent*>(s);
  1.1419 +        if (sp->mNPP != this)
  1.1420 +            NS_RUNTIMEABORT("Mismatched plugin data");
  1.1421 +
  1.1422 +        sp->NPP_DestroyStream(reason);
  1.1423 +        return NPERR_NO_ERROR;
  1.1424 +    }
  1.1425 +    else {
  1.1426 +        PluginStreamParent* sp =
  1.1427 +            static_cast<PluginStreamParent*>(s);
  1.1428 +        if (sp->mInstance != this)
  1.1429 +            NS_RUNTIMEABORT("Mismatched plugin data");
  1.1430 +
  1.1431 +        return PPluginStreamParent::Call__delete__(sp, reason, false) ?
  1.1432 +            NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
  1.1433 +    }
  1.1434 +}
  1.1435 +
  1.1436 +void
  1.1437 +PluginInstanceParent::NPP_Print(NPPrint* platformPrint)
  1.1438 +{
  1.1439 +    // TODO: implement me
  1.1440 +    NS_ERROR("Not implemented");
  1.1441 +}
  1.1442 +
  1.1443 +PPluginScriptableObjectParent*
  1.1444 +PluginInstanceParent::AllocPPluginScriptableObjectParent()
  1.1445 +{
  1.1446 +    return new PluginScriptableObjectParent(Proxy);
  1.1447 +}
  1.1448 +
  1.1449 +#ifdef DEBUG
  1.1450 +namespace {
  1.1451 +
  1.1452 +struct ActorSearchData
  1.1453 +{
  1.1454 +    PluginScriptableObjectParent* actor;
  1.1455 +    bool found;
  1.1456 +};
  1.1457 +
  1.1458 +PLDHashOperator
  1.1459 +ActorSearch(NPObject* aKey,
  1.1460 +            PluginScriptableObjectParent* aData,
  1.1461 +            void* aUserData)
  1.1462 +{
  1.1463 +    ActorSearchData* asd = reinterpret_cast<ActorSearchData*>(aUserData);
  1.1464 +    if (asd->actor == aData) {
  1.1465 +        asd->found = true;
  1.1466 +        return PL_DHASH_STOP;
  1.1467 +    }
  1.1468 +    return PL_DHASH_NEXT;
  1.1469 +}
  1.1470 +
  1.1471 +} // anonymous namespace
  1.1472 +#endif // DEBUG
  1.1473 +
  1.1474 +bool
  1.1475 +PluginInstanceParent::DeallocPPluginScriptableObjectParent(
  1.1476 +                                         PPluginScriptableObjectParent* aObject)
  1.1477 +{
  1.1478 +    PluginScriptableObjectParent* actor =
  1.1479 +        static_cast<PluginScriptableObjectParent*>(aObject);
  1.1480 +
  1.1481 +    NPObject* object = actor->GetObject(false);
  1.1482 +    if (object) {
  1.1483 +        NS_ASSERTION(mScriptableObjects.Get(object, nullptr),
  1.1484 +                     "NPObject not in the hash!");
  1.1485 +        mScriptableObjects.Remove(object);
  1.1486 +    }
  1.1487 +#ifdef DEBUG
  1.1488 +    else {
  1.1489 +        ActorSearchData asd = { actor, false };
  1.1490 +        mScriptableObjects.EnumerateRead(ActorSearch, &asd);
  1.1491 +        NS_ASSERTION(!asd.found, "Actor in the hash with a null NPObject!");
  1.1492 +    }
  1.1493 +#endif
  1.1494 +
  1.1495 +    delete actor;
  1.1496 +    return true;
  1.1497 +}
  1.1498 +
  1.1499 +bool
  1.1500 +PluginInstanceParent::RecvPPluginScriptableObjectConstructor(
  1.1501 +                                          PPluginScriptableObjectParent* aActor)
  1.1502 +{
  1.1503 +    // This is only called in response to the child process requesting the
  1.1504 +    // creation of an actor. This actor will represent an NPObject that is
  1.1505 +    // created by the plugin and returned to the browser.
  1.1506 +    PluginScriptableObjectParent* actor =
  1.1507 +        static_cast<PluginScriptableObjectParent*>(aActor);
  1.1508 +    NS_ASSERTION(!actor->GetObject(false), "Actor already has an object?!");
  1.1509 +
  1.1510 +    actor->InitializeProxy();
  1.1511 +    NS_ASSERTION(actor->GetObject(false), "Actor should have an object!");
  1.1512 +
  1.1513 +    return true;
  1.1514 +}
  1.1515 +
  1.1516 +void
  1.1517 +PluginInstanceParent::NPP_URLNotify(const char* url, NPReason reason,
  1.1518 +                                    void* notifyData)
  1.1519 +{
  1.1520 +    PLUGIN_LOG_DEBUG(("%s (%s, %i, %p)",
  1.1521 +                      FULLFUNCTION, url, (int) reason, notifyData));
  1.1522 +
  1.1523 +    PStreamNotifyParent* streamNotify =
  1.1524 +        static_cast<PStreamNotifyParent*>(notifyData);
  1.1525 +    unused << PStreamNotifyParent::Send__delete__(streamNotify, reason);
  1.1526 +}
  1.1527 +
  1.1528 +bool
  1.1529 +PluginInstanceParent::RegisterNPObjectForActor(
  1.1530 +                                           NPObject* aObject,
  1.1531 +                                           PluginScriptableObjectParent* aActor)
  1.1532 +{
  1.1533 +    NS_ASSERTION(aObject && aActor, "Null pointers!");
  1.1534 +    NS_ASSERTION(!mScriptableObjects.Get(aObject, nullptr), "Duplicate entry!");
  1.1535 +    mScriptableObjects.Put(aObject, aActor);
  1.1536 +    return true;
  1.1537 +}
  1.1538 +
  1.1539 +void
  1.1540 +PluginInstanceParent::UnregisterNPObject(NPObject* aObject)
  1.1541 +{
  1.1542 +    NS_ASSERTION(aObject, "Null pointer!");
  1.1543 +    NS_ASSERTION(mScriptableObjects.Get(aObject, nullptr), "Unknown entry!");
  1.1544 +    mScriptableObjects.Remove(aObject);
  1.1545 +}
  1.1546 +
  1.1547 +PluginScriptableObjectParent*
  1.1548 +PluginInstanceParent::GetActorForNPObject(NPObject* aObject)
  1.1549 +{
  1.1550 +    NS_ASSERTION(aObject, "Null pointer!");
  1.1551 +
  1.1552 +    if (aObject->_class == PluginScriptableObjectParent::GetClass()) {
  1.1553 +        // One of ours!
  1.1554 +        ParentNPObject* object = static_cast<ParentNPObject*>(aObject);
  1.1555 +        NS_ASSERTION(object->parent, "Null actor!");
  1.1556 +        return object->parent;
  1.1557 +    }
  1.1558 +
  1.1559 +    PluginScriptableObjectParent* actor;
  1.1560 +    if (mScriptableObjects.Get(aObject, &actor)) {
  1.1561 +        return actor;
  1.1562 +    }
  1.1563 +
  1.1564 +    actor = new PluginScriptableObjectParent(LocalObject);
  1.1565 +    if (!actor) {
  1.1566 +        NS_ERROR("Out of memory!");
  1.1567 +        return nullptr;
  1.1568 +    }
  1.1569 +
  1.1570 +    if (!SendPPluginScriptableObjectConstructor(actor)) {
  1.1571 +        NS_WARNING("Failed to send constructor message!");
  1.1572 +        return nullptr;
  1.1573 +    }
  1.1574 +
  1.1575 +    actor->InitializeLocal(aObject);
  1.1576 +    return actor;
  1.1577 +}
  1.1578 +
  1.1579 +PPluginSurfaceParent*
  1.1580 +PluginInstanceParent::AllocPPluginSurfaceParent(const WindowsSharedMemoryHandle& handle,
  1.1581 +                                                const gfxIntSize& size,
  1.1582 +                                                const bool& transparent)
  1.1583 +{
  1.1584 +#ifdef XP_WIN
  1.1585 +    return new PluginSurfaceParent(handle, size, transparent);
  1.1586 +#else
  1.1587 +    NS_ERROR("This shouldn't be called!");
  1.1588 +    return nullptr;
  1.1589 +#endif
  1.1590 +}
  1.1591 +
  1.1592 +bool
  1.1593 +PluginInstanceParent::DeallocPPluginSurfaceParent(PPluginSurfaceParent* s)
  1.1594 +{
  1.1595 +#ifdef XP_WIN
  1.1596 +    delete s;
  1.1597 +    return true;
  1.1598 +#else
  1.1599 +    return false;
  1.1600 +#endif
  1.1601 +}
  1.1602 +
  1.1603 +bool
  1.1604 +PluginInstanceParent::AnswerNPN_PushPopupsEnabledState(const bool& aState)
  1.1605 +{
  1.1606 +    mNPNIface->pushpopupsenabledstate(mNPP, aState ? 1 : 0);
  1.1607 +    return true;
  1.1608 +}
  1.1609 +
  1.1610 +bool
  1.1611 +PluginInstanceParent::AnswerNPN_PopPopupsEnabledState()
  1.1612 +{
  1.1613 +    mNPNIface->poppopupsenabledstate(mNPP);
  1.1614 +    return true;
  1.1615 +}
  1.1616 +
  1.1617 +bool
  1.1618 +PluginInstanceParent::AnswerNPN_GetValueForURL(const NPNURLVariable& variable,
  1.1619 +                                               const nsCString& url,
  1.1620 +                                               nsCString* value,
  1.1621 +                                               NPError* result)
  1.1622 +{
  1.1623 +    char* v;
  1.1624 +    uint32_t len;
  1.1625 +
  1.1626 +    *result = mNPNIface->getvalueforurl(mNPP, (NPNURLVariable) variable,
  1.1627 +                                        url.get(), &v, &len);
  1.1628 +    if (NPERR_NO_ERROR == *result)
  1.1629 +        value->Adopt(v, len);
  1.1630 +
  1.1631 +    return true;
  1.1632 +}
  1.1633 +
  1.1634 +bool
  1.1635 +PluginInstanceParent::AnswerNPN_SetValueForURL(const NPNURLVariable& variable,
  1.1636 +                                               const nsCString& url,
  1.1637 +                                               const nsCString& value,
  1.1638 +                                               NPError* result)
  1.1639 +{
  1.1640 +    *result = mNPNIface->setvalueforurl(mNPP, (NPNURLVariable) variable,
  1.1641 +                                        url.get(), value.get(),
  1.1642 +                                        value.Length());
  1.1643 +    return true;
  1.1644 +}
  1.1645 +
  1.1646 +bool
  1.1647 +PluginInstanceParent::AnswerNPN_GetAuthenticationInfo(const nsCString& protocol,
  1.1648 +                                                      const nsCString& host,
  1.1649 +                                                      const int32_t& port,
  1.1650 +                                                      const nsCString& scheme,
  1.1651 +                                                      const nsCString& realm,
  1.1652 +                                                      nsCString* username,
  1.1653 +                                                      nsCString* password,
  1.1654 +                                                      NPError* result)
  1.1655 +{
  1.1656 +    char* u;
  1.1657 +    uint32_t ulen;
  1.1658 +    char* p;
  1.1659 +    uint32_t plen;
  1.1660 +
  1.1661 +    *result = mNPNIface->getauthenticationinfo(mNPP, protocol.get(),
  1.1662 +                                               host.get(), port,
  1.1663 +                                               scheme.get(), realm.get(),
  1.1664 +                                               &u, &ulen, &p, &plen);
  1.1665 +    if (NPERR_NO_ERROR == *result) {
  1.1666 +        username->Adopt(u, ulen);
  1.1667 +        password->Adopt(p, plen);
  1.1668 +    }
  1.1669 +    return true;
  1.1670 +}
  1.1671 +
  1.1672 +bool
  1.1673 +PluginInstanceParent::AnswerNPN_ConvertPoint(const double& sourceX,
  1.1674 +                                             const bool&   ignoreDestX,
  1.1675 +                                             const double& sourceY,
  1.1676 +                                             const bool&   ignoreDestY,
  1.1677 +                                             const NPCoordinateSpace& sourceSpace,
  1.1678 +                                             const NPCoordinateSpace& destSpace,
  1.1679 +                                             double *destX,
  1.1680 +                                             double *destY,
  1.1681 +                                             bool *result)
  1.1682 +{
  1.1683 +    *result = mNPNIface->convertpoint(mNPP, sourceX, sourceY, sourceSpace,
  1.1684 +                                      ignoreDestX ? nullptr : destX,
  1.1685 +                                      ignoreDestY ? nullptr : destY,
  1.1686 +                                      destSpace);
  1.1687 +
  1.1688 +    return true;
  1.1689 +}
  1.1690 +
  1.1691 +bool
  1.1692 +PluginInstanceParent::AnswerNPN_InitAsyncSurface(const gfxIntSize& size,
  1.1693 +                                                 const NPImageFormat& format,
  1.1694 +                                                 NPRemoteAsyncSurface* surfData,
  1.1695 +                                                 bool* result)
  1.1696 +{
  1.1697 +    if (!IsAsyncDrawing()) {
  1.1698 +        *result = false;
  1.1699 +        return true;
  1.1700 +    }
  1.1701 +
  1.1702 +    switch (mDrawingModel) {
  1.1703 +    case NPDrawingModelAsyncBitmapSurface: {
  1.1704 +            Shmem sharedMem;
  1.1705 +            if (!AllocUnsafeShmem(size.width * size.height * 4, SharedMemory::TYPE_BASIC, &sharedMem)) {
  1.1706 +                *result = false;
  1.1707 +                return true;
  1.1708 +            }
  1.1709 +
  1.1710 +            surfData->size() = size;
  1.1711 +            surfData->hostPtr() = (uintptr_t)sharedMem.get<unsigned char>();
  1.1712 +            surfData->stride() = size.width * 4;
  1.1713 +            surfData->format() = format;
  1.1714 +            surfData->data() = sharedMem;
  1.1715 +            *result = true;
  1.1716 +            return true;
  1.1717 +        }
  1.1718 +#ifdef XP_WIN
  1.1719 +    case NPDrawingModelAsyncWindowsDXGISurface: {
  1.1720 +            ID3D10Device1 *device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
  1.1721 +
  1.1722 +            nsRefPtr<ID3D10Texture2D> texture;
  1.1723 +            
  1.1724 +            CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, size.width, size.height, 1, 1);
  1.1725 +            desc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX;
  1.1726 +            desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
  1.1727 +            if (FAILED(device->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture)))) {
  1.1728 +                *result = false;
  1.1729 +                return true;
  1.1730 +            }
  1.1731 +
  1.1732 +            nsRefPtr<IDXGIResource> resource;
  1.1733 +            if (FAILED(texture->QueryInterface(IID_IDXGIResource, getter_AddRefs(resource)))) {
  1.1734 +                *result = false;
  1.1735 +                return true;
  1.1736 +            }
  1.1737 +
  1.1738 +            HANDLE sharedHandle;
  1.1739 +
  1.1740 +            if (FAILED(resource->GetSharedHandle(&sharedHandle))) {
  1.1741 +                *result = false;
  1.1742 +                return true;
  1.1743 +            }
  1.1744 +            
  1.1745 +            surfData->size() = size;
  1.1746 +            surfData->data() = sharedHandle;
  1.1747 +            surfData->format() = format;
  1.1748 +
  1.1749 +            mTextureMap.Put(sharedHandle, texture);
  1.1750 +            *result = true;
  1.1751 +        }
  1.1752 +#endif
  1.1753 +    }
  1.1754 +
  1.1755 +    return true;
  1.1756 +}
  1.1757 +
  1.1758 +bool
  1.1759 +PluginInstanceParent::RecvRedrawPlugin()
  1.1760 +{
  1.1761 +    nsNPAPIPluginInstance *inst = static_cast<nsNPAPIPluginInstance*>(mNPP->ndata);
  1.1762 +    if (!inst) {
  1.1763 +        return false;
  1.1764 +    }
  1.1765 +
  1.1766 +    inst->RedrawPlugin();
  1.1767 +    return true;
  1.1768 +}
  1.1769 +
  1.1770 +bool
  1.1771 +PluginInstanceParent::RecvNegotiatedCarbon()
  1.1772 +{
  1.1773 +    nsNPAPIPluginInstance *inst = static_cast<nsNPAPIPluginInstance*>(mNPP->ndata);
  1.1774 +    if (!inst) {
  1.1775 +        return false;
  1.1776 +    }
  1.1777 +    inst->CarbonNPAPIFailure();
  1.1778 +    return true;
  1.1779 +}
  1.1780 +
  1.1781 +bool
  1.1782 +PluginInstanceParent::RecvReleaseDXGISharedSurface(const DXGISharedSurfaceHandle &aHandle)
  1.1783 +{
  1.1784 +#ifdef XP_WIN
  1.1785 +    mTextureMap.Remove(aHandle);
  1.1786 +#endif
  1.1787 +    return true;
  1.1788 +}
  1.1789 +
  1.1790 +#if defined(OS_WIN)
  1.1791 +
  1.1792 +/*
  1.1793 +  plugin focus changes between processes
  1.1794 +
  1.1795 +  focus from dom -> child:
  1.1796 +    Focus manager calls on widget to set the focus on the window.
  1.1797 +    We pick up the resulting wm_setfocus event here, and forward
  1.1798 +    that over ipc to the child which calls set focus on itself. 
  1.1799 +
  1.1800 +  focus from child -> focus manager:
  1.1801 +    Child picks up the local wm_setfocus and sends it via ipc over
  1.1802 +    here. We then post a custom event to widget/windows/nswindow
  1.1803 +    which fires off a gui event letting the browser know.
  1.1804 +*/
  1.1805 +
  1.1806 +static const wchar_t kPluginInstanceParentProperty[] =
  1.1807 +                         L"PluginInstanceParentProperty";
  1.1808 +
  1.1809 +// static
  1.1810 +LRESULT CALLBACK
  1.1811 +PluginInstanceParent::PluginWindowHookProc(HWND hWnd,
  1.1812 +                                           UINT message,
  1.1813 +                                           WPARAM wParam,
  1.1814 +                                           LPARAM lParam)
  1.1815 +{
  1.1816 +    PluginInstanceParent* self = reinterpret_cast<PluginInstanceParent*>(
  1.1817 +        ::GetPropW(hWnd, kPluginInstanceParentProperty));
  1.1818 +    if (!self) {
  1.1819 +        NS_NOTREACHED("PluginInstanceParent::PluginWindowHookProc null this ptr!");
  1.1820 +        return DefWindowProc(hWnd, message, wParam, lParam);
  1.1821 +    }
  1.1822 +
  1.1823 +    NS_ASSERTION(self->mPluginHWND == hWnd, "Wrong window!");
  1.1824 +
  1.1825 +    switch (message) {
  1.1826 +        case WM_SETFOCUS:
  1.1827 +        // Let the child plugin window know it should take focus.
  1.1828 +        unused << self->CallSetPluginFocus();
  1.1829 +        break;
  1.1830 +
  1.1831 +        case WM_CLOSE:
  1.1832 +        self->UnsubclassPluginWindow();
  1.1833 +        break;
  1.1834 +    }
  1.1835 +
  1.1836 +    if (self->mPluginWndProc == PluginWindowHookProc) {
  1.1837 +      NS_NOTREACHED(
  1.1838 +        "PluginWindowHookProc invoking mPluginWndProc w/"
  1.1839 +        "mPluginWndProc == PluginWindowHookProc????");
  1.1840 +        return DefWindowProc(hWnd, message, wParam, lParam);
  1.1841 +    }
  1.1842 +    return ::CallWindowProc(self->mPluginWndProc, hWnd, message, wParam,
  1.1843 +                            lParam);
  1.1844 +}
  1.1845 +
  1.1846 +void
  1.1847 +PluginInstanceParent::SubclassPluginWindow(HWND aWnd)
  1.1848 +{
  1.1849 +    NS_ASSERTION(!(mPluginHWND && aWnd != mPluginHWND),
  1.1850 +      "PluginInstanceParent::SubclassPluginWindow hwnd is not our window!");
  1.1851 +
  1.1852 +    if (!mPluginHWND) {
  1.1853 +        mPluginHWND = aWnd;
  1.1854 +        mPluginWndProc = 
  1.1855 +            (WNDPROC)::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
  1.1856 +                         reinterpret_cast<LONG_PTR>(PluginWindowHookProc));
  1.1857 +        DebugOnly<bool> bRes = ::SetPropW(mPluginHWND, kPluginInstanceParentProperty, this);
  1.1858 +        NS_ASSERTION(mPluginWndProc,
  1.1859 +          "PluginInstanceParent::SubclassPluginWindow failed to set subclass!");
  1.1860 +        NS_ASSERTION(bRes,
  1.1861 +          "PluginInstanceParent::SubclassPluginWindow failed to set prop!");
  1.1862 +   }
  1.1863 +}
  1.1864 +
  1.1865 +void
  1.1866 +PluginInstanceParent::UnsubclassPluginWindow()
  1.1867 +{
  1.1868 +    if (mPluginHWND && mPluginWndProc) {
  1.1869 +        ::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
  1.1870 +                            reinterpret_cast<LONG_PTR>(mPluginWndProc));
  1.1871 +
  1.1872 +        ::RemovePropW(mPluginHWND, kPluginInstanceParentProperty);
  1.1873 +
  1.1874 +        mPluginWndProc = nullptr;
  1.1875 +        mPluginHWND = nullptr;
  1.1876 +    }
  1.1877 +}
  1.1878 +
  1.1879 +/* windowless drawing helpers */
  1.1880 +
  1.1881 +/*
  1.1882 + * Origin info:
  1.1883 + *
  1.1884 + * windowless, offscreen:
  1.1885 + *
  1.1886 + * WM_WINDOWPOSCHANGED: origin is relative to container 
  1.1887 + * setwindow: origin is 0,0
  1.1888 + * WM_PAINT: origin is 0,0
  1.1889 + *
  1.1890 + * windowless, native:
  1.1891 + *
  1.1892 + * WM_WINDOWPOSCHANGED: origin is relative to container 
  1.1893 + * setwindow: origin is relative to container
  1.1894 + * WM_PAINT: origin is relative to container
  1.1895 + *
  1.1896 + * PluginInstanceParent:
  1.1897 + *
  1.1898 + * painting: mPluginPort (nsIntRect, saved in SetWindow)
  1.1899 + */
  1.1900 +
  1.1901 +void
  1.1902 +PluginInstanceParent::SharedSurfaceRelease()
  1.1903 +{
  1.1904 +    mSharedSurfaceDib.Close();
  1.1905 +}
  1.1906 +
  1.1907 +bool
  1.1908 +PluginInstanceParent::SharedSurfaceSetWindow(const NPWindow* aWindow,
  1.1909 +                                             NPRemoteWindow& aRemoteWindow)
  1.1910 +{
  1.1911 +    aRemoteWindow.window = 0;
  1.1912 +    aRemoteWindow.x      = aWindow->x;
  1.1913 +    aRemoteWindow.y      = aWindow->y;
  1.1914 +    aRemoteWindow.width  = aWindow->width;
  1.1915 +    aRemoteWindow.height = aWindow->height;
  1.1916 +    aRemoteWindow.type   = aWindow->type;
  1.1917 +
  1.1918 +    nsIntRect newPort(aWindow->x, aWindow->y, aWindow->width, aWindow->height);
  1.1919 +
  1.1920 +    // save the the rect location within the browser window.
  1.1921 +    mPluginPort = newPort;
  1.1922 +
  1.1923 +    // move the port to our shared surface origin
  1.1924 +    newPort.MoveTo(0,0);
  1.1925 +
  1.1926 +    // check to see if we have the room in shared surface
  1.1927 +    if (mSharedSurfaceDib.IsValid() && mSharedSize.Contains(newPort)) {
  1.1928 +      // ok to paint
  1.1929 +      aRemoteWindow.surfaceHandle = 0;
  1.1930 +      return true;
  1.1931 +    }
  1.1932 +
  1.1933 +    // allocate a new shared surface
  1.1934 +    SharedSurfaceRelease();
  1.1935 +    if (NS_FAILED(mSharedSurfaceDib.Create(reinterpret_cast<HDC>(aWindow->window),
  1.1936 +                                           newPort.width, newPort.height, false)))
  1.1937 +      return false;
  1.1938 +
  1.1939 +    // save the new shared surface size we just allocated
  1.1940 +    mSharedSize = newPort;
  1.1941 +
  1.1942 +    base::SharedMemoryHandle handle;
  1.1943 +    if (NS_FAILED(mSharedSurfaceDib.ShareToProcess(mParent->ChildProcessHandle(), &handle)))
  1.1944 +      return false;
  1.1945 +
  1.1946 +    aRemoteWindow.surfaceHandle = handle;
  1.1947 +
  1.1948 +    return true;
  1.1949 +}
  1.1950 +
  1.1951 +void
  1.1952 +PluginInstanceParent::SharedSurfaceBeforePaint(RECT& rect,
  1.1953 +                                               NPRemoteEvent& npremoteevent)
  1.1954 +{
  1.1955 +    RECT* dr = (RECT*)npremoteevent.event.lParam;
  1.1956 +    HDC parentHdc = (HDC)npremoteevent.event.wParam;
  1.1957 +
  1.1958 +    nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
  1.1959 +    dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y); // should always be smaller than dirtyRect
  1.1960 +
  1.1961 +    ::BitBlt(mSharedSurfaceDib.GetHDC(),
  1.1962 +             dirtyRect.x,
  1.1963 +             dirtyRect.y,
  1.1964 +             dirtyRect.width,
  1.1965 +             dirtyRect.height,
  1.1966 +             parentHdc,
  1.1967 +             dr->left,
  1.1968 +             dr->top,
  1.1969 +             SRCCOPY);
  1.1970 +
  1.1971 +    // setup the translated dirty rect we'll send to the child
  1.1972 +    rect.left   = dirtyRect.x;
  1.1973 +    rect.top    = dirtyRect.y;
  1.1974 +    rect.right  = dirtyRect.x + dirtyRect.width;
  1.1975 +    rect.bottom = dirtyRect.y + dirtyRect.height;
  1.1976 +
  1.1977 +    npremoteevent.event.wParam = WPARAM(0);
  1.1978 +    npremoteevent.event.lParam = LPARAM(&rect);
  1.1979 +}
  1.1980 +
  1.1981 +void
  1.1982 +PluginInstanceParent::SharedSurfaceAfterPaint(NPEvent* npevent)
  1.1983 +{
  1.1984 +    RECT* dr = (RECT*)npevent->lParam;
  1.1985 +    HDC parentHdc = (HDC)npevent->wParam;
  1.1986 +
  1.1987 +    nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
  1.1988 +    dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y);
  1.1989 +
  1.1990 +    // src copy the shared dib into the parent surface we are handed.
  1.1991 +    ::BitBlt(parentHdc,
  1.1992 +             dr->left,
  1.1993 +             dr->top,
  1.1994 +             dirtyRect.width,
  1.1995 +             dirtyRect.height,
  1.1996 +             mSharedSurfaceDib.GetHDC(),
  1.1997 +             dirtyRect.x,
  1.1998 +             dirtyRect.y,
  1.1999 +             SRCCOPY);
  1.2000 +}
  1.2001 +
  1.2002 +#endif // defined(OS_WIN)
  1.2003 +
  1.2004 +bool
  1.2005 +PluginInstanceParent::AnswerPluginFocusChange(const bool& gotFocus)
  1.2006 +{
  1.2007 +    PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
  1.2008 +
  1.2009 +    // Currently only in use on windows - an rpc event we receive from the
  1.2010 +    // child when it's plugin window (or one of it's children) receives keyboard
  1.2011 +    // focus. We forward the event down to widget so the dom/focus manager can
  1.2012 +    // be updated.
  1.2013 +#if defined(OS_WIN)
  1.2014 +    ::SendMessage(mPluginHWND, gOOPPPluginFocusEvent, gotFocus ? 1 : 0, 0);
  1.2015 +    return true;
  1.2016 +#else
  1.2017 +    NS_NOTREACHED("PluginInstanceParent::AnswerPluginFocusChange not implemented!");
  1.2018 +    return false;
  1.2019 +#endif
  1.2020 +}

mercurial