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 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.
    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.
    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.
    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.
    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.
    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))
    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))
    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))
    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))
    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))
    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