/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qquickevents_p_p.h"
#include <QtCore/qmap.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qtouchdevice_p.h>
#include <QtGui/private/qevent_p.h>
#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/private/qquickpointerhandler_p.h>
#include <QtQuick/private/qquickwindow_p.h>
#include <private/qdebug_p.h>

QT_BEGIN_NAMESPACE

Q_LOGGING_CATEGORY(lcPointerEvents, "qt.quick.pointer.events")
Q_LOGGING_CATEGORY(lcPointerGrab, "qt.quick.pointer.grab")

/*!
    \qmltype KeyEvent
    \instantiates QQuickKeyEvent
    \inqmlmodule QtQuick
    \ingroup qtquick-input-events

    \brief Provides information about a key event.

    For example, the following changes the Item's state property when the Enter
    key is pressed:
    \qml
Item {
    focus: true
    Keys.onPressed: { if (event.key == Qt.Key_Enter) state = 'ShowDetails'; }
}
    \endqml
*/

/*!
    \qmlproperty int QtQuick::KeyEvent::key

    This property holds the code of the key that was pressed or released.

    See \l {Qt::Key}{Qt.Key} for the list of keyboard codes. These codes are
    independent of the underlying window system. Note that this
    function does not distinguish between capital and non-capital
    letters; use the \l {KeyEvent::}{text} property for this purpose.

    A value of either 0 or \l {Qt::Key_unknown}{Qt.Key_Unknown} means that the event is not
    the result of a known key; for example, it may be the result of
    a compose sequence, a keyboard macro, or due to key event
    compression.
*/

/*!
    \qmlproperty string QtQuick::KeyEvent::text

    This property holds the Unicode text that the key generated.
    The text returned can be an empty string in cases where modifier keys,
    such as Shift, Control, Alt, and Meta, are being pressed or released.
    In such cases \c key will contain a valid value
*/

/*!
    \qmlproperty bool QtQuick::KeyEvent::isAutoRepeat

    This property holds whether this event comes from an auto-repeating key.
*/

/*!
    \qmlproperty quint32 QtQuick::KeyEvent::nativeScanCode

    This property contains the native scan code of the key that was pressed. It is
    passed through from QKeyEvent unchanged.

    \sa QKeyEvent::nativeScanCode()
*/

/*!
    \qmlproperty int QtQuick::KeyEvent::count

    This property holds the number of keys involved in this event. If \l KeyEvent::text
    is not empty, this is simply the length of the string.
*/

/*!
    \qmlproperty bool QtQuick::KeyEvent::accepted

    Setting \a accepted to true prevents the key event from being
    propagated to the item's parent.

    Generally, if the item acts on the key event then it should be accepted
    so that ancestor items do not also respond to the same event.
*/

/*!
    \qmlproperty int QtQuick::KeyEvent::modifiers

    This property holds the keyboard modifier flags that existed immediately
    before the event occurred.

    It contains a bitwise combination of:
    \list
    \li \l {Qt::NoModifier} {Qt.NoModifier} - No modifier key is pressed.
    \li \l {Qt::ShiftModifier} {Qt.ShiftModifier} - A Shift key on the keyboard is pressed.
    \li \l {Qt::ControlModifier} {Qt.ControlModifier} - A Ctrl key on the keyboard is pressed.
    \li \l {Qt::AltModifier} {Qt.AltModifier} - An Alt key on the keyboard is pressed.
    \li \l {Qt::MetaModifier} {Qt.MetaModifier} - A Meta key on the keyboard is pressed.
    \li \l {Qt::KeypadModifier} {Qt.KeypadModifier} - A keypad button is pressed.
    \li \l {Qt::GroupSwitchModifier} {Qt.GroupSwitchModifier} - X11 only. A Mode_switch key on the keyboard is pressed.
    \endlist

    For example, to react to a Shift key + Enter key combination:
    \qml
    Item {
        focus: true
        Keys.onPressed: {
            if ((event.key == Qt.Key_Enter) && (event.modifiers & Qt.ShiftModifier))
                doSomething();
        }
    }
    \endqml
*/

/*!
    \qmlmethod bool QtQuick::KeyEvent::matches(StandardKey key)
    \since 5.2

    Returns \c true if the key event matches the given standard \a key; otherwise returns \c false.

    \qml
    Item {
        focus: true
        Keys.onPressed: {
            if (event.matches(StandardKey.Undo))
                myModel.undo();
            else if (event.matches(StandardKey.Redo))
                myModel.redo();
        }
    }
    \endqml

    \sa QKeySequence::StandardKey
*/

/*!
    \qmltype MouseEvent
    \instantiates QQuickMouseEvent
    \inqmlmodule QtQuick
    \ingroup qtquick-input-events

    \brief Provides information about a mouse event.

    The position of the mouse can be found via the \l {Item::x} {x} and \l {Item::y} {y} properties.
    The button that caused the event is available via the \l button property.

    \sa MouseArea
*/

/*!
    \internal
    \class QQuickMouseEvent
*/

/*!
    \qmlproperty real QtQuick::MouseEvent::x
    \qmlproperty real QtQuick::MouseEvent::y

    These properties hold the coordinates of the position supplied by the mouse event.
*/


/*!
    \qmlproperty bool QtQuick::MouseEvent::accepted

    Setting \a accepted to true prevents the mouse event from being
    propagated to items below this item.

    Generally, if the item acts on the mouse event then it should be accepted
    so that items lower in the stacking order do not also respond to the same event.
*/

/*!
    \qmlproperty enumeration QtQuick::MouseEvent::button

    This property holds the button that caused the event.  It can be one of:
    \list
    \li \l {Qt::LeftButton} {Qt.LeftButton}
    \li \l {Qt::RightButton} {Qt.RightButton}
    \li \l {Qt::MiddleButton} {Qt.MiddleButton}
    \endlist
*/

/*!
    \qmlproperty bool QtQuick::MouseEvent::wasHeld

    This property is true if the mouse button has been held pressed longer
    than the threshold (800ms).
*/

/*!
    \qmlproperty int QtQuick::MouseEvent::buttons

    This property holds the mouse buttons pressed when the event was generated.
    For mouse move events, this is all buttons that are pressed down. For mouse
    press and double click events this includes the button that caused the event.
    For mouse release events this excludes the button that caused the event.

    It contains a bitwise combination of:
    \list
    \li \l {Qt::LeftButton} {Qt.LeftButton}
    \li \l {Qt::RightButton} {Qt.RightButton}
    \li \l {Qt::MiddleButton} {Qt.MiddleButton}
    \endlist
*/

/*!
    \qmlproperty int QtQuick::MouseEvent::modifiers

    This property holds the keyboard modifier flags that existed immediately
    before the event occurred.

    It contains a bitwise combination of:
    \list
    \li \l {Qt::NoModifier} {Qt.NoModifier} - No modifier key is pressed.
    \li \l {Qt::ShiftModifier} {Qt.ShiftModifier} - A Shift key on the keyboard is pressed.
    \li \l {Qt::ControlModifier} {Qt.ControlModifier} - A Ctrl key on the keyboard is pressed.
    \li \l {Qt::AltModifier} {Qt.AltModifier} - An Alt key on the keyboard is pressed.
    \li \l {Qt::MetaModifier} {Qt.MetaModifier} - A Meta key on the keyboard is pressed.
    \li \l {Qt::KeypadModifier} {Qt.KeypadModifier} - A keypad button is pressed.
    \endlist

    For example, to react to a Shift key + Left mouse button click:
    \qml
    MouseArea {
        onClicked: {
            if ((mouse.button == Qt.LeftButton) && (mouse.modifiers & Qt.ShiftModifier))
                doSomething();
        }
    }
    \endqml
*/

/*!
    \qmlproperty int QtQuick::MouseEvent::source
    \since 5.7

    This property holds the source of the mouse event.

    The mouse event source can be used to distinguish between genuine and
    artificial mouse events. When using other pointing devices such as
    touchscreens and graphics tablets, if the application does not make use of
    the actual touch or tablet events, mouse events may be synthesized by the
    operating system or by Qt itself.

    The value can be one of:

    \list
    \li \l{Qt::MouseEventNotSynthesized} {Qt.MouseEventNotSynthesized}
    - The most common value. On platforms where such information is
    available, this value indicates that the event represents a genuine
    mouse event from the system.

    \li \l{Qt::MouseEventSynthesizedBySystem} {Qt.MouseEventSynthesizedBySystem} - Indicates that the mouse event was
    synthesized from a touch or tablet event by the platform.

    \li \l{Qt::MouseEventSynthesizedByQt} {Qt.MouseEventSynthesizedByQt}
    - Indicates that the mouse event was synthesized from an unhandled
    touch or tablet event by Qt.

    \li \l{Qt::MouseEventSynthesizedByApplication} {Qt.MouseEventSynthesizedByApplication}
    - Indicates that the mouse event was synthesized by the application.
    This allows distinguishing application-generated mouse events from
    the ones that are coming from the system or are synthesized by Qt.
    \endlist

    For example, to react only to events which come from an actual mouse:
    \qml
    MouseArea {
        onPressed: if (mouse.source !== Qt.MouseEventNotSynthesized) {
            mouse.accepted = false
        }

        onClicked: doSomething()
    }
    \endqml

    If the handler for the press event rejects the event, it will be propagated
    further, and then another Item underneath can handle synthesized events
    from touchscreens. For example, if a Flickable is used underneath (and the
    MouseArea is not a child of the Flickable), it can be useful for the
    MouseArea to handle genuine mouse events in one way, while allowing touch
    events to fall through to the Flickable underneath, so that the ability to
    flick on a touchscreen is retained. In that case the ability to drag the
    Flickable via mouse would be lost, but it does not prevent Flickable from
    receiving mouse wheel events.
*/

