basic support for windowless X11 plugins. gfx not quite working yet

This commit is contained in:
Chris Jones 2009-09-24 21:03:59 -05:00
parent fb35538a29
commit 0531f8f96b
9 changed files with 315 additions and 82 deletions

View File

@ -66,6 +66,13 @@ child:
rpc NPP_SetWindow(NPWindow window)
returns (NPError rv);
rpc NPP_GetValue_NPPVpluginWindow()
returns (bool value, NPError result);
rpc NPP_GetValue_NPPVpluginTransparent()
returns (bool value, NPError result);
// this message is not used on non-X platforms
rpc NPP_GetValue_NPPVpluginNeedsXEmbed()
returns (bool value, NPError result);
rpc NPP_GetValue_NPPVpluginScriptableNPObject()
returns (PPluginScriptableObject value, NPError result);
@ -84,6 +91,11 @@ parent:
rpc NPN_GetValue_NPNVprivateModeBool()
returns (bool value, NPError result);
rpc NPN_SetValue_NPPVpluginWindow(bool windowed)
returns (NPError result);
rpc NPN_SetValue_NPPVpluginTransparent(bool transparent)
returns (NPError result);
rpc NPN_GetURL(nsCString url, nsCString target)
returns (NPError result);
rpc NPN_PostURL(nsCString url, nsCString target, nsCString buffer, bool file)

View File

@ -57,42 +57,6 @@ using namespace mozilla::plugins;
#endif
namespace {
static const char*
NPNVariableToString(NPNVariable aVar)
{
#define VARSTR(v_) case v_: return #v_
switch(aVar) {
VARSTR(NPNVxDisplay);
VARSTR(NPNVxtAppContext);
VARSTR(NPNVnetscapeWindow);
VARSTR(NPNVjavascriptEnabledBool);
VARSTR(NPNVasdEnabledBool);
VARSTR(NPNVisOfflineBool);
VARSTR(NPNVserviceManager);
VARSTR(NPNVDOMElement);
VARSTR(NPNVDOMWindow);
VARSTR(NPNVToolkit);
VARSTR(NPNVSupportsXEmbedBool);
VARSTR(NPNVWindowNPObject);
VARSTR(NPNVPluginElementNPObject);
VARSTR(NPNVSupportsWindowless);
VARSTR(NPNVprivateModeBool);
default: return "???";
}
#undef VARSTR
}
} /* anonymous namespace */
PluginInstanceChild::~PluginInstanceChild()
{
#if defined(OS_WIN)
@ -110,9 +74,11 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
switch(aVar) {
case NPNVSupportsWindowless:
// FIXME/cjones report true here and use XComposite + child
// surface to implement windowless plugins
#if defined(OS_LINUX)
*((NPBool*)aValue) = true;
#else
*((NPBool*)aValue) = false;
#endif
return NPERR_NO_ERROR;
#if defined(OS_LINUX)
@ -160,11 +126,87 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
default:
printf(" unhandled var %s\n", NPNVariableToString(aVar));
return NPERR_GENERIC_ERROR;
return NPERR_GENERIC_ERROR;
}
}
NPError
PluginInstanceChild::NPN_SetValue(NPPVariable aVar, void* aValue)
{
printf ("[PluginInstanceChild] NPN_SetValue(%s, %ld)\n",
NPPVariableToString(aVar), reinterpret_cast<intptr_t>(aValue));
switch (aVar) {
case NPPVpluginWindowBool: {
NPError rv;
bool windowed = (NPBool) (intptr_t) aValue;
if (!CallNPN_SetValue_NPPVpluginWindow(windowed, &rv))
return NPERR_GENERIC_ERROR;
return rv;
}
case NPPVpluginTransparentBool: {
NPError rv;
bool transparent = (NPBool) (intptr_t) aValue;
if (!CallNPN_SetValue_NPPVpluginTransparent(transparent, &rv))
return NPERR_GENERIC_ERROR;
return rv;
}
default:
printf(" unhandled var %s\n", NPPVariableToString(aVar));
return NPERR_GENERIC_ERROR;
}
}
bool
PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginWindow(
bool* windowed, NPError* rv)
{
NPBool isWindowed;
*rv = mPluginIface->getvalue(GetNPP(), NPPVpluginWindowBool,
reinterpret_cast<void*>(&isWindowed));
*windowed = isWindowed;
return true;
}
bool
PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginTransparent(
bool* transparent, NPError* rv)
{
NPBool isTransparent;
*rv = mPluginIface->getvalue(GetNPP(), NPPVpluginTransparentBool,
reinterpret_cast<void*>(&isTransparent));
*transparent = isTransparent;
return true;
}
bool
PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginNeedsXEmbed(
bool* needs, NPError* rv)
{
#ifdef OS_LINUX
NPBool needsXEmbed;
*rv = mPluginIface->getvalue(GetNPP(), NPPVpluginNeedsXEmbed,
reinterpret_cast<void*>(&needsXEmbed));
*needs = needsXEmbed;
return true;
#else
NS_RUNTIMEABORT("shouldn't be called on non-linux platforms");
#endif
}
bool
PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginScriptableNPObject(
PPluginScriptableObjectChild** value,
@ -194,6 +236,14 @@ bool
PluginInstanceChild::AnswerNPP_HandleEvent(const NPEvent& event,
int16_t* handled)
{
_MOZ_LOG(__FUNCTION__);
#if defined(OS_LINUX) && defined(DEBUG_cjones)
if (GraphicsExpose == event.type)
printf(" received drawable 0x%lx\n",
event.xgraphicsexpose.drawable);
#endif
// plugins might be fooling with these, make a copy
NPEvent evcopy = event;
*handled = mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy));
@ -218,7 +268,7 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPWindow& aWindow,
mWindow.window = (void*) handle;
mWindow.width = aWindow.width;
mWindow.height = aWindow.height;
mWindow.type = NPWindowTypeWindow;
mWindow.type = aWindow.type;
mWsInfo.display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());

