porting to windows
git-svn-id: svn://10.0.0.236/branches/THREADS_20060213_BRANCH@190582 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -968,6 +968,7 @@ public:
|
||||
} else {
|
||||
NS_WARNING("missing library from nsPluginUnloadEvent");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRLibrary* mLibrary;
|
||||
|
||||
@@ -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<PluginWindowWeakRef> 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<nsIEventQueueService> mEventService;
|
||||
PluginWindowEvent mPluginWindowEvent;
|
||||
nsRefPtr<PluginWindowWeakRef> mWeakRef;
|
||||
nsRefPtr<PluginWindowEvent> 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<nsIEventQueue> 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<nsIThread> thread = do_GetCurrentThread();
|
||||
if (thread) {
|
||||
nsCOMPtr<nsIRunnable> 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<nsIPluginInstanceInternal> 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<nsIEventQueue> 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<nsIThread> thread = do_GetCurrentThread();
|
||||
if (thread) {
|
||||
nsCOMPtr<nsIRunnable> 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<nsIEventQueueService> eventService(do_GetService(kEventQueueServiceCID));
|
||||
if (eventService) {
|
||||
nsCOMPtr<nsIEventQueue> 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<nsIPluginInstance> 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<nsIPluginInstance> 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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user