/*!
    \qmlproperty int QtQuick::MouseEvent::flags
    \since 5.11

    This property holds the flags that provide additional information about the
    mouse event.

    \list
    \li \l {Qt::MouseEventCreatedDoubleClick} {Qt.MouseEventCreatedDoubleClick}
    - Indicates that Qt has created a double click event from this event.
    This flag is set in the event originating from a button press, and not
    in the resulting double click event.
    \endlist
*/

/*!
    \qmltype WheelEvent
    \instantiates QQuickWheelEvent
    \inqmlmodule QtQuick
    \ingroup qtquick-input-events
    \brief Provides information about a mouse wheel event.

    The position of the mouse can be found via the
    \l {Item::x} {x} and \l {Item::y} {y} properties.

    \sa MouseArea
*/

/*!
    \internal
    \class QQuickWheelEvent
*/

/*!
    \qmlproperty real QtQuick::WheelEvent::x
    \qmlproperty real QtQuick::WheelEvent::y

    These properties hold the coordinates of the position supplied by the wheel event.
*/

/*!
    \qmlproperty bool QtQuick::WheelEvent::accepted

    Setting \a accepted to true prevents the wheel event from being
    propagated to items below this item.

    Generally, if the item acts on the wheel event then it should be accepted
    so that items lower in the stacking order do not also respond to the same event.
*/

/*!
    \qmlproperty int QtQuick::WheelEvent::buttons

    This property holds the mouse buttons pressed when the wheel event was generated.

    It contains a bitwise combination of:
    \list
    \li \l {Qt::LeftButton} {Qt.LeftButton}
    \li \l {Qt::RightButton} {Qt.RightButton}
    \li \l {Qt::MiddleButton} {Qt.MiddleButton}
    \endlist
*/

/*!
    \qmlproperty point QtQuick::WheelEvent::angleDelta

    This property holds the distance that the wheel is rotated in wheel degrees.
    The x and y cordinate of this property holds the delta in horizontal and
    vertical orientation.

    A positive value indicates that the wheel was rotated up/right;
    a negative value indicates that the wheel was rotated down/left.

    Most mouse types work in steps of 15 degrees, in which case the delta value is a
    multiple of 120; i.e., 120 units * 1/8 = 15 degrees.
*/

/*!
    \qmlproperty point QtQuick::WheelEvent::pixelDelta

    This property holds the delta in screen pixels and is available in platforms that
    have high-resolution trackpads, such as \macos.
    The x and y cordinate of this property holds the delta in horizontal and
    vertical orientation. The value should be used directly to scroll content on screen.

    For platforms without high-resolution trackpad support, pixelDelta will always be (0,0),
    and angleDelta should be used instead.
*/

/*!
    \qmlproperty int QtQuick::WheelEvent::modifiers

    This property holds the keyboard modifier flags that existed immediately
    before the event occurred.

    It contains a bitwise combination of:
    \list
    \li \l {Qt::NoModifier} {Qt.NoModifier} - No modifier key is pressed.
    \li \l {Qt::ShiftModifier} {Qt.ShiftModifier} - A Shift key on the keyboard is pressed.
    \li \l {Qt::ControlModifier} {Qt.ControlModifier} - A Ctrl key on the keyboard is pressed.
    \li \l {Qt::AltModifier} {Qt.AltModifier} - An Alt key on the keyboard is pressed.
    \li \l {Qt::MetaModifier} {Qt.MetaModifier} - A Meta key on the keyboard is pressed.
    \li \l {Qt::KeypadModifier} {Qt.KeypadModifier} - A keypad button is pressed.
    \endlist

    For example, to react to a Control key pressed during the wheel event:
    \qml
    MouseArea {
        onWheel: {
            if (wheel.modifiers & Qt.ControlModifier) {
                adjustZoom(wheel.angleDelta.y / 120);
            }
        }
    }
    \endqml
*/

/*!
    \qmlproperty bool QtQuick::WheelEvent::inverted

    Returns whether the delta values delivered with the event are inverted.

    Normally, a vertical wheel will produce a WheelEvent with positive delta
    values if the top of the wheel is rotating away from the hand operating it.
    Similarly, a horizontal wheel movement will produce a QWheelEvent with
    positive delta values if the top of the wheel is moved to the left.

    However, on some platforms this is configurable, so that the same
    operations described above will produce negative delta values (but with the
    same magnitude). For instance, in a QML component (such as a tumbler or a
    slider) where it is appropriate to synchronize the movement or rotation of
    an item with the direction of the wheel, regardless of the system settings,
    the wheel event handler can use the inverted property to decide whether to
    negate the angleDelta or pixelDelta values.

    \note Many platforms provide no such information. On such platforms
    \l inverted always returns false.
*/

/*!
    \qmltype PointerDevice
    \instantiates QQuickPointerDevice
    \inqmlmodule QtQuick
    \ingroup qtquick-input-events

    \brief Provides information about a pointing device.

    A pointing device can be a mouse, a touchscreen, or a stylus on a graphics
    tablet.

    \sa PointerEvent, PointerHandler
*/

/*!
    \readonly
    \qmlproperty enumeration QtQuick::PointerDevice::type

    This property holds the type of the pointing device.

    Valid values are:

    \value DeviceType.UnknownDevice
        the device cannot be identified
    \value DeviceType.Mouse
        a mouse
    \value DeviceType.TouchScreen
        a touchscreen providing absolute coordinates
    \value DeviceType.TouchPad
        a trackpad or touchpad providing relative coordinates
    \value DeviceType.Stylus
        a pen-like device
    \value DeviceType.Airbrush
        a stylus with a thumbwheel to adjust
        \l {QTabletEvent::tangentialPressure}{tangentialPressure}
    \value DeviceType.Puck
        a device that is similar to a flat mouse with a
        transparent circle with cross-hairs
        (same as \l {QTabletEvent::Puck} {Puck})
    \value DeviceType.AllDevices
        any of the above; used as a default value for construction

    \sa QTouchDevice::DeviceType
*/

/*!
    \readonly
    \qmlproperty enumeration QtQuick::PointerDevice::pointerType

    This property holds a value indicating what is interacting with
    the device. Think of the device as having a planar 2D surface, and
    the value of this property as identifying what interacts with the
    device.

    There is some redundancy between this property and \l {PointerDevice::type}.
    If a tocuchscreen is used, then the device is TouchScreen and
    pointerType is Finger (always).

    Valid values are:

    \value PointerDevice.GenericPointer
        a mouse or something acting like a mouse (the core pointer on X11)
    \value PointerDevice.Finger
        the user's finger
    \value PointerDevice.Pen
        the drawing end of a stylus
    \value PointerDevice.Eraser
        the other end of the stylus (if it has a virtual eraser on the other end)
    \value PointerDevice.Cursor
        a cursor in the pre-computer sense of the word
    \value PointerDevice.AllPointerTypes
        any of the above (used as a default value in constructors)
*/


/*!
    \readonly
    \qmlproperty enumeration QtQuick::PointerDevice::capabilities

    This property holds a bitwise combination of the capabilities of the
    pointing device. It tells you under which conditions events are sent,
    and which properties of PointerEvent are expected to be valid.

    Valid values are:

    \value CapabilityFlag.Position
        the \l {QtQuick::EventPoint::position}{position} and
        \l {QtQuick::EventPoint::scenePosition}{scenePosition} properties
    \value CapabilityFlag.Area
        the \l {QtQuick::EventTouchPoint::ellipseDiameters}{ellipseDiameters} property
    \value CapabilityFlag.Pressure
        the \l {QtQuick::EventTouchPoint::pressure}{pressure} property
    \value CapabilityFlag.Velocity
        the \l {QtQuick::EventPoint::velocity}{velocity} property
    \value CapabilityFlag.Scroll
        a \l {QtQuick::PointerDevice::type}{Mouse} has a wheel, or the
        operating system recognizes scroll gestures on a
        \l {QtQuick::PointerDevice::type}{TouchPad}
    \value CapabilityFlag.Hover
        events are sent even when no button is pressed, or the finger or stylus
        is not in contact with the surface
    \value CapabilityFlag.Rotation
        the \l {QtQuick::EventTouchPoint::rotation}{rotation} property
    \value CapabilityFlag.XTilt
        horizontal angle between a stylus and the axis perpendicular to the surface
    \value CapabilityFlag.YTilt
        vertical angle between a stylus and the axis perpendicular to the surface

    \sa QTouchDevice::capabilities
*/

typedef QHash<const QTouchDevice *, QQuickPointerDevice *> PointerDeviceForTouchDeviceHash;
Q_GLOBAL_STATIC(PointerDeviceForTouchDeviceHash, g_touchDevices)

struct ConstructableQQuickPointerDevice : public QQuickPointerDevice
{
    ConstructableQQuickPointerDevice(DeviceType devType, PointerType pType, Capabilities caps,
                              int maxPoints, int buttonCount, const QString &name,
                              qint64 uniqueId = 0)
        : QQuickPointerDevice(devType, pType, caps, maxPoints, buttonCount, name, uniqueId) {}

};
Q_GLOBAL_STATIC_WITH_ARGS(ConstructableQQuickPointerDevice, g_genericMouseDevice,
                            (QQuickPointerDevice::Mouse,
                             QQuickPointerDevice::GenericPointer,
                             QQuickPointerDevice::Position | QQuickPointerDevice::Scroll | QQuickPointerDevice::Hover,
                             1, 3, QLatin1String("core pointer"), 0))

#if QT_CONFIG(tabletevent)
typedef QHash<qint64, QQuickPointerDevice *> PointerDeviceForDeviceIdHash;
Q_GLOBAL_STATIC(PointerDeviceForDeviceIdHash, g_tabletDevices)
#endif

// debugging helpers
static const char *pointStateString(const QQuickEventPoint *point)
{
    static const QMetaEnum stateMetaEnum = point->metaObject()->enumerator(point->metaObject()->indexOfEnumerator("State"));
    return stateMetaEnum.valueToKey(point->state());
}

