diff --git a/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp b/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp index a5539488e58..5fb88a0ed25 100644 --- a/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp +++ b/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp @@ -968,6 +968,7 @@ public: } else { NS_WARNING("missing library from nsPluginUnloadEvent"); } + return NS_OK; } PRLibrary* mLibrary; diff --git a/mozilla/modules/plugin/base/src/nsPluginNativeWindowWin.cpp b/mozilla/modules/plugin/base/src/nsPluginNativeWindowWin.cpp index 5a8e888fd1a..96153f9197d 100644 --- a/mozilla/modules/plugin/base/src/nsPluginNativeWindowWin.cpp +++ b/mozilla/modules/plugin/base/src/nsPluginNativeWindowWin.cpp @@ -50,37 +50,52 @@ #include "nsDebug.h" -#include "plevent.h" -#include "nsIEventQueueService.h" #include "nsGUIEvent.h" #include "nsIPluginInstancePeer.h" #include "nsIPluginInstanceInternal.h" #include "nsPluginSafety.h" #include "nsPluginNativeWindow.h" +#include "nsThreadUtils.h" +#include "nsAutoPtr.h" -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kCPluginManagerCID, NS_PLUGINMANAGER_CID); // needed for NS_TRY_SAFE_CALL #define NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION "MozillaPluginWindowPropertyAssociation" +class PluginWindowWeakRef { +public: + void AddRef() { ++mRefCnt; } + void Release() { if (--mRefCnt == 0) delete this; } + + // A pointer to the plugin window: + class nsPluginNativeWindowWin *mWin; + + PluginWindowWeakRef() : mWin(nsnull), mRefCnt(0) {} + +private: + PRInt32 mRefCnt; +}; + /** * PLEvent handling code */ -class PluginWindowEvent : public PLEvent { +class PluginWindowEvent : public nsRunnable { public: PluginWindowEvent(); - void Init(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + void Init(PluginWindowWeakRef *ref, HWND hWnd, UINT msg, WPARAM wParam, + LPARAM lParam); void Clear(); HWND GetWnd() { return mWnd; }; UINT GetMsg() { return mMsg; }; WPARAM GetWParam() { return mWParam; }; LPARAM GetLParam() { return mLParam; }; - PRBool GetIsAlloced() { return mIsAlloced; }; - void SetIsAlloced(PRBool aIsAlloced) { mIsAlloced = aIsAlloced; }; - PRBool InUse() { return (mWnd!=NULL || mMsg!=0); }; + PRBool InUse() { return (mWnd!=NULL || mMsg!=0); }; + + NS_IMETHOD Run(); protected: + nsRefPtr mPluginWindowRef; HWND mWnd; UINT mMsg; WPARAM mWParam; @@ -101,10 +116,12 @@ void PluginWindowEvent::Clear() mLParam = 0; } -void PluginWindowEvent::Init(HWND aWnd, UINT aMsg, WPARAM aWParam, LPARAM aLParam) +void PluginWindowEvent::Init(PluginWindowWeakRef *ref, HWND aWnd, UINT aMsg, + WPARAM aWParam, LPARAM aLParam) { NS_ASSERTION(aWnd!=NULL && aMsg!=0, "invalid plugin event value"); NS_ASSERTION(mWnd==NULL && mMsg==0 && mWParam==0 && mLParam==0,"event already in use"); + mPluginWindowRef = ref; mWnd = aWnd; mMsg = aMsg; mWParam = aWParam; @@ -139,14 +156,13 @@ public: // locals WNDPROC GetPrevWindowProc(); WNDPROC GetWindowProc(); - nsIEventQueueService *GetEventService(); PluginWindowEvent * GetPluginWindowEvent(HWND aWnd, UINT aMsg, WPARAM aWParam, LPARAM aLParam); private: WNDPROC mPrevWinProc; WNDPROC mPluginWinProc; - nsCOMPtr mEventService; - PluginWindowEvent mPluginWindowEvent; + nsRefPtr mWeakRef; + nsRefPtr mCachedPluginWindowEvent; public: nsPluginType mPluginType; @@ -164,43 +180,30 @@ static PRBool ProcessFlashMessageDelayed(nsPluginNativeWindowWin * aWin, return PR_FALSE; // no need to delay // do stuff - nsIEventQueueService *eventService = aWin->GetEventService(); - if (eventService) { - nsCOMPtr eventQueue; - eventService->GetThreadEventQueue(PR_GetCurrentThread(), - getter_AddRefs(eventQueue)); - if (eventQueue) { - PluginWindowEvent *pwe = aWin->GetPluginWindowEvent(hWnd, msg, wParam, lParam); - if (pwe) { - eventQueue->PostEvent(pwe); - return PR_TRUE; - } + nsCOMPtr thread = do_GetCurrentThread(); + if (thread) { + nsCOMPtr pwe = aWin->GetPluginWindowEvent(hWnd, msg, wParam, lParam); + if (pwe) { + thread->Dispatch(pwe, NS_DISPATCH_NORMAL); + return PR_TRUE; } } return PR_FALSE; } -PR_STATIC_CALLBACK(void*) -DelayedPopupsEnabledEvent_Handle(PLEvent *event) +class nsDelayedPopupsEnabledEvent : public nsRunnable { - nsIPluginInstanceInternal *instInternal = - (nsIPluginInstanceInternal *)event->owner; - - instInternal->PushPopupsEnabledState(PR_FALSE); - - return nsnull; -} - -PR_STATIC_CALLBACK(void) -DelayedPopupsEnabledEvent_Destroy(PLEvent *event) -{ - nsIPluginInstanceInternal *instInternal = - (nsIPluginInstanceInternal *)event->owner; - - NS_RELEASE(instInternal); - - delete event; -} +public: + nsDelayedPopupsEnabledEvent(nsIPluginInstanceInternal *inst) + : mInst(inst) + {} + NS_IMETHOD Run() { + mInst->PushPopupsEnabledState(PR_FALSE); + return NS_OK; + } +private: + nsCOMPtr mInst; +}; /** * New plugin window procedure @@ -375,25 +378,12 @@ static LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM // code will pop any popup state pushed by this plugin on // destruction. - nsIEventQueueService *eventService = win->GetEventService(); - if (eventService) { - nsCOMPtr eventQueue; - eventService->GetThreadEventQueue(PR_GetCurrentThread(), - getter_AddRefs(eventQueue)); - if (eventQueue) { - PLEvent *event = new PLEvent; - - if (event) { - nsIPluginInstanceInternal *eventInst = instInternal; - - // Make the event own the plugin instance. - NS_ADDREF(eventInst); - - PL_InitEvent(event, eventInst, DelayedPopupsEnabledEvent_Handle, - DelayedPopupsEnabledEvent_Destroy); - - eventQueue->PostEvent(event); - } + nsCOMPtr thread = do_GetCurrentThread(); + if (thread) { + nsCOMPtr event = + new nsDelayedPopupsEnabledEvent(instInternal); + if (event) { + thread->Dispatch(event, NS_DISPATCH_NORMAL); } } } @@ -415,21 +405,13 @@ nsPluginNativeWindowWin::nsPluginNativeWindowWin() : nsPluginNativeWindow() mPrevWinProc = NULL; mPluginWinProc = NULL; - mPluginWindowEvent.SetIsAlloced(PR_FALSE); mPluginType = nsPluginType_Unknown; } nsPluginNativeWindowWin::~nsPluginNativeWindowWin() { // clear any pending events to avoid dangling pointers - nsCOMPtr eventService(do_GetService(kEventQueueServiceCID)); - if (eventService) { - nsCOMPtr eventQueue; - eventService->GetThreadEventQueue(PR_GetCurrentThread(), getter_AddRefs(eventQueue)); - if (eventQueue) { - eventQueue->RevokeEvents(this); - } - } + mWeakRef->mWin = nsnull; } WNDPROC nsPluginNativeWindowWin::GetPrevWindowProc() @@ -442,61 +424,40 @@ WNDPROC nsPluginNativeWindowWin::GetWindowProc() return mPluginWinProc; } -PR_STATIC_CALLBACK(void*) -PluginWindowEvent_Handle(PLEvent* self) +NS_IMETHODIMP PluginWindowEvent::Run() { - if (!self) - return nsnull; + nsPluginNativeWindowWin *win = mPluginWindowRef->mWin; + if (!win) + return NS_OK; - PluginWindowEvent *event = NS_STATIC_CAST(PluginWindowEvent*, self); - - HWND hWnd = event->GetWnd(); + HWND hWnd = GetWnd(); if (!hWnd) - return nsnull; + return NS_OK; - nsPluginNativeWindowWin * win = (nsPluginNativeWindowWin *)::GetProp(hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION); - if (win) { - nsCOMPtr inst; - win->GetPluginInstance(inst); - NS_TRY_SAFE_CALL_VOID(::CallWindowProc(win->GetWindowProc(), - hWnd, - event->GetMsg(), - event->GetWParam(), - event->GetLParam()), - nsnull, inst); - } - - return nsnull; -} - -PR_STATIC_CALLBACK(void) -PluginWindowEvent_Destroy(PLEvent* self) -{ - if (!self) - return; - - PluginWindowEvent *event = NS_STATIC_CAST(PluginWindowEvent*, self); - if (event->GetIsAlloced()) { - delete event; - } - else - event->Clear(); -} - -nsIEventQueueService *nsPluginNativeWindowWin::GetEventService() -{ - if (!mEventService) { - mEventService = do_GetService(kEventQueueServiceCID); - } - - return mEventService; + nsCOMPtr inst; + win->GetPluginInstance(inst); + NS_TRY_SAFE_CALL_VOID(::CallWindowProc(win->GetWindowProc(), + hWnd, + GetMsg(), + GetWParam(), + GetLParam()), + nsnull, inst); + Clear(); + return NS_OK; } PluginWindowEvent* nsPluginNativeWindowWin::GetPluginWindowEvent(HWND aWnd, UINT aMsg, WPARAM aWParam, LPARAM aLParam) { + if (!mWeakRef) { + mWeakRef = new PluginWindowWeakRef; + if (!mWeakRef) + return nsnull; + mWeakRef->mWin = this; + } + PluginWindowEvent *event; - if (mPluginWindowEvent.InUse()) { + if (!mCachedPluginWindowEvent || mCachedPluginWindowEvent->InUse()) { // We have the ability to alloc if needed in case in the future some plugin // should post multiple PostMessages. However, this could lead to many // alloc's per second which could become a performance issue. If/when this @@ -505,15 +466,13 @@ nsPluginNativeWindowWin::GetPluginWindowEvent(HWND aWnd, UINT aMsg, WPARAM aWPar event = new PluginWindowEvent(); if (!event) return nsnull; - - event->SetIsAlloced(PR_TRUE); } else { - event = &mPluginWindowEvent; + event = mCachedPluginWindowEvent; } + NS_ADDREF(event); - event->Init(aWnd, aMsg, aWParam, aLParam); - PL_InitEvent(event, (void *)this, &PluginWindowEvent_Handle, PluginWindowEvent_Destroy); + event->Init(mWeakRef, aWnd, aMsg, aWParam, aLParam); return event; }