/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the $MODULE$ of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtGui/QScreen>
#include <QtWidgets/QGraphicsItem>
#include <QtWidgets/QGraphicsScene>
#include <QtWidgets/QGraphicsView>
#include <QtWidgets/QGraphicsWidget>
#include <QtWidgets/QWidget>
#include <QtTest>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qwindowsysteminterface_p.h>
#include <private/qhighdpiscaling_p.h>
#include <private/qtouchdevice_p.h>

class tst_QTouchEventWidget : public QWidget
{
public:
    QList<QTouchEvent::TouchPoint> touchBeginPoints, touchUpdatePoints, touchEndPoints;
    bool seenTouchBegin, seenTouchUpdate, seenTouchEnd;
    bool acceptTouchBegin, acceptTouchUpdate, acceptTouchEnd;
    bool deleteInTouchBegin, deleteInTouchUpdate, deleteInTouchEnd;
    ulong timestamp;
    QTouchDevice *deviceFromEvent;

    explicit tst_QTouchEventWidget(QWidget *parent = nullptr) : QWidget(parent)
    {
        reset();
    }

    void reset()
    {
        touchBeginPoints.clear();
        touchUpdatePoints.clear();
        touchEndPoints.clear();
        seenTouchBegin = seenTouchUpdate = seenTouchEnd = false;
        acceptTouchBegin = acceptTouchUpdate = acceptTouchEnd = true;
        deleteInTouchBegin = deleteInTouchUpdate = deleteInTouchEnd = false;
    }

    bool event(QEvent *event) override
    {
        switch (event->type()) {
        case QEvent::TouchBegin:
            if (seenTouchBegin) qWarning("TouchBegin: already seen a TouchBegin");
            if (seenTouchUpdate) qWarning("TouchBegin: TouchUpdate cannot happen before TouchBegin");
            if (seenTouchEnd) qWarning("TouchBegin: TouchEnd cannot happen before TouchBegin");
            seenTouchBegin = !seenTouchBegin && !seenTouchUpdate && !seenTouchEnd;
            touchBeginPoints = static_cast<QTouchEvent *>(event)->touchPoints();
            timestamp = static_cast<QTouchEvent *>(event)->timestamp();
            deviceFromEvent = static_cast<QTouchEvent *>(event)->device();
            event->setAccepted(acceptTouchBegin);
            if (deleteInTouchBegin)
                delete this;
            break;
        case QEvent::TouchUpdate:
            if (!seenTouchBegin) qWarning("TouchUpdate: have not seen TouchBegin");
            if (seenTouchEnd) qWarning("TouchUpdate: TouchEnd cannot happen before TouchUpdate");
            seenTouchUpdate = seenTouchBegin && !seenTouchEnd;
            touchUpdatePoints = static_cast<QTouchEvent *>(event)->touchPoints();
            timestamp = static_cast<QTouchEvent *>(event)->timestamp();
            deviceFromEvent = static_cast<QTouchEvent *>(event)->device();
            event->setAccepted(acceptTouchUpdate);
            if (deleteInTouchUpdate)
                delete this;
            break;
        case QEvent::TouchEnd:
            if (!seenTouchBegin) qWarning("TouchEnd: have not seen TouchBegin");
            if (seenTouchEnd) qWarning("TouchEnd: already seen a TouchEnd");
            seenTouchEnd = seenTouchBegin && !seenTouchEnd;
            touchEndPoints = static_cast<QTouchEvent *>(event)->touchPoints();
            timestamp = static_cast<QTouchEvent *>(event)->timestamp();
            deviceFromEvent = static_cast<QTouchEvent *>(event)->device();
            event->setAccepted(acceptTouchEnd);
            if (deleteInTouchEnd)
                delete this;
            break;
        default:
            return QWidget::event(event);
        }
        return true;
    }
};

class tst_QTouchEventGraphicsItem : public QGraphicsItem
{
public:
    QList<QTouchEvent::TouchPoint> touchBeginPoints, touchUpdatePoints, touchEndPoints;
    bool seenTouchBegin, seenTouchUpdate, seenTouchEnd;
    int touchBeginCounter, touchUpdateCounter, touchEndCounter;
    bool acceptTouchBegin, acceptTouchUpdate, acceptTouchEnd;
    bool deleteInTouchBegin, deleteInTouchUpdate, deleteInTouchEnd;
    tst_QTouchEventGraphicsItem **weakpointer;

    explicit tst_QTouchEventGraphicsItem(QGraphicsItem *parent = nullptr)
        : QGraphicsItem(parent), weakpointer(0)
    {
        reset();
    }

    ~tst_QTouchEventGraphicsItem()
    {
        if (weakpointer)
            *weakpointer = 0;
    }

    void reset()
    {
        touchBeginPoints.clear();
        touchUpdatePoints.clear();
        touchEndPoints.clear();
        seenTouchBegin = seenTouchUpdate = seenTouchEnd = false;
        touchBeginCounter = touchUpdateCounter = touchEndCounter = 0;
        acceptTouchBegin = acceptTouchUpdate = acceptTouchEnd = true;
        deleteInTouchBegin = deleteInTouchUpdate = deleteInTouchEnd = false;
    }

    QRectF boundingRect() const override { return QRectF(0, 0, 10, 10); }
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override
    {
        painter->fillRect(QRectF(QPointF(0, 0), boundingRect().size()), Qt::yellow);
    }

    bool sceneEvent(QEvent *event) override
    {
        switch (event->type()) {
        case QEvent::TouchBegin:
            if (seenTouchBegin) qWarning("TouchBegin: already seen a TouchBegin");
            if (seenTouchUpdate) qWarning("TouchBegin: TouchUpdate cannot happen before TouchBegin");
            if (seenTouchEnd) qWarning("TouchBegin: TouchEnd cannot happen before TouchBegin");
            seenTouchBegin = !seenTouchBegin && !seenTouchUpdate && !seenTouchEnd;
            ++touchBeginCounter;
            touchBeginPoints = static_cast<QTouchEvent *>(event)->touchPoints();
            event->setAccepted(acceptTouchBegin);
            if (deleteInTouchBegin)
                delete this;
            break;
        case QEvent::TouchUpdate:
            if (!seenTouchBegin) qWarning("TouchUpdate: have not seen TouchBegin");
            if (seenTouchEnd) qWarning("TouchUpdate: TouchEnd cannot happen before TouchUpdate");
            seenTouchUpdate = seenTouchBegin && !seenTouchEnd;
            ++touchUpdateCounter;
            touchUpdatePoints = static_cast<QTouchEvent *>(event)->touchPoints();
            event->setAccepted(acceptTouchUpdate);
            if (deleteInTouchUpdate)
                delete this;
            break;
        case QEvent::TouchEnd:
            if (!seenTouchBegin) qWarning("TouchEnd: have not seen TouchBegin");
            if (seenTouchEnd) qWarning("TouchEnd: already seen a TouchEnd");
            seenTouchEnd = seenTouchBegin && !seenTouchEnd;
            ++touchEndCounter;
            touchEndPoints = static_cast<QTouchEvent *>(event)->touchPoints();
            event->setAccepted(acceptTouchEnd);
            if (deleteInTouchEnd)
                delete this;
            break;
        default:
            return QGraphicsItem::sceneEvent(event);
        }
        return true;
    }
};

class tst_QTouchEvent : public QObject
{
    Q_OBJECT
public:
    tst_QTouchEvent();

private slots:
    void cleanup();
    void qPointerUniqueId();
    void touchDisabledByDefault();
    void touchEventAcceptedByDefault();
    void touchBeginPropagatesWhenIgnored();
    void touchUpdateAndEndNeverPropagate();
    void basicRawEventTranslation();
    void basicRawEventTranslationOfIds();
    void multiPointRawEventTranslationOnTouchScreen();
    void multiPointRawEventTranslationOnTouchPad();
    void touchOnMultipleTouchscreens();
    void deleteInEventHandler();
    void deleteInRawEventTranslation();
    void crashInQGraphicsSceneAfterNotHandlingTouchBegin();
    void touchBeginWithGraphicsWidget();
    void testQGuiAppDelivery();
    void testMultiDevice();

private:
    QTouchDevice *touchScreenDevice;
    QTouchDevice *secondaryTouchScreenDevice;
    QTouchDevice *touchPadDevice;
};

tst_QTouchEvent::tst_QTouchEvent()
  : touchScreenDevice(QTest::createTouchDevice())
  , secondaryTouchScreenDevice(QTest::createTouchDevice())
  , touchPadDevice(QTest::createTouchDevice(QTouchDevice::TouchPad))
{
}

void tst_QTouchEvent::cleanup()
{
    QVERIFY(QGuiApplication::topLevelWindows().isEmpty());
    QWindowSystemInterfacePrivate::clearPointIdMap();
}

void tst_QTouchEvent::qPointerUniqueId()
{
    QPointingDeviceUniqueId id1, id2;

    QCOMPARE(id1.numericId(), Q_INT64_C(-1));
    QVERIFY(!id1.isValid());

    QVERIFY(  id1 == id2);
    QVERIFY(!(id1 != id2));

    QSet<QPointingDeviceUniqueId> set; // compile test
    set.insert(id1);
    set.insert(id2);
    QCOMPARE(set.size(), 1);


    const auto id3 = QPointingDeviceUniqueId::fromNumericId(-1);
    QCOMPARE(id3.numericId(), Q_INT64_C(-1));
    QVERIFY(!id3.isValid());

    QVERIFY(  id1 == id3);
    QVERIFY(!(id1 != id3));

    set.insert(id3);
    QCOMPARE(set.size(), 1);


    const auto id4 = QPointingDeviceUniqueId::fromNumericId(4);
    QCOMPARE(id4.numericId(), Q_INT64_C(4));
    QVERIFY(id4.isValid());

    QVERIFY(  id1 != id4);
    QVERIFY(!(id1 == id4));

    set.insert(id4);
    QCOMPARE(set.size(), 2);
}

