• 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/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, regardless of state.
492      WebTouchPoint touches[touchesLengthCap];
493  
494      // Whether the event can be canceled (with preventDefault). If true then the browser
495      // must wait for an ACK for this event. If false then no ACK IPC is expected.
496      // See comment at the top for why an int is used here instead of a bool.
497      int cancelable;
498  
WebTouchEvent()499      WebTouchEvent()
500          : WebInputEvent(sizeof(WebTouchEvent))
501          , touchesLength(0)
502          , cancelable(true)
503      {
504      }
505  };
506  
507  #pragma pack(pop)
508  
509  } // namespace blink
510  
511  #endif
512