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:
darin%meer.net
2006-02-20 18:09:43 +00:00
parent 1af1b725f9
commit 59fd29cd6e
2 changed files with 81 additions and 121 deletions

View File

@@ -968,6 +968,7 @@ public:
} else {
NS_WARNING("missing library from nsPluginUnloadEvent");
}
return NS_OK;
}
PRLibrary* mLibrary;

View File

@@ -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;
}