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