Bug 384845. Make the NPSetWindowCallbackStruct memory associated with

window->ws_info available before SetWindow is called, and disable the plugin
window GtkSocket or xtbin creation for windowless plugins.
patch by Karl Tomlinson, r+sr=jst
This commit is contained in:
roc+@cs.cmu.edu 2007-07-02 20:29:47 -07:00
parent 674a9da875
commit 71fc801e9d
3 changed files with 114 additions and 121 deletions

View File

@ -1615,15 +1615,6 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner()
mTagText = nsnull;
}
#if defined(XP_UNIX) && !defined(XP_MACOSX)
// the mem for this struct is allocated
// by PR_MALLOC in ns4xPluginInstance.cpp:ns4xPluginInstance::SetWindow()
if (mPluginWindow && mPluginWindow->ws_info) {
PR_Free(mPluginWindow->ws_info);
mPluginWindow->ws_info = nsnull;
}
#endif
// clean up plugin native window object
nsCOMPtr<nsIPluginHost> ph = do_GetService(kCPluginManagerCID);
nsCOMPtr<nsPIPluginHost> pph(do_QueryInterface(ph));

View File

@ -1105,123 +1105,113 @@ NS_IMETHODIMP ns4xPluginInstance::Destroy(void)
////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window)
{
#if defined (MOZ_WIDGET_GTK2)
NPSetWindowCallbackStruct *ws;
#endif
// XXX 4.x plugins don't want a SetWindow(NULL).
if (!window || !mStarted)
return NS_OK;
NPError error;
// It would be nice if this was all moved to
// nsPluginNativeWindowGtk2::CallSetWindow or nsWindow or somewhere else?
#if defined (MOZ_WIDGET_GTK2)
PRBool isXembed = PR_FALSE;
// bug 108337, flash plugin on linux doesn't like window->width <= 0
if ((PRInt32) window->width <= 0 || (PRInt32) window->height <= 0)
return NS_OK;
if (window->type == nsPluginWindowType_Window) {
PRBool isXembed = PR_FALSE;
// bug 108337, flash plugin on linux doesn't like window->width <= 0
if ((PRInt32) window->width <= 0 || (PRInt32) window->height <= 0)
return NS_OK;
// We need to test if this is an xembed window before doing checks
// below, as they might be used on the first pass or on later passes
// when we resize the plugin window.
GdkWindow *win = gdk_window_lookup((XID)window->window);
if (!win)
return NS_ERROR_FAILURE;
// We need to test if this is an xembed window before doing checks
// below, as they might be used on the first pass or on later passes
// when we resize the plugin window.
GdkWindow *win = gdk_window_lookup((XID)window->window);
if (!win)
return NS_ERROR_FAILURE;
gpointer user_data = nsnull;
gdk_window_get_user_data(win, &user_data);
if (user_data && GTK_IS_WIDGET(user_data)) {
GtkWidget* widget = GTK_WIDGET(user_data);
gpointer user_data = nsnull;
gdk_window_get_user_data(win, &user_data);
if (user_data && GTK_IS_WIDGET(user_data)) {
GtkWidget* widget = GTK_WIDGET(user_data);
if (GTK_IS_SOCKET(widget))
isXembed = PR_TRUE;
}
// Allocate and fill out the ws_info data
if (!window->ws_info || !mXtBin) {
if (!window->ws_info) {
#ifdef NS_DEBUG
printf("About to create new ws_info...\n");
#endif
// allocate a new NPSetWindowCallbackStruct structure at ws_info
window->ws_info = (NPSetWindowCallbackStruct *)PR_MALLOC(sizeof(NPSetWindowCallbackStruct));
if (!window->ws_info)
return NS_ERROR_OUT_OF_MEMORY;
if (GTK_IS_SOCKET(widget))
isXembed = PR_TRUE;
}
ws = (NPSetWindowCallbackStruct *)window->ws_info;
// Fill out the ws_info data.
// (ws_info should be non-null but check just in case.)
if (!mXtBin && window->ws_info) {
if (!isXembed)
{
NPSetWindowCallbackStruct* ws =
NS_STATIC_CAST(NPSetWindowCallbackStruct*, window->ws_info);
if (!isXembed) {
#ifdef NS_DEBUG
printf("About to create new xtbin of %i X %i from %p...\n",
window->width, window->height, win);
printf("About to create new xtbin of %i X %i from %p...\n",
window->width, window->height, (void*)win);
#endif
#if 0
// if we destroyed the plugin when we left the page, we could remove this
// code (i believe) the problem here is that the window gets destroyed when
// its parent, etc does by changing a page the plugin instance is being
// held on to, so when we return to the page, we have a mXtBin, but it is
// in a not-so-good state.
// --
// this is lame. we shouldn't be destroying this everytime, but I can't find
// a good way to tell if we need to destroy/recreate the xtbin or not
// what if the plugin wants to change the window and not just resize it??
// (pav)
// if we destroyed the plugin when we left the page, we could remove this
// code (i believe) the problem here is that the window gets destroyed when
// its parent, etc does by changing a page the plugin instance is being
// held on to, so when we return to the page, we have a mXtBin, but it is
// in a not-so-good state.
// --
// this is lame. we shouldn't be destroying this everytime, but I can't find
// a good way to tell if we need to destroy/recreate the xtbin or not
// what if the plugin wants to change the window and not just resize it??
// (pav)
if (mXtBin) {
gtk_widget_destroy(mXtBin);
mXtBin = NULL;
if (mXtBin) {
gtk_widget_destroy(mXtBin);
mXtBin = NULL;
}
#endif
if (!mXtBin) {
mXtBin = gtk_xtbin_new(win, 0);
// Check to see if creating mXtBin failed for some reason.
// if it did, we can't go any further.
if (!mXtBin)
return NS_ERROR_FAILURE;
}
gtk_widget_set_usize(mXtBin, window->width, window->height);
#ifdef NS_DEBUG
printf("About to show xtbin(%p)...\n", (void*)mXtBin); fflush(NULL);
#endif
gtk_widget_show(mXtBin);
#ifdef NS_DEBUG
printf("completed gtk_widget_show(%p)\n", (void*)mXtBin); fflush(NULL);
#endif
}
#endif
if (!mXtBin) {
mXtBin = gtk_xtbin_new(win, 0);
// Check to see if creating mXtBin failed for some reason.
// if it did, we can't go any further.
if (!mXtBin)
return NS_ERROR_FAILURE;
}
gtk_widget_set_usize(mXtBin, window->width, window->height);
#ifdef NS_DEBUG
printf("About to show xtbin(%p)...\n", mXtBin); fflush(NULL);
#endif
gtk_widget_show(mXtBin);
#ifdef NS_DEBUG
printf("completed gtk_widget_show(%p)\n", mXtBin); fflush(NULL);
#endif
}
// fill in window info structure
ws->type = 0; // OK, that was a guess!!
// fill in window info structure
ws->type = 0; // OK, that was a guess!!
#ifdef MOZ_X11
ws->depth = gdk_window_get_visual(win)->depth;
if (!isXembed)
ws->display = GTK_XTBIN(mXtBin)->xtdisplay;
else
ws->display = GDK_WINDOW_XDISPLAY(win);
ws->visual = GDK_VISUAL_XVISUAL(gdk_window_get_visual(win));
ws->colormap = GDK_COLORMAP_XCOLORMAP(gdk_window_get_colormap(win));
ws->depth = gdk_window_get_visual(win)->depth;
if (!isXembed)
ws->display = GTK_XTBIN(mXtBin)->xtdisplay;
else
ws->display = GDK_WINDOW_XDISPLAY(win);
ws->visual = GDK_VISUAL_XVISUAL(gdk_window_get_visual(win));
ws->colormap = GDK_COLORMAP_XCOLORMAP(gdk_window_get_colormap(win));
XFlush(ws->display);
XFlush(ws->display);
#endif
} // !window->ws_info
} // !mXtBin
if (!mXtBin && !isXembed)
return NS_ERROR_FAILURE;
if (!mXtBin && !isXembed)
return NS_ERROR_FAILURE;
if (!isXembed) {
// And now point the NPWindow structures window
// to the actual X window
window->window = (nsPluginPort *)GTK_XTBIN(mXtBin)->xtwindow;
if (!isXembed) {
// And now point the NPWindow structures window
// to the actual X window
window->window = (nsPluginPort *)GTK_XTBIN(mXtBin)->xtwindow;
gtk_xtbin_resize(mXtBin, window->width, window->height);
gtk_xtbin_resize(mXtBin, window->width, window->height);
}
}
#endif // MOZ_WIDGET
@ -1352,9 +1342,8 @@ NS_IMETHODIMP ns4xPluginInstance::HandleEvent(nsPluginEvent* event, PRBool* hand
result = CallNPP_HandleEventProc(fCallbacks->event,
&fNPP,
(void*) event->event);
#endif
#if defined(XP_WIN) || defined(XP_OS2)
#elif defined(XP_WIN) || defined(XP_OS2)
NPEvent npEvent;
npEvent.event = event->event;
npEvent.wParam = event->wParam;
@ -1363,6 +1352,11 @@ NS_IMETHODIMP ns4xPluginInstance::HandleEvent(nsPluginEvent* event, PRBool* hand
NS_TRY_SAFE_CALL_RETURN(result, CallNPP_HandleEventProc(fCallbacks->event,
&fNPP,
(void*)&npEvent), fLibrary, this);
#else // MOZ_X11 or other
result = CallNPP_HandleEventProc(fCallbacks->event,
&fNPP,
(void*)&event->event);
#endif
NPP_PLUGIN_LOG(PLUGIN_LOG_NOISY,

View File

@ -64,6 +64,7 @@ public:
virtual nsresult CallSetWindow(nsCOMPtr<nsIPluginInstance> &aPluginInstance);
private:
GtkWidget* mGtkSocket;
NPSetWindowCallbackStruct m_ws_info;
nsresult CreateXEmbedWindow();
void SetAllocation();
PRBool CanGetValueFromPlugin(nsCOMPtr<nsIPluginInstance> &aPluginInstance);
@ -80,9 +81,14 @@ nsPluginNativeWindowGtk2::nsPluginNativeWindowGtk2() : nsPluginNativeWindow()
width = 0;
height = 0;
memset(&clipRect, 0, sizeof(clipRect));
ws_info = nsnull;
ws_info = &m_ws_info;
type = nsPluginWindowType_Window;
mGtkSocket = 0;
m_ws_info.type = 0;
m_ws_info.display = nsnull;
m_ws_info.visual = nsnull;
m_ws_info.colormap = 0;
m_ws_info.depth = 0;
}
nsPluginNativeWindowGtk2::~nsPluginNativeWindowGtk2()
@ -111,28 +117,30 @@ nsresult PLUG_DeletePluginNativeWindow(nsPluginNativeWindow * aPluginNativeWindo
nsresult nsPluginNativeWindowGtk2::CallSetWindow(nsCOMPtr<nsIPluginInstance> &aPluginInstance)
{
if(aPluginInstance) {
nsresult rv;
PRBool val = PR_FALSE;
if(!mGtkSocket) {
if (CanGetValueFromPlugin(aPluginInstance))
rv = aPluginInstance->GetValue
((nsPluginInstanceVariable)NPPVpluginNeedsXEmbed, &val);
}
if (type == nsPluginWindowType_Window) {
nsresult rv;
PRBool val = PR_FALSE;
if(!mGtkSocket) {
if (CanGetValueFromPlugin(aPluginInstance))
rv = aPluginInstance->GetValue
((nsPluginInstanceVariable)NPPVpluginNeedsXEmbed, &val);
}
#ifdef DEBUG
printf("nsPluginNativeWindowGtk2: NPPVpluginNeedsXEmbed=%d\n", val);
printf("nsPluginNativeWindowGtk2: NPPVpluginNeedsXEmbed=%d\n", val);
#endif
if(val) {
CreateXEmbedWindow();
}
if(val) {
CreateXEmbedWindow();
}
if(mGtkSocket) {
// Make sure to resize and re-place the window if required
SetAllocation();
window = (nsPluginPort *)gtk_socket_get_id(GTK_SOCKET(mGtkSocket));
}
if(mGtkSocket) {
// Make sure to resize and re-place the window if required
SetAllocation();
window = (nsPluginPort *)gtk_socket_get_id(GTK_SOCKET(mGtkSocket));
}
#ifdef DEBUG
printf("nsPluginNativeWindowGtk2: call SetWindow with xid=%p\n", (void *)window);
printf("nsPluginNativeWindowGtk2: call SetWindow with xid=%p\n", (void *)window);
#endif
}
aPluginInstance->SetWindow(this);
}
else if (mPluginInstance)