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