void tst_QTouchEvent::touchDisabledByDefault()
{
    // QWidget
    {
        // the widget attribute is not enabled by default
        QWidget widget;
        QVERIFY(!widget.testAttribute(Qt::WA_AcceptTouchEvents));

        // events should not be accepted since they are not enabled
        QList<QTouchEvent::TouchPoint> touchPoints;
        touchPoints.append(QTouchEvent::TouchPoint(0));
        QTouchEvent touchEvent(QEvent::TouchBegin,
                               touchScreenDevice,
                               Qt::NoModifier,
                               Qt::TouchPointPressed,
                               touchPoints);
        QVERIFY(!QApplication::sendEvent(&widget, &touchEvent));
        QVERIFY(!touchEvent.isAccepted());
    }

    // QGraphicsView
    {
        QGraphicsScene scene;
        tst_QTouchEventGraphicsItem item;
        QGraphicsView view(&scene);
        scene.addItem(&item);
        item.setPos(100, 100);
        view.resize(200, 200);
        view.fitInView(scene.sceneRect());

        // touch events are not accepted by default
        QVERIFY(!item.acceptTouchEvents());

        // compose an event to the scene that is over the item
        QTouchEvent::TouchPoint touchPoint(0);
        touchPoint.setState(Qt::TouchPointPressed);
        touchPoint.setPos(view.mapFromScene(item.mapToScene(item.boundingRect().center())));
        touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint()));
        touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint()));
        QTouchEvent touchEvent(QEvent::TouchBegin,
                               touchScreenDevice,
                               Qt::NoModifier,
                               Qt::TouchPointPressed,
                               (QList<QTouchEvent::TouchPoint>() << touchPoint));
        QVERIFY(!QApplication::sendEvent(view.viewport(), &touchEvent));
        QVERIFY(!touchEvent.isAccepted());
        QVERIFY(!item.seenTouchBegin);
    }
}

void tst_QTouchEvent::touchEventAcceptedByDefault()
{
    // QWidget
    {
        // enabling touch events should automatically accept touch events
        QWidget widget;
        widget.setAttribute(Qt::WA_AcceptTouchEvents);

        // QWidget handles touch event by converting them into a mouse event, so the event is both
        // accepted and handled (res == true)
        QList<QTouchEvent::TouchPoint> touchPoints;
        touchPoints.append(QTouchEvent::TouchPoint(0));
        QTouchEvent touchEvent(QEvent::TouchBegin,
                               touchScreenDevice,
                               Qt::NoModifier,
                               Qt::TouchPointPressed,
                               touchPoints);
        QVERIFY(QApplication::sendEvent(&widget, &touchEvent));
        QVERIFY(!touchEvent.isAccepted()); // Qt 5.X ignores touch events.

        // tst_QTouchEventWidget does handle, sending succeeds
        tst_QTouchEventWidget touchWidget;
        touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
        touchEvent.ignore();
        QVERIFY(QApplication::sendEvent(&touchWidget, &touchEvent));
        QVERIFY(touchEvent.isAccepted());
    }

    // QGraphicsView
    {
        QGraphicsScene scene;
        tst_QTouchEventGraphicsItem item;
        QGraphicsView view(&scene);
        scene.addItem(&item);
        item.setPos(100, 100);
        view.resize(200, 200);
        view.fitInView(scene.sceneRect());

        // enabling touch events on the item also enables events on the viewport
        item.setAcceptTouchEvents(true);
        QVERIFY(view.viewport()->testAttribute(Qt::WA_AcceptTouchEvents));

        // compose an event to the scene that is over the item
        QTouchEvent::TouchPoint touchPoint(0);
        touchPoint.setState(Qt::TouchPointPressed);
        touchPoint.setPos(view.mapFromScene(item.mapToScene(item.boundingRect().center())));
        touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint()));
        touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint()));
        QTouchEvent touchEvent(QEvent::TouchBegin,
                               touchScreenDevice,
                               Qt::NoModifier,
                               Qt::TouchPointPressed,
                               (QList<QTouchEvent::TouchPoint>() << touchPoint));
        QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent));
        QVERIFY(touchEvent.isAccepted());
        QVERIFY(item.seenTouchBegin);
    }
}

void tst_QTouchEvent::touchBeginPropagatesWhenIgnored()
{
    // QWidget
    {
        tst_QTouchEventWidget window, child, grandchild;
        child.setParent(&window);
        grandchild.setParent(&child);

        // all widgets accept touch events, grandchild ignores, so child sees the event, but not window
        window.setAttribute(Qt::WA_AcceptTouchEvents);
        child.setAttribute(Qt::WA_AcceptTouchEvents);
        grandchild.setAttribute(Qt::WA_AcceptTouchEvents);
        grandchild.acceptTouchBegin = false;

        QList<QTouchEvent::TouchPoint> touchPoints;
        touchPoints.append(QTouchEvent::TouchPoint(0));
        QTouchEvent touchEvent(QEvent::TouchBegin,
                               touchScreenDevice,
                               Qt::NoModifier,
                               Qt::TouchPointPressed,
                               touchPoints);
        QVERIFY(QApplication::sendEvent(&grandchild, &touchEvent));
        QVERIFY(touchEvent.isAccepted());
        QVERIFY(grandchild.seenTouchBegin);
        QVERIFY(child.seenTouchBegin);
        QVERIFY(!window.seenTouchBegin);

        // disable touch on grandchild. even though it doesn't accept it, child should still get the
        // TouchBegin
        grandchild.reset();
        child.reset();
        window.reset();
        grandchild.setAttribute(Qt::WA_AcceptTouchEvents, false);

        touchEvent.ignore();
        QVERIFY(QApplication::sendEvent(&grandchild, &touchEvent));
        QVERIFY(touchEvent.isAccepted());
        QVERIFY(!grandchild.seenTouchBegin);
        QVERIFY(child.seenTouchBegin);
        QVERIFY(!window.seenTouchBegin);
    }

    // QGraphicsView
    {
        QGraphicsScene scene;
        tst_QTouchEventGraphicsItem root, child, grandchild;
        QGraphicsView view(&scene);
        scene.addItem(&root);
        root.setPos(100, 100);
        child.setParentItem(&root);
        grandchild.setParentItem(&child);
        view.resize(200, 200);
        view.fitInView(scene.sceneRect());

        // all items accept touch events, grandchild ignores, so child sees the event, but not root
        root.setAcceptTouchEvents(true);
        child.setAcceptTouchEvents(true);
        grandchild.setAcceptTouchEvents(true);
        grandchild.acceptTouchBegin = false;

        // compose an event to the scene that is over the grandchild
        QTouchEvent::TouchPoint touchPoint(0);
        touchPoint.setState(Qt::TouchPointPressed);
        touchPoint.setPos(view.mapFromScene(grandchild.mapToScene(grandchild.boundingRect().center())));
        touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint()));
        touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint()));
        QTouchEvent touchEvent(QEvent::TouchBegin,
                               touchScreenDevice,
                               Qt::NoModifier,
                               Qt::TouchPointPressed,
                               (QList<QTouchEvent::TouchPoint>() << touchPoint));
        QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent));
        QVERIFY(touchEvent.isAccepted());
        QVERIFY(grandchild.seenTouchBegin);
        QVERIFY(child.seenTouchBegin);
        QVERIFY(!root.seenTouchBegin);
    }

    // QGraphicsView
    {
        QGraphicsScene scene;
        tst_QTouchEventGraphicsItem root, child, grandchild;
        QGraphicsView view(&scene);
        scene.addItem(&root);
        root.setPos(100, 100);
        child.setParentItem(&root);
        grandchild.setParentItem(&child);
        view.resize(200, 200);
        view.fitInView(scene.sceneRect());

        // leave touch disabled on grandchild. even though it doesn't accept it, child should
        // still get the TouchBegin
        root.setAcceptTouchEvents(true);
        child.setAcceptTouchEvents(true);

        // compose an event to the scene that is over the grandchild
        QTouchEvent::TouchPoint touchPoint(0);
        touchPoint.setState(Qt::TouchPointPressed);
        touchPoint.setPos(view.mapFromScene(grandchild.mapToScene(grandchild.boundingRect().center())));
        touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint()));
        touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint()));
        QTouchEvent touchEvent(QEvent::TouchBegin,
                               touchScreenDevice,
                               Qt::NoModifier,
                               Qt::TouchPointPressed,
                               (QList<QTouchEvent::TouchPoint>() << touchPoint));
        QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent));
        QVERIFY(touchEvent.isAccepted());
        QVERIFY(!grandchild.seenTouchBegin);
        QVERIFY(child.seenTouchBegin);
        QVERIFY(!root.seenTouchBegin);
    }
}

void tst_QTouchEvent::touchUpdateAndEndNeverPropagate()
{
    // QWidget
    {
        tst_QTouchEventWidget window, child;
        child.setParent(&window);

        window.setAttribute(Qt::WA_AcceptTouchEvents);
        child.setAttribute(Qt::WA_AcceptTouchEvents);
        child.acceptTouchUpdate = false;
        child.acceptTouchEnd = false;

        QList<QTouchEvent::TouchPoint> touchPoints;
        touchPoints.append(QTouchEvent::TouchPoint(0));
        QTouchEvent touchBeginEvent(QEvent::TouchBegin,
                                    touchScreenDevice,
                                    Qt::NoModifier,
                                    Qt::TouchPointPressed,
                                    touchPoints);
        QVERIFY(QApplication::sendEvent(&child, &touchBeginEvent));
        QVERIFY(touchBeginEvent.isAccepted());
        QVERIFY(child.seenTouchBegin);
        QVERIFY(!window.seenTouchBegin);

        // send the touch update to the child, but ignore it, it doesn't propagate
        QTouchEvent touchUpdateEvent(QEvent::TouchUpdate,
                                     touchScreenDevice,
                                     Qt::NoModifier,
                                     Qt::TouchPointMoved,
                                     touchPoints);
        QVERIFY(QApplication::sendEvent(&child, &touchUpdateEvent));
        QVERIFY(!touchUpdateEvent.isAccepted());
        QVERIFY(child.seenTouchUpdate);
        QVERIFY(!window.seenTouchUpdate);

        // send the touch end, same thing should happen as with touch update
        QTouchEvent touchEndEvent(QEvent::TouchEnd,
                                  touchScreenDevice,
                                  Qt::NoModifier,
                                  Qt::TouchPointReleased,
                                  touchPoints);
        QVERIFY(QApplication::sendEvent(&child, &touchEndEvent));
        QVERIFY(!touchEndEvent.isAccepted());
        QVERIFY(child.seenTouchEnd);
        QVERIFY(!window.seenTouchEnd);
    }

    // QGraphicsView
    {
        QGraphicsScene scene;
        tst_QTouchEventGraphicsItem root, child, grandchild;
        QGraphicsView view(&scene);
        scene.addItem(&root);
        root.setPos(100, 100);
        child.setParentItem(&root);
        grandchild.setParentItem(&child);
        view.resize(200, 200);
        view.fitInView(scene.sceneRect());

        root.setAcceptTouchEvents(true);
        child.setAcceptTouchEvents(true);
        child.acceptTouchUpdate = false;
        child.acceptTouchEnd = false;

        // compose an event to the scene that is over the child
        QTouchEvent::TouchPoint touchPoint(0);
        touchPoint.setState(Qt::TouchPointPressed);
        touchPoint.setPos(view.mapFromScene(grandchild.mapToScene(grandchild.boundingRect().center())));
        touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint()));
        touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint()));
        QTouchEvent touchBeginEvent(QEvent::TouchBegin,
                                    touchScreenDevice,
                                    Qt::NoModifier,
                                    Qt::TouchPointPressed,
                                    (QList<QTouchEvent::TouchPoint>() << touchPoint));
        QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent));
        QVERIFY(touchBeginEvent.isAccepted());
        QVERIFY(child.seenTouchBegin);
        QVERIFY(!root.seenTouchBegin);

        // send the touch update to the child, but ignore it, it doesn't propagate
        touchPoint.setState(Qt::TouchPointMoved);
        QTouchEvent touchUpdateEvent(QEvent::TouchUpdate,
                                     touchScreenDevice,
                                     Qt::NoModifier,
                                     Qt::TouchPointMoved,
                                     (QList<QTouchEvent::TouchPoint>() << touchPoint));
        QVERIFY(QApplication::sendEvent(view.viewport(), &touchUpdateEvent));
        // the scene accepts the event, since it found an item to send the event to
        QVERIFY(!touchUpdateEvent.isAccepted());
        QVERIFY(child.seenTouchUpdate);
        QVERIFY(!root.seenTouchUpdate);

        // send the touch end, same thing should happen as with touch update
        touchPoint.setState(Qt::TouchPointReleased);
        QTouchEvent touchEndEvent(QEvent::TouchEnd,
                                  touchScreenDevice,
                                  Qt::NoModifier,
                                  Qt::TouchPointReleased,
                                  (QList<QTouchEvent::TouchPoint>() << touchPoint));
        QVERIFY(QApplication::sendEvent(view.viewport(), &touchEndEvent));
        // the scene accepts the event, since it found an item to send the event to
        QVERIFY(!touchEndEvent.isAccepted());
        QVERIFY(child.seenTouchEnd);
        QVERIFY(!root.seenTouchEnd);
    }
}

