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 #ifndef WebInputEvent_h 32 #define WebInputEvent_h 33 34 #include "../platform/WebCommon.h" 35 #include "../platform/WebGestureDevice.h" 36 #include "../platform/WebRect.h" 37 #include "WebTouchPoint.h" 38 39 #include <string.h> 40 41 namespace blink { 42 43 // The classes defined in this file are intended to be used with 44 // WebWidget's handleInputEvent method. These event types are cross- 45 // platform and correspond closely to WebCore's Platform*Event classes. 46 // 47 // WARNING! These classes must remain PODs (plain old data). They are 48 // intended to be "serializable" by copying their raw bytes, so they must 49 // not contain any non-bit-copyable member variables! 50 // 51 // Furthermore, the class members need to be packed so they are aligned 52 // properly and don't have paddings/gaps, otherwise memory check tools 53 // like Valgrind will complain about uninitialized memory usage when 54 // transferring these classes over the wire. 55 56 #pragma pack(push, 4) 57 58 // WebInputEvent -------------------------------------------------------------- 59 60 class WebInputEvent { 61 public: 62 // When we use an input method (or an input method editor), we receive 63 // two events for a keypress. The former event is a keydown, which 64 // provides a keycode, and the latter is a textinput, which provides 65 // a character processed by an input method. (The mapping from a 66 // keycode to a character code is not trivial for non-English 67 // keyboards.) 68 // To support input methods, Safari sends keydown events to WebKit for 69 // filtering. WebKit sends filtered keydown events back to Safari, 70 // which sends them to input methods. 71 // Unfortunately, it is hard to apply this design to Chrome because of 72 // our multiprocess architecture. An input method is running in a 73 // browser process. On the other hand, WebKit is running in a renderer 74 // process. So, this design results in increasing IPC messages. 75 // To support input methods without increasing IPC messages, Chrome 76 // handles keyboard events in a browser process and send asynchronous 77 // input events (to be translated to DOM events) to a renderer 78 // process. 79 // This design is mostly the same as the one of Windows and Mac Carbon. 80 // So, for what it's worth, our Linux and Mac front-ends emulate our 81 // Windows front-end. To emulate our Windows front-end, we can share 82 // our back-end code among Windows, Linux, and Mac. 83 // TODO(hbono): Issue 18064: remove the KeyDown type since it isn't 84 // used in Chrome any longer. 85 86 enum Type { 87 Undefined = -1, 88 TypeFirst = Undefined, 89 90 // WebMouseEvent 91 MouseDown, 92 MouseTypeFirst = MouseDown, 93 MouseUp, 94 MouseMove, 95 MouseEnter, 96 MouseLeave, 97 ContextMenu, 98 MouseTypeLast = ContextMenu, 99 100 // WebMouseWheelEvent 101 MouseWheel, 102 103 // WebKeyboardEvent 104 RawKeyDown, 105 KeyboardTypeFirst = RawKeyDown, 106 KeyDown, 107 KeyUp, 108 Char, 109 KeyboardTypeLast = Char, 110 111 // WebGestureEvent 112 GestureScrollBegin, 113 GestureTypeFirst = GestureScrollBegin, 114 GestureScrollEnd, 115 GestureScrollUpdate, 116 GestureScrollUpdateWithoutPropagation, 117 GestureFlingStart, 118 GestureFlingCancel, 119 GestureShowPress, 120 GestureTap, 121 GestureTapUnconfirmed, 122 GestureTapDown, 123 GestureTapCancel, 124 GestureDoubleTap, 125 GestureTwoFingerTap, 126 GestureLongPress, 127 GestureLongTap, 128 GesturePinchBegin, 129 GesturePinchEnd, 130 GesturePinchUpdate, 131 GestureTypeLast = GesturePinchUpdate, 132 133 // WebTouchEvent 134 TouchStart, 135 TouchTypeFirst = TouchStart, 136 TouchMove, 137 TouchEnd, 138 TouchCancel, 139 TouchTypeLast = TouchCancel, 140 141 TypeLast = TouchTypeLast 142 }; 143 144 enum Modifiers { 145 // modifiers for all events: 146 ShiftKey = 1 << 0, 147 ControlKey = 1 << 1, 148 AltKey = 1 << 2, 149 MetaKey = 1 << 3, 150 151 // modifiers for keyboard events: 152 IsKeyPad = 1 << 4, 153 IsAutoRepeat = 1 << 5, 154 155 // modifiers for mouse events: 156 LeftButtonDown = 1 << 6, 157 MiddleButtonDown = 1 << 7, 158 RightButtonDown = 1 << 8, 159 160 // Toggle modifiers for all events. Danger: these are not reflected 161 // into WebCore, so round-tripping from WebInputEvent to a WebCore 162 // event and back will not preserve these flags. 163 CapsLockOn = 1 << 9, 164 NumLockOn = 1 << 10, 165 166 // Left/right modifiers for keyboard events. 167 IsLeft = 1 << 11, 168 IsRight = 1 << 12, 169 170 // Last input event to be sent for the current vsync interval. If this 171 // flag is set, the sender guarantees that no more input events will be 172 // delivered until the next vsync and the receiver can schedule 173 // rendering accordingly. If it isn't set, the receiver should not make 174 // any assumptions about the delivery times of future input events 175 // w.r.t. vsync. 176 IsLastInputEventForCurrentVSync = 1 << 13, 177 }; 178 179 static const int InputModifiers = ShiftKey | ControlKey | AltKey | MetaKey; 180 181 double timeStampSeconds; // Seconds since epoch. 182 unsigned size; // The size of this structure, for serialization. 183 Type type; 184 int modifiers; 185 186 // Returns true if the WebInputEvent |type| is a mouse event. isMouseEventType(int type)187 static bool isMouseEventType(int type) 188 { 189 return MouseTypeFirst <= type && type <= MouseTypeLast; 190 } 191 192 // Returns true if the WebInputEvent |type| is a keyboard event. isKeyboardEventType(int type)193 static bool isKeyboardEventType(int type) 194 { 195 return KeyboardTypeFirst <= type && type <= KeyboardTypeLast; 196 } 197 198 // Returns true if the WebInputEvent |type| is a touch event. isTouchEventType(int type)199 static bool isTouchEventType(int type) 200 { 201 return TouchTypeFirst <= type && type <= TouchTypeLast; 202 } 203 204 // Returns true if the WebInputEvent is a gesture event. isGestureEventType(int type)205 static bool isGestureEventType(int type) 206 { 207 return GestureTypeFirst <= type && type <= GestureTypeLast; 208 } 209 210 protected: WebInputEvent(unsigned sizeParam)211 explicit WebInputEvent(unsigned sizeParam) 212 { 213 memset(this, 0, sizeParam); 214 timeStampSeconds = 0.0; 215 size = sizeParam; 216 type = Undefined; 217 modifiers = 0; 218 } 219 }; 220 221 // WebKeyboardEvent ----------------------------------------------------------- 222 223 class WebKeyboardEvent : public WebInputEvent { 224 public: 225 // Caps on string lengths so we can make them static arrays and keep 226 // them PODs. 227 static const size_t textLengthCap = 4; 228 229 // http://www.w3.org/TR/DOM-Level-3-Events/keyset.html lists the 230 // identifiers. The longest is 18 characters, so we round up to the 231 // next multiple of 4. 232 static const size_t keyIdentifierLengthCap = 20; 233 234 // |windowsKeyCode| is the Windows key code associated with this key 235 // event. Sometimes it's direct from the event (i.e. on Windows), 236 // sometimes it's via a mapping function. If you want a list, see 237 // WebCore/platform/chromium/KeyboardCodes* . Note that this should 238 // ALWAYS store the non-locational version of a keycode as this is 239 // what is returned by the Windows API. For example, it should 240 // store VK_SHIFT instead of VK_RSHIFT. The location information 241 // should be stored in |modifiers|. 242 int windowsKeyCode; 243 244 // The actual key code genenerated by the platform. The DOM spec runs 245 // on Windows-equivalent codes (thus |windowsKeyCode| above) but it 246 // doesn't hurt to have this one around. 247 int nativeKeyCode; 248 249 // This identifies whether this event was tagged by the system as being 250 // a "system key" event (see 251 // http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx for 252 // details). Other platforms don't have this concept, but it's just 253 // easier to leave it always false than ifdef. 254 // See comment at the top of the file for why an int is used here. 255 bool isSystemKey; 256 257 // |text| is the text generated by this keystroke. |unmodifiedText| is 258 // |text|, but unmodified by an concurrently-held modifiers (except 259 // shift). This is useful for working out shortcut keys. Linux and 260 // Windows guarantee one character per event. The Mac does not, but in 261 // reality that's all it ever gives. We're generous, and cap it a bit 262 // longer. 263 WebUChar text[textLengthCap]; 264 WebUChar unmodifiedText[textLengthCap]; 265 266 // This is a string identifying the key pressed. 267 char keyIdentifier[keyIdentifierLengthCap]; 268 WebKeyboardEvent()269 WebKeyboardEvent() 270 : WebInputEvent(sizeof(WebKeyboardEvent)) 271 , windowsKeyCode(0) 272 , nativeKeyCode(0) 273 , isSystemKey(false) 274 { 275 memset(&text, 0, sizeof(text)); 276 memset(&unmodifiedText, 0, sizeof(unmodifiedText)); 277 memset(&keyIdentifier, 0, sizeof(keyIdentifier)); 278 } 279 280 // Sets keyIdentifier based on the value of windowsKeyCode. This is 281 // handy for generating synthetic keyboard events. 282 BLINK_EXPORT void setKeyIdentifierFromWindowsKeyCode(); 283 284 static int windowsKeyCodeWithoutLocation(int keycode); 285 static int locationModifiersFromWindowsKeyCode(int keycode); 286 }; 287 288 // WebMouseEvent -------------------------------------------------------------- 289 290 class WebMouseEvent : public WebInputEvent { 291 public: 292 enum Button { 293 ButtonNone = -1, 294 ButtonLeft, 295 ButtonMiddle, 296 ButtonRight 297 }; 298 299 Button button; 300 int x; 301 int y; 302 int windowX; 303 int windowY; 304 int globalX; 305 int globalY; 306 int movementX; 307 int movementY; 308 int clickCount; 309 WebMouseEvent()310 WebMouseEvent() 311 : WebInputEvent(sizeof(WebMouseEvent)) 312 , button(ButtonNone) 313 , x(0) 314 , y(0) 315 , windowX(0) 316 , windowY(0) 317 , globalX(0) 318 , globalY(0) 319 , movementX(0) 320 , movementY(0) 321 , clickCount(0) 322 { 323 } 324 325 protected: WebMouseEvent(unsigned sizeParam)326 explicit WebMouseEvent(unsigned sizeParam) 327 : WebInputEvent(sizeParam) 328 , button(ButtonNone) 329 , x(0) 330 , y(0) 331 , windowX(0) 332 , windowY(0) 333 , globalX(0) 334 , globalY(0) 335 , movementX(0) 336 , movementY(0) 337 , clickCount(0) 338 { 339 } 340 }; 341 342 // WebMouseWheelEvent --------------------------------------------------------- 343 344 class WebMouseWheelEvent : public WebMouseEvent { 345 public: 346 enum Phase { 347 PhaseNone = 0, 348 PhaseBegan = 1 << 0, 349 PhaseStationary = 1 << 1, 350 PhaseChanged = 1 << 2, 351 PhaseEnded = 1 << 3, 352 PhaseCancelled = 1 << 4, 353 PhaseMayBegin = 1 << 5, 354 }; 355 356 float deltaX; 357 float deltaY; 358 float wheelTicksX; 359 float wheelTicksY; 360 361 float accelerationRatioX; 362 float accelerationRatioY; 363 364 // See comment at the top of the file for why an int is used here. 365 int scrollByPage; 366 367 // See comment at the top of the file for why an int is used here. 368 int hasPreciseScrollingDeltas; 369 Phase phase; 370 Phase momentumPhase; 371 372 // See comment at the top of the file for why an int is used here. 373 // Rubberbanding is an OSX visual effect. When a user scrolls the content 374 // area with a track pad, and the content area is already at its limit in 375 // the direction being scrolled, the entire content area is allowed to 376 // scroll slightly off screen, revealing a grey background. When the user 377 // lets go, the content area snaps back into place. Blink is responsible 378 // for this rubberbanding effect, but the embedder may wish to disable 379 // rubber banding in the left or right direction, if the scroll should have 380 // an alternate effect. The common case is that a scroll in the left or 381 // right directions causes a back or forwards navigation, respectively. 382 // 383 // These flags prevent rubber banding from starting in a given direction, 384 // but have no effect on an ongoing rubber banding. A rubber banding that 385 // started in the vertical direction is allowed to continue in the right 386 // direction, even if canRubberbandRight is 0. 387 int canRubberbandLeft; 388 int canRubberbandRight; 389 WebMouseWheelEvent()390 WebMouseWheelEvent() 391 : WebMouseEvent(sizeof(WebMouseWheelEvent)) 392 , deltaX(0.0f) 393 , deltaY(0.0f) 394 , wheelTicksX(0.0f) 395 , wheelTicksY(0.0f) 396 , accelerationRatioX(1.0f) 397 , accelerationRatioY(1.0f) 398 , scrollByPage(false) 399 , hasPreciseScrollingDeltas(false) 400 , phase(PhaseNone) 401 , momentumPhase(PhaseNone) 402 , canRubberbandLeft(true) 403 , canRubberbandRight(true) 404 { 405 } 406 }; 407 408 // WebGestureEvent -------------------------------------------------------------- 409 410 class WebGestureEvent : public WebInputEvent { 411 public: 412 int x; 413 int y; 414 int globalX; 415 int globalY; 416 WebGestureDevice sourceDevice; 417 418 union { 419 // Tap information must be set for GestureTap, GestureTapUnconfirmed, 420 // and GestureDoubleTap events. 421 struct { 422 int tapCount; 423 float width; 424 float height; 425 } tap; 426 427 struct { 428 float width; 429 float height; 430 } tapDown; 431 432 struct { 433 float width; 434 float height; 435 } showPress; 436 437 struct { 438 float width; 439 float height; 440 } longPress; 441 442 struct { 443 float firstFingerWidth; 444 float firstFingerHeight; 445 } twoFingerTap; 446 447 struct { 448 // Initial motion that triggered the scroll. 449 // May be redundant with deltaX/deltaY in the first scrollUpdate. 450 float deltaXHint; 451 float deltaYHint; 452 } scrollBegin; 453 454 struct { 455 float deltaX; 456 float deltaY; 457 float velocityX; 458 float velocityY; 459 } scrollUpdate; 460 461 struct { 462 float velocityX; 463 float velocityY; 464 } flingStart; 465 466 struct { 467 float scale; 468 } pinchUpdate; 469 } data; 470 WebGestureEvent()471 WebGestureEvent() 472 : WebInputEvent(sizeof(WebGestureEvent)) 473 , x(0) 474 , y(0) 475 , globalX(0) 476 , globalY(0) 477 { 478 memset(&data, 0, sizeof(data)); 479 } 480 }; 481 482 // WebTouchEvent -------------------------------------------------------------- 483 484 class WebTouchEvent : public WebInputEvent { 485 public: 486 // Maximum number of simultaneous touches supported on 487 // Ash/Aura. 488 enum { touchesLengthCap = 12 }; 489 490 unsigned touchesLength; 491 // List of all touches which are currently down. 492 WebTouchPoint touches[touchesLengthCap]; 493 494 unsigned changedTouchesLength; 495 // List of all touches whose state has changed since the last WebTouchEvent 496 WebTouchPoint changedTouches[touchesLengthCap]; 497 498 unsigned targetTouchesLength; 499 // List of all touches which are currently down and are targeting the event recipient. 500 WebTouchPoint targetTouches[touchesLengthCap]; 501 502 // Whether the event can be canceled (with preventDefault). If true then the browser 503 // must wait for an ACK for this event. If false then no ACK IPC is expected. 504 // See comment at the top for why an int is used here instead of a bool. 505 int cancelable; 506 WebTouchEvent()507 WebTouchEvent() 508 : WebInputEvent(sizeof(WebTouchEvent)) 509 , touchesLength(0) 510 , changedTouchesLength(0) 511 , targetTouchesLength(0) 512 , cancelable(true) 513 { 514 } 515 }; 516 517 #pragma pack(pop) 518 519 } // namespace blink 520 521 #endif 522