From c46f74d325892b0f3b3068241535c32ffe6e3a98 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 22 Apr 2016 16:38:32 +0200 Subject: eglfs: Support dynamic mouse cursor show/hide with DRM HW cursor Task-number: QTBUG-52743 Change-Id: I0bea1451dfe7b049c129b11716d593115e3d8374 Reviewed-by: Louai Al-Khanji --- .../eglfs_kms/qeglfskmscursor.cpp | 59 +++++++++++++++++++--- .../deviceintegration/eglfs_kms/qeglfskmscursor.h | 30 ++++++++++- 2 files changed, 81 insertions(+), 8 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp index 97ea3f1eca..830e270eeb 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 Pier Luigi Fiorini -** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -62,13 +63,13 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen) , m_cursorSize(64, 64) // 64x64 is the old standard size, we now try to query the real size below , m_bo(Q_NULLPTR) , m_cursorImage(0, 0, 0, 0, 0, 0) - , m_visible(true) + , m_state(CursorPendingVisible) { QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR"); - if (!hideCursorVal.isEmpty()) - m_visible = hideCursorVal.toInt() == 0; - if (!m_visible) + if (!hideCursorVal.isEmpty() && hideCursorVal.toInt()) { + m_state = CursorDisabled; return; + } uint64_t width, height; if ((drmGetCap(m_screen->device()->fd(), DRM_CAP_CURSOR_WIDTH, &width) == 0) @@ -85,6 +86,12 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen) initCursorAtlas(); } + m_deviceListener = new QEglFSKmsCursorDeviceListener(this); + connect(QGuiApplicationPrivate::inputDeviceManager(), &QInputDeviceManager::deviceListChanged, + m_deviceListener, &QEglFSKmsCursorDeviceListener::onDeviceListChanged); + if (!m_deviceListener->hasMouse()) + m_state = CursorPendingHidden; + #ifndef QT_NO_CURSOR QCursor cursor(Qt::ArrowCursor); changeCursor(&cursor, 0); @@ -94,6 +101,8 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen) QEglFSKmsCursor::~QEglFSKmsCursor() { + delete m_deviceListener; + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { QEglFSKmsScreen *kmsScreen = static_cast(screen); drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); @@ -106,6 +115,31 @@ QEglFSKmsCursor::~QEglFSKmsCursor() } } +void QEglFSKmsCursor::updateMouseStatus() +{ + const bool wasVisible = m_state == CursorVisible; + const bool visible = m_deviceListener->hasMouse(); + if (visible == wasVisible) + return; + + m_state = visible ? CursorPendingVisible : CursorPendingHidden; + +#ifndef QT_NO_CURSOR + changeCursor(nullptr, m_screen->topLevelAt(pos())); +#endif +} + +bool QEglFSKmsCursorDeviceListener::hasMouse() const +{ + return QGuiApplicationPrivate::inputDeviceManager()->deviceCount(QInputDeviceManager::DeviceTypePointer) > 0; +} + +void QEglFSKmsCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type) +{ + if (type == QInputDeviceManager::DeviceTypePointer) + m_cursor->updateMouseStatus(); +} + void QEglFSKmsCursor::pointerEvent(const QMouseEvent &event) { setPos(event.screenPos().toPoint()); @@ -119,7 +153,15 @@ void QEglFSKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window) if (!m_bo) return; - if (!m_visible) + if (m_state == CursorPendingHidden) { + m_state = CursorHidden; + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { + QEglFSKmsScreen *kmsScreen = static_cast(screen); + drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); + } + } + + if (m_state == CursorHidden || m_state == CursorDisabled) return; const Qt::CursorShape newShape = windowCursor ? windowCursor->shape() : Qt::ArrowCursor; @@ -159,6 +201,9 @@ void QEglFSKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window) uint32_t handle = gbm_bo_get_handle(m_bo).u32; + if (m_state == CursorPendingVisible) + m_state = CursorVisible; + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { QEglFSKmsScreen *kmsScreen = static_cast(screen); @@ -206,7 +251,7 @@ void QEglFSKmsCursor::initCursorAtlas() drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0); } - m_visible = false; + m_state = CursorDisabled; return; } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.h index 68bc72a03f..f26df91be5 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.h @@ -37,12 +37,29 @@ #include #include #include +#include #include QT_BEGIN_NAMESPACE class QEglFSKmsScreen; +class QEglFSKmsCursor; + +class QEglFSKmsCursorDeviceListener : public QObject +{ + Q_OBJECT + +public: + QEglFSKmsCursorDeviceListener(QEglFSKmsCursor *cursor) : m_cursor(cursor) { } + bool hasMouse() const; + +public slots: + void onDeviceListChanged(QInputDeviceManager::DeviceType type); + +private: + QEglFSKmsCursor *m_cursor; +}; class QEglFSKmsCursor : public QPlatformCursor { @@ -60,15 +77,26 @@ public: QPoint pos() const Q_DECL_OVERRIDE; void setPos(const QPoint &pos) Q_DECL_OVERRIDE; + void updateMouseStatus(); + private: void initCursorAtlas(); + enum CursorState { + CursorDisabled, + CursorPendingHidden, + CursorHidden, + CursorPendingVisible, + CursorVisible + }; + QEglFSKmsScreen *m_screen; QSize m_cursorSize; gbm_bo *m_bo; QPoint m_pos; QPlatformCursorImage m_cursorImage; - bool m_visible; + CursorState m_state; + QEglFSKmsCursorDeviceListener *m_deviceListener; // cursor atlas information struct CursorAtlas { -- cgit v1.2.3