// Copyright (c) 2006-2008 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. #include "config.h" #include "webkit/glue/event_conversion.h" #include "EventNames.h" #include "FrameView.h" #include "KeyboardCodes.h" #include "KeyboardEvent.h" #include "MouseEvent.h" #include "StringImpl.h" // This is so that the KJS build works #include "PlatformKeyboardEvent.h" #include "PlatformMouseEvent.h" #include "PlatformWheelEvent.h" #include "Widget.h" #undef LOG #include "base/gfx/point.h" #include "base/logging.h" #include "webkit/api/public/WebInputEvent.h" #include "webkit/api/public/WebKit.h" #include "webkit/glue/glue_util.h" #include "webkit/glue/webkit_glue.h" using namespace WebCore; using WebKit::WebInputEvent; using WebKit::WebKeyboardEvent; using WebKit::WebMouseEvent; using WebKit::WebMouseWheelEvent; // MakePlatformMouseEvent ----------------------------------------------------- MakePlatformMouseEvent::MakePlatformMouseEvent(Widget* widget, const WebMouseEvent& e) { // TODO(mpcomplete): widget is always toplevel, unless it's a popup. We // may be able to get rid of this once we abstract popups into a WebKit API. m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y)); m_globalPosition = IntPoint(e.globalX, e.globalY); m_button = static_cast(e.button); m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey) != 0; m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey) != 0; m_altKey = (e.modifiers & WebInputEvent::AltKey) != 0; m_metaKey = (e.modifiers & WebInputEvent::MetaKey) != 0; m_modifierFlags = e.modifiers; m_timestamp = e.timeStampSeconds; m_clickCount = e.clickCount; switch (e.type) { case WebInputEvent::MouseMove: case WebInputEvent::MouseLeave: // synthesize a move event m_eventType = MouseEventMoved; break; case WebInputEvent::MouseDown: m_eventType = MouseEventPressed; break; case WebInputEvent::MouseUp: m_eventType = MouseEventReleased; break; default: NOTREACHED() << "unexpected mouse event type"; } } // MakePlatformWheelEvent ----------------------------------------------------- MakePlatformWheelEvent::MakePlatformWheelEvent(Widget* widget, const WebMouseWheelEvent& e) { m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y)); m_globalPosition = IntPoint(e.globalX, e.globalY); m_deltaX = e.deltaX; m_deltaY = e.deltaY; m_wheelTicksX = e.wheelTicksX; m_wheelTicksY = e.wheelTicksY; m_isAccepted = false; m_granularity = e.scrollByPage ? ScrollByPageWheelEvent : ScrollByPixelWheelEvent; m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey) != 0; m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey) != 0; m_altKey = (e.modifiers & WebInputEvent::AltKey) != 0; m_metaKey = (e.modifiers & WebInputEvent::MetaKey) != 0; } // MakePlatformKeyboardEvent -------------------------------------------------- static inline const PlatformKeyboardEvent::Type ToPlatformKeyboardEventType( WebInputEvent::Type type) { switch (type) { case WebInputEvent::KeyUp: return PlatformKeyboardEvent::KeyUp; case WebInputEvent::KeyDown: return PlatformKeyboardEvent::KeyDown; case WebInputEvent::RawKeyDown: return PlatformKeyboardEvent::RawKeyDown; case WebInputEvent::Char: return PlatformKeyboardEvent::Char; default: ASSERT_NOT_REACHED(); } return PlatformKeyboardEvent::KeyDown; } MakePlatformKeyboardEvent::MakePlatformKeyboardEvent( const WebKeyboardEvent& e) { m_type = ToPlatformKeyboardEventType(e.type); m_text = WebCore::String(e.text); m_unmodifiedText = WebCore::String(e.unmodifiedText); m_keyIdentifier = WebCore::String(e.keyIdentifier); m_autoRepeat = (e.modifiers & WebInputEvent::IsAutoRepeat) != 0; m_windowsVirtualKeyCode = e.windowsKeyCode; m_nativeVirtualKeyCode = e.nativeKeyCode; m_isKeypad = (e.modifiers & WebInputEvent::IsKeyPad) != 0; m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey) != 0; m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey) != 0; m_altKey = (e.modifiers & WebInputEvent::AltKey) != 0; m_metaKey = (e.modifiers & WebInputEvent::MetaKey) != 0; m_isSystemKey = e.isSystemKey; } void MakePlatformKeyboardEvent::SetKeyType(Type type) { // According to the behavior of Webkit in Windows platform, // we need to convert KeyDown to RawKeydown and Char events // See WebKit/WebKit/Win/WebView.cpp ASSERT(m_type == KeyDown); ASSERT(type == RawKeyDown || type == Char); m_type = type; if (type == RawKeyDown) { m_text = String(); m_unmodifiedText = String(); } else { m_keyIdentifier = String(); m_windowsVirtualKeyCode = 0; } } // Please refer to bug http://b/issue?id=961192, which talks about Webkit // keyboard event handling changes. It also mentions the list of keys // which don't have associated character events. bool MakePlatformKeyboardEvent::IsCharacterKey() const { switch (windowsVirtualKeyCode()) { case VKEY_BACK: case VKEY_ESCAPE: return false; default: break; } return true; } static int GetWebInputModifiers(const WebCore::UIEventWithKeyState& event) { int modifiers = 0; if (event.ctrlKey()) modifiers |= WebInputEvent::ControlKey; if (event.shiftKey()) modifiers |= WebInputEvent::ShiftKey; if (event.altKey()) modifiers |= WebInputEvent::AltKey; if (event.metaKey()) modifiers |= WebInputEvent::MetaKey; return modifiers; } bool ToWebMouseEvent(const WebCore::FrameView& view, const WebCore::MouseEvent& event, WebKit::WebMouseEvent* web_event) { if (event.type() == WebCore::eventNames().mousemoveEvent) { web_event->type = WebInputEvent::MouseMove; } else if (event.type() == WebCore::eventNames().mouseoutEvent) { web_event->type = WebInputEvent::MouseLeave; } else if (event.type() == WebCore::eventNames().mouseoverEvent) { web_event->type = WebInputEvent::MouseEnter; } else if (event.type() == WebCore::eventNames().mousedownEvent) { web_event->type = WebInputEvent::MouseDown; } else if (event.type() == WebCore::eventNames().mouseupEvent) { web_event->type = WebInputEvent::MouseUp; } else { // Skip all other mouse events. return false; } web_event->timeStampSeconds = event.timeStamp() * 1.0e-3; switch (event.button()) { case WebCore::LeftButton: web_event->button = WebMouseEvent::ButtonLeft; break; case WebCore::MiddleButton: web_event->button = WebMouseEvent::ButtonMiddle; break; case WebCore::RightButton: web_event->button = WebMouseEvent::ButtonRight; break; } web_event->modifiers = GetWebInputModifiers(event); if (event.buttonDown()) { switch (event.button()) { case WebCore::LeftButton: web_event->modifiers |= WebInputEvent::LeftButtonDown; break; case WebCore::MiddleButton: web_event->modifiers |= WebInputEvent::MiddleButtonDown; break; case WebCore::RightButton: web_event->modifiers |= WebInputEvent::RightButtonDown; break; } } WebCore::IntPoint p = view.contentsToWindow(WebCore::IntPoint(event.pageX(), event.pageY())); web_event->globalX = event.screenX(); web_event->globalY = event.screenY(); web_event->windowX = p.x(); web_event->windowY = p.y(); web_event->x = event.offsetX(); web_event->y = event.offsetY(); return true; } bool ToWebKeyboardEvent(const WebCore::KeyboardEvent& event, WebKeyboardEvent* web_event) { if (event.type() == WebCore::eventNames().keydownEvent) { web_event->type = WebInputEvent::KeyDown; } else if (event.type() == WebCore::eventNames().keyupEvent) { web_event->type = WebInputEvent::KeyUp; } else { // Skip all other keyboard events. return false; } web_event->modifiers = GetWebInputModifiers(event); web_event->timeStampSeconds = event.timeStamp() * 1.0e-3; web_event->windowsKeyCode = event.keyCode(); web_event->nativeKeyCode = event.keyEvent()->nativeVirtualKeyCode(); return true; }