merge bent's changes from libchromiumipc. Gtk plugins now drawing

This commit is contained in:
Ben Turner 2009-07-01 14:19:32 -07:00
Родитель dfbd660460
Коммит 808c61f598
14 изменённых файлов: 366 добавлений и 157 удалений

Просмотреть файл

@ -17,7 +17,6 @@ rpc protocol NPAPI
rpc out NPP(String aMimeType,
int aHandle,
uint16_t aMode,
StringArray aNames,
StringArray aValues) returns (NPError rv);

Просмотреть файл

@ -914,7 +914,6 @@ NPAPIPluginChild::AnswerNP_Initialize(NPError* rv)
NPPProtocolChild*
NPAPIPluginChild::NPPConstructor(const String& aMimeType,
/*const NPPParent*&*/const int& aHandle,
const uint16_t& aMode,
const StringArray& aNames,
const StringArray& aValues,
@ -923,7 +922,12 @@ NPAPIPluginChild::NPPConstructor(const String& aMimeType,
_MOZ_LOG(__FUNCTION__);
// create our wrapper instance
NPPInstanceChild* childInstance = new NPPInstanceChild(&mFunctions);
nsAutoPtr<NPPInstanceChild> childInstance(
new NPPInstanceChild(&mFunctions));
if (!childInstance->Initialize()) {
*rv = NPERR_GENERIC_ERROR;
return 0;
}
// unpack the arguments into a C format
int argc = aNames.size();
@ -967,13 +971,19 @@ out:
free(argn);
free(argv);
return childInstance;
return childInstance.forget();
}
nsresult
NPAPIPluginChild::NPPDestructor(NPPProtocolChild* actor, NPError* rv)
{
_MOZ_LOG(__FUNCTION__);
NPPInstanceChild* inst = static_cast<NPPInstanceChild*>(actor);
*rv = mFunctions.destroy(inst->GetNPP(), 0);
delete actor;
inst->GetNPP()->ndata = 0;
return NS_OK;
}

Просмотреть файл

@ -52,7 +52,7 @@
#include "npfunctions.h"
#include "nsplugindefs.h"
#include "base/hash_tables.h"
#include "nsAutoPtr.h"
#include "mozilla/plugins/NPAPIProtocolChild.h"
#include "mozilla/plugins/NPPInstanceChild.h"
@ -102,7 +102,6 @@ protected:
virtual NPPProtocolChild* NPPConstructor(
const String& aMimeType,
/*const NPPParent*&*/const int& aHandle,
const uint16_t& aMode,
const StringArray& aNames,
const StringArray& aValues,
@ -130,9 +129,6 @@ private:
std::string mPluginFilename;
PRLibrary* mLibrary;
// base::hash_map<int, Instance*> mInstances;
// int mNextInstanceId;
// we get this from the plugin
#ifdef OS_LINUX
NP_PLUGINUNIXINIT mInitializeFunc;

Просмотреть файл

@ -106,12 +106,12 @@ NPAPIPluginParent::LaunchSubprocess()
NPPProtocolParent*
NPAPIPluginParent::NPPConstructor(const String& aMimeType,
const int& aHandle,
const uint16_t& aMode,
const StringArray& aNames,
const StringArray& aValues,
NPError* rv)
{
_MOZ_LOG(__FUNCTION__);
return new NPPInstanceParent(mNPNIface);
}
@ -119,7 +119,8 @@ nsresult
NPAPIPluginParent::NPPDestructor(NPPProtocolParent* __a,
NPError* rv)
{
return NS_OK;
_MOZ_LOG(__FUNCTION__);
delete __a;
}
void
@ -205,12 +206,11 @@ NPAPIPluginParent::NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode,
}
NPError prv;
NPPInstanceParent* parentInstance = static_cast<NPPInstanceParent*>(
CallNPPConstructor(pluginType,
/*instance*/42,
mode, names,
values,
&prv));
nsAutoPtr<NPPInstanceParent> parentInstance(
static_cast<NPPInstanceParent*>(CallNPPConstructor(pluginType,
mode, names,
values,
&prv)));
printf ("[NPAPIPluginParent] %s: got return value %hd\n", __FUNCTION__,
prv);
@ -219,15 +219,34 @@ NPAPIPluginParent::NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode,
NS_ASSERTION(parentInstance,
"if there's no parentInstance, there should be an error");
// FIXME/cjones: HACK ALERT! kill this and manage through NPAPI
// parentInstance->mNpp.SetChannel(mNpapi.HACK_getchannel_please());
// mNpapi.HACK_npp = &(parentInstance->mNpp);
instance->pdata = (void*) parentInstance;
instance->pdata = (void*) parentInstance.forget();
return prv;
}
NPError
NPAPIPluginParent::NPP_Destroy(NPP instance,
NPSavedData** save)
{
// FIXME/cjones:
// (1) send a "destroy" message to the child
// (2) the child shuts down its instance
// (3) remove both parent and child IDs from map
// (4) free parent
_MOZ_LOG(__FUNCTION__);
NPPInstanceParent* parentInstance =
static_cast<NPPInstanceParent*>(instance->pdata);
NPError prv;
if (CallNPPDestructor(parentInstance, &prv)) {
prv = NPERR_GENERIC_ERROR;
}
instance->pdata = nsnull;
return prv;
}
// HACKS
NPAPIPluginParent* NPAPIPluginParent::Shim::HACK_target;