static const QString pointDeviceName(const QQuickEventPoint *point)
{
    auto device = static_cast<const QQuickPointerEvent *>(point->parent())->device();
    QString deviceName = (device ? device->name() : QLatin1String("null device"));
    deviceName.resize(16, ' '); // shorten, and align in case of sequential output
    return deviceName;
}


QQuickPointerDevice *QQuickPointerDevice::touchDevice(const QTouchDevice *d)
{
    if (g_touchDevices->contains(d))
        return g_touchDevices->value(d);

    QQuickPointerDevice::DeviceType type = QQuickPointerDevice::TouchScreen;
    QString name;
    int maximumTouchPoints = 10;
    QQuickPointerDevice::Capabilities caps = QQuickPointerDevice::Capabilities(QTouchDevice::Position);
    if (d) {
        caps = static_cast<QQuickPointerDevice::Capabilities>(static_cast<int>(d->capabilities()) & 0xFF);
        if (d->type() == QTouchDevice::TouchPad) {
            type = QQuickPointerDevice::TouchPad;
            caps |= QQuickPointerDevice::Scroll;
        }
        name = d->name();
        maximumTouchPoints = d->maximumTouchPoints();
    } else {
        qWarning() << "QQuickWindowPrivate::touchDevice: creating touch device from nullptr device in QTouchEvent";
    }

    QQuickPointerDevice *dev = new QQuickPointerDevice(type, QQuickPointerDevice::Finger,
        caps, maximumTouchPoints, 0, name, 0);
    g_touchDevices->insert(d, dev);
    return dev;
}

const QTouchDevice *QQuickPointerDevice::qTouchDevice() const
{
    return g_touchDevices->key(const_cast<QQuickPointerDevice *>(this));
}

QList<QQuickPointerDevice*> QQuickPointerDevice::touchDevices()
{
    return g_touchDevices->values();
}

QQuickPointerDevice *QQuickPointerDevice::genericMouseDevice()
{
    return g_genericMouseDevice;
}

#if QT_CONFIG(tabletevent)
QQuickPointerDevice *QQuickPointerDevice::tabletDevice(const QTabletEvent *event)
{
    // QTabletEvent::uniqueId() is the same for the pointy end and the eraser end of the stylus.
    // We need to make those unique. QTabletEvent::PointerType only needs 2 bits' worth of storage.
    // The key into g_tabletDevices just needs to be unique; we don't need to extract uniqueId
    // back out of it, because QQuickPointerDevice stores that separately anyway.
    // So the shift-and-add can be thought of as a sort of hash function, even though
    // most of the time the result will be recognizable because the uniqueId MSBs are often 0.
    qint64 key = event->uniqueId() + (qint64(event->pointerType()) << 60);
    auto it = g_tabletDevices->find(key);
    if (it != g_tabletDevices->end())
        return it.value();

    DeviceType type = UnknownDevice;
    int buttonCount = 0;
    Capabilities caps = Position | Pressure | Hover;
    // TODO Qt 6: we can't know for sure about XTilt or YTilt until we have a
    // QTabletDevice populated with capabilities provided by QPA plugins

    switch (event->deviceType()) {
    case QTabletEvent::Stylus:
        type = QQuickPointerDevice::Stylus;
        buttonCount = 3;
        break;
    case QTabletEvent::RotationStylus:
        type = QQuickPointerDevice::Stylus;
        caps |= QQuickPointerDevice::Rotation;
        buttonCount = 1;
        break;
    case QTabletEvent::Airbrush:
        type = QQuickPointerDevice::Airbrush;
        buttonCount = 2;
        break;
    case QTabletEvent::Puck:
        type = QQuickPointerDevice::Puck;
        buttonCount = 3;
        break;
    case QTabletEvent::FourDMouse:
        type = QQuickPointerDevice::Mouse;
        caps |= QQuickPointerDevice::Rotation;
        buttonCount = 3;
        break;
    default:
        type = QQuickPointerDevice::UnknownDevice;
        break;
    }

    PointerType ptype = GenericPointer;
    switch (event->pointerType()) {
    case QTabletEvent::Pen:
        ptype = Pen;
        break;
    case QTabletEvent::Eraser:
        ptype = Eraser;
        break;
    case QTabletEvent::Cursor:
        ptype = Cursor;
        break;
    case QTabletEvent::UnknownPointer:
        break;
    }

    QQuickPointerDevice *device = new QQuickPointerDevice(type, ptype, caps, 1, buttonCount,
        QLatin1String("tablet tool ") + QString::number(event->uniqueId()), event->uniqueId());

    g_tabletDevices->insert(key, device);
    return device;
}
#endif

/*!
    \qmltype EventPoint
    \qmlabstract
    \instantiates QQuickEventPoint
    \inqmlmodule QtQuick
    \ingroup qtquick-input-events
    \brief Provides information about an individual point within a PointerEvent.

    A PointerEvent contains an EventPoint for each point of contact: one corresponding
    to the mouse cursor, or one for each finger touching a touchscreen.

    \sa PointerEvent, PointerHandler
*/

/*!
    \readonly
    \qmlproperty point QtQuick::EventPoint::position

    This property holds the coordinates of the position supplied by the event,
    relative to the upper-left corner of the Item which has the PointerHandler.
    If a contact patch is available from the pointing device, this point
    represents its centroid.
*/

/*!
    \readonly
    \qmlproperty point QtQuick::EventPoint::scenePosition

    This property holds the coordinates of the position supplied by the event,
    relative to the scene. If a contact patch is available from the
    \l {QtQuick::PointerEvent::device} {device}, this point represents its centroid.
*/

/*!
    \readonly
    \qmlproperty point QtQuick::EventPoint::scenePressPosition

    This property holds the scene-relative position at which the press event
    (on a touch device) or most recent change in QQuickPointerEvent::buttons()
    (on a mouse or tablet stylus) occurred.
*/

/*!
    \readonly
    \qmlproperty point QtQuick::EventPoint::sceneGrabPosition

    This property holds the scene-relative position at which the EventPoint was
    located when setGrabber() was called most recently.
*/

/*!
    \readonly
    \qmlproperty vector2d QtQuick::EventPoint::velocity

    This property holds average recent velocity: how fast and in which
    direction the event point has been moving recently.
*/

/*!
    \readonly
    \qmlproperty int QtQuick::EventPoint::state

    This property tells what the user is currently doing at this point.

    It can be one of:
    \value Pressed
        The user's finger is now pressing a touchscreen, button or stylus
        which was not pressed already
    \value Updated
        The touchpoint or position is being moved, with no change in pressed state
    \value Stationary
        The touchpoint or position is not being moved, and there is also
        no change in pressed state
    \value Released
        The user's finger has now released a touch point, button or stylus
        which was pressed
*/

/*!
    \readonly
    \qmlproperty int QtQuick::EventPoint::pointId

    This property holds the ID of the event, if any.

    Touchpoints have automatically-incrementing IDs: each time the user
    presses a finger against the touchscreen, it will be a larger number.
    In other cases, it will be -1.

    \sa {QtQuick::EventTouchPoint::uniqueId}{uniqueId}
*/

/*!
    \readonly
    \qmlproperty bool QtQuick::EventPoint::accepted

    Setting \a accepted to true prevents the event from being propagated to
    Items below the PointerHandler's Item.

    Generally, if the handler acts on the mouse event, then it should be
    accepted so that items lower in the stacking order do not also respond to
    the same event.
*/

/*!
    \readonly
    \qmlproperty real QtQuick::EventPoint::timeHeld

    This property holds the amount of time in seconds that the button or touchpoint has
    been held.  It can be used to detect a "long press", and can drive an
    animation to show progress toward activation of the "long press" action.
*/

void QQuickEventPoint::reset(Qt::TouchPointState state, const QPointF &scenePos, int pointId, ulong timestamp, const QVector2D &velocity)
{
    m_scenePos = scenePos;
    m_pointId = pointId;
    m_accept = false;
    m_state = static_cast<QQuickEventPoint::State>(state);
    m_timestamp = timestamp;
    if (state == Qt::TouchPointPressed) {
        m_pressTimestamp = timestamp;
        m_scenePressPos = scenePos;
    }
    m_velocity = (Q_LIKELY(velocity.isNull()) ? estimatedVelocity() : velocity);
}

void QQuickEventPoint::localizePosition(QQuickItem *target)
{
    if (target)
        m_pos = target->mapFromScene(scenePosition());
    else
        m_pos = QPointF();
}

/*!
    If this point has an exclusive grabber, returns a pointer to it; else
    returns null, if there is no grabber.  The grabber could be either
    an Item or a PointerHandler.
*/
QObject *QQuickEventPoint::exclusiveGrabber() const
{
    return m_exclusiveGrabber.data();
}

/*!
    Set the given Item or PointerHandler as the exclusive grabber of this point.
    If there was already an exclusive grab, it will be canceled.  If there
    were passive grabbers, they will continue to lurk, but the exclusive grab
    is a behavioral override of the passive grab as long as it remains.
    If you already know whether the grabber is to be an Item or a PointerHandler,
    you should instead call setGrabberItem() or setGrabberPointerHandler(),
    because it is slightly more efficient.
*/
void QQuickEventPoint::setExclusiveGrabber(QObject *grabber)
{
    if (QQuickPointerHandler *phGrabber = qmlobject_cast<QQuickPointerHandler *>(grabber))
        setGrabberPointerHandler(phGrabber, true);
    else
        setGrabberItem(static_cast<QQuickItem *>(grabber));
}

/*!
    If the exclusive grabber of this point is an Item, returns a
    pointer to that Item; else returns null, if there is no grabber or if
    the grabber is a PointerHandler.
*/
QQuickItem *QQuickEventPoint::grabberItem() const
{
    return (m_grabberIsHandler ? nullptr : static_cast<QQuickItem *>(m_exclusiveGrabber.data()));
}