QPointF normalized(const QPointF &pos, const QRectF &rect)
{
    return QPointF(pos.x() / rect.width(), pos.y() / rect.height());
}

void tst_QTouchEvent::basicRawEventTranslation()
{
    tst_QTouchEventWidget touchWidget;
    touchWidget.setWindowTitle(QTest::currentTestFunction());
    touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
    touchWidget.setGeometry(100, 100, 400, 300);
    touchWidget.show();
    QVERIFY(QTest::qWaitForWindowExposed(&touchWidget));

    QPointF pos = touchWidget.rect().center();
    QPointF screenPos = touchWidget.mapToGlobal(pos.toPoint());
    QPointF delta(10, 10);
    QRectF screenGeometry = touchWidget.screen()->geometry();

    QTouchEvent::TouchPoint rawTouchPoint;
    rawTouchPoint.setId(0);

    // this should be translated to a TouchBegin
    rawTouchPoint.setState(Qt::TouchPointPressed);
    rawTouchPoint.setScreenPos(screenPos);
    rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry));
    QVector<QPointF> rawPosList;
    rawPosList << QPointF(12, 34) << QPointF(56, 78);
    rawTouchPoint.setRawScreenPositions(rawPosList);
    const ulong timestamp = 1234;
    QWindow *window = touchWidget.windowHandle();
    QList<QWindowSystemInterface::TouchPoint> nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoint, window);
    QWindowSystemInterface::handleTouchEvent(window, timestamp, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(touchWidget.seenTouchBegin);
    QVERIFY(!touchWidget.seenTouchUpdate);
    QVERIFY(!touchWidget.seenTouchEnd);
    QCOMPARE(touchWidget.touchBeginPoints.count(), 1);
    QCOMPARE(touchWidget.timestamp, timestamp);
    QTouchEvent::TouchPoint touchBeginPoint = touchWidget.touchBeginPoints.first();
    const int touchPointId = (QTouchDevicePrivate::get(touchScreenDevice)->id << 24) + 1;
    QCOMPARE(touchBeginPoint.id(), touchPointId);
    QCOMPARE(touchBeginPoint.state(), rawTouchPoint.state());
    QCOMPARE(touchBeginPoint.pos(), pos);
    QCOMPARE(touchBeginPoint.startPos(), pos);
    QCOMPARE(touchBeginPoint.lastPos(), pos);
    QCOMPARE(touchBeginPoint.scenePos(), rawTouchPoint.screenPos());
    QCOMPARE(touchBeginPoint.startScenePos(), rawTouchPoint.screenPos());
    QCOMPARE(touchBeginPoint.lastScenePos(), rawTouchPoint.screenPos());
    QCOMPARE(touchBeginPoint.screenPos(), rawTouchPoint.screenPos());
    QCOMPARE(touchBeginPoint.startScreenPos(), rawTouchPoint.screenPos());
    QCOMPARE(touchBeginPoint.lastScreenPos(), rawTouchPoint.screenPos());
    QCOMPARE(touchBeginPoint.normalizedPos(), rawTouchPoint.normalizedPos());
    QCOMPARE(touchBeginPoint.startNormalizedPos(), touchBeginPoint.normalizedPos());
    QCOMPARE(touchBeginPoint.lastNormalizedPos(), touchBeginPoint.normalizedPos());
    QCOMPARE(touchBeginPoint.pos(), pos);
    QCOMPARE(touchBeginPoint.screenPos(), rawTouchPoint.screenPos());
    QCOMPARE(touchBeginPoint.scenePos(), touchBeginPoint.scenePos());
    QCOMPARE(touchBeginPoint.ellipseDiameters(), QSizeF(0, 0));
    QCOMPARE(touchBeginPoint.pressure(), qreal(1.));
    QCOMPARE(touchBeginPoint.velocity(), QVector2D());
    if (!QHighDpiScaling::isActive())
        QCOMPARE(touchBeginPoint.rawScreenPositions(), rawPosList);

    // moving the point should translate to TouchUpdate
    rawTouchPoint.setState(Qt::TouchPointMoved);
    rawTouchPoint.setScreenPos(screenPos + delta);
    rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry));
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoint, window);
    QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(touchWidget.seenTouchBegin);
    QVERIFY(touchWidget.seenTouchUpdate);
    QVERIFY(!touchWidget.seenTouchEnd);
    QCOMPARE(touchWidget.touchUpdatePoints.count(), 1);
    QTouchEvent::TouchPoint touchUpdatePoint = touchWidget.touchUpdatePoints.first();
    QCOMPARE(touchUpdatePoint.id(), touchPointId);
    QCOMPARE(touchUpdatePoint.state(), rawTouchPoint.state());
    QCOMPARE(touchUpdatePoint.pos(), pos + delta);
    QCOMPARE(touchUpdatePoint.startPos(), pos);
    QCOMPARE(touchUpdatePoint.lastPos(), pos);
    QCOMPARE(touchUpdatePoint.scenePos(), rawTouchPoint.screenPos());
    QCOMPARE(touchUpdatePoint.startScenePos(), screenPos);
    QCOMPARE(touchUpdatePoint.lastScenePos(), screenPos);
    QCOMPARE(touchUpdatePoint.screenPos(), rawTouchPoint.screenPos());
    QCOMPARE(touchUpdatePoint.startScreenPos(), screenPos);
    QCOMPARE(touchUpdatePoint.lastScreenPos(), screenPos);
    QCOMPARE(touchUpdatePoint.normalizedPos(), rawTouchPoint.normalizedPos());
    QCOMPARE(touchUpdatePoint.startNormalizedPos(), touchBeginPoint.normalizedPos());
    QCOMPARE(touchUpdatePoint.lastNormalizedPos(), touchBeginPoint.normalizedPos());
    QCOMPARE(touchUpdatePoint.pos(), pos + delta);
    QCOMPARE(touchUpdatePoint.screenPos(), rawTouchPoint.screenPos());
    QCOMPARE(touchUpdatePoint.scenePos(), touchUpdatePoint.scenePos());
    QCOMPARE(touchUpdatePoint.ellipseDiameters(), QSizeF(0, 0));
    QCOMPARE(touchUpdatePoint.pressure(), qreal(1.));

    // releasing the point translates to TouchEnd
    rawTouchPoint.setState(Qt::TouchPointReleased);
    rawTouchPoint.setScreenPos(screenPos + delta + delta);
    rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry));
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoint, window);
    QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(touchWidget.seenTouchBegin);
    QVERIFY(touchWidget.seenTouchUpdate);
    QVERIFY(touchWidget.seenTouchEnd);
    QCOMPARE(touchWidget.touchEndPoints.count(), 1);
    QTouchEvent::TouchPoint touchEndPoint = touchWidget.touchEndPoints.first();
    QCOMPARE(touchEndPoint.id(), touchPointId);
    QCOMPARE(touchEndPoint.state(), rawTouchPoint.state());
    QCOMPARE(touchEndPoint.pos(), pos + delta + delta);
    QCOMPARE(touchEndPoint.startPos(), pos);
    QCOMPARE(touchEndPoint.lastPos(), pos + delta);
    QCOMPARE(touchEndPoint.scenePos(), rawTouchPoint.screenPos());
    QCOMPARE(touchEndPoint.startScenePos(), screenPos);
    QCOMPARE(touchEndPoint.lastScenePos(), screenPos + delta);
    QCOMPARE(touchEndPoint.screenPos(), rawTouchPoint.screenPos());
    QCOMPARE(touchEndPoint.startScreenPos(), screenPos);
    QCOMPARE(touchEndPoint.lastScreenPos(), screenPos + delta);
    QCOMPARE(touchEndPoint.normalizedPos(), rawTouchPoint.normalizedPos());
    QCOMPARE(touchEndPoint.startNormalizedPos(), touchBeginPoint.normalizedPos());
    QCOMPARE(touchEndPoint.lastNormalizedPos(), touchUpdatePoint.normalizedPos());
    QCOMPARE(touchEndPoint.pos(), pos + delta + delta);
    QCOMPARE(touchEndPoint.screenPos(), rawTouchPoint.screenPos());
    QCOMPARE(touchEndPoint.scenePos(), touchEndPoint.scenePos());
    QCOMPARE(touchEndPoint.ellipseDiameters(), QSizeF(0, 0));
    QCOMPARE(touchEndPoint.pressure(), qreal(0.));
}