Просмотреть файл

@ -58,6 +58,8 @@
#include "mozilla/plugins/NPPInstanceParent.h"
#include "mozilla/plugins/PluginProcessParent.h"
#include "nsAutoPtr.h"
#undef _MOZ_LOG
#define _MOZ_LOG(s) printf("[NPAPIPluginParent] %s\n", s)
@ -84,7 +86,6 @@ private:
protected:
NPPProtocolParent* NPPConstructor(
const String& aMimeType,
const int& aHandle,
const uint16_t& aMode,
const StringArray& aNames,
const StringArray& aValues,
@ -161,17 +162,7 @@ private:
int16_t argc, char* argn[], char* argv[],
NPSavedData* saved);
NPError NPP_Destroy(NPP instance, NPSavedData** save)
{
// FIXME/cjones:
// (1) send a "destroy" message to the child
// (2) the child shuts down its instance
// (3) remove both parent and child IDs from map
// (4) free parent
_MOZ_LOG(__FUNCTION__);
return 1;
}
NPError NPP_Destroy(NPP instance, NPSavedData** save);
static inline NPPInstanceParent& InstCast(void* p)
{

Просмотреть файл

@ -96,7 +96,6 @@ public:
};
Msg_NPPConstructor(
const String& aMimeType,
const int& aHandle,
const uint16_t& aMode,
const StringArray& aNames,
const StringArray& aValues,
@ -104,7 +103,6 @@ public:
IPC::Message(MSG_ROUTING_NONE, ID, PRIORITY_NORMAL)
{
IPC::WriteParam(this, aMimeType);
IPC::WriteParam(this, aHandle);
IPC::WriteParam(this, aMode);
IPC::WriteParam(this, aNames);
IPC::WriteParam(this, aValues);
@ -114,7 +112,6 @@ public:
static bool Read(
const Message* msg,
String* aMimeType,
int* aHandle,
uint16_t* aMode,
StringArray* aNames,
StringArray* aValues,
@ -126,10 +123,6 @@ public:
return false;
}
if (!(IPC::ReadParam(msg, &(iter), aHandle))) {
return false;
}
if (!(IPC::ReadParam(msg, &(iter), aMode))) {
return false;
}

Просмотреть файл

@ -26,7 +26,6 @@ protected:
virtual nsresult AnswerNP_Initialize(NPError* rv) = 0;
virtual NPPProtocolChild* NPPConstructor(
const String& aMimeType,
const int& aHandle,
const uint16_t& aMode,
const StringArray& aNames,
const StringArray& aValues,
@ -117,19 +116,18 @@ public:
case NPAPIProtocol::Msg_NPPConstructor__ID:
{
String aMimeType;
int aHandle;
uint16_t aMode;
StringArray aNames;
StringArray aValues;
NPError rv;
mozilla::ipc::ActorHandle __ah;
if (!(NPAPIProtocol::Msg_NPPConstructor::Read(&(msg), &(aMimeType), &(aHandle), &(aMode), &(aNames), &(aValues), &(__ah)))) {
if (!(NPAPIProtocol::Msg_NPPConstructor::Read(&(msg), &(aMimeType), &(aMode), &(aNames), &(aValues), &(__ah)))) {
return MsgPayloadError;
}
NPPProtocolChild* __a;
__a = NPPConstructor(aMimeType, aHandle, aMode, aNames, aValues, &(rv));
__a = NPPConstructor(aMimeType, aMode, aNames, aValues, &(rv));
if (!(__a)) {
return MsgValueError;
}

Просмотреть файл

@ -25,7 +25,6 @@ protected:
virtual NPPProtocolParent* NPPConstructor(
const String& aMimeType,
const int& aHandle,
const uint16_t& aMode,
const StringArray& aNames,
const StringArray& aValues,
@ -77,14 +76,13 @@ public:
NPPProtocolParent* CallNPPConstructor(
const String& aMimeType,
const int& aHandle,
const uint16_t& aMode,
const StringArray& aNames,
const StringArray& aValues,
NPError* rv)
{
NPPProtocolParent* __a;
__a = NPPConstructor(aMimeType, aHandle, aMode, aNames, aValues, rv);
__a = NPPConstructor(aMimeType, aMode, aNames, aValues, rv);
if (!(__a)) {
return 0;
}
@ -94,7 +92,7 @@ public:
Message __reply;
Message* __msg;
__msg = new NPAPIProtocol::Msg_NPPConstructor(aMimeType, aHandle, aMode, aNames, aValues, __ah);
__msg = new NPAPIProtocol::Msg_NPPConstructor(aMimeType, aMode, aNames, aValues, __ah);
__msg->set_routing_id(MSG_ROUTING_CONTROL);
if (!(mChannel.Call(__msg, &(__reply)))) {
return 0;

Просмотреть файл

@ -38,11 +38,17 @@
#include "NPPInstanceChild.h"
#ifdef OS_LINUX
#if defined(OS_LINUX)
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <gdk/gdk.h>
#include "gtk2xtbin.h"
#elif defined(OS_WIN)
#include <windows.h>
#endif
namespace mozilla {
@ -81,6 +87,13 @@ NPNVariableToString(NPNVariable aVar)
#undef VARSTR
}
NPPInstanceChild::~NPPInstanceChild()
{
#if defined(OS_WIN)
DestroyPluginWindow();
#endif
}
NPError
NPPInstanceChild::NPN_GetValue(NPNVariable aVar, void* aValue)
{
@ -90,14 +103,14 @@ NPPInstanceChild::NPN_GetValue(NPNVariable aVar, void* aValue)
switch(aVar) {
case NPNVSupportsWindowless:
// FIXME/cjones report PR_TRUE here and use XComposite + child
// FIXME/cjones report true here and use XComposite + child
// surface to implement windowless plugins
*((NPBool*)aValue) = PR_FALSE;
*((NPBool*)aValue) = false;
return NPERR_NO_ERROR;
#if defined(OS_LINUX)
case NPNVSupportsXEmbedBool:
*((NPBool*)aValue) = PR_TRUE;
*((NPBool*)aValue) = true;
return NPERR_NO_ERROR;
case NPNVToolkit:
@ -159,20 +172,189 @@ NPPInstanceChild::AnswerNPP_SetWindow(const NPWindow& aWindow, NPError* rv)
mWindow.ws_info = (void*) &mWsInfo;
*rv = mPluginIface->setwindow(&mData, &mWindow);
#elif defined(OS_WIN)
mWindow.window = aWindow.window;
ReparentPluginWindow((HWND)aWindow.window);
SizePluginWindow(aWindow.width, aWindow.height);
mWindow.window = (void*)mPluginWindowHWND;
mWindow.width = aWindow.width;
mWindow.height = aWindow.height;
mWindow.type = NPWindowTypeWindow;
*rv = mPluginIface->setwindow(&mData, &mWindow);
if (*rv == NPERR_NO_ERROR) {
WNDPROC wndProc = reinterpret_cast<WNDPROC>(
GetWindowLongPtr(mPluginWindowHWND, GWLP_WNDPROC));
if (wndProc != PluginWindowProc) {
mPluginWndProc = reinterpret_cast<WNDPROC>(
SetWindowLongPtr(mPluginWindowHWND, GWLP_WNDPROC,
reinterpret_cast<LONG>(PluginWindowProc)));
}
}
#else
# error Implement me for your OS
#endif
*rv = mPluginIface->setwindow(&mData, &mWindow);
return NS_OK;
}
bool
NPPInstanceChild::Initialize()
{
#if defined(OS_WIN)
if (!CreatePluginWindow())
return false;
#endif
return true;
}
#if defined(OS_WIN)
static const TCHAR kWindowClassName[] = TEXT("GeckoPluginWindow");
static const TCHAR kNPPInstanceChildProperty[] = TEXT("NPPInstanceChildProperty");
// static
bool
NPPInstanceChild::RegisterWindowClass()
{
static bool alreadyRegistered = false;
if (alreadyRegistered)
return true;
alreadyRegistered = true;
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_DBLCLKS;
wcex.lpfnWndProc = DummyWindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = GetModuleHandle(NULL);
wcex.hIcon = 0;
wcex.hCursor = 0;
wcex.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW1);
wcex.lpszMenuName = 0;
wcex.lpszClassName = kWindowClassName;
wcex.hIconSm = 0;
return RegisterClassEx(&wcex) ? true : false;
}
bool
NPPInstanceChild::CreatePluginWindow()
{
if (!RegisterWindowClass())
return false;
if (!mPluginWindowHWND) {
mPluginWindowHWND =
CreateWindowEx(WS_EX_LEFT | WS_EX_LTRREADING |
WS_EX_NOPARENTNOTIFY | // XXXbent Get rid of this!
WS_EX_RIGHTSCROLLBAR,
kWindowClassName, 0,
WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0,
0, 0, NULL, 0, GetModuleHandle(NULL), 0);
if (!mPluginWindowHWND)
return false;
if (!SetProp(mPluginWindowHWND, kNPPInstanceChildProperty, this))
return false;
// Apparently some plugins require an ASCII WndProc.
SetWindowLongPtrA(mPluginWindowHWND, GWLP_WNDPROC,
reinterpret_cast<LONG>(DefWindowProcA));
}
return true;
}
void
NPPInstanceChild::DestroyPluginWindow()
{
if (mPluginWindowHWND) {
// Unsubclass the window.
WNDPROC wndProc = reinterpret_cast<WNDPROC>(
GetWindowLongPtr(mPluginWindowHWND, GWLP_WNDPROC));
if (wndProc == PluginWindowProc) {
NS_ASSERTION(mPluginWndProc, "Should have old proc here!");
SetWindowLongPtr(mPluginWindowHWND, GWLP_WNDPROC,
reinterpret_cast<LONG>(mPluginWndProc));
mPluginWndProc = 0;
}
RemoveProp(mPluginWindowHWND, kNPPInstanceChildProperty);
DestroyWindow(mPluginWindowHWND);
mPluginWindowHWND = 0;
}
}
void
NPPInstanceChild::ReparentPluginWindow(HWND hWndParent)
{
if (hWndParent != mPluginParentHWND && IsWindow(hWndParent)) {
LONG style = GetWindowLongPtr(mPluginWindowHWND, GWL_STYLE);
style |= WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
SetWindowLongPtr(mPluginWindowHWND, GWL_STYLE, style);
SetParent(mPluginWindowHWND, hWndParent);
ShowWindow(mPluginWindowHWND, SW_SHOWNA);
}
mPluginParentHWND = hWndParent;
}
void
NPPInstanceChild::SizePluginWindow(int width,
int height)
{
if (mPluginWindowHWND) {
SetWindowPos(mPluginWindowHWND, NULL, 0, 0, width, height,
SWP_NOZORDER | SWP_NOREPOSITION);
}
}
// See chromium's webplugin_delegate_impl.cc for explanation of this function.
// static
LRESULT CALLBACK
NPPInstanceChild::DummyWindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
return CallWindowProc(DefWindowProc, hWnd, message, wParam, lParam);
}
// static
LRESULT CALLBACK
NPPInstanceChild::PluginWindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
NPPInstanceChild* self = reinterpret_cast<NPPInstanceChild*>(
GetProp(hWnd, kNPPInstanceChildProperty));
if (!self) {
NS_NOTREACHED("Badness!");
return 0;
}
NS_ASSERTION(self->mPluginWindowHWND == hWnd, "Wrong window!");
LRESULT res = CallWindowProc(self->mPluginWndProc, hWnd, message, wParam,
lParam);
if (message == WM_CLOSE)
self->DestroyPluginWindow();
if (message == WM_NCDESTROY)
RemoveProp(hWnd, kNPPInstanceChildProperty);
return res;
}
#endif // OS_WIN
} // namespace plugins
} // namespace mozilla

Просмотреть файл

@ -52,6 +52,13 @@ namespace plugins {
class NPPInstanceChild : public NPPProtocolChild
{
#ifdef OS_WIN
friend LRESULT CALLBACK PluginWindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
#endif
protected:
virtual nsresult AnswerNPP_SetWindow(const NPWindow& window, NPError* rv);
@ -60,15 +67,24 @@ protected:
public:
NPPInstanceChild(const NPPluginFuncs* aPluginIface) :
mPluginIface(aPluginIface)
#if defined(OS_LINUX)
, mPlug(0)
#elif defined(OS_WIN)
, mPluginWindowHWND(0)
, mPluginWndProc(0)
, mPluginParentHWND(0)
#endif
{
memset(&mWindow, 0, sizeof(mWindow));
mData.ndata = (void*) this;
#if defined(OS_LINUX)
memset(&mWsInfo, 0, sizeof(mWsInfo));
#endif
}
virtual ~NPPInstanceChild()
{
virtual ~NPPInstanceChild();
}
bool Initialize();
NPP GetNPP()
{
@ -78,6 +94,23 @@ public:
NPError NPN_GetValue(NPNVariable aVariable, void* aValue);
private:
#if defined(OS_WIN)
static bool RegisterWindowClass();
bool CreatePluginWindow();
void DestroyPluginWindow();
void ReparentPluginWindow(HWND hWndParent);
void SizePluginWindow(int width, int height);
static LRESULT CALLBACK DummyWindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
static LRESULT CALLBACK PluginWindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
#endif
const NPPluginFuncs* mPluginIface;
NPP_t mData;
#ifdef OS_LINUX
@ -86,6 +119,10 @@ private:
NPWindow mWindow;
#ifdef OS_LINUX
NPSetWindowCallbackStruct mWsInfo;
#elif defined(OS_WIN)
HWND mPluginWindowHWND;
WNDPROC mPluginWndProc;
HWND mPluginParentHWND;
#endif
};

Просмотреть файл

@ -38,13 +38,15 @@
#include "nsIAppShell.h"
#include "nsIThread.h"
#include "nsIThreadInternal.h"
#include "nsITimer.h"
#include "nsComponentManagerUtils.h"
#include "nsCOMPtr.h"
#include "nsServiceManagerUtils.h"
#include "nsStringGlue.h"
#include "nsThreadUtils.h"
#include "nsWidgetsCID.h"
#include "pratom.h"
#include "prthread.h"
#include "base/logging.h"
@ -55,74 +57,29 @@ using mozilla::ipc::MessagePumpForChildProcess;
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
namespace mozilla {
namespace ipc {
namespace {
class UIThreadObserver : public nsIThreadObserver
void
TimerCallback(nsITimer* aTimer,
void* aClosure)
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSITHREADOBSERVER
UIThreadObserver(MessagePump& aPump,
nsIThreadObserver* aRealObserver)
: mPump(aPump),
mRealObserver(aRealObserver),
mPRThread(PR_GetCurrentThread())
{
NS_ASSERTION(aRealObserver, "This should never be null!");
}
private:
MessagePump& mPump;
nsIThreadObserver* mRealObserver;
PRThread* mPRThread;
};
} /* namespace ipc */
} /* namespace mozilla */
using mozilla::ipc::UIThreadObserver;
NS_IMETHODIMP_(nsrefcnt)
UIThreadObserver::AddRef()
{
return 2;
MessagePump* messagePump = reinterpret_cast<MessagePump*>(aClosure);
messagePump->ScheduleWork();
}
NS_IMETHODIMP_(nsrefcnt)
UIThreadObserver::Release()
} /* anonymous namespace */
MessagePump::MessagePump()
: mThread(nsnull)
{
return 1;
mDummyEvent = new nsRunnable();
// I'm tired of adding OOM checks.
NS_ADDREF(mDummyEvent);
}
NS_IMPL_QUERY_INTERFACE1(UIThreadObserver, nsIThreadObserver)
NS_IMETHODIMP
UIThreadObserver::OnDispatchedEvent(nsIThreadInternal* aThread)
MessagePump::~MessagePump()
{
// XXXbent See if we can figure out some faster way of doing this. On posix
// the Signal() call grabs a lock and on windows it calls SetEvent. Seems
// like a good idea to avoid calling Signal if we're on the main thead.
if (PR_GetCurrentThread() != mPRThread) {
mPump.event_.Signal();
}
return mRealObserver->OnDispatchedEvent(aThread);
}
NS_IMETHODIMP
UIThreadObserver::OnProcessNextEvent(nsIThreadInternal* aThread,
PRBool aMayWait,
PRUint32 aRecursionDepth)
{
return mRealObserver->OnProcessNextEvent(aThread, aMayWait, aRecursionDepth);
}
NS_IMETHODIMP
UIThreadObserver::AfterProcessNextEvent(nsIThreadInternal* aThread,
PRUint32 aRecursionDepth)
{
return mRealObserver->AfterProcessNextEvent(aThread, aRecursionDepth);
NS_RELEASE(mDummyEvent);
}
void
@ -130,33 +87,22 @@ MessagePump::Run(MessagePump::Delegate* aDelegate)
{
NS_ASSERTION(keep_running_, "Quit must have been called outside of Run!");
nsCOMPtr<nsIThread> thread(do_GetCurrentThread());
NS_ASSERTION(thread, "This should never be null!");
NS_ASSERTION(NS_IsMainThread(),
"This should only ever happen on Gecko's main thread!");
nsCOMPtr<nsIThreadInternal> threadInternal(do_QueryInterface(thread));
NS_ASSERTION(threadInternal, "QI failed?!");
mThread = NS_GetCurrentThread();
NS_ASSERTION(mThread, "This should never be null!");
nsCOMPtr<nsIThreadObserver> realObserver;
threadInternal->GetObserver(getter_AddRefs(realObserver));
NS_ASSERTION(realObserver, "This should never be null!");
UIThreadObserver observer(*this, realObserver);
threadInternal->SetObserver(&observer);
#ifdef DEBUG
{
nsCOMPtr<nsIAppShell> appShell(do_QueryInterface(realObserver));
NS_ASSERTION(appShell, "Should be the app shell!");
}
#endif
nsCOMPtr<nsITimer> timer(do_CreateInstance(NS_TIMER_CONTRACTID));
NS_ASSERTION(timer, "Failed to create timer!");
base::ScopedNSAutoreleasePool autoReleasePool;
for (;;) {
// XXXbent This looks fishy... Maybe have one that calls Recycle each time
// through the loop? Copied straight from message_pump_default.
base::ScopedNSAutoreleasePool autorelease_pool;
autoReleasePool.Recycle();
timer->Cancel();
bool did_work = NS_ProcessNextEvent(thread, PR_FALSE) ? true : false;
bool did_work = NS_ProcessNextEvent(mThread, PR_FALSE) ? true : false;
if (!keep_running_)
break;
@ -179,26 +125,42 @@ MessagePump::Run(MessagePump::Delegate* aDelegate)
continue;
if (delayed_work_time_.is_null()) {
event_.Wait();
} else {
base::TimeDelta delay = delayed_work_time_ - base::Time::Now();
if (delay > base::TimeDelta()) {
event_.TimedWait(delay);
} else {
// It looks like delayed_work_time_ indicates a time in the past, so we
// need to call DoDelayedWork now.
delayed_work_time_ = base::Time();
}
// This will sleep or process native events.
NS_ProcessNextEvent(mThread, PR_TRUE);
continue;
}
// Since event_ is auto-reset, we don't need to do anything special here
// other than service each delegate method.
base::TimeDelta delay = delayed_work_time_ - base::Time::Now();
if (delay > base::TimeDelta()) {
PRUint32 delayMS = PRUint32(delay.InMilliseconds());
timer->InitWithFuncCallback(TimerCallback, this, delayMS,
nsITimer::TYPE_ONE_SHOT);
// This will sleep or process native events. The timer should wake us up
// if nothing else does.
NS_ProcessNextEvent(mThread, PR_TRUE);
continue;
}
// It looks like delayed_work_time_ indicates a time in the past, so we
// need to call DoDelayedWork now.
delayed_work_time_ = base::Time();
}
threadInternal->SetObserver(realObserver);
timer->Cancel();
keep_running_ = true;
}
void
MessagePump::ScheduleWork()
{
// Make sure the event loop wakes up.
if (mThread) {
mThread->Dispatch(mDummyEvent, NS_DISPATCH_NORMAL);
event_.Signal();
}
}
#ifdef DEBUG
namespace {
MessagePump::Delegate* gFirstDelegate = nsnull;
@ -228,8 +190,10 @@ MessagePumpForChildProcess::Run(MessagePump::Delegate* aDelegate)
#endif
return;
}
#ifdef DEBUG
NS_ASSERTION(aDelegate && aDelegate == gFirstDelegate, "Huh?!");
#endif
// Really run.
mozilla::ipc::MessagePump::Run(aDelegate);
}

Просмотреть файл

@ -39,15 +39,29 @@
#include "base/message_pump_default.h"
#include "prtypes.h"
#include "nsCOMPtr.h"
class nsIRunnable;
class nsIThread;
namespace mozilla {
namespace ipc {
class MessagePump : public base::MessagePumpDefault
{
public:
friend class UIThreadObserver;
MessagePump();
~MessagePump();
virtual void Run(base::MessagePump::Delegate* aDelegate);
virtual void ScheduleWork();
private:
nsIRunnable* mDummyEvent;
// Weak!
nsIThread* mThread;
};
class MessagePumpForChildProcess : public MessagePump

Просмотреть файл

@ -542,6 +542,10 @@ nsresult nsPluginNativeWindowWin::SubclassAndAssociateWindow()
if (PluginWndProc == currentWndProc)
return NS_OK;
LONG style = GetWindowLongPtr(hWnd, GWL_STYLE);
style |= WS_CLIPCHILDREN;
SetWindowLongPtr(hWnd, GWL_STYLE, style);
mPluginWinProc = SubclassWindow(hWnd, (LONG_PTR)PluginWndProc);
if (!mPluginWinProc)
return NS_ERROR_FAILURE;
@ -571,6 +575,10 @@ nsresult nsPluginNativeWindowWin::UndoSubclassAndAssociateWindow()
WNDPROC currentWndProc = (WNDPROC)::GetWindowLongPtr(hWnd, GWLP_WNDPROC);
if (currentWndProc == PluginWndProc)
SubclassWindow(hWnd, (LONG_PTR)mPluginWinProc);
LONG style = GetWindowLongPtr(hWnd, GWL_STYLE);
style &= ~WS_CLIPCHILDREN;
SetWindowLongPtr(hWnd, GWL_STYLE, style);
}
return NS_OK;

Просмотреть файл

@ -154,7 +154,7 @@ pluginDrawWindow(InstanceData* instanceData, GdkDrawable* gdkWindow)
int width = window.width;
int height = window.height;
if (instanceData->scriptableObject->drawMode == DM_SOLID_COLOR) {
if (0 && instanceData->scriptableObject->drawMode == DM_SOLID_COLOR) {
// drawing a solid color for reftests
pluginDrawSolid(instanceData, gdkWindow, x, y, width, height);
return;