diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp index cd92c49ff1..fe47c947b4 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2015 Pier Luigi Fiorini ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** @@ -87,8 +88,11 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen) QEglFSKmsCursor::~QEglFSKmsCursor() { - drmModeSetCursor(m_screen->device()->fd(), m_screen->output().crtc_id, 0, 0, 0); - drmModeMoveCursor(m_screen->device()->fd(), m_screen->output().crtc_id, 0, 0); + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { + QEglFSKmsScreen *kmsScreen = static_cast(screen); + drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); + drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0); + } gbm_bo_destroy(m_bo); m_bo = Q_NULLPTR; @@ -143,10 +147,15 @@ void QEglFSKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window) gbm_bo_write(m_bo, cursorImage.constBits(), cursorImage.byteCount()); uint32_t handle = gbm_bo_get_handle(m_bo).u32; - int status = drmModeSetCursor(m_screen->device()->fd(), m_screen->output().crtc_id, handle, - m_cursorSize.width(), m_cursorSize.height()); - if (status != 0) - qWarning("Could not set cursor: %d", status); + + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { + QEglFSKmsScreen *kmsScreen = static_cast(screen); + + int status = drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, handle, + m_cursorSize.width(), m_cursorSize.height()); + if (status != 0) + qWarning("Could not set cursor on screen %s: %d", kmsScreen->name().toLatin1().constData(), status); + } } #endif // QT_NO_CURSOR @@ -157,12 +166,17 @@ QPoint QEglFSKmsCursor::pos() const void QEglFSKmsCursor::setPos(const QPoint &pos) { - QPoint adjustedPos = pos - m_cursorImage.hotspot(); - int ret = drmModeMoveCursor(m_screen->device()->fd(), m_screen->output().crtc_id, adjustedPos.x(), adjustedPos.y()); - if (ret == 0) { - m_pos = pos; - } else { - qWarning("Failed to move cursor: %d", ret); + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { + QEglFSKmsScreen *kmsScreen = static_cast(screen); + QPoint origin = kmsScreen->geometry().topLeft(); + QPoint localPos = pos - origin; + QPoint adjustedPos = localPos - m_cursorImage.hotspot(); + + int ret = drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, adjustedPos.x(), adjustedPos.y()); + if (ret == 0) + m_pos = pos; + else + qWarning("Failed to move cursor on screen %s: %d", kmsScreen->name().toLatin1().constData(), ret); } } @@ -176,8 +190,11 @@ void QEglFSKmsCursor::initCursorAtlas() QFile file(QString::fromUtf8(json)); if (!file.open(QFile::ReadOnly)) { - drmModeSetCursor(m_screen->device()->fd(), m_screen->output().crtc_id, 0, 0, 0); - drmModeMoveCursor(m_screen->device()->fd(), m_screen->output().crtc_id, 0, 0); + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { + QEglFSKmsScreen *kmsScreen = static_cast(screen); + drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); + drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0); + } m_visible = false; return; } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp index bafe1e3324..18a66e34f5 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2015 Pier Luigi Fiorini ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** @@ -308,6 +309,7 @@ QEglFSKmsDevice::QEglFSKmsDevice(QEglFSKmsIntegration *integration, const QStrin , m_gbm_device(Q_NULLPTR) , m_crtc_allocator(0) , m_connector_allocator(0) + , m_globalCursor(Q_NULLPTR) { } @@ -347,6 +349,10 @@ void QEglFSKmsDevice::close() qt_safe_close(m_dri_fd); m_dri_fd = -1; } + + if (m_globalCursor) + m_globalCursor->deleteLater(); + m_globalCursor = Q_NULLPTR; } void QEglFSKmsDevice::createScreens() @@ -357,6 +363,8 @@ void QEglFSKmsDevice::createScreens() return; } + QEglFSKmsScreen *primaryScreen = Q_NULLPTR; + QList siblings; QPoint pos(0, 0); QEglFSIntegration *integration = static_cast(QGuiApplicationPrivate::platformIntegration()); @@ -369,12 +377,24 @@ void QEglFSKmsDevice::createScreens() if (screen) { integration->addScreen(screen); pos.rx() += screen->geometry().width(); + siblings << screen; + + if (!primaryScreen) + primaryScreen = screen; } drmModeFreeConnector(connector); } drmModeFreeResources(resources); + + if (!m_integration->separateScreens()) { + Q_FOREACH (QPlatformScreen *screen, siblings) + static_cast(screen)->setVirtualSiblings(siblings); + + if (primaryScreen) + m_globalCursor = new QEglFSKmsCursor(primaryScreen); + } } gbm_device *QEglFSKmsDevice::device() const @@ -387,6 +407,11 @@ int QEglFSKmsDevice::fd() const return m_dri_fd; } +QPlatformCursor *QEglFSKmsDevice::globalCursor() const +{ + return m_globalCursor; +} + void QEglFSKmsDevice::handleDrmEvent() { drmEventContext drmEvent = { diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h index 29a1332c9a..23fca934e5 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2015 Pier Luigi Fiorini ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** @@ -34,6 +35,7 @@ #ifndef QEGLFSKMSDEVICE_H #define QEGLFSKMSDEVICE_H +#include "qeglfskmscursor.h" #include "qeglfskmsintegration.h" #include @@ -57,6 +59,8 @@ public: gbm_device *device() const; int fd() const; + QPlatformCursor *globalCursor() const; + void handleDrmEvent(); private: @@ -70,6 +74,8 @@ private: quint32 m_crtc_allocator; quint32 m_connector_allocator; + QEglFSKmsCursor *m_globalCursor; + int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector); QEglFSKmsScreen *screenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, QPoint pos); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp index 7bb932cf00..45224ccb87 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2015 Pier Luigi Fiorini ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** @@ -60,6 +61,7 @@ QEglFSKmsIntegration::QEglFSKmsIntegration() : m_device(Q_NULLPTR) , m_hwCursor(true) , m_pbuffers(false) + , m_separateScreens(false) {} void QEglFSKmsIntegration::platformInit() @@ -203,6 +205,11 @@ bool QEglFSKmsIntegration::hwCursor() const return m_hwCursor; } +bool QEglFSKmsIntegration::separateScreens() const +{ + return m_separateScreens; +} + QMap QEglFSKmsIntegration::outputSettings() const { return m_outputSettings; @@ -235,6 +242,7 @@ void QEglFSKmsIntegration::loadConfig() m_hwCursor = object.value(QStringLiteral("hwcursor")).toBool(m_hwCursor); m_pbuffers = object.value(QStringLiteral("pbuffers")).toBool(m_pbuffers); m_devicePath = object.value(QStringLiteral("device")).toString(); + m_separateScreens = object.value(QStringLiteral("separateScreens")).toBool(m_separateScreens); const QJsonArray outputs = object.value(QStringLiteral("outputs")).toArray(); for (int i = 0; i < outputs.size(); i++) { @@ -254,6 +262,7 @@ void QEglFSKmsIntegration::loadConfig() qCDebug(qLcEglfsKmsDebug) << "Configuration:\n" << "\thwcursor:" << m_hwCursor << "\n" << "\tpbuffers:" << m_pbuffers << "\n" + << "\tseparateScreens:" << m_separateScreens << "\n" << "\toutputs:" << m_outputSettings; } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h index 9a160d2570..edb6906a4b 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2015 Pier Luigi Fiorini ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** @@ -65,6 +66,7 @@ public: bool supportsPBuffers() const Q_DECL_OVERRIDE; bool hwCursor() const; + bool separateScreens() const; QMap outputSettings() const; private: @@ -73,6 +75,7 @@ private: QEglFSKmsDevice *m_device; bool m_hwCursor; bool m_pbuffers; + bool m_separateScreens; QString m_devicePath; QMap m_outputSettings; }; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp index a27819d1dd..5e49c224a0 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2015 Pier Luigi Fiorini ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** @@ -120,6 +121,7 @@ QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration, , m_cursor(Q_NULLPTR) , m_interruptHandler(new QEglFSKmsInterruptHandler(this)) { + m_siblings << this; } QEglFSKmsScreen::~QEglFSKmsScreen() @@ -185,6 +187,9 @@ QString QEglFSKmsScreen::name() const QPlatformCursor *QEglFSKmsScreen::cursor() const { if (m_integration->hwCursor()) { + if (!m_integration->separateScreens()) + return m_device->globalCursor(); + if (m_cursor.isNull()) { QEglFSKmsScreen *that = const_cast(this); that->m_cursor.reset(new QEglFSKmsCursor(that)); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h index 16521c7fe0..4c1b0d02ad 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2015 Pier Luigi Fiorini ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** @@ -85,6 +86,10 @@ public: qreal refreshRate() const Q_DECL_OVERRIDE; + QList virtualSiblings() const Q_DECL_OVERRIDE { return m_siblings; } + void setVirtualSiblings(QList sl) { m_siblings = sl; } + + QEglFSKmsIntegration *integration() const { return m_integration; } QEglFSKmsDevice *device() const { return m_device; } gbm_surface *surface() const { return m_gbm_surface; } @@ -110,6 +115,8 @@ private: QPoint m_pos; QScopedPointer m_cursor; + QList m_siblings; + struct FrameBuffer { FrameBuffer() : fb(0) {} uint32_t fb;