diff options
Diffstat (limited to 'widget/InputData.cpp')
-rw-r--r-- | widget/InputData.cpp | 777 |
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 |