void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen()
{
    tst_QTouchEventWidget touchWidget;
    touchWidget.setWindowTitle(QTest::currentTestFunction());
    touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
    touchWidget.setGeometry(100, 100, 400, 300);

    tst_QTouchEventWidget leftWidget(&touchWidget);
    leftWidget.setAttribute(Qt::WA_AcceptTouchEvents);
    leftWidget.setGeometry(0, 100, 100, 100);

    tst_QTouchEventWidget rightWidget(&touchWidget);
    rightWidget.setAttribute(Qt::WA_AcceptTouchEvents);
    rightWidget.setGeometry(300, 100, 100, 100);

    touchWidget.show();
    QVERIFY(QTest::qWaitForWindowExposed(&touchWidget));

    QPointF leftPos = leftWidget.rect().center();
    QPointF rightPos = rightWidget.rect().center();
    QPointF centerPos = touchWidget.rect().center();
    QPointF leftScreenPos = leftWidget.mapToGlobal(leftPos.toPoint());
    QPointF rightScreenPos = rightWidget.mapToGlobal(rightPos.toPoint());
    QPointF centerScreenPos = touchWidget.mapToGlobal(centerPos.toPoint());
    QRectF screenGeometry = touchWidget.screen()->geometry();

    QList<QTouchEvent::TouchPoint> rawTouchPoints;
    rawTouchPoints.append(QTouchEvent::TouchPoint(0));
    rawTouchPoints.append(QTouchEvent::TouchPoint(1));

    // generate TouchBegins on both leftWidget and rightWidget
    rawTouchPoints[0].setState(Qt::TouchPointPressed);
    rawTouchPoints[0].setScreenPos(leftScreenPos);
    rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
    rawTouchPoints[1].setState(Qt::TouchPointPressed);
    rawTouchPoints[1].setScreenPos(rightScreenPos);
    rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
    QWindow *window = touchWidget.windowHandle();
    QList<QWindowSystemInterface::TouchPoint> nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window);
    QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(!touchWidget.seenTouchBegin);
    QVERIFY(!touchWidget.seenTouchUpdate);
    QVERIFY(!touchWidget.seenTouchEnd);
    QVERIFY(leftWidget.seenTouchBegin);
    QVERIFY(!leftWidget.seenTouchUpdate);
    QVERIFY(!leftWidget.seenTouchEnd);
    QVERIFY(rightWidget.seenTouchBegin);
    QVERIFY(!rightWidget.seenTouchUpdate);
    QVERIFY(!rightWidget.seenTouchEnd);
    QCOMPARE(leftWidget.touchBeginPoints.count(), 1);
    QCOMPARE(rightWidget.touchBeginPoints.count(), 1);
    const int touchPointId0 = (QTouchDevicePrivate::get(touchScreenDevice)->id << 24) + 1;
    const int touchPointId1 = touchPointId0 + 1;
    {
        QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchBeginPoints.first();
        QCOMPARE(leftTouchPoint.id(), touchPointId0);
        QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
        QCOMPARE(leftTouchPoint.pos(), leftPos);
        QCOMPARE(leftTouchPoint.startPos(), leftPos);
        QCOMPARE(leftTouchPoint.lastPos(), leftPos);
        QCOMPARE(leftTouchPoint.scenePos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.lastScenePos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.screenPos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.lastScreenPos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.pos(), leftPos);
        QCOMPARE(leftTouchPoint.scenePos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.screenPos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.ellipseDiameters(), QSizeF(0, 0));
        QCOMPARE(leftTouchPoint.pressure(), qreal(1.));

        QTouchEvent::TouchPoint rightTouchPoint = rightWidget.touchBeginPoints.first();
        QCOMPARE(rightTouchPoint.id(), touchPointId1);
        QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
        QCOMPARE(rightTouchPoint.pos(), rightPos);
        QCOMPARE(rightTouchPoint.startPos(), rightPos);
        QCOMPARE(rightTouchPoint.lastPos(), rightPos);
        QCOMPARE(rightTouchPoint.scenePos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.lastScenePos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.screenPos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.lastScreenPos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.pos(), rightPos);
        QCOMPARE(rightTouchPoint.scenePos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.screenPos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.ellipseDiameters(), QSizeF(0, 0));
        QCOMPARE(rightTouchPoint.pressure(), qreal(1.));
    }

    // generate TouchUpdates on both leftWidget and rightWidget
    rawTouchPoints[0].setState(Qt::TouchPointMoved);
    rawTouchPoints[0].setScreenPos(centerScreenPos);
    rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
    rawTouchPoints[1].setState(Qt::TouchPointMoved);
    rawTouchPoints[1].setScreenPos(centerScreenPos);
    rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window);
    QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(!touchWidget.seenTouchBegin);
    QVERIFY(!touchWidget.seenTouchUpdate);
    QVERIFY(!touchWidget.seenTouchEnd);
    QVERIFY(leftWidget.seenTouchBegin);
    QVERIFY(leftWidget.seenTouchUpdate);
    QVERIFY(!leftWidget.seenTouchEnd);
    QVERIFY(rightWidget.seenTouchBegin);
    QVERIFY(rightWidget.seenTouchUpdate);
    QVERIFY(!rightWidget.seenTouchEnd);
    QCOMPARE(leftWidget.touchUpdatePoints.count(), 1);
    QCOMPARE(rightWidget.touchUpdatePoints.count(), 1);
    {
        QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchUpdatePoints.first();
        QCOMPARE(leftTouchPoint.id(), touchPointId0);
        QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
        QCOMPARE(leftTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
        QCOMPARE(leftTouchPoint.startPos(), leftPos);
        QCOMPARE(leftTouchPoint.lastPos(), leftPos);
        QCOMPARE(leftTouchPoint.scenePos(), centerScreenPos);
        QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.lastScenePos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.screenPos(), centerScreenPos);
        QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.lastScreenPos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.pos(), leftWidget.mapFromParent(centerPos.toPoint()));
        QCOMPARE(leftTouchPoint.scenePos(), centerScreenPos);
        QCOMPARE(leftTouchPoint.screenPos(), centerScreenPos);
        QCOMPARE(leftTouchPoint.ellipseDiameters(), QSizeF(0, 0));
        QCOMPARE(leftTouchPoint.pressure(), qreal(1.));

        QTouchEvent::TouchPoint rightTouchPoint = rightWidget.touchUpdatePoints.first();
        QCOMPARE(rightTouchPoint.id(), touchPointId1);
        QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
        QCOMPARE(rightTouchPoint.pos(), QPointF(rightWidget.mapFromParent(centerPos.toPoint())));
        QCOMPARE(rightTouchPoint.startPos(), rightPos);
        QCOMPARE(rightTouchPoint.lastPos(), rightPos);
        QCOMPARE(rightTouchPoint.scenePos(), centerScreenPos);
        QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.lastScenePos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.screenPos(), centerScreenPos);
        QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.lastScreenPos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.pos(), rightWidget.mapFromParent(centerPos.toPoint()));
        QCOMPARE(rightTouchPoint.scenePos(), centerScreenPos);
        QCOMPARE(rightTouchPoint.screenPos(), centerScreenPos);
        QCOMPARE(rightTouchPoint.ellipseDiameters(), QSizeF(0, 0));
        QCOMPARE(rightTouchPoint.pressure(), qreal(1.));
    }

    // generate TouchEnds on both leftWidget and rightWidget
    rawTouchPoints[0].setState(Qt::TouchPointReleased);
    rawTouchPoints[0].setScreenPos(centerScreenPos);
    rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
    rawTouchPoints[1].setState(Qt::TouchPointReleased);
    rawTouchPoints[1].setScreenPos(centerScreenPos);
    rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window);
    QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(!touchWidget.seenTouchBegin);
    QVERIFY(!touchWidget.seenTouchUpdate);
    QVERIFY(!touchWidget.seenTouchEnd);
    QVERIFY(leftWidget.seenTouchBegin);
    QVERIFY(leftWidget.seenTouchUpdate);
    QVERIFY(leftWidget.seenTouchEnd);
    QVERIFY(rightWidget.seenTouchBegin);
    QVERIFY(rightWidget.seenTouchUpdate);
    QVERIFY(rightWidget.seenTouchEnd);
    QCOMPARE(leftWidget.touchEndPoints.count(), 1);
    QCOMPARE(rightWidget.touchEndPoints.count(), 1);
    {
        QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchEndPoints.first();
        QCOMPARE(leftTouchPoint.id(), touchPointId0);
        QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
        QCOMPARE(leftTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
        QCOMPARE(leftTouchPoint.startPos(), leftPos);
        QCOMPARE(leftTouchPoint.lastPos(), leftTouchPoint.pos());
        QCOMPARE(leftTouchPoint.scenePos(), centerScreenPos);
        QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.lastScenePos(), leftTouchPoint.scenePos());
        QCOMPARE(leftTouchPoint.screenPos(), centerScreenPos);
        QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.lastScreenPos(), leftTouchPoint.screenPos());
        QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.pos(), leftWidget.mapFromParent(centerPos.toPoint()));
        QCOMPARE(leftTouchPoint.scenePos(), centerScreenPos);
        QCOMPARE(leftTouchPoint.screenPos(), centerScreenPos);
        QCOMPARE(leftTouchPoint.ellipseDiameters(), QSizeF(0, 0));
        QCOMPARE(leftTouchPoint.pressure(), qreal(0.));

        QTouchEvent::TouchPoint rightTouchPoint = rightWidget.touchEndPoints.first();
        QCOMPARE(rightTouchPoint.id(), touchPointId1);
        QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
        QCOMPARE(rightTouchPoint.pos(), QPointF(rightWidget.mapFromParent(centerPos.toPoint())));
        QCOMPARE(rightTouchPoint.startPos(), rightPos);
        QCOMPARE(rightTouchPoint.lastPos(), rightTouchPoint.pos());
        QCOMPARE(rightTouchPoint.scenePos(), centerScreenPos);
        QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.lastScenePos(), rightTouchPoint.scenePos());
        QCOMPARE(rightTouchPoint.screenPos(), centerScreenPos);
        QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.lastScreenPos(), rightTouchPoint.screenPos());
        QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.pos(), rightWidget.mapFromParent(centerPos.toPoint()));
        QCOMPARE(rightTouchPoint.scenePos(), centerScreenPos);
        QCOMPARE(rightTouchPoint.screenPos(), centerScreenPos);
        QCOMPARE(rightTouchPoint.ellipseDiameters(), QSizeF(0, 0));
        QCOMPARE(rightTouchPoint.pressure(), qreal(0.));
    }
}

