Home | History | Annotate | Download | only in web
      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 WebKit {
     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         GestureTap,
    122         GestureTapUnconfirmed,
    123         GestureTapDown,
    124         GestureTapCancel,
    125         GestureDoubleTap,
    126         GestureTwoFingerTap,
    127         GestureLongPress,
    128         GestureLongTap,
    129         GesturePinchBegin,
    130         GesturePinchEnd,
    131         GesturePinchUpdate,
    132 
    133         // WebTouchEvent
    134         TouchStart,
    135         TouchMove,
    136         TouchEnd,
    137         TouchCancel,
    138     };
    139 
    140     enum Modifiers {
    141         // modifiers for all events:
    142         ShiftKey         = 1 << 0,
    143         ControlKey       = 1 << 1,
    144         AltKey           = 1 << 2,
    145         MetaKey          = 1 << 3,
    146 
    147         // modifiers for keyboard events:
    148         IsKeyPad         = 1 << 4,
    149         IsAutoRepeat     = 1 << 5,
    150 
    151         // modifiers for mouse events:
    152         LeftButtonDown   = 1 << 6,
    153         MiddleButtonDown = 1 << 7,
    154         RightButtonDown  = 1 << 8,
    155 
    156         // Toggle modifiers for all events. Danger: these are not reflected
    157         // into WebCore, so round-tripping from WebInputEvent to a WebCore
    158         // event and back will not preserve these flags.
    159         CapsLockOn       = 1 << 9,
    160         NumLockOn        = 1 << 10,
    161 
    162         // Left/right modifiers for keyboard events.
    163         IsLeft           = 1 << 11,
    164         IsRight          = 1 << 12,
    165 
    166         // Last input event to be sent for the current vsync interval. If this
    167         // flag is set, the sender guarantees that no more input events will be
    168         // delivered until the next vsync and the receiver can schedule
    169         // rendering accordingly. If it isn't set, the receiver should not make
    170         // any assumptions about the delivery times of future input events
    171         // w.r.t. vsync.
    172         IsLastInputEventForCurrentVSync = 1 << 13,
    173     };
    174 
    175     static const int InputModifiers = ShiftKey | ControlKey | AltKey | MetaKey;
    176 
    177     double timeStampSeconds; // Seconds since epoch.
    178     unsigned size; // The size of this structure, for serialization.
    179     Type type;
    180     int modifiers;
    181 
    182     // Returns true if the WebInputEvent |type| is a mouse event.
    183     static bool isMouseEventType(int type)
    184     {
    185         return type == MouseDown
    186             || type == MouseUp
    187             || type == MouseMove
    188             || type == MouseEnter
    189             || type == MouseLeave
    190             || type == ContextMenu;
    191     }
    192 
    193     // Returns true if the WebInputEvent |type| is a keyboard event.
    194     static bool isKeyboardEventType(int type)
    195     {
    196         return type == RawKeyDown
    197             || type == KeyDown
    198             || type == KeyUp
    199             || type == Char;
    200     }
    201 
    202     // Returns true if the WebInputEvent |type| is a touch event.
    203     static bool isTouchEventType(int type)
    204     {
    205         return type == TouchStart
    206             || type == TouchMove
    207             || type == TouchEnd
    208             || type == TouchCancel;
    209     }
    210 
    211     // Returns true if the WebInputEvent |type| should be handled as user gesture.
    212     static bool isUserGestureEventType(int type)
    213     {
    214         return isKeyboardEventType(type)
    215             || type == MouseDown
    216             || type == MouseUp
    217             || type == TouchStart
    218             || type == TouchEnd;
    219     }
    220 
    221     // Returns true if the WebInputEvent is a gesture event.
    222     static bool isGestureEventType(int type)
    223     {
    224         return type == GestureScrollBegin
    225             || type == GestureScrollEnd
    226             || type == GestureScrollUpdate
    227             || type == GestureScrollUpdateWithoutPropagation
    228             || type == GestureFlingStart
    229             || type == GestureFlingCancel
    230             || type == GesturePinchBegin
    231             || type == GesturePinchEnd
    232             || type == GesturePinchUpdate
    233             || type == GestureTap
    234             || type == GestureTapUnconfirmed
    235             || type == GestureTapDown
    236             || type == GestureTapCancel
    237             || type == GestureDoubleTap
    238             || type == GestureTwoFingerTap
    239             || type == GestureLongPress
    240             || type == GestureLongTap;
    241     }
    242 };
    243 
    244 // WebKeyboardEvent -----------------------------------------------------------
    245 
    246 class WebKeyboardEvent : public WebInputEvent {
    247 public:
    248     // Caps on string lengths so we can make them static arrays and keep
    249     // them PODs.
    250     static const size_t textLengthCap = 4;
    251 
    252     // http://www.w3.org/TR/DOM-Level-3-Events/keyset.html lists the
    253     // identifiers.  The longest is 18 characters, so we round up to the
    254     // next multiple of 4.
    255     static const size_t keyIdentifierLengthCap = 20;
    256 
    257     // |windowsKeyCode| is the Windows key code associated with this key
    258     // event.  Sometimes it's direct from the event (i.e. on Windows),
    259     // sometimes it's via a mapping function.  If you want a list, see
    260     // WebCore/platform/chromium/KeyboardCodes* . Note that this should
    261     // ALWAYS store the non-locational version of a keycode as this is
    262     // what is returned by the Windows API. For example, it should
    263     // store VK_SHIFT instead of VK_RSHIFT. The location information
    264     // should be stored in |modifiers|.
    265     int windowsKeyCode;
    266 
    267     // The actual key code genenerated by the platform.  The DOM spec runs
    268     // on Windows-equivalent codes (thus |windowsKeyCode| above) but it
    269     // doesn't hurt to have this one around.
    270     int nativeKeyCode;
    271 
    272     // This identifies whether this event was tagged by the system as being
    273     // a "system key" event (see
    274     // http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx for
    275     // details). Other platforms don't have this concept, but it's just
    276     // easier to leave it always false than ifdef.
    277     // See comment at the top of the file for why an int is used here.
    278     bool isSystemKey;
    279 
    280     // |text| is the text generated by this keystroke.  |unmodifiedText| is
    281     // |text|, but unmodified by an concurrently-held modifiers (except
    282     // shift).  This is useful for working out shortcut keys.  Linux and
    283     // Windows guarantee one character per event.  The Mac does not, but in
    284     // reality that's all it ever gives.  We're generous, and cap it a bit
    285     // longer.
    286     WebUChar text[textLengthCap];
    287     WebUChar unmodifiedText[textLengthCap];
    288 
    289     // This is a string identifying the key pressed.
    290     char keyIdentifier[keyIdentifierLengthCap];
    291 
    292     WebKeyboardEvent(unsigned sizeParam = sizeof(WebKeyboardEvent))
    293         : WebInputEvent(sizeParam)
    294         , windowsKeyCode(0)
    295         , nativeKeyCode(0)
    296         , isSystemKey(false)
    297     {
    298         memset(&text, 0, sizeof(text));
    299         memset(&unmodifiedText, 0, sizeof(unmodifiedText));
    300         memset(&keyIdentifier, 0, sizeof(keyIdentifier));
    301     }
    302 
    303     // Sets keyIdentifier based on the value of windowsKeyCode.  This is
    304     // handy for generating synthetic keyboard events.
    305     WEBKIT_EXPORT void setKeyIdentifierFromWindowsKeyCode();
    306 
    307     static int windowsKeyCodeWithoutLocation(int keycode);
    308     static int locationModifiersFromWindowsKeyCode(int keycode);
    309 };
    310 
    311 // WebMouseEvent --------------------------------------------------------------
    312 
    313 class WebMouseEvent : public WebInputEvent {
    314 public:
    315     // These values defined for WebCore::MouseButton
    316     enum Button {
    317         ButtonNone = -1,
    318         ButtonLeft,
    319         ButtonMiddle,
    320         ButtonRight
    321     };
    322 
    323     Button button;
    324     int x;
    325     int y;
    326     int windowX;
    327     int windowY;
    328     int globalX;
    329     int globalY;
    330     int movementX;
    331     int movementY;
    332     int clickCount;
    333 
    334     WebMouseEvent(unsigned sizeParam = sizeof(WebMouseEvent))
    335         : WebInputEvent(sizeParam)
    336         , button(ButtonNone)
    337         , x(0)
    338         , y(0)
    339         , windowX(0)
    340         , windowY(0)
    341         , globalX(0)
    342         , globalY(0)
    343         , movementX(0)
    344         , movementY(0)
    345         , clickCount(0)
    346     {
    347     }
    348 };
    349 
    350 // WebMouseWheelEvent ---------------------------------------------------------
    351 
    352 class WebMouseWheelEvent : public WebMouseEvent {
    353 public:
    354     enum Phase {
    355         PhaseNone        = 0,
    356         PhaseBegan       = 1 << 0,
    357         PhaseStationary  = 1 << 1,
    358         PhaseChanged     = 1 << 2,
    359         PhaseEnded       = 1 << 3,
    360         PhaseCancelled   = 1 << 4,
    361         PhaseMayBegin    = 1 << 5,
    362     };
    363 
    364     float deltaX;
    365     float deltaY;
    366     float wheelTicksX;
    367     float wheelTicksY;
    368 
    369     float accelerationRatioX;
    370     float accelerationRatioY;
    371 
    372     // See comment at the top of the file for why an int is used here.
    373     int scrollByPage;
    374 
    375     // See comment at the top of the file for why an int is used here.
    376     int hasPreciseScrollingDeltas;
    377     Phase phase;
    378     Phase momentumPhase;
    379 
    380     WebMouseWheelEvent(unsigned sizeParam = sizeof(WebMouseWheelEvent))
    381         : WebMouseEvent(sizeParam)
    382         , deltaX(0.0f)
    383         , deltaY(0.0f)
    384         , wheelTicksX(0.0f)
    385         , wheelTicksY(0.0f)
    386         , accelerationRatioX(1.0f)
    387         , accelerationRatioY(1.0f)
    388         , scrollByPage(false)
    389         , hasPreciseScrollingDeltas(false)
    390         , phase(PhaseNone)
    391         , momentumPhase(PhaseNone)
    392     {
    393     }
    394 };
    395 
    396 // WebGestureEvent --------------------------------------------------------------
    397 
    398 class WebGestureEvent : public WebInputEvent {
    399 public:
    400     enum SourceDevice {
    401         Touchpad,
    402         Touchscreen,
    403     };
    404 
    405     int x;
    406     int y;
    407     int globalX;
    408     int globalY;
    409     SourceDevice sourceDevice;
    410 
    411     union {
    412         struct {
    413             int tapCount;
    414             float width;
    415             float height;
    416         } tap;
    417 
    418         struct {
    419             float width;
    420             float height;
    421         } tapDown;
    422 
    423         struct {
    424             float width;
    425             float height;
    426         } longPress;
    427 
    428         struct {
    429             float firstFingerWidth;
    430             float firstFingerHeight;
    431         } twoFingerTap;
    432 
    433         struct {
    434             float deltaX;
    435             float deltaY;
    436             float velocityX;
    437             float velocityY;
    438         } scrollUpdate;
    439 
    440         struct {
    441             float velocityX;
    442             float velocityY;
    443         } flingStart;
    444 
    445         struct {
    446             float scale;
    447         } pinchUpdate;
    448     } data;
    449 
    450     WebGestureEvent(unsigned sizeParam = sizeof(WebGestureEvent))
    451         : WebInputEvent(sizeParam)
    452         , x(0)
    453         , y(0)
    454         , globalX(0)
    455         , globalY(0)
    456     {
    457         memset(&data, 0, sizeof(data));
    458     }
    459 };
    460 
    461 // WebTouchEvent --------------------------------------------------------------
    462 
    463 class WebTouchEvent : public WebInputEvent {
    464 public:
    465     // Maximum number of simultaneous touches supported on
    466     // Ash/Aura.
    467     enum { touchesLengthCap = 12 };
    468 
    469     unsigned touchesLength;
    470     // List of all touches which are currently down.
    471     WebTouchPoint touches[touchesLengthCap];
    472 
    473     unsigned changedTouchesLength;
    474     // List of all touches whose state has changed since the last WebTouchEvent
    475     WebTouchPoint changedTouches[touchesLengthCap];
    476 
    477     unsigned targetTouchesLength;
    478     // List of all touches which are currently down and are targeting the event recipient.
    479     WebTouchPoint targetTouches[touchesLengthCap];
    480 
    481     WebTouchEvent(unsigned sizeParam = sizeof(WebTouchEvent))
    482         : WebInputEvent(sizeParam)
    483         , touchesLength(0)
    484         , changedTouchesLength(0)
    485         , targetTouchesLength(0)
    486     {
    487     }
    488 };
    489 
    490 #pragma pack(pop)
    491 
    492 } // namespace WebKit
    493 
    494 #endif
    495