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/. */
8 #include "mozilla/dom/Touch.h"
10 #include "nsThreadUtils.h"
11 #include "mozilla/MouseEvents.h"
12 #include "mozilla/TouchEvents.h"
13 #include "UnitTransforms.h"
19 already_AddRefed
<Touch
> SingleTouchData::ToNewDOMTouch() const
21 NS_ABORT_IF_FALSE(NS_IsMainThread(),
22 "Can only create dom::Touch instances on main thread");
23 nsRefPtr
<Touch
> touch
= new Touch(mIdentifier
,
24 nsIntPoint(mScreenPoint
.x
, mScreenPoint
.y
),
25 nsIntPoint(mRadius
.width
, mRadius
.height
),
28 return touch
.forget();
31 MultiTouchInput::MultiTouchInput(const WidgetTouchEvent
& aTouchEvent
)
32 : InputData(MULTITOUCH_INPUT
, aTouchEvent
.time
, aTouchEvent
.timeStamp
,
33 aTouchEvent
.modifiers
)
35 NS_ABORT_IF_FALSE(NS_IsMainThread(),
36 "Can only copy from WidgetTouchEvent on main thread");
38 switch (aTouchEvent
.message
) {
40 mType
= MULTITOUCH_START
;
43 mType
= MULTITOUCH_MOVE
;
46 mType
= MULTITOUCH_END
;
49 mType
= MULTITOUCH_CANCEL
;
52 MOZ_ASSERT_UNREACHABLE("Did not assign a type to a MultiTouchInput");
56 for (size_t i
= 0; i
< aTouchEvent
.touches
.Length(); i
++) {
57 const Touch
* domTouch
= aTouchEvent
.touches
[i
];
59 // Extract data from weird interfaces.
60 int32_t identifier
= domTouch
->Identifier();
61 int32_t radiusX
= domTouch
->RadiusX();
62 int32_t radiusY
= domTouch
->RadiusY();
63 float rotationAngle
= domTouch
->RotationAngle();
64 float force
= domTouch
->Force();
66 SingleTouchData
data(identifier
,
67 ScreenIntPoint::FromUnknownPoint(
68 gfx::IntPoint(domTouch
->mRefPoint
.x
,
69 domTouch
->mRefPoint
.y
)),
70 ScreenSize(radiusX
, radiusY
),
74 mTouches
.AppendElement(data
);
79 MultiTouchInput::ToWidgetTouchEvent(nsIWidget
* aWidget
) const
81 NS_ABORT_IF_FALSE(NS_IsMainThread(),
82 "Can only convert To WidgetTouchEvent on main thread");
84 uint32_t touchType
= NS_EVENT_NULL
;
86 case MULTITOUCH_START
:
87 touchType
= NS_TOUCH_START
;
90 touchType
= NS_TOUCH_MOVE
;
93 touchType
= NS_TOUCH_END
;
95 case MULTITOUCH_CANCEL
:
96 touchType
= NS_TOUCH_CANCEL
;
99 MOZ_ASSERT_UNREACHABLE("Did not assign a type to WidgetTouchEvent in MultiTouchInput");
103 WidgetTouchEvent
event(true, touchType
, aWidget
);
104 if (touchType
== NS_EVENT_NULL
) {
108 event
.modifiers
= this->modifiers
;
109 event
.time
= this->mTime
;
110 event
.timeStamp
= this->mTimeStamp
;
112 for (size_t i
= 0; i
< mTouches
.Length(); i
++) {
113 *event
.touches
.AppendElement() = mTouches
[i
].ToNewDOMTouch();
120 MultiTouchInput::ToWidgetMouseEvent(nsIWidget
* aWidget
) const
122 NS_ABORT_IF_FALSE(NS_IsMainThread(),
123 "Can only convert To WidgetMouseEvent on main thread");
125 uint32_t mouseEventType
= NS_EVENT_NULL
;
127 case MultiTouchInput::MULTITOUCH_START
:
128 mouseEventType
= NS_MOUSE_BUTTON_DOWN
;
130 case MultiTouchInput::MULTITOUCH_MOVE
:
131 mouseEventType
= NS_MOUSE_MOVE
;
133 case MultiTouchInput::MULTITOUCH_CANCEL
:
134 case MultiTouchInput::MULTITOUCH_END
:
135 mouseEventType
= NS_MOUSE_BUTTON_UP
;
138 MOZ_ASSERT_UNREACHABLE("Did not assign a type to WidgetMouseEvent");
142 WidgetMouseEvent
event(true, mouseEventType
, aWidget
,
143 WidgetMouseEvent::eReal
, WidgetMouseEvent::eNormal
);
145 const SingleTouchData
& firstTouch
= mTouches
[0];
146 event
.refPoint
.x
= firstTouch
.mScreenPoint
.x
;
147 event
.refPoint
.y
= firstTouch
.mScreenPoint
.y
;
150 event
.button
= WidgetMouseEvent::eLeftButton
;
151 event
.inputSource
= nsIDOMMouseEvent::MOZ_SOURCE_TOUCH
;
152 event
.modifiers
= modifiers
;
154 if (mouseEventType
!= NS_MOUSE_MOVE
) {
155 event
.clickCount
= 1;
162 MultiTouchInput::IndexOfTouch(int32_t aTouchIdentifier
)
164 for (size_t i
= 0; i
< mTouches
.Length(); i
++) {
165 if (mTouches
[i
].mIdentifier
== aTouchIdentifier
) {
172 // This conversion from WidgetMouseEvent to MultiTouchInput is needed because on
173 // the B2G emulator we can only receive mouse events, but we need to be able
174 // to pan correctly. To do this, we convert the events into a format that the
175 // panning code can handle. This code is very limited and only supports
176 // SingleTouchData. It also sends garbage for the identifier, radius, force
177 // and rotation angle.
178 MultiTouchInput::MultiTouchInput(const WidgetMouseEvent
& aMouseEvent
)
179 : InputData(MULTITOUCH_INPUT
, aMouseEvent
.time
, aMouseEvent
.timeStamp
,
180 aMouseEvent
.modifiers
)
182 NS_ABORT_IF_FALSE(NS_IsMainThread(),
183 "Can only copy from WidgetMouseEvent on main thread");
184 switch (aMouseEvent
.message
) {
185 case NS_MOUSE_BUTTON_DOWN
:
186 mType
= MULTITOUCH_START
;
189 mType
= MULTITOUCH_MOVE
;
191 case NS_MOUSE_BUTTON_UP
:
192 mType
= MULTITOUCH_END
;
194 // The mouse pointer has been interrupted in an implementation-specific
195 // manner, such as a synchronous event or action cancelling the touch, or a
196 // touch point leaving the document window and going into a non-document
197 // area capable of handling user interactions.
199 mType
= MULTITOUCH_CANCEL
;
202 NS_WARNING("Did not assign a type to a MultiTouchInput");
206 mTouches
.AppendElement(SingleTouchData(0,
207 ScreenIntPoint::FromUnknownPoint(
208 gfx::IntPoint(aMouseEvent
.refPoint
.x
,
209 aMouseEvent
.refPoint
.y
)),
216 MultiTouchInput::TransformToLocal(const gfx::Matrix4x4
& aTransform
)
218 for (size_t i
= 0; i
< mTouches
.Length(); i
++) {
219 mTouches
[i
].mLocalScreenPoint
= TransformTo
<ParentLayerPixel
>(aTransform
, ScreenPoint(mTouches
[i
].mScreenPoint
));
224 PanGestureInput::TransformToLocal(const gfx::Matrix4x4
& aTransform
)
226 mLocalPanStartPoint
= TransformTo
<ParentLayerPixel
>(aTransform
, mPanStartPoint
);
227 mLocalPanDisplacement
= TransformVector
<ParentLayerPixel
>(aTransform
, mPanDisplacement
, mPanStartPoint
);
231 PinchGestureInput::TransformToLocal(const gfx::Matrix4x4
& aTransform
)
233 mLocalFocusPoint
= TransformTo
<ParentLayerPixel
>(aTransform
, mFocusPoint
);
237 TapGestureInput::TransformToLocal(const gfx::Matrix4x4
& aTransform
)
239 mLocalPoint
= TransformTo
<ParentLayerPixel
>(aTransform
, mPoint
);
243 ScrollWheelInput::TransformToLocal(const gfx::Matrix4x4
& aTransform
)
245 mLocalOrigin
= TransformTo
<ParentLayerPixel
>(aTransform
, mOrigin
);
248 } // namespace mozilla