From b35b700c571de53703b5da22571d37469de67406 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 27 Oct 2009 15:58:33 -0400 Subject: [PATCH] Bug 522122. Electrolysis: Forawrd windows events to windowless plugins. r=cjones,karlt This gets windowless plugin events mostly working. We don't forward IME events because they are much more complicated. --- dom/plugins/NPEventWindows.h | 103 ++++++++++++++++++++++++++- dom/plugins/NPEventX11.h | 19 ++++- dom/plugins/PPluginInstance.ipdl | 4 +- dom/plugins/PluginInstanceChild.cpp | 8 +-- dom/plugins/PluginInstanceChild.h | 2 +- dom/plugins/PluginInstanceParent.cpp | 4 +- dom/plugins/PluginMessageUtils.h | 1 - 7 files changed, 126 insertions(+), 15 deletions(-) diff --git a/dom/plugins/NPEventWindows.h b/dom/plugins/NPEventWindows.h index 0dcd9d8bb96..966802aeab2 100644 --- a/dom/plugins/NPEventWindows.h +++ b/dom/plugins/NPEventWindows.h @@ -41,28 +41,125 @@ #include "npapi.h" +namespace mozilla { -#pragma message(__FILE__ ": This is only a stub implementation IMPLEMENT ME") +namespace plugins { + +// We use an NPRemoteEvent struct so that we can store the extra data on +// the stack so that we don't need to worry about managing the memory. +struct NPRemoteEvent +{ + NPEvent event; + union { + NPRect rect; + WINDOWPOS windowpos; + } lParamData; +}; + +} + +} namespace IPC { template <> -struct ParamTraits +struct ParamTraits { - typedef NPEvent paramType; + typedef mozilla::plugins::NPRemoteEvent paramType; static void Write(Message* aMsg, const paramType& aParam) { + // Make a non-const copy of aParam so that we can muck with + // its insides for tranport + paramType paramCopy; + + paramCopy.event = aParam.event; + + // We can't blindly ipc events because they may sometimes contain + // pointers to memory in the sending process. For example, the + // WM_IME_CONTROL with the IMC_GETCOMPOSITIONFONT message has lParam + // set to a pointer to a LOGFONT structure. + switch (paramCopy.event.event) { + case WM_WINDOWPOSCHANGED: + // The lParam paramter of WM_WINDOWPOSCHANGED holds a pointer to + // a WINDOWPOS structure that contains information about the + // window's new size and position + paramCopy.lParamData.windowpos = *(reinterpret_cast(paramCopy.event.lParam)); + break; + case WM_PAINT: + // The lParam paramter of WM_PAINT holds a pointer to an NPRect + // structure specifying the bounding box of the update area. + paramCopy.lParamData.rect = *(reinterpret_cast(paramCopy.event.lParam)); + break; + + // the white list of events that we will ipc to the client + case WM_CHAR: + case WM_SYSCHAR: + + case WM_KEYUP: + case WM_SYSKEYUP: + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + + case WM_DEADCHAR: + case WM_SYSDEADCHAR: + case WM_CONTEXTMENU: + + case WM_CUT: + case WM_COPY: + case WM_PASTE: + case WM_CLEAR: + case WM_UNDO: + + case WM_MOUSEMOVE: + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + case WM_LBUTTONDBLCLK: + case WM_MBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: + + case WM_SETFOCUS: + case WM_KILLFOCUS: + break; + + // ignore any events we don't expect + default: + return; + } + + aMsg->WriteBytes(¶mCopy, sizeof(paramType)); } static bool Read(const Message* aMsg, void** aIter, paramType* aResult) { + const char* bytes = 0; + + if (!aMsg->ReadBytes(aIter, &bytes, sizeof(paramType))) { + return false; + } + memcpy(aResult, bytes, sizeof(paramType)); + + if (aResult->event.event == WM_PAINT) { + // restore the lParam to point at the NPRect + aResult->event.lParam = reinterpret_cast(&aResult->lParamData.rect); + } else if (aResult->event.event == WM_WINDOWPOSCHANGED) { + // restore the lParam to point at the WINDOWPOS + aResult->event.lParam = reinterpret_cast(&aResult->lParamData.windowpos); + } + return true; } static void Log(const paramType& aParam, std::wstring* aLog) { + aLog->append(L"(WINEvent)"); } + }; } // namespace IPC diff --git a/dom/plugins/NPEventX11.h b/dom/plugins/NPEventX11.h index 13c891b89be..66c7a318942 100644 --- a/dom/plugins/NPEventX11.h +++ b/dom/plugins/NPEventX11.h @@ -48,6 +48,19 @@ #include "npapi.h" +namespace mozilla { + +namespace plugins { + +struct NPRemoteEvent { + NPEvent event; +}; + +} + +} + + // // XEvent is defined as a union of all more specific X*Events. // Luckily, as of xorg 1.6.0 / X protocol 11 rev 0, the only pointer @@ -68,9 +81,9 @@ namespace IPC { template <> -struct ParamTraits // synonym for XEvent +struct ParamTraits // synonym for XEvent { - typedef NPEvent paramType; + typedef mozilla::plugins::NPRemoteEvent paramType; static void Write(Message* aMsg, const paramType& aParam) { @@ -86,7 +99,7 @@ struct ParamTraits // synonym for XEvent } memcpy(aResult, bytes, sizeof(paramType)); - SetXDisplay(*aResult); + SetXDisplay(aResult->event); return true; } diff --git a/dom/plugins/PPluginInstance.ipdl b/dom/plugins/PPluginInstance.ipdl index 559db62bba6..6eb10113cea 100644 --- a/dom/plugins/PPluginInstance.ipdl +++ b/dom/plugins/PPluginInstance.ipdl @@ -46,8 +46,8 @@ include protocol "PStreamNotify.ipdl"; include "mozilla/plugins/PluginMessageUtils.h"; using NPError; -using NPEvent; using NPRemoteWindow; +using NPRemoteEvent; using NPReason; using NPRect; @@ -77,7 +77,7 @@ child: rpc NPP_GetValue_NPPVpluginScriptableNPObject() returns (PPluginScriptableObject value, NPError result); - rpc NPP_HandleEvent(NPEvent event) + rpc NPP_HandleEvent(NPRemoteEvent event) returns (int16_t handled); parent: diff --git a/dom/plugins/PluginInstanceChild.cpp b/dom/plugins/PluginInstanceChild.cpp index 743990f53fe..24864f02905 100644 --- a/dom/plugins/PluginInstanceChild.cpp +++ b/dom/plugins/PluginInstanceChild.cpp @@ -94,7 +94,7 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar, switch(aVar) { case NPNVSupportsWindowless: -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_WIN) *((NPBool*)aValue) = true; #else *((NPBool*)aValue) = false; @@ -307,7 +307,7 @@ PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginScriptableNPObject( } bool -PluginInstanceChild::AnswerNPP_HandleEvent(const NPEvent& event, +PluginInstanceChild::AnswerNPP_HandleEvent(const NPRemoteEvent& event, int16_t* handled) { _MOZ_LOG(__FUNCTION__); @@ -320,7 +320,7 @@ PluginInstanceChild::AnswerNPP_HandleEvent(const NPEvent& event, #endif // plugins might be fooling with these, make a copy - NPEvent evcopy = event; + NPEvent evcopy = event.event; *handled = mPluginIface->event(&mData, reinterpret_cast(&evcopy)); #ifdef MOZ_X11 @@ -407,7 +407,7 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow, mWindow.y = aWindow.y; mWindow.width = aWindow.width; mWindow.height = aWindow.height; - mWindow.type = NPWindowTypeWindow; + mWindow.type = aWindow.type; *rv = mPluginIface->setwindow(&mData, &mWindow); if (*rv == NPERR_NO_ERROR) { diff --git a/dom/plugins/PluginInstanceChild.h b/dom/plugins/PluginInstanceChild.h index 5e88ccfea36..ea2325c2d47 100644 --- a/dom/plugins/PluginInstanceChild.h +++ b/dom/plugins/PluginInstanceChild.h @@ -82,7 +82,7 @@ protected: NPError* result); virtual bool - AnswerNPP_HandleEvent(const NPEvent& event, int16_t* handled); + AnswerNPP_HandleEvent(const NPRemoteEvent& event, int16_t* handled); virtual PPluginScriptableObjectChild* AllocPPluginScriptableObject(); diff --git a/dom/plugins/PluginInstanceParent.cpp b/dom/plugins/PluginInstanceParent.cpp index ddaaa6412dc..b8dcfd8cdf0 100644 --- a/dom/plugins/PluginInstanceParent.cpp +++ b/dom/plugins/PluginInstanceParent.cpp @@ -432,6 +432,8 @@ PluginInstanceParent::NPP_HandleEvent(void* event) _MOZ_LOG(__FUNCTION__); NPEvent* npevent = reinterpret_cast(event); + NPRemoteEvent npremoteevent; + npremoteevent.event = *npevent; #if defined(MOZ_X11) if (GraphicsExpose == npevent->type) { @@ -451,7 +453,7 @@ PluginInstanceParent::NPP_HandleEvent(void* event) #endif int16_t handled; - if (!CallNPP_HandleEvent(*npevent, &handled)) { + if (!CallNPP_HandleEvent(npremoteevent, &handled)) { return 0; // no good way to handle errors here... } return handled; diff --git a/dom/plugins/PluginMessageUtils.h b/dom/plugins/PluginMessageUtils.h index 151dd265cbe..345d25d8cba 100644 --- a/dom/plugins/PluginMessageUtils.h +++ b/dom/plugins/PluginMessageUtils.h @@ -90,7 +90,6 @@ struct NPRemoteWindow #endif /* XP_UNIX */ }; - // XXX maybe not the best place for these. better one? #define VARSTR(v_) case v_: return #v_