dom/plugins/ipc/PluginInstanceParent.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * vim: sw=4 ts=4 et :
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "mozilla/DebugOnly.h"
michael@0 8 #include <stdint.h> // for intptr_t
michael@0 9
michael@0 10 #include "PluginInstanceParent.h"
michael@0 11 #include "BrowserStreamParent.h"
michael@0 12 #include "PluginBackgroundDestroyer.h"
michael@0 13 #include "PluginModuleParent.h"
michael@0 14 #include "PluginStreamParent.h"
michael@0 15 #include "StreamNotifyParent.h"
michael@0 16 #include "npfunctions.h"
michael@0 17 #include "nsAutoPtr.h"
michael@0 18 #include "gfxASurface.h"
michael@0 19 #include "gfxContext.h"
michael@0 20 #include "gfxPlatform.h"
michael@0 21 #include "gfxSharedImageSurface.h"
michael@0 22 #include "nsNPAPIPluginInstance.h"
michael@0 23 #ifdef MOZ_X11
michael@0 24 #include "gfxXlibSurface.h"
michael@0 25 #endif
michael@0 26 #include "gfxContext.h"
michael@0 27 #include "gfxColor.h"
michael@0 28 #include "gfxUtils.h"
michael@0 29 #include "mozilla/gfx/2D.h"
michael@0 30 #include "Layers.h"
michael@0 31 #include "SharedTextureImage.h"
michael@0 32 #include "GLContext.h"
michael@0 33 #include "GLContextProvider.h"
michael@0 34
michael@0 35 #ifdef XP_MACOSX
michael@0 36 #include "MacIOSurfaceImage.h"
michael@0 37 #endif
michael@0 38
michael@0 39 #if defined(OS_WIN)
michael@0 40 #include <windowsx.h>
michael@0 41 #include "gfxWindowsPlatform.h"
michael@0 42 #include "mozilla/plugins/PluginSurfaceParent.h"
michael@0 43
michael@0 44 // Plugin focus event for widget.
michael@0 45 extern const wchar_t* kOOPPPluginFocusEventId;
michael@0 46 UINT gOOPPPluginFocusEvent =
michael@0 47 RegisterWindowMessage(kOOPPPluginFocusEventId);
michael@0 48 extern const wchar_t* kFlashFullscreenClass;
michael@0 49 #elif defined(MOZ_WIDGET_GTK)
michael@0 50 #include <gdk/gdk.h>
michael@0 51 #elif defined(XP_MACOSX)
michael@0 52 #include <ApplicationServices/ApplicationServices.h>
michael@0 53 #endif // defined(XP_MACOSX)
michael@0 54
michael@0 55 using namespace mozilla::plugins;
michael@0 56 using namespace mozilla::layers;
michael@0 57 using namespace mozilla::gl;
michael@0 58
michael@0 59 bool
michael@0 60 StreamNotifyParent::RecvRedirectNotifyResponse(const bool& allow)
michael@0 61 {
michael@0 62 PluginInstanceParent* instance = static_cast<PluginInstanceParent*>(Manager());
michael@0 63 instance->mNPNIface->urlredirectresponse(instance->mNPP, this, static_cast<NPBool>(allow));
michael@0 64 return true;
michael@0 65 }
michael@0 66
michael@0 67 PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent,
michael@0 68 NPP npp,
michael@0 69 const nsCString& aMimeType,
michael@0 70 const NPNetscapeFuncs* npniface)
michael@0 71 : mParent(parent)
michael@0 72 , mNPP(npp)
michael@0 73 , mNPNIface(npniface)
michael@0 74 , mWindowType(NPWindowTypeWindow)
michael@0 75 , mDrawingModel(kDefaultDrawingModel)
michael@0 76 #if defined(OS_WIN)
michael@0 77 , mPluginHWND(nullptr)
michael@0 78 , mPluginWndProc(nullptr)
michael@0 79 , mNestedEventState(false)
michael@0 80 #endif // defined(XP_WIN)
michael@0 81 #if defined(XP_MACOSX)
michael@0 82 , mShWidth(0)
michael@0 83 , mShHeight(0)
michael@0 84 , mShColorSpace(nullptr)
michael@0 85 #endif
michael@0 86 {
michael@0 87 }
michael@0 88
michael@0 89 PluginInstanceParent::~PluginInstanceParent()
michael@0 90 {
michael@0 91 if (mNPP)
michael@0 92 mNPP->pdata = nullptr;
michael@0 93
michael@0 94 #if defined(OS_WIN)
michael@0 95 NS_ASSERTION(!(mPluginHWND || mPluginWndProc),
michael@0 96 "Subclass was not reset correctly before the dtor was reached!");
michael@0 97 #endif
michael@0 98 #if defined(MOZ_WIDGET_COCOA)
michael@0 99 if (mShWidth != 0 && mShHeight != 0) {
michael@0 100 DeallocShmem(mShSurface);
michael@0 101 }
michael@0 102 if (mShColorSpace)
michael@0 103 ::CGColorSpaceRelease(mShColorSpace);
michael@0 104 #endif
michael@0 105 if (mRemoteImageDataShmem.IsWritable()) {
michael@0 106 if (mImageContainer) {
michael@0 107 mImageContainer->SetRemoteImageData(nullptr, nullptr);
michael@0 108 mImageContainer->SetCompositionNotifySink(nullptr);
michael@0 109 }
michael@0 110 DeallocShmem(mRemoteImageDataShmem);
michael@0 111 }
michael@0 112 }
michael@0 113
michael@0 114 bool
michael@0 115 PluginInstanceParent::Init()
michael@0 116 {
michael@0 117 return true;
michael@0 118 }
michael@0 119
michael@0 120 void
michael@0 121 PluginInstanceParent::ActorDestroy(ActorDestroyReason why)
michael@0 122 {
michael@0 123 #if defined(OS_WIN)
michael@0 124 if (why == AbnormalShutdown) {
michael@0 125 // If the plugin process crashes, this is the only
michael@0 126 // chance we get to destroy resources.
michael@0 127 SharedSurfaceRelease();
michael@0 128 UnsubclassPluginWindow();
michael@0 129 }
michael@0 130 #endif
michael@0 131 // After this method, the data backing the remote surface may no
michael@0 132 // longer be valid. The X surface may be destroyed, or the shared
michael@0 133 // memory backing this surface may no longer be valid.
michael@0 134 if (mFrontSurface) {
michael@0 135 mFrontSurface = nullptr;
michael@0 136 if (mImageContainer) {
michael@0 137 mImageContainer->SetCurrentImage(nullptr);
michael@0 138 }
michael@0 139 #ifdef MOZ_X11
michael@0 140 FinishX(DefaultXDisplay());
michael@0 141 #endif
michael@0 142 }
michael@0 143 }
michael@0 144
michael@0 145 NPError
michael@0 146 PluginInstanceParent::Destroy()
michael@0 147 {
michael@0 148 NPError retval;
michael@0 149 if (!CallNPP_Destroy(&retval))
michael@0 150 retval = NPERR_GENERIC_ERROR;
michael@0 151
michael@0 152 #if defined(OS_WIN)
michael@0 153 SharedSurfaceRelease();
michael@0 154 UnsubclassPluginWindow();
michael@0 155 #endif
michael@0 156
michael@0 157 return retval;
michael@0 158 }
michael@0 159
michael@0 160 PBrowserStreamParent*
michael@0 161 PluginInstanceParent::AllocPBrowserStreamParent(const nsCString& url,
michael@0 162 const uint32_t& length,
michael@0 163 const uint32_t& lastmodified,
michael@0 164 PStreamNotifyParent* notifyData,
michael@0 165 const nsCString& headers,
michael@0 166 const nsCString& mimeType,
michael@0 167 const bool& seekable,
michael@0 168 NPError* rv,
michael@0 169 uint16_t *stype)
michael@0 170 {
michael@0 171 NS_RUNTIMEABORT("Not reachable");
michael@0 172 return nullptr;
michael@0 173 }
michael@0 174
michael@0 175 bool
michael@0 176 PluginInstanceParent::DeallocPBrowserStreamParent(PBrowserStreamParent* stream)
michael@0 177 {
michael@0 178 delete stream;
michael@0 179 return true;
michael@0 180 }
michael@0 181
michael@0 182 PPluginStreamParent*
michael@0 183 PluginInstanceParent::AllocPPluginStreamParent(const nsCString& mimeType,
michael@0 184 const nsCString& target,
michael@0 185 NPError* result)
michael@0 186 {
michael@0 187 return new PluginStreamParent(this, mimeType, target, result);
michael@0 188 }
michael@0 189
michael@0 190 bool
michael@0 191 PluginInstanceParent::DeallocPPluginStreamParent(PPluginStreamParent* stream)
michael@0 192 {
michael@0 193 delete stream;
michael@0 194 return true;
michael@0 195 }
michael@0 196
michael@0 197 bool
michael@0 198 PluginInstanceParent::AnswerNPN_GetValue_NPNVnetscapeWindow(NativeWindowHandle* value,
michael@0 199 NPError* result)
michael@0 200 {
michael@0 201 #ifdef XP_WIN
michael@0 202 HWND id;
michael@0 203 #elif defined(MOZ_X11)
michael@0 204 XID id;
michael@0 205 #elif defined(XP_MACOSX)
michael@0 206 intptr_t id;
michael@0 207 #elif defined(ANDROID)
michael@0 208 // TODO: Need Android impl
michael@0 209 int id;
michael@0 210 #elif defined(MOZ_WIDGET_QT)
michael@0 211 // TODO: Need Qt non X impl
michael@0 212 int id;
michael@0 213 #else
michael@0 214 #warning Implement me
michael@0 215 #endif
michael@0 216
michael@0 217 *result = mNPNIface->getvalue(mNPP, NPNVnetscapeWindow, &id);
michael@0 218 *value = id;
michael@0 219 return true;
michael@0 220 }
michael@0 221
michael@0 222 bool
michael@0 223 PluginInstanceParent::InternalGetValueForNPObject(
michael@0 224 NPNVariable aVariable,
michael@0 225 PPluginScriptableObjectParent** aValue,
michael@0 226 NPError* aResult)
michael@0 227 {
michael@0 228 NPObject* npobject;
michael@0 229 NPError result = mNPNIface->getvalue(mNPP, aVariable, (void*)&npobject);
michael@0 230 if (result == NPERR_NO_ERROR) {
michael@0 231 NS_ASSERTION(npobject, "Shouldn't return null and NPERR_NO_ERROR!");
michael@0 232
michael@0 233 PluginScriptableObjectParent* actor = GetActorForNPObject(npobject);
michael@0 234 mNPNIface->releaseobject(npobject);
michael@0 235 if (actor) {
michael@0 236 *aValue = actor;
michael@0 237 *aResult = NPERR_NO_ERROR;
michael@0 238 return true;
michael@0 239 }
michael@0 240
michael@0 241 NS_ERROR("Failed to get actor!");
michael@0 242 result = NPERR_GENERIC_ERROR;
michael@0 243 }
michael@0 244
michael@0 245 *aValue = nullptr;
michael@0 246 *aResult = result;
michael@0 247 return true;
michael@0 248 }
michael@0 249
michael@0 250 bool
michael@0 251 PluginInstanceParent::IsAsyncDrawing()
michael@0 252 {
michael@0 253 return IsDrawingModelAsync(mDrawingModel);
michael@0 254 }
michael@0 255
michael@0 256 bool
michael@0 257 PluginInstanceParent::AnswerNPN_GetValue_NPNVWindowNPObject(
michael@0 258 PPluginScriptableObjectParent** aValue,
michael@0 259 NPError* aResult)
michael@0 260 {
michael@0 261 return InternalGetValueForNPObject(NPNVWindowNPObject, aValue, aResult);
michael@0 262 }
michael@0 263
michael@0 264 bool
michael@0 265 PluginInstanceParent::AnswerNPN_GetValue_NPNVPluginElementNPObject(
michael@0 266 PPluginScriptableObjectParent** aValue,
michael@0 267 NPError* aResult)
michael@0 268 {
michael@0 269 return InternalGetValueForNPObject(NPNVPluginElementNPObject, aValue,
michael@0 270 aResult);
michael@0 271 }
michael@0 272
michael@0 273 bool
michael@0 274 PluginInstanceParent::AnswerNPN_GetValue_NPNVprivateModeBool(bool* value,
michael@0 275 NPError* result)
michael@0 276 {
michael@0 277 NPBool v;
michael@0 278 *result = mNPNIface->getvalue(mNPP, NPNVprivateModeBool, &v);
michael@0 279 *value = v;
michael@0 280 return true;
michael@0 281 }
michael@0 282
michael@0 283 bool
michael@0 284 PluginInstanceParent::AnswerNPN_GetValue_DrawingModelSupport(const NPNVariable& model, bool* value)
michael@0 285 {
michael@0 286 *value = false;
michael@0 287
michael@0 288 #ifdef XP_WIN
michael@0 289 switch (model) {
michael@0 290 case NPNVsupportsAsyncWindowsDXGISurfaceBool: {
michael@0 291 if (gfxWindowsPlatform::GetPlatform()->GetRenderMode() == gfxWindowsPlatform::RENDER_DIRECT2D) {
michael@0 292 *value = true;
michael@0 293 }
michael@0 294 }
michael@0 295 }
michael@0 296 #endif
michael@0 297
michael@0 298 return true;
michael@0 299 }
michael@0 300
michael@0 301 bool
michael@0 302 PluginInstanceParent::AnswerNPN_GetValue_NPNVdocumentOrigin(nsCString* value,
michael@0 303 NPError* result)
michael@0 304 {
michael@0 305 void *v = nullptr;
michael@0 306 *result = mNPNIface->getvalue(mNPP, NPNVdocumentOrigin, &v);
michael@0 307 if (*result == NPERR_NO_ERROR && v) {
michael@0 308 value->Adopt(static_cast<char*>(v));
michael@0 309 }
michael@0 310 return true;
michael@0 311 }
michael@0 312
michael@0 313 bool
michael@0 314 PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginWindow(
michael@0 315 const bool& windowed, NPError* result)
michael@0 316 {
michael@0 317 // Yes, we are passing a boolean as a void*. We have to cast to intptr_t
michael@0 318 // first to avoid gcc warnings about casting to a pointer from a
michael@0 319 // non-pointer-sized integer.
michael@0 320 *result = mNPNIface->setvalue(mNPP, NPPVpluginWindowBool,
michael@0 321 (void*)(intptr_t)windowed);
michael@0 322 return true;
michael@0 323 }
michael@0 324
michael@0 325 bool
michael@0 326 PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginTransparent(
michael@0 327 const bool& transparent, NPError* result)
michael@0 328 {
michael@0 329 *result = mNPNIface->setvalue(mNPP, NPPVpluginTransparentBool,
michael@0 330 (void*)(intptr_t)transparent);
michael@0 331 return true;
michael@0 332 }
michael@0 333
michael@0 334 bool
michael@0 335 PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginUsesDOMForCursor(
michael@0 336 const bool& useDOMForCursor, NPError* result)
michael@0 337 {
michael@0 338 *result = mNPNIface->setvalue(mNPP, NPPVpluginUsesDOMForCursorBool,
michael@0 339 (void*)(intptr_t)useDOMForCursor);
michael@0 340 return true;
michael@0 341 }
michael@0 342
michael@0 343 class NotificationSink : public CompositionNotifySink
michael@0 344 {
michael@0 345 public:
michael@0 346 NotificationSink(PluginInstanceParent *aInstance) : mInstance(aInstance)
michael@0 347 { }
michael@0 348
michael@0 349 virtual void DidComposite() { mInstance->DidComposite(); }
michael@0 350 private:
michael@0 351 PluginInstanceParent *mInstance;
michael@0 352 };
michael@0 353
michael@0 354 bool
michael@0 355 PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginDrawingModel(
michael@0 356 const int& drawingModel, OptionalShmem *shmem, CrossProcessMutexHandle *mutex, NPError* result)
michael@0 357 {
michael@0 358 *shmem = null_t();
michael@0 359
michael@0 360 #ifdef XP_MACOSX
michael@0 361 if (drawingModel == NPDrawingModelCoreAnimation ||
michael@0 362 drawingModel == NPDrawingModelInvalidatingCoreAnimation) {
michael@0 363 // We need to request CoreGraphics otherwise
michael@0 364 // the nsObjectFrame will try to draw a CALayer
michael@0 365 // that can not be shared across process.
michael@0 366 mDrawingModel = drawingModel;
michael@0 367 *result = mNPNIface->setvalue(mNPP, NPPVpluginDrawingModel,
michael@0 368 (void*)NPDrawingModelCoreGraphics);
michael@0 369 } else
michael@0 370 #endif
michael@0 371 if (drawingModel == NPDrawingModelAsyncBitmapSurface
michael@0 372 #ifdef XP_WIN
michael@0 373 || drawingModel == NPDrawingModelAsyncWindowsDXGISurface
michael@0 374 #endif
michael@0 375 ) {
michael@0 376 ImageContainer *container = GetImageContainer();
michael@0 377 if (!container) {
michael@0 378 *result = NPERR_GENERIC_ERROR;
michael@0 379 return true;
michael@0 380 }
michael@0 381
michael@0 382 #ifdef XP_WIN
michael@0 383 if (drawingModel == NPDrawingModelAsyncWindowsDXGISurface &&
michael@0 384 gfxWindowsPlatform::GetPlatform()->GetRenderMode() != gfxWindowsPlatform::RENDER_DIRECT2D) {
michael@0 385 *result = NPERR_GENERIC_ERROR;
michael@0 386 return true;
michael@0 387 }
michael@0 388 #endif
michael@0 389
michael@0 390 mDrawingModel = drawingModel;
michael@0 391 *result = mNPNIface->setvalue(mNPP, NPPVpluginDrawingModel,
michael@0 392 reinterpret_cast<void*>(static_cast<uintptr_t>(drawingModel)));
michael@0 393
michael@0 394
michael@0 395 if (*result != NPERR_NO_ERROR) {
michael@0 396 return true;
michael@0 397 }
michael@0 398
michael@0 399 AllocUnsafeShmem(sizeof(RemoteImageData), SharedMemory::TYPE_BASIC, &mRemoteImageDataShmem);
michael@0 400
michael@0 401 *shmem = mRemoteImageDataShmem;
michael@0 402
michael@0 403 mRemoteImageDataMutex = new CrossProcessMutex("PluginInstanceParent.mRemoteImageDataMutex");
michael@0 404
michael@0 405 *mutex = mRemoteImageDataMutex->ShareToProcess(OtherProcess());
michael@0 406 container->SetRemoteImageData(mRemoteImageDataShmem.get<RemoteImageData>(), mRemoteImageDataMutex);
michael@0 407
michael@0 408 mNotifySink = new NotificationSink(this);
michael@0 409
michael@0 410 container->SetCompositionNotifySink(mNotifySink);
michael@0 411 } else if (
michael@0 412 #if defined(XP_WIN)
michael@0 413 drawingModel == NPDrawingModelSyncWin
michael@0 414 #elif defined(XP_MACOSX)
michael@0 415 drawingModel == NPDrawingModelOpenGL ||
michael@0 416 drawingModel == NPDrawingModelCoreGraphics
michael@0 417 #elif defined(MOZ_X11)
michael@0 418 drawingModel == NPDrawingModelSyncX
michael@0 419 #else
michael@0 420 false
michael@0 421 #endif
michael@0 422 ) {
michael@0 423 *shmem = null_t();
michael@0 424
michael@0 425 mDrawingModel = drawingModel;
michael@0 426 *result = mNPNIface->setvalue(mNPP, NPPVpluginDrawingModel,
michael@0 427 (void*)(intptr_t)drawingModel);
michael@0 428
michael@0 429 if (mRemoteImageDataShmem.IsWritable()) {
michael@0 430 if (mImageContainer) {
michael@0 431 mImageContainer->SetRemoteImageData(nullptr, nullptr);
michael@0 432 mImageContainer->SetCompositionNotifySink(nullptr);
michael@0 433 }
michael@0 434 DeallocShmem(mRemoteImageDataShmem);
michael@0 435 mRemoteImageDataMutex = nullptr;
michael@0 436 }
michael@0 437 } else {
michael@0 438 *result = NPERR_GENERIC_ERROR;
michael@0 439 }
michael@0 440 return true;
michael@0 441 }
michael@0 442
michael@0 443 bool
michael@0 444 PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginEventModel(
michael@0 445 const int& eventModel, NPError* result)
michael@0 446 {
michael@0 447 #ifdef XP_MACOSX
michael@0 448 *result = mNPNIface->setvalue(mNPP, NPPVpluginEventModel,
michael@0 449 (void*)(intptr_t)eventModel);
michael@0 450 return true;
michael@0 451 #else
michael@0 452 *result = NPERR_GENERIC_ERROR;
michael@0 453 return true;
michael@0 454 #endif
michael@0 455 }
michael@0 456
michael@0 457 bool
michael@0 458 PluginInstanceParent::AnswerNPN_GetURL(const nsCString& url,
michael@0 459 const nsCString& target,
michael@0 460 NPError* result)
michael@0 461 {
michael@0 462 *result = mNPNIface->geturl(mNPP,
michael@0 463 NullableStringGet(url),
michael@0 464 NullableStringGet(target));
michael@0 465 return true;
michael@0 466 }
michael@0 467
michael@0 468 bool
michael@0 469 PluginInstanceParent::AnswerNPN_PostURL(const nsCString& url,
michael@0 470 const nsCString& target,
michael@0 471 const nsCString& buffer,
michael@0 472 const bool& file,
michael@0 473 NPError* result)
michael@0 474 {
michael@0 475 *result = mNPNIface->posturl(mNPP, url.get(), NullableStringGet(target),
michael@0 476 buffer.Length(), buffer.get(), file);
michael@0 477 return true;
michael@0 478 }
michael@0 479
michael@0 480 PStreamNotifyParent*
michael@0 481 PluginInstanceParent::AllocPStreamNotifyParent(const nsCString& url,
michael@0 482 const nsCString& target,
michael@0 483 const bool& post,
michael@0 484 const nsCString& buffer,
michael@0 485 const bool& file,
michael@0 486 NPError* result)
michael@0 487 {
michael@0 488 return new StreamNotifyParent();
michael@0 489 }
michael@0 490
michael@0 491 bool
michael@0 492 PluginInstanceParent::AnswerPStreamNotifyConstructor(PStreamNotifyParent* actor,
michael@0 493 const nsCString& url,
michael@0 494 const nsCString& target,
michael@0 495 const bool& post,
michael@0 496 const nsCString& buffer,
michael@0 497 const bool& file,
michael@0 498 NPError* result)
michael@0 499 {
michael@0 500 bool streamDestroyed = false;
michael@0 501 static_cast<StreamNotifyParent*>(actor)->
michael@0 502 SetDestructionFlag(&streamDestroyed);
michael@0 503
michael@0 504 if (!post) {
michael@0 505 *result = mNPNIface->geturlnotify(mNPP,
michael@0 506 NullableStringGet(url),
michael@0 507 NullableStringGet(target),
michael@0 508 actor);
michael@0 509 }
michael@0 510 else {
michael@0 511 *result = mNPNIface->posturlnotify(mNPP,
michael@0 512 NullableStringGet(url),
michael@0 513 NullableStringGet(target),
michael@0 514 buffer.Length(),
michael@0 515 NullableStringGet(buffer),
michael@0 516 file, actor);
michael@0 517 }
michael@0 518
michael@0 519 if (streamDestroyed) {
michael@0 520 // If the stream was destroyed, we must return an error code in the
michael@0 521 // constructor.
michael@0 522 *result = NPERR_GENERIC_ERROR;
michael@0 523 }
michael@0 524 else {
michael@0 525 static_cast<StreamNotifyParent*>(actor)->ClearDestructionFlag();
michael@0 526 if (*result != NPERR_NO_ERROR)
michael@0 527 return PStreamNotifyParent::Send__delete__(actor,
michael@0 528 NPERR_GENERIC_ERROR);
michael@0 529 }
michael@0 530
michael@0 531 return true;
michael@0 532 }
michael@0 533
michael@0 534 bool
michael@0 535 PluginInstanceParent::DeallocPStreamNotifyParent(PStreamNotifyParent* notifyData)
michael@0 536 {
michael@0 537 delete notifyData;
michael@0 538 return true;
michael@0 539 }
michael@0 540
michael@0 541 bool
michael@0 542 PluginInstanceParent::RecvNPN_InvalidateRect(const NPRect& rect)
michael@0 543 {
michael@0 544 mNPNIface->invalidaterect(mNPP, const_cast<NPRect*>(&rect));
michael@0 545 return true;
michael@0 546 }
michael@0 547
michael@0 548 bool
michael@0 549 PluginInstanceParent::RecvShow(const NPRect& updatedRect,
michael@0 550 const SurfaceDescriptor& newSurface,
michael@0 551 SurfaceDescriptor* prevSurface)
michael@0 552 {
michael@0 553 PLUGIN_LOG_DEBUG(
michael@0 554 ("[InstanceParent][%p] RecvShow for <x=%d,y=%d, w=%d,h=%d>",
michael@0 555 this, updatedRect.left, updatedRect.top,
michael@0 556 updatedRect.right - updatedRect.left,
michael@0 557 updatedRect.bottom - updatedRect.top));
michael@0 558
michael@0 559 // XXXjwatt rewrite to use Moz2D
michael@0 560 nsRefPtr<gfxASurface> surface;
michael@0 561 if (newSurface.type() == SurfaceDescriptor::TShmem) {
michael@0 562 if (!newSurface.get_Shmem().IsReadable()) {
michael@0 563 NS_WARNING("back surface not readable");
michael@0 564 return false;
michael@0 565 }
michael@0 566 surface = gfxSharedImageSurface::Open(newSurface.get_Shmem());
michael@0 567 }
michael@0 568 #ifdef XP_MACOSX
michael@0 569 else if (newSurface.type() == SurfaceDescriptor::TIOSurfaceDescriptor) {
michael@0 570 IOSurfaceDescriptor iodesc = newSurface.get_IOSurfaceDescriptor();
michael@0 571
michael@0 572 RefPtr<MacIOSurface> newIOSurface =
michael@0 573 MacIOSurface::LookupSurface(iodesc.surfaceId(),
michael@0 574 iodesc.contentsScaleFactor());
michael@0 575
michael@0 576 if (!newIOSurface) {
michael@0 577 NS_WARNING("Got bad IOSurfaceDescriptor in RecvShow");
michael@0 578 return false;
michael@0 579 }
michael@0 580
michael@0 581 if (mFrontIOSurface)
michael@0 582 *prevSurface = IOSurfaceDescriptor(mFrontIOSurface->GetIOSurfaceID(),
michael@0 583 mFrontIOSurface->GetContentsScaleFactor());
michael@0 584 else
michael@0 585 *prevSurface = null_t();
michael@0 586
michael@0 587 mFrontIOSurface = newIOSurface;
michael@0 588
michael@0 589 RecvNPN_InvalidateRect(updatedRect);
michael@0 590
michael@0 591 PLUGIN_LOG_DEBUG((" (RecvShow invalidated for surface %p)",
michael@0 592 mFrontSurface.get()));
michael@0 593
michael@0 594 return true;
michael@0 595 }
michael@0 596 #endif
michael@0 597 #ifdef MOZ_X11
michael@0 598 else if (newSurface.type() == SurfaceDescriptor::TSurfaceDescriptorX11) {
michael@0 599 surface = newSurface.get_SurfaceDescriptorX11().OpenForeign();
michael@0 600 }
michael@0 601 #endif
michael@0 602 #ifdef XP_WIN
michael@0 603 else if (newSurface.type() == SurfaceDescriptor::TPPluginSurfaceParent) {
michael@0 604 PluginSurfaceParent* s =
michael@0 605 static_cast<PluginSurfaceParent*>(newSurface.get_PPluginSurfaceParent());
michael@0 606 surface = s->Surface();
michael@0 607 }
michael@0 608 #endif
michael@0 609
michael@0 610 if (mFrontSurface) {
michael@0 611 // This is the "old front buffer" we're about to hand back to
michael@0 612 // the plugin. We might still have drawing operations
michael@0 613 // referencing it.
michael@0 614 #ifdef MOZ_X11
michael@0 615 if (mFrontSurface->GetType() == gfxSurfaceType::Xlib) {
michael@0 616 // Finish with the surface and XSync here to ensure the server has
michael@0 617 // finished operations on the surface before the plugin starts
michael@0 618 // scribbling on it again, or worse, destroys it.
michael@0 619 mFrontSurface->Finish();
michael@0 620 FinishX(DefaultXDisplay());
michael@0 621 } else
michael@0 622 #endif
michael@0 623 {
michael@0 624 mFrontSurface->Flush();
michael@0 625 }
michael@0 626 }
michael@0 627
michael@0 628 if (mFrontSurface && gfxSharedImageSurface::IsSharedImage(mFrontSurface))
michael@0 629 *prevSurface = static_cast<gfxSharedImageSurface*>(mFrontSurface.get())->GetShmem();
michael@0 630 else
michael@0 631 *prevSurface = null_t();
michael@0 632
michael@0 633 if (surface) {
michael@0 634 // Notify the cairo backend that this surface has changed behind
michael@0 635 // its back.
michael@0 636 gfxRect ur(updatedRect.left, updatedRect.top,
michael@0 637 updatedRect.right - updatedRect.left,
michael@0 638 updatedRect.bottom - updatedRect.top);
michael@0 639 surface->MarkDirty(ur);
michael@0 640
michael@0 641 ImageContainer *container = GetImageContainer();
michael@0 642 nsRefPtr<Image> image = container->CreateImage(ImageFormat::CAIRO_SURFACE);
michael@0 643 NS_ASSERTION(image->GetFormat() == ImageFormat::CAIRO_SURFACE, "Wrong format?");
michael@0 644 CairoImage* cairoImage = static_cast<CairoImage*>(image.get());
michael@0 645 CairoImage::Data cairoData;
michael@0 646 cairoData.mSize = surface->GetSize().ToIntSize();
michael@0 647 cairoData.mSourceSurface = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, surface);
michael@0 648 cairoImage->SetData(cairoData);
michael@0 649
michael@0 650 container->SetCurrentImage(cairoImage);
michael@0 651 }
michael@0 652 else if (mImageContainer) {
michael@0 653 mImageContainer->SetCurrentImage(nullptr);
michael@0 654 }
michael@0 655
michael@0 656 mFrontSurface = surface;
michael@0 657 RecvNPN_InvalidateRect(updatedRect);
michael@0 658
michael@0 659 PLUGIN_LOG_DEBUG((" (RecvShow invalidated for surface %p)",
michael@0 660 mFrontSurface.get()));
michael@0 661
michael@0 662 return true;
michael@0 663 }
michael@0 664
michael@0 665 nsresult
michael@0 666 PluginInstanceParent::AsyncSetWindow(NPWindow* aWindow)
michael@0 667 {
michael@0 668 NPRemoteWindow window;
michael@0 669 mWindowType = aWindow->type;
michael@0 670 window.window = reinterpret_cast<uint64_t>(aWindow->window);
michael@0 671 window.x = aWindow->x;
michael@0 672 window.y = aWindow->y;
michael@0 673 window.width = aWindow->width;
michael@0 674 window.height = aWindow->height;
michael@0 675 window.clipRect = aWindow->clipRect;
michael@0 676 window.type = aWindow->type;
michael@0 677 #ifdef XP_MACOSX
michael@0 678 double scaleFactor = 1.0;
michael@0 679 mNPNIface->getvalue(mNPP, NPNVcontentsScaleFactor, &scaleFactor);
michael@0 680 window.contentsScaleFactor = scaleFactor;
michael@0 681 #endif
michael@0 682 if (!SendAsyncSetWindow(gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType(),
michael@0 683 window))
michael@0 684 return NS_ERROR_FAILURE;
michael@0 685
michael@0 686 return NS_OK;
michael@0 687 }
michael@0 688
michael@0 689 nsresult
michael@0 690 PluginInstanceParent::GetImageContainer(ImageContainer** aContainer)
michael@0 691 {
michael@0 692 #ifdef XP_MACOSX
michael@0 693 MacIOSurface* ioSurface = nullptr;
michael@0 694
michael@0 695 if (mFrontIOSurface) {
michael@0 696 ioSurface = mFrontIOSurface;
michael@0 697 } else if (mIOSurface) {
michael@0 698 ioSurface = mIOSurface;
michael@0 699 }
michael@0 700
michael@0 701 if (!mFrontSurface && !ioSurface)
michael@0 702 #else
michael@0 703 if (!mFrontSurface)
michael@0 704 #endif
michael@0 705 return NS_ERROR_NOT_AVAILABLE;
michael@0 706
michael@0 707 ImageContainer *container = GetImageContainer();
michael@0 708
michael@0 709 if (!container) {
michael@0 710 return NS_ERROR_FAILURE;
michael@0 711 }
michael@0 712
michael@0 713 if (IsAsyncDrawing()) {
michael@0 714 NS_IF_ADDREF(container);
michael@0 715 *aContainer = container;
michael@0 716 return NS_OK;
michael@0 717 }
michael@0 718
michael@0 719 #ifdef XP_MACOSX
michael@0 720 if (ioSurface) {
michael@0 721 nsRefPtr<Image> image = container->CreateImage(ImageFormat::MAC_IOSURFACE);
michael@0 722 if (!image) {
michael@0 723 return NS_ERROR_FAILURE;
michael@0 724 }
michael@0 725
michael@0 726 NS_ASSERTION(image->GetFormat() == ImageFormat::MAC_IOSURFACE, "Wrong format?");
michael@0 727
michael@0 728 MacIOSurfaceImage* pluginImage = static_cast<MacIOSurfaceImage*>(image.get());
michael@0 729 pluginImage->SetSurface(ioSurface);
michael@0 730
michael@0 731 container->SetCurrentImageInTransaction(pluginImage);
michael@0 732
michael@0 733 NS_IF_ADDREF(container);
michael@0 734 *aContainer = container;
michael@0 735 return NS_OK;
michael@0 736 }
michael@0 737 #endif
michael@0 738
michael@0 739 NS_IF_ADDREF(container);
michael@0 740 *aContainer = container;
michael@0 741 return NS_OK;
michael@0 742 }
michael@0 743
michael@0 744 nsresult
michael@0 745 PluginInstanceParent::GetImageSize(nsIntSize* aSize)
michael@0 746 {
michael@0 747 if (mFrontSurface) {
michael@0 748 gfxIntSize size = mFrontSurface->GetSize();
michael@0 749 *aSize = nsIntSize(size.width, size.height);
michael@0 750 return NS_OK;
michael@0 751 }
michael@0 752
michael@0 753 #ifdef XP_MACOSX
michael@0 754 if (mFrontIOSurface) {
michael@0 755 *aSize = nsIntSize(mFrontIOSurface->GetWidth(), mFrontIOSurface->GetHeight());
michael@0 756 return NS_OK;
michael@0 757 } else if (mIOSurface) {
michael@0 758 *aSize = nsIntSize(mIOSurface->GetWidth(), mIOSurface->GetHeight());
michael@0 759 return NS_OK;
michael@0 760 }
michael@0 761 #endif
michael@0 762
michael@0 763 return NS_ERROR_NOT_AVAILABLE;
michael@0 764 }
michael@0 765
michael@0 766 #ifdef XP_MACOSX
michael@0 767 nsresult
michael@0 768 PluginInstanceParent::IsRemoteDrawingCoreAnimation(bool *aDrawing)
michael@0 769 {
michael@0 770 *aDrawing = (NPDrawingModelCoreAnimation == (NPDrawingModel)mDrawingModel ||
michael@0 771 NPDrawingModelInvalidatingCoreAnimation == (NPDrawingModel)mDrawingModel);
michael@0 772 return NS_OK;
michael@0 773 }
michael@0 774
michael@0 775 nsresult
michael@0 776 PluginInstanceParent::ContentsScaleFactorChanged(double aContentsScaleFactor)
michael@0 777 {
michael@0 778 bool rv = SendContentsScaleFactorChanged(aContentsScaleFactor);
michael@0 779 return rv ? NS_OK : NS_ERROR_FAILURE;
michael@0 780 }
michael@0 781 #endif // #ifdef XP_MACOSX
michael@0 782
michael@0 783 nsresult
michael@0 784 PluginInstanceParent::SetBackgroundUnknown()
michael@0 785 {
michael@0 786 PLUGIN_LOG_DEBUG(("[InstanceParent][%p] SetBackgroundUnknown", this));
michael@0 787
michael@0 788 if (mBackground) {
michael@0 789 DestroyBackground();
michael@0 790 NS_ABORT_IF_FALSE(!mBackground, "Background not destroyed");
michael@0 791 }
michael@0 792
michael@0 793 return NS_OK;
michael@0 794 }
michael@0 795
michael@0 796 nsresult
michael@0 797 PluginInstanceParent::BeginUpdateBackground(const nsIntRect& aRect,
michael@0 798 gfxContext** aCtx)
michael@0 799 {
michael@0 800 PLUGIN_LOG_DEBUG(
michael@0 801 ("[InstanceParent][%p] BeginUpdateBackground for <x=%d,y=%d, w=%d,h=%d>",
michael@0 802 this, aRect.x, aRect.y, aRect.width, aRect.height));
michael@0 803
michael@0 804 if (!mBackground) {
michael@0 805 // XXX if we failed to create a background surface on one
michael@0 806 // update, there's no guarantee that later updates will be for
michael@0 807 // the entire background area until successful. We might want
michael@0 808 // to fix that eventually.
michael@0 809 NS_ABORT_IF_FALSE(aRect.TopLeft() == nsIntPoint(0, 0),
michael@0 810 "Expecting rect for whole frame");
michael@0 811 if (!CreateBackground(aRect.Size())) {
michael@0 812 *aCtx = nullptr;
michael@0 813 return NS_OK;
michael@0 814 }
michael@0 815 }
michael@0 816
michael@0 817 gfxIntSize sz = mBackground->GetSize();
michael@0 818 #ifdef DEBUG
michael@0 819 NS_ABORT_IF_FALSE(nsIntRect(0, 0, sz.width, sz.height).Contains(aRect),
michael@0 820 "Update outside of background area");
michael@0 821 #endif
michael@0 822
michael@0 823 RefPtr<gfx::DrawTarget> dt = gfxPlatform::GetPlatform()->
michael@0 824 CreateDrawTargetForSurface(mBackground, gfx::IntSize(sz.width, sz.height));
michael@0 825 nsRefPtr<gfxContext> ctx = new gfxContext(dt);
michael@0 826 ctx.forget(aCtx);
michael@0 827
michael@0 828 return NS_OK;
michael@0 829 }
michael@0 830
michael@0 831 nsresult
michael@0 832 PluginInstanceParent::EndUpdateBackground(gfxContext* aCtx,
michael@0 833 const nsIntRect& aRect)
michael@0 834 {
michael@0 835 PLUGIN_LOG_DEBUG(
michael@0 836 ("[InstanceParent][%p] EndUpdateBackground for <x=%d,y=%d, w=%d,h=%d>",
michael@0 837 this, aRect.x, aRect.y, aRect.width, aRect.height));
michael@0 838
michael@0 839 #ifdef MOZ_X11
michael@0 840 // Have to XSync here to avoid the plugin trying to draw with this
michael@0 841 // surface racing with its creation in the X server. We also want
michael@0 842 // to avoid the plugin drawing onto stale pixels, then handing us
michael@0 843 // back a front surface from those pixels that we might
michael@0 844 // recomposite for "a while" until the next update. This XSync
michael@0 845 // still doesn't guarantee that the plugin draws onto a consistent
michael@0 846 // view of its background, but it does mean that the plugin is
michael@0 847 // drawing onto pixels no older than those in the latest
michael@0 848 // EndUpdateBackground().
michael@0 849 XSync(DefaultXDisplay(), False);
michael@0 850 #endif
michael@0 851
michael@0 852 unused << SendUpdateBackground(BackgroundDescriptor(), aRect);
michael@0 853
michael@0 854 return NS_OK;
michael@0 855 }
michael@0 856
michael@0 857 bool
michael@0 858 PluginInstanceParent::CreateBackground(const nsIntSize& aSize)
michael@0 859 {
michael@0 860 NS_ABORT_IF_FALSE(!mBackground, "Already have a background");
michael@0 861
michael@0 862 // XXX refactor me
michael@0 863
michael@0 864 #if defined(MOZ_X11)
michael@0 865 Screen* screen = DefaultScreenOfDisplay(DefaultXDisplay());
michael@0 866 Visual* visual = DefaultVisualOfScreen(screen);
michael@0 867 mBackground = gfxXlibSurface::Create(screen, visual,
michael@0 868 gfxIntSize(aSize.width, aSize.height));
michael@0 869 return !!mBackground;
michael@0 870
michael@0 871 #elif defined(XP_WIN)
michael@0 872 // We have chosen to create an unsafe surface in which the plugin
michael@0 873 // can read from the region while we're writing to it.
michael@0 874 mBackground =
michael@0 875 gfxSharedImageSurface::CreateUnsafe(
michael@0 876 this,
michael@0 877 gfxIntSize(aSize.width, aSize.height),
michael@0 878 gfxImageFormat::RGB24);
michael@0 879 return !!mBackground;
michael@0 880 #else
michael@0 881 return nullptr;
michael@0 882 #endif
michael@0 883 }
michael@0 884
michael@0 885 void
michael@0 886 PluginInstanceParent::DestroyBackground()
michael@0 887 {
michael@0 888 if (!mBackground) {
michael@0 889 return;
michael@0 890 }
michael@0 891
michael@0 892 // Relinquish ownership of |mBackground| to its destroyer
michael@0 893 PPluginBackgroundDestroyerParent* pbd =
michael@0 894 new PluginBackgroundDestroyerParent(mBackground);
michael@0 895 mBackground = nullptr;
michael@0 896
michael@0 897 // If this fails, there's no problem: |bd| will be destroyed along
michael@0 898 // with the old background surface.
michael@0 899 unused << SendPPluginBackgroundDestroyerConstructor(pbd);
michael@0 900 }
michael@0 901
michael@0 902 mozilla::plugins::SurfaceDescriptor
michael@0 903 PluginInstanceParent::BackgroundDescriptor()
michael@0 904 {
michael@0 905 NS_ABORT_IF_FALSE(mBackground, "Need a background here");
michael@0 906
michael@0 907 // XXX refactor me
michael@0 908
michael@0 909 #ifdef MOZ_X11
michael@0 910 gfxXlibSurface* xsurf = static_cast<gfxXlibSurface*>(mBackground.get());
michael@0 911 return SurfaceDescriptorX11(xsurf);
michael@0 912 #endif
michael@0 913
michael@0 914 #ifdef XP_WIN
michael@0 915 NS_ABORT_IF_FALSE(gfxSharedImageSurface::IsSharedImage(mBackground),
michael@0 916 "Expected shared image surface");
michael@0 917 gfxSharedImageSurface* shmem =
michael@0 918 static_cast<gfxSharedImageSurface*>(mBackground.get());
michael@0 919 return shmem->GetShmem();
michael@0 920 #endif
michael@0 921
michael@0 922 // If this is ever used, which it shouldn't be, it will trigger a
michael@0 923 // hard assertion in IPDL-generated code.
michael@0 924 return mozilla::plugins::SurfaceDescriptor();
michael@0 925 }
michael@0 926
michael@0 927 ImageContainer*
michael@0 928 PluginInstanceParent::GetImageContainer()
michael@0 929 {
michael@0 930 if (mImageContainer) {
michael@0 931 return mImageContainer;
michael@0 932 }
michael@0 933
michael@0 934 mImageContainer = LayerManager::CreateImageContainer();
michael@0 935 return mImageContainer;
michael@0 936 }
michael@0 937
michael@0 938 PPluginBackgroundDestroyerParent*
michael@0 939 PluginInstanceParent::AllocPPluginBackgroundDestroyerParent()
michael@0 940 {
michael@0 941 NS_RUNTIMEABORT("'Power-user' ctor is used exclusively");
michael@0 942 return nullptr;
michael@0 943 }
michael@0 944
michael@0 945 bool
michael@0 946 PluginInstanceParent::DeallocPPluginBackgroundDestroyerParent(
michael@0 947 PPluginBackgroundDestroyerParent* aActor)
michael@0 948 {
michael@0 949 delete aActor;
michael@0 950 return true;
michael@0 951 }
michael@0 952
michael@0 953 NPError
michael@0 954 PluginInstanceParent::NPP_SetWindow(const NPWindow* aWindow)
michael@0 955 {
michael@0 956 PLUGIN_LOG_DEBUG(("%s (aWindow=%p)", FULLFUNCTION, (void*) aWindow));
michael@0 957
michael@0 958 NS_ENSURE_TRUE(aWindow, NPERR_GENERIC_ERROR);
michael@0 959
michael@0 960 NPRemoteWindow window;
michael@0 961 mWindowType = aWindow->type;
michael@0 962
michael@0 963 #if defined(OS_WIN)
michael@0 964 // On windowless controls, reset the shared memory surface as needed.
michael@0 965 if (mWindowType == NPWindowTypeDrawable) {
michael@0 966 // SharedSurfaceSetWindow will take care of NPRemoteWindow.
michael@0 967 if (!SharedSurfaceSetWindow(aWindow, window)) {
michael@0 968 return NPERR_OUT_OF_MEMORY_ERROR;
michael@0 969 }
michael@0 970 }
michael@0 971 else {
michael@0 972 SubclassPluginWindow(reinterpret_cast<HWND>(aWindow->window));
michael@0 973
michael@0 974 window.window = reinterpret_cast<uint64_t>(aWindow->window);
michael@0 975 window.x = aWindow->x;
michael@0 976 window.y = aWindow->y;
michael@0 977 window.width = aWindow->width;
michael@0 978 window.height = aWindow->height;
michael@0 979 window.type = aWindow->type;
michael@0 980 }
michael@0 981 #else
michael@0 982 window.window = reinterpret_cast<uint64_t>(aWindow->window);
michael@0 983 window.x = aWindow->x;
michael@0 984 window.y = aWindow->y;
michael@0 985 window.width = aWindow->width;
michael@0 986 window.height = aWindow->height;
michael@0 987 window.clipRect = aWindow->clipRect; // MacOS specific
michael@0 988 window.type = aWindow->type;
michael@0 989 #endif
michael@0 990
michael@0 991 #if defined(XP_MACOSX)
michael@0 992 double floatScaleFactor = 1.0;
michael@0 993 mNPNIface->getvalue(mNPP, NPNVcontentsScaleFactor, &floatScaleFactor);
michael@0 994 int scaleFactor = ceil(floatScaleFactor);
michael@0 995 window.contentsScaleFactor = floatScaleFactor;
michael@0 996
michael@0 997 if (mShWidth != window.width * scaleFactor || mShHeight != window.height * scaleFactor) {
michael@0 998 if (mDrawingModel == NPDrawingModelCoreAnimation ||
michael@0 999 mDrawingModel == NPDrawingModelInvalidatingCoreAnimation) {
michael@0 1000 mIOSurface = MacIOSurface::CreateIOSurface(window.width, window.height,
michael@0 1001 floatScaleFactor);
michael@0 1002 } else if (uint32_t(mShWidth * mShHeight) !=
michael@0 1003 window.width * scaleFactor * window.height * scaleFactor) {
michael@0 1004 if (mShWidth != 0 && mShHeight != 0) {
michael@0 1005 DeallocShmem(mShSurface);
michael@0 1006 mShWidth = 0;
michael@0 1007 mShHeight = 0;
michael@0 1008 }
michael@0 1009
michael@0 1010 if (window.width != 0 && window.height != 0) {
michael@0 1011 if (!AllocShmem(window.width * scaleFactor * window.height*4 * scaleFactor,
michael@0 1012 SharedMemory::TYPE_BASIC, &mShSurface)) {
michael@0 1013 PLUGIN_LOG_DEBUG(("Shared memory could not be allocated."));
michael@0 1014 return NPERR_GENERIC_ERROR;
michael@0 1015 }
michael@0 1016 }
michael@0 1017 }
michael@0 1018 mShWidth = window.width * scaleFactor;
michael@0 1019 mShHeight = window.height * scaleFactor;
michael@0 1020 }
michael@0 1021 #endif
michael@0 1022
michael@0 1023 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
michael@0 1024 const NPSetWindowCallbackStruct* ws_info =
michael@0 1025 static_cast<NPSetWindowCallbackStruct*>(aWindow->ws_info);
michael@0 1026 window.visualID = ws_info->visual ? ws_info->visual->visualid : None;
michael@0 1027 window.colormap = ws_info->colormap;
michael@0 1028 #endif
michael@0 1029
michael@0 1030 if (!CallNPP_SetWindow(window))
michael@0 1031 return NPERR_GENERIC_ERROR;
michael@0 1032
michael@0 1033 return NPERR_NO_ERROR;
michael@0 1034 }
michael@0 1035
michael@0 1036 NPError
michael@0 1037 PluginInstanceParent::NPP_GetValue(NPPVariable aVariable,
michael@0 1038 void* _retval)
michael@0 1039 {
michael@0 1040 switch (aVariable) {
michael@0 1041
michael@0 1042 case NPPVpluginWantsAllNetworkStreams: {
michael@0 1043 bool wantsAllStreams;
michael@0 1044 NPError rv;
michael@0 1045
michael@0 1046 if (!CallNPP_GetValue_NPPVpluginWantsAllNetworkStreams(&wantsAllStreams, &rv)) {
michael@0 1047 return NPERR_GENERIC_ERROR;
michael@0 1048 }
michael@0 1049
michael@0 1050 if (NPERR_NO_ERROR != rv) {
michael@0 1051 return rv;
michael@0 1052 }
michael@0 1053
michael@0 1054 (*(NPBool*)_retval) = wantsAllStreams;
michael@0 1055 return NPERR_NO_ERROR;
michael@0 1056 }
michael@0 1057
michael@0 1058 #ifdef MOZ_X11
michael@0 1059 case NPPVpluginNeedsXEmbed: {
michael@0 1060 bool needsXEmbed;
michael@0 1061 NPError rv;
michael@0 1062
michael@0 1063 if (!CallNPP_GetValue_NPPVpluginNeedsXEmbed(&needsXEmbed, &rv)) {
michael@0 1064 return NPERR_GENERIC_ERROR;
michael@0 1065 }
michael@0 1066
michael@0 1067 if (NPERR_NO_ERROR != rv) {
michael@0 1068 return rv;
michael@0 1069 }
michael@0 1070
michael@0 1071 (*(NPBool*)_retval) = needsXEmbed;
michael@0 1072 return NPERR_NO_ERROR;
michael@0 1073 }
michael@0 1074 #endif
michael@0 1075
michael@0 1076 case NPPVpluginScriptableNPObject: {
michael@0 1077 PPluginScriptableObjectParent* actor;
michael@0 1078 NPError rv;
michael@0 1079 if (!CallNPP_GetValue_NPPVpluginScriptableNPObject(&actor, &rv)) {
michael@0 1080 return NPERR_GENERIC_ERROR;
michael@0 1081 }
michael@0 1082
michael@0 1083 if (NPERR_NO_ERROR != rv) {
michael@0 1084 return rv;
michael@0 1085 }
michael@0 1086
michael@0 1087 if (!actor) {
michael@0 1088 NS_ERROR("NPPVpluginScriptableNPObject succeeded but null.");
michael@0 1089 return NPERR_GENERIC_ERROR;
michael@0 1090 }
michael@0 1091
michael@0 1092 const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs();
michael@0 1093 if (!npn) {
michael@0 1094 NS_WARNING("No netscape functions?!");
michael@0 1095 return NPERR_GENERIC_ERROR;
michael@0 1096 }
michael@0 1097
michael@0 1098 NPObject* object =
michael@0 1099 static_cast<PluginScriptableObjectParent*>(actor)->GetObject(true);
michael@0 1100 NS_ASSERTION(object, "This shouldn't ever be null!");
michael@0 1101
michael@0 1102 (*(NPObject**)_retval) = npn->retainobject(object);
michael@0 1103 return NPERR_NO_ERROR;
michael@0 1104 }
michael@0 1105
michael@0 1106 #ifdef MOZ_ACCESSIBILITY_ATK
michael@0 1107 case NPPVpluginNativeAccessibleAtkPlugId: {
michael@0 1108 nsCString plugId;
michael@0 1109 NPError rv;
michael@0 1110 if (!CallNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId(&plugId, &rv)) {
michael@0 1111 return NPERR_GENERIC_ERROR;
michael@0 1112 }
michael@0 1113
michael@0 1114 if (NPERR_NO_ERROR != rv) {
michael@0 1115 return rv;
michael@0 1116 }
michael@0 1117
michael@0 1118 (*(nsCString*)_retval) = plugId;
michael@0 1119 return NPERR_NO_ERROR;
michael@0 1120 }
michael@0 1121 #endif
michael@0 1122
michael@0 1123 default:
michael@0 1124 PR_LOG(GetPluginLog(), PR_LOG_WARNING,
michael@0 1125 ("In PluginInstanceParent::NPP_GetValue: Unhandled NPPVariable %i (%s)",
michael@0 1126 (int) aVariable, NPPVariableToString(aVariable)));
michael@0 1127 return NPERR_GENERIC_ERROR;
michael@0 1128 }
michael@0 1129 }
michael@0 1130
michael@0 1131 NPError
michael@0 1132 PluginInstanceParent::NPP_SetValue(NPNVariable variable, void* value)
michael@0 1133 {
michael@0 1134 switch (variable) {
michael@0 1135 case NPNVprivateModeBool:
michael@0 1136 NPError result;
michael@0 1137 if (!CallNPP_SetValue_NPNVprivateModeBool(*static_cast<NPBool*>(value),
michael@0 1138 &result))
michael@0 1139 return NPERR_GENERIC_ERROR;
michael@0 1140
michael@0 1141 return result;
michael@0 1142
michael@0 1143 default:
michael@0 1144 NS_ERROR("Unhandled NPNVariable in NPP_SetValue");
michael@0 1145 PR_LOG(GetPluginLog(), PR_LOG_WARNING,
michael@0 1146 ("In PluginInstanceParent::NPP_SetValue: Unhandled NPNVariable %i (%s)",
michael@0 1147 (int) variable, NPNVariableToString(variable)));
michael@0 1148 return NPERR_GENERIC_ERROR;
michael@0 1149 }
michael@0 1150 }
michael@0 1151
michael@0 1152 void
michael@0 1153 PluginInstanceParent::NPP_URLRedirectNotify(const char* url, int32_t status,
michael@0 1154 void* notifyData)
michael@0 1155 {
michael@0 1156 if (!notifyData)
michael@0 1157 return;
michael@0 1158
michael@0 1159 PStreamNotifyParent* streamNotify = static_cast<PStreamNotifyParent*>(notifyData);
michael@0 1160 unused << streamNotify->SendRedirectNotify(NullableString(url), status);
michael@0 1161 }
michael@0 1162
michael@0 1163 int16_t
michael@0 1164 PluginInstanceParent::NPP_HandleEvent(void* event)
michael@0 1165 {
michael@0 1166 PLUGIN_LOG_DEBUG_FUNCTION;
michael@0 1167
michael@0 1168 #if defined(XP_MACOSX)
michael@0 1169 NPCocoaEvent* npevent = reinterpret_cast<NPCocoaEvent*>(event);
michael@0 1170 #else
michael@0 1171 NPEvent* npevent = reinterpret_cast<NPEvent*>(event);
michael@0 1172 #endif
michael@0 1173 NPRemoteEvent npremoteevent;
michael@0 1174 npremoteevent.event = *npevent;
michael@0 1175 #if defined(XP_MACOSX)
michael@0 1176 double scaleFactor = 1.0;
michael@0 1177 mNPNIface->getvalue(mNPP, NPNVcontentsScaleFactor, &scaleFactor);
michael@0 1178 npremoteevent.contentsScaleFactor = scaleFactor;
michael@0 1179 #endif
michael@0 1180 int16_t handled = 0;
michael@0 1181
michael@0 1182 #if defined(OS_WIN)
michael@0 1183 if (mWindowType == NPWindowTypeDrawable) {
michael@0 1184 if (IsAsyncDrawing()) {
michael@0 1185 if (npevent->event == WM_PAINT || npevent->event == DoublePassRenderingEvent()) {
michael@0 1186 // This plugin maintains its own async drawing.
michael@0 1187 return handled;
michael@0 1188 }
michael@0 1189 }
michael@0 1190 if (DoublePassRenderingEvent() == npevent->event) {
michael@0 1191 return CallPaint(npremoteevent, &handled) && handled;
michael@0 1192 }
michael@0 1193
michael@0 1194 switch (npevent->event) {
michael@0 1195 case WM_PAINT:
michael@0 1196 {
michael@0 1197 RECT rect;
michael@0 1198 SharedSurfaceBeforePaint(rect, npremoteevent);
michael@0 1199 if (!CallPaint(npremoteevent, &handled)) {
michael@0 1200 handled = false;
michael@0 1201 }
michael@0 1202 SharedSurfaceAfterPaint(npevent);
michael@0 1203 return handled;
michael@0 1204 }
michael@0 1205 break;
michael@0 1206
michael@0 1207 case WM_KILLFOCUS:
michael@0 1208 {
michael@0 1209 // When the user selects fullscreen mode in Flash video players,
michael@0 1210 // WM_KILLFOCUS will be delayed by deferred event processing:
michael@0 1211 // WM_LBUTTONUP results in a call to CreateWindow within Flash,
michael@0 1212 // which fires WM_KILLFOCUS. Delayed delivery causes Flash to
michael@0 1213 // misinterpret the event, dropping back out of fullscreen. Trap
michael@0 1214 // this event and drop it.
michael@0 1215 wchar_t szClass[26];
michael@0 1216 HWND hwnd = GetForegroundWindow();
michael@0 1217 if (hwnd && hwnd != mPluginHWND &&
michael@0 1218 GetClassNameW(hwnd, szClass,
michael@0 1219 sizeof(szClass)/sizeof(char16_t)) &&
michael@0 1220 !wcscmp(szClass, kFlashFullscreenClass)) {
michael@0 1221 return 0;
michael@0 1222 }
michael@0 1223 }
michael@0 1224 break;
michael@0 1225
michael@0 1226 case WM_WINDOWPOSCHANGED:
michael@0 1227 {
michael@0 1228 // We send this in nsObjectFrame just before painting
michael@0 1229 return SendWindowPosChanged(npremoteevent);
michael@0 1230 }
michael@0 1231 break;
michael@0 1232 }
michael@0 1233 }
michael@0 1234 #endif
michael@0 1235
michael@0 1236 #if defined(MOZ_X11)
michael@0 1237 switch (npevent->type) {
michael@0 1238 case GraphicsExpose:
michael@0 1239 PLUGIN_LOG_DEBUG((" schlepping drawable 0x%lx across the pipe\n",
michael@0 1240 npevent->xgraphicsexpose.drawable));
michael@0 1241 // Make sure the X server has created the Drawable and completes any
michael@0 1242 // drawing before the plugin draws on top.
michael@0 1243 //
michael@0 1244 // XSync() waits for the X server to complete. Really this parent
michael@0 1245 // process does not need to wait; the child is the process that needs
michael@0 1246 // to wait. A possibly-slightly-better alternative would be to send
michael@0 1247 // an X event to the child that the child would wait for.
michael@0 1248 FinishX(DefaultXDisplay());
michael@0 1249
michael@0 1250 return CallPaint(npremoteevent, &handled) ? handled : 0;
michael@0 1251
michael@0 1252 case ButtonPress:
michael@0 1253 // Release any active pointer grab so that the plugin X client can
michael@0 1254 // grab the pointer if it wishes.
michael@0 1255 Display *dpy = DefaultXDisplay();
michael@0 1256 # ifdef MOZ_WIDGET_GTK
michael@0 1257 // GDK attempts to (asynchronously) track whether there is an active
michael@0 1258 // grab so ungrab through GDK.
michael@0 1259 gdk_pointer_ungrab(npevent->xbutton.time);
michael@0 1260 # else
michael@0 1261 XUngrabPointer(dpy, npevent->xbutton.time);
michael@0 1262 # endif
michael@0 1263 // Wait for the ungrab to complete.
michael@0 1264 XSync(dpy, False);
michael@0 1265 break;
michael@0 1266 }
michael@0 1267 #endif
michael@0 1268
michael@0 1269 #ifdef XP_MACOSX
michael@0 1270 if (npevent->type == NPCocoaEventDrawRect) {
michael@0 1271 if (mDrawingModel == NPDrawingModelCoreAnimation ||
michael@0 1272 mDrawingModel == NPDrawingModelInvalidatingCoreAnimation) {
michael@0 1273 if (!mIOSurface) {
michael@0 1274 NS_ERROR("No IOSurface allocated.");
michael@0 1275 return false;
michael@0 1276 }
michael@0 1277 if (!CallNPP_HandleEvent_IOSurface(npremoteevent,
michael@0 1278 mIOSurface->GetIOSurfaceID(),
michael@0 1279 &handled))
michael@0 1280 return false; // no good way to handle errors here...
michael@0 1281
michael@0 1282 CGContextRef cgContext = npevent->data.draw.context;
michael@0 1283 if (!mShColorSpace) {
michael@0 1284 mShColorSpace = CreateSystemColorSpace();
michael@0 1285 }
michael@0 1286 if (!mShColorSpace) {
michael@0 1287 PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
michael@0 1288 return false;
michael@0 1289 }
michael@0 1290 if (cgContext) {
michael@0 1291 nsCARenderer::DrawSurfaceToCGContext(cgContext, mIOSurface,
michael@0 1292 mShColorSpace,
michael@0 1293 npevent->data.draw.x,
michael@0 1294 npevent->data.draw.y,
michael@0 1295 npevent->data.draw.width,
michael@0 1296 npevent->data.draw.height);
michael@0 1297 }
michael@0 1298 return true;
michael@0 1299 } else if (mFrontIOSurface) {
michael@0 1300 CGContextRef cgContext = npevent->data.draw.context;
michael@0 1301 if (!mShColorSpace) {
michael@0 1302 mShColorSpace = CreateSystemColorSpace();
michael@0 1303 }
michael@0 1304 if (!mShColorSpace) {
michael@0 1305 PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
michael@0 1306 return false;
michael@0 1307 }
michael@0 1308 if (cgContext) {
michael@0 1309 nsCARenderer::DrawSurfaceToCGContext(cgContext, mFrontIOSurface,
michael@0 1310 mShColorSpace,
michael@0 1311 npevent->data.draw.x,
michael@0 1312 npevent->data.draw.y,
michael@0 1313 npevent->data.draw.width,
michael@0 1314 npevent->data.draw.height);
michael@0 1315 }
michael@0 1316 return true;
michael@0 1317 } else {
michael@0 1318 if (mShWidth == 0 && mShHeight == 0) {
michael@0 1319 PLUGIN_LOG_DEBUG(("NPCocoaEventDrawRect on window of size 0."));
michael@0 1320 return false;
michael@0 1321 }
michael@0 1322 if (!mShSurface.IsReadable()) {
michael@0 1323 PLUGIN_LOG_DEBUG(("Shmem is not readable."));
michael@0 1324 return false;
michael@0 1325 }
michael@0 1326
michael@0 1327 if (!CallNPP_HandleEvent_Shmem(npremoteevent, mShSurface,
michael@0 1328 &handled, &mShSurface))
michael@0 1329 return false; // no good way to handle errors here...
michael@0 1330
michael@0 1331 if (!mShSurface.IsReadable()) {
michael@0 1332 PLUGIN_LOG_DEBUG(("Shmem not returned. Either the plugin crashed "
michael@0 1333 "or we have a bug."));
michael@0 1334 return false;
michael@0 1335 }
michael@0 1336
michael@0 1337 char* shContextByte = mShSurface.get<char>();
michael@0 1338
michael@0 1339 if (!mShColorSpace) {
michael@0 1340 mShColorSpace = CreateSystemColorSpace();
michael@0 1341 }
michael@0 1342 if (!mShColorSpace) {
michael@0 1343 PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
michael@0 1344 return false;
michael@0 1345 }
michael@0 1346 CGContextRef shContext = ::CGBitmapContextCreate(shContextByte,
michael@0 1347 mShWidth, mShHeight, 8,
michael@0 1348 mShWidth*4, mShColorSpace,
michael@0 1349 kCGImageAlphaPremultipliedFirst |
michael@0 1350 kCGBitmapByteOrder32Host);
michael@0 1351 if (!shContext) {
michael@0 1352 PLUGIN_LOG_DEBUG(("Could not allocate CGBitmapContext."));
michael@0 1353 return false;
michael@0 1354 }
michael@0 1355
michael@0 1356 CGImageRef shImage = ::CGBitmapContextCreateImage(shContext);
michael@0 1357 if (shImage) {
michael@0 1358 CGContextRef cgContext = npevent->data.draw.context;
michael@0 1359
michael@0 1360 ::CGContextDrawImage(cgContext,
michael@0 1361 CGRectMake(0,0,mShWidth,mShHeight),
michael@0 1362 shImage);
michael@0 1363 ::CGImageRelease(shImage);
michael@0 1364 } else {
michael@0 1365 ::CGContextRelease(shContext);
michael@0 1366 return false;
michael@0 1367 }
michael@0 1368 ::CGContextRelease(shContext);
michael@0 1369 return true;
michael@0 1370 }
michael@0 1371 }
michael@0 1372 #endif
michael@0 1373
michael@0 1374 if (!CallNPP_HandleEvent(npremoteevent, &handled))
michael@0 1375 return 0; // no good way to handle errors here...
michael@0 1376
michael@0 1377 return handled;
michael@0 1378 }
michael@0 1379
michael@0 1380 NPError
michael@0 1381 PluginInstanceParent::NPP_NewStream(NPMIMEType type, NPStream* stream,
michael@0 1382 NPBool seekable, uint16_t* stype)
michael@0 1383 {
michael@0 1384 PLUGIN_LOG_DEBUG(("%s (type=%s, stream=%p, seekable=%i)",
michael@0 1385 FULLFUNCTION, (char*) type, (void*) stream, (int) seekable));
michael@0 1386
michael@0 1387 BrowserStreamParent* bs = new BrowserStreamParent(this, stream);
michael@0 1388
michael@0 1389 NPError err;
michael@0 1390 if (!CallPBrowserStreamConstructor(bs,
michael@0 1391 NullableString(stream->url),
michael@0 1392 stream->end,
michael@0 1393 stream->lastmodified,
michael@0 1394 static_cast<PStreamNotifyParent*>(stream->notifyData),
michael@0 1395 NullableString(stream->headers),
michael@0 1396 NullableString(type), seekable,
michael@0 1397 &err, stype))
michael@0 1398 return NPERR_GENERIC_ERROR;
michael@0 1399
michael@0 1400 if (NPERR_NO_ERROR != err)
michael@0 1401 unused << PBrowserStreamParent::Send__delete__(bs);
michael@0 1402
michael@0 1403 return err;
michael@0 1404 }
michael@0 1405
michael@0 1406 NPError
michael@0 1407 PluginInstanceParent::NPP_DestroyStream(NPStream* stream, NPReason reason)
michael@0 1408 {
michael@0 1409 PLUGIN_LOG_DEBUG(("%s (stream=%p, reason=%i)",
michael@0 1410 FULLFUNCTION, (void*) stream, (int) reason));
michael@0 1411
michael@0 1412 AStream* s = static_cast<AStream*>(stream->pdata);
michael@0 1413 if (s->IsBrowserStream()) {
michael@0 1414 BrowserStreamParent* sp =
michael@0 1415 static_cast<BrowserStreamParent*>(s);
michael@0 1416 if (sp->mNPP != this)
michael@0 1417 NS_RUNTIMEABORT("Mismatched plugin data");
michael@0 1418
michael@0 1419 sp->NPP_DestroyStream(reason);
michael@0 1420 return NPERR_NO_ERROR;
michael@0 1421 }
michael@0 1422 else {
michael@0 1423 PluginStreamParent* sp =
michael@0 1424 static_cast<PluginStreamParent*>(s);
michael@0 1425 if (sp->mInstance != this)
michael@0 1426 NS_RUNTIMEABORT("Mismatched plugin data");
michael@0 1427
michael@0 1428 return PPluginStreamParent::Call__delete__(sp, reason, false) ?
michael@0 1429 NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
michael@0 1430 }
michael@0 1431 }
michael@0 1432
michael@0 1433 void
michael@0 1434 PluginInstanceParent::NPP_Print(NPPrint* platformPrint)
michael@0 1435 {
michael@0 1436 // TODO: implement me
michael@0 1437 NS_ERROR("Not implemented");
michael@0 1438 }
michael@0 1439
michael@0 1440 PPluginScriptableObjectParent*
michael@0 1441 PluginInstanceParent::AllocPPluginScriptableObjectParent()
michael@0 1442 {
michael@0 1443 return new PluginScriptableObjectParent(Proxy);
michael@0 1444 }
michael@0 1445
michael@0 1446 #ifdef DEBUG
michael@0 1447 namespace {
michael@0 1448
michael@0 1449 struct ActorSearchData
michael@0 1450 {
michael@0 1451 PluginScriptableObjectParent* actor;
michael@0 1452 bool found;
michael@0 1453 };
michael@0 1454
michael@0 1455 PLDHashOperator
michael@0 1456 ActorSearch(NPObject* aKey,
michael@0 1457 PluginScriptableObjectParent* aData,
michael@0 1458 void* aUserData)
michael@0 1459 {
michael@0 1460 ActorSearchData* asd = reinterpret_cast<ActorSearchData*>(aUserData);
michael@0 1461 if (asd->actor == aData) {
michael@0 1462 asd->found = true;
michael@0 1463 return PL_DHASH_STOP;
michael@0 1464 }
michael@0 1465 return PL_DHASH_NEXT;
michael@0 1466 }
michael@0 1467
michael@0 1468 } // anonymous namespace
michael@0 1469 #endif // DEBUG
michael@0 1470
michael@0 1471 bool
michael@0 1472 PluginInstanceParent::DeallocPPluginScriptableObjectParent(
michael@0 1473 PPluginScriptableObjectParent* aObject)
michael@0 1474 {
michael@0 1475 PluginScriptableObjectParent* actor =
michael@0 1476 static_cast<PluginScriptableObjectParent*>(aObject);
michael@0 1477
michael@0 1478 NPObject* object = actor->GetObject(false);
michael@0 1479 if (object) {
michael@0 1480 NS_ASSERTION(mScriptableObjects.Get(object, nullptr),
michael@0 1481 "NPObject not in the hash!");
michael@0 1482 mScriptableObjects.Remove(object);
michael@0 1483 }
michael@0 1484 #ifdef DEBUG
michael@0 1485 else {
michael@0 1486 ActorSearchData asd = { actor, false };
michael@0 1487 mScriptableObjects.EnumerateRead(ActorSearch, &asd);
michael@0 1488 NS_ASSERTION(!asd.found, "Actor in the hash with a null NPObject!");
michael@0 1489 }
michael@0 1490 #endif
michael@0 1491
michael@0 1492 delete actor;
michael@0 1493 return true;
michael@0 1494 }
michael@0 1495
michael@0 1496 bool
michael@0 1497 PluginInstanceParent::RecvPPluginScriptableObjectConstructor(
michael@0 1498 PPluginScriptableObjectParent* aActor)
michael@0 1499 {
michael@0 1500 // This is only called in response to the child process requesting the
michael@0 1501 // creation of an actor. This actor will represent an NPObject that is
michael@0 1502 // created by the plugin and returned to the browser.
michael@0 1503 PluginScriptableObjectParent* actor =
michael@0 1504 static_cast<PluginScriptableObjectParent*>(aActor);
michael@0 1505 NS_ASSERTION(!actor->GetObject(false), "Actor already has an object?!");
michael@0 1506
michael@0 1507 actor->InitializeProxy();
michael@0 1508 NS_ASSERTION(actor->GetObject(false), "Actor should have an object!");
michael@0 1509
michael@0 1510 return true;
michael@0 1511 }
michael@0 1512
michael@0 1513 void
michael@0 1514 PluginInstanceParent::NPP_URLNotify(const char* url, NPReason reason,
michael@0 1515 void* notifyData)
michael@0 1516 {
michael@0 1517 PLUGIN_LOG_DEBUG(("%s (%s, %i, %p)",
michael@0 1518 FULLFUNCTION, url, (int) reason, notifyData));
michael@0 1519
michael@0 1520 PStreamNotifyParent* streamNotify =
michael@0 1521 static_cast<PStreamNotifyParent*>(notifyData);
michael@0 1522 unused << PStreamNotifyParent::Send__delete__(streamNotify, reason);
michael@0 1523 }
michael@0 1524
michael@0 1525 bool
michael@0 1526 PluginInstanceParent::RegisterNPObjectForActor(
michael@0 1527 NPObject* aObject,
michael@0 1528 PluginScriptableObjectParent* aActor)
michael@0 1529 {
michael@0 1530 NS_ASSERTION(aObject && aActor, "Null pointers!");
michael@0 1531 NS_ASSERTION(!mScriptableObjects.Get(aObject, nullptr), "Duplicate entry!");
michael@0 1532 mScriptableObjects.Put(aObject, aActor);
michael@0 1533 return true;
michael@0 1534 }
michael@0 1535
michael@0 1536 void
michael@0 1537 PluginInstanceParent::UnregisterNPObject(NPObject* aObject)
michael@0 1538 {
michael@0 1539 NS_ASSERTION(aObject, "Null pointer!");
michael@0 1540 NS_ASSERTION(mScriptableObjects.Get(aObject, nullptr), "Unknown entry!");
michael@0 1541 mScriptableObjects.Remove(aObject);
michael@0 1542 }
michael@0 1543
michael@0 1544 PluginScriptableObjectParent*
michael@0 1545 PluginInstanceParent::GetActorForNPObject(NPObject* aObject)
michael@0 1546 {
michael@0 1547 NS_ASSERTION(aObject, "Null pointer!");
michael@0 1548
michael@0 1549 if (aObject->_class == PluginScriptableObjectParent::GetClass()) {
michael@0 1550 // One of ours!
michael@0 1551 ParentNPObject* object = static_cast<ParentNPObject*>(aObject);
michael@0 1552 NS_ASSERTION(object->parent, "Null actor!");
michael@0 1553 return object->parent;
michael@0 1554 }
michael@0 1555
michael@0 1556 PluginScriptableObjectParent* actor;
michael@0 1557 if (mScriptableObjects.Get(aObject, &actor)) {
michael@0 1558 return actor;
michael@0 1559 }
michael@0 1560
michael@0 1561 actor = new PluginScriptableObjectParent(LocalObject);
michael@0 1562 if (!actor) {
michael@0 1563 NS_ERROR("Out of memory!");
michael@0 1564 return nullptr;
michael@0 1565 }
michael@0 1566
michael@0 1567 if (!SendPPluginScriptableObjectConstructor(actor)) {
michael@0 1568 NS_WARNING("Failed to send constructor message!");
michael@0 1569 return nullptr;
michael@0 1570 }
michael@0 1571
michael@0 1572 actor->InitializeLocal(aObject);
michael@0 1573 return actor;
michael@0 1574 }
michael@0 1575
michael@0 1576 PPluginSurfaceParent*
michael@0 1577 PluginInstanceParent::AllocPPluginSurfaceParent(const WindowsSharedMemoryHandle& handle,
michael@0 1578 const gfxIntSize& size,
michael@0 1579 const bool& transparent)
michael@0 1580 {
michael@0 1581 #ifdef XP_WIN
michael@0 1582 return new PluginSurfaceParent(handle, size, transparent);
michael@0 1583 #else
michael@0 1584 NS_ERROR("This shouldn't be called!");
michael@0 1585 return nullptr;
michael@0 1586 #endif
michael@0 1587 }
michael@0 1588
michael@0 1589 bool
michael@0 1590 PluginInstanceParent::DeallocPPluginSurfaceParent(PPluginSurfaceParent* s)
michael@0 1591 {
michael@0 1592 #ifdef XP_WIN
michael@0 1593 delete s;
michael@0 1594 return true;
michael@0 1595 #else
michael@0 1596 return false;
michael@0 1597 #endif
michael@0 1598 }
michael@0 1599
michael@0 1600 bool
michael@0 1601 PluginInstanceParent::AnswerNPN_PushPopupsEnabledState(const bool& aState)
michael@0 1602 {
michael@0 1603 mNPNIface->pushpopupsenabledstate(mNPP, aState ? 1 : 0);
michael@0 1604 return true;
michael@0 1605 }
michael@0 1606
michael@0 1607 bool
michael@0 1608 PluginInstanceParent::AnswerNPN_PopPopupsEnabledState()
michael@0 1609 {
michael@0 1610 mNPNIface->poppopupsenabledstate(mNPP);
michael@0 1611 return true;
michael@0 1612 }
michael@0 1613
michael@0 1614 bool
michael@0 1615 PluginInstanceParent::AnswerNPN_GetValueForURL(const NPNURLVariable& variable,
michael@0 1616 const nsCString& url,
michael@0 1617 nsCString* value,
michael@0 1618 NPError* result)
michael@0 1619 {
michael@0 1620 char* v;
michael@0 1621 uint32_t len;
michael@0 1622
michael@0 1623 *result = mNPNIface->getvalueforurl(mNPP, (NPNURLVariable) variable,
michael@0 1624 url.get(), &v, &len);
michael@0 1625 if (NPERR_NO_ERROR == *result)
michael@0 1626 value->Adopt(v, len);
michael@0 1627
michael@0 1628 return true;
michael@0 1629 }
michael@0 1630
michael@0 1631 bool
michael@0 1632 PluginInstanceParent::AnswerNPN_SetValueForURL(const NPNURLVariable& variable,
michael@0 1633 const nsCString& url,
michael@0 1634 const nsCString& value,
michael@0 1635 NPError* result)
michael@0 1636 {
michael@0 1637 *result = mNPNIface->setvalueforurl(mNPP, (NPNURLVariable) variable,
michael@0 1638 url.get(), value.get(),
michael@0 1639 value.Length());
michael@0 1640 return true;
michael@0 1641 }
michael@0 1642
michael@0 1643 bool
michael@0 1644 PluginInstanceParent::AnswerNPN_GetAuthenticationInfo(const nsCString& protocol,
michael@0 1645 const nsCString& host,
michael@0 1646 const int32_t& port,
michael@0 1647 const nsCString& scheme,
michael@0 1648 const nsCString& realm,
michael@0 1649 nsCString* username,
michael@0 1650 nsCString* password,
michael@0 1651 NPError* result)
michael@0 1652 {
michael@0 1653 char* u;
michael@0 1654 uint32_t ulen;
michael@0 1655 char* p;
michael@0 1656 uint32_t plen;
michael@0 1657
michael@0 1658 *result = mNPNIface->getauthenticationinfo(mNPP, protocol.get(),
michael@0 1659 host.get(), port,
michael@0 1660 scheme.get(), realm.get(),
michael@0 1661 &u, &ulen, &p, &plen);
michael@0 1662 if (NPERR_NO_ERROR == *result) {
michael@0 1663 username->Adopt(u, ulen);
michael@0 1664 password->Adopt(p, plen);
michael@0 1665 }
michael@0 1666 return true;
michael@0 1667 }
michael@0 1668
michael@0 1669 bool
michael@0 1670 PluginInstanceParent::AnswerNPN_ConvertPoint(const double& sourceX,
michael@0 1671 const bool& ignoreDestX,
michael@0 1672 const double& sourceY,
michael@0 1673 const bool& ignoreDestY,
michael@0 1674 const NPCoordinateSpace& sourceSpace,
michael@0 1675 const NPCoordinateSpace& destSpace,
michael@0 1676 double *destX,
michael@0 1677 double *destY,
michael@0 1678 bool *result)
michael@0 1679 {
michael@0 1680 *result = mNPNIface->convertpoint(mNPP, sourceX, sourceY, sourceSpace,
michael@0 1681 ignoreDestX ? nullptr : destX,
michael@0 1682 ignoreDestY ? nullptr : destY,
michael@0 1683 destSpace);
michael@0 1684
michael@0 1685 return true;
michael@0 1686 }
michael@0 1687
michael@0 1688 bool
michael@0 1689 PluginInstanceParent::AnswerNPN_InitAsyncSurface(const gfxIntSize& size,
michael@0 1690 const NPImageFormat& format,
michael@0 1691 NPRemoteAsyncSurface* surfData,
michael@0 1692 bool* result)
michael@0 1693 {
michael@0 1694 if (!IsAsyncDrawing()) {
michael@0 1695 *result = false;
michael@0 1696 return true;
michael@0 1697 }
michael@0 1698
michael@0 1699 switch (mDrawingModel) {
michael@0 1700 case NPDrawingModelAsyncBitmapSurface: {
michael@0 1701 Shmem sharedMem;
michael@0 1702 if (!AllocUnsafeShmem(size.width * size.height * 4, SharedMemory::TYPE_BASIC, &sharedMem)) {
michael@0 1703 *result = false;
michael@0 1704 return true;
michael@0 1705 }
michael@0 1706
michael@0 1707 surfData->size() = size;
michael@0 1708 surfData->hostPtr() = (uintptr_t)sharedMem.get<unsigned char>();
michael@0 1709 surfData->stride() = size.width * 4;
michael@0 1710 surfData->format() = format;
michael@0 1711 surfData->data() = sharedMem;
michael@0 1712 *result = true;
michael@0 1713 return true;
michael@0 1714 }
michael@0 1715 #ifdef XP_WIN
michael@0 1716 case NPDrawingModelAsyncWindowsDXGISurface: {
michael@0 1717 ID3D10Device1 *device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
michael@0 1718
michael@0 1719 nsRefPtr<ID3D10Texture2D> texture;
michael@0 1720
michael@0 1721 CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, size.width, size.height, 1, 1);
michael@0 1722 desc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX;
michael@0 1723 desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
michael@0 1724 if (FAILED(device->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture)))) {
michael@0 1725 *result = false;
michael@0 1726 return true;
michael@0 1727 }
michael@0 1728
michael@0 1729 nsRefPtr<IDXGIResource> resource;
michael@0 1730 if (FAILED(texture->QueryInterface(IID_IDXGIResource, getter_AddRefs(resource)))) {
michael@0 1731 *result = false;
michael@0 1732 return true;
michael@0 1733 }
michael@0 1734
michael@0 1735 HANDLE sharedHandle;
michael@0 1736
michael@0 1737 if (FAILED(resource->GetSharedHandle(&sharedHandle))) {
michael@0 1738 *result = false;
michael@0 1739 return true;
michael@0 1740 }
michael@0 1741
michael@0 1742 surfData->size() = size;
michael@0 1743 surfData->data() = sharedHandle;
michael@0 1744 surfData->format() = format;
michael@0 1745
michael@0 1746 mTextureMap.Put(sharedHandle, texture);
michael@0 1747 *result = true;
michael@0 1748 }
michael@0 1749 #endif
michael@0 1750 }
michael@0 1751
michael@0 1752 return true;
michael@0 1753 }
michael@0 1754
michael@0 1755 bool
michael@0 1756 PluginInstanceParent::RecvRedrawPlugin()
michael@0 1757 {
michael@0 1758 nsNPAPIPluginInstance *inst = static_cast<nsNPAPIPluginInstance*>(mNPP->ndata);
michael@0 1759 if (!inst) {
michael@0 1760 return false;
michael@0 1761 }
michael@0 1762
michael@0 1763 inst->RedrawPlugin();
michael@0 1764 return true;
michael@0 1765 }
michael@0 1766
michael@0 1767 bool
michael@0 1768 PluginInstanceParent::RecvNegotiatedCarbon()
michael@0 1769 {
michael@0 1770 nsNPAPIPluginInstance *inst = static_cast<nsNPAPIPluginInstance*>(mNPP->ndata);
michael@0 1771 if (!inst) {
michael@0 1772 return false;
michael@0 1773 }
michael@0 1774 inst->CarbonNPAPIFailure();
michael@0 1775 return true;
michael@0 1776 }
michael@0 1777
michael@0 1778 bool
michael@0 1779 PluginInstanceParent::RecvReleaseDXGISharedSurface(const DXGISharedSurfaceHandle &aHandle)
michael@0 1780 {
michael@0 1781 #ifdef XP_WIN
michael@0 1782 mTextureMap.Remove(aHandle);
michael@0 1783 #endif
michael@0 1784 return true;
michael@0 1785 }
michael@0 1786
michael@0 1787 #if defined(OS_WIN)
michael@0 1788
michael@0 1789 /*
michael@0 1790 plugin focus changes between processes
michael@0 1791
michael@0 1792 focus from dom -> child:
michael@0 1793 Focus manager calls on widget to set the focus on the window.
michael@0 1794 We pick up the resulting wm_setfocus event here, and forward
michael@0 1795 that over ipc to the child which calls set focus on itself.
michael@0 1796
michael@0 1797 focus from child -> focus manager:
michael@0 1798 Child picks up the local wm_setfocus and sends it via ipc over
michael@0 1799 here. We then post a custom event to widget/windows/nswindow
michael@0 1800 which fires off a gui event letting the browser know.
michael@0 1801 */
michael@0 1802
michael@0 1803 static const wchar_t kPluginInstanceParentProperty[] =
michael@0 1804 L"PluginInstanceParentProperty";
michael@0 1805
michael@0 1806 // static
michael@0 1807 LRESULT CALLBACK
michael@0 1808 PluginInstanceParent::PluginWindowHookProc(HWND hWnd,
michael@0 1809 UINT message,
michael@0 1810 WPARAM wParam,
michael@0 1811 LPARAM lParam)
michael@0 1812 {
michael@0 1813 PluginInstanceParent* self = reinterpret_cast<PluginInstanceParent*>(
michael@0 1814 ::GetPropW(hWnd, kPluginInstanceParentProperty));
michael@0 1815 if (!self) {
michael@0 1816 NS_NOTREACHED("PluginInstanceParent::PluginWindowHookProc null this ptr!");
michael@0 1817 return DefWindowProc(hWnd, message, wParam, lParam);
michael@0 1818 }
michael@0 1819
michael@0 1820 NS_ASSERTION(self->mPluginHWND == hWnd, "Wrong window!");
michael@0 1821
michael@0 1822 switch (message) {
michael@0 1823 case WM_SETFOCUS:
michael@0 1824 // Let the child plugin window know it should take focus.
michael@0 1825 unused << self->CallSetPluginFocus();
michael@0 1826 break;
michael@0 1827
michael@0 1828 case WM_CLOSE:
michael@0 1829 self->UnsubclassPluginWindow();
michael@0 1830 break;
michael@0 1831 }
michael@0 1832
michael@0 1833 if (self->mPluginWndProc == PluginWindowHookProc) {
michael@0 1834 NS_NOTREACHED(
michael@0 1835 "PluginWindowHookProc invoking mPluginWndProc w/"
michael@0 1836 "mPluginWndProc == PluginWindowHookProc????");
michael@0 1837 return DefWindowProc(hWnd, message, wParam, lParam);
michael@0 1838 }
michael@0 1839 return ::CallWindowProc(self->mPluginWndProc, hWnd, message, wParam,
michael@0 1840 lParam);
michael@0 1841 }
michael@0 1842
michael@0 1843 void
michael@0 1844 PluginInstanceParent::SubclassPluginWindow(HWND aWnd)
michael@0 1845 {
michael@0 1846 NS_ASSERTION(!(mPluginHWND && aWnd != mPluginHWND),
michael@0 1847 "PluginInstanceParent::SubclassPluginWindow hwnd is not our window!");
michael@0 1848
michael@0 1849 if (!mPluginHWND) {
michael@0 1850 mPluginHWND = aWnd;
michael@0 1851 mPluginWndProc =
michael@0 1852 (WNDPROC)::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
michael@0 1853 reinterpret_cast<LONG_PTR>(PluginWindowHookProc));
michael@0 1854 DebugOnly<bool> bRes = ::SetPropW(mPluginHWND, kPluginInstanceParentProperty, this);
michael@0 1855 NS_ASSERTION(mPluginWndProc,
michael@0 1856 "PluginInstanceParent::SubclassPluginWindow failed to set subclass!");
michael@0 1857 NS_ASSERTION(bRes,
michael@0 1858 "PluginInstanceParent::SubclassPluginWindow failed to set prop!");
michael@0 1859 }
michael@0 1860 }
michael@0 1861
michael@0 1862 void
michael@0 1863 PluginInstanceParent::UnsubclassPluginWindow()
michael@0 1864 {
michael@0 1865 if (mPluginHWND && mPluginWndProc) {
michael@0 1866 ::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
michael@0 1867 reinterpret_cast<LONG_PTR>(mPluginWndProc));
michael@0 1868
michael@0 1869 ::RemovePropW(mPluginHWND, kPluginInstanceParentProperty);
michael@0 1870
michael@0 1871 mPluginWndProc = nullptr;
michael@0 1872 mPluginHWND = nullptr;
michael@0 1873 }
michael@0 1874 }
michael@0 1875
michael@0 1876 /* windowless drawing helpers */
michael@0 1877
michael@0 1878 /*
michael@0 1879 * Origin info:
michael@0 1880 *
michael@0 1881 * windowless, offscreen:
michael@0 1882 *
michael@0 1883 * WM_WINDOWPOSCHANGED: origin is relative to container
michael@0 1884 * setwindow: origin is 0,0
michael@0 1885 * WM_PAINT: origin is 0,0
michael@0 1886 *
michael@0 1887 * windowless, native:
michael@0 1888 *
michael@0 1889 * WM_WINDOWPOSCHANGED: origin is relative to container
michael@0 1890 * setwindow: origin is relative to container
michael@0 1891 * WM_PAINT: origin is relative to container
michael@0 1892 *
michael@0 1893 * PluginInstanceParent:
michael@0 1894 *
michael@0 1895 * painting: mPluginPort (nsIntRect, saved in SetWindow)
michael@0 1896 */
michael@0 1897
michael@0 1898 void
michael@0 1899 PluginInstanceParent::SharedSurfaceRelease()
michael@0 1900 {
michael@0 1901 mSharedSurfaceDib.Close();
michael@0 1902 }
michael@0 1903
michael@0 1904 bool
michael@0 1905 PluginInstanceParent::SharedSurfaceSetWindow(const NPWindow* aWindow,
michael@0 1906 NPRemoteWindow& aRemoteWindow)
michael@0 1907 {
michael@0 1908 aRemoteWindow.window = 0;
michael@0 1909 aRemoteWindow.x = aWindow->x;
michael@0 1910 aRemoteWindow.y = aWindow->y;
michael@0 1911 aRemoteWindow.width = aWindow->width;
michael@0 1912 aRemoteWindow.height = aWindow->height;
michael@0 1913 aRemoteWindow.type = aWindow->type;
michael@0 1914
michael@0 1915 nsIntRect newPort(aWindow->x, aWindow->y, aWindow->width, aWindow->height);
michael@0 1916
michael@0 1917 // save the the rect location within the browser window.
michael@0 1918 mPluginPort = newPort;
michael@0 1919
michael@0 1920 // move the port to our shared surface origin
michael@0 1921 newPort.MoveTo(0,0);
michael@0 1922
michael@0 1923 // check to see if we have the room in shared surface
michael@0 1924 if (mSharedSurfaceDib.IsValid() && mSharedSize.Contains(newPort)) {
michael@0 1925 // ok to paint
michael@0 1926 aRemoteWindow.surfaceHandle = 0;
michael@0 1927 return true;
michael@0 1928 }
michael@0 1929
michael@0 1930 // allocate a new shared surface
michael@0 1931 SharedSurfaceRelease();
michael@0 1932 if (NS_FAILED(mSharedSurfaceDib.Create(reinterpret_cast<HDC>(aWindow->window),
michael@0 1933 newPort.width, newPort.height, false)))
michael@0 1934 return false;
michael@0 1935
michael@0 1936 // save the new shared surface size we just allocated
michael@0 1937 mSharedSize = newPort;
michael@0 1938
michael@0 1939 base::SharedMemoryHandle handle;
michael@0 1940 if (NS_FAILED(mSharedSurfaceDib.ShareToProcess(mParent->ChildProcessHandle(), &handle)))
michael@0 1941 return false;
michael@0 1942
michael@0 1943 aRemoteWindow.surfaceHandle = handle;
michael@0 1944
michael@0 1945 return true;
michael@0 1946 }
michael@0 1947
michael@0 1948 void
michael@0 1949 PluginInstanceParent::SharedSurfaceBeforePaint(RECT& rect,
michael@0 1950 NPRemoteEvent& npremoteevent)
michael@0 1951 {
michael@0 1952 RECT* dr = (RECT*)npremoteevent.event.lParam;
michael@0 1953 HDC parentHdc = (HDC)npremoteevent.event.wParam;
michael@0 1954
michael@0 1955 nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
michael@0 1956 dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y); // should always be smaller than dirtyRect
michael@0 1957
michael@0 1958 ::BitBlt(mSharedSurfaceDib.GetHDC(),
michael@0 1959 dirtyRect.x,
michael@0 1960 dirtyRect.y,
michael@0 1961 dirtyRect.width,
michael@0 1962 dirtyRect.height,
michael@0 1963 parentHdc,
michael@0 1964 dr->left,
michael@0 1965 dr->top,
michael@0 1966 SRCCOPY);
michael@0 1967
michael@0 1968 // setup the translated dirty rect we'll send to the child
michael@0 1969 rect.left = dirtyRect.x;
michael@0 1970 rect.top = dirtyRect.y;
michael@0 1971 rect.right = dirtyRect.x + dirtyRect.width;
michael@0 1972 rect.bottom = dirtyRect.y + dirtyRect.height;
michael@0 1973
michael@0 1974 npremoteevent.event.wParam = WPARAM(0);
michael@0 1975 npremoteevent.event.lParam = LPARAM(&rect);
michael@0 1976 }
michael@0 1977
michael@0 1978 void
michael@0 1979 PluginInstanceParent::SharedSurfaceAfterPaint(NPEvent* npevent)
michael@0 1980 {
michael@0 1981 RECT* dr = (RECT*)npevent->lParam;
michael@0 1982 HDC parentHdc = (HDC)npevent->wParam;
michael@0 1983
michael@0 1984 nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
michael@0 1985 dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y);
michael@0 1986
michael@0 1987 // src copy the shared dib into the parent surface we are handed.
michael@0 1988 ::BitBlt(parentHdc,
michael@0 1989 dr->left,
michael@0 1990 dr->top,
michael@0 1991 dirtyRect.width,
michael@0 1992 dirtyRect.height,
michael@0 1993 mSharedSurfaceDib.GetHDC(),
michael@0 1994 dirtyRect.x,
michael@0 1995 dirtyRect.y,
michael@0 1996 SRCCOPY);
michael@0 1997 }
michael@0 1998
michael@0 1999 #endif // defined(OS_WIN)
michael@0 2000
michael@0 2001 bool
michael@0 2002 PluginInstanceParent::AnswerPluginFocusChange(const bool& gotFocus)
michael@0 2003 {
michael@0 2004 PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
michael@0 2005
michael@0 2006 // Currently only in use on windows - an rpc event we receive from the
michael@0 2007 // child when it's plugin window (or one of it's children) receives keyboard
michael@0 2008 // focus. We forward the event down to widget so the dom/focus manager can
michael@0 2009 // be updated.
michael@0 2010 #if defined(OS_WIN)
michael@0 2011 ::SendMessage(mPluginHWND, gOOPPPluginFocusEvent, gotFocus ? 1 : 0, 0);
michael@0 2012 return true;
michael@0 2013 #else
michael@0 2014 NS_NOTREACHED("PluginInstanceParent::AnswerPluginFocusChange not implemented!");
michael@0 2015 return false;
michael@0 2016 #endif
michael@0 2017 }

mercurial