mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 522299 - Electrolysis: Get windowless plugins drawing on win32. r=jmuizelaar.
This commit is contained in:
parent
5d5e9d38fe
commit
705471067a
@ -21,6 +21,7 @@
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jim Mathies <jmathies@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -45,6 +46,7 @@
|
||||
#include "mozilla/ipc/SyncChannel.h"
|
||||
|
||||
using namespace mozilla::plugins;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK2
|
||||
|
||||
@ -328,8 +330,15 @@ PluginInstanceChild::AnswerNPP_HandleEvent(const NPRemoteEvent& event,
|
||||
event.event.xgraphicsexpose.drawable);
|
||||
#endif
|
||||
|
||||
// plugins might be fooling with these, make a copy
|
||||
// Make a copy since we may modify values.
|
||||
NPEvent evcopy = event.event;
|
||||
|
||||
#ifdef OS_WIN
|
||||
// Setup the shared dib for painting and update evcopy.
|
||||
if (NPWindowTypeDrawable == mWindow.type && WM_PAINT == evcopy.event)
|
||||
SharedSurfaceBeforePaint(evcopy);
|
||||
#endif
|
||||
|
||||
*handled = mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy));
|
||||
|
||||
#ifdef MOZ_X11
|
||||
@ -408,25 +417,43 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow,
|
||||
*rv = mPluginIface->setwindow(&mData, &mWindow);
|
||||
|
||||
#elif defined(OS_WIN)
|
||||
ReparentPluginWindow((HWND)aWindow.window);
|
||||
SizePluginWindow(aWindow.width, aWindow.height);
|
||||
switch (aWindow.type) {
|
||||
case NPWindowTypeWindow:
|
||||
{
|
||||
if (!CreatePluginWindow())
|
||||
return false;
|
||||
|
||||
mWindow.window = (void*)mPluginWindowHWND;
|
||||
mWindow.x = aWindow.x;
|
||||
mWindow.y = aWindow.y;
|
||||
mWindow.width = aWindow.width;
|
||||
mWindow.height = aWindow.height;
|
||||
mWindow.type = aWindow.type;
|
||||
ReparentPluginWindow((HWND)aWindow.window);
|
||||
SizePluginWindow(aWindow.width, aWindow.height);
|
||||
|
||||
*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)));
|
||||
}
|
||||
mWindow.window = (void*)mPluginWindowHWND;
|
||||
mWindow.x = aWindow.x;
|
||||
mWindow.y = aWindow.y;
|
||||
mWindow.width = aWindow.width;
|
||||
mWindow.height = aWindow.height;
|
||||
mWindow.type = aWindow.type;
|
||||
|
||||
*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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NPWindowTypeDrawable:
|
||||
return SharedSurfaceSetWindow(aWindow, rv);
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_NOTREACHED("Bad plugin window type.");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
#elif defined(OS_MACOSX)
|
||||
@ -442,11 +469,6 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow,
|
||||
bool
|
||||
PluginInstanceChild::Initialize()
|
||||
{
|
||||
#if defined(OS_WIN)
|
||||
if (!CreatePluginWindow())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -468,6 +490,10 @@ PluginInstanceChild::Destroy()
|
||||
PluginScriptableObjectChild::ScriptableInvalidate(object);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
SharedSurfaceRelease();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
@ -505,26 +531,28 @@ PluginInstanceChild::RegisterWindowClass()
|
||||
bool
|
||||
PluginInstanceChild::CreatePluginWindow()
|
||||
{
|
||||
// already initialized
|
||||
if (mPluginWindowHWND)
|
||||
return true;
|
||||
|
||||
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, kPluginInstanceChildProperty, this))
|
||||
return false;
|
||||
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, kPluginInstanceChildProperty, this))
|
||||
return false;
|
||||
|
||||
// Apparently some plugins require an ASCII WndProc.
|
||||
SetWindowLongPtrA(mPluginWindowHWND, GWLP_WNDPROC,
|
||||
reinterpret_cast<LONG>(DefWindowProcA));
|
||||
}
|
||||
// Apparently some plugins require an ASCII WndProc.
|
||||
SetWindowLongPtrA(mPluginWindowHWND, GWLP_WNDPROC,
|
||||
reinterpret_cast<LONG>(DefWindowProcA));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -620,6 +648,60 @@ PluginInstanceChild::PluginWindowProc(HWND hWnd,
|
||||
return res;
|
||||
}
|
||||
|
||||
/* windowless drawing helpers */
|
||||
|
||||
bool
|
||||
PluginInstanceChild::SharedSurfaceSetWindow(const NPRemoteWindow& aWindow,
|
||||
NPError* rv)
|
||||
{
|
||||
// If the surfaceHandle is empty, parent is telling us we can reuse our cached
|
||||
// memory surface and hdc. Otherwise, we need to reset, usually due to a
|
||||
// expanding plugin port size.
|
||||
if (!aWindow.surfaceHandle) {
|
||||
if (!mSharedSurfaceDib.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Attach to the new shared surface parent handed us.
|
||||
if (NS_FAILED(mSharedSurfaceDib.Attach((SharedDIB::Handle)aWindow.surfaceHandle,
|
||||
aWindow.width, aWindow.height, 32)))
|
||||
return false;
|
||||
}
|
||||
|
||||
// NPRemoteWindow's origin is the origin of our shared dib.
|
||||
mWindow.x = 0;
|
||||
mWindow.y = 0;
|
||||
mWindow.width = aWindow.width;
|
||||
mWindow.height = aWindow.height;
|
||||
mWindow.type = aWindow.type;
|
||||
|
||||
mWindow.window = reinterpret_cast<void*>(mSharedSurfaceDib.GetHDC());
|
||||
*rv = mPluginIface->setwindow(&mData, &mWindow);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceChild::SharedSurfaceRelease()
|
||||
{
|
||||
mSharedSurfaceDib.Close();
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceChild::SharedSurfaceBeforePaint(NPEvent& evcopy)
|
||||
{
|
||||
// Update the clip rect on our internal hdc
|
||||
RECT* pRect = reinterpret_cast<RECT*>(evcopy.lParam);
|
||||
if (pRect) {
|
||||
HRGN clip = ::CreateRectRgnIndirect(pRect);
|
||||
::SelectClipRgn(mSharedSurfaceDib.GetHDC(), clip);
|
||||
::DeleteObject(clip);
|
||||
}
|
||||
// pass the internal hdc to the plugin
|
||||
evcopy.wParam = WPARAM(mSharedSurfaceDib.GetHDC());
|
||||
}
|
||||
|
||||
#endif // OS_WIN
|
||||
|
||||
PPluginScriptableObjectChild*
|
||||
@ -853,10 +935,17 @@ PluginInstanceChild::InternalInvalidateRect(NPRect* aInvalidRect)
|
||||
NS_ASSERTION(aInvalidRect, "Null pointer!");
|
||||
|
||||
#ifdef OS_WIN
|
||||
NS_ASSERTION(IsWindow(mPluginWindowHWND), "Bad window?!");
|
||||
RECT rect = { aInvalidRect->left, aInvalidRect->top,
|
||||
aInvalidRect->right, aInvalidRect->bottom };
|
||||
InvalidateRect(mPluginWindowHWND, &rect, FALSE);
|
||||
// Invalidate and draw locally for windowed plugins.
|
||||
if (mWindow.type == NPWindowTypeWindow) {
|
||||
NS_ASSERTION(IsWindow(mPluginWindowHWND), "Bad window?!");
|
||||
RECT rect = { aInvalidRect->left, aInvalidRect->top,
|
||||
aInvalidRect->right, aInvalidRect->bottom };
|
||||
InvalidateRect(mPluginWindowHWND, &rect, FALSE);
|
||||
return false;
|
||||
}
|
||||
// Windowless need the invalidation to propegate to parent
|
||||
// triggering wm_paint handle event calls.
|
||||
return true;
|
||||
#endif
|
||||
|
||||
// Windowless plugins must return true!
|
||||
|
@ -41,6 +41,9 @@
|
||||
|
||||
#include "mozilla/plugins/PPluginInstanceChild.h"
|
||||
#include "mozilla/plugins/PluginScriptableObjectChild.h"
|
||||
#if defined(OS_WIN)
|
||||
#include "mozilla/gfx/SharedDIBWin.h"
|
||||
#endif
|
||||
|
||||
#include "npfunctions.h"
|
||||
#include "nsAutoPtr.h"
|
||||
@ -204,6 +207,17 @@ private:
|
||||
#endif
|
||||
|
||||
nsTArray<nsAutoPtr<PluginScriptableObjectChild> > mScriptableObjects;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
private:
|
||||
// Shared dib rendering management for windowless plugins.
|
||||
bool SharedSurfaceSetWindow(const NPRemoteWindow& aWindow, NPError* rv);
|
||||
void SharedSurfaceBeforePaint(NPEvent& evcopy);
|
||||
void SharedSurfaceRelease();
|
||||
|
||||
private:
|
||||
gfx::SharedDIBWin mSharedSurfaceDib;
|
||||
#endif // defined(OS_WIN)
|
||||
};
|
||||
|
||||
} // namespace plugins
|
||||
|
@ -21,6 +21,7 @@
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jim Mathies <jmathies@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -46,6 +47,10 @@
|
||||
#include "npfunctions.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#define NS_OOPP_DOUBLEPASS_MSGID TEXT("MozDoublePassMsg")
|
||||
#endif
|
||||
|
||||
using namespace mozilla::plugins;
|
||||
|
||||
PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent,
|
||||
@ -53,8 +58,17 @@ PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent,
|
||||
const NPNetscapeFuncs* npniface)
|
||||
: mParent(parent),
|
||||
mNPP(npp),
|
||||
mNPNIface(npniface)
|
||||
mNPNIface(npniface),
|
||||
mWindowType(NPWindowTypeWindow)
|
||||
{
|
||||
#if defined(OS_WIN)
|
||||
// Event sent from nsObjectFrame indicating double pass rendering for
|
||||
// windowless plugins. RegisterWindowMessage makes it easy sync event
|
||||
// values, and insures we never conflict with windowing events we allow
|
||||
// for windowless plugins.
|
||||
mDoublePassEvent = ::RegisterWindowMessage(NS_OOPP_DOUBLEPASS_MSGID);
|
||||
mLocalCopyRender = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
PluginInstanceParent::~PluginInstanceParent()
|
||||
@ -78,6 +92,10 @@ PluginInstanceParent::Destroy()
|
||||
PluginScriptableObjectParent::ScriptableInvalidate(object);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
SharedSurfaceRelease();
|
||||
#endif
|
||||
}
|
||||
|
||||
PBrowserStreamParent*
|
||||
@ -319,13 +337,34 @@ PluginInstanceParent::NPP_SetWindow(const NPWindow* aWindow)
|
||||
NS_ENSURE_TRUE(aWindow, NPERR_GENERIC_ERROR);
|
||||
|
||||
NPRemoteWindow window;
|
||||
mWindowType = aWindow->type;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// On windowless controls, reset the shared memory surface as needed.
|
||||
if (mWindowType == NPWindowTypeDrawable) {
|
||||
// SharedSurfaceSetWindow will take care of NPRemoteWindow.
|
||||
if (!SharedSurfaceSetWindow(aWindow, window)) {
|
||||
return NPERR_OUT_OF_MEMORY_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
window.window = reinterpret_cast<unsigned long>(aWindow->window);
|
||||
window.x = aWindow->x;
|
||||
window.y = aWindow->y;
|
||||
window.width = aWindow->width;
|
||||
window.height = aWindow->height;
|
||||
window.type = aWindow->type;
|
||||
}
|
||||
#else
|
||||
window.window = reinterpret_cast<unsigned long>(aWindow->window);
|
||||
window.x = aWindow->x;
|
||||
window.y = aWindow->y;
|
||||
window.width = aWindow->width;
|
||||
window.height = aWindow->height;
|
||||
window.clipRect = aWindow->clipRect;
|
||||
window.clipRect = aWindow->clipRect; // MacOS specific
|
||||
window.type = aWindow->type;
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
const NPSetWindowCallbackStruct* ws_info =
|
||||
static_cast<NPSetWindowCallbackStruct*>(aWindow->ws_info);
|
||||
@ -443,6 +482,21 @@ PluginInstanceParent::NPP_HandleEvent(void* event)
|
||||
NPRemoteEvent npremoteevent;
|
||||
npremoteevent.event = *npevent;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
RECT rect;
|
||||
if (mWindowType == NPWindowTypeDrawable) {
|
||||
if (mDoublePassEvent && mDoublePassEvent == npevent->event) {
|
||||
// Sent from nsObjectFrame to let us know a double pass render is in progress.
|
||||
mLocalCopyRender = PR_TRUE;
|
||||
return true;
|
||||
} else if (WM_PAINT == npevent->event) {
|
||||
// Don't forward on the second pass, otherwise, fall through.
|
||||
if (!SharedSurfaceBeforePaint(rect, npremoteevent))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_X11)
|
||||
if (GraphicsExpose == npevent->type) {
|
||||
printf(" schlepping drawable 0x%lx across the pipe\n",
|
||||
@ -464,6 +518,12 @@ PluginInstanceParent::NPP_HandleEvent(void* event)
|
||||
if (!CallNPP_HandleEvent(npremoteevent, &handled)) {
|
||||
return 0; // no good way to handle errors here...
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
if (handled && mWindowType == NPWindowTypeDrawable && WM_PAINT == npevent->event)
|
||||
SharedSurfaceAfterPaint(npevent);
|
||||
#endif
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
@ -632,3 +692,126 @@ PluginInstanceParent::AnswerNPN_PopPopupsEnabledState(bool* aSuccess)
|
||||
*aSuccess = mNPNIface->poppopupsenabledstate(mNPP);
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
/* windowless drawing helpers */
|
||||
|
||||
void
|
||||
PluginInstanceParent::SharedSurfaceRelease()
|
||||
{
|
||||
mSharedSurfaceDib.Close();
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceParent::SharedSurfaceSetWindow(const NPWindow* aWindow,
|
||||
NPRemoteWindow& aRemoteWindow)
|
||||
{
|
||||
aRemoteWindow.window = nsnull;
|
||||
aRemoteWindow.x = 0;
|
||||
aRemoteWindow.y = 0;
|
||||
aRemoteWindow.width = aWindow->width;
|
||||
aRemoteWindow.height = aWindow->height;
|
||||
aRemoteWindow.type = aWindow->type;
|
||||
|
||||
nsIntRect newPort(aWindow->x, aWindow->y, aWindow->width, aWindow->height);
|
||||
|
||||
// save the the rect location within the browser window.
|
||||
mPluginPort = newPort;
|
||||
|
||||
// move the port to our shared surface origin
|
||||
newPort.MoveTo(0,0);
|
||||
|
||||
// check to see if we have the room in shared surface
|
||||
if (mSharedSurfaceDib.IsValid() && mSharedSize.Contains(newPort)) {
|
||||
// ok to paint
|
||||
aRemoteWindow.surfaceHandle = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// allocate a new shared surface
|
||||
SharedSurfaceRelease();
|
||||
if (NS_FAILED(mSharedSurfaceDib.Create(reinterpret_cast<HDC>(aWindow->window),
|
||||
newPort.width, newPort.height, 32)))
|
||||
return false;
|
||||
|
||||
// save the new shared surface size we just allocated
|
||||
mSharedSize = newPort;
|
||||
|
||||
base::SharedMemoryHandle handle;
|
||||
if (NS_FAILED(mSharedSurfaceDib.ShareToProcess(mParent->ChildProcessHandle(), &handle)))
|
||||
return false;
|
||||
|
||||
aRemoteWindow.surfaceHandle = handle;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceParent::SharedSurfaceBeforePaint(RECT& rect,
|
||||
NPRemoteEvent& npremoteevent)
|
||||
{
|
||||
RECT* dr = (RECT*)npremoteevent.event.lParam;
|
||||
HDC parentHdc = (HDC)npremoteevent.event.wParam;
|
||||
|
||||
// We render twice per frame for windowless plugins that sit in transparent
|
||||
// frames. (See nsObjectFrame and gfxWindowsNativeDrawing for details.) IPC
|
||||
// message delays in OOP plugin painting can result in two passes yeilding
|
||||
// different animation frames. The second rendering doesn't need to go over
|
||||
// the wire (we already have a copy of the frame in mSharedSurfaceDib) so we
|
||||
// skip off requesting the second. This also gives us a nice perf boost.
|
||||
if (mLocalCopyRender) {
|
||||
mLocalCopyRender = false;
|
||||
// Reuse the old render.
|
||||
SharedSurfaceAfterPaint(&npremoteevent.event);
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
|
||||
dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y); // should always be smaller than dirtyRect
|
||||
|
||||
::BitBlt(mSharedSurfaceDib.GetHDC(),
|
||||
dirtyRect.x,
|
||||
dirtyRect.y,
|
||||
dirtyRect.width,
|
||||
dirtyRect.height,
|
||||
parentHdc,
|
||||
dr->left,
|
||||
dr->top,
|
||||
SRCCOPY);
|
||||
|
||||
// setup the translated dirty rect we'll send to the child
|
||||
rect.left = dirtyRect.x;
|
||||
rect.top = dirtyRect.y;
|
||||
rect.right = dirtyRect.width;
|
||||
rect.bottom = dirtyRect.height;
|
||||
|
||||
npremoteevent.event.wParam = WPARAM(0);
|
||||
npremoteevent.event.lParam = LPARAM(&rect);
|
||||
|
||||
// Send the event to the plugin
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceParent::SharedSurfaceAfterPaint(NPEvent* npevent)
|
||||
{
|
||||
RECT* dr = (RECT*)npevent->lParam;
|
||||
HDC parentHdc = (HDC)npevent->wParam;
|
||||
|
||||
nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
|
||||
dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y);
|
||||
|
||||
// src copy the shared dib into the parent surface we are handed.
|
||||
::BitBlt(parentHdc,
|
||||
dr->left,
|
||||
dr->top,
|
||||
dirtyRect.width,
|
||||
dirtyRect.height,
|
||||
mSharedSurfaceDib.GetHDC(),
|
||||
dirtyRect.x,
|
||||
dirtyRect.y,
|
||||
SRCCOPY);
|
||||
}
|
||||
|
||||
#endif // defined(OS_WIN)
|
||||
|
@ -41,10 +41,14 @@
|
||||
|
||||
#include "mozilla/plugins/PPluginInstanceParent.h"
|
||||
#include "mozilla/plugins/PluginScriptableObjectParent.h"
|
||||
#if defined(OS_WIN)
|
||||
#include "mozilla/gfx/SharedDIBWin.h"
|
||||
#endif
|
||||
|
||||
#include "npfunctions.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
#undef _MOZ_LOG
|
||||
#define _MOZ_LOG(s) printf("[PluginInstanceParent] %s\n", s)
|
||||
@ -218,8 +222,25 @@ private:
|
||||
PluginModuleParent* mParent;
|
||||
NPP mNPP;
|
||||
const NPNetscapeFuncs* mNPNIface;
|
||||
NPWindowType mWindowType;
|
||||
|
||||
nsTArray<nsAutoPtr<PluginScriptableObjectParent> > mScriptableObjects;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
private:
|
||||
// Used in rendering windowless plugins in other processes.
|
||||
bool SharedSurfaceSetWindow(const NPWindow* aWindow, NPRemoteWindow& aRemoteWindow);
|
||||
bool SharedSurfaceBeforePaint(RECT &rect, NPRemoteEvent& npremoteevent);
|
||||
void SharedSurfaceAfterPaint(NPEvent* npevent);
|
||||
void SharedSurfaceRelease();
|
||||
|
||||
private:
|
||||
gfx::SharedDIBWin mSharedSurfaceDib;
|
||||
nsIntRect mPluginPort;
|
||||
nsIntRect mSharedSize;
|
||||
PRUint32 mDoublePassEvent;
|
||||
bool mLocalCopyRender;
|
||||
#endif // defined(XP_WIN)
|
||||
};
|
||||
|
||||
|
||||
|
@ -89,6 +89,9 @@ struct NPRemoteWindow
|
||||
VisualID visualID;
|
||||
Colormap colormap;
|
||||
#endif /* XP_UNIX */
|
||||
#if defined(XP_WIN)
|
||||
base::SharedMemoryHandle surfaceHandle;
|
||||
#endif
|
||||
};
|
||||
|
||||
// XXX maybe not the best place for these. better one?
|
||||
@ -277,6 +280,9 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
aMsg->WriteULong(aParam.visualID);
|
||||
aMsg->WriteULong(aParam.colormap);
|
||||
#endif
|
||||
#if defined(XP_WIN)
|
||||
WriteParam(aMsg, aParam.surfaceHandle);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -304,6 +310,12 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
base::SharedMemoryHandle surfaceHandle;
|
||||
if (!ReadParam(aMsg, aIter, &surfaceHandle))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
aResult->window = window;
|
||||
aResult->x = x;
|
||||
aResult->y = y;
|
||||
@ -314,6 +326,9 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
aResult->visualID = visualID;
|
||||
aResult->colormap = colormap;
|
||||
#endif
|
||||
#if defined(XP_WIN)
|
||||
aResult->surfaceHandle = surfaceHandle;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
@ -141,6 +141,7 @@ public:
|
||||
|
||||
bool EnsureValidNPIdentifier(NPIdentifier aIdentifier);
|
||||
|
||||
base::ProcessHandle ChildProcessHandle() { return mSubprocess->GetChildProcessHandle(); }
|
||||
private:
|
||||
void SetPluginFuncs(NPPluginFuncs* aFuncs);
|
||||
|
||||
|
@ -50,6 +50,10 @@ endif
|
||||
|
||||
DIRS += thebes public idl src qcms
|
||||
|
||||
ifdef MOZ_IPC
|
||||
DIRS += ipc
|
||||
endif
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
ifndef MOZ_ENABLE_LIBXUL
|
||||
TOOL_DIRS += tests
|
||||
|
73
gfx/ipc/Makefile.in
Normal file
73
gfx/ipc/Makefile.in
Normal file
@ -0,0 +1,73 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1998
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
ifdef MOZ_IPC
|
||||
|
||||
MODULE = gfxipc
|
||||
LIBRARY_NAME = gfxipc_s
|
||||
FORCE_STATIC_LIB = 1
|
||||
LIBXUL_LIBRARY = 1
|
||||
EXPORT_LIBRARY = 1
|
||||
|
||||
EXPORTS_NAMESPACES = mozilla/gfx
|
||||
|
||||
EXPORTS_mozilla/gfx = \
|
||||
SharedDIB.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = SharedDIB.cpp
|
||||
|
||||
ENABLE_CXX_EXCEPTIONS = 1
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
CPPSRCS += SharedDIBWin.cpp
|
||||
EXPORTS_mozilla/gfx += SharedDIBWin.h
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
118
gfx/ipc/SharedDIB.cpp
Normal file
118
gfx/ipc/SharedDIB.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jim Mathies <jmathies@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "SharedDIB.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
SharedDIB::SharedDIB() :
|
||||
mShMem(nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
SharedDIB::~SharedDIB()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
nsresult
|
||||
SharedDIB::Create(PRUint32 aSize)
|
||||
{
|
||||
Close();
|
||||
|
||||
mShMem = new base::SharedMemory();
|
||||
if (!mShMem || !mShMem->Create(std::wstring(L""), false, false, aSize))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Map the entire section
|
||||
if (!mShMem->Map(0))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
SharedDIB::IsValid()
|
||||
{
|
||||
if (!mShMem)
|
||||
return false;
|
||||
|
||||
return (mShMem->handle() != mShMem->NULLHandle() ? true : false);
|
||||
}
|
||||
|
||||
nsresult
|
||||
SharedDIB::Close()
|
||||
{
|
||||
if (mShMem)
|
||||
delete mShMem;
|
||||
|
||||
mShMem = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SharedDIB::Attach(Handle aHandle, PRUint32 aSize)
|
||||
{
|
||||
Close();
|
||||
|
||||
mShMem = new base::SharedMemory(aHandle, false);
|
||||
if(!mShMem)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (!mShMem->Map(aSize))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SharedDIB::ShareToProcess(base::ProcessHandle aChildProcess, Handle *aChildHandle)
|
||||
{
|
||||
if (!mShMem)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if (!mShMem->ShareToProcess(aChildProcess, aChildHandle))
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // gfx
|
||||
} // mozilla
|
82
gfx/ipc/SharedDIB.h
Normal file
82
gfx/ipc/SharedDIB.h
Normal file
@ -0,0 +1,82 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jim Mathies <jmathies@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef gfx_SharedDIB_h__
|
||||
#define gfx_SharedDIB_h__
|
||||
|
||||
#include "base/shared_memory.h"
|
||||
#include "prtypes.h"
|
||||
#include "nscore.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class SharedDIB
|
||||
{
|
||||
public:
|
||||
typedef base::SharedMemoryHandle Handle;
|
||||
|
||||
public:
|
||||
SharedDIB();
|
||||
~SharedDIB();
|
||||
|
||||
// Create and allocate a new shared dib.
|
||||
nsresult Create(PRUint32 aSize);
|
||||
|
||||
// Destroy or release resources associated with this dib.
|
||||
nsresult Close();
|
||||
|
||||
// Returns true if this object contains a valid dib.
|
||||
bool IsValid();
|
||||
|
||||
// Wrap a new shared dib around allocated shared memory. Note aHandle must point
|
||||
// to a memory section large enough to hold a dib of size aSize, otherwise this
|
||||
// will fail.
|
||||
nsresult Attach(Handle aHandle, PRUint32 aSize);
|
||||
|
||||
// Returns a SharedMemoryHandle suitable for sharing with another process.
|
||||
nsresult ShareToProcess(base::ProcessHandle aChildProcess, Handle *aChildHandle);
|
||||
|
||||
protected:
|
||||
base::SharedMemory *mShMem;
|
||||
};
|
||||
|
||||
} // gfx
|
||||
} // mozilla
|
||||
|
||||
#endif
|
161
gfx/ipc/SharedDIBWin.cpp
Normal file
161
gfx/ipc/SharedDIBWin.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jim Mathies <jmathies@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "SharedDIBWin.h"
|
||||
#include "nsMathUtils.h"
|
||||
#include "nsDebug.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
SharedDIBWin::SharedDIBWin() :
|
||||
mSharedHdc(nsnull)
|
||||
, mSharedBmp(nsnull)
|
||||
, mOldObj(nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
SharedDIBWin::~SharedDIBWin()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
nsresult
|
||||
SharedDIBWin::Close()
|
||||
{
|
||||
if (mSharedHdc && mOldObj)
|
||||
::SelectObject(mSharedHdc, mOldObj);
|
||||
|
||||
if (mSharedHdc)
|
||||
::DeleteObject(mSharedHdc);
|
||||
|
||||
if (mSharedBmp)
|
||||
::DeleteObject(mSharedBmp);
|
||||
|
||||
mSharedHdc = NULL;
|
||||
mOldObj = mSharedBmp = NULL;
|
||||
|
||||
SharedDIB::Close();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SharedDIBWin::Create(HDC aHdc, PRUint32 aWidth, PRUint32 aHeight, PRUint32 aDepth)
|
||||
{
|
||||
Close();
|
||||
|
||||
// create the offscreen shared dib
|
||||
BITMAPINFOHEADER bmih;
|
||||
PRUint32 size = SetupBitmapHeader(aWidth, aHeight, aDepth, &bmih);
|
||||
|
||||
nsresult rv = SharedDIB::Create(size);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (NS_FAILED(SetupSurface(aHdc, &bmih))) {
|
||||
Close();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SharedDIBWin::Attach(Handle aHandle, PRUint32 aWidth, PRUint32 aHeight, PRUint32 aDepth)
|
||||
{
|
||||
Close();
|
||||
|
||||
BITMAPINFOHEADER bmih;
|
||||
SetupBitmapHeader(aWidth, aHeight, aDepth, &bmih);
|
||||
|
||||
nsresult rv = SharedDIB::Attach(aHandle, 0);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (NS_FAILED(SetupSurface(NULL, &bmih))) {
|
||||
Close();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
SharedDIBWin::SetupBitmapHeader(PRUint32 aWidth, PRUint32 aHeight, PRUint32 aDepth, BITMAPINFOHEADER *aHeader)
|
||||
{
|
||||
NS_ASSERTION(aDepth == 32, "Invalid SharedDIBWin depth");
|
||||
|
||||
memset((void*)aHeader, 0, sizeof(BITMAPINFOHEADER));
|
||||
aHeader->biSize = sizeof(BITMAPINFOHEADER);
|
||||
aHeader->biWidth = aWidth;
|
||||
aHeader->biHeight = aHeight;
|
||||
aHeader->biPlanes = 1;
|
||||
aHeader->biBitCount = aDepth;
|
||||
aHeader->biCompression = BI_RGB;
|
||||
|
||||
// deal better with varying depths. (we currently only ask for 32 bit)
|
||||
return (sizeof(BITMAPINFOHEADER) + (aHeader->biHeight * aHeader->biWidth * (PRUint32)NS_ceil(aDepth/8)));
|
||||
}
|
||||
|
||||
nsresult
|
||||
SharedDIBWin::SetupSurface(HDC aHdc, BITMAPINFOHEADER *aHdr)
|
||||
{
|
||||
mSharedHdc = ::CreateCompatibleDC(aHdc);
|
||||
|
||||
if (!mSharedHdc)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
void* ppvBits = nsnull;
|
||||
mSharedBmp = ::CreateDIBSection(mSharedHdc,
|
||||
(BITMAPINFO*)aHdr,
|
||||
DIB_RGB_COLORS,
|
||||
(void**)&ppvBits,
|
||||
mShMem->handle(),
|
||||
(unsigned long)sizeof(BITMAPINFOHEADER));
|
||||
if (!mSharedBmp)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mOldObj = SelectObject(mSharedHdc, mSharedBmp);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
} // gfx
|
||||
} // mozilla
|
82
gfx/ipc/SharedDIBWin.h
Normal file
82
gfx/ipc/SharedDIBWin.h
Normal file
@ -0,0 +1,82 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jim Mathies <jmathies@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef gfx_SharedDIBWin_h__
|
||||
#define gfx_SharedDIBWin_h__
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "SharedDIB.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class SharedDIBWin : public SharedDIB
|
||||
{
|
||||
public:
|
||||
SharedDIBWin();
|
||||
~SharedDIBWin();
|
||||
|
||||
// Allocate a new win32 dib section compatible with an hdc. The dib will
|
||||
// be selected into the hdc on return.
|
||||
nsresult Create(HDC aHdc, PRUint32 aWidth, PRUint32 aHeight, PRUint32 aDepth);
|
||||
|
||||
// Wrap a dib section around an existing shared memory object. aHandle should
|
||||
// point to a section large enough for the dib's memory, otherwise this call
|
||||
// will fail.
|
||||
nsresult Attach(Handle aHandle, PRUint32 aWidth, PRUint32 aHeight, PRUint32 aDepth);
|
||||
|
||||
// Destroy or release resources associated with this dib.
|
||||
nsresult Close();
|
||||
|
||||
// Return the HDC of the shared dib.
|
||||
HDC GetHDC() { return mSharedHdc; }
|
||||
|
||||
private:
|
||||
HDC mSharedHdc;
|
||||
HBITMAP mSharedBmp;
|
||||
HGDIOBJ mOldObj;
|
||||
|
||||
PRUint32 SetupBitmapHeader(PRUint32 aWidth, PRUint32 aHeight, PRUint32 aDepth, BITMAPINFOHEADER *aHeader);
|
||||
nsresult SetupSurface(HDC aHdc, BITMAPINFOHEADER *aHdr);
|
||||
};
|
||||
|
||||
} // gfx
|
||||
} // mozilla
|
||||
|
||||
#endif
|
@ -205,6 +205,9 @@ enum { XKeyPress = KeyPress };
|
||||
#ifdef XP_WIN
|
||||
#include <wtypes.h>
|
||||
#include <winuser.h>
|
||||
#ifdef MOZ_IPC
|
||||
#define NS_OOPP_DOUBLEPASS_MSGID TEXT("MozDoublePassMsg")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef XP_OS2
|
||||
@ -605,6 +608,9 @@ nsObjectFrame::Init(nsIContent* aContent,
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NotifyPluginEventObservers(NS_LITERAL_STRING("init").get());
|
||||
}
|
||||
#ifdef XP_WIN
|
||||
mDoublePassEvent = 0;
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1680,6 +1686,7 @@ nsObjectFrame::PaintPlugin(nsIRenderingContext& aRenderingContext,
|
||||
nsPoint origin;
|
||||
|
||||
gfxWindowsNativeDrawing nativeDraw(ctx, frameGfxRect);
|
||||
PRBool doublePass = PR_FALSE;
|
||||
do {
|
||||
HDC hdc = nativeDraw.BeginNativeDrawing();
|
||||
if (!hdc)
|
||||
@ -1742,7 +1749,26 @@ nsObjectFrame::PaintPlugin(nsIRenderingContext& aRenderingContext,
|
||||
|
||||
mInstanceOwner->Paint(dirty, hdc);
|
||||
nativeDraw.EndNativeDrawing();
|
||||
} while (nativeDraw.ShouldRenderAgain());
|
||||
doublePass = nativeDraw.ShouldRenderAgain();
|
||||
#ifdef MOZ_IPC
|
||||
if (doublePass) {
|
||||
// OOP plugin specific: let the shim know we are in the middle of a double pass
|
||||
// render. The second pass will reuse the previous rendering without going over
|
||||
// the wire.
|
||||
if (!mDoublePassEvent)
|
||||
mDoublePassEvent = ::RegisterWindowMessage(NS_OOPP_DOUBLEPASS_MSGID);
|
||||
if (mDoublePassEvent) {
|
||||
NPEvent pluginEvent;
|
||||
pluginEvent.event = mDoublePassEvent;
|
||||
pluginEvent.wParam = 0;
|
||||
pluginEvent.lParam = 0;
|
||||
PRBool eventHandled = PR_FALSE;
|
||||
|
||||
inst->HandleEvent(&pluginEvent, &eventHandled);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} while (doublePass);
|
||||
|
||||
nativeDraw.PaintToContext();
|
||||
} else if (!(ctx->GetFlags() & gfxContext::FLAG_DESTINED_FOR_SCREEN)) {
|
||||
|
@ -235,6 +235,9 @@ private:
|
||||
nsIView* mInnerView;
|
||||
nsCOMPtr<nsIWidget> mWidget;
|
||||
nsIntRect mWindowlessRect;
|
||||
#ifdef XP_WIN
|
||||
PRUint32 mDoublePassEvent;
|
||||
#endif
|
||||
|
||||
// For assertions that make it easier to determine if a crash is due
|
||||
// to the underlying problem described in bug 136927, and to prevent
|
||||
|
@ -98,6 +98,7 @@ STATIC_LIBS += \
|
||||
mozipc_s \
|
||||
chromium_s \
|
||||
ipcshell_s \
|
||||
gfxipc_s \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_IPDL_TESTS
|
||||
|
Loading…
Reference in New Issue
Block a user