From 73c329b27c2267ff78e60a4a052d401de18e021f Mon Sep 17 00:00:00 2001 From: Date: Mon, 2 Jul 2007 20:29:47 -0700 Subject: [PATCH] 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 --- layout/generic/nsObjectFrame.cpp | 9 - .../plugin/base/src/ns4xPluginInstance.cpp | 182 +++++++++--------- .../base/src/nsPluginNativeWindowGtk2.cpp | 44 +++-- 3 files changed, 114 insertions(+), 121 deletions(-) diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index e943017bc1cb..70a7350aba1c 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -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 ph = do_GetService(kCPluginManagerCID); nsCOMPtr pph(do_QueryInterface(ph)); diff --git a/modules/plugin/base/src/ns4xPluginInstance.cpp b/modules/plugin/base/src/ns4xPluginInstance.cpp index fd715315ee63..07f0c449e92a 100644 --- a/modules/plugin/base/src/ns4xPluginInstance.cpp +++ b/modules/plugin/base/src/ns4xPluginInstance.cpp @@ -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, diff --git a/modules/plugin/base/src/nsPluginNativeWindowGtk2.cpp b/modules/plugin/base/src/nsPluginNativeWindowGtk2.cpp index e9e8398a47a1..42a99ba6702e 100644 --- a/modules/plugin/base/src/nsPluginNativeWindowGtk2.cpp +++ b/modules/plugin/base/src/nsPluginNativeWindowGtk2.cpp @@ -64,6 +64,7 @@ public: virtual nsresult CallSetWindow(nsCOMPtr &aPluginInstance); private: GtkWidget* mGtkSocket; + NPSetWindowCallbackStruct m_ws_info; nsresult CreateXEmbedWindow(); void SetAllocation(); PRBool CanGetValueFromPlugin(nsCOMPtr &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 &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)