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 "WebCommon.h" 35 #include "WebTouchPoint.h" 36 37 #include <string.h> 38 39 namespace WebKit { 40 41 // The classes defined in this file are intended to be used with 42 // WebWidget's handleInputEvent method. These event types are cross- 43 // platform and correspond closely to WebCore's Platform*Event classes. 44 // 45 // WARNING! These classes must remain PODs (plain old data). They are 46 // intended to be "serializable" by copying their raw bytes, so they must 47 // not contain any non-bit-copyable member variables! 48 49 // WebInputEvent -------------------------------------------------------------- 50 51 class WebInputEvent { 52 public: 53 WebInputEvent(unsigned sizeParam = sizeof(WebInputEvent)) size(sizeParam)54 : size(sizeParam) 55 , type(Undefined) 56 , modifiers(0) 57 , timeStampSeconds(0.0) { } 58 59 // When we use an input method (or an input method editor), we receive 60 // two events for a keypress. The former event is a keydown, which 61 // provides a keycode, and the latter is a textinput, which provides 62 // a character processed by an input method. (The mapping from a 63 // keycode to a character code is not trivial for non-English 64 // keyboards.) 65 // To support input methods, Safari sends keydown events to WebKit for 66 // filtering. WebKit sends filtered keydown events back to Safari, 67 // which sends them to input methods. 68 // Unfortunately, it is hard to apply this design to Chrome because of 69 // our multiprocess architecture. An input method is running in a 70 // browser process. On the other hand, WebKit is running in a renderer 71 // process. So, this design results in increasing IPC messages. 72 // To support input methods without increasing IPC messages, Chrome 73 // handles keyboard events in a browser process and send asynchronous 74 // input events (to be translated to DOM events) to a renderer 75 // process. 76 // This design is mostly the same as the one of Windows and Mac Carbon. 77 // So, for what it's worth, our Linux and Mac front-ends emulate our 78 // Windows front-end. To emulate our Windows front-end, we can share 79 // our back-end code among Windows, Linux, and Mac. 80 // TODO(hbono): Issue 18064: remove the KeyDown type since it isn't 81 // used in Chrome any longer. 82 83 enum Type { 84 Undefined = -1, 85 86 // WebMouseEvent 87 MouseDown, 88 MouseUp, 89 MouseMove, 90 MouseEnter, 91 MouseLeave, 92 ContextMenu, 93 94 // WebMouseWheelEvent 95 MouseWheel, 96 97 // WebKeyboardEvent 98 RawKeyDown, 99 KeyDown, 100 KeyUp, 101 Char, 102 103 // WebTouchEvent 104 TouchStart, 105 TouchMove, 106 TouchEnd, 107 TouchCancel, 108 }; 109 110 enum Modifiers { 111 // modifiers for all events: 112 ShiftKey = 1 << 0, 113 ControlKey = 1 << 1, 114 AltKey = 1 << 2, 115 MetaKey = 1 << 3, 116 117 // modifiers for keyboard events: 118 IsKeyPad = 1 << 4, 119 IsAutoRepeat = 1 << 5, 120 121 // modifiers for mouse events: 122 LeftButtonDown = 1 << 6, 123 MiddleButtonDown = 1 << 7, 124 RightButtonDown = 1 << 8, 125 126 // Toggle modifiers for all events. Danger: these are not reflected 127 // into WebCore, so round-tripping from WebInputEvent to a WebCore 128 // event and back will not preserve these flags. 129 CapsLockOn = 1 << 9, 130 NumLockOn = 1 << 10, 131 }; 132 133 static const int InputModifiers = ShiftKey | ControlKey | AltKey | MetaKey; 134 135 unsigned size; // The size of this structure, for serialization. 136 Type type; 137 int modifiers; 138 double timeStampSeconds; // Seconds since epoch. 139 140 // Returns true if the WebInputEvent |type| is a mouse event. isMouseEventType(int type)141 static bool isMouseEventType(int type) 142 { 143 return type == MouseDown 144 || type == MouseUp 145 || type == MouseMove 146 || type == MouseEnter 147 || type == MouseLeave 148 || type == ContextMenu; 149 } 150 151 // Returns true if the WebInputEvent |type| is a keyboard event. isKeyboardEventType(int type)152 static bool isKeyboardEventType(int type) 153 { 154 return type == RawKeyDown 155 || type == KeyDown 156 || type == KeyUp 157 || type == Char; 158 } 159 160 // Returns true if the WebInputEvent |type| is a touch event. isTouchEventType(int type)161 static bool isTouchEventType(int type) 162 { 163 return type == TouchStart 164 || type == TouchMove 165 || type == TouchEnd 166 || type == TouchCancel; 167 } 168 169 // Returns true if the WebInputEvent |type| should be handled as user gesture. isUserGestureEventType(int type)170 static bool isUserGestureEventType(int type) 171 { 172 return isKeyboardEventType(type) 173 || type == MouseDown 174 || type == MouseUp 175 || type == TouchStart 176 || type == TouchEnd; 177 } 178 }; 179 180 // WebKeyboardEvent ----------------------------------------------------------- 181 182 class WebKeyboardEvent : public WebInputEvent { 183 public: 184 // Caps on string lengths so we can make them static arrays and keep 185 // them PODs. 186 static const size_t textLengthCap = 4; 187 188 // http://www.w3.org/TR/DOM-Level-3-Events/keyset.html lists the 189 // identifiers. The longest is 18 characters, so we round up to the 190 // next multiple of 4. 191 static const size_t keyIdentifierLengthCap = 20; 192 193 // |windowsKeyCode| is the Windows key code associated with this key 194 // event. Sometimes it's direct from the event (i.e. on Windows), 195 // sometimes it's via a mapping function. If you want a list, see 196 // WebCore/platform/chromium/KeyboardCodes* . 197 int windowsKeyCode; 198 199 // The actual key code genenerated by the platform. The DOM spec runs 200 // on Windows-equivalent codes (thus |windowsKeyCode| above) but it 201 // doesn't hurt to have this one around. 202 int nativeKeyCode; 203 204 // |text| is the text generated by this keystroke. |unmodifiedText| is 205 // |text|, but unmodified by an concurrently-held modifiers (except 206 // shift). This is useful for working out shortcut keys. Linux and 207 // Windows guarantee one character per event. The Mac does not, but in 208 // reality that's all it ever gives. We're generous, and cap it a bit 209 // longer. 210 WebUChar text[textLengthCap]; 211 WebUChar unmodifiedText[textLengthCap]; 212 213 // This is a string identifying the key pressed. 214 char keyIdentifier[keyIdentifierLengthCap]; 215 216 // This identifies whether this event was tagged by the system as being 217 // a "system key" event (see 218 // http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx for 219 // details). Other platforms don't have this concept, but it's just 220 // easier to leave it always false than ifdef. 221 // int is used instead of bool to ensure the size of this structure is 222 // strictly aligned to a factor of 4 bytes, otherwise memory check tools 223 // like valgrind may complain about uninitialized memory usage when 224 // transfering it over the wire. 225 int isSystemKey; 226 227 WebKeyboardEvent(unsigned sizeParam = sizeof(WebKeyboardEvent)) WebInputEvent(sizeParam)228 : WebInputEvent(sizeParam) 229 , windowsKeyCode(0) 230 , nativeKeyCode(0) 231 , isSystemKey(false) 232 { 233 memset(&text, 0, sizeof(text)); 234 memset(&unmodifiedText, 0, sizeof(unmodifiedText)); 235 memset(&keyIdentifier, 0, sizeof(keyIdentifier)); 236 } 237 238 // Sets keyIdentifier based on the value of windowsKeyCode. This is 239 // handy for generating synthetic keyboard events. 240 WEBKIT_API void setKeyIdentifierFromWindowsKeyCode(); 241 }; 242 243 // WebMouseEvent -------------------------------------------------------------- 244 245 class WebMouseEvent : public WebInputEvent { 246 public: 247 // These values defined for WebCore::MouseButton 248 enum Button { 249 ButtonNone = -1, 250 ButtonLeft, 251 ButtonMiddle, 252 ButtonRight 253 }; 254 255 Button button; 256 int x; 257 int y; 258 int windowX; 259 int windowY; 260 int globalX; 261 int globalY; 262 int clickCount; 263 264 WebMouseEvent(unsigned sizeParam = sizeof(WebMouseEvent)) WebInputEvent(sizeParam)265 : WebInputEvent(sizeParam) 266 , button(ButtonNone) 267 , x(0) 268 , y(0) 269 , windowX(0) 270 , windowY(0) 271 , globalX(0) 272 , globalY(0) 273 , clickCount(0) 274 { 275 } 276 }; 277 278 // WebMouseWheelEvent --------------------------------------------------------- 279 280 class WebMouseWheelEvent : public WebMouseEvent { 281 public: 282 float deltaX; 283 float deltaY; 284 float wheelTicksX; 285 float wheelTicksY; 286 287 // int is used instead of bool to ensure the size of this structure is 288 // strictly aligned to a factor of 4 bytes, otherwise memory check tools 289 // like valgrind may complain about uninitialized memory usage when 290 // transfering it over the wire. 291 int scrollByPage; 292 293 WebMouseWheelEvent(unsigned sizeParam = sizeof(WebMouseWheelEvent)) WebMouseEvent(sizeParam)294 : WebMouseEvent(sizeParam) 295 , deltaX(0.0f) 296 , deltaY(0.0f) 297 , wheelTicksX(0.0f) 298 , wheelTicksY(0.0f) 299 , scrollByPage(false) 300 { 301 } 302 }; 303 304 // WebTouchEvent -------------------------------------------------------------- 305 306 class WebTouchEvent : public WebInputEvent { 307 public: 308 static const int touchPointsLengthCap = 4; 309 310 int touchPointsLength; 311 WebTouchPoint touchPoints[touchPointsLengthCap]; 312 313 WebTouchEvent(unsigned sizeParam = sizeof(WebTouchEvent)) WebInputEvent(sizeParam)314 : WebInputEvent(sizeParam) 315 , touchPointsLength(0) 316 { 317 } 318 }; 319 320 } // namespace WebKit 321 322 #endif 323