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
39namespace 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
51class WebInputEvent {
52public:
53    WebInputEvent(unsigned sizeParam = sizeof(WebInputEvent))
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.
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.
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.
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.
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
182class WebKeyboardEvent : public WebInputEvent {
183public:
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))
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
245class WebMouseEvent : public WebInputEvent {
246public:
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))
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
280class WebMouseWheelEvent : public WebMouseEvent {
281public:
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))
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
306class WebTouchEvent : public WebInputEvent {
307public:
308    static const int touchPointsLengthCap = 4;
309
310    int touchPointsLength;
311    WebTouchPoint touchPoints[touchPointsLengthCap];
312
313    WebTouchEvent(unsigned sizeParam = sizeof(WebTouchEvent))
314        : WebInputEvent(sizeParam)
315        , touchPointsLength(0)
316    {
317    }
318};
319
320} // namespace WebKit
321
322#endif
323