patch for bug 189229 : xembed for plugins

patched by robin.lu@sun.com r=joshua.xia@sun.com sr=blizzard@mozilla.org
This commit is contained in:
robin.lu%sun.com 2003-09-16 01:44:41 +00:00
Родитель 2403f46a2d
Коммит 6c65d4e63d
10 изменённых файлов: 284 добавлений и 27 удалений

Просмотреть файл

@ -38,7 +38,7 @@
/*
* npapi.h $Revision: 3.31 $
* npapi.h $Revision: 3.32 $
* Netscape client plug-in API spec
*/
@ -387,7 +387,8 @@ typedef enum {
/* 12 and over are available on Mozilla builds starting with 0.9.9 */
NPPVjavascriptPushCallerBool = 12,
NPPVpluginKeepLibraryInMemory = 13 /* available in Mozilla 1.0 */
NPPVpluginKeepLibraryInMemory = 13, /* available in Mozilla 1.0 */
NPPVpluginNeedsXEmbed = 14
} NPPVariable;
/*
@ -404,9 +405,19 @@ typedef enum {
/* 10 and over are available on Mozilla builds starting with 0.9.4 */
NPNVserviceManager = (10 | NP_ABI_MASK),
NPNVDOMElement = (11 | NP_ABI_MASK), /* available in Mozilla 1.2 */
NPNVDOMWindow = (12 | NP_ABI_MASK)
NPNVDOMWindow = (12 | NP_ABI_MASK),
NPNVToolkit = (13 | NP_ABI_MASK),
NPNVSupportsXEmbedBool = 14
} NPNVariable;
/*
* The type of Tookkit the widgets use
*/
typedef enum {
NPNVGtk12 = 1,
NPNVGtk2
} NPNToolkitType;
/*
* The type of a NPWindow - it specifies the type of the data structure
* returned in the window field.

Просмотреть файл

@ -188,7 +188,8 @@ enum nsPluginVariable {
enum nsPluginManagerVariable {
nsPluginManagerVariable_XDisplay = 1,
nsPluginManagerVariable_XtAppContext = 2
nsPluginManagerVariable_XtAppContext = 2,
nsPluginManagerVariable_SupportsXEmbed = 14
};
enum nsPluginInstancePeerVariable {
@ -203,7 +204,8 @@ enum nsPluginInstanceVariable {
nsPluginInstanceVariable_DoCacheBool = 5,
nsPluginInstanceVariable_CallSetWindowAfterDestroyBool = 6,
nsPluginInstanceVariable_ScriptableInstance = 10,
nsPluginInstanceVariable_ScriptableIID = 11
nsPluginInstanceVariable_ScriptableIID = 11,
nsPluginInstanceVariable_NeedsXEmbed = 14
};
////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -89,6 +89,10 @@ else
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
CPPSRCS += nsPluginsDirDarwin.cpp
CPPSRCS += nsPluginNativeWindow.cpp
else
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
CPPSRCS += nsPluginsDirUnix.cpp
CPPSRCS += nsPluginNativeWindowGtk2.cpp
else
CPPSRCS += nsPluginsDirUnix.cpp
CPPSRCS += nsPluginNativeWindow.cpp
@ -96,6 +100,7 @@ endif
endif
endif
endif
endif
ifneq (,$(filter WINNT Darwin,$(OS_ARCH)))
EXTRA_DSO_LIBS += gkgfx

Просмотреть файл

@ -1225,6 +1225,17 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
switch(variable) {
#if defined(XP_UNIX) && !defined(XP_MACOSX)
case NPNVxDisplay : {
#ifdef MOZ_WIDGET_GTK2
if(npp) {
ns4xPluginInstance *inst = (ns4xPluginInstance *) npp->ndata;
NPBool rtv = PR_FALSE;
inst->GetValue((nsPluginInstanceVariable)NPPVpluginNeedsXEmbed, &rtv);
if(rtv) {
(*(Display **)result) = GDK_DISPLAY();
return NPERR_NO_ERROR;
}
}
#endif
#if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_GTK2)
// adobe nppdf calls XtGetApplicationNameAndClass(display, &instance, &class)
// we have to init Xt toolkit before get XtDisplay
@ -1337,6 +1348,30 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
}
return NPERR_GENERIC_ERROR;
}
case NPNVToolkit: {
#ifdef MOZ_WIDGET_GTK
*((NPNToolkitType*)result) = NPNVGtk12;
#endif
#ifdef MOZ_WIDGET_GTK2
*((NPNToolkitType*)result) = NPNVGtk2;
#endif
if (result)
return NPERR_NO_ERROR;
return NPERR_GENERIC_ERROR;
}
case NPNVSupportsXEmbedBool: {
#ifdef MOZ_WIDGET_GTK2
*(NPBool*)result = PR_TRUE;
#else
*(NPBool*)result = PR_FALSE;
#endif
return NPERR_NO_ERROR;
}
default : return NPERR_GENERIC_ERROR;
}
}

Просмотреть файл

@ -860,6 +860,7 @@ NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window)
NPError error;
#if defined (MOZ_WIDGET_GTK) || 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;
@ -881,6 +882,15 @@ NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* 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) {
GtkWidget* widget = GTK_WIDGET(user_data);
if (GTK_IS_SOCKET(widget)) {
isXembed = PR_TRUE;
}
}
if (!isXembed)
{
#ifdef NS_DEBUG
printf("About to create new xtbin of %i X %i from %p...\n",
@ -929,7 +939,10 @@ NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window)
ws->type = 0; // OK, that was a guess!!
#ifdef MOZ_X11
ws->depth = gdk_window_get_visual(win)->depth;
ws->display = GTK_XTBIN(mXtBin)->xtdisplay;
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));
@ -937,14 +950,16 @@ NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window)
#endif
} // !window->ws_info
if (!mXtBin)
if (!mXtBin && !isXembed)
return NS_ERROR_FAILURE;
// 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);
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);
}
#elif defined(MOZ_WIDGET_XLIB)

Просмотреть файл

@ -2095,7 +2095,10 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request, nsISupports* aCo
// If we've got a native window, the let the plugin know
// about it.
if (window->window)
mInstance->SetWindow(window);
{
nsCOMPtr<nsIPluginInstance> inst = mInstance;
((nsPluginNativeWindow*)window)->CallSetWindow(inst);
}
}
}
}
@ -2638,6 +2641,13 @@ NS_IMETHODIMP nsPluginHostImpl::GetValue(nsPluginManagerVariable aVariable, void
}
}
#endif
if (nsPluginManagerVariable_SupportsXEmbed == aVariable) {
#ifdef MOZ_WIDGET_GTK2
*(NPBool*)aValue = PR_TRUE;
#else
*(NPBool*)aValue = PR_FALSE;
#endif
}
return rv;
}
@ -3454,7 +3464,10 @@ NS_IMETHODIMP nsPluginHostImpl::InstantiateEmbededPlugin(const char *aMimeType,
// If we've got a native window, the let the plugin know about it.
if (window->window)
instance->SetWindow(window);
{
nsCOMPtr<nsIPluginInstance> inst = instance;
((nsPluginNativeWindow*)window)->CallSetWindow(inst);
}
// create an initial stream with data
// don't make the stream if it's a java applet or we don't have SRC or DATA attribute
@ -3596,7 +3609,10 @@ nsresult nsPluginHostImpl::FindStoppedPluginForURL(nsIURI* aURL,
// If we've got a native window, the let the plugin know about it.
if (window->window)
instance->SetWindow(window);
{
nsCOMPtr<nsIPluginInstance> inst = instance;
((nsPluginNativeWindow*)window)->CallSetWindow(inst);
}
plugin->setStopped(PR_FALSE);
return NS_OK;
@ -6601,7 +6617,10 @@ nsresult nsPluginStreamListenerPeer::ServeStreamAsFile(nsIRequest *request,
nsPluginWindow *window = nsnull;
owner->GetWindow(window);
if (window->window)
mInstance->SetWindow(window);
{
nsCOMPtr<nsIPluginInstance> inst = mInstance;
((nsPluginNativeWindow*)window)->CallSetWindow(inst);
}
}
}

Просмотреть файл

@ -0,0 +1,157 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=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 Sun Microsystems, Inc.
* Portions created by Sun Microsystems are Copyright (C) 2003
* the Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Robin Lu <robin.lu@sun.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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* This file is the Gtk2 implementation of plugin native window.
*/
#include "nsDebug.h"
#include "nsPluginNativeWindow.h"
#include "npapi.h"
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <gdk/gdk.h>
class nsPluginNativeWindowGtk2 : public nsPluginNativeWindow {
public:
nsPluginNativeWindowGtk2();
virtual ~nsPluginNativeWindowGtk2();
virtual nsresult CallSetWindow(nsCOMPtr<nsIPluginInstance> &aPluginInstance);
private:
GtkWidget* mGtkSocket;
nsresult CreateXEmbedWindow();
};
nsPluginNativeWindowGtk2::nsPluginNativeWindowGtk2() : nsPluginNativeWindow()
{
// initialize the struct fields
window = nsnull;
x = 0;
y = 0;
width = 0;
height = 0;
memset(&clipRect, 0, sizeof(clipRect));
ws_info = nsnull;
type = nsPluginWindowType_Window;
mGtkSocket = 0;
}
nsPluginNativeWindowGtk2::~nsPluginNativeWindowGtk2()
{
if(mGtkSocket) {
gtk_widget_destroy(mGtkSocket);
mGtkSocket = 0;
}
}
nsresult PLUG_NewPluginNativeWindow(nsPluginNativeWindow ** aPluginNativeWindow)
{
NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
*aPluginNativeWindow = new nsPluginNativeWindowGtk2();
return *aPluginNativeWindow ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
nsresult PLUG_DeletePluginNativeWindow(nsPluginNativeWindow * aPluginNativeWindow)
{
NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
nsPluginNativeWindowGtk2 *p = (nsPluginNativeWindowGtk2 *)aPluginNativeWindow;
delete p;
return NS_OK;
}
nsresult nsPluginNativeWindowGtk2::CallSetWindow(nsCOMPtr<nsIPluginInstance> &aPluginInstance)
{
if(aPluginInstance) {
nsresult rv;
PRBool val = PR_FALSE;
if(!mGtkSocket) {
rv = aPluginInstance->GetValue
((nsPluginInstanceVariable)NPPVpluginNeedsXEmbed, &val);
}
#ifdef DEBUG
printf("nsPluginNativeWindowGtk2: NPPVpluginNeedsXEmbed=%d\n", &val);
#endif
if(val) {
CreateXEmbedWindow();
}
if(mGtkSocket)
window = (nsPluginPort *)gtk_socket_get_id(GTK_SOCKET(mGtkSocket));
#ifdef DEBUG
printf("nsPluginNativeWindowGtk2: call SetWindow with xid=%p\n", window);
#endif
aPluginInstance->SetWindow(this);
}
else if (mPluginInstance)
mPluginInstance->SetWindow(nsnull);
SetPluginInstance(aPluginInstance);
return NS_OK;
}
nsresult nsPluginNativeWindowGtk2::CreateXEmbedWindow() {
if(!mGtkSocket) {
GdkWindow *win = gdk_window_lookup((XID)window);
mGtkSocket = gtk_socket_new();
//attach the socket to the container widget
gtk_widget_set_parent_window(mGtkSocket, win);
gpointer user_data = NULL;
gdk_window_get_user_data(win, &user_data);
GtkContainer *container = GTK_CONTAINER(user_data);
gtk_container_add(container, mGtkSocket);
gtk_widget_realize(mGtkSocket);
GtkAllocation new_allocation;
new_allocation.x = 0;
new_allocation.y = 0;
new_allocation.width = width;
new_allocation.height = height;
gtk_widget_size_allocate(mGtkSocket, &new_allocation);
gtk_widget_show(mGtkSocket);
gdk_flush();
window = (nsPluginPort *)gtk_socket_get_id(GTK_SOCKET(mGtkSocket));
}
return NS_OK;
}

Просмотреть файл

@ -39,6 +39,7 @@ REQUIRES = xpcom \
dom \
necko \
uconv \
gtkxtbin \
xremoteservice
CSRCS = \
@ -72,6 +73,7 @@ SHARED_LIBRARY_LIBS = $(DIST)/lib/libxpwidgets_s.a
EXTRA_DSO_LDOPTS += \
$(MOZ_COMPONENT_LIBS) \
-lgkgfx \
-lgtkxtbin \
$(XLDFLAGS) \
$(XLIBS) \
$(MOZ_GTK2_LIBS)

Просмотреть файл

@ -55,6 +55,8 @@
#include <gdk/gdkx.h>
#include <gdk/gdkkeysyms.h>
#include "gtk2xtbin.h"
#include "nsIPref.h"
#include "nsIServiceManager.h"
@ -233,12 +235,12 @@ nsWindow::nsWindow()
mIsVisible = PR_FALSE;
mRetryPointerGrab = PR_FALSE;
mRetryKeyboardGrab = PR_FALSE;
mHasNonXembedPlugin = PR_FALSE;
mActivatePending = PR_FALSE;
mTransientParent = nsnull;
mWindowType = eWindowType_child;
mSizeState = nsSizeMode_Normal;
mOldFocusWindow = 0;
mPluginType = PluginType_NONE;
if (!gGlobalsInitialized) {
gGlobalsInitialized = PR_TRUE;
@ -2590,15 +2592,15 @@ nsWindow::SetDefaultIcon(void)
}
void
nsWindow::SetPluginType(PRBool aIsXembed)
nsWindow::SetPluginType(PluginType aPluginType)
{
mHasNonXembedPlugin = !aIsXembed;
mPluginType = aPluginType;
}
void
nsWindow::SetNonXEmbedPluginFocus()
{
if (gPluginFocusWindow == this) {
if (gPluginFocusWindow == this || mPluginType!=PluginType_NONXEMBED) {
return;
}
@ -2654,7 +2656,7 @@ nsWindow::LoseNonXEmbedPluginFocus()
// This method is only for the nsWindow which contains a
// Non-XEmbed plugin, for example, JAVA plugin.
if (gPluginFocusWindow != this) {
if (gPluginFocusWindow != this || mPluginType!=PluginType_NONXEMBED) {
return;
}
@ -3246,16 +3248,19 @@ plugin_window_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data
gdk_window_get_user_data(plugin_window, &user_data);
widget = GTK_WIDGET(user_data);
if (GTK_IS_SOCKET(widget)) {
if (GTK_IS_XTBIN(widget)) {
nswindow->SetPluginType(nsWindow::PluginType_NONXEMBED);
break;
}
else if(GTK_IS_SOCKET(widget)) {
nswindow->SetPluginType(nsWindow::PluginType_XEMBED);
break;
}
}
nswindow->SetPluginType(PR_FALSE);
nswindow->SetPluginType(nsWindow::PluginType_NONXEMBED);
return_val = GDK_FILTER_REMOVE;
break;
case EnterNotify:
// Currently we consider all plugins are non-xembed and calls
// SetNonXEmbedPluginFocus without any checking.
nswindow->SetNonXEmbedPluginFocus();
break;
case DestroyNotify:

Просмотреть файл

@ -235,7 +235,13 @@ public:
void GrabKeyboard (void);
void ReleaseGrabs (void);
void SetPluginType(PRBool aIsXembed);
enum PluginType {
PluginType_NONE = 0, /* do not have any plugin */
PluginType_XEMBED, /* the plugin support xembed */
PluginType_NONXEMBED /* the plugin does not support xembed */
};
void SetPluginType(PluginType aPluginType);
void SetNonXEmbedPluginFocus(void);
void LoseNonXEmbedPluginFocus(void);
@ -281,11 +287,11 @@ private:
mInKeyRepeat : 1,
mIsVisible : 1,
mRetryPointerGrab : 1,
mHasNonXembedPlugin : 1,
mActivatePending : 1,
mRetryKeyboardGrab : 1;
GtkWindow *mTransientParent;
PRInt32 mSizeState;
PluginType mPluginType;
#ifdef ACCESSIBILITY
nsCOMPtr<nsIAccessible> mRootAccessible;