diff --git a/tests/manual/qcursor/qcursor.pro b/tests/manual/qcursor/qcursor.pro
index af082a4b82fddff24e9e65296027c6a61af4f684..0b5c2b194529efb7d2c2ae3cc6c823b8ace6ca20 100644
--- a/tests/manual/qcursor/qcursor.pro
+++ b/tests/manual/qcursor/qcursor.pro
@@ -1,3 +1,3 @@
 TEMPLATE = subdirs
 
-SUBDIRS = allcursors grab_override
+SUBDIRS = allcursors grab_override qcursorhighdpi
diff --git a/tests/manual/qcursor/qcursorhighdpi/main.cpp b/tests/manual/qcursor/qcursorhighdpi/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fc45ae00d159e096514baee37630cbfec360a285
--- /dev/null
+++ b/tests/manual/qcursor/qcursorhighdpi/main.cpp
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QAction>
+#include <QApplication>
+#include <QDesktopWidget>
+#include <QGridLayout>
+#include <QLabel>
+#include <QMainWindow>
+#include <QMenu>
+#include <QMenuBar>
+#include <QSharedPointer>
+#include <QToolBar>
+
+#include <QBitmap>
+#include <QCursor>
+#include <QPainter>
+#include <QPixmap>
+
+#include <QDebug>
+#include <QStringList>
+#include <QTextStream>
+
+#if QT_VERSION > 0x050000
+#  include <QScreen>
+#  include <QWindow>
+#  include <private/qhighdpiscaling_p.h>
+#  include <qpa/qplatformwindow.h>
+#else
+#   define Q_NULLPTR 0
+#   define Q_DECL_OVERRIDE
+#endif
+
+#ifdef Q_OS_WIN
+#  include <qt_windows.h>
+#endif
+
+#include <algorithm>
+#include <iterator>
+
+// High DPI cursor test for testing cursor sizes in multi-screen setups.
+// It creates one widget per screen with a grid of standard cursors,
+// pixmap / bitmap cursors and pixmap / bitmap cursors with device pixel ratio 2.
+// On the left, there is a ruler with 10 DIP marks.
+// The code is meant to compile with Qt 4 also.
+
+static QString screenInfo(const QWidget *w)
+{
+    QString result;
+    QTextStream str(&result);
+#if QT_VERSION > 0x050000
+    QScreen *screen = Q_NULLPTR;
+    if (const QWindow *window = w->windowHandle())
+        screen = window->screen();
+    if (screen) {
+        str << '"' << screen->name() << "\" " << screen->size().width() << 'x'
+            << screen->size().height() << ", DPR=" << screen->devicePixelRatio()
+            << ", " << screen->logicalDotsPerInchX() << "DPI ";
+        if (QHighDpiScaling::isActive())
+            str << ", factor=" << QHighDpiScaling::factor(screen);
+        else
+            str << ", no scaling";
+    } else {
+        str << "<null>";
+    }
+#else
+    QDesktopWidget *desktop = QApplication::desktop();
+    int screenNumber = desktop->screenNumber(w);
+    str << "Screen #" <<screenNumber << ' ' << desktop->screenGeometry(screenNumber).width()
+        << 'x' << desktop->screenGeometry(screenNumber).height() << " PD: " << w->logicalDpiX() << "DPI";
+#endif
+#ifdef Q_OS_WIN
+    str << ", SM_C_CURSOR: " << GetSystemMetrics(SM_CXCURSOR) << 'x' << GetSystemMetrics(SM_CYCURSOR);
+#endif
+    return result;
+}
+
+// Helpers for painting pixmaps and creating cursors
+static QPixmap paintPixmap(int size, QColor c)
+{
+    QPixmap result(size, size);
+    result.fill(c);
+    QPainter p(&result);
+    p.drawRect(QRect(QPoint(0, 0), result.size() - QSize(1, 1)));
+    p.drawLine(0, 0, size, size);
+    p.drawLine(0, size, size, 0);
+    return result;
+}
+
+static QCursor pixmapCursor(int size)
+{
+    QCursor result(paintPixmap(size, Qt::red), size / 2, size / 2);
+    return result;
+}
+
+static QPair<QBitmap, QBitmap> paintBitmaps(int size)
+{
+    QBitmap bitmap(size, size);
+    bitmap.fill(Qt::color1);
+    QBitmap mask(size, size);
+    mask.fill(Qt::color1);
+    {
+        QPainter mp(&mask);
+        mp.fillRect(QRect(0, 0, size / 2, size / 2), Qt::color0);
+    }
+    return QPair<QBitmap, QBitmap>(bitmap, mask);
+}
+
+static QCursor bitmapCursor(int size)
+{
+    QPair<QBitmap, QBitmap> bitmaps = paintBitmaps(size);
+    return QCursor(bitmaps.first, bitmaps.second, size / 2, size / 2);
+}
+
+#if QT_VERSION > 0x050000
+static QCursor pixmapCursorDevicePixelRatio(int size, int dpr)
+{
+    QPixmap pixmap = paintPixmap(dpr * size, Qt::yellow);
+    pixmap.setDevicePixelRatio(dpr);
+    return QCursor(pixmap, size / 2, size / 2);
+}
+
+static QCursor bitmapCursorDevicePixelRatio(int size, int dpr)
+{
+    QPair<QBitmap, QBitmap> bitmaps = paintBitmaps(dpr * size);
+    bitmaps.first.setDevicePixelRatio(dpr);
+    bitmaps.second.setDevicePixelRatio(dpr);
+    return QCursor(bitmaps.first, bitmaps.second, size / 2, size / 2);
+}
+#endif // Qt 5
+
+// Vertical ruler widget with 10 px marks
+class VerticalRuler : public QWidget {
+public:
+    VerticalRuler(QWidget *parent = Q_NULLPTR);
+
+protected:
+    void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
+};
+
+VerticalRuler::VerticalRuler(QWidget *parent) : QWidget(parent)
+{
+    const int screenWidth = QApplication::desktop()->screenGeometry(this).width();
+    setFixedWidth(screenWidth / 48); // 1920 pixel monitor ->40
+}
+
+void VerticalRuler::paintEvent(QPaintEvent *)
+{
+    const QSize sizeS(size());
+    const QPoint sizeP(sizeS.width(), sizeS.height());
+    const QPoint center = sizeP / 2;
+    QPainter painter(this);
+    painter.fillRect(QRect(QPoint(0, 0), sizeS), Qt::white);
+    painter.drawLine(center.x(), 0, center.x(), sizeP.y());
+    for (int y = 0; y < sizeP.y(); y += 10)
+        painter.drawLine(center.x() - 5, y, center.x() + 5, y);
+}
+
+class MainWindow : public QMainWindow
+{
+    Q_OBJECT
+public:
+    explicit MainWindow(QWidget *parent = Q_NULLPTR);
+    void updateScreenInfo() { m_screenInfoLabel->setText(screenInfo(this)); }
+
+public slots:
+    void screenChanged() { updateScreenInfo(); }
+
+private:
+    QLabel *m_screenInfoLabel;
+};
+
+static QLabel *createCursorLabel(const QCursor &cursor, const QString &additionalText = QString())
+{
+    QString labelText;
+    QDebug(&labelText).nospace() << cursor.shape();
+#if QT_VERSION > 0x050000
+    labelText.remove(0, labelText.indexOf('(') + 1);
+    labelText.chop(1);
+#endif // Qt 5
+    if (!additionalText.isEmpty())
+        labelText += ' ' + additionalText;
+    QLabel *result = new QLabel(labelText);
+    result->setFrameShape(QFrame::Box);
+    result->setCursor(cursor);
+    return result;
+}
+
+static void addToGrid(QWidget *w, QGridLayout *gridLayout, int columnCount, int &row, int &col)
+{
+    gridLayout->addWidget(w, row, col);
+    if (col >= columnCount) {
+        col = 0;
+        row++;
+    } else {
+        col++;
+    }
+}
+
+MainWindow::MainWindow(QWidget *parent)
+    : QMainWindow(parent)
+    , m_screenInfoLabel(new QLabel)
+{
+    QString title = "Cursors ";
+#if QT_VERSION > 0x050000
+    title += '(' + QGuiApplication::platformName() + ") ";
+#endif
+    title += QT_VERSION_STR;
+    setWindowTitle(title);
+
+    QMenu *fileMenu = menuBar()->addMenu("File");
+    QAction *quitAction = fileMenu->addAction("Quit");
+    quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
+    connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
+
+    QToolBar *fileToolBar = addToolBar("File");
+    fileToolBar->addAction(quitAction);
+
+    QWidget *cw = new QWidget;
+    QHBoxLayout *hLayout = new QHBoxLayout(cw);
+    hLayout->addWidget(new VerticalRuler(cw));
+    QGridLayout *gridLayout = new QGridLayout;
+    hLayout->addLayout(gridLayout);
+
+    const int columnCount = 5;
+    const int size = 32;
+
+    int row = 0;
+    int col = 0;
+    for (int i = 0; i < Qt::BitmapCursor; ++i)
+        addToGrid(createCursorLabel(QCursor(static_cast<Qt::CursorShape>(i))), gridLayout, columnCount, row, col);
+
+    addToGrid(createCursorLabel(QCursor(pixmapCursor(size)),
+                                QLatin1String("Plain PX ") + QString::number(size)),
+                                gridLayout, columnCount, row, col);
+
+    addToGrid(createCursorLabel(bitmapCursor(size),
+                                QLatin1String("Plain BM ") + QString::number(size)),
+                                gridLayout, columnCount, row, col);
+
+#if QT_VERSION > 0x050000
+    addToGrid(createCursorLabel(QCursor(pixmapCursorDevicePixelRatio(size, 2)),
+                                "PX with DPR 2 " + QString::number(size)),
+                                gridLayout, columnCount, row, col);
+
+    addToGrid(createCursorLabel(QCursor(bitmapCursorDevicePixelRatio(size, 2)),
+                                "BM with DPR 2 " + QString::number(size)),
+                                gridLayout, columnCount, row, col);
+#endif // Qt 5
+
+    gridLayout->addWidget(m_screenInfoLabel, row + 1, 0, 1, columnCount);
+
+    setCentralWidget(cw);
+}
+
+typedef QSharedPointer<MainWindow> MainWindowPtr;
+typedef QList<MainWindowPtr> MainWindowPtrList;
+
+int main(int argc, char *argv[])
+{
+    QStringList arguments;
+    std::copy(argv + 1, argv + argc, std::back_inserter(arguments));
+
+#if QT_VERSION > 0x050000
+    if (arguments.contains("-s"))
+        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+    else if (arguments.contains("-n"))
+        QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
+#endif // Qt 5
+
+    QApplication app(argc, argv);
+
+    MainWindowPtrList windows;
+
+    QDesktopWidget *desktopWidget = app.desktop();
+
+    for (int s = desktopWidget->screenCount() - 1; s >= 0; --s) {
+        MainWindowPtr window(new MainWindow(desktopWidget->screen(s)));
+        const QPoint pos = desktopWidget->screenGeometry(s).center() - QPoint(200, 100);
+        window->move(pos);
+        windows.append(window);
+        window->show();
+        window->updateScreenInfo();
+#if QT_VERSION > 0x050000
+        QObject::connect(window->windowHandle(), &QWindow::screenChanged,
+                         window.data(), &MainWindow::updateScreenInfo);
+#endif
+    }
+    return app.exec();
+}
+#include "main.moc"
diff --git a/tests/manual/qcursor/qcursorhighdpi/qcursorhighdpi.pro b/tests/manual/qcursor/qcursorhighdpi/qcursorhighdpi.pro
new file mode 100644
index 0000000000000000000000000000000000000000..3a8fc25b333840d1c517050dce8be2a828a4025e
--- /dev/null
+++ b/tests/manual/qcursor/qcursorhighdpi/qcursorhighdpi.pro
@@ -0,0 +1,6 @@
+TEMPLATE = app
+QT = core gui
+greaterThan(QT_MAJOR_VERSION, 4): QT += gui-private core-private widgets
+CONFIG -= app_bundle
+SOURCES += main.cpp
+win32: LIBS += -lUser32