1/*
2 * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
3 * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#ifndef WebEvent_h
28#define WebEvent_h
29
30// FIXME: We should probably move to makeing the WebCore/PlatformFooEvents trivial classes so that
31// we can use them as the event type.
32
33#include <WebCore/FloatPoint.h>
34#include <WebCore/FloatSize.h>
35#include <WebCore/IntPoint.h>
36#include <WebCore/IntSize.h>
37#include <wtf/text/WTFString.h>
38
39namespace IPC {
40    class ArgumentDecoder;
41    class ArgumentEncoder;
42}
43
44#if USE(APPKIT)
45namespace WebCore {
46struct KeypressCommand;
47}
48#endif
49
50namespace WebKit {
51
52class WebEvent {
53public:
54    enum Type {
55        NoType = -1,
56
57        // WebMouseEvent
58        MouseDown,
59        MouseUp,
60        MouseMove,
61
62        // WebWheelEvent
63        Wheel,
64
65        // WebKeyboardEvent
66        KeyDown,
67        KeyUp,
68        RawKeyDown,
69        Char,
70
71#if ENABLE(TOUCH_EVENTS)
72        // WebTouchEvent
73        TouchStart,
74        TouchMove,
75        TouchEnd,
76        TouchCancel,
77#endif
78    };
79
80    enum Modifiers {
81        ShiftKey    = 1 << 0,
82        ControlKey  = 1 << 1,
83        AltKey      = 1 << 2,
84        MetaKey     = 1 << 3,
85        CapsLockKey = 1 << 4,
86    };
87
88    Type type() const { return static_cast<Type>(m_type); }
89
90    bool shiftKey() const { return m_modifiers & ShiftKey; }
91    bool controlKey() const { return m_modifiers & ControlKey; }
92    bool altKey() const { return m_modifiers & AltKey; }
93    bool metaKey() const { return m_modifiers & MetaKey; }
94    bool capsLockKey() const { return m_modifiers & CapsLockKey; }
95
96    Modifiers modifiers() const { return static_cast<Modifiers>(m_modifiers); }
97
98    double timestamp() const { return m_timestamp; }
99
100protected:
101    WebEvent();
102
103    WebEvent(Type, Modifiers, double timestamp);
104
105    void encode(IPC::ArgumentEncoder&) const;
106    static bool decode(IPC::ArgumentDecoder&, WebEvent&);
107
108private:
109    uint32_t m_type; // Type
110    uint32_t m_modifiers; // Modifiers
111    double m_timestamp;
112};
113
114// FIXME: Move this class to its own header file.
115class WebMouseEvent : public WebEvent {
116public:
117    enum Button {
118        NoButton = -1,
119        LeftButton,
120        MiddleButton,
121        RightButton
122    };
123
124    WebMouseEvent();
125
126    WebMouseEvent(Type, Button, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, Modifiers, double timestamp);
127
128    Button button() const { return static_cast<Button>(m_button); }
129    const WebCore::IntPoint& position() const { return m_position; }
130    const WebCore::IntPoint& globalPosition() const { return m_globalPosition; }
131    float deltaX() const { return m_deltaX; }
132    float deltaY() const { return m_deltaY; }
133    float deltaZ() const { return m_deltaZ; }
134    int32_t clickCount() const { return m_clickCount; }
135
136    void encode(IPC::ArgumentEncoder&) const;
137    static bool decode(IPC::ArgumentDecoder&, WebMouseEvent&);
138
139private:
140    static bool isMouseEventType(Type);
141
142    uint32_t m_button;
143    WebCore::IntPoint m_position;
144    WebCore::IntPoint m_globalPosition;
145    float m_deltaX;
146    float m_deltaY;
147    float m_deltaZ;
148    int32_t m_clickCount;
149};
150
151// FIXME: Move this class to its own header file.
152class WebWheelEvent : public WebEvent {
153public:
154    enum Granularity {
155        ScrollByPageWheelEvent,
156        ScrollByPixelWheelEvent
157    };
158
159#if PLATFORM(COCOA)
160    enum Phase {
161        PhaseNone        = 0,
162        PhaseBegan       = 1 << 0,
163        PhaseStationary  = 1 << 1,
164        PhaseChanged     = 1 << 2,
165        PhaseEnded       = 1 << 3,
166        PhaseCancelled   = 1 << 4,
167        PhaseMayBegin    = 1 << 5,
168    };
169#endif
170
171    WebWheelEvent() { }
172
173    WebWheelEvent(Type, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, const WebCore::FloatSize& delta, const WebCore::FloatSize& wheelTicks, Granularity, Modifiers, double timestamp);
174#if PLATFORM(COCOA)
175    WebWheelEvent(Type, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, const WebCore::FloatSize& delta, const WebCore::FloatSize& wheelTicks, Granularity, bool directionInvertedFromDevice, Phase, Phase momentumPhase, bool hasPreciseScrollingDeltas, uint32_t scrollCount, const WebCore::FloatSize& unacceleratedScrollingDelta, Modifiers, double timestamp);
176#endif
177
178    const WebCore::IntPoint position() const { return m_position; }
179    const WebCore::IntPoint globalPosition() const { return m_globalPosition; }
180    const WebCore::FloatSize delta() const { return m_delta; }
181    const WebCore::FloatSize wheelTicks() const { return m_wheelTicks; }
182    Granularity granularity() const { return static_cast<Granularity>(m_granularity); }
183    bool directionInvertedFromDevice() const { return m_directionInvertedFromDevice; }
184#if PLATFORM(COCOA)
185    Phase phase() const { return static_cast<Phase>(m_phase); }
186    Phase momentumPhase() const { return static_cast<Phase>(m_momentumPhase); }
187    bool hasPreciseScrollingDeltas() const { return m_hasPreciseScrollingDeltas; }
188    uint32_t scrollCount() const { return m_scrollCount; }
189    const WebCore::FloatSize& unacceleratedScrollingDelta() const { return m_unacceleratedScrollingDelta; }
190#endif
191
192    void encode(IPC::ArgumentEncoder&) const;
193    static bool decode(IPC::ArgumentDecoder&, WebWheelEvent&);
194
195private:
196    static bool isWheelEventType(Type);
197
198    WebCore::IntPoint m_position;
199    WebCore::IntPoint m_globalPosition;
200    WebCore::FloatSize m_delta;
201    WebCore::FloatSize m_wheelTicks;
202    uint32_t m_granularity; // Granularity
203    bool m_directionInvertedFromDevice;
204#if PLATFORM(COCOA)
205    uint32_t m_phase; // Phase
206    uint32_t m_momentumPhase; // Phase
207    bool m_hasPreciseScrollingDeltas;
208    uint32_t m_scrollCount;
209    WebCore::FloatSize m_unacceleratedScrollingDelta;
210#endif
211};
212
213// FIXME: Move this class to its own header file.
214class WebKeyboardEvent : public WebEvent {
215public:
216    WebKeyboardEvent();
217    ~WebKeyboardEvent();
218
219#if USE(APPKIT)
220    WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool handledByInputMethod, const Vector<WebCore::KeypressCommand>&, bool isAutoRepeat, bool isKeypad, bool isSystemKey, Modifiers, double timestamp);
221#else
222    WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, Modifiers, double timestamp);
223#endif
224
225    const String& text() const { return m_text; }
226    const String& unmodifiedText() const { return m_unmodifiedText; }
227    const String& keyIdentifier() const { return m_keyIdentifier; }
228    int32_t windowsVirtualKeyCode() const { return m_windowsVirtualKeyCode; }
229    int32_t nativeVirtualKeyCode() const { return m_nativeVirtualKeyCode; }
230    int32_t macCharCode() const { return m_macCharCode; }
231#if USE(APPKIT)
232    bool handledByInputMethod() const { return m_handledByInputMethod; }
233    const Vector<WebCore::KeypressCommand>& commands() const { return m_commands; }
234#endif
235    bool isAutoRepeat() const { return m_isAutoRepeat; }
236    bool isKeypad() const { return m_isKeypad; }
237    bool isSystemKey() const { return m_isSystemKey; }
238
239    void encode(IPC::ArgumentEncoder&) const;
240    static bool decode(IPC::ArgumentDecoder&, WebKeyboardEvent&);
241
242    static bool isKeyboardEventType(Type);
243
244private:
245    String m_text;
246    String m_unmodifiedText;
247    String m_keyIdentifier;
248    int32_t m_windowsVirtualKeyCode;
249    int32_t m_nativeVirtualKeyCode;
250    int32_t m_macCharCode;
251#if USE(APPKIT)
252    bool m_handledByInputMethod;
253    Vector<WebCore::KeypressCommand> m_commands;
254#endif
255    bool m_isAutoRepeat;
256    bool m_isKeypad;
257    bool m_isSystemKey;
258};
259
260#if ENABLE(TOUCH_EVENTS)
261#if PLATFORM(IOS)
262class WebPlatformTouchPoint {
263public:
264    enum TouchPointState {
265        TouchReleased,
266        TouchPressed,
267        TouchMoved,
268        TouchStationary,
269        TouchCancelled
270    };
271
272    WebPlatformTouchPoint() { }
273    WebPlatformTouchPoint(unsigned identifier, WebCore::IntPoint location, TouchPointState phase)
274        : m_identifier(identifier)
275        , m_location(location)
276        , m_phase(phase)
277    {
278    }
279
280    unsigned identifier() const { return m_identifier; }
281    WebCore::IntPoint location() const { return m_location; }
282    TouchPointState phase() const { return static_cast<TouchPointState>(m_phase); }
283    TouchPointState state() const { return phase(); }
284
285    void encode(IPC::ArgumentEncoder&) const;
286    static bool decode(IPC::ArgumentDecoder&, WebPlatformTouchPoint&);
287
288private:
289    unsigned m_identifier;
290    WebCore::IntPoint m_location;
291    uint32_t m_phase;
292};
293
294class WebTouchEvent : public WebEvent {
295public:
296    WebTouchEvent() { }
297    WebTouchEvent(WebEvent::Type type, Modifiers modifiers, double timestamp, const Vector<WebPlatformTouchPoint>& touchPoints, WebCore::IntPoint position, bool isGesture, float gestureScale, float gestureRotation)
298        : WebEvent(type, modifiers, timestamp)
299        , m_touchPoints(touchPoints)
300        , m_position(position)
301        , m_canPreventNativeGestures(true)
302        , m_isGesture(isGesture)
303        , m_gestureScale(gestureScale)
304        , m_gestureRotation(gestureRotation)
305    {
306        ASSERT(type == TouchStart || type == TouchMove || type == TouchEnd || type == TouchCancel);
307    }
308
309    const Vector<WebPlatformTouchPoint>& touchPoints() const { return m_touchPoints; }
310
311    WebCore::IntPoint position() const { return m_position; }
312
313    bool isGesture() const { return m_isGesture; }
314    float gestureScale() const { return m_gestureScale; }
315    float gestureRotation() const { return m_gestureRotation; }
316
317    bool canPreventNativeGestures() const { return m_canPreventNativeGestures; }
318    void setCanPreventNativeGestures(bool canPreventNativeGestures) { m_canPreventNativeGestures = canPreventNativeGestures; }
319
320    bool allTouchPointsAreReleased() const;
321
322    void encode(IPC::ArgumentEncoder&) const;
323    static bool decode(IPC::ArgumentDecoder&, WebTouchEvent&);
324
325private:
326    Vector<WebPlatformTouchPoint> m_touchPoints;
327
328    WebCore::IntPoint m_position;
329    bool m_canPreventNativeGestures;
330    bool m_isGesture;
331    float m_gestureScale;
332    float m_gestureRotation;
333};
334#else
335// FIXME: Move this class to its own header file.
336// FIXME: Having "Platform" in the name makes it sound like this event is platform-specific or low-
337// level in some way. That doesn't seem to be the case.
338class WebPlatformTouchPoint {
339public:
340    enum TouchPointState {
341        TouchReleased,
342        TouchPressed,
343        TouchMoved,
344        TouchStationary,
345        TouchCancelled
346    };
347
348    WebPlatformTouchPoint() : m_rotationAngle(0.0), m_force(0.0) { }
349
350    WebPlatformTouchPoint(uint32_t id, TouchPointState, const WebCore::IntPoint& screenPosition, const WebCore::IntPoint& position);
351
352    WebPlatformTouchPoint(uint32_t id, TouchPointState, const WebCore::IntPoint& screenPosition, const WebCore::IntPoint& position, const WebCore::IntSize& radius, float rotationAngle = 0.0, float force = 0.0);
353
354    uint32_t id() const { return m_id; }
355    TouchPointState state() const { return static_cast<TouchPointState>(m_state); }
356
357    const WebCore::IntPoint& screenPosition() const { return m_screenPosition; }
358    const WebCore::IntPoint& position() const { return m_position; }
359    const WebCore::IntSize& radius() const { return m_radius; }
360    float rotationAngle() const { return m_rotationAngle; }
361    float force() const { return m_force; }
362
363    void setState(TouchPointState state) { m_state = state; }
364
365    void encode(IPC::ArgumentEncoder&) const;
366    static bool decode(IPC::ArgumentDecoder&, WebPlatformTouchPoint&);
367
368private:
369    uint32_t m_id;
370    uint32_t m_state;
371    WebCore::IntPoint m_screenPosition;
372    WebCore::IntPoint m_position;
373    WebCore::IntSize m_radius;
374    float m_rotationAngle;
375    float m_force;
376};
377
378// FIXME: Move this class to its own header file.
379class WebTouchEvent : public WebEvent {
380public:
381    WebTouchEvent() { }
382
383    // FIXME: It would be nice not to have to copy the Vector here.
384    WebTouchEvent(Type, Vector<WebPlatformTouchPoint>, Modifiers, double timestamp);
385
386    const Vector<WebPlatformTouchPoint>& touchPoints() const { return m_touchPoints; }
387
388    bool allTouchPointsAreReleased() const;
389
390    void encode(IPC::ArgumentEncoder&) const;
391    static bool decode(IPC::ArgumentDecoder&, WebTouchEvent&);
392
393private:
394    static bool isTouchEventType(Type);
395
396    Vector<WebPlatformTouchPoint> m_touchPoints;
397};
398
399#endif // PLATFORM(IOS)
400#endif // ENABLE(TOUCH_EVENTS)
401
402} // namespace WebKit
403
404#endif // WebEvent_h
405