diff --git a/content/base/public/nsIObjectLoadingContent.idl b/content/base/public/nsIObjectLoadingContent.idl index 3305780c345..0e1ef863ee3 100644 --- a/content/base/public/nsIObjectLoadingContent.idl +++ b/content/base/public/nsIObjectLoadingContent.idl @@ -39,11 +39,13 @@ interface nsIObjectFrame; interface nsIPluginInstance; +interface nsIDOMElement; +interface nsIDOMClientRect; /** * This interface represents a content node that loads objects. */ -[scriptable, uuid(90ab443e-3e99-405e-88c9-9c42adaa3217)] +[scriptable, uuid(8afe3b08-293c-48bd-a997-321745478611)] interface nsIObjectLoadingContent : nsISupports { const unsigned long TYPE_LOADING = 0; @@ -105,4 +107,12 @@ interface nsIObjectLoadingContent : nsISupports * because nsIObjectFrame is unscriptable. */ [noscript] void hasNewFrame(in nsIObjectFrame aFrame); + + /** + * Tells the object to paint directly in this location ignoring any + * positioning information that may have been provided otherwise + */ + void setAbsoluteScreenPosition(in nsIDOMElement element, + in nsIDOMClientRect position, + in nsIDOMClientRect clip); }; diff --git a/content/base/src/nsObjectLoadingContent.cpp b/content/base/src/nsObjectLoadingContent.cpp index 5b00c983c25..8ab742ace6c 100644 --- a/content/base/src/nsObjectLoadingContent.cpp +++ b/content/base/src/nsObjectLoadingContent.cpp @@ -890,7 +890,6 @@ nsObjectLoadingContent::GetInterface(const nsIID & aIID, void **aResult) NS_ADDREF(sink); return NS_OK; } - return NS_NOINTERFACE; } @@ -1872,3 +1871,17 @@ nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType) return ePluginBlocklisted; return ePluginUnsupported; } + +NS_IMETHODIMP +nsObjectLoadingContent::SetAbsoluteScreenPosition(nsIDOMElement* element, + nsIDOMClientRect* position, + nsIDOMClientRect* clip) +{ + nsIObjectFrame* frame = GetExistingFrame(eFlushLayout); + if (!frame) + return NS_ERROR_NOT_AVAILABLE; + + return frame->SetAbsoluteScreenPosition(element, position, clip); +} + + diff --git a/layout/generic/nsIObjectFrame.h b/layout/generic/nsIObjectFrame.h index 7a1e30c6528..107bd730836 100644 --- a/layout/generic/nsIObjectFrame.h +++ b/layout/generic/nsIObjectFrame.h @@ -94,6 +94,14 @@ public: * Get the native widget for the plugin, if any. */ virtual nsIWidget* GetWidget() = 0; + + /** + * Tells the object to paint directly in this location ignoring any + * positioning information that may have been provided otherwise. + */ + virtual nsresult SetAbsoluteScreenPosition(class nsIDOMElement* element, + nsIDOMClientRect* position, + nsIDOMClientRect* clip) = 0; }; #endif /* nsIObjectFrame_h___ */ diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index e255ceb7877..8e8368f0934 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -108,6 +108,7 @@ #include "nsIImageLoadingContent.h" #include "nsIObjectLoadingContent.h" #include "nsPIDOMWindow.h" +#include "nsIDOMElement.h" #include "nsContentUtils.h" #include "nsDisplayList.h" #include "nsAttrName.h" @@ -124,6 +125,7 @@ #include "nsIXPConnect.h" #include "nsIXPCScriptable.h" #include "nsIClassInfo.h" +#include "nsIDOMClientRect.h" #include "nsObjectFrame.h" #include "nsIObjectFrame.h" @@ -172,6 +174,16 @@ enum { XKeyPress = KeyPress }; #if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2) #define MOZ_COMPOSITED_PLUGINS 1 + +#include "gfxXlibSurface.h" + +#include +#include +#include +#include +#include + + #endif #ifdef MOZ_WIDGET_GTK2 @@ -331,11 +343,6 @@ public: void SetPluginHost(nsIPluginHost* aHost); -#ifdef MOZ_PLATFORM_HILDON - /* the flash plugin(s) need to have thier visiblity poked */ - PRBool UpdateVisibility(PRBool aForce = PR_FALSE); -#endif - nsEventStatus ProcessEvent(const nsGUIEvent & anEvent); #ifdef XP_MACOSX @@ -405,6 +412,12 @@ public: return strncmp(GetPluginName(), aPluginName, strlen(aPluginName)) == 0; } +#ifdef MOZ_PLATFORM_HILDON + nsresult SetAbsoluteScreenPosition(nsIDOMElement* element, + nsIDOMClientRect* position, + nsIDOMClientRect* clip); +#endif + private: void FixUpURLS(const nsString &name, nsAString &value); @@ -498,15 +511,34 @@ private: #ifdef MOZ_PLATFORM_HILDON // On hildon, we attempt to use NPImageExpose which allows us faster - // painting. We hold a memory buffer to avoid reallocations on - // every plugin invalidate. - unsigned char* mImageExposeBuffer; - gfxIntSize mImageExposeBufferSize; + // painting. + + // used to keep track of how big our buffer is. + nsIntSize mPluginSize; + + // the scale between the actual instance plugin window and what + // we want to scale it to. + float mPluginScale; + + // the element that was passed into SetAbsoluteScreenPosition(). + // This will be the element we use to determine which Window we draw into. + nsCOMPtr mBlitParentElement; + + // The absolute position on the screen to draw to. + nsIntRect mAbsolutePosition; + + // The clip region that we should draw into. + nsIntRect mAbsolutePositionClip; + + Window mBlitWindow; + XImage *mSharedXImage; + XShmSegmentInfo mSharedSegmentInfo; + + PRBool SetupXShm(); + void ReleaseXShm(); + nsresult NativeImageDraw(); + PRBool UpdateVisibility(); - nsresult NativeImageDraw(gfxContext *aContext, - NPWindow* mWindow, - const nsIntSize& mPluginSize, - const nsIntRect& mDirtyRect); #endif }; @@ -931,10 +963,6 @@ nsObjectFrame::FixupWindow(const nsSize& aSize) NS_ENSURE_TRUE(window, /**/); -#ifdef MOZ_PLATFORM_HILDON - mInstanceOwner->UpdateVisibility(PR_TRUE); -#endif - #ifdef XP_MACOSX mInstanceOwner->FixUpPluginWindow(ePluginPaintDisable); #endif @@ -978,11 +1006,6 @@ nsObjectFrame::CallSetWindow() return; nsPluginNativeWindow *window = (nsPluginNativeWindow *)win; - -#ifdef MOZ_PLATFORM_HILDON - mInstanceOwner->UpdateVisibility(PR_TRUE); -#endif - #ifdef XP_MACOSX mInstanceOwner->FixUpPluginWindow(ePluginPaintDisable); #endif @@ -1190,6 +1213,19 @@ nsObjectFrame::ComputeWidgetGeometry(const nsRegion& aRegion, } } +nsresult +nsObjectFrame::SetAbsoluteScreenPosition(nsIDOMElement* element, + nsIDOMClientRect* position, + nsIDOMClientRect* clip) +{ +#ifdef MOZ_PLATFORM_HILDON + NS_ASSERTION(mInstanceOwner, "failed to get mInstanceOwner"); + return mInstanceOwner->SetAbsoluteScreenPosition(element, position, clip); +#else + return NS_ERROR_NOT_IMPLEMENTED; +#endif +} + void nsObjectFrame::DidSetWidgetGeometry() { @@ -2363,15 +2399,10 @@ nsPluginInstanceOwner::nsPluginInstanceOwner() #endif #ifdef MOZ_PLATFORM_HILDON - mImageExposeBuffer = nsnull; - mImageExposeBufferSize = gfxIntSize(0,0); -#endif -#ifdef XP_MACOSX -#ifndef NP_NO_QUICKDRAW - mEventModel = NPEventModelCarbon; -#else - mEventModel = NPEventModelCocoa; -#endif + mPluginSize = nsIntSize(0,0); + mPluginScale = 1.0; + mSharedXImage = nsnull; + mSharedSegmentInfo.shmaddr = nsnull; #endif PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG, ("nsPluginInstanceOwner %p created\n", this)); @@ -2428,11 +2459,8 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner() } #ifdef MOZ_PLATFORM_HILDON - if (mImageExposeBuffer) - free(mImageExposeBuffer); - mImageExposeBuffer = nsnull; + ReleaseXShm(); #endif - } /* @@ -2649,6 +2677,11 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetDocument(nsIDocument* *aDocument) NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect) { +#ifdef MOZ_PLATFORM_HILDON + if (mObjectFrame && mBlitWindow && NS_SUCCEEDED(NativeImageDraw())) + return NS_OK; +#endif + if (!mObjectFrame || !invalidRect || !mWidgetVisible) return NS_ERROR_FAILURE; @@ -3485,10 +3518,6 @@ nsPluginInstanceOwner::GetEventloopNestingLevel() nsresult nsPluginInstanceOwner::ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY) { -#ifdef MOZ_PLATFORM_HILDON - CancelTimer(); -#endif - #if defined(XP_MACOSX) && !defined(NP_NO_CARBON) if (GetEventModel() != NPEventModelCarbon) return NS_OK; @@ -4735,7 +4764,18 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext, if (!mInstance || !mObjectFrame) return; - // Align to device pixels where sensible +#ifdef MOZ_PLATFORM_HILDON + PRBool simpleImageRender = PR_FALSE; + mInstance->GetValueFromPlugin(NPPVpluginWindowlessLocalBool, + &simpleImageRender); + if (simpleImageRender) { + gfxMatrix matrix = aContext->CurrentMatrix(); + if (!matrix.HasNonAxisAlignedTransform() && + NS_SUCCEEDED(NativeImageDraw())) + return; + } +#endif + // to provide crisper and faster drawing. gfxRect pluginRect = aFrameRect; if (aContext->UserToDevicePixelSnapped(pluginRect)) { @@ -4788,15 +4828,6 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext, gfxContextAutoSaveRestore autoSR(aContext); aContext->Translate(pluginRect.pos); -#ifdef MOZ_PLATFORM_HILDON - PRBool simpleImageRender = PR_FALSE; - mInstance->GetValueFromPlugin(NPPVpluginWindowlessLocalBool, (void *)&simpleImageRender); - - if (simpleImageRender && NS_SUCCEEDED(NativeImageDraw(aContext, window, pluginSize, pluginDirtyRect))) - return; - -#endif - Renderer renderer(window, mInstance, pluginSize, pluginDirtyRect); renderer.Draw(aContext, window->width, window->height, rendererFlags, nsnull); @@ -4821,6 +4852,103 @@ DepthOfVisual(const Screen* screen, const Visual* visual) #ifdef MOZ_PLATFORM_HILDON +static GdkWindow* GetClosestWindow(nsIDOMElement *element) +{ + nsCOMPtr domDocument; + element->GetOwnerDocument(getter_AddRefs(domDocument)); + + nsCOMPtr doc = do_QueryInterface(domDocument); + if (!doc) + return nsnull; + + nsIPresShell *presShell = doc->GetPrimaryShell(); + if (!presShell) + return nsnull; + + nsCOMPtr content = do_QueryInterface(element); + nsIFrame* frame = presShell->GetPrimaryFrameFor(content); + if (!frame) + return nsnull; + + nsIWidget* win = frame->GetWindow(); + if (!win) + return nsnull; + + GdkWindow* w = static_cast(win->GetNativeData(NS_NATIVE_WINDOW)); + return w; +} + +void +nsPluginInstanceOwner::ReleaseXShm() +{ + if (mSharedSegmentInfo.shmaddr) { + XShmDetach(gdk_x11_get_default_xdisplay(), &mSharedSegmentInfo); + shmdt(mSharedSegmentInfo.shmaddr); + mSharedSegmentInfo.shmaddr = nsnull; + } + + if (mSharedXImage) { + XDestroyImage(mSharedXImage); + mSharedXImage = nsnull; + } +} + +PRBool +nsPluginInstanceOwner::SetupXShm() +{ + mBlitWindow = GDK_WINDOW_XWINDOW(GetClosestWindow(mBlitParentElement)); + if (!mBlitWindow) + return PR_FALSE; + + ReleaseXShm(); + + // we use 16 as the default depth because that is the value of the + // screen, but not the default X default depth. + XVisualInfo vinfo; + int foundVisual = XMatchVisualInfo(gdk_x11_get_default_xdisplay(), + gdk_x11_get_default_screen(), + 16, + TrueColor, + &vinfo); + if (!foundVisual) + return PR_FALSE; + + memset(&mSharedSegmentInfo, 0, sizeof(XShmSegmentInfo)); + mSharedXImage = XShmCreateImage(gdk_x11_get_default_xdisplay(), + vinfo.visual, + 16, + ZPixmap, + 0, + &mSharedSegmentInfo, + mPluginSize.width, + mPluginSize.height); + if (!mSharedXImage) + return PR_FALSE; + + mSharedSegmentInfo.shmid = shmget(IPC_PRIVATE, + mSharedXImage->bytes_per_line * mSharedXImage->height, + IPC_CREAT | 0777); + + mSharedXImage->data = static_cast(shmat(mSharedSegmentInfo.shmid, 0, 0)); + mSharedSegmentInfo.shmaddr = mSharedXImage->data; + mSharedSegmentInfo.readOnly = False; + + Status s = XShmAttach(gdk_x11_get_default_xdisplay(), &mSharedSegmentInfo); + XSync(gdk_x11_get_default_xdisplay(), False); + shmctl(mSharedSegmentInfo.shmid, IPC_RMID, 0); + if (!s) { + // attach failed, call shmdt and null shmaddr before calling + // ReleaseXShm(). + shmdt(mSharedSegmentInfo.shmaddr); + mSharedSegmentInfo.shmaddr = nsnull; + ReleaseXShm(); + return PR_FALSE; + } + + return PR_TRUE; +} + + // NativeImageDraw // // This method supports the NPImageExpose API which is specific to the @@ -4840,65 +4968,53 @@ DepthOfVisual(const Screen* screen, const Visual* visual) // Hopefully this API can die off in favor of a more robust plugin API. nsresult -nsPluginInstanceOwner::NativeImageDraw(gfxContext *aContext, - NPWindow* mWindow, - const nsIntSize& mPluginSize, - const nsIntRect& mDirtyRect) +nsPluginInstanceOwner::NativeImageDraw() { - PRBool doupdatewindow = PR_FALSE; + // if we haven't been positioned yet, ignore + if (!mBlitParentElement) + return NS_OK; - if (mWindow->x || mWindow->y) { - mWindow->x = 0; - mWindow->y = 0; - doupdatewindow = PR_TRUE; - } + // if the clip rect is zero, we have nothing to do. + if (mAbsolutePositionClip.width == 0 || mAbsolutePositionClip.height == 0) + return NS_OK; - if (nsIntSize(mWindow->width, mWindow->height) != mPluginSize) { - mWindow->width = mPluginSize.width; - mWindow->height = mPluginSize.height; - doupdatewindow = PR_TRUE; - } + // if we haven't been setup before, or if the size of the plugin increased. + if (!mSharedXImage || + mPluginSize.width != mAbsolutePosition.width || + mPluginSize.height != mAbsolutePosition.height) { - // The clip rect is relative to drawable top-left. - nsIntRect clipRect; - clipRect.x = 0; - clipRect.y = 0; - clipRect.width = mWindow->width; - clipRect.height = mWindow->height; + mPluginSize = nsIntSize(mAbsolutePosition.width, mAbsolutePosition.height); + if (NS_FAILED(SetupXShm())) + return NS_ERROR_FAILURE; + } + + NPWindow* window; + GetWindow(window); + NS_ASSERTION(window, "Window can not be null"); + + // setup window such that it knows about the size and clip. This + // is to work around a flash clipping bug when using the Image + // Expose API. + NPRect newClipRect; - newClipRect.left = clipRect.x; - newClipRect.top = clipRect.y; - newClipRect.right = clipRect.XMost(); - newClipRect.bottom = clipRect.YMost(); - if (mWindow->clipRect.left != newClipRect.left || - mWindow->clipRect.top != newClipRect.top || - mWindow->clipRect.right != newClipRect.right || - mWindow->clipRect.bottom != newClipRect.bottom) { - mWindow->clipRect = newClipRect; - doupdatewindow = PR_TRUE; - } - + newClipRect.left = 0; + newClipRect.top = 0; + newClipRect.right = window->width; + newClipRect.bottom = window->height; + + window->clipRect = newClipRect; + window->x = 0; + window->y = 0; + NPSetWindowCallbackStruct* ws_info = - static_cast(mWindow->ws_info); + static_cast(window->ws_info); ws_info->visual = 0; ws_info->colormap = 0; - if (ws_info->depth != 24) { - ws_info->depth = 24; - doupdatewindow = PR_TRUE; - } + ws_info->depth = 16; + mInstance->SetWindow(window); - if (doupdatewindow) - mInstance->SetWindow(mWindow); - - nsIntRect dirtyRect = mDirtyRect; - - // Intersect the dirty rect with the clip rect to ensure that it lies within - // the drawable. - if (!dirtyRect.IntersectRect(mDirtyRect, clipRect)) - return NS_ERROR_FAILURE; - - XEvent pluginEvent; + NPEvent pluginEvent; NPImageExpose imageExpose; XGraphicsExposeEvent& exposeEvent = pluginEvent.xgraphicsexpose; @@ -4908,71 +5024,82 @@ nsPluginInstanceOwner::NativeImageDraw(gfxContext *aContext, // Store imageExpose structure pointer as drawable member exposeEvent.drawable = (Drawable)&imageExpose; - exposeEvent.x = mDirtyRect.x; - exposeEvent.y = mDirtyRect.y; - exposeEvent.width = mDirtyRect.width; - exposeEvent.height = mDirtyRect.height; exposeEvent.count = 0; - - // information not set: exposeEvent.serial = 0; exposeEvent.send_event = False; exposeEvent.major_code = 0; exposeEvent.minor_code = 0; - // defaults for NPImageExpose - imageExpose.depth = 24; - imageExpose.translateX = 1; - imageExpose.translateY = 1; - imageExpose.scaleX = 1; - imageExpose.scaleY = 1; + exposeEvent.x = 0; + exposeEvent.y = 0; + exposeEvent.width = window->width; + exposeEvent.height = window->height; - // only have the plugin draw what is dirty - imageExpose.x = mDirtyRect.x; - imageExpose.y = mDirtyRect.y; - imageExpose.width = mDirtyRect.width; - imageExpose.height = mDirtyRect.height; + imageExpose.x = 0; + imageExpose.y = 0; + imageExpose.width = window->width; + imageExpose.height = window->height; - // reallocate buffer if there is a size change or if we haven't allocated one yet. We probably can do this - // somewhere else. - if (!mImageExposeBuffer || - (mImageExposeBufferSize.width * mImageExposeBufferSize.height < mWindow->width * mWindow->height)) { - if (mImageExposeBuffer) - free(mImageExposeBuffer); + imageExpose.depth = 16; - mImageExposeBuffer = (unsigned char*) malloc (mWindow->width * mWindow->height * 4); - mImageExposeBufferSize = gfxIntSize(mWindow->width, mWindow->height); - } + imageExpose.translateX = 0; + imageExpose.translateY = 0; - NS_ENSURE_TRUE(mImageExposeBuffer, NS_ERROR_OUT_OF_MEMORY); + imageExpose.scaleX = mPluginScale; + imageExpose.scaleY = mPluginScale; - // Because we are reusing mImageExposeBuffer, there might be old bytes. The API NPImageExpose - // expects that the buffer be zero'ed out. - memset(mImageExposeBuffer, 0, mImageExposeBufferSize.height * mImageExposeBufferSize.width * 4); - - nsRefPtr surf = new gfxImageSurface(mImageExposeBuffer, - mImageExposeBufferSize, - mImageExposeBufferSize.width * 4, - gfxASurface::ImageFormatRGB24); - NS_ENSURE_TRUE(surf, NS_ERROR_OUT_OF_MEMORY); - - // Setup temporary context scaled size - imageExpose.stride = surf->Stride(); - imageExpose.data = reinterpret_cast(surf->Data()); - imageExpose.dataSize.width = surf->Width(); - imageExpose.dataSize.height = surf->Height(); + imageExpose.stride = mPluginSize.width * 2; + imageExpose.data = mSharedXImage->data; + imageExpose.dataSize.width = mPluginSize.width; + imageExpose.dataSize.height = mPluginSize.height; PRBool eventHandled = PR_FALSE; - // Get Image surface from original context - // Draw plugin content to temp surface mInstance->HandleEvent(&pluginEvent, &eventHandled); - - if (eventHandled) { - nsRefPtr pat = new gfxPattern(surf); - aContext->NewPath(); - aContext->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWindow->width, mWindow->height), pat); - aContext->Fill(); + + if (!eventHandled) { + // XXX we should set a flag that the plugin didn't handle this event, + // and we should deallocate the SHM surface and just skip trying to + // draw this way + return NS_ERROR_FAILURE; } + + // Setup the clip rectangle + XRectangle rect; + rect.x = mAbsolutePositionClip.x; + rect.y = mAbsolutePositionClip.y; + rect.width = mAbsolutePositionClip.width; + rect.height = mAbsolutePositionClip.height; + + GC gc = XCreateGC(gdk_x11_get_default_xdisplay(), + mBlitWindow, + 0, + 0); + if (!gc) + return NS_ERROR_FAILURE; + + XSetClipRectangles(gdk_x11_get_default_xdisplay(), + gc, + mAbsolutePosition.x, + mAbsolutePosition.y, + &rect, 1, + Unsorted); + + XShmPutImage(gdk_x11_get_default_xdisplay(), + mBlitWindow, + gc, + mSharedXImage, + 0, + 0, + mAbsolutePosition.x, + mAbsolutePosition.y, + mPluginSize.width, + mPluginSize.height, + PR_FALSE); + + XSetClipRectangles(gdk_x11_get_default_xdisplay(), gc, 0, 0, nsnull, 0, Unsorted); + + XFreeGC(gdk_x11_get_default_xdisplay(), gc); + XFlush(gdk_x11_get_default_xdisplay()); return NS_OK; } #endif @@ -5149,11 +5276,6 @@ nsPluginInstanceOwner::Renderer::NativeDraw(QWidget * drawable, NS_IMETHODIMP nsPluginInstanceOwner::Notify(nsITimer* timer) { -#ifdef MOZ_PLATFORM_HILDON - if (mInstance) - UpdateVisibility(); -#endif - #if defined(XP_MACOSX) && !defined(NP_NO_CARBON) if (GetEventModel() != NPEventModelCarbon) return NS_OK; @@ -5204,20 +5326,6 @@ void nsPluginInstanceOwner::StartTimer(unsigned int aDelay) mPluginTimer->InitWithCallback(this, aDelay, nsITimer::TYPE_REPEATING_SLACK); } #endif - -#ifdef MOZ_PLATFORM_HILDON - if (!mTimerCanceled) - return; - - // start a periodic timer to provide null events to the plugin instance. - if (!mPluginTimer) - mPluginTimer = do_CreateInstance("@mozilla.org/timer;1"); - - if (mPluginTimer) { - mTimerCanceled = PR_FALSE; - mPluginTimer->InitWithCallback(this, aDelay, nsITimer::TYPE_ONE_SHOT); - } -#endif } void nsPluginInstanceOwner::CancelTimer() @@ -5423,27 +5531,20 @@ void nsPluginInstanceOwner::SetPluginHost(nsIPluginHost* aHost) } #ifdef MOZ_PLATFORM_HILDON -PRBool nsPluginInstanceOwner::UpdateVisibility(PRBool aForce) +PRBool nsPluginInstanceOwner::UpdateVisibility() { - if (!mPluginWindow || !mInstance || !mObjectFrame) - return PR_FALSE; + NS_ASSERTION(mInstance, "mInstance should never be null"); + + PRBool handled; + NPEvent pluginEvent; + XVisibilityEvent& visibilityEvent = pluginEvent.xvisibility; + visibilityEvent.type = VisibilityNotify; + visibilityEvent.display = 0; + visibilityEvent.state = VisibilityUnobscured; + mInstance->HandleEvent(&pluginEvent, &handled); - // first, check our view for CSS visibility style - PRBool isVisible = - mObjectFrame->GetView()->GetVisibility() == nsViewVisibility_kShow; - - if (aForce || mWidgetVisible != isVisible) { - PRBool handled; - NPEvent pluginEvent; - XVisibilityEvent& visibilityEvent = pluginEvent.xvisibility; - visibilityEvent.type = VisibilityNotify; - visibilityEvent.display = 0; - visibilityEvent.state = isVisible ? VisibilityUnobscured : VisibilityFullyObscured; - mInstance->HandleEvent(&pluginEvent, &handled); - mWidgetVisible = isVisible; - return PR_TRUE; - } - return PR_FALSE; + mWidgetVisible = PR_TRUE; + return PR_TRUE; } #endif @@ -5584,3 +5685,50 @@ void nsPluginInstanceOwner::FixUpURLS(const nsString &name, nsAString &value) value = newURL; } } + +#ifdef MOZ_PLATFORM_HILDON +nsresult +nsPluginInstanceOwner::SetAbsoluteScreenPosition(nsIDOMElement* element, + nsIDOMClientRect* position, + nsIDOMClientRect* clip) +{ + if ((mBlitParentElement && (mBlitParentElement != element)) || + !position || !clip) + return NS_ERROR_FAILURE; + + // convert to a int rect. + float left, top, width, height; + position->GetLeft(&left); + position->GetTop(&top); + position->GetWidth(&width); + position->GetHeight(&height); + + NPWindow *window; + GetWindow(window); + NS_ASSERTION(window, "Must have a window here"); + + mPluginScale = width / window->width; + + // The flash plugin on Maemo n900 requires the width/height to be + // even. + mAbsolutePosition = nsIntRect(NSToIntFloor(left), + NSToIntFloor(top), + NSToIntCeil(width) / 2 * 2, + NSToIntCeil(height) / 2 * 2); + clip->GetLeft(&left); + clip->GetTop(&top); + clip->GetWidth(&width); + clip->GetHeight(&height); + + mAbsolutePositionClip = nsIntRect(NSToIntFloor(left), + NSToIntFloor(top), + NSToIntCeil(width), + NSToIntCeil(height)); + mBlitParentElement = element; + + // The hildon plugin needs to have it visibility poked + UpdateVisibility(); + return NS_OK; +} +#endif + diff --git a/layout/generic/nsObjectFrame.h b/layout/generic/nsObjectFrame.h index 954dd5c2844..8294e797209 100644 --- a/layout/generic/nsObjectFrame.h +++ b/layout/generic/nsObjectFrame.h @@ -58,6 +58,7 @@ class nsIPluginHost; class nsIPluginInstance; class nsPresContext; class nsDisplayPlugin; +class nsIDOMElement; #define nsObjectFrameSuper nsFrame @@ -220,6 +221,10 @@ protected: nsIWidget* GetWidget() { return mWidget; } + nsresult SetAbsoluteScreenPosition(nsIDOMElement* element, + nsIDOMClientRect* position, + nsIDOMClientRect* clip); + friend class nsPluginInstanceOwner; friend class nsDisplayPlugin;