void tst_QTouchEvent::touchOnMultipleTouchscreens()
{
    tst_QTouchEventWidget touchWidget;
    touchWidget.setWindowTitle(QTest::currentTestFunction());
    touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
    touchWidget.setGeometry(100, 100, 400, 300);
    touchWidget.show();
    QVERIFY(QTest::qWaitForWindowExposed(&touchWidget));
    QWindow *window = touchWidget.windowHandle();

    QPointF pos = touchWidget.rect().center();
    QPointF screenPos = touchWidget.mapToGlobal(pos.toPoint());
    QPointF delta(10, 10);
    QRectF screenGeometry = touchWidget.screen()->geometry();

    QVector<QTouchEvent::TouchPoint> rawTouchPoints(3);
    rawTouchPoints[0].setId(0);
    rawTouchPoints[1].setId(10);
    rawTouchPoints[2].setId(11);

    // this should be translated to a TouchBegin
    rawTouchPoints[0].setState(Qt::TouchPointPressed);
    rawTouchPoints[0].setScreenPos(screenPos);
    rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
    rawTouchPoints[0].setRawScreenPositions({{12, 34}, {56, 78}});
    ulong timestamp = 1234;
    QList<QWindowSystemInterface::TouchPoint> nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[0], window);
    QWindowSystemInterface::handleTouchEvent(window, timestamp, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(touchWidget.seenTouchBegin);
    QVERIFY(!touchWidget.seenTouchUpdate);
    QVERIFY(!touchWidget.seenTouchEnd);
    QCOMPARE(touchWidget.touchBeginPoints.count(), 1);
    QCOMPARE(touchWidget.timestamp, timestamp);
    QTouchEvent::TouchPoint touchBeginPoint = touchWidget.touchBeginPoints.first();
    const int touchPointId = (QTouchDevicePrivate::get(touchScreenDevice)->id << 24) + 1;
    const int secTouchPointId = (QTouchDevicePrivate::get(secondaryTouchScreenDevice)->id << 24) + 2;
    QCOMPARE(touchBeginPoint.id(), touchPointId);
    QCOMPARE(touchBeginPoint.state(), rawTouchPoints[0].state());
    QCOMPARE(touchBeginPoint.pos(), pos);

    // press a point on secondaryTouchScreenDevice
    touchWidget.seenTouchBegin = false;
    rawTouchPoints[1].setState(Qt::TouchPointPressed);
    rawTouchPoints[1].setScreenPos(screenPos);
    rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
    rawTouchPoints[1].setRawScreenPositions({{90, 100}, {110, 120}});
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[1], window);
    QWindowSystemInterface::handleTouchEvent(window, ++timestamp, secondaryTouchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(!touchWidget.seenTouchEnd);
    QCOMPARE(touchWidget.touchBeginPoints.count(), 1);
    QCOMPARE(touchWidget.timestamp, timestamp);
    touchBeginPoint = touchWidget.touchBeginPoints[0];
    QCOMPARE(touchBeginPoint.id(), (QTouchDevicePrivate::get(secondaryTouchScreenDevice)->id << 24) + 2);
    QCOMPARE(touchBeginPoint.state(), rawTouchPoints[1].state());
    QCOMPARE(touchBeginPoint.pos(), pos);

    // press another point on secondaryTouchScreenDevice
    touchWidget.seenTouchBegin = false;
    rawTouchPoints[2].setState(Qt::TouchPointPressed);
    rawTouchPoints[2].setScreenPos(screenPos);
    rawTouchPoints[2].setNormalizedPos(normalized(rawTouchPoints[2].pos(), screenGeometry));
    rawTouchPoints[2].setRawScreenPositions({{130, 140}, {150, 160}});
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[2], window);
    QWindowSystemInterface::handleTouchEvent(window, ++timestamp, secondaryTouchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(!touchWidget.seenTouchEnd);
    QCOMPARE(touchWidget.touchBeginPoints.count(), 1);
    QCOMPARE(touchWidget.timestamp, timestamp);
    touchBeginPoint = touchWidget.touchBeginPoints[0];
    QCOMPARE(touchBeginPoint.id(), (QTouchDevicePrivate::get(secondaryTouchScreenDevice)->id << 24) + 3);
    QCOMPARE(touchBeginPoint.state(), rawTouchPoints[2].state());
    QCOMPARE(touchBeginPoint.pos(), pos);

    // moving the first point should translate to TouchUpdate
    rawTouchPoints[0].setState(Qt::TouchPointMoved);
    rawTouchPoints[0].setScreenPos(screenPos + delta);
    rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[0], window);
    QWindowSystemInterface::handleTouchEvent(window, ++timestamp, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(touchWidget.seenTouchBegin);
    QVERIFY(touchWidget.seenTouchUpdate);
    QVERIFY(!touchWidget.seenTouchEnd);
    QCOMPARE(touchWidget.touchUpdatePoints.count(), 1);
    QTouchEvent::TouchPoint touchUpdatePoint = touchWidget.touchUpdatePoints.first();
    QCOMPARE(touchUpdatePoint.id(), touchPointId);
    QCOMPARE(touchUpdatePoint.state(), rawTouchPoints[0].state());
    QCOMPARE(touchUpdatePoint.pos(), pos + delta);

    // releasing the first point translates to TouchEnd
    rawTouchPoints[0].setState(Qt::TouchPointReleased);
    rawTouchPoints[0].setScreenPos(screenPos + delta + delta);
    rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[0], window);
    QWindowSystemInterface::handleTouchEvent(window, ++timestamp, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(touchWidget.seenTouchBegin);
    QVERIFY(touchWidget.seenTouchUpdate);
    QVERIFY(touchWidget.seenTouchEnd);
    QCOMPARE(touchWidget.touchEndPoints.count(), 1);
    QTouchEvent::TouchPoint touchEndPoint = touchWidget.touchEndPoints.first();
    QCOMPARE(touchEndPoint.id(), touchPointId);
    QCOMPARE(touchEndPoint.state(), rawTouchPoints[0].state());
    QCOMPARE(touchEndPoint.pos(), pos + delta + delta);

    // Widgets don't normally handle this case: if a TouchEnd was seen before, then
    // WA_WState_AcceptedTouchBeginEvent will be false, and
    // QApplicationPrivate::translateRawTouchEvent will ignore touch events that aren't TouchBegin.
    // So we have to set it true.  It _did_ in fact accept the touch begin from the secondary device,
    // but it also got a TouchEnd from the primary device in the meantime.
    touchWidget.setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, true);

    // Releasing one point on the secondary touchscreen does not yet generate TouchEnd.
    touchWidget.seenTouchEnd = false;
    touchWidget.touchEndPoints.clear();
    rawTouchPoints[1].setState(Qt::TouchPointReleased);
    rawTouchPoints[2].setState(Qt::TouchPointStationary);
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[1] << rawTouchPoints[2], window);
    QWindowSystemInterface::handleTouchEvent(window, ++timestamp, secondaryTouchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(touchWidget.seenTouchBegin);
    QVERIFY(touchWidget.seenTouchUpdate);
    QVERIFY(!touchWidget.seenTouchEnd);
    QCOMPARE(touchWidget.touchUpdatePoints.count(), 2);
    QCOMPARE(touchWidget.touchUpdatePoints[0].id(), secTouchPointId);
    QCOMPARE(touchWidget.touchUpdatePoints[1].id(), secTouchPointId + 1);

    // releasing the last point on the secondary touchscreen translates to TouchEnd
    touchWidget.seenTouchEnd = false;
    rawTouchPoints[2].setState(Qt::TouchPointReleased);
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[2], window);
    QWindowSystemInterface::handleTouchEvent(window, ++timestamp, secondaryTouchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(touchWidget.seenTouchBegin);
    QVERIFY(touchWidget.seenTouchUpdate);
    QVERIFY(touchWidget.seenTouchEnd);
    QCOMPARE(touchWidget.touchEndPoints.count(), 1);
    touchEndPoint = touchWidget.touchEndPoints.first();
    QCOMPARE(touchEndPoint.id(), secTouchPointId + 1);
    QCOMPARE(touchEndPoint.state(), rawTouchPoints[2].state());
}

