summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstuartmorgan@chromium.org <stuartmorgan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-29 20:49:41 +0000
committerstuartmorgan@chromium.org <stuartmorgan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-29 20:49:41 +0000
commit7c64a2f4b4aa2b755a67b6625d3a508039e2fad4 (patch)
tree9619a45a2736ca7bce7a27d2e3ce3daea91cd43f
parentbb20bfdc0036e870e87fd9067f1f7f310d7de3c6 (diff)
downloadchromium_src-7c64a2f4b4aa2b755a67b6625d3a508039e2fad4.zip
chromium_src-7c64a2f4b4aa2b755a67b6625d3a508039e2fad4.tar.gz
chromium_src-7c64a2f4b4aa2b755a67b6625d3a508039e2fad4.tar.bz2
Move Mac plugin event conversion into helper classes
Creates new helper classes for Carbon and Cocoa plugin event conversion, and abstracts away the difference via a common interface and a model-driven factory. The guts of the converters is just the old static methods, moved into the classes with a couple of minor changes: - Switched to using WebInputEvent::isMouseEventType/isKeyboardEventType, since our methods were essentially duplicates. - The newer key types, RawKeyDown and Char, are now explicitly unhandled, rather than logging warnings. BUG=none TEST=Plugin events (mouse, keyboard, scroll wheel) on the Mac should continue to work as before. Review URL: http://codereview.chromium.org/1566002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42993 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--webkit/glue/plugins/plugin_host.cc6
-rw-r--r--webkit/glue/plugins/plugin_instance.h12
-rw-r--r--webkit/glue/plugins/plugin_web_event_converter_mac.h60
-rw-r--r--webkit/glue/plugins/plugin_web_event_converter_mac.mm368
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_mac.mm375
-rw-r--r--webkit/glue/webkit_glue.gypi2
6 files changed, 478 insertions, 345 deletions
diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc
index 6341bc0..5ceea68 100644
--- a/webkit/glue/plugins/plugin_host.cc
+++ b/webkit/glue/plugins/plugin_host.cc
@@ -872,11 +872,11 @@ NPError NPN_SetValue(NPP id, NPPVariable variable, void* value) {
case NPPVpluginDrawingModel: {
int model = reinterpret_cast<int>(value);
if (model == NPDrawingModelCoreGraphics) {
- plugin->set_drawing_model(model);
+ plugin->set_drawing_model(static_cast<NPDrawingModel>(model));
return NPERR_NO_ERROR;
} else if (model == NPDrawingModelCoreAnimation &&
SupportsSharingAcceleratedSurfaces()) {
- plugin->set_drawing_model(model);
+ plugin->set_drawing_model(static_cast<NPDrawingModel>(model));
return NPERR_NO_ERROR;
}
return NPERR_GENERIC_ERROR;
@@ -889,7 +889,7 @@ NPError NPN_SetValue(NPP id, NPPVariable variable, void* value) {
case NPEventModelCarbon:
#endif
case NPEventModelCocoa:
- plugin->set_event_model(model);
+ plugin->set_event_model(static_cast<NPEventModel>(model));
return NPERR_NO_ERROR;
break;
}
diff --git a/webkit/glue/plugins/plugin_instance.h b/webkit/glue/plugins/plugin_instance.h
index bd3a0d7..afb4b58 100644
--- a/webkit/glue/plugins/plugin_instance.h
+++ b/webkit/glue/plugins/plugin_instance.h
@@ -109,10 +109,10 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> {
#if defined(OS_MACOSX)
// Get/Set the Mac NPAPI drawing and event models
- int drawing_model() { return drawing_model_; }
- void set_drawing_model(int value) { drawing_model_ = value; }
- int event_model() { return event_model_; }
- void set_event_model(int value) { event_model_ = value; }
+ NPDrawingModel drawing_model() { return drawing_model_; }
+ void set_drawing_model(NPDrawingModel value) { drawing_model_ = value; }
+ NPEventModel event_model() { return event_model_; }
+ void set_event_model(NPEventModel value) { event_model_ = value; }
// Updates the instance's tracking of the location of the plugin location
// relative to the upper left of the screen.
void set_plugin_origin(const gfx::Point& origin) { plugin_origin_ = origin; }
@@ -286,8 +286,8 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> {
intptr_t get_notify_data_;
bool use_mozilla_user_agent_;
#if defined(OS_MACOSX)
- int drawing_model_;
- int event_model_;
+ NPDrawingModel drawing_model_;
+ NPEventModel event_model_;
gfx::Point plugin_origin_;
gfx::Rect containing_window_frame_;
NPCocoaEvent* currently_handled_event_; // weak
diff --git a/webkit/glue/plugins/plugin_web_event_converter_mac.h b/webkit/glue/plugins/plugin_web_event_converter_mac.h
new file mode 100644
index 0000000..ec5b86f
--- /dev/null
+++ b/webkit/glue/plugins/plugin_web_event_converter_mac.h
@@ -0,0 +1,60 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_GLUE_PLUGIN_PLUGIN_WEB_EVENT_CONVERTER_MAC_H_
+#define WEBKIT_GLUE_PLUGIN_PLUGIN_WEB_EVENT_CONVERTER_MAC_H_
+
+#include "third_party/npapi/bindings/npapi.h"
+
+namespace WebKit {
+class WebInputEvent;
+class WebKeyboardEvent;
+class WebMouseEvent;
+class WebMouseWheelEvent;
+}
+
+// Utility class to translating WebInputEvent structs to equivalent structures
+// suitable for sending to Mac plugins (via NPP_HandleEvent).
+class PluginWebEventConverter {
+ public:
+ PluginWebEventConverter() {}
+ virtual ~PluginWebEventConverter() {}
+
+ // Initializes a converter for the given web event. Returns false if the event
+ // could not be converted.
+ virtual bool InitWithEvent(const WebKit::WebInputEvent& web_event);
+
+ // Returns a pointer to a plugin event--suitable for passing to
+ // NPP_HandleEvent--corresponding to the the web event this converter was
+ // created with. The pointer is valid only as long as this object is.
+ // Returns NULL iff InitWithEvent returned false.
+ virtual void* plugin_event() = 0;
+
+protected:
+ // To be overridden by subclasses to store a converted plugin representation
+ // of the given web event, suitable for returning from plugin_event.
+ // Returns true if the event was successfully converted.
+ virtual bool ConvertKeyboardEvent(
+ const WebKit::WebKeyboardEvent& web_event) = 0;
+ virtual bool ConvertMouseEvent(const WebKit::WebMouseEvent& web_event) = 0;
+ virtual bool ConvertMouseWheelEvent(
+ const WebKit::WebMouseWheelEvent& web_event) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PluginWebEventConverter);
+};
+
+// Factory for generating PluginWebEventConverter objects by event model.
+class PluginWebEventConverterFactory {
+ public:
+ // Returns a new PluginWebEventConverter corresponding to the given plugin
+ // event model.
+ static PluginWebEventConverter*
+ CreateConverterForModel(NPEventModel event_model);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PluginWebEventConverterFactory);
+};
+
+#endif // WEBKIT_GLUE_PLUGIN_PLUGIN_WEB_EVENT_CONVERTER_MAC_H_
diff --git a/webkit/glue/plugins/plugin_web_event_converter_mac.mm b/webkit/glue/plugins/plugin_web_event_converter_mac.mm
new file mode 100644
index 0000000..030ed06
--- /dev/null
+++ b/webkit/glue/plugins/plugin_web_event_converter_mac.mm
@@ -0,0 +1,368 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Cocoa/Cocoa.h>
+
+#include "base/logging.h"
+#include "webkit/glue/plugins/plugin_web_event_converter_mac.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
+
+using WebKit::WebInputEvent;
+using WebKit::WebKeyboardEvent;
+using WebKit::WebMouseEvent;
+using WebKit::WebMouseWheelEvent;
+
+namespace {
+
+// Returns true if the caps lock flag should be set for the given event.
+// TODO: Ideally the event itself would know about the caps lock key; see
+// <http://crbug.com/38226>. This function is only a temporary workaround that
+// guesses based on live state.
+bool CapsLockIsActive(const WebInputEvent& event) {
+ NSUInteger current_flags = [[NSApp currentEvent] modifierFlags];
+ bool caps_lock_on = (current_flags & NSAlphaShiftKeyMask) ? true : false;
+ // If this a caps lock keypress, then the event stream state can be wrong.
+ // Luckily, the weird event stream for caps lock makes it easy to tell whether
+ // caps lock is being turned on or off.
+ if (event.type == WebInputEvent::KeyDown ||
+ event.type == WebInputEvent::KeyUp) {
+ const WebKeyboardEvent* key_event =
+ static_cast<const WebKeyboardEvent*>(&event);
+ if (key_event->nativeKeyCode == 57)
+ caps_lock_on = (event.type == WebInputEvent::KeyDown);
+ }
+ return caps_lock_on;
+}
+
+} // namespace
+
+#pragma mark -
+
+#ifndef NP_NO_CARBON
+
+// Converter implementation for the Carbon event model.
+class CarbonPluginWebEventConverter : public PluginWebEventConverter {
+ public:
+ CarbonPluginWebEventConverter() {}
+ virtual ~CarbonPluginWebEventConverter() {}
+
+ virtual bool InitWithEvent(const WebInputEvent& web_event);
+
+ virtual void* plugin_event() { return &carbon_event_; }
+
+ protected:
+ virtual bool ConvertKeyboardEvent(const WebKeyboardEvent& key_event);
+ virtual bool ConvertMouseEvent(const WebMouseEvent& mouse_event);
+ virtual bool ConvertMouseWheelEvent(const WebMouseWheelEvent& wheel_event);
+
+ private:
+ // Returns the Carbon translation of web_event's modifiers.
+ static EventModifiers CarbonModifiers(const WebInputEvent& web_event);
+
+ NPEvent carbon_event_;
+
+ DISALLOW_COPY_AND_ASSIGN(CarbonPluginWebEventConverter);
+};
+
+bool CarbonPluginWebEventConverter::InitWithEvent(
+ const WebInputEvent& web_event) {
+ memset(&carbon_event_, 0, sizeof(carbon_event_));
+ // Set the fields common to all event types.
+ carbon_event_.when = TickCount();
+ carbon_event_.modifiers |= CarbonModifiers(web_event);
+
+ return PluginWebEventConverter::InitWithEvent(web_event);
+}
+
+bool CarbonPluginWebEventConverter::ConvertKeyboardEvent(
+ const WebKeyboardEvent& key_event) {
+ // TODO: Figure out how to handle Unicode input to plugins, if that's
+ // even possible in the NPAPI Carbon event model.
+ carbon_event_.message = (key_event.nativeKeyCode << 8) & keyCodeMask;
+ carbon_event_.message |= key_event.text[0] & charCodeMask;
+ carbon_event_.modifiers |= btnState;
+
+ switch (key_event.type) {
+ case WebInputEvent::KeyDown:
+ if (key_event.modifiers & WebInputEvent::IsAutoRepeat)
+ carbon_event_.what = autoKey;
+ else
+ carbon_event_.what = keyDown;
+ return true;
+ case WebInputEvent::KeyUp:
+ carbon_event_.what = keyUp;
+ return true;
+ case WebInputEvent::RawKeyDown:
+ case WebInputEvent::Char:
+ // May be used eventually for IME, but currently not needed.
+ return false;
+ default:
+ NOTREACHED();
+ return false;
+ }
+}
+
+bool CarbonPluginWebEventConverter::ConvertMouseEvent(
+ const WebMouseEvent& mouse_event) {
+ carbon_event_.where.h = mouse_event.globalX;
+ carbon_event_.where.v = mouse_event.globalY;
+
+ // Default to "button up"; override this for mouse down events below.
+ carbon_event_.modifiers |= btnState;
+
+ switch (mouse_event.button) {
+ case WebMouseEvent::ButtonLeft:
+ break;
+ case WebMouseEvent::ButtonMiddle:
+ carbon_event_.modifiers |= cmdKey;
+ break;
+ case WebMouseEvent::ButtonRight:
+ carbon_event_.modifiers |= controlKey;
+ break;
+ default:
+ NOTIMPLEMENTED();
+ }
+ switch (mouse_event.type) {
+ case WebInputEvent::MouseMove:
+ carbon_event_.what = nullEvent;
+ return true;
+ case WebInputEvent::MouseLeave:
+ case WebInputEvent::MouseEnter:
+ carbon_event_.what = NPEventType_AdjustCursorEvent;
+ return true;
+ case WebInputEvent::MouseDown:
+ carbon_event_.modifiers &= ~btnState;
+ carbon_event_.what = mouseDown;
+ return true;
+ case WebInputEvent::MouseUp:
+ carbon_event_.what = mouseUp;
+ return true;
+ default:
+ NOTREACHED();
+ return false;
+ }
+}
+
+bool CarbonPluginWebEventConverter::ConvertMouseWheelEvent(
+ const WebMouseWheelEvent& wheel_event) {
+ return false; // The Carbon NPAPI event model has no "mouse wheel" concept.
+}
+
+EventModifiers CarbonPluginWebEventConverter::CarbonModifiers(
+ const WebInputEvent& web_event) {
+ NSInteger modifiers = 0;
+ if (web_event.modifiers & WebInputEvent::ControlKey)
+ modifiers |= controlKey;
+ if (web_event.modifiers & WebInputEvent::ShiftKey)
+ modifiers |= shiftKey;
+ if (web_event.modifiers & WebInputEvent::AltKey)
+ modifiers |= optionKey;
+ if (web_event.modifiers & WebInputEvent::MetaKey)
+ modifiers |= cmdKey;
+ if (CapsLockIsActive(web_event))
+ modifiers |= alphaLock;
+ return modifiers;
+}
+
+#endif // !NP_NO_CARBON
+
+#pragma mark -
+
+// Converter implementation for the Cocoa event model.
+class CocoaPluginWebEventConverter : public PluginWebEventConverter {
+public:
+ CocoaPluginWebEventConverter() {}
+ virtual ~CocoaPluginWebEventConverter() {}
+
+ virtual bool InitWithEvent(const WebInputEvent& web_event);
+
+ virtual void* plugin_event() { return &cocoa_event_; }
+
+protected:
+ virtual bool ConvertKeyboardEvent(const WebKeyboardEvent& key_event);
+ virtual bool ConvertMouseEvent(const WebMouseEvent& mouse_event);
+ virtual bool ConvertMouseWheelEvent(const WebMouseWheelEvent& wheel_event);
+
+private:
+ // Returns the Cocoa translation of web_event's modifiers.
+ static NSUInteger CocoaModifiers(const WebInputEvent& web_event);
+
+ // Returns true if the given key is a modifier key.
+ static bool KeyIsModifier(int native_key_code);
+
+ NPCocoaEvent cocoa_event_;
+
+ DISALLOW_COPY_AND_ASSIGN(CocoaPluginWebEventConverter);
+};
+
+bool CocoaPluginWebEventConverter::InitWithEvent(
+ const WebInputEvent& web_event) {
+ memset(&cocoa_event_, 0, sizeof(cocoa_event_));
+ return PluginWebEventConverter::InitWithEvent(web_event);
+}
+
+bool CocoaPluginWebEventConverter::ConvertKeyboardEvent(
+ const WebKeyboardEvent& key_event) {
+ cocoa_event_.data.key.keyCode = key_event.nativeKeyCode;
+
+ cocoa_event_.data.key.modifierFlags |= CocoaModifiers(key_event);
+
+ // Modifier keys have their own event type, and don't get character or
+ // repeat data.
+ if (KeyIsModifier(key_event.nativeKeyCode)) {
+ cocoa_event_.type = NPCocoaEventFlagsChanged;
+ return true;
+ }
+
+ cocoa_event_.data.key.characters = reinterpret_cast<NPNSString*>(
+ [NSString stringWithFormat:@"%S", key_event.text]);
+ cocoa_event_.data.key.charactersIgnoringModifiers =
+ reinterpret_cast<NPNSString*>(
+ [NSString stringWithFormat:@"%S", key_event.unmodifiedText]);
+
+ if (key_event.modifiers & WebInputEvent::IsAutoRepeat)
+ cocoa_event_.data.key.isARepeat = true;
+
+ switch (key_event.type) {
+ case WebInputEvent::KeyDown:
+ cocoa_event_.type = NPCocoaEventKeyDown;
+ return true;
+ case WebInputEvent::KeyUp:
+ cocoa_event_.type = NPCocoaEventKeyUp;
+ return true;
+ case WebInputEvent::RawKeyDown:
+ case WebInputEvent::Char:
+ // May be used eventually for IME, but currently not needed.
+ return false;
+ default:
+ NOTREACHED();
+ return false;
+ }
+}
+
+bool CocoaPluginWebEventConverter::ConvertMouseEvent(
+ const WebMouseEvent& mouse_event) {
+ cocoa_event_.data.mouse.pluginX = mouse_event.x;
+ cocoa_event_.data.mouse.pluginY = mouse_event.y;
+ cocoa_event_.data.mouse.modifierFlags |= CocoaModifiers(mouse_event);
+ cocoa_event_.data.mouse.clickCount = mouse_event.clickCount;
+ switch (mouse_event.button) {
+ case WebMouseEvent::ButtonLeft:
+ cocoa_event_.data.mouse.buttonNumber = 0;
+ break;
+ case WebMouseEvent::ButtonMiddle:
+ cocoa_event_.data.mouse.buttonNumber = 2;
+ break;
+ case WebMouseEvent::ButtonRight:
+ cocoa_event_.data.mouse.buttonNumber = 1;
+ break;
+ default:
+ cocoa_event_.data.mouse.buttonNumber = mouse_event.button;
+ break;
+ }
+ switch (mouse_event.type) {
+ case WebInputEvent::MouseDown:
+ cocoa_event_.type = NPCocoaEventMouseDown;
+ return true;
+ case WebInputEvent::MouseUp:
+ cocoa_event_.type = NPCocoaEventMouseUp;
+ return true;
+ case WebInputEvent::MouseMove: {
+ bool mouse_is_down =
+ (mouse_event.modifiers & WebInputEvent::LeftButtonDown) ||
+ (mouse_event.modifiers & WebInputEvent::RightButtonDown) ||
+ (mouse_event.modifiers & WebInputEvent::MiddleButtonDown);
+ cocoa_event_.type = mouse_is_down ? NPCocoaEventMouseDragged
+ : NPCocoaEventMouseMoved;
+ return true;
+ }
+ case WebInputEvent::MouseEnter:
+ cocoa_event_.type = NPCocoaEventMouseEntered;
+ return true;
+ case WebInputEvent::MouseLeave:
+ cocoa_event_.type = NPCocoaEventMouseExited;
+ return true;
+ default:
+ NOTREACHED();
+ return false;
+ }
+}
+
+bool CocoaPluginWebEventConverter::ConvertMouseWheelEvent(
+ const WebMouseWheelEvent& wheel_event) {
+ cocoa_event_.type = NPCocoaEventScrollWheel;
+ cocoa_event_.data.mouse.pluginX = wheel_event.x;
+ cocoa_event_.data.mouse.pluginY = wheel_event.y;
+ cocoa_event_.data.mouse.modifierFlags |= CocoaModifiers(wheel_event);
+ cocoa_event_.data.mouse.deltaX = wheel_event.deltaX;
+ cocoa_event_.data.mouse.deltaY = wheel_event.deltaY;
+ return true;
+}
+
+NSUInteger CocoaPluginWebEventConverter::CocoaModifiers(
+ const WebInputEvent& web_event) {
+ NSInteger modifiers = 0;
+ if (web_event.modifiers & WebInputEvent::ControlKey)
+ modifiers |= NSControlKeyMask;
+ if (web_event.modifiers & WebInputEvent::ShiftKey)
+ modifiers |= NSShiftKeyMask;
+ if (web_event.modifiers & WebInputEvent::AltKey)
+ modifiers |= NSAlternateKeyMask;
+ if (web_event.modifiers & WebInputEvent::MetaKey)
+ modifiers |= NSCommandKeyMask;
+ if (CapsLockIsActive(web_event))
+ modifiers |= NSAlphaShiftKeyMask;
+ return modifiers;
+}
+
+bool CocoaPluginWebEventConverter::KeyIsModifier(int native_key_code) {
+ switch (native_key_code) {
+ case 55: // Left command
+ case 54: // Right command
+ case 58: // Left option
+ case 61: // Right option
+ case 59: // Left control
+ case 62: // Right control
+ case 56: // Left shift
+ case 60: // Right shift
+ case 57: // Caps lock
+ return true;
+ default:
+ return false;
+ }
+}
+
+#pragma mark -
+
+bool PluginWebEventConverter::InitWithEvent(const WebInputEvent& web_event) {
+ if (web_event.type == WebInputEvent::MouseWheel) {
+ return ConvertMouseWheelEvent(
+ *static_cast<const WebMouseWheelEvent*>(&web_event));
+ } else if (WebInputEvent::isMouseEventType(web_event.type)) {
+ return ConvertMouseEvent(*static_cast<const WebMouseEvent*>(&web_event));
+ } else if (WebInputEvent::isKeyboardEventType(web_event.type)) {
+ return ConvertKeyboardEvent(
+ *static_cast<const WebKeyboardEvent*>(&web_event));
+ }
+ DLOG(WARNING) << "Unknown event type " << web_event.type;
+ return false;
+}
+
+#pragma mark -
+
+PluginWebEventConverter*
+ PluginWebEventConverterFactory::CreateConverterForModel(
+ NPEventModel event_model) {
+ switch (event_model) {
+ case NPEventModelCocoa:
+ return new CocoaPluginWebEventConverter();
+#ifndef NP_NO_CARBON
+ case NPEventModelCarbon:
+ return new CarbonPluginWebEventConverter();
+#endif
+ default:
+ NOTIMPLEMENTED();
+ return NULL;
+ }
+}
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
index f1f7cbd..d2445ed 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
+++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
@@ -21,11 +21,11 @@
#include "webkit/default_plugin/plugin_impl.h"
#include "webkit/glue/webplugin.h"
#include "webkit/glue/plugins/coregraphics_private_symbols_mac.h"
-#include "webkit/glue/plugins/plugin_constants_win.h"
#include "webkit/glue/plugins/plugin_instance.h"
#include "webkit/glue/plugins/plugin_lib.h"
#include "webkit/glue/plugins/plugin_list.h"
#include "webkit/glue/plugins/plugin_stream_url.h"
+#include "webkit/glue/plugins/plugin_web_event_converter_mac.h"
#include "webkit/glue/webkit_glue.h"
#ifndef NP_NO_CARBON
@@ -935,300 +935,6 @@ void WebPluginDelegateImpl::UpdateIdleEventRate() {
}
#endif // !NP_NO_CARBON
-static bool WebInputEventIsWebMouseEvent(const WebInputEvent& 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 true;
- default:
- return false;
- }
-}
-
-static bool WebInputEventIsWebKeyboardEvent(const WebInputEvent& event) {
- switch (event.type) {
- case WebInputEvent::KeyDown:
- case WebInputEvent::KeyUp:
- if (event.size < sizeof(WebKeyboardEvent)) {
- NOTREACHED();
- return false;
- }
- return true;
- default:
- return false;
- }
-}
-
-// Returns true if the caps lock flag should be set for the given event.
-// TODO: Ideally the event itself would know about the caps lock key; see
-// <http://crbug.com/38226>. This function is only a temporary workaround that
-// guesses based on live state.
-static bool CapsLockIsActive(const WebInputEvent& event) {
- NSUInteger current_flags = [[NSApp currentEvent] modifierFlags];
- bool caps_lock_on = (current_flags & NSAlphaShiftKeyMask) ? true : false;
- // If this a caps lock keypress, then the event stream state can be wrong.
- // Luckily, the weird event stream for caps lock makes it easy to tell whether
- // caps lock is being turned on or off.
- if (event.type == WebInputEvent::KeyDown ||
- event.type == WebInputEvent::KeyUp) {
- const WebKeyboardEvent* key_event =
- static_cast<const WebKeyboardEvent*>(&event);
- if (key_event->nativeKeyCode == 57)
- caps_lock_on = (event.type == WebInputEvent::KeyDown);
- }
- return caps_lock_on;
-}
-
-#ifndef NP_NO_CARBON
-static NSInteger CarbonModifiersFromWebEvent(const WebInputEvent& event) {
- NSInteger modifiers = 0;
- if (event.modifiers & WebInputEvent::ControlKey)
- modifiers |= controlKey;
- if (event.modifiers & WebInputEvent::ShiftKey)
- modifiers |= shiftKey;
- if (event.modifiers & WebInputEvent::AltKey)
- modifiers |= optionKey;
- if (event.modifiers & WebInputEvent::MetaKey)
- modifiers |= cmdKey;
- if (CapsLockIsActive(event))
- modifiers |= alphaLock;
- return modifiers;
-}
-
-static bool NPEventFromWebMouseEvent(const WebMouseEvent& event,
- NPEvent *np_event) {
- np_event->where.h = event.globalX;
- np_event->where.v = event.globalY;
-
- np_event->modifiers |= CarbonModifiersFromWebEvent(event);
-
- // default to "button up"; override this for mouse down events below.
- np_event->modifiers |= btnState;
-
- switch (event.button) {
- case WebMouseEvent::ButtonLeft:
- break;
- case WebMouseEvent::ButtonMiddle:
- np_event->modifiers |= cmdKey;
- break;
- case WebMouseEvent::ButtonRight:
- np_event->modifiers |= controlKey;
- break;
- default:
- NOTIMPLEMENTED();
- }
- switch (event.type) {
- case WebInputEvent::MouseMove:
- np_event->what = nullEvent;
- return true;
- case WebInputEvent::MouseLeave:
- case WebInputEvent::MouseEnter:
- np_event->what = NPEventType_AdjustCursorEvent;
- return true;
- case WebInputEvent::MouseDown:
- np_event->modifiers &= ~btnState;
- np_event->what = mouseDown;
- return true;
- case WebInputEvent::MouseUp:
- np_event->what = mouseUp;
- return true;
- default:
- NOTREACHED();
- return false;
- }
-}
-
-static bool NPEventFromWebKeyboardEvent(const WebKeyboardEvent& event,
- NPEvent *np_event) {
- // TODO: figure out how to handle Unicode input to plugins, if that's
- // even possible in the NPAPI Carbon event model.
- np_event->message = (event.nativeKeyCode << 8) & keyCodeMask;
- np_event->message |= event.text[0] & charCodeMask;
- np_event->modifiers |= btnState;
- np_event->modifiers |= CarbonModifiersFromWebEvent(event);
-
- switch (event.type) {
- case WebInputEvent::KeyDown:
- if (event.modifiers & WebInputEvent::IsAutoRepeat)
- np_event->what = autoKey;
- else
- np_event->what = keyDown;
- return true;
- case WebInputEvent::KeyUp:
- np_event->what = keyUp;
- return true;
- default:
- NOTREACHED();
- return false;
- }
-}
-
-static bool NPEventFromWebInputEvent(const WebInputEvent& event,
- NPEvent* np_event) {
- np_event->when = TickCount();
- if (event.type == WebInputEvent::MouseWheel) {
- return false; // Carbon NPAPI event model has no "mouse wheel" concept.
- } else if (WebInputEventIsWebMouseEvent(event)) {
- return NPEventFromWebMouseEvent(*static_cast<const WebMouseEvent*>(&event),
- np_event);
- } else if (WebInputEventIsWebKeyboardEvent(event)) {
- return NPEventFromWebKeyboardEvent(
- *static_cast<const WebKeyboardEvent*>(&event), np_event);
- }
- DLOG(WARNING) << "unknown event type " << event.type;
- return false;
-}
-#endif // !NP_NO_CARBON
-
-static NSInteger CocoaModifiersFromWebEvent(const WebInputEvent& event) {
- NSInteger modifiers = 0;
- if (event.modifiers & WebInputEvent::ControlKey)
- modifiers |= NSControlKeyMask;
- if (event.modifiers & WebInputEvent::ShiftKey)
- modifiers |= NSShiftKeyMask;
- if (event.modifiers & WebInputEvent::AltKey)
- modifiers |= NSAlternateKeyMask;
- if (event.modifiers & WebInputEvent::MetaKey)
- modifiers |= NSCommandKeyMask;
- if (CapsLockIsActive(event))
- modifiers |= NSAlphaShiftKeyMask;
- return modifiers;
-}
-
-static bool KeyIsModifier(int native_key_code) {
- switch (native_key_code) {
- case 55: // Left command
- case 54: // Right command
- case 58: // Left option
- case 61: // Right option
- case 59: // Left control
- case 62: // Right control
- case 56: // Left shift
- case 60: // Right shift
- case 57: // Caps lock
- return true;
- default:
- return false;
- }
-}
-
-static bool NPCocoaEventFromWebMouseEvent(const WebMouseEvent& event,
- NPCocoaEvent *np_cocoa_event) {
- np_cocoa_event->data.mouse.pluginX = event.x;
- np_cocoa_event->data.mouse.pluginY = event.y;
- np_cocoa_event->data.mouse.modifierFlags |= CocoaModifiersFromWebEvent(event);
- np_cocoa_event->data.mouse.clickCount = event.clickCount;
- switch (event.button) {
- case WebMouseEvent::ButtonLeft:
- np_cocoa_event->data.mouse.buttonNumber = 0;
- break;
- case WebMouseEvent::ButtonMiddle:
- np_cocoa_event->data.mouse.buttonNumber = 2;
- break;
- case WebMouseEvent::ButtonRight:
- np_cocoa_event->data.mouse.buttonNumber = 1;
- break;
- default:
- np_cocoa_event->data.mouse.buttonNumber = event.button;
- break;
- }
- switch (event.type) {
- case WebInputEvent::MouseDown:
- np_cocoa_event->type = NPCocoaEventMouseDown;
- return true;
- case WebInputEvent::MouseUp:
- np_cocoa_event->type = NPCocoaEventMouseUp;
- return true;
- case WebInputEvent::MouseMove: {
- bool mouse_is_down = (event.modifiers & WebInputEvent::LeftButtonDown) ||
- (event.modifiers & WebInputEvent::RightButtonDown) ||
- (event.modifiers & WebInputEvent::MiddleButtonDown);
- np_cocoa_event->type = mouse_is_down ? NPCocoaEventMouseDragged
- : NPCocoaEventMouseMoved;
- return true;
- }
- case WebInputEvent::MouseEnter:
- np_cocoa_event->type = NPCocoaEventMouseEntered;
- return true;
- case WebInputEvent::MouseLeave:
- np_cocoa_event->type = NPCocoaEventMouseExited;
- return true;
- default:
- NOTREACHED();
- return false;
- }
-}
-
-static bool NPCocoaEventFromWebMouseWheelEvent(const WebMouseWheelEvent& event,
- NPCocoaEvent *np_cocoa_event) {
- np_cocoa_event->type = NPCocoaEventScrollWheel;
- np_cocoa_event->data.mouse.pluginX = event.x;
- np_cocoa_event->data.mouse.pluginY = event.y;
- np_cocoa_event->data.mouse.modifierFlags |= CocoaModifiersFromWebEvent(event);
- np_cocoa_event->data.mouse.deltaX = event.deltaX;
- np_cocoa_event->data.mouse.deltaY = event.deltaY;
- return true;
-}
-
-static bool NPCocoaEventFromWebKeyboardEvent(const WebKeyboardEvent& event,
- NPCocoaEvent *np_cocoa_event) {
- np_cocoa_event->data.key.keyCode = event.nativeKeyCode;
-
- np_cocoa_event->data.key.modifierFlags |= CocoaModifiersFromWebEvent(event);
-
- // Modifier keys have their own event type, and don't get character or
- // repeat data.
- if (KeyIsModifier(event.nativeKeyCode)) {
- np_cocoa_event->type = NPCocoaEventFlagsChanged;
- return true;
- }
-
- np_cocoa_event->data.key.characters = reinterpret_cast<NPNSString*>(
- [NSString stringWithFormat:@"%S", event.text]);
- np_cocoa_event->data.key.charactersIgnoringModifiers =
- reinterpret_cast<NPNSString*>(
- [NSString stringWithFormat:@"%S", event.unmodifiedText]);
-
- if (event.modifiers & WebInputEvent::IsAutoRepeat)
- np_cocoa_event->data.key.isARepeat = true;
-
- switch (event.type) {
- case WebInputEvent::KeyDown:
- np_cocoa_event->type = NPCocoaEventKeyDown;
- return true;
- case WebInputEvent::KeyUp:
- np_cocoa_event->type = NPCocoaEventKeyUp;
- return true;
- default:
- NOTREACHED();
- return false;
- }
-}
-
-static bool NPCocoaEventFromWebInputEvent(const WebInputEvent& event,
- NPCocoaEvent *np_cocoa_event) {
- memset(np_cocoa_event, 0, sizeof(NPCocoaEvent));
- if (event.type == WebInputEvent::MouseWheel) {
- return NPCocoaEventFromWebMouseWheelEvent(
- *static_cast<const WebMouseWheelEvent*>(&event), np_cocoa_event);
- } else if (WebInputEventIsWebMouseEvent(event)) {
- return NPCocoaEventFromWebMouseEvent(
- *static_cast<const WebMouseEvent*>(&event), np_cocoa_event);
- } else if (WebInputEventIsWebKeyboardEvent(event)) {
- return NPCocoaEventFromWebKeyboardEvent(
- *static_cast<const WebKeyboardEvent*>(&event), np_cocoa_event);
- }
- DLOG(WARNING) << "unknown event type " << event.type;
- return false;
-}
-
// Returns the mask for just the button state in a WebInputEvent's modifiers.
static int WebEventButtonModifierMask() {
return WebInputEvent::LeftButtonDown |
@@ -1298,7 +1004,7 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent(
}
#endif
- if (WebInputEventIsWebMouseEvent(event)) {
+ if (WebInputEvent::isMouseEventType(event.type)) {
// Check our plugin location before we send the event to the plugin, just
// in case we somehow missed a plugin frame change.
const WebMouseEvent* mouse_event =
@@ -1329,7 +1035,7 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent(
// This isn't perfect (specifically, click-and-hold doesn't seem to work
// if the fast path is on), but the slight regression is worthwhile
// for the improved framerates.
- if (WebInputEventIsWebMouseEvent(event)) {
+ if (WebInputEvent::isMouseEventType(event.type)) {
if (event.type == WebInputEvent::MouseLeave) {
SetQuickDrawFastPathEnabled(true);
} else {
@@ -1367,55 +1073,52 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent(
ScopedActiveDelegate active_delegate(this);
- // Create the plugin event structure, and send it to the plugin.
- bool ret = false;
- switch (instance()->event_model()) {
-#ifndef NP_NO_CARBON
- case NPEventModelCarbon: {
- NPEvent np_event = {0};
- if (!NPEventFromWebInputEvent(event, &np_event))
- return false;
- ret = instance()->NPP_HandleEvent(&np_event) != 0;
- break;
- }
-#endif
- case NPEventModelCocoa: {
- NPCocoaEvent np_cocoa_event;
- if (!NPCocoaEventFromWebInputEvent(event, &np_cocoa_event))
- return false;
-
- // Keep track of whether or not we are in a drag that started outside the
- // plugin; if we are, filter out drag-related events (and convert the end
- // of the external drag into an enter event) per the NPAPI Cocoa event
- // model spec.
- // If we eventually add a page-capture mode at the WebKit layer, mirroring
- // the plugin-capture mode that handles drags starting inside the plugin
- // and going outside, this can all be removed.
- bool drag_related = EventIsRelatedToDrag(event, external_drag_buttons_);
- external_drag_buttons_ = UpdatedDragStateFromEvent(external_drag_buttons_,
- event);
- if (drag_related) {
- if (event.type == WebInputEvent::MouseUp && !external_drag_buttons_)
- np_cocoa_event.type = NPCocoaEventMouseEntered;
- else
- return false;
+ // Create the plugin event structure.
+ NPEventModel event_model = instance()->event_model();
+ scoped_ptr<PluginWebEventConverter> event_converter(
+ PluginWebEventConverterFactory::CreateConverterForModel(event_model));
+ if (!(event_converter.get() && event_converter->InitWithEvent(event)))
+ return false;
+ void* plugin_event = event_converter->plugin_event();
+
+ if (instance()->event_model() == NPEventModelCocoa) {
+ // We recieve events related to drags starting outside the plugin, but the
+ // NPAPI Cocoa event model spec says plugins shouldn't receive them, so
+ // filter them out.
+ // If we add a page capture mode at the WebKit layer (like the plugin
+ // capture mode that handles drags starting inside) this can be removed.
+ bool drag_related = EventIsRelatedToDrag(event, external_drag_buttons_);
+ external_drag_buttons_ = UpdatedDragStateFromEvent(external_drag_buttons_,
+ event);
+ if (drag_related) {
+ if (event.type == WebInputEvent::MouseUp && !external_drag_buttons_) {
+ // When an external drag ends, we need to synthesize a MouseEntered.
+ NPCocoaEvent enter_event = *(static_cast<NPCocoaEvent*>(plugin_event));
+ enter_event.type = NPCocoaEventMouseEntered;
+ NPAPI::ScopedCurrentPluginEvent event_scope(instance(), &enter_event);
+ instance()->NPP_HandleEvent(&enter_event);
}
-
- NPAPI::ScopedCurrentPluginEvent event_scope(instance(), &np_cocoa_event);
- ret = instance()->NPP_HandleEvent(&np_cocoa_event) != 0;
- break;
+ return false;
}
}
- if (WebInputEventIsWebMouseEvent(event)) {
+ // Send the plugin the event.
+ scoped_ptr<NPAPI::ScopedCurrentPluginEvent> event_scope(NULL);
+ if (instance()->event_model() == NPEventModelCocoa) {
+ event_scope.reset(new NPAPI::ScopedCurrentPluginEvent(
+ instance(), static_cast<NPCocoaEvent*>(plugin_event)));
+ }
+ bool handled = instance()->NPP_HandleEvent(plugin_event) != 0;
+
+ if (WebInputEvent::isMouseEventType(event.type)) {
// Plugins are not good about giving accurate information about whether or
// not they handled events, and other browsers on the Mac generally ignore
// the return value. We may need to expand this to other input types, but
// we'll need to be careful about things like Command-keys.
- ret = true;
+ handled = true;
}
- return ret;
+ return handled;
}
#ifndef NP_NO_CARBON
diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi
index c8f3725..ff96daa 100644
--- a/webkit/glue/webkit_glue.gypi
+++ b/webkit/glue/webkit_glue.gypi
@@ -182,6 +182,8 @@
'plugins/plugin_string_stream.cc',
'plugins/plugin_string_stream.h',
'plugins/plugin_stubs.cc',
+ 'plugins/plugin_web_event_converter_mac.h',
+ 'plugins/plugin_web_event_converter_mac.mm',
'plugins/webplugin_2d_device_delegate.h',
'plugins/webplugin_3d_device_delegate.h',
'plugins/webplugin_delegate_impl.cc',