1 /* 2 * Copyright (C) 2009 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "WebInputEventConversion.h" 33 34 #include "EventNames.h" 35 #include "KeyboardCodes.h" 36 #include "KeyboardEvent.h" 37 #include "MouseEvent.h" 38 #include "PlatformKeyboardEvent.h" 39 #include "PlatformMouseEvent.h" 40 #include "PlatformWheelEvent.h" 41 #include "ScrollView.h" 42 #include "WebInputEvent.h" 43 #include "Widget.h" 44 45 using namespace WebCore; 46 47 namespace WebKit { 48 49 // MakePlatformMouseEvent ----------------------------------------------------- 50 51 PlatformMouseEventBuilder::PlatformMouseEventBuilder(Widget* widget, const WebMouseEvent& e) 52 { 53 // FIXME: widget is always toplevel, unless it's a popup. We may be able 54 // to get rid of this once we abstract popups into a WebKit API. 55 m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y)); 56 m_globalPosition = IntPoint(e.globalX, e.globalY); 57 m_button = static_cast<MouseButton>(e.button); 58 m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey); 59 m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey); 60 m_altKey = (e.modifiers & WebInputEvent::AltKey); 61 m_metaKey = (e.modifiers & WebInputEvent::MetaKey); 62 m_modifierFlags = e.modifiers; 63 m_timestamp = e.timeStampSeconds; 64 m_clickCount = e.clickCount; 65 66 switch (e.type) { 67 case WebInputEvent::MouseMove: 68 case WebInputEvent::MouseLeave: // synthesize a move event 69 m_eventType = MouseEventMoved; 70 break; 71 72 case WebInputEvent::MouseDown: 73 m_eventType = MouseEventPressed; 74 break; 75 76 case WebInputEvent::MouseUp: 77 m_eventType = MouseEventReleased; 78 break; 79 80 default: 81 ASSERT_NOT_REACHED(); 82 } 83 } 84 85 // PlatformWheelEventBuilder -------------------------------------------------- 86 87 PlatformWheelEventBuilder::PlatformWheelEventBuilder(Widget* widget, const WebMouseWheelEvent& e) 88 { 89 m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y)); 90 m_globalPosition = IntPoint(e.globalX, e.globalY); 91 m_deltaX = e.deltaX; 92 m_deltaY = e.deltaY; 93 m_wheelTicksX = e.wheelTicksX; 94 m_wheelTicksY = e.wheelTicksY; 95 m_isAccepted = false; 96 m_granularity = e.scrollByPage ? 97 ScrollByPageWheelEvent : ScrollByPixelWheelEvent; 98 m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey); 99 m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey); 100 m_altKey = (e.modifiers & WebInputEvent::AltKey); 101 m_metaKey = (e.modifiers & WebInputEvent::MetaKey); 102 } 103 104 // MakePlatformKeyboardEvent -------------------------------------------------- 105 106 static inline const PlatformKeyboardEvent::Type toPlatformKeyboardEventType(WebInputEvent::Type type) 107 { 108 switch (type) { 109 case WebInputEvent::KeyUp: 110 return PlatformKeyboardEvent::KeyUp; 111 case WebInputEvent::KeyDown: 112 return PlatformKeyboardEvent::KeyDown; 113 case WebInputEvent::RawKeyDown: 114 return PlatformKeyboardEvent::RawKeyDown; 115 case WebInputEvent::Char: 116 return PlatformKeyboardEvent::Char; 117 default: 118 ASSERT_NOT_REACHED(); 119 } 120 return PlatformKeyboardEvent::KeyDown; 121 } 122 123 PlatformKeyboardEventBuilder::PlatformKeyboardEventBuilder(const WebKeyboardEvent& e) 124 { 125 m_type = toPlatformKeyboardEventType(e.type); 126 m_text = String(e.text); 127 m_unmodifiedText = String(e.unmodifiedText); 128 m_keyIdentifier = String(e.keyIdentifier); 129 m_autoRepeat = (e.modifiers & WebInputEvent::IsAutoRepeat); 130 m_windowsVirtualKeyCode = e.windowsKeyCode; 131 m_nativeVirtualKeyCode = e.nativeKeyCode; 132 m_isKeypad = (e.modifiers & WebInputEvent::IsKeyPad); 133 m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey); 134 m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey); 135 m_altKey = (e.modifiers & WebInputEvent::AltKey); 136 m_metaKey = (e.modifiers & WebInputEvent::MetaKey); 137 m_isSystemKey = e.isSystemKey; 138 } 139 140 void PlatformKeyboardEventBuilder::setKeyType(Type type) 141 { 142 // According to the behavior of Webkit in Windows platform, 143 // we need to convert KeyDown to RawKeydown and Char events 144 // See WebKit/WebKit/Win/WebView.cpp 145 ASSERT(m_type == KeyDown); 146 ASSERT(type == RawKeyDown || type == Char); 147 m_type = type; 148 149 if (type == RawKeyDown) { 150 m_text = String(); 151 m_unmodifiedText = String(); 152 } else { 153 m_keyIdentifier = String(); 154 m_windowsVirtualKeyCode = 0; 155 } 156 } 157 158 // Please refer to bug http://b/issue?id=961192, which talks about Webkit 159 // keyboard event handling changes. It also mentions the list of keys 160 // which don't have associated character events. 161 bool PlatformKeyboardEventBuilder::isCharacterKey() const 162 { 163 switch (windowsVirtualKeyCode()) { 164 case VKEY_BACK: 165 case VKEY_ESCAPE: 166 return false; 167 } 168 return true; 169 } 170 171 static int getWebInputModifiers(const UIEventWithKeyState& event) 172 { 173 int modifiers = 0; 174 if (event.ctrlKey()) 175 modifiers |= WebInputEvent::ControlKey; 176 if (event.shiftKey()) 177 modifiers |= WebInputEvent::ShiftKey; 178 if (event.altKey()) 179 modifiers |= WebInputEvent::AltKey; 180 if (event.metaKey()) 181 modifiers |= WebInputEvent::MetaKey; 182 return modifiers; 183 } 184 185 WebMouseEventBuilder::WebMouseEventBuilder(const ScrollView* view, const MouseEvent& event) 186 { 187 if (event.type() == eventNames().mousemoveEvent) 188 type = WebInputEvent::MouseMove; 189 else if (event.type() == eventNames().mouseoutEvent) 190 type = WebInputEvent::MouseLeave; 191 else if (event.type() == eventNames().mouseoverEvent) 192 type = WebInputEvent::MouseEnter; 193 else if (event.type() == eventNames().mousedownEvent) 194 type = WebInputEvent::MouseDown; 195 else if (event.type() == eventNames().mouseupEvent) 196 type = WebInputEvent::MouseUp; 197 else 198 return; // Skip all other mouse events. 199 timeStampSeconds = event.timeStamp() * 1.0e-3; 200 switch (event.button()) { 201 case LeftButton: 202 button = WebMouseEvent::ButtonLeft; 203 break; 204 case MiddleButton: 205 button = WebMouseEvent::ButtonMiddle; 206 break; 207 case RightButton: 208 button = WebMouseEvent::ButtonRight; 209 break; 210 } 211 modifiers = getWebInputModifiers(event); 212 if (event.buttonDown()) { 213 switch (event.button()) { 214 case LeftButton: 215 modifiers |= WebInputEvent::LeftButtonDown; 216 break; 217 case MiddleButton: 218 modifiers |= WebInputEvent::MiddleButtonDown; 219 break; 220 case RightButton: 221 modifiers |= WebInputEvent::RightButtonDown; 222 break; 223 } 224 } 225 IntPoint p = view->contentsToWindow(IntPoint(event.pageX(), event.pageY())); 226 globalX = event.screenX(); 227 globalY = event.screenY(); 228 windowX = p.x(); 229 windowY = p.y(); 230 x = event.offsetX(); 231 y = event.offsetY(); 232 clickCount = event.detail(); 233 } 234 235 WebKeyboardEventBuilder::WebKeyboardEventBuilder(const KeyboardEvent& event) 236 { 237 if (event.type() == eventNames().keydownEvent) 238 type = KeyDown; 239 else if (event.type() == eventNames().keyupEvent) 240 type = WebInputEvent::KeyUp; 241 else if (event.type() == eventNames().keypressEvent) 242 type = WebInputEvent::Char; 243 else 244 return; // Skip all other keyboard events. 245 modifiers = getWebInputModifiers(event); 246 timeStampSeconds = event.timeStamp() * 1.0e-3; 247 windowsKeyCode = event.keyCode(); 248 nativeKeyCode = event.keyEvent()->nativeVirtualKeyCode(); 249 unsigned int numChars = std::min(event.keyEvent()->text().length(), 250 static_cast<unsigned int>(WebKeyboardEvent::textLengthCap)); 251 for (unsigned int i = 0; i < numChars; i++) { 252 text[i] = event.keyEvent()->text()[i]; 253 unmodifiedText[i] = event.keyEvent()->unmodifiedText()[i]; 254 } 255 } 256 257 } // namespace WebKit 258