void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad()
{
    tst_QTouchEventWidget touchWidget;
    touchWidget.setWindowTitle(QTest::currentTestFunction());
    touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
    touchWidget.setGeometry(100, 100, 400, 300);

    tst_QTouchEventWidget leftWidget(&touchWidget);
    leftWidget.setAttribute(Qt::WA_AcceptTouchEvents);
    leftWidget.setGeometry(0, 100, 100, 100);
    leftWidget.acceptTouchBegin =true;

    tst_QTouchEventWidget rightWidget(&touchWidget);
    rightWidget.setAttribute(Qt::WA_AcceptTouchEvents);
    rightWidget.setGeometry(300, 100, 100, 100);

    touchWidget.show();
    QVERIFY(QTest::qWaitForWindowExposed(&touchWidget));

    QPointF leftPos = leftWidget.rect().center();
    QPointF rightPos = rightWidget.rect().center();
    QPointF centerPos = touchWidget.rect().center();
    QPointF leftScreenPos = leftWidget.mapToGlobal(leftPos.toPoint());
    QPointF rightScreenPos = rightWidget.mapToGlobal(rightPos.toPoint());
    QPointF centerScreenPos = touchWidget.mapToGlobal(centerPos.toPoint());
    QRectF screenGeometry = touchWidget.screen()->geometry();

    QList<QTouchEvent::TouchPoint> rawTouchPoints;
    rawTouchPoints.append(QTouchEvent::TouchPoint(0));
    rawTouchPoints.append(QTouchEvent::TouchPoint(1));

    // generate TouchBegin on leftWidget only
    rawTouchPoints[0].setState(Qt::TouchPointPressed);
    rawTouchPoints[0].setScreenPos(leftScreenPos);
    rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
    rawTouchPoints[1].setState(Qt::TouchPointPressed);
    rawTouchPoints[1].setScreenPos(rightScreenPos);
    rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
    QWindow *window = touchWidget.windowHandle();
    QList<QWindowSystemInterface::TouchPoint> nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window);
    QWindowSystemInterface::handleTouchEvent(window, 0, touchPadDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(!touchWidget.seenTouchBegin);
    QVERIFY(!touchWidget.seenTouchUpdate);
    QVERIFY(!touchWidget.seenTouchEnd);
    QEXPECT_FAIL("", "QTBUG-46266, fails in Qt 5", Abort);
    QVERIFY(!leftWidget.seenTouchBegin);
    QVERIFY(!leftWidget.seenTouchUpdate);
    QVERIFY(!leftWidget.seenTouchEnd);
    QVERIFY(!rightWidget.seenTouchBegin);
    QVERIFY(!rightWidget.seenTouchUpdate);
    QVERIFY(!rightWidget.seenTouchEnd);
    QCOMPARE(leftWidget.touchBeginPoints.count(), 2);
    QCOMPARE(rightWidget.touchBeginPoints.count(), 0);
    {
        QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchBeginPoints.at(0);
        QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id());
        QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
        QCOMPARE(leftTouchPoint.pos(), leftPos);
        QCOMPARE(leftTouchPoint.startPos(), leftPos);
        QCOMPARE(leftTouchPoint.lastPos(), leftPos);
        QCOMPARE(leftTouchPoint.scenePos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.lastScenePos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.screenPos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.lastScreenPos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.pos(), leftPos);
        QCOMPARE(leftTouchPoint.scenePos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.screenPos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.ellipseDiameters(), QSizeF(0, 0));
        QCOMPARE(leftTouchPoint.pressure(), qreal(1.));

        QTouchEvent::TouchPoint rightTouchPoint = leftWidget.touchBeginPoints.at(1);
        QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id());
        QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
        QCOMPARE(rightTouchPoint.pos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
        QCOMPARE(rightTouchPoint.startPos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
        QCOMPARE(rightTouchPoint.lastPos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
        QCOMPARE(rightTouchPoint.scenePos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.lastScenePos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.screenPos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.lastScreenPos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.pos(), rightWidget.mapFromParent(rightScreenPos.toPoint()));
        QCOMPARE(rightTouchPoint.scenePos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.screenPos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.ellipseDiameters(), QSizeF(0, 0));
        QCOMPARE(rightTouchPoint.pressure(), qreal(1.));
    }

    // generate TouchUpdate on leftWidget
    rawTouchPoints[0].setState(Qt::TouchPointMoved);
    rawTouchPoints[0].setScreenPos(centerScreenPos);
    rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
    rawTouchPoints[1].setState(Qt::TouchPointMoved);
    rawTouchPoints[1].setScreenPos(centerScreenPos);
    rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window);
    QWindowSystemInterface::handleTouchEvent(window, 0, touchPadDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(!touchWidget.seenTouchBegin);
    QVERIFY(!touchWidget.seenTouchUpdate);
    QVERIFY(!touchWidget.seenTouchEnd);
    QVERIFY(leftWidget.seenTouchBegin);
    QVERIFY(leftWidget.seenTouchUpdate);
    QVERIFY(!leftWidget.seenTouchEnd);
    QVERIFY(!rightWidget.seenTouchBegin);
    QVERIFY(!rightWidget.seenTouchUpdate);
    QVERIFY(!rightWidget.seenTouchEnd);
    QCOMPARE(leftWidget.touchUpdatePoints.count(), 2);
    QCOMPARE(rightWidget.touchUpdatePoints.count(), 0);
    {
        QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchUpdatePoints.at(0);
        QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id());
        QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
        QCOMPARE(leftTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
        QCOMPARE(leftTouchPoint.startPos(), leftPos);
        QCOMPARE(leftTouchPoint.lastPos(), leftPos);
        QCOMPARE(leftTouchPoint.scenePos(), centerScreenPos);
        QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.lastScenePos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.screenPos(), centerScreenPos);
        QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.lastScreenPos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.pos(), leftWidget.mapFromParent(centerPos.toPoint()));
        QCOMPARE(leftTouchPoint.scenePos(), centerScreenPos);
        QCOMPARE(leftTouchPoint.screenPos(), centerScreenPos);
        QCOMPARE(leftTouchPoint.ellipseDiameters(), QSizeF(0, 0));
        QCOMPARE(leftTouchPoint.pressure(), qreal(1.));

        QTouchEvent::TouchPoint rightTouchPoint = leftWidget.touchUpdatePoints.at(1);
        QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id());
        QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
        QCOMPARE(rightTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
        QCOMPARE(rightTouchPoint.startPos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
        QCOMPARE(rightTouchPoint.lastPos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
        QCOMPARE(rightTouchPoint.scenePos(), centerScreenPos);
        QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.lastScenePos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.screenPos(), centerScreenPos);
        QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.lastScreenPos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.pos(), leftWidget.mapFromParent(centerPos.toPoint()));
        QCOMPARE(rightTouchPoint.scenePos(), centerScreenPos);
        QCOMPARE(rightTouchPoint.screenPos(), centerScreenPos);
        QCOMPARE(rightTouchPoint.ellipseDiameters(), QSizeF(0, 0));
        QCOMPARE(rightTouchPoint.pressure(), qreal(1.));
    }

    // generate TouchEnd on leftWidget
    rawTouchPoints[0].setState(Qt::TouchPointReleased);
    rawTouchPoints[0].setScreenPos(centerScreenPos);
    rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
    rawTouchPoints[1].setState(Qt::TouchPointReleased);
    rawTouchPoints[1].setScreenPos(centerScreenPos);
    rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window);
    QWindowSystemInterface::handleTouchEvent(window, 0, touchPadDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(!touchWidget.seenTouchBegin);
    QVERIFY(!touchWidget.seenTouchUpdate);
    QVERIFY(!touchWidget.seenTouchEnd);
    QVERIFY(leftWidget.seenTouchBegin);
    QVERIFY(leftWidget.seenTouchUpdate);
    QVERIFY(leftWidget.seenTouchEnd);
    QVERIFY(!rightWidget.seenTouchBegin);
    QVERIFY(!rightWidget.seenTouchUpdate);
    QVERIFY(!rightWidget.seenTouchEnd);
    QCOMPARE(leftWidget.touchEndPoints.count(), 2);
    QCOMPARE(rightWidget.touchEndPoints.count(), 0);
    {
        QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchEndPoints.at(0);
        QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id());
        QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
        QCOMPARE(leftTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
        QCOMPARE(leftTouchPoint.startPos(), leftPos);
        QCOMPARE(leftTouchPoint.lastPos(), leftTouchPoint.pos());
        QCOMPARE(leftTouchPoint.scenePos(), centerScreenPos);
        QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.lastScenePos(), leftTouchPoint.scenePos());
        QCOMPARE(leftTouchPoint.screenPos(), centerScreenPos);
        QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
        QCOMPARE(leftTouchPoint.lastScreenPos(), leftTouchPoint.screenPos());
        QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
        QCOMPARE(leftTouchPoint.pos(), leftWidget.mapFromParent(centerPos.toPoint()));
        QCOMPARE(leftTouchPoint.scenePos(), centerScreenPos);
        QCOMPARE(leftTouchPoint.screenPos(), centerScreenPos);
        QCOMPARE(leftTouchPoint.ellipseDiameters(), QSizeF(0, 0));
        QCOMPARE(leftTouchPoint.pressure(), qreal(0.));

        QTouchEvent::TouchPoint rightTouchPoint = leftWidget.touchEndPoints.at(1);
        QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id());
        QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
        QCOMPARE(rightTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
        QCOMPARE(rightTouchPoint.startPos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
        QCOMPARE(rightTouchPoint.lastPos(), rightTouchPoint.pos());
        QCOMPARE(rightTouchPoint.scenePos(), centerScreenPos);
        QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.lastScenePos(), rightTouchPoint.scenePos());
        QCOMPARE(rightTouchPoint.screenPos(), centerScreenPos);
        QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
        QCOMPARE(rightTouchPoint.lastScreenPos(), rightTouchPoint.screenPos());
        QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
        QCOMPARE(rightTouchPoint.pos(), leftWidget.mapFromParent(centerPos.toPoint()));
        QCOMPARE(rightTouchPoint.scenePos(), centerScreenPos);
        QCOMPARE(rightTouchPoint.screenPos(), centerScreenPos);
        QCOMPARE(rightTouchPoint.ellipseDiameters(), QSizeF(0, 0));
        QCOMPARE(rightTouchPoint.pressure(), qreal(0.));
    }
}

void tst_QTouchEvent::basicRawEventTranslationOfIds()
{
    tst_QTouchEventWidget touchWidget;
    touchWidget.setWindowTitle(QTest::currentTestFunction());
    touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
    touchWidget.setGeometry(100, 100, 400, 300);
    touchWidget.show();
    QVERIFY(QTest::qWaitForWindowExposed(&touchWidget));

    QVarLengthArray<QPointF, 2> pos;
    QVarLengthArray<QPointF, 2> screenPos;
    for (int i = 0; i < 2; ++i) {
        pos << touchWidget.rect().center() + QPointF(20*i, 20*i);
        screenPos << touchWidget.mapToGlobal(pos[i].toPoint());
    }
    QPointF delta(10, 10);
    QRectF screenGeometry = touchWidget.screen()->geometry();

    QVector<QPointF> rawPosList;
    rawPosList << QPointF(12, 34) << QPointF(56, 78);

    QList<QTouchEvent::TouchPoint> rawTouchPoints;

    // Press both points, this should be translated to a TouchBegin
    for (int i = 0; i < 2; ++i) {
        QTouchEvent::TouchPoint rawTouchPoint;
        rawTouchPoint.setId(i);
        rawTouchPoint.setState(Qt::TouchPointPressed);
        rawTouchPoint.setScreenPos(screenPos[i]);
        rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry));
        rawTouchPoint.setRawScreenPositions(rawPosList);
        rawTouchPoints << rawTouchPoint;
    }
    QTouchEvent::TouchPoint &p0 = rawTouchPoints[0];
    QTouchEvent::TouchPoint &p1 = rawTouchPoints[1];

    const ulong timestamp = 1234;
    QWindow *window = touchWidget.windowHandle();
    QList<QWindowSystemInterface::TouchPoint> nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window);
    QWindowSystemInterface::handleTouchEvent(window, timestamp, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(touchWidget.seenTouchBegin);
    QVERIFY(!touchWidget.seenTouchUpdate);
    QVERIFY(!touchWidget.seenTouchEnd);
    QCOMPARE(touchWidget.touchBeginPoints.count(), 2);

    const int initialTouchPointId = (QTouchDevicePrivate::get(touchScreenDevice)->id << 24) + 1;

    for (int i = 0; i < touchWidget.touchBeginPoints.count(); ++i) {
        QTouchEvent::TouchPoint touchBeginPoint = touchWidget.touchBeginPoints.at(i);
        QCOMPARE(touchBeginPoint.id(), initialTouchPointId + i);
        QCOMPARE(touchBeginPoint.state(), rawTouchPoints[i].state());
    }

    // moving the point should translate to TouchUpdate
    for (int i = 0; i < rawTouchPoints.count(); ++i) {
        QTouchEvent::TouchPoint &p = rawTouchPoints[i];
        p.setState(Qt::TouchPointMoved);
        p.setScreenPos(p.screenPos() + delta);
        p.setNormalizedPos(normalized(p.pos(), screenGeometry));
    }
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window);
    QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(touchWidget.seenTouchBegin);
    QVERIFY(touchWidget.seenTouchUpdate);
    QVERIFY(!touchWidget.seenTouchEnd);
    QCOMPARE(touchWidget.touchUpdatePoints.count(), 2);
    QCOMPARE(touchWidget.touchUpdatePoints.at(0).id(), initialTouchPointId);
    QCOMPARE(touchWidget.touchUpdatePoints.at(1).id(), initialTouchPointId + 1);

    // release last point
    p0.setState(Qt::TouchPointStationary);
    p1.setState(Qt::TouchPointReleased);

    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window);
    QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(touchWidget.seenTouchBegin);
    QVERIFY(touchWidget.seenTouchUpdate);
    QVERIFY(!touchWidget.seenTouchEnd);
    QCOMPARE(touchWidget.touchUpdatePoints.count(), 2);
    QCOMPARE(touchWidget.touchUpdatePoints[0].id(), initialTouchPointId);
    QCOMPARE(touchWidget.touchUpdatePoints[1].id(), initialTouchPointId + 1);

    // Press last point again, id should increase
    p1.setState(Qt::TouchPointPressed);
    p1.setId(42);   // new id
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window);
    QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(touchWidget.seenTouchBegin);
    QVERIFY(touchWidget.seenTouchUpdate);
    QVERIFY(!touchWidget.seenTouchEnd);
    QCOMPARE(touchWidget.touchUpdatePoints.count(), 2);
    QCOMPARE(touchWidget.touchUpdatePoints[0].id(), initialTouchPointId);
    QCOMPARE(touchWidget.touchUpdatePoints[1].id(), initialTouchPointId + 2);

    // release everything
    p0.setState(Qt::TouchPointReleased);
    p1.setState(Qt::TouchPointReleased);
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window);
    QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(touchWidget.seenTouchBegin);
    QVERIFY(touchWidget.seenTouchUpdate);
    QVERIFY(touchWidget.seenTouchEnd);
    QCOMPARE(touchWidget.touchUpdatePoints.count(), 2);
    QCOMPARE(touchWidget.touchUpdatePoints[0].id(), initialTouchPointId);
    QCOMPARE(touchWidget.touchUpdatePoints[1].id(), initialTouchPointId + 2);
}

