diff --git a/dom/plugins/ipc/PPluginModule.ipdl b/dom/plugins/ipc/PPluginModule.ipdl index 6e8288017258..7be57db5bd9e 100644 --- a/dom/plugins/ipc/PPluginModule.ipdl +++ b/dom/plugins/ipc/PPluginModule.ipdl @@ -169,6 +169,8 @@ parent: // Used to broker the GetOpenFileName/GetSaveFileName file pickers on Windows. intr GetFileName(GetFileNameFunc aFunc, OpenFileNameIPC aOfnIn) returns (OpenFileNameRetIPC aOfnOut, bool aResult); + + intr SetCursorPos(int x, int y) returns (bool aResult); }; } // namespace plugins diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp index 9e5ad4d850d8..109e101dc116 100644 --- a/dom/plugins/ipc/PluginModuleChild.cpp +++ b/dom/plugins/ipc/PluginModuleChild.cpp @@ -107,6 +107,10 @@ typedef BOOL (WINAPI *GetOpenFileNameWPtr)(LPOPENFILENAMEW lpofn); static GetOpenFileNameWPtr sGetOpenFileNameWPtrStub = nullptr; typedef BOOL (WINAPI *GetSaveFileNameWPtr)(LPOPENFILENAMEW lpofn); static GetSaveFileNameWPtr sGetSaveFileNameWPtrStub = nullptr; + +typedef BOOL (WINAPI *SetCursorPosPtr)(int x, int y); +static SetCursorPosPtr sSetCursorPosPtrStub = nullptr; + #endif /* static */ @@ -2233,6 +2237,38 @@ PMCGetOpenFileNameW(LPOPENFILENAMEW aLpofn) { return PMCGetFileNameW(OPEN_FUNC, aLpofn); } + +BOOL WINAPI PMCSetCursorPos(int x, int y); + +class SetCursorPosTaskData : public PluginThreadTaskData +{ +public: + SetCursorPosTaskData(int x, int y) : mX(x), mY(y) {} + bool RunTask() { return PMCSetCursorPos(mX, mY); } +private: + int mX, mY; +}; + +// static +BOOL WINAPI +PMCSetCursorPos(int x, int y) +{ + if (!IsPluginThread()) { + SetCursorPosTaskData scpData(x, y); + return PostToPluginThread(&scpData); + } + + PluginModuleChild* chromeInstance = PluginModuleChild::GetChrome(); + if (chromeInstance) { + bool ret = FALSE; + chromeInstance->CallSetCursorPos(x, y, &ret); + return ret; + } + + return sSetCursorPosPtrStub(x, y); +} + + #endif PPluginInstanceChild* @@ -2265,6 +2301,11 @@ PluginModuleChild::AllocPPluginInstanceChild(const nsCString& aMimeType, (void**) &sGetKeyStatePtrStub); } + if (!sSetCursorPosPtrStub) { + sUser32Intercept.AddHook("SetCursorPos", reinterpret_cast(PMCSetCursorPos), + (void**) &sSetCursorPosPtrStub); + } + sComDlg32Intercept.Init("comdlg32.dll"); if (!sGetSaveFileNameWPtrStub) { sComDlg32Intercept.AddHook("GetSaveFileNameW", reinterpret_cast(PMCGetSaveFileNameW), diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index 985f32640aad..fcde6caecbca 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -3358,3 +3358,15 @@ PluginModuleChromeParent::AnswerGetFileName(const GetFileNameFunc& aFunc, return IPC_FAIL_NO_REASON(this); #endif } + +mozilla::ipc::IPCResult +PluginModuleChromeParent::AnswerSetCursorPos(const int &x, const int &y, + bool* aResult) +{ +#if defined(XP_WIN) + *aResult = ::SetCursorPos(x, y); + return IPC_OK(); +#else + return PluginModuleParent::AnswerSetCursorPos(x, y, aResult); +#endif +} diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index b633338da3c0..58bbbceef5c1 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -225,6 +225,12 @@ protected: return IPC_FAIL_NO_REASON(this); } + virtual mozilla::ipc::IPCResult + AnswerSetCursorPos(const int &x, const int &y, bool* aResult) override + { + return IPC_FAIL_NO_REASON(this); + } + protected: void SetChildTimeout(const int32_t aChildTimeout); static void TimeoutChanged(const char* aPref, void* aModule); @@ -538,6 +544,10 @@ class PluginModuleChromeParent const OpenFileNameIPC& aOfnIn, OpenFileNameRetIPC* aOfnOut, bool* aResult) override; + // Proxy SetCursorPos on Windows. + virtual mozilla::ipc::IPCResult + AnswerSetCursorPos(const int &x, const int &y, bool* aResult) override; + private: virtual void EnteredCxxStack() override; diff --git a/ipc/ipdl/sync-messages.ini b/ipc/ipdl/sync-messages.ini index ce3dc578d51b..ef15fea9c946 100644 --- a/ipc/ipdl/sync-messages.ini +++ b/ipc/ipdl/sync-messages.ini @@ -775,6 +775,8 @@ description = description = [PPluginModule::GetFileName] description = +[PPluginModule::SetCursorPos] +description = [PPluginScriptableObject::NPN_Evaluate] description = [PPluginScriptableObject::Invalidate] diff --git a/toolkit/xre/test/win/TestDllInterceptor.cpp b/toolkit/xre/test/win/TestDllInterceptor.cpp index 1f7604198ac9..359d0765e6d0 100644 --- a/toolkit/xre/test/win/TestDllInterceptor.cpp +++ b/toolkit/xre/test/win/TestDllInterceptor.cpp @@ -397,6 +397,20 @@ bool TestProcessCaretEvents(void* aFunc) return true; } +bool TestSetCursorPos(void* aFunc) +{ + auto patchedSetCursorPos = + reinterpret_cast(aFunc); + POINT cursorPos; + BOOL ok = GetCursorPos(&cursorPos); + if (ok) { + ok = patchedSetCursorPos(cursorPos.x, cursorPos.y); + } else { + ok = patchedSetCursorPos(512, 512); + } + return ok; +} + static DWORD sTlsIndex = 0; bool TestTlsAlloc(void* aFunc) @@ -517,6 +531,7 @@ int main() #ifdef _M_IX86 TestHook(TestSendMessageTimeoutW, "user32.dll", "SendMessageTimeoutW") && #endif + TestHook(TestSetCursorPos, "user32.dll", "SetCursorPos") && TestHook(TestTlsAlloc, "kernel32.dll", "TlsAlloc") && TestHook(TestTlsFree, "kernel32.dll", "TlsFree") && #ifdef _M_IX86