зеркало из https://github.com/mozilla/pjs.git
merge bent's changes from libchromiumipc. Gtk plugins now drawing
This commit is contained in:
Родитель
dfbd660460
Коммит
808c61f598
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче