diff --git a/mozilla/modules/plugin/base/src/ns4xPluginInstance.cpp b/mozilla/modules/plugin/base/src/ns4xPluginInstance.cpp index a29f9cf389b..9305f4d47bd 100644 --- a/mozilla/modules/plugin/base/src/ns4xPluginInstance.cpp +++ b/mozilla/modules/plugin/base/src/ns4xPluginInstance.cpp @@ -49,6 +49,7 @@ #include "nsPluginSafety.h" #include "nsIPref.h" // needed for NS_TRY_SAFE_CALL_* #include "nsPluginLogging.h" +#include "nsIPluginWidget.h" #if defined(MOZ_WIDGET_GTK) #include @@ -363,6 +364,10 @@ ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo, // do not read more that supplier wants us to read bytesToRead = length; } + +#if defined(XP_MAC) || defined(XP_MACOSX) + mInst->SetupForPluginDrawing(); +#endif do { @@ -463,6 +468,11 @@ ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo, } // end of for(;;) } while ((PRInt32)(length) > 0); + +#if defined(XP_MAC) || defined(XP_MACOSX) + mInst->DonePluginDrawing(); +#endif + return rv; } @@ -618,6 +628,27 @@ ns4xPluginInstance :: IsStarted(void) } +/////////////////////////////////////////////////////////////////////////////// +nsresult +ns4xPluginInstance::SetupForPluginDrawing() +{ +#if defined(XP_MAC) || defined(XP_MACOSX) + ::SetPort(mWindow->window->port); +#endif + return NS_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +nsresult +ns4xPluginInstance::DonePluginDrawing() +{ +#if defined(XP_MAC) || defined(XP_MACOSX) + +#endif + return NS_OK; +} + + //////////////////////////////////////////////////////////////////////// NS_IMETHODIMP ns4xPluginInstance::Initialize(nsIPluginInstancePeer* peer) { @@ -1012,8 +1043,8 @@ NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window) NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, - ("NPP SetWindow called: this=%p, [x=%d,y=%d,w=%d,h=%d], clip[t=%d,b=%d,l=%d,r=%d], return=%d\n", - this, window->x, window->y, window->width, window->height, + ("NPP SetWindow called: this=%p, window=%p, [x=%d,y=%d,w=%d,h=%d], clip[t=%d,b=%d,l=%d,r=%d], return=%d\n", + this, *window->window, window->x, window->y, window->width, window->height, window->clipRect.top, window->clipRect.bottom, window->clipRect.left, window->clipRect.right, error)); // XXX In the old code, we'd just ignore any errors coming @@ -1122,25 +1153,12 @@ NS_IMETHODIMP ns4xPluginInstance::HandleEvent(nsPluginEvent* event, PRBool* hand if (fCallbacks->event) { #if defined(XP_MAC) || defined(XP_MACOSX) -#if 0 - switch(event->event->what) { - case updateEvt: - if (mWindow) { - GrafPtr port; - GetPort(&port); - if (port != mWindow->window->port) printf("[!!! port isn't set correctly !!!!]\n"); - RGBColor oldColor; - RGBColor green = { 0, 0xFFFF, 0 }; - GetForeColor(&oldColor); - RGBForeColor(&green); - PaintRect((Rect*)&mWindow->clipRect); - // ::QDFlushPortBuffer(port, NULL); - RGBForeColor(&oldColor); - // printf("[portx = %d, porty = %d]\n", mWindow->window->portx, mWindow->window->porty); - } - break; - } -#endif + + NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, + ("CallNPP_HandleEventProc called: this=%p, [x=%d,y=%d,w=%d,h=%d], clip[t=%d,b=%d,l=%d,r=%d]\n", + this, mWindow->x, mWindow->y, mWindow->width, mWindow->height, + mWindow->clipRect.top, mWindow->clipRect.bottom, mWindow->clipRect.left, mWindow->clipRect.right)); + result = CallNPP_HandleEventProc(fCallbacks->event, &fNPP, (void*) event->event); diff --git a/mozilla/modules/plugin/base/src/ns4xPluginInstance.h b/mozilla/modules/plugin/base/src/ns4xPluginInstance.h index 17b166c0b46..51728625c4a 100644 --- a/mozilla/modules/plugin/base/src/ns4xPluginInstance.h +++ b/mozilla/modules/plugin/base/src/ns4xPluginInstance.h @@ -153,6 +153,11 @@ public: // cache this 4.x plugin like an XPCOM plugin nsresult SetCached(PRBool aCache) { mCached = aCache; return NS_OK; }; + // only used on Mac; called to ensure that the plugin can draw whenever + // we call into it + nsresult SetupForPluginDrawing(); + nsresult DonePluginDrawing(); + protected: nsresult InitializePlugin(nsIPluginInstancePeer* peer); diff --git a/mozilla/modules/plugin/base/src/nsPluginViewer.cpp b/mozilla/modules/plugin/base/src/nsPluginViewer.cpp index 81f224f9567..72c755b7463 100644 --- a/mozilla/modules/plugin/base/src/nsPluginViewer.cpp +++ b/mozilla/modules/plugin/base/src/nsPluginViewer.cpp @@ -53,6 +53,7 @@ #include "nsIContentViewerEdit.h" #include "nsIWebBrowserPrint.h" #include "nsIWidget.h" +#include "nsIPluginWidget.h" #include "nsIContent.h" #include "nsIDocument.h" #include "nsIInterfaceRequestor.h" @@ -650,6 +651,7 @@ PluginViewerImpl::SetBounds(const nsRect& aBounds) #if defined(XP_MAC) || defined(XP_MACOSX) // On Mac we also need to add in the widget offset to the plugin window mOwner->FixUpPluginWindow(); + mWindow->Invalidate(PR_FALSE); #endif inst->SetWindow(win); } @@ -679,6 +681,7 @@ PluginViewerImpl::Move(PRInt32 aX, PRInt32 aY) #if defined(XP_MAC) || defined(XP_MACOSX) // On Mac we also need to add in the widget offset to the plugin window mOwner->FixUpPluginWindow(); + mWindow->Invalidate(PR_FALSE); #endif inst->SetWindow(win); } @@ -1038,7 +1041,30 @@ PluginListener::OnDataAvailable(nsIRequest *request, nsISupports *ctxt, if (nsnull == mNextStream) { return NS_ERROR_FAILURE; } - return mNextStream->OnDataAvailable(request, ctxt, inStr, sourceOffset, count); + + nsresult rv = NS_OK; + +#if defined (XP_MAC) || defined(XP_MACOSX) + NS_ASSERTION(mViewer, "Need plugin viewer"); + nsCOMPtr pluginWidget = do_QueryInterface(mViewer->mWindow); + PRBool startDrawCalled = PR_FALSE; + + if (pluginWidget) + { + rv = pluginWidget->StartDrawPlugin(); + NS_ASSERTION(NS_SUCCEEDED(rv), "StartDrawPlugin failed in OnDataAvailable!"); + startDrawCalled = NS_SUCCEEDED(rv); + } +#endif + + rv = mNextStream->OnDataAvailable(request, ctxt, inStr, sourceOffset, count); + +#if defined (XP_MAC) || defined(XP_MACOSX) + if (pluginWidget && startDrawCalled) + pluginWidget->EndDrawPlugin(); +#endif + + return rv; } //---------------------------------------------------------------------- @@ -1291,38 +1317,48 @@ nsEventStatus pluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent) return rv; #if defined(XP_MAC) || defined(XP_MACOSX) - //if (mWidget != NULL) { // check for null mWidget - EventRecord* event = (EventRecord*)anEvent.nativeMsg; - if (event == NULL || event->what == nullEvent || - anEvent.message == NS_CONTEXTMENU_MESSAGE_START) { - EventRecord macEvent; - GUItoMacEvent(anEvent, macEvent); - event = &macEvent; - if (event->what == updateEvt) { - // Add in child windows absolute position to get make the dirty rect - // relative to the top-level window. - nsPluginPort* pluginPort = FixUpPluginWindow(); - if (pluginPort) { - EventRecord updateEvent; - InitializeEventRecord(&updateEvent); - updateEvent.what = updateEvt; - updateEvent.message = UInt32(pluginPort->port); - - nsPluginEvent pluginEvent = { &updateEvent, nsPluginPlatformWindowRef(pluginPort->port) }; - PRBool eventHandled = PR_FALSE; - mInstance->HandleEvent(&pluginEvent, &eventHandled); + + nsCOMPtr pluginWidget = do_QueryInterface(mWindow); + if (pluginWidget && NS_SUCCEEDED(pluginWidget->StartDrawPlugin())) + { + //if (mWidget != NULL) { // check for null mWidget + EventRecord* event = (EventRecord*)anEvent.nativeMsg; + if (event == NULL || event->what == nullEvent || + anEvent.message == NS_CONTEXTMENU_MESSAGE_START) { + EventRecord macEvent; + GUItoMacEvent(anEvent, macEvent); + event = &macEvent; + if (event->what == updateEvt) { + // Add in child windows absolute position to get make the dirty rect + // relative to the top-level window. + nsPluginPort* pluginPort = FixUpPluginWindow(); + if (pluginPort) { + EventRecord updateEvent; + InitializeEventRecord(&updateEvent); + updateEvent.what = updateEvt; + updateEvent.message = UInt32(pluginPort->port); + + nsPluginEvent pluginEvent = { &updateEvent, nsPluginPlatformWindowRef(pluginPort->port) }; + PRBool eventHandled = PR_FALSE; + mInstance->HandleEvent(&pluginEvent, &eventHandled); + } } + rv = nsEventStatus_eConsumeNoDefault; } - return nsEventStatus_eConsumeNoDefault; - - } - nsPluginPort* port = (nsPluginPort*)mWindow->GetNativeData(NS_NATIVE_PLUGIN_PORT); - nsPluginEvent pluginEvent = { event, nsPluginPlatformWindowRef(port->port) }; - PRBool eventHandled = PR_FALSE; - mInstance->HandleEvent(&pluginEvent, &eventHandled); - if (eventHandled && anEvent.message != NS_MOUSE_LEFT_BUTTON_DOWN) - rv = nsEventStatus_eConsumeNoDefault; - // } + else + { + nsPluginPort* port = (nsPluginPort*)mWindow->GetNativeData(NS_NATIVE_PLUGIN_PORT); + nsPluginEvent pluginEvent = { event, nsPluginPlatformWindowRef(port->port) }; + PRBool eventHandled = PR_FALSE; + mInstance->HandleEvent(&pluginEvent, &eventHandled); + if (eventHandled && anEvent.message != NS_MOUSE_LEFT_BUTTON_DOWN) + rv = nsEventStatus_eConsumeNoDefault; + } + // } + + pluginWidget->EndDrawPlugin(); + } + #endif //~~~ @@ -1348,33 +1384,31 @@ NS_IMETHODIMP_(void) pluginInstanceOwner::Notify(nsITimer* /* timer */) // validate the plugin clipping information by syncing the plugin window info to // reflect the current widget location. This makes sure that everything is updated // correctly in the event of scrolling in the window. - if (mInstance != NULL) { - nsPluginPort* pluginPort = FixUpPluginWindow(); - if (pluginPort) { - EventRecord idleEvent; - InitializeEventRecord(&idleEvent); - idleEvent.what = nullEvent; - - // give a bogus 'where' field of our null event when hidden, so Flash - // won't respond to mouse moves in other tabs, see bug 120875 - if (!mWidgetVisible) - idleEvent.where.h = idleEvent.where.v = 20000; - - nsPluginEvent pluginEvent = { &idleEvent, nsPluginPlatformWindowRef(pluginPort->port) }; - - PRBool eventHandled = PR_FALSE; - mInstance->HandleEvent(&pluginEvent, &eventHandled); + if (mInstance != NULL) + { + nsCOMPtr pluginWidget = do_QueryInterface(mWindow); + if (pluginWidget && NS_SUCCEEDED(pluginWidget->StartDrawPlugin())) + { + nsPluginPort* pluginPort = FixUpPluginWindow(); + if (pluginPort) { + EventRecord idleEvent; + InitializeEventRecord(&idleEvent); + idleEvent.what = nullEvent; + + // give a bogus 'where' field of our null event when hidden, so Flash + // won't respond to mouse moves in other tabs, see bug 120875 + if (!mWidgetVisible) + idleEvent.where.h = idleEvent.where.v = 20000; + + nsPluginEvent pluginEvent = { &idleEvent, nsPluginPlatformWindowRef(pluginPort->port) }; + + PRBool eventHandled = PR_FALSE; + mInstance->HandleEvent(&pluginEvent, &eventHandled); + } + + pluginWidget->EndDrawPlugin(); } } - -#ifndef REPEATING_TIMERS - // reprime the timer? currently have to create a new timer for each call, which is - // kind of wasteful. need to get periodic timers working on all platforms. - nsresult rv; - mPluginTimer = do_CreateInstance("@mozilla.org/timer;1", &rv); - if (NS_SUCCEEDED(rv)) - mPluginTimer->Init(this, 1020 / 60); -#endif // REPEATING_TIMERS #endif // XP_MAC } @@ -1473,31 +1507,49 @@ nsPluginPort* pluginInstanceOwner::FixUpPluginWindow() { if (mWindow) { nsPluginPort* pluginPort = GetPluginPort(); - nscoord absWidgetX = 0; - nscoord absWidgetY = 0; + nsRect widgetClip(0, 0, 0, 0); PRBool isVisible = PR_TRUE; - GetWidgetPosClipAndVis(mWindow, absWidgetX, absWidgetY, widgetClip, isVisible); #if defined(MOZ_WIDGET_COCOA) + nsPoint pluginOrigin; + nsCOMPtr pluginWidget = do_QueryInterface(mWindow); + pluginWidget->GetPluginClipRect(widgetClip, pluginOrigin); + + // check widget visibility (do we really have to do this here?) + nsCOMPtr widget = mWindow; + while (widget) + { + PRBool widgetVisible; + widget->IsVisible(widgetVisible); + isVisible &= widgetVisible; + + widget = getter_AddRefs(widget->GetParent()); + } + + if (!isVisible) + widgetClip.Empty(); + // set the port coordinates mPluginWindow.x = -pluginPort->portx; mPluginWindow.y = -pluginPort->porty; - widgetClip.x += mPluginWindow.x - absWidgetX; - widgetClip.y += mPluginWindow.y - absWidgetY; #else + nscoord absWidgetX = 0; + nscoord absWidgetY = 0; + GetWidgetPosClipAndVis(mWindow, absWidgetX, absWidgetY, widgetClip, isVisible); // set the port coordinates mPluginWindow.x = absWidgetX; mPluginWindow.y = absWidgetY; #endif // fix up the clipping region - mPluginWindow.clipRect.top = widgetClip.y; - mPluginWindow.clipRect.left = widgetClip.x; - mPluginWindow.clipRect.bottom = mPluginWindow.clipRect.top + widgetClip.height; - mPluginWindow.clipRect.right = mPluginWindow.clipRect.left + widgetClip.width; + mPluginWindow.clipRect.top = widgetClip.y; + mPluginWindow.clipRect.left = widgetClip.x; + mPluginWindow.clipRect.bottom = mPluginWindow.clipRect.top + widgetClip.height; + mPluginWindow.clipRect.right = mPluginWindow.clipRect.left + widgetClip.width; - if (mWidgetVisible != isVisible) { + if (mWidgetVisible != isVisible) + { mWidgetVisible = isVisible; // must do this to disable async Java Applet drawing if (isVisible) {