summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/gfx/native_widget_types.h13
-rw-r--r--chrome/common/ipc_message_utils.h19
-rw-r--r--chrome/plugin/webplugin_proxy.cc10
-rw-r--r--chrome/plugin/webplugin_proxy.h4
-rw-r--r--webkit/glue/plugins/gtk_plugin_container.cc16
-rw-r--r--webkit/glue/plugins/plugin_host.cc2
-rw-r--r--webkit/glue/plugins/plugin_instance.h8
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.cc4
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.h6
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_gtk.cc55
-rw-r--r--webkit/glue/webplugin.h8
-rw-r--r--webkit/glue/webplugin_delegate.h5
-rw-r--r--webkit/glue/webplugin_impl.cc2
-rw-r--r--webkit/glue/webplugin_impl.h6
-rw-r--r--webkit/tools/test_shell/test_webview_delegate_gtk.cc39
-rw-r--r--webkit/tools/test_shell/webview_host.h30
-rw-r--r--webkit/tools/test_shell/webview_host_gtk.cc37
17 files changed, 177 insertions, 87 deletions
diff --git a/base/gfx/native_widget_types.h b/base/gfx/native_widget_types.h
index 9444a61..bd8815c 100644
--- a/base/gfx/native_widget_types.h
+++ b/base/gfx/native_widget_types.h
@@ -114,6 +114,19 @@ static inline NativeViewId IdFromNativeView(NativeView view) {
NativeViewId IdFromNativeView(NativeView view);
#endif // defined(OS_LINUX)
+
+// PluginWindowHandle is an abstraction wrapping "the types of windows
+// used by NPAPI plugins". On Windows it's an HWND, on X it's an X
+// window id.
+#if defined(OS_WIN)
+ typedef HWND PluginWindowHandle;
+#elif defined(OS_LINUX)
+ typedef unsigned long PluginWindowHandle;
+#else
+ // On OS X we don't have windowed plugins.
+ typedef void* PluginWindowHandle;
+#endif
+
} // namespace gfx
#endif // BASE_GFX_NATIVE_WIDGET_TYPES_H_
diff --git a/chrome/common/ipc_message_utils.h b/chrome/common/ipc_message_utils.h
index 2ae2ab5..8c50d6e 100644
--- a/chrome/common/ipc_message_utils.h
+++ b/chrome/common/ipc_message_utils.h
@@ -176,6 +176,25 @@ struct ParamTraits<long> {
}
};
+// unsigned long is used for serializing X window ids.
+template <>
+struct ParamTraits<unsigned long> {
+ typedef unsigned long param_type;
+ static void Write(Message* m, const param_type& p) {
+ m->WriteLong(p);
+ }
+ static bool Read(const Message* m, void** iter, param_type* r) {
+ long read_output;
+ if (!m->ReadLong(iter, &read_output))
+ return false;
+ *r = static_cast<unsigned long>(read_output);
+ return true;
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ l->append(StringPrintf(L"%ul", p));
+ }
+};
+
template <>
struct ParamTraits<size_t> {
typedef size_t param_type;
diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc
index 286659b..57c07fc 100644
--- a/chrome/plugin/webplugin_proxy.cc
+++ b/chrome/plugin/webplugin_proxy.cc
@@ -56,15 +56,21 @@ bool WebPluginProxy::Send(IPC::Message* msg) {
return channel_->Send(msg);
}
-void WebPluginProxy::SetWindow(gfx::NativeView window) {
+void WebPluginProxy::SetWindow(gfx::PluginWindowHandle window) {
+#if defined(OS_WIN)
Send(new PluginHostMsg_SetWindow(route_id_, gfx::IdFromNativeView(window)));
+#else
+ NOTIMPLEMENTED();
+#endif
}
-void WebPluginProxy::WillDestroyWindow(gfx::NativeView window) {
+void WebPluginProxy::WillDestroyWindow(gfx::PluginWindowHandle window) {
#if defined(OS_WIN)
PluginThread::current()->Send(
new PluginProcessHostMsg_PluginWindowDestroyed(
window, ::GetParent(window)));
+#else
+ NOTIMPLEMENTED();
#endif
}
diff --git a/chrome/plugin/webplugin_proxy.h b/chrome/plugin/webplugin_proxy.h
index 46c16d1..e143297 100644
--- a/chrome/plugin/webplugin_proxy.h
+++ b/chrome/plugin/webplugin_proxy.h
@@ -37,8 +37,8 @@ class WebPluginProxy : public WebPlugin {
~WebPluginProxy();
// WebPlugin overrides
- void SetWindow(gfx::NativeView window);
- void WillDestroyWindow(gfx::NativeView window);
+ void SetWindow(gfx::PluginWindowHandle window);
+ void WillDestroyWindow(gfx::PluginWindowHandle window);
#if defined(OS_WIN)
void SetWindowlessPumpEvent(HANDLE pump_messages_event);
// Returns true on success.
diff --git a/webkit/glue/plugins/gtk_plugin_container.cc b/webkit/glue/plugins/gtk_plugin_container.cc
index 18bdb30..c487fa0 100644
--- a/webkit/glue/plugins/gtk_plugin_container.cc
+++ b/webkit/glue/plugins/gtk_plugin_container.cc
@@ -14,13 +14,6 @@ namespace {
// through GLib's object management.
class GtkPluginContainer : public GtkSocket {
public:
- static GtkWidget* CreateNewWidget() {
- GtkWidget* container = GTK_WIDGET(g_object_new(GetType(), NULL));
- g_signal_connect(GTK_SOCKET(container), "plug-removed",
- G_CALLBACK(OnPlugRemoved), NULL);
- return container;
- }
-
// Sets the requested size of the widget.
void set_size(int width, int height) {
width_ = width;
@@ -33,7 +26,6 @@ class GtkPluginContainer : public GtkSocket {
return G_TYPE_CHECK_INSTANCE_CAST(instance, GetType(), GtkPluginContainer);
}
- private:
// Create and register our custom container type with GTK.
static GType GetType() {
static GType type = 0; // We only want to register our type once.
@@ -74,12 +66,6 @@ class GtkPluginContainer : public GtkSocket {
requisition->height = container->height_;
}
- static gboolean OnPlugRemoved(GtkSocket* socket) {
- // This is called when the other side of the socket goes away.
- // We return TRUE to indicate that we don't want to destroy our side.
- return TRUE;
- }
-
int width_;
int height_;
DISALLOW_IMPLICIT_CONSTRUCTORS(GtkPluginContainer);
@@ -89,7 +75,7 @@ class GtkPluginContainer : public GtkSocket {
// Create a new instance of our GTK widget object.
GtkWidget* gtk_plugin_container_new() {
- return GtkPluginContainer::CreateNewWidget();
+ return GTK_WIDGET(g_object_new(GtkPluginContainer::GetType(), NULL));
}
void gtk_plugin_container_set_size(GtkWidget *widget, int width, int height) {
diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc
index 815b415..2e1c233 100644
--- a/webkit/glue/plugins/plugin_host.cc
+++ b/webkit/glue/plugins/plugin_host.cc
@@ -711,7 +711,7 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void *value) {
{
#if defined(OS_WIN) || defined(OS_LINUX)
scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id);
- gfx::NativeView handle = plugin->window_handle();
+ gfx::PluginWindowHandle handle = plugin->window_handle();
*((void**)value) = (void*)handle;
rv = NPERR_NO_ERROR;
#else
diff --git a/webkit/glue/plugins/plugin_instance.h b/webkit/glue/plugins/plugin_instance.h
index e73d49f..ba8824f8 100644
--- a/webkit/glue/plugins/plugin_instance.h
+++ b/webkit/glue/plugins/plugin_instance.h
@@ -70,8 +70,10 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> {
NPP npp() { return npp_; }
// Get/Set for the instance's window handle.
- gfx::NativeView window_handle() { return window_handle_; }
- void set_window_handle(gfx::NativeView value) { window_handle_ = value; }
+ gfx::PluginWindowHandle window_handle() const { return window_handle_; }
+ void set_window_handle(gfx::PluginWindowHandle value) {
+ window_handle_ = value;
+ }
// Get/Set whether this instance is in Windowless mode.
// Default is false.
@@ -223,7 +225,7 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> {
scoped_refptr<PluginHost> host_;
NPPluginFuncs* npp_functions_;
std::vector<scoped_refptr<PluginStream> > open_streams_;
- gfx::NativeView window_handle_;
+ gfx::PluginWindowHandle window_handle_;
bool windowless_;
bool transparent_;
WebPlugin* webplugin_;
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.cc b/webkit/glue/plugins/webplugin_delegate_impl.cc
index 5cf00a5..d197fb11 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl.cc
@@ -71,7 +71,7 @@ base::LazyInstance<iat_patch::IATPatchFunction> g_iat_patch_set_cursor(
WebPluginDelegate* WebPluginDelegate::Create(
const FilePath& filename,
const std::string& mime_type,
- gfx::NativeView containing_view) {
+ gfx::PluginWindowHandle containing_view) {
scoped_refptr<NPAPI::PluginLib> plugin =
NPAPI::PluginLib::CreatePluginLib(filename);
if (plugin.get() == NULL)
@@ -140,7 +140,7 @@ LRESULT CALLBACK WebPluginDelegateImpl::HandleEventMessageFilterHook(
}
WebPluginDelegateImpl::WebPluginDelegateImpl(
- gfx::NativeView containing_view,
+ gfx::PluginWindowHandle containing_view,
NPAPI::PluginInstance *instance)
: parent_(containing_view),
instance_(instance),
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h
index 61a41cd..d3cbdbf 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.h
+++ b/webkit/glue/plugins/webplugin_delegate_impl.h
@@ -91,7 +91,7 @@ class WebPluginDelegateImpl : public WebPluginDelegate {
private:
friend class DeleteTask<WebPluginDelegateImpl>;
- WebPluginDelegateImpl(gfx::NativeView containing_view,
+ WebPluginDelegateImpl(gfx::PluginWindowHandle containing_view,
NPAPI::PluginInstance *instance);
~WebPluginDelegateImpl();
@@ -154,7 +154,7 @@ class WebPluginDelegateImpl : public WebPluginDelegate {
void DestroyInstance();
// used for windowed plugins
- gfx::NativeView windowed_handle_;
+ gfx::PluginWindowHandle windowed_handle_;
bool windowed_did_set_window_;
#if defined(OS_WIN)
gfx::Rect windowed_last_pos_;
@@ -190,7 +190,7 @@ class WebPluginDelegateImpl : public WebPluginDelegate {
void EnsurePixmapAtLeastSize(int width, int height);
#endif
- gfx::NativeView parent_;
+ gfx::PluginWindowHandle parent_;
NPWindow window_;
#if defined(OS_MACOSX)
NP_CGContext cg_context_;
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
index f583876..49670fc 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
@@ -38,7 +38,7 @@ using WebKit::WebMouseEvent;
WebPluginDelegate* WebPluginDelegate::Create(
const FilePath& filename,
const std::string& mime_type,
- gfx::NativeView containing_view) {
+ gfx::PluginWindowHandle containing_view) {
scoped_refptr<NPAPI::PluginLib> plugin =
NPAPI::PluginLib::CreatePluginLib(filename);
if (plugin.get() == NULL)
@@ -54,7 +54,7 @@ WebPluginDelegate* WebPluginDelegate::Create(
}
WebPluginDelegateImpl::WebPluginDelegateImpl(
- gfx::NativeView containing_view,
+ gfx::PluginWindowHandle containing_view,
NPAPI::PluginInstance *instance)
:
windowed_handle_(0),
@@ -263,63 +263,40 @@ bool WebPluginDelegateImpl::WindowedCreatePlugin() {
return false;
}
- windowed_handle_ = gtk_plugin_container_new();
- gtk_container_add(GTK_CONTAINER(parent_), windowed_handle_);
- gtk_widget_show(windowed_handle_);
- gtk_widget_realize(windowed_handle_);
-
- window_.window = GINT_TO_POINTER(
- gtk_socket_get_id(GTK_SOCKET(windowed_handle_)));
+ window_.window = reinterpret_cast<void*>(parent_);
+ // The remainder of the code expects windowed_handle_ to exist for
+ // windowed mode, despite not actually ever reaching through
+ // windowed_handle_. So let's set it to the one window handle we
+ // actually have available.
+ windowed_handle_ = parent_;
if (!window_.ws_info)
window_.ws_info = new NPSetWindowCallbackStruct;
NPSetWindowCallbackStruct* extra =
static_cast<NPSetWindowCallbackStruct*>(window_.ws_info);
- extra->display = GDK_WINDOW_XDISPLAY(windowed_handle_->window);
- GdkVisual* visual = gdk_drawable_get_visual(windowed_handle_->window);
- extra->visual = GDK_VISUAL_XVISUAL(visual);
- extra->depth = visual->depth;
- extra->colormap = GDK_COLORMAP_XCOLORMAP(gdk_drawable_get_colormap(windowed_handle_->window));
+ extra->display = GDK_DISPLAY();
+ extra->visual = DefaultVisual(GDK_DISPLAY(), 0);
+ extra->depth = DefaultDepth(GDK_DISPLAY(), 0);
+ extra->colormap = DefaultColormap(GDK_DISPLAY(), 0);
return true;
}
void WebPluginDelegateImpl::WindowedDestroyWindow() {
- if (windowed_handle_ != NULL) {
- gtk_widget_destroy(windowed_handle_);
- windowed_handle_ = NULL;
- }
+ // We have no window to destroy; see comment in WindowedCreatePlugin
+ // where windowed_handle_ is set.
+ windowed_handle_ = 0;
}
bool WebPluginDelegateImpl::WindowedReposition(
const gfx::Rect& window_rect,
const gfx::Rect& clip_rect) {
- if (!windowed_handle_) {
- NOTREACHED();
- return false;
- }
-
- if (window_rect_ == window_rect && clip_rect_ == clip_rect)
+ if (window_rect == window_rect_ && clip_rect == clip_rect_)
return false;
- // We only set the plugin's size here. Its position is moved elsewhere, which
- // allows the window moves/scrolling/clipping to be synchronized with the page
- // and other windows.
- if (window_rect.size() != window_rect_.size()) {
- gtk_plugin_container_set_size(windowed_handle_, window_rect.width(),
- window_rect.height());
- GtkAllocation allocation = { 0, 0,
- window_rect.width(), window_rect.height() };
- gtk_widget_size_allocate(windowed_handle_, &allocation);
- }
-
window_rect_ = window_rect;
clip_rect_ = clip_rect;
- // TODO(deanm): Is this really needed?
- // Ensure that the entire window gets repainted.
- gtk_widget_queue_draw(windowed_handle_);
-
return true;
}
diff --git a/webkit/glue/webplugin.h b/webkit/glue/webplugin.h
index d6a5b75..2debf9a 100644
--- a/webkit/glue/webplugin.h
+++ b/webkit/glue/webplugin.h
@@ -25,7 +25,9 @@ struct NPObject;
// Describes the new location for a plugin window.
struct WebPluginGeometry {
- gfx::NativeView window;
+ // On Windows, this is the plugin window in the plugin process.
+ // On X11, this is the browser process's hosting window (the GtkSocket).
+ gfx::PluginWindowHandle window;
gfx::Rect window_rect;
// Clip rect (include) and cutouts (excludes), relative to
// window_rect origin.
@@ -54,11 +56,11 @@ class WebPlugin {
// windowed (i.e. handle is not NULL) or windowless (handle is NULL). This
// tells the WebPlugin to send mouse/keyboard events to the plugin delegate,
// as well as the information about the HDC for paint operations.
- virtual void SetWindow(gfx::NativeView window) = 0;
+ virtual void SetWindow(gfx::PluginWindowHandle window) = 0;
// Called by the plugin delegate to let it know that the window is being
// destroyed.
- virtual void WillDestroyWindow(gfx::NativeView window) = 0;
+ virtual void WillDestroyWindow(gfx::PluginWindowHandle window) = 0;
#if defined(OS_WIN)
// The pump_messages_event is a event handle which is valid only for
// windowless plugins and is used in NPP_HandleEvent calls to pump messages
diff --git a/webkit/glue/webplugin_delegate.h b/webkit/glue/webplugin_delegate.h
index 385044d..7d0fa88 100644
--- a/webkit/glue/webplugin_delegate.h
+++ b/webkit/glue/webplugin_delegate.h
@@ -8,10 +8,9 @@
#include <string>
#include "base/gfx/native_widget_types.h"
+#include "build/build_config.h"
#include "third_party/npapi/bindings/npapi.h"
-// TODO(port): put in OS_WIN check.
-typedef struct HDC__* HDC;
struct NPObject;
class FilePath;
@@ -48,7 +47,7 @@ class WebPluginDelegate {
static WebPluginDelegate* Create(const FilePath& filename,
const std::string& mime_type,
- gfx::NativeView containing_view);
+ gfx::PluginWindowHandle containing_view);
// Initializes the plugin implementation with the given (UTF8) arguments.
// Note that the lifetime of WebPlugin must be longer than this delegate.
diff --git a/webkit/glue/webplugin_impl.cc b/webkit/glue/webplugin_impl.cc
index d3c8d6a..69f6259 100644
--- a/webkit/glue/webplugin_impl.cc
+++ b/webkit/glue/webplugin_impl.cc
@@ -388,7 +388,7 @@ WebPluginImpl::WebPluginImpl(WebCore::HTMLPlugInElement* element,
WebPluginImpl::~WebPluginImpl() {
}
-void WebPluginImpl::SetWindow(gfx::NativeView window) {
+void WebPluginImpl::SetWindow(gfx::PluginWindowHandle window) {
if (window) {
DCHECK(!windowless_); // Make sure not called twice.
window_ = window;
diff --git a/webkit/glue/webplugin_impl.h b/webkit/glue/webplugin_impl.h
index ab7ea8f..9082820 100644
--- a/webkit/glue/webplugin_impl.h
+++ b/webkit/glue/webplugin_impl.h
@@ -148,8 +148,8 @@ class WebPluginImpl : public WebPlugin,
int arg_count, char** arg_names, char** arg_values);
// WebPlugin implementation:
- void SetWindow(gfx::NativeView window);
- void WillDestroyWindow(gfx::NativeView window) { }
+ void SetWindow(gfx::PluginWindowHandle window);
+ void WillDestroyWindow(gfx::PluginWindowHandle window) { }
#if defined(OS_WIN)
void SetWindowlessPumpEvent(HANDLE pump_messages_event) { }
#endif
@@ -333,7 +333,7 @@ class WebPluginImpl : public WebPlugin,
std::vector<ClientInfo> clients_;
bool windowless_;
- gfx::NativeView window_;
+ gfx::PluginWindowHandle window_;
WebCore::HTMLPlugInElement* element_;
WebFrameImpl* webframe_;
diff --git a/webkit/tools/test_shell/test_webview_delegate_gtk.cc b/webkit/tools/test_shell/test_webview_delegate_gtk.cc
index d4a0574..74586e5 100644
--- a/webkit/tools/test_shell/test_webview_delegate_gtk.cc
+++ b/webkit/tools/test_shell/test_webview_delegate_gtk.cc
@@ -22,6 +22,7 @@
#include "webkit/glue/webplugin.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/webview.h"
+#include "webkit/glue/plugins/gtk_plugin_container.h"
#include "webkit/glue/plugins/plugin_list.h"
#include "webkit/glue/window_open_disposition.h"
#include "webkit/glue/plugins/webplugin_delegate_impl.h"
@@ -87,12 +88,14 @@ WebPluginDelegate* TestWebViewDelegate::CreatePluginDelegate(
actual_mime_type))
return NULL;
- if (actual_mime_type && !actual_mime_type->empty())
- return WebPluginDelegateImpl::Create(info.path, *actual_mime_type,
- shell_->webViewHost()->view_handle());
- else
- return WebPluginDelegateImpl::Create(info.path, mime_type,
- shell_->webViewHost()->view_handle());
+ const std::string& mtype =
+ (actual_mime_type && !actual_mime_type->empty()) ? *actual_mime_type
+ : mime_type;
+
+ GdkNativeWindow plugin_parent =
+ shell_->webViewHost()->CreatePluginContainer();
+
+ return WebPluginDelegateImpl::Create(info.path, mtype, plugin_parent);
}
void TestWebViewDelegate::ShowJavaScriptAlert(const std::wstring& message) {
@@ -216,11 +219,24 @@ void TestWebViewDelegate::GetRootWindowResizerRect(WebWidget* webwidget,
void TestWebViewDelegate::DidMove(WebWidget* webwidget,
const WebPluginGeometry& move) {
- // The window on WebPluginGeometry is misnamed, as it's a view. In our case
- // it should be the GtkSocket of the plugin window.
- GtkWidget* widget = move.window;
+ WebWidgetHost* host = GetHostForWidget(webwidget);
+
+ // The "window" on WebPluginGeometry is actually the XEmbed parent
+ // X window id.
+ GtkWidget* widget = ((WebViewHost*)host)->MapIDToWidget(move.window);
+ // If we don't know about this plugin (maybe we're shutting down the
+ // window?), ignore the message.
+ if (!widget)
+ return;
DCHECK(!GTK_WIDGET_NO_WINDOW(widget) && GTK_WIDGET_REALIZED(widget));
+ if (!move.visible) {
+ gtk_widget_hide(widget);
+ return;
+ } else {
+ gtk_widget_show(widget);
+ }
+
// Update the clipping region on the GdkWindow.
GdkRectangle clip_rect = move.clip_rect.ToGdkRectangle();
GdkRegion* clip_region = gdk_region_rectangle(&clip_rect);
@@ -232,7 +248,6 @@ void TestWebViewDelegate::DidMove(WebWidget* webwidget,
// TODO(deanm): Verify that we only need to move and not resize.
// TODO(evanm): we should cache the last shape and position and skip all
// of this business in the common case where nothing has changed.
- WebWidgetHost* host = GetHostForWidget(webwidget);
int current_x, current_y;
// Until the above TODO is resolved, we can grab the last position
@@ -255,6 +270,10 @@ void TestWebViewDelegate::DidMove(WebWidget* webwidget,
move.window_rect.x(),
move.window_rect.y());
}
+
+ gtk_plugin_container_set_size(widget,
+ move.window_rect.width(),
+ move.window_rect.height());
}
void TestWebViewDelegate::RunModal(WebWidget* webwidget) {
diff --git a/webkit/tools/test_shell/webview_host.h b/webkit/tools/test_shell/webview_host.h
index 337a355..0cd62ee 100644
--- a/webkit/tools/test_shell/webview_host.h
+++ b/webkit/tools/test_shell/webview_host.h
@@ -5,6 +5,8 @@
#ifndef WEBKIT_TOOLS_TEST_SHELL_WEBVIEW_HOST_H_
#define WEBKIT_TOOLS_TEST_SHELL_WEBVIEW_HOST_H_
+#include <map>
+
#include "base/basictypes.h"
#include "base/gfx/native_widget_types.h"
#include "base/gfx/rect.h"
@@ -14,6 +16,10 @@ struct WebPreferences;
class WebView;
class WebViewDelegate;
+#if defined(OS_LINUX)
+typedef struct _GtkSocket GtkSocket;
+#endif
+
// This class is a simple NativeView-based host for a WebView
class WebViewHost : public WebWidgetHost {
public:
@@ -26,12 +32,36 @@ class WebViewHost : public WebWidgetHost {
WebView* webview() const;
+#if defined(OS_LINUX)
+ // Create a new plugin parent container, returning its X window id for
+ // embedders to use.
+ GdkNativeWindow CreatePluginContainer();
+
+ // Map a GdkNativeWindow returned by CreatePluginContainer() back to
+ // the GtkWidget hosting it. Used when we get a message back from the
+ // renderer indicating a plugin needs to move.
+ GtkWidget* MapIDToWidget(GdkNativeWindow id);
+#endif
+
protected:
#if defined(OS_WIN)
virtual bool WndProc(UINT message, WPARAM wparam, LPARAM lparam) {
return false;
}
#endif
+
+#if defined(OS_LINUX)
+ // A map used for MapIDToWidget() above.
+ typedef std::map<GdkNativeWindow, GtkWidget*> NativeWindowToWidgetMap;
+ NativeWindowToWidgetMap native_window_to_widget_map_;
+
+ // Callback for when one of our plugins goes away.
+ static gboolean OnPlugRemovedThunk(GtkSocket* socket,
+ WebViewHost* web_view_host) {
+ return web_view_host->OnPlugRemoved(socket);
+ }
+ gboolean OnPlugRemoved(GtkSocket* socket);
+#endif
};
#endif // WEBKIT_TOOLS_TEST_SHELL_WEBVIEW_HOST_H_
diff --git a/webkit/tools/test_shell/webview_host_gtk.cc b/webkit/tools/test_shell/webview_host_gtk.cc
index 54e3ec8..cd491af 100644
--- a/webkit/tools/test_shell/webview_host_gtk.cc
+++ b/webkit/tools/test_shell/webview_host_gtk.cc
@@ -6,9 +6,11 @@
#include "webkit/tools/test_shell/webview_host.h"
+#include "base/logging.h"
#include "base/gfx/rect.h"
#include "base/gfx/size.h"
#include "skia/ext/platform_canvas.h"
+#include "webkit/glue/plugins/gtk_plugin_container.h"
#include "webkit/glue/webview.h"
// static
@@ -29,3 +31,38 @@ WebViewHost* WebViewHost::Create(GtkWidget* parent_view,
WebView* WebViewHost::webview() const {
return static_cast<WebView*>(webwidget_);
}
+
+GdkNativeWindow WebViewHost::CreatePluginContainer() {
+ GtkWidget* plugin_container = gtk_plugin_container_new();
+ g_signal_connect(G_OBJECT(plugin_container), "plug-removed",
+ G_CALLBACK(OnPlugRemovedThunk), this);
+ gtk_container_add(GTK_CONTAINER(view_handle()), plugin_container);
+ gtk_widget_show(plugin_container);
+ gtk_widget_realize(plugin_container);
+
+ GdkNativeWindow id = gtk_socket_get_id(GTK_SOCKET(plugin_container));
+
+ native_window_to_widget_map_.insert(std::make_pair(id, plugin_container));
+
+ return id;
+}
+
+GtkWidget* WebViewHost::MapIDToWidget(GdkNativeWindow id) {
+ NativeWindowToWidgetMap::const_iterator i =
+ native_window_to_widget_map_.find(id);
+ if (i != native_window_to_widget_map_.end())
+ return i->second;
+
+ LOG(ERROR) << "Request for widget host for unknown window id " << id;
+
+ return NULL;
+}
+
+gboolean WebViewHost::OnPlugRemoved(GtkSocket* socket) {
+ // Remove the socket's id from our list of widgets.
+ GdkNativeWindow id = gtk_socket_get_id(socket);
+ native_window_to_widget_map_.erase(id);
+
+ return FALSE; // Destroy our widget.
+}
+