michael@0: /* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8; -*- */ michael@0: /* vim: set sw=2 ts=8 et tw=80 : */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "PluginMessageUtils.h" michael@0: #include "nsIRunnable.h" michael@0: #include "nsThreadUtils.h" michael@0: michael@0: #include "PluginInstanceParent.h" michael@0: #include "PluginInstanceChild.h" michael@0: #include "PluginScriptableObjectParent.h" michael@0: #include "PluginScriptableObjectChild.h" michael@0: michael@0: using std::string; michael@0: michael@0: using mozilla::ipc::MessageChannel; michael@0: michael@0: namespace { michael@0: michael@0: class DeferNPObjectReleaseRunnable : public nsRunnable michael@0: { michael@0: public: michael@0: DeferNPObjectReleaseRunnable(const NPNetscapeFuncs* f, NPObject* o) michael@0: : mFuncs(f) michael@0: , mObject(o) michael@0: { michael@0: NS_ASSERTION(o, "no release null objects"); michael@0: } michael@0: michael@0: NS_IMETHOD Run(); michael@0: michael@0: private: michael@0: const NPNetscapeFuncs* mFuncs; michael@0: NPObject* mObject; michael@0: }; michael@0: michael@0: NS_IMETHODIMP michael@0: DeferNPObjectReleaseRunnable::Run() michael@0: { michael@0: mFuncs->releaseobject(mObject); michael@0: return NS_OK; michael@0: } michael@0: michael@0: } // anonymous namespace michael@0: michael@0: namespace mozilla { michael@0: namespace plugins { michael@0: michael@0: NPRemoteWindow::NPRemoteWindow() : michael@0: window(0), x(0), y(0), width(0), height(0), type(NPWindowTypeDrawable) michael@0: #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX) michael@0: , visualID(0) michael@0: , colormap(0) michael@0: #endif /* XP_UNIX */ michael@0: #if defined(XP_WIN) michael@0: ,surfaceHandle(0) michael@0: #endif michael@0: #if defined(XP_MACOSX) michael@0: ,contentsScaleFactor(1.0) michael@0: #endif michael@0: { michael@0: clipRect.top = 0; michael@0: clipRect.left = 0; michael@0: clipRect.bottom = 0; michael@0: clipRect.right = 0; michael@0: } michael@0: michael@0: ipc::RacyInterruptPolicy michael@0: MediateRace(const MessageChannel::Message& parent, michael@0: const MessageChannel::Message& child) michael@0: { michael@0: switch (parent.type()) { michael@0: case PPluginInstance::Msg_Paint__ID: michael@0: case PPluginInstance::Msg_NPP_SetWindow__ID: michael@0: case PPluginInstance::Msg_NPP_HandleEvent_Shmem__ID: michael@0: case PPluginInstance::Msg_NPP_HandleEvent_IOSurface__ID: michael@0: // our code relies on the frame list not changing during paints and michael@0: // reflows michael@0: return ipc::RIPParentWins; michael@0: michael@0: default: michael@0: return ipc::RIPChildWins; michael@0: } michael@0: } michael@0: michael@0: #if defined(OS_LINUX) michael@0: static string michael@0: ReplaceAll(const string& haystack, const string& needle, const string& with) michael@0: { michael@0: string munged = haystack; michael@0: string::size_type i = 0; michael@0: michael@0: while (string::npos != (i = munged.find(needle, i))) { michael@0: munged.replace(i, needle.length(), with); michael@0: i += with.length(); michael@0: } michael@0: michael@0: return munged; michael@0: } michael@0: #endif michael@0: michael@0: string michael@0: MungePluginDsoPath(const string& path) michael@0: { michael@0: #if defined(OS_LINUX) michael@0: // https://bugzilla.mozilla.org/show_bug.cgi?id=519601 michael@0: return ReplaceAll(path, "netscape", "netsc@pe"); michael@0: #else michael@0: return path; michael@0: #endif michael@0: } michael@0: michael@0: string michael@0: UnmungePluginDsoPath(const string& munged) michael@0: { michael@0: #if defined(OS_LINUX) michael@0: return ReplaceAll(munged, "netsc@pe", "netscape"); michael@0: #else michael@0: return munged; michael@0: #endif michael@0: } michael@0: michael@0: michael@0: PRLogModuleInfo* michael@0: GetPluginLog() michael@0: { michael@0: static PRLogModuleInfo *sLog; michael@0: if (!sLog) michael@0: sLog = PR_NewLogModule("IPCPlugins"); michael@0: return sLog; michael@0: } michael@0: michael@0: void michael@0: DeferNPObjectLastRelease(const NPNetscapeFuncs* f, NPObject* o) michael@0: { michael@0: if (!o) michael@0: return; michael@0: michael@0: if (o->referenceCount > 1) { michael@0: f->releaseobject(o); michael@0: return; michael@0: } michael@0: michael@0: NS_DispatchToCurrentThread(new DeferNPObjectReleaseRunnable(f, o)); michael@0: } michael@0: michael@0: void DeferNPVariantLastRelease(const NPNetscapeFuncs* f, NPVariant* v) michael@0: { michael@0: if (!NPVARIANT_IS_OBJECT(*v)) { michael@0: f->releasevariantvalue(v); michael@0: return; michael@0: } michael@0: DeferNPObjectLastRelease(f, v->value.objectValue); michael@0: VOID_TO_NPVARIANT(*v); michael@0: } michael@0: michael@0: #ifdef XP_WIN michael@0: michael@0: // The private event used for double-pass widgetless plugin rendering. michael@0: UINT DoublePassRenderingEvent() michael@0: { michael@0: static UINT gEventID = 0; michael@0: if (!gEventID) michael@0: gEventID = ::RegisterWindowMessage(L"MozDoublePassMsg"); michael@0: return gEventID; michael@0: } michael@0: michael@0: #endif michael@0: michael@0: } // namespace plugins michael@0: } // namespace mozilla