PluginIdentifierParent::StackIdentifier::StackIdentifier (NPObject* aObject, NPIdentifier aIdentifier) : mIdentifier(NULL) { PluginInstanceParent* inst = GetInstance(aObject); mIdentifier = inst->Module()->GetIdentifierForNPIdentifier(inst->GetNPP(), aIdentifier); }
nsresult PluginModuleParent::GetImageContainer(NPP instance, mozilla::layers::ImageContainer** aContainer) { PluginInstanceParent* i = InstCast(instance); return !i ? NS_ERROR_FAILURE : i->GetImageContainer(aContainer); }
void PluginModuleParent::NPP_Print(NPP instance, NPPrint* platformPrint) { PluginInstanceParent* i = InstCast(instance); if (i) i->NPP_Print(platformPrint); }
bool PluginScriptableObjectParent::AnswerRemoveProperty(PPluginIdentifierParent* aId, bool* aSuccess) { if (!mObject) { NS_WARNING("Calling AnswerRemoveProperty with an invalidated object!"); *aSuccess = false; return true; } NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); NS_ASSERTION(mType == LocalObject, "Bad type!"); PluginInstanceParent* instance = GetInstance(); if (!instance) { NS_ERROR("No instance?!"); *aSuccess = false; return true; } const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); *aSuccess = false; return true; } PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId); *aSuccess = npn->removeproperty(instance->GetNPP(), mObject, id->ToNPIdentifier()); return true; }
nsresult PluginModuleParent::GetImageSize(NPP instance, nsIntSize* aSize) { PluginInstanceParent* i = InstCast(instance); return !i ? NS_ERROR_FAILURE : i->GetImageSize(aSize); }
nsresult PluginModuleParent::AsyncSetWindow(NPP instance, NPWindow* window) { PluginInstanceParent* i = InstCast(instance); if (!i) return NS_ERROR_FAILURE; return i->AsyncSetWindow(window); }
NPError PluginModuleParent::NPP_SetWindow(NPP instance, NPWindow* window) { PluginInstanceParent* i = InstCast(instance); if (!i) return NPERR_GENERIC_ERROR; return i->NPP_SetWindow(window); }
nsresult PluginModuleParent::SetBackgroundUnknown(NPP instance) { PluginInstanceParent* i = InstCast(instance); if (!i) return NS_ERROR_FAILURE; return i->SetBackgroundUnknown(); }
int16_t PluginModuleParent::NPP_HandleEvent(NPP instance, void* event) { PluginInstanceParent* i = InstCast(instance); if (!i) return false; return i->NPP_HandleEvent(event); }
nsresult PluginModuleParent::IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing) { PluginInstanceParent* i = InstCast(instance); if (!i) return NS_ERROR_FAILURE; return i->IsRemoteDrawingCoreAnimation(aDrawing); }
bool PluginScriptableObjectParent::AnswerEnumerate(InfallibleTArray<PPluginIdentifierParent*>* aProperties, bool* aSuccess) { if (!mObject) { NS_WARNING("Calling AnswerEnumerate with an invalidated object!"); *aSuccess = false; return true; } NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); NS_ASSERTION(mType == LocalObject, "Bad type!"); PluginInstanceParent* instance = GetInstance(); if (!instance) { NS_ERROR("No instance?!"); *aSuccess = false; return true; } const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_WARNING("No netscape funcs?!"); *aSuccess = false; return true; } NPIdentifier* ids; uint32_t idCount; if (!npn->enumerate(instance->GetNPP(), mObject, &ids, &idCount)) { *aSuccess = false; return true; } aProperties->SetCapacity(idCount); mozilla::AutoSafeJSContext cx; for (uint32_t index = 0; index < idCount; index++) { // Because of GC hazards, all identifiers returned from enumerate // must be made permanent. if (_identifierisstring(ids[index])) { JSString* str = NPIdentifierToString(ids[index]); if (!JS_StringHasBeenInterned(cx, str)) { DebugOnly<JSString*> str2 = JS_InternJSString(cx, str); NS_ASSERTION(str2 == str, "Interning a JS string which is currently an ID should return itself."); } } PluginIdentifierParent* id = instance->Module()->GetIdentifierForNPIdentifier(instance->GetNPP(), ids[index]); aProperties->AppendElement(id); NS_ASSERTION(!id->IsTemporary(), "Should only have permanent identifiers!"); } npn->memfree(ids); *aSuccess = true; return true; }
void PluginModuleParent::NPP_URLRedirectNotify(NPP instance, const char* url, int32_t status, void* notifyData) { PluginInstanceParent* i = InstCast(instance); if (!i) return; i->NPP_URLRedirectNotify(url, status, notifyData); }
NPError PluginModuleParent::NPP_SetValue(NPP instance, NPNVariable variable, void *value) { PluginInstanceParent* i = InstCast(instance); if (!i) return NPERR_GENERIC_ERROR; return i->NPP_SetValue(variable, value); }
void PluginModuleParent::NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) { PluginInstanceParent* i = InstCast(instance); if (!i) return; i->NPP_URLNotify(url, reason, notifyData); }
nsresult PluginModuleParent::NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved, NPError* error) { PLUGIN_LOG_DEBUG_METHOD; if (mShutdown) { *error = NPERR_GENERIC_ERROR; return NS_ERROR_FAILURE; } // create the instance on the other side InfallibleTArray<nsCString> names; InfallibleTArray<nsCString> values; for (int i = 0; i < argc; ++i) { names.AppendElement(NullableString(argn[i])); values.AppendElement(NullableString(argv[i])); } PluginInstanceParent* parentInstance = new PluginInstanceParent(this, instance, nsDependentCString(pluginType), mNPNIface); if (!parentInstance->Init()) { delete parentInstance; return NS_ERROR_FAILURE; } instance->pdata = parentInstance; if (!CallPPluginInstanceConstructor(parentInstance, nsDependentCString(pluginType), mode, names, values, error)) { // |parentInstance| is automatically deleted. instance->pdata = nsnull; // if IPC is down, we'll get an immediate "failed" return, but // without *error being set. So make sure that the error // condition is signaled to nsNPAPIPluginInstance if (NPERR_NO_ERROR == *error) *error = NPERR_GENERIC_ERROR; return NS_ERROR_FAILURE; } if (*error != NPERR_NO_ERROR) { NPP_Destroy(instance, 0); return NS_ERROR_FAILURE; } TimeoutChanged(kParentTimeoutPref, this); return NS_OK; }
NPError PluginModuleParent::NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason) { PluginInstanceParent* i = InstCast(instance); if (!i) return NPERR_GENERIC_ERROR; return i->NPP_DestroyStream(stream, reason); }
nsresult PluginModuleParent::EndUpdateBackground(NPP instance, gfxContext* aCtx, const nsIntRect& aRect) { PluginInstanceParent* i = InstCast(instance); if (!i) return NS_ERROR_FAILURE; return i->EndUpdateBackground(aCtx, aRect); }
nsresult PluginModuleParent::BeginUpdateBackground(NPP instance, const nsIntRect& aRect, gfxContext** aCtx) { PluginInstanceParent* i = InstCast(instance); if (!i) return NS_ERROR_FAILURE; return i->BeginUpdateBackground(aRect, aCtx); }
nsresult PluginModuleParent::HandleGUIEvent(NPP instance, const nsGUIEvent& anEvent, bool* handled) { PluginInstanceParent* i = InstCast(instance); if (!i) return NS_ERROR_FAILURE; return i->HandleGUIEvent(anEvent, handled); }
NPError PluginModuleParent::NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype) { PluginInstanceParent* i = InstCast(instance); if (!i) return NPERR_GENERIC_ERROR; return i->NPP_NewStream(type, stream, seekable, stype); }
bool PluginScriptableObjectParent::AnswerGetParentProperty( PPluginIdentifierParent* aId, Variant* aResult, bool* aSuccess) { if (!mObject) { NS_WARNING("Calling AnswerGetProperty with an invalidated object!"); *aResult = void_t(); *aSuccess = false; return true; } NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); NS_ASSERTION(mType == LocalObject, "Bad type!"); PluginInstanceParent* instance = GetInstance(); if (!instance) { NS_ERROR("No instance?!"); *aResult = void_t(); *aSuccess = false; return true; } const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); *aResult = void_t(); *aSuccess = false; return true; } PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId); NPVariant result; if (!npn->getproperty(instance->GetNPP(), mObject, id->ToNPIdentifier(), &result)) { *aResult = void_t(); *aSuccess = false; return true; } Variant converted; if ((*aSuccess = ConvertToRemoteVariant(result, converted, instance))) { DeferNPVariantLastRelease(npn, &result); *aResult = converted; } else { *aResult = void_t(); } return true; }
bool PluginScriptableObjectParent::AnswerEnumerate(nsTArray<PPluginIdentifierParent*>* aProperties, bool* aSuccess) { if (!mObject) { NS_WARNING("Calling AnswerEnumerate with an invalidated object!"); *aSuccess = false; return true; } NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); NS_ASSERTION(mType == LocalObject, "Bad type!"); PluginInstanceParent* instance = GetInstance(); if (!instance) { NS_ERROR("No instance?!"); *aSuccess = false; return true; } const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_WARNING("No netscape funcs?!"); *aSuccess = false; return true; } NPIdentifier* ids; uint32_t idCount; if (!npn->enumerate(instance->GetNPP(), mObject, &ids, &idCount)) { *aSuccess = false; return true; } if (!aProperties->SetCapacity(idCount)) { npn->memfree(ids); *aSuccess = false; return true; } for (uint32_t index = 0; index < idCount; index++) { aProperties->AppendElement(GetIdentifier(instance, ids[index])); } npn->memfree(ids); *aSuccess = true; return true; }
bool PluginScriptableObjectParent::AnswerNPN_Evaluate(const nsCString& aScript, Variant* aResult, bool* aSuccess) { PluginInstanceParent* instance = GetInstance(); if (!instance) { NS_ERROR("No instance?!"); *aResult = void_t(); *aSuccess = false; return true; } const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); *aResult = void_t(); *aSuccess = false; return true; } NPString script = { aScript.get(), aScript.Length() }; NPVariant result; bool success = npn->evaluate(instance->GetNPP(), mObject, &script, &result); if (!success) { *aResult = void_t(); *aSuccess = false; return true; } Variant convertedResult; success = ConvertToRemoteVariant(result, convertedResult, instance); DeferNPVariantLastRelease(npn, &result); if (!success) { *aResult = void_t(); *aSuccess = false; return true; } *aSuccess = true; *aResult = convertedResult; return true; }
void PluginScriptableObjectParent::DropNPObject() { NS_ASSERTION(mObject, "Invalidated object!"); NS_ASSERTION(mObject->_class == GetClass(), "Wrong type of object!"); NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!"); // We think we're about to be deleted, but we could be racing with the other // process. PluginInstanceParent* instance = GetInstance(); NS_ASSERTION(instance, "Must have an instance!"); instance->UnregisterNPObject(mObject); mObject = nullptr; unused << SendUnprotect(); }
bool PluginWidgetChild::RecvSetScrollCaptureId(const uint64_t& aScrollCaptureId, const uintptr_t& aPluginInstanceId) { #if defined(XP_WIN) PluginInstanceParent* instance = PluginInstanceParent::LookupPluginInstanceByID(aPluginInstanceId); if (instance) { NS_WARN_IF(NS_FAILED(instance->SetScrollCaptureId(aScrollCaptureId))); } return true; #else MOZ_ASSERT_UNREACHABLE( "PluginWidgetChild::RecvSetScrollCaptureId calls not expected."); return false; #endif }
NPError PluginAsyncSurrogate::NPP_GetValue(NPPVariable aVariable, void* aRetval) { if (aVariable != NPPVpluginScriptableNPObject) { if (!WaitForInit()) { return NPERR_GENERIC_ERROR; } PluginInstanceParent* instance = PluginInstanceParent::Cast(mInstance); MOZ_ASSERT(instance); return instance->NPP_GetValue(aVariable, aRetval); } NPObject* npobject = parent::_createobject(mInstance, const_cast<NPClass*>(GetClass())); MOZ_ASSERT(npobject); MOZ_ASSERT(npobject->_class == GetClass()); MOZ_ASSERT(npobject->referenceCount == 1); *(NPObject**)aRetval = npobject; return npobject ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR; }
bool PluginScriptableObjectParent::AnswerSetProperty(PPluginIdentifierParent* aId, const Variant& aValue, bool* aSuccess) { if (!mObject) { NS_WARNING("Calling AnswerSetProperty with an invalidated object!"); *aSuccess = false; return true; } NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); NS_ASSERTION(mType == LocalObject, "Bad type!"); PluginInstanceParent* instance = GetInstance(); if (!instance) { NS_ERROR("No instance?!"); *aSuccess = false; return true; } const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); *aSuccess = false; return true; } NPVariant converted; if (!ConvertToVariant(aValue, converted, instance)) { *aSuccess = false; return true; } PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId); if ((*aSuccess = npn->setproperty(instance->GetNPP(), mObject, id->ToNPIdentifier(), &converted))) { ReleaseVariant(converted, instance); } return true; }
NPError PluginModuleParent::NPP_Destroy(NPP instance, NPSavedData** /*saved*/) { // FIXME/cjones: // (1) send a "destroy" message to the child // (2) the child shuts down its instance // (3) remove both parent and child IDs from map // (4) free parent PLUGIN_LOG_DEBUG_FUNCTION; PluginInstanceParent* parentInstance = static_cast<PluginInstanceParent*>(instance->pdata); if (!parentInstance) return NPERR_NO_ERROR; NPError retval = parentInstance->Destroy(); instance->pdata = nsnull; unused << PluginInstanceParent::Call__delete__(parentInstance); return retval; }
bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel) { // We never have reentrant paint events, except when we're running our RPC // windows event spin loop. If we don't trap for this, we'll try to paint, // but view manager will refuse to paint the surface, resulting is black // flashes on the plugin rendering surface. if (mozilla::ipc::RPCChannel::IsSpinLoopActive() && mPainting) return false; if (mWindowType == eWindowType_plugin) { /** * After we CallUpdateWindow to the child, occasionally a WM_PAINT message * is posted to the parent event loop with an empty update rect. Do a * dummy paint so that Windows stops dispatching WM_PAINT in an inifinite * loop. See bug 543788. */ RECT updateRect; if (!GetUpdateRect(mWnd, &updateRect, FALSE) || (updateRect.left == updateRect.right && updateRect.top == updateRect.bottom)) { PAINTSTRUCT ps; BeginPaint(mWnd, &ps); EndPaint(mWnd, &ps); return true; } PluginInstanceParent* instance = reinterpret_cast<PluginInstanceParent*>( ::GetPropW(mWnd, L"PluginInstanceParentProperty")); if (instance) { unused << instance->CallUpdateWindow(); } else { // We should never get here since in-process plugins should have // subclassed our HWND and handled WM_PAINT, but in some cases that // could fail. Return without asserting since it's not our fault. NS_WARNING("Plugin failed to subclass our window"); } ValidateRect(mWnd, NULL); return true; } // Do an early async composite so that we at least have something on screen // in the right place, even if the content is out of date. if (GetLayerManager()->GetBackendType() == LAYERS_CLIENT && mCompositorParent) { mCompositorParent->ScheduleRenderOnCompositorThread(); } nsIWidgetListener* listener = GetPaintListener(); if (listener) { listener->WillPaintWindow(this); } // Re-get the listener since the will paint notification may have killed it. listener = GetPaintListener(); if (!listener) return false; bool result = true; PAINTSTRUCT ps; #ifdef MOZ_XUL if (!aDC && (eTransparencyTransparent == mTransparencyMode)) { // For layered translucent windows all drawing should go to memory DC and no // WM_PAINT messages are normally generated. To support asynchronous painting // we force generation of WM_PAINT messages by invalidating window areas with // RedrawWindow, InvalidateRect or InvalidateRgn function calls. // BeginPaint/EndPaint must be called to make Windows think that invalid area // is painted. Otherwise it will continue sending the same message endlessly. ::BeginPaint(mWnd, &ps); ::EndPaint(mWnd, &ps); aDC = mMemoryDC; } #endif mPainting = true; #ifdef WIDGET_DEBUG_OUTPUT HRGN debugPaintFlashRegion = NULL; HDC debugPaintFlashDC = NULL; if (debug_WantPaintFlashing()) { debugPaintFlashRegion = ::CreateRectRgn(0, 0, 0, 0); ::GetUpdateRgn(mWnd, debugPaintFlashRegion, TRUE); debugPaintFlashDC = ::GetDC(mWnd); } #endif // WIDGET_DEBUG_OUTPUT HDC hDC = aDC ? aDC : (::BeginPaint(mWnd, &ps)); if (!IsRenderMode(gfxWindowsPlatform::RENDER_DIRECT2D)) { mPaintDC = hDC; } #ifdef MOZ_XUL bool forceRepaint = aDC || (eTransparencyTransparent == mTransparencyMode); #else bool forceRepaint = NULL != aDC; #endif nsIntRegion region = GetRegionToPaint(forceRepaint, ps, hDC); if (!region.IsEmpty() && listener) { // Should probably pass in a real region here, using GetRandomRgn // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/clipping_4q0e.asp #ifdef WIDGET_DEBUG_OUTPUT debug_DumpPaintEvent(stdout, this, region, nsAutoCString("noname"), (int32_t) mWnd); #endif // WIDGET_DEBUG_OUTPUT switch (GetLayerManager()->GetBackendType()) { case LAYERS_BASIC: { nsRefPtr<gfxASurface> targetSurface; #if defined(MOZ_XUL) // don't support transparency for non-GDI rendering, for now if ((IsRenderMode(gfxWindowsPlatform::RENDER_GDI) || IsRenderMode(gfxWindowsPlatform::RENDER_DIRECT2D)) && eTransparencyTransparent == mTransparencyMode) { if (mTransparentSurface == nullptr) SetupTranslucentWindowMemoryBitmap(mTransparencyMode); targetSurface = mTransparentSurface; } #endif #ifdef CAIRO_HAS_D2D_SURFACE if (!targetSurface && IsRenderMode(gfxWindowsPlatform::RENDER_DIRECT2D)) { if (!mD2DWindowSurface) { gfxASurface::gfxContentType content = gfxASurface::CONTENT_COLOR; #if defined(MOZ_XUL) if (mTransparencyMode != eTransparencyOpaque) { content = gfxASurface::CONTENT_COLOR_ALPHA; } #endif mD2DWindowSurface = new gfxD2DSurface(mWnd, content); } if (!mD2DWindowSurface->CairoStatus()) { targetSurface = mD2DWindowSurface; } else { mD2DWindowSurface = nullptr; } } #endif nsRefPtr<gfxWindowsSurface> targetSurfaceWin; if (!targetSurface && (IsRenderMode(gfxWindowsPlatform::RENDER_GDI) || IsRenderMode(gfxWindowsPlatform::RENDER_DIRECT2D))) { uint32_t flags = (mTransparencyMode == eTransparencyOpaque) ? 0 : gfxWindowsSurface::FLAG_IS_TRANSPARENT; targetSurfaceWin = new gfxWindowsSurface(hDC, flags); targetSurface = targetSurfaceWin; } nsRefPtr<gfxImageSurface> targetSurfaceImage; if (!targetSurface && (IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH32) || IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH24))) { gfxIntSize surfaceSize(ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top); if (!EnsureSharedSurfaceSize(surfaceSize)) { NS_ERROR("Couldn't allocate a shared image surface!"); return false; } // don't use the shared surface directly; instead, create a new one // that just reuses its buffer. targetSurfaceImage = new gfxImageSurface(sSharedSurfaceData.get(), surfaceSize, surfaceSize.width * 4, gfxASurface::ImageFormatRGB24); if (targetSurfaceImage && !targetSurfaceImage->CairoStatus()) { targetSurfaceImage->SetDeviceOffset(gfxPoint(-ps.rcPaint.left, -ps.rcPaint.top)); targetSurface = targetSurfaceImage; } } if (!targetSurface) { NS_ERROR("Invalid RenderMode!"); return false; } nsRefPtr<gfxContext> thebesContext; if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(mozilla::gfx::BACKEND_CAIRO)) { RECT paintRect; ::GetClientRect(mWnd, &paintRect); RefPtr<mozilla::gfx::DrawTarget> dt = gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(targetSurface, mozilla::gfx::IntSize(paintRect.right - paintRect.left, paintRect.bottom - paintRect.top)); thebesContext = new gfxContext(dt); } else { thebesContext = new gfxContext(targetSurface); } if (IsRenderMode(gfxWindowsPlatform::RENDER_DIRECT2D)) { const nsIntRect* r; for (nsIntRegionRectIterator iter(region); (r = iter.Next()) != nullptr;) { thebesContext->Rectangle(gfxRect(r->x, r->y, r->width, r->height), true); } thebesContext->Clip(); thebesContext->SetOperator(gfxContext::OPERATOR_CLEAR); thebesContext->Paint(); thebesContext->SetOperator(gfxContext::OPERATOR_OVER); } // don't need to double buffer with anything but GDI BufferMode doubleBuffering = mozilla::layers::BUFFER_NONE; if (IsRenderMode(gfxWindowsPlatform::RENDER_GDI)) { #ifdef MOZ_XUL switch (mTransparencyMode) { case eTransparencyGlass: case eTransparencyBorderlessGlass: default: // If we're not doing translucency, then double buffer doubleBuffering = mozilla::layers::BUFFER_BUFFERED; break; case eTransparencyTransparent: // If we're rendering with translucency, we're going to be // rendering the whole window; make sure we clear it first thebesContext->SetOperator(gfxContext::OPERATOR_CLEAR); thebesContext->Paint(); thebesContext->SetOperator(gfxContext::OPERATOR_OVER); break; } #else doubleBuffering = mozilla::layers::BUFFER_BUFFERED; #endif } { AutoLayerManagerSetup setupLayerManager(this, thebesContext, doubleBuffering); result = listener->PaintWindow(this, region); } #ifdef MOZ_XUL if ((IsRenderMode(gfxWindowsPlatform::RENDER_GDI) || IsRenderMode(gfxWindowsPlatform::RENDER_DIRECT2D))&& eTransparencyTransparent == mTransparencyMode) { // Data from offscreen drawing surface was copied to memory bitmap of transparent // bitmap. Now it can be read from memory bitmap to apply alpha channel and after // that displayed on the screen. UpdateTranslucentWindow(); } else #endif #ifdef CAIRO_HAS_D2D_SURFACE if (result) { if (mD2DWindowSurface) { mD2DWindowSurface->Present(); } } #endif if (result) { if (IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH24) || IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH32)) { gfxIntSize surfaceSize = targetSurfaceImage->GetSize(); // Just blit this directly BITMAPINFOHEADER bi; memset(&bi, 0, sizeof(BITMAPINFOHEADER)); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = surfaceSize.width; bi.biHeight = - surfaceSize.height; bi.biPlanes = 1; bi.biBitCount = 32; bi.biCompression = BI_RGB; if (IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH24)) { // On Windows CE/Windows Mobile, 24bpp packed-pixel sources // seem to be far faster to blit than 32bpp (see bug 484864). // So, convert the bits to 24bpp by stripping out the unused // alpha byte. 24bpp DIBs also have scanlines that are 4-byte // aligned though, so that must be taken into account. int srcstride = surfaceSize.width*4; int dststride = surfaceSize.width*3; dststride = (dststride + 3) & ~3; // Convert in place for (int j = 0; j < surfaceSize.height; ++j) { unsigned int *src = (unsigned int*) (targetSurfaceImage->Data() + j*srcstride); unsigned int *dst = (unsigned int*) (targetSurfaceImage->Data() + j*dststride); // go 4 pixels at a time, since each 4 pixels // turns into 3 DWORDs when converted into BGR: // BGRx BGRx BGRx BGRx -> BGRB GRBG RBGR // // However, since we're dealing with little-endian ints, this is actually: // xRGB xrgb xRGB xrgb -> bRGB GBrg rgbR int width_left = surfaceSize.width; while (width_left >= 4) { unsigned int a = *src++; unsigned int b = *src++; unsigned int c = *src++; unsigned int d = *src++; *dst++ = (a & 0x00ffffff) | (b << 24); *dst++ = ((b & 0x00ffff00) >> 8) | (c << 16); *dst++ = ((c & 0x00ff0000) >> 16) | (d << 8); width_left -= 4; } // then finish up whatever number of pixels are left, // using bytes. unsigned char *bsrc = (unsigned char*) src; unsigned char *bdst = (unsigned char*) dst; switch (width_left) { case 3: *bdst++ = *bsrc++; *bdst++ = *bsrc++; *bdst++ = *bsrc++; bsrc++; case 2: *bdst++ = *bsrc++; *bdst++ = *bsrc++; *bdst++ = *bsrc++; bsrc++; case 1: *bdst++ = *bsrc++; *bdst++ = *bsrc++; *bdst++ = *bsrc++; bsrc++; case 0: break; } } bi.biBitCount = 24; } StretchDIBits(hDC, ps.rcPaint.left, ps.rcPaint.top, surfaceSize.width, surfaceSize.height, 0, 0, surfaceSize.width, surfaceSize.height, targetSurfaceImage->Data(), (BITMAPINFO*) &bi, DIB_RGB_COLORS, SRCCOPY); } } } break; case LAYERS_OPENGL: static_cast<mozilla::layers::LayerManagerOGL*>(GetLayerManager())-> SetClippingRegion(region); result = listener->PaintWindow(this, region); break; #ifdef MOZ_ENABLE_D3D9_LAYER case LAYERS_D3D9: { nsRefPtr<LayerManagerD3D9> layerManagerD3D9 = static_cast<mozilla::layers::LayerManagerD3D9*>(GetLayerManager()); layerManagerD3D9->SetClippingRegion(region); result = listener->PaintWindow(this, region); if (layerManagerD3D9->DeviceWasRemoved()) { mLayerManager->Destroy(); mLayerManager = nullptr; // When our device was removed, we should have gfxWindowsPlatform // check if its render mode is up to date! gfxWindowsPlatform::GetPlatform()->UpdateRenderMode(); Invalidate(); } } break; #endif #ifdef MOZ_ENABLE_D3D10_LAYER case LAYERS_D3D10: { gfxWindowsPlatform::GetPlatform()->UpdateRenderMode(); LayerManagerD3D10 *layerManagerD3D10 = static_cast<mozilla::layers::LayerManagerD3D10*>(GetLayerManager()); if (layerManagerD3D10->device() != gfxWindowsPlatform::GetPlatform()->GetD3D10Device()) { Invalidate(); } else { result = listener->PaintWindow(this, region); } } break; #endif case LAYERS_CLIENT: result = listener->PaintWindow(this, region); break; default: NS_ERROR("Unknown layers backend used!"); break; }
bool PluginScriptableObjectParent::AnswerInvokeDefault(const InfallibleTArray<Variant>& aArgs, Variant* aResult, bool* aSuccess) { if (!mObject) { NS_WARNING("Calling AnswerInvoke with an invalidated object!"); *aResult = void_t(); *aSuccess = false; return true; } NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); NS_ASSERTION(mType == LocalObject, "Bad type!"); PluginInstanceParent* instance = GetInstance(); if (!instance) { NS_ERROR("No instance?!"); *aResult = void_t(); *aSuccess = false; return true; } const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); *aResult = void_t(); *aSuccess = false; return true; } nsAutoTArray<NPVariant, 10> convertedArgs; uint32_t argCount = aArgs.Length(); if (!convertedArgs.SetLength(argCount)) { *aResult = void_t(); *aSuccess = false; return true; } for (uint32_t index = 0; index < argCount; index++) { if (!ConvertToVariant(aArgs[index], convertedArgs[index], instance)) { // Don't leak things we've already converted! while (index-- > 0) { ReleaseVariant(convertedArgs[index], instance); } *aResult = void_t(); *aSuccess = false; return true; } } NPVariant result; bool success = npn->invokeDefault(instance->GetNPP(), mObject, convertedArgs.Elements(), argCount, &result); for (uint32_t index = 0; index < argCount; index++) { ReleaseVariant(convertedArgs[index], instance); } if (!success) { *aResult = void_t(); *aSuccess = false; return true; } Variant convertedResult; success = ConvertToRemoteVariant(result, convertedResult, GetInstance()); DeferNPVariantLastRelease(npn, &result); if (!success) { *aResult = void_t(); *aSuccess = false; return true; } *aResult = convertedResult; *aSuccess = true; return true; }