summaryrefslogtreecommitdiffstats
path: root/webkit/glue/plugins
diff options
context:
space:
mode:
authorevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-22 01:29:05 +0000
committerevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-22 01:29:05 +0000
commit41fbf097c8e01c4971de118eb8fb791b9abaa6eb (patch)
tree8216ee10224ebb84ace23ef8d227e8ec07666bac /webkit/glue/plugins
parentd77232f96be7900e1e7230d145c06bb9e5ed7e44 (diff)
downloadchromium_src-41fbf097c8e01c4971de118eb8fb791b9abaa6eb.zip
chromium_src-41fbf097c8e01c4971de118eb8fb791b9abaa6eb.tar.gz
chromium_src-41fbf097c8e01c4971de118eb8fb791b9abaa6eb.tar.bz2
Add events to windowless plugins on linux. This CL also refactors the event
communication between WebPlugin and WebPluginDelegate, to use a cross-platform message based on WebInputEvent. BUG=8202 TEST=A lot of manual testing on Linux and Windows, with Flash plugins and a custom plugin that dumps events on Linux. Review URL: http://codereview.chromium.org/115330 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16692 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/plugins')
-rw-r--r--webkit/glue/plugins/plugin_host.cc15
-rw-r--r--webkit/glue/plugins/plugin_instance.cc7
-rw-r--r--webkit/glue/plugins/plugin_instance.h13
-rw-r--r--webkit/glue/plugins/test/plugin_javascript_open_popup.cc15
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.cc131
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.h9
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_gtk.cc235
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_mac.mm10
8 files changed, 353 insertions, 82 deletions
diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc
index a349e43..815b415 100644
--- a/webkit/glue/plugins/plugin_host.cc
+++ b/webkit/glue/plugins/plugin_host.cc
@@ -2,17 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// HACK: we need this #define in place before npapi.h is included for
-// plugins to work. However, all sorts of headers include npapi.h, so
-// the only way to be certain the define is in place is to put it
-// here. You might ask, "Why not set it in npapi.h directly, or in
-// this directory's SConscript, then?" but it turns out this define
-// makes npapi.h include Xlib.h, which in turn defines a ton of symbols
-// like None and Status, causing conflicts with the aforementioned
-// many headers that include npapi.h. Ugh.
-// See also webplugin_delegate_impl.cc.
-#define MOZ_X11 1
-
#include "config.h"
#include "webkit/glue/plugins/plugin_host.h"
@@ -720,9 +709,9 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void *value) {
}
case NPNVnetscapeWindow:
{
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_LINUX)
scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id);
- HWND handle = plugin->window_handle();
+ gfx::NativeView handle = plugin->window_handle();
*((void**)value) = (void*)handle;
rv = NPERR_NO_ERROR;
#else
diff --git a/webkit/glue/plugins/plugin_instance.cc b/webkit/glue/plugins/plugin_instance.cc
index f8c1814..23df8c0 100644
--- a/webkit/glue/plugins/plugin_instance.cc
+++ b/webkit/glue/plugins/plugin_instance.cc
@@ -5,9 +5,6 @@
#include "config.h"
#include "build/build_config.h"
-#if defined(OS_LINUX)
-#define MOZ_X11 1
-#endif
#include "webkit/glue/plugins/plugin_instance.h"
@@ -41,9 +38,7 @@ PluginInstance::PluginInstance(PluginLib *plugin, const std::string &mime_type)
npp_(0),
host_(PluginHost::Singleton()),
npp_functions_(plugin->functions()),
-#if defined(OS_WIN)
- hwnd_(0),
-#endif
+ window_handle_(0),
windowless_(false),
transparent_(true),
webplugin_(0),
diff --git a/webkit/glue/plugins/plugin_instance.h b/webkit/glue/plugins/plugin_instance.h
index 2c3bb49..e73d49f 100644
--- a/webkit/glue/plugins/plugin_instance.h
+++ b/webkit/glue/plugins/plugin_instance.h
@@ -14,6 +14,7 @@
#include "base/basictypes.h"
#include "base/file_path.h"
+#include "base/gfx/native_widget_types.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "webkit/glue/plugins/nphostapi.h"
@@ -68,11 +69,9 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> {
// NPAPI's instance identifier for this instance
NPP npp() { return npp_; }
-#if defined(OS_WIN)
- // Get/Set for the instance's HWND.
- HWND window_handle() { return hwnd_; }
- void set_window_handle(HWND value) { hwnd_ = value; }
-#endif
+ // 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; }
// Get/Set whether this instance is in Windowless mode.
// Default is false.
@@ -224,9 +223,7 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> {
scoped_refptr<PluginHost> host_;
NPPluginFuncs* npp_functions_;
std::vector<scoped_refptr<PluginStream> > open_streams_;
-#if defined(OS_WIN)
- HWND hwnd_;
-#endif
+ gfx::NativeView window_handle_;
bool windowless_;
bool transparent_;
WebPlugin* webplugin_;
diff --git a/webkit/glue/plugins/test/plugin_javascript_open_popup.cc b/webkit/glue/plugins/test/plugin_javascript_open_popup.cc
index 9af6656..558aa71 100644
--- a/webkit/glue/plugins/test/plugin_javascript_open_popup.cc
+++ b/webkit/glue/plugins/test/plugin_javascript_open_popup.cc
@@ -3,20 +3,11 @@
// found in the LICENSE file.
#include "build/build_config.h"
-#if defined(OS_LINUX)
-// HACK: we need this #define in place before npapi.h is included for
-// plugins to work. However, all sorts of headers include npapi.h, so
-// the only way to be certain the define is in place is to put it
-// here. You might ask, "Why not set it in npapi.h directly, or in
-// this directory's SConscript, then?" but it turns out this define
-// makes npapi.h include Xlib.h, which in turn defines a ton of symbols
-// like None and Status, causing conflicts with the aforementioned
-// many headers that include npapi.h. Ugh.
-#define MOZ_X11 1
-#endif
-
#include "webkit/glue/plugins/test/plugin_javascript_open_popup.h"
+#if defined(OS_LINUX)
+#include "third_party/npapi/bindings/npapi_x11.h"
+#endif
#include "webkit/glue/plugins/test/plugin_client.h"
namespace NPAPIClient {
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.cc b/webkit/glue/plugins/webplugin_delegate_impl.cc
index 2c41851..23c11aa 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl.cc
@@ -13,6 +13,7 @@
#include "base/message_loop.h"
#include "base/stats_counters.h"
#include "base/string_util.h"
+#include "webkit/api/public/WebInputEvent.h"
#include "webkit/default_plugin/plugin_impl.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webplugin.h"
@@ -23,6 +24,10 @@
#include "webkit/glue/plugins/plugin_stream_url.h"
#include "webkit/glue/webkit_glue.h"
+using WebKit::WebKeyboardEvent;
+using WebKit::WebInputEvent;
+using WebKit::WebMouseEvent;
+
namespace {
const wchar_t kWebPluginDelegateProperty[] = L"WebPluginDelegateProperty";
@@ -260,7 +265,6 @@ bool WebPluginDelegateImpl::Initialize(const GURL& url,
}
plugin->SetWindow(windowed_handle_);
-#if defined(OS_WIN)
if (windowless_) {
// For windowless plugins we should set the containing window handle
// as the instance window handle. This is what Safari does. Not having
@@ -268,11 +272,12 @@ bool WebPluginDelegateImpl::Initialize(const GURL& url,
// the window handle and validate the same. The window handle can be
// retreived via NPN_GetValue of NPNVnetscapeWindow.
instance_->set_window_handle(parent_);
+#if defined(OS_WIN)
CreateDummyWindowForActivation();
handle_event_pump_messages_event_ = CreateEvent(NULL, TRUE, FALSE, NULL);
plugin->SetWindowlessPumpEvent(handle_event_pump_messages_event_);
- }
#endif
+ }
plugin_url_ = url.spec();
// The windowless version of the Silverlight plugin calls the
@@ -999,11 +1004,117 @@ void WebPluginDelegateImpl::SetFocus() {
instance()->NPP_HandleEvent(&focus_event);
}
-bool WebPluginDelegateImpl::HandleEvent(NPEvent* event,
- WebCursor* cursor) {
+static bool NPEventFromWebMouseEvent(const WebMouseEvent& event,
+ NPEvent *np_event) {
+ np_event->lParam = static_cast<uint32>(MAKELPARAM(event.windowX,
+ event.windowY));
+ np_event->wParam = 0;
+
+ if (event.modifiers & WebInputEvent::ControlKey)
+ np_event->wParam |= MK_CONTROL;
+ if (event.modifiers & WebInputEvent::ShiftKey)
+ np_event->wParam |= MK_SHIFT;
+ if (event.modifiers & WebInputEvent::LeftButtonDown)
+ np_event->wParam |= MK_LBUTTON;
+ if (event.modifiers & WebInputEvent::MiddleButtonDown)
+ np_event->wParam |= MK_MBUTTON;
+ if (event.modifiers & WebInputEvent::RightButtonDown)
+ np_event->wParam |= MK_RBUTTON;
+
+ switch (event.type) {
+ case WebInputEvent::MouseMove:
+ case WebInputEvent::MouseLeave:
+ case WebInputEvent::MouseEnter:
+ np_event->event = WM_MOUSEMOVE;
+ return true;
+ case WebInputEvent::MouseDown:
+ switch (event.button) {
+ case WebMouseEvent::ButtonLeft:
+ np_event->event = WM_LBUTTONDOWN;
+ break;
+ case WebMouseEvent::ButtonMiddle:
+ np_event->event = WM_MBUTTONDOWN;
+ break;
+ case WebMouseEvent::ButtonRight:
+ np_event->event = WM_RBUTTONDOWN;
+ break;
+ }
+ return true;
+ case WebInputEvent::MouseUp:
+ switch (event.button) {
+ case WebMouseEvent::ButtonLeft:
+ np_event->event = WM_LBUTTONUP;
+ break;
+ case WebMouseEvent::ButtonMiddle:
+ np_event->event = WM_MBUTTONUP;
+ break;
+ case WebMouseEvent::ButtonRight:
+ np_event->event = WM_RBUTTONUP;
+ break;
+ }
+ return true;
+ default:
+ NOTREACHED();
+ return false;
+ }
+}
+
+static bool NPEventFromWebKeyboardEvent(const WebKeyboardEvent& event,
+ NPEvent *np_event) {
+ np_event->wParam = event.windowsKeyCode;
+
+ switch (event.type) {
+ case WebInputEvent::KeyDown:
+ np_event->event = WM_KEYDOWN;
+ np_event->lParam = 0;
+ return true;
+ case WebInputEvent::KeyUp:
+ np_event->event = WM_KEYUP;
+ np_event->lParam = 0x8000;
+ return true;
+ default:
+ NOTREACHED();
+ return false;
+ }
+}
+
+static bool NPEventFromWebInputEvent(const WebInputEvent& event,
+ NPEvent* np_event) {
+ switch (event.type) {
+ case WebInputEvent::MouseMove:
+ case WebInputEvent::MouseLeave:
+ case WebInputEvent::MouseEnter:
+ case WebInputEvent::MouseDown:
+ case WebInputEvent::MouseUp:
+ if (event.size < sizeof(WebMouseEvent)) {
+ NOTREACHED();
+ return false;
+ }
+ return NPEventFromWebMouseEvent(
+ *static_cast<const WebMouseEvent*>(&event), np_event);
+ case WebInputEvent::KeyDown:
+ case WebInputEvent::KeyUp:
+ if (event.size < sizeof(WebKeyboardEvent)) {
+ NOTREACHED();
+ return false;
+ }
+ return NPEventFromWebKeyboardEvent(
+ *static_cast<const WebKeyboardEvent*>(&event), np_event);
+ default:
+ return false;
+ }
+}
+
+bool WebPluginDelegateImpl::HandleInputEvent(const WebInputEvent& event,
+ WebCursor* cursor) {
DCHECK(windowless_) << "events should only be received in windowless mode";
DCHECK(cursor != NULL);
+ NPEvent np_event;
+ if (!NPEventFromWebInputEvent(event, &np_event)) {
+ return false;
+ }
+
// To ensure that the plugin receives keyboard events we set focus to the
// dummy window.
// TODO(iyengar) We need a framework in the renderer to identify which
@@ -1011,11 +1122,11 @@ bool WebPluginDelegateImpl::HandleEvent(NPEvent* event,
// also require some changes in RenderWidgetHost to detect this in the
// WM_MOUSEACTIVATE handler and inform the renderer accordingly.
HWND prev_focus_window = NULL;
- if (event->event == WM_RBUTTONDOWN) {
+ if (np_event.event == WM_RBUTTONDOWN) {
prev_focus_window = ::SetFocus(dummy_window_for_activation_);
}
- if (ShouldTrackEventForModalLoops(event)) {
+ if (ShouldTrackEventForModalLoops(&np_event)) {
// A windowless plugin can enter a modal loop in a NPP_HandleEvent call.
// For e.g. Flash puts up a context menu when we right click on the
// windowless plugin area. We detect this by setting up a message filter
@@ -1042,14 +1153,14 @@ bool WebPluginDelegateImpl::HandleEvent(NPEvent* event,
bool pop_user_gesture = false;
- if (IsUserGestureMessage(event->event)) {
+ if (IsUserGestureMessage(np_event.event)) {
pop_user_gesture = true;
instance()->PushPopupsEnabledState(true);
}
- bool ret = instance()->NPP_HandleEvent(event) != 0;
+ bool ret = instance()->NPP_HandleEvent(&np_event) != 0;
- if (event->event == WM_MOUSEMOVE) {
+ if (np_event.event == WM_MOUSEMOVE) {
// Snag a reference to the current cursor ASAP in case the plugin modified
// it. There is a nasty race condition here with the multiprocess browser
// as someone might be setting the cursor in the main process as well.
@@ -1078,7 +1189,7 @@ bool WebPluginDelegateImpl::HandleEvent(NPEvent* event,
ResetEvent(handle_event_pump_messages_event_);
}
- if (event->event == WM_RBUTTONUP && ::IsWindow(prev_focus_window)) {
+ if (np_event.event == WM_RBUTTONUP && ::IsWindow(prev_focus_window)) {
::SetFocus(prev_focus_window);
}
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h
index 80c478b..aa856b4 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.h
+++ b/webkit/glue/plugins/webplugin_delegate_impl.h
@@ -53,9 +53,10 @@ class WebPluginDelegateImpl : public WebPluginDelegate {
virtual void Print(gfx::NativeDrawingContext context);
virtual void SetFocus(); // only called when windowless
-// only called when windowless
- virtual bool HandleEvent(NPEvent* event,
- WebCursor* cursor);
+ // only called when windowless
+ // See NPAPI NPP_HandleEvent for more information.
+ virtual bool HandleInputEvent(const WebKit::WebInputEvent& event,
+ WebCursor* cursor);
virtual NPObject* GetPluginScriptableObject();
virtual void DidFinishLoadWithReason(NPReason reason);
virtual int GetProcessId();
@@ -146,7 +147,6 @@ class WebPluginDelegateImpl : public WebPluginDelegate {
// See NPAPI NPP_SetWindow for more information.
void WindowlessSetWindow(bool force_set_window);
-
//-----------------------------------------
// used for windowed and windowless plugins
@@ -186,6 +186,7 @@ class WebPluginDelegateImpl : public WebPluginDelegate {
#if defined(OS_LINUX)
// The pixmap we're drawing into, for a windowless plugin.
GdkPixmap* pixmap_;
+ double first_event_time_;
// Ensure pixmap_ exists and is at least width by height pixels.
void EnsurePixmapAtLeastSize(int width, int height);
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
index 4922bf4..45fe78c 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
@@ -2,17 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// HACK: we need this #define in place before npapi.h is included for
-// plugins to work. However, all sorts of headers include npapi.h, so
-// the only way to be certain the define is in place is to put it
-// here. You might ask, "Why not set it in npapi.h directly, or in
-// this directory's SConscript, then?" but it turns out this define
-// makes npapi.h include Xlib.h, which in turn defines a ton of symbols
-// like None and Status, causing conflicts with the aforementioned
-// many headers that include npapi.h. Ugh.
-// See also plugin_host.cc.
-#define MOZ_X11 1
-
#include "webkit/glue/plugins/webplugin_delegate_impl.h"
#include <string>
@@ -27,6 +16,7 @@
#include "base/process_util.h"
#include "base/stats_counters.h"
#include "base/string_util.h"
+#include "webkit/api/public/WebInputEvent.h"
// #include "webkit/default_plugin/plugin_impl.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webplugin.h"
@@ -36,6 +26,13 @@
#include "webkit/glue/plugins/plugin_list.h"
#include "webkit/glue/plugins/plugin_stream_url.h"
#include "webkit/glue/webkit_glue.h"
+#if defined(OS_LINUX)
+#include "third_party/npapi/bindings/npapi_x11.h"
+#endif
+
+using WebKit::WebKeyboardEvent;
+using WebKit::WebInputEvent;
+using WebKit::WebMouseEvent;
WebPluginDelegate* WebPluginDelegate::Create(
const FilePath& filename,
@@ -63,13 +60,13 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
windowed_did_set_window_(false),
windowless_(false),
plugin_(NULL),
+ windowless_needs_set_window_(true),
instance_(instance),
pixmap_(NULL),
+ first_event_time_(-1.0),
parent_(containing_view),
- quirks_(0)
- {
+ quirks_(0) {
memset(&window_, 0, sizeof(window_));
-
}
WebPluginDelegateImpl::~WebPluginDelegateImpl() {
@@ -120,7 +117,7 @@ bool WebPluginDelegateImpl::Initialize(const GURL& url,
// a valid window handle causes subtle bugs with plugins which retreive
// the window handle and validate the same. The window handle can be
// retreived via NPN_GetValue of NPNVnetscapeWindow.
- // instance_->set_window_handle(parent_);
+ instance_->set_window_handle(parent_);
// CreateDummyWindowForActivation();
// handle_event_pump_messages_event_ = CreateEvent(NULL, TRUE, FALSE, NULL);
} else {
@@ -393,7 +390,7 @@ void WebPluginDelegateImpl::WindowedSetWindow() {
return;
}
- // XXX instance()->set_window_handle(windowed_handle_);
+ instance()->set_window_handle(windowed_handle_);
DCHECK(!instance()->windowless());
@@ -545,7 +542,8 @@ void WebPluginDelegateImpl::WindowlessPaint(cairo_surface_t* context,
cairo_destroy(cairo);
// Construct the paint message, targeting the pixmap.
- XGraphicsExposeEvent event = {0};
+ NPEvent np_event = {0};
+ XGraphicsExposeEvent &event = np_event.xgraphicsexpose;
event.type = GraphicsExpose;
event.display = GDK_DISPLAY();
event.drawable = GDK_PIXMAP_XID(pixmap_);
@@ -557,7 +555,7 @@ void WebPluginDelegateImpl::WindowlessPaint(cairo_surface_t* context,
// Tell the plugin to paint into the pixmap.
static StatsRate plugin_paint("Plugin.Paint");
StatsScope<StatsRate> scope(plugin_paint);
- NPError err = instance()->NPP_HandleEvent(reinterpret_cast<XEvent*>(&event));
+ NPError err = instance()->NPP_HandleEvent(&np_event);
DCHECK_EQ(err, NPERR_NO_ERROR);
// Now copy the rendered image pixmap back into the drawing buffer.
@@ -621,18 +619,201 @@ void WebPluginDelegateImpl::WindowlessSetWindow(bool force_set_window) {
void WebPluginDelegateImpl::SetFocus() {
DCHECK(instance()->windowless());
- NOTIMPLEMENTED();
- /* NPEvent focus_event;
- focus_event.event = WM_SETFOCUS;
- focus_event.wParam = 0;
- focus_event.lParam = 0;
+ NPEvent np_event = {0};
+ XFocusChangeEvent &event = np_event.xfocus;
+ event.type = FocusIn;
+ event.display = GDK_DISPLAY();
+ // Same values as Firefox. .serial and .window stay 0.
+ event.mode = -1;
+ event.detail = NotifyDetailNone;
+ instance()->NPP_HandleEvent(&np_event);
+}
+
+// Converts a WebInputEvent::Modifiers bitfield into a
+// corresponding X modifier state.
+static int GetXModifierState(int modifiers) {
+ int x_state = 0;
+ if (modifiers & WebInputEvent::ControlKey)
+ x_state |= ControlMask;
+ if (modifiers & WebInputEvent::ShiftKey)
+ x_state |= ShiftMask;
+ if (modifiers & WebInputEvent::AltKey)
+ x_state |= Mod1Mask;
+ if (modifiers & WebInputEvent::MetaKey)
+ x_state |= Mod2Mask;
+ if (modifiers & WebInputEvent::LeftButtonDown)
+ x_state |= Button1Mask;
+ if (modifiers & WebInputEvent::MiddleButtonDown)
+ x_state |= Button2Mask;
+ if (modifiers & WebInputEvent::RightButtonDown)
+ x_state |= Button3Mask;
+ // TODO(piman@google.com): There are other modifiers, e.g. Num Lock, that
+ // should be set (and Firefox does), but we didn't keep the information in
+ // the WebKit event.
+ return x_state;
+}
+
+static bool NPEventFromWebMouseEvent(const WebMouseEvent& event,
+ Time timestamp,
+ NPEvent *np_event) {
+ np_event->xany.display = GDK_DISPLAY();
+ // NOTE: Firefox keeps xany.serial and xany.window as 0.
+
+ int modifier_state = GetXModifierState(event.modifiers);
+
+ Window root = GDK_ROOT_WINDOW();
+ switch (event.type) {
+ case WebInputEvent::MouseMove: {
+ np_event->type = MotionNotify;
+ XMotionEvent &motion_event = np_event->xmotion;
+ motion_event.root = root;
+ motion_event.time = timestamp;
+ motion_event.x = event.x;
+ motion_event.y = event.y;
+ motion_event.x_root = event.globalX;
+ motion_event.y_root = event.globalY;
+ motion_event.state = modifier_state;
+ motion_event.is_hint = NotifyNormal;
+ motion_event.same_screen = True;
+ break;
+ }
+ case WebInputEvent::MouseLeave:
+ case WebInputEvent::MouseEnter: {
+ if (event.type == WebInputEvent::MouseEnter) {
+ np_event->type = EnterNotify;
+ } else {
+ np_event->type = LeaveNotify;
+ }
+ XCrossingEvent &crossing_event = np_event->xcrossing;
+ crossing_event.root = root;
+ crossing_event.time = timestamp;
+ crossing_event.x = event.x;
+ crossing_event.y = event.y;
+ crossing_event.x_root = event.globalX;
+ crossing_event.y_root = event.globalY;
+ crossing_event.mode = -1; // This is what Firefox sets it to.
+ crossing_event.detail = NotifyDetailNone;
+ crossing_event.same_screen = True;
+ // TODO(piman@google.com): set this to the correct value. Firefox does. I
+ // don't know where to get the information though, we get focus
+ // notifications, but no unfocus.
+ crossing_event.focus = 0;
+ crossing_event.state = modifier_state;
+ break;
+ }
+ case WebInputEvent::MouseUp:
+ case WebInputEvent::MouseDown: {
+ if (event.type == WebInputEvent::MouseDown) {
+ np_event->type = ButtonPress;
+ } else {
+ np_event->type = ButtonRelease;
+ }
+ XButtonEvent &button_event = np_event->xbutton;
+ button_event.root = root;
+ button_event.time = timestamp;
+ button_event.x = event.x;
+ button_event.y = event.y;
+ button_event.x_root = event.globalX;
+ button_event.y_root = event.globalY;
+ button_event.state = modifier_state;
+ switch (event.button) {
+ case WebMouseEvent::ButtonLeft:
+ button_event.button = Button1;
+ break;
+ case WebMouseEvent::ButtonMiddle:
+ button_event.button = Button2;
+ break;
+ case WebMouseEvent::ButtonRight:
+ button_event.button = Button3;
+ break;
+ }
+ button_event.same_screen = True;
+ break;
+ }
+ default:
+ NOTREACHED();
+ return false;
+ }
+ return true;
+}
- instance()->NPP_HandleEvent(&focus_event);*/
+static bool NPEventFromWebKeyboardEvent(const WebKeyboardEvent& event,
+ Time timestamp,
+ NPEvent *np_event) {
+ np_event->xany.display = GDK_DISPLAY();
+ // NOTE: Firefox keeps xany.serial and xany.window as 0.
+
+ switch (event.type) {
+ case WebKeyboardEvent::KeyDown:
+ np_event->type = KeyPress;
+ break;
+ case WebKeyboardEvent::KeyUp:
+ np_event->type = KeyRelease;
+ break;
+ default:
+ NOTREACHED();
+ return false;
+ }
+ XKeyEvent &key_event = np_event->xkey;
+ key_event.send_event = False;
+ key_event.display = GDK_DISPLAY();
+ // NOTE: Firefox keeps xany.serial and xany.window as 0.
+ // TODO(piman@google.com): is this right for multiple screens ?
+ key_event.root = DefaultRootWindow(key_event.display);
+ key_event.time = timestamp;
+ // NOTE: We don't have the correct information for x/y/x_root/y_root. Firefox
+ // doesn't have it either, so we pass the same values.
+ key_event.x = 0;
+ key_event.y = 0;
+ key_event.x_root = -1;
+ key_event.y_root = -1;
+ key_event.state = GetXModifierState(event.modifiers);
+ key_event.keycode = event.nativeKeyCode;
+ key_event.same_screen = True;
+ return true;
}
-bool WebPluginDelegateImpl::HandleEvent(NPEvent* event,
- WebCursor* cursor) {
- bool ret = instance()->NPP_HandleEvent(event) != 0;
+static bool NPEventFromWebInputEvent(const WebInputEvent& event,
+ Time timestamp,
+ NPEvent* np_event) {
+ switch (event.type) {
+ case WebInputEvent::MouseMove:
+ case WebInputEvent::MouseLeave:
+ case WebInputEvent::MouseEnter:
+ case WebInputEvent::MouseDown:
+ case WebInputEvent::MouseUp:
+ if (event.size < sizeof(WebMouseEvent)) {
+ NOTREACHED();
+ return false;
+ }
+ return NPEventFromWebMouseEvent(
+ *static_cast<const WebMouseEvent*>(&event), timestamp, np_event);
+ case WebInputEvent::KeyDown:
+ case WebInputEvent::KeyUp:
+ if (event.size < sizeof(WebKeyboardEvent)) {
+ NOTREACHED();
+ return false;
+ }
+ return NPEventFromWebKeyboardEvent(
+ *static_cast<const WebKeyboardEvent*>(&event), timestamp, np_event);
+ default:
+ return false;
+ }
+}
+
+bool WebPluginDelegateImpl::HandleInputEvent(const WebInputEvent& event,
+ WebCursor* cursor) {
+ DCHECK(windowless_) << "events should only be received in windowless mode";
+
+ if (first_event_time_ < 0.0)
+ first_event_time_ = event.timeStampSeconds;
+ Time timestamp = static_cast<Time>(
+ (event.timeStampSeconds - first_event_time_) * 1.0e3);
+ NPEvent np_event = {0};
+ if (!NPEventFromWebInputEvent(event, timestamp, &np_event)) {
+ return false;
+ }
+ bool ret = instance()->NPP_HandleEvent(&np_event) != 0;
#if 0
if (event->event == WM_MOUSEMOVE) {
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
index f758ce0..54bf43b 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
+++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
@@ -13,6 +13,7 @@
#include "base/message_loop.h"
#include "base/stats_counters.h"
#include "base/string_util.h"
+#include "webkit/api/public/WebInputEvent.h"
#include "webkit/default_plugin/plugin_impl.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webplugin.h"
@@ -23,6 +24,10 @@
#include "webkit/glue/plugins/plugin_stream_url.h"
#include "webkit/glue/webkit_glue.h"
+using WebKit::WebKeyboardEvent;
+using WebKit::WebInputEvent;
+using WebKit::WebMouseEvent;
+
namespace {
const wchar_t kWebPluginDelegateProperty[] = L"WebPluginDelegateProperty";
@@ -413,10 +418,11 @@ void WebPluginDelegateImpl::SetFocus() {
instance()->NPP_HandleEvent(&focus_event);
}
-bool WebPluginDelegateImpl::HandleEvent(NPEvent* event,
- WebCursor* cursor) {
+bool WebPluginDelegateImpl::HandleInputEvent(const WebInputEvent& event,
+ WebCursor* cursor) {
DCHECK(windowless_) << "events should only be received in windowless mode";
DCHECK(cursor != NULL);
+ // TODO: convert event into a NPEvent, and call NPP_HandleEvent(np_event).
return true;
}