/*!
    Set the given Item \a grabber as the exclusive grabber of this point.
    If there was already an exclusive grab, it will be canceled.  If there
    were passive grabbers, they will continue to lurk, but the exclusive grab
    is a behavioral override of the passive grab as long as it remains.
*/
void QQuickEventPoint::setGrabberItem(QQuickItem *grabber)
{
    if (grabber != m_exclusiveGrabber.data()) {
        QQuickPointerHandler *oldGrabberHandler = grabberPointerHandler();
        if (oldGrabberHandler && !oldGrabberHandler->approveGrabTransition(this, grabber))
            return;
        if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
            qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << Qt::hex << m_pointId << pointStateString(this) << "@" << m_scenePos
                                   << ": grab" << m_exclusiveGrabber << "->" << grabber;
        }
        QQuickItem *oldGrabberItem = grabberItem();
        m_exclusiveGrabber = QPointer<QObject>(grabber);
        m_grabberIsHandler = false;
        m_sceneGrabPos = m_scenePos;
        if (oldGrabberHandler) {
            oldGrabberHandler->onGrabChanged(oldGrabberHandler, (grabber ? CancelGrabExclusive : UngrabExclusive), this);
        } else if (oldGrabberItem && oldGrabberItem != grabber && grabber && grabber->window()) {
            QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(grabber->window());
            windowPriv->sendUngrabEvent(oldGrabberItem, windowPriv->isDeliveringTouchAsMouse());
        }
        if (grabber) {
            for (QPointer<QQuickPointerHandler> passiveGrabber : m_passiveGrabbers)
                if (passiveGrabber)
                    passiveGrabber->onGrabChanged(passiveGrabber, OverrideGrabPassive, this);
        }
    }
}

/*!
    If the exclusive grabber of this point is a PointerHandler, returns a
    pointer to that handler; else returns null, if there is no grabber or if
    the grabber is an Item.
*/
QQuickPointerHandler *QQuickEventPoint::grabberPointerHandler() const
{
    return (m_grabberIsHandler ? static_cast<QQuickPointerHandler *>(m_exclusiveGrabber.data()) : nullptr);
}

/*!
    Set the given PointerHandler \a grabber as grabber of this point. If \a
    exclusive is true, it will override any other grabs; if false, \a grabber
    will be added to the list of passive grabbers of this point.
*/
void QQuickEventPoint::setGrabberPointerHandler(QQuickPointerHandler *grabber, bool exclusive)
{
    if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
        if (exclusive) {
            if (m_exclusiveGrabber != grabber)
                qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << Qt::hex << m_pointId << pointStateString(this)
                                       << ": grab (exclusive)" << m_exclusiveGrabber << "->" << grabber;
        } else {
            qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << Qt::hex << m_pointId << pointStateString(this)
                                   << ": grab (passive)" << grabber;
        }
    }
    if (exclusive) {
        if (grabber != m_exclusiveGrabber.data()) {
            QQuickPointerHandler *oldGrabberHandler = grabberPointerHandler();
            QQuickItem *oldGrabberItem = grabberItem();
            m_exclusiveGrabber = QPointer<QObject>(grabber);
            m_grabberIsHandler = true;
            m_sceneGrabPos = m_scenePos;
            if (grabber) {
                grabber->onGrabChanged(grabber, GrabExclusive, this);
                for (QPointer<QQuickPointerHandler> passiveGrabber : m_passiveGrabbers) {
                    if (!passiveGrabber.isNull() && passiveGrabber != grabber)
                        passiveGrabber->onGrabChanged(grabber, OverrideGrabPassive, this);
                }
            }
            if (oldGrabberHandler) {
                oldGrabberHandler->onGrabChanged(oldGrabberHandler, (grabber ? CancelGrabExclusive : UngrabExclusive), this);
            } else if (oldGrabberItem) {
                if (pointerEvent()->asPointerTouchEvent())
                    oldGrabberItem->touchUngrabEvent();
                else if (pointerEvent()->asPointerMouseEvent())
                    oldGrabberItem->mouseUngrabEvent();
            }
            // touchUngrabEvent() can result in the grabber being set to null (MPTA does that, for example).
            // So set it again to ensure that final state is what we want.
            m_exclusiveGrabber = QPointer<QObject>(grabber);
            m_grabberIsHandler = true;
            m_sceneGrabPos = m_scenePos;
        }
    } else {
        if (!grabber) {
            qDebug() << "can't set passive grabber to null";
            return;
        }
        auto ptr = QPointer<QQuickPointerHandler>(grabber);
        if (!m_passiveGrabbers.contains(ptr)) {
            m_passiveGrabbers.append(ptr);
            grabber->onGrabChanged(grabber, GrabPassive, this);
        }
    }
}

/*!
    If this point has an existing exclusive grabber (Item or PointerHandler),
    inform the grabber that its grab is canceled, and remove it as grabber.
    This normally happens when the grab is stolen by another Item.
*/
void QQuickEventPoint::cancelExclusiveGrab()
{
    if (m_exclusiveGrabber.isNull())
        qWarning("cancelGrab: no grabber");
    else
        cancelExclusiveGrabImpl();
}

void QQuickEventPoint::cancelExclusiveGrabImpl(QTouchEvent *cancelEvent)
{
    if (m_exclusiveGrabber.isNull())
        return;
    if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
        qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << Qt::hex << m_pointId << pointStateString(this)
                               << ": grab (exclusive)" << m_exclusiveGrabber << "-> nullptr";
    }
    if (auto handler = grabberPointerHandler()) {
        handler->onGrabChanged(handler, CancelGrabExclusive, this);
    } else if (auto item = grabberItem()) {
        if (cancelEvent)
            QCoreApplication::sendEvent(item, cancelEvent);
        else
            item->touchUngrabEvent();
    }
    m_exclusiveGrabber.clear();
}

/*!
    If this point has the given \a handler as a passive grabber,
    inform the grabber that its grab is canceled, and remove it as grabber.
    This normally happens when another Item or PointerHandler does an exclusive grab.
*/
void QQuickEventPoint::cancelPassiveGrab(QQuickPointerHandler *handler)
{
    if (removePassiveGrabber(handler)) {
        if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
            qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << Qt::hex << m_pointId << pointStateString(this)
                                   << ": grab (passive)" << handler << "removed";
        }
        handler->onGrabChanged(handler, CancelGrabPassive, this);
    }
}

/*!
    If this point has the given \a handler as a passive grabber, remove it as grabber.
    Returns true if it was removed, false if it wasn't a grabber.
*/
bool QQuickEventPoint::removePassiveGrabber(QQuickPointerHandler *handler)
{
    return m_passiveGrabbers.removeOne(handler);
}

/*!
    If the given \a handler is grabbing this point passively, exclusively
    or both, cancel the grab and remove it as grabber.
    This normally happens when the handler decides that the behavior of this
    point can no longer satisfy the handler's behavioral constraints within
    the remainder of the gesture which the user is performing: for example
    the handler tries to detect a tap but a drag is occurring instead, or
    it tries to detect a drag in one direction but the drag is going in
    another direction.  In such cases the handler no longer needs or wants
    to be informed of any further movements of this point.
*/
void QQuickEventPoint::cancelAllGrabs(QQuickPointerHandler *handler)
{
    if (m_exclusiveGrabber == handler) {
        handler->onGrabChanged(handler, CancelGrabExclusive, this);
        m_exclusiveGrabber.clear();
    }
    cancelPassiveGrab(handler);
}

/*!
    Sets this point as \a accepted (true) or rejected (false).

    During delivery of the current event to the Items in the scene, each Item
    or Pointer Handler should accept the points for which it is taking
    responsibility. As soon as all points within the event are accepted, event
    propagation stops. However accepting the point does not imply any kind of
    grab, passive or exclusive.

    \sa setExclusiveGrabber, QQuickPointerHandler::setPassiveGrab, QQuickPointerHandler::setExclusiveGrab
*/
void QQuickEventPoint::setAccepted(bool accepted)
{
    if (m_accept != accepted) {
        qCDebug(lcPointerEvents) << this << m_accept << "->" << accepted;
        m_accept = accepted;
    }
}


/*!
    \qmltype EventTouchPoint
    \qmlabstract
    \instantiates QQuickEventTouchPoint
    \inqmlmodule QtQuick
    \ingroup qtquick-input-events
    \brief Provides information about an individual touch point within a PointerEvent.

    \sa PointerEvent, PointerHandler
*/

/*!
    \readonly
    \qmlproperty QPointerUniqueId QtQuick::EventTouchPoint::uniqueId

    This property holds the unique ID of the fiducial or stylus in use, if any.

    On touchscreens that can track physical objects (such as knobs or game
    pieces) in addition to fingers, each object usually has a unique ID.
    Likewise, each stylus that can be used with a graphics tablet usually has a
    unique serial number. Qt so far only supports numeric IDs. You can get the
    actual number as uniqueId.numeric, but that is a device-specific detail.
    In the future, there may be support for non-numeric IDs, so you should
    not assume that the number is meaningful.

    If you need to identify specific objects, your application should provide
    UI for registering objects and mapping them to functionality: allow the
    user to select a meaning, virtual tool, or action, prompt the user to bring
    the object into proximity, and store a mapping from uniqueId to its
    purpose, for example in \l Settings.
*/

/*!
    \readonly
    \qmlproperty qreal QtQuick::EventTouchPoint::rotation

    This property holds the rotation angle of the stylus on a graphics tablet
    or the contact patch of a touchpoint on a touchscreen.

    It is valid only with certain tablet stylus devices and touchscreens that
    can measure the rotation angle. Otherwise, it will be zero.
*/

/*!
    \readonly
    \qmlproperty qreal QtQuick::EventTouchPoint::pressure

    This property tells how hard the user is pressing the stylus on a graphics
    tablet or the finger against a touchscreen, in the range from \c 0 (no
    measurable pressure) to \c 1.0 (maximum pressure which the device can
    measure).

    It is valid only with certain tablets and touchscreens that can measure
    pressure. Otherwise, it will be \c 1.0 when pressed.
*/