View File

@ -70,6 +70,13 @@ class PluginInstanceChild : public PPluginInstanceChild
protected:
virtual bool AnswerNPP_SetWindow(const NPWindow& window, NPError* rv);
virtual bool
AnswerNPP_GetValue_NPPVpluginWindow(bool* windowed, NPError* rv);
virtual bool
AnswerNPP_GetValue_NPPVpluginTransparent(bool* transparent, NPError* rv);
virtual bool
AnswerNPP_GetValue_NPPVpluginNeedsXEmbed(bool* needs, NPError* rv);
virtual bool
AnswerNPP_GetValue_NPPVpluginScriptableNPObject(PPluginScriptableObjectChild** value,
NPError* result);
@ -157,8 +164,10 @@ public:
}
NPError
NPN_GetValue(NPNVariable aVariable,
void* aValue);
NPN_GetValue(NPNVariable aVariable, void* aValue);
NPError
NPN_SetValue(NPPVariable aVariable, void* aValue);
PluginScriptableObjectChild*
GetActorForNPObject(NPObject* aObject);

View File

@ -169,6 +169,28 @@ PluginInstanceParent::AnswerNPN_GetValue_NPNVprivateModeBool(bool* value,
return true;
}
bool
PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginWindow(
const bool& windowed, NPError* result)
{
NPBool isWindowed = windowed;
*result = mNPNIface->setvalue(mNPP, NPPVpluginWindowBool,
(void*)isWindowed);
return true;
}
bool
PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginTransparent(
const bool& transparent, NPError* result)
{
NPBool isTransparent = transparent;
*result = mNPNIface->setvalue(mNPP, NPPVpluginTransparentBool,
(void*)isTransparent);
return true;
}
bool
PluginInstanceParent::AnswerNPN_GetURL(const nsCString& url,
const nsCString& target,
@ -243,46 +265,90 @@ NPError
PluginInstanceParent::NPP_GetValue(NPPVariable aVariable,
void* _retval)
{
_MOZ_LOG(__FUNCTION__);
printf("[PluginInstanceParent] NPP_GetValue(%s)\n",
NPPVariableToString(aVariable));
switch (aVariable) {
#ifdef OS_LINUX
// FIXME/cjones: HACK ALERT! should forward to child
case NPPVpluginNeedsXEmbed:
(*(PRBool*)_retval) = PR_TRUE;
return NPERR_NO_ERROR;
#endif
case NPPVpluginWindowBool: {
bool windowed;
NPError rv;
case NPPVpluginScriptableNPObject: {
PPluginScriptableObjectParent* actor;
NPError rv;
if (!CallNPP_GetValue_NPPVpluginScriptableNPObject(&actor, &rv)) {
return NPERR_GENERIC_ERROR;
}
if (NPERR_NO_ERROR != rv) {
return rv;
}
const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs();
if (!npn) {
NS_WARNING("No netscape functions?!");
return NPERR_GENERIC_ERROR;
}
NPObject* object =
reinterpret_cast<PluginScriptableObjectParent*>(actor)->
GetObject();
NS_ASSERTION(object, "This shouldn't ever be null!");
(*(NPObject**)_retval) = npn->retainobject(object);
return NPERR_NO_ERROR;
if (!CallNPP_GetValue_NPPVpluginWindow(&windowed, &rv)) {
return NPERR_GENERIC_ERROR;
}
// TODO: more values
default:
if (NPERR_NO_ERROR != rv) {
return rv;
}
(*(NPBool*)_retval) = windowed;
return NPERR_NO_ERROR;
}
case NPPVpluginTransparentBool: {
bool transparent;
NPError rv;
if (!CallNPP_GetValue_NPPVpluginTransparent(&transparent, &rv)) {
return NPERR_GENERIC_ERROR;
}
if (NPERR_NO_ERROR != rv) {
return rv;
}
(*(NPBool*)_retval) = transparent;
return NPERR_NO_ERROR;
}
#ifdef OS_LINUX
case NPPVpluginNeedsXEmbed: {
bool needsXEmbed;
NPError rv;
if (!CallNPP_GetValue_NPPVpluginNeedsXEmbed(&needsXEmbed, &rv)) {
return NPERR_GENERIC_ERROR;
}
if (NPERR_NO_ERROR != rv) {
return rv;
}
(*(NPBool*)_retval) = needsXEmbed;
return NPERR_NO_ERROR;
}
#endif
case NPPVpluginScriptableNPObject: {
PPluginScriptableObjectParent* actor;
NPError rv;
if (!CallNPP_GetValue_NPPVpluginScriptableNPObject(&actor, &rv)) {
return NPERR_GENERIC_ERROR;
}
if (NPERR_NO_ERROR != rv) {
return rv;
}
const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs();
if (!npn) {
NS_WARNING("No netscape functions?!");
return NPERR_GENERIC_ERROR;
}
NPObject* object =
reinterpret_cast<PluginScriptableObjectParent*>(actor)->
GetObject();
NS_ASSERTION(object, "This shouldn't ever be null!");
(*(NPObject**)_retval) = npn->retainobject(object);
return NPERR_NO_ERROR;
}
default:
printf(" unhandled var %s\n", NPPVariableToString(aVariable));
return NPERR_GENERIC_ERROR;
}
}
@ -291,9 +357,22 @@ PluginInstanceParent::NPP_HandleEvent(void* event)
{
_MOZ_LOG(__FUNCTION__);
NPEvent* npevent = reinterpret_cast<NPEvent*>(event);
#if defined(OS_LINUX)
if (GraphicsExpose == npevent->type) {
printf(" schlepping drawable 0x%lx across the pipe\n",
npevent->xgraphicsexpose.drawable);
// FIXME: this is probably rather expensive, should only do it
// when necessary. which raises the question: when is it
// necessary?
XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), False);
}
#endif
int16_t handled;
if (!CallNPP_HandleEvent(*reinterpret_cast<NPEvent*>(event),
&handled)) {
if (!CallNPP_HandleEvent(*npevent, &handled)) {
return 0; // no good way to handle errors here...
}

View File

@ -123,6 +123,12 @@ public:
virtual bool
AnswerNPN_GetValue_NPNVprivateModeBool(bool* value, NPError* result);
virtual bool
AnswerNPN_SetValue_NPPVpluginWindow(const bool& windowed, NPError* result);
virtual bool
AnswerNPN_SetValue_NPPVpluginTransparent(const bool& transparent,
NPError* result);
virtual bool
AnswerNPN_GetURL(const nsCString& url, const nsCString& target,
NPError *result);
@ -143,15 +149,14 @@ public:
const NPReason& reason);
NPError NPP_SetWindow(NPWindow* aWindow);
NPError NPP_GetValue(NPPVariable variable, void *ret_value);
NPError NPP_GetValue(NPPVariable variable, void *ret_value);
NPError NPP_SetValue(NPNVariable variable, void *value)
{
_MOZ_LOG(__FUNCTION__);
return 1;
}
NPError NPP_NewStream(NPMIMEType type, NPStream* stream,
NPBool seekable, uint16_t* stype);
NPError NPP_DestroyStream(NPStream* stream, NPReason reason);

View File

@ -80,6 +80,78 @@ typedef std::vector<IPCByteRange> IPCByteRanges;
typedef nsCString Buffer;
// XXX maybe not the best place for these. better one?
#define VARSTR(v_) case v_: return #v_
inline const char* const
NPPVariableToString(NPPVariable aVar)
{
switch (aVar) {
VARSTR(NPPVpluginNameString);
VARSTR(NPPVpluginDescriptionString);
VARSTR(NPPVpluginWindowBool);
VARSTR(NPPVpluginTransparentBool);
VARSTR(NPPVjavaClass);
VARSTR(NPPVpluginWindowSize);
VARSTR(NPPVpluginTimerInterval);
VARSTR(NPPVpluginScriptableInstance);
VARSTR(NPPVpluginScriptableIID);
VARSTR(NPPVjavascriptPushCallerBool);
VARSTR(NPPVpluginKeepLibraryInMemory);
VARSTR(NPPVpluginNeedsXEmbed);
VARSTR(NPPVpluginScriptableNPObject);
VARSTR(NPPVformValue);
VARSTR(NPPVpluginUrlRequestsDisplayedBool);
VARSTR(NPPVpluginWantsAllNetworkStreams);
#ifdef XP_MACOSX
VARSTR(NPPVpluginDrawingModel);
VARSTR(NPPVpluginEventModel);
#endif
default: return "???";
}
}
inline const char*
NPNVariableToString(NPNVariable aVar)
{
switch(aVar) {
VARSTR(NPNVxDisplay);
VARSTR(NPNVxtAppContext);
VARSTR(NPNVnetscapeWindow);
VARSTR(NPNVjavascriptEnabledBool);
VARSTR(NPNVasdEnabledBool);
VARSTR(NPNVisOfflineBool);
VARSTR(NPNVserviceManager);
VARSTR(NPNVDOMElement);
VARSTR(NPNVDOMWindow);
VARSTR(NPNVToolkit);
VARSTR(NPNVSupportsXEmbedBool);
VARSTR(NPNVWindowNPObject);
VARSTR(NPNVPluginElementNPObject);
VARSTR(NPNVSupportsWindowless);
VARSTR(NPNVprivateModeBool);
default: return "???";
}
}
#undef VARSTR
} /* namespace plugins */
} /* namespace mozilla */