void tst_QTouchEvent::deleteInEventHandler()
{
    // QWidget
    {
        QWidget window;
        QPointer<tst_QTouchEventWidget> child1 = new tst_QTouchEventWidget(&window);
        QPointer<tst_QTouchEventWidget> child2 = new tst_QTouchEventWidget(&window);
        QPointer<tst_QTouchEventWidget> child3 = new tst_QTouchEventWidget(&window);
        child1->setAttribute(Qt::WA_AcceptTouchEvents);
        child2->setAttribute(Qt::WA_AcceptTouchEvents);
        child3->setAttribute(Qt::WA_AcceptTouchEvents);
        child1->deleteInTouchBegin = true;
        child2->deleteInTouchUpdate = true;
        child3->deleteInTouchEnd = true;

        QList<QTouchEvent::TouchPoint> touchPoints;
        touchPoints.append(QTouchEvent::TouchPoint(0));
        QTouchEvent touchBeginEvent(QEvent::TouchBegin,
                                    touchScreenDevice,
                                    Qt::NoModifier,
                                    Qt::TouchPointPressed,
                                    touchPoints);
        QTouchEvent touchUpdateEvent(QEvent::TouchUpdate,
                               touchScreenDevice,
                               Qt::NoModifier,
                               Qt::TouchPointStationary,
                               touchPoints);
        QTouchEvent touchEndEvent(QEvent::TouchEnd,
                               touchScreenDevice,
                               Qt::NoModifier,
                               Qt::TouchPointReleased,
                               touchPoints);
        touchBeginEvent.ignore();
        QVERIFY(QApplication::sendEvent(child1, &touchBeginEvent));
        // event is handled, but widget should be deleted
        QVERIFY(touchBeginEvent.isAccepted());
        QVERIFY(child1.isNull());

        touchBeginEvent.ignore();
        QVERIFY(QApplication::sendEvent(child2, &touchBeginEvent));
        QVERIFY(touchBeginEvent.isAccepted());
        QVERIFY(!child2.isNull());
        touchUpdateEvent.ignore();
        QVERIFY(QApplication::sendEvent(child2, &touchUpdateEvent));
        QVERIFY(touchUpdateEvent.isAccepted());
        QVERIFY(child2.isNull());

        touchBeginEvent.ignore();
        QVERIFY(QApplication::sendEvent(child3, &touchBeginEvent));
        QVERIFY(touchBeginEvent.isAccepted());
        QVERIFY(!child3.isNull());
        touchUpdateEvent.ignore();
        QVERIFY(QApplication::sendEvent(child3, &touchUpdateEvent));
        QVERIFY(touchUpdateEvent.isAccepted());
        QVERIFY(!child3.isNull());
        touchEndEvent.ignore();
        QVERIFY(QApplication::sendEvent(child3, &touchEndEvent));
        QVERIFY(touchEndEvent.isAccepted());
        QVERIFY(child3.isNull());
    }

    // QGraphicsView
    {
        QGraphicsScene scene;
        QGraphicsView view(&scene);
        QScopedPointer<tst_QTouchEventGraphicsItem> root(new tst_QTouchEventGraphicsItem);
        tst_QTouchEventGraphicsItem *child1 = new tst_QTouchEventGraphicsItem(root.data());
        tst_QTouchEventGraphicsItem *child2 = new tst_QTouchEventGraphicsItem(root.data());
        tst_QTouchEventGraphicsItem *child3 = new tst_QTouchEventGraphicsItem(root.data());
        child1->setZValue(1.);
        child2->setZValue(0.);
        child3->setZValue(-1.);
        child1->setAcceptTouchEvents(true);
        child2->setAcceptTouchEvents(true);
        child3->setAcceptTouchEvents(true);
        child1->deleteInTouchBegin = true;
        child2->deleteInTouchUpdate = true;
        child3->deleteInTouchEnd = true;

        scene.addItem(root.data());
        view.resize(200, 200);
        view.fitInView(scene.sceneRect());

        QTouchEvent::TouchPoint touchPoint(0);
        touchPoint.setState(Qt::TouchPointPressed);
        touchPoint.setPos(view.mapFromScene(child1->mapToScene(child1->boundingRect().center())));
        touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint()));
        touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint()));
        QList<QTouchEvent::TouchPoint> touchPoints;
        touchPoints.append(touchPoint);
        QTouchEvent touchBeginEvent(QEvent::TouchBegin,
                                    touchScreenDevice,
                                    Qt::NoModifier,
                                    Qt::TouchPointPressed,
                                    touchPoints);
        touchPoints[0].setState(Qt::TouchPointMoved);
        QTouchEvent touchUpdateEvent(QEvent::TouchUpdate,
                               touchScreenDevice,
                               Qt::NoModifier,
                               Qt::TouchPointMoved,
                               touchPoints);
        touchPoints[0].setState(Qt::TouchPointReleased);
        QTouchEvent touchEndEvent(QEvent::TouchEnd,
                               touchScreenDevice,
                               Qt::NoModifier,
                               Qt::TouchPointReleased,
                               touchPoints);

        child1->weakpointer = &child1;
        touchBeginEvent.ignore();
        QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent));
        QVERIFY(touchBeginEvent.isAccepted());
        QVERIFY(!child1);
        touchUpdateEvent.ignore();
        QVERIFY(QApplication::sendEvent(view.viewport(), &touchUpdateEvent));
        QVERIFY(!touchUpdateEvent.isAccepted()); // Qt 5.X ignores touch events.
        QVERIFY(!child1);
        touchEndEvent.ignore();
        QVERIFY(QApplication::sendEvent(view.viewport(), &touchEndEvent));
        QVERIFY(!touchUpdateEvent.isAccepted());
        QVERIFY(!child1);

        child2->weakpointer = &child2;
        touchBeginEvent.ignore();
        QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent));
        QVERIFY(touchBeginEvent.isAccepted());
        QVERIFY(child2);
        touchUpdateEvent.ignore();
        QVERIFY(QApplication::sendEvent(view.viewport(), &touchUpdateEvent));
        QVERIFY(!touchUpdateEvent.isAccepted());
        QVERIFY(!child2);
        touchEndEvent.ignore();
        QVERIFY(QApplication::sendEvent(view.viewport(), &touchEndEvent));
        QVERIFY(!touchUpdateEvent.isAccepted());
        QVERIFY(!child2);

        child3->weakpointer = &child3;
        QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent));
        QVERIFY(touchBeginEvent.isAccepted());
        QVERIFY(child3);
        QVERIFY(QApplication::sendEvent(view.viewport(), &touchUpdateEvent));
        QVERIFY(!touchUpdateEvent.isAccepted());
        QVERIFY(child3);
        QVERIFY(QApplication::sendEvent(view.viewport(), &touchEndEvent));
        QVERIFY(!touchEndEvent.isAccepted());
        QVERIFY(!child3);
    }
}

void tst_QTouchEvent::deleteInRawEventTranslation()
{
    tst_QTouchEventWidget touchWidget;
    touchWidget.setWindowTitle(QTest::currentTestFunction());
    touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
    touchWidget.setGeometry(100, 100, 300, 300);

    QPointer<tst_QTouchEventWidget> leftWidget = new tst_QTouchEventWidget(&touchWidget);
    leftWidget->setAttribute(Qt::WA_AcceptTouchEvents);
    leftWidget->setGeometry(0, 100, 100, 100);
    leftWidget->deleteInTouchBegin = true;

    QPointer<tst_QTouchEventWidget> centerWidget = new tst_QTouchEventWidget(&touchWidget);
    centerWidget->setAttribute(Qt::WA_AcceptTouchEvents);
    centerWidget->setGeometry(100, 100, 100, 100);
    centerWidget->deleteInTouchUpdate = true;

    QPointer<tst_QTouchEventWidget> rightWidget = new tst_QTouchEventWidget(&touchWidget);
    rightWidget->setAttribute(Qt::WA_AcceptTouchEvents);
    rightWidget->setGeometry(200, 100, 100, 100);
    rightWidget->deleteInTouchEnd = true;

    touchWidget.show();
    QVERIFY(QTest::qWaitForWindowExposed(&touchWidget));

    QPointF leftPos = leftWidget->rect().center();
    QPointF centerPos = centerWidget->rect().center();
    QPointF rightPos = rightWidget->rect().center();
    QPointF leftScreenPos = leftWidget->mapToGlobal(leftPos.toPoint());
    QPointF centerScreenPos = centerWidget->mapToGlobal(centerPos.toPoint());
    QPointF rightScreenPos = rightWidget->mapToGlobal(rightPos.toPoint());
    QRectF screenGeometry = touchWidget.screen()->geometry();

    QList<QTouchEvent::TouchPoint> rawTouchPoints;
    rawTouchPoints.append(QTouchEvent::TouchPoint(0));
    rawTouchPoints.append(QTouchEvent::TouchPoint(1));
    rawTouchPoints.append(QTouchEvent::TouchPoint(2));
    rawTouchPoints[0].setState(Qt::TouchPointPressed);
    rawTouchPoints[0].setScreenPos(leftScreenPos);
    rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
    rawTouchPoints[1].setState(Qt::TouchPointPressed);
    rawTouchPoints[1].setScreenPos(centerScreenPos);
    rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
    rawTouchPoints[2].setState(Qt::TouchPointPressed);
    rawTouchPoints[2].setScreenPos(rightScreenPos);
    rawTouchPoints[2].setNormalizedPos(normalized(rawTouchPoints[2].pos(), screenGeometry));

    // generate begin events on all widgets, the left widget should die
    QWindow *window = touchWidget.windowHandle();
    QList<QWindowSystemInterface::TouchPoint> nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window);
    QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
    QVERIFY(leftWidget.isNull());
    QVERIFY(!centerWidget.isNull());
    QVERIFY(!rightWidget.isNull());

    // generate update events on all widget, the center widget should die
    rawTouchPoints[0].setState(Qt::TouchPointMoved);
    rawTouchPoints[1].setState(Qt::TouchPointMoved);
    rawTouchPoints[2].setState(Qt::TouchPointMoved);
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window);
    QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();

    // generate end events on all widget, the right widget should die
    rawTouchPoints[0].setState(Qt::TouchPointReleased);
    rawTouchPoints[1].setState(Qt::TouchPointReleased);
    rawTouchPoints[2].setState(Qt::TouchPointReleased);
    nativeTouchPoints =
        QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window);
    QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints);
    QCoreApplication::processEvents();
}