/*!
    \readonly
    \qmlproperty size QtQuick::EventTouchPoint::ellipseDiameters

    This property holds the diameters of the contact patch, if the event
    comes from a touchpoint and the \l {QtQuick::PointerEvent::device} {device}
    provides this information.

    A touchpoint is modeled as an elliptical area where the finger is
    pressed against the touchscreen. (In fact, it could also be
    modeled as a bitmap; but in that case we expect an elliptical
    bounding estimate to be fitted to the contact patch before the
    event is sent.) The harder the user presses, the larger the
    contact patch; so, these diameters provide an alternate way of
    detecting pressure, in case the device does not include a separate
    pressure sensor. The ellipse is centered on
    \l {QtQuick::EventPoint::scenePosition} {scenePosition}
    (\l {QtQuick::EventPoint::position} {position} in the PointerHandler's
    Item's local coordinates).  The \l rotation property provides the
    rotation of the ellipse, if known.  It is expected that if the
    \l rotation is zero, the verticalDiameter of the ellipse is the
    larger one (the major axis), because of the usual hand position,
    reaching upward or outward across the surface.

    If the contact patch is unknown, or the \l {QtQuick::PointerEvent::device} {device}
    is not a touchscreen, these values will be zero.
*/

QQuickEventTouchPoint::QQuickEventTouchPoint(QQuickPointerTouchEvent *parent)
    : QQuickEventPoint(parent), m_rotation(0), m_pressure(0)
{}

void QQuickEventTouchPoint::reset(const QTouchEvent::TouchPoint &tp, ulong timestamp)
{
    QQuickEventPoint::reset(tp.state(), tp.scenePos(), tp.id(), timestamp, tp.velocity());
    m_exclusiveGrabber.clear();
    m_passiveGrabbers.clear();
    m_rotation = tp.rotation();
    m_pressure = tp.pressure();
    m_ellipseDiameters = tp.ellipseDiameters();
    m_uniqueId = tp.uniqueId();
}

struct PointVelocityData {
    QVector2D velocity;
    QPointF pos;
    ulong timestamp = 0;
};

typedef QMap<quint64, PointVelocityData> PointDataForPointIdMap;
Q_GLOBAL_STATIC(PointDataForPointIdMap, g_previousPointData)
static const int PointVelocityAgeLimit = 500; // milliseconds

/*!
    \internal
    Estimates the velocity based on a weighted average of all previous velocities.
    The older the velocity is, the less significant it becomes for the estimate.
*/
QVector2D QQuickEventPoint::estimatedVelocity() const
{
    auto prevPointIt = g_previousPointData->find(m_pointId);
    auto end = g_previousPointData->end();
    if (prevPointIt == end) {
        // cleanup events older than PointVelocityAgeLimit
        for (auto it = g_previousPointData->begin(); it != end; ) {
            if (m_timestamp - it->timestamp > PointVelocityAgeLimit)
                it = g_previousPointData->erase(it);
            else
                ++it;
        }
        prevPointIt = g_previousPointData->insert(m_pointId, PointVelocityData());
    }

    auto &prevPoint = prevPointIt.value();
    const ulong timeElapsed = m_timestamp - prevPoint.timestamp;
    if (timeElapsed == 0)   // in case we call estimatedVelocity() twice on the same QQuickEventPoint
        return m_velocity;

    QVector2D newVelocity;
    if (prevPoint.timestamp != 0)
        newVelocity = QVector2D(m_scenePos - prevPoint.pos) / timeElapsed;

    // VERY simple kalman filter: does a weighted average
    // where the older velocities get less and less significant
    static const float KalmanGain = 0.7f;
    QVector2D filteredVelocity = newVelocity * KalmanGain + m_velocity * (1.0f - KalmanGain);

    prevPoint.velocity = filteredVelocity;
    prevPoint.pos = m_scenePos;
    prevPoint.timestamp = m_timestamp;
    return filteredVelocity;
}

/*!
    \qmltype PointerEvent
    \instantiates QQuickPointerEvent
    \inqmlmodule QtQuick
    \ingroup qtquick-input-events

    \brief Provides information about an event from a pointing device.

    A PointerEvent is an event describing contact or movement across a surface,
    provided by a mouse, a touchpoint (single finger on a touchscreen), or a
    stylus on a graphics tablet. The \l {QtQuick::PointerEvent::device} {device}
    property provides more information about where the event came from.

    \sa PointerHandler

    \image touchpoint-metrics.png
*/

/*!
    \internal
    \class QQuickPointerEvent

    QQuickPointerEvent is used as a long-lived object to store data related to
    an event from a pointing device, such as a mouse, touch or tablet event,
    during event delivery. It also provides properties which may be used later
    to expose the event to QML, the same as is done with QQuickMouseEvent,
    QQuickTouchPoint, QQuickKeyEvent, etc. Since only one event can be
    delivered at a time, this class is effectively a singleton.  We don't worry
    about the QObject overhead because the instances are long-lived: we don't
    dynamically create and destroy objects of this type for each event.
*/

/*!
    \readonly
    \qmlproperty enumeration QtQuick::PointerEvent::button

    This property holds the \l {Qt::MouseButton}{button} that caused the event,
    if any. If the \l {QtQuick::PointerEvent::device} {device} does not have
    buttons, or the event is a hover event, it will be \c Qt.NoButton.
*/

/*!
    \readonly
    \qmlproperty int QtQuick::PointerEvent::buttons

    This property holds the combination of mouse or stylus
    \l {Qt::MouseButton}{buttons} pressed when the event was generated. For move
    events, this is all buttons that are pressed down.  For press events, this
    includes the button that caused the event, as well as any others that were
    already held.  For release events, this excludes the button that caused the
    event.
*/

/*!
    \readonly
    \qmlproperty int QtQuick::PointerEvent::modifiers

    This property holds the \l {Qt::KeyboardModifier}{keyboard modifier} flags
    that existed immediately before the event occurred.

    It contains a bitwise combination of the following flags:
    \value Qt.NoModifier
        No modifier key is pressed.
    \value Qt.ShiftModifier
        A Shift key on the keyboard is pressed.
    \value Qt.ControlModifier
        A Ctrl key on the keyboard is pressed.
    \value Qt.AltModifier
        An Alt key on the keyboard is pressed.
    \value Qt.MetaModifier
        A Meta key on the keyboard is pressed.
    \value Qt.KeypadModifier
        A keypad button is pressed.

    For example, to react to a Shift key + Left mouse button click:
    \qml
    Item {
        TapHandler {
            onTapped: {
                if ((event.button == Qt.LeftButton) && (event.modifiers & Qt.ShiftModifier))
                    doSomething();
            }
        }
    }
    \endqml
*/

/*!
    \readonly
    \qmlproperty PointerDevice QtQuick::PointerEvent::device

    This property holds the device that generated the event.
*/

QQuickPointerEvent::~QQuickPointerEvent()
{}

QQuickPointerMouseEvent::QQuickPointerMouseEvent(QObject *parent, QQuickPointerDevice *device)
    : QQuickSinglePointEvent(parent, device)
{
    m_point = new QQuickEventPoint(this);
}

QQuickPointerEvent *QQuickPointerMouseEvent::reset(QEvent *event)
{
    auto ev = static_cast<QMouseEvent*>(event);
    m_event = ev;
    if (!event)
        return this;

    m_device = QQuickPointerDevice::genericMouseDevice();
    m_device->eventDeliveryTargets().clear();
    m_button = ev->button();
    m_pressedButtons = ev->buttons();
    Qt::TouchPointState state = Qt::TouchPointStationary;
    switch (ev->type()) {
    case QEvent::MouseButtonPress:
        m_point->clearPassiveGrabbers();
        Q_FALLTHROUGH();
    case QEvent::MouseButtonDblClick:
        state = Qt::TouchPointPressed;
        break;
    case QEvent::MouseButtonRelease:
        state = Qt::TouchPointReleased;
        break;
    case QEvent::MouseMove:
        state = Qt::TouchPointMoved;
        break;
    default:
        break;
    }
    m_point->reset(state, ev->windowPos(), quint64(1) << 24, ev->timestamp());  // mouse has device ID 1
    return this;
}

void QQuickSinglePointEvent::localize(QQuickItem *target)
{
    m_point->localizePosition(target);
}

QQuickPointerEvent *QQuickPointerTouchEvent::reset(QEvent *event)
{
    auto ev = static_cast<QTouchEvent*>(event);
    m_event = ev;
    if (!event)
        return this;

    m_device = QQuickPointerDevice::touchDevice(ev->device());
    m_device->eventDeliveryTargets().clear();
    m_button = Qt::NoButton;
    m_pressedButtons = Qt::NoButton;

    const QList<QTouchEvent::TouchPoint> &tps = ev->touchPoints();
    int newPointCount = tps.count();
    m_touchPoints.reserve(newPointCount);

    for (int i = m_touchPoints.size(); i < newPointCount; ++i)
        m_touchPoints.insert(i, new QQuickEventTouchPoint(this));

    // Make sure the grabbers and on-pressed values are right from one event to the next
    struct ToPreserve {
        int pointId; // just for double-checking
        ulong pressTimestamp;
        QPointF scenePressPos;
        QPointF sceneGrabPos;
        QObject * grabber;
        QVector <QPointer <QQuickPointerHandler> > passiveGrabbers;

        ToPreserve() : pointId(0), pressTimestamp(0), grabber(nullptr) {}
    };
    QVector<ToPreserve> preserves(newPointCount); // jar of pickled touchpoints, in order of points in the _new_ event

    // Copy stuff we need to preserve, because the order of points might have changed in the event.
    // The ID is all that we can rely on (release might remove the first point etc).
    for (int i = 0; i < newPointCount; ++i) {
        int pid = tps.at(i).id();
        if (auto point = pointById(pid)) {
            preserves[i].pointId = pid;
            preserves[i].pressTimestamp = point->m_pressTimestamp;
            preserves[i].scenePressPos = point->scenePressPosition();
            preserves[i].sceneGrabPos = point->sceneGrabPosition();
            preserves[i].grabber = point->exclusiveGrabber();
            preserves[i].passiveGrabbers = point->passiveGrabbers();
        }
    }

    for (int i = 0; i < newPointCount; ++i) {
        auto point = m_touchPoints.at(i);
        point->reset(tps.at(i), ev->timestamp());
        const auto &preserved = preserves.at(i);
        if (point->state() == QQuickEventPoint::Pressed) {
            if (preserved.grabber)
                qWarning() << "TouchPointPressed without previous release event" << point;
            point->setGrabberItem(nullptr);
            point->clearPassiveGrabbers();
        } else {
            // Restore the grabbers without notifying (don't call onGrabChanged)
            Q_ASSERT(preserved.pointId == 0 || preserved.pointId == point->pointId());
            point->m_pressTimestamp = preserved.pressTimestamp;
            point->m_scenePressPos = preserved.scenePressPos;
            point->m_sceneGrabPos = preserved.sceneGrabPos;
            point->m_exclusiveGrabber = preserved.grabber;
            point->m_grabberIsHandler = (qmlobject_cast<QQuickPointerHandler *>(point->m_exclusiveGrabber) != nullptr);
            point->m_passiveGrabbers = preserved.passiveGrabbers;
        }
    }
    m_pointCount = newPointCount;
    return this;
}

