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#pragma once
28
29// FIXME: We should probably move to makeing the WebCore/PlatformFooEvents trivial classes so that
30// we can use them as the event type.
31
32#include <WebCore/FloatPoint.h>
33#include <WebCore/FloatSize.h>
34#include <WebCore/IntPoint.h>
35#include <WebCore/IntSize.h>
36#include <WebCore/KeypressCommand.h>
37#include <wtf/OptionSet.h>
38#include <wtf/WallTime.h>
39#include <wtf/text/WTFString.h>
40
41namespace IPC {
42class Decoder;
43class Encoder;
44}
45
46#if USE(APPKIT)
47namespace WebCore {
48struct KeypressCommand;
49}
50#endif
51
52namespace WebKit {
53
54class WebEvent {
55 WTF_MAKE_FAST_ALLOCATED;
56public:
57 enum Type {
58 NoType = -1,
59
60 // WebMouseEvent
61 MouseDown,
62 MouseUp,
63 MouseMove,
64 MouseForceChanged,
65 MouseForceDown,
66 MouseForceUp,
67
68 // WebWheelEvent
69 Wheel,
70
71 // WebKeyboardEvent
72 KeyDown,
73 KeyUp,
74 RawKeyDown,
75 Char,
76
77#if ENABLE(TOUCH_EVENTS)
78 // WebTouchEvent
79 TouchStart,
80 TouchMove,
81 TouchEnd,
82 TouchCancel,
83#endif
84
85#if ENABLE(MAC_GESTURE_EVENTS)
86 GestureStart,
87 GestureChange,
88 GestureEnd,
89#endif
90 };
91
92 enum class Modifier : uint8_t {
93 ShiftKey = 1 << 0,
94 ControlKey = 1 << 1,
95 AltKey = 1 << 2,
96 MetaKey = 1 << 3,
97 CapsLockKey = 1 << 4,
98 };
99
100 Type type() const { return static_cast<Type>(m_type); }
101
102 bool shiftKey() const { return m_modifiers.contains(Modifier::ShiftKey); }
103 bool controlKey() const { return m_modifiers.contains(Modifier::ControlKey); }
104 bool altKey() const { return m_modifiers.contains(Modifier::AltKey); }
105 bool metaKey() const { return m_modifiers.contains(Modifier::MetaKey); }
106 bool capsLockKey() const { return m_modifiers.contains(Modifier::CapsLockKey); }
107
108 OptionSet<Modifier> modifiers() const { return m_modifiers; }
109
110 WallTime timestamp() const { return m_timestamp; }
111
112protected:
113 WebEvent();
114
115 WebEvent(Type, OptionSet<Modifier>, WallTime timestamp);
116
117 void encode(IPC::Encoder&) const;
118 static bool decode(IPC::Decoder&, WebEvent&);
119
120private:
121 uint32_t m_type;
122 OptionSet<Modifier> m_modifiers;
123 WallTime m_timestamp;
124};
125
126// FIXME: Move this class to its own header file.
127class WebMouseEvent : public WebEvent {
128public:
129 enum Button {
130 LeftButton = 0,
131 MiddleButton,
132 RightButton,
133 NoButton = -2
134 };
135
136 enum SyntheticClickType { NoTap, OneFingerTap, TwoFingerTap };
137
138 WebMouseEvent();
139
140#if PLATFORM(MAC)
141 WebMouseEvent(Type, Button, unsigned short buttons, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier>, WallTime timestamp, double force, SyntheticClickType = NoTap, int eventNumber = -1, int menuType = 0);
142#else
143 WebMouseEvent(Type, Button, unsigned short buttons, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier>, WallTime timestamp, double force = 0, SyntheticClickType = NoTap);
144#endif
145
146 Button button() const { return static_cast<Button>(m_button); }
147 unsigned short buttons() const { return m_buttons; }
148 const WebCore::IntPoint& position() const { return m_position; }
149 const WebCore::IntPoint& globalPosition() const { return m_globalPosition; }
150 float deltaX() const { return m_deltaX; }
151 float deltaY() const { return m_deltaY; }
152 float deltaZ() const { return m_deltaZ; }
153 int32_t clickCount() const { return m_clickCount; }
154#if PLATFORM(MAC)
155 int32_t eventNumber() const { return m_eventNumber; }
156 int32_t menuTypeForEvent() const { return m_menuTypeForEvent; }
157#endif
158 double force() const { return m_force; }
159 SyntheticClickType syntheticClickType() const { return static_cast<SyntheticClickType>(m_syntheticClickType); }
160
161 void encode(IPC::Encoder&) const;
162 static bool decode(IPC::Decoder&, WebMouseEvent&);
163
164private:
165 static bool isMouseEventType(Type);
166
167 uint32_t m_button;
168 unsigned short m_buttons { 0 };
169 WebCore::IntPoint m_position;
170 WebCore::IntPoint m_globalPosition;
171 float m_deltaX;
172 float m_deltaY;
173 float m_deltaZ;
174 int32_t m_clickCount;
175#if PLATFORM(MAC)
176 int32_t m_eventNumber;
177 int32_t m_menuTypeForEvent;
178#endif
179 double m_force { 0 };
180 uint32_t m_syntheticClickType { NoTap };
181};
182
183// FIXME: Move this class to its own header file.
184class WebWheelEvent : public WebEvent {
185public:
186 enum Granularity {
187 ScrollByPageWheelEvent,
188 ScrollByPixelWheelEvent
189 };
190
191#if PLATFORM(COCOA) || PLATFORM(GTK)
192 enum Phase {
193 PhaseNone = 0,
194 PhaseBegan = 1 << 0,
195 PhaseStationary = 1 << 1,
196 PhaseChanged = 1 << 2,
197 PhaseEnded = 1 << 3,
198 PhaseCancelled = 1 << 4,
199 PhaseMayBegin = 1 << 5,
200 };
201#endif
202
203 WebWheelEvent() { }
204
205 WebWheelEvent(Type, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, const WebCore::FloatSize& delta, const WebCore::FloatSize& wheelTicks, Granularity, OptionSet<Modifier>, WallTime timestamp);
206#if PLATFORM(COCOA)
207 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, OptionSet<Modifier>, WallTime timestamp);
208#elif PLATFORM(GTK)
209 WebWheelEvent(Type, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, const WebCore::FloatSize& delta, const WebCore::FloatSize& wheelTicks, Phase, Phase momentumPhase, Granularity, OptionSet<Modifier>, WallTime timestamp);
210#endif
211
212 const WebCore::IntPoint position() const { return m_position; }
213 const WebCore::IntPoint globalPosition() const { return m_globalPosition; }
214 const WebCore::FloatSize delta() const { return m_delta; }
215 const WebCore::FloatSize wheelTicks() const { return m_wheelTicks; }
216 Granularity granularity() const { return static_cast<Granularity>(m_granularity); }
217 bool directionInvertedFromDevice() const { return m_directionInvertedFromDevice; }
218#if PLATFORM(COCOA) || PLATFORM(GTK)
219 Phase phase() const { return static_cast<Phase>(m_phase); }
220 Phase momentumPhase() const { return static_cast<Phase>(m_momentumPhase); }
221#endif
222#if PLATFORM(COCOA)
223 bool hasPreciseScrollingDeltas() const { return m_hasPreciseScrollingDeltas; }
224 uint32_t scrollCount() const { return m_scrollCount; }
225 const WebCore::FloatSize& unacceleratedScrollingDelta() const { return m_unacceleratedScrollingDelta; }
226#endif
227
228 void encode(IPC::Encoder&) const;
229 static bool decode(IPC::Decoder&, WebWheelEvent&);
230
231private:
232 static bool isWheelEventType(Type);
233
234 WebCore::IntPoint m_position;
235 WebCore::IntPoint m_globalPosition;
236 WebCore::FloatSize m_delta;
237 WebCore::FloatSize m_wheelTicks;
238 uint32_t m_granularity; // Granularity
239 bool m_directionInvertedFromDevice;
240#if PLATFORM(COCOA) || PLATFORM(GTK)
241 uint32_t m_phase { Phase::PhaseNone };
242 uint32_t m_momentumPhase { Phase::PhaseNone };
243#endif
244#if PLATFORM(COCOA)
245 bool m_hasPreciseScrollingDeltas;
246 uint32_t m_scrollCount;
247 WebCore::FloatSize m_unacceleratedScrollingDelta;
248#endif
249};
250
251// FIXME: Move this class to its own header file.
252class WebKeyboardEvent : public WebEvent {
253public:
254 WebKeyboardEvent();
255 ~WebKeyboardEvent();
256
257#if USE(APPKIT)
258 WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool handledByInputMethod, const Vector<WebCore::KeypressCommand>&, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp);
259#elif PLATFORM(GTK)
260 WebKeyboardEvent(Type, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool handledByInputMethod, Vector<String>&& commands, bool isKeypad, OptionSet<Modifier>, WallTime timestamp);
261#elif PLATFORM(IOS_FAMILY)
262 WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool handledByInputMethod, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp);
263#elif USE(LIBWPE)
264 WebKeyboardEvent(Type, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isKeypad, OptionSet<Modifier>, WallTime timestamp);
265#else
266 WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp);
267#endif
268
269 const String& text() const { return m_text; }
270 const String& unmodifiedText() const { return m_unmodifiedText; }
271#if ENABLE(KEYBOARD_KEY_ATTRIBUTE)
272 const String& key() const { return m_key; }
273#endif
274#if ENABLE(KEYBOARD_CODE_ATTRIBUTE)
275 const String& code() const { return m_code; }
276#endif
277 const String& keyIdentifier() const { return m_keyIdentifier; }
278 int32_t windowsVirtualKeyCode() const { return m_windowsVirtualKeyCode; }
279 int32_t nativeVirtualKeyCode() const { return m_nativeVirtualKeyCode; }
280 int32_t macCharCode() const { return m_macCharCode; }
281#if USE(APPKIT) || USE(UIKIT_KEYBOARD_ADDITIONS) || PLATFORM(GTK)
282 bool handledByInputMethod() const { return m_handledByInputMethod; }
283#endif
284#if USE(APPKIT)
285 const Vector<WebCore::KeypressCommand>& commands() const { return m_commands; }
286#elif PLATFORM(GTK)
287 const Vector<String>& commands() const { return m_commands; }
288#endif
289 bool isAutoRepeat() const { return m_isAutoRepeat; }
290 bool isKeypad() const { return m_isKeypad; }
291 bool isSystemKey() const { return m_isSystemKey; }
292
293 void encode(IPC::Encoder&) const;
294 static bool decode(IPC::Decoder&, WebKeyboardEvent&);
295
296 static bool isKeyboardEventType(Type);
297
298private:
299 String m_text;
300 String m_unmodifiedText;
301#if ENABLE(KEYBOARD_KEY_ATTRIBUTE)
302 String m_key;
303#endif
304#if ENABLE(KEYBOARD_CODE_ATTRIBUTE)
305 String m_code;
306#endif
307 String m_keyIdentifier;
308 int32_t m_windowsVirtualKeyCode;
309 int32_t m_nativeVirtualKeyCode;
310 int32_t m_macCharCode;
311#if USE(APPKIT) || USE(UIKIT_KEYBOARD_ADDITIONS) || PLATFORM(GTK)
312 bool m_handledByInputMethod;
313#endif
314#if USE(APPKIT)
315 Vector<WebCore::KeypressCommand> m_commands;
316#elif PLATFORM(GTK)
317 Vector<String> m_commands;
318#endif
319 bool m_isAutoRepeat;
320 bool m_isKeypad;
321 bool m_isSystemKey;
322};
323
324#if ENABLE(TOUCH_EVENTS)
325#if PLATFORM(IOS_FAMILY)
326class WebPlatformTouchPoint {
327public:
328 enum TouchPointState {
329 TouchReleased,
330 TouchPressed,
331 TouchMoved,
332 TouchStationary,
333 TouchCancelled
334 };
335
336 enum class TouchType {
337 Direct,
338 Stylus
339 };
340
341 WebPlatformTouchPoint() { }
342 WebPlatformTouchPoint(unsigned identifier, WebCore::IntPoint location, TouchPointState phase)
343 : m_identifier(identifier)
344 , m_location(location)
345 , m_phase(phase)
346 {
347 }
348
349 unsigned identifier() const { return m_identifier; }
350 WebCore::IntPoint location() const { return m_location; }
351 TouchPointState phase() const { return static_cast<TouchPointState>(m_phase); }
352 TouchPointState state() const { return phase(); }
353
354#if ENABLE(IOS_TOUCH_EVENTS)
355 void setRadiusX(double radiusX) { m_radiusX = radiusX; }
356 double radiusX() const { return m_radiusX; }
357 void setRadiusY(double radiusY) { m_radiusY = radiusY; }
358 double radiusY() const { return m_radiusY; }
359 void setRotationAngle(double rotationAngle) { m_rotationAngle = rotationAngle; }
360 double rotationAngle() const { return m_rotationAngle; }
361 void setForce(double force) { m_force = force; }
362 double force() const { return m_force; }
363 void setAltitudeAngle(double altitudeAngle) { m_altitudeAngle = altitudeAngle; }
364 double altitudeAngle() const { return m_altitudeAngle; }
365 void setAzimuthAngle(double azimuthAngle) { m_azimuthAngle = azimuthAngle; }
366 double azimuthAngle() const { return m_azimuthAngle; }
367 void setTouchType(TouchType touchType) { m_touchType = static_cast<uint32_t>(touchType); }
368 TouchType touchType() const { return static_cast<TouchType>(m_touchType); }
369#endif
370
371 void encode(IPC::Encoder&) const;
372 static Optional<WebPlatformTouchPoint> decode(IPC::Decoder&);
373
374private:
375 unsigned m_identifier;
376 WebCore::IntPoint m_location;
377 uint32_t m_phase;
378#if ENABLE(IOS_TOUCH_EVENTS)
379 double m_radiusX { 0 };
380 double m_radiusY { 0 };
381 double m_rotationAngle { 0 };
382 double m_force { 0 };
383 double m_altitudeAngle { 0 };
384 double m_azimuthAngle { 0 };
385 uint32_t m_touchType { static_cast<uint32_t>(TouchType::Direct) };
386#endif
387};
388
389class WebTouchEvent : public WebEvent {
390public:
391 WebTouchEvent() { }
392 WebTouchEvent(WebEvent::Type type, OptionSet<Modifier> modifiers, WallTime timestamp, const Vector<WebPlatformTouchPoint>& touchPoints, WebCore::IntPoint position, bool isPotentialTap, bool isGesture, float gestureScale, float gestureRotation)
393 : WebEvent(type, modifiers, timestamp)
394 , m_touchPoints(touchPoints)
395 , m_position(position)
396 , m_canPreventNativeGestures(true)
397 , m_isPotentialTap(isPotentialTap)
398 , m_isGesture(isGesture)
399 , m_gestureScale(gestureScale)
400 , m_gestureRotation(gestureRotation)
401 {
402 ASSERT(type == TouchStart || type == TouchMove || type == TouchEnd || type == TouchCancel);
403 }
404
405 const Vector<WebPlatformTouchPoint>& touchPoints() const { return m_touchPoints; }
406
407 WebCore::IntPoint position() const { return m_position; }
408
409 bool isPotentialTap() const { return m_isPotentialTap; }
410
411 bool isGesture() const { return m_isGesture; }
412 float gestureScale() const { return m_gestureScale; }
413 float gestureRotation() const { return m_gestureRotation; }
414
415 bool canPreventNativeGestures() const { return m_canPreventNativeGestures; }
416 void setCanPreventNativeGestures(bool canPreventNativeGestures) { m_canPreventNativeGestures = canPreventNativeGestures; }
417
418 bool allTouchPointsAreReleased() const;
419
420 void encode(IPC::Encoder&) const;
421 static bool decode(IPC::Decoder&, WebTouchEvent&);
422
423private:
424 Vector<WebPlatformTouchPoint> m_touchPoints;
425
426 WebCore::IntPoint m_position;
427 bool m_canPreventNativeGestures;
428 bool m_isPotentialTap;
429 bool m_isGesture;
430 float m_gestureScale;
431 float m_gestureRotation;
432};
433#else
434// FIXME: Move this class to its own header file.
435// FIXME: Having "Platform" in the name makes it sound like this event is platform-specific or low-
436// level in some way. That doesn't seem to be the case.
437class WebPlatformTouchPoint {
438public:
439 enum TouchPointState {
440 TouchReleased,
441 TouchPressed,
442 TouchMoved,
443 TouchStationary,
444 TouchCancelled
445 };
446
447 WebPlatformTouchPoint() : m_rotationAngle(0.0), m_force(0.0) { }
448
449 WebPlatformTouchPoint(uint32_t id, TouchPointState, const WebCore::IntPoint& screenPosition, const WebCore::IntPoint& position);
450
451 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);
452
453 uint32_t id() const { return m_id; }
454 TouchPointState state() const { return static_cast<TouchPointState>(m_state); }
455
456 const WebCore::IntPoint& screenPosition() const { return m_screenPosition; }
457 const WebCore::IntPoint& position() const { return m_position; }
458 const WebCore::IntSize& radius() const { return m_radius; }
459 float rotationAngle() const { return m_rotationAngle; }
460 float force() const { return m_force; }
461
462 void setState(TouchPointState state) { m_state = state; }
463
464 void encode(IPC::Encoder&) const;
465 static Optional<WebPlatformTouchPoint> decode(IPC::Decoder&);
466
467private:
468 uint32_t m_id;
469 uint32_t m_state;
470 WebCore::IntPoint m_screenPosition;
471 WebCore::IntPoint m_position;
472 WebCore::IntSize m_radius;
473 float m_rotationAngle;
474 float m_force;
475};
476
477// FIXME: Move this class to its own header file.
478class WebTouchEvent : public WebEvent {
479public:
480 WebTouchEvent() { }
481 WebTouchEvent(Type, Vector<WebPlatformTouchPoint>&&, OptionSet<Modifier>, WallTime timestamp);
482
483 const Vector<WebPlatformTouchPoint>& touchPoints() const { return m_touchPoints; }
484
485 bool allTouchPointsAreReleased() const;
486
487 void encode(IPC::Encoder&) const;
488 static bool decode(IPC::Decoder&, WebTouchEvent&);
489
490private:
491 static bool isTouchEventType(Type);
492
493 Vector<WebPlatformTouchPoint> m_touchPoints;
494};
495
496#endif // PLATFORM(IOS_FAMILY)
497#endif // ENABLE(TOUCH_EVENTS)
498
499} // namespace WebKit
500