void tst_QTouchEvent::crashInQGraphicsSceneAfterNotHandlingTouchBegin()
{
    QGraphicsRectItem *rect = new QGraphicsRectItem(0, 0, 100, 100);
    rect->setAcceptTouchEvents(true);

    QGraphicsRectItem *mainRect = new QGraphicsRectItem(0, 0, 100, 100, rect);
    mainRect->setBrush(Qt::lightGray);

    QGraphicsRectItem *button = new QGraphicsRectItem(-20, -20, 40, 40, mainRect);
    button->setPos(50, 50);
    button->setBrush(Qt::darkGreen);

    QGraphicsView view;
    QGraphicsScene scene;
    scene.addItem(rect);
    scene.setSceneRect(0,0,100,100);
    view.setScene(&scene);

    view.show();
    QVERIFY(QTest::qWaitForWindowExposed(&view));

    QPoint centerPos = view.mapFromScene(rect->boundingRect().center());
    // Touch the button
    QTest::touchEvent(view.viewport(), touchScreenDevice).press(0, centerPos, static_cast<QWindow *>(0));
    QTest::touchEvent(view.viewport(), touchScreenDevice).release(0, centerPos, static_cast<QWindow *>(0));
    // Touch outside of the button
    QTest::touchEvent(view.viewport(), touchScreenDevice).press(0, view.mapFromScene(QPoint(10, 10)), static_cast<QWindow *>(0));
    QTest::touchEvent(view.viewport(), touchScreenDevice).release(0, view.mapFromScene(QPoint(10, 10)), static_cast<QWindow *>(0));
}

void tst_QTouchEvent::touchBeginWithGraphicsWidget()
{
    if (QHighDpiScaling::isActive())
        QSKIP("Fails when scaling is active");
    QGraphicsScene scene;
    QGraphicsView view(&scene);
    view.setWindowTitle(QTest::currentTestFunction());
    QScopedPointer<tst_QTouchEventGraphicsItem> root(new tst_QTouchEventGraphicsItem);
    root->setAcceptTouchEvents(true);
    scene.addItem(root.data());

    QScopedPointer<QGraphicsWidget> glassWidget(new QGraphicsWidget);
    glassWidget->setMinimumSize(100, 100);
    scene.addItem(glassWidget.data());

    view.setAlignment(Qt::AlignLeft | Qt::AlignTop);
    const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
    view.resize(availableGeometry.size() - QSize(100, 100));
    view.move(availableGeometry.topLeft() + QPoint(50, 50));
    view.fitInView(scene.sceneRect());
    view.show();
    QVERIFY(QTest::qWaitForWindowExposed(&view));

    QTest::touchEvent(&view, touchScreenDevice)
            .press(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport());
    QTest::touchEvent(&view, touchScreenDevice)
            .stationary(0)
            .press(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport());
    QTest::touchEvent(&view, touchScreenDevice)
            .release(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport())
            .release(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport());

    QTRY_COMPARE(root->touchBeginCounter, 1);
    QCOMPARE(root->touchUpdateCounter, 1);
    QCOMPARE(root->touchEndCounter, 1);
    QCOMPARE(root->touchUpdatePoints.size(), 2);

    root->reset();
    glassWidget->setWindowFlags(Qt::Window); // make the glassWidget a panel

    QTest::touchEvent(&view, touchScreenDevice)
            .press(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport());
    QTest::touchEvent(&view, touchScreenDevice)
            .stationary(0)
            .press(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport());
    QTest::touchEvent(&view, touchScreenDevice)
            .release(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport())
            .release(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport());

    QCOMPARE(root->touchBeginCounter, 0);
    QCOMPARE(root->touchUpdateCounter, 0);
    QCOMPARE(root->touchEndCounter, 0);
}

class WindowTouchEventFilter : public QObject
{
    Q_OBJECT
public:
    bool eventFilter(QObject *obj, QEvent *event) override;
    struct TouchInfo {
        QList<QTouchEvent::TouchPoint> points;
        QEvent::Type lastSeenType;
    };
    QMap<QTouchDevice *, TouchInfo> d;
};

bool WindowTouchEventFilter::eventFilter(QObject *, QEvent *event)
{
    if (event->type() == QEvent::TouchBegin
            || event->type() == QEvent::TouchUpdate
            || event->type() == QEvent::TouchEnd) {
        QTouchEvent *te = static_cast<QTouchEvent *>(event);
        TouchInfo &td = d[te->device()];
        if (event->type() == QEvent::TouchBegin)
            td.points.clear();
        td.points.append(te->touchPoints());
        td.lastSeenType = event->type();
    }
    return false;
}

void tst_QTouchEvent::testQGuiAppDelivery()
{
    QWindow w;
    w.setGeometry(100, 100, 100, 100);
    w.show();
    QVERIFY(QTest::qWaitForWindowExposed(&w));

    WindowTouchEventFilter filter;
    w.installEventFilter(&filter);

    QList<QWindowSystemInterface::TouchPoint> points;

    // Pass empty list, should be ignored.
    QWindowSystemInterface::handleTouchEvent(&w, 0, points);
    QCoreApplication::processEvents();
    QCOMPARE(filter.d.isEmpty(), true);

    QWindowSystemInterface::TouchPoint tp;
    tp.id = 0;
    tp.state = Qt::TouchPointPressed;
    tp.area = QRectF(120, 120, 20, 20);
    points.append(tp);

    // Pass 0 as device, should be ignored.
    QWindowSystemInterface::handleTouchEvent(&w, 0, points);
    QCoreApplication::processEvents();
    QCOMPARE(filter.d.isEmpty(), true);

    // Now the real thing.
    QWindowSystemInterface::handleTouchEvent(&w, touchScreenDevice, points); // TouchBegin
    QCoreApplication::processEvents();
    QCOMPARE(filter.d.count(), 1);
    QCOMPARE(filter.d.contains(touchScreenDevice), true);
    QCOMPARE(filter.d.value(touchScreenDevice).points.count(), 1);
    QCOMPARE(filter.d.value(touchScreenDevice).lastSeenType, QEvent::TouchBegin);

    points[0].state = Qt::TouchPointMoved;
    QWindowSystemInterface::handleTouchEvent(&w, touchScreenDevice, points); // TouchUpdate
    QCoreApplication::processEvents();
    QCOMPARE(filter.d.count(), 1);
    QCOMPARE(filter.d.contains(touchScreenDevice), true);
    QCOMPARE(filter.d.value(touchScreenDevice).points.count(), 2);
    QCOMPARE(filter.d.value(touchScreenDevice).lastSeenType, QEvent::TouchUpdate);

    points[0].state = Qt::TouchPointReleased;
    QWindowSystemInterface::handleTouchEvent(&w, touchScreenDevice, points); // TouchEnd
    QCoreApplication::processEvents();
    QCOMPARE(filter.d.count(), 1);
    QCOMPARE(filter.d.contains(touchScreenDevice), true);
    QCOMPARE(filter.d.value(touchScreenDevice).points.count(), 3);
    QCOMPARE(filter.d.value(touchScreenDevice).lastSeenType, QEvent::TouchEnd);
}

void tst_QTouchEvent::testMultiDevice()
{
    QTouchDevice *deviceTwo = QTest::createTouchDevice();

    QWindow w;
    w.setGeometry(100, 100, 100, 100);
    w.show();
    QVERIFY(QTest::qWaitForWindowExposed(&w));

    WindowTouchEventFilter filter;
    w.installEventFilter(&filter);

    QList<QWindowSystemInterface::TouchPoint> pointsOne, pointsTwo;

    // touchScreenDevice reports a single point, deviceTwo reports the beginning of a multi-point sequence.
    // Even though there is a point with id 0 for both devices, they should be delivered cleanly, independently.
    QWindowSystemInterface::TouchPoint tp;
    tp.id = 0;
    tp.state = Qt::TouchPointPressed;
    const QPoint screenOrigin = w.screen()->geometry().topLeft();
    const QRectF area0(120, 120, 20, 20);
    tp.area = QHighDpi::toNative(area0, QHighDpiScaling::factor(&w), screenOrigin);
    pointsOne.append(tp);

    pointsTwo.append(tp);
    tp.id = 1;
    const QRectF area1(140, 140, 20, 20);
    tp.area = QHighDpi::toNative(area1, QHighDpiScaling::factor(&w), screenOrigin);
    pointsTwo.append(tp);

    QWindowSystemInterface::handleTouchEvent(&w, touchScreenDevice, pointsOne);
    QWindowSystemInterface::handleTouchEvent(&w, deviceTwo, pointsTwo);
    QCoreApplication::processEvents();

    QCOMPARE(filter.d.contains(touchScreenDevice), true);
    QCOMPARE(filter.d.contains(deviceTwo), true);

    QCOMPARE(filter.d.value(touchScreenDevice).lastSeenType, QEvent::TouchBegin);
    QCOMPARE(filter.d.value(deviceTwo).lastSeenType, QEvent::TouchBegin);
    QCOMPARE(filter.d.value(touchScreenDevice).points.count(), 1);
    QCOMPARE(filter.d.value(deviceTwo).points.count(), 2);

    QCOMPARE(filter.d.value(touchScreenDevice).points.at(0).screenPos(), area0.center());
    QCOMPARE(filter.d.value(touchScreenDevice).points.at(0).ellipseDiameters(), area0.size());
    QCOMPARE(filter.d.value(touchScreenDevice).points.at(0).state(), pointsOne[0].state);

    QCOMPARE(filter.d.value(deviceTwo).points.at(0).screenPos(), area0.center());
    QCOMPARE(filter.d.value(deviceTwo).points.at(0).ellipseDiameters(), area0.size());
    QCOMPARE(filter.d.value(deviceTwo).points.at(0).state(), pointsTwo[0].state);
    QCOMPARE(filter.d.value(deviceTwo).points.at(1).screenPos(), area1.center());
    QCOMPARE(filter.d.value(deviceTwo).points.at(1).state(), pointsTwo[1].state);
}

QTEST_MAIN(tst_QTouchEvent)

#include "tst_qtouchevent.moc"