void QQuickPointerTouchEvent::localize(QQuickItem *target)
{
    for (auto point : qAsConst(m_touchPoints))
        point->localizePosition(target);
}

#if QT_CONFIG(gestures)
QQuickPointerNativeGestureEvent::QQuickPointerNativeGestureEvent(QObject *parent, QQuickPointerDevice *device)
    : QQuickSinglePointEvent(parent, device)
{
    m_point = new QQuickEventPoint(this);
}

QQuickPointerEvent *QQuickPointerNativeGestureEvent::reset(QEvent *event)
{
    auto ev = static_cast<QNativeGestureEvent*>(event);
    m_event = ev;
    if (!event)
        return this;

    m_device = QQuickPointerDevice::touchDevice(ev->device());
    m_device->eventDeliveryTargets().clear();
    Qt::TouchPointState state = Qt::TouchPointMoved;
    switch (type()) {
    case Qt::BeginNativeGesture:
        state = Qt::TouchPointPressed;
        break;
    case Qt::EndNativeGesture:
        state = Qt::TouchPointReleased;
        break;
    default:
        break;
    }
    quint64 deviceId = QTouchDevicePrivate::get(const_cast<QTouchDevice *>(ev->device()))->id; // a bit roundabout since QTouchDevice::mTouchDeviceId is protected
    m_point->reset(state, ev->windowPos(), deviceId << 24, ev->timestamp());
    return this;
}
#endif // QT_CONFIG(gestures)

QQuickEventPoint *QQuickSinglePointEvent::point(int i) const
{
    if (i == 0)
        return m_point;
    return nullptr;
}


/*!
    \qmltype PointerScrollEvent
    \instantiates QQuickPointerScrollEvent
    \inqmlmodule QtQuick
    \ingroup qtquick-input-events
    \brief Provides information about a scrolling event, such as from a mouse wheel.

    \sa WheelHandler
*/

/*!
    \internal
    \class QQuickPointerScrollEvent
*/

/*!
    \readonly
    \qmlproperty PointerDevice QtQuick::PointerScrollEvent::device

    This property holds the device that generated the event.
*/

/*!
    \qmlproperty int QtQuick::PointerScrollEvent::buttons

    This property holds the mouse buttons pressed when the wheel event was generated.

    It contains a bitwise combination of:
    \list
    \li \l {Qt::LeftButton} {Qt.LeftButton}
    \li \l {Qt::RightButton} {Qt.RightButton}
    \li \l {Qt::MiddleButton} {Qt.MiddleButton}
    \endlist
*/

/*!
    \readonly
    \qmlproperty int QtQuick::PointerScrollEvent::modifiers

    This property holds the \l {Qt::KeyboardModifier}{keyboard modifier} keys
    that were pressed immediately before the event occurred.

    It contains a bitwise combination of the following flags:
    \value Qt.NoModifier
        No modifier key is pressed.
    \value Qt.ShiftModifier
        A Shift key on the keyboard is pressed.
    \value Qt.ControlModifier
        A Ctrl key on the keyboard is pressed.
    \value Qt.AltModifier
        An Alt key on the keyboard is pressed.
    \value Qt.MetaModifier
        A Meta key on the keyboard is pressed.
    \value Qt.KeypadModifier
        A keypad button is pressed.

    For example, to react to a Shift key + Left mouse button click:
    \qml
    Item {
        TapHandler {
            onTapped: {
                if ((event.button == Qt.LeftButton) && (event.modifiers & Qt.ShiftModifier))
                    doSomething();
            }
        }
    }
    \endqml
*/

/*!
    \qmlproperty point QtQuick::PointerScrollEvent::angleDelta

    This property holds the distance that the wheel is rotated in wheel degrees.
    The x and y cordinate of this property holds the delta in horizontal and
    vertical orientation.

    A positive value indicates that the wheel was rotated up/right;
    a negative value indicates that the wheel was rotated down/left.

    Most mouse types work in steps of 15 degrees, in which case the delta value is a
    multiple of 120; i.e., 120 units * 1/8 = 15 degrees.
*/

/*!
    \qmlproperty point QtQuick::PointerScrollEvent::pixelDelta

    This property holds the delta in screen pixels and is available in platforms that
    have high-resolution trackpads, such as \macos.
    The x and y coordinates of this property hold the delta in horizontal and
    vertical orientation. The value should be used directly to scroll content on screen.

    For platforms without high-resolution touchpad support, pixelDelta will
    always be (0,0), and angleDelta should be used instead.
*/

/*!
    \qmlproperty bool QtQuick::PointerScrollEvent::hasAngleDelta

    Returns whether the \l angleDelta property has a non-null value.
*/

/*!
    \qmlproperty bool QtQuick::PointerScrollEvent::hasPixelDelta

    Returns whether the \l pixelDelta property has a non-null value.
*/

/*!
    \qmlproperty bool QtQuick::PointerScrollEvent::inverted

    Returns whether the delta values delivered with the event are inverted.

    Normally, a vertical wheel will produce a PointerScrollEvent with positive delta
    values if the top of the wheel is rotating away from the hand operating it.
    Similarly, a horizontal wheel movement will produce a PointerScrollEvent with
    positive delta values if the top of the wheel is moved to the left.

    However, on some platforms this is configurable, so that the same
    operations described above will produce negative delta values (but with the
    same magnitude). In a QML component (such as a tumbler or a slider) where
    it is appropriate to synchronize the movement or rotation of an item with
    the direction of the wheel, regardless of the system settings, the wheel
    event handler can use the inverted property to decide whether to negate the
    \l angleDelta or \l pixelDelta values.

    \note Many platforms provide no such information. On such platforms,
    \c inverted always returns false.
*/
QQuickPointerScrollEvent::QQuickPointerScrollEvent(QObject *parent, QQuickPointerDevice *device)
    : QQuickSinglePointEvent(parent, device)
{
    m_point = new QQuickEventPoint(this);
}

QQuickPointerEvent *QQuickPointerScrollEvent::reset(QEvent *event)
{
    m_event = static_cast<QInputEvent*>(event);
    if (!event)
        return this;
#if QT_CONFIG(wheelevent)
    if (event->type() == QEvent::Wheel) {
        auto ev = static_cast<QWheelEvent*>(event);
        m_device = QQuickPointerDevice::genericMouseDevice();
        m_device->eventDeliveryTargets().clear();
        // m_button = Qt::NoButton;
        m_pressedButtons = ev->buttons();
        m_angleDelta = QVector2D(ev->angleDelta());
        m_pixelDelta = QVector2D(ev->pixelDelta());
        m_phase = ev->phase();
        m_synthSource = ev->source();
        m_inverted = ev->inverted();

        m_point->reset(Qt::TouchPointMoved, ev->position(), quint64(1) << 24, ev->timestamp()); // mouse has device ID 1
    }
#endif
    // TODO else if (event->type() == QEvent::Scroll) ...
    return this;
}

void QQuickPointerScrollEvent::localize(QQuickItem *target)
{
    m_point->localizePosition(target);
}

QQuickEventPoint *QQuickPointerTouchEvent::point(int i) const
{
    if (i >= 0 && i < m_pointCount)
        return m_touchPoints.at(i);
    return nullptr;
}

QQuickEventPoint::QQuickEventPoint(QQuickPointerEvent *parent)
  : QObject(parent), m_pointId(0), m_exclusiveGrabber(nullptr), m_timestamp(0), m_pressTimestamp(0),
    m_state(QQuickEventPoint::Released), m_accept(false), m_grabberIsHandler(false)
{
    Q_UNUSED(m_reserved);
}

QQuickPointerEvent *QQuickEventPoint::pointerEvent() const
{
    return static_cast<QQuickPointerEvent *>(parent());
}

bool QQuickSinglePointEvent::allPointsAccepted() const
{
    return m_point->isAccepted();
}

bool QQuickSinglePointEvent::allUpdatedPointsAccepted() const
{
    return m_point->state() == QQuickEventPoint::Pressed || m_point->isAccepted();
}

bool QQuickSinglePointEvent::allPointsGrabbed() const
{
    return m_point->exclusiveGrabber() != nullptr;
}

QMouseEvent *QQuickPointerMouseEvent::asMouseEvent(const QPointF &localPos) const
{
    if (!m_event)
        return nullptr;
    auto event = static_cast<QMouseEvent *>(m_event);
    event->setLocalPos(localPos);
    return event;
}

/*!
    Returns the exclusive grabber of this event, if any, in a vector.
*/
QVector<QObject *> QQuickSinglePointEvent::exclusiveGrabbers() const
{
    QVector<QObject *> result;
    if (QObject *grabber = m_point->exclusiveGrabber())
        result << grabber;
    return result;
}