View File

@ -174,6 +174,9 @@ PluginModuleChild::InitGraphics()
// FIXME/cjones: is this the place for this?
#if defined(OS_LINUX)
gtk_init(0, 0);
XSynchronize(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
True);
#else
// may not be necessary on all platforms
#endif
@ -480,7 +483,7 @@ _setvalue(NPP aNPP,
void* aValue)
{
_MOZ_LOG(__FUNCTION__);
return NPERR_NO_ERROR;
return InstCast(aNPP)->NPN_SetValue(aVariable, aValue);
}
NPError NP_CALLBACK

View File

@ -88,7 +88,7 @@ typedef NS_NPAPIPLUGIN_CALLBACK(NPError, NP_MAIN) (NPNetscapeFuncs* nCallbacks,
#endif
#undef _MOZ_LOG
#define _MOZ_LOG(s) printf("[NPAPIPluginChild] %s\n", s)
#define _MOZ_LOG(s) printf("[PluginModuleChild] %s\n", s)
namespace mozilla {
namespace plugins {

View File

@ -155,6 +155,9 @@ pluginDrawWindow(InstanceData* instanceData, GdkDrawable* gdkWindow)
int width = window.width;
int height = window.height;
if (!instanceData->hasWidget)
gdk_drawable_set_colormap(gdkWindow, gdk_rgb_get_colormap());
if (instanceData->scriptableObject->drawMode == DM_SOLID_COLOR) {
// drawing a solid color for reftests
pluginDrawSolid(instanceData, gdkWindow, x, y, width, height);
@ -307,7 +310,7 @@ pluginHandleEvent(InstanceData* instanceData, void* event)
GdkNativeWindow nativeWinId =
reinterpret_cast<XID>(instanceData->window.window);
GdkDrawable* gdkWindow = GDK_DRAWABLE(gdk_window_foreign_new(nativeWinId));
GdkDrawable* gdkWindow = GDK_DRAWABLE(gdk_pixmap_foreign_new(nativeWinId));
pluginDrawWindow(instanceData, gdkWindow);
g_object_unref(gdkWindow);
break;