mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 544088 - Support Xt plugins OOP. r=karlt
This commit is contained in:
parent
196d5ba025
commit
cba37b7a79
@ -11,6 +11,7 @@
|
||||
|
||||
#include "nsDebug.h"
|
||||
#include "nsPluginNativeWindow.h"
|
||||
#include "nsNPAPIPlugin.h"
|
||||
#include "npapi.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
@ -32,7 +33,7 @@ private:
|
||||
* that encapsulates the Xt toolkit within a Gtk Application.
|
||||
*/
|
||||
GtkWidget* mSocketWidget;
|
||||
nsresult CreateXEmbedWindow();
|
||||
nsresult CreateXEmbedWindow(bool aEnableXtFocus);
|
||||
nsresult CreateXtWindow();
|
||||
void SetAllocation();
|
||||
};
|
||||
@ -105,8 +106,10 @@ nsresult nsPluginNativeWindowGtk2::CallSetWindow(nsRefPtr<nsNPAPIPluginInstance>
|
||||
printf("nsPluginNativeWindowGtk2: NPPVpluginNeedsXEmbed=%d\n", needsXEmbed);
|
||||
#endif
|
||||
|
||||
if (needsXEmbed) {
|
||||
rv = CreateXEmbedWindow();
|
||||
bool isOOPPlugin = aPluginInstance->GetPlugin()->GetLibrary()->IsOOP();
|
||||
if (needsXEmbed || isOOPPlugin) {
|
||||
bool enableXtFocus = !needsXEmbed;
|
||||
rv = CreateXEmbedWindow(enableXtFocus);
|
||||
}
|
||||
else {
|
||||
rv = CreateXtWindow();
|
||||
@ -129,7 +132,7 @@ nsresult nsPluginNativeWindowGtk2::CallSetWindow(nsRefPtr<nsNPAPIPluginInstance>
|
||||
// Point the NPWindow structures window to the actual X window
|
||||
window = (void*)GTK_XTBIN(mSocketWidget)->xtwindow;
|
||||
}
|
||||
else { // XEmbed
|
||||
else { // XEmbed or OOP&Xt
|
||||
SetAllocation();
|
||||
window = (void*)gtk_socket_get_id(GTK_SOCKET(mSocketWidget));
|
||||
}
|
||||
@ -146,7 +149,7 @@ nsresult nsPluginNativeWindowGtk2::CallSetWindow(nsRefPtr<nsNPAPIPluginInstance>
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPluginNativeWindowGtk2::CreateXEmbedWindow() {
|
||||
nsresult nsPluginNativeWindowGtk2::CreateXEmbedWindow(bool aEnableXtFocus) {
|
||||
NS_ASSERTION(!mSocketWidget,"Already created a socket widget!");
|
||||
GdkDisplay *display = gdk_display_get_default();
|
||||
GdkWindow *parent_win = gdk_x11_window_lookup_for_display(display, (XID)window);
|
||||
@ -155,6 +158,10 @@ nsresult nsPluginNativeWindowGtk2::CreateXEmbedWindow() {
|
||||
//attach the socket to the container widget
|
||||
gtk_widget_set_parent_window(mSocketWidget, parent_win);
|
||||
|
||||
// enable/disable focus event handlers,
|
||||
// see plugin_window_filter_func() for details
|
||||
g_object_set_data(G_OBJECT(mSocketWidget), "enable-xt-focus", (void *)aEnableXtFocus);
|
||||
|
||||
// Make sure to handle the plug_removed signal. If we don't the
|
||||
// socket will automatically be destroyed when the plug is
|
||||
// removed, which means we're destroying it more than once.
|
||||
|
@ -108,6 +108,9 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface)
|
||||
, mAsyncInvalidateTask(0)
|
||||
, mCachedWindowActor(nsnull)
|
||||
, mCachedElementActor(nsnull)
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
, mXEmbed(false)
|
||||
#endif // MOZ_X11 && XP_UNIX && !XP_MACOSX
|
||||
#if defined(OS_WIN)
|
||||
, mPluginWindowHWND(0)
|
||||
, mPluginWndProc(0)
|
||||
@ -146,13 +149,15 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface)
|
||||
#endif
|
||||
{
|
||||
memset(&mWindow, 0, sizeof(mWindow));
|
||||
mWindow.type = NPWindowTypeWindow;
|
||||
mData.ndata = (void*) this;
|
||||
mData.pdata = nsnull;
|
||||
mAsyncBitmaps.Init();
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
mWindow.ws_info = &mWsInfo;
|
||||
memset(&mWsInfo, 0, sizeof(mWsInfo));
|
||||
mWsInfo.display = DefaultXDisplay();
|
||||
mWsInfo.display = NULL;
|
||||
mXtClient.top_widget = NULL;
|
||||
#endif // MOZ_X11 && XP_UNIX && !XP_MACOSX
|
||||
#if defined(OS_WIN)
|
||||
memset(&mAlphaExtract, 0, sizeof(mAlphaExtract));
|
||||
@ -306,6 +311,15 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
|
||||
*((NPNToolkitType*)aValue) = NPNVGtk2;
|
||||
return NPERR_NO_ERROR;
|
||||
|
||||
case NPNVxDisplay:
|
||||
if (!mWsInfo.display) {
|
||||
// We are called before Initialize() so we have to call it now.
|
||||
Initialize();
|
||||
NS_ASSERTION(mWsInfo.display, "We should have a valid display!");
|
||||
}
|
||||
*(void **)aValue = mWsInfo.display;
|
||||
return NPERR_NO_ERROR;
|
||||
|
||||
#elif defined(OS_WIN)
|
||||
case NPNVToolkit:
|
||||
return NPERR_GENERIC_ERROR;
|
||||
@ -492,6 +506,19 @@ PluginInstanceChild::NPN_SetValue(NPPVariable aVar, void* aValue)
|
||||
if (!CallNPN_SetValue_NPPVpluginWindow(windowed, &rv))
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
NPWindowType newWindowType = windowed ? NPWindowTypeWindow : NPWindowTypeDrawable;
|
||||
if (mWindow.type != newWindowType && mWsInfo.display) {
|
||||
// plugin type has been changed but we already have a valid display
|
||||
// so update it for the recent plugin mode
|
||||
if (mXEmbed || !windowed) {
|
||||
// Use default GTK display for XEmbed and windowless plugins
|
||||
mWsInfo.display = DefaultXDisplay();
|
||||
}
|
||||
else {
|
||||
mWsInfo.display = xt_client_get_display();
|
||||
}
|
||||
}
|
||||
mWindow.type = newWindowType;
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -975,6 +1002,52 @@ PluginInstanceChild::RecvWindowPosChanged(const NPRemoteEvent& event)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
// Create a new window from NPWindow
|
||||
bool PluginInstanceChild::CreateWindow(const NPRemoteWindow& aWindow)
|
||||
{
|
||||
PLUGIN_LOG_DEBUG(("%s (aWindow=<window: 0x%lx, x: %d, y: %d, width: %d, height: %d>)",
|
||||
FULLFUNCTION,
|
||||
aWindow.window,
|
||||
aWindow.x, aWindow.y,
|
||||
aWindow.width, aWindow.height));
|
||||
|
||||
if (mXEmbed) {
|
||||
mWindow.window = reinterpret_cast<void*>(aWindow.window);
|
||||
}
|
||||
else {
|
||||
Window browserSocket = (Window)(aWindow.window);
|
||||
xt_client_init(&mXtClient, mWsInfo.visual, mWsInfo.colormap, mWsInfo.depth);
|
||||
xt_client_create(&mXtClient, browserSocket, mWindow.width, mWindow.height);
|
||||
mWindow.window = (void *)XtWindow(mXtClient.child_widget);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Destroy window
|
||||
void PluginInstanceChild::DeleteWindow()
|
||||
{
|
||||
PLUGIN_LOG_DEBUG(("%s (aWindow=<window: 0x%lx, x: %d, y: %d, width: %d, height: %d>)",
|
||||
FULLFUNCTION,
|
||||
mWindow.window,
|
||||
mWindow.x, mWindow.y,
|
||||
mWindow.width, mWindow.height));
|
||||
|
||||
if (!mWindow.window)
|
||||
return;
|
||||
|
||||
if (mXtClient.top_widget) {
|
||||
xt_client_unrealize(&mXtClient);
|
||||
xt_client_destroy(&mXtClient);
|
||||
mXtClient.top_widget = NULL;
|
||||
}
|
||||
|
||||
// We don't have to keep the plug-in window ID any longer.
|
||||
mWindow.window = nsnull;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
|
||||
{
|
||||
@ -988,10 +1061,11 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
|
||||
AssertPluginThread();
|
||||
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
NS_ASSERTION(mWsInfo.display, "We should have a valid display!");
|
||||
|
||||
// The minimum info is sent over IPC to allow this
|
||||
// code to determine the rest.
|
||||
|
||||
mWindow.window = reinterpret_cast<void*>(aWindow.window);
|
||||
mWindow.x = aWindow.x;
|
||||
mWindow.y = aWindow.y;
|
||||
mWindow.width = aWindow.width;
|
||||
@ -1004,8 +1078,12 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
|
||||
&mWsInfo.visual, &mWsInfo.depth))
|
||||
return false;
|
||||
|
||||
if (!mWindow.window && mWindow.type == NPWindowTypeWindow) {
|
||||
CreateWindow(aWindow);
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK2
|
||||
if (gtk_check_version(2,18,7) != NULL) { // older
|
||||
if (mXEmbed && gtk_check_version(2,18,7) != NULL) { // older
|
||||
if (aWindow.type == NPWindowTypeWindow) {
|
||||
GdkWindow* socket_window = gdk_window_lookup(static_cast<GdkNativeWindow>(aWindow.window));
|
||||
if (socket_window) {
|
||||
@ -1136,6 +1214,33 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
|
||||
bool
|
||||
PluginInstanceChild::Initialize()
|
||||
{
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
NPError rv;
|
||||
|
||||
if (mWsInfo.display) {
|
||||
// Already initialized
|
||||
return false;
|
||||
}
|
||||
|
||||
// Request for windowless plugins is set in newp(), before this call.
|
||||
if (mWindow.type == NPWindowTypeWindow) {
|
||||
AnswerNPP_GetValue_NPPVpluginNeedsXEmbed(&mXEmbed, &rv);
|
||||
|
||||
// Set up Xt loop for windowed plugins without XEmbed support
|
||||
if (!mXEmbed) {
|
||||
xt_client_xloop_create();
|
||||
}
|
||||
}
|
||||
|
||||
// Use default GTK display for XEmbed and windowless plugins
|
||||
if (mXEmbed || mWindow.type != NPWindowTypeWindow) {
|
||||
mWsInfo.display = DefaultXDisplay();
|
||||
}
|
||||
else {
|
||||
mWsInfo.display = xt_client_get_display();
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3996,5 +4101,12 @@ PluginInstanceChild::AnswerNPP_Destroy(NPError* aResult)
|
||||
mAsyncBitmaps.Enumerate(DeleteSurface, this);
|
||||
}
|
||||
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
if (mWindow.type == NPWindowTypeWindow && !mXEmbed) {
|
||||
xt_client_xloop_destroy();
|
||||
}
|
||||
DeleteWindow();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -35,6 +35,10 @@ using namespace mozilla::plugins::PluginUtilsOSX;
|
||||
|
||||
#include <map>
|
||||
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
#include "gtk2xtbin.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace layers {
|
||||
@ -189,6 +193,11 @@ protected:
|
||||
virtual bool
|
||||
RecvNPP_DidComposite();
|
||||
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
bool CreateWindow(const NPRemoteWindow& aWindow);
|
||||
void DeleteWindow();
|
||||
#endif
|
||||
|
||||
public:
|
||||
PluginInstanceChild(const NPPluginFuncs* aPluginIface);
|
||||
|
||||
@ -375,6 +384,8 @@ private:
|
||||
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
NPSetWindowCallbackStruct mWsInfo;
|
||||
bool mXEmbed;
|
||||
XtClient mXtClient;
|
||||
#elif defined(OS_WIN)
|
||||
HWND mPluginWindowHWND;
|
||||
WNDPROC mPluginWndProc;
|
||||
|
@ -1094,7 +1094,19 @@ _getvalue(NPP aNPP,
|
||||
*(NPBool*)aValue = value ? true : false;
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
case NPNVxDisplay: {
|
||||
if (aNPP) {
|
||||
return InstCast(aNPP)->NPN_GetValue(aVariable, aValue);
|
||||
}
|
||||
else {
|
||||
*(void **)aValue = xt_client_get_display();
|
||||
}
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
case NPNVxtAppContext:
|
||||
return NPERR_GENERIC_ERROR;
|
||||
#endif
|
||||
default: {
|
||||
if (aNPP) {
|
||||
return InstCast(aNPP)->NPN_GetValue(aVariable, aValue);
|
||||
@ -1938,13 +1950,7 @@ PluginModuleChild::AllocPPluginInstance(const nsCString& aMimeType,
|
||||
}
|
||||
#endif
|
||||
|
||||
nsAutoPtr<PluginInstanceChild> childInstance(
|
||||
new PluginInstanceChild(&mFunctions));
|
||||
if (!childInstance->Initialize()) {
|
||||
*rv = NPERR_GENERIC_ERROR;
|
||||
return 0;
|
||||
}
|
||||
return childInstance.forget();
|
||||
return new PluginInstanceChild(&mFunctions);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2037,6 +2043,8 @@ PluginModuleChild::AnswerPPluginInstanceConstructor(PPluginInstanceChild* aActor
|
||||
return true;
|
||||
}
|
||||
|
||||
childInstance->Initialize();
|
||||
|
||||
#if defined(XP_MACOSX) && defined(__i386__)
|
||||
// If an i386 Mac OS X plugin has selected the Carbon event model then
|
||||
// we have to fail. We do not support putting Carbon event model plugins
|
||||
|
@ -5412,8 +5412,10 @@ plugin_window_filter_func(GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
|
||||
else
|
||||
#endif
|
||||
if(GTK_IS_SOCKET(widget)) {
|
||||
nswindow->SetPluginType(nsWindow::PluginType_XEMBED);
|
||||
break;
|
||||
if (!g_object_get_data(G_OBJECT(widget), "enable-xt-focus")) {
|
||||
nswindow->SetPluginType(nsWindow::PluginType_XEMBED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
nswindow->SetPluginType(nsWindow::PluginType_NONXEMBED);
|
||||
|
Loading…
Reference in New Issue
Block a user