/*!
    Remove all passive and exclusive grabbers of this event, without notifying.
*/
void QQuickSinglePointEvent::clearGrabbers() const
{
    m_point->setGrabberItem(nullptr);
    m_point->clearPassiveGrabbers();
}

/*!
    Returns whether the given \a handler is the exclusive grabber of this event.
*/
bool QQuickSinglePointEvent::hasExclusiveGrabber(const QQuickPointerHandler *handler) const
{
    return handler && (m_point->exclusiveGrabber() == handler);
}

bool QQuickPointerMouseEvent::isPressEvent() const
{
    if (!m_event)
        return false;
    auto me = static_cast<QMouseEvent*>(m_event);
    return ((me->type() == QEvent::MouseButtonPress || me->type() == QEvent::MouseButtonDblClick) &&
            (me->buttons() & me->button()) == me->buttons());
}

bool QQuickPointerMouseEvent::isDoubleClickEvent() const
{
    if (!m_event)
        return false;
    auto me = static_cast<QMouseEvent*>(m_event);
    return (me->type() == QEvent::MouseButtonDblClick);
}

bool QQuickPointerMouseEvent::isUpdateEvent() const
{
    if (!m_event)
        return false;
    auto me = static_cast<QMouseEvent*>(m_event);
    return me->type() == QEvent::MouseMove;
}

bool QQuickPointerMouseEvent::isReleaseEvent() const
{
    if (!m_event)
        return false;
    auto me = static_cast<QMouseEvent*>(m_event);
    return me && me->type() == QEvent::MouseButtonRelease;
}

bool QQuickPointerTouchEvent::allPointsAccepted() const
{
    for (int i = 0; i < m_pointCount; ++i) {
        if (!m_touchPoints.at(i)->isAccepted())
            return false;
    }
    return true;
}

bool QQuickPointerTouchEvent::allUpdatedPointsAccepted() const
{
    for (int i = 0; i < m_pointCount; ++i) {
        auto point = m_touchPoints.at(i);
        if (point->state() != QQuickEventPoint::Pressed && !point->isAccepted())
            return false;
    }
    return true;
}

bool QQuickPointerTouchEvent::allPointsGrabbed() const
{
    for (int i = 0; i < m_pointCount; ++i) {
        if (!m_touchPoints.at(i)->exclusiveGrabber())
            return false;
    }
    return true;
}

/*!
    Returns the exclusive grabbers of all points in this event, if any, in a vector.
*/
QVector<QObject *> QQuickPointerTouchEvent::exclusiveGrabbers() const
{
    QVector<QObject *> result;
    for (int i = 0; i < m_pointCount; ++i) {
        if (QObject *grabber = m_touchPoints.at(i)->exclusiveGrabber()) {
            if (!result.contains(grabber))
                result << grabber;
        }
    }
    return result;
}

/*!
    Remove all passive and exclusive grabbers of all touchpoints in this event,
    without notifying.
*/
void QQuickPointerTouchEvent::clearGrabbers() const
{
    for (auto point: m_touchPoints) {
        point->setGrabberItem(nullptr);
        point->clearPassiveGrabbers();
    }
}

Qt::TouchPointStates QQuickPointerTouchEvent::touchPointStates() const
{
    return m_event
        ? static_cast<QTouchEvent*>(m_event)->touchPointStates()
        : Qt::TouchPointStates();
}

/*!
    Returns whether the given \a handler is the exclusive grabber of any
    touchpoint within this event.
*/
bool QQuickPointerTouchEvent::hasExclusiveGrabber(const QQuickPointerHandler *handler) const
{
    for (auto point: m_touchPoints)
        if (point->exclusiveGrabber() == handler)
            return true;
    return false;
}

bool QQuickPointerTouchEvent::isPressEvent() const
{
    return touchPointStates() & Qt::TouchPointPressed;
}

bool QQuickPointerTouchEvent::isUpdateEvent() const
{
    return touchPointStates() & (Qt::TouchPointMoved | Qt::TouchPointStationary);
}

bool QQuickPointerTouchEvent::isReleaseEvent() const
{
    return touchPointStates() & Qt::TouchPointReleased;
}

QVector<QPointF> QQuickPointerEvent::unacceptedPressedPointScenePositions() const
{
    QVector<QPointF> points;
    for (int i = 0; i < pointCount(); ++i) {
        if (!point(i)->isAccepted() && point(i)->state() == QQuickEventPoint::Pressed)
            points << point(i)->scenePosition();
    }
    return points;
}

/*!
    \internal
    Populate the reusable synth-mouse event from one touchpoint.
    It's required that isTouchEvent() be true when this is called.
    If the touchpoint cannot be found, this returns nullptr.
    Ownership of the event is NOT transferred to the caller.
*/
QMouseEvent *QQuickPointerTouchEvent::syntheticMouseEvent(int pointID, QQuickItem *relativeTo) const
{
    const QTouchEvent::TouchPoint *p = touchPointById(pointID);
    if (!p)
        return nullptr;
    QEvent::Type type;
    Qt::MouseButton buttons = Qt::LeftButton;
    switch (p->state()) {
    case Qt::TouchPointPressed:
        type = QEvent::MouseButtonPress;
        break;
    case Qt::TouchPointMoved:
    case Qt::TouchPointStationary:
        type = QEvent::MouseMove;
        break;
    case Qt::TouchPointReleased:
        type = QEvent::MouseButtonRelease;
        buttons = Qt::NoButton;
        break;
    default:
        Q_ASSERT(false);
        return nullptr;
    }
    m_synthMouseEvent = QMouseEvent(type, relativeTo->mapFromScene(p->scenePos()),
        p->scenePos(), p->screenPos(), Qt::LeftButton, buttons, m_event->modifiers());
    m_synthMouseEvent.setAccepted(true);
    m_synthMouseEvent.setTimestamp(m_event->timestamp());
    // In the future we will try to always have valid velocity in every QQuickEventPoint.
    // QQuickFlickablePrivate::handleMouseMoveEvent() checks for QTouchDevice::Velocity
    // and if it is set, then it does not need to do its own velocity calculations.
    // That's probably the only usecase for this, so far.  Some day Flickable should handle
    // pointer events, and then passing touchpoint velocity via QMouseEvent will be obsolete.
    // Conveniently (by design), QTouchDevice::Velocity == QQuickPointerDevice.Velocity
    // so that we don't need to convert m_device->capabilities().
    if (m_device)
        QGuiApplicationPrivate::setMouseEventCapsAndVelocity(&m_synthMouseEvent, m_device->capabilities(), p->velocity());
    QGuiApplicationPrivate::setMouseEventSource(&m_synthMouseEvent, Qt::MouseEventSynthesizedByQt);
    return &m_synthMouseEvent;
}

#if QT_CONFIG(tabletevent)
QQuickPointerTabletEvent::QQuickPointerTabletEvent(QObject *parent, QQuickPointerDevice *device)
    : QQuickSinglePointEvent(parent, device)
{
    m_point = new QQuickEventTabletPoint(this);
}

QQuickPointerEvent *QQuickPointerTabletEvent::reset(QEvent *event)
{
    auto ev = static_cast<QTabletEvent*>(event);
    m_event = ev;
    if (!event)
        return this;

    Q_ASSERT(m_device == QQuickPointerDevice::tabletDevice(ev));
    m_device->eventDeliveryTargets().clear();
    m_button = ev->button();
    m_pressedButtons = ev->buttons();
    static_cast<QQuickEventTabletPoint *>(m_point)->reset(ev);
    return this;
}

QQuickEventTabletPoint::QQuickEventTabletPoint(QQuickPointerTabletEvent *parent)
  : QQuickEventPoint(parent)
{
}

void QQuickEventTabletPoint::reset(const QTabletEvent *ev)
{
    Qt::TouchPointState state = Qt::TouchPointStationary;
    switch (ev->type()) {
    case QEvent::TabletPress:
        state = Qt::TouchPointPressed;
        clearPassiveGrabbers();
        break;
    case QEvent::TabletRelease:
        state = Qt::TouchPointReleased;
        break;
    case QEvent::TabletMove:
        state = Qt::TouchPointMoved;
        break;
    default:
        break;
    }
    QQuickEventPoint::reset(state, ev->posF(), 1, ev->timestamp());
    m_rotation = ev->rotation();
    m_pressure = ev->pressure();
    m_tangentialPressure = ev->tangentialPressure();
    m_tilt = QVector2D(ev->xTilt(), ev->yTilt());
}

bool QQuickPointerTabletEvent::isPressEvent() const
{
    auto me = static_cast<QTabletEvent *>(m_event);
    return me->type() == QEvent::TabletPress;
}

bool QQuickPointerTabletEvent::isUpdateEvent() const
{
    auto me = static_cast<QTabletEvent *>(m_event);
    return me->type() == QEvent::TabletMove;
}

bool QQuickPointerTabletEvent::isReleaseEvent() const
{
    auto me = static_cast<QTabletEvent *>(m_event);
    return me->type() == QEvent::TabletRelease;
}

QTabletEvent *QQuickPointerTabletEvent::asTabletEvent() const
{
    return static_cast<QTabletEvent *>(m_event);
}
#endif // QT_CONFIG(tabletevent)

#if QT_CONFIG(gestures)
bool QQuickPointerNativeGestureEvent::isPressEvent() const
{
    return type() == Qt::BeginNativeGesture;
}

bool QQuickPointerNativeGestureEvent::isUpdateEvent() const
{
    switch (type()) {
    case Qt::BeginNativeGesture:
    case Qt::EndNativeGesture:
        return false;
    default:
        return true;
    }
}

bool QQuickPointerNativeGestureEvent::isReleaseEvent() const
{
    return type() == Qt::EndNativeGesture;
}

Qt::NativeGestureType QQuickPointerNativeGestureEvent::type() const
{
    return static_cast<QNativeGestureEvent *>(m_event)->gestureType();
}

