1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef mozilla_TouchEvents_h__
7 #define mozilla_TouchEvents_h__
8 
9 #include <stdint.h>
10 
11 #include "mozilla/dom/Touch.h"
12 #include "mozilla/MouseEvents.h"
13 #include "mozilla/RefPtr.h"
14 #include "nsTArray.h"
15 
16 namespace mozilla {
17 
18 /******************************************************************************
19  * mozilla::WidgetGestureNotifyEvent
20  *
21  * This event is the first event generated when the user touches
22  * the screen with a finger, and it's meant to decide what kind
23  * of action we'll use for that touch interaction.
24  *
25  * The event is dispatched to the layout and based on what is underneath
26  * the initial contact point it's then decided if we should pan
27  * (finger scrolling) or drag the target element.
28  ******************************************************************************/
29 
30 class WidgetGestureNotifyEvent : public WidgetGUIEvent {
31  public:
AsGestureNotifyEvent()32   virtual WidgetGestureNotifyEvent* AsGestureNotifyEvent() override {
33     return this;
34   }
35 
WidgetGestureNotifyEvent(bool aIsTrusted,EventMessage aMessage,nsIWidget * aWidget)36   WidgetGestureNotifyEvent(bool aIsTrusted, EventMessage aMessage,
37                            nsIWidget* aWidget)
38       : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, eGestureNotifyEventClass),
39         mPanDirection(ePanNone),
40         mDisplayPanFeedback(false) {}
41 
Duplicate()42   virtual WidgetEvent* Duplicate() const override {
43     // XXX Looks like this event is handled only in PostHandleEvent() of
44     //     EventStateManager.  Therefore, it might be possible to handle this
45     //     in PreHandleEvent() and not to dispatch as a DOM event into the DOM
46     //     tree like ContentQueryEvent.  Then, this event doesn't need to
47     //     support Duplicate().
48     MOZ_ASSERT(mClass == eGestureNotifyEventClass,
49                "Duplicate() must be overridden by sub class");
50     // Not copying widget, it is a weak reference.
51     WidgetGestureNotifyEvent* result =
52         new WidgetGestureNotifyEvent(false, mMessage, nullptr);
53     result->AssignGestureNotifyEventData(*this, true);
54     result->mFlags = mFlags;
55     return result;
56   }
57 
58   typedef int8_t PanDirectionType;
59   enum PanDirection : PanDirectionType {
60     ePanNone,
61     ePanVertical,
62     ePanHorizontal,
63     ePanBoth
64   };
65 
66   PanDirection mPanDirection;
67   bool mDisplayPanFeedback;
68 
AssignGestureNotifyEventData(const WidgetGestureNotifyEvent & aEvent,bool aCopyTargets)69   void AssignGestureNotifyEventData(const WidgetGestureNotifyEvent& aEvent,
70                                     bool aCopyTargets) {
71     AssignGUIEventData(aEvent, aCopyTargets);
72 
73     mPanDirection = aEvent.mPanDirection;
74     mDisplayPanFeedback = aEvent.mDisplayPanFeedback;
75   }
76 };
77 
78 /******************************************************************************
79  * mozilla::WidgetSimpleGestureEvent
80  ******************************************************************************/
81 
82 class WidgetSimpleGestureEvent : public WidgetMouseEventBase {
83  public:
AsSimpleGestureEvent()84   virtual WidgetSimpleGestureEvent* AsSimpleGestureEvent() override {
85     return this;
86   }
87 
WidgetSimpleGestureEvent(bool aIsTrusted,EventMessage aMessage,nsIWidget * aWidget)88   WidgetSimpleGestureEvent(bool aIsTrusted, EventMessage aMessage,
89                            nsIWidget* aWidget)
90       : WidgetMouseEventBase(aIsTrusted, aMessage, aWidget,
91                              eSimpleGestureEventClass),
92         mAllowedDirections(0),
93         mDirection(0),
94         mClickCount(0),
95         mDelta(0.0) {}
96 
WidgetSimpleGestureEvent(const WidgetSimpleGestureEvent & aOther)97   WidgetSimpleGestureEvent(const WidgetSimpleGestureEvent& aOther)
98       : WidgetMouseEventBase(aOther.IsTrusted(), aOther.mMessage,
99                              aOther.mWidget, eSimpleGestureEventClass),
100         mAllowedDirections(aOther.mAllowedDirections),
101         mDirection(aOther.mDirection),
102         mClickCount(0),
103         mDelta(aOther.mDelta) {}
104 
Duplicate()105   virtual WidgetEvent* Duplicate() const override {
106     MOZ_ASSERT(mClass == eSimpleGestureEventClass,
107                "Duplicate() must be overridden by sub class");
108     // Not copying widget, it is a weak reference.
109     WidgetSimpleGestureEvent* result =
110         new WidgetSimpleGestureEvent(false, mMessage, nullptr);
111     result->AssignSimpleGestureEventData(*this, true);
112     result->mFlags = mFlags;
113     return result;
114   }
115 
116   // See SimpleGestureEvent.webidl for values
117   uint32_t mAllowedDirections;
118   // See SimpleGestureEvent.webidl for values
119   uint32_t mDirection;
120   // The number of taps for tap events
121   uint32_t mClickCount;
122   // Delta for magnify and rotate events
123   double mDelta;
124 
125   // XXX Not tested by test_assign_event_data.html
AssignSimpleGestureEventData(const WidgetSimpleGestureEvent & aEvent,bool aCopyTargets)126   void AssignSimpleGestureEventData(const WidgetSimpleGestureEvent& aEvent,
127                                     bool aCopyTargets) {
128     AssignMouseEventBaseData(aEvent, aCopyTargets);
129 
130     // mAllowedDirections isn't copied
131     mDirection = aEvent.mDirection;
132     mDelta = aEvent.mDelta;
133     mClickCount = aEvent.mClickCount;
134   }
135 };
136 
137 /******************************************************************************
138  * mozilla::WidgetTouchEvent
139  ******************************************************************************/
140 
141 class WidgetTouchEvent : public WidgetInputEvent {
142  public:
143   typedef nsTArray<RefPtr<mozilla::dom::Touch>> TouchArray;
144   typedef AutoTArray<RefPtr<mozilla::dom::Touch>, 10> AutoTouchArray;
145   typedef AutoTouchArray::base_type TouchArrayBase;
146 
AsTouchEvent()147   virtual WidgetTouchEvent* AsTouchEvent() override { return this; }
148 
149   MOZ_COUNTED_DEFAULT_CTOR(WidgetTouchEvent)
150 
WidgetTouchEvent(const WidgetTouchEvent & aOther)151   WidgetTouchEvent(const WidgetTouchEvent& aOther)
152       : WidgetInputEvent(aOther.IsTrusted(), aOther.mMessage, aOther.mWidget,
153                          eTouchEventClass) {
154     MOZ_COUNT_CTOR(WidgetTouchEvent);
155     mModifiers = aOther.mModifiers;
156     mTime = aOther.mTime;
157     mTimeStamp = aOther.mTimeStamp;
158     mTouches.AppendElements(aOther.mTouches);
159     mInputSource = aOther.mInputSource;
160     mButton = aOther.mButton;
161     mButtons = aOther.mButtons;
162     mFlags.mCancelable = mMessage != eTouchCancel;
163     mFlags.mHandledByAPZ = aOther.mFlags.mHandledByAPZ;
164   }
165 
WidgetTouchEvent(bool aIsTrusted,EventMessage aMessage,nsIWidget * aWidget)166   WidgetTouchEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget)
167       : WidgetInputEvent(aIsTrusted, aMessage, aWidget, eTouchEventClass) {
168     MOZ_COUNT_CTOR(WidgetTouchEvent);
169     mFlags.mCancelable = mMessage != eTouchCancel;
170   }
171 
MOZ_COUNTED_DTOR_OVERRIDE(WidgetTouchEvent)172   MOZ_COUNTED_DTOR_OVERRIDE(WidgetTouchEvent)
173 
174   virtual WidgetEvent* Duplicate() const override {
175     MOZ_ASSERT(mClass == eTouchEventClass,
176                "Duplicate() must be overridden by sub class");
177     // Not copying widget, it is a weak reference.
178     WidgetTouchEvent* result = new WidgetTouchEvent(false, mMessage, nullptr);
179     result->AssignTouchEventData(*this, true);
180     result->mFlags = mFlags;
181     return result;
182   }
183 
184   TouchArray mTouches;
185   uint16_t mInputSource = 5;  // MouseEvent_Binding::MOZ_SOURCE_TOUCH
186   int16_t mButton = eNotPressed;
187   int16_t mButtons = 0;
188 
AssignTouchEventData(const WidgetTouchEvent & aEvent,bool aCopyTargets)189   void AssignTouchEventData(const WidgetTouchEvent& aEvent, bool aCopyTargets) {
190     AssignInputEventData(aEvent, aCopyTargets);
191 
192     // Assign*EventData() assume that they're called only new instance.
193     MOZ_ASSERT(mTouches.IsEmpty());
194     mTouches.AppendElements(aEvent.mTouches);
195     mInputSource = aEvent.mInputSource;
196   }
197 };
198 
199 }  // namespace mozilla
200 
201 #endif  // mozilla_TouchEvents_h__
202