зеркало из https://github.com/mozilla/pjs.git
Bug 547353 - [OOPP] Mouse pointer coordinates misaligned with winless Silverlight. r=bent.
This commit is contained in:
Родитель
27fa3622a3
Коммит
14da2adae7
|
@ -61,6 +61,7 @@ using namespace mozilla::plugins;
|
|||
using mozilla::gfx::SharedDIB;
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
#define NS_OOPP_DOUBLEPASS_MSGID TEXT("MozDoublePassMsg")
|
||||
|
||||
|
@ -73,10 +74,12 @@ using mozilla::gfx::SharedDIB;
|
|||
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface) :
|
||||
mPluginIface(aPluginIface),
|
||||
mCachedWindowActor(nsnull),
|
||||
mCachedElementActor(nsnull)
|
||||
PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
|
||||
const nsCString& aMimeType) :
|
||||
mPluginIface(aPluginIface)
|
||||
, mCachedWindowActor(nsnull)
|
||||
, mCachedElementActor(nsnull)
|
||||
, mQuirks(0)
|
||||
#if defined(OS_WIN)
|
||||
, mPluginWindowHWND(0)
|
||||
, mPluginWndProc(0)
|
||||
|
@ -104,6 +107,7 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface) :
|
|||
memset(&mAlphaExtract, 0, sizeof(mAlphaExtract));
|
||||
mAlphaExtract.doublePassEvent = ::RegisterWindowMessage(NS_OOPP_DOUBLEPASS_MSGID);
|
||||
#endif // OS_WIN
|
||||
InitQuirksModes(aMimeType);
|
||||
}
|
||||
|
||||
PluginInstanceChild::~PluginInstanceChild()
|
||||
|
@ -113,6 +117,19 @@ PluginInstanceChild::~PluginInstanceChild()
|
|||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceChild::InitQuirksModes(const nsCString& aMimeType)
|
||||
{
|
||||
#ifdef OS_WIN
|
||||
// application/x-silverlight
|
||||
// application/x-silverlight-2
|
||||
NS_NAMED_LITERAL_CSTRING(silverlight, "application/x-silverlight");
|
||||
if (FindInReadable(silverlight, aMimeType)) {
|
||||
mQuirks |= QUIRK_SILVERLIGHT_WINLESS_INPUT_TRANSLATION;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NPError
|
||||
PluginInstanceChild::InternalGetNPObjectForValue(NPNVariable aValue,
|
||||
NPObject** aObject)
|
||||
|
@ -791,23 +808,6 @@ PluginInstanceChild::PluginWindowProc(HWND hWnd,
|
|||
|
||||
/* winless modal ui loop logic */
|
||||
|
||||
static bool
|
||||
IsUserInputEvent(UINT msg)
|
||||
{
|
||||
// Events we assume some sort of modal ui *might* be generated.
|
||||
switch (msg) {
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_CONTEXTMENU:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
VOID CALLBACK
|
||||
PluginInstanceChild::PumpTimerProc(HWND hwnd,
|
||||
UINT uMsg,
|
||||
|
@ -923,42 +923,101 @@ PluginInstanceChild::InternalCallSetNestedEventState(bool aState)
|
|||
}
|
||||
}
|
||||
|
||||
/* windowless handle event helpers */
|
||||
|
||||
static bool
|
||||
NeedsNestedEventCoverage(UINT msg)
|
||||
{
|
||||
// Events we assume some sort of modal ui *might* be generated.
|
||||
switch (msg) {
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_CONTEXTMENU:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsMouseInputEvent(UINT msg)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_MBUTTONDBLCLK:
|
||||
case WM_RBUTTONDBLCLK:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int16_t
|
||||
PluginInstanceChild::WinlessHandleEvent(NPEvent& event)
|
||||
{
|
||||
if (!IsUserInputEvent(event.event)) {
|
||||
return mPluginIface->event(&mData, reinterpret_cast<void*>(&event));
|
||||
}
|
||||
// Winless Silverlight quirk: winposchanged events are not used in
|
||||
// determining the position of the plugin within the parent window,
|
||||
// NPP_SetWindow values are used instead. Due to shared memory dib
|
||||
// rendering, the origin of NPP_SetWindow is 0x0, so we trap
|
||||
// winposchanged events here and do the translation internally for
|
||||
// mouse input events.
|
||||
if (mQuirks & QUIRK_SILVERLIGHT_WINLESS_INPUT_TRANSLATION) {
|
||||
if (event.event == WM_WINDOWPOSCHANGED && event.lParam) {
|
||||
WINDOWPOS* pos = reinterpret_cast<WINDOWPOS*>(event.lParam);
|
||||
mPluginOffset.x = pos->x;
|
||||
mPluginOffset.y = pos->y;
|
||||
}
|
||||
else if (IsMouseInputEvent(event.event)) {
|
||||
event.lParam =
|
||||
MAKELPARAM((GET_X_LPARAM(event.lParam) - mPluginOffset.x),
|
||||
(GET_Y_LPARAM(event.lParam) - mPluginOffset.y));
|
||||
}
|
||||
}
|
||||
|
||||
int16_t handled;
|
||||
if (!NeedsNestedEventCoverage(event.event)) {
|
||||
return mPluginIface->event(&mData, reinterpret_cast<void*>(&event));
|
||||
}
|
||||
|
||||
mNestedEventLevelDepth++;
|
||||
PLUGIN_LOG_DEBUG(("WinlessHandleEvent start depth: %i", mNestedEventLevelDepth));
|
||||
// Events that might generate nested event dispatch loops need
|
||||
// special handling during delivery.
|
||||
int16_t handled;
|
||||
|
||||
// On the first, non-reentrant call, setup our modal ui detection hook.
|
||||
if (mNestedEventLevelDepth == 1) {
|
||||
NS_ASSERTION(!gTempChildPointer, "valid gTempChildPointer here?");
|
||||
gTempChildPointer = this;
|
||||
SetNestedInputEventHook();
|
||||
}
|
||||
mNestedEventLevelDepth++;
|
||||
PLUGIN_LOG_DEBUG(("WinlessHandleEvent start depth: %i", mNestedEventLevelDepth));
|
||||
|
||||
bool old_state = MessageLoop::current()->NestableTasksAllowed();
|
||||
MessageLoop::current()->SetNestableTasksAllowed(true);
|
||||
handled = mPluginIface->event(&mData, reinterpret_cast<void*>(&event));
|
||||
MessageLoop::current()->SetNestableTasksAllowed(old_state);
|
||||
// On the first, non-reentrant call, setup our modal ui detection hook.
|
||||
if (mNestedEventLevelDepth == 1) {
|
||||
NS_ASSERTION(!gTempChildPointer, "valid gTempChildPointer here?");
|
||||
gTempChildPointer = this;
|
||||
SetNestedInputEventHook();
|
||||
}
|
||||
|
||||
gTempChildPointer = NULL;
|
||||
bool old_state = MessageLoop::current()->NestableTasksAllowed();
|
||||
MessageLoop::current()->SetNestableTasksAllowed(true);
|
||||
handled = mPluginIface->event(&mData, reinterpret_cast<void*>(&event));
|
||||
MessageLoop::current()->SetNestableTasksAllowed(old_state);
|
||||
|
||||
mNestedEventLevelDepth--;
|
||||
PLUGIN_LOG_DEBUG(("WinlessHandleEvent end depth: %i", mNestedEventLevelDepth));
|
||||
gTempChildPointer = NULL;
|
||||
|
||||
NS_ASSERTION(!(mNestedEventLevelDepth < 0), "mNestedEventLevelDepth < 0?");
|
||||
if (mNestedEventLevelDepth <= 0) {
|
||||
ResetNestedEventHook();
|
||||
ResetPumpHooks();
|
||||
InternalCallSetNestedEventState(false);
|
||||
}
|
||||
return handled;
|
||||
mNestedEventLevelDepth--;
|
||||
PLUGIN_LOG_DEBUG(("WinlessHandleEvent end depth: %i", mNestedEventLevelDepth));
|
||||
|
||||
NS_ASSERTION(!(mNestedEventLevelDepth < 0), "mNestedEventLevelDepth < 0?");
|
||||
if (mNestedEventLevelDepth <= 0) {
|
||||
ResetNestedEventHook();
|
||||
ResetPumpHooks();
|
||||
InternalCallSetNestedEventState(false);
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
/* windowless drawing helpers */
|
||||
|
|
|
@ -149,7 +149,7 @@ protected:
|
|||
AnswerUpdateWindow();
|
||||
|
||||
public:
|
||||
PluginInstanceChild(const NPPluginFuncs* aPluginIface);
|
||||
PluginInstanceChild(const NPPluginFuncs* aPluginIface, const nsCString& aMimeType);
|
||||
|
||||
virtual ~PluginInstanceChild();
|
||||
|
||||
|
@ -181,6 +181,12 @@ public:
|
|||
void UnscheduleTimer(uint32_t id);
|
||||
|
||||
private:
|
||||
// Quirks mode support for various plugin mime types
|
||||
enum PluginQuirks {
|
||||
QUIRK_SILVERLIGHT_WINLESS_INPUT_TRANSLATION = 1, // Win32
|
||||
};
|
||||
|
||||
void InitQuirksModes(const nsCString& aMimeType);
|
||||
|
||||
NPError
|
||||
InternalGetNPObjectForValue(NPNVariable aValue,
|
||||
|
@ -221,6 +227,7 @@ private:
|
|||
const NPPluginFuncs* mPluginIface;
|
||||
NPP_t mData;
|
||||
NPWindow mWindow;
|
||||
int mQuirks;
|
||||
|
||||
// Cached scriptable actors to avoid IPC churn
|
||||
PluginScriptableObjectChild* mCachedWindowActor;
|
||||
|
@ -239,6 +246,7 @@ private:
|
|||
HWND mCachedWinlessPluginHWND;
|
||||
UINT_PTR mEventPumpTimer;
|
||||
nsIntPoint mPluginSize;
|
||||
nsIntPoint mPluginOffset;
|
||||
#endif
|
||||
|
||||
friend class ChildAsyncCall;
|
||||
|
|
|
@ -1448,7 +1448,7 @@ PluginModuleChild::AllocPPluginInstance(const nsCString& aMimeType,
|
|||
AssertPluginThread();
|
||||
|
||||
nsAutoPtr<PluginInstanceChild> childInstance(
|
||||
new PluginInstanceChild(&mFunctions));
|
||||
new PluginInstanceChild(&mFunctions, aMimeType));
|
||||
if (!childInstance->Initialize()) {
|
||||
*rv = NPERR_GENERIC_ERROR;
|
||||
return 0;
|
||||
|
|
Загрузка…
Ссылка в новой задаче