qreal QQuickPointerNativeGestureEvent::value() const
{
    return static_cast<QNativeGestureEvent *>(m_event)->value();
}
#endif // QT_CONFIG(gestures)

/*!
    Returns whether the scroll event has Qt::ScrollBegin phase. On touchpads
    which provide phase information, this is true when the fingers are placed
    on the touchpad and scrolling begins. On other devices where this
    information is not available, it remains false.
*/
bool QQuickPointerScrollEvent::isPressEvent() const
{
    return phase() == Qt::ScrollBegin;
}

/*!
    Returns true when the scroll event has Qt::ScrollUpdate phase, or when the
    phase is unknown. Some multi-touch-capable touchpads and trackpads provide
    phase information; whereas ordinary mouse wheels and other types of
    trackpads do not, and in such cases this is always true.
*/
bool QQuickPointerScrollEvent::isUpdateEvent() const
{
    return phase() == Qt::ScrollUpdate || phase() == Qt::NoScrollPhase;
}

/*!
    Returns whether the scroll event has Qt::ScrollBegin phase. On touchpads
    which provide phase information, this is true when the fingers are lifted
    from the touchpad. On other devices where this information is not
    available, it remains false.
*/
bool QQuickPointerScrollEvent::isReleaseEvent() const
{
    return phase() == Qt::ScrollEnd;
}

/*!
    \internal
    Returns a pointer to the QQuickEventPoint which has the \a pointId as
    \l {QQuickEventPoint::pointId}{pointId}.
    Returns nullptr if there is no point with that ID.

    \fn QQuickPointerEvent::pointById(int pointId) const
*/
QQuickEventPoint *QQuickSinglePointEvent::pointById(int pointId) const
{
    if (m_point && pointId == m_point->pointId())
        return m_point;
    return nullptr;
}

QQuickEventPoint *QQuickPointerTouchEvent::pointById(int pointId) const
{
    auto it = std::find_if(m_touchPoints.constBegin(), m_touchPoints.constEnd(),
        [pointId](const QQuickEventTouchPoint *tp) { return tp->pointId() == pointId; } );
    if (it != m_touchPoints.constEnd())
        return *it;
    return nullptr;
}

/*!
    \internal
    Returns a pointer to the original TouchPoint which has the same
    \l {QTouchEvent::TouchPoint::id}{id} as \a pointId, if the original event is a
    QTouchEvent, and if that point is found. Otherwise, returns nullptr.
*/
const QTouchEvent::TouchPoint *QQuickPointerTouchEvent::touchPointById(int pointId) const
{
    const QTouchEvent *ev = asTouchEvent();
    if (!ev)
        return nullptr;
    const QList<QTouchEvent::TouchPoint> &tps = ev->touchPoints();
    auto it = std::find_if(tps.constBegin(), tps.constEnd(),
        [pointId](QTouchEvent::TouchPoint const& tp) { return tp.id() == pointId; } );
    // return the pointer to the actual TP in QTouchEvent::_touchPoints
    return (it == tps.constEnd() ? nullptr : it.operator->());
}

/*!
    \internal
    Make a new QTouchEvent, giving it a subset of the original touch points.

    Returns a nullptr if all points are stationary, or there are no points inside the item,
    or none of the points were pressed inside and the item was not grabbing any of them
    and isFiltering is false.  When isFiltering is true, it is assumed that the item
    cares about all points which are inside its bounds, because most filtering items
    need to monitor eventpoint movements until a drag threshold is exceeded or the
    requirements for a gesture to be recognized are met in some other way.
*/
QTouchEvent *QQuickPointerTouchEvent::touchEventForItem(QQuickItem *item, bool isFiltering) const
{
    QList<QTouchEvent::TouchPoint> touchPoints;
    Qt::TouchPointStates eventStates;
    // TODO maybe add QQuickItem::mapVector2DFromScene(QVector2D) to avoid needing QQuickItemPrivate here
    // Or else just document that velocity is always scene-relative and is not scaled and rotated with the item
    // but that would require changing tst_qquickwindow::touchEvent_velocity(): it expects transformed velocity

    bool anyPressOrReleaseInside = false;
    bool anyStationaryWithModifiedPropertyInside = false;
    bool anyGrabber = false;
    QMatrix4x4 transformMatrix(QQuickItemPrivate::get(item)->windowToItemTransform());
    for (int i = 0; i < m_pointCount; ++i) {
        auto p = m_touchPoints.at(i);
        if (p->isAccepted())
            continue;
        // include points where item is the grabber
        bool isGrabber = p->exclusiveGrabber() == item;
        if (isGrabber)
            anyGrabber = true;
        // include points inside the bounds if no other item is the grabber or if the item is filtering
        bool isInside = item->contains(item->mapFromScene(p->scenePosition()));
        bool hasAnotherGrabber = p->exclusiveGrabber() && p->exclusiveGrabber() != item;

        // filtering: (childMouseEventFilter) include points that are grabbed by children of the target item
        bool grabberIsChild = false;
        auto parent = p->grabberItem();
        while (isFiltering && parent) {
            if (parent == item) {
                grabberIsChild = true;
                break;
            }
            parent = parent->parentItem();
        }

        bool filterRelevant = isFiltering && grabberIsChild;
        if (!(isGrabber || (isInside && (!hasAnotherGrabber || isFiltering)) || filterRelevant))
            continue;
        if ((p->state() == QQuickEventPoint::Pressed || p->state() == QQuickEventPoint::Released) && isInside)
            anyPressOrReleaseInside = true;
        const QTouchEvent::TouchPoint *tp = touchPointById(p->pointId());
        if (tp) {
            if (isInside && tp->d->stationaryWithModifiedProperty)
                anyStationaryWithModifiedPropertyInside = true;
            eventStates |= tp->state();
            QTouchEvent::TouchPoint tpCopy = *tp;
            tpCopy.setPos(item->mapFromScene(tpCopy.scenePos()));
            tpCopy.setLastPos(item->mapFromScene(tpCopy.lastScenePos()));
            tpCopy.setStartPos(item->mapFromScene(tpCopy.startScenePos()));
            tpCopy.setEllipseDiameters(tpCopy.ellipseDiameters());
            tpCopy.setVelocity(transformMatrix.mapVector(tpCopy.velocity()).toVector2D());
            touchPoints << tpCopy;
        }
    }

    // Now touchPoints will have only points which are inside the item.
    // But if none of them were just pressed inside, and the item has no other reason to care, ignore them anyway.
    if ((eventStates == Qt::TouchPointStationary && !anyStationaryWithModifiedPropertyInside) ||
            touchPoints.isEmpty() || (!anyPressOrReleaseInside && !anyGrabber && !isFiltering))
        return nullptr;

    // if all points have the same state, set the event type accordingly
    const QTouchEvent &event = *asTouchEvent();
    QEvent::Type eventType = event.type();
    switch (eventStates) {
    case Qt::TouchPointPressed:
        eventType = QEvent::TouchBegin;
        break;
    case Qt::TouchPointReleased:
        eventType = QEvent::TouchEnd;
        break;
    default:
        eventType = QEvent::TouchUpdate;
        break;
    }

    QTouchEvent *touchEvent = new QTouchEvent(eventType);
    touchEvent->setWindow(event.window());
    touchEvent->setTarget(item);
    touchEvent->setDevice(event.device());
    touchEvent->setModifiers(event.modifiers());
    touchEvent->setTouchPoints(touchPoints);
    touchEvent->setTouchPointStates(eventStates);
    touchEvent->setTimestamp(event.timestamp());
    touchEvent->accept();
    return touchEvent;
}

QTouchEvent *QQuickPointerTouchEvent::asTouchEvent() const
{
    return static_cast<QTouchEvent *>(m_event);
}

#ifndef QT_NO_DEBUG_STREAM

Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QQuickPointerDevice *dev)
{
    QDebugStateSaver saver(dbg);
    dbg.nospace();
    if (!dev) {
        dbg << "QQuickPointerDevice(0)";
        return dbg;
    }
    dbg << "QQuickPointerDevice("<< dev->name() << ' ';
    QtDebugUtils::formatQEnum(dbg, dev->type());
    dbg << ' ';
    QtDebugUtils::formatQEnum(dbg, dev->pointerType());
    dbg << " caps:";
    QtDebugUtils::formatQFlags(dbg, dev->capabilities());
    if (dev->type() == QQuickPointerDevice::TouchScreen ||
            dev->type() == QQuickPointerDevice::TouchPad)
        dbg << " maxTouchPoints:" << dev->maximumTouchPoints();
    else
        dbg << " buttonCount:" << dev->buttonCount();
    dbg << ')';
    return dbg;
}

Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QQuickPointerEvent *event)
{
    QDebugStateSaver saver(dbg);
    dbg.nospace();
    if (!event) {
        dbg << "QQuickPointerEvent(0)";
        return dbg;
    }
    dbg << "QQuickPointerEvent(";
    dbg << event->timestamp();
    dbg << " dev:";
    QtDebugUtils::formatQEnum(dbg, event->device()->type());
    if (event->buttons() != Qt::NoButton) {
        dbg << " buttons:";
        QtDebugUtils::formatQEnum(dbg, event->buttons());
    }
    dbg << " [";
    int c = event->pointCount();
    for (int i = 0; i < c; ++i)
        dbg << event->point(i) << ' ';
    dbg << "])";
    return dbg;
}

Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QQuickEventPoint *event)
{
    QDebugStateSaver saver(dbg);
    dbg.nospace();
    if (!event) {
        dbg << "QQuickEventPoint(0)";
        return dbg;
    }
    dbg << "QQuickEventPoint(accepted:" << event->isAccepted()
        << " state:";
    QtDebugUtils::formatQEnum(dbg, event->state());
    dbg << " scenePos:" << event->scenePosition() << " id:" << Qt::hex << event->pointId() << Qt::dec
        << " timeHeld:" << event->timeHeld() << ')';
    return dbg;
}

#endif

QT_END_NAMESPACE
