summaryrefslogtreecommitdiffstats
path: root/widget/InputData.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'widget/InputData.cpp')
-rw-r--r--widget/InputData.cpp777
1 files changed, 777 insertions, 0 deletions
diff --git a/widget/InputData.cpp b/widget/InputData.cpp
new file mode 100644
index 000000000..70072778d
--- /dev/null
+++ b/widget/InputData.cpp
@@ -0,0 +1,777 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "InputData.h"
+
+#include "mozilla/dom/Touch.h"
+#include "nsDebug.h"
+#include "nsThreadUtils.h"
+#include "mozilla/MouseEvents.h"
+#include "mozilla/TouchEvents.h"
+#include "UnitTransforms.h"
+
+namespace mozilla {
+
+using namespace dom;
+
+InputData::~InputData()
+{
+}
+
+InputData::InputData(InputType aInputType)
+ : mInputType(aInputType)
+ , mTime(0)
+ , modifiers(0)
+{
+}
+
+InputData::InputData(InputType aInputType, uint32_t aTime, TimeStamp aTimeStamp,
+ Modifiers aModifiers)
+ : mInputType(aInputType)
+ , mTime(aTime)
+ , mTimeStamp(aTimeStamp)
+ , modifiers(aModifiers)
+{
+}
+
+SingleTouchData::SingleTouchData(int32_t aIdentifier, ScreenIntPoint aScreenPoint,
+ ScreenSize aRadius, float aRotationAngle,
+ float aForce)
+ : mIdentifier(aIdentifier)
+ , mScreenPoint(aScreenPoint)
+ , mRadius(aRadius)
+ , mRotationAngle(aRotationAngle)
+ , mForce(aForce)
+{
+}
+
+SingleTouchData::SingleTouchData(int32_t aIdentifier,
+ ParentLayerPoint aLocalScreenPoint,
+ ScreenSize aRadius, float aRotationAngle,
+ float aForce)
+ : mIdentifier(aIdentifier)
+ , mLocalScreenPoint(aLocalScreenPoint)
+ , mRadius(aRadius)
+ , mRotationAngle(aRotationAngle)
+ , mForce(aForce)
+{
+}
+
+SingleTouchData::SingleTouchData()
+{
+}
+
+already_AddRefed<Touch> SingleTouchData::ToNewDOMTouch() const
+{
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Can only create dom::Touch instances on main thread");
+ RefPtr<Touch> touch = new Touch(mIdentifier,
+ LayoutDeviceIntPoint::Truncate(mScreenPoint.x, mScreenPoint.y),
+ LayoutDeviceIntPoint::Truncate(mRadius.width, mRadius.height),
+ mRotationAngle,
+ mForce);
+ return touch.forget();
+}
+
+MultiTouchInput::MultiTouchInput(MultiTouchType aType, uint32_t aTime,
+ TimeStamp aTimeStamp, Modifiers aModifiers)
+ : InputData(MULTITOUCH_INPUT, aTime, aTimeStamp, aModifiers)
+ , mType(aType)
+ , mHandledByAPZ(false)
+{
+}
+
+MultiTouchInput::MultiTouchInput()
+ : InputData(MULTITOUCH_INPUT)
+ , mHandledByAPZ(false)
+{
+}
+
+MultiTouchInput::MultiTouchInput(const MultiTouchInput& aOther)
+ : InputData(MULTITOUCH_INPUT, aOther.mTime, aOther.mTimeStamp, aOther.modifiers)
+ , mType(aOther.mType)
+ , mHandledByAPZ(aOther.mHandledByAPZ)
+{
+ mTouches.AppendElements(aOther.mTouches);
+}
+
+MultiTouchInput::MultiTouchInput(const WidgetTouchEvent& aTouchEvent)
+ : InputData(MULTITOUCH_INPUT, aTouchEvent.mTime, aTouchEvent.mTimeStamp,
+ aTouchEvent.mModifiers)
+ , mHandledByAPZ(aTouchEvent.mFlags.mHandledByAPZ)
+{
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Can only copy from WidgetTouchEvent on main thread");
+
+ switch (aTouchEvent.mMessage) {
+ case eTouchStart:
+ mType = MULTITOUCH_START;
+ break;
+ case eTouchMove:
+ mType = MULTITOUCH_MOVE;
+ break;
+ case eTouchEnd:
+ mType = MULTITOUCH_END;
+ break;
+ case eTouchCancel:
+ mType = MULTITOUCH_CANCEL;
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Did not assign a type to a MultiTouchInput");
+ break;
+ }
+
+ for (size_t i = 0; i < aTouchEvent.mTouches.Length(); i++) {
+ const Touch* domTouch = aTouchEvent.mTouches[i];
+
+ // Extract data from weird interfaces.
+ int32_t identifier = domTouch->Identifier();
+ int32_t radiusX = domTouch->RadiusX();
+ int32_t radiusY = domTouch->RadiusY();
+ float rotationAngle = domTouch->RotationAngle();
+ float force = domTouch->Force();
+
+ SingleTouchData data(identifier,
+ ViewAs<ScreenPixel>(domTouch->mRefPoint,
+ PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent),
+ ScreenSize(radiusX, radiusY),
+ rotationAngle,
+ force);
+
+ mTouches.AppendElement(data);
+ }
+}
+
+MultiTouchInput::MultiTouchInput(const WidgetMouseEvent& aMouseEvent)
+ : InputData(MULTITOUCH_INPUT, aMouseEvent.mTime, aMouseEvent.mTimeStamp,
+ aMouseEvent.mModifiers)
+ , mHandledByAPZ(aMouseEvent.mFlags.mHandledByAPZ)
+{
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Can only copy from WidgetMouseEvent on main thread");
+ switch (aMouseEvent.mMessage) {
+ case eMouseDown:
+ mType = MULTITOUCH_START;
+ break;
+ case eMouseMove:
+ mType = MULTITOUCH_MOVE;
+ break;
+ case eMouseUp:
+ mType = MULTITOUCH_END;
+ break;
+ // The mouse pointer has been interrupted in an implementation-specific
+ // manner, such as a synchronous event or action cancelling the touch, or a
+ // touch point leaving the document window and going into a non-document
+ // area capable of handling user interactions.
+ case eMouseExitFromWidget:
+ mType = MULTITOUCH_CANCEL;
+ break;
+ default:
+ NS_WARNING("Did not assign a type to a MultiTouchInput");
+ break;
+ }
+
+ mTouches.AppendElement(SingleTouchData(0,
+ ViewAs<ScreenPixel>(aMouseEvent.mRefPoint,
+ PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent),
+ ScreenSize(1, 1),
+ 180.0f,
+ 1.0f));
+}
+
+WidgetTouchEvent
+MultiTouchInput::ToWidgetTouchEvent(nsIWidget* aWidget) const
+{
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Can only convert To WidgetTouchEvent on main thread");
+
+ EventMessage touchEventMessage = eVoidEvent;
+ switch (mType) {
+ case MULTITOUCH_START:
+ touchEventMessage = eTouchStart;
+ break;
+ case MULTITOUCH_MOVE:
+ touchEventMessage = eTouchMove;
+ break;
+ case MULTITOUCH_END:
+ touchEventMessage = eTouchEnd;
+ break;
+ case MULTITOUCH_CANCEL:
+ touchEventMessage = eTouchCancel;
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Did not assign a type to WidgetTouchEvent in MultiTouchInput");
+ break;
+ }
+
+ WidgetTouchEvent event(true, touchEventMessage, aWidget);
+ if (touchEventMessage == eVoidEvent) {
+ return event;
+ }
+
+ event.mModifiers = this->modifiers;
+ event.mTime = this->mTime;
+ event.mTimeStamp = this->mTimeStamp;
+ event.mFlags.mHandledByAPZ = mHandledByAPZ;
+
+ for (size_t i = 0; i < mTouches.Length(); i++) {
+ *event.mTouches.AppendElement() = mTouches[i].ToNewDOMTouch();
+ }
+
+ return event;
+}
+
+WidgetMouseEvent
+MultiTouchInput::ToWidgetMouseEvent(nsIWidget* aWidget) const
+{
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Can only convert To WidgetMouseEvent on main thread");
+
+ EventMessage mouseEventMessage = eVoidEvent;
+ switch (mType) {
+ case MultiTouchInput::MULTITOUCH_START:
+ mouseEventMessage = eMouseDown;
+ break;
+ case MultiTouchInput::MULTITOUCH_MOVE:
+ mouseEventMessage = eMouseMove;
+ break;
+ case MultiTouchInput::MULTITOUCH_CANCEL:
+ case MultiTouchInput::MULTITOUCH_END:
+ mouseEventMessage = eMouseUp;
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Did not assign a type to WidgetMouseEvent");
+ break;
+ }
+
+ WidgetMouseEvent event(true, mouseEventMessage, aWidget,
+ WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
+
+ const SingleTouchData& firstTouch = mTouches[0];
+ event.mRefPoint.x = firstTouch.mScreenPoint.x;
+ event.mRefPoint.y = firstTouch.mScreenPoint.y;
+
+ event.mTime = mTime;
+ event.button = WidgetMouseEvent::eLeftButton;
+ event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
+ event.mModifiers = modifiers;
+ event.mFlags.mHandledByAPZ = mHandledByAPZ;
+
+ if (mouseEventMessage != eMouseMove) {
+ event.mClickCount = 1;
+ }
+
+ return event;
+}
+
+int32_t
+MultiTouchInput::IndexOfTouch(int32_t aTouchIdentifier)
+{
+ for (size_t i = 0; i < mTouches.Length(); i++) {
+ if (mTouches[i].mIdentifier == aTouchIdentifier) {
+ return (int32_t)i;
+ }
+ }
+ return -1;
+}
+
+bool
+MultiTouchInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
+{
+ for (size_t i = 0; i < mTouches.Length(); i++) {
+ Maybe<ParentLayerIntPoint> point = UntransformBy(aTransform, mTouches[i].mScreenPoint);
+ if (!point) {
+ return false;
+ }
+ mTouches[i].mLocalScreenPoint = *point;
+ }
+ return true;
+}
+
+MouseInput::MouseInput()
+ : InputData(MOUSE_INPUT)
+ , mType(MOUSE_NONE)
+ , mButtonType(NONE)
+ , mInputSource(0)
+ , mButtons(0)
+ , mHandledByAPZ(false)
+{
+}
+
+MouseInput::MouseInput(MouseType aType, ButtonType aButtonType,
+ uint16_t aInputSource, int16_t aButtons,
+ const ScreenPoint& aPoint, uint32_t aTime,
+ TimeStamp aTimeStamp, Modifiers aModifiers)
+ : InputData(MOUSE_INPUT, aTime, aTimeStamp, aModifiers)
+ , mType(aType)
+ , mButtonType(aButtonType)
+ , mInputSource(aInputSource)
+ , mButtons(aButtons)
+ , mOrigin(aPoint)
+ , mHandledByAPZ(false)
+{
+}
+
+MouseInput::MouseInput(const WidgetMouseEventBase& aMouseEvent)
+ : InputData(MOUSE_INPUT, aMouseEvent.mTime, aMouseEvent.mTimeStamp,
+ aMouseEvent.mModifiers)
+ , mType(MOUSE_NONE)
+ , mButtonType(NONE)
+ , mInputSource(aMouseEvent.inputSource)
+ , mButtons(aMouseEvent.buttons)
+ , mHandledByAPZ(aMouseEvent.mFlags.mHandledByAPZ)
+{
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Can only copy from WidgetTouchEvent on main thread");
+
+ mButtonType = NONE;
+
+ switch (aMouseEvent.button) {
+ case WidgetMouseEventBase::eLeftButton:
+ mButtonType = MouseInput::LEFT_BUTTON;
+ break;
+ case WidgetMouseEventBase::eMiddleButton:
+ mButtonType = MouseInput::MIDDLE_BUTTON;
+ break;
+ case WidgetMouseEventBase::eRightButton:
+ mButtonType = MouseInput::RIGHT_BUTTON;
+ break;
+ }
+
+ switch (aMouseEvent.mMessage) {
+ case eMouseMove:
+ mType = MOUSE_MOVE;
+ break;
+ case eMouseUp:
+ mType = MOUSE_UP;
+ break;
+ case eMouseDown:
+ mType = MOUSE_DOWN;
+ break;
+ case eDragStart:
+ mType = MOUSE_DRAG_START;
+ break;
+ case eDragEnd:
+ mType = MOUSE_DRAG_END;
+ break;
+ case eMouseEnterIntoWidget:
+ mType = MOUSE_WIDGET_ENTER;
+ break;
+ case eMouseExitFromWidget:
+ mType = MOUSE_WIDGET_EXIT;
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Mouse event type not supported");
+ break;
+ }
+
+ mOrigin =
+ ScreenPoint(ViewAs<ScreenPixel>(aMouseEvent.mRefPoint,
+ PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
+}
+
+bool
+MouseInput::IsLeftButton() const
+{
+ return mButtonType == LEFT_BUTTON;
+}
+
+bool
+MouseInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
+{
+ Maybe<ParentLayerPoint> point = UntransformBy(aTransform, mOrigin);
+ if (!point) {
+ return false;
+ }
+ mLocalOrigin = *point;
+
+ return true;
+}
+
+WidgetMouseEvent
+MouseInput::ToWidgetMouseEvent(nsIWidget* aWidget) const
+{
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Can only convert To WidgetTouchEvent on main thread");
+
+ EventMessage msg = eVoidEvent;
+ uint32_t clickCount = 0;
+ switch (mType) {
+ case MOUSE_MOVE:
+ msg = eMouseMove;
+ break;
+ case MOUSE_UP:
+ msg = eMouseUp;
+ clickCount = 1;
+ break;
+ case MOUSE_DOWN:
+ msg = eMouseDown;
+ clickCount = 1;
+ break;
+ case MOUSE_DRAG_START:
+ msg = eDragStart;
+ break;
+ case MOUSE_DRAG_END:
+ msg = eDragEnd;
+ break;
+ case MOUSE_WIDGET_ENTER:
+ msg = eMouseEnterIntoWidget;
+ break;
+ case MOUSE_WIDGET_EXIT:
+ msg = eMouseExitFromWidget;
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Did not assign a type to WidgetMouseEvent in MouseInput");
+ break;
+ }
+
+ WidgetMouseEvent event(true, msg, aWidget, WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
+
+ if (msg == eVoidEvent) {
+ return event;
+ }
+
+ switch (mButtonType) {
+ case MouseInput::LEFT_BUTTON:
+ event.button = WidgetMouseEventBase::eLeftButton;
+ break;
+ case MouseInput::MIDDLE_BUTTON:
+ event.button = WidgetMouseEventBase::eMiddleButton;
+ break;
+ case MouseInput::RIGHT_BUTTON:
+ event.button = WidgetMouseEventBase::eRightButton;
+ break;
+ case MouseInput::NONE:
+ default:
+ break;
+ }
+
+ event.buttons = mButtons;
+ event.mModifiers = modifiers;
+ event.mTime = mTime;
+ event.mTimeStamp = mTimeStamp;
+ event.mFlags.mHandledByAPZ = mHandledByAPZ;
+ event.mRefPoint =
+ RoundedToInt(ViewAs<LayoutDevicePixel>(mOrigin,
+ PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
+ event.mClickCount = clickCount;
+ event.inputSource = mInputSource;
+ event.mIgnoreRootScrollFrame = true;
+
+ return event;
+}
+
+PanGestureInput::PanGestureInput()
+ : InputData(PANGESTURE_INPUT)
+ , mLineOrPageDeltaX(0)
+ , mLineOrPageDeltaY(0)
+ , mUserDeltaMultiplierX(1.0)
+ , mUserDeltaMultiplierY(1.0)
+ , mHandledByAPZ(false)
+ , mFollowedByMomentum(false)
+ , mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(false)
+{
+}
+
+PanGestureInput::PanGestureInput(PanGestureType aType, uint32_t aTime,
+ TimeStamp aTimeStamp,
+ const ScreenPoint& aPanStartPoint,
+ const ScreenPoint& aPanDisplacement,
+ Modifiers aModifiers)
+ : InputData(PANGESTURE_INPUT, aTime, aTimeStamp, aModifiers)
+ , mType(aType)
+ , mPanStartPoint(aPanStartPoint)
+ , mPanDisplacement(aPanDisplacement)
+ , mLineOrPageDeltaX(0)
+ , mLineOrPageDeltaY(0)
+ , mUserDeltaMultiplierX(1.0)
+ , mUserDeltaMultiplierY(1.0)
+ , mHandledByAPZ(false)
+ , mFollowedByMomentum(false)
+ , mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(false)
+{
+}
+
+bool
+PanGestureInput::IsMomentum() const
+{
+ switch (mType) {
+ case PanGestureInput::PANGESTURE_MOMENTUMSTART:
+ case PanGestureInput::PANGESTURE_MOMENTUMPAN:
+ case PanGestureInput::PANGESTURE_MOMENTUMEND:
+ return true;
+ default:
+ return false;
+ }
+}
+
+WidgetWheelEvent
+PanGestureInput::ToWidgetWheelEvent(nsIWidget* aWidget) const
+{
+ WidgetWheelEvent wheelEvent(true, eWheel, aWidget);
+ wheelEvent.mModifiers = this->modifiers;
+ wheelEvent.mTime = mTime;
+ wheelEvent.mTimeStamp = mTimeStamp;
+ wheelEvent.mRefPoint =
+ RoundedToInt(ViewAs<LayoutDevicePixel>(mPanStartPoint,
+ PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
+ wheelEvent.buttons = 0;
+ wheelEvent.mDeltaMode = nsIDOMWheelEvent::DOM_DELTA_PIXEL;
+ wheelEvent.mMayHaveMomentum = true; // pan inputs may have momentum
+ wheelEvent.mIsMomentum = IsMomentum();
+ wheelEvent.mLineOrPageDeltaX = mLineOrPageDeltaX;
+ wheelEvent.mLineOrPageDeltaY = mLineOrPageDeltaY;
+ wheelEvent.mDeltaX = mPanDisplacement.x;
+ wheelEvent.mDeltaY = mPanDisplacement.y;
+ wheelEvent.mFlags.mHandledByAPZ = mHandledByAPZ;
+ return wheelEvent;
+}
+
+bool
+PanGestureInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
+{
+ Maybe<ParentLayerPoint> panStartPoint = UntransformBy(aTransform, mPanStartPoint);
+ if (!panStartPoint) {
+ return false;
+ }
+ mLocalPanStartPoint = *panStartPoint;
+
+ Maybe<ParentLayerPoint> panDisplacement = UntransformVector(aTransform, mPanDisplacement, mPanStartPoint);
+ if (!panDisplacement) {
+ return false;
+ }
+ mLocalPanDisplacement = *panDisplacement;
+ return true;
+}
+
+ScreenPoint
+PanGestureInput::UserMultipliedPanDisplacement() const
+{
+ return ScreenPoint(mPanDisplacement.x * mUserDeltaMultiplierX,
+ mPanDisplacement.y * mUserDeltaMultiplierY);
+}
+
+ParentLayerPoint
+PanGestureInput::UserMultipliedLocalPanDisplacement() const
+{
+ return ParentLayerPoint(mLocalPanDisplacement.x * mUserDeltaMultiplierX,
+ mLocalPanDisplacement.y * mUserDeltaMultiplierY);
+}
+
+PinchGestureInput::PinchGestureInput()
+ : InputData(PINCHGESTURE_INPUT)
+{
+}
+
+PinchGestureInput::PinchGestureInput(PinchGestureType aType, uint32_t aTime,
+ TimeStamp aTimeStamp,
+ const ParentLayerPoint& aLocalFocusPoint,
+ ParentLayerCoord aCurrentSpan,
+ ParentLayerCoord aPreviousSpan,
+ Modifiers aModifiers)
+ : InputData(PINCHGESTURE_INPUT, aTime, aTimeStamp, aModifiers)
+ , mType(aType)
+ , mLocalFocusPoint(aLocalFocusPoint)
+ , mCurrentSpan(aCurrentSpan)
+ , mPreviousSpan(aPreviousSpan)
+{
+}
+
+bool
+PinchGestureInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
+{
+ Maybe<ParentLayerPoint> point = UntransformBy(aTransform, mFocusPoint);
+ if (!point) {
+ return false;
+ }
+ mLocalFocusPoint = *point;
+ return true;
+}
+
+TapGestureInput::TapGestureInput()
+ : InputData(TAPGESTURE_INPUT)
+{
+}
+
+TapGestureInput::TapGestureInput(TapGestureType aType, uint32_t aTime,
+ TimeStamp aTimeStamp,
+ const ScreenIntPoint& aPoint,
+ Modifiers aModifiers)
+ : InputData(TAPGESTURE_INPUT, aTime, aTimeStamp, aModifiers)
+ , mType(aType)
+ , mPoint(aPoint)
+{
+}
+
+TapGestureInput::TapGestureInput(TapGestureType aType, uint32_t aTime,
+ TimeStamp aTimeStamp,
+ const ParentLayerPoint& aLocalPoint,
+ Modifiers aModifiers)
+ : InputData(TAPGESTURE_INPUT, aTime, aTimeStamp, aModifiers)
+ , mType(aType)
+ , mLocalPoint(aLocalPoint)
+{
+}
+
+bool
+TapGestureInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
+{
+ Maybe<ParentLayerIntPoint> point = UntransformBy(aTransform, mPoint);
+ if (!point) {
+ return false;
+ }
+ mLocalPoint = *point;
+ return true;
+}
+
+ScrollWheelInput::ScrollWheelInput()
+ : InputData(SCROLLWHEEL_INPUT)
+ , mHandledByAPZ(false)
+ , mLineOrPageDeltaX(0)
+ , mLineOrPageDeltaY(0)
+ , mScrollSeriesNumber(0)
+ , mUserDeltaMultiplierX(1.0)
+ , mUserDeltaMultiplierY(1.0)
+ , mMayHaveMomentum(false)
+ , mIsMomentum(false)
+{
+}
+
+ScrollWheelInput::ScrollWheelInput(uint32_t aTime, TimeStamp aTimeStamp,
+ Modifiers aModifiers, ScrollMode aScrollMode,
+ ScrollDeltaType aDeltaType,
+ const ScreenPoint& aOrigin, double aDeltaX,
+ double aDeltaY,
+ bool aAllowToOverrideSystemScrollSpeed)
+ : InputData(SCROLLWHEEL_INPUT, aTime, aTimeStamp, aModifiers)
+ , mDeltaType(aDeltaType)
+ , mScrollMode(aScrollMode)
+ , mOrigin(aOrigin)
+ , mHandledByAPZ(false)
+ , mDeltaX(aDeltaX)
+ , mDeltaY(aDeltaY)
+ , mLineOrPageDeltaX(0)
+ , mLineOrPageDeltaY(0)
+ , mScrollSeriesNumber(0)
+ , mUserDeltaMultiplierX(1.0)
+ , mUserDeltaMultiplierY(1.0)
+ , mMayHaveMomentum(false)
+ , mIsMomentum(false)
+ , mAllowToOverrideSystemScrollSpeed(aAllowToOverrideSystemScrollSpeed)
+{
+}
+
+ScrollWheelInput::ScrollWheelInput(const WidgetWheelEvent& aWheelEvent)
+ : InputData(SCROLLWHEEL_INPUT, aWheelEvent.mTime, aWheelEvent.mTimeStamp,
+ aWheelEvent.mModifiers)
+ , mDeltaType(DeltaTypeForDeltaMode(aWheelEvent.mDeltaMode))
+ , mScrollMode(SCROLLMODE_INSTANT)
+ , mHandledByAPZ(aWheelEvent.mFlags.mHandledByAPZ)
+ , mDeltaX(aWheelEvent.mDeltaX)
+ , mDeltaY(aWheelEvent.mDeltaY)
+ , mLineOrPageDeltaX(aWheelEvent.mLineOrPageDeltaX)
+ , mLineOrPageDeltaY(aWheelEvent.mLineOrPageDeltaY)
+ , mScrollSeriesNumber(0)
+ , mUserDeltaMultiplierX(1.0)
+ , mUserDeltaMultiplierY(1.0)
+ , mMayHaveMomentum(aWheelEvent.mMayHaveMomentum)
+ , mIsMomentum(aWheelEvent.mIsMomentum)
+ , mAllowToOverrideSystemScrollSpeed(
+ aWheelEvent.mAllowToOverrideSystemScrollSpeed)
+{
+ mOrigin =
+ ScreenPoint(ViewAs<ScreenPixel>(aWheelEvent.mRefPoint,
+ PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
+}
+
+ScrollWheelInput::ScrollDeltaType
+ScrollWheelInput::DeltaTypeForDeltaMode(uint32_t aDeltaMode)
+{
+ switch (aDeltaMode) {
+ case nsIDOMWheelEvent::DOM_DELTA_LINE:
+ return SCROLLDELTA_LINE;
+ case nsIDOMWheelEvent::DOM_DELTA_PAGE:
+ return SCROLLDELTA_PAGE;
+ case nsIDOMWheelEvent::DOM_DELTA_PIXEL:
+ return SCROLLDELTA_PIXEL;
+ default:
+ MOZ_CRASH();
+ }
+ return SCROLLDELTA_LINE;
+}
+
+uint32_t
+ScrollWheelInput::DeltaModeForDeltaType(ScrollDeltaType aDeltaType)
+{
+ switch (aDeltaType) {
+ case ScrollWheelInput::SCROLLDELTA_LINE:
+ return nsIDOMWheelEvent::DOM_DELTA_LINE;
+ case ScrollWheelInput::SCROLLDELTA_PAGE:
+ return nsIDOMWheelEvent::DOM_DELTA_PAGE;
+ case ScrollWheelInput::SCROLLDELTA_PIXEL:
+ default:
+ return nsIDOMWheelEvent::DOM_DELTA_PIXEL;
+ }
+}
+
+nsIScrollableFrame::ScrollUnit
+ScrollWheelInput::ScrollUnitForDeltaType(ScrollDeltaType aDeltaType)
+{
+ switch (aDeltaType) {
+ case SCROLLDELTA_LINE:
+ return nsIScrollableFrame::LINES;
+ case SCROLLDELTA_PAGE:
+ return nsIScrollableFrame::PAGES;
+ case SCROLLDELTA_PIXEL:
+ return nsIScrollableFrame::DEVICE_PIXELS;
+ default:
+ MOZ_CRASH();
+ }
+ return nsIScrollableFrame::LINES;
+}
+
+WidgetWheelEvent
+ScrollWheelInput::ToWidgetWheelEvent(nsIWidget* aWidget) const
+{
+ WidgetWheelEvent wheelEvent(true, eWheel, aWidget);
+ wheelEvent.mModifiers = this->modifiers;
+ wheelEvent.mTime = mTime;
+ wheelEvent.mTimeStamp = mTimeStamp;
+ wheelEvent.mRefPoint =
+ RoundedToInt(ViewAs<LayoutDevicePixel>(mOrigin,
+ PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
+ wheelEvent.buttons = 0;
+ wheelEvent.mDeltaMode = DeltaModeForDeltaType(mDeltaType);
+ wheelEvent.mMayHaveMomentum = mMayHaveMomentum;
+ wheelEvent.mIsMomentum = mIsMomentum;
+ wheelEvent.mDeltaX = mDeltaX;
+ wheelEvent.mDeltaY = mDeltaY;
+ wheelEvent.mLineOrPageDeltaX = mLineOrPageDeltaX;
+ wheelEvent.mLineOrPageDeltaY = mLineOrPageDeltaY;
+ wheelEvent.mAllowToOverrideSystemScrollSpeed =
+ mAllowToOverrideSystemScrollSpeed;
+ wheelEvent.mFlags.mHandledByAPZ = mHandledByAPZ;
+ return wheelEvent;
+}
+
+bool
+ScrollWheelInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
+{
+ Maybe<ParentLayerPoint> point = UntransformBy(aTransform, mOrigin);
+ if (!point) {
+ return false;
+ }
+ mLocalOrigin = *point;
+ return true;
+}
+
+bool
+ScrollWheelInput::IsCustomizedByUserPrefs() const
+{
+ return mUserDeltaMultiplierX != 1.0 ||
+ mUserDeltaMultiplierY != 1.0;
+}
+
+